重构策划agent,接入新工作流+harness #322

Merged
lhk229 merged 46 commits from design_agent_refactor into master 2026-09-12 16:10:08 +08:00
Owner
No description provided.
lhk229 added 1 commit 2026-09-10 17:01:36 +08:00
接入策划 Agent 生产迁移初版
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
aaa52c2b34
新增独立设计会话、工作区工具和随包资源
platform-llm 支持 Responses 原生 input 续轮
无旧 V2 会话的策划入口切换到新设计 Agent
增加阶段审批、澄清卡和工作区文件浏览
同步迁移方案与决策记录
lhk229 added 1 commit 2026-09-10 17:14:23 +08:00
对齐策划入口测试到新设计 Agent
Project CI / Repository checks (pull_request) Failing after 6m22s
Project CI / Frontend tests (pull_request) Failing after 6m48s
Project CI / Native shell tests (pull_request) Failing after 9m54s
Project CI / Backend tests (pull_request) Failing after 16m19s
cb79c4a9c6
新建策划入口走设计会话命令,已有 V2 会话仍走原链路
补审批与澄清卡界面用例
lhk229 added 1 commit 2026-09-10 17:57:49 +08:00
接入策划 Agent 脚本化假 Provider 定向测试
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
af96174e07
拦截测试态 Provider 请求,按队列返回脚本响应或错误
覆盖五阶段推进、审批拒绝不唤醒、重启恢复、资源与工具失败及瞬态重试
同步迁移方案第 8 步验证口径
lhk229 added 1 commit 2026-09-10 18:30:54 +08:00
拆分策划 Agent 与 Codex 随包清单
Project CI / Repository checks (pull_request) Failing after 53s
Project CI / Frontend tests (pull_request) Failing after 2m17s
Project CI / Backend tests (pull_request) Failing after 3m39s
Project CI / Native shell tests (pull_request) Failing after 3m54s
18ed9778d8
将 design-agent 资源包放到全平台 Tauri 基础配置
Windows 配置只保留 pinned Codex sidecar
配置门禁分别校验两份清单,禁止互相混入
lhk229 added 1 commit 2026-09-10 19:00:36 +08:00
补齐 LlmRunRequest 字面量的 responses_input 字段
Project CI / Repository checks (pull_request) Failing after 1m18s
Project CI / Frontend tests (pull_request) Failing after 2m15s
Project CI / Native shell tests (pull_request) Failing after 4m59s
Project CI / Backend tests (pull_request) Successful in 6m10s
a38eec743a
api-server LLM 代理与 platform-agent 适配器补 None
避免 cargo run api-server 因缺字段编不过
lhk229 added 2 commits 2026-09-10 19:23:00 +08:00
按 rustfmt 整理策划 Runtime 与相关测试字面量
首页做方案用例改为断言设计 Agent 命令
合并最新 master
Project CI / Frontend tests (pull_request) Successful in 3m23s
Project CI / Backend tests (pull_request) Successful in 5m41s
Project CI / Native shell tests (pull_request) Failing after 15m24s
Project CI / Repository checks (pull_request) Has been cancelled
36dc93222a
lhk229 added 1 commit 2026-09-10 19:43:01 +08:00
修复策划样式插入导致 Tailwind 解析失败
Project CI / Frontend tests (pull_request) Successful in 3m22s
Project CI / Backend tests (pull_request) Successful in 6m2s
Project CI / Repository checks (pull_request) Failing after 2m34s
Project CI / Native shell tests (pull_request) Successful in 17m37s
5d24301ef5
把阶段进度 span 颜色补回原规则
删除 design-agent 预览后的孤儿声明
lhk229 added 1 commit 2026-09-10 19:49:54 +08:00
清理策划文档空白以通过仓库检查
Project CI / Repository checks (pull_request) Successful in 2m52s
Project CI / Frontend tests (pull_request) Successful in 3m17s
Project CI / Backend tests (pull_request) Successful in 5m39s
Project CI / Native shell tests (pull_request) Successful in 18m32s
bb010b4b1e
去掉 system-prompt 文件末多余空行
去掉迁移方案标题下的行尾空格
lhk229 added 1 commit 2026-09-10 23:50:50 +08:00
Merge branch 'master' into design_agent_refactor
Project CI / Repository checks (pull_request) Successful in 3m43s
Project CI / Frontend tests (pull_request) Successful in 4m37s
Project CI / Backend tests (pull_request) Successful in 7m30s
Project CI / Native shell tests (pull_request) Successful in 18m45s
782fa77950
lhk229 added 2 commits 2026-09-11 10:55:49 +08:00
completed 未带 output 时保留 output_item 与工具参数
补空 completed 与顶层 output 的回放测试并记录排障
Merge remote-tracking branch 'web/design_agent_refactor' into design_agent_refactor
Project CI / Repository checks (pull_request) Successful in 3m8s
Project CI / Frontend tests (pull_request) Successful in 4m3s
Project CI / Backend tests (pull_request) Successful in 6m54s
Project CI / Native shell tests (pull_request) Successful in 18m8s
7484764024
lhk229 added 1 commit 2026-09-11 11:36:09 +08:00
重构策划 Agent 工作台界面
Project CI / Frontend tests (pull_request) Failing after 3m19s
Project CI / Repository checks (pull_request) Failing after 3m25s
Project CI / Native shell tests (pull_request) Failing after 6m54s
Project CI / Backend tests (pull_request) Successful in 7m20s
9345236b93
新增始终可见的策划工作区与文件预览

复用 GameAgent 双栏布局并调整审批澄清交互

审批按钮改为文字与图标并保留现有 Runtime 行为
lhk229 added 1 commit 2026-09-11 11:52:42 +08:00
修复策划工作台输入框布局
Project CI / Frontend tests (pull_request) Failing after 2m16s
Project CI / Repository checks (pull_request) Failing after 2m27s
Project CI / Backend tests (pull_request) Successful in 6m58s
Project CI / Native shell tests (pull_request) Failing after 4m45s
fd09f61473
让策划聊天消息区只占用剩余空间

确保输入框在工作台底部持续可见
lhk229 added 1 commit 2026-09-11 12:04:13 +08:00
修复策划审批按钮的界面测试回归
Project CI / Repository checks (pull_request) Successful in 3m5s
Project CI / Frontend tests (pull_request) Successful in 3m54s
Project CI / Backend tests (pull_request) Successful in 6m38s
Project CI / Native shell tests (pull_request) Successful in 17m51s
87711e4034
补齐批准和继续修改按钮的无障碍名称

同步审批按钮文档并通过 389 个界面用例
lhk229 added 1 commit 2026-09-11 13:17:29 +08:00
修复策划工作区文件树显示
Project CI / Repository checks (pull_request) Successful in 2m44s
Project CI / Frontend tests (pull_request) Successful in 3m32s
Project CI / Backend tests (pull_request) Successful in 6m21s
Project CI / Native shell tests (pull_request) Successful in 18m20s
26169102a0
改用可展开的层级目录树显示文件

保留相对路径读取并修复目录内产物不可见问题
lhk229 added 1 commit 2026-09-11 13:28:54 +08:00
优化策划工作区后台刷新体验
Project CI / Repository checks (pull_request) Successful in 2m36s
Project CI / Frontend tests (pull_request) Successful in 3m27s
Project CI / Native shell tests (pull_request) Successful in 20m41s
Project CI / Backend tests (pull_request) Successful in 22m53s
8444dee9e9
合并 Agent 工具事件并避免刷新时清空文件树

仅首次打开和手动刷新显示加载状态
lhk229 marked the pull request as work in progress 2026-09-11 14:46:31 +08:00
lhk229 added 2 commits 2026-09-11 14:52:51 +08:00
保存策划会话的模型目录 ID并交由 api-server 解析

移除官方直连路径的固定模型并补齐 AGC 客户端标记
修复策划澄清卡自由文本回答
Project CI / Repository checks (pull_request) Successful in 5m25s
Project CI / Frontend tests (pull_request) Successful in 6m36s
Project CI / Backend tests (pull_request) Successful in 29m4s
Project CI / Native shell tests (pull_request) Successful in 33m51s
123c699db9
将自由文本与选项回答分开提交

补充澄清卡回归测试和迁移方案说明
lhk229 added 1 commit 2026-09-11 15:37:26 +08:00
调整策划项目命名
Project CI / Repository checks (pull_request) Failing after 2m57s
Project CI / Frontend tests (pull_request) Failing after 7m44s
Project CI / Backend tests (pull_request) Successful in 8m6s
Project CI / Native shell tests (pull_request) Failing after 4m31s
e6e2a5fda6
策划入口使用带随机短码的策划项目名称

保留游戏与素材入口的现有命名链路

补充自动建项测试与技术方案说明
lhk229 added 1 commit 2026-09-11 17:13:51 +08:00
修复策划项目命名相关 CI 检查
Project CI / Repository checks (pull_request) Successful in 2m47s
Project CI / Frontend tests (pull_request) Successful in 3m25s
Project CI / Backend tests (pull_request) Successful in 6m55s
Project CI / Native shell tests (pull_request) Successful in 20m14s
d6a72c895c
同步首页项目创建测试中的 planning 参数断言
格式化项目 Rust 测试文件以通过 rustfmt
lhk229 reviewed 2026-09-11 17:35:01 +08:00
lhk229 left a comment
Author
Owner

代码审查(branch design_agent_refactor vs master

本 PR 用策划 Agent 运行时替换 Planning V2:阶段工作流、工作区工具、Responses 原生 output[] history replay,并抽出项目写锁分类和官方路由 AGC 模型选择。核心循环、崩溃/不确定工具恢复、工作区路径隔离、platform-llm 回放整体连贯,测试覆盖也不差。

合并前建议先修 4 个 bug:前端 retry / 阶段审批的 turn-id 与流式清理、write_file 静默空覆盖、顾问阶段工作区导轨错位。其余为建议项。

统计:4 bug / 5 suggestion / 1 nit。下面按严重程度列,行内评论已挂到对应 diff。

Bug

  1. Retry 流式丢失App.tsx):前端 retry 换了新 clientTurnId,后端 DesignInput::Retrybegin_design_turn,事件仍带原 session.turn.id,被前端丢掉,崩溃恢复/last-error 重试看不到 token 流和工具进度。
  2. 阶段审批不清理 transientApp.tsx):decide_design_phase 绕过 executeDesignAgentTurnfinally 不清 planningV2TransientReply,批准后会在已持久化消息下残留重复气泡。
  3. write_file 静默空覆盖design_tools.rs):content 缺失或非字符串时 unwrap_or_default() 写空文件却返回「已写入」。
  4. 顾问阶段导轨回落到概念设计DesignWorkspacePanel.tsx):PHASES 只有五段创作阶段,consultantfindIndex 为 -1,rail 把概念设计标成当前。

Suggestion

  1. common-tail.md 要求 submit_phase_for_approval,顾问阶段又追加 consultant-tail.md 说不要提交,运行时也会拒绝,两段 tail 在 live system prompt 里互相打架。
  2. design_debug 默认开启,把完整 history(含用户文本和 encrypted reasoning)写进 {project}/.debug/design-agent/
  3. ask_clarification 文档写 2–4 个选项,执行器接受任意长度(含 0)。
  4. platform-llmoutput_item.added.done 共用路径后,非 function_calloutput_index 会打挂整条流,影响非策划 Agent 的 Responses 调用方。
  5. 若干新注释在复述改动历史 / Issue #318,而不是短 invariant。

