1
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
# server-node 冻结隔离说明(2026-04-24)
|
||||
|
||||
## 1. 当前状态
|
||||
|
||||
`server-node/` 已进入冻结隔离状态,不再作为可运行、可扩展、可引用的后端工程使用。
|
||||
|
||||
冻结原因:项目后端主线已经切到 `server-rs/` 的 Rust + SpacetimeDB 多 crate 方案,继续保留可执行的 `server-node/` 入口会误导后续开发,并增加提示词资产、AI 工作流与运行态逻辑的迁移漂移风险。
|
||||
|
||||
## 2. 冻结边界
|
||||
|
||||
1. 禁止新增任何以 `server-node/` 为目标的运行脚本、开发入口、CI 入口或工程依赖。
|
||||
2. 禁止新增从前端、Rust 后端、脚本或配置主动调用 `server-node/` 的逻辑。
|
||||
3. 禁止在 `server-node/` 内继续新增业务能力;后续能力必须落到 `server-rs/` 对应 crate。
|
||||
4. 历史文档、审计文档、迁移基线中允许保留 `server-node/` 作为旧系统来源说明,但不得把它描述成当前推荐实现。
|
||||
5. 删除 `server-node/` 前,必须先完成提示词资产与提示词相关工作流的最终迁移确认。
|
||||
|
||||
## 3. 删除前阻断项
|
||||
|
||||
以下资产仍需要在删除目录前逐项确认迁移或废弃:
|
||||
|
||||
1. `server-node/src/prompts/customWorldEntityPrompts.ts`:自定义世界实体生成 prompt。
|
||||
2. `server-node/src/prompts/customWorldSceneNpcPrompts.ts`:自定义世界场景 NPC prompt。
|
||||
3. `server-node/src/prompts/questPrompts.ts`:任务意图识别 prompt。
|
||||
4. `server-node/src/prompts/runtimeItemPrompts.ts`:运行时物品意图识别 prompt。
|
||||
5. `server-node/src/prompts/customWorldOrchestratorPrompts.ts`:旧 Custom World JSON 生成与修复 prompt。
|
||||
6. `src/services/ai.ts` 与 `src/prompts/customWorldPrompts.ts` 中仍由前端承载的 AI orchestration / prompt 编排。
|
||||
|
||||
## 4. 工程防线
|
||||
|
||||
1. 根目录 `package.json` 中的 `server-node:*` 脚本统一改为冻结失败入口。
|
||||
2. 新增 `npm run check:server-node-freeze`,用于阻止新增 `server-node` 引用。
|
||||
3. 新增 `scripts/server-node-frozen.mjs`,任何旧 `server-node:*` 入口被误执行时都会直接失败并提示迁移到 `server-rs/`。
|
||||
4. 新增 `scripts/server-node-freeze-baseline.json`,只允许冻结前已经存在的引用继续作为迁移基线存在。
|
||||
|
||||
## 5. 后续处理顺序
|
||||
|
||||
1. 优先迁移或废弃提示词资产与 prompt 工作流。
|
||||
2. 确认前端不再通过任何路径调用 Node 后端能力。
|
||||
3. 删除旧脚本、旧 smoke、旧 manifest 与 `server-node/` 目录。
|
||||
4. 删除冻结基线检查中对历史引用的豁免。
|
||||
@@ -0,0 +1,35 @@
|
||||
# 平台首页响应式布局优化设计
|
||||
|
||||
更新时间:`2026-04-24`
|
||||
|
||||
## 1. 问题结论
|
||||
|
||||
当前平台首页桌面端视觉方向成立,但移动端存在明显横向溢出:Hero 右侧按钮、底部导航末项和部分卡片会被裁切。问题根因不是数据逻辑,而是桌面式固定宽度、外层 padding 与若干卡片最小宽度在窄屏下叠加,超过了 `100vw`。
|
||||
|
||||
## 2. 本次目标
|
||||
|
||||
- 移动端优先保证首页不横向滚动、不裁切底部导航。
|
||||
- Hero 在手机宽度下改为紧凑单列,标题、按钮和标签都完整显示。
|
||||
- 桌面端降低外框视觉噪声,让主内容和 CTA 更清晰。
|
||||
- 空状态区域收敛高度,避免首屏出现大面积空白。
|
||||
|
||||
## 3. 编码落点
|
||||
|
||||
- `src/components/rpg-runtime-shell/RpgRuntimeStageRouter.tsx`
|
||||
- 平台壳移动端使用更小边距,避免根容器加宽。
|
||||
- `src/components/rpg-entry/RpgEntryHomeView.tsx`
|
||||
- 移动端根节点显式 `min-w-0` 与 `overflow-hidden`。
|
||||
- 底部导航外层不再额外制造宽度。
|
||||
- Hero/内容卡片补充 `min-w-0`,窄屏内按容器收缩。
|
||||
- `src/index.css`
|
||||
- 全局与平台壳禁止横向溢出。
|
||||
- 移动端压缩底部导航间距、字号和图标壳尺寸。
|
||||
- 移动端收敛 `platform-page-stage` 圆角与边框层级。
|
||||
- 桌面端保留卡片质感,但弱化多层外框阴影。
|
||||
|
||||
## 4. 验收标准
|
||||
|
||||
- `390px` 宽度截图中,首页内容、Hero 按钮和底部四个导航项完整可见。
|
||||
- 桌面端首页仍保持顶部栏、侧边导航、主推荐区和右侧趋势区结构。
|
||||
- 页面不新增功能说明类 UI 文案。
|
||||
- 修改中文文件后通过编码检查。
|
||||
@@ -1,4 +1,4 @@
|
||||
# UI 改动记录(供后续 Agent 阅读)
|
||||
# UI 改动记录(供后续 Agent 阅读)
|
||||
|
||||
本文档汇总 **像素 RPG UI 皮肤化** 相关实现与决策,便于新会话快速接手。更细的命名与规范见同目录上一级的 **`UI_CODING_STANDARD.md`**。
|
||||
|
||||
@@ -172,4 +172,31 @@
|
||||
|
||||
---
|
||||
|
||||
## 14. 2026-04-24 Agent 工作区恢复指针按用户隔离
|
||||
|
||||
- `custom-world agent session` 现在由 `server-rs` Axum 路由接入 SpacetimeDB procedure,模块内按 `owner_user_id + session_id` 查询;前端恢复旧工作区前必须确认本地指针属于当前登录用户,否则旧账号残留会先请求一次 `/api/runtime/custom-world/agent/sessions/:sessionId` 并产生 404。
|
||||
- `src/services/customWorldAgentUiState.ts` 的 URL 仍只保留 `customWorldSessionId` / `customWorldOperationId`,用户归属只写入 `sessionStorage`,避免把 `userId` 暴露到可分享链接里。
|
||||
- `src/components/rpg-entry/useRpgCreationSessionController.ts` 在恢复初始工作区时会对比 `ownerUserId`,发现不是当前用户就清空恢复指针并停留在创作入口,不再打后端失效 session。
|
||||
- 后续新增 Agent 类恢复入口时,同样要区分“可分享的 URL 指针”和“仅本机使用的登录用户归属”,不要只凭 sessionId 自动恢复受保护资源。
|
||||
|
||||
---
|
||||
|
||||
## 15. 2026-04-24 多玩法 Agent 聊天顶部文案统一隐藏
|
||||
|
||||
- `CreationAgentWorkspace` 已支持在 `title` 与 `assistantSummary` 为空时只展示返回、主操作、进度与锚点区域;各玩法适配层不要再传入“世界共创 / 玩法共创”这类模块标题或引导副文案。
|
||||
- `custom-world`、`big-fish`、`puzzle` 三条 Agent 聊天工作区现在统一隐藏顶部标题与标题下方说明,避免只有 RPG / 自定义世界生效、其他玩法模板仍残留旧文案。
|
||||
- 后续新增玩法模板时,聊天页顶部模块应保持清爽:必要状态放进进度、操作横幅或聊天消息,不把功能说明类文案默认写入 UI。
|
||||
|
||||
---
|
||||
|
||||
## 16. 2026-04-24 创作结果页亮色主题细节补色
|
||||
|
||||
- RPG / 拼图 / 大鱼结果页根容器统一挂 `platform-remap-surface`,让亮色主题能接管遗留的 `text-white`、`text-zinc-*`、`bg-white/*`、`bg-black/*` 和状态色工具类。
|
||||
- 拼图与大鱼结果页顶部 Hero 只增加 `platform-result-hero` 语义类,不改变整体布局;亮色主题下由 `src/index.css` 统一换成暖白底、轻粉高光和平台主按钮色。
|
||||
- 地图弹窗新增 `map-modal-overlay`、`map-modal-shell`、`map-modal-backdrop`、`map-modal-shade`、`map-info-panel` 语义类;亮色主题通过这些类降低暗色遮罩、提亮地图背景、统一节点卡与连线颜色。
|
||||
- 结果页中保存、生成、发布等旧的 `bg-amber-600` / `bg-cyan-600` / `bg-cyan-200` 按钮,在 `platform-remap-surface` 内被映射回 `platform-button--primary` 同款渐变,避免亮色主题下按钮体系割裂。
|
||||
- 后续继续做结果页 UI 细节时,优先补语义 class + `src/index.css` 的 light remap,不要在每个结果页组件里复制一套亮色配色,也不要调整页面整体布局结构。
|
||||
|
||||
---
|
||||
|
||||
_文档目的:交接给下一个 Agent 时,优先读本文件 + `UI_CODING_STANDARD.md`,再改 `uiAssets.ts` / `App.tsx` / `index.css`。_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 迁入配置;首版不做过度抽象。
|
||||
@@ -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 风格。
|
||||
|
||||
@@ -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。
|
||||
@@ -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`。
|
||||
@@ -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`,不新增前端本地编译分支。
|
||||
- 结果页点击新增实体后,如果服务端没有回传新增内容,必须展示错误提示。
|
||||
@@ -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 只负责落库。
|
||||
|
||||
@@ -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. 回滚 checkpoint:Rust 有 `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`,并在结果页显示对应入口。
|
||||
@@ -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 专属字段。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user