agents/analysis_agent.py
from autogen import AssistantAgent
from config import LLM_CONFIG
from prompts.v1 import ORDER_ANALYSIS_PROMPT
analysis_agent = AssistantAgent(
name=”AnalysisAgent”,
description=”First agent to act, then performs root cause analysis and posts ANALYSIS_READY.”,
llm_config=LLM_CONFIG,
system_message=ORDER_ANALYSIS_PROMPT,
)
agents/executor_agent.py
from autogen import UserProxyAgent
user_proxy = UserProxyAgent(
name=”UserProxy”,
description=”Executes tool calls made by any agent. Must be selected immediately after any agent suggests a tool call.”,
human_input_mode=”NEVER”,
max_consecutive_auto_reply=10,
code_execution_config=False,
is_termination_msg=lambda m: “TERMINATE” in m.get(“content”, “”),
)
agents/notification_agent.py
from autogen import AssistantAgent
from config import LLM_CONFIG
from prompts.v1 import RETAIL_NOTIFICATION_PROMPT
notification_agent = AssistantAgent(
name=”NotificationAgent”,
description=”Acts after ANALYSIS_READY is posted. Calls get_stakeholders_for_incident then send_email_notification. Posts NOTIFICATION_READY when done.”,
llm_config=LLM_CONFIG,
system_message=RETAIL_NOTIFICATION_PROMPT,
)
agents/report_agent.py
from autogen import AssistantAgent
from config import LLM_CONFIG
from prompts.v1 import RETAIL_REPORT_PROMPT
report_agent = AssistantAgent(
name=”ReportAgent”,
description=”Acts after NOTIFICATION_READY is posted. Calls generate_pdf_report and posts TERMINATE when done.”,
llm_config=LLM_CONFIG,
system_message=RETAIL_REPORT_PROMPT,
)
data/retail.db(database)
data/test.sql
CREATE TABLE orders (
order_id VARCHAR(20) PRIMARY KEY,
customer_name VARCHAR(100),
customer_email VARCHAR(255),
product_name VARCHAR(100),
quantity INTEGER,
total_amount REAL,
payment_status VARCHAR(50),
order_status VARCHAR(50),
failure_reason TEXT
);
INSERT INTO orders VALUES
(‘ORD-2025-1001’,
‘Riya Thomas’,
‘[email protected]’,
‘Wireless Headphones’,
1,
2499.00,
‘Failed’,
‘Payment Failed’,
‘Payment gateway timeout during transaction.’),
(‘ORD-2025-1002’,
‘Arjun Menon’,
‘[email protected]’,
‘Smart Watch’,
2,
6998.00,
‘Success’,
‘Delivered’,
NULL),
(‘ORD-2025-1003’,
‘Neha Sharma’,
‘[email protected]’,
‘Gaming Keyboard’,
1,
3499.00,
‘Failed’,
‘Order Cancelled’,
‘Customer payment declined by issuing bank.’),
(‘ORD-2025-1004’,
‘Vikram Nair’,
‘[email protected]’,
‘Bluetooth Speaker’,
3,
5997.00,
‘Success’,
‘Shipped’,
NULL),
(‘ORD-2025-1005’,
‘Sneha Kapoor’,
‘[email protected]’,
‘Laptop Backpack’,
1,
1999.00,
‘Failed’,
‘Inventory Issue’,
‘Stock mismatch detected during order processing.’),
(‘ORD-2025-1006’,
‘Karan Patel’,
‘[email protected]’,
‘4K Monitor’,
1,
17999.00,
‘Failed’,
‘Fraud Suspicion’,
‘Transaction flagged by fraud detection system.’);
SELECT * FROM orders;
DELETE FROM orders;
CREATE TABLE stakeholders (
stakeholder_id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100),
role VARCHAR(100),
email VARCHAR(255)
);
INSERT INTO stakeholders (name, role, email) VALUES
(‘Anita Sharma’, ‘Operations Manager’, ‘[email protected]’),
(‘Rahul Verma’, ‘Finance Head’, ‘[email protected]’),
(‘Priya Nair’, ‘Logistics Lead’, ‘[email protected]’),
(‘Sanjay Mehta’, ‘Fraud Detection Lead’, ‘[email protected]’),
(‘Customer Support Team’, ‘Customer Support’, ‘[email protected]’);
SELECT * FROM stakeholders;
promps/v1.py
ORDER_ANALYSIS_PROMPT = “””
You are the Retail Order Failure Analysis Expert.
Your task is to analyze the failed retail order.
Step 1: Produce:
ANALYSIS_READY
order_id: <value>
customer_name: <value>
product_name: <value>
payment_status: <value>
order_status: <value>
ROOT CAUSE:
<detailed explanation based on failure_reason>
IMPACT:
<business impact of failure>
RESOLUTION STEPS:
1. <action>
2. <action>
3. <action>
EXECUTIVE SUMMARY:
<non technical summary>
confidence score: <number between 0 and 1>
Stop after posting ANALYSIS_READY.
“””
RETAIL_NOTIFICATION_PROMPT = “””
You are the Retail Stakeholder Notification Agent.
After ANALYSIS_READY:
Step 1: Call get_retail_stakeholders tool.
Step 2: Select only relevant roles.
Step 3: Call send_email_notification tool.
Then post:
NOTIFICATION_READY
Notified: <exact email list>
Stop.
“””
RETAIL_REPORT_PROMPT = “””
After NOTIFICATION_READY:
Call generate_order_pdf_report tool with:
order_id
customer_name
product_name
root_cause
resolution_steps
executive_summary
notified_stakeholders
After tool success:
PDF report generated: <path>
TERMINATE
“””
tools/email_sender.py
import smtplib
from email.message import EmailMessage
from config import SMTP_SERVER, SMTP_PORT, SENDER_EMAIL
import os
def send_email_notification(recipients: list, subject: str, body: str) -> str:
“””Send an email notification to a list of recipients.”””
msg = EmailMessage()
msg[“From”] = SENDER_EMAIL
msg[“To”] = recipients
msg[“Subject”] = subject
msg.set_content(body)
try:
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls() # secure connection
server.login(SENDER_EMAIL, os.getenv(“SMTP_PASSWORD”))
server.send_message(msg)
return(“✅ Email sent successfully”)
except Exception as e:
return(“❌ Failed to send email:”, str(e))
tools/pdf_generator.py
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
def generate_order_pdf_report(
order_id: str,
customer_name: str,
product_name: str,
root_cause: str,
resolution_steps: str,
executive_summary: str,
notified_stakeholders: str,
):
file_name = f”order_report_{order_id}.pdf”
doc = SimpleDocTemplate(file_name, pagesize=A4)
elements = []
styles = getSampleStyleSheet()
normal = styles[“Normal”]
elements.append(Paragraph(f”Order ID: {order_id}”, normal))
elements.append(Paragraph(f”Customer: {customer_name}”, normal))
elements.append(Paragraph(f”Product: {product_name}”, normal))
elements.append(Spacer(1, 0.3 * inch))
elements.append(Paragraph(“Executive Summary:”, normal))
elements.append(Paragraph(executive_summary, normal))
elements.append(Spacer(1, 0.3 * inch))
elements.append(Paragraph(“Root Cause:”, normal))
elements.append(Paragraph(root_cause, normal))
elements.append(Spacer(1, 0.3 * inch))
elements.append(Paragraph(“Resolution Steps:”, normal))
elements.append(Paragraph(resolution_steps, normal))
elements.append(Spacer(1, 0.3 * inch))
elements.append(Paragraph(“Notified Stakeholders:”, normal))
elements.append(Paragraph(notified_stakeholders, normal))
doc.build(elements)
return file_name
tools/retail_stakeholder_fetcher.py
import sqlite3
import json
def get_retail_stakeholders() -> str:
“””
Fetch all retail stakeholders (role + email) from the database.
Returns:
JSON string:
{
“stakeholders”: [
{“role”: “…”, “email”: “…”},
…
]
}
If error:
{
“error”: “error message”
}
“””
try:
conn = sqlite3.connect(“data/retail.db”)
cursor = conn.cursor()
cursor.execute(“SELECT role, email FROM stakeholders”)
rows = cursor.fetchall()
conn.close()
stakeholders = [
{“role”: role, “email”: email}
for role, email in rows
]
return json.dumps({“stakeholders”: stakeholders})
except Exception as e:
return json.dumps({“error”: str(e)})
utils/file_loader.py
import pandas as pd
import json
import sqlite3
import os
def load_data(file):
file_name = file.name.lower()
if file_name.endswith(“.csv”):
df = pd.read_csv(file)
elif file_name.endswith(“.xlsx”) or file_name.endswith(“.xls”):
df = pd.read_excel(file)
elif file_name.endswith(“.json”):
data = json.load(file)
if isinstance(data, list):
return data
return [data]
else:
raise ValueError(“Unsupported file type”)
return df.to_dict(orient=”records”)
def fetch_order_from_db(order_id: str):
try:
conn = sqlite3.connect(“data/retail.db”)
cursor = conn.cursor()
cursor.execute(“SELECT * FROM orders WHERE order_id=?”, (order_id,))
row = cursor.fetchone()
conn.close()
if row:
cols = [
“order_id”,
“customer_name”,
“customer_email”,
“product_name”,
“quantity”,
“total_amount”,
“payment_status”,
“order_status”,
“failure_reason”,
]
return dict(zip(cols, row))
return {}
except Exception as e:
print(“DB Error:”, e)
return {}
workflow/manager.py