完善Agent最终回复崩溃恢复
新增三阶段 finalization journal,恢复时不重放 LLM、工具或回执 为会话消息增加兼容 messageId 与审计幂等自愈 补齐取消、revision 漂移、状态丢失、损坏文件和跨平台替换恢复 增加并发锁短等待、长回复容量与故障注入回归 同步 AI 游戏创作 App 技术方案和项目决策记录
This commit is contained in:
@@ -55,7 +55,9 @@ Agent Runtime 负责:
|
||||
- 2026-07-10 补充:后台 Runtime 每次追加 `.agent/runtime/events/<agentId>.jsonl` 后会通过 Tauri `game-creator-agent-runtime-update` 事件广播当前 `AgentRuntimeResult`,开发单 Agent 聊天页、项目内 Agent 对话弹窗和主窗口 Agent 状态卡用同一套前端归一化逻辑合并状态;该事件只做实时 UI 通知,`.agent/runtime/agents`、`events` 和 `tasks` 仍是重开项目后的事实源。
|
||||
- 2026-07-10 补充:后台 Agent loop 的统一语义事件类型为 `thinking_summary / plan / action / observation / response / error`。普通失败和 loop 预算耗尽都会追加 `error` 事件,并继续保留 `turn.failed / turn.budget_exhausted` 生命周期事件兼容既有读取方;开发窗口、项目内 Agent 对话弹窗和主窗口状态卡通过现有最近事件列表直接展示统一错误事件及其安全详情。状态面板默认保持最新 4 条的紧凑视图,当前后端返回的最近事件超过 4 条时可展开查看全部返回记录,确保同一 run 的六类语义事件不会因 UI 硬截断而无法检查。
|
||||
- 2026-07-11 补充:开发单 Agent 聊天页继续使用整页纵向滚动,不把 Runtime 锁进固定视口;聊天消息区使用固定响应式高度并在内部滚动,避免历史消息持续撑高聊天面板。可选的 Runtime 恢复确认区始终占据独立布局行,不能与 Runtime 详情或聊天消息重叠。Runtime 状态面板支持折叠详情,折叠时只卸载目标、计划、事件、动作和任务等详情 DOM,仍保留状态标题与取消、重试、确认、拒绝、刷新操作;等待 LLM 时在消息区持续显示连接 / 等待首包 / 接收中的动态状态和“请求仍在进行中”提示。流式聊天的连续 delta 通过 `requestAnimationFrame` 合并为每帧最多一次消息更新,delta 不重复提交未变化的 Runtime state;OpenAI Chat SSE 的空数组或 `null` `choices` 心跳 / 元数据事件会跳过,usage-only 尾包会回填最终 token usage,finish-only 事件会把结束原因送入状态流,上游 error 保留真实消息,`[DONE]` 立即结束读取;正文与 finish reason 已接收后即使尾包异常也保存完整正文,不再改判整轮失败。持久事件订阅失败时显示非致命 Runtime 错误,聊天事件监听不可用或流式请求在首个文本片段前失败时自动降级普通回复。
|
||||
- 2026-07-12 调整:开发单 Agent 对话框新增 `执行 / 聊天` 分段模式,默认 `执行`。默认发送直接调用 `start_game_creator_agent_runtime_task`,复用工具规划、权限确认、取消、队列和 Runtime 实时状态;`聊天` 作为显式模式继续走不执行工具的流式回复。消息区在 Runtime 启动、排队、等待 LLM、执行工具、等待确认和同步终态回复期间持续显示当前状态,不再要求开发者从页头文案猜测请求是否仍在运行;原独立“后台运行”按钮移除。Runtime 必须先取得项目写锁并重读项目 revision 与当前 run 的 verification gate;只有 run 从未要求验证,或成功验证绑定的 revision 与锁内当前 revision 完全一致,才允许在同一把锁内先把最终 assistant 回复可靠写入当前 Agent Session,再写 completed 终态并广播事件。每次可形成最终回复的 planning 请求或独立 final reply 请求开始前都记录 `responseRevision`;回复完成后锁内当前 revision 与它不同即返回可恢复 `Stale`,该规则同样覆盖 `requiresVerification=false` 的只读 run。旧回复不得进入会话或 completed,Runtime 记录 completion blocker、`response.stale` 事件与审计,并保持原 Agent、Task、Session、Run、loop 计数和 per-Agent 锁回到 planning,重新读取或验证当前项目状态后再生成回复。revision / gate 读取失败、stale continuation 持久化失败或对话写入失败仍进入 failed。前端只对当前项目、Agent、Session 和 runId 匹配的终态事件自动重读对话,直到看到新 assistant 消息或重试结束,切换 Session 后旧 run 不得污染当前聊天记录。
|
||||
- 2026-07-12 调整:开发单 Agent 对话框新增 `执行 / 聊天` 分段模式,默认 `执行`。默认发送直接调用 `start_game_creator_agent_runtime_task`,复用工具规划、权限确认、取消、队列和 Runtime 实时状态;`聊天` 作为显式模式继续走不执行工具的流式回复。消息区在 Runtime 启动、排队、等待 LLM、执行工具、等待确认和同步终态回复期间持续显示当前状态,不再要求开发者从页头文案猜测请求是否仍在运行;原独立“后台运行”按钮移除。Runtime 必须先取得项目写锁并重读项目 revision 与当前 run 的 verification gate;只有 run 从未要求验证,或成功验证绑定的 revision 与锁内当前 revision 完全一致,才允许在同一把锁内先把最终 assistant 回复可靠写入当前 Agent Session,再写 completed 终态并广播事件。完成预检、finalization、恢复和取消收束遇到同项目另一个 Agent 的短暂写锁时,最多等待约 1 秒后重试;锁持续占用才返回 blocker,不能把毫秒级竞争误判为验证缺失并重新请求 LLM。每次可形成最终回复的 planning 请求或独立 final reply 请求开始前都记录 `responseRevision`;回复完成后锁内当前 revision 与它不同即返回可恢复 `Stale`,该规则同样覆盖 `requiresVerification=false` 的只读 run。旧回复不得进入会话或 completed,Runtime 记录 completion blocker、`response.stale` 事件与审计,并保持原 Agent、Task、Session、Run、loop 计数和 per-Agent 锁回到 planning,重新读取或验证当前项目状态后再生成回复。revision / gate 读取失败或 stale continuation 持久化失败仍进入 failed;一旦 finalization journal 已进入 `prepared`,后续对话或终态落盘失败改为保持可恢复 `finalizing`,不得把当前 run 误记为 failed。前端只对当前项目、Agent、Session 和 runId 匹配的终态事件自动重读对话,直到看到新 assistant 消息或重试结束,切换 Session 后旧 run 不得污染当前聊天记录。
|
||||
- 2026-07-12 补充并冻结:后台最终回复通过 `.agent/runtime/finalizations/<agentId>/<runId>.json` 的 `game-creator-runtime-finalization.v1` journal 跨越多文件落盘,状态严格按 `prepared -> assistant-persisted -> runtime-completed` 推进,终态可靠投影后删除 journal。journal 绑定项目、Agent、Task、Session、Run、source、父委派身份、任务正文、回复指纹、`responseRevision`、verification gate、`finalizationId` 和稳定 `messageId`;finalization 单独使用 512 KiB 上限,必须容纳 32,000 字符的最大合法回复及元数据。跨平台替换先写临时文件;目标平台不能原子覆盖旧文件时,先把旧 journal 原子移动为同目录 `.previous` 恢复副本,再安装新文件,读取时主文件缺失必须回退恢复副本,成功推进或终态清理时同时删除副本,禁止先删除唯一旧 journal。`resume` 在 pending action、普通 running/pending task 和 delegate receipt 修复之前优先恢复 finalization,只按 journal 补齐 assistant 与终态,不重新请求 LLM、不重放工具或 receipt 任务;Runtime state 只是可重建投影,状态文件缺失或损坏但 task ledger 仍能唯一定位主 journal 或恢复副本时,必须从 task ledger 重建同一 run 后继续恢复。`prepared` 且 assistant 尚未落盘时若任务已取消,或当前 revision / verification gate 已使回复过期,则丢弃 journal,分别保持取消终态或回到同 run planning;assistant JSONL 是用户可见提交点,取消 command 必须在持有 per-Agent 锁后检查 journal,assistant 尚未存在时立即删除 prepared journal 再取消,assistant 已存在时则完成原 finalization 并忽略迟到取消,不能留下孤儿 journal 或把可见回复改判为 cancelled。journal 损坏、版本不支持、身份/回复指纹/幂等 ID 冲突必须 fail closed,并把同一 live run 投影为 `status=running / phase=finalizing` 供 UI 明确显示,不能降级为普通任务恢复。
|
||||
- 2026-07-12 补充并冻结:本地 conversation JSONL 的 `messageId` 是可选向后兼容字段,旧记录无需迁移仍可读取。finalization 使用稳定 `messageId` 幂等追加 assistant;同一 Agent / Session 下相同 ID 且 role/content 一致时不得重复写 JSONL,若消息已存在但 `.agent/agent.db` 缺少对应 `conversation.message` audit,重试必须在 audit 追加锁内补写一次,已有 audit 不重复;同一 Agent / Session 作用域下相同 ID 对应不同 role 或 content 时继续按冲突失败关闭。completed task JSONL、Runtime state、`turn.completed / response` 事件、`agent.runtime.completed / background_task.completed` audit、pending/confirmation 清理和 delegate result 发布均按既有身份幂等补齐,重启不得制造第二份终态投影。
|
||||
- 2026-07-11 补充:后台单 Agent 新增 Codex 风格的代码导航与局部编辑闭环。`project.search` 接受 `query / path / maxResults / caseSensitive`,在项目边界内做字面量搜索并返回 `path:line`,最多扫描 500 个、单个不超过 512 KiB 的文本文件,跳过 `.agent`、`.git`、`node_modules`、`dist`、`build`、`target`、`.next`、`coverage` 和 `.env*`;该工具映射到 `file.read` 权限。`file.read` 接受 `startLine / maxLines`,返回带行号的指定片段、总行数和下一页提示,单次最多 240 行、8,000 字符。`file.patch` 接受 `path / oldText / newText / expectedReplacements`,只在实际匹配数与预期一致时持锁写入,目标文件和修改后文件最大 2 MiB,成功后写 `agent.runtime.file.patch` 审计;该工具映射到 `file.write` 权限。Agent planning prompt 明确要求批量修改前创建 checkpoint,并可在修改后再次 `file.read` 验证;本轮不开放任意 shell 命令。
|
||||
- 2026-07-11 补充,2026-07-12 更新:代码修改后的真实验证由开发专用 `project.verify` 承接。输入固定为 `script / expectedCommand / timeoutSeconds`;`script` 允许项目根 `package.json` 中的固定脚本 `check / typecheck / test / lint / build`,以及以 `check: / test: / lint: / typecheck: / build: / verify: / validate:` 开头、后缀由安全非空段组成的命名脚本。脚本必须真实存在于项目根普通文件 `package.json` 的 `scripts` 中,`expectedCommand` 必须与执行时重新读取的脚本正文完全一致,`timeoutSeconds` 为 1-300;当前执行器只支持 npm,非 npm `packageManager` 或 pnpm / yarn / bun 锁文件明确失败,不接受自由命令、参数或工作目录。`pre* / post*` 生命周期脚本名不在允许范围,执行器再通过 npm `--ignore-scripts` 禁止所选脚本关联的 pre/post lifecycle。工具映射到独立且默认需确认的 `project.verify` 权限,确认动作指纹绑定完整输入,不再因为放行验证而同时放行 `command.run_limited` 静态 smoke。执行器由 npm 运行已确认脚本,使用空 stdin、隔离 HOME/TMP/cache、清理后的环境、独立进程组和有界脱敏输出;Unix 下无论根进程正常结束还是超时都会清理同组残留后代。项目写锁记录 PID 和唯一 nonce,活进程继续持锁,Unix 死进程锁或跨平台超过安全时限的无效锁可回收,且控制路径拒绝符号链接。进入进程执行后的终态写命令日志和 manifest command run,Agent 触发时另写 `agent.runtime.project.verify`;输入预检拒绝只写 Runtime observation / error 事件。失败输出作为 observation 回到下一轮 planning。项目级 revision 独立持久化到 `.agent/runtime/project-revision.json`;每个 run 的 gate 与验证结果持久化到 `.agent/runtime/verification/<agentId>/<runId>.json`。`file.write / file.patch / project.restore` 在项目写锁内、实际修改前先保守推进 revision,并把 `requiresVerification` 单向置为 `true`,操作失败或崩溃也不回退;成功的 `project.verify` 或 `command.run_limited / game.static_smoke` 只为执行时的当前 revision 写入凭证。空 actions 前如果门禁仍要求验证、验证失败或凭证 revision 已过期,Runtime 注入 `runtime.verification: blocked` 并继续 replan;多窗口重复无进展而以 `loop-budget-exhausted` 终止时,仍未形成当前 revision 的通过结果则保持失败。该能力会执行用户项目脚本,环境隔离不是 OS 沙箱;普通用户 `/smoke` 与 `game.static_smoke` 保持原边界,不暴露该开发工具。
|
||||
- 2026-07-11 补充:开发验证可用 `npm run ai-game-creator-shell:agent-task -- [--init] <projectPath> <agentId> <task>` 无 UI 启动单 Agent 后台任务。CLI 只负责可选初始化、调用现有 Runtime、按 runId 轮询终态并打印 `status / phase / replyText / pendingActionId`,不复制 planning 或工具执行逻辑;默认 10 分钟轮询上限。`waiting-for-confirmation` 会以非零状态退出并要求转到开发窗口确认,CLI 不提供跳过项目权限的自动确认参数。该入口用于真实 provider 的可重复端到端验收,不进入普通用户界面。
|
||||
|
||||
Reference in New Issue
Block a user