deerflow-code/offline-backend-20260512/backend/app/report_collaboration/contracts/nodes.py
2026-09-07 18:24:55 +08:00

88 lines
2.7 KiB
Python

"""Node contracts and live node state. The public contract endpoint never returns execution bodies."""
from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field
from app.report_collaboration.contracts.enums import CollaborationNodeStatus
class NodeAwaitingInput(BaseModel):
model_config = ConfigDict(extra="forbid")
reason: str
question: str
impact: list[str] = Field(default_factory=list)
class NodeAttemptState(BaseModel):
model_config = ConfigDict(extra="forbid")
attempt: int
status: CollaborationNodeStatus
started_at: str | None = None
ended_at: str | None = None
error: str | None = None
class CollaborationNodeState(BaseModel):
model_config = ConfigDict(extra="forbid")
node_id: str
label: str
role_display_name: str | None = None
angle: str | None = None
status: CollaborationNodeStatus
attempt: int
progress: str | None = None
awaiting_input: NodeAwaitingInput | None = None
error: str | None = None
attempts: list[NodeAttemptState] = Field(default_factory=list)
class CollaborationNodeContract(BaseModel):
"""Internal full contract stored on a node-run row."""
model_config = ConfigDict(extra="forbid")
node_id: str
mission: str
input_artifact_types: list[str] = Field(default_factory=list)
output_artifact_type: str
allowed_tools: list[str] = Field(default_factory=list)
source_policy: str | None = None
acceptance_criteria: list[str] = Field(default_factory=list)
max_attempts: int = 3
time_budget_seconds: int | None = None
token_budget: int | None = None
agent_profile_snapshot: dict[str, object] = Field(default_factory=dict)
dependencies: list[str] = Field(default_factory=list)
forbidden: list[str] = Field(default_factory=list)
output_structure: str | None = None
class NodeContractDetail(BaseModel):
"""``GET /runs/{run_id}/nodes/{node_id}/contract`` — duties only, never result text."""
model_config = ConfigDict(extra="forbid")
node_id: str
label: str
role: str | None = None
angle: str | None = None
status: CollaborationNodeStatus
attempt: int
mission: str
input_artifact_types: list[str] = Field(default_factory=list)
source_policy: str | None = None
output_artifact_type: str
output_structure: str | None = None
acceptance_criteria: list[str] = Field(default_factory=list)
allowed_tools: list[str] = Field(default_factory=list)
forbidden: list[str] = Field(default_factory=list)
time_budget_seconds: int | None = None
token_budget: int | None = None
max_attempts: int
upstream: list[str] = Field(default_factory=list)
downstream: list[str] = Field(default_factory=list)