- 缘契域 domains/yuanqi:covenants(当前版)+ covenant_events(不可变历史);提议—问心—铭契—撤回全链;边界变更立即生效;多维关系并存,服务层拒绝 affinity/好感度单一键;浪漫维度成人资格标记位 - 道体铸魂与分灵 domains/jingsheng/soul.py:soul_forgings 确认流(锚点变更 pending→confirmed 应用并签发新魂籍版本,确认前人物锚点不变);分灵创建新人物(继承资料与谱系 lineage 链、不继承原身份,魂籍从 v1 起) - 河图域 domains/hetu:persistent_worlds 境界 + world_entities/world_relations 境界作用域重建 + 世谱挂接;境界正史视图(scope=persistent_world 归真集合);canonize 后置推进正史计数 - 三界分流:reality→息壤提取(不变);persistent_world→境界实录+正史推进;simulation→只记试演实录;factual_records 增 scope 列——境界/幻境实录与真界本相隔离 - 正影打通:引文 target_type=memory 时被引记忆 superseded → 返回 successor_memory_id 提示,不静默替换 - 前端:人物详情页缘契面板(提议维度选择/铭契/撤回/事件史)+ 世界页重建(境界目录/实体/正史概览)+ covenants/worlds api 库 - 退役:旧 personality/drive/evolution/world 模块、服务、端点、仓储、schema、前端五页与组件样式;迁移 007 退役九张旧表与 characters.current_personality_version_id - 验收(test_m6_domains 六用例):多维无单一好感度/铭契版本链/事件不可抹除/撤回立即生效/边界即时/铸魂确认流+魂籍版本/分灵谱系/境界正史不进真界(实录 scope 隔离+真界候选=0)/引文正影后继 - 四套件:后端 379、前端 199、BFF 4、神识 5 包全绿(2 个预存环境失败不变);迁移 007 净库+±1 干净
136 lines
6.4 KiB
Python
136 lines
6.4 KiB
Python
"""人物 API schema。"""
|
||
|
||
from typing import Any
|
||
|
||
from pydantic import BaseModel, ConfigDict, Field
|
||
|
||
|
||
class CharacterResponse(BaseModel):
|
||
model_config = ConfigDict(
|
||
json_schema_extra={
|
||
"examples": [
|
||
{
|
||
"id": "character_ec83d55746c54e47ab6f98d683032626",
|
||
"name": "default",
|
||
"display_name": "魂镜默认人物",
|
||
"status": "active",
|
||
"language": "zh-CN",
|
||
"profile": {"bio": "本地 MVP 默认人物。"},
|
||
"model_policy": {"default_model_hint": "deepseek-v4-flash"},
|
||
"privacy_level": "normal",
|
||
"owner_scope": "local-user",
|
||
"is_system_template": False,
|
||
"source_template_id": "character_template_default",
|
||
"created_at": "2026-06-19T09:00:00.000000Z",
|
||
"updated_at": "2026-06-19T09:00:00.000000Z",
|
||
}
|
||
]
|
||
}
|
||
)
|
||
|
||
id: str = Field(description="人物 ID,前缀为 character_。")
|
||
name: str = Field(description="人物内部名称。")
|
||
display_name: str | None = Field(description="人物显示名称。")
|
||
status: str = Field(description="人物状态,取值见契约字典 character.status。")
|
||
language: str = Field(description="人物默认语言。")
|
||
profile: dict[str, Any] = Field(description="人物档案 JSON。")
|
||
model_policy: dict[str, Any] = Field(description="人物模型策略。")
|
||
privacy_level: str = Field(description="隐私等级:normal / sensitive / local_only。")
|
||
owner_scope: str = Field(description="归属范围;当前本地 MVP 为 local-user。")
|
||
is_system_template: bool = Field(description="是否系统人物模板;active API 通常返回 false。")
|
||
source_template_id: str | None = Field(
|
||
description="来源系统模板人物 ID;非模板复制人物通常有值。"
|
||
)
|
||
avatar_url: str | None = Field(
|
||
default=None, description="角色头像 URL。无头像时为 null。"
|
||
)
|
||
created_at: str = Field(description="创建时间,UTC ISO 8601 字符串。")
|
||
updated_at: str = Field(description="更新时间,UTC ISO 8601 字符串。")
|
||
|
||
|
||
class CharacterSummaryResponse(BaseModel):
|
||
"""人物列表项(api-spec §6 列出人物)。"""
|
||
|
||
id: str = Field(description="人物 ID,前缀为 character_。")
|
||
name: str = Field(description="人物内部名称。")
|
||
display_name: str | None = Field(description="人物显示名称。")
|
||
status: str = Field(description="人物状态,取值见契约字典 character.status。")
|
||
memory_count: int = Field(default=0, description="人物关联的未删除记忆数量。")
|
||
personality_version: int = Field(default=0, description="当前人格版本号;尚未形成人格时为 0。")
|
||
activated_at: str | None = Field(
|
||
default=None, description="最近激活时间,UTC ISO 8601 字符串。"
|
||
)
|
||
|
||
|
||
class CreateCharacterRequest(BaseModel):
|
||
name: str = Field(min_length=1, description="人物内部名称,必填。")
|
||
display_name: str | None = Field(default=None, description="可选显示昵称。")
|
||
template_key: str | None = Field(
|
||
default=None,
|
||
description="系统模板 key;传此值则从模板创建(继承档案/模型策略,status=active)。",
|
||
)
|
||
profile: dict[str, Any] | None = Field(
|
||
default=None,
|
||
description="人物档案,可含 birthday/height/weight/background/speaking_style。",
|
||
)
|
||
model_policy: dict[str, Any] | None = Field(
|
||
default=None,
|
||
description="模型策略,可含 default_chat_model_hint / memory_extraction_model_hint 等。",
|
||
)
|
||
|
||
|
||
class UpdateProfileRequest(BaseModel):
|
||
"""更新人物档案(api-spec §6 PATCH /characters/{id}/profile)。手动编辑视为用户确认。"""
|
||
|
||
display_name: str | None = Field(default=None, description="可选显示昵称。")
|
||
birthday: str | None = Field(default=None)
|
||
height: str | None = Field(default=None)
|
||
weight: str | None = Field(default=None)
|
||
description: str | None = Field(default=None, description="一句话简介。")
|
||
background: str | None = Field(default=None)
|
||
speaking_style: str | None = Field(default=None, description="表达风格。")
|
||
temperament: str | None = Field(default=None, description="性情气质。")
|
||
hobbies: list[str] | None = Field(default=None, description="兴趣爱好列表。")
|
||
values: list[str] | None = Field(default=None, description="价值观列表。")
|
||
|
||
|
||
class UpdateModelPolicyRequest(BaseModel):
|
||
"""更新人物模型策略(api-spec §6 PATCH /characters/{id}/model-policy)。"""
|
||
|
||
default_chat_model_hint: str | None = Field(default=None)
|
||
memory_extraction_model_hint: str | None = Field(default=None)
|
||
personality_analysis_model_hint: str | None = Field(default=None)
|
||
embedding_model_hint: str | None = Field(default=None)
|
||
privacy_level: str | None = Field(default=None)
|
||
|
||
|
||
class ActivateCharacterResponse(BaseModel):
|
||
"""激活人物响应(api-spec §6 POST /characters/{id}/activate)。"""
|
||
|
||
active_character_id: str = Field(description="当前激活人物 ID。")
|
||
status: str = Field(description="激活后状态,恒为 active。")
|
||
|
||
|
||
class CharacterTemplateSummaryResponse(BaseModel):
|
||
"""系统模板列表项(GET /character-templates)。"""
|
||
|
||
key: str = Field(description="模板唯一标识(template_key)。")
|
||
name: str = Field(description="模板人物内部名称。")
|
||
display_name: str | None = Field(description="模板人物显示昵称。")
|
||
description: str | None = Field(description="档案中的一句话描述(profile.description)。")
|
||
temperament: str | None = Field(description="档案中的性情气质(profile.temperament)。")
|
||
speaking_style: str | None = Field(description="档案中的说话风格(profile.speaking_style)。")
|
||
language: str = Field(description="默认语言。")
|
||
|
||
|
||
class ImportCardResponse(BaseModel):
|
||
"""角色卡导入结果。"""
|
||
|
||
character_id: str = Field(description="新建人物 ID。")
|
||
name: str = Field(description="人物名称。")
|
||
display_name: str | None = Field(default=None, description="显示名(V3 nickname 优先)。")
|
||
lorebook_id: str | None = Field(
|
||
default=None, description="导入的世谱 ID(character_book);无则为 null。"
|
||
)
|
||
entry_count: int = Field(default=0, description="世谱条目数。")
|