Files
life-echo/api/app/features/evaluation/schemas.py

217 lines
4.9 KiB
Python
Raw Normal View History

"""HTTP / OpenAPI 模型。"""
from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import BaseModel, ConfigDict, Field
class RegressionSetCreate(BaseModel):
name: str
description: str | None = None
class RegressionSetOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
name: str
description: str | None
created_at: datetime
class CaseCreate(BaseModel):
title: str | None = None
user_utterances: list[str]
source_conversation_id: str | None = None
source_user_id: str | None = None
reference_memoir_markdown: str | None = None
is_protected: bool = False
meta: dict[str, Any] | None = None
class CaseOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
regression_set_id: str
source_conversation_id: str | None
source_user_id: str | None
title: str | None
user_utterances: list[Any]
is_protected: bool
created_at: datetime
class VersionCreate(BaseModel):
name: str
runner_kind: str = "llm_chat_v1"
config_json: dict[str, Any] | None = None
class VersionOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
name: str
runner_kind: str
config_json: dict[str, Any] | None
created_at: datetime
class ExperimentCreate(BaseModel):
name: str
regression_set_id: str
baseline_version_id: str
candidate_version_id: str
rubric_pack: str = "conversation_v1+memoir_v1"
composite_weights_json: dict[str, Any] | None = Field(
default=None,
description='默认 {"conversation":0.5,"memoir":0.5}',
)
class ExperimentOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
name: str
regression_set_id: str
baseline_version_id: str
candidate_version_id: str
rubric_pack: str
status: str
error_message: str | None
created_at: datetime
completed_at: datetime | None
class SessionDialogueMessageOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
role: str
content: str
created_at: datetime | None = None
class SessionDialogueOut(BaseModel):
conversation_id: str
messages: list[SessionDialogueMessageOut]
class SessionListItem(BaseModel):
id: str
user_id: str
user_phone: str | None = Field(default=None, description="users.phone列表展示用")
started_at: datetime | None
last_message_at: datetime | None = None
conversation_stage: str | None
current_topic: str | None
status: str | None
class SessionListResponse(BaseModel):
items: list[SessionListItem]
total: int
class SessionTranscriptOut(BaseModel):
conversation_id: str
user_id: str
user_utterances_from_segments: list[str]
user_utterances_from_messages: list[str]
class UserExportFixtureTurnOut(BaseModel):
user: str
ai: str
class UserExportFixtureListOut(BaseModel):
items: list[str]
class UserExportFixtureDetailOut(BaseModel):
filename: str
turns: list[UserExportFixtureTurnOut]
class SnapshotFromConversationBody(BaseModel):
title: str | None = None
use_messages: bool = False
is_protected: bool = False
class ImportMarkdownBody(BaseModel):
markdown: str
title: str | None = None
is_protected: bool = False
class ImportJsonCaseBody(BaseModel):
regression_set_id: str
utterances: list[str] | None = None
raw_json: dict[str, Any] | list[Any] | None = Field(
default=None,
description="与 utterances 二选一:对象含 utterances 键或根数组",
)
title: str | None = None
is_protected: bool = False
class RunTurnOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
turn_index: int
user_utterance: str
assistant_reply: str | None
duration_ms: int | None
judge_scores_json: dict[str, Any] | None
judge_rationale: str | None
class EvalRunOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
experiment_id: str
case_id: str
side: str
status: str
error_message: str | None
memoir_markdown: str | None
conversation_score_total: float | None
memoir_score_total: float | None
composite_score: float | None
judge_bundle_json: dict[str, Any] | None = None
turns: list[RunTurnOut] = []
class SessionEvalRunItem(BaseModel):
experiment_name: str
run: EvalRunOut
class SessionEvalRunsOut(BaseModel):
conversation_id: str
items: list[SessionEvalRunItem]
class GateVerdictOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
passed: bool
mean_composite_delta: float | None
protected_regressions_json: list[dict[str, Any]] | None
details_json: dict[str, Any] | None
computed_at: datetime
class ExperimentDetailOut(BaseModel):
experiment: ExperimentOut
runs: list[EvalRunOut]
gate: GateVerdictOut | None