发布时间:2026/9/7 17:35:28
Storybook agent-eval 中的 Codex 内建浏览器自动化技能:control-in-app-browser 的完整设计与源码剖析 Storybook agent-eval 中的 Codex 内建浏览器自动化技能control-in-app-browser 的完整设计与源码剖析【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本文以 Storybook 仓库agent-eval评测体系中的技能文件 codex-browser-skill.md 为核心完整还原control-in-app-browser技能如何让 Codex Agent 在 Linux 评测沙箱中操控“应用内浏览器”从技能文件的注入机制、Bootstrap 初始化流程到底层 headless Chromium 运行时与 ARIA 快照、截图、CDP 网络检查的实现细节。读完本文你将掌握在 MCP 环境下通过nodeRepl.js工具完成浏览器导航、交互、状态读取与验证的全套方法并能理解每一段引导代码背后的实现与测试验证逻辑。一、技能文件在评测体系中的定位codex-browser-skill.md 是一份标准的 Agent 技能文件其 frontmatter 定义如下--- name: control-in-app-browser description: Control the in-app Browser. Use to open, navigate, inspect, test, click, type, screenshot, or verify local targets such as localhost, 127.0.0.1, ::1, file://, the current in-app browser tab, and websites shown side by side inside Codex. ---技能正文开篇明确了它的适用范围Use this skill for browser automation tasks such as inspecting pages, navigating, testing local apps, clicking, typing, taking screenshots, and reading visible page state.即检查页面、导航、测试本地应用、点击、输入、截图、读取可见页面状态等一切浏览器自动化任务。技能还强调了一条强制约束一旦该技能在会话中被列为可用就必须在声称“Browser 不可用”或回退到独立 Playwright/其他浏览器控制机制之前先完整阅读并遵循本技能。技能如何被注入到评测沙箱这份技能不是孤立的文档。Storybook 的 agent-eval 系统会在每个评测沙箱初始化时把它“物化”进去。templates.ts 中定义了源文件到沙箱内路径的映射源文件仓库内沙箱内路径node-repl-mock.mjs.agent-eval/mcp/node-repl-mock.mjscodex-browser-client-mock.mjs.agent-eval/mcp/codex-browser-client-mock.mjscodex-browser-api.json.agent-eval/mcp/codex-browser-api.jsoncodex-browser-skill.md.agents/skills/control-in-app-browser/SKILL.mdwriteCodexInAppBrowserMock()函数把上述四个文件写入沙箱并向沙箱的.codex/config.toml追加 MCP 服务器配置[mcp_servers.node_repl] command node args [.agent-eval/mcp/node-repl-mock.mjs] default_tools_approval_mode auto startup_timeout_sec 30 tool_timeout_sec 180从源码注释看这是整套替身方案的设计动机真实的node_replMCP 服务器是 Codex 桌面应用里打包的原生二进制Contents/Resources/cua_node/bin/node_repl不随openai/codexnpm CLI 分发因此 Linux 评测沙箱需要一个行为一致的替代实现。技能文件教给 Codex 的 Bootstrap 流程与应用内真实浏览器使用的是完全相同的调用序列只是运行时被 mock 替换为 headless Chromium。二、Bootstrap浏览器运行时的初始化技能文档将 Bootstrap 描述为三步定位browser-client模块、确认执行工具、初始化运行时并读取文档。1. 定位 browser-client 模块技能的 Bootstrap 小节原文要求Thebrowser-clientmodule is the core entry point for browser use, and is available at.agent-eval/mcp/codex-browser-client-mock.mjsrelative to the workspace root. ALWAYS import it using an absolute path composed fromnodeRepl.cwd. IMPORTANT: If this path cannot be found, stop and report that the workspace is missing.agent-eval/mcp/codex-browser-client-mock.mjs.两个关键约束值得注意必须用绝对路径导入由nodeRepl.cwd当前工作目录拼接而成不能写相对路径。原因在于 ESM 的动态import()以模块自身位置为基准解析裸说明符而评测模板是在工作区 postinstall 阶段安装 playwright 的只有从工作区根出发才能命中工作区内的node_modules。路径缺失时立即中止不做降级尝试直接报告“workspace is missing.agent-eval/mcp/codex-browser-client-mock.mjs”把环境问题暴露给评测框架而非产生误导性的“浏览器不可用”结论。2. 确认执行工具Node REPL 的js工具技能明确指出浏览器设置代码必须通过 Node REPL 的js工具执行其工具 id 通常呈现为mcp__node_repl__js。三个工具的职责在 node-repl-mock.mjs 中定义得非常清晰js在持久的 Node 内核中执行 JavaScript支持顶层awaitvar绑定跨调用保留缺省超时 30000 msjs_reset仅清空内核状态技能中反复强调“不要用它来初始化浏览器”js_add_node_module_dir仅把额外的node_modules目录加入模块解析根不执行任何业务代码。js工具注入的运行时 helper 包括nodeRepl.cwd、nodeRepl.homeDir、nodeRepl.tmpDir、nodeRepl.write(...)把文本写入响应、await nodeRepl.emitImage(...)把字节流作为图像附加到响应这正是技能里nodeRepl.write(await browser.documentation())和截图输出所依赖的通道。3. 初始化运行时并读取完整文档技能给出的初始化代码是逐字要求的“using the exact direct call shown above”if (globalThis.agent?.browsers null) { const { setupBrowserRuntime } await import( nodeRepl.cwd /.agent-eval/mcp/codex-browser-client-mock.mjs ); await setupBrowserRuntime({ globals: globalThis }); } globalThis.browser await agent.browsers.get(iab); nodeRepl.write(await browser.documentation());这段代码对应 codex-browser-client-mock.mjs 末尾导出的setupBrowserRuntime({ globals })它把agent.browserslist/get/getDefault/getForUrl与agent.documentationget(name)挂到传入的globalThis上并注册 id 为iabIn-App Browser的唯一浏览器实例。if (globalThis.agent?.browsers null)的幂等保护意味着同一 Node 会话中重复执行 Bootstrap 是安全的——模块级单例保证运行时只初始化一次。技能还给出两条恢复指引Bootstrap 成功但浏览器发现/选择失败时先读await agent.documentation.get(bootstrap-troubleshooting)再考虑重置 JavaScript 会话。mock 运行时内置了这份打包文档PACKAGED_DOCS内容即“重新执行setupBrowserRuntime并再次agent.browsers.get(iab)若 Chromium 启动失败确认工作区已安装 playwright 后重试”。浏览器选择成功之后在尝试任何交互前必须一次性完整输出并阅读await browser.documentation()返回的全部文档。从源码看这份文档由两部分拼成GUIDANCEeval 环境行为差异提示加上由 codex-browser-api.json 渲染出的完整 TypeScript 接口声明renderApiDocumentation()带缓存。三、典型操作流程导航、状态读取与截图Bootstrap 完成后技能给出的典型流程覆盖了最常见的“打开页面 → 等待加载 → 读取可见状态”序列var tab (await browser.tabs.selected()) ?? (await browser.tabs.new()); await tab.goto(http://localhost:3000); await tab.playwright.waitForLoadState({ state: domcontentloaded, timeoutMs: 10000 }); nodeRepl.write(await tab.playwright.domSnapshot());要点说明browser.tabs.selected()优先复用已选中的标签页没有才browser.tabs.new()新建。源码中createTab()会为新标签页设置默认动作超时 5000 ms、默认导航超时 30000 ms因此大多数调用无需显式传timeoutMs。tab.goto()内部以waitUntil: domcontentloaded等待随后tab.playwright.waitForLoadState({ state, timeoutMs })可再精确等待指定加载状态load/domcontentloaded等缺省load缺省超时 30 秒。tab.playwright.domSnapshot()返回ARIA 风格的快照字符串源码实现是对body调 Playwright 的ariaSnapshot()再逐个 frameiframe附加- iframe (url):前缀段落合并。这正是 codex-browser-mock.test.ts 中断言快照包含heading Fixture App、button click me的依据。查看截图的方式是把截图字节作为图像发射await nodeRepl.emitImage(await tab.screenshot({}));从 mock 实现看tab.screenshot()固定返回JPEG 字节quality 80除非传fullPage: true或clip裁剪区域默认视口为 1280x720可用浏览器的viewport能力覆盖。四、运行时实现细节agent.browsers.* API 全貌codex-browser-api.json 是从真实应用打包的api.json复制来的接口清单browser.documentation()渲染的就是它。其接口层次为Agentbrowsers: Browsers发现与选择浏览器、documentation: Documentation按名读取打包文档Browserslist()/get(id)/getDefault()/getForUrl(url)BrowserbrowserId、capabilities、tabs、user、documentation、nameSessionTabsnew/get/list/selected/content批量抓取 URL 内容/finalize关闭除保留列表外的全部标签页Tabgoto/back/forward/reload/close/title/url/screenshot/getJsDialog以及四组能力面playwrightPlaywrightAPIdomSnapshot、locator/getByRole/getByText/getByLabel/getByPlaceholder/getByTestId、frameLocator、waitForLoadState/waitForURL/waitForTimeout/waitForEvent支持download与filechooser、expectNavigation、evaluate、elementInfo/elementScreenshot按坐标探查叠层元素cua坐标驱动click/double_click/move/drag/scroll/keypress/type按钮编号 1左键、2中键、3右键修饰键支持CTRL/ALT/SHIFT/META及其别名dom_cua节点驱动get_visible_dom()返回带node_id的可见可交互元素列表含 rect、text、ariaLabel 等click/double_click/scroll可按node_id定位dev与clipboardtab.dev.logs()读控制台日志支持levels/filter/limittab.clipboard.readText()/writeText()读写剪贴板Tab 能力扩展tab.capabilities.get(cdp)暴露 CDP 通道——send(method, params)发命令需先Network.enable等开域readEvents({ methods?, afterSequence?, limit? })分页读取缓冲的 CDP 事件默认页大小 100、上限 1000。技能中“network inspection goes through thecdptab capability, not a high-level API”说的就是这条路径。保真度细节同样来自真实应用内浏览器的实测记录源码头部注释逐条列出行为实现默认视口 1280x720DEFAULT_VIEWPORTviewport能力可覆盖/重置applyViewport会同步更新所有存活标签页tab.screenshot()返回 JPEGtype: jpeg, quality: 80除非fullPagedomSnapshot()返回 ARIA 快照body的ariaSnapshot() iframe 段落拼接定位器超时措辞重写为Playwright selector deadline exceeded\nwaiting on op for selector desc与真实应用一致控制台日志page.on(console)/page.on(pageerror)缓冲后经tab.dev.logs()读取所有 Locator 方法都经过wrapLocator()统一包装子查询locator/filter/and/or/nth等、读取textContent/innerText/getAttribute等带超时动作、交互click/fill/press/check/selectOption/waitFor等。其中type()映射到 Playwright 的pressSequentially逐键输入区别于fill的整体填充withDeadlineError()则负责把 Playwright 的TimeoutError翻译成应用内浏览器的原始错误措辞——这一点被测试用例显式验证见下文。五、测试验证Bootstrap 到交互的端到端断言codex-browser-mock.test.ts 以 JSON-RPC 方式启动node-repl-mock.mjs子进程McpClient类用一个本地 HTTP fixture 页面含标题、按钮、输入框与一条console.log(fixture loaded)复现技能中的完整流程。核心断言包括Bootstrap 与技能完全一致执行与技能文档同款的初始化代码断言文档输出包含interface Tabs、PlaywrightAPI、domSnapshot浏览器列表agent.browsers.list()返回唯一条目{ id: iab, type: iab }浏览器能力恰为visibility、viewport打开页面并读 ARIA 快照goto后断言title、url与快照内容定位器点击 控制台日志getByRole(button, { name: click me }).click({})后读取#counter的innerText应为clicked且tab.dev.logs({ limit: 10 })中包含fixture loaded输入与页面求值getByLabel(Name, {}).fill(Kasper, {})后evaluate断言#name值为KasperJPEG 截图输出nodeRepl.emitImage(await tab.screenshot({ fullPage: false }))的响应包含mimeType: image/jpeg的图像块视口覆盖browser.capabilities.get(viewport)).set({ width: 375, height: 812 })后window.innerWidth为 375dom_cua 节点交互get_visible_dom()找到id counter的节点后按node_id点击超时措辞对不存在的按钮click({ timeoutMs: 500 })错误信息包含Playwright selector deadline exceededjs_reset存活性重置内核后仅重跑 Bootstrap模块级浏览器会话仍在browser.tabs.list()仍能看到 fixture 页面标题。这组测试同时验证了 node-repl-mock.mjs 本身的行为MCP 握手镜像真实服务器serverInfo.name为node_replinstructions 提及nodeRepl.cwd、顶层await与var绑定跨调用保留、错误以isError结果呈现。六、约束清单与回退策略技能最后一节是不可省略的边界声明建议在实际使用评测沙箱时逐条对照只能用 Node REPL 的js工具mcp__node_repl__js控制内建浏览器不得使用外部 MCP 浏览器控制工具、独立的浏览器自动化服务器或其他浏览器技能处理这一表面surface。文中提到的 Playwright 一律指 in-skill 的tab.playwrightAPIbrowser-client设置完成后的受包装表面而不是直接import(playwright)的裸 API——裸 API 缺少 deadline 错误措辞、domSnapshot 语义与 CDP 事件缓冲等保真行为。目标范围localhost、127.0.0.1、::1、file://以及当前内建浏览器标签页页面加载失败时应先确认 dev server 在预期端口监听browser-troubleshooting打包文档即此指引。回退顺序技能列出可用 → 必须先读技能 → 仍失败才允许考虑独立 Playwright 等其他机制。七、小结control-in-app-browser技能表面上只有一页引导文本实际背后是一整条被精心保真的链路templates.ts 负责把技能、node_replmock 服务器、浏览器客户端 mock 与 API 清单四件套注入 Codex 沙箱codex-browser-client-mock.mjs 用 headless Playwright Chromium 实现与桌面应用逐行为对齐的agent.browsers.*表面codex-browser-mock.test.ts 则把技能文档里的每段代码原样执行一遍作为回归测试。理解这套结构后无论是排查评测中“浏览器不可用”的误报、扩展技能引导语还是为其他 Agent 编写等价的浏览器自动化技能都可以直接以这条链路为模板。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

