内置工具错误改成每工具一个 typed enum,工具桥与 MCP 预检收口

- 每个内置工具在 agent/tool/<tool>/error.rs 定义自己的错误 enum:一个 case 一个变体,用户(以及转述给用户的模型)可见文案写在变体的 to_user_msg() 上,捕获处只调 to_user_msg()
- 跨工具重复的 case(入参形状、项目权限门禁、分页、清单读取、资源登记完成投影、客户端 Direct 回合门禁、宿主执行门禁、未登记工具名)在 agent/tool/error.rs 定义一次,各工具用包装变体 + From 复用,不复制文案
- 工具失败诊断的 code 由「反推错误文案」改成稳定的工具名,开发者信息进 metadata:tool、脱敏 arguments、directTurn、dispatchDenied
- 统一错误事件去掉 retryable 字段,AGENT_RUNTIME_ERROR_SCHEMA_VERSION 升到 agent-runtime-error.v2
- 独立客户端 MCP 的 validate_* 改成调用工具桥同一份入参规则,再用该工具 enum 的 to_user_msg() 渲染,删掉重复的字符串文案
- project/verification.rs 的项目权限策略判定改为返回 typed ProjectPermissionRejection(Denied / PolicyUnavailable)
- 同步更新技术方案文档的字段表与共享记忆的决策记录
This commit is contained in:
2026-10-01 10:51:50 +08:00
parent 41c3dea3fd
commit 1dfe0dd8d4
56 changed files with 4417 additions and 1896 deletions
@@ -9276,3 +9276,15 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 后台 AGC 模型目录新增 `agentMode`,只允许 `codex` / `cc`,缺失的历史目录按 `codex` 兼容;模型选择返回的公开摘要同步携带该绑定。
- 客户端把后台 `codex` 映射到现有 Codex app-server,把 `cc` 映射到独立 Claude Code CLI adapter;不通过替换 Codex JSON-RPC 可执行文件实现。
- Claude Code 只使用隔离环境和 AGC loopback MCP,禁用原生工具;取消通过独立 Direct 回合进程树回收处理。Codex、provider 和自定义 Responses 链路保持原路径。
## 2026-09-30 内置工具错误改成每工具一个 typed enum,统一错误事件去掉 retryable
- 背景:`agc-tools` 的失败诊断把预算相关三类之外的所有工具失败都写成 `retryable=true`,`code` 由错误文案 `contains("validation-budget-exhausted")` 之类反推;余额不足、非法参数这类条件不变就不会恢复的失败也被呈现为「可重试」,并发排障时只能靠 `metadata.tool` 认是哪个工具出的错。
- 决策(工具侧):每个内置工具在自己的 `agent/tool/<tool>/error.rs` 里定义错误 enum,一个 case 一个变体,用户(以及转述给用户的模型)可见文案写在变体的 `to_user_msg()` 上;捕获处只调 `to_user_msg()`,不解析文案、不分类、不算重试标志。跨工具重复的 case(入参不是对象 / 不认识的字段、项目权限门禁、分页、清单读取、资源登记完成投影、客户端 Direct 回合门禁、宿主执行门禁、未登记工具名)只在 `agent/tool/error.rs` 定义一次,各工具用包装变体 + `From` 复用,不复制文案。
- 决策(宿主侧):工具失败诊断的 `code` 改成稳定的工具名(不再从错误文案反推),开发者信息进 `metadata`:`tool`、脱敏后的 `arguments`、`directTurn`、`dispatchDenied`;`clientTurnId` 仍按回合归属记录,桥未被回合授权时如实记 `null`。
- 决策(schema):统一错误事件(`.agent/runtime/errors/<eventId>.json` 与应用日志身份行)去掉 `retryable` 字段,`AGENT_RUNTIME_ERROR_SCHEMA_VERSION` 升到 `agent-runtime-error.v2`。Direct Codex 用户可见文案里的 `direct-codex-failure:v2 … retryable=…` 由 typed `DirectTurnError::is_retryable()` 判定,不依赖这个字段,前端解析不受影响。
- 决策(MCP 预检收口,同日续做):独立客户端 MCP 的 `validate_*` 不再自带一套文案,改成调用工具桥同一份入参规则,再用该工具错误 enum 的 `to_user_msg()` 渲染 MCP 结果:`write_file_input`、`list_registered_assets_input`、`list_project_files_input`、`list_account_assets_input`、`account_asset_import_inputs`、`resource_generation_input`、`remove_background_input`、`generate_image_input`、`edit_image_arguments`、`prepare_game_art_input`、`web_search_input`、`editor_execute_code_input`、`cocos_execute_code_input` 都是「工具桥校验 + MCP 预检」共用入口;`ToolArgumentsRejection`(入参不是对象 / 不认识的字段)同时供 MCP 与 Runtime 侧虚拟工具观测(`agent/runtime_tools/context.rs`)复用。
- 收口时显式对齐的两处语义差异:① `agc_remove_background` 的 `backgroundMode` / `screenColor` 传显式 `null` 与省略等价(与工具桥其他可选字段同一口径),MCP 不再单独拒绝 `null`;② `.hermes` 并入 `bridge_project_file_is_hidden_control_path` 的保护目录集合,工具桥与 MCP、`preview.rs` 的受控目录口径一致。
- 改动范围:`agent/tool/**`(`error.rs` + 每个工具的错误模块;工具实现仍留在 `direct_tool_bridge.rs`,不搬家)、`agent/direct_tool_bridge.rs`、`agent/direct_tools_mcp.rs`、`agent/runtime_tools/context.rs`、`agent/runtime_error.rs`、`agent/runtime_state.rs`、`agent/direct_runtime/mod.rs`;同步去掉 `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 与 `docs/technical/【技术方案】AGC错误报告与诊断上传-2026-08-31.md` 身份行字段表里的 retryable。
- 验证:`cargo test --bin genarrative-ai-game-creator-shell agent::` 951 passed / 0 failed(5 ignored);`cargo check --tests` 通过;`npm run check:encoding`、`git diff --check` 通过;前端 `resourceCanvasAssetGenerationQueue`、`resourceCanvasGenerationHostLifecycle`、`appSurface` 套件通过(「项目权限策略拒绝执行:{id}」对外文案保持原字面)。
- 边界(未完成):Windows 专属的 Cocos / Unity / Godot 执行工具(含 MCP 预检)已按同一口径实现,但只做了交叉配置编译校验(Linux 上临时放开 `windows` cfg 后 `cargo check --features cocos-editor-execute,unity-editor-execute,godot-editor-execute --tests`),没有 Windows 真机构建;`agent/direct_validation.rs` 的 Runtime 动作(`run_command` / `run_browser`)与 `direct_tools_mcp.rs` 里 MCP 专有记录协议(Codex 返回记录、skill 资源读取)仍用各自的字符串错误,它们是 Runtime 动作 / MCP 协议而非内置工具。