Refactor server-rs runtime and update related docs

This commit is contained in:
2026-04-25 14:29:44 +08:00
parent 019dd9efba
commit 6be3afe45a
56 changed files with 1561 additions and 1158 deletions

View File

@@ -325,7 +325,6 @@
例如:
- `initialAffinity`
- `dangerLevel`
- 精确数值型 build 倾向
- 复杂掉落预算

View File

@@ -596,7 +596,6 @@ chapterXpBudget =
1. `SceneChapterBlueprint.acts` 数量
2. 当前章节 hostile NPC 数量
3. 当前章节任务 step 中战斗目标占比
4. `dangerLevel`
5. linked thread 是否为主线高压线程
## 6.4 实际速度评估规则

View File

@@ -307,7 +307,6 @@
1. `name`
2. `description`
3. `dangerLevel`
## 7.4 第四阶段不允许编辑的内容
@@ -425,7 +424,6 @@
1. `id`
2. `name`
3. `description``summary`
4. `dangerLevel`
5. `purpose`
6. `mood`

View File

@@ -505,7 +505,6 @@ draftProfile.landmarks.find(...)
kind: 'camp' | 'landmark';
name: string;
description: string;
dangerLevel?: string;
imageSrc?: string;
};
onPublishSuccess: (payload) => void;

View File

@@ -213,7 +213,6 @@
1. 开局场景允许配置的字段必须与普通场景一致,至少包括:
- `name`
- `description`
- `dangerLevel`
- `imageSrc`
- `sceneNpcIds`
- `connections`

View File

@@ -55,7 +55,7 @@ name, role, publicMask, hiddenHook, relationToPlayer, summary, threadIds
新增场景保留旧 Node 的 system prompt 与 user prompt 字段约束:
```text
name, purpose, mood, dangerLevel, secret, summary, threadIds, characterIds
name, purpose, mood, secret, summary, threadIds, characterIds
```
Rust 侧只做最小归一化:补 `id`、去除重名、限制数量 `1..=3`,不改写提示词原文语义。

View File

@@ -60,6 +60,6 @@
- 某一幕连续重试仍失败时,只允许在该幕写入 `backgroundGenerationError` 作为诊断字段;只要至少一幕成功,草稿仍应完成并让前端展示成功图片。
- 只有全部幕背景均失败时,才把“生成幕背景图失败”作为草稿素材阶段失败原因保存。
- Rust 服务实际生图模型读取 `DASHSCOPE_SCENE_IMAGE_MODEL` / `DASHSCOPE_COVER_IMAGE_MODEL` / `DASHSCOPE_REFERENCE_IMAGE_MODEL`;兼容旧 `DASHSCOPE_IMAGE_MODEL`,避免 `.env.example` 中配置了模型但服务端仍使用硬编码模型。
- 自动草稿幕背景不能把 `backgroundPromptText` 直接作为最终 `prompt` 传给 DashScope它必须像草稿页手动生成一样把幕级描述作为 `userPrompt`,并用同一个地点对象的 `name/description/dangerLevel` 作为场景上下文,再由 `build_custom_world_scene_image_prompt` 统一拼入世界名、世界摘要、风格、玩家目标、场景名、场景描述和负面词。用户不修改默认描述直接点生成时,手动生成与自动草稿生成的正式生图上下文必须一致。
- 自动草稿幕背景不能把 `backgroundPromptText` 直接作为最终 `prompt` 传给 DashScope它必须像草稿页手动生成一样把幕级描述作为 `userPrompt`,并用同一个地点对象的 `name/description` 作为场景上下文,再由 `build_custom_world_scene_image_prompt` 统一拼入世界名、世界摘要、风格、玩家目标、场景名、场景描述和负面词。用户不修改默认描述直接点生成时,手动生成与自动草稿生成的正式生图上下文必须一致。
- 自动草稿幕背景的默认尺寸必须与草稿页手动生成默认尺寸一致,当前统一为 `1280*720`;不能在自动链路中单独改成 `1600*900`,否则同一 prompt 在同一模型下也可能因供应商尺寸支持或耗时不同而表现不一致。
- 批量自动生图失败日志必须保留 `AppError.details.message` 中的供应商真实原因,不能只记录 `AppError.message()` 的 HTTP 泛化文案,否则排查时只能看到“上游服务请求失败”,无法确认是尺寸、模型、限流、超时还是内容审核失败。

