Spaces:
Running
Running
| from __future__ import annotations | |
| from typing import Any, Optional | |
| from pydantic import BaseModel, Field, field_validator | |
| from openenv.core.env_server.types import Action, Observation, State | |
| from vocabulary import ( | |
| ASSIGNMENT_GROUPS, | |
| ISSUE_TYPES, | |
| PRIORITIES, | |
| RESOLUTION_ACTIONS, | |
| ) | |
| ISSUE_TYPE_SET = set(ISSUE_TYPES) | |
| PRIORITY_SET = set(PRIORITIES) | |
| ASSIGNMENT_GROUP_SET = set(ASSIGNMENT_GROUPS) | |
| RESOLUTION_ACTION_SET = set(RESOLUTION_ACTIONS) | |
| ACTION_TYPE_SET = { | |
| "submit", | |
| "investigate", | |
| "request_info", | |
| "defer", | |
| "open_incident", | |
| } | |
| TOOL_NAME_SET = {"lookup_related_ticket", "lookup_requester_history"} | |
| TOOL_NAME_SET.add("lookup_internal_routing_note") | |
| TOOL_NAME_SET.add("lookup_queue_capacity_forecast") | |
| TOOL_NAME_SET.add("lookup_queue_cluster_summary") | |
| def _validate_choice(value: str, allowed: set[str], field_name: str) -> str: | |
| if value not in allowed: | |
| allowed_values = ", ".join(sorted(allowed)) | |
| raise ValueError(f"{field_name} must be one of: {allowed_values}") | |
| return value | |
| def _validate_optional_choice( | |
| value: Optional[str], allowed: set[str], field_name: str | |
| ) -> Optional[str]: | |
| if value is None: | |
| return None | |
| return _validate_choice(value, allowed, field_name) | |
| class HelpdeskTicketRecord(BaseModel): | |
| ticket_id: str | |
| title: str | |
| requester: str | |
| description: str | |
| issue_type: str | |
| priority: str | |
| assignment_group: str | |
| resolution_action: str | |
| ambiguity_note: Optional[str] = None | |
| related_ticket_id: Optional[str] = None | |
| planning_note: Optional[str] = None | |
| alternate_issue_type: Optional[str] = None | |
| alternate_priority: Optional[str] = None | |
| alternate_assignment_group: Optional[str] = None | |
| alternate_resolution_action: Optional[str] = None | |
| alternate_route_score_multiplier: float = 0.0 | |
| customer_update_note: Optional[str] = None | |
| incident_recommended: bool = False | |
| generated_from_ticket_id: Optional[str] = None | |
| service_cluster_id: Optional[str] = None | |
| def validate_issue_type(cls, value: str) -> str: | |
| return _validate_choice(value, ISSUE_TYPE_SET, "issue_type") | |
| def validate_priority(cls, value: str) -> str: | |
| return _validate_choice(value, PRIORITY_SET, "priority") | |
| def validate_assignment_group(cls, value: str) -> str: | |
| return _validate_choice(value, ASSIGNMENT_GROUP_SET, "assignment_group") | |
| def validate_resolution_action(cls, value: str) -> str: | |
| return _validate_choice(value, RESOLUTION_ACTION_SET, "resolution_action") | |
| def validate_alternate_issue_type(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, ISSUE_TYPE_SET, "alternate_issue_type") | |
| def validate_alternate_priority(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, PRIORITY_SET, "alternate_priority") | |
| def validate_alternate_assignment_group(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice( | |
| value, | |
| ASSIGNMENT_GROUP_SET, | |
| "alternate_assignment_group", | |
| ) | |
| def validate_alternate_resolution_action( | |
| cls, | |
| value: Optional[str], | |
| ) -> Optional[str]: | |
| return _validate_optional_choice( | |
| value, | |
| RESOLUTION_ACTION_SET, | |
| "alternate_resolution_action", | |
| ) | |
| def validate_alternate_route_score_multiplier(cls, value: float) -> float: | |
| if not 0.0 <= value <= 1.0: | |
| raise ValueError("alternate_route_score_multiplier must be in [0.0, 1.0]") | |
| return value | |
| class HelpdeskTicketAction(Action): | |
| action_type: str = "submit" | |
| tool_name: Optional[str] = None | |
| tool_target_ticket_id: Optional[str] = None | |
| issue_type: Optional[str] = None | |
| priority: Optional[str] = None | |
| assignment_group: Optional[str] = None | |
| resolution_action: Optional[str] = None | |
| def validate_action_type(cls, value: str) -> str: | |
| return _validate_choice(value, ACTION_TYPE_SET, "action_type") | |
| def validate_tool_name(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, TOOL_NAME_SET, "tool_name") | |
| def validate_issue_type(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, ISSUE_TYPE_SET, "issue_type") | |
| def validate_priority(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, PRIORITY_SET, "priority") | |
| def validate_assignment_group(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, ASSIGNMENT_GROUP_SET, "assignment_group") | |
| def validate_resolution_action(cls, value: Optional[str]) -> Optional[str]: | |
| return _validate_optional_choice(value, RESOLUTION_ACTION_SET, "resolution_action") | |
| class HelpdeskTicketObservation(Observation): | |
| task_id: int = 0 | |
| task_name: str = "" | |
| instructions: str = "" | |
| allowed_fields: list[str] = Field(default_factory=list) | |
| available_action_types: list[str] = Field(default_factory=list) | |
| available_tools: list[str] = Field(default_factory=list) | |
| investigation_budget_remaining: int = 0 | |
| last_tool_result: Optional[dict[str, Any]] = None | |
| current_ticket: Optional[dict[str, Any]] = None | |
| queue_size: int = 0 | |
| tickets_remaining: int = 0 | |
| tickets_after_current: int = 0 | |
| tickets_processed: int = 0 | |
| queue_position: int = 0 | |
| average_score_so_far: float = 0.0 | |
| progress_fraction: float = 0.0 | |
| history: list[dict[str, Any]] = Field(default_factory=list) | |
| last_reward_components: dict[str, Any] = Field(default_factory=dict) | |
| rubric_reward: Optional[float] = None | |
| class HelpdeskTicketState(State): | |
| current_task_id: Optional[int] = None | |
| seed: Optional[int] = None | |
| queue_ticket_ids: list[str] = Field(default_factory=list) | |
| current_ticket_index: int = 0 | |
| per_ticket_scores: list[float] = Field(default_factory=list) | |
| total_reward: float = 0.0 | |
| last_step_reward: Optional[float] = None | |
| # `reward` is the field the evaluator checks on GET /state (mentor spec) | |
| reward: Optional[float] = None | |
| done: bool = False | |
| average_score_so_far: float = 0.0 | |
| investigation_steps: int = 0 | |
| investigation_budget_remaining: int = 0 | |
| investigation_penalty_applied: float = 0.0 | |
| planning_penalty_applied: float = 0.0 | |
| last_tool_result: Optional[dict[str, Any]] = None | |
| last_reward_components: dict[str, Any] = Field(default_factory=dict) | |
| ticket_tool_usage: dict[str, list[str]] = Field(default_factory=dict) | |
| team_capacity_initial: dict[str, int] = Field(default_factory=dict) | |
| team_capacity_remaining: dict[str, int] = Field(default_factory=dict) | |
| high_priority_slots_initial: int = 0 | |
| high_priority_slots_remaining: int = 0 | |
| escalation_slots_initial: int = 0 | |
| escalation_slots_remaining: int = 0 | |
| planning_penalty_total: float = 0.0 | |
| capacity_pressure_tickets_resolved: int = 0 | |
| cluster_stabilizations_total: int = 0 | |
| cluster_destabilizations_total: int = 0 | |
| ticket_request_info_usage: dict[str, int] = Field(default_factory=dict) | |
| ticket_defer_counts: dict[str, int] = Field(default_factory=dict) | |
| open_incident_ticket_ids: list[str] = Field(default_factory=list) | |
| incident_slots_initial: int = 0 | |
| incident_slots_remaining: int = 0 | |
| incident_actions_used: int = 0 | |
| incident_gap_total: float = 0.0 | |
| deferred_ticket_count: int = 0 | |
| sla_breach_count: int = 0 | |
| spawned_follow_up_ticket_ids: list[str] = Field(default_factory=list) | |
| spawned_follow_up_source_ids: list[str] = Field(default_factory=list) | |
| dynamic_queue_events: list[dict[str, Any]] = Field(default_factory=list) | |
| queue_management_score: float = 0.0 | |
| queue_management_breakdown: dict[str, Any] = Field(default_factory=dict) | |
| history_entries: list[dict] = Field(default_factory=list) | |