Nit

  1. ensure_design_session 未使用且硬编码 model "quality",与 selected_model_id 不一致。

核心 runtime / 回放 / 写锁分类可以合;前端 turn 身份、审批流、以及 write_file 契约建议修完再合。

## 代码审查(branch `design_agent_refactor` vs `master`) 本 PR 用策划 Agent 运行时替换 Planning V2:阶段工作流、工作区工具、Responses 原生 `output[]` history replay,并抽出项目写锁分类和官方路由 AGC 模型选择。核心循环、崩溃/不确定工具恢复、工作区路径隔离、`platform-llm` 回放整体连贯,测试覆盖也不差。 **合并前建议先修 4 个 bug**:前端 retry / 阶段审批的 turn-id 与流式清理、`write_file` 静默空覆盖、顾问阶段工作区导轨错位。其余为建议项。 统计:4 bug / 5 suggestion / 1 nit。下面按严重程度列,行内评论已挂到对应 diff。 ### Bug 1. **Retry 流式丢失**(`App.tsx`):前端 retry 换了新 `clientTurnId`,后端 `DesignInput::Retry` 不 `begin_design_turn`,事件仍带原 `session.turn.id`,被前端丢掉,崩溃恢复/last-error 重试看不到 token 流和工具进度。 2. **阶段审批不清理 transient**(`App.tsx`):`decide_design_phase` 绕过 `executeDesignAgentTurn`,`finally` 不清 `planningV2TransientReply`,批准后会在已持久化消息下残留重复气泡。 3. **`write_file` 静默空覆盖**(`design_tools.rs`):`content` 缺失或非字符串时 `unwrap_or_default()` 写空文件却返回「已写入」。 4. **顾问阶段导轨回落到概念设计**(`DesignWorkspacePanel.tsx`):`PHASES` 只有五段创作阶段,`consultant` 的 `findIndex` 为 -1,rail 把概念设计标成当前。 ### Suggestion 5. `common-tail.md` 要求 `submit_phase_for_approval`,顾问阶段又追加 `consultant-tail.md` 说不要提交,运行时也会拒绝,两段 tail 在 live system prompt 里互相打架。 6. `design_debug` 默认开启,把完整 history(含用户文本和 encrypted reasoning)写进 `{project}/.debug/design-agent/`。 7. `ask_clarification` 文档写 2–4 个选项,执行器接受任意长度(含 0)。 8. `platform-llm` 把 `output_item.added` 与 `.done` 共用路径后,非 `function_call` 缺 `output_index` 会打挂整条流,影响非策划 Agent 的 Responses 调用方。 9. 若干新注释在复述改动历史 / Issue #318,而不是短 invariant。 ### Nit 10. `ensure_design_session` 未使用且硬编码 model `"quality"`,与 `selected_model_id` 不一致。 核心 runtime / 回放 / 写锁分类可以合;前端 turn 身份、审批流、以及 `write_file` 契约建议修完再合。
Author
Owner

[suggestion] design_debug 默认常开,把完整会话写进用户项目

