ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Airi computer-use-mcp 浏览器修复契约:让浏览器自动化错误可分类、可诊断、可自愈

Airi computer-use-mcp 浏览器修复契约:让浏览器自动化错误可分类、可诊断、可自愈 Airi computer-use-mcp 浏览器修复契约让浏览器自动化错误可分类、可诊断、可自愈【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi浏览器自动化最让 Agent 头疼的并非不会操作而是操作失败后不知道该做什么选择器没匹配、元素被遮挡、动作超时、frame 被分离……如果每次失败都把原始错误文本丢给上层模型Agent 只能靠猜。Airi 的computer-use-mcp服务在src/browser-dom/browser-repair-contract.ts中实现了一套浏览器修复契约Browser Repair Contract把浏览器 DOM 操作的常见失败模式归类为有限的几类并给每一类绑定一个既有的恢复工具与一段可直接回填给模型的操作指引。本文以 验证契约文档 为骨架结合源码、测试用例与验证流程完整拆解这套机制的契约结构、实现原理与验证方法。读完你将掌握如何在浏览器自动化栈中建立错误分类 → 恢复建议 → 回传模型的修复闭环以及如何复现该模块的全部验证命令。一、为什么需要修复契约从原始报错到结构化建议computer-use-mcp是 Airi 的本地 macOS 桌面编排 MCP 服务负责把桌面控制与浏览器 DOM 控制统一到一个可观测、可审计的工具面见 services/computer-use-mcp/README.md。它明确区分桌面控制与浏览器 DOM 控制两种执行面桌面侧通过坐标注入鼠标键盘浏览器侧则通过 Chrome 扩展桥接browser DOM bridge以 CSS 选择器为粒度操作页面。选择器驱动的操作天然脆弱页面异步渲染、路由跳转、SPA 重渲染、iframe 生命周期都会让一条刚才还成立的选择器瞬间失效。如果失败响应只包含一行英文错误文本上层 Agent 无法稳定判断这是选择器过期还是元素被遮挡还是应该再等一会儿。修复契约解决的正是在这个环节错误分类把千变万化的报错字符串映射到有限的、语义明确的失败类型pattern恢复建议为每个失败类型绑定一个既有的 MCP 恢复工具suggestedTool及其参数suggestedParams模型可消费生成一段可直接拼接进工具响应文本的操作指引reactionText让模型无需猜测即可执行下一步。这套机制定义在 browser-repair-contract.ts由 register-tools.ts 在浏览器 DOM 工具出错时调用并由两个测试文件共 12 个用例验证见 browser-repair-contract.test.ts 与 register-tools-pty-approval.test.ts。二、契约的数据结构BrowserRepairSuggestion契约的产出是一个BrowserRepairSuggestion对象字段定义如下源码 browser-repair-contract.ts字段类型含义patternstring匹配到的错误模式标识例如element_not_foundreasonstring人类可读的失败原因说明suggestedToolstring可用于恢复的既有 MCP 工具名suggestedParamsRecordstring, unknown恢复工具的建议参数reactionTextstring可追加到工具响应文本中的简短操作指引可以看出契约的输出刻意做成模型友好suggestedToolsuggestedParams是机器可直接调用的目标reason与reactionText则是供模型理解上下文与编排下一步的自然语言。二者合一既是诊断结论也是恢复预案。三、五类错误模式正则、分类与恢复动作全解析契约的核心是模块内私有的ERROR_PATTERNS数组源码 browser-repair-contract.ts。它定义了五组错误正则 → 分类构建器的映射按数组顺序依次尝试匹配。下面逐类展开。1. element_not_found —— 元素不存在匹配正则/not found|no .* match|could not find|cannot find|selector .* did not match/i分类element_not_found建议工具browser_dom_read_page重新读取页面 DOM刷新对页面结构的认知建议参数{}无需参数全量重读reactionTextRe-read the page DOM before retrying selector. The selector may be stale, too specific, or not loaded yet.它对应页面结构中根本没有匹配元素的情形比如选择器拼错、页面还没渲染完、或者元素被移除。恢复动作是先重新观察再重试。2. element_not_visible —— 元素存在但不可交互匹配正则/not visible|not interactable|element .* hidden|element .* obscured|element .* covered|zero.*(width|height)/i分类element_not_visible建议工具browser_dom_get_computed_styles检查元素的最终计算样式建议参数{ selector }把当前选择器透传给检查工具reactionTextInspect computed styles for selector and check whether an overlay, hidden state, or off-screen position is blocking interaction.元素存在但不可点常见于被遮罩层覆盖、display:none、移出视口或尺寸为零。恢复动作是检查计算样式定位是哪种遮挡因素。3. action_timeout —— 动作等待超时匹配正则/timed? ?out|exceeded.*deadline/i注意timed?同时覆盖time out与timeout分类action_timeout建议工具browser_dom_wait_for_element等待选择器出现建议参数{ selector }reactionTextWait for selector with browser_dom_wait_for_element, then retry the action after the page settles.异步页面最典型的失败。恢复动作是显式等待元素就绪等页面稳定后再重试。4. frame_detached —— frame 或标签页失效匹配正则/frame .* (detached|removed|not available)|tab .* (closed|not found)/i分类frame_detached建议工具browser_dom_get_active_tab重新发现当前活动标签页与 frame建议参数{}reactionTextRe-discover the active tab and frames before retrying the browser DOM action.多 frame 页面iframe / 嵌套 frame中目标 frame 可能已从 DOM 分离或标签页被关闭。此时坐标层面的当前 frame已失效必须先重新枚举活动标签页与 frame 结构。5. stale_element —— 元素引用过期匹配正则/stale .* reference|element .* (changed|replaced|removed|no longer)/i分类stale_element建议工具browser_dom_find_elements重新查询选择器拿到最新匹配建议参数{ selector }reactionTextRe-query selector with browser_dom_find_elements and retry immediately with the refreshed match.SPA 重渲染的典型问题元素曾被解析过但随后被替换。恢复动作是重新查询并用最新结果立即重试。以上五类覆盖了找不到、看不见、等不到、环境变、引用旧五类浏览器自动化的高频故障且每类恢复动作都尽量落在既有工具上不引入新的专用恢复通道——这正是契约而非新功能的定位。四、诊断引擎diagnoseBrowserActionError 的匹配流程诊断入口是diagnoseBrowserActionError(error, selector, actionKind)源码 browser-repair-contract.ts实现非常精简先通过errorMessageFromValue(error)把任意抛出的值Error、字符串、对象统一提取为消息文本该函数位于 error-message.ts内部复用moeru/std的errorMessageFrom提取不到时回退到String(error)保证消息提取永不抛错。按ERROR_PATTERNS数组顺序逐条执行pattern.test(message)命中即调用该条目预置的build(selector, actionKind)构建BrowserRepairSuggestion并返回全部未命中则返回null表示不在契约覆盖范围内。actionKind参数例如browser_dom_click当前主要用于错误响应中的上下文标记而分类决策完全由消息文本驱动——这意味着同一段错误消息无论发生在哪个工具上得到的修复建议是一致的保证跨工具行为可预期。五、契约在工具层的落地错误响应的结构化改造修复契约不是独立运行的而是被 register-tools.ts 的buildBrowserDomActionErrorResponse集成进 MCP 工具的错误路径register-tools.ts。其流程为用errorMessageFrom(error)提取原始错误消息调用diagnoseBrowserActionError(error, selector, actionKind)获取修复建议构造isError: true的响应content文本命中契约时形如${actionKind} failed for ${selector}: ${message}\n\n${repairSuggestion.reactionText}即把reactionText直接拼进模型可见的文本通道未命中则只输出原始失败信息structuredContent统一携带status: error、selector、actionKind、error以及命中时的repairSuggestion对象还附上browserDomBridge.getStatus()桥接状态供上层审计。目前接入该错误响应的工具包括browser_dom_clickregister-tools.tsclickSelector抛错时走buildBrowserDomActionErrorResponse。另外还有一个值得注意的细节——clickSelector即使在clickAt步骤落空例如查找到点击之间页面发生 reflow时也可能正常 resolve因此注册层还会检查每个 frame 的clickResults若没有任何 frame 报告success: true则返回status: click_miss的错误避免把没点中误报为成功。browser_dom_wait_for_elementregister-tools.tswaitForElement抛错时同样走该错误响应其超时默认值来自runtime.config.browserDomBridge.requestTimeoutMs。此外工具层还对桥接不可用与传输能力不足单独建模buildBrowserDomUnavailableResponse返回status: unavailable并通过capabilities.ts见 capabilities.ts中的isBrowserDomActionSupported/getUnsupportedBrowserDomActions区分扩展未连接与已连接的扩展传输不支持写操作如只读传输不支持clickAt/triggerEvent。这与修复契约形成互补契约处理操作失败能力检查处理操作根本无法执行。六、测试驱动的契约验证12 个用例全覆盖契约的正确性由两个测试文件、共 12 个用例锁定。单元层browser-repair-contract.test.ts5 个用例见 browser-repair-contract.test.ts直接对diagnoseBrowserActionError做输入输出断言输入错误期望 pattern期望建议工具额外断言selector #submit did not match any elementelement_not_foundbrowser_dom_read_pagereactionText包含#submitelement is not visible or is coveredelement_not_visiblebrowser_dom_get_computed_stylessuggestedParams.selector #menutimed out waiting for selectoraction_timeoutbrowser_dom_wait_for_elementsuggestedParams.selector .toastframe was detached before dispatchframe_detachedbrowser_dom_get_active_tab—extension returned a custom opaque errornull不识别—验证未覆盖错误返回null第 5 个用例尤其重要它界定了契约的边界——无法识别的错误必须原样透传不允许硬套分类避免错误归因。集成层register-tools-pty-approval.test.ts7 个用例见 register-tools-pty-approval.test.ts。该文件用 mock 的McpServer与ComputerUseServerRuntime注册全部工具后直接invoke其中与修复契约直接相关的两个用例browser_dom_click抛出已知选择器错误mockclickSelector抛selector #submit did not match any element断言响应isError true、文本包含Re-read the page DOM、structuredContent.repairSuggestion命中element_not_found/browser_dom_read_pagebrowser_dom_wait_for_element超时mockwaitForElement抛timed out waiting for selector断言isError true、文本包含browser_dom_wait_for_element、repairSuggestion命中action_timeout/browser_dom_wait_for_element。其余用例验证了同一工具注册层的配套行为PTY 创建审批、Chrome 会话审批、browser_dom_trigger_event对非法optsJson返回invalid_params、只读传输下browser_dom_click与browser_dom_trigger_event返回status: unavailable且unsupportedActions准确列出受限动作。这组用例确认修复契约与能力检查、审批队列在同一个工具面上协作时行为互不干扰。七、复现验证流程一条命令接一条命令验证契约文档browser-repair-contract.md记录了完整的验证命令与结果可直接在仓库根目录复现。1. 依赖安装跳过生命周期脚本pnpm install --ignore-scripts --frozen-lockfile结果通过。--frozen-lockfile保证 lockfile 不变--ignore-scripts有意跳过生命周期脚本仅用于本地验证环境搭建。2. 运行契约相关测试pnpm -F proj-airi/computer-use-mcp exec vitest run \ src/browser-dom/browser-repair-contract.test.ts \ src/server/register-tools-pty-approval.test.ts \ --config ./vitest.config.ts结果通过。共 2 个测试文件、12 个测试即上文第五、六节所述用例总数。-F proj-airi/computer-use-mcp限定在该包作用域内执行。3. 代码风格检查moeru-lintpnpm exec moeru-lint --fix \ services/computer-use-mcp/validation/browser-repair-contract.md \ services/computer-use-mcp/src/browser-dom/browser-repair-contract.ts \ services/computer-use-mcp/src/browser-dom/browser-repair-contract.test.ts \ services/computer-use-mcp/src/server/register-tools.ts \ services/computer-use-mcp/src/server/register-tools-pty-approval.test.ts结果在 Node 24 下以 0 警告、0 错误通过。注意 lint 的输入同时包含文档Markdown与源码/测试TypeScript说明该仓库对文档与代码执行同一套风格约束。4. 空白与冲突检查git diff --check结果通过无尾随空白或冲突标记。5. 类型检查含已知 baseline 失败pnpm -F proj-airi/computer-use-mcp typecheck结果对本次改动相关文件无类型错误但整体命令在既有基线文件上失败src/chrome-session-manager.tssrc/chrome-session-manager.test.tssrc/desktop-grounding.ts观察到的基线错误类别TS2339与TS2353围绕ChromeSessionInfo.ensureOutcomeTS2451/TS2304重复的chromeWindowBounds与缺失的isChromeInFront这是仓库中与本次契约改动无关的存量问题。验证文档如实记录该失败正是为了明确本次 patch 的类型健康度与仓库整体类型健康度是两个不同的事实——在评审时不应因整体失败误伤本次改动也不应掩盖存量问题。同一模式也出现在同目录的 tool-lane-hygiene.md 验证记录中说明这是该仓库验证文档的固定披露约定。八、验证文档的隐私与脱敏约定验证契约文档在开头明确声明browser-repair-contract.md所有证据均为公开仓库脱敏版本不包含本地绝对路径、token、账号标识符、截图或原始环境转储。这意味着验证文档只记录命令、结果与错误类别绝不外泄个人环境细节。对于维护computer-use-mcp这类需要控制本机浏览器与桌面的服务而言这份纪律与功能本身同等重要——它保证了契约文档可以被安全地提交到公开仓库同时仍保留足够的可复现信息。九、小结契约的边界与扩展方式从源码结构可以总结出这套修复契约的三个设计取舍只覆盖可识别的高频模式未匹配的错误返回null由调用方原样透传绝不强行归类对应测试用例 5恢复动作全部复用既有工具五类失败映射到的browser_dom_read_page、browser_dom_get_computed_styles、browser_dom_wait_for_element、browser_dom_get_active_tab、browser_dom_find_elements都是已注册的浏览器 DOM 工具契约层不引入新的执行通道结果双通道输出reactionText进content文本供模型直接消费repairSuggestion进structuredContent供上层结构化审计。若需扩展契约只需在 ERROR_PATTERNS 数组中追加错误正则 分类构建器条目并在测试文件中补充对应输入输出断言——契约结构天然支持增量演进。对于正在构建浏览器自动化的 Agent 系统而言把失败建模成可枚举的契约、为每个失败绑定恢复动作、并用测试锁定映射关系正是这套实现最值得借鉴的工程模式。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表