PMFlow/backend/app/schemas/pmflow_launch.py

141 lines
4.1 KiB
Python

"""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",
]