| import gradio as gr |
| import requests |
| import os |
| import base64 |
| from PIL import Image |
| import io |
| import datetime |
|
|
| |
| OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY") |
| DEFAULT_REPORT_EMAIL = os.getenv("REPORT_EMAIL") |
| BREVO_API_KEY = os.getenv("BREVO_API_KEY") |
| BREVO_FROM_EMAIL = os.getenv("BREVO_FROM_EMAIL", "noreply@yourdomain.com") |
|
|
| |
| |
| DEMO_MODE = os.getenv("DEMO_MODE", "false").lower() == "true" if BREVO_API_KEY else True |
|
|
| |
| conversation_history = [] |
| current_report_email = DEFAULT_REPORT_EMAIL |
|
|
| |
| departments = { |
| "administration": { |
| "name": "Administration", |
| "email": os.getenv("ADMIN_EMAIL", "admin@demo.com"), |
| "responsibilities": "Overall management, decision making, and coordination" |
| }, |
| "production": { |
| "name": "Production", |
| "email": os.getenv("PRODUCTION_EMAIL", "production@demo.com"), |
| "responsibilities": "Manufacturing, quality control, and production planning" |
| }, |
| "magazine": { |
| "name": "Magazine Management", |
| "email": os.getenv("MAGAZINE_EMAIL", "magazine@demo.com"), |
| "responsibilities": "Content creation, publishing, and distribution" |
| } |
| } |
|
|
| def update_report_email(new_email): |
| """Update the report email address""" |
| global current_report_email |
| if new_email and "@" in new_email and "." in new_email: |
| current_report_email = new_email.strip() |
| return f"β
Report email updated to: {current_report_email}" |
| else: |
| return "β Please enter a valid email address" |
|
|
| def send_email(to_email, subject, html_content, from_name="AI Coordination System"): |
| """Send email using Brevo API""" |
| try: |
| |
| if DEMO_MODE or not BREVO_API_KEY: |
| return f"π§ͺ [DEMO MODE] Email simulated to {to_email}" |
| |
| response = requests.post( |
| "https://api.brevo.com/v3/smtp/email", |
| headers={ |
| "accept": "application/json", |
| "content-type": "application/json", |
| "api-key": BREVO_API_KEY |
| }, |
| json={ |
| "sender": { |
| "name": from_name, |
| "email": BREVO_FROM_EMAIL |
| }, |
| "to": [{"email": to_email}], |
| "subject": subject, |
| "htmlContent": html_content |
| }, |
| timeout=10 |
| ) |
| |
| if response.status_code == 201: |
| return f"β
Email sent to {to_email}" |
| else: |
| error_msg = response.json().get('message', 'Unknown error') |
| return f"β Failed to send email: {error_msg}" |
| |
| except Exception as e: |
| return f"β Email error: {str(e)}" |
|
|
| def get_mock_ai_response(user_message, department, user_name, has_image=False): |
| """Generate a mock AI response for demo/testing mode""" |
| |
| image_section = """ |
| === IMAGE OBSERVATIONS === |
| β’ Mock analysis: Image appears to show office equipment |
| β’ Suggested action: Forward to relevant department for review |
| """ if has_image else "" |
| |
| responses = { |
| "administration": { |
| "equipment": f""" |
| === EXECUTIVE SUMMARY === |
| Request from {user_name} regarding equipment needs requires coordination between Administration and Production departments for budget approval and implementation. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Production |
| This is primarily a production-related request that requires equipment or facility resources. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Production β Equipment assessment and implementation |
| β’ Administration β Budget approval and procurement authorization |
| |
| === ACTION PLAN === |
| 1. Production department to assess equipment specifications and requirements |
| 2. Administration to review budget implications and approve funding |
| 3. Production to coordinate installation and training |
| |
| === PRIORITY === |
| Medium β Standard equipment request requiring normal procurement timeline |
| |
| === FOLLOW-UP === |
| Weekly status updates until equipment is operational |
| """, |
| "default": f""" |
| === EXECUTIVE SUMMARY === |
| Administrative request from {user_name} requires internal review and possible coordination with other departments. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Administration |
| This request should be handled within the Administration department. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Administration β Primary responsibility for coordination and decision-making |
| |
| === ACTION PLAN === |
| 1. Review request details and requirements |
| 2. Determine resource allocation and timeline |
| 3. Coordinate with relevant stakeholders |
| |
| === PRIORITY === |
| Normal β Standard administrative workflow |
| |
| === FOLLOW-UP === |
| Monitor progress and provide status updates as needed |
| """ |
| }, |
| "production": { |
| "content": f""" |
| === EXECUTIVE SUMMARY === |
| Production request from {user_name} involves content creation, requiring Magazine department collaboration. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Magazine |
| This request involves content creation and publishing activities. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Magazine β Content development and design |
| β’ Production β Material production and quality control |
| |
| === ACTION PLAN === |
| 1. Magazine to develop content and design specifications |
| 2. Production to review technical feasibility |
| 3. Coordinate timeline for material production |
| |
| === PRIORITY === |
| Medium β Requires cross-departmental coordination |
| |
| === FOLLOW-UP === |
| Bi-weekly alignment meetings until project completion |
| """, |
| "default": f""" |
| === EXECUTIVE SUMMARY === |
| Production request from {user_name} requires assessment of manufacturing capabilities and resource allocation. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Production |
| Internal production department matter requiring operational attention. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Production β Manufacturing operations and quality assurance |
| β’ Administration β Resource approval if needed |
| |
| === ACTION PLAN === |
| 1. Assess current production capacity and requirements |
| 2. Identify resource needs and constraints |
| 3. Develop implementation timeline |
| |
| === PRIORITY === |
| Normal β Standard production workflow |
| |
| === FOLLOW-UP === |
| Regular progress monitoring through production meetings |
| """ |
| }, |
| "magazine": { |
| "printing": f""" |
| === EXECUTIVE SUMMARY === |
| Magazine request from {user_name} regarding printing requires Production department involvement for manufacturing execution. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Production |
| Printing and manufacturing activities fall under Production responsibility. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Magazine β Content finalization and specifications |
| β’ Production β Printing operations and quality control |
| |
| === ACTION PLAN === |
| 1. Magazine to finalize all content and design specifications |
| 2. Production to schedule printing resources |
| 3. Coordinate delivery timeline and distribution |
| |
| === PRIORITY === |
| High β Publishing deadline-sensitive activity |
| |
| === FOLLOW-UP === |
| Daily updates during production phase |
| """, |
| "default": f""" |
| === EXECUTIVE SUMMARY === |
| Magazine department request from {user_name} involves content development and publishing coordination. |
| |
| {image_section} |
| === RECOMMENDED TARGET DEPARTMENT === |
| Magazine |
| Editorial and publishing matter for Magazine department handling. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Magazine β Content creation and editorial oversight |
| β’ Production β Technical production support if needed |
| |
| === ACTION PLAN === |
| 1. Develop content strategy and editorial plan |
| 2. Coordinate with relevant stakeholders |
| 3. Execute publishing timeline |
| |
| === PRIORITY === |
| Normal β Standard editorial workflow |
| |
| === FOLLOW-UP === |
| Editorial review meetings and publication tracking |
| """ |
| } |
| } |
| |
| |
| message_lower = user_message.lower() |
| dept_responses = responses.get(department, responses["administration"]) |
| |
| for keyword, response in dept_responses.items(): |
| if keyword != "default" and keyword in message_lower: |
| return response |
| |
| return dept_responses["default"] |
|
|
| def analyze_coordination_needs(user_message, department, user_name, image=None): |
| """Use LLM to analyze coordination needs and suggest actions - with image support""" |
| |
| |
| if DEMO_MODE or not OPENROUTER_API_KEY: |
| return get_mock_ai_response(user_message, department, user_name, has_image=image is not None) |
| |
| if image: |
| |
| buffered = io.BytesIO() |
| image.save(buffered, format="PNG") |
| img_base64 = base64.b64encode(buffered.getvalue()).decode() |
| |
| prompt = f""" |
| You are an Enterprise Operations Coordination AI. |
| |
| Analyze the request AND the attached image to determine responsibility and next actions. |
| |
| Write formally and professionally. |
| No casual tone. No emojis. |
| |
| AVAILABLE DEPARTMENTS: |
| - Administration: approvals, management, coordination |
| - Production: equipment, facilities, manufacturing, maintenance |
| - Magazine: design, content, publishing |
| |
| REQUEST: |
| Requestor: {user_name} |
| Origin Department: {department} |
| Message: {user_message} |
| |
| Provide: |
| |
| === EXECUTIVE SUMMARY === |
| Short professional summary |
| |
| === IMAGE OBSERVATIONS === |
| Important findings from the image |
| |
| === RECOMMENDED TARGET DEPARTMENT === |
| Choose ONLY ONE: Administration | Production | Magazine |
| Reason |
| |
| === ACTION PLAN === |
| Numbered steps |
| |
| === PRIORITY === |
| Low | Medium | High with reason |
| |
| === FOLLOW-UP === |
| Monitoring or escalation steps |
| """ |
| try: |
| response = requests.post( |
| "https://openrouter.ai/api/v1/chat/completions", |
| headers={ |
| "Authorization": f"Bearer {OPENROUTER_API_KEY}", |
| "Content-Type": "application/json", |
| }, |
| json={ |
| "model": "google/gemma-3-27b-it:free", |
| "messages": [ |
| { |
| "role": "user", |
| "content": [ |
| { |
| "type": "text", |
| "text": prompt |
| }, |
| { |
| "type": "image_url", |
| "image_url": { |
| "url": f"data:image/png;base64,{img_base64}" |
| } |
| } |
| ] |
| } |
| ], |
| "temperature": 0.3 |
| }, |
| timeout=30 |
| ) |
| |
| if response.status_code == 200: |
| data = response.json() |
| return data["choices"][0]["message"]["content"] |
| else: |
| |
| return get_mock_ai_response(user_message, department, user_name, has_image=True) |
| |
| except Exception as e: |
| |
| return get_mock_ai_response(user_message, department, user_name, has_image=True) |
| |
| else: |
| |
| prompt = f""" |
| You are an Enterprise Operations Coordination AI used inside a professional organization. |
| |
| Your responsibility is to: |
| β’ analyze the request |
| β’ determine which department should handle it |
| β’ produce a concise, executive-style coordination plan |
| |
| Write formally and professionally. |
| Do NOT use conversational tone. |
| Do NOT use emojis. |
| Be precise, structured, and action-oriented. |
| |
| AVAILABLE DEPARTMENTS: |
| - Administration: management, approvals, policies, finance, coordination |
| - Production: manufacturing, maintenance, equipment, operations, logistics |
| - Magazine: content creation, publishing, marketing materials, communication |
| |
| REQUEST: |
| Requestor: {user_name} |
| Origin Department: {department} |
| Message: {user_message} |
| |
| Return your answer STRICTLY using this format: |
| |
| === EXECUTIVE SUMMARY === |
| 2β3 sentence professional summary. |
| |
| === RECOMMENDED TARGET DEPARTMENT === |
| Choose ONLY ONE: Administration | Production | Magazine |
| Brief justification. |
| |
| === DEPARTMENTS INVOLVED === |
| β’ Department β responsibility |
| |
| === ACTION PLAN === |
| 1. Step |
| 2. Step |
| 3. Step |
| |
| === PRIORITY === |
| Low | Medium | High with reason |
| |
| === FOLLOW-UP === |
| Required monitoring or reporting actions |
| """ |
|
|
| try: |
| response = requests.post( |
| "https://openrouter.ai/api/v1/chat/completions", |
| headers={ |
| "Authorization": f"Bearer {OPENROUTER_API_KEY}", |
| "Content-Type": "application/json", |
| }, |
| json={ |
| "model": "google/gemma-3-27b-it:free", |
| "messages": [{"role": "user", "content": prompt}], |
| "temperature": 0.3 |
| }, |
| timeout=20 |
| ) |
| |
| if response.status_code == 200: |
| data = response.json() |
| return data["choices"][0]["message"]["content"] |
| else: |
| |
| return get_mock_ai_response(user_message, department, user_name, has_image=False) |
| |
| except Exception as e: |
| |
| return get_mock_ai_response(user_message, department, user_name, has_image=False) |
|
|
| def send_department_email(sender_dept, recipient_dept, subject, message, user_name, urgency="Normal", image=None): |
| """Send email between departments with optional image attachment""" |
| try: |
| |
| recipient_email = departments[recipient_dept]["email"] |
| if not recipient_email: |
| |
| recipient_email = current_report_email |
| |
| |
| image_note = "<p style='margin: 5px 0;'><strong>π Attachment:</strong> Image included with request</p>" if image else "" |
| urgency_class = f"urgency-{urgency.lower()}" if urgency.lower() in ['high', 'medium'] else "urgency-normal" |
| 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 "" |
| |
| html_content = f"""<html> |
| <head> |
| <style> |
| body {{ font-family: Arial, sans-serif; margin: 20px; }} |
| .header {{ background-color: #f4f4f4; padding: 20px; border-radius: 8px; margin-bottom: 20px; }} |
| .urgency-high {{ border-left: 5px solid #dc2626; background-color: #fef2f2; }} |
| .urgency-medium {{ border-left: 5px solid #d97706; background-color: #fffbeb; }} |
| .urgency-normal {{ border-left: 5px solid #2563eb; background-color: #eff6ff; }} |
| .message-content {{ padding: 20px; background-color: white; border-radius: 8px; margin: 15px 0; }} |
| .user-info {{ background-color: #f8fafc; padding: 10px 15px; border-radius: 6px; margin: 10px 0; }} |
| </style> |
| </head> |
| <body> |
| <div class="header"> |
| <h1 style="margin: 0; color: #1f2937;">π’ Inter-Department Communication</h1> |
| <p style="margin: 5px 0;"><strong>From:</strong> {departments[sender_dept]['name']}</p> |
| <p style="margin: 5px 0;"><strong>Requested by:</strong> {user_name}</p> |
| <p style="margin: 5px 0;"><strong>To:</strong> {departments[recipient_dept]['name']}</p> |
| <p style="margin: 5px 0;"><strong>Date:</strong> {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p> |
| <p style="margin: 5px 0;"><strong>Urgency:</strong> {urgency}</p> |
| {image_note} |
| </div> |
| |
| <div class="user-info"> |
| <strong>π€ Requestor Details:</strong><br> |
| Name: {user_name}<br> |
| Department: {departments[sender_dept]['name']} |
| </div> |
| |
| <div class="message-content {urgency_class}"> |
| <h3 style="margin-top: 0;">{subject}</h3> |
| <div style="white-space: pre-line;">{message}</div> |
| </div> |
| |
| <div style="color: #6b7280; font-size: 0.9em; margin-top: 20px;"> |
| <p>This is an automated message from the AI Coordination System.</p> |
| {image_footer} |
| </div> |
| </body> |
| </html>""" |
| |
| |
| from_name = f"{departments[sender_dept]['name']}" |
| email_status = send_email(recipient_email, f"[{urgency}] {subject}", html_content, from_name) |
| return email_status |
| |
| except Exception as e: |
| return f"β Failed to send email: {str(e)}" |
|
|
| def send_email_report(conversation_data): |
| """Send comprehensive coordination report to administration""" |
| |
| if DEMO_MODE or not BREVO_API_KEY: |
| return "π§ͺ [DEMO MODE] Report email simulated successfully" |
| |
| if not current_report_email: |
| return "β Report email not configured - please set report email address" |
| |
| try: |
| |
| dept_activity = {} |
| user_activity = {} |
| for entry in conversation_data: |
| dept = entry.get('department', 'Unknown') |
| user = entry.get('user_name', 'Unknown') |
| dept_activity[dept] = dept_activity.get(dept, 0) + 1 |
| user_activity[user] = user_activity.get(user, 0) + 1 |
| |
| |
| subject = f"Coordination Report - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}" |
| |
| |
| dept_activity_html = "" |
| for dept, count in dept_activity.items(): |
| dept_activity_html += f"<p><strong>{dept.title()}:</strong> {count} interactions</p>" |
| |
| |
| user_activity_html = "" |
| for user, count in user_activity.items(): |
| if user != 'Unknown': |
| user_activity_html += f"<p><strong>{user}:</strong> {count} requests</p>" |
| |
| |
| recent_activities_html = "" |
| for i, entry in enumerate(conversation_data[-10:], 1): |
| dept_badge = f"<span class='department-badge'>{entry.get('department', 'General').title()}</span>" if entry.get('department') else "" |
| user_badge = f"<span class='user-badge'>{entry.get('user_name', 'User')}</span>" if entry.get('user_name') else "" |
| image_indicator = " <span class='image-indicator'>π·</span>" if entry.get('image_uploaded') else "" |
| email_indicator = " π§" if entry.get('email_sent') else "" |
| |
| recent_activities_html += f"""<div class="exchange"> |
| <div style="display: flex; justify-content: between; align-items: center; margin-bottom: 10px;"> |
| <h4 style="margin: 0; color: #374151;">Activity #{i}</h4> |
| <div> |
| {dept_badge} |
| {user_badge} |
| {image_indicator} |
| </div> |
| </div> |
| <p class="user"><strong>π¬ Message:</strong> {entry['user_input']}{email_indicator}</p> |
| <p class="ai"><strong>π€ AI Coordination:</strong> {entry['ai_response']}</p> |
| <p class="timestamp">{entry['timestamp']}</p> |
| </div>""" |
| |
| |
| html_content = f"""<html> |
| <head> |
| <style> |
| body {{ font-family: Arial, sans-serif; margin: 20px; }} |
| .header {{ background-color: #1f2937; color: white; padding: 25px; border-radius: 8px; margin-bottom: 20px; }} |
| .stats {{ display: flex; justify-content: space-between; margin: 20px 0; }} |
| .stat-card {{ background-color: #f8fafc; padding: 15px; border-radius: 8px; text-align: center; flex: 1; margin: 0 10px; }} |
| .exchange {{ border: 1px solid #e0e0e0; margin: 15px 0; padding: 15px; border-radius: 8px; background-color: #fafafa; }} |
| .user {{ color: #2563eb; font-weight: 600; }} |
| .ai {{ color: #059669; }} |
| .timestamp {{ color: #6b7280; font-size: 0.8em; font-style: italic; }} |
| .department-badge {{ background-color: #3b82f6; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8em; }} |
| .user-badge {{ background-color: #10b981; color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8em; margin-left: 5px; }} |
| .image-indicator {{ background-color: #f59e0b; color: white; padding: 2px 6px; border-radius: 10px; font-size: 0.7em; margin-left: 5px; }} |
| </style> |
| </head> |
| <body> |
| <div class="header"> |
| <h1 style="margin: 0;">π€ AI Coordination System Report</h1> |
| <p style="margin: 5px 0; opacity: 0.9;">Comprehensive inter-department coordination summary</p> |
| <p style="margin: 5px 0;"><strong>Generated:</strong> {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p> |
| </div> |
| |
| <div class="stats"> |
| <div class="stat-card"> |
| <h3 style="margin: 0; color: #3b82f6;">{len(conversation_data)}</h3> |
| <p style="margin: 5px 0;">Total Interactions</p> |
| </div> |
| <div class="stat-card"> |
| <h3 style="margin: 0; color: #10b981;">{len(dept_activity)}</h3> |
| <p style="margin: 5px 0;">Active Departments</p> |
| </div> |
| <div class="stat-card"> |
| <h3 style="margin: 0; color: #f59e0b;">{sum(1 for entry in conversation_history if entry.get('email_sent'))}</h3> |
| <p style="margin: 5px 0;">Emails Sent</p> |
| </div> |
| </div> |
| |
| <h3>π Department Activity</h3> |
| {dept_activity_html} |
| |
| <h3>π₯ User Activity</h3> |
| {user_activity_html if user_activity_html else "<p>No user activity data</p>"} |
| |
| <h3>π Recent Coordination Activities</h3> |
| {recent_activities_html if recent_activities_html else "<p>No recent activities</p>"} |
| |
| <div style="margin-top: 30px; padding: 15px; background-color: #f0fdf4; border-radius: 8px;"> |
| <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> |
| </div> |
| </body> |
| </html>""" |
| |
| |
| email_status = send_email(current_report_email, subject, html_content, "AI Coordination System") |
| return email_status |
| |
| except Exception as e: |
| return f"Failed to send report: {str(e)}" |
|
|
| def add_to_conversation_history(user_input, department, user_name, ai_response, email_sent=False, image_uploaded=False): |
| """Add current exchange to conversation history""" |
| entry = { |
| 'timestamp': datetime.datetime.now().isoformat(), |
| 'user_input': user_input, |
| 'department': department, |
| 'user_name': user_name, |
| 'ai_response': ai_response, |
| 'email_sent': email_sent, |
| 'image_uploaded': image_uploaded |
| } |
| conversation_history.append(entry) |
| |
| |
| if len(conversation_history) > 50: |
| conversation_history.pop(0) |
|
|
| def process_coordination_request(name, department, message, image, recipient_dept, send_email, urgency): |
| """Process coordination requests between departments with image support""" |
| if not message.strip(): |
| return "Please enter a coordination message." |
| |
| if not department: |
| return "Please select your department." |
| |
| if not name.strip(): |
| return "Please enter your name." |
| |
| |
| ai_analysis = analyze_coordination_needs(message, department, name, image) |
| |
| |
| response_parts = [] |
| |
| |
| if DEMO_MODE: |
| response_parts.append("π§ͺ **DEMO MODE ACTIVE** - Using simulated AI responses") |
| |
| response_parts.append(f"**π€ Request from:** {name} | **π’ Department:** {departments[department]['name']}") |
| |
| if image: |
| response_parts.append("**π· Image attached and analyzed**") |
| |
| response_parts.append(f"\n**π€ Coordination Guidance:**\n{ai_analysis}") |
| |
| |
| email_status = "" |
| if send_email and recipient_dept: |
| subject = f"Coordination Request from {departments[department]['name']} - {name}" |
| |
| |
| email_lines = [ |
| f"Requestor: {name}", |
| f"Department: {departments[department]['name']}", |
| "", |
| "Message:", |
| message, |
| "" |
| ] |
| |
| if image: |
| email_lines.append("Note: An image was included with this request. Please check the system for visual details.") |
| email_lines.append("") |
| |
| email_lines.extend([ |
| "---", |
| "Coordination Suggestions:", |
| ai_analysis |
| ]) |
| |
| email_message = "\n".join(email_lines) |
| email_status = send_department_email(department, recipient_dept, subject, email_message, name, urgency, image) |
| response_parts.append(f"\n**π§ Email Status:** {email_status}") |
| |
| full_response = "\n".join(response_parts) |
| |
| |
| add_to_conversation_history( |
| user_input=message, |
| department=department, |
| user_name=name, |
| ai_response=full_response, |
| email_sent=bool(send_email and recipient_dept), |
| image_uploaded=image is not None |
| ) |
| |
| return full_response |
|
|
| def get_conversation_stats(): |
| """Get statistics about current coordination activities""" |
| if not conversation_history: |
| return "No coordination activities yet" |
| |
| total_exchanges = len(conversation_history) |
| dept_activity = {} |
| user_activity = {} |
| emails_sent = sum(1 for entry in conversation_history if entry.get('email_sent')) |
| images_uploaded = sum(1 for entry in conversation_history if entry.get('image_uploaded')) |
| |
| for entry in conversation_history: |
| dept = entry.get('department', 'Unknown') |
| user = entry.get('user_name', 'Unknown') |
| dept_activity[dept] = dept_activity.get(dept, 0) + 1 |
| if user != 'Unknown': |
| user_activity[user] = user_activity.get(user, 0) + 1 |
| |
| stats_text = f"π **Coordination Summary:**\n" |
| stats_text += f"β’ Total Activities: {total_exchanges}\n" |
| stats_text += f"β’ Emails Sent: {emails_sent}\n" |
| stats_text += f"β’ Images Shared: {images_uploaded}\n\n" |
| |
| stats_text += "**Department Activity:**\n" |
| for dept, count in dept_activity.items(): |
| stats_text += f"β’ {dept.title()}: {count} requests\n" |
| |
| if user_activity: |
| stats_text += f"\n**Active Team Members:** {', '.join(user_activity.keys())}" |
| |
| return stats_text |
|
|
| def clear_conversation(): |
| """Clear the conversation history""" |
| global conversation_history |
| conversation_history = [] |
| return "ποΈ Coordination history cleared!" |
|
|
| def get_current_email(): |
| """Get the current report email address""" |
| return current_report_email if current_report_email else "demo@example.com" |
|
|
| def clear_form(): |
| """Clear the form fields""" |
| return ["", None, "", None, "administration", "Normal", False] |
|
|
| def load_sample_request(sample_type): |
| """Load sample requests for testing""" |
| samples = { |
| "Equipment Request": { |
| "name": "John Smith", |
| "dept": "production", |
| "message": "We need to upgrade our printing equipment. The current machines are outdated and causing quality issues.", |
| "recipient": "administration", |
| "urgency": "Medium" |
| }, |
| "Content Collaboration": { |
| "name": "Sarah Johnson", |
| "dept": "magazine", |
| "message": "Need production support for our next magazine issue. We have special requirements for paper quality and binding.", |
| "recipient": "production", |
| "urgency": "High" |
| }, |
| "Budget Approval": { |
| "name": "Mike Chen", |
| "dept": "production", |
| "message": "Requesting budget approval for preventive maintenance on critical machinery.", |
| "recipient": "administration", |
| "urgency": "Normal" |
| } |
| } |
| |
| if sample_type in samples: |
| s = samples[sample_type] |
| return s["name"], s["dept"], s["message"], s["recipient"], s["urgency"] |
| return "", "administration", "", None, "Normal" |
|
|
| def get_system_status(): |
| """Get current system configuration status""" |
| status_lines = [] |
| status_lines.append("**System Configuration:**") |
| status_lines.append(f"β’ Demo Mode: {'π§ͺ ENABLED' if DEMO_MODE else 'β
DISABLED'}") |
| status_lines.append(f"β’ OpenRouter API: {'β
Configured' if OPENROUTER_API_KEY else 'β Not configured (using demo)'}") |
| status_lines.append(f"β’ Brevo Email API: {'β
Configured' if BREVO_API_KEY else 'β Not configured (simulated)'}") |
| status_lines.append(f"β’ Report Email: {current_report_email if current_report_email else 'β Not set'}") |
| return "\n".join(status_lines) |
|
|
| |
| with gr.Blocks( |
| theme=gr.themes.Soft(), |
| title="AI Coordination System" |
| ) as ui: |
| gr.Markdown("# π’ AI Department Coordination System") |
| gr.Markdown("*Streamline communication between Administration, Production, and Magazine Management*") |
| |
| |
| if DEMO_MODE: |
| gr.Markdown(""" |
| <div style="background-color: #fef3c7; padding: 15px; border-radius: 8px; border-left: 4px solid #f59e0b; margin-bottom: 20px;"> |
| <strong>π§ͺ DEMO MODE ACTIVE</strong><br> |
| This space is running in demo mode with simulated AI responses. |
| To enable full functionality, configure the required API keys in Settings β Repository Secrets. |
| </div> |
| """) |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| with gr.Accordion("βοΈ System Settings", open=False): |
| gr.Markdown("### Email Configuration") |
| email_input = gr.Textbox( |
| label="Administration Report Email", |
| value=get_current_email, |
| placeholder="admin@company.com" |
| ) |
| email_status = gr.Textbox( |
| label="Email Status", |
| value=get_current_email, |
| interactive=False, |
| max_lines=2 |
| ) |
| update_email_btn = gr.Button("πΎ Save Email", variant="primary") |
| |
| gr.Markdown("### System Status") |
| system_status = gr.Textbox( |
| label="Configuration", |
| value=get_system_status, |
| interactive=False, |
| max_lines=6 |
| ) |
| |
| with gr.Accordion("π§ͺ Testing & Samples", open=True): |
| gr.Markdown("### Quick Test Samples") |
| sample_selector = gr.Radio( |
| choices=["Equipment Request", "Content Collaboration", "Budget Approval"], |
| label="Load Sample Request" |
| ) |
| load_sample_btn = gr.Button("π Load Sample", variant="secondary") |
| |
| gr.Markdown("---") |
| gr.Markdown("### π New Coordination Request") |
| |
| with gr.Group(): |
| gr.Markdown("#### π€ Your Information") |
| name_input = gr.Textbox( |
| label="Your Name", |
| placeholder="Enter your full name" |
| ) |
| |
| department_dropdown = gr.Dropdown( |
| choices=["administration", "production", "magazine"], |
| label="Your Department", |
| value="administration" |
| ) |
| |
| with gr.Group(): |
| gr.Markdown("#### π¬ Request Details") |
| message_input = gr.Textbox( |
| label="What do you need help with?", |
| lines=4, |
| placeholder="Describe what you need from other departments..." |
| ) |
| |
| image_input = gr.Image( |
| label="π· Attach Image (Optional)", |
| type="pil" |
| ) |
| |
| with gr.Group(): |
| gr.Markdown("#### π§ Notification Options") |
| recipient_dropdown = gr.Dropdown( |
| choices=["administration", "production", "magazine"], |
| label="Notify Department" |
| ) |
| |
| urgency_dropdown = gr.Dropdown( |
| choices=["Normal", "Medium", "High"], |
| value="Normal", |
| label="Priority Level" |
| ) |
| |
| send_email_checkbox = gr.Checkbox( |
| label="Send email notification", |
| value=True |
| ) |
| |
| with gr.Row(): |
| submit_btn = gr.Button("π Get Coordination Help", variant="primary") |
| clear_form_btn = gr.Button("ποΈ Clear Form", variant="secondary") |
| |
| with gr.Row(): |
| report_btn = gr.Button("π Submit & Send Report", variant="secondary") |
| clear_btn = gr.Button("ποΈ Clear History", variant="stop") |
| stats_btn = gr.Button("π View Stats") |
| |
| status_display = gr.Textbox( |
| label="System Status", |
| interactive=False, |
| max_lines=2 |
| ) |
| |
| stats_display = gr.Textbox( |
| label="Activity Summary", |
| interactive=False, |
| max_lines=8 |
| ) |
| |
| with gr.Column(scale=2): |
| gr.Markdown("### π‘ Coordination Guidance") |
| output = gr.Textbox( |
| label="Recommended Actions", |
| lines=20, |
| show_copy_button=True |
| ) |
| |
| with gr.Accordion("π’ Department Overview", open=True): |
| gr.Markdown(""" |
| **Administration**: Overall management, decision making, and coordination |
| **Production**: Manufacturing, quality control, and production planning |
| **Magazine Management**: Content creation, publishing, and distribution |
| |
| *The AI will analyze your message and any attached images to provide specific coordination recommendations.* |
| |
| --- |
| |
| **Testing Tips:** |
| - Use the sample requests to quickly test functionality |
| - Try different departments and priority levels |
| - Upload images to test vision capabilities (if API configured) |
| - Monitor the activity log to see coordination history |
| """) |
| |
| with gr.Accordion("π Recent Activity", open=False): |
| history_display = gr.JSON( |
| label="Activity Log", |
| value=lambda: conversation_history[-10:] if conversation_history else [] |
| ) |
|
|
| |
| update_email_btn.click( |
| fn=update_report_email, |
| inputs=[email_input], |
| outputs=email_status |
| ) |
| |
| email_input.submit( |
| fn=update_report_email, |
| inputs=[email_input], |
| outputs=email_status |
| ) |
|
|
| load_sample_btn.click( |
| fn=load_sample_request, |
| inputs=[sample_selector], |
| outputs=[name_input, department_dropdown, message_input, recipient_dropdown, urgency_dropdown] |
| ) |
|
|
| submit_btn.click( |
| fn=process_coordination_request, |
| inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown], |
| outputs=output |
| ).then( |
| fn=lambda: conversation_history[-10:] if conversation_history else [], |
| inputs=[], |
| outputs=history_display |
| ) |
| |
| report_btn.click( |
| 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), |
| inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown], |
| outputs=output |
| ).then( |
| fn=lambda: conversation_history[-10:] if conversation_history else [], |
| inputs=[], |
| outputs=history_display |
| ) |
| |
| message_input.submit( |
| fn=process_coordination_request, |
| inputs=[name_input, department_dropdown, message_input, image_input, recipient_dropdown, send_email_checkbox, urgency_dropdown], |
| outputs=output |
| ).then( |
| fn=lambda: conversation_history[-10:] if conversation_history else [], |
| inputs=[], |
| outputs=history_display |
| ) |
| |
| clear_btn.click( |
| fn=clear_conversation, |
| inputs=[], |
| outputs=status_display |
| ).then( |
| fn=lambda: [], |
| inputs=[], |
| outputs=history_display |
| ) |
| |
| clear_form_btn.click( |
| fn=clear_form, |
| inputs=[], |
| outputs=[name_input, image_input, message_input, recipient_dropdown, department_dropdown, urgency_dropdown, send_email_checkbox] |
| ) |
| |
| stats_btn.click( |
| fn=get_conversation_stats, |
| inputs=[], |
| outputs=stats_display |
| ) |
|
|
| if __name__ == "__main__": |
| ui.launch(share=True) |
|
|