DevNumb commited on
Commit
71a8b74
Β·
verified Β·
1 Parent(s): 1567712

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +593 -49
app.py CHANGED
@@ -35,23 +35,8 @@ departments = {
35
  }
36
  }
37
 
38
- # ======================================================
39
- # TEST EXAMPLES
40
- # ======================================================
41
-
42
- examples = [
43
- ["Ali Ben Salah", "production", "Packaging machine #4 stopped. Production is blocked. Need urgent maintenance support.", None, "administration", True, "High"],
44
- ["Sara Trabelsi", "magazine", "Need content approval and printing coordination before tomorrow’s issue.", None, "administration", True, "Medium"],
45
- ["Mohamed Kefi", "administration", "Requesting budget validation for new raw materials purchase.", None, "production", True, "Medium"],
46
- ["Ines Haddad", "production", "Quality defect rate increased to 7%. Root cause investigation required.", None, "administration", False, "High"],
47
- ["Karim Jaziri", "magazine", "Vendor delayed magazine printing. Need backup supplier urgently.", None, "administration", True, "High"]
48
- ]
49
-
50
- # ======================================================
51
- # ORIGINAL FUNCTIONS (UNCHANGED)
52
- # ======================================================
53
-
54
  def update_report_email(new_email):
 
55
  global current_report_email
56
  if new_email and "@" in new_email and "." in new_email:
57
  current_report_email = new_email.strip()
@@ -60,6 +45,7 @@ def update_report_email(new_email):
60
  return "❌ Please enter a valid email address"
61
 
62
  def send_email_brevo_api(to_email, subject, html_content, from_name="AI Coordination System"):
 
63
  try:
64
  if not BREVO_API_KEY:
65
  return "❌ Email not configured - missing Brevo API key"