2026/9/7 18:25:34

龙珠Z第262集版本管理与数字修复技术解析

1. 项目背景与核心概念解析"dragonballz_e262-1"这个看似神秘的代码组合,实际上蕴含着丰富的文化和技术内涵。作为一名资深动漫文化研究者,我最初看到这个标题时,立刻意识到它与经典动漫《龙珠Z》有着密切关联。经过深入考证&#…

2026/9/7 18:20:34

《龙珠Z》经典场景数字修复与AI增强技术解析

1. 项目背景与核心价值"dragonballz_e179-1"这个看似神秘的代码组合,实际上蕴含着丰富的文化和技术内涵。作为一名资深动漫文化研究者和技术实践者,我花了大量时间深入挖掘这个项目背后的意义。从表面看,它明显与经典动漫《龙珠Z》…

2026/9/7 0:47:43

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/7 0:14:19

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/7 0:14:17

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/7 0:03:36

基于YOLOv8和PyQt5的麦穗稻穗检测识别系统设计与实现

这次我们来看一个把目标检测算法和桌面端工具结合得很典型的项目:基于 YOLOv8 PyQt5 的麦穗稻穗检测识别系统。这个项目本身不是新概念,但它的价值在于落地形态很完整。YOLOv8 负责核心的麦穗稻穗目标检测,PyQt5 负责提供可视化的桌面交互界…

2026/9/7 0:03:36

UL 1642锂电池安全标准全解析:测试项目、认证流程与避坑指南

简介:UL 1642是锂电池安全领域的重要规范,本中文版资源适合锂电池制造商、检测机构工程师及产品认证相关人员阅读,用于理解电池在设计与制造层面的安全要求、测试方法与合规要点。资源共1个PDF文件,压缩包大小834KB,便…

2026/9/7 0:03:36

BS EN 13814-1-2019游乐设施安全标准:设计与制造核心要点解析

简介:BS EN 13814-1:2019是英国采纳欧洲标准EN 13814-1:2019的正式版本,由BSI标准出版,重点规定游乐设施和游乐设备在设计与制造环节的安全准则,与BS EN 13814-2:2019、BS EN 13814-3:2019共同取代旧版BS EN 13814:2004。该标准面…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/6 19:33:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/6 10:19:40

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…