from __future__ import annotations from typing import Any, Literal, Optional from pydantic import BaseModel, ConfigDict class ViewModel(BaseModel): model_config = ConfigDict(extra="forbid") class RunSummary(ViewModel): script_build_id: int title: str status: str checkpoint: str root_trace_id: str revision: int task_count: int attempt_count: int planner_turn_count: int current_focus_task_id: Optional[str] current_gap: str created_at: str updated_at: str class TaskNode(ViewModel): task_id: str display_path: str parent_task_id: Optional[str] child_task_ids: list[str] task_kind: str phase: str objective: str status: str blocked_reason: Optional[str] attempt_count: int validation_count: int decision_count: int current_spec_version: int acceptance_criteria: list[dict[str, Any]] context_refs: list[str] created_at: str updated_at: str class PlannerTurn(ViewModel): turn_id: str order: int message_sequence: int phase: str action: str action_label: str summary: str observable_reasoning: str result_summary: str status: Literal["succeeded", "failed", "unknown"] focus_task_id: Optional[str] affected_task_ids: list[str] visible_task_ids: list[str] tool_name: str tool_arguments: dict[str, Any] tokens: int cost: float created_at: str class LifecycleEvent(ViewModel): event_id: str kind: Literal["task", "attempt", "validation", "decision"] title: str status: str summary: str created_at: str attempt_id: Optional[str] = None class AgentStep(ViewModel): sequence: int role: str step_kind: Literal["instruction", "explanation", "tool_call", "tool_result"] title: str text: str tool_name: Optional[str] tool_arguments: Optional[dict[str, Any]] tokens: int cost: float duration_ms: Optional[float] created_at: str class DataUsage(ViewModel): inherited_inputs: list[dict[str, Any]] confirmed_reads: list[dict[str, Any]] produced_outputs: list[dict[str, Any]] adoption: list[dict[str, Any]] class AttemptDetail(ViewModel): attempt_id: str task_id: str status: str worker_preset: Optional[str] worker_trace_id: Optional[str] execution_mode: Optional[str] started_at: Optional[str] completed_at: Optional[str] total_tokens: int total_cost: float error: Optional[Any] submission: Optional[dict[str, Any]] validation: Optional[dict[str, Any]] decision: Optional[dict[str, Any]] prompt: str steps: list[AgentStep] class TaskDetail(ViewModel): task: TaskNode contract: Optional[dict[str, Any]] lifecycle: list[LifecycleEvent] attempts: list[AttemptDetail] data_usage: DataUsage class ExecutionView(ViewModel): schema_version: Literal["script-build-execution-view/v1"] data_mode: Literal["persisted-real-run"] generated_at: str run: RunSummary planner_turns: list[PlannerTurn] tasks: list[TaskNode] snapshot_basis: str warnings: list[str]