from typing import Any, Literal from pydantic import BaseModel, Field NodeKind = Literal["Input", "AI Worker", "Decision Rules", "Human Review", "Simulated Tool", "Output"] class Position(BaseModel): x: float = 0 y: float = 0 class NodeData(BaseModel): label: str mode: NodeKind prompt: str = "" value: str = "" description: str = "" input_guidance: str = "" class WorkflowNode(BaseModel): id: str type: str = "workflow" position: Position = Field(default_factory=Position) data: NodeData class EdgeData(BaseModel): connectionType: Literal["flow", "tool"] = "flow" class WorkflowEdge(BaseModel): id: str source: str target: str label: str = "" sourceHandle: str | None = None targetHandle: str | None = None data: EdgeData = Field(default_factory=EdgeData) class Workflow(BaseModel): name: str = "Untitled workflow" nodes: list[WorkflowNode] edges: list[WorkflowEdge] class StartRequest(BaseModel): workflow: Workflow input: str = "" class ResumeRequest(BaseModel): run_id: str response: str class TraceEvent(BaseModel): node_id: str label: str mode: str input: str output: str kind: Literal["flow", "tool"] = "flow" class RunResponse(BaseModel): run_id: str status: Literal["completed", "awaiting_review", "error"] current_node_id: str | None = None message: str = "" result: str = "" trace: list[TraceEvent] = Field(default_factory=list) detail: dict[str, Any] = Field(default_factory=dict)