fix custom world agent draft profile identity

This commit is contained in:
2026-04-23 13:54:38 +08:00
parent 1e200ec5ba
commit da7c1ff0c5
8 changed files with 356 additions and 6 deletions

View File

@@ -0,0 +1,109 @@
# Agent 草稿编译后重复生成草稿修复 2026-04-23
更新时间:`2026-04-23`
## 1. 问题现象
当前创作链里,用户打开一个已有 Agent 草稿,继续编辑并触发结果页编译或自动保存后,作品库里会新增一份 draft而不是更新原来的那一份。
这会带来两个直接问题:
1. 同一个会话在作品库里出现多份草稿
2. 原草稿状态没有被正确推进,导致发布、恢复、继续创作都可能命中旧条目
## 2. 根因拆解
本次问题不是单点,而是两段身份链没有收口到同一套规则:
### 2.1 `sync_result_profile` 会直接覆盖 session 里的 `draft_profile_json.id`
当前 `sync_result_profile` 会把结果页传回来的 `profile` 直接写回 `draft_profile_json`
如果结果页上的 `profile.id` 已经不是原草稿 id那么
1. session 主链中的 `draft_profile_json.id` 会被改成新 id
2. `resultPreview.preview.id` 也会跟着变成新 id
3. 前端 autosave 会拿着这个新 id 去调作品库 `PUT /custom-world-library/:profileId`
### 2.2 作品库 upsert 只按 `profile_id` 命中,不按 `source_agent_session_id` 兜底
当前作品库落库路径:
`结果页 autosave -> PUT /custom-world-library/:profileId -> upsert_custom_world_profile_record`
其中普通 autosave 路径此前存在两个问题:
1. 前端没有透传 `sourceAgentSessionId`
2. 后端普通 upsert 只按 `(owner_user_id, profile_id)` 查旧记录
所以一旦 `profile.id` 漂移,后端就会把它当作一条新的 draft 插入。
## 3. 修复目标
本轮修复要求同时满足下面两条:
1. Agent 草稿结果页继续编辑时,必须优先继承当前 session 已有的稳定 `profileId`
2. 即使前端传来的 `profile.id` 已经漂移,作品库 upsert 也要能按 `source_agent_session_id` 命中同一份 draft 并更新
## 4. 本轮落地策略
### 4.1 session 主链侧:稳定保留草稿 id
`sync_result_profile` 中,若当前 session 已经存在草稿身份:
1. 优先读取 `draft_profile_json.legacyResultProfile.id`
2. 其次读取 `draft_profile_json.id`
3. 若命中稳定 id则把传入 profile 的:
- 顶层 `id`
- `legacyResultProfile.id`
都强制回写为这个稳定 id
这样可以保证:
1. `draft_profile_json.id` 不会被结果页里的漂移 id 覆盖
2. `resultPreview.preview.id` 会持续稳定
3. 前端后续 autosave 会继续更新原草稿
### 4.2 作品库保存侧:透传 `sourceAgentSessionId`
前端 `upsertRpgWorldProfile(...)` 新增可选参数:
`sourceAgentSessionId?: string | null`
结果页属于 Agent 草稿视图时autosave 会把 `activeAgentSessionId` 一并传给作品库接口。
### 4.3 后端 upsert 侧:按 session 命中旧 draft
普通作品库 `PUT /custom-world-library/:profileId` 接口新增读取 `sourceAgentSessionId`
Spacetime `upsert_custom_world_profile_record(...)` 在按 `profile_id` 未命中时,新增二级兜底:
1. `owner_user_id` 相同
2. `publication_status == draft`
3. `deleted_at == None`
4. `source_agent_session_id == input.source_agent_session_id`
若命中这条旧 draft
1. 删除旧 row
2. 使用旧 row 的 `profile_id`
3. 更新 payload / metadata / updated_at
这样即使前端 path 参数已经是新 id也仍然会命中原草稿并更新而不是再插入第二份草稿。
## 5. 验收标准
修复后应满足:
1. 打开已有 Agent draft 后继续编译,不会新增第二份 draft
2. 原 draft 的 `profileId` 保持不变
3. `resultPreview.preview.id` 与作品库 `profileId` 一致
4. 自动保存、继续创作、进入世界、发布前检查都围绕同一份草稿身份工作
## 6. 结论
这次问题的本质不是“自动保存重复调用”,而是:
**Agent 草稿在 session 主链和作品库 upsert 两端都缺少稳定身份约束。**
本轮通过“session 保 id + 作品库按 session 兜底命中”双保险,把同一份草稿重新收口为单一身份。