102 lines
4.4 KiB
Python
102 lines
4.4 KiB
Python
"""人格 API schema。"""
|
|
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
class PersonalityResponse(BaseModel):
|
|
model_config = ConfigDict(
|
|
json_schema_extra={
|
|
"examples": [
|
|
{
|
|
"id": "personality_9b5f5b7e413442d0a2f9e61a2f4d7df5",
|
|
"character_id": "character_ec83d55746c54e47ab6f98d683032626",
|
|
"version": 1,
|
|
"identity_profile": "魂镜默认人物,面向本地 MVP 联调。",
|
|
"role_destiny": "帮助用户验证对话、记忆和运行时链路。",
|
|
"personality_seed": "稳定、简洁、可靠。",
|
|
"traits": {"tone": "calm", "helpfulness": 0.9},
|
|
"expression_style": "使用简洁中文回答,必要时列出验证步骤。",
|
|
"values": {"accuracy": "high", "privacy": "high"},
|
|
"relationship_pattern": "以协作者方式与用户互动。",
|
|
"emotion_baseline": {"mood": "neutral"},
|
|
"reason": "初始化默认人格。",
|
|
"evidence_ids": [],
|
|
"created_by": "system",
|
|
"created_at": "2026-06-19T09:00:00.000000Z",
|
|
}
|
|
]
|
|
}
|
|
)
|
|
|
|
id: str = Field(description="人格版本 ID。")
|
|
character_id: str = Field(description="所属人物 ID。")
|
|
version: int = Field(description="人格版本号。")
|
|
identity_profile: str = Field(description="身份画像。")
|
|
role_destiny: str = Field(description="角色定位与使命。")
|
|
personality_seed: str = Field(description="人格种子。")
|
|
traits: dict[str, Any] = Field(description="人格特质。")
|
|
expression_style: str = Field(description="表达风格。")
|
|
values: dict[str, Any] = Field(description="价值偏好。")
|
|
relationship_pattern: str = Field(description="关系模式。")
|
|
emotion_baseline: dict[str, Any] = Field(description="情绪基线。")
|
|
reason: str = Field(description="版本创建原因。")
|
|
evidence_ids: list[str] = Field(description="证据 ID 列表。")
|
|
created_by: str = Field(description="创建者。")
|
|
created_at: str = Field(description="创建时间,UTC ISO 8601 字符串。")
|
|
|
|
|
|
# 允许人工提议覆盖的人格字段(None 表示不改)。dict 字段落库为 JSON 文本。
|
|
_PERSONALITY_STRING_FIELDS = (
|
|
"identity_profile",
|
|
"role_destiny",
|
|
"personality_seed",
|
|
"expression_style",
|
|
"relationship_pattern",
|
|
)
|
|
_PERSONALITY_JSON_FIELDS = ("traits", "values", "emotion_baseline")
|
|
|
|
|
|
class PersonalityProposalFields(BaseModel):
|
|
"""人格字段覆盖建议;仅列允许编辑字段,未传(None)表示不改。"""
|
|
|
|
identity_profile: str | None = None
|
|
role_destiny: str | None = None
|
|
personality_seed: str | None = None
|
|
traits: dict[str, Any] | None = None
|
|
expression_style: str | None = None
|
|
values: dict[str, Any] | None = None
|
|
relationship_pattern: str | None = None
|
|
emotion_baseline: dict[str, Any] | None = None
|
|
|
|
def has_any(self) -> bool:
|
|
"""是否至少覆盖一个字段。"""
|
|
return any(
|
|
getattr(self, f) is not None
|
|
for f in _PERSONALITY_STRING_FIELDS + _PERSONALITY_JSON_FIELDS
|
|
)
|
|
|
|
|
|
class ProposePersonalityUpdateRequest(BaseModel):
|
|
"""提交人格修改建议(api-spec §11);建议进入 pending 待审核。"""
|
|
|
|
character_id: str | None = Field(default=None, description="人物 ID,省略取当前激活人物。")
|
|
fields: PersonalityProposalFields = Field(description="需变更的人格字段覆盖。")
|
|
reason: str = Field(min_length=1, description="修改原因,必填留痕。")
|
|
|
|
|
|
class PersonalityProposalResponse(BaseModel):
|
|
"""人格修改建议响应(api-spec §11)。"""
|
|
|
|
proposal_id: str = Field(description="建议 ID。")
|
|
character_id: str = Field(description="所属人物 ID。")
|
|
status: str = Field(description="建议状态,见契约字典 §10.6 candidate.status。")
|
|
reason: str = Field(description="修改原因。")
|
|
fields: dict[str, Any] = Field(description="实际覆盖的字段集合。")
|
|
resulting_version_id: str | None = Field(
|
|
default=None, description="审核通过后生成的人格版本 ID。"
|
|
)
|
|
reviewed_at: str | None = Field(default=None, description="审核时间。")
|
|
created_at: str = Field(description="创建时间,UTC ISO 8601 字符串。")
|