feat: extend operational investigation workflows
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Durable investigation questions; answers are user input, not field evidence."""
|
||||
from typing import Annotated, Literal
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import Field, model_validator
|
||||
|
||||
from app.domain.schemas.shared import StrictModel, PositiveInt
|
||||
from app.domain.schemas.workbench_runtime import WorkbenchDateTime
|
||||
|
||||
Id = Annotated[str, Field(min_length=1, max_length=128)]
|
||||
|
||||
|
||||
class TaskQuestionOption(StrictModel):
|
||||
id: Id
|
||||
label: Annotated[str, Field(min_length=1, max_length=200)]
|
||||
|
||||
|
||||
class TaskQuestion(StrictModel):
|
||||
question_id: Id
|
||||
title: Annotated[str, Field(min_length=1, max_length=200)]
|
||||
body: Annotated[str, Field(min_length=1, max_length=2000)]
|
||||
options: list[TaskQuestionOption] = Field(max_length=12)
|
||||
mode: Literal["single", "multiple"]
|
||||
allow_custom: bool
|
||||
required: bool
|
||||
|
||||
@model_validator(mode="after")
|
||||
def valid_options(self):
|
||||
if len({o.id for o in self.options}) != len(self.options):
|
||||
raise ValueError("duplicate option ids")
|
||||
if not self.options and not self.allow_custom:
|
||||
raise ValueError("question must offer an answer input")
|
||||
return self
|
||||
|
||||
|
||||
class TaskQuestionAnswer(StrictModel):
|
||||
question_id: Id
|
||||
selected_option_ids: list[Id] = Field(max_length=12)
|
||||
custom_text: Annotated[str, Field(max_length=2000)]
|
||||
|
||||
|
||||
class TaskQuestionCreate(StrictModel):
|
||||
request_id: UUID
|
||||
source_session_id: Id
|
||||
run_id: UUID
|
||||
questions: list[TaskQuestion] = Field(min_length=1, max_length=3)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def unique_questions(self):
|
||||
if len({q.question_id for q in self.questions}) != len(self.questions):
|
||||
raise ValueError("duplicate question ids")
|
||||
if len(self.model_dump_json().encode()) > 32768:
|
||||
raise ValueError("question definition too large")
|
||||
return self
|
||||
|
||||
|
||||
class TaskQuestionReply(StrictModel):
|
||||
request_id: UUID
|
||||
expected_version: PositiveInt
|
||||
answers: list[TaskQuestionAnswer] = Field(max_length=3)
|
||||
|
||||
|
||||
class TaskQuestionRequest(StrictModel):
|
||||
question_request_id: UUID
|
||||
task_id: UUID
|
||||
run_id: UUID
|
||||
execution_generation: PositiveInt
|
||||
source_session_id: Id
|
||||
questions: list[TaskQuestion]
|
||||
status: Literal["pending", "answered", "cancelled"]
|
||||
version: PositiveInt
|
||||
created_at: WorkbenchDateTime
|
||||
answered_at: WorkbenchDateTime | None = None
|
||||
answered_by: str | None = None
|
||||
answers: list[TaskQuestionAnswer] = Field(default_factory=list)
|
||||
Reference in New Issue
Block a user