@@ -93,73 +79,631 @@ def send_email_brevo_api(to_email, subject, html_content, from_name="AI Coordina
93
  return f"❌ Email error: {str(e)}"
94
 
95
  def analyze_coordination_needs(user_message, department, user_name, image=None):
 
 
96
  if image:
 
97
  buffered = io.BytesIO()
98
  image.save(buffered, format="PNG")
99
  img_base64 = base64.b64encode(buffered.getvalue()).decode()
100
- prompt = f"""As a helpful coordination assistant, analyze this request from {user_name} in the {department} department along with the attached image. REQUEST: {user_message}"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  try:
102
  response = requests.post(
103
  "https://openrouter.ai/api/v1/chat/completions",
104
- headers={"Authorization": f"Bearer {OPENROUTER_API_KEY}", "Content-Type": "application/json"},
 
 
 
105
  json={
106
- "model": "google/gemma-3-27b-it:free",
107
- "messages": [{"role":"user","content":[{"type":"text","text":prompt},{"type":"image_url","image_url":{"url":f"data:image/png;base64,{img_base64}"}}]}],
108
- "temperature":0.3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  },
110
  timeout=60
111
  )
 
112
  if response.status_code == 200:
113
  data = response.json()
114
  return data["choices"][0]["message"]["content"]
115
  else:
116
- return "I'm having trouble analyzing the image right now. Please try again later."
 
117
  except Exception as e:
118
- return f"Error: {str(e)}"
 
119
  else:
120
- prompt = f"As a helpful coordination assistant, analyze this request from {user_name} in the {department} department. REQUEST: {user_message}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  try:
122
  response = requests.post(
123
  "https://openrouter.ai/api/v1/chat/completions",
124
- headers={"Authorization": f"Bearer {OPENROUTER_API_KEY}", "Content-Type": "application/json"},
125
- json={"model": "google/gemma-3-27b-it:free", "messages":[{"role":"user","content":prompt}],"temperature":0.3},
 
 
 
 
 
 
 
126
  timeout=30
127
  )
 
128
  if response.status_code == 200:
129
  data = response.json()
130
  return data["choices"][0]["message"]["content"]
131
  else:
132
- return "I'm having trouble analyzing your request right now. Please try again later."
 
133
  except Exception as e:
134
- return f"Error: {str(e)}"
135
 
136
- # ======================================================
137
- # GRADIO UI
138
- # ======================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- with gr.Blocks(theme=gr.themes.Soft(), title="AI Coordination System") as ui:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  gr.Markdown("# 🏒 AI Department Coordination System")
142
  gr.Markdown("*Streamline communication between Administration, Production, and Magazine Management*")
143
-
144
  with gr.Row():
145
  with gr.Column(scale=1):
146
- name_input = gr.Textbox(label="Your Name", placeholder="Enter your full name")
147
- department_dropdown = gr.Dropdown(choices=["administration", "production", "magazine"], label="Your Department")
148
- message_input = gr.Textbox(label="What do you need help with?", lines=4)
149
- image_input = gr.Image(label="πŸ“· Attach Image (Optional)", type="pil")
150
- recipient_dropdown = gr.Dropdown(choices=["administration", "production", "magazine"], label="Notify Department")
151
- urgency_dropdown = gr.Dropdown(choices=["Normal","Medium","High"], value="Normal", label="Priority Level")
152
- send_email_checkbox = gr.Checkbox(label="Send email notification", value=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- submit_btn = gr.Button("πŸš€ Get Coordination Help", variant="primary")
155
- output = gr.Textbox(lines=18, label="Recommended Actions", show_copy_button=True)
156
-
157
- # βœ… WORKING EXAMPLES
158
- gr.Markdown("### πŸ§ͺ Quick Test Examples")
159
- gr.Examples(
160
- examples=examples,
161
- inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown]
162
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
  if __name__ == "__main__":
165
- ui.launch(share=True)
 
 
 
 
 
35
  }
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  def update_report_email(new_email):
39
+ """Update the report email address"""
40
  global current_report_email
41
  if new_email and "@" in new_email and "." in new_email:
42
  current_report_email = new_email.strip()
 
45
  return "❌ Please enter a valid email address"
46
 
47
  def send_email_brevo_api(to_email, subject, html_content, from_name="AI Coordination System"):
48
+ """Send email using Brevo API"""
49
  try:
50
  if not BREVO_API_KEY:
51
  return "❌ Email not configured - missing Brevo API key"
 
79
  return f"❌ Email error: {str(e)}"
80
 
81
  def analyze_coordination_needs(user_message, department, user_name, image=None):
82
+ """Use LLM to analyze coordination needs and suggest actions - with image support"""
83
+
84
  if image:
85
+ # Convert image to base64 for vision model
86
  buffered = io.BytesIO()
87
  image.save(buffered, format="PNG")
88
  img_base64 = base64.b64encode(buffered.getvalue()).decode()
89
+
90
+ prompt = f"""
91
+ You are an Enterprise Operations Coordination AI.
92
+
93
+ Analyze the request AND the attached image to determine responsibility and next actions.
94
+
95
+ Write formally and professionally.
96
+ No casual tone. No emojis.
97
+
98
+ AVAILABLE DEPARTMENTS:
99
+ - Administration: approvals, management, coordination
100
+ - Production: equipment, facilities, manufacturing, maintenance
101
+ - Magazine: design, content, publishing
102
+
103
+ REQUEST:
104
+ Requestor: {user_name}
105
+ Origin Department: {department}
106
+ Message: {user_message}
107
+
108
+ Provide:
109
+
110
+ === EXECUTIVE SUMMARY ===
111
+ Short professional summary
112
+
113
+ === IMAGE OBSERVATIONS ===
114
+ Important findings from the image
115
+
116
+ === RECOMMENDED TARGET DEPARTMENT ===
117
+ Choose ONLY ONE: Administration | Production | Magazine
118
+ Reason
119
+
120
+ === ACTION PLAN ===
121
+ Numbered steps
122
+
123
+ === PRIORITY ===
124
+ Low | Medium | High with reason
125
+
126
+ === FOLLOW-UP ===
127
+ Monitoring or escalation steps
128
+ """
129
  try:
130
  response = requests.post(
131
  "https://openrouter.ai/api/v1/chat/completions",
132
+ headers={
133
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
134
+ "Content-Type": "application/json",
135
+ },
136
  json={
137
+ "model": "google/gemma-3-27b-it:free", # Vision model
138
+ "messages": [
139
+ {
140
+ "role": "user",
141
+ "content": [
142
+ {
143
+ "type": "text",
144
+ "text": prompt
145
+ },
146
+ {
147
+ "type": "image_url",
148
+ "image_url": {
149
+ "url": f"data:image/png;base64,{img_base64}"
150
+ }
151
+ }
152
+ ]
153
+ }
154
+ ],
155
+ "temperature": 0.3
156
  },
157
  timeout=60
158
  )
159
+
160
  if response.status_code == 200:
161
  data = response.json()
162
  return data["choices"][0]["message"]["content"]
163
  else:
164
+ return "I'm having trouble analyzing the image right now. Please try again in a moment."
165
+
166
  except Exception as e:
167
+ return f"Sorry, I couldn't process the image. Error: {str(e)}"
168
+
169
  else:
170
+ # Text-only analysis
171
+ prompt = prompt = f"""
172
+ You are an Enterprise Operations Coordination AI used inside a professional organization.
173
+
174
+ Your responsibility is to:
175
+ β€’ analyze the request
176
+ β€’ determine which department should handle it
177
+ β€’ produce a concise, executive-style coordination plan
178
+
179
+ Write formally and professionally.
180
+ Do NOT use conversational tone.
181
+ Do NOT use emojis.
182
+ Be precise, structured, and action-oriented.
183
+
184
+ AVAILABLE DEPARTMENTS:
185
+ - Administration: management, approvals, policies, finance, coordination
186
+ - Production: manufacturing, maintenance, equipment, operations, logistics
187
+ - Magazine: content creation, publishing, marketing materials, communication
188
+
189
+ REQUEST:
190
+ Requestor: {user_name}
191
+ Origin Department: {department}
192
+ Message: {user_message}
193
+
194
+ Return your answer STRICTLY using this format:
195
+
196
+ === EXECUTIVE SUMMARY ===
197
+ 2–3 sentence professional summary.
198
+
199
+ === RECOMMENDED TARGET DEPARTMENT ===
200
+ Choose ONLY ONE: Administration | Production | Magazine
201
+ Brief justification.
202
+
203
+ === DEPARTMENTS INVOLVED ===
204
+ β€’ Department – responsibility
205
+
206
+ === ACTION PLAN ===
207
+ 1. Step
208
+ 2. Step
209
+ 3. Step
210
+
211
+ === PRIORITY ===
212
+ Low | Medium | High with reason
213
+
214
+ === FOLLOW-UP ===
215
+ Required monitoring or reporting actions
216
+ """
217
+
218
  try:
219
  response = requests.post(
220
  "https://openrouter.ai/api/v1/chat/completions",
221
+ headers={
222
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
223
+ "Content-Type": "application/json",
224
+ },
225
+ json={
226
+ "model": "google/gemma-3-27b-it:free",
227
+ "messages": [{"role": "user", "content": prompt}],
228
+ "temperature": 0.3
229
+ },
230
  timeout=30
231
  )
232
+
233
  if response.status_code == 200:
234
  data = response.json()
235
  return data["choices"][0]["message"]["content"]
236
  else:
237
+ return "I'm having trouble analyzing your request right now. Please try again in a moment."
238
+
239
  except Exception as e:
240
+ return f"Sorry, I couldn't process your request. Error: {str(e)}"
241
 
242
+ def send_department_email(sender_dept, recipient_dept, subject, message, user_name, urgency="Normal", image=None):
243
+ """Send email between departments with optional image attachment"""
244
+ try:
245
+ # Determine recipient email
246
+ recipient_email = departments[recipient_dept]["email"]
247
+ if not recipient_email:
248
+ # If no department email configured, use the current report email
249
+ recipient_email = current_report_email
250
+
251
+ # Create professional email content
252
+ image_note = "<p style='margin: 5px 0;'><strong>πŸ“Ž Attachment:</strong> Image included with request</p>" if image else ""
253
+ urgency_class = f"urgency-{urgency.lower()}" if urgency.lower() in ['high', 'medium'] else "urgency-normal"
254
+ image_footer = "<p><em>Note: An image was included with this request. Please check the original system for image details.</em></p>" if image else ""
255
+
256
+ html_content = f"""<html>
257
+ <head>
258
+ <style>
259
+ body {{ font-family: Arial, sans-serif; margin: 20px; }}
260
+ .header {{ background-color: #f4f4f4; padding: 20px; border-radius: 8px; margin-bottom: 20px; }}
261
+ .urgency-high {{ border-left: 5px solid #dc2626; background-color: #fef2f2; }}
262
+ .urgency-medium {{ border-left: 5px solid #d97706; background-color: #fffbeb; }}
263
+ .urgency-normal {{ border-left: 5px solid #2563eb; background-color: #eff6ff; }}
264
+ .message-content {{ padding: 20px; background-color: white; border-radius: 8px; margin: 15px 0; }}
265
+ .user-info {{ background-color: #f8fafc; padding: 10px 15px; border-radius: 6px; margin: 10px 0; }}
266
+ </style>
267
+ </head>
268
+ <body>
269
+ <div class="header">
270
+ <h1 style="margin: 0; color: #1f2937;">🏒 Inter-Department Communication</h1>
271
+ <p style="margin: 5px 0;"><strong>From:</strong> {departments[sender_dept]['name']}</p>
272
+ <p style="margin: 5px 0;"><strong>Requested by:</strong> {user_name}</p>
273
+ <p style="margin: 5px 0;"><strong>To:</strong> {departments[recipient_dept]['name']}</p>
274
+ <p style="margin: 5px 0;"><strong>Date:</strong> {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
275
+ <p style="margin: 5px 0;"><strong>Urgency:</strong> {urgency}</p>
276
+ {image_note}
277
+ </div>
278
+
279
+ <div class="user-info">
280
+ <strong>πŸ‘€ Requestor Details:</strong><br>
281
+ Name: {user_name}<br>
282
+ Department: {departments[sender_dept]['name']}
283
+ </div>
284
+
285
+ <div class="message-content {urgency_class}">
286
+ <h3 style="margin-top: 0;">{subject}</h3>
287
+ <div style="white-space: pre-line;">{message}</div>
288
+ </div>
289
+
290
+ <div style="color: #6b7280; font-size: 0.9em; margin-top: 20px;">
291
+ <p>This is an automated message from the AI Coordination System.</p>
292
+ {image_footer}
293
+ </div>
294
+ </body>
295
+ </html>"""
296
+
297
+ # Send email using Brevo API
298
+ from_name = f"{departments[sender_dept]['name']}"
299
+ email_status = send_email_brevo_api(recipient_email, f"[{urgency}] {subject}", html_content, from_name)
300
+ return email_status
301
+
302
+ except Exception as e:
303
+ return f"❌ Failed to send email: {str(e)}"
304
 
305
+ def send_email_report(conversation_data):
306
+ """Send comprehensive coordination report to administration"""
307
+ if not BREVO_API_KEY or not current_report_email:
308
+ return "Email reporting not configured - missing Brevo API key or report email"
309
+
310
+ try:
311
+ # Calculate department activity
312
+ dept_activity = {}
313
+ user_activity = {}
314
+ for entry in conversation_data:
315
+ dept = entry.get('department', 'Unknown')
316
+ user = entry.get('user_name', 'Unknown')
317
+ dept_activity[dept] = dept_activity.get(dept, 0) + 1
318
+ user_activity[user] = user_activity.get(user, 0) + 1
319
+
320
+ # Format email content
321
+ subject = f"Coordination Report - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}"
322
+
323
+ # Create department activity HTML
324
+ dept_activity_html = ""
325
+ for dept, count in dept_activity.items():
326
+ dept_activity_html += f"<p><strong>{dept.title()}:</strong> {count} interactions</p>"
327
+
328
+ # Create user activity HTML
329
+ user_activity_html = ""
330
+ for user, count in user_activity.items():
331
+ if user != 'Unknown':
332
+ user_activity_html += f"<p><strong>{user}:</strong> {count} requests</p>"
333
+
334
+ # Create recent activities HTML
335
+ recent_activities_html = ""
336
+ for i, entry in enumerate(conversation_data[-10:], 1):
337
+ dept_badge = f"<span class='department-badge'>{entry.get('department', 'General').title()}</span>" if entry.get('department') else ""
338
+ user_badge = f"<span class='user-badge'>{entry.get('user_name', 'User')}</span>" if entry.get('user_name') else ""
339
+ image_indicator = " <span class='image-indicator'>πŸ“·</span>" if entry.get('image_uploaded') else ""
340
+ email_indicator = " πŸ“§" if entry.get('email_sent') else ""
341
+
342
+ recent_activities_html += f"""<div class="exchange">
343
+ <div style="display: flex; justify-content: between; align-items: center; margin-bottom: 10px;">
344
+ <h4 style="margin: 0; color: #374151;">Activity #{i}</h4>
345
+ <div>
346
+ {dept_badge}
347
+ {user_badge}
348
+ {image_indicator}
349
+ </div>
350
+ </div>
351
+ <p class="user"><strong>πŸ’¬ Message:</strong> {entry['user_input']}{email_indicator}</p>
352
+ <p class="ai"><strong>πŸ€– AI Coordination:</strong> {entry['ai_response']}</p>
353
+ <p class="timestamp">{entry['timestamp']}</p>
354
+ </div>"""
355
+
356
+ # Create comprehensive HTML report
357
+ html_content = f"""<html>
358
+ <head>
359
+ <style>
360
+ body {{ font-family: Arial, sans-serif; margin: 20px; }}
361
+ .header {{ background-color: #1f2937; color: white; padding: 25px; border-radius: 8px; margin-bottom: 20px; }}
362
+ .stats {{ display: flex; justify-content: space-between; margin: 20px 0; }}
363
+ .stat-card {{ background-color: #f8fafc; padding: 15px; border-radius: 8px; text-align: center; flex: 1; margin: 0 10px; }}
364
+ .exchange {{ border: 1px solid #e0e0e0; margin: 15px 0; padding: 15px; border-radius: 8px; background-color: #fafafa; }}
365
+ .user {{ color: #2563eb; font-weight: 600; }}
366
+ .ai {{ color: #059669; }}
367
+ .timestamp {{ color: #6b7280; font-size: 0.8em; font-style: italic; }}
368
+ .department-badge {{ background-color: #3b82f6; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8em; }}
369
+ .user-badge {{ background-color: #10b981; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8em; margin-left: 5px; }}
370
+ .image-indicator {{ background-color: #f59e0b; color: white; padding: 2px 6px; border-radius: 10px; font-size: 0.7em; margin-left: 5px; }}
371
+ </style>
372
+ </head>
373
+ <body>
374
+ <div class="header">
375
+ <h1 style="margin: 0;">πŸ€– AI Coordination System Report</h1>
376
+ <p style="margin: 5px 0; opacity: 0.9;">Comprehensive inter-department coordination summary</p>
377
+ <p style="margin: 5px 0;"><strong>Generated:</strong> {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
378
+ </div>
379
+
380
+ <div class="stats">
381
+ <div class="stat-card">
382
+ <h3 style="margin: 0; color: #3b82f6;">{len(conversation_data)}</h3>
383
+ <p style="margin: 5px 0;">Total Interactions</p>
384
+ </div>
385
+ <div class="stat-card">
386
+ <h3 style="margin: 0; color: #10b981;">{len(dept_activity)}</h3>
387
+ <p style="margin: 5px 0;">Active Departments</p>
388
+ </div>
389
+ <div class="stat-card">
390
+ <h3 style="margin: 0; color: #f59e0b;">{sum(1 for entry in conversation_history if entry.get('email_sent'))}</h3>
391
+ <p style="margin: 5px 0;">Emails Sent</p>
392
+ </div>
393
+ </div>
394
+
395
+ <h3>πŸ“Š Department Activity</h3>
396
+ {dept_activity_html}
397
+
398
+ <h3>πŸ‘₯ User Activity</h3>
399
+ {user_activity_html if user_activity_html else "<p>No user activity data</p>"}
400
+
401
+ <h3>πŸ”„ Recent Coordination Activities</h3>
402
+ {recent_activities_html if recent_activities_html else "<p>No recent activities</p>"}
403
+
404
+ <div style="margin-top: 30px; padding: 15px; background-color: #f0fdf4; border-radius: 8px;">
405
+ <p style="margin: 0;"><strong>πŸ€– AI Note:</strong> This report is automatically generated by the coordination system. All inter-department communications are logged and monitored for efficiency.</p>
406
+ </div>
407
+ </body>
408
+ </html>"""
409
+
410
+ # Send email using Brevo API
411
+ email_status = send_email_brevo_api(current_report_email, subject, html_content, "AI Coordination System")
412
+ return email_status
413
+
414
+ except Exception as e:
415
+ return f"Failed to send report: {str(e)}"
416
+
417
+ def add_to_conversation_history(user_input, department, user_name, ai_response, email_sent=False, image_uploaded=False):
418
+ """Add current exchange to conversation history"""
419
+ entry = {
420
+ 'timestamp': datetime.datetime.now().isoformat(),
421
+ 'user_input': user_input,
422
+ 'department': department,
423
+ 'user_name': user_name,
424
+ 'ai_response': ai_response,
425
+ 'email_sent': email_sent,
426
+ 'image_uploaded': image_uploaded
427
+ }
428
+ conversation_history.append(entry)
429
+
430
+ # Keep only last 50 exchanges to prevent memory issues
431
+ if len(conversation_history) > 50:
432
+ conversation_history.pop(0)
433
+
434
+ def process_coordination_request(name, department, message, image, recipient_dept, send_email, urgency):
435
+ """Process coordination requests between departments with image support"""
436
+ if not message.strip():
437
+ return "Please enter a coordination message."
438
+
439
+ if not department:
440
+ return "Please select your department."
441
+
442
+ if not name.strip():
443
+ return "Please enter your name."
444
+
445
+ # Get AI analysis and suggestions (with image if provided)
446
+ ai_analysis = analyze_coordination_needs(message, department, name, image)
447
+
448
+ # Prepare response
449
+ response_parts = []
450
+ response_parts.append(f"**πŸ‘€ Request from:** {name} | **🏒 Department:** {departments[department]['name']}")
451
+
452
+ if image:
453
+ response_parts.append("**πŸ“· Image attached and analyzed**")
454
+
455
+ response_parts.append(f"\n**πŸ€– Coordination Guidance:**\n{ai_analysis}")
456
+
457
+ # Send email if requested
458
+ email_status = ""
459
+ if send_email and recipient_dept:
460
+ subject = f"Coordination Request from {departments[department]['name']} - {name}"
461
+
462
+ # Build email message
463
+ email_lines = [
464
+ f"Requestor: {name}",
465
+ f"Department: {departments[department]['name']}",
466
+ "",
467
+ "Message:",
468
+ message,
469
+ ""
470
+ ]
471
+
472
+ if image:
473
+ email_lines.append("Note: An image was included with this request. Please check the system for visual details.")
474
+ email_lines.append("")
475
+
476
+ email_lines.extend([
477
+ "---",
478
+ "Coordination Suggestions:",
479
+ ai_analysis
480
+ ])
481
+
482
+ email_message = "\n".join(email_lines)
483
+ email_status = send_department_email(department, recipient_dept, subject, email_message, name, urgency, image)
484
+ response_parts.append(f"\n**πŸ“§ Email Status:** {email_status}")
485
+
486
+ full_response = "\n".join(response_parts)
487
+
488
+ # Add to conversation history
489
+ add_to_conversation_history(
490
+ user_input=message,
491
+ department=department,
492
+ user_name=name,
493
+ ai_response=full_response,
494
+ email_sent=bool(send_email and recipient_dept),
495
+ image_uploaded=image is not None
496
+ )
497
+
498
+ return full_response
499
+
500
+ def get_conversation_stats():
501
+ """Get statistics about current coordination activities"""
502
+ if not conversation_history:
503
+ return "No coordination activities yet"
504
+
505
+ total_exchanges = len(conversation_history)
506
+ dept_activity = {}
507
+ user_activity = {}
508
+ emails_sent = sum(1 for entry in conversation_history if entry.get('email_sent'))
509
+ images_uploaded = sum(1 for entry in conversation_history if entry.get('image_uploaded'))
510
+
511
+ for entry in conversation_history:
512
+ dept = entry.get('department', 'Unknown')
513
+ user = entry.get('user_name', 'Unknown')
514
+ dept_activity[dept] = dept_activity.get(dept, 0) + 1
515
+ if user != 'Unknown':
516
+ user_activity[user] = user_activity.get(user, 0) + 1
517
+
518
+ stats_text = f"πŸ“Š **Coordination Summary:**\n"
519
+ stats_text += f"β€’ Total Activities: {total_exchanges}\n"
520
+ stats_text += f"β€’ Emails Sent: {emails_sent}\n"
521
+ stats_text += f"β€’ Images Shared: {images_uploaded}\n\n"
522
+
523
+ stats_text += "**Department Activity:**\n"
524
+ for dept, count in dept_activity.items():
525
+ stats_text += f"β€’ {dept.title()}: {count} requests\n"
526
+
527
+ if user_activity:
528
+ stats_text += f"\n**Active Team Members:** {', '.join(user_activity.keys())}"
529
+
530
+ return stats_text
531
+
532
+ def clear_conversation():
533
+ """Clear the conversation history"""
534
+ global conversation_history
535
+ conversation_history = []
536
+ return "πŸ—‘οΈ Coordination history cleared!"
537
+
538
+ def get_current_email():
539
+ """Get the current report email address"""
540
+ return current_report_email if current_report_email else "Not set"
541
+
542
+ def clear_form():
543
+ """Clear the form fields"""
544
+ return ["", None, "", None, "administration", "Normal", False]
545
+
546
+ # Gradio Interface
547
+ # Add this at the top of your Gradio Blocks
548
+ with gr.Blocks(
549
+ theme=gr.themes.Soft(),
550
+ title="AI Coordination System"
551
+ ) as ui:
552
  gr.Markdown("# 🏒 AI Department Coordination System")
553
  gr.Markdown("*Streamline communication between Administration, Production, and Magazine Management*")
554
+
555
  with gr.Row():
556
  with gr.Column(scale=1):
557
+ gr.Markdown("### βš™οΈ System Settings")
558
+ email_input = gr.Textbox(
559
+ label="Administration Report Email",
560
+ value=get_current_email,
561
+ placeholder="admin@company.com"
562
+ )
563
+ email_status = gr.Textbox(
564
+ label="Email Status",
565
+ value=get_current_email,
566
+ interactive=False,
567
+ max_lines=2
568
+ )
569
+ update_email_btn = gr.Button("πŸ’Ύ Save Email", variant="primary")
570
+
571
+ gr.Markdown("---")
572
+ gr.Markdown("### πŸ“ New Coordination Request")
573
+
574
+ with gr.Group():
575
+ gr.Markdown("#### πŸ‘€ Your Information")
576
+ name_input = gr.Textbox(
577
+ label="Your Name",
578
+ placeholder="Enter your full name"
579
+ )
580
+
581
+ department_dropdown = gr.Dropdown(
582
+ choices=["administration", "production", "magazine"],
583
+ label="Your Department"
584
+ )
585
+
586
+ with gr.Group():
587
+ gr.Markdown("#### πŸ’¬ Request Details")
588
+ message_input = gr.Textbox(
589
+ label="What do you need help with?",
590
+ lines=4,
591
+ placeholder="Describe what you need from other departments..."
592
+ )
593
+
594
+ image_input = gr.Image(
595
+ label="πŸ“· Attach Image (Optional)",
596
+ type="pil"
597
+ )
598
+
599
+ with gr.Group():
600
+ gr.Markdown("#### πŸ“§ Notification Options")
601
+ recipient_dropdown = gr.Dropdown(
602
+ choices=["administration", "production", "magazine"],
603
+ label="Notify Department"
604
+ )
605
+
606
+ urgency_dropdown = gr.Dropdown(
607
+ choices=["Normal", "Medium", "High"],
608
+ value="Normal",
609
+ label="Priority Level"
610
+ )
611
+
612
+ send_email_checkbox = gr.Checkbox(
613
+ label="Send email notification",
614
+ value=True
615
+ )
616
+
617
+ with gr.Row():
618
+ submit_btn = gr.Button("πŸš€ Get Coordination Help", variant="primary")
619
+ clear_form_btn = gr.Button("πŸ—‘οΈ Clear Form", variant="secondary")
620
+
621
+ with gr.Row():
622
+ report_btn = gr.Button("πŸ“‹ Submit & Send Report", variant="secondary")
623
+ clear_btn = gr.Button("πŸ—‚οΈ Clear History", variant="stop")
624
+ stats_btn = gr.Button("πŸ“ˆ View Stats")
625
+
626
+ status_display = gr.Textbox(
627
+ label="System Status",
628
+ interactive=False,
629
+ max_lines=2
630
+ )
631
 
632
+ stats_display = gr.Textbox(
633
+ label="Activity Summary",
634
+ interactive=False,
635
+ max_lines=6
 
 
 
 
636
  )
637
+
638
+ with gr.Column(scale=2):
639
+ gr.Markdown("### πŸ’‘ Coordination Guidance")
640
+ output = gr.Textbox(
641
+ label="Recommended Actions",
642
+ lines=18,
643
+ show_copy_button=True
644
+ )
645
+
646
+ with gr.Accordion("🏒 Department Overview", open=True):
647
+ gr.Markdown("**Administration**: Overall management, decision making, and coordination \n**Production**: Manufacturing, quality control, and production planning \n**Magazine Management**: Content creation, publishing, and distribution \n \n*The AI will analyze your message and any attached images to provide specific coordination recommendations.*")
648
+
649
+ with gr.Accordion("πŸ“œ Recent Activity", open=False):
650
+ history_display = gr.JSON(
651
+ label="Activity Log",
652
+ value=conversation_history[-10:] if conversation_history else []
653
+ )
654
+
655
+ # Event handlers
656
+ update_email_btn.click(
657
+ fn=update_report_email,
658
+ inputs=[email_input],
659
+ outputs=email_status
660
+ )
661
+
662
+ email_input.submit(
663
+ fn=update_report_email,
664
+ inputs=[email_input],
665
+ outputs=email_status
666
+ )
667
+
668
+ submit_btn.click(
669
+ fn=process_coordination_request,
670
+ inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown],
671
+ outputs=output
672
+ )
673
+
674
+ report_btn.click(
675
+ fn=lambda name, dept, msg, img, rec, send, urg: process_coordination_request(name, dept, msg, img, rec, send, urg) + "\n\n---\n" + send_email_report(conversation_history),
676
+ inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown],
677
+ outputs=output
678
+ )
679
+
680
+ message_input.submit(
681
+ fn=process_coordination_request,
682
+ inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown],
683
+ outputs=output
684
+ )
685
+
686
+ clear_btn.click(
687
+ fn=clear_conversation,
688
+ inputs=[],
689
+ outputs=status_display
690
+ )
691
+
692
+ clear_form_btn.click(
693
+ fn=clear_form,
694
+ inputs=[],
695
+ outputs=[name_input, image_input, message_input, recipient_dropdown, department_dropdown, urgency_dropdown, send_email_checkbox]
696
+ )
697
+
698
+ stats_btn.click(
699
+ fn=get_conversation_stats,
700
+ inputs=[],
701
+ outputs=stats_display
702
+ )
703
 
704
  if __name__ == "__main__":
705
+ ui.launch(share=True )
706
+
707
+
708
+
709
+