"""PMFlow Project Launch API schemas.""" from __future__ import annotations from typing import Any, Literal, Optional from pydantic import BaseModel, Field class PMFlowLaunchAttachment(BaseModel): type: str = "text" name: Optional[str] = None summary: Optional[str] = None payload: Optional[dict[str, Any]] = None class PMFlowLaunchDraftRequest(BaseModel): input: str = Field(min_length=1, max_length=4000) input_type: Literal["text", "file", "screenshot", "template"] = "text" attachments: list[PMFlowLaunchAttachment] = Field(default_factory=list) source: str = "web" class PMFlowLaunchDraftJobRequest(PMFlowLaunchDraftRequest): parent_draft_id: Optional[str] = None revision_note: Optional[str] = Field(default=None, max_length=1200) mode: Literal["create", "merge_supplement", "regenerate"] = "create" class PMFlowLaunchRequirement(BaseModel): title: str summary: str = "" acceptance_criteria: list[str] = Field(default_factory=list) class PMFlowLaunchRisk(BaseModel): title: str summary: str = "" level: Literal["low", "medium", "high"] = "medium" mitigation: str = "" class PMFlowLaunchDecision(BaseModel): title: str reason: str = "" owner: str = "" class PMFlowLaunchTask(BaseModel): title: str summary: str = "" group: Literal["product", "engineering", "qa"] = "product" priority: Literal["low", "medium", "high", "urgent"] = "medium" acceptance_criteria: list[str] = Field(default_factory=list) requirement_index: Optional[int] = None class PMFlowLaunchEvidence(BaseModel): source: str = "user_input" excerpt: str class PMFlowLaunchDraftPayload(BaseModel): title: str one_liner: str target_user: str problem: str solution: str requirements: list[PMFlowLaunchRequirement] = Field(default_factory=list) risks: list[PMFlowLaunchRisk] = Field(default_factory=list) decisions: list[PMFlowLaunchDecision] = Field(default_factory=list) tasks: list[PMFlowLaunchTask] = Field(default_factory=list) evidence: list[PMFlowLaunchEvidence] = Field(default_factory=list) confidence: float = 0.0 warnings: list[str] = Field(default_factory=list) class PMFlowLaunchDraftResponse(PMFlowLaunchDraftPayload): draft_id: str status: str = "draft" expires_at: str class PMFlowLaunchDraftJobRuntimePolicy(BaseModel): foreground_wait_seconds: int = 10 provider_timeout_seconds: int = 90 job_timeout_seconds: int = 180 max_retries: int = 1 large_input_policy: str = "preprocess_then_generate" class PMFlowLaunchDraftJobResponse(BaseModel): job_id: str revision_id: str status: Literal["queued", "running", "user_paused", "superseded", "completed", "failed", "cancelled"] mode: str parent_draft_id: Optional[str] = None superseded_by_job_id: Optional[str] = None draft_id: Optional[str] = None draft: Optional[PMFlowLaunchDraftResponse] = None changed_fields: list[str] = Field(default_factory=list) error_code: Optional[str] = None error_message: Optional[str] = None started_at: Optional[str] = None completed_at: Optional[str] = None expires_at: str runtime_policy: Optional[PMFlowLaunchDraftJobRuntimePolicy] = None class PMFlowLaunchConfirmRequest(BaseModel): edited_draft: dict[str, Any] = Field(default_factory=dict) confirm: bool = True class PMFlowLaunchConfirmResponse(BaseModel): project_id: int redirect_url: str created_truth_node_ids: list[int] = Field(default_factory=list) created_task_ids: list[int] = Field(default_factory=list) thread_id: Optional[int] = None thread_message_id: Optional[int] = None warnings: list[str] = Field(default_factory=list) __all__ = [ "PMFlowLaunchAttachment", "PMFlowLaunchConfirmRequest", "PMFlowLaunchConfirmResponse", "PMFlowLaunchDecision", "PMFlowLaunchDraftJobRequest", "PMFlowLaunchDraftJobResponse", "PMFlowLaunchDraftJobRuntimePolicy", "PMFlowLaunchDraftPayload", "PMFlowLaunchDraftRequest", "PMFlowLaunchDraftResponse", "PMFlowLaunchEvidence", "PMFlowLaunchRequirement", "PMFlowLaunchRisk", "PMFlowLaunchTask", ]