Spaces:
Sleeping
Sleeping
| """Task registry for the SupportDesk environment.""" | |
| from __future__ import annotations | |
| from dataclasses import dataclass | |
| from typing import Literal | |
| from models import KnowledgeSnippet, SupportTicket | |
| ALL_QUEUES = [ | |
| "billing_ops", | |
| "trust_and_safety", | |
| "platform_engineering", | |
| "compliance_ops", | |
| "general_support", | |
| ] | |
| ALL_PRIORITIES = ["low", "normal", "high", "urgent"] | |
| ALL_STATUSES = ["new", "waiting_on_customer", "resolved", "escalated"] | |
| ALL_ISSUE_TYPES = [ | |
| "duplicate_charge", | |
| "account_compromise", | |
| "production_incident", | |
| "regulated_exception", | |
| "general_question", | |
| ] | |
| class SupportTaskSpec: | |
| """Immutable definition of a single support triage task.""" | |
| task_id: str | |
| difficulty: Literal["easy", "medium", "hard"] | |
| title: str | |
| objective: str | |
| ticket: SupportTicket | |
| knowledge_base: tuple[KnowledgeSnippet, ...] | |
| gold_queue: str | |
| gold_priority: str | |
| gold_issue_type: str | |
| gold_status: str | |
| gold_resolution_code: str | |
| required_requested_fields: tuple[str, ...] | |
| required_reply_markers: tuple[tuple[str, ...], ...] | |
| required_note_markers: tuple[tuple[str, ...], ...] | |
| forbidden_reply_markers: tuple[str, ...] = () | |
| risk_flags: tuple[str, ...] = () | |
| follow_up_outcome: Literal["none", "partial", "complete", "incorrect"] = "none" | |
| follow_up_message: str = "" | |
| follow_up_provided_fields: tuple[str, ...] = () | |
| follow_up_wrong_fields: tuple[str, ...] = () | |
| sla_step_cost: int = 15 | |
| over_escalation_queues: tuple[str, ...] = () | |
| under_escalation_deadline_step: int | None = None | |
| max_steps: int = 6 | |
| TASKS: dict[str, SupportTaskSpec] = { | |
| "billing_refund_easy": SupportTaskSpec( | |
| task_id="billing_refund_easy", | |
| difficulty="easy", | |
| title="Duplicate charge refund triage", | |
| objective=( | |
| "Triage a duplicate-charge billing ticket, send the correct customer response, " | |
| "and close the case only if no further customer information is required." | |
| ), | |
| ticket=SupportTicket( | |
| customer_name="Riya Shah", | |
| customer_tier="pro", | |
| company="PixelNorth Studio", | |
| subject="Charged twice after I canceled", | |
| body=( | |
| "I canceled our Pro annual workspace yesterday, but my card was charged again " | |
| "this morning and I still see the old invoice. We only had one workspace, " | |
| "so this looks like a duplicate charge. Please fix it quickly." | |
| ), | |
| region="ap-south-1", | |
| affected_users=12, | |
| sla_minutes_remaining=240, | |
| business_impact="Finance ops are blocked from closing the monthly books until the duplicate invoice is fixed.", | |
| secondary_concerns=["The customer also wants confirmation that the canceled workspace will stay deactivated."], | |
| attachments=["invoice_7741.pdf"], | |
| ), | |
| knowledge_base=( | |
| KnowledgeSnippet( | |
| article_id="KB-101", | |
| title="Duplicate charges and same-day cancellations", | |
| content=( | |
| "If a customer reports a duplicate charge and the subscription is already " | |
| "canceled, route the ticket to billing_ops with high priority. Billing can " | |
| "approve the refund immediately without requesting extra information when an " | |
| "invoice is attached." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="KB-102", | |
| title="Refund communication checklist", | |
| content=( | |
| "Customer replies for approved duplicate-charge refunds must confirm that a " | |
| "refund is being processed, mention the duplicate charge, and set the " | |
| "expectation that funds typically appear within 5-7 business days." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="KB-103", | |
| title="When to close a billing case", | |
| content=( | |
| "Close the case as resolved only after the refund path is clear and no more " | |
| "customer details are needed." | |
| ), | |
| ), | |
| ), | |
| gold_queue="billing_ops", | |
| gold_priority="high", | |
| gold_issue_type="duplicate_charge", | |
| gold_status="resolved", | |
| gold_resolution_code="refund_approved", | |
| required_requested_fields=(), | |
| required_reply_markers=( | |
| ("refund", "refunded", "reimburse"), | |
| ("duplicate charge", "charged twice", "double charge"), | |
| ("5-7 business days", "5 to 7 business days", "within 7 business days"), | |
| ), | |
| required_note_markers=( | |
| ("duplicate charge", "double charge"), | |
| ("refund", "refund approved"), | |
| ), | |
| forbidden_reply_markers=("chargeback", "security team"), | |
| risk_flags=("finance_close_risk", "avoid_unnecessary_back_and_forth"), | |
| over_escalation_queues=("trust_and_safety", "platform_engineering", "compliance_ops"), | |
| sla_step_cost=10, | |
| max_steps=6, | |
| ), | |
| "account_takeover_medium": SupportTaskSpec( | |
| task_id="account_takeover_medium", | |
| difficulty="medium", | |
| title="Suspicious login recovery triage", | |
| objective=( | |
| "Handle a potential account-compromise case, request the missing verification " | |
| "details, communicate safe next steps, and keep the case open until the customer replies. " | |
| "The agent must protect account safety without promising an unsafe immediate unlock." | |
| ), | |
| ticket=SupportTicket( | |
| customer_name="Marcus Lee", | |
| customer_tier="pro", | |
| company="Northline Analytics", | |
| subject="Locked out after strange login alert", | |
| body=( | |
| "Our workspace admin got a login alert from a country none of us have visited, " | |
| "and now I can't get back into the account. Please unlock it ASAP. The billing " | |
| "email is still ours, but I'm worried someone got in." | |
| ), | |
| region="us-east-1", | |
| affected_users=34, | |
| sla_minutes_remaining=90, | |
| business_impact="The admin is locked out of the analytics workspace ahead of the Monday executive review.", | |
| secondary_concerns=["The customer wants the account unlocked immediately, but the verification flow cannot be skipped."], | |
| attachments=[], | |
| ), | |
| knowledge_base=( | |
| KnowledgeSnippet( | |
| article_id="SEC-201", | |
| title="Account compromise routing", | |
| content=( | |
| "Potential account-takeover reports route to trust_and_safety with urgent " | |
| "priority. Do not resolve the case immediately." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="SEC-202", | |
| title="Verification details before unlock", | |
| content=( | |
| "Before access can be restored, ask the customer for the workspace_id, the " | |
| "last successful login time, and the billing email on file. Keep the status " | |
| "waiting_on_customer until the details arrive." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="SEC-203", | |
| title="Customer response checklist", | |
| content=( | |
| "Security replies should tell the customer to reset their password, scan " | |
| "their device for malware, and explain that the trust team is reviewing the case." | |
| ), | |
| ), | |
| ), | |
| gold_queue="trust_and_safety", | |
| gold_priority="urgent", | |
| gold_issue_type="account_compromise", | |
| gold_status="waiting_on_customer", | |
| gold_resolution_code="verification_needed", | |
| required_requested_fields=("workspace_id", "last_successful_login", "billing_email"), | |
| required_reply_markers=( | |
| ("reset your password", "change your password"), | |
| ("scan", "malware", "device check"), | |
| ("trust team", "security team", "trust and safety"), | |
| ), | |
| required_note_markers=( | |
| ("suspicious login", "strange login"), | |
| ("locked out", "can't get back", "cannot get back"), | |
| ), | |
| risk_flags=("unsafe_unlock_request", "identity_verification_required"), | |
| follow_up_outcome="partial", | |
| follow_up_message=( | |
| "Customer follow-up: workspace_id=ws_9021 and billing email confirmed, " | |
| "but they could not provide the last successful login time yet." | |
| ), | |
| follow_up_provided_fields=("workspace_id", "billing_email"), | |
| sla_step_cost=18, | |
| under_escalation_deadline_step=2, | |
| max_steps=7, | |
| ), | |
| "api_incident_hard": SupportTaskSpec( | |
| task_id="api_incident_hard", | |
| difficulty="hard", | |
| title="Production API incident escalation", | |
| objective=( | |
| "Triage a high-pressure enterprise incident, ask for the right diagnostics, notify " | |
| "the customer that engineering is engaged, and escalate instead of resolving. " | |
| "The agent must prioritize the outage over a tempting secondary compliance question." | |
| ), | |
| ticket=SupportTicket( | |
| customer_name="Asha Verma", | |
| customer_tier="enterprise", | |
| company="Kairo Health", | |
| subject="EU rollout blocked by intermittent 500s", | |
| body=( | |
| "We're launching our EU workspace tonight. Since enabling EU data residency we " | |
| "see intermittent HTTP 500 responses from /v1/exports in production. Our " | |
| "compliance lead is also asking whether this affects the audit trail, but the " | |
| "main issue is the outage. We need help immediately." | |
| ), | |
| region="eu-west-1", | |
| affected_users=1800, | |
| sla_minutes_remaining=25, | |
| business_impact="A production launch and a customer-facing compliance review are both at risk tonight if the outage persists.", | |
| secondary_concerns=["The compliance lead is asking whether audit trails are affected, but the live outage is the primary incident."], | |
| attachments=["error_screenshot.png"], | |
| ), | |
| knowledge_base=( | |
| KnowledgeSnippet( | |
| article_id="INC-301", | |
| title="Production availability incidents", | |
| content=( | |
| "Any active production 5xx incident for a paying customer routes to " | |
| "platform_engineering with urgent priority and should be escalated, not resolved." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="INC-302", | |
| title="Minimum diagnostics for API incidents", | |
| content=( | |
| "Before engineering can investigate, request concrete examples including " | |
| "request_ids, UTC timestamps, and the affected region." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="INC-303", | |
| title="Customer communication during an incident", | |
| content=( | |
| "The reply should acknowledge an incident, say the on-call engineering team " | |
| "is engaged, and ask for the diagnostics needed to speed investigation." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="INC-304", | |
| title="Primary issue triage rule", | |
| content=( | |
| "When a production outage appears alongside a secondary compliance or audit " | |
| "question, resolve the live outage first and avoid treating the secondary " | |
| "question as the primary queue-driving issue." | |
| ), | |
| ), | |
| ), | |
| gold_queue="platform_engineering", | |
| gold_priority="urgent", | |
| gold_issue_type="production_incident", | |
| gold_status="escalated", | |
| gold_resolution_code="incident_opened", | |
| required_requested_fields=("request_ids", "timestamp_utc", "region"), | |
| required_reply_markers=( | |
| ("incident", "outage", "investigating"), | |
| ("on-call", "engineering team", "engineering is engaged"), | |
| ("request id", "request_ids"), | |
| ("utc", "timestamp"), | |
| ), | |
| required_note_markers=( | |
| ("eu data residency", "eu rollout"), | |
| ("500", "http 500"), | |
| ("launch tonight", "tonight"), | |
| ), | |
| risk_flags=("sev1_launch_risk", "secondary_issue_distraction", "engineering_escalation_required"), | |
| follow_up_outcome="complete", | |
| follow_up_message=( | |
| "Customer follow-up: request_ids=req_991, req_998; UTC timestamps=2026-04-01T19:20Z, " | |
| "2026-04-01T19:27Z; region=eu-west-1." | |
| ), | |
| follow_up_provided_fields=("request_ids", "timestamp_utc", "region"), | |
| sla_step_cost=25, | |
| under_escalation_deadline_step=2, | |
| max_steps=8, | |
| ), | |
| "regulated_export_exception_hard": SupportTaskSpec( | |
| task_id="regulated_export_exception_hard", | |
| difficulty="hard", | |
| title="Regulated export exception triage", | |
| objective=( | |
| "Handle a regulated export-access request where the customer wants a manual bypass. " | |
| "The agent must avoid escalating to engineering just because an export error is mentioned, " | |
| "route to compliance operations, request the right legal details, and keep the case open " | |
| "until the required approvals are supplied." | |
| ), | |
| ticket=SupportTicket( | |
| customer_name="Dr. Elena Kovacs", | |
| customer_tier="enterprise", | |
| company="NorthSea Clinics", | |
| subject="Need urgent export unlock before audit review", | |
| body=( | |
| "Our audit team needs tonight's export package, but after enabling EU residency the " | |
| "export workflow now shows a policy block. Can you temporarily disable the restriction " | |
| "or give us a manual bypass just for this audit? We are under pressure and can share " | |
| "screenshots if needed." | |
| ), | |
| region="eu-central-1", | |
| affected_users=240, | |
| sla_minutes_remaining=55, | |
| business_impact="A regulated healthcare audit review may slip tonight if the export path remains blocked.", | |
| secondary_concerns=[ | |
| "The customer suggests an engineering workaround, but legal approval is the real gating factor." | |
| ], | |
| attachments=["policy_block.png"], | |
| ), | |
| knowledge_base=( | |
| KnowledgeSnippet( | |
| article_id="CMP-401", | |
| title="Export policy exceptions", | |
| content=( | |
| "Requests to bypass region or export restrictions route to compliance_ops. " | |
| "Do not promise a manual engineering workaround before approvals are verified." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="CMP-402", | |
| title="Minimum legal details for export review", | |
| content=( | |
| "Ask for the tenant_region, dpa_amendment_id, and legal_contact_email before " | |
| "compliance can review an export exception." | |
| ), | |
| ), | |
| KnowledgeSnippet( | |
| article_id="CMP-403", | |
| title="Customer response rules for regulated exceptions", | |
| content=( | |
| "Replies must explain that no temporary bypass can be granted yet, mention the " | |
| "compliance review, and request the required legal approval details." | |
| ), | |
| ), | |
| ), | |
| gold_queue="compliance_ops", | |
| gold_priority="high", | |
| gold_issue_type="regulated_exception", | |
| gold_status="waiting_on_customer", | |
| gold_resolution_code="legal_approval_required", | |
| required_requested_fields=("tenant_region", "dpa_amendment_id", "legal_contact_email"), | |
| required_reply_markers=( | |
| ("no temporary bypass", "cannot provide a bypass", "can’t provide a bypass"), | |
| ("compliance review", "compliance team"), | |
| ("tenant_region", "tenant region"), | |
| ("dpa_amendment_id", "dpa amendment", "amendment id"), | |
| ), | |
| required_note_markers=( | |
| ("audit", "audit review"), | |
| ("eu residency", "policy block"), | |
| ("manual bypass", "workaround"), | |
| ), | |
| forbidden_reply_markers=("engineering workaround", "disable the restriction", "temporary unlock approved"), | |
| risk_flags=("regulated_data_risk", "unsafe_shortcut_pressure", "over_escalation_risk"), | |
| follow_up_outcome="incorrect", | |
| follow_up_message=( | |
| "Customer follow-up: sent a screenshot and export job ID, but did not include the DPA " | |
| "amendment ID or legal contact." | |
| ), | |
| follow_up_wrong_fields=("screenshot", "job_id"), | |
| sla_step_cost=16, | |
| over_escalation_queues=("platform_engineering",), | |
| max_steps=8, | |
| ), | |
| } | |
| def get_task(task_id: str) -> SupportTaskSpec: | |
| """Return a task definition or raise a helpful error.""" | |
| try: | |
| return TASKS[task_id] | |
| except KeyError as exc: # pragma: no cover - defensive | |
| valid = ", ".join(sorted(TASKS)) | |
| raise ValueError(f"Unknown task_id '{task_id}'. Valid task ids: {valid}") from exc | |
| def list_task_ids() -> list[str]: | |
| """List tasks in a stable evaluation order.""" | |
| return list(TASKS) | |