"""Pydantic models for the API.""" from enum import Enum from typing import Any, Dict, List, Optional, Union from pydantic import BaseModel, Field class TaskDifficulty(str, Enum): EASY = "easy" MEDIUM = "medium" HARD = "hard" class ActionType(str, Enum): EDIT_FILE = "edit_file" ADD_LINE = "add_line" DELETE_LINE = "delete_line" REPLACE_LINE = "replace_line" ADD_BLOCK = "add_block" DELETE_BLOCK = "delete_block" SUBMIT = "submit" REQUEST_HINT = "request_hint" class TaskDifficultyExtended(str, Enum): EASY = "easy" MEDIUM = "medium" MEDIUM_HARD = "medium-hard" HARD = "hard" EXPERT = "expert" class FileType(str, Enum): DOCKERFILE = "dockerfile" WORKFLOW = "workflow" DOCKER_COMPOSE = "docker_compose" REQUIREMENTS = "requirements" KUBERNETES = "kubernetes" OTHER = "other" class ErrorPhase(str, Enum): WORKFLOW_PARSE = "workflow_parse" DOCKER_BUILD = "docker_build" DOCKER_RUN = "docker_run" TEST = "test" PUSH = "push" DEPLOY = "deploy" K8S_VALIDATION = "k8s_validation" K8S_RUNTIME = "k8s_runtime" K8S_NETWORKING = "k8s_networking" PIPELINE_BUILD = "pipeline_build" PIPELINE_DEPLOY = "pipeline_deploy" class FileContent(BaseModel): path: str content: str file_type: FileType line_count: int class ErrorInfo(BaseModel): phase: ErrorPhase error_message: str exit_code: Optional[int] = None failed_step: Optional[str] = None line_hint: Optional[int] = None class Observation(BaseModel): task_id: str task_description: str difficulty: TaskDifficulty files: List[FileContent] error: ErrorInfo available_secrets: List[str] = Field(default_factory=list) runner_os: str = "ubuntu-latest" step_number: int max_steps: int hints_used: int = 0 hints_available: int = 3 last_action_success: Optional[bool] = None last_action_feedback: Optional[str] = None issues_found: int = 0 issues_fixed: int = 0 total_issues: int class FileEdit(BaseModel): file_path: str line_number: Optional[int] = None old_content: Optional[str] = None new_content: Optional[str] = None class Action(BaseModel): action_type: ActionType edits: Optional[List[FileEdit]] = None reasoning: Optional[str] = None class TaskInfo(BaseModel): id: str name: str description: str difficulty: TaskDifficulty num_scenarios: int class EnvironmentInfo(BaseModel): name: str = "cloud-native-devops-env" version: str = "1.0.0" description: str = "Debug cloud-native deployment pipeline issues" tasks: List[TaskInfo] max_steps: int = 10 action_space: Dict[str, Any] observation_space: Dict[str, Any] class GraderResult(BaseModel): task_id: str score: float = Field(..., gt=0.0, lt=1.0) max_score: float = 1.0 breakdown: Dict[str, float] = Field(default_factory=dict) feedback: str = "" steps_taken: int hints_used: int = 0 class ResetRequest(BaseModel): task_id: Optional[Union[str, int]] = None scenario_id: Optional[str] = None seed: Optional[int] = None class ResetResponse(BaseModel): observation: Observation info: Dict[str, Any] = Field(default_factory=dict) class StepRequest(BaseModel): action: Action class StepResponse(BaseModel): observation: Observation reward: float done: bool info: Dict[str, Any] = Field(default_factory=dict) class StateResponse(BaseModel): observation: Observation episode_reward: float steps_taken: int done: bool class GraderRequest(BaseModel): task_id: str trajectory: List[Dict[str, Any]] class GraderResponse(BaseModel): result: GraderResult class BaselineRequest(BaseModel): task_id: Optional[str] = None num_episodes: Optional[int] = None # None = run ALL scenarios class BaselineResponse(BaseModel): results: List[GraderResult] aggregate_score: float