Merge branch 'codex/backend-rewrite-spacetimedb' of http://82.157.175.59:3000/GenarrativeAI/Genarrative into codex/backend-rewrite-spacetimedb

# Conflicts:
#	server-rs/crates/spacetime-client/src/lib.rs
#	src/components/platform-entry/PlatformEntryFlowShellImpl.tsx
This commit is contained in:
2026-04-24 22:17:37 +08:00
54 changed files with 2339 additions and 434 deletions

View File

@@ -0,0 +1,54 @@
# 自定义世界资产 Prompt 与默认描述配置说明2026-04-24
## 1. 目标
本说明记录生成世界草稿时,角色形象图像、角色动作视频、每一幕场景背景图像三类资产的默认描述与正式模型 prompt 的配置位置,避免后续继续误改旧 `server-node` 链路。
## 2. 世界草稿默认描述字段
生成世界草稿时,后端会要求模型在角色与幕级剧情结构阶段直接产出资产默认描述字段:
- 角色:`visualDescription`,用于打开角色形象图像生成面板时默认填入角色形象描述框。
- 角色:`actionDescription`,用于打开角色动作视频生成面板时默认填入各动作描述框;当前每个动作会从同一角色默认动作描述起步,用户切换动作后可分别编辑并缓存。
- 每一幕:`sceneChapterBlueprints[*].acts[*].backgroundPromptText`,用于打开该幕背景图像生成面板时默认填入场景描述框。
- 场景:`visualDescription` 只作为旧场景图或没有幕级描述时的兜底,不再从角色 AI 形象生成面板维护场景背景描述。
草稿生成契约位置:
- `server-rs/crates/api-server/src/custom_world_foundation_draft.rs`
- `build_custom_world_role_outline_batch_prompt`
- `build_custom_world_landmark_seed_batch_prompt`
- `build_foundation_draft_user_prompt`
- `normalize_scene_act_blueprint`
前端默认框映射位置:
- `src/prompts/customWorldRolePromptDefaults.ts`
- `visualPromptText` 优先取 `role.visualDescription`
- `animationPromptText` 优先取 `role.actionDescription`
- `src/components/rpg-creation-asset-studio/RpgCreationRoleAssetStudioModalImpl.tsx`
- 角色形象与动作工坊初始化默认文本。
- `animationPromptTextByKey` 负责分动作保存动作描述。
- 当角色本身已有 `visualDescription/actionDescription` 时,必须优先使用这批世界草稿新生成字段,不能让旧 workflow cache 覆盖当前草稿默认文本。
- `src/components/rpg-creation-editor/RpgCreationEntityEditorShared.tsx`
- 幕背景图像生成弹窗优先使用 `act.backgroundPromptText`
- 普通场景图像生成弹窗仍可使用 `landmark.visualDescription` 兜底。
## 3. 正式模型 Prompt 配置
正式生成图片或视频时,不直接使用默认描述字段作为完整 prompt而是在 `server-rs` 继续编译:
- 角色主图:`server-rs/crates/api-server/src/custom_world_asset_prompts.rs`
- `build_character_visual_prompt`
- 内部使用 `build_master_prompt`
- 角色动作视频:`server-rs/crates/api-server/src/custom_world_asset_prompts.rs`
- `build_character_animation_prompt`
- 图生视频分支使用 `build_video_action_prompt`
- 场景背景图:`server-rs/crates/api-server/src/custom_world_ai.rs`
- `build_custom_world_scene_image_prompt`
## 4. 当前约束
- 不再把 `server-node/src/prompts/characterAssetPrompts.ts` 作为主链修改目标。
- 默认描述字段必须由世界草稿生成阶段写入,前端只负责把字段填入输入框并允许用户编辑。
- UI 不默认展示规则解释文案,正式约束只进入后端 prompt。

View File

