Files
Genarrative/docs/technical/CUSTOM_WORLD_RESULT_ENTITY_GENERATION_FIX_2026-04-24.md
kdletters cbc27bad4a
Some checks failed
CI / verify (push) Has been cancelled
init with react+axum+spacetimedb
2026-04-26 18:06:23 +08:00

3.5 KiB
Raw Permalink Blame History

世界结果页新增场景与 NPC 生成修复

背景

世界结果页在 Agent 草稿模式下点击“新增场景角色”和“新增场景”时,会走 api-servergenerate_characters / generate_landmarks 动作:

  1. api-server 根据当前 draft_profile 请求 LLM 生成新增实体。
  2. spacetime-modulegeneratedCharacters / generatedLandmarks 写回 draft_profile
  3. 结果页从服务端 resultPreview.preview 读取最新世界 profile。

问题

LLM 扩展提示词为了草稿卡片简洁,只要求返回角色的 publicMask / hiddenHook / relationToPlayer / summary,以及场景的 purpose / mood / secret / summary / characterIds

但结果页与运行时 CustomWorldProfile 读取的是当前完整字段:

  • NPCdescription / backstory / personality / motivation / relationshipHooks / tags / initialAffinity
  • 场景:description / sceneNpcIds / connections

因此新增实体即使后端动作成功,也可能因为字段缺失或关联字段名不一致,在结果页表现为“生成后没有可用内容 / 场景没有 NPC 关联”。

此外Agent 结果页生成回调原本只返回 void:当 activeAgentSessionId 失效、服务端没有返回最新 resultPreview,或最新 profile 没有新增实体时,前端只会结束 pending 动画,表现为“点击后闪一下就消失”。

修复方案

本次修复保持“前端只表现,后端负责数据整理”的边界:

  1. api-server 生成实体归一化阶段补齐结果页需要的最小完整字段。
  2. NPC 将 publicMask / summary 映射为 descriptionhiddenHook 映射为 backstory / motivationrelationToPlayer 进入 relationshipHooks
  3. 场景将 summary / purpose / mood / secret 合成 description,将 characterIds 转为 sceneNpcIds
  4. 保留 LLM 已返回的字段,不覆盖更完整的结构化结果。
  5. 增加后端单元测试锁定新增 NPC 与场景的 profile 字段契约。
  6. 前端 Agent 生成回调返回最新 profile如果没有可用会话或最新 profile 未增加对应实体,结果页显示明确错误,不再静默消失。

验收

  • generate_characters 的 payload 中新增角色必须包含非空 description 与可用 relationshipHooks
  • generate_landmarks 的 payload 中新增场景必须包含非空 description,并能把 characterIds 落为 sceneNpcIds
  • 结果页继续只消费 resultPreview.preview,不新增前端本地编译分支。
  • 结果页点击新增实体后,如果服务端没有回传新增内容,必须展示错误提示。

2026-04-24 追加:可扮演角色结果页空刷新修复

新增可扮演角色报“生成请求已完成,但结果页未收到新增内容”的根因是:api-server 已经把 LLM 生成结果注入 generatedCharacters,但 spacetime-module 缺少 generate_characters / generate_landmarks 的真实落库 executoraction 会进入分派却无法把新增内容写入 draft_profile_jsonresult_preview_json

本次补齐 SpacetimeDB module executor

  1. generate_characters(roleType=playable) 写入 draftProfile.playableNpcs
  2. generate_characters(roleType=story) 写入 draftProfile.storyNpcs
  3. generate_landmarks 写入 draftProfile.landmarks
  4. 每个新增实体同步生成 draft card并刷新 publish_gate_json / result_preview_json / checkpoints_json / operation / message

结果页仍只消费服务端 resultPreview.preview;前端不会本地伪造新增角色。