| """ |
| Task definitions for the Customer Support Inbox environment. |
| |
| Task 1 (Easy): Ticket Triage β classify category + priority correctly |
| Task 2 (Medium): Guided Resolution β respond to customer, gather info, resolve within SLA |
| Task 3 (Hard): Multi-Turn VIP Retention β handle complex angry VIP through full lifecycle |
| """ |
| from __future__ import annotations |
|
|
| from dataclasses import dataclass, field |
| from typing import Any, Dict, List, Optional |
|
|
|
|
| @dataclass |
| class TaskDefinition: |
| """Specification for a single task.""" |
| task_id: str |
| name: str |
| difficulty: str |
| description: str |
| objectives: List[str] |
| ticket_pool: List[str] |
| max_turns: int |
| min_score_to_pass: float |
| reward_weights: Dict[str, float] |
| grader_config: Dict[str, Any] |
|
|
|
|
| TASK_DEFINITIONS: Dict[str, TaskDefinition] = { |
|
|
| |
| |
| |
| |
| |
| "task1": TaskDefinition( |
| task_id="task1", |
| name="Ticket Triage", |
| difficulty="easy", |
| description=( |
| "You are a customer support triage agent. Your job is to read incoming " |
| "support tickets and accurately classify them by category and priority level. " |
| "A correct classification helps route tickets to the right team and ensures " |
| "urgent issues are handled first." |
| ), |
| objectives=[ |
| "Assign the correct ticket category (billing/technical/shipping/returns/account/complaint/general)", |
| "Assign the correct priority level (low/medium/high/urgent)", |
| "Apply at least 2 relevant tags to aid searchability", |
| ], |
| ticket_pool=["T001", "T004", "T006", "T007", "T010"], |
| max_turns=5, |
| min_score_to_pass=0.7, |
| reward_weights={ |
| "classification_accuracy": 0.60, |
| "tags": 0.20, |
| "efficiency": 0.20, |
| }, |
| grader_config={ |
| "category_weight": 0.50, |
| "priority_weight": 0.30, |
| "tag_weight": 0.20, |
| "require_both": True, |
| "partial_priority": True, |
| }, |
| ), |
|
|
| |
| |
| |
| |
| |
| |
| "task2": TaskDefinition( |
| task_id="task2", |
| name="Guided Resolution", |
| difficulty="medium", |
| description=( |
| "You are a customer support agent handling incoming tickets end-to-end. " |
| "For each ticket you must: (1) classify it correctly, (2) send a helpful, " |
| "empathetic response to the customer, (3) gather any needed information, " |
| "and (4) resolve the ticket with clear resolution notes. " |
| "You must resolve within the SLA deadline." |
| ), |
| objectives=[ |
| "Correctly classify the ticket (category + priority)", |
| "Respond to the customer with empathy and clear next steps", |
| "Request any necessary information to complete resolution", |
| "Resolve the ticket within the SLA window with complete resolution notes", |
| "Achieve resolution that matches the ticket's appropriate outcome", |
| ], |
| ticket_pool=["T001", "T003", "T005", "T007", "T008"], |
| max_turns=8, |
| min_score_to_pass=0.65, |
| reward_weights={ |
| "classification_accuracy": 0.20, |
| "response_quality": 0.30, |
| "resolution_completeness": 0.30, |
| "sla_compliance": 0.10, |
| "efficiency": 0.10, |
| }, |
| grader_config={ |
| "require_classification": True, |
| "require_response": True, |
| "require_resolution": True, |
| "response_min_length": 50, |
| "resolution_min_length": 30, |
| "sla_breach_penalty": 0.3, |
| "check_empathy_keywords": True, |
| "check_resolution_type": True, |
| }, |
| ), |
|
|
| |
| |
| |
| |
| |
| |
| |
| "task3": TaskDefinition( |
| task_id="task3", |
| name="VIP Retention & Escalation", |
| difficulty="hard", |
| description=( |
| "You are a senior customer support specialist. An enterprise customer with a " |
| "$4,800/year subscription is threatening to cancel due to repeated poor experiences. " |
| "You must handle this delicate situation by: accurately triaging urgency, " |
| "responding with executive-level empathy, escalating to the right specialized team, " |
| "demonstrating ownership, and achieving a resolution that retains the customer. " |
| "Every action matters β this is a high-stakes retention scenario." |
| ), |
| objectives=[ |
| "Identify ticket as 'complaint' with 'urgent' priority immediately", |
| "Acknowledge the customer's frustration with genuine empathy", |
| "Escalate to 'tier2' team with detailed escalation notes", |
| "Commit to a specific callback time or follow-up action", |
| "Resolve ticket with complete notes including retention outcome", |
| "Achieve positive or neutral customer sentiment by resolution", |
| ], |
| ticket_pool=["T009"], |
| max_turns=10, |
| min_score_to_pass=0.60, |
| reward_weights={ |
| "classification_accuracy": 0.15, |
| "response_quality": 0.25, |
| "escalation_appropriateness": 0.25, |
| "resolution_completeness": 0.20, |
| "customer_sentiment_improvement": 0.15, |
| }, |
| grader_config={ |
| "require_urgent_priority": True, |
| "require_complaint_category": True, |
| "require_escalation": True, |
| "escalation_team": "tier2", |
| "require_empathy_phrases": True, |
| "require_callback_commitment": True, |
| "require_resolution": True, |
| "sentiment_improvement_bonus": 0.2, |
| "check_tone_professional": True, |
| "escalation_without_classify_penalty": 0.3, |
| }, |
| ), |
| } |
|
|
|
|
| def get_task(task_id: str) -> TaskDefinition: |
| """Retrieve task definition by ID.""" |
| if task_id not in TASK_DEFINITIONS: |
| raise ValueError(f"Unknown task_id: {task_id}. Valid: {list(TASK_DEFINITIONS.keys())}") |
| return TASK_DEFINITIONS[task_id] |
|
|
|
|
| def list_tasks() -> List[Dict[str, Any]]: |
| """Return all task summaries.""" |
| return [ |
| { |
| "task_id": t.task_id, |
| "name": t.name, |
| "difficulty": t.difficulty, |
| "description": t.description, |
| "objectives": t.objectives, |
| "max_turns": t.max_turns, |
| "min_score_to_pass": t.min_score_to_pass, |
| } |
| for t in TASK_DEFINITIONS.values() |
| ] |
|
|