scmlewis commited on
Commit
cb13e5e
·
verified ·
1 Parent(s): 92f091f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -14
app.py CHANGED
@@ -1,9 +1,13 @@
 
 
1
  import os
2
  import gradio as gr
3
  import requests
4
  import json
5
  from datetime import datetime
6
 
 
 
7
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
8
  GROQ_COMPLETION_URL = "https://api.groq.com/openai/v1/chat/completions"
9
  GROQ_MODEL = "llama-3.1-8b-instant"
@@ -28,12 +32,13 @@ def groq_completion(prompt, sys_prompt=None):
28
  response = requests.post(GROQ_COMPLETION_URL, headers=headers, json=body)
29
  response.raise_for_status()
30
  return response.json()["choices"][0]["message"]["content"]
31
- except Exception as e:
32
- return "Error"
33
 
34
  def email_classifier_router(raw_email):
35
  prompt = (
36
- "Return ONLY compact JSON for analysis and response. Given the business email below, extract:"
 
37
  "\n- Category (Support Request, Sales Inquiry, Finance/Billing, Urgent Incident, Spam/Marketing)"
38
  "\n- Priority (Low, Medium, High)"
39
  "\n- Suggested Recipient"
@@ -44,16 +49,29 @@ def email_classifier_router(raw_email):
44
  f"{raw_email}"
45
  )
46
  raw_result = groq_completion(prompt)
 
 
 
 
 
 
 
 
 
47
  try:
48
  output = json.loads(raw_result)
49
- except Exception as e:
 
 
 
 
50
  output = {
51
- "Category": "Error",
52
- "Priority": "Error",
53
- "Suggested Recipient": "Error",
54
- "Draft Response": "",
55
- "Summary": "Error",
56
- "Action Items": ["Error"]
57
  }
58
  return output
59
 
@@ -71,6 +89,8 @@ def add_to_history(email, cat, pri, summ, dra):
71
  css="""
72
  body { background: linear-gradient(120deg, #10193a 0%, #175ad7 120%) !important; font-family: 'Inter', 'Segoe UI', Arial, sans-serif;}
73
  .gradio-container { background: transparent !important; }
 
 
74
  .card-block { background: rgba(27,36,68,0.96); border-radius: 30px; box-shadow: 0 6px 42px #0b2269bb, 0 1.5px 0 #186fc055 inset; padding: 38px 28px 29px 28px; margin: 32px 0; color: #fafeff; border: 2px solid #2847a46c; backdrop-filter: blur(8px);}
75
  input, textarea, .wrap.svelte-psy7la, .wrap.svelte-1ybjah6 { background: rgba(21,28,56,0.91)!important; border:1.5px solid #345ca3e3!important; color:#def1ff!important; border-radius: 14px !important; box-shadow: none !important;}
76
  label, .label.svelte-1ybjah6 { color: #70acf8!important; font-size: 1em !important; font-weight: 400;}
@@ -92,7 +112,13 @@ label, .label.svelte-1ybjah6 { color: #70acf8!important; font-size: 1em !importa
92
  """
93
 
94
  with gr.Blocks(css=css) as demo:
95
- gr.Markdown("<div class='card-header' style='text-align:center;margin-bottom:-10px;'>AI Email Classifier & Router</div>")
 
 
 
 
 
 
96
  with gr.Row():
97
  with gr.Column(scale=6, min_width=420):
98
  with gr.Group(elem_id="input-card", elem_classes=["card-block"]):
@@ -153,8 +179,9 @@ with gr.Blocks(css=css) as demo:
153
  acts = result.get("Action Items", [])
154
  acts = "\n".join(acts) if isinstance(acts, list) else acts
155
  add_to_history(email_text, cat, pri, summ, dra)
156
- badge = f"<b>Category:</b> <span class='badge'>{cat}</span> <b>Priority:</b> <span class='badge priority-{pri.lower()}'>{pri}</span>"
157
- result_labels_text = f"<div class='history-top'><span class='badge'>{cat}</span><span class='badge priority-{pri.lower()}'>{pri}</span></div>"
 
158
  # Only show last 5 records
159
  recent_history = classification_history[-5:][::-1]
160
  history_html = "<div class='history-cardrow'>"
@@ -174,7 +201,7 @@ with gr.Blocks(css=css) as demo:
174
  </div>
