M6:缘契、人格与世界——契约版本链、铸魂分灵、河图境界与三界分流

- 缘契域 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 干净
This commit is contained in:
chenxin committed 2026-08-27 20:10:11 +08:00
1 parent 684261f4b4
commit 7e23d6fa84
108 files changed
+2600 -9732

No files matched your search

-2
View File
@@ -17,7 +17,6 @@ class CharacterResponse(BaseModel):
"language": "zh-CN",
"profile": {"bio": "本地 MVP 默认人物。"},
"model_policy": {"default_model_hint": "deepseek-v4-flash"},
"current_personality_version_id": "personality_9b5f5b7e413442d0a2f9e61a2f4d7df5",
"privacy_level": "normal",
"owner_scope": "local-user",
"is_system_template": False,
@@ -36,7 +35,6 @@ class CharacterResponse(BaseModel):
language: str = Field(description="人物默认语言。")
profile: dict[str, Any] = Field(description="人物档案 JSON。")
model_policy: dict[str, Any] = Field(description="人物模型策略。")
current_personality_version_id: str | None = Field(description="当前人格版本 ID。")
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。")
-41
View File
@@ -1,41 +0,0 @@
"""内驱力 API schema(database-schema §22;/drive 端点)。"""
from datetime import datetime
from pydantic import Field
from app.schemas.common import OrmModel
class CuriosityResponse(OrmModel):
"""好奇问题响应(related_entities 已从 JSON 文本解析)。"""
id: str
character_id: str
cycle_id: str
question: str
source: str
related_entities: list[str] = Field(default_factory=list)
expected_value: float
urgency: float
risk_level: str
created_at: datetime
class SubgoalResponse(OrmModel):
"""探索性次生目标响应。"""
id: str
character_id: str
cycle_id: str
parent_goal_id: str | None = None
curiosity_question_id: str
title: str
description: str
expected_information_gain: float
interruption_cost: float
risk_level: str
status: str
reviewed_at: datetime | None = None
reviewed_by: str
created_at: datetime
-101
View File
@@ -1,101 +0,0 @@
"""人格 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 字符串。")