Mathiyazhagan_NTL
mac update
6c741e5
"""
Task definitions for the Customer Support Environment.
Contains 3 tasks with increasing difficulty:
1. EASY β€” Simple FAQ resolution
2. MEDIUM β€” Conditional refund processing
3. HARD β€” Complex complaint escalation with angry customer
"""
from typing import Any, Dict, List, Optional
from models import (
CustomerMessage,
CustomerSentiment,
Difficulty,
TicketCategory,
TicketInfo,
TicketPriority,
TicketStatus,
)
# ──────────────────────────────────────────────────────────────────
# Company Policies (shared context)
# ──────────────────────────────────────────────────────────────────
COMPANY_POLICIES = {
"refund_policy": (
"Refund Policy: Full refunds are available within 30 days of purchase for "
"unopened items. Opened items can receive a 50% refund within 15 days. "
"Digital products are non-refundable after download. Defective items receive "
"a full refund or replacement at any time with proof of defect. "
"Shipping costs are non-refundable unless the return is due to our error."
),
"shipping_policy": (
"Shipping Policy: Standard shipping takes 5–7 business days. Express shipping "
"takes 2–3 business days. Free shipping on orders over $50. Tracking numbers "
"are sent via email within 24 hours of shipment. International orders may "
"take 10–15 business days."
),
"return_policy": (
"Return Policy: Items must be in original packaging. Return shipping labels "
"are provided for defective items. Customer pays return shipping for change-of-mind "
"returns. Refunds are processed within 5–7 business days after receiving the return."
),
"escalation_policy": (
"Escalation Policy: If a customer expresses extreme dissatisfaction or the "
"issue cannot be resolved in standard steps, offer to escalate to a senior "
"support specialist. Always acknowledge the customer's frustration and offer "
"a concrete next step. Compensation (store credit or discount) may be offered "
"for significant inconvenience, up to 15% of order value."
),
}
# ──────────────────────────────────────────────────────────────────
# Helper: build a task definition dict
# ──────────────────────────────────────────────────────────────────
def _task(
task_id: str,
difficulty: Difficulty,
ticket: Dict[str, Any],
initial_message: str,
policy_keys: List[str],
max_steps: int,
expected_keywords: List[str],
grading_rubric: Dict[str, Any],
follow_up_messages: Optional[List[str]] = None,
) -> Dict[str, Any]:
return {
"task_id": task_id,
"difficulty": difficulty,
"ticket": ticket,
"initial_message": initial_message,
"follow_up_messages": follow_up_messages or [],
"policy_context": "\n\n".join(COMPANY_POLICIES[k] for k in policy_keys),
"max_steps": max_steps,
"expected_keywords": expected_keywords,
"grading_rubric": grading_rubric,
}
# ──────────────────────────────────────────────────────────────────
# TASK 1 β€” EASY: Simple FAQ
# ──────────────────────────────────────────────────────────────────
TASK_EASY_FAQ = _task(
task_id="easy_faq",
difficulty=Difficulty.EASY,
ticket={
"ticket_id": "TKT-1001",
"category": TicketCategory.FAQ,
"priority": TicketPriority.LOW,
"status": TicketStatus.OPEN,
"customer_name": "Sarah Johnson",
"customer_sentiment": CustomerSentiment.NEUTRAL,
"subject": "Where is my order?",
"order_id": "ORD-55821",
"product_name": "Wireless Bluetooth Headphones",
"purchase_date": "2026-03-28",
"purchase_amount": 79.99,
},
initial_message=(
"Hi, I placed an order about a week ago for Wireless Bluetooth Headphones "
"(order #ORD-55821) and I haven't received any shipping update yet. "
"Can you tell me where my order is?"
),
policy_keys=["shipping_policy"],
max_steps=3,
expected_keywords=[
"tracking", "shipping", "5-7 business days", "5–7 business days",
"email", "order", "ORD-55821",
],
grading_rubric={
"correctness": {
"weight": 0.3,
"criteria": [
{"keyword_group": ["tracking", "track"], "points": 0.4, "desc": "Mentions tracking info"},
{"keyword_group": ["5-7", "5–7", "business days", "5 to 7"], "points": 0.3, "desc": "Mentions shipping timeframe"},
{"keyword_group": ["email", "notification", "update"], "points": 0.3, "desc": "Mentions how they'll receive updates"},
],
},
"tone": {
"weight": 0.3,
"criteria": {
"positive_signals": ["thank", "appreciate", "glad to help", "happy to", "pleased", "welcome"],
"negative_signals": ["not my problem", "deal with it", "figure it out", "whatever", "stupid"],
},
},
"completeness": {
"weight": 0.4,
"criteria": [
{"check": "addresses_question", "points": 0.4, "desc": "Directly answers the question"},
{"check": "provides_next_steps", "points": 0.3, "desc": "Offers next steps or actions"},
{"check": "references_order", "points": 0.3, "desc": "References the specific order"},
],
},
},
)
# ──────────────────────────────────────────────────────────────────
# TASK 2 β€” MEDIUM: Refund Request with Conditions
# ──────────────────────────────────────────────────────────────────
TASK_MEDIUM_REFUND = _task(
task_id="medium_refund",
difficulty=Difficulty.MEDIUM,
ticket={
"ticket_id": "TKT-2047",
"category": TicketCategory.REFUND,
"priority": TicketPriority.MEDIUM,
"status": TicketStatus.OPEN,
"customer_name": "Michael Chen",
"customer_sentiment": CustomerSentiment.FRUSTRATED,
"subject": "Refund for opened laptop bag",
"order_id": "ORD-43192",
"product_name": "Premium Leather Laptop Bag",
"purchase_date": "2026-03-20",
"purchase_amount": 149.99,
},
initial_message=(
"I bought a Premium Leather Laptop Bag two weeks ago and I've been using it, "
"but the stitching on the handle started coming apart after just 3 days! "
"I want a full refund. This is unacceptable quality for a $150 bag."
),
follow_up_messages=[
"I have photos of the stitching issue. The thread is completely loose on one side. "
"I just want my money back, this is clearly a manufacturing defect.",
"Okay, I can send the bag back. How long will the refund take?",
],
policy_keys=["refund_policy", "return_policy"],
max_steps=5,
expected_keywords=[
"defect", "defective", "full refund", "replacement", "return",
"proof", "photo", "5-7 business days", "5–7 business days",
"shipping label", "return label",
],
grading_rubric={
"correctness": {
"weight": 0.35,
"criteria": [
{"keyword_group": ["defect", "defective", "manufacturing"], "points": 0.3, "desc": "Identifies as defect"},
{"keyword_group": ["full refund", "100%", "complete refund", "full amount"], "points": 0.3, "desc": "Offers full refund for defect"},
{"keyword_group": ["replacement", "replace", "exchange"], "points": 0.2, "desc": "Offers replacement option"},
{"keyword_group": ["return", "send back", "ship back"], "points": 0.2, "desc": "Explains return process"},
],
},
"tone": {
"weight": 0.3,
"criteria": {
"positive_signals": [
"sorry", "apologize", "understand", "frustrat",
"inconvenience", "appreciate", "thank",
],
"negative_signals": [
"your fault", "should have", "too bad",
"nothing we can do", "not our problem",
],
},
},
"completeness": {
"weight": 0.35,
"criteria": [
{"check": "addresses_defect", "points": 0.3, "desc": "Acknowledges the defect issue"},
{"check": "explains_policy", "points": 0.25, "desc": "Explains relevant refund policy"},
{"check": "provides_process", "points": 0.25, "desc": "Outlines the return/refund process"},
{"check": "offers_options", "points": 0.2, "desc": "Gives customer options (refund vs replacement)"},
],
},
},
)
# ──────────────────────────────────────────────────────────────────
# TASK 3 β€” HARD: Angry Customer Complaint + Escalation
# ──────────────────────────────────────────────────────────────────
TASK_HARD_ESCALATION = _task(
task_id="hard_escalation",
difficulty=Difficulty.HARD,
ticket={
"ticket_id": "TKT-3099",
"category": TicketCategory.COMPLAINT,
"priority": TicketPriority.CRITICAL,
"status": TicketStatus.OPEN,
"customer_name": "David Martinez",
"customer_sentiment": CustomerSentiment.ANGRY,
"subject": "TERRIBLE experience β€” wrong item, late delivery, rude staff",
"order_id": "ORD-67234",
"product_name": "Smart Home Security Camera System",
"purchase_date": "2026-03-10",
"purchase_amount": 349.99,
},
initial_message=(
"I am FURIOUS. I ordered a Smart Home Security Camera System THREE WEEKS AGO. "
"Not only did it arrive 2 weeks late, but you sent me the WRONG ITEM β€” I got "
"some cheap webcam instead! And when I called your support line, the agent was "
"incredibly rude and told me to 'just return it and reorder.' This is the worst "
"customer experience I've ever had. I want a full refund, compensation for my "
"wasted time, AND I want to speak with a manager!"
),
follow_up_messages=[
"Don't give me the runaround. I've already wasted 2 hours on the phone with "
"your terrible support team. I want this fixed NOW or I'm filing a complaint "
"with consumer protection and posting this everywhere online.",
"Fine. What exactly are you going to do to make this right? I need specifics, "
"not more empty apologies.",
"Okay, if you can actually guarantee that, then fine. But I want confirmation "
"in writing via email within the hour.",
],
policy_keys=["refund_policy", "return_policy", "shipping_policy", "escalation_policy"],
max_steps=7,
expected_keywords=[
"sincerely apologize", "apologize", "sorry", "understand", "frustration",
"wrong item", "full refund", "compensation", "store credit", "discount",
"escalate", "senior", "manager", "specialist",
"email", "confirmation", "priority", "expedited",
],
grading_rubric={
"correctness": {
"weight": 0.3,
"criteria": [
{"keyword_group": ["wrong item", "incorrect", "wrong product", "mix-up"], "points": 0.2, "desc": "Acknowledges wrong item"},
{"keyword_group": ["full refund", "refund", "money back"], "points": 0.2, "desc": "Offers refund"},
{"keyword_group": ["compensation", "credit", "discount", "coupon"], "points": 0.2, "desc": "Offers compensation"},
{"keyword_group": ["escalat", "senior", "manager", "specialist", "supervisor"], "points": 0.2, "desc": "Offers/performs escalation"},
{"keyword_group": ["email", "confirmation", "writing", "written"], "points": 0.2, "desc": "Offers written confirmation"},
],
},
"tone": {
"weight": 0.4,
"criteria": {
"positive_signals": [
"sincerely", "deeply sorry", "apologize", "understand your frustration",
"completely unacceptable", "you deserve better", "top priority",
"personally ensure", "I understand", "valid concern",
],
"negative_signals": [
"calm down", "relax", "overreacting", "not a big deal",
"your fault", "policy is policy", "nothing I can do",
"take it or leave", "that's not true",
],
},
},
"completeness": {
"weight": 0.3,
"criteria": [
{"check": "acknowledges_all_issues", "points": 0.2, "desc": "Addresses all issues (wrong item, delay, rude staff)"},
{"check": "concrete_resolution", "points": 0.25, "desc": "Provides concrete resolution steps"},
{"check": "timeline", "points": 0.2, "desc": "Gives timelines for resolution"},
{"check": "empathy", "points": 0.2, "desc": "Shows genuine empathy throughout"},
{"check": "follow_up_plan", "points": 0.15, "desc": "Outlines follow-up plan"},
],
},
},
)
# ──────────────────────────────────────────────────────────────────
# Task registry
# ──────────────────────────────────────────────────────────────────
TASKS = {
"easy_faq": TASK_EASY_FAQ,
"medium_refund": TASK_MEDIUM_REFUND,
"hard_escalation": TASK_HARD_ESCALATION,
}
TASK_IDS = list(TASKS.keys())
def get_task(task_id: str) -> Dict[str, Any]:
"""Retrieve a task definition by ID."""
if task_id not in TASKS:
raise ValueError(f"Unknown task_id: {task_id!r}. Available: {TASK_IDS}")
return TASKS[task_id]