每次 provider attempt 都会把完整 session.history(以及后续 raw responses_output)经后台线程 try_send{project}/.debug/design-agent/*.json。这是整段策划对话,含用户文本和 encrypted reasoning,背压只有 16 条 drop queue。

建议:用 debug flag / build profile 门控,写到 app 私有诊断目录(对齐 provider-reconciliation dump),并排除出项目分享/导出。

**[suggestion] `design_debug` 默认常开,把完整会话写进用户项目** 每次 provider attempt 都会把完整 `session.history`(以及后续 raw `responses_output`)经后台线程 `try_send` 到 `{project}/.debug/design-agent/*.json`。这是整段策划对话,含用户文本和 encrypted reasoning,背压只有 16 条 drop queue。 建议:用 debug flag / build profile 门控,写到 app 私有诊断目录(对齐 provider-reconciliation dump),并排除出项目分享/导出。
lhk229 marked this conversation as resolved
Author
Owner

[bug] write_file 对缺失/非字符串 content 静默空覆盖

contentValue::as_str().unwrap_or_default()。字段缺失或是 object/array/number 时会写成空文件,却返回「已写入 {path}」。已有工作区文档会被空字节覆盖,模型还以为成功。

建议:要求 content 必须是 JSON string;缺失或非字符串返回 Err。只有模型明确传 "" 时才允许截断。

**[bug] `write_file` 对缺失/非字符串 `content` 静默空覆盖** `content` 用 `Value::as_str().unwrap_or_default()`。字段缺失或是 object/array/number 时会写成空文件,却返回「已写入 {path}」。已有工作区文档会被空字节覆盖,模型还以为成功。 建议:要求 `content` 必须是 JSON string;缺失或非字符串返回 `Err`。只有模型明确传 `""` 时才允许截断。
Author
Owner

[suggestion] consultant 阶段 system prompt 自相矛盾

每个阶段(含 consultant)都会追加 common-tail.md,要求必须调用 submit_phase_for_approval。consultant 随后又追加 consultant-tail.md,说没有下一阶段、不要提交。运行时也会拒绝 consultant submit(design_session.rs)。两段 tail 同时出现在 live system prompt 里。

建议:current_phase == "consultant" 时跳过 common_tail(或其中的审批句)。

**[suggestion] consultant 阶段 system prompt 自相矛盾** 每个阶段(含 consultant)都会追加 `common-tail.md`,要求必须调用 `submit_phase_for_approval`。consultant 随后又追加 `consultant-tail.md`,说没有下一阶段、不要提交。运行时也会拒绝 consultant submit(`design_session.rs`)。两段 tail 同时出现在 live system prompt 里。 建议:`current_phase == "consultant"` 时跳过 `common_tail`(或其中的审批句)。
Author
Owner

[suggestion] ask_clarification 的 options 契约与 schema 不一致

tools.json 写 options 为 2–4 项,执行器却接受缺失/空/Vec 任意长度,并仍设置 pending_clarification。0 选项卡片只剩 textarea;1 或 10 选项原样展示。除了第一个 wait 之后跳过剩余工具,没有「每 turn 一次澄清」的硬校验。

建议:options 不在 2–4 就拒绝(或改 schema 允许纯自由文本)。空 options 若是有意的 fallback,描述里就不要写 2–4。

**[suggestion] `ask_clarification` 的 options 契约与 schema 不一致** `tools.json` 写 options 为 2–4 项,执行器却接受缺失/空/`Vec` 任意长度,并仍设置 `pending_clarification`。0 选项卡片只剩 textarea;1 或 10 选项原样展示。除了第一个 wait 之后跳过剩余工具,没有「每 turn 一次澄清」的硬校验。 建议:options 不在 2–4 就拒绝(或改 schema 允许纯自由文本)。空 options 若是有意的 fallback,描述里就不要写 2–4。
Author
Owner

[suggestion] consultant 阶段 system prompt 自相矛盾

这个根本无所谓

[suggestion] consultant 阶段 system prompt 自相矛盾 这个根本无所谓
lhk229 marked this conversation as resolved
Author
Owner

[suggestion] 新注释在复述改动史,而不是短 invariant

这几处(以及约 1503 行、write_lock.rs:443project_gates.rs:1825)引用 Issue #318、叙述「原本零等待」和为什么挪到 spawn_blocking。读的人需要的是类型/exhausted_projection API 看不出来的契约,而不是设计史。

建议:类型系统看不出的 WHY 留一行(例如 Windows ACCESS_DENIED vs Unix EACCES)。Issue 编号 /「原本零等待」叙述可以删。

**[suggestion] 新注释在复述改动史,而不是短 invariant** 这几处(以及约 1503 行、`write_lock.rs:443`、`project_gates.rs:1825`)引用 Issue #318、叙述「原本零等待」和为什么挪到 `spawn_blocking`。读的人需要的是类型/`exhausted_projection` API 看不出来的契约,而不是设计史。 建议:类型系统看不出的 WHY 留一行(例如 Windows `ACCESS_DENIED` vs Unix `EACCES`)。Issue 编号 /「原本零等待」叙述可以删。
lhk229 marked this conversation as resolved
Author
Owner

[nit] ensure_design_session 未使用,且硬编码 model "quality"

若以后有人从 command path 调用,会和 continue_design_agent_at 使用的 selected_model_id 不一致。

建议:删掉,或接收真实 model id 并接到 command 路径。

**[nit] `ensure_design_session` 未使用,且硬编码 model `"quality"`** 若以后有人从 command path 调用,会和 `continue_design_agent_at` 使用的 `selected_model_id` 不一致。 建议:删掉,或接收真实 model id 并接到 command 路径。
lhk229 marked this conversation as resolved
Author
Owner

[bug] Retry 会丢掉流式事件

这里用 designAgentTurnRef.current.clientTurnId 过滤 design-agent-update。Retry 会生成新的 clientTurnId 并写入 ref,但后端 DesignInput::Retry 不调用 begin_design_turn,事件继续带 session.turn.id(原 message id)。结果:崩溃恢复 / last-error 重试看不到 token 流和工具进度,直到 invoke 返回。

也不能直接复用原 id:design_command_replayed 会拒绝用 {type:"retry"} 对上已存的 {type:"message"}

建议:Retry 时先把 session.turn.id 更新成新 command id 再发事件,或事件一律带当前 command id。前端测试应覆盖 retry 事件能匹配 in-flight command。

**[bug] Retry 会丢掉流式事件** 这里用 `designAgentTurnRef.current.clientTurnId` 过滤 `design-agent-update`。Retry 会生成新的 `clientTurnId` 并写入 ref,但后端 `DesignInput::Retry` 不调用 `begin_design_turn`,事件继续带 `session.turn.id`(原 message id)。结果:崩溃恢复 / last-error 重试看不到 token 流和工具进度,直到 invoke 返回。 也不能直接复用原 id:`design_command_replayed` 会拒绝用 `{type:"retry"}` 对上已存的 `{type:"message"}`。 建议:Retry 时先把 `session.turn.id` 更新成新 command id 再发事件,或事件一律带当前 command id。前端测试应覆盖 retry 事件能匹配 in-flight command。
Author
Owner

[bug] 阶段审批绕过 executeDesignAgentTurn,不清 transient

onDesignApprove 自己 invoke('decide_design_phase')。批准会启动下一阶段(LLM + tools),流式写入 planningV2TransientReply,但这条路径不像 executeDesignAgentTurnfinally(约 942 行)那样清理 transient。ProjectSupervisorView 在 turn 结束后仍渲染 {!directCodex && transientReply},最后一块 stream / tool 行会作为重复助手气泡留在已持久化消息下面。这是每次批准阶段后的 happy path。

建议:decide_design_phase 走同一套 turn helper(设 designAgentTurnRef、busy,并在 finallyplanningV2TransientReply),或至少在 apply/catch 后清掉。

**[bug] 阶段审批绕过 `executeDesignAgentTurn`,不清 transient** `onDesignApprove` 自己 `invoke('decide_design_phase')`。批准会启动下一阶段(LLM + tools),流式写入 `planningV2TransientReply`,但这条路径不像 `executeDesignAgentTurn` 的 `finally`(约 942 行)那样清理 transient。`ProjectSupervisorView` 在 turn 结束后仍渲染 `{!directCodex && transientReply}`,最后一块 stream / tool 行会作为重复助手气泡留在已持久化消息下面。这是每次批准阶段后的 happy path。 建议:`decide_design_phase` 走同一套 turn helper(设 `designAgentTurnRef`、busy,并在 `finally` 清 `planningV2TransientReply`),或至少在 apply/catch 后清掉。
lhk229 marked this conversation as resolved
Author
Owner

[bug] 顾问阶段导轨回落到「概念设计」

PHASES 只有五段创作阶段。TDD 批准后 currentPhaseconsultantfindIndex-1Math.max(0, -1) 变成 0,rail 把概念设计标成当前、没有任何阶段标完成。DesignAgentSurface 已有顾问文案,工作区 header 则回退到原始 id。

建议:rail 纳入 consultant(或单独的「五段已完成」态),未知/consultant 不要当 index 0。

**[bug] 顾问阶段导轨回落到「概念设计」** `PHASES` 只有五段创作阶段。TDD 批准后 `currentPhase` 是 `consultant`,`findIndex` 为 `-1`,`Math.max(0, -1)` 变成 `0`,rail 把概念设计标成当前、没有任何阶段标完成。`DesignAgentSurface` 已有顾问文案,工作区 header 则回退到原始 id。 建议:rail 纳入 `consultant`(或单独的「五段已完成」态),未知/`consultant` 不要当 index 0。
lhk229 marked this conversation as resolved
Author
Owner

[suggestion] 非 function_call 的 output_item.addedoutput_index 会打挂整条流

以前 response.output_item.added 会忽略非 function_call item。现在与 .done 共用路径,任何 item 类型都要求 output_index。兼容网关若对 message/reasoning 的 output_item.added 不带该字段,会 Deserialize/槽位失败并中断整条流,包括非策划 Agent 的 Responses 调用方。官方 OpenAI 带这个字段;这是平台级行为变化。

建议:function_call 继续 fail-closed(回放需要)。其它 item 类型缺 output_index 时忽略该事件,不要失败整条流。

**[suggestion] 非 function_call 的 `output_item.added` 缺 `output_index` 会打挂整条流** 以前 `response.output_item.added` 会忽略非 `function_call` item。现在与 `.done` 共用路径,任何 item 类型都要求 `output_index`。兼容网关若对 message/reasoning 的 `output_item.added` 不带该字段,会 Deserialize/槽位失败并中断整条流,包括非策划 Agent 的 Responses 调用方。官方 OpenAI 带这个字段;这是平台级行为变化。 建议:`function_call` 继续 fail-closed(回放需要)。其它 item 类型缺 `output_index` 时忽略该事件,不要失败整条流。
lhk229 added 1 commit 2026-09-11 18:18:09 +08:00
策划工作区改名为design_artifacts
Project CI / Repository checks (pull_request) Failing after 13s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Native shell tests (pull_request) Successful in 17m35s
712f28e207
更新策划文件工具和阶段产物检查路径

同步测试夹具与生产迁移方案文档
lhk229 added 1 commit 2026-09-11 19:00:29 +08:00
修复策划 Agent 四个审查问题
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m40s
Project CI / Native shell tests (pull_request) Successful in 17m42s
811abdd375
修复 Retry 流式回合身份与阶段审批 transient 清理

拒绝无效 write_file 内容并补齐顾问阶段导轨
lhk229 added 1 commit 2026-09-11 19:12:16 +08:00
精简项目写锁历史型注释
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m51s
Project CI / Native shell tests (pull_request) Successful in 18m39s
63f5a1d49e
移除 Issue 编号和旧实现叙述

保留写锁等待与排障契约说明
lhk229 added 1 commit 2026-09-11 19:21:48 +08:00
调整策划调试日志默认开关
Project CI / Repository checks (pull_request) Failing after 13s
Project CI / Backend tests (pull_request) Failing after 13s
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
fd5a4c3136
npm run agc 开发启动时默认开启 design debug

其他启动方式默认不创建 .debug 目录
lhk229 added 1 commit 2026-09-11 19:23:13 +08:00
Merge remote-tracking branch 'origin/master' into design_agent_refactor
Project CI / Repository checks (pull_request) Successful in 2m24s
Project CI / Frontend tests (pull_request) Successful in 3m13s
Project CI / Backend tests (pull_request) Successful in 6m15s
Project CI / Native shell tests (pull_request) Successful in 18m32s
1102b5af23
lhk229 added 1 commit 2026-09-11 19:29:46 +08:00
清理未使用的策划会话入口
Project CI / Repository checks (pull_request) Successful in 2m46s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 5m46s
Project CI / Native shell tests (pull_request) Successful in 17m26s
f8f1cdd1f4
删除硬编码 quality 模型的 ensure_design_session

保留现有 selected_model_id 创建链路
lhk229 added 1 commit 2026-09-11 20:02:50 +08:00
接入策划顾问态做成游戏运行时切换
Project CI / Frontend tests (pull_request) Failing after 2m24s
Project CI / Repository checks (pull_request) Failing after 2m42s
Project CI / Native shell tests (pull_request) Failing after 5m45s
Project CI / Backend tests (pull_request) Successful in 6m46s
3047434b33
新增项目 Agent 运行时模式持久化与恢复判断

在顾问态增加做成游戏按钮并切换同项目 DirectProject

切换时不自动发起首轮 Provider 请求
lhk229 added 1 commit 2026-09-11 20:13:45 +08:00
修复直接创作首轮消息被误抑制
Project CI / Repository checks (pull_request) Successful in 2m26s
Project CI / Frontend tests (pull_request) Successful in 3m2s
Project CI / Backend tests (pull_request) Successful in 5m38s
Project CI / Native shell tests (pull_request) Successful in 19m38s
8528c5ffce
仅在顾问态切换到 GameAgent 时禁止自动首轮调用

恢复普通直接创作入口的初始需求投递
lhk229 marked the pull request as ready for review 2026-09-11 20:19:06 +08:00
lhk229 requested review from suzmii 2026-09-11 20:19:18 +08:00
lhk229 added 1 commit 2026-09-11 20:22:56 +08:00
替换文档占位符
Project CI / Repository checks (pull_request) Successful in 2m24s
Project CI / Frontend tests (pull_request) Successful in 2m45s
Project CI / Backend tests (pull_request) Successful in 6m5s
Project CI / Native shell tests (pull_request) Successful in 18m40s
8012008d83
lhk229 added 1 commit 2026-09-11 20:33:46 +08:00
兼容缺少槽位的非工具 Responses 事件
Project CI / Repository checks (pull_request) Successful in 2m41s
Project CI / Frontend tests (pull_request) Successful in 3m13s
Project CI / Backend tests (pull_request) Successful in 6m10s
Project CI / Native shell tests (pull_request) Successful in 19m54s
d9530047db
非 function_call output item 缺少 output_index 时忽略

保留 function_call 槽位缺失的 fail-closed 契约并补回归测试
lhk229 reviewed 2026-09-11 20:39:53 +08:00
lhk229 left a comment
Author
Owner

复审补充:顾问态「做成游戏」没有切到 DirectProject

上次四个 bug(Retry 流式身份、审批 transient、write_file 空覆盖、顾问导轨)看起来都还在。这条是新问题。

顾问态点「做成游戏」会写 .agent/runtime-mode.json、把工作台外壳切成游戏布局,并重挂 supervisor。但传给 AppplanningStartMode 仍是 startMode === 'planning',没有跟外壳一样用 agentRuntimeMode === 'design' 门控。startMode 不会变,结果:

  1. App 以策划模式重挂,directCodexProductRuntime 被关掉。
  2. hydrate_design_agent_session 因 sidecar 已是 game 返回 null,策划会话被藏起来。
  3. useDesignAgentSurface 仍为真,游戏工作台侧栏继续渲染空的策划控件(阶段回落到「概念设计」)。
  4. 发消息仍走 executeDesignAgentTurncontinue_design_agent_session 不读 runtime-mode,顾问 Agent 继续跑。

和提交说明「切换同项目 DirectProject、不自动发首轮」对不上。8528c5ffc 只压住了首轮 prompt,没有把 App 切进 Direct Codex。

建议:

  • ProjectSupervisorplanningStartMode 与外壳用同一条件:agentRuntimeMode === 'design' && startMode === 'planning'
  • continue_design_agent_session / decide_design_phaseactive_runtime == "game" 时直接拒绝,不要只挡 hydrate。
  • 补一条界面测试:顾问态点「做成游戏」后应走 Direct 对话,而不是 continue_design_agent_session
## 复审补充:顾问态「做成游戏」没有切到 DirectProject 上次四个 bug(Retry 流式身份、审批 transient、`write_file` 空覆盖、顾问导轨)看起来都还在。这条是新问题。 顾问态点「做成游戏」会写 `.agent/runtime-mode.json`、把工作台外壳切成游戏布局,并重挂 supervisor。但传给 `App` 的 `planningStartMode` 仍是 `startMode === 'planning'`,没有跟外壳一样用 `agentRuntimeMode === 'design'` 门控。`startMode` 不会变,结果: 1. `App` 以策划模式重挂,`directCodexProductRuntime` 被关掉。 2. `hydrate_design_agent_session` 因 sidecar 已是 `game` 返回 `null`,策划会话被藏起来。 3. `useDesignAgentSurface` 仍为真,游戏工作台侧栏继续渲染空的策划控件(阶段回落到「概念设计」)。 4. 发消息仍走 `executeDesignAgentTurn`;`continue_design_agent_session` 不读 runtime-mode,顾问 Agent 继续跑。 和提交说明「切换同项目 DirectProject、不自动发首轮」对不上。`8528c5ffc` 只压住了首轮 prompt,没有把 `App` 切进 Direct Codex。 建议: - `ProjectSupervisor` 的 `planningStartMode` 与外壳用同一条件:`agentRuntimeMode === 'design' && startMode === 'planning'`。 - `continue_design_agent_session` / `decide_design_phase` 在 `active_runtime == "game"` 时直接拒绝,不要只挡 hydrate。 - 补一条界面测试:顾问态点「做成游戏」后应走 Direct 对话,而不是 `continue_design_agent_session`。
Author
Owner

[bug] continue_design_agent_session 不读 runtime-mode

hydrate_design_agent_sessionactive_runtime == "game" 时返回 None,但这条续轮入口没有同样的检查。做成游戏之后前端如果仍误走策划 turn(当前 WorkspaceLauncher 就会),顾问 Agent 会继续跑。

decide_design_phase_at 同样没挡。建议两处在 active_runtime == "game" 时直接拒绝,不要只挡 hydrate。

**[bug] `continue_design_agent_session` 不读 runtime-mode** `hydrate_design_agent_session` 在 `active_runtime == "game"` 时返回 `None`,但这条续轮入口没有同样的检查。做成游戏之后前端如果仍误走策划 turn(当前 `WorkspaceLauncher` 就会),顾问 Agent 会继续跑。 `decide_design_phase_at` 同样没挡。建议两处在 `active_runtime == "game"` 时直接拒绝,不要只挡 hydrate。
lhk229 marked this conversation as resolved
Author
Owner

[bug] 顾问态「做成游戏」只换了外壳,对话仍停在策划 Agent

上面工作台外壳的 planningStartMode 已经用 agentRuntimeMode === 'design' && startMode === 'planning' 门控(约 352 行)。点「做成游戏」后 agentRuntimeMode 变成 game,外壳切到游戏工作台。

这里传给 App 的仍是 startMode === 'planning'startMode 不会变,所以重挂后的 App 仍是策划模式:directCodexProductRuntime 关着,hydrate 因 sidecar=game 返回空,useDesignAgentSurface 仍为真,侧栏变成空的策划控件(阶段回落到概念设计),发消息继续走 executeDesignAgentTurn

建议与外壳用同一条件:agentRuntimeMode === 'design' && startMode === 'planning'

**[bug] 顾问态「做成游戏」只换了外壳,对话仍停在策划 Agent** 上面工作台外壳的 `planningStartMode` 已经用 `agentRuntimeMode === 'design' && startMode === 'planning'` 门控(约 352 行)。点「做成游戏」后 `agentRuntimeMode` 变成 `game`,外壳切到游戏工作台。 这里传给 `App` 的仍是 `startMode === 'planning'`。`startMode` 不会变,所以重挂后的 `App` 仍是策划模式:`directCodexProductRuntime` 关着,hydrate 因 sidecar=`game` 返回空,`useDesignAgentSurface` 仍为真,侧栏变成空的策划控件(阶段回落到概念设计),发消息继续走 `executeDesignAgentTurn`。 建议与外壳用同一条件:`agentRuntimeMode === 'design' && startMode === 'planning'`。
lhk229 marked this conversation as resolved
lhk229 added 2 commits 2026-09-11 21:11:16 +08:00
增加策划 Agent reasoningText 事件字段与默认折叠展示入口

补充正文、思考过程和工具状态的字体层级样式

记录当前 Provider 尚未输出 reasoning 的现状与后续边界
修复顾问态切换游戏后的策划分流
Project CI / Repository checks (pull_request) Failing after 2m39s
Project CI / Frontend tests (pull_request) Failing after 2m57s
Project CI / Backend tests (pull_request) Successful in 6m46s
Project CI / Native shell tests (pull_request) Failing after 6m5s
d77d0ca9eb
统一 runtime mode 下的 planningStartMode

游戏运行态拒绝策划 Agent 续轮与阶段审批

补充游戏态运行时守卫测试
lhk229 added 1 commit 2026-09-11 21:32:30 +08:00
修复策划项目首轮运行模式初始化
Project CI / Repository checks (pull_request) Successful in 3m23s
Project CI / Frontend tests (pull_request) Successful in 3m34s
Project CI / Backend tests (pull_request) Successful in 8m44s
Project CI / Native shell tests (pull_request) Successful in 19m35s
c2f2b9867a
规划项目首次挂载时保持 planning lane

保留切换游戏运行态后的 DirectProject 分流
suzmii requested changes 2026-09-11 22:09:17 +08:00
suzmii left a comment
Member

评审结论:Request changes

问题清单:1 阻塞 / 4 重要 / 7 建议 / 6 细节。每条给出「位置 — 问题 — 影响 — 建议」。

关于 CI:CI 未通过本身不作为评审意见,它只是证据。本 PR 的 Repository checksFrontend testsNative shell tests 三个 job 因同一批 4 个 appSurface 用例失败(Tests 4 failed | 386 passed),本机复现一致;根因是下面的 B1,属于代码缺陷而非测试脆弱。


一、阻塞(Blocking)

B1 首页「做方案」新建项目后,首轮消息不会进入策划 Agent

  • 位置apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx:61-63:88-93:385-388;配合 apps/ai-game-creator-shell/src/App.tsx:270:6444-6497
  • 问题agentRuntimeMode 初值恒为 'game',仅在 render 之后的 effect 中跟随 currentProjectContext 同步,因此项目上下文出现的第一帧 planningStartModefalse。此时 ProjectSupervisor 先以游戏 lane 挂载,App.tsx:6444-6497 的自动首轮 effect(directCodexProductRuntime 为真时不 return)把首轮 prompt 发给 Direct Codex;随后 lane 切到 'design' 触发重挂,但首轮 claim 记录在跨实例共享的 initialSupervisorMessageClaimsByPage 中,已被前一实例消耗,重挂后的策划实例不再发送首轮。
  • 影响continue_design_agent_session 从未被调用,新策划链路在真实入口上不可用(用户会看到策划工作台打开但 Agent 不工作,或项目被 Direct Codex 抢跑)。
  • 依据
    1. 失败用例全部落在该路径:routes 做方案 false/true creation to the design agentkeeps 做方案 first turn on Supervisor without a Direct attachment sidecarsurfaces the planning clarification card after 做方案 creates the project from home(CI job 7182/7183/7185,本机 npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts 复现 4 failed | 386 passed (390))。
    2. 实测 invoke 调用序列出现 chat_with_game_creator_direct_codex,而 continue_design_agent_session 一次都没有出现。
    3. :385-388 临时改为仅按 currentProjectContext.startMode === 'planning' 派生后,4 个用例全部转绿(诊断改动已还原)。
  • 建议:lane 判定改为渲染期派生而非“渲染后同步”,例如 planningLaneActive = currentProjectContext?.startMode === 'planning' && runtimeOverride !== 'game'runtimeOverride 仅在用户点「做成游戏」时置为 'game');无论采用哪种写法,都要保证 lane 切换时首轮 claim 不被上一个 lane 消耗(例如把 claim 归属到 projectPath + lane,或在 lane 切换时重置)。

二、重要(Major)

M1 顾问阶段同时收到“必须提交审批”和“不需要提交审批”

  • 位置apps/ai-game-creator-shell/src-tauri/design-agent/phase-context/common-tail.md:6phase-context/consultant-tail.md:4;执行侧 src-tauri/src/agent/runtime_protocol/design_session.rs:284-286
  • 问题common-tail.md 每个阶段都会追加(design_tools.rs:159-161),其中要求“必需产物完成后必须提交阶段审批”;顾问阶段再追加的 consultant-tail.md 明确“顾问阶段没有下一层,也不需要提交阶段审批”。同一份 live system prompt 内两条相反指令并存,而运行期 submit_design_phase_for_approvalconsultant 会直接报 “顾问态不提交阶段审批”。
  • 影响:进入顾问态后大概率白跑一轮工具调用,用户看到无意义的“等待阶段审批失败”。
  • 建议:二选一并保持单一事实源——在 common-tail.md 增加“顾问阶段除外”,或顾问阶段不再追加 common-tail.md

M2 resources/skills/tdd.md 是五册串联,且含与本阶段冲突的红线(需确认是否原型基线)

  • 位置src-tauri/design-agent/resources/skills/tdd.md:1,100,275,459,641,748,红线出现在 :259(同族 :453:626);登记于 resources/catalog.jsonskills.tdd 为 tdd 阶段唯一注入资源)
  • 问题:该文件 833 行 / 52KB,标题结构依次是「TDD 分册总纲 → 概念层分册 → 顶层设计分册 → 系统架构分册 → 系统文档分册 → TDD 分册总纲(与第 10 行重复)」,即五册全量串联;其中 :259 一带是概念层红线“出现具体数值、按键、界面即删”,而 tdd 阶段的目标恰恰是产出数值、配表与字段字典。
  • 影响:tdd 阶段每轮多注入约 2 万 token,且模型可能因红线自我限制甚至拒绝写数值,阶段行为不可控。若这确实是原型基线,请在 PR 描述里说明;否则建议只保留 TDD 总纲段。
  • 建议:重建该文件为单一 TDD 分册,或把注入拆成“只注入当前阶段分册”。

M3 会话 history 无上限 + 64MB sidecar 上限会让会话永久写不进去

  • 位置src-tauri/src/agent/runtime_protocol/design_session.rs:13:102-111;写入侧 src-tauri/src/agent/runtime_protocol/json_sidecar.rs:122-135;调用点 src-tauri/src/agent/design_runtime.rs:250-254
  • 问题DesignSession.history 会累积全部 Responses 原生 output 与工具结果,每个 checkpoint 全量序列化;DESIGN_SESSION_MAX_BYTES 超限时直接返回“超过 64MiB 上限”,没有任何裁剪、压缩或降级路径。
  • 影响:策划 Agent 定位是长期协作,一旦越过阈值,会话将无法再写入,且无法通过正常操作恢复(只能手工处理项目文件)。
  • 建议:加入 history 裁剪 / 上下文压缩策略,或调整上限并明确超限后的可恢复行为。

M4 resources/SKILL.md 是原型方案残留,会随安装包发布

  • 位置src-tauri/design-agent/resources/SKILL.md:1,5,9-13;打包映射 src-tauri/tauri.conf.json:34-36
  • 问题:该文件 1480 行 / 97KB(约占资源包 25%),开头是“# 9 系统提示词(全文)”“# 10 交付与施工”,包含“第一批(10~15 人日)”“速览卡 12 字段完整性校验”“project-planning.md 整文件替换”等内部施工文案,并要求 ask_user / finish(summary) 这类生产工具集中不存在的工具;附录 A 五册在文件内重复两次,且与 resources/skills/*.md 逐行重复。我核对了 design_tools.rs 的读取逻辑(只读 system-prompt.md / tools.json / resources/catalog.json / phase-context/*),确认它没有任何运行期调用方。
  • 影响:安装包无谓增重,且原型的旧工具协议与旧产物口径会长期留在发布物里,后续维护者容易误当成现行契约。
  • 建议:移出随包资源,或明确标注“原型归档、不参与运行”,并处理三处重复内容。

三、建议(Minor)

S1 dev 启动脚本默认把完整 history 写入用户项目

  • 位置apps/ai-game-creator-shell/scripts/start-tauri-dev.mjs:109-115;写入侧 src-tauri/src/agent/design_runtime.rs:465-492
  • 问题:dev 脚本硬编码 GENARRATIVE_AGC_DESIGN_DEBUG=1design_debug 会把 session.history(含用户文本与 reasoning.encrypted_content)写到 {project}/.debug/design-agent/*.json。方案文档只承诺 .debug 是“可删除、不阻塞”的旁路,但默认开启意味着本地开发必然写入真实项目目录。
  • 建议:改回显式 opt-in(例如单独的 debug 命令或环境变量交给开发者自行设置)。

S2 App.tsx 中一批策划工作区接线没有 UI 出口

  • 位置src/App.tsx:572-578:11663-11665:11740-11760:912-960refreshDesignWorkspace);消费侧 src/features/project-workspace/DesignAgentSurface.tsx:38-46
  • 问题designWorkspaceFiles / designPreviewPath / designPreviewText / onDesignOpenFile / onDesignClosePreview 一路传下去,但 DesignAgentSurface 既不解构也不渲染这些 props(文件浏览实际由左栏 DesignWorkspacePanel 承担)。
  • 影响:每轮事件都会多打一次 list_design_workspace,结果无人使用;同时留下“这套接线到底该不该存在”的维护歧义。
  • 建议:删除,或真正接到右栏 UI(按仓库“保持简洁、不保留无调用方对象”的口径,倾向删除)。

S3 注入文档引用的“配套文件”在资源包内不存在

  • 位置resources/skills/concept.md:7-8(另有 top_design.mdarchitecture.mdsystems.mdtdd.md 同族引用);模块层 resources/modules/system-types/06_战斗与敌人/SKILL.md:5-6
  • 问题:正文引用 模板_概念设计.md例子_星露谷_概念设计.md例子_星露谷_分析.md 等名称,包内真实文件是 templates/concept-design.mdexemplars/stardew-concept.mdtemplates/stardew-analysis.md;模块层还写着“与总纲 ..\SKILL.md 配套”“本目录 例子_星露谷_系统设计_S06战斗.md”,两者都不存在(总纲实为 resources/skills/systems.md,范例实为 exemplars/stardew-s06-combat.md)。
  • 影响:Agent 只能通过 list_resources 拿到逻辑 ID,而 tools.json 明确要求“不要猜测物理路径”,两者相加会诱发必然失败的 read_file
  • 建议:引用改为逻辑资源 ID,并修掉模块层的死引用。

S4 速览卡存在两套互相矛盾的结构

  • 位置phase-context/overview-card.md:1(正文 10 节)与 resources/exemplars/overview-card.md:3,54
  • 问题:前者明确“不要加入审批操作说明或独立的决定状态段落”;后者自称“12 字段版本;渲染器照旧出卡走审批”,并把第 12 节设为“决定状态与原型验证项”,两处第 2-4 节顺序也不同。
  • 影响:速览卡是概念阶段唯一被检查存在性的非 design 产物,收到两套写法则结构与内容随机。
  • 建议:以 phase-context/overview-card.md 为准收敛范例表述。

S5 tools.json 声明与执行器行为有偏差

  • 位置src-tauri/design-agent/tools.json:4,5,7,11,12;执行侧 design_runtime.rs:284-302design_tools.rs:11,206-208,279-283,468-475,554-585
  • 问题ask_clarification 声明“选项数 2-4”“每轮最多一次”,实际无任何校验(0/1/5+ 都可,UI 直接按数组渲染);search_text 200 条命中被静默截断;patch_file 文件不存在时返回 Ok("局部修改失败:文件不存在")design_tool_line 会把它渲染成看起来成功的“局部修改:path”;list_dir.path 声明必填而运行期默认为 .read_resource 描述里的“未实现占位文档”在包内不存在。
  • 建议:按实际实现补齐描述,或补上 2-4 选项数与截断提示的校验。

S6 策划回合没有取消入口与预算约束

  • 位置src-tauri/src/agent/design_runtime.rs:693-718run_design_loop
  • 问题:循环只在模型不再要求工具调用、或进入审批/澄清等待时退出,没有轮次与 token 预算,也没有对应 game runtime 的停止命令。
  • 影响:长任务下用户只能关闭窗口,成本与可中断性不可控(方案文档只说了“不引入同轮调用次数门禁”,未覆盖取消能力)。
  • 建议:至少提供取消/停止命令。

S7 官方 router 模型来源变更是跨模块影响,需要说明与后端确认

  • 位置src-tauri/src/config.rs:96:207-215
  • 问题:删除了 OFFICIAL_LLM_ROUTER_MODEL = "gpt-6-astra",官方 router 路径改用 llm.model(AGC 模型目录 ID,例如 quality)并新增 x-genarrative-client: agc 头。api-server 侧已有该头解析(非本 PR 新增),但这条改动影响所有走官方 router 的 Agent,不只是策划。
  • 建议:在 PR 描述中显式写明该行为变更与影响面,并由后端同学确认模型目录 ID 解析覆盖全部官方调用方。

四、细节(Nit)

  • N1 DesignWorkspacePanel.tsx:330-334Math.max(0, PHASES.findIndex(...)) 会把未知阶段静默显示成“概念设计”,建议显式处理未知值。
  • N2 DesignAgentSurface.tsx:48view === null(尚未 hydrate)时也把阶段兜底成 concept 并渲染“概念设计”,实际会话可能已在 tdd;建议无 view 时先显示加载态。
  • N3 DesignWorkspacePanel.tsx:345,402,452:出现“Agent 产生的策划文档会显示在这里。”“文档会在这里按普通 Markdown 方式预览。”等功能说明文案,与 AGENTS.md“UI 面板中不要默认写功能说明、规则描述或开发解释文案”冲突。
  • N4 design_tools.rs:130-133:注入资源缺失/为空时静默 continue,没有任何诊断记录,与方案文档第 176 行“只记录诊断并继续请求 Provider”不符。
  • N5 resources/catalog.json:47 条 summary 为同一句模板文案,list_resources 的“简介”无区分度,Agent 只能靠标题猜内容。
  • N6 资源包缺少构建期一致性校验:仓库 skill-pack:check 只覆盖 Codex skill 包,策划资源包的“目录 / 登记表 / 注入阶段”一致性没有检查;本次我逐条核对了 52 条登记(无重复 ID、path 全部大小写精确存在、无未登记文件、无空文件),建议补一个轻量脚本把它固化下来。

五、已核对通过的部分

  • npm run check:encoding(4394 文件)、git diff --check、两个 manifest 的 cargo fmt --all -- --check 均通过。
  • CI Repository checks 中的 npm run lint 全链通过(脚本按序执行到了测试步骤),CI Backend tests 通过(含 platform-llm 新增的原生回放用例)。
  • 上一轮 review 提到的四点已确认修复:Retry 回合身份(design_runtime.rs:162-171)、审批 transient 清理(App.tsx:11700-11715)、write_file 空覆盖(design_tools.rs:255-264)、顾问阶段导轨(DesignWorkspacePanel.tsx:16-23);ensure_design_session 遗留也已清理。
  • platform-llm 的 Responses 原生回放在实现上很干净:responses_input / responses_output 只在原生模式生效(store=false + include=reasoning.encrypted_content),legacy 路径不受影响,neutral adapter 与 validate_for_transport 都做了拒绝;流式增量按 output_index 累积、completed 仅在有非空 output[] 时覆盖,用例覆盖到位。
  • 安全边界保留完整:normalize_relative_path 拒绝绝对路径 / .. / 反斜杠,resolve_local_project_path 逐段拒绝符号链接与 Windows reparse point,删除与遍历跳过链接,项目写锁 + 活跃锁 + 错误脱敏一致沿用。

六、合并前建议

  1. B1,让 4 个 appSurface 用例转绿(建议同时补一条“lane 切换后首轮仍归属策划”的回归用例);
  2. 处理 M1(提示词冲突)与 M2(tdd 注入内容)——这两条直接影响 Agent 行为;
  3. 明确 M3 的 history 裁剪策略,处理 M4 的原型残留;
  4. 其余 S/N 项建议至少在 PR 描述或后续 issue 中登记。
## 评审结论:Request changes 问题清单:**1 阻塞 / 4 重要 / 7 建议 / 6 细节**。每条给出「位置 — 问题 — 影响 — 建议」。 > 关于 CI:CI 未通过本身不作为评审意见,它只是证据。本 PR 的 `Repository checks`、`Frontend tests`、`Native shell tests` 三个 job 因同一批 4 个 appSurface 用例失败(`Tests 4 failed | 386 passed`),本机复现一致;根因是下面的 **B1**,属于代码缺陷而非测试脆弱。 --- ## 一、阻塞(Blocking) ### B1 首页「做方案」新建项目后,首轮消息不会进入策划 Agent - **位置**:`apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx:61-63`、`:88-93`、`:385-388`;配合 `apps/ai-game-creator-shell/src/App.tsx:270`、`:6444-6497` - **问题**:`agentRuntimeMode` 初值恒为 `'game'`,仅在 render 之后的 effect 中跟随 `currentProjectContext` 同步,因此项目上下文出现的第一帧 `planningStartMode` 为 `false`。此时 `ProjectSupervisor` 先以游戏 lane 挂载,`App.tsx:6444-6497` 的自动首轮 effect(`directCodexProductRuntime` 为真时不 return)把首轮 prompt 发给 Direct Codex;随后 lane 切到 `'design'` 触发重挂,但首轮 claim 记录在跨实例共享的 `initialSupervisorMessageClaimsByPage` 中,已被前一实例消耗,重挂后的策划实例不再发送首轮。 - **影响**:`continue_design_agent_session` 从未被调用,新策划链路在真实入口上不可用(用户会看到策划工作台打开但 Agent 不工作,或项目被 Direct Codex 抢跑)。 - **依据**: 1. 失败用例全部落在该路径:`routes 做方案 false/true creation to the design agent`、`keeps 做方案 first turn on Supervisor without a Direct attachment sidecar`、`surfaces the planning clarification card after 做方案 creates the project from home`(CI job 7182/7183/7185,本机 `npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts` 复现 `4 failed | 386 passed (390)`)。 2. 实测 `invoke` 调用序列出现 `chat_with_game_creator_direct_codex`,而 `continue_design_agent_session` 一次都没有出现。 3. 把 `:385-388` 临时改为仅按 `currentProjectContext.startMode === 'planning'` 派生后,4 个用例全部转绿(诊断改动已还原)。 - **建议**:lane 判定改为渲染期派生而非“渲染后同步”,例如 `planningLaneActive = currentProjectContext?.startMode === 'planning' && runtimeOverride !== 'game'`(`runtimeOverride` 仅在用户点「做成游戏」时置为 `'game'`);无论采用哪种写法,都要保证 lane 切换时首轮 claim 不被上一个 lane 消耗(例如把 claim 归属到 `projectPath + lane`,或在 lane 切换时重置)。 --- ## 二、重要(Major) ### M1 顾问阶段同时收到“必须提交审批”和“不需要提交审批” - **位置**:`apps/ai-game-creator-shell/src-tauri/design-agent/phase-context/common-tail.md:6`、`phase-context/consultant-tail.md:4`;执行侧 `src-tauri/src/agent/runtime_protocol/design_session.rs:284-286` - **问题**:`common-tail.md` 每个阶段都会追加(`design_tools.rs:159-161`),其中要求“必需产物完成后必须提交阶段审批”;顾问阶段再追加的 `consultant-tail.md` 明确“顾问阶段没有下一层,也不需要提交阶段审批”。同一份 live system prompt 内两条相反指令并存,而运行期 `submit_design_phase_for_approval` 在 `consultant` 会直接报 “顾问态不提交阶段审批”。 - **影响**:进入顾问态后大概率白跑一轮工具调用,用户看到无意义的“等待阶段审批失败”。 - **建议**:二选一并保持单一事实源——在 `common-tail.md` 增加“顾问阶段除外”,或顾问阶段不再追加 `common-tail.md`。 ### M2 `resources/skills/tdd.md` 是五册串联,且含与本阶段冲突的红线(需确认是否原型基线) - **位置**:`src-tauri/design-agent/resources/skills/tdd.md:1,100,275,459,641,748`,红线出现在 `:259`(同族 `:453`、`:626`);登记于 `resources/catalog.json`(`skills.tdd` 为 tdd 阶段唯一注入资源) - **问题**:该文件 833 行 / 52KB,标题结构依次是「TDD 分册总纲 → 概念层分册 → 顶层设计分册 → 系统架构分册 → 系统文档分册 → TDD 分册总纲(与第 10 行重复)」,即五册全量串联;其中 `:259` 一带是概念层红线“出现具体数值、按键、界面即删”,而 tdd 阶段的目标恰恰是产出数值、配表与字段字典。 - **影响**:tdd 阶段每轮多注入约 2 万 token,且模型可能因红线自我限制甚至拒绝写数值,阶段行为不可控。若这确实是原型基线,请在 PR 描述里说明;否则建议只保留 TDD 总纲段。 - **建议**:重建该文件为单一 TDD 分册,或把注入拆成“只注入当前阶段分册”。 ### M3 会话 history 无上限 + 64MB sidecar 上限会让会话永久写不进去 - **位置**:`src-tauri/src/agent/runtime_protocol/design_session.rs:13`、`:102-111`;写入侧 `src-tauri/src/agent/runtime_protocol/json_sidecar.rs:122-135`;调用点 `src-tauri/src/agent/design_runtime.rs:250-254` - **问题**:`DesignSession.history` 会累积全部 Responses 原生 output 与工具结果,每个 checkpoint 全量序列化;`DESIGN_SESSION_MAX_BYTES` 超限时直接返回“超过 64MiB 上限”,没有任何裁剪、压缩或降级路径。 - **影响**:策划 Agent 定位是长期协作,一旦越过阈值,会话将无法再写入,且无法通过正常操作恢复(只能手工处理项目文件)。 - **建议**:加入 history 裁剪 / 上下文压缩策略,或调整上限并明确超限后的可恢复行为。 ### M4 `resources/SKILL.md` 是原型方案残留,会随安装包发布 - **位置**:`src-tauri/design-agent/resources/SKILL.md:1,5,9-13`;打包映射 `src-tauri/tauri.conf.json:34-36` - **问题**:该文件 1480 行 / 97KB(约占资源包 25%),开头是“# 9 系统提示词(全文)”“# 10 交付与施工”,包含“第一批(10~15 人日)”“速览卡 12 字段完整性校验”“project-planning.md 整文件替换”等内部施工文案,并要求 `ask_user` / `finish(summary)` 这类生产工具集中不存在的工具;附录 A 五册在文件内重复两次,且与 `resources/skills/*.md` 逐行重复。我核对了 `design_tools.rs` 的读取逻辑(只读 `system-prompt.md` / `tools.json` / `resources/catalog.json` / `phase-context/*`),确认它没有任何运行期调用方。 - **影响**:安装包无谓增重,且原型的旧工具协议与旧产物口径会长期留在发布物里,后续维护者容易误当成现行契约。 - **建议**:移出随包资源,或明确标注“原型归档、不参与运行”,并处理三处重复内容。 --- ## 三、建议(Minor) ### S1 dev 启动脚本默认把完整 history 写入用户项目 - **位置**:`apps/ai-game-creator-shell/scripts/start-tauri-dev.mjs:109-115`;写入侧 `src-tauri/src/agent/design_runtime.rs:465-492` - **问题**:dev 脚本硬编码 `GENARRATIVE_AGC_DESIGN_DEBUG=1`,`design_debug` 会把 `session.history`(含用户文本与 `reasoning.encrypted_content`)写到 `{project}/.debug/design-agent/*.json`。方案文档只承诺 `.debug` 是“可删除、不阻塞”的旁路,但默认开启意味着本地开发必然写入真实项目目录。 - **建议**:改回显式 opt-in(例如单独的 debug 命令或环境变量交给开发者自行设置)。 ### S2 `App.tsx` 中一批策划工作区接线没有 UI 出口 - **位置**:`src/App.tsx:572-578`、`:11663-11665`、`:11740-11760`、`:912-960`(`refreshDesignWorkspace`);消费侧 `src/features/project-workspace/DesignAgentSurface.tsx:38-46` - **问题**:`designWorkspaceFiles` / `designPreviewPath` / `designPreviewText` / `onDesignOpenFile` / `onDesignClosePreview` 一路传下去,但 `DesignAgentSurface` 既不解构也不渲染这些 props(文件浏览实际由左栏 `DesignWorkspacePanel` 承担)。 - **影响**:每轮事件都会多打一次 `list_design_workspace`,结果无人使用;同时留下“这套接线到底该不该存在”的维护歧义。 - **建议**:删除,或真正接到右栏 UI(按仓库“保持简洁、不保留无调用方对象”的口径,倾向删除)。 ### S3 注入文档引用的“配套文件”在资源包内不存在 - **位置**:`resources/skills/concept.md:7-8`(另有 `top_design.md`、`architecture.md`、`systems.md`、`tdd.md` 同族引用);模块层 `resources/modules/system-types/06_战斗与敌人/SKILL.md:5-6` - **问题**:正文引用 `模板_概念设计.md`、`例子_星露谷_概念设计.md`、`例子_星露谷_分析.md` 等名称,包内真实文件是 `templates/concept-design.md`、`exemplars/stardew-concept.md`、`templates/stardew-analysis.md`;模块层还写着“与总纲 `..\SKILL.md` 配套”“本目录 `例子_星露谷_系统设计_S06战斗.md`”,两者都不存在(总纲实为 `resources/skills/systems.md`,范例实为 `exemplars/stardew-s06-combat.md`)。 - **影响**:Agent 只能通过 `list_resources` 拿到逻辑 ID,而 `tools.json` 明确要求“不要猜测物理路径”,两者相加会诱发必然失败的 `read_file`。 - **建议**:引用改为逻辑资源 ID,并修掉模块层的死引用。 ### S4 速览卡存在两套互相矛盾的结构 - **位置**:`phase-context/overview-card.md:1`(正文 10 节)与 `resources/exemplars/overview-card.md:3,54` - **问题**:前者明确“不要加入审批操作说明或独立的决定状态段落”;后者自称“12 字段版本;渲染器照旧出卡走审批”,并把第 12 节设为“决定状态与原型验证项”,两处第 2-4 节顺序也不同。 - **影响**:速览卡是概念阶段唯一被检查存在性的非 design 产物,收到两套写法则结构与内容随机。 - **建议**:以 `phase-context/overview-card.md` 为准收敛范例表述。 ### S5 `tools.json` 声明与执行器行为有偏差 - **位置**:`src-tauri/design-agent/tools.json:4,5,7,11,12`;执行侧 `design_runtime.rs:284-302`、`design_tools.rs:11,206-208,279-283,468-475,554-585` - **问题**:`ask_clarification` 声明“选项数 2-4”“每轮最多一次”,实际无任何校验(0/1/5+ 都可,UI 直接按数组渲染);`search_text` 200 条命中被静默截断;`patch_file` 文件不存在时返回 `Ok("局部修改失败:文件不存在")`,`design_tool_line` 会把它渲染成看起来成功的“局部修改:path”;`list_dir.path` 声明必填而运行期默认为 `.`;`read_resource` 描述里的“未实现占位文档”在包内不存在。 - **建议**:按实际实现补齐描述,或补上 2-4 选项数与截断提示的校验。 ### S6 策划回合没有取消入口与预算约束 - **位置**:`src-tauri/src/agent/design_runtime.rs:693-718`(`run_design_loop`) - **问题**:循环只在模型不再要求工具调用、或进入审批/澄清等待时退出,没有轮次与 token 预算,也没有对应 game runtime 的停止命令。 - **影响**:长任务下用户只能关闭窗口,成本与可中断性不可控(方案文档只说了“不引入同轮调用次数门禁”,未覆盖取消能力)。 - **建议**:至少提供取消/停止命令。 ### S7 官方 router 模型来源变更是跨模块影响,需要说明与后端确认 - **位置**:`src-tauri/src/config.rs:96`、`:207-215` - **问题**:删除了 `OFFICIAL_LLM_ROUTER_MODEL = "gpt-6-astra"`,官方 router 路径改用 `llm.model`(AGC 模型目录 ID,例如 `quality`)并新增 `x-genarrative-client: agc` 头。api-server 侧已有该头解析(非本 PR 新增),但这条改动影响所有走官方 router 的 Agent,不只是策划。 - **建议**:在 PR 描述中显式写明该行为变更与影响面,并由后端同学确认模型目录 ID 解析覆盖全部官方调用方。 --- ## 四、细节(Nit) - **N1** `DesignWorkspacePanel.tsx:330-334`:`Math.max(0, PHASES.findIndex(...))` 会把未知阶段静默显示成“概念设计”,建议显式处理未知值。 - **N2** `DesignAgentSurface.tsx:48`:`view === null`(尚未 hydrate)时也把阶段兜底成 `concept` 并渲染“概念设计”,实际会话可能已在 `tdd`;建议无 view 时先显示加载态。 - **N3** `DesignWorkspacePanel.tsx:345,402,452`:出现“Agent 产生的策划文档会显示在这里。”“文档会在这里按普通 Markdown 方式预览。”等功能说明文案,与 `AGENTS.md`“UI 面板中不要默认写功能说明、规则描述或开发解释文案”冲突。 - **N4** `design_tools.rs:130-133`:注入资源缺失/为空时静默 `continue`,没有任何诊断记录,与方案文档第 176 行“只记录诊断并继续请求 Provider”不符。 - **N5** `resources/catalog.json`:47 条 `summary` 为同一句模板文案,`list_resources` 的“简介”无区分度,Agent 只能靠标题猜内容。 - **N6** 资源包缺少构建期一致性校验:仓库 `skill-pack:check` 只覆盖 Codex skill 包,策划资源包的“目录 / 登记表 / 注入阶段”一致性没有检查;本次我逐条核对了 52 条登记(无重复 ID、path 全部大小写精确存在、无未登记文件、无空文件),建议补一个轻量脚本把它固化下来。 --- ## 五、已核对通过的部分 - `npm run check:encoding`(4394 文件)、`git diff --check`、两个 manifest 的 `cargo fmt --all -- --check` 均通过。 - CI `Repository checks` 中的 `npm run lint` 全链通过(脚本按序执行到了测试步骤),CI `Backend tests` 通过(含 `platform-llm` 新增的原生回放用例)。 - 上一轮 review 提到的四点已确认修复:Retry 回合身份(`design_runtime.rs:162-171`)、审批 transient 清理(`App.tsx:11700-11715`)、`write_file` 空覆盖(`design_tools.rs:255-264`)、顾问阶段导轨(`DesignWorkspacePanel.tsx:16-23`);`ensure_design_session` 遗留也已清理。 - `platform-llm` 的 Responses 原生回放在实现上很干净:`responses_input` / `responses_output` 只在原生模式生效(`store=false` + `include=reasoning.encrypted_content`),legacy 路径不受影响,neutral adapter 与 `validate_for_transport` 都做了拒绝;流式增量按 `output_index` 累积、completed 仅在有非空 `output[]` 时覆盖,用例覆盖到位。 - 安全边界保留完整:`normalize_relative_path` 拒绝绝对路径 / `..` / 反斜杠,`resolve_local_project_path` 逐段拒绝符号链接与 Windows reparse point,删除与遍历跳过链接,项目写锁 + 活跃锁 + 错误脱敏一致沿用。 --- ## 六、合并前建议 1. 修 **B1**,让 4 个 appSurface 用例转绿(建议同时补一条“lane 切换后首轮仍归属策划”的回归用例); 2. 处理 **M1**(提示词冲突)与 **M2**(tdd 注入内容)——这两条直接影响 Agent 行为; 3. 明确 **M3** 的 history 裁剪策略,处理 **M4** 的原型残留; 4. 其余 S/N 项建议至少在 PR 描述或后续 issue 中登记。
@@ -111,1 +112,3 @@
env: withAgcDevEndpointEnv(endpoint),
env: {
...withAgcDevEndpointEnv(endpoint),
[AGC_DESIGN_DEBUG_ENV]: '1',
Member

S1(建议):dev 下硬编码开启设计调试,会把含用户文本与 reasoning.encrypted_content 的完整 history 写进 {project}/.debug/design-agent/*.json。建议改为显式 opt-in。

**S1(建议)**:dev 下硬编码开启设计调试,会把含用户文本与 `reasoning.encrypted_content` 的完整 history 写进 `{project}/.debug/design-agent/*.json`。建议改为显式 opt-in。
lhk229 marked this conversation as resolved
@@ -0,0 +1,4 @@
顾问阶段不需要继续自主推动项目或主动安排下一步;遵照用户的具体指示行动。
根据用户指示回答问题、读取相关文档、修改工作区文件,并说明改动可能影响的已有产物。
涉及方向性变化或多个可行方案时,先向用户说明影响并等待用户决定;不要替用户做决定。
顾问阶段没有下一层,也不需要提交阶段审批。
Member

M1(重要):本行与 phase-context/common-tail.md:6 的“必须提交阶段审批”在同一份 live system prompt 内互相矛盾(common-tail.md 每个阶段都会追加),运行期还会硬拒绝(design_session.rs:284)。建议二选一:common-tail 增加“顾问阶段除外”,或顾问阶段不再追加 common-tail

**M1(重要)**:本行与 `phase-context/common-tail.md:6` 的“必须提交阶段审批”在同一份 live system prompt 内互相矛盾(`common-tail.md` 每个阶段都会追加),运行期还会硬拒绝(`design_session.rs:284`)。建议二选一:`common-tail` 增加“顾问阶段除外”,或顾问阶段不再追加 `common-tail`。
lhk229 marked this conversation as resolved
@@ -0,0 +256,4 @@
## 七、红线(只有三条)
1. 不冒充用户决定:用户没说的方向标"待确认",正文不写死。
2. 不越层:出现具体数值、按键、界面即删。
Member

M2(重要):该文件实为五册串联(833 行 / 52KB,catalog.json 中 tdd 阶段唯一注入资源),本行一带是概念层“出现具体数值、按键、界面即删”红线,与 tdd 阶段必须产出数值、配表与字段字典的目标冲突,且每轮多注入约 2 万 token。请确认是否为原型基线;若否,建议只保留 TDD 总册段。

**M2(重要)**:该文件实为五册串联(833 行 / 52KB,`catalog.json` 中 tdd 阶段唯一注入资源),本行一带是概念层“出现具体数值、按键、界面即删”红线,与 tdd 阶段必须产出数值、配表与字段字典的目标冲突,且每轮多注入约 2 万 token。请确认是否为原型基线;若否,建议只保留 TDD 总册段。
lhk229 marked this conversation as resolved
@@ -11435,2 +11660,4 @@
onPlanGddDecision={decidePlanGdd}
planningLane={planningV2Active}
designView={useDesignAgentSurface ? designAgentView : null}
designFiles={designWorkspaceFiles}
Member

S2(建议)designFiles / designPreviewPath / designPreviewText / onDesignOpenFile / onDesignClosePreviewDesignAgentSurface.tsx:38-46 中并未被解构使用(文件浏览实际由左栏 DesignWorkspacePanel 承担),属死接线,且每轮事件会多打一次 list_design_workspace。建议删除或真正接通。

**S2(建议)**:`designFiles` / `designPreviewPath` / `designPreviewText` / `onDesignOpenFile` / `onDesignClosePreview` 在 `DesignAgentSurface.tsx:38-46` 中并未被解构使用(文件浏览实际由左栏 `DesignWorkspacePanel` 承担),属死接线,且每轮事件会多打一次 `list_design_workspace`。建议删除或真正接通。
lhk229 marked this conversation as resolved
@@ -350,3 +385,2 @@
currentProjectContext.startMode === 'planning'
}
planningStartMode={planningStartMode}
playRequest={playRequest}
Member

B1(阻塞):策划 lane 判定依赖渲染后才同步的 agentRuntimeMode(初值恒为 game),首帧 planningStartMode 为 false,导致 ProjectSupervisor 先以游戏 lane 挂载并消耗掉首轮 claim。详见评审正文 B1(含调用序列实测与验证)。建议改为渲染期派生(startMode === 'planning' && runtimeOverride !== 'game'),并保证 lane 切换时首轮 claim 不被上一 lane 消耗。

**B1(阻塞)**:策划 lane 判定依赖渲染后才同步的 `agentRuntimeMode`(初值恒为 `game`),首帧 `planningStartMode` 为 false,导致 `ProjectSupervisor` 先以游戏 lane 挂载并消耗掉首轮 claim。详见评审正文 B1(含调用序列实测与验证)。建议改为渲染期派生(`startMode === 'planning' && runtimeOverride !== 'game'`),并保证 lane 切换时首轮 claim 不被上一 lane 消耗。
lhk229 marked this conversation as resolved
lhk229 added 1 commit 2026-09-12 00:48:37 +08:00
修复策划首轮错 lane 挂载导致 Agent 不工作
Project CI / Repository checks (pull_request) Successful in 2m38s
Project CI / Backend tests (pull_request) Successful in 6m24s
Project CI / Frontend tests (pull_request) Successful in 3m19s
Project CI / Native shell tests (pull_request) Successful in 17m51s
86adaa738f
运行模式改为随项目上下文同步派生,移除 effect 后置修正

做成游戏切换记录按项目路径与创建时间定位,跨项目自动失效

消除首帧游戏运行时挂载消耗首轮 claim 后策划实例无法补发的问题
lhk229 added 1 commit 2026-09-12 09:44:41 +08:00
删除策划对话栏未接通的文件浏览死接线
Project CI / Repository checks (pull_request) Successful in 2m21s
Project CI / Frontend tests (pull_request) Successful in 2m56s
Project CI / Backend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 17m55s
22c4807612
DesignAgentSurface 移除从未消费的 files 与预览 props

ProjectSupervisorView 同步移除死 props 声明与透传

App 移除 designWorkspaceFiles 等状态与 refreshDesignWorkspace,每轮策划事件不再多打一次 list_design_workspace
lhk229 added 1 commit 2026-09-12 13:10:28 +08:00
完善策划调试入口与顾问态切换
Project CI / Repository checks (pull_request) Failing after 16s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
8853e3b48e
统一策划 Debug 日志、快速推进按钮和快速推进命令的开关。

将做成游戏入口放到顾问阶段条末尾并接入正常运行时切换。

登记策划产物资产并补充工作区调试入口测试与技术文档。
lhk229 added 1 commit 2026-09-12 13:10:44 +08:00
Merge branch 'master' into design_agent_refactor
Project CI / Repository checks (pull_request) Failing after 1m19s
Project CI / Frontend tests (pull_request) Failing after 2m23s
Project CI / Native shell tests (pull_request) Failing after 4m42s
Project CI / Backend tests (pull_request) Successful in 6m50s
226cfbc8a1
lhk229 added 1 commit 2026-09-12 13:22:09 +08:00
修复 CI 调试工作区测试
Project CI / Repository checks (pull_request) Successful in 2m42s
Project CI / Frontend tests (pull_request) Successful in 3m15s
Project CI / Backend tests (pull_request) Successful in 7m2s
Project CI / Native shell tests (pull_request) Successful in 19m28s
34616e1631
格式化 design runtime 调试命令

为 debug fixture 测试显式开启并清理 debug 环境变量
lhk229 added 1 commit 2026-09-12 13:29:48 +08:00
修正策划资源文档引用路径
Project CI / Repository checks (pull_request) Successful in 2m38s
Project CI / Frontend tests (pull_request) Successful in 3m15s
Project CI / Backend tests (pull_request) Successful in 6m44s
Project CI / Native shell tests (pull_request) Successful in 17m36s
a4373d7494
将阶段 Skill 和系统模块中的旧附件名称统一为资源逻辑路径。

修正模板、范例、系统总纲及模块配套文件引用。
suzmii added 1 commit 2026-09-12 14:25:30 +08:00
Merge branch 'master' into design_agent_refactor
Project CI / Repository checks (pull_request) Successful in 2m31s
Project CI / Frontend tests (pull_request) Successful in 3m5s
Project CI / Backend tests (pull_request) Successful in 6m27s
Project CI / Native shell tests (pull_request) Successful in 20m9s
281e6ccf48
lhk229 marked the pull request as work in progress 2026-09-12 14:28:44 +08:00
lhk229 added 1 commit 2026-09-12 14:43:50 +08:00
修复策划项目重开运行态恢复
Project CI / Repository checks (pull_request) Successful in 2m17s
Project CI / Frontend tests (pull_request) Successful in 3m8s
Project CI / Backend tests (pull_request) Successful in 7m46s
Project CI / Native shell tests (pull_request) Successful in 19m52s
832f1e8b59
持久化策划项目 design 运行模式并在重开时恢复 design/game 工作台。

补充旧策划会话兼容判断、前端夹具和恢复回归测试。
Author
Owner

代码审查意见

整体结构清晰:会话崩溃恢复(executing 标记 + 检查点重放)、命令幂等、路径安全复用既有 resolve_local_project_path/normalize_relative_path 护栏、工具白名单与 tools.json 一一对应、契约侧 responses_input 在 neutral adapter 有明确拒绝兜底,测试覆盖也比较到位。以下问题按严重度排序:

需要修复

1. App.tsx 审批回调缺少项目切换防护(中)

executeDesignAgentTurn.then/.catch 里都有 localProjectPathRef.current !== nextProjectPath 的检查,但 onDesignApprovedecide_design_phase 回调没有:

.then((view) => { applyDesignView(view, nextProjectPath); })

applyDesignView 会写 setMessagessavedConversationProjectPathReflatestMessagesRef 等会话级状态。真实场景:用户点「批准」后审批请求在途(审批通过会触发下一轮完整 Agent 循环,可能耗时几十秒),此时切到另一个项目,旧项目的 DesignView 会被套用到新项目的对话状态上,且 savedConversationProjectPathRef 被写成旧项目路径,后续会话保存归属错乱。建议补上与 executeDesignAgentTurn 一致的 ref 检查。

2. upsert_responses_output_item 对上游 slot 无上界保护(低-中)

server-rs/crates/platform-llm/src/lib.rs

let index = slot as usize;
if index >= output.len() {
    output.resize(index + 1, serde_json::Value::Null);
}

output_index 来自上游 SSE 事件,属不可信输入。AGC 支持用户自配 OpenAI-compatible endpoint,一个异常/恶意的 provider 发 output_index: 2^40 会让 resize 尝试巨额分配直接 abort 进程。建议加一个合理上限(如 slot > 1024 时按错误事件处理或忽略)。

建议修复

3. ask_clarification 同轮重复调用会静默覆盖(低)

tools.json 里写了「每轮最多调用一次」,但 execute_design_tool 未兜底:同一批次里模型连续调两次 ask_clarification,第二次会直接覆盖 session.pending_clarification,而第一次的 function_call_output 已经告诉模型「waiting_for_user + 第一个问题」。结果模型以为用户在回答第一个问题,用户看到的卡却是第二个,后续 Clarification 输入按 request_id 匹配的是第二个问题,上下文错位。建议第二次调用返回错误(如「当前已有待回答的澄清」),与 submit_phase_for_approval 的幂等返回已有请求保持一致。

4. 策划项目会话损坏后无法打开项目(低)

项目打开链路里 hydrateDesignAgentSession 抛错且 planningStartMode 为真时直接 throw,整个打开流程中止。read_design_session 的 schema 校验失败(如 64MB 超限写入中断留下的半截文件、手改过的 session.json)会把项目彻底锁死,UI 没有恢复入口。建议 hydrate 失败时降级为「会话损坏,可重新开始策划会话」,而不是阻断项目打开。

5. 会话历史无界增长(风险项,可不本 PR 处理)

session.history 每轮累积完整原生 output(含 reasoning encrypted_content、function_call_output 的完整文件内容),commands 只增不减。两个后果:长会话(尤其 consultant 阶段反复迭代)token 上下文最终会爆;session.json 超过 64MB 上限后 checkpoint_design 每次写盘都失败,回合卡死在错误态。建议记入后续事项:历史压缩或 commands 淘汰策略。

提示性意见

6. planningV2Reasoning 是死状态design_eventreasoning_text 恒为 None,前端 setPlanningV2Reasoning 永远不会被触发,且 resetTerminalPlanningConversation 也没有清它。既然是「预留」,建议要么接上 reasoning 增量事件,要么先不加这段状态和 designReasoning 展示,避免后续接线的以为已通。

7. 调试开关默认开start-tauri-dev.mjsGENARRATIVE_AGC_DESIGN_DEBUG 除非显式设为 '0' 否则一律按 '1' 注入,dev 下默认出现「快速准备做成游戏测试」按钮并写 .debug dump。如果是有意的 opt-out 设计建议在文档里写一句;否则建议改成显式 '1' 才开。

8. UI 说明文案DesignWorkspacePanel 头部的「Agent 产生的策划文档会显示在这里。」和 project-development 里的「持续协作推进设计」属于 AGENTS.md「UI 面板中不要默认写功能说明、规则描述」约束覆盖的文案,建议移除(空态引导文案可保留)。

9. search_text 空 query"".contains 恒真,空 query 会把工作区每行都当命中直到 200 上限。建议在 executor 里拒掉空 query

## 代码审查意见 整体结构清晰:会话崩溃恢复(executing 标记 + 检查点重放)、命令幂等、路径安全复用既有 `resolve_local_project_path`/`normalize_relative_path` 护栏、工具白名单与 tools.json 一一对应、契约侧 `responses_input` 在 neutral adapter 有明确拒绝兜底,测试覆盖也比较到位。以下问题按严重度排序: ### 需要修复 **1. `App.tsx` 审批回调缺少项目切换防护(中)** `executeDesignAgentTurn` 的 `.then`/`.catch` 里都有 `localProjectPathRef.current !== nextProjectPath` 的检查,但 `onDesignApprove` 的 `decide_design_phase` 回调没有: ```ts .then((view) => { applyDesignView(view, nextProjectPath); }) ``` `applyDesignView` 会写 `setMessages`、`savedConversationProjectPathRef`、`latestMessagesRef` 等会话级状态。真实场景:用户点「批准」后审批请求在途(审批通过会触发下一轮完整 Agent 循环,可能耗时几十秒),此时切到另一个项目,旧项目的 DesignView 会被套用到新项目的对话状态上,且 `savedConversationProjectPathRef` 被写成旧项目路径,后续会话保存归属错乱。建议补上与 `executeDesignAgentTurn` 一致的 ref 检查。 **2. `upsert_responses_output_item` 对上游 slot 无上界保护(低-中)** `server-rs/crates/platform-llm/src/lib.rs`: ```rust let index = slot as usize; if index >= output.len() { output.resize(index + 1, serde_json::Value::Null); } ``` `output_index` 来自上游 SSE 事件,属不可信输入。AGC 支持用户自配 OpenAI-compatible endpoint,一个异常/恶意的 provider 发 `output_index: 2^40` 会让 `resize` 尝试巨额分配直接 abort 进程。建议加一个合理上限(如 slot > 1024 时按错误事件处理或忽略)。 ### 建议修复 **3. `ask_clarification` 同轮重复调用会静默覆盖(低)** tools.json 里写了「每轮最多调用一次」,但 `execute_design_tool` 未兜底:同一批次里模型连续调两次 `ask_clarification`,第二次会直接覆盖 `session.pending_clarification`,而第一次的 `function_call_output` 已经告诉模型「waiting_for_user + 第一个问题」。结果模型以为用户在回答第一个问题,用户看到的卡却是第二个,后续 `Clarification` 输入按 `request_id` 匹配的是第二个问题,上下文错位。建议第二次调用返回错误(如「当前已有待回答的澄清」),与 `submit_phase_for_approval` 的幂等返回已有请求保持一致。 **4. 策划项目会话损坏后无法打开项目(低)** 项目打开链路里 `hydrateDesignAgentSession` 抛错且 `planningStartMode` 为真时直接 `throw`,整个打开流程中止。`read_design_session` 的 schema 校验失败(如 64MB 超限写入中断留下的半截文件、手改过的 session.json)会把项目彻底锁死,UI 没有恢复入口。建议 hydrate 失败时降级为「会话损坏,可重新开始策划会话」,而不是阻断项目打开。 **5. 会话历史无界增长(风险项,可不本 PR 处理)** `session.history` 每轮累积完整原生 output(含 reasoning encrypted_content、`function_call_output` 的完整文件内容),`commands` 只增不减。两个后果:长会话(尤其 consultant 阶段反复迭代)token 上下文最终会爆;session.json 超过 64MB 上限后 `checkpoint_design` 每次写盘都失败,回合卡死在错误态。建议记入后续事项:历史压缩或 commands 淘汰策略。 ### 提示性意见 **6. `planningV2Reasoning` 是死状态**:`design_event` 里 `reasoning_text` 恒为 `None`,前端 `setPlanningV2Reasoning` 永远不会被触发,且 `resetTerminalPlanningConversation` 也没有清它。既然是「预留」,建议要么接上 reasoning 增量事件,要么先不加这段状态和 `designReasoning` 展示,避免后续接线的以为已通。 **7. 调试开关默认开**:`start-tauri-dev.mjs` 里 `GENARRATIVE_AGC_DESIGN_DEBUG` 除非显式设为 `'0'` 否则一律按 `'1'` 注入,dev 下默认出现「快速准备做成游戏测试」按钮并写 `.debug` dump。如果是有意的 opt-out 设计建议在文档里写一句;否则建议改成显式 `'1'` 才开。 **8. UI 说明文案**:`DesignWorkspacePanel` 头部的「Agent 产生的策划文档会显示在这里。」和 project-development 里的「持续协作推进设计」属于 AGENTS.md「UI 面板中不要默认写功能说明、规则描述」约束覆盖的文案,建议移除(空态引导文案可保留)。 **9. `search_text` 空 query**:`"".contains` 恒真,空 query 会把工作区每行都当命中直到 200 上限。建议在 executor 里拒掉空 `query`。
Author
Owner

这个问题描述的风险在抽象上成立,但对当前生产代码来说,实际链路已经有 Runtime 兜底,不会出现同一批次第二次 ask_clarification 覆盖第一次的问题

当前处理顺序是:

  1. process_design_batch 每次只取一个工具调用;

  2. 第一次 ask_clarification 执行后写入 session.pending_clarification

  3. 随后计算:

    let waiting =
        session.pending_approval.is_some() ||
        session.pending_clarification.is_some();
    
  4. 因为已经进入等待状态,剩余调用会被标记为:

    正在等待用户,本次调用未执行
    
  5. pending_batch 被清空,当前回合停止。

所以即使 Provider 在同一批 Responses 输出中返回多个 ask_clarification

  • 第一个会真正执行;
  • 后续调用不会进入 execute_design_tool
  • 不会覆盖 pending_clarification
  • 会被记录为未执行;
  • Agent 收到的第一个工具输出和用户看到的澄清卡保持一致。

需要区分两点:

  • execute_design_tool 本身没有“已有澄清请求时拒绝覆盖”的独立保护;
  • 但它不是公开并发入口,生产调用路径由 process_design_batch 串行收束,并在第一个等待工具后停止剩余调用。

因此这条审查意见更准确的结论是:工具函数局部缺少防御,但当前批处理 Runtime 已经提供了有效门禁,描述中的实际错位场景在现有链路不会发生。

如果要进一步增强,可以在 ask_clarification 分支再加一个极小的保险判断:

if session.pending_clarification.is_some() {
    return Err("当前已有待回答的澄清问题".into());
}

但它主要是防止未来新增其他调用路径,当前不属于必须修复的生产 bug。

这个问题描述的风险在抽象上成立,但对当前生产代码来说,实际链路已经有 Runtime 兜底,**不会出现同一批次第二次 `ask_clarification` 覆盖第一次的问题**。 当前处理顺序是: 1. `process_design_batch` 每次只取一个工具调用; 2. 第一次 `ask_clarification` 执行后写入 `session.pending_clarification`; 3. 随后计算: ```rust let waiting = session.pending_approval.is_some() || session.pending_clarification.is_some(); ``` 4. 因为已经进入等待状态,剩余调用会被标记为: ```text 正在等待用户,本次调用未执行 ``` 5. `pending_batch` 被清空,当前回合停止。 所以即使 Provider 在同一批 Responses 输出中返回多个 `ask_clarification`: - 第一个会真正执行; - 后续调用不会进入 `execute_design_tool`; - 不会覆盖 `pending_clarification`; - 会被记录为未执行; - Agent 收到的第一个工具输出和用户看到的澄清卡保持一致。 需要区分两点: - `execute_design_tool` 本身没有“已有澄清请求时拒绝覆盖”的独立保护; - 但它不是公开并发入口,生产调用路径由 `process_design_batch` 串行收束,并在第一个等待工具后停止剩余调用。 因此这条审查意见更准确的结论是:**工具函数局部缺少防御,但当前批处理 Runtime 已经提供了有效门禁,描述中的实际错位场景在现有链路不会发生。** 如果要进一步增强,可以在 `ask_clarification` 分支再加一个极小的保险判断: ```rust if session.pending_clarification.is_some() { return Err("当前已有待回答的澄清问题".into()); } ``` 但它主要是防止未来新增其他调用路径,当前不属于必须修复的生产 bug。
lhk229 added 3 commits 2026-09-12 15:34:35 +08:00
为审批响应增加项目路径与请求身份校验

防止旧项目回调覆盖当前会话并清理新项目状态
拒绝超出 4096 的 output_index,避免异常上游输入触发巨额扩容

补充安全边界测试且不限制正常输出内容
允许损坏策划会话降级打开项目
Project CI / Repository checks (pull_request) Successful in 2m34s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Native shell tests (pull_request) Failing after 4m5s
Project CI / Backend tests (pull_request) Successful in 5m51s
f505d2792f
会话读取失败时保留工作台与产物访问能力

新增策划会话备份重置命令,不删除工作区产物
lhk229 marked the pull request as ready for review 2026-09-12 15:35:24 +08:00
lhk229 added 1 commit 2026-09-12 15:49:14 +08:00
自动隔离损坏的策划会话并修复 CI
Project CI / Repository checks (pull_request) Successful in 2m40s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 6m3s
Project CI / Native shell tests (pull_request) Successful in 17m48s
2e87a1403a
会话读取损坏时自动备份并允许项目继续打开

登记会话重置命令并补齐 Native shell 配置检查
lhk229 merged commit 3f69ce8bb7 into master 2026-09-12 16:10:08 +08:00
lhk229 deleted branch design_agent_refactor 2026-09-12 16:10:08 +08:00
Sign in to join this conversation.