补齐Agent自动工具动作恢复屏障

自动工具动作使用耐久账本记录 approved、executing 与 observed 状态,按崩溃点恢复精确动作或观察
将 needs-reconciliation 提升为 Agent 队列屏障,并在系统锁内按 FIFO 启动 pending 任务
补充自动动作恢复、策略收紧、审计配对、核对队列与并发配置回归测试
同步 Agent Runtime 决策和实施计划,修正项目策略确认文案断言
This commit is contained in:
AIGameCreator App
2026-07-10 15:51:14 +08:00
parent c88c94b98c
commit aea75ef701
5 changed files with 1563 additions and 107 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -185,7 +185,9 @@ describe('AI 游戏创作聊天记忆命令', () => {
},
'/tmp/game',
),
).toBe('写入 /tmp/game/.agent/policy.json · 拒绝:file.write · 确认:无');
).toBe(
'写入 /tmp/game/.agent/policy.json · 拒绝:file.write · 确认:无 · Agent:无 Agent 独立策略',
);
});
it('describes canvas asset imports before confirmation', () => {
@@ -4072,6 +4072,8 @@
- 2026-07-10 调整:Agent Runtime 和本地对话使用 append-only JSONL 作为事实源时,进程内必须按目标文件路径串行追加整行。`.agent/agent.db``.agent/conversations/**/*.jsonl``.agent/runtime/events/*.jsonl``.agent/runtime/tasks/*.jsonl``.agent/activity.jsonl``.agent/output.jsonl` 统一走共享追加 helper,避免多个后台 Agent 并行完成时 JSON record 与换行交错。
- 2026-07-10 调整:Agent Runtime 待确认工具动作改用 durable `AgentRuntimePendingToolAction`。Runtime 将精确 `action` 输入、当前 task/run、loop 轮次、action 序号、计划、已有 observations 与后续 loop 所需上下文先做敏感内容和项目绝对路径校验,再通过临时文件替换原子写入 `.agent/runtime/pending-actions/<agentId>/<runId>.json`;公共 runtime state 的 `pendingToolAction` 只暴露 `actionId / actionFingerprint / tool / inputSummary / reason / requestedAt` 安全摘要,完整输入不进入公共状态。`actionFingerprint` 绑定工具名、完整输入 JSON 与实际执行使用的 task context`actionId` 还绑定 run、loop、action 序号和 occurrence nonce,使同一 run 内输入相同的两次动作仍是两个不同发生。确认和拒绝都必须匹配 `runId + actionId`,Runtime 会重算指纹并与私有落盘动作及公共摘要交叉校验,不一致时失败关闭。确认通过后在同一 run 直接执行持久化的原 action,把真实 observation 接回后续 Agent loop,不创建新 run,也不让模型重复生成待确认动作;拒绝不执行工具,写入 `blocked` observation 后在同一 run 继续规划。待确认账本按 `pending-confirmation / approved / executing / observed-approved / observed-rejected` 迁移:重启时 `approved` 可恢复精确动作,已持久化 observation 可直接续 loop`executing` 表示外部副作用结果未知,Runtime 必须进入 `failed / needs-reconciliation` 并禁止自动重放,开发者核对项目状态后只能先取消原任务。waiting run、完整待确认动作和安全摘要均已落盘,App 重启不会越过该 run 去启动后续任务;等待期间同 Agent 新任务只保持 `pending`,确认、拒绝或取消结束后再由同一 drain 串行排空。`.agent/runtime/` 是 Runtime 私有控制面,通用 `file.list / file.read / file.write / file.delete` 不得列出、读取、修改或删除;checkpoint/index/diff/restore 继续整体排除该目录。每 Agent 锁包含唯一 token,旧持有者析构时只删除自己的锁;Linux 上其他仍存活进程的锁不会因超过固定时长被抢占。确认、拒绝及工具 observation 分别写入 `agent.runtime.tool_confirmation.approved``agent.runtime.tool_confirmation.rejected``agent.runtime.tool_observation` 审计;pending 和 confirmation 文件只在 observation/终态可靠落盘后清理,失败清理会显式报错。
- 2026-07-10 调整:per-agent 互斥锁最终改用 OS 级文件锁,而不是依赖 JSON token、PID、超时和 `remove + create_new` 竞争所有权。Unix 使用非阻塞独占 `flock`,Windows 使用禁止共享的文件句柄;锁文件只保留诊断元数据并长期存在,进程退出会由 OS 释放所有权。确认、拒绝和取消必须先取得同一系统锁,再重新读取 runtime、latest task 和 durable pending action 后迁移状态;恢复入口也必须先拿锁,再读取 durable pending action 或 recoverable task,禁止用锁外旧快照覆盖并发结果。waiting 取消只短暂等待原 worker 释放系统锁,running 取消拿不到锁时只保留 tombstone,并由原 worker 在 LLM / 工具成功或失败返回后的检查点收束,不得根据 Runtime status 抢锁。这条最终实现取代上一条中的 token 删除和 Linux PID 存活判断描述。
- 2026-07-10 调整:`AgentRuntimePendingToolAction` 同时作为白名单自动工具的精确动作账本,新增 `executionMode = auto | confirmation`。自动动作执行前必须依次持久化 `approved``executing`,工具返回后先持久化 `observed-approved` observation,再写 Runtime task/state/event/audit;账本必须覆盖后续 LLM replan,只有下一条精确动作以新账本接管,或当前 run 的 completed / failed / cancelled 终态可靠落盘后才能清理。App 在 `approved + auto` 崩溃点可恢复同一精确动作,在 `observed-approved + auto` 崩溃点只能复用 observation 继续规划,不得重放工具;`executing + auto` 一律进入 `failed / needs-reconciliation``needs-reconciliation` 是恢复硬屏障,即使磁盘账本因前一轮写入失败仍停在 `approved` 也不得继续执行或排空队列。恢复时若项目策略从 auto 收紧为 confirm,原 action 保持同一 actionId / fingerprint 并转回 `pending-confirmation + confirmation`,等待开发者决定。自动动作另写 `agent.runtime.tool_action.executing``agent.runtime.tool_action.observed``agent.runtime.tool_action.needs_reconciliation` 审计。
- 2026-07-10 调整:`needs-reconciliation` 同时是整个 Agent 队列的准入屏障,不只保护当前 pending action。屏障存在时,通过开发窗口、`agent.delegate``agent.schedule_ready` 投递的新 run 只能追加为 `pending`,任何恢复和 drain 都不得启动后续任务;取消某个排队 run 也不能越过核对 run 去启动再后面的任务。新任务的 waiting / cancelling / reconciliation 准入判断必须在成功取得该 Agent 的 OS 锁后重新读取,禁止用锁外快照启动新 run;通过检查后也必须从 task JSONL 选择最早的 pending run 作为队首启动,不能直接启动当前调用方刚提交的 run。即使私有 pending ledger 意外缺失,也必须从 Runtime state 或 task JSONL 的最新 `needs-reconciliation` 记录识别屏障,继续禁止 retry;开发者人工核对后显式取消该 run,才允许既有 per-agent drain 按顺序恢复队列。
- 2026-07-10 调整:Agent Runtime 工具箱新增 `task.create`,用于让 Agent 把目标拆成新的 manifest 任务,而不只能更新 seed task。该工具默认 `confirm` 权限,写入前要求 taskId 唯一、依赖指向已有任务、列表长度受限,并写 `agent.runtime.task.create` 审计;策略要求确认或拒绝时不修改 `.agent/manifest.json`
- 2026-07-10 调整:Agent Runtime 新增 `agent.schedule_ready` 调度入口,默认 `confirm` 权限。命令会扫描 `.agent/manifest.json` 中依赖已完成且仍为 `pending` 的 ready task,先把任务标成 `running`,再用 taskId 作为 Agent id 投递到既有后台队列,source 记为 `agent-ready-task-scheduler`,并写 `agent.runtime.ready_task.scheduled` 审计;后续执行仍走原 per-agent 锁、任务 JSONL、LLM loop、工具策略和事件流,不新增独立 worker。默认确认策略下该命令不会静默调度。
- 2026-07-10 调整:Agent Runtime state 新增 `recentToolCalls`,后台 loop 每次执行白名单工具后记录最近 20 条结构化动作,包含 tool、status、actionFingerprint、inputSummary、reason、summary、detail 和 updatedAt。状态面板展示最近动作与安全目标摘要时使用该字段,不解析 observation 文本;写入前继续过滤敏感上下文,不保存原始密钥、待写正文或任意未过滤输入。
@@ -42,6 +42,8 @@ Agent Runtime 负责:
- 2026-07-10 补充:本地 append-only JSONL 追加写入按目标文件路径做进程内串行化。`.agent/agent.db`、项目 / Agent 对话、Runtime events、Runtime tasks、Agent activity 和 output 都通过共享 helper 写入完整 JSON 行,防止多个后台 Agent 并行运行时 record 内容与换行交错;该约束服务于当前单客户端进程内并行,不把跨进程同项目写入作为 v1 支持目标。
- 2026-07-10 补充:后台 Agent 待确认工具动作改用 durable `AgentRuntimePendingToolAction`。完整记录包含精确工具 action、当前 task/run、loop 轮次、action 序号、计划、已有 observations 和续跑上下文;写入前拒绝密钥、Token、Cookie、App 配置痕迹和项目绝对路径,再通过临时文件替换原子写入 `.agent/runtime/pending-actions/<agentId>/<runId>.json`。公共 runtime state 的 `pendingToolAction` 只暴露 `actionId / actionFingerprint / tool / inputSummary / reason / requestedAt` 安全摘要。`actionFingerprint` 绑定工具名、完整输入 JSON 与实际执行 task context`actionId` 再绑定 run、loop、action 序号和 occurrence nonce,防止同一 run 内相同输入的旧 UI 点击批准后一次动作。开发窗口和项目内 Agent 面板的“确认继续 / 拒绝并继续”都提交当前 `runId + actionId`,Runtime 与私有动作、公共摘要交叉校验后才迁移账本状态。确认后在同一 run 直接执行原 action 并把 observation 接回后续 loop,不创建新 run、不要求模型重复动作;拒绝不执行工具,写 `blocked` observation 后在同一 run 继续规划。账本状态使用 `pending-confirmation / approved / executing / observed-approved / observed-rejected`:重启可恢复 waiting、未执行的 approved action 或已落盘 observation;若进程中断在 `executing`Runtime 进入 `failed / needs-reconciliation`,禁止自动重放外部副作用,开发者核对项目状态后先取消原任务。等待期间同 Agent 新任务保持 `pending`,重启不会越过 waiting run,确认、拒绝或取消后再串行排空。`.agent/runtime/` 作为私有控制面,不允许通用文件工具列出、读取、写入或删除;每 Agent 锁使用唯一 token,旧持有者不会删除替换后的新锁,Linux 上仍存活的其他进程锁不会按超时强占。
- 2026-07-10 补充:per-agent 锁最终采用 OS 级文件锁,取代上一条末尾的 token/PID/超时抢占方案。Unix 使用非阻塞独占 `flock`,Windows 使用禁止共享的文件句柄;`.agent/runtime/locks/<agentId>.lock` 只保存诊断元数据并可长期存在,真正所有权随文件句柄和进程生命周期释放。任何确认、拒绝、恢复、取消和队列 drain 都必须使用同一系统锁;确认、拒绝和取消只能在拿锁后重新读取当前 runtime、task 与待确认动作再迁移状态,恢复也必须先拿锁再读取 durable pending action 或 recoverable task,不能用拿锁前的旧快照覆盖并发结果。waiting 状态只允许短暂等待原 worker 正常释放,不得按状态删除并重建锁文件;running 取消在拿不到锁时只保留取消 tombstone,由原 worker 在 LLM / 工具成功或失败返回后的检查点收束。
- 2026-07-10 补充:白名单自动工具也必须使用 durable `AgentRuntimePendingToolAction`,并以 `executionMode = auto` 区别待开发者确认的动作。Runtime 在副作用前依次落盘 `approved``executing`,返回后落盘 `observed-approved` 和 observation;该账本继续覆盖下一轮 LLM planning,直到下一条精确动作接管或 completed / failed / cancelled 终态可靠落盘,不能在 observation 刚落盘时提前删除。恢复 `approved + auto` 时执行同一 action 一次,恢复 `observed-approved + auto` 时只把 observation 交回 Agent,恢复 `executing + auto` 时停止在 `failed / needs-reconciliation`;该核对阶段是硬屏障,即使磁盘仍是 `approved` 也禁止继续。恢复时策略由 auto 收紧为 confirm,则保留原 actionId / fingerprint 并转换成 `pending-confirmation + confirmation`。自动动作在 `.agent/agent.db``agent.runtime.tool_action.executing``agent.runtime.tool_action.observed``agent.runtime.tool_action.needs_reconciliation` 审计。
- 2026-07-10 补充:`needs-reconciliation` 按 Agent 队列级屏障处理。该 Agent 的新聊天后台任务、delegate 和 ready-task 调度仍可入队,但只能保持 `pending`;恢复、正常 drain 和取消其他排队 run 后触发的 drain 都不得越过当前核对 run。新 run 只能在取得 per-agent OS 锁后重新读取 waiting / cancelling / reconciliation 状态并通过准入检查,不能在锁外检查后直接启动;锁内通过检查后统一从 task JSONL 选择最早 pending run,保证并发投递时仍按 FIFO 启动。屏障判定同时读取当前 Runtime state 与 task JSONL 最新记录,因此 pending ledger 缺失时也不放行、不允许 retry;开发者核对外部副作用后必须显式取消该 run,后续队列才继续。
- 2026-07-10 补充:后台任务工具箱已加入 `task.create`。Agent 可在 loop 中把拆解出的后续工作追加为 manifest 任务;Runtime 复用 `task.create` 策略和项目写锁,写入前校验 taskId 唯一、依赖指向已有任务、任务分组合法、标题 / 角色非空以及列表长度,并写入 `agent.runtime.task.create` 审计记录。策略要求确认或拒绝时不会修改 manifest。
- 2026-07-10 补充:Agent Runtime state 新增 `recentToolCalls`,每次后台工具执行后记录最近 20 条结构化工具动作,包含 tool、status、actionFingerprint、inputSummary、reason、summary、detail 和 updatedAt;开发窗口、项目内 Agent 对话弹窗和主窗口 Agent 状态列表可直接展示“最近动作”和安全目标摘要,不再只能从 observation 字符串里猜测 action / observation 对应关系。`inputSummary` 只保留相对路径、checkpoint id、目标 Agent、内容字符数等确认所需信息,不保存原始 API Key、待写正文、消息正文、素材 prompt 或任意未过滤输入。
- 2026-07-10 补充:Agent Runtime state 新增 `currentGoal``waitingOn`,把本轮目标与当前等待对象从 `currentTask / currentAction / nextStep` 中显式拆出来;后台任务启动、工具 observation、完成和失败都会刷新该状态,开发窗口、项目内 Agent 对话弹窗、主窗口 Agent 状态列表、`agent.run_status` observation 和下一轮 planning prompt 都展示同一份目标 / 等待信息,避免开发者只能从动作文本里猜 Agent 卡在 LLM、工具、同伴还是人工输入。