Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,152 +1,105 @@
|
|
| 1 |
-
|
| 2 |
import random
|
| 3 |
import gradio as gr
|
|
|
|
| 4 |
from transformers import pipeline
|
| 5 |
-
from simple_salesforce import Salesforce
|
| 6 |
-
|
| 7 |
-
#
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
"
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
"Performance": "Medium",
|
| 32 |
-
"Error": "High",
|
| 33 |
-
"Security": "High",
|
| 34 |
-
"Best Practice": "Low"
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
# ---------- Load QnA Model ----------
|
| 38 |
-
qa_pipeline = pipeline("text2text-generation", model="google/flan-t5-base")
|
| 39 |
-
|
| 40 |
-
# ---------- Code Analyzer ----------
|
| 41 |
-
def analyze_code(code):
|
| 42 |
-
if not code.strip():
|
| 43 |
-
return "No code provided.", "", ""
|
| 44 |
-
|
| 45 |
-
# Simulate classification
|
| 46 |
-
label = random.choice(list(label_to_issue_type.keys()))
|
| 47 |
-
issue_type = label_to_issue_type[label]
|
| 48 |
-
suggestion = suggestions[issue_type]
|
| 49 |
-
severity = severities[issue_type]
|
| 50 |
|
| 51 |
try:
|
| 52 |
-
sf.
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
"
|
| 56 |
-
|
| 57 |
-
"
|
| 58 |
-
})
|
| 59 |
except Exception as e:
|
| 60 |
-
|
| 61 |
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
# ---------- Metadata Validator ----------
|
| 65 |
-
def validate_metadata(metadata):
|
| 66 |
-
if not metadata.strip():
|
| 67 |
-
return "No metadata provided.", "", ""
|
| 68 |
-
|
| 69 |
-
mtype = "Field"
|
| 70 |
-
issue = "Unused field detected"
|
| 71 |
-
recommendation = "Remove it to improve performance"
|
| 72 |
-
|
| 73 |
-
try:
|
| 74 |
-
sf.MetadataAuditLog__c.create({
|
| 75 |
-
"Name": f"MetadataLog_{mtype}",
|
| 76 |
-
"MetadataType__c": mtype,
|
| 77 |
-
"IssueDescription__c": issue,
|
| 78 |
-
"Recommendation__c": recommendation,
|
| 79 |
-
"Status__c": "Open"
|
| 80 |
-
})
|
| 81 |
-
except Exception as e:
|
| 82 |
-
recommendation += f" ⚠️ Salesforce logging failed: {str(e)}"
|
| 83 |
-
|
| 84 |
-
return mtype, issue, recommendation
|
| 85 |
-
|
| 86 |
-
# ---------- Natural Language Assistant (Improved Prompt) ----------
|
| 87 |
-
def process_nlp_query(query):
|
| 88 |
-
if not query.strip():
|
| 89 |
-
return "No question provided."
|
| 90 |
-
|
| 91 |
-
# Few-shot examples included in the prompt to simulate training
|
| 92 |
-
prompt = f"""
|
| 93 |
-
You are an expert Salesforce Apex developer and trainer. Your job is to answer questions accurately, concisely, and based strictly on Salesforce best practices and official documentation. Always include real values like governor limits, correct terminology, and coding insights.
|
| 94 |
-
|
| 95 |
-
Examples:
|
| 96 |
-
|
| 97 |
-
Q: How many DML operations are allowed in Apex?
|
| 98 |
-
A: You can perform up to 150 DML statements per Apex transaction.
|
| 99 |
-
|
| 100 |
-
Q: How many SOQL queries are allowed in Apex?
|
| 101 |
-
A: You can perform up to 100 SOQL queries per Apex transaction.
|
| 102 |
-
|
| 103 |
-
Q: What is a trigger in Salesforce?
|
| 104 |
-
A: A trigger is a piece of Apex code that executes before or after records are inserted, updated, deleted, or undeleted. Triggers help automate tasks and enforce business rules.
|
| 105 |
-
|
| 106 |
-
Q: What are governor limits in Apex?
|
| 107 |
-
A: Governor limits are runtime limits enforced by Salesforce to ensure efficient multi-tenancy. They include limits like 100 SOQL queries, 150 DML statements, and 10,000 records returned in queries per transaction.
|
| 108 |
-
|
| 109 |
-
Q: What is bulkification in Apex?
|
| 110 |
-
A: Bulkification is the practice of writing code that can handle multiple records at once, such as using loops and collections with DML to avoid hitting governor limits.
|
| 111 |
-
|
| 112 |
-
Now answer this new question as an expert would:
|
| 113 |
-
|
| 114 |
-
Q: {query.strip()}
|
| 115 |
-
A:
|
| 116 |
-
"""
|
| 117 |
-
|
| 118 |
-
try:
|
| 119 |
-
result = qa_pipeline(prompt, max_new_tokens=256, do_sample=False)
|
| 120 |
-
output = result[0]["generated_text"]
|
| 121 |
-
return output.strip()
|
| 122 |
-
except Exception as e:
|
| 123 |
-
return f"⚠️ AI Response Error: {str(e)}"
|
| 124 |
|
| 125 |
# ---------- Gradio UI ----------
|
| 126 |
-
with gr.Blocks() as demo:
|
| 127 |
-
gr.Markdown("# 🤖 Salesforce AI Code Review &
|
| 128 |
|
|
|
|
| 129 |
with gr.Tab("Code Review"):
|
| 130 |
-
code_input = gr.Textbox(label="Apex / LWC Code", lines=8)
|
| 131 |
issue_type = gr.Textbox(label="Issue Type")
|
| 132 |
suggestion = gr.Textbox(label="AI Suggestion")
|
| 133 |
severity = gr.Textbox(label="Severity")
|
| 134 |
code_button = gr.Button("Analyze Code")
|
| 135 |
code_button.click(analyze_code, inputs=code_input, outputs=[issue_type, suggestion, severity])
|
| 136 |
|
|
|
|
| 137 |
with gr.Tab("Metadata Validation"):
|
| 138 |
-
metadata_input = gr.Textbox(label="Metadata XML", lines=8)
|
| 139 |
mtype = gr.Textbox(label="Type")
|
| 140 |
issue = gr.Textbox(label="Issue")
|
| 141 |
recommendation = gr.Textbox(label="Recommendation")
|
| 142 |
metadata_button = gr.Button("Validate Metadata")
|
| 143 |
metadata_button.click(validate_metadata, inputs=metadata_input, outputs=[mtype, issue, recommendation])
|
| 144 |
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
# ---------- Start UI ----------
|
| 152 |
if __name__ == "__main__":
|
|
|
|
| 1 |
+
# [All your existing imports]
|
| 2 |
import random
|
| 3 |
import gradio as gr
|
| 4 |
+
from datetime import datetime
|
| 5 |
from transformers import pipeline
|
| 6 |
+
from simple_salesforce import Salesforce, SalesforceLogin, SFType
|
| 7 |
+
|
| 8 |
+
# [Your existing mappings, knowledge base, and model loading code remain unchanged]
|
| 9 |
+
|
| 10 |
+
# ---------- Salesforce Connection Setup ----------
|
| 11 |
+
# Replace these with your actual Salesforce credentials or use environment variables for security
|
| 12 |
+
SF_USERNAME = "your_username@example.com"
|
| 13 |
+
SF_PASSWORD = "your_password"
|
| 14 |
+
SF_SECURITY_TOKEN = "your_security_token"
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
session_id, instance = SalesforceLogin(
|
| 18 |
+
username=SF_USERNAME,
|
| 19 |
+
password=SF_PASSWORD,
|
| 20 |
+
security_token=SF_SECURITY_TOKEN
|
| 21 |
+
)
|
| 22 |
+
sf = Salesforce(instance=instance, session_id=session_id)
|
| 23 |
+
print("✅ Connected to Salesforce successfully")
|
| 24 |
+
except Exception as e:
|
| 25 |
+
sf = None
|
| 26 |
+
print(f"❌ Failed to connect to Salesforce: {e}")
|
| 27 |
+
|
| 28 |
+
# ---------- Function to Create Salesforce Record ----------
|
| 29 |
+
def create_salesforce_record(object_type, field_name, field_value):
|
| 30 |
+
if not sf:
|
| 31 |
+
return "Salesforce connection not established."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
try:
|
| 34 |
+
sobject = SFType(object_type, sf.session_id, sf.sf_instance)
|
| 35 |
+
result = sobject.create({field_name: field_value})
|
| 36 |
+
if result.get("success"):
|
| 37 |
+
return f"✅ Record created successfully in {object_type} with ID: {result['id']}"
|
| 38 |
+
else:
|
| 39 |
+
return f"❌ Failed to create record: {result}"
|
|
|
|
| 40 |
except Exception as e:
|
| 41 |
+
return f"⚠️ Error: {str(e)}"
|
| 42 |
|
| 43 |
+
# [Your existing functions: analyze_code, validate_metadata, salesforce_chatbot, etc. remain unchanged]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
|
| 45 |
# ---------- Gradio UI ----------
|
| 46 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 47 |
+
gr.Markdown("# 🤖 Advanced Salesforce AI Code Review & Chatbot")
|
| 48 |
|
| 49 |
+
# Tab 1: Code Review
|
| 50 |
with gr.Tab("Code Review"):
|
| 51 |
+
code_input = gr.Textbox(label="Apex / LWC Code", lines=8, placeholder="Enter your Apex or LWC code here")
|
| 52 |
issue_type = gr.Textbox(label="Issue Type")
|
| 53 |
suggestion = gr.Textbox(label="AI Suggestion")
|
| 54 |
severity = gr.Textbox(label="Severity")
|
| 55 |
code_button = gr.Button("Analyze Code")
|
| 56 |
code_button.click(analyze_code, inputs=code_input, outputs=[issue_type, suggestion, severity])
|
| 57 |
|
| 58 |
+
# Tab 2: Metadata Validation
|
| 59 |
with gr.Tab("Metadata Validation"):
|
| 60 |
+
metadata_input = gr.Textbox(label="Metadata XML", lines=8, placeholder="Enter your metadata XML here")
|
| 61 |
mtype = gr.Textbox(label="Type")
|
| 62 |
issue = gr.Textbox(label="Issue")
|
| 63 |
recommendation = gr.Textbox(label="Recommendation")
|
| 64 |
metadata_button = gr.Button("Validate Metadata")
|
| 65 |
metadata_button.click(validate_metadata, inputs=metadata_input, outputs=[mtype, issue, recommendation])
|
| 66 |
|
| 67 |
+
# Tab 3: Salesforce Chatbot
|
| 68 |
+
with gr.Tab("Salesforce Chatbot"):
|
| 69 |
+
gr.Markdown("### Ask a Salesforce Question\nGet expert answers on Apex, SOQL, LWC, and more!")
|
| 70 |
+
chatbot_output = gr.Chatbot(label="Conversation History", height=400)
|
| 71 |
+
query_input = gr.Textbox(label="Your Question", placeholder="e.g., How do I bulkify an Apex trigger?")
|
| 72 |
+
with gr.Row():
|
| 73 |
+
chatbot_button = gr.Button("Ask")
|
| 74 |
+
clear_button = gr.Button("Clear Chat")
|
| 75 |
+
|
| 76 |
+
chat_state = gr.State(value=[])
|
| 77 |
+
|
| 78 |
+
def update_chatbot(query, chat_history):
|
| 79 |
+
if not query.strip():
|
| 80 |
+
return chat_history, "Please enter a valid question."
|
| 81 |
+
response = salesforce_chatbot(query, chat_history)
|
| 82 |
+
chat_history.append((query, response))
|
| 83 |
+
return chat_history, ""
|
| 84 |
+
|
| 85 |
+
def clear_chat():
|
| 86 |
+
global conversation_history
|
| 87 |
+
conversation_history = []
|
| 88 |
+
return [], ""
|
| 89 |
+
|
| 90 |
+
chatbot_button.click(fn=update_chatbot, inputs=[query_input, chat_state], outputs=[chatbot_output, query_input])
|
| 91 |
+
clear_button.click(fn=clear_chat, inputs=None, outputs=[chatbot_output, query_input])
|
| 92 |
+
|
| 93 |
+
# Tab 4: Create Salesforce Record
|
| 94 |
+
with gr.Tab("Create Salesforce Record"):
|
| 95 |
+
gr.Markdown("### 📇 Create a New Salesforce Record")
|
| 96 |
+
object_type = gr.Textbox(label="Salesforce Object API Name", placeholder="e.g., Account")
|
| 97 |
+
field_name = gr.Textbox(label="Field API Name", placeholder="e.g., Name")
|
| 98 |
+
field_value = gr.Textbox(label="Field Value", placeholder="e.g., Test Company")
|
| 99 |
+
create_button = gr.Button("Create Record")
|
| 100 |
+
record_result = gr.Textbox(label="Result")
|
| 101 |
+
|
| 102 |
+
create_button.click(create_salesforce_record, inputs=[object_type, field_name, field_value], outputs=record_result)
|
| 103 |
|
| 104 |
# ---------- Start UI ----------
|
| 105 |
if __name__ == "__main__":
|