scmlewis commited on
Commit
e9c8c34
·
verified ·
1 Parent(s): 4eec9b9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -49
app.py CHANGED
@@ -7,7 +7,7 @@ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
7
  GROQ_COMPLETION_URL = "https://api.groq.com/openai/v1/chat/completions"
8
  GROQ_MODEL = "llama-3.1-8b-instant"
9
 
10
- def groq_completion(prompt, system_prompt=None):
11
  headers = {
12
  "Authorization": f"Bearer {GROQ_API_KEY}",
13
  "Content-Type": "application/json"
@@ -15,7 +15,7 @@ def groq_completion(prompt, system_prompt=None):
15
  body = {
16
  "model": GROQ_MODEL,
17
  "messages": [
18
- {"role": "system", "content": system_prompt or "You are a fast and reliable business email classification assistant."},
19
  {"role": "user", "content": prompt}
20
  ],
21
  "temperature": 0.3,
@@ -28,63 +28,98 @@ def groq_completion(prompt, system_prompt=None):
28
  except Exception as e:
29
  print("Groq API error:", e)
30
  if 'response' in locals():
31
- print("Groq API response text:", response.text)
32
  return "Error"
33
 
34
- def email_assistant(email_text):
35
- # Clear, strict prompt for JSON extraction
36
  prompt = (
37
- "Analyze the following business email and extract ONLY the following elements as a compact JSON dictionary:\n"
38
- "Category (Sales, Support, Spam, Finance, General),\n"
39
- "Confidence (percentage),\n"
40
- "Priority (High/Normal/Low),\n"
41
- "Suggested Action or Forwarding Address,\n"
42
- "Draft professional response,\n"
43
- "Action items (bulleted list).\n\n"
44
- "Return ONLY a compact JSON dictionary, nothing else:\n"
45
- '{"Category":"...", "Confidence":"...", "Priority":"...", "Suggested Action":"...", "Draft Response":"...", "Action Items":"..."}\n\n'
46
- f"EMAIL:\n{email_text}\n"
 
47
  )
48
  raw_result = groq_completion(prompt)
49
  try:
50
  output = json.loads(raw_result)
51
- return [
52
- output.get("Category", "Error"),
53
- output.get("Confidence", "Error"),
54
- output.get("Priority", "Error"),
55
- output.get("Suggested Action", "Error"),
56
- output.get("Draft Response", "Error"),
57
- output.get("Action Items", "Error"),
58
- ]
59
  except Exception as e:
60
- print(f"Parsing or LLM output error: {e}\nRaw output: {raw_result}")
61
- # Fail gracefully: show result in all fields for debugging
62
- return [raw_result]*6
 
 
 
 
 
 
 
63
 
64
- with gr.Blocks() as demo:
65
- gr.Markdown("# Email Classification & Response Assistant (Groq powered)")
66
- email_input = gr.TextArea(
67
- label="Paste your email here (include Subject, From, Body if possible)",
68
- placeholder="Subject: ...\nFrom: ...\nBody: ..."
69
  )
70
- submit = gr.Button("Analyze Email")
71
- output_category = gr.Textbox(label="Category")
72
- output_confidence = gr.Textbox(label="Confidence")
73
- output_priority = gr.Textbox(label="Priority")
74
- output_action = gr.Textbox(label="Suggested Action")
75
- output_response = gr.Textbox(label="Draft Response")
76
- output_items = gr.Textbox(label="Extracted Action Items")
77
- submit.click(
78
- email_assistant,
79
- inputs=email_input,
80
- outputs=[
81
- output_category,
82
- output_confidence,
83
- output_priority,
84
- output_action,
85
- output_response,
86
- output_items,
87
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  )
89
 
90
  if __name__ == "__main__":
 
7
  GROQ_COMPLETION_URL = "https://api.groq.com/openai/v1/chat/completions"
8
  GROQ_MODEL = "llama-3.1-8b-instant"
9
 
10
+ def groq_completion(prompt, sys_prompt=None):
11
  headers = {
12
  "Authorization": f"Bearer {GROQ_API_KEY}",
13
  "Content-Type": "application/json"
 
15
  body = {
16
  "model": GROQ_MODEL,
17
  "messages": [
18
+ {"role": "system", "content": sys_prompt or "You are a fast and reliable business email assistant."},
19
  {"role": "user", "content": prompt}
20
  ],
21
  "temperature": 0.3,
 
28
  except Exception as e:
29
  print("Groq API error:", e)
30
  if 'response' in locals():
31
+ print("Groq API response:", response.text)
32
  return "Error"
33
 
34
+ def email_classifier_router(raw_email):
 
35
  prompt = (
36
+ "Return ONLY compact JSON for analysis and response.\n"
37
+ "Given the business email below, extract:\n"
38
+ "- Category (Support Request, Sales Inquiry, Finance/Billing, Urgent Incident, Spam/Marketing)\n"
39
+ "- Priority (Low, Medium, High)\n"
40
+ "- Suggested Recipient (department or address)\n"
41
+ "- Professional draft reply\n"
42
+ "- Summary (one sentence)\n"
43
+ "- Action Items (numbered list)\n\n"
44
+ "Format:\n"
45
+ '{"Category":"...", "Priority":"...", "Suggested Recipient":"...", "Draft Response":"...", "Summary":"...", "Action Items":["...","..."]}\n\n'
46
+ f"{raw_email}"
47
  )
48
  raw_result = groq_completion(prompt)
49
  try:
50
  output = json.loads(raw_result)
 
 
 
 
 
 
 
 
51
  except Exception as e:
52
+ print(f"JSON parse error: {e}\nRAW: {raw_result}")
53
+ output = {
54
+ "Category": "Error",
55
+ "Priority": "Error",
56
+ "Suggested Recipient": "Error",
57
+ "Draft Response": raw_result,
58
+ "Summary": "Error",
59
+ "Action Items": ["Error"]
60
+ }
61
+ return output
62
 
63
+ # Gradio UI
64
+ with gr.Blocks(theme=gr.themes.Base(color_mode="dark")) as demo:
65
+ gr.Markdown(
66
+ "## 📨 AI Email Classifier & Router\n"
67
+ "Easily classify, route, and summarize business emails."
68
  )
69
+
70
+ with gr.Row():
71
+ gr.Markdown("**Load an example:**")
72
+ ex1 = "From: help@company.com\nSubject: Unable to Login\nHi, I can't access my dashboard. Can you help?"
73
+ ex2 = "From: sales@prospect.com\nSubject: Inquiry about pricing\nHi, Can you send over your latest pricing for enterprise?"
74
+ ex3 = "From: accounts@supplier.com\nSubject: Invoice #2024-00123 Due Date Reminder\nDear Valued Client, This is a reminder invoice #2024-00123 for $1,500.00 is due..."
75
+ ex4 = "From: it@company.com\nSubject: Server Down Alert\nURGENT: Database server unreachable since 3AM. Needs escalation."
76
+ ex5 = "From: spammer@promo.com\nSubject: BIG SALE!!!\nDon't miss our special offers!"
77
+ gr.Button("Support Request", elem_id="exSupport").click(lambda: ex1, None, 'email_box')
78
+ gr.Button("Sales Inquiry", elem_id="exSales").click(lambda: ex2, None, 'email_box')
79
+ gr.Button("Finance / Billing", elem_id="exFinance").click(lambda: ex3, None, 'email_box')
80
+ gr.Button("Urgent Incident", elem_id="exUrgent").click(lambda: ex4, None, 'email_box')
81
+ gr.Button("Spam / Marketing", elem_id="exSpam").click(lambda: ex5, None, 'email_box')
82
+
83
+ gr.Markdown("#### 📋 Paste or Load a Full Email:")
84
+ email_box = gr.Textbox(lines=8, label="Paste the entire raw email (including lines like 'From:', 'Subject:', etc.)", elem_id='email_box')
85
+
86
+ with gr.Row():
87
+ classify_btn = gr.Button("Classify Email", elem_id='classify_btn', variant="primary")
88
+
89
+ with gr.Column():
90
+ gr.Markdown("### ✅ Classification Results")
91
+ category = gr.Textbox(label="Category", elem_id='category')
92
+ priority = gr.Textbox(label="Priority", elem_id='priority')
93
+ recipient = gr.Textbox(label="Suggested Recipient", elem_id='recipient')
94
+
95
+ with gr.Column():
96
+ gr.Markdown("### ✨ Generated Response Draft")
97
+ draft_response = gr.Textbox(lines=8, label="Generated Draft", elem_id='draft_response')
98
+
99
+ with gr.Column():
100
+ gr.Markdown("#### Summary")
101
+ summary = gr.Textbox(label="Summary", elem_id='summary')
102
+
103
+ with gr.Column():
104
+ gr.Markdown("#### 🟣 Extracted Action Items")
105
+ action_items = gr.Textbox(lines=4, label="Extracted Action Items", elem_id='actions')
106
+
107
+ def classify_and_render(email_text):
108
+ result = email_classifier_router(email_text)
109
+ cat = result.get("Category", "")
110
+ pri = result.get("Priority", "")
111
+ rec = result.get("Suggested Recipient", "")
112
+ dra = result.get("Draft Response", "")
113
+ summ = result.get("Summary", "")
114
+ acts = result.get("Action Items", [])
115
+ # Render action items as multi-line string if list
116
+ acts = "\n".join(acts) if isinstance(acts, list) else acts
117
+ return cat, pri, rec, dra, summ, acts
118
+
119
+ classify_btn.click(
120
+ classify_and_render,
121
+ inputs=[email_box],
122
+ outputs=[category, priority, recipient, draft_response, summary, action_items]
123
  )
124
 
125
  if __name__ == "__main__":