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,20 @@
# 创作页作品删除入口设计 2026-04-24
## 背景
创作页作品卡曾把删除作为底部大按钮展示,并且只对带 `profileId` 的 RPG 作品传入删除回调,导致大鱼、拼图、以及部分草稿作品没有删除入口。用户预期是:删除不是主操作,放在卡片右上角的小 icon 即可;任何作品都应该能删除。
## 落地规则
- 作品卡右上角固定展示删除 icon底部主操作区只保留继续创作、查看详情、体验等正向操作。
- 删除入口不按发布状态隐藏:草稿、已发布作品均可删除。
- 删除入口不按玩法类型隐藏RPG、大鱼吃小鱼、拼图作品均应在创作页可删除。
- 点击删除前保留浏览器确认弹窗,避免误触;删除中仅禁用当前作品卡的删除 icon。
- 删除成功后刷新或替换对应玩法的作品列表,确保卡片立即消失。
## 工程边界
- 前端只负责表现和触发删除,实际删除由 `server-rs` API 与 SpacetimeDB 模块过程完成。
- 大鱼作品按 `sourceSessionId` 删除创作 session并同步清理消息、素材槽和运行快照。
- 拼图作品按 `profileId` 删除作品 profile并同步清理来源 Agent session、消息和入口运行快照。
- RPG 已发布/持久草稿按 `profileId` 走既有自定义世界删除链路;纯 Agent session 草稿按 `sessionId` 走 owner-only session 删除过程,并清理消息、操作与草稿卡。

View File

@@ -0,0 +1,27 @@
# PC 端世界生成与草稿页布局优化说明 2026-04-24
## 目标
在移动端现有布局不变的前提下,只优化 PC 端世界生成页与世界草稿页的信息组织,让页面更紧凑、更有层次,并保留全部已有功能入口。
## 范围
- 世界生成页:`src/components/CustomWorldGenerationView.tsx`
- 世界草稿页 / 作品页:`src/components/custom-world-home/CustomWorldCreationHub.tsx`
- 新建作品入口:`src/components/custom-world-home/CustomWorldCreationStartCard.tsx`
- 作品卡片:`src/components/custom-world-home/CustomWorldWorkCard.tsx`
- 筛选标签:`src/components/custom-world-home/CustomWorldWorkTabs.tsx`
## PC 端落地规则
1. 移动端默认类名保持原布局语义,只通过 `lg:` / `xl:` 断点追加 PC 布局。
2. 世界生成页在 PC 端改为左右双栏:左侧突出进度与阶段,右侧承载玩家设定 / 结构化锚点,减少纵向滚动。
3. 世界草稿页在 PC 端将“新建作品”和“作品列表”分区强化:顶部入口更紧凑,作品卡片网格密度提升。
4. 不新增规则说明文案,不改变按钮、筛选、删除、体验、进入等功能行为。
5. 中文文本只做必要保留,不因为布局调整改写已有中文内容。
## 视觉策略
- PC 端使用更明确的 `xl:grid`、固定信息侧栏和更小间距,让主内容首屏承载更多信息。
- 卡片在 PC 端降低无效高度,操作按钮与状态信息尽量同行展示。
- 保留现有 `platform-*` 视觉体系,避免引入新的 UI 系统。

View File

@@ -0,0 +1,17 @@
# PC 世界档案草稿编辑页布局修正 2026-04-24
## 背景
用户反馈 PC 端世界草稿页没有明显变化。复核截图后确认实际页面是世界档案草稿编辑页中的实体目录,而不是创作首页作品列表。
## 本次修正范围
- `src/components/CustomWorldEntityCatalog.tsx`
## 落地要求
1. 移动端仍保持原来的单列滚动、顶部标签与搜索结构。
2. PC 端把超宽单列实体列表改成卡片网格,减少横向空白,提高信息密度。
3. PC 端顶部世界标题、标签、搜索和操作按钮更紧凑,避免首屏被空白标题区占用。
4. 功能不变:搜索、切换标签、新增、批量删除、选择、编辑、发布入口均保持原有行为。
5. 不新增说明类文案,不改写已有中文内容。

View File

@@ -0,0 +1,30 @@
# 世界草稿发布面板与测试入口设计 2026-04-24
## 目标
世界草稿页底部不再只有“发布并进入世界”一个动作,而是拆成两个明确入口:
1. 作品测试:跳过发布阻断项检查,直接进入当前草稿游戏体验。
2. 发布:打开发布面板,在面板内集中处理发布阻断项与封面设置,满足条件后发布到广场。
## 页面范围
- `src/components/rpg-creation-result/RpgCreationResultActionBar.tsx`
- `src/components/rpg-creation-result/RpgCreationResultViewImpl.tsx`
- `src/components/CustomWorldEntityCatalog.tsx`
- `src/components/rpg-entry/useRpgCreationEnterWorld.ts`
- `src/components/platform-entry/PlatformEntryFlowShellImpl.tsx`
## 交互规则
1. 世界草稿页右下角显示“作品测试”和“发布”两个按钮。
2. “作品测试”只同步当前草稿结果并进入游戏,不触发发布阻断项检查,也不执行发布动作。
3. “发布”打开独立发布面板,不在当前页面下方展开内容。
4. 发布面板显示当前阻断项;没有阻断项时允许执行发布。
5. 发布面板显示封面预览与封面状态,并提供“设置封面”入口。
6. 封面生成、封面上传与封面预览从世界档案页迁移到发布面板;世界档案页不再展示作品封面模块。
7. 移动端仍使用底部弹层式面板PC 端使用居中 modal。
## 发布后行为
发布成功后刷新本地结果档案,并进入正式世界;作品由既有 `publish_world` 流程同步到作品库 / 广场。

View File

@@ -96,6 +96,7 @@
7. 不把“点击配置”实现成在当前卡片下面继续展开大段内容。
8. 不重写现有高好感委托链路,只在本次规则下明确它什么时候还能触发。
9. 不在草稿生成阶段默认补动作、待机、攻击、跑动或技能动作素材。
10. RPG 世界草稿的可扮演角色、场景角色与场景列表项不再直接展示“生成资产 / 生成场景图”按钮;资产生成由草稿生成链路或后续专门工坊入口承接,列表卡片只保留浏览、编辑、选择和删除等核心操作。
---

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 大鱼吃小鱼
保留差异: