Merge remote-tracking branch 'origin/master' into feat/smoother-dialog-history
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m50s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m30s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 4m51s
Project CI / Backend tests (pull_request) Successful in 4m53s
Project CI / Frontend tests (pull_request) Successful in 2m33s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m27s
Project CI / Native shell tests (pull_request) Successful in 5m47s
Project CI / Repository checks (pull_request) Successful in 3m4s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m50s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m30s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 4m51s
Project CI / Backend tests (pull_request) Successful in 4m53s
Project CI / Frontend tests (pull_request) Successful in 2m33s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m27s
Project CI / Native shell tests (pull_request) Successful in 5m47s
Project CI / Repository checks (pull_request) Successful in 3m4s
This commit is contained in:
@@ -5,6 +5,8 @@ Status: implemented-awaiting-runtime-acceptance
|
||||
Date: 2026-09-14
|
||||
Milestone: `【里程碑】项目客户端占用锁收敛-2026-09-14.md`
|
||||
|
||||
> 2026-10-02 更新:本计划里 Runner 侧的 `runner/project_owner.rs`、`.agent/runtime/execution-owner.lock` 与项目 execution-owner / known-roots 语义已随自建 Agent Runtime 退役删除(见 `docs/adr/【ADR】退役AGC独立Agent Runtime与CLI执行面-2026-10-02.md`);统一客户端占用锁(`project/write_lock.rs`)保留,下述 Runner owner 部分仅作历史追溯。
|
||||
|
||||
## 代码边界
|
||||
|
||||
- `apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs`
|
||||
@@ -67,4 +69,4 @@ Milestone: `【里程碑】项目客户端占用锁收敛-2026-09-14.md`
|
||||
|
||||
- 统一锁与 Runner owner 两条路径都在工作树里:`apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs`、`runner/project_owner.rs`。
|
||||
- 定向用例:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --offline -- write_lock --test-threads=1` → **21 passed**;`-- gui_ --test-threads=1` → **31 passed**(覆盖 `gui_owner_*`、`gui_owned_runner_*`、`gui_participant_lock_*` 等同进程重入、跨线程争用、owner 交接与崩溃恢复分支)。
|
||||
- 仍待补:真机多窗口/跨进程占用的运行时表现(本机只到定向用例级)。
|
||||
- 仍待补:真机多窗口/跨进程占用的运行时表现(本机只到定向用例级)。
|
||||
|
||||
@@ -5,6 +5,8 @@ Status: implemented-awaiting-runtime-acceptance
|
||||
Date: 2026-09-14
|
||||
Parent Spec: `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
|
||||
|
||||
> 2026-10-02 更新:Runner 侧 `execution-owner.lock` / `runner/project_owner.rs` 已随自建 Agent Runtime 退役删除(见 `docs/adr/【ADR】退役AGC独立Agent Runtime与CLI执行面-2026-10-02.md`);统一客户端占用锁保留,下述 Runner owner 迁移项不再执行。
|
||||
|
||||
## 目标
|
||||
|
||||
项目只保留一个面向客户端占用的项目级跨进程锁,防止多个客户端同时打开同一项目;同一客户端进程内**同一条写调用链(同一线程)的嵌套调用**复用既有项目锁,不因自身持锁进入等待。
|
||||
@@ -60,4 +62,4 @@ Parent Spec: `docs/technical/【技术方案】AI游戏创作智能体App实施
|
||||
|
||||
- 统一锁与 Runner owner 两条路径都在工作树里:`apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs`、`runner/project_owner.rs`。
|
||||
- 定向用例:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --offline -- write_lock --test-threads=1` → **21 passed**;`-- gui_ --test-threads=1` → **31 passed**(覆盖 `gui_owner_*`、`gui_owned_runner_*`、`gui_participant_lock_*` 等同进程重入、跨线程争用、owner 交接与崩溃恢复分支)。
|
||||
- 仍待补:真机多窗口/跨进程占用的运行时表现(本机只到定向用例级)。
|
||||
- 仍待补:真机多窗口/跨进程占用的运行时表现(本机只到定向用例级)。
|
||||
|
||||
@@ -92,6 +92,16 @@
|
||||
- 未修(另开):`redact_absolute_path_tokens` 的无语境绝对路径扫描仍会把 HTML 结束标签、嵌套 JSON 转义里的 `/` 误判成路径,是 issue #553 的根因;本次只删死路径,未改扫描器。
|
||||
- 验证:`cargo test --bin genarrative-ai-game-creator-shell agent:: -- --test-threads=1`(929 passed / 0 failed / 5 ignored)、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。
|
||||
|
||||
## 2026-10-02 退役AGC独立Agent Runtime与CLI执行面
|
||||
|
||||
- 决策:AGC 自建 Agent Runtime 执行面整体退役,按「从未存在」处理——`src-tauri/src` 的 `agent/runtime_driver`、`runtime_protocol`、`runtime_tools`、`runtime_actions`、`runtime_state`、`runtime_adapter`、`agent/prompt.rs`、`agent_native_tools.rs`、`collaboration.rs`、`delegation.rs`、`goal.rs`、`context_compaction.rs`、`isolated_agent.rs`、`provider_handoff.rs`、`provider_retry.rs`、`tool_plan_handoff/`、`user_input.rs` 及专属测试/fixture 删除;`generate_local_game_draft`、`control_agent_run`、`chat_with_game_creator_agent`、`*_game_creator_agent_goal`、`*_game_creator_agent_runtime_*`、`schedule_game_creator_agent_ready_tasks`、`start_game_creator_supervisor_runtime_task` 移出 Tauri `generate_handler!` 与 `check-config.mjs` 白名单;`--agent-run` / `--agent-task` / `--agent-goal-*` / `--agent-resume` / `--agent-context-compact` / runner 状态类 CLI 一并删除,`CliCommand` 收敛为 `LlmStatus | EnvironmentCheck | PreviewServe`。
|
||||
- 决策(Runner 收缩):外部 Runner 的项目 execution-owner / known-roots / `runner.status` / read-only configure 删除,只保留编辑器桥 RPC(`*.editor.rpc` / `*.editor.ack` / `*.editor.mark_uncertain`)与 `runner.attach_gui_owner` + GUI owner 参与锁 / watchdog;`--agent-runner` 模式保留,`runner.rs` 用 `TODO(retire-runner)` 记录后续整体退役条件。
|
||||
- 决策(前端与 harness):删除前端 `read/resume/confirm_resume_game_creator_agent_runtimes*` 调用链、`agentRuntimeById` 状态与 `onAgentRuntimeSummariesChange` 透传、`AgentRuntime*` / `AgentGoal*` 类型、`AgentStatusCard` 的 `runtime*` 字段与 `projectAgentRuntimeSummaries` / `formatAgentCardRuntimeStatus`;删除 `agent-runtime-real-e2e*`、`agent-runtime-steer-real-e2e`、`smoke-agent-run-local-provider.mjs`、`llm-transient-fault-proxy.mjs` 及其 CI job 与缓存预热条目。
|
||||
- 边界:AGC 会话命令、项目权限策略、DirectProject 的 `enqueue/cancel_direct_codex_turn` 链路与编辑器桥不受影响;保留项与备选方案见 ADR。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src/**`、`src-tauri/src/**`、`scripts/**`、`tests/**`、root / App `package.json`、`.gitea/workflows/project-ci.yml`、`deploy/container/README.md`、AGC 实施计划与 Runtime V1.1 文档。
|
||||
- 验证:`cargo check --tests --bin genarrative-ai-game-creator-shell`、`cargo test --bin genarrative-ai-game-creator-shell runner::`、`node apps/ai-game-creator-shell/scripts/check-config.mjs`(App 目录内执行)、`npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`、`npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts`、`npx vitest run scripts/project-ci-workflow.test.ts`、`git diff --check`。
|
||||
- 关联:[【ADR】退役AGC独立Agent Runtime与CLI执行面-2026-10-02](../../adr/【ADR】退役AGC独立Agent Runtime与CLI执行面-2026-10-02.md)。
|
||||
|
||||
## 2026-09-30 release 渠道移除产品名与包名后缀
|
||||
|
||||
- 决策:`release` 渠道的正式产品名统一为 `陶泥儿`,Windows NSIS、macOS DMG / updater 归档等由 Tauri `productName` 派生的包名不再包含 `Release` 文本;`identifier=world.genarrative.ai-game-creator.release` 与 `release-win` 更新分区保持不变。
|
||||
@@ -453,7 +463,7 @@
|
||||
|
||||
- 背景:AGC 项目对话曾把大量能力挂在「聊天输入 `/<cmd>`」上(`/history`、`/read`、`/help`、`/status`、`/trace`、`/export`、`/preview`、`/remember`、`/brief` 等),无 GUI 的终端 swarm chat 入口 `--swarm-chat` 又自带一套控制命令(`/help`、`/agents`、`/status`、`/history`、`/compact`、`/resume`、`/goal`、`/quit`)。两套入口都没有现役调用方,撤回成本却持续存在:命令字面量散落在前端命令分支、润色绕过、摘要模块、`swarm_cli` 终端输入解析、构建期门禁条目和文档承诺里,任何新对话形态都要额外维护这套死词汇表。
|
||||
- 决策:斜杠命令语义与终端 swarm chat 入口整体退役,按「从未存在」处理。应用侧删除 Direct 聊天的 `/history` 精确匹配分支与 `reloadHistory`、`chatPromptPolish` 的 `/` 前缀绕过、`chatCommandMetadata` / `chatCommandHelp` / `memoryCommands` 的命令清单与参数解析、只服务退役 Supervisor 摘要面板的 `project-summary/*Summaries.ts` 与 `agentTrace.ts`、草稿回填死链(前端 `agentPresentation.ts` + Rust `suggested_canvas_tool_call`)、无人调用的 Tauri 命令 `get_game_creation_agent_capabilities` / `get_limited_local_commands`,以及钉住这些字符串的构建期门禁条目与专属测试。终端侧连同入口一并删除:`--swarm-chat`、`src-tauri/src/swarm_cli.rs` 与整个 `swarm_cli/` 目录(命令解析与帮助输出、turn 派发、观察器、报告、专属测试)、`SwarmChatFlow`、`SwarmTurnObservation`、`SwarmTurnOutcome::Quit`、`SwarmConfirmationResolution::Quit`、`SWARM_TURN_*_ERROR`、只服务这些命令的 `agent.compact` / `agent.resume` / `agent.run_status` 权限门禁与 `print_runtime_response_stream_status` 打印器,以及只服务终端交互内核的 `agent/interaction.rs` 整层(`AgentInteractionAction`、tool registry、`game_creator_agent_uses_interaction_kernel`、`decide_game_creator_agent_interaction_turn_for_session_at`、`AgentInteractionProviderStreamSink`);该文件只保留自然语言 steer 决策路径 `decide_game_creator_agent_runtime_steer_at`。真实 E2E 的交互式 CLI 管道、`scripts/agent-swarm-test-chat.mjs`、`agentSwarmTestEntry.test.ts` 与 `agc:test:chat` / `agc:test:chat:manual` / `agc:chat` / `agc:swarm` 等 npm 脚本同步删除。
|
||||
- 保留项:命令 id 注册表 `GAME_CREATION_APP_COMMANDS` 与 `GameCreationAppPermission`(项目权限策略词汇表;App 前端只用 `GameCreationAppCommandDescriptor` 类型表达权限判定与审计粒度,数组本体由 Rust 策略路径消费)、`needsInitializedChatProject`,以及 `--agent-run` / `--agent-enqueue` / `--agent-steer` / `--agent-resume` / `--agent-context-compact` 等非聊天 CLI 控制命令与 Tauri IPC 注册。
|
||||
- 保留项:命令 id 注册表 `GAME_CREATION_APP_COMMANDS` 与 `GameCreationAppPermission`(项目权限策略词汇表;App 前端只用 `GameCreationAppCommandDescriptor` 类型表达权限判定与审计粒度,数组本体由 Rust 策略路径消费)、`needsInitializedChatProject`,以及 `--agent-run` / `--agent-enqueue` / `--agent-steer` / `--agent-resume` / `--agent-context-compact` 等非聊天 CLI 控制命令与 Tauri IPC 注册。(2026-10-02:这些 CLI 控制命令与对应 Tauri IPC 已随自建 Agent Runtime 整体退役,见同日前条与 ADR。)
|
||||
- 影响范围:`apps/ai-game-creator-shell/src/**`(Direct 聊天控制器、润色、`project-summary`、`project-workspace`)、`src-tauri/src/**`(`cli.rs`、`main.rs`、`swarm_cli` 整目录删除、`agent/interaction.rs` 收敛、命令注册、canvas 生成、provider / project 测试)、`apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e/**`、`scripts/check-config.mjs`、root 与 App 的 `package.json` 脚本、`tests/**`,以及 AGC 主实施计划文档、Runtime V1.1 文档与 `CONTEXT.md` 术语。
|
||||
- 验证方式:`npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`、`npm run --workspace apps/ai-game-creator-shell typecheck`(含 `check-config.mjs` 的脚本与门禁一致性)、`npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts`、`cargo check --tests`(告警消息集与基线一致)、`npm run check:encoding`、`git diff --check`;保留的 e2e 套件为 `supervisor-swarm`、`-transient-retry`、`-final-reply-transient-retry`、`-tool-plan-handoff-runner-kill`、`goal-runtime`、`response-stream`、`web-search`、`context-compaction`、`scoped-agents`、`project-skill`、`parallel-read`、`steer-runner-kill`、`process-session`。
|
||||
- 关联文档:[【ADR】退役AGC项目对话斜杠命令与终端swarm chat入口-2026-09-22](../../adr/【ADR】退役AGC项目对话斜杠命令与终端swarm chat入口-2026-09-22.md)、`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。(2026-09-24:对应里程碑已完成并删除,结论以 ADR 为准。)
|
||||
@@ -6556,7 +6566,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
## 2026-07-15 AI 游戏创作 Agent Runtime V1.21 token-aware 持久上下文压缩
|
||||
|
||||
- 顺序:MCP 动态工具目录与输出会进一步放大上下文,因此先补 Codex 风格 token-aware compaction,再进入 MCP。当前固定 12 条 conversation/observation 截断不再作为“已具备压缩”的完成证据。
|
||||
- 配置:`llm` 增加 `contextWindowTokens=128000 / autoCompactTokenLimit=64000 / toolOutputTokenLimit=12000`,`agentLlm` 可逐 Agent 覆盖。预算估算必须包含 function schema;Provider usage 单独标记为真实值,不能与估算混用。
|
||||
- 配置:`llm` 增加 `contextWindowTokens=128000 / autoCompactTokenLimit=64000`,`agentLlm` 可逐 Agent 覆盖。预算估算必须包含 function schema;Provider usage 单独标记为真实值,不能与估算混用。
|
||||
- 边界:只压缩旧 Agent/legacy conversation 和当前 run 的旧 observation,保留最近精确 tail;Goal、任务、结构化计划、steer、pending action、project/repository revision、verification、process/join/delegate、receipt 和 finalization 身份保持规范事实,不进入摘要改写。
|
||||
- 持久化:私有 `game-creator-runtime-context-compaction.v1` sidecar 绑定 Agent/Session、source prefix 指纹、可选 run、summary 指纹、预算与 usage;同源幂等,追加后 revision 单调,前缀漂移失败关闭。context bundle 只绑定压缩元数据,不复制 summary 正文。
|
||||
- 请求安全:compaction 使用独立 Provider lifecycle、稳定 request slot、零工具和零 web search。未知 started 或 completed 后 sidecar 未提交均按 orphan barrier 进入 reconciliation,禁止自动重发;sidecar 已提交后恢复直接复用。
|
||||
@@ -9419,6 +9429,38 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 客户端把后台 `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 协议而非内置工具。
|
||||
|
||||
## 2026-10-01 统一错误事件收成一个 message(去掉 public_text / recovery_hint / detail)
|
||||
|
||||
- 背景:`AgentRuntimeErrorEvent` 的三个文本字段在工具桥这条路径上完全退化——`publicText` 与 `detail` 逐字相同,`recoveryHint` 是常量「查看项目错误诊断后处理」,而且三个字段同时进 sidecar 与日志,读者分不清哪个才是「要给人看的话」。核对确认这个事件没有任何读取方:三处调用都是 `let _ = persist_agent_runtime_error(...)`;前端读的 `publicText` 属于 `AgentRuntimeEventRecord`(`runtime_state.rs` 的 runtime event,`app/types.ts` + `features/agent-runtime/model.ts` 的 `formatAgentRuntimeEvent`),是另一个结构;`.agent/runtime/errors/*.json` 只有测试在读,`read_agent_runtime_error_detail` 命令早已退役。这条链路的用途就是写日志与诊断包。
|
||||
- 决策(字段):事件只保留一个 `message`——由产生失败的 typed 错误在失败现场写好的人类可读文案(工具侧就是 `ToolFailure::to_user_msg()` 的那一句);删掉 `recovery_hint` 与 `detail` 两个字段及其入参。开发者信息不另开字段,全部进 `metadata`:`tool` + 脱敏 `arguments` + `directTurn` / `dispatchDenied`,即「工具 + 参数(脱敏)+ 上下文」。`persist_agent_runtime_error` 由 10 个入参减到 8 个,`agent_runtime_error_app_log_lines` 同步收口。
|
||||
- 决策(schema 与日志):`AGENT_RUNTIME_ERROR_SCHEMA_VERSION` 是 `agent-runtime-error.v2`,sidecar 由 `publicText / recoveryHint / detail` 收成 `message`(无读取方,不需要兼容层)。应用日志详情行由 `hint=… summary=… detail=… metadata=…` 收成 `message=… metadata=…`,身份行不变(本来就只放程序生成与调用方常量字段)。`message` 在应用日志里取原 `detail` 的 1200 字符预算、在 sidecar 里按 8 KiB 上限:用户只上传 AppData 应用日志、拿不到 sidecar,日志这一份必须是信息量最大的那份。
|
||||
- 决策(保留项):`direct-codex-failure:v2 … retryable=… summary=…;建议:…` 是前端(`features/agent-runtime/model.ts` 的 v2 正则)要解析的用户可见文案,`retryable` / `recovery_hint` 由 typed `DirectTurnError::is_retryable()` / `recovery_hint()` 判定,原样保留,只是不再进统一事件;`direct-codex` 路径把信息量最大的 `failure.to_string()`(typed Display)作为 `message`。`runtime_state.rs` 那条改为只记原始 `error`(投影后的用户文案已写进 `project.jsonl`,不必再存一遍)。
|
||||
- 改动范围:`agent/runtime_error.rs`、`agent/runtime_state.rs`、`agent/direct_tool_bridge.rs`、`agent/direct_runtime/mod.rs`;同步修正 `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 里 2026-09-15 的「统一事件至少包含 …」字段表与 2026-09-21 的日志两行口径。
|
||||
|
||||
## 2026-10-01 工具失败改成 typed 错误穿出 dispatch 边界,统一事件携带原始 error
|
||||
|
||||
- 背景:工具桥的派发边界把失败吞成 `Value`——`bridge_outcome(root, result)` 内部就把 typed 错误压成一句 `bridge_tool_failure` 文案,`isError` 由工具与桥手传;诊断只能从结果值里回读 `/content/0/text` 与(上一阶段临时挂在结果上的)`error` 键。结果是「哪一轮、哪个工具、什么结构化事实」在派发期间被降级成字符串,composer 只能靠 `isError=true` 反推分支。
|
||||
- 决策(dispatch 边界):`handle_direct_tool_bridge` 里的 `dispatch` 现在返回 `Result<Value, ToolCallError>`,失败原样穿出,不再在派发期压成 `Value`。`ToolCallError { message, redact_limit, error }` 是唯一载体:泛型 `impl<T: ToolFailure + ?Sized> From<&T>` 把具体错误 enum 的 `to_user_msg()`、`redact_limit()` 和原样序列化一起带出来——不做跨工具大 enum,不 Box(`?Sized` 让 trait 对象也能转)。`bridge_outcome` 随之删除。
|
||||
- 决策(composer):工具桥只有一个出口 `compose_direct_tool_outcome(state, tool, arguments, dispatchDenied, outcome)`:`Ok` 补 `isError=false`,`Err` 补 `isError=true` 并落一次诊断。`isError` 由分支决定,工具与桥都不再手传;MCP 完成包仍必须带布尔 `isError`(`direct_tools_mcp.rs::call_client_tool_bridge` 会校验),所以两条分支都写。五条早退(付费 / 写入 / 执行许可取不到、许可任务丢失、结算未落盘 `ReceiptNotPersisted`)也走同一出口:它们以前直接 `return Json(bridge_tool_failure(…))`,不写诊断。
|
||||
- 决策(诊断字段):`AgentRuntimeErrorEvent` 新增 `error`——产生失败的 typed 错误 enum 的原样序列化,`Value::Null` 表示该调用方(`agent/runtime_state.rs` 的终态公开消息)没有 typed 错误;`message` 仍是给人(以及转述给用户的模型)的那句话。应用日志详情行由 `message=… metadata=…` 扩成 `message=… error=… metadata=…`,`error` 取 400 字符预算(`AGENT_RUNTIME_ERROR_APP_LOG_ERROR_CHARS`)。`AGENT_RUNTIME_ERROR_SCHEMA_VERSION` 升到 `agent-runtime-error.v3`(sidecar 无读取方,不需要兼容层)。sidecar 里的 `error` 与既有 `metadata` 一样按原文落盘、只在应用日志里脱敏:sidecar 留在项目内不上传,上传的日志那份已经过 `redact_agent_runtime_error`。
|
||||
- 决策(周边收口):`bridge_tool_result(text, images)` 去掉 `is_error` 入参,模板只剩 `{ content }`;`record_completed_regeneration` 不再用 `isError` 判「能否缓存这次美术重生成」——走到那里的只有 `Ok`(失败会 `?` 上抛),`ArtRegenerationAuthorizationRejection::CompletedResultNotSuccessful` 因此退役。
|
||||
- 决策(软失败清零,同日续做):不接受「工具调用本身成功、载荷里写着失败」的软失败,十处全部改成各工具自己的 typed 变体,载荷原样进变体、由 `to_user_msg()` 拼成给模型的文案:`ImportAccountAssetsError::ImportFailed / ImportPartial`、`RunValidationError::ValidationNotPassed`、`BrowserPlaytestError::PlaytestNotPassed`、`EnvironmentCheckError::EnvironmentNotReady`、`ApplyPatchError::PatchNotApplied`、`EditorExecuteError::ExecutionNotCompleted / ExecutionUnconfirmed`、`CocosExecuteError::ExecutionBusy / ReconciliationPending / ExecutionNotCompleted`。于是 `isError` 与执行租约的 `passed`(`result.is_ok()`)重新对齐:execute 类失败仍落 `ExecutionPhase::Draining`。
|
||||
- 决策(证据图):`ToolFailure` 增加 `attached_images() -> Vec<String>`(默认空),`ToolCallError` 增加 `images`;composer 的 `Err` 分支在 `bridge_tool_failure` 的成文结果上追加 MCP image block。带图的两个变体(`ValidationNotPassed` / `PlaytestNotPassed` / `ExecutionNotCompleted`)把截图正文放在 `#[serde(skip)]` 字段里:图要回到结果里,但 base64 不能进 sidecar 的 `error` 正文。`bridge_validation_result` 由泛型 `?` 改成接受一个 `fn(Value, Vec<String>) -> E` 构造器,验证与试玩共用同一份 `passed` / 截图投影。
|
||||
- 改动范围:`agent/direct_tool_bridge.rs`、`agent/runtime_error.rs`、`agent/tool/error.rs` 与 23 个 `agent/tool/<tool>/error.rs`(补 `serde::Serialize`,`EditorKind` 同样补)、`agent/tool/run_validation/error.rs`、`agent/tool/browser_playtest/error.rs`、`agent/tool/environment_check/error.rs`、`agent/tool/apply_patch/error.rs`、`agent/tool/import_account_assets/error.rs`、`agent/tool/editor_execute/error.rs`、`agent/tool/cocos_execute/error.rs`、`agent/tool/prepare_game_art/error.rs`、`agent/generation/canvas_generation.rs`(并发测试改用 `Result`)、`agent/runtime_state.rs`、`agent/direct_runtime/mod.rs`;同步修正 `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 的统一事件字段表与应用日志两行口径。
|
||||
- 验证:`cargo check --bin genarrative-ai-game-creator-shell --tests` 通过(无新增警告);Windows 专属的 Cocos / Unity / Godot 执行路径在 Linux 上临时去掉 `#[cfg(all(windows, …))]` 的 `windows` 条件后,用 `cargo check --features cocos-editor-execute,unity-editor-execute,godot-editor-execute --tests` 交叉编译校验通过,随后原样还原(没有 Windows 真机构建);`cargo test --bin genarrative-ai-game-creator-shell -- agent::` 951 passed / 0 failed(5 ignored);`-- agent::direct_tool_bridge:: agent::direct_tools_mcp:: agent::runtime_error::` 73 passed;`-- agent:: tests::project::` 1076 passed / 2 failed,两条都是并行负载下的已知 flake(`agent::runtime_actions::provider_request_builders::tests::art_director_request_exposes_canvas_only_for_the_keyed_owner_route` 与 `tests::project::background_agent_runtime_can_generate_platform_art_asset`),单跑各自通过;`npm run check:encoding`、`git diff --check` 通过。
|
||||
|
||||
## 2026-09-30 合入 master 时把 Claude Agent SDK sidecar 归位到随包资源准备步骤
|
||||
|
||||
- 背景:master `fb130d184` 新增 `cc` 执行模式与 Claude Agent SDK sidecar,sidecar 的 staging 写在 `build.rs`(构建期 `remove_dir_all` + 从 `node_modules/@anthropic-ai/**` 复制 `resources/claude-agent`),同时把 `resources/claude-agent` 映射进**基线** `tauri.conf.json`。本分支的 M1–M3(issue #519)已把「构建期写随包资源」定性为结构问题,合入时必须按同一套架构落地,不能把写入分支带回来。
|
||||
|
||||
@@ -523,7 +523,7 @@ Direct 工具桥会 canonicalize 项目根,事件中的路径可能带 `\\?\`
|
||||
- **现象**:把 `Native shell tests` 拆成客户端三个 job 后,如果只跑 `npm run check:native-shells:release`,静态契约和壳运行时门禁都不会执行;如果只跑 `--groups=contract`,`desktop-release-binary-artifact` 又会因为缺少 `build/native/desktop/` 产物而失败。
|
||||
- **原因**:分组是执行范围,不是"额外检查"。`desktop-release-binary-artifact` 断言依赖同 job 内的 `desktop-shell-stage-release-binary` 步骤,所以它归 `release` 组,不能放进 `contract`;反过来,任何"只跑一组"的命令都不能被当成完整门禁。
|
||||
- **处理**:分组与 job 的对应关系固定为 `contract`+`shells`+`release` → `Native shell tests`,`agc-web` → `AI game creator shell web tests`,`agc-rust-shard-1..2` → `AI game creator shell Rust lane 1/2`,`agc-rust-shard-3..4` → `AI game creator shell Rust lane 2/2`,`agc-rust-smoke` → `AI game creator shell Rust smoke`,`agc-rust-crates` → `AI game creator shell Rust crates`;`scripts/project-ci-workflow.test.ts` 校验"每个分组恰好被一个 lane/job 调用一次"和"CI 不再调用全量 `npm run check:native-shells`",新增分组必须同步门禁脚本、根脚本与 workflow 三处。
|
||||
- **易错点**:① 拆 job / 改 job 名后要确认分支保护里没有残留已不再上报的旧 job 名(本仓库现在不配 required context,只需人工确认 CI 结果,见置顶条目的「分支保护口径」);② 每个 job 只预热自己会构建的 Cargo 依赖,`agent-run:smoke` 因为会 spawn `cargo` 必须与 AGC 壳的依赖预热同 job;③ 本地全量 `npm run check:native-shells` 仍会串行跑完所有分组,用它作为本地完整门禁,不要用单组脚本冒充。
|
||||
- **易错点**:① 拆 job / 改 job 名后要确认分支保护里没有残留已不再上报的旧 job 名(本仓库现在不配 required context,只需人工确认 CI 结果,见置顶条目的「分支保护口径」);② 每个 job 只预热自己会构建的 Cargo 依赖,需要 spawn `cargo` 的 smoke 必须与 AGC 壳的依赖预热同 job(原 `agent-run:smoke` 已随自建 Agent Runtime 退役,2026-10-02);③ 本地全量 `npm run check:native-shells` 仍会串行跑完所有分组,用它作为本地完整门禁,不要用单组脚本冒充。
|
||||
- **关联**:`.gitea/workflows/project-ci.yml`、`scripts/check-native-shells.mjs`、`scripts/project-ci-workflow.test.ts`、`.gitea` 分支保护设置。
|
||||
|
||||
## 2026-09-24 重复 `#[test]` 属性会让 Rust 分片门禁报「同一用例被分到两片」
|
||||
@@ -1008,16 +1008,6 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 验证:AppSurface 先用全新但内容相同的 Agent 结果数组 rerender,断言图读取仍只有一次且原卡片 DOM 保持连接;再增加真实资源并延迟第二次图响应,断言旧卡片在刷新窗口持续挂载,新图返回后新增卡片正常出现。
|
||||
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`。
|
||||
|
||||
## Supervisor steer 不能只有内部排队事件(2026-08-10)
|
||||
|
||||
- 现象:自主制作期间继续向项目总控发消息,用户消息已进入同一 Run,当前 Provider 也被中断并重新规划,但普通工作台短暂的提交状态消失后一直没有回复,直到整轮制作最终收束。
|
||||
- 原因:steer 只持久化用户消息与内部 `steer.queued` 事件;公开事件投影又明确排除 `steer.*`。普通工作台提交后会用后端 conversation 覆盖本地消息,因此仅追加临时前端气泡也无法稳定跨刷新显示。
|
||||
- 处理:根 Project Supervisor 的 steer 进入 durable `queued` 后,先写“正在判断、当前任务继续”的公开确认,再由独立 `steer-decision` LLM turn 返回自然语言回复和 `interruptCurrentProvider`。状态询问、解释和不冲突补充默认不中断;明确停止、改向或会使在途方案过期时才允许请求中断。判定和回复按 `run + steer` 持久幂等,刷新后仍可见;判定失败时继续当前任务,并在下一安全边界应用 steer。
|
||||
- 并发边界:steer 入队、Runner `runtime.steer` 通知都不得直接触发 Provider interrupt。Codex app-server 的判定使用独立节点,不能等待主节点 turn 锁;判定为 true 后也只能中断 `appliedSteerCursor < steer.sequence` 的旧 Provider 请求,已经消费该 steer 后启动的新请求不可被误杀。已经开始的工具和外部动作不强杀,完成 observation 后再消费 steer。
|
||||
- 验证:真实 mock LLM 回归必须覆盖状态询问回复且 `interruptCurrentProvider=false`;持久重放只保留一条语义回复;steer 入队后旧 Provider 继续运行,判定为 true 后才中断;新规划 Provider 的 cursor 已包含该 steer 时即使旧判定为 true 也不能中断。前端同秒多条消息保持“用户补充 → 判断提示/语义回复”的关联顺序。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/interaction.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs`、`apps/ai-game-creator-shell/src-tauri/src/runner/dispatch.rs`、`apps/ai-game-creator-shell/src/features/agent-runtime/model.ts`。
|
||||
- 2026-09-23 更新:`agent/interaction.rs` 与 `steer-decision` LLM 判定链已整体删除,本条中「判定 LLM / `interruptCurrentProvider` / 只中断旧 cursor」的实现细节仅作历史记录;现役语义是 steer durable 入队后由 `runtime.steer` 唤醒,并在下一安全边界应用。
|
||||
|
||||
## Jenkins 异步备份不能用 nohup 脱离作业
|
||||
|
||||
- 现象:Stdb Publish 成功,上传日志只留下“已获取进程锁 / 上传已有备份 / 目标对象”,没有成功或可捕获错误;本地 tar.gz 和 `uploadStatus=deferred` manifest 每次发布后继续增长。
|
||||
@@ -1050,30 +1040,6 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 验证:锁定 `generate-ui-design.image_size = ["1K", "2K"]`,三个可切换图片模型的工具都接入共享 `gpt-image-2 -> image_size = ["1K", "2K"]` 条件,以及视频 fast 条件没有内层 `required`、其 `then.resolution = ["480p", "720p"]`;同时保留运行时拒绝 `gpt-image-2 + 0.5K` 与 `seedance2.0-fast + 1080p` 的测试。
|
||||
- 关联:`server-rs/crates/platform-editor-agent/src/agent/tools/image_generation_options.rs`、`server-rs/crates/platform-editor-agent/src/agent/tools/generate_ui_design.rs`、`server-rs/crates/platform-editor-agent/src/agent/tools/generate_video.rs`、`docs/【编辑器】画布Agent对话面板-2026-07-03.md`。
|
||||
|
||||
## 重复成功的 agent.message 不能被当成新的 Runtime 进展
|
||||
|
||||
- 现象:专业 Agent 已把一条定向消息写入目标 Session,却在后续 planning 中反复发送相同正文;目标会话看起来没有重复消息,但 Provider 请求持续增长,run 可能长期不返回自身终态回执。
|
||||
- 原因:conversation 层的 messageId 幂等只能阻止重复落盘。若每个新 Runtime action 的 `status=ok` 都进入上下文进展指纹,相同 durable no-op 会不断刷新 6 轮停滞窗口;只检查目标会话条数无法证明 action loop 已有界收束。
|
||||
- 处理:消息语义键必须包含来源 Agent/run、目标 Agent/已解析 Session 和清洗截断后正文 SHA-256;conversation message、`conversation.message` 和 `agent.runtime.agent.message` 各自 exactly-once。重复调用继续完整记录自己的 action/observation/receipt,但私有 observation 固定返回 `messageAppended=false`,ContextWindowTracker 只忽略这一精确 no-op,不能忽略不同正文的新消息。专业 Agent prompt 同时明确中途消息不能替代自身 final response。
|
||||
- 验证:`background_agent_runtime_bounds_duplicate_agent_message_livelock` 必须真实驱动 6 个相同指纹、不同 actionId 的消息动作,证明 action/observation/receipt 各 6 条,目标消息和两类消息审计各 1 条,后 5 次不算进展,第 6 轮保留 `in_progress` 计划并进入 `budget-exhausted`,没有第 7 次 Provider 请求、context compaction 或 completed。另保留 `agent_runtime_context_window_counts_distinct_agent_message_bodies`,防止把真正不同的新消息误压成 no-op。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent.rs`、`apps/ai-game-creator-shell/src-tauri/src/project.rs`、`apps/ai-game-creator-shell/src-tauri/src/tests.rs`、`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`。
|
||||
|
||||
## Swarm E2E 的隔离 AppData 不能建在正式 AppData 里面
|
||||
|
||||
- 现象:真实 suite 自称使用隔离配置,但一次性 AppData 出现在正式 AppData 子目录;源目录 watcher、配置副本计数和清理归属变得含糊,Runner 还可能把临时 endpoint 或运行态写进正式目录树。
|
||||
- 原因:把 `mkdtemp` 前缀拼在 source config dir 内,只隔离了文件名,没有隔离目录所有权;source-dir guard 无法区分 suite 自己的合法子目录写入与污染,失败清理也可能触碰正式目录边界。
|
||||
- 处理:需要保护正式配置的 suite 一律在 `dirname(realConfigDir)` 下创建 sentinel 管理的 sibling AppData,并要求 realpath 后与源目录同父、互不包含。配置只使用私有副本或受控 hardlink/overlay,启动 CLI/Runner 全部指向 sibling;清理前核对 sentinel、源配置 inode/hash/link count、source-dir 前缀事件、正式 endpoint 身份和正式 CLI 调用计数,随后只删除拥有明确 token 的临时目录。
|
||||
- 验证:真实报告必须同时满足 `isolatedAppDataUsed=true`、`sourceAppDataDirectoryUntouched=true`、`sourceRunnerEndpointUnchanged=true`、`formalConfigCliCallCount=0`、配置副本校验和 `AppDataCleanupPerformed=true`;项目选择 `--keep-project` 时也不能改变 AppData 自动清理。
|
||||
- 关联:`apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e.mjs`、`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`。
|
||||
|
||||
## 异步 Runtime 测试不能把 child idle 当成终态结果已发布
|
||||
|
||||
- 现象:isolated child 已显示 idle,单次 all-join reconcile 却偶发返回空列表;或者 Runtime 已显示 completed / failed,Goal、conversation、Agent DB 审计和 per-Agent lock 仍未完成,完整 Rust suite 里出现低概率失败,单独重跑通常通过。
|
||||
- 原因:Runtime state、Goal sidecar、终态 result、conversation、审计记录、handoff 清理和执行 lane 释放不是同一个原子观测点;测试只等待 idle / failed 会在同一后台 drain 的 durable 收尾前抢先断言。
|
||||
- 处理:产品协议仍以 durable terminal result 和 join readiness 为准。测试在有界时限内等待业务目标终态;需要断言同一 drain 的后续副作用时,同时以 per-Agent runtime task lock 释放为 fence,命中后重新读取投影。join 场景继续重复调用幂等 reconcile,直到取得唯一 join 或超时;不得靠固定长 sleep,也不能因为第一次为空就把协议改成吞掉未完成 child。
|
||||
- 验证:`isolated_agents_with_same_template_run_independently_and_join_once` 最多执行 100 次、每次间隔 20ms 的 reconcile,并继续断言只有一个 all-join 和一次父唤醒;Goal、loop-budget、finalization 与 Supervisor reconciliation 测试必须在目标 status / phase 与 Agent lane 同时收束后再读取最终副作用。`background_agent_runtime_marks_response_plan_step_failed_when_final_reply_fails` 和 `background_agent_runtime_tasks_can_run_in_parallel_and_persist_replies` 同样必须经过该 fence 后再断言 `turn.failed` 或 `agent.runtime.completed` 审计。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/tests.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent.rs`。
|
||||
|
||||
## CI root 环境不能用文件只读权限注入写失败
|
||||
|
||||
- 现象:本地测试把 conversation 文件设为 readonly 后能稳定得到写入失败,Gitea Actions 中同一断言却发现写入成功并继续执行任务。
|
||||
@@ -1082,14 +1048,6 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 验证:在普通本地用户和 root 容器中分别运行用户消息、assistant 最终回复持久化失败测试,均应进入相同 durable phase 并通过恢复断言。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/project.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent.rs`、`apps/ai-game-creator-shell/src-tauri/src/tests.rs`。
|
||||
|
||||
## Ubuntu 容器不能把 chromium-browser 的 Snap 占位包当成 CI 浏览器
|
||||
|
||||
- 现象:AI 游戏创作壳的 1132 条 Rust 测试全部通过,尾部 `agent-run:smoke` 却以 `spawn google-chrome ENOENT` 失败;直接给 Ubuntu 24.04 job 安装 `chromium-browser` 仍拿不到可执行浏览器。
|
||||
- 原因:Ubuntu 24.04 仓库里的 `chromium-browser` 是 Snap 过渡包,普通 Docker job 没有 snapd 宿主能力;固定 job image 也不预装 Google Chrome。脚本回退到命令名 `google-chrome` 后只能在本机通过,在干净 Runner 中必然 ENOENT。
|
||||
- 处理:Native job 通过 Google 官方签名 APT 源安装 `google-chrome-stable`,安装后先执行 `google-chrome --version`;smoke 继续真实启动 headless 浏览器验证 DOM / canvas,不允许因 CI 缺浏览器而跳过或降级为静态 HTTP 检查。
|
||||
- 验证:固定 Ubuntu 24.04 job image 内先确认 `apt-cache policy chromium-browser` 仅为 Snap 占位,再安装官方签名包并运行 `google-chrome --version`;Gitea Native job 最终必须在 1132 passed / 5 ignored 后继续通过 `agent-run:smoke`。
|
||||
- 关联:`.gitea/workflows/project-ci.yml`、`apps/ai-game-creator-shell/scripts/smoke-agent-run-local-provider.mjs`。
|
||||
|
||||
## PTY 测试不能假设输入回显与后续输出必然分行
|
||||
|
||||
- 现象:PTY 环境隔离用例偶发得到 `你好BRIDGE_ENV:`,而不是独立的 `你好` 与 `BRIDGE_ENV:` 两行;真实私有环境变量并未泄漏,但整行相等断言失败。
|
||||
@@ -1098,30 +1056,6 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- 验证:`process_session_pty_uses_private_environment_and_redacts_public_records` 对 `BRIDGE_ENV:` 使用行尾匹配,并保留真实私有环境变量、stdin 正文与公共记录泄漏扫描。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/process_session.rs`、`apps/ai-game-creator-shell/src-tauri/src/command_output.rs`。
|
||||
|
||||
## 自主 Swarm 验收不能把父 project.verify 当成意外确认动作
|
||||
|
||||
- 现象:两个专业 Agent 已完成初始交付,Supervisor 在语义 repair 前合法执行项目宿主验证,但 E2E harness 把所有父 run pending action 一律拒绝,导致真实协作链在业务逻辑正常时提前失败。
|
||||
- 原因:验收器把“repair 前不允许父 Agent 绕过专业工作”错误实现成“父 run 不能出现任何确认动作”,混淆了 Supervisor 自己的 `project.verify` 与会改变专业交付/文件的意外动作。
|
||||
- 处理:确认过滤器必须按 owning run 和 tool 精确判断。repair 前允许当前父 run 的 `project.verify`,仍拒绝其它未列入场景合同的父 pending action;专业 Agent 的修改和验证继续按各自 run、policy 和预期确认集合处理。允许确认不等于通过验收,最终仍由 host oracle、最新 revision verification、delivery/claim/repair 和唯一回复共同裁决。
|
||||
- 验证:自主 suite 必须出现有效 `hostVerificationPassed=true`,同时保持恰好 2 个初始 + 1 个 repair delivery、父计划完成、意外 pending 为 0、Runner 强杀恢复和唯一 Supervisor assistant;若放宽后出现额外父写动作,场景必须失败而不是吞掉。
|
||||
- 关联:`apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e.mjs`、`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`。
|
||||
|
||||
## Provider 全成功的真实报告不能证明显式重试可用
|
||||
|
||||
- 现象:真实 Swarm 报告显示全部 Provider lifecycle completed,E2E 的 retry validator 也没有报错,于是文档把“支持瞬态重试”一并写成已真实验收。
|
||||
- 原因:validator 只在实际出现 failed lifecycle 时校验 retry audit;`failed=0 / retry=0` 会自然通过。随机等待外部网络故障既不可重复,也无法在故障和重试之间证明副作用仍为 0。
|
||||
- 处理:为重试单独建立 fail-first loopback proxy。在正式 AppData 同级创建 sentinel 管理的一次性目录,只覆盖其中一个目标 Agent 的 base URL 和重试配置;首个 POST 在正文进入 upstream 前断线,第二个请求由 forwarding gate 暂停。gate 内交叉检查 failed lifecycle、retry audit、request slot/identity、action、pending、receipt、delivery、claim、assistant、project revision 和目标产物,再显式放行真实 Provider。代理不能记录 URL、headers 或正文,不能跟随 redirect,必须可幂等清理;启动 CLI/Runner 时同时设置合并后的 `NO_PROXY / no_proxy` 并显式加入 loopback,不能假设开发机已正确配置代理绕过;source-dir guard 禁止本 suite 前缀进入源目录,配置和 endpoint 身份保持只读并逐字复核。不要用源目录 mtime/ctime 归因,正式 Runner heartbeat 会并发改变它。完整链在 checkpoint 后失败时,partial report 也要保留已取得的 identity、slot 和零副作用证据,不能退回模板默认值。
|
||||
- 验证:`npm run test -- apps/ai-game-creator-shell/tests/llmTransientFaultProxy.test.ts` 覆盖故障、暂停、base path、流式转发、fallback、隐私和清理;`npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-transient-retry-real-e2e -- --config-dir <AppData>` 必须得到恰好 1 failed/1 retry、重试前副作用全 0,并继续通过完整 Swarm/Runner 恢复和零泄漏门禁。
|
||||
- 关联:`apps/ai-game-creator-shell/scripts/llm-transient-fault-proxy.mjs`、`apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e.mjs`、`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`。
|
||||
|
||||
## Agent 真实验收的阶段等待必须同步观察 Runtime 终态
|
||||
|
||||
- 现象:真实 Provider 已因 transport、格式修复或其它不可恢复错误把 task/Runtime 写成 failed,专项验收仍在等待某个 pending action、observation 或 receipt,直到 30 分钟总超时才返回。
|
||||
- 原因:阶段等待只轮询“想看到的成功证据”,没有同时读取 owning Agent/run 的最新 task 与 Runtime phase;外部错误发生在该证据之前时,目标条件永远不会出现。
|
||||
- 处理:所有分钟级阶段等待都要在每轮先检查 owning task 的 failed/cancelled/budget-exhausted,以及 Runtime 的 needs-reconciliation;命中后立即抛出带阶段前缀的结构化错误。正常 pause 必须保留为可恢复状态,不能被 fail-fast 当失败;Runner 强杀后的 paused 稳定窗口继续按签名零推进单独验证。
|
||||
- 验证:用正式 `goal-runtime` 观察 Provider repair transport failure,确认部分报告立即保留成功/repair 协议计数、生命周期闭合和零泄漏证据;随后完整复跑仍能通过 Goal edit/pause/Runner kill/resume/finalization,证明 fail-fast 未破坏正常恢复路径。
|
||||
- 关联:`apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e.mjs`、`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`。
|
||||
|
||||
## 图片生成的 K 档不能靠回图后缩放实现
|
||||
|
||||
- 现象:用户选择 2K 时占位框看起来是 2K,最终资源元数据也显示为 2K,但模型请求实际仍是固定 1K 或竖版回落尺寸;画面只是后端放大后的低分辨率结果。
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
- (2026-09-24 快照,已被上面 2026-09-29 重新盘点取代)74 份计划里 63 份为 `implemented-awaiting-runtime-acceptance`;当轮未勾选复选框从 85 条降到 43 条。
|
||||
- **路由类门禁已于 2026-09-29 转绿并接进 CI**:`npm run check:nginx-spa-routes` OK(12 路由 / 3 模板)、`npm run check:pingora-route-parity` OK(24 路由)。这条曾经红了一个月(`/components`、`/design-system`、5 条 `/games*` 的 SPA allowlist),收口记录见上面「已关闭」两条;同日还给 parity 门禁补了**反向覆盖**(两份 Nginx 模板里的每条 `location` 都必须被矩阵声明),并将 `check:pingora-gateway-smoke` 扩到覆盖发行网关重写与 Cookie 清空。**根因修复**:两条门禁现在串进 `npm run lint`(⇒ `check:repository-ci` ⇒ CI 与 pre-push 都会跑;`npm run lint` 已实跑全绿),并且 `check:production-ops` 新增两条 guardrail 锁住这个接线——把任一条从 lint 链里拿掉都会立刻变红(变异验证通过)。判据与踩坑见 `pitfalls.md` 同日条目。
|
||||
- 其余门禁(2026-09-24 本机实跑):`ai-game-creator-shell:check:rust:crates` exit 0、`agc:plugins:test` 35 passed、`agc:plugins:native-test` 30 passed、`check:repository-ci origin/master` exit 0(含 admin-web typecheck 与生产构建)。
|
||||
- CI 全部 job 的命令(2026-09-24 起逐条对齐,本机实跑):AGC agent-run smoke `ai-game-creator-shell:agent-run:smoke` passed(本地 provider 桩,约 2.5 分钟);`cargo check --locked -p api-server --all-targets` 与 `-p spacetime-module` exit 0;两把 Cargo.lock 的「构建不改锁」判据以 `--locked` 全绿 + desktop 锁未被构建改动佐证。至此除「AGC Rust 四个分片跑全量(Windows 不实用)」与已记录的 Linux-only 门禁外,CI 每个 job 的命令都有本机结果。
|
||||
- CI 全部 job 的命令(2026-09-24 起逐条对齐,本机实跑):(2026-10-02:AGC agent-run smoke 脚本与 `agc-rust-smoke` CI job 已随自建 Agent Runtime 退役删除,见 `docs/adr/【ADR】退役AGC独立Agent Runtime与CLI执行面-2026-10-02.md`;本行当时的实跑结果仅作历史记录);`cargo check --locked -p api-server --all-targets` 与 `-p spacetime-module` exit 0;两把 Cargo.lock 的「构建不改锁」判据以 `--locked` 全绿 + desktop 锁未被构建改动佐证。至此除「AGC Rust 四个分片跑全量(Windows 不实用)」与已记录的 Linux-only 门禁外,CI 每个 job 的命令都有本机结果。
|
||||
- CI 对齐的其余命令(2026-09-24 本机实跑):`npm run test:ci:frontend` 230 files / 2583 passed / 12 skipped、`npm run bgfilter-worker:smoke-test` 4 passed、`npm run build`(web + admin-web)exit 0;release 分组三步在 Windows 上全部可跑——`ai-game-creator-shell:build --no-bundle`(5m47s,产出 exe)、`desktop-shell:build --no-bundle`(1m29s)、`desktop-shell:stage-release-binary`(修掉 `new URL(...).pathname` 拼出 `F:\F:\…` 的 Windows 路径缺陷后通过)。
|
||||
- 运维类门禁(2026-09-24 本机实跑):`check:pingora-direct-preflight`、`check:pingora-canary-live-guard`、`check:pingora-direct-live-guard`、`check:nginx-pingora-canary` 直接通过;`check:production-api-release`、`check:production-api-deploy`、`check:production-health-patrol`、`check:pingora-release-readiness`、`check:pingora-tls-cert-sync` 是 Linux 生产机/CI 专属(`bash`+`chmod`、`/usr/bin/stat`、`systemctl`、写死的 `npm`、Linux 拷贝语义),本机不跑,已在 pitfalls 记录。
|
||||
- 唯一需要环境变量的是 `check:pingora-gateway-smoke`:本机要先设 `OPENSSL_CONF=C:\Program Files\Git\usr\ssl\openssl.cnf`(Strawberry OpenSSL 自带 config 路径不存在),同时脚本已修掉 Windows 二进制名与并发保护用例的竞态;设好变量后本机 `通过`。
|
||||
|
||||
Reference in New Issue
Block a user