feat: add Pydantic schemas for branching, handoffs, and resolution outputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-24 08:30:18 +00:00
parent f884f6af92
commit 52fa1153c4
4 changed files with 184 additions and 0 deletions

View File

@@ -228,6 +228,8 @@ class AISessionDetail(AISessionSummary):
ticket_data: dict[str, Any] | None = None
steps: list[AISessionStepResponse] = []
conversation_messages: list[dict[str, Any]] = [] # Chat sessions store messages here
is_branching: bool = False
active_branch_id: str | None = None
model_config = {"from_attributes": True}

View File

@@ -0,0 +1,83 @@
"""Pydantic schemas for session branches and fork points."""
from __future__ import annotations
from typing import Any
from uuid import UUID
from datetime import datetime
from pydantic import BaseModel, Field
class BranchCreate(BaseModel):
label: str = Field(..., max_length=200)
status: str = "untried"
class BranchUpdate(BaseModel):
status: str = Field(..., pattern="^(active|dead_end|solved|untried|revived)$")
status_reason: str | None = None
class BranchResponse(BaseModel):
id: UUID
session_id: UUID
parent_branch_id: UUID | None
fork_point_step_id: UUID | None
branch_order: int
label: str
status: str
status_reason: str | None
status_changed_at: datetime | None
context_summary: dict[str, Any] | None
evidence_from_branch_id: UUID | None
evidence_description: str | None
step_count: int = 0
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class BranchTreeResponse(BaseModel):
branches: list[BranchResponse]
active_branch_id: UUID | None
class ForkOption(BaseModel):
label: str = Field(..., max_length=200)
description: str = Field(..., max_length=500)
class ForkCreateRequest(BaseModel):
fork_reason: str = Field(..., min_length=5, max_length=2000)
options: list[ForkOption] = Field(..., min_length=2, max_length=10)
class ForkPointResponse(BaseModel):
id: UUID
session_id: UUID
parent_branch_id: UUID
trigger_step_id: UUID | None
fork_reason: str
options: list[dict[str, Any]]
created_at: datetime
model_config = {"from_attributes": True}
class BranchSwitchResponse(BaseModel):
active_branch_id: UUID
branch: BranchResponse
conversation_messages: list[dict[str, Any]]
class ReviveRequest(BaseModel):
evidence_from_branch_id: UUID
evidence_description: str = Field(..., min_length=5, max_length=2000)
class BranchMessageRequest(BaseModel):
message: str = Field(..., min_length=1, max_length=8000)
upload_ids: list[UUID] = Field(default_factory=list, max_length=10)
class BranchMessageResponse(BaseModel):
content: str
branch_id: UUID
step_id: UUID | None = None

View File

@@ -0,0 +1,57 @@
"""Pydantic schemas for session handoffs."""
from __future__ import annotations
from typing import Any
from uuid import UUID
from datetime import datetime
from pydantic import BaseModel, Field
class HandoffCreateRequest(BaseModel):
intent: str = Field(..., pattern="^(park|escalate)$")
engineer_notes: str | None = None
priority: str = Field("normal", pattern="^(normal|elevated)$")
class HandoffResponse(BaseModel):
id: UUID
session_id: UUID
handed_off_by: UUID
intent: str
source_branch_id: UUID | None
snapshot: dict[str, Any]
ai_assessment: str | None
ai_assessment_data: dict[str, Any] | None
artifacts: list[dict[str, Any]] | None
engineer_notes: str | None
priority: str
claimed_by: UUID | None
claimed_at: datetime | None
psa_note_pushed: bool
notification_sent: bool
created_at: datetime
model_config = {"from_attributes": True}
class HandoffClaimRequest(BaseModel):
pass
class HandoffBriefingResponse(BaseModel):
briefing: str
handoff: HandoffResponse
class QueueItemResponse(BaseModel):
handoff_id: UUID
session_id: UUID
intent: str
problem_summary: str | None
problem_domain: str | None
priority: str
handed_off_by_name: str | None
engineer_notes: str | None
branch_count: int = 0
created_at: datetime
claimed_by: UUID | None
claimed_at: datetime | None
model_config = {"from_attributes": True}

View File

@@ -0,0 +1,42 @@
"""Pydantic schemas for session resolution outputs."""
from __future__ import annotations
from typing import Any
from uuid import UUID
from datetime import datetime
from pydantic import BaseModel, Field
class ResolutionOutputResponse(BaseModel):
id: UUID
session_id: UUID
output_type: str
generated_content: str
structured_data: dict[str, Any] | None
edited_content: str | None
status: str
pushed_to: str | None
pushed_at: datetime | None
pushed_reference: str | None
generated_by_model: str
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class ResolutionOutputEditRequest(BaseModel):
edited_content: str = Field(..., min_length=1)
class ResolutionOutputPushRequest(BaseModel):
destination: str = Field(..., pattern="^(psa|kb_library|clipboard|email)$")
class ResolutionOutputPushResponse(BaseModel):
output_id: UUID
status: str
pushed_to: str
pushed_reference: str | None = None
class AllResolutionOutputsResponse(BaseModel):
outputs: list[ResolutionOutputResponse]