| """ |
| Typed Pydantic models for the API Contract Debugger environment. |
| |
| The environment gives an agent a broken OpenAPI-style spec and asks it to |
| fix contract violations by proposing targeted field-level corrections. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from enum import Enum |
| from typing import Any, Dict, List, Optional |
|
|
| from openenv.core.env_server.types import Action, Observation, State |
| from pydantic import Field |
|
|
|
|
| |
| |
| |
|
|
| class FieldType(str, Enum): |
| """Supported JSON Schema primitive types.""" |
| STRING = "string" |
| INTEGER = "integer" |
| NUMBER = "number" |
| BOOLEAN = "boolean" |
| ARRAY = "array" |
| OBJECT = "object" |
| NULL = "null" |
|
|
|
|
| class HttpMethod(str, Enum): |
| GET = "GET" |
| POST = "POST" |
| PUT = "PUT" |
| PATCH = "PATCH" |
| DELETE = "DELETE" |
|
|
|
|
| class ActionKind(str, Enum): |
| """What kind of fix the agent is proposing.""" |
| ADD_FIELD = "add_field" |
| REMOVE_FIELD = "remove_field" |
| CHANGE_TYPE = "change_type" |
| CHANGE_STATUS = "change_status" |
| NO_OP = "no_op" |
|
|
|
|
| |
| |
| |
|
|
| class FieldSpec(dict): |
| """A JSON Schema-like field definition. Stored as plain dict for flexibility.""" |
| pass |
|
|
|
|
| class EndpointSpec(dict): |
| """A single endpoint definition: method, path, request_body, response.""" |
| pass |
|
|
|
|
| |
| |
| |
|
|
| class DebugAction(Action): |
| """ |
| A single fix proposed by the agent. |
| |
| The agent targets one endpoint + one field and proposes exactly one change. |
| """ |
|
|
| kind: ActionKind = Field( |
| ..., |
| description="The type of fix being applied", |
| ) |
| endpoint_index: int = Field( |
| ..., |
| ge=0, |
| description="0-based index into the endpoint list", |
| ) |
| location: str = Field( |
| ..., |
| description=( |
| "Where in the endpoint to apply the fix. " |
| "One of: 'request_body', 'response_body', 'status_code'" |
| ), |
| ) |
| field_name: Optional[str] = Field( |
| default=None, |
| description="Field name to add/remove/change (null for status_code fixes)", |
| ) |
| new_value: Optional[Any] = Field( |
| default=None, |
| description=( |
| "The corrected value. " |
| "For CHANGE_TYPE: a FieldType string. " |
| "For ADD_FIELD: a dict with 'type' (and optional 'description'). " |
| "For CHANGE_STATUS: an integer HTTP status code. " |
| "For REMOVE_FIELD / NO_OP: null." |
| ), |
| ) |
|
|
|
|
| |
| |
| |
|
|
| class Violation(dict): |
| """ |
| Describes a single detected contract violation. |
| |
| Keys: endpoint_index, location, field_name, violation_type, description |
| """ |
| pass |
|
|
|
|
| class DebugObservation(Observation): |
| """ |
| What the agent sees after each reset() / step(). |
| """ |
|
|
| task_name: str = Field( |
| ..., |
| description="Which task is currently active (easy / medium / hard)", |
| ) |
| task_description: str = Field( |
| ..., |
| description="Human-readable description of the task objective", |
| ) |
| endpoints: List[Dict[str, Any]] = Field( |
| ..., |
| description="Current (potentially partially-fixed) endpoint specs", |
| ) |
| violations: List[Dict[str, Any]] = Field( |
| default_factory=list, |
| description="List of detected violations still present in the spec", |
| ) |
| violations_fixed_this_step: int = Field( |
| default=0, |
| description="How many violations the last action resolved", |
| ) |
| violations_introduced_this_step: int = Field( |
| default=0, |
| description="How many new violations the last action introduced", |
| ) |
| total_violations_at_start: int = Field( |
| ..., |
| description="Number of violations at episode start (for progress tracking)", |
| ) |
| step_count: int = Field( |
| default=0, |
| description="Steps taken so far in this episode", |
| ) |
| max_steps: int = Field( |
| default=10, |
| description="Maximum steps allowed per episode", |
| ) |
| last_action_error: Optional[str] = Field( |
| default=None, |
| description="Error message if the last action was malformed / out-of-range", |
| ) |
|
|
|
|
| |
| |
| |
|
|
| class DebugState(State): |
| """ |
| Full internal state of the environment (not exposed to the agent by default). |
| """ |
|
|
| task_name: str = Field(default="") |
| original_endpoints: List[Dict[str, Any]] = Field(default_factory=list) |
| current_endpoints: List[Dict[str, Any]] = Field(default_factory=list) |
| golden_endpoints: List[Dict[str, Any]] = Field(default_factory=list) |
| violations: List[Dict[str, Any]] = Field(default_factory=list) |
| total_violations_at_start: int = Field(default=0) |
| max_steps: int = Field(default=10) |
|
|