View File

@@ -15,7 +15,7 @@ LLM 扩展提示词为了草稿卡片简洁,只要求返回角色的 `publicMa
但结果页与运行时 `CustomWorldProfile` 读取的是当前完整字段:
- NPC`description / backstory / personality / motivation / relationshipHooks / tags / initialAffinity`
- 场景:`description / dangerLevel / sceneNpcIds / connections`
- 场景:`description / sceneNpcIds / connections`
因此新增实体即使后端动作成功,也可能因为字段缺失或关联字段名不一致,在结果页表现为“生成后没有可用内容 / 场景没有 NPC 关联”。

View File

@@ -0,0 +1,27 @@
# 自定义世界场景 dangerLevel 字段移除落地说明2026-04-25
## 背景
自定义世界场景对象过去在开局归处、地标、草稿实体和生图上下文中携带 `dangerLevel`。该字段会让场景结构额外承载“危险等级”枚举,并在提示词中要求模型生成固定的 `low|medium|high|extreme` 值。当前场景设计更依赖 `description``visualDescription`、幕级事件和任务描述表达氛围,不再需要独立危险等级字段。
## 落地范围
- 场景数据结构删除 `dangerLevel`,包括开局归处、地标、共享草稿协议与前端表单映射。
- 自定义世界生成、修复和补全提示词不再要求模型输出 `dangerLevel`
- 场景生图上下文只使用世界名、世界摘要、整体基调、玩家目标、场景名、场景描述和用户画面描述,不再拼接危险等级氛围。
- Rust API 与 SpacetimeDB 模块展示卡片不再从 `dangerLevel` 读取副标题或场景上下文。
- 测试夹具移除 `dangerLevel` 输入,避免新测试继续固化该字段。
## 兼容策略
- 旧存档或旧 LLM 返回中若仍包含 `dangerLevel`,前端和 Rust 归一化流程不再读取或回写该字段。
- 不新增替代字段;需要表达危险、压迫或安全感时,写入 `description``visualDescription``mood``sceneTaskDescription` 或幕级描述。
- `server-node` 旧实现不作为兼容目标,本次仅清理当前前端、共享协议与 `server-rs` 链路。
## 编码落点
- `src/types/customWorld.ts`:删除场景类型上的 `dangerLevel`
- `src/prompts/customWorldPrompts.ts``server-rs/crates/api-server/src/prompt/foundation_draft.rs`:删除所有生成/修复 `dangerLevel` 的模板与约束。
- `src/services/customWorld.ts``src/services/customWorldCamp.ts``src/services/customWorldBuilder.ts`:删除归一化和 fallback 写入。
- `src/data/customWorldLibrary.ts``src/data/customWorldSceneGraph.ts``src/data/customWorldVisuals.ts`:删除持久化、场景图谱和视觉上下文映射。
- `server-rs/crates/api-server``server-rs/crates/spacetime-module`:删除 Rust 侧默认 JSON、提示词、实体卡片副标题和场景上下文读取。

View File

@@ -0,0 +1,49 @@
# NPC 相遇先手发言与 Runtime 聊天路由修复
## 背景
进入游戏与 NPC 相遇后,前端会调用 `POST /api/runtime/chat/npc/turn/stream` 生成 NPC 主动开场或聊天回合。Rust API 尚未承接旧 Node 的该路由时,接口返回 404前端解析为“资源不存在”导致
1. NPC 主动开场失败,对话框中没有先发言。
2. 点击聊天选项继续对话时同样报“资源不存在”。
3. 场景中和平相遇 NPC 的朝向与站位不稳定,不能稳定表现为与主角对望。
## 本轮落地规则
1. 前端只负责表现和触发,不在本地补 LLM 编排。
2. Rust API 必须至少提供契约兼容的后端 SSE 路由,避免回退到 server-node。
3. 任意好感度下,首次与一个 NPC 相遇都先进入 NPC 主动开场;后续再按敌对/普通分支处理。
4. 和平相遇态 NPC 固定使用已解析相遇锚点,与主角形成面对面的右侧对称表现,并强制朝向主角。
## 代码设计
### Rust Runtime Chat
新增 `server-rs/crates/api-server/src/runtime_chat.rs`
1. 注册 `POST /api/runtime/chat/npc/turn/stream`
2. 返回前端已支持的 SSE 事件:
- `reply_delta`:增量文本。
- `complete``npcReply / affinityDelta / affinityText / suggestions / pendingQuestOffer / chatDirective`
3. 当前先提供后端确定性兜底回复,保证 Rust API 迁移期间链路可用;后续完整 LLM 编排应继续在 Rust API 内实现,不回接 server-node。
### 前端交互
调整 `src/hooks/rpg-runtime-story/useRpgRuntimeNpcInteraction.ts`
1. 首次相遇判断提前到敌对短路之前。
2. `firstMeaningfulContactResolved` 为 false 时,无论好感度或敌对状态如何,都调用 `startNpcInitiatedOpening(...)`
调整 `src/components/game-canvas/GameCanvasEntityLayer.tsx`
1. 和平相遇 NPC 使用 `RESOLVED_ENTITY_X_METERS` 作为稳定右侧锚点。
2. 渲染朝向直接使用 `getFacingTowardPlayer(...)` 结果,避免通用 NPC 形象被二次反转。
## 后续迁移点
Rust 兜底路由只解决运行时断链。完整体验仍应继续迁移旧 Node 中 NPC 聊天编排能力,包括:
1. 基于上下文的 LLM 回复。
2. 聊天建议生成。
3. 待接委托 `pendingQuestOffer` 的服务端判定与生成。
4. 限轮与强制退出指令的完整结算。

View File

@@ -0,0 +1,32 @@
# Rust 生成链路 Prompt 脚本迁移设计2026-04-25
## 1. 目标
`server-rs` 中四条现役生成链路的提示词从业务流程文件中抽离到独立 `prompt` 目录,后续迭代只修改 prompt 脚本,不在路由、任务、资产持久化代码中直接堆提示词。
## 2. 目录约定
新增目录:`server-rs/crates/api-server/src/prompt/`
模块划分:
1. `scene_background.rs`:场景背景图与幕背景图提示词。
2. `character_visual.rs`:角色主形象提示词与负向提示词。
3. `character_animation.rs`:角色动作、序列帧、图生视频、动作迁移提示词。
4. `foundation_draft.rs`:草稿生成各阶段 JSON 系统提示词、修复提示词、框架/角色/场景/档案分阶段 user prompt。
5. `mod.rs`:统一导出子模块。
## 3. 迁移边界
1. 只迁移 prompt 构造与 prompt 常量,不迁移 DashScope、OSS、SpacetimeDB、任务状态、并发控制和持久化逻辑。
2. `custom_world.rs` 只保留场景幕引用收集、校验和调用生成服务,不再承载幕背景图提示词正文。
3. `custom_world_ai.rs` 只保留图片生成、下载、入库、接口 payload 归一化;场景图 prompt builder 迁入 `prompt::scene_background`
4. `custom_world_asset_prompts.rs` 作为兼容转发层保留,避免一次性改动角色资产调用点过大;真实提示词脚本迁入 `prompt::character_visual``prompt::character_animation`
5. `custom_world_foundation_draft.rs` 只保留分阶段编排、JSON 解析、归一化和写回;所有阶段 prompt builder 迁入 `prompt::foundation_draft`
## 4. 验收标准
1. `cargo fmt -p api-server` 通过。
2. `cargo check -p api-server` 通过。
3. 四条链路仍能从原调用点拿到相同语义的提示词。
4. 文档明确后续 prompt 修改主源在 `src/prompt/`