Spaces:
Sleeping
Sleeping
| """Ticket data model with ground-truth labels for deterministic grading.""" | |
| from __future__ import annotations | |
| from typing import Literal | |
| from pydantic import BaseModel, Field | |
| Category = Literal[ | |
| "billing", | |
| "bug_report", | |
| "feature_request", | |
| "account_access", | |
| "general_inquiry", | |
| "cancellation", | |
| ] | |
| Priority = Literal["low", "medium", "high", "critical"] | |
| Department = Literal["billing", "technical", "account", "general"] | |
| Sentiment = Literal["angry", "frustrated", "neutral", "satisfied"] | |
| CustomerTier = Literal["free", "pro", "enterprise"] | |
| Difficulty = Literal["easy", "medium", "hard"] | |
| EscalationTarget = Literal["l2_support", "engineering", "management"] | |
| CustomerValue = Literal["low", "medium", "high"] | |
| SLA_DEFAULTS: dict[str, int] = { | |
| "low": 8, | |
| "medium": 6, | |
| "high": 4, | |
| "critical": 3, | |
| } | |
| CUSTOMER_VALUE_PENALTY_MULTIPLIER: dict[str, float] = { | |
| "low": 1.0, | |
| "medium": 1.3, | |
| "high": 1.8, | |
| } | |
| class KeywordSpec(BaseModel): | |
| """Weighted keyword specification for grading text quality. | |
| *required* β must appear; 60 % of quality score. | |
| *optional* β bonus if present; 40 % of quality score. | |
| *forbidden* β penalty per match (``-0.03`` each). | |
| *min_required_hits* β hard floor; score halved when not met. | |
| """ | |
| model_config = {"frozen": True} | |
| required: list[str] = Field(default_factory=list) | |
| optional: list[str] = Field(default_factory=list) | |
| forbidden: list[str] = Field(default_factory=list) | |
| min_required_hits: int = 0 | |
| class TicketData(BaseModel): | |
| """Ground-truth ticket used internally by the environment.""" | |
| model_config = {"frozen": True} | |
| ticket_id: str | |
| ticket_text: str | |
| customer_sentiment: Sentiment | |
| customer_tier: CustomerTier | |
| gold_category: Category | |
| gold_priority: Priority | |
| gold_department: Department | |
| response_spec: KeywordSpec = Field(default_factory=KeywordSpec) | |
| resolution_spec: KeywordSpec = Field(default_factory=KeywordSpec) | |
| requires_escalation: bool = False | |
| escalation_reason: str | None = None | |
| escalation_target: EscalationTarget | None = None | |
| compensation_range: tuple[float, float] | None = None | |
| constraints: list[str] = Field(default_factory=list) | |
| difficulty: Difficulty | |
| category_hint: str | None = None | |
| # --- v2 fields --- | |
| customer_value: CustomerValue = "medium" | |
| sla_steps: int | None = None | |
| secondary_category: Category | None = None | |
| distractors: list[str] = Field(default_factory=list) | |
| partial_info: bool = False | |
| info_reveals: str | None = None | |
| def effective_sla_steps(self) -> int: | |
| if self.sla_steps is not None: | |
| return self.sla_steps | |
| return SLA_DEFAULTS[self.gold_priority] | |
| def penalty_multiplier(self) -> float: | |
| return CUSTOMER_VALUE_PENALTY_MULTIPLIER[self.customer_value] | |