This commit is contained in:
2026-04-24 12:21:33 +08:00
parent 3528980645
commit 70b5a7cf73
515 changed files with 14971 additions and 6831 deletions

View File

@@ -152,12 +152,11 @@
开发态本地链路补充约定:
1. 浏览器仍只请求同源 `/api/runtime/big-fish/*`
2. `vite -> server-node:8081` 保持不变,由 `server-node` 先复用现有登录态完成 Bearer 校验
3. `server-node` 作为 Big Fish 兼容网关,把“已校验用户身份 + 原始请求体”转发到 Rust `api-server`
4. Rust `api-server` 继续作为 Big Fish 真相后端,正式处理会话、草稿、资产动作和运行态规则
2. `vite -> Rust api-server:3100` 是默认开发链路,禁止把新运行态接口继续接回 `server-node`
3. Rust `api-server` 作为 Big Fish 真相后端,正式处理鉴权、会话、草稿、资产动作和运行态规则
4. 若本机端口不同,只能通过 `RUST_SERVER_TARGET``GENARRATIVE_API_TARGET``GENARRATIVE_RUNTIME_SERVER_TARGET` 显式覆盖 Vite 代理目标
5. 本地默认端口:
- `vite`: `3000`
- `server-node`: `8081`
- Rust `api-server`: `3100`
- `SpacetimeDB standalone`: `3001`
6. `GENARRATIVE_SPACETIME_DATABASE` 本地开发优先跟随仓库根目录 `spacetime.local.json``database` 字段,避免 `api-server` 默认连到错误数据库名。
@@ -192,6 +191,12 @@
2. `GET /api/runtime/big-fish/runs/{runId}`
3. `POST /api/runtime/big-fish/runs/{runId}/input`
### 6.3 作品列表
1. `GET /api/runtime/big-fish/works`
开发态 Vite 必须把该同源接口代理到 Rust `api-server`;前端作品页只调用同源 `/api/runtime/big-fish/works`,不得直连 Rust 端口或回退到 `server-node`
`input` 请求体:
```json

View File

@@ -0,0 +1,66 @@
# 创作模板 Agent 聊天共用化设计2026-04-24
## 背景
当前创作模板的 Agent 聊天链路不一致RPG 世界共创与拼图共创已经由后端调用模型推理生成回复和锚点状态,大鱼吃小鱼仍在 SpacetimeDB 过程内用规则推断锚点并返回固定回复。这样会导致同一入口下不同模板的共创体验不一致,也会让后续新增模板重复实现聊天流程。
## 目标
1. 所有创作模板的 Agent 聊天都必须由后端模型推理生成回复与下一轮锚点状态。
2. Agent 聊天能力对齐 RPG 世界共创的功能效果:后端负责模型调用、锚点更新、进度推进与落库,前端只消费 session snapshot。
3. 不同模板在 Agent 聊天环节只允许通过“锚点问题配置”体现差异其余提示词骨架、流式回复、JSON 解析、失败兜底流程复用。
4. 锚点配置必须从代码逻辑中抽离为独立配置文件,新增模板时优先新增配置而不是复制聊天代码。
## 首版落地范围
| 模板 | 现状 | 本次处理 |
| --- | --- | --- |
| RPG 世界共创 | 已走模型推理,八锚点结构最完整 | 保持现有流程,作为统一体验标杆 |
| 拼图共创 | 已走模型推理,但锚点问题硬编码在 Rust 提示词中 | 把 5 个锚点问题迁入配置文件,提示词读取配置 |
| 大鱼吃小鱼 | 规则推断 + 固定回复 | 新增模型推理 turn读取 4 个锚点配置,提交消息后再 finalize 落库 |
## 配置设计
配置文件路径固定为:`server-rs/crates/api-server/src/creation_agent_anchor_templates.json`
每个模板配置包含:
- `templateId`:模板唯一标识。
- `displayName`:用于后端提示词,不直接展示在 UI。
- `creationGoal`:模板最终要收束出的可玩结果。
- `anchorQuestions`:锚点问题列表,包含 `key / label / question / requiredEffect`
首版配置只存“问题与效果”,不存模型输出 schema。原因是各模板 session 的锚点结构不同schema 仍由各自 domain 类型约束,避免为了统一而牺牲类型安全。
## 共用聊天骨架
后端新增 `creation_agent_anchor_templates` 模块,提供:
1. 读取并缓存配置文件。
2.`templateId` 返回模板配置。
3. 渲染统一的“锚点问题段落”。
各模板 agent turn 共用以下模型推理约束:
1. 系统提示词说明当前模板目标。
2. 插入配置文件中的锚点问题段落。
3. 插入当前锚点状态与最近聊天记录。
4. 要求模型只输出 JSON。
5. 流式过程中只把 `replyText` 增量给前端。
6. 完整响应解析后,由模板自身 domain 类型反序列化并落库。
## 大鱼吃小鱼落库调整
SpacetimeDB module 仍保持数据真相源职责,但不再在 `submit_big_fish_message` 内生成 assistant 回复与新锚点。流程调整为:
1. `submit_big_fish_message` 只写入用户消息,保留原锚点与进度。
2. api-server 调用模型生成 `replyText / progressPercent / nextAnchorPack`
3. 新增 `finalize_big_fish_agent_message_turn` procedure把模型结果写回 assistant 消息、锚点、进度与 `last_assistant_reply`
4. 模型失败时通过 finalize 记录失败提示,避免用户消息丢失。
## 约束
- 前端不新增逻辑分支,不在 UI 中展示规则说明类文本。
- 后端 prompt、配置与 Rust 代码必须保留中文注释或中文语义说明。
- 配置文件是后端资产,不依赖前端动态编辑。
- 若未来模板锚点结构统一,可以再把输出 schema 迁入配置;首版不做过度抽象。

View File

@@ -73,3 +73,24 @@ RPG 创作结果页已经能看到完整草稿内容,但页面底部仍然持
3. “发布并进入世界”在 blocker 清空后恢复可点击。
4. `ensure_minimal_draft_profile(...)` 生成的兜底草稿也包含 `sceneChapterBlueprints`
5. 新增 Rust 单测,覆盖“当前 Agent 结果 schema 不应再误报 blocker”与“最小草稿必须保留 `sceneChapterBlueprints` 默认槽位”。
## 5. 亮色主题阻断项弹窗配色修复
日期:`2026-04-24`
### 5.1 问题现象
点击“发布并进入世界”但仍存在阻断项时,`PublishBlockersDialog` 会通过 portal 挂载到 `document.body`。在亮色主题下,弹窗面板使用平台浅色面板变量,但标题、分隔线和阻断项标签仍混用暗色主题下的 `text-white``border-white/10``text-amber-100/78` 等硬编码类名,导致局部对比度和色相不一致。
### 5.2 修复口径
1. portal 根节点显式补上 `platform-theme platform-theme--${platformTheme}`,避免弹窗脱离原页面主题变量继承。
2. 弹窗标题、上下分隔线统一改为 `--platform-text-strong``--platform-subpanel-border`
3. 阻断项卡片复用 `platform-banner platform-banner--warning`,由平台主题变量决定亮色和暗色下的边框、背景与警示文字色。
4. 阻断项正文保持 `--platform-text-strong`,保证亮色主题下可读性,不再依赖暗色主题的琥珀色文本。
### 5.3 验收标准
1. 亮色主题下阻断项弹窗标题、正文、分隔线和按钮均保持平台浅色视觉体系。
2. 阻断项卡片呈现柔和警示底色,不出现白字或过浅琥珀字落在浅底上的情况。
3. 暗色主题下弹窗仍保持原有平台暗色 warning banner 风格。

View File

@@ -0,0 +1,85 @@
# Custom World Agent 删除作品 / 新增 NPC / 新增场景 Rust 迁移记录
日期:`2026-04-24`
## 范围
本次继续检查 RPG 创作 Agent 从旧 `server-node` 迁到 `server-rs` 后的功能缺口,重点覆盖:
1. 删除作品。
2. 新增 NPC`generate_characters`)。
3. 新增场景 / 地点(`generate_landmarks`)。
## 结论
### 删除作品
Rust 链路已经存在:
```text
DELETE /api/runtime/custom-world/library/:profileId
-> api-server.delete_custom_world_library_profile
-> spacetime-client.delete_custom_world_profile
-> SpacetimeDB delete_custom_world_profile_and_return
-> owner-only 软删除 profile并从 gallery 读模型移除
```
本次未改删除作品实现,只确认它已走 Rust + SpacetimeDB不再依赖 Node。
### 新增 NPC / 新增场景
迁移前,`spacetime-module``generate_characters``generate_landmarks` 只走 `execute_placeholder_custom_world_action(...)`,不会真的调用 AI也不会更新 `draftProfile` / draft card。
本次迁移后链路变为:
```text
前端 action
-> api-server execute_custom_world_agent_action
-> api-server 读取 session snapshot
-> platform-llm 使用旧 Node prompt 生成 JSON 数组
-> payload 注入 generatedCharacters / generatedLandmarks
-> spacetime-client.execute_custom_world_agent_action
-> SpacetimeDB 更新 draftProfile
-> SpacetimeDB upsert 对应 draft card
-> SpacetimeDB 更新 publishGate / resultPreview / checkpoint / operation / action result message
```
## Node 对齐点
新增 NPC 保留旧 Node 的 system prompt 与 user prompt 字段约束:
```text
name, role, publicMask, hiddenHook, relationToPlayer, summary, threadIds
```
新增场景保留旧 Node 的 system prompt 与 user prompt 字段约束:
```text
name, purpose, mood, dangerLevel, secret, summary, threadIds, characterIds
```
Rust 侧只做最小归一化:补 `id`、去除重名、限制数量 `1..=3`,不改写提示词原文语义。
## 落库设计
1. `generate_characters` 默认追加到 `draftProfile.storyNpcs`
2. `generate_landmarks` 追加到 `draftProfile.landmarks`
3. 每个新增对象都会生成 / 更新一张 `custom_world_draft_card`
4. 操作完成后同步更新:
- `last_assistant_reply`
- `publish_gate_json`
- `result_preview_json`
- `checkpoints_json`
- `custom_world_agent_operation`
- `custom_world_agent_message`
## 验证
已运行:
```bash
cargo test -p api-server custom_world_agent_entities --no-default-features
cargo check -p spacetime-module
```
结果:通过。`spacetime-module` 仅保留仓库既有 glob re-export warning。

View File

@@ -0,0 +1,54 @@
# Custom World `draft_foundation` Rust/Node AI 工作流对齐记录
日期:`2026-04-24`
## 背景
本次检查发现 `server-rs` 的 RPG 档案 / 世界底稿生成只做了单次 LLM 调用:直接让模型输出完整 `draftProfile`,再做最小字段归一化。这与旧 `server-node``CustomWorldAgentFoundationDraftService.generate()` 不一致。
旧 Node 流程不是单 prompt 直出,而是分阶段生成:
```text
buildFoundationGenerationSeedText
-> buildCustomWorldFrameworkPrompt
-> generateFoundationRoleOutlineEntries(playable)
-> generateFoundationRoleOutlineEntries(story)
-> generateFoundationLandmarkSeedEntries
-> expandFoundationLandmarkNetworkEntries
-> expandFoundationRoleEntries(playable, narrative)
-> expandFoundationRoleEntries(playable, dossier)
-> expandFoundationRoleEntries(story, narrative)
-> expandFoundationRoleEntries(story, dossier)
-> buildFoundationDraftProfileFromFramework
```
## 本次落地
`server-rs/crates/api-server/src/custom_world_foundation_draft.rs` 已改为按 Node 原顺序执行多阶段 AI 生成:
1. 先从 `anchorContent / anchorPack / creatorIntent / seedText` 构造 `settingText`
2. 使用旧 Node 的 framework prompt 生成世界核心骨架。
3. 分批生成可扮演角色 outline。
4. 分批生成场景角色 outline。
5. 分批生成关键场景 seed。
6. 补全关键场景探索网络。
7. 先补可扮演角色叙事档案,再补养成档案。
8. 先补场景角色叙事档案,再补养成档案。
9. 将分阶段结果编译回 `draftProfile`,再交给 SpacetimeDB action 落库。
## 约束
1. 未修改旧 Node 提示词原文的语义与阶段顺序。
2. Rust 侧新增 prompt 构造只服务 `api-server` 外部 LLM 调用SpacetimeDB reducer 仍只负责校验与落库,不承担联网生成。
3. 当前仍保留 Rust 侧最小归一化,目的仅是保证 `publish gate / result preview` 需要的字段存在,不替代 Node 的 AI 工作流。
4. 后续如继续迁移,需要优先把 Node `buildFoundationDraftProfileFromFramework` 的结构编译细节进一步完整 Rust 化,而不是回退到单 prompt 直出。
## 验证
已运行:
```bash
cargo test -p api-server custom_world_foundation_draft --no-default-features
```
结果:`3 passed`

View File

@@ -0,0 +1,40 @@
# 世界结果页新增场景与 NPC 生成修复
## 背景
世界结果页在 Agent 草稿模式下点击“新增场景角色”和“新增场景”时,会走 `api-server``generate_characters / generate_landmarks` 动作:
1. `api-server` 根据当前 `draft_profile` 请求 LLM 生成新增实体。
2. `spacetime-module``generatedCharacters / generatedLandmarks` 写回 `draft_profile`
3. 结果页从服务端 `resultPreview.preview` 读取最新世界 profile。
## 问题
LLM 扩展提示词为了草稿卡片简洁,只要求返回角色的 `publicMask / hiddenHook / relationToPlayer / summary`,以及场景的 `purpose / mood / secret / summary / characterIds`
但结果页与运行时 `CustomWorldProfile` 读取的是当前完整字段:
- NPC`description / backstory / personality / motivation / relationshipHooks / tags / initialAffinity`
- 场景:`description / dangerLevel / sceneNpcIds / connections`
因此新增实体即使后端动作成功,也可能因为字段缺失或关联字段名不一致,在结果页表现为“生成后没有可用内容 / 场景没有 NPC 关联”。
此外Agent 结果页生成回调原本只返回 `void`:当 `activeAgentSessionId` 失效、服务端没有返回最新 `resultPreview`,或最新 profile 没有新增实体时,前端只会结束 pending 动画,表现为“点击后闪一下就消失”。
## 修复方案
本次修复保持“前端只表现,后端负责数据整理”的边界:
1.`api-server` 生成实体归一化阶段补齐结果页需要的最小完整字段。
2. NPC 将 `publicMask / summary` 映射为 `description``hiddenHook` 映射为 `backstory / motivation``relationToPlayer` 进入 `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`,不新增前端本地编译分支。
- 结果页点击新增实体后,如果服务端没有回传新增内容,必须展示错误提示。

View File

@@ -4,6 +4,7 @@
## 文档列表
- [CUSTOM_WORLD_RESULT_ENTITY_GENERATION_FIX_2026-04-24.md](./CUSTOM_WORLD_RESULT_ENTITY_GENERATION_FIX_2026-04-24.md):记录世界结果页在 Agent 草稿模式下新增场景、新增 NPC 生成成功但结果页字段不可用的根因,并冻结 `api-server` 生成归一化层补齐 profile 字段的修复口径。
- [ADMIN_CONSOLE_SERVICE_DESIGN_2026-04-23.md](./ADMIN_CONSOLE_SERVICE_DESIGN_2026-04-23.md):冻结 Rust `api-server` 内后台管理服务首版方案,明确管理员用户名密码登录、管理员 JWT 鉴权、数据库概览、受控 API 调试台与同源管理页面的落地边界。
- [SPACETIME_MODULE_LIB_RS_SPLIT_EXECUTION_2026-04-23.md](./SPACETIME_MODULE_LIB_RS_SPLIT_EXECUTION_2026-04-23.md):冻结 `server-rs/crates/spacetime-module/src/lib.rs` 的模块地图、二级落位点与迁移顺序,要求后续 SpacetimeDB 主工程改动按对应模块落位,不再继续堆回单大文件。
- [CUSTOM_WORLD_DRAFT_FOUNDATION_API_SERVER_LLM_MIGRATION_2026-04-23.md](./CUSTOM_WORLD_DRAFT_FOUNDATION_API_SERVER_LLM_MIGRATION_2026-04-23.md):冻结 `draft_foundation` 从 SpacetimeDB 内部规则编译迁到 `api-server + platform-llm` 的边界,明确草稿必须由 `api-server` 真实调 LLM 生成SpacetimeDB 只负责落库。

View File

@@ -0,0 +1,55 @@
# RPG 创作结果页编辑功能迁移审计
日期:`2026-04-24`
## 本次发现
`generate_characters` / `generate_landmarks` 后端已经迁到 Rust但前端 Agent 结果页看不到入口,原因不是后端能力缺失,而是:
1. `RpgCreationResultViewImpl``compactAgentResultMode=true` 时隐藏 `createActionLabel / onCreateAction`
2. `PlatformEntryFlowShellImpl` 对 Agent 草稿结果页传入了 `compactAgentResultMode={isAgentDraftResultView}`
3. 结果页原有“新增可扮演角色 / 新增场景角色 / 新增场景”仍走 legacy `rpgCreationAssetClient`,只改前端内存态,不会触发 Agent action。
## 本次前端修复
已改为:
```text
Agent 结果页点击新增场景角色 / 新增场景
-> RpgCreationResultView.onGenerateEntity
-> autosaveCoordinator.executeAgentActionAndWait
-> POST /api/runtime/custom-world/agent/sessions/:sessionId/actions
-> generate_characters / generate_landmarks
-> 等 operation completed
-> 拉最新 session
-> rpgCreationPreviewAdapter.buildPreviewFromSession
-> 刷新结果页 profile
```
说明:当前可扮演角色 tab 的“新增可扮演角色”也会调用 `generate_characters`,后端现阶段会追加到 `storyNpcs`。因此严格意义上的“新增可扮演角色”仍未完整迁移,需要后续给 action 增加角色类型参数或新增 `generate_playable_characters`
## 已迁移 / 可见
1. 删除作品:已有 Rust + SpacetimeDB 软删除链路。
2. 新增场景角色:结果页可见,调用 Rust `generate_characters`
3. 新增场景 / 地点:结果页可见,调用 Rust `generate_landmarks`
4. Agent 结果页发布进入世界:已有 `publish_world` + publish gate 链路。
5. 手动编辑结果页 profile目前仍通过 `sync_result_profile` 自动保存回 Agent session。
## 尚未完整迁移的结果页编辑功能
1. 新增可扮演角色:前端有入口,但 Rust action 暂无角色类型区分,当前会落到 `storyNpcs`
2. 批量删除场景角色:前端只改本地 profile再靠 `sync_result_profile` 同步,不是独立 Rust action。
3. 批量删除场景:前端只改本地 profile再靠 `sync_result_profile` 同步,不是独立 Rust action。
4. 单个角色 / 场景的细粒度编辑:前端 modal 仍编辑本地 profile再靠 `sync_result_profile` 同步SpacetimeDB 虽有 `update_draft_card`,但结果页表单尚未按 card section action 化。
5. 角色资产生成:`generate_role_assets / sync_role_assets` Rust 侧仍是 placeholder 或外部链路未完全接入结果页。
6. 场景资产生成:`generate_scene_assets / sync_scene_assets` Rust 侧仍是 placeholder 或外部链路未完全接入结果页。
7. 长尾补全:`expand_long_tail` Rust 侧仍是 placeholder。
8. 回滚 checkpointRust 有 `revert_checkpoint`,但结果页没有清晰可见入口。
## 下一步建议
1.`generate_characters` 增加 `roleType: playable|story` 契约,并让可扮演角色 tab 真正落到 `playableNpcs`
2. 将删除角色 / 删除场景改为独立 action避免继续依赖整份 profile 同步。
3. 将角色 / 场景编辑 modal 的保存改为 `update_draft_card` 或更细粒度 reducer而不是每次整份 profile 覆盖。
4. 继续迁移 `generate_role_assets / generate_scene_assets / expand_long_tail`,并在结果页显示对应入口。

View File

@@ -50,9 +50,10 @@ src/services/creation-agent/
聊天页展示规则:
1. Agent 聊天页不展示锚点内容卡片,锚点只作为进度与后端生成依据。
2. 生成草稿 / 生成结果页主按钮只在 `progressPercent` 归一化后达到 `100%` 时显示
3. 进度条下方承载“总结当前设定”“补全剩余设定”等进度操作按钮
4. “补全剩余设定”必须配置 `minTurn: 2`,对话不足两轮时不显示
2. 标题区文案支持按品类留空;当 `title``assistantSummary` 都为空时,顶部模块只保留返回、进度和操作按钮,不显示额外标题与副文案
3. 生成草稿 / 生成结果页主按钮只在 `progressPercent` 归一化后达到 `100%` 时显示
4. 进度条下方承载“总结当前设定”“补全剩余设定”等进度操作按钮
5. “补全剩余设定”必须配置 `minTurn: 2`,对话不足两轮时不显示。
组件内部只做表现,不读取任何 RPG、Big Fish、Puzzle 专属字段。