@@ -38,3 +38,16 @@ LLM 扩展提示词为了草稿卡片简洁,只要求返回角色的 `publicMa
- `generate_landmarks` 的 payload 中新增场景必须包含非空 `description`,并能把 `characterIds` 落为 `sceneNpcIds`
- 结果页继续只消费 `resultPreview.preview`,不新增前端本地编译分支。
- 结果页点击新增实体后,如果服务端没有回传新增内容,必须展示错误提示。
## 2026-04-24 追加:可扮演角色结果页空刷新修复
新增可扮演角色报“生成请求已完成,但结果页未收到新增内容”的根因是:`api-server` 已经把 LLM 生成结果注入 `generatedCharacters`,但 `spacetime-module` 缺少 `generate_characters / generate_landmarks` 的真实落库 executoraction 会进入分派却无法把新增内容写入 `draft_profile_json``result_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`;前端不会本地伪造新增角色。

View File

@@ -13,6 +13,18 @@
目标是把旧 Node 写入本地 `public/generated-character-drafts/*/workflow-cache.json` 的临时缓存,切到 OSS JSON 草稿对象,继续保持前端当前可消费 contract。
## 1.1 2026-04-24 修订:按作品隔离缓存
世界草稿生成后的首个场景角色经常使用 `hero / npc-1` 等稳定角色 ID。若缓存对象键只包含 `characterId`,不同作品打开同名角色时会复用上一部作品的 `visualPromptText / imageSrc / visualDrafts`导致“AI 角色生成的形象描述默认文本”和当前剧本无关。
本修订冻结以下口径:
1. 前端在角色资产工坊读写缓存时必须传入 `cacheScopeId`,默认取当前作品 `profile.id`
2. Rust 保存接口接受可选 `cacheScopeId`,并写回缓存 JSON便于读取时校验归属。
3. 新缓存对象键改为 `generated-character-drafts/{cacheScopeSegment}/{characterSegment}/workflow-cache/workflow-cache.json`
4. 未带 `cacheScopeId` 的旧请求仍走历史对象键,避免破坏旧工具或历史兼容入口。
5. 新前端不会回退读取旧无作品维度缓存,避免把跨作品旧缓存再次带入新世界草稿。
## 2. 当前前提
当前仓库已经具备以下能力:
@@ -63,15 +75,16 @@
请求结构继续保持前端当前字段:
1. `characterId`
2. `visualPromptText`
3. `animationPromptText`
4. `visualDrafts`
5. `selectedVisualDraftId`
6. `selectedAnimation`
7. `imageSrc`
8. `generatedVisualAssetId`
9. `generatedAnimationSetId`
10. `animationMap`
2. `cacheScopeId`:可选;当前自定义世界作品写入 `profile.id`
3. `visualPromptText`
4. `animationPromptText`
5. `visualDrafts`
6. `selectedVisualDraftId`
7. `selectedAnimation`
8. `imageSrc`
9. `generatedVisualAssetId`
10. `generatedAnimationSetId`
11. `animationMap`
返回结构继续保持:
@@ -83,28 +96,36 @@
缓存 JSON 固定写入:
新前端写入:
`generated-character-drafts/{cacheScopeSegment}/{characterSegment}/workflow-cache/workflow-cache.json`
旧兼容入口未提供 `cacheScopeId` 时继续写入:
`generated-character-drafts/{characterSegment}/workflow-cache/workflow-cache.json`
其中:
1. `characterSegment` 来自 `characterId` 的安全路径片段
2. 文件名固定为 `workflow-cache.json`
3. content type 固定为 `application/json; charset=utf-8`
1. `cacheScopeSegment` 来自 `cacheScopeId` 的安全路径片段,通常等于作品 `profile.id`
2. `characterSegment` 来自 `characterId` 的安全路径片段
3. 文件名固定为 `workflow-cache.json`
4. content type 固定为 `application/json; charset=utf-8`
## 6. 字段归一化规则
保存接口固定执行以下归一化:
1. `characterId` 必填trim 后不能为空
2. `visualPromptText` 最长保留 280 字
3. `animationPromptText` 最长保留 280 字
4. `visualDrafts` 只保留有 `imageSrc` 的候选
5. `visualDrafts[].width` 默认 `1024`
6. `visualDrafts[].height` 默认 `1536`
7. `selectedAnimation` 默认 `idle`
8. `imageSrc / generatedVisualAssetId / generatedAnimationSetId` 不序列化
9. 非对象 `animationMap` 归一化为 `null`
10. `updatedAt` 由 Rust 服务端生成 UTC 时间
2. `cacheScopeId` trim 后为空则视为旧兼容缓存,不写新作品目录
3. `visualPromptText` 最长保留 280 字
4. `animationPromptText` 最长保留 280 字
5. `visualDrafts` 只保留有 `imageSrc` 的候选
6. `visualDrafts[].width` 默认 `1024`
7. `visualDrafts[].height` 默认 `1536`
8. `selectedAnimation` 默认 `idle`
9. `imageSrc / generatedVisualAssetId / generatedAnimationSetId` 不序列化
10. 非对象 `animationMap` 归一化为 `null`
11. `updatedAt` 由 Rust 服务端生成 UTC 时间
## 7. 元数据规范
@@ -115,6 +136,7 @@
3. `entity_kind = character`
4. `entity_id = characterId`
5. `slot = workflow_cache`
6. `cache_scope_id = cacheScopeId`,仅新作品维度缓存写入
说明:

View File

@@ -103,6 +103,8 @@ src/services/creation-agent/
3. 补全剩余设定话术。
4. 生成结果页 action`draft_foundation`
`draft_foundation` 的生成进度必须展示并真实执行后端后台任务阶段:世界骨架、角色/场景结构、底稿编译、角色主形象生成、幕背景图生成、草稿卡编译、结果页写回。角色主形象与幕背景图不能只作为 UI 进度占位;后台任务必须调用素材生成链路,将角色 `imageSrc / generatedVisualAssetId` 与场景幕 `backgroundImageSrc / backgroundAssetId` 写回 `draftProfile` 后,才能继续进入草稿卡编译与结果页写回。
### 4.2 大鱼吃小鱼
保留差异: