CoolFace
Apppublic

hyperlinken/ALT_DESIGN

sourceHugging Faceapache-2.0updated 6mo agoView on Hugging Face
0likes
models.py192 linesDownload Raw Back to root
1"""2models.py3Pydantic v2 typed models for the IT Helpdesk Triage OpenEnv environment.4Defines the complete Action / Observation / State interface contracts.5"""6 7from __future__ import annotations8 9from enum import Enum10from typing import Any, Dict, List, Optional11 12from pydantic import BaseModel, Field13 14 15# ──────────────────────────────────────────────────────────────────────────────16# Domain Enums17# ──────────────────────────────────────────────────────────────────────────────18 19class TicketCategory(str, Enum):20    """ITIL-aligned classification categories for IT support tickets."""21    HARDWARE    = "hardware"22    SOFTWARE    = "software"23    NETWORK     = "network"24    SECURITY    = "security"25    ACCESS      = "access"26    DATABASE    = "database"27    PERFORMANCE = "performance"28    OTHER       = "other"29 30 31class TicketPriority(str, Enum):32    """33    Priority levels following ITIL P1-P4 convention.34    P1 = Critical (complete outage / business-stopping).35    P4 = Low (cosmetic, informational, no business impact).36    """37    P1 = "P1"   # Critical  – SLA: 1 h38    P2 = "P2"   # High      – SLA: 4 h39    P3 = "P3"   # Medium    – SLA: 8 h40    P4 = "P4"   # Low       – SLA: 48 h41 42 43class AssignedTeam(str, Enum):44    """Available support teams for ticket routing."""45    INFRASTRUCTURE      = "infrastructure"46    APPLICATION_SUPPORT = "application_support"47    NETWORK_OPS         = "network_ops"48    SECURITY_OPS        = "security_ops"49    DATABASE_ADMIN      = "database_admin"50    HELPDESK            = "helpdesk"51 52 53# ──────────────────────────────────────────────────────────────────────────────54# Action Space55# ──────────────────────────────────────────────────────────────────────────────56 57class TriageAction(BaseModel):58    """59    The complete action an agent submits to triage one ticket.60    Used as the primary Action type across all three tasks.61    """62    ticket_id: str = Field(63        ...,64        description="Exact ID of the ticket being triaged (e.g. 'TKT-E001')."65    )66    category: TicketCategory = Field(67        ...,68        description="Issue classification category."69    )70    priority: TicketPriority = Field(71        ...,72        description="Assigned ITIL priority level (P1-P4)."73    )74    assigned_team: AssignedTeam = Field(75        ...,76        description="Resolver team responsible for this ticket."77    )78    is_part_of_incident: bool = Field(79        default=False,80        description="True when this ticket is a symptom of a declared major incident."81    )82    incident_id: Optional[str] = Field(83        default=None,84        description="Major-incident identifier if applicable (e.g. 'INC-MAJOR-01')."85    )86    resolution_steps: Optional[List[str]] = Field(87        default=None,88        description=(89            "Ordered list of remediation steps. "90            "Required for P1 tickets in the 'incident_escalation' task."91        )92    )93    escalate_to_management: bool = Field(94        default=False,95        description="Whether to page senior management / C-suite for this ticket."96    )97 98 99# ──────────────────────────────────────────────────────────────────────────────100# Observation Space101# ──────────────────────────────────────────────────────────────────────────────102 103class Ticket(BaseModel):104    """A single IT support ticket as seen by the agent."""105    id: str                          = Field(..., description="Unique ticket identifier.")106    subject: str                     = Field(..., description="One-line summary of the issue.")107    description: str                 = Field(..., description="Full free-text description from the reporter.")108    reporter: str                    = Field(..., description="Full name of the person who raised the ticket.")109    reporter_department: str         = Field(..., description="Business department of the reporter.")110    timestamp: str                   = Field(..., description="ISO-8601 creation timestamp.")111    affected_systems: List[str]      = Field(..., description="Hostnames / service identifiers impacted.")112    affected_users_count: int        = Field(default=1, description="Number of end-users affected.")113    sla_hours: int                   = Field(..., description="SLA resolution target in hours.")114 115 116class Observation(BaseModel):117    """118    Returned after every reset() and step() call.119    Contains the next ticket to triage plus episode-level metadata.120    """121    task_id: str                        = Field(..., description="Active task identifier.")122    current_ticket: Optional[Ticket]    = Field(123        default=None,124        description="Ticket awaiting triage. None when the queue is exhausted."125    )126    queue_remaining: int                = Field(..., description="Tickets still waiting in the queue.")127    processed_count: int                = Field(..., description="Tickets triaged so far this episode.")128    step_number: int                    = Field(..., description="Current step index (0-based).")129    action_feedback: Optional[str]      = Field(130        default=None,131        description="Human-readable correctness feedback on the previous action."132    )133    cumulative_score: float             = Field(134        default=0.0, ge=0.0, le=1.0,135        description="Running mean reward across all completed steps."136    )137    episode_done: bool                  = Field(default=False, description="True when the episode has ended.")138    active_incidents: List[str]         = Field(139        default_factory=list,140        description="Incident IDs declared so far in this episode."141    )142    hints: List[str]                    = Field(143        default_factory=list,144        description="Task-level guidance hints for the agent."145    )146 147 148# ──────────────────────────────────────────────────────────────────────────────149# Step Result150# ──────────────────────────────────────────────────────────────────────────────151 152class StepResult(BaseModel):153    """Full return value of the /step endpoint (OpenEnv convention)."""154    observation: Observation155    reward: float                       = Field(..., ge=0.0, le=1.0, description="Per-step reward.")156    done: bool157    info: Dict[str, Any]                = Field(default_factory=dict)158 159 160# ──────────────────────────────────────────────────────────────────────────────161# Reward Breakdown (internal / surfaced in info)162# ──────────────────────────────────────────────────────────────────────────────163 164class RewardBreakdown(BaseModel):165    """Granular per-dimension reward decomposition returned inside StepResult.info."""166    category_score:          float = Field(0.0, ge=0.0, le=1.0)167    priority_score:          float = Field(0.0, ge=0.0, le=1.0)168    routing_score:           float = Field(0.0, ge=0.0, le=1.0)169    incident_score:          float = Field(0.0, ge=0.0, le=1.0)170    escalation_score:        float = Field(0.0, ge=0.0, le=1.0)171    resolution_score:        float = Field(0.0, ge=0.0, le=1.0)172    penalty:                 float = Field(0.0, ge=0.0, le=1.0)173    total:                   float = Field(0.0, ge=0.0, le=1.0)174 175 176# ──────────────────────────────────────────────────────────────────────────────177# Environment State (for /state endpoint)178# ──────────────────────────────────────────────────────────────────────────────179 180class EnvironmentState(BaseModel):181    """Complete serialisable snapshot of the environment (returned by state())."""182    task_id:             str183    step_number:         int184    episode_complete:    bool185    tickets_total:       int186    tickets_processed:   int187    tickets_remaining:   int188    cumulative_score:    float189    reward_history:      List[float]190    declared_incidents:  List[str]191    action_history:      List[Dict[str, Any]]192