175
  """
176
  history_html += "</div>"
177
- return result_labels_text, rec, dra, summ, acts, history_html
178
 
179
  def clear_history():
180
  classification_history.clear()
 
1
+ # email_classifier_v2025.10.29-01.py
2
+
3
  import os
4
  import gradio as gr
5
  import requests
6
  import json
7
  from datetime import datetime
8
 
9
+ __version__ = "v2025.10.29-01"
10
+
11
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
12
  GROQ_COMPLETION_URL = "https://api.groq.com/openai/v1/chat/completions"
13
  GROQ_MODEL = "llama-3.1-8b-instant"
 
32
  response = requests.post(GROQ_COMPLETION_URL, headers=headers, json=body)
33
  response.raise_for_status()
34
  return response.json()["choices"][0]["message"]["content"]
35
+ except Exception:
36
+ return "ERROR:model_request"
37
 
38
  def email_classifier_router(raw_email):
39
  prompt = (
40
+ "Your reply MUST BE valid compact JSON. NO TEXT OR EXPLANATION before or after the JSON. "
41
+ "Given the business email below, extract:"
42
  "\n- Category (Support Request, Sales Inquiry, Finance/Billing, Urgent Incident, Spam/Marketing)"
43
  "\n- Priority (Low, Medium, High)"
44
  "\n- Suggested Recipient"
 
49
  f"{raw_email}"
50
  )
51
  raw_result = groq_completion(prompt)
52
+ if raw_result == "ERROR:model_request":
53
+ return {
54
+ "Category": "ERROR",
55
+ "Priority": "ERROR",
56
+ "Suggested Recipient": "ERROR",
57
+ "Draft Response": "Model request failed, please check API or retry.",
58
+ "Summary": "ERROR",
59
+ "Action Items": ["ERROR"]
60
+ }
61
  try:
62
  output = json.loads(raw_result)
63
+ # Ensure keys present, fallback if missing
64
+ for key in ["Category", "Priority", "Suggested Recipient", "Draft Response", "Summary", "Action Items"]:
65
+ if key not in output:
66
+ output[key] = ""
67
+ except Exception:
68
  output = {
69
+ "Category": "PARSE ERROR",
70
+ "Priority": "PARSE ERROR",
71
+ "Suggested Recipient": "",
72
+ "Draft Response": f"Could not extract valid JSON. Raw LLM output:\n{raw_result}",
73
+ "Summary": "PARSE ERROR",
74
+ "Action Items": ["PARSE ERROR"]
75
  }
76
  return output
77
 
 
89
  css="""
90
  body { background: linear-gradient(120deg, #10193a 0%, #175ad7 120%) !important; font-family: 'Inter', 'Segoe UI', Arial, sans-serif;}
91
  .gradio-container { background: transparent !important; }
92
+ .artifact-header { background:linear-gradient(90deg,#283e9d 70%,#36d1fa 150%); border-radius:28px; padding:38px 78px; box-shadow:0 10px 52px #184fa988; margin:0 auto 38px auto; display:flex;align-items:center;justify-content:center;}
93
+ .artifact-header-text {font-size:3.1em;font-weight:900;color:#fff;text-shadow:0 4px 44px #09f6ef,0 2px 20px #2e96ff;}
94
  .card-block { background: rgba(27,36,68,0.96); border-radius: 30px; box-shadow: 0 6px 42px #0b2269bb, 0 1.5px 0 #186fc055 inset; padding: 38px 28px 29px 28px; margin: 32px 0; color: #fafeff; border: 2px solid #2847a46c; backdrop-filter: blur(8px);}
95
  input, textarea, .wrap.svelte-psy7la, .wrap.svelte-1ybjah6 { background: rgba(21,28,56,0.91)!important; border:1.5px solid #345ca3e3!important; color:#def1ff!important; border-radius: 14px !important; box-shadow: none !important;}
96
  label, .label.svelte-1ybjah6 { color: #70acf8!important; font-size: 1em !important; font-weight: 400;}
 
112
  """
113
 
114
  with gr.Blocks(css=css) as demo:
115
+ gr.HTML("""
116
+ <div class="artifact-header">
117
+ <span class="artifact-header-text">📧 AI Email Classifier & Router</span>
118
+ <span style='margin-left:30px; font-size:1.5em; color:#fff;opacity:.50;'>Artifact <b>{ver}</b></span>
119
+ </div>
120
+ """.format(ver=__version__))
121
+
122
  with gr.Row():
123
  with gr.Column(scale=6, min_width=420):
124
  with gr.Group(elem_id="input-card", elem_classes=["card-block"]):
 
179
  acts = result.get("Action Items", [])
180
  acts = "\n".join(acts) if isinstance(acts, list) else acts
181
  add_to_history(email_text, cat, pri, summ, dra)
182
+ badge = (
183
+ f"<div class='history-top'><span class='badge'>{cat}</span><span class='badge priority-{pri.lower()}'>{pri}</span></div>"
184
+ )
185
  # Only show last 5 records
186
  recent_history = classification_history[-5:][::-1]
187
  history_html = "<div class='history-cardrow'>"
 
201
  </div>
202
  """
203
  history_html += "</div>"
204
+ return badge, rec, dra, summ, acts, history_html
205
 
206
  def clear_history():
207
  classification_history.clear()