Spaces:
Sleeping
Sleeping
Prasham.Jain
refactor(branch-a): A1 — adopt openenv-core MCPEnvironment + create_app for canonical OpenEnv compliance
4c1ad51 | """OpenEnv-compliant wire types for the CI triage env. | |
| These wrap our frozen domain Pydantic schemas into OpenEnv's Action / Observation / | |
| State envelope so the env is consumable by the canonical ``EnvClient``, | |
| ``serialize_observation`` / ``deserialize_action`` helpers, and HF Spaces' OpenEnv | |
| runner. The domain schemas in ``ci_triage_env.schemas`` are unchanged. | |
| """ | |
| from typing import Literal | |
| from openenv.core.env_server.types import Action, Observation, State | |
| from pydantic import ConfigDict, Field | |
| from ci_triage_env.schemas.action import SecondaryAction, TerminalAction, ToolCall | |
| from ci_triage_env.schemas.diagnosis import DiagnosisLabel | |
| from ci_triage_env.schemas.episode import EpisodeState | |
| from ci_triage_env.schemas.observation import Observation as DomainObservation | |
| class CITriageAction(Action): | |
| """Wire action: discriminated on ``kind``. | |
| - ``kind="tool_call"`` carries ``tool_call`` (a domain ``ToolCall``). | |
| - ``kind="submit_diagnosis"`` carries ``terminal`` (a domain ``TerminalAction``). | |
| A separate envelope (rather than directly subclassing OpenEnv's MCP | |
| ``CallToolAction``) keeps tool-call cost/budget bookkeeping inside our env | |
| rather than at the FastMCP layer, while still letting agents discover tools | |
| via the standard MCP ``tools/list`` route. | |
| """ | |
| model_config = ConfigDict(extra="forbid", validate_assignment=True) | |
| kind: Literal["tool_call", "submit_diagnosis"] | |
| tool_call: ToolCall | None = None | |
| terminal: TerminalAction | None = None | |
| def from_tool_call(cls, tool_name: str, args: dict | None = None) -> "CITriageAction": | |
| return cls(kind="tool_call", tool_call=ToolCall(tool_name=tool_name, args=args or {})) | |
| def from_terminal( | |
| cls, | |
| diagnosis: DiagnosisLabel, | |
| confidence: float, | |
| secondary_actions: list[SecondaryAction] | None = None, | |
| ) -> "CITriageAction": | |
| return cls( | |
| kind="submit_diagnosis", | |
| terminal=TerminalAction( | |
| diagnosis=diagnosis, | |
| confidence=confidence, | |
| secondary_actions=secondary_actions or [], | |
| ), | |
| ) | |
| class CITriageObservation(Observation): | |
| """Wire observation: OpenEnv envelope (``done``, ``reward``, ``metadata``) plus | |
| the full domain ``Observation`` as ``payload`` for clients that need scenario, | |
| budget, tool response, etc.""" | |
| model_config = ConfigDict(extra="forbid", validate_assignment=True) | |
| payload: DomainObservation = Field(description="Domain-level observation") | |
| class CITriageState(State): | |
| """Wire state: OpenEnv envelope plus the full domain ``EpisodeState``.""" | |
| model_config = ConfigDict(extra="allow", validate_assignment=True) | |
| payload: EpisodeState | None = Field( | |
| default=None, | |
| description="Full domain episode state; None before the first reset.", | |
| ) | |