-
released this
2026-07-21 11:46:15 +08:00 | 6 commits to master since this release本次版本聚焦并行工具审批体验与安全频率限制两大方向。共 1 次提交,修改 11 个文件,+608 / -177。
一、工具批量审批(核心特性)
问题现象
- Agent 并行调用多个需要确认的工具(如 5 个 read_file)时,后端
pendingConfirmationsMap 本身支持并发,但前端ConfirmationDialog用单值 state,多个tool:confirmationRequestIPC 事件几乎同时到达会互相覆盖 - 最终 UI 只显示最后一个请求,前 4 个 request 在 120 秒超时后全部 reject,导致 4 个工具自动失败
- 同一工具多次调用场景下,
rememberedDecisions缓存按 toolName 写入,但并发场景下 5 个调用同时进入beforeExecute时缓存还没写入,5 个全部触发 IPC 请求
修复方案
后端(confirmation-hook.ts):
- 扩展
pendingConfirmationsMap 类型,缓存 args/riskLevel/reason 完整请求信息 - 新增
resolveConfirmationsBatch(toolCallIds, approved, remember, autoExecute)批量处理 - 新增
getPendingConfirmations()供前端主动拉取已积压的请求 - remember/autoExecute 按 toolName 去重写入,避免 Map 重复赋值
IPC 层(handlers.ts / preload.ts):
- 新增
tool:confirmationResponseBatchIPC 通道(ipcMain.on) - 新增
tool:getPendingConfirmationsIPC 通道(ipcMain.handle) - 严格参数校验(toolCallIds 必须是非空字符串数组,approved 必须是 boolean)
- preload 暴露
sendConfirmationResponseBatch和getPendingConfirmationsAPI
前端(ConfirmationDialog.tsx):
- state 从单值
request改为数组requests: ConfirmationRequest[] - 弹框打开时主动调用
getPendingConfirmations拉取已积压请求,解决 state 覆盖丢失 - 同工具多次调用按 toolName 分组展示(如
read_file (×5)) - 支持批量勾选 / 批量批准 / 批量拒绝
- 三种操作按钮:拒绝全部 / 批准全部 / 批准选中(动态文案)
- 倒计时取最早过期的,进度条按最早过期算
- 全部使用 MUI 组件(Dialog/List/ListItem/Accordion/Checkbox/Chip/Button)
二、审批弹框健壮性增强
超时 toast 防风暴
问题:5 个并行工具全部超时会触发 5 个 toast:show 事件,用户看到 5 条几乎相同的警告。
修复:加
lastTimeoutToastAt时间戳,3 秒节流。消息改为汇总形式:工具确认超时(120秒),N 个工具未执行。agent 状态同步
问题:abort 场景下后端
clearPending()清空 Map,但前端 requests state 不会自动同步,弹框会停留在已失效的请求上。修复:监听
agent:stateChange,收到 INIT(新 run 开始)或 TERMINATED(run 结束/abort/超时)时清空前端 state。批准选中保留未选中项
问题:用户点击"批准选中",只有选中的 toolCallId 被处理,未选中的仍 pending。但原代码
setRequests([])会清空所有,导致 Dialog 关闭,用户看不到未选中的 pending,120 秒后超时失败。修复:
onlySelected=true时只从 requests 中移除已处理的 toolCallId,保留未选中的。若保留后 requests 为空,setTimeout主动拉取后端最新 pending。Dialog onClose 一致性
问题:isExpired 时"拒绝全部"按钮 disabled,但 Dialog 的 onClose 仍会触发拒绝全部,与按钮状态不一致。
修复:isExpired 时 onClose 直接 return,禁止关闭。正常情况下只在 backdropClick/escapeKeyDown 时触发拒绝全部。
ErrorBoundary 防白屏
用
ErrorBoundary包裹ConfirmationDialog,即使弹框内部抛异常也不会白屏整个应用,显示"工具确认弹框渲染失败"降级 UI + 错误消息 + 重试按钮。三、run_command 频率限制优化
问题
run_command的maxFrequency配置为 3(每分钟最多调用 3 次),正常开发场景 Agent 经常需要连续跑命令,第 4 次调用被拦截返回Rate limit exceeded for run_command: max 3 calls per minute (current: 3)。修复
maxFrequency从 3 调整为 10,与file_editor/git_commit同档。工具 maxFrequency 风险等级 run_command 3 → 10 EXTERNAL_ACTION write_file 5 WRITE file_editor 10 WRITE git_commit 10 WRITE web_browser 20 EXTERNAL_ACTION delete_file 30 WRITE run_command已有requireConfirmation: true作为主要安全防线,10 次/分钟仍能防止失控循环。四、开发规范补充
新增 3.2 Toast 通知铁律
所有 Toast 通知必须使用项目封装的
MeToast组件,禁止自写 Toast 组件、禁止直接使用第三方 Toast 库(notistack、react-hot-toast、react-toastify 等)。场景 规范 前端主动显示 Toast 使用 MeToast组件(通过showToast()或对应 hook 调用)后端通过 IPC 触发 Toast 主进程发送 toast:showIPC 事件,参数{ type, message },前端 MeToast 监听并统一渲染type 枚举 success/info/warning/error四种并行事件防风暴 同一来源的并行事件需在后端节流 本次 toast 防风暴实现(
lastTimeoutToastAt3 秒节流)符合新规范。五、改动文件清单
文件 改动 electron/harness/hooks/confirmation-hook.ts 接口加 expiresAt 字段;新增 resolveConfirmationsBatch / getPendingConfirmations;toast 防风暴 electron/harness/sandbox/permissions.ts run_command maxFrequency: 3 → 10 electron/ipc/handlers.ts 新增 tool:confirmationResponseBatch / tool:getPendingConfirmations IPC electron/preload.ts 暴露 sendConfirmationResponseBatch / getPendingConfirmations src/App.tsx 用 ErrorBoundary 包裹 ConfirmationDialog src/components/ConfirmationDialog.tsx 完全重写为批量列表 UI src/types/global.d.ts MetonaConfirmationRequest 加 expiresAt;MetonaToolAPI 加两个新方法 standard/开发规范.md 新增 3.2 Toast 通知铁律 package.json / package-lock.json / README.md 版本号 0.3.8 → 0.3.9 六、升级说明
- 直接拉取 master 分支或 v0.3.9 tag
npm install后npm run dev启动- 无数据库 schema 变更,无需迁移
- 与 v0.3.8 完全兼容
Downloads
- Agent 并行调用多个需要确认的工具(如 5 个 read_file)时,后端