如何为 jcode 编写浏览器 Provider 适配器:certified 最低命令集与能力协商
【免费下载链接】jcodeThe most RAM efficient harness项目地址: https://gitcode.com/GitHub_Trending/jcod/jcode
jcode 对外只暴露一个一等browser工具,但底层要兼容多种浏览器自动化后端(Firefox Agent Bridge、Chrome Agent Bridge、CDP 适配器、WebDriver/BiDi、Safari 等)。如果你要让自研的浏览器控制系统接入 jcode,需要按 docs/BROWSER_PROVIDER_PROTOCOL.md 定义的归一化契约实现一个 provider 或 adapter。该协议目前状态为 draft,protocol_version固定为"0.1"。本文按协议文档梳理出一条从实现到自证的最小路径:实现 certified 最低命令集、通过provider.describe/provider.status完成能力协商、最后按协议给出的 10 个最小一致性场景逐项自检。
术语先对齐(来自协议文档):
- provider:满足该协议的后端实现;
- bridge:外部浏览器集成,例如 Firefox Agent Bridge;
- adapter:把 bridge 的原生 API 翻译成该协议的胶水层;
- element ref:provider 签发的、指向可操作元素的不透明句柄。
jcode 侧对内部机制不敏感:它只依赖一套稳定的语义方法和不透明句柄(session_id、page_id、tab_id、element_ref、download_id),不假设标识符的形状。传输层也不强制单一 wire format——进程内 Rust trait 调用、stdio JSON 请求/响应、本地 socket RPC、包装远程 API 都可以;外部进程集成推荐 JSON-RPC 风格的稳定信封。
传输选型与信封格式
外部 provider 的请求与响应必须使用统一信封。请求:
{ "protocol_version": "0.1", "id": "req_123", "method": "page.open", "params": { "session_id": "sess_abc", "url": "https://example.com" } }成功响应(文档示例):
{ "protocol_version": "0.1", "id": "req_123", "ok": true, "result": { "page_id": "page_1", "url": "https://example.com", "title": "Example Domain" }, "warnings": [] }错误响应携带结构化错误码:
{ "protocol_version": "0.1", "id": "req_123", "ok": false, "error": { "code": "unsupported_method", "message": "This provider does not implement page.eval", "retryable": false, "details": {} } }协议还定义了可选的事件信封(event+payload,例如page.navigated);事件在 v1 中是可选的,可以不实现。
错误码应覆盖协议列出的标准集合:unsupported_method、unsupported_target、invalid_request、invalid_selector、element_not_found、element_not_actionable、navigation_timeout、not_ready、setup_required、permission_denied、browser_not_running、session_not_found、page_not_found、internal_error。provider 可以在error.details中追加自己的细分码,但不要自创顶层码。
certified 最低命令集:必须实现的 10 个方法
协议把命令分三档。要被视为certified,provider 必须支持这 10 个归一化操作:
| 方法 | 作用 | 关键请求/响应字段(按协议文档) |
|---|---|---|
provider.describe | 返回 provider 静态/半静态元数据 | 见下节能力协商 |
provider.status | 返回当前可用性与设置状态 | 见下节能力协商 |
session.ensure | 创建或复用浏览器会话 | 请求含client_session_id、isolation、attach、persist;响应含session_id、default_page_id |
session.close | 关闭或脱离 provider 会话 | 关闭 tab、脱离目标还是仅释放 provider 侧状态由 provider 决定,需在describe或status诊断中说明 |
page.open | 在当前页或新页打开 URL | 请求必填session_id、url;wait_until可选值load \| domcontentloaded \| networkidle \| provider_default;响应含page_id、url |
page.snapshot | 返回归一化页面视图,供模型推理 | 协议称其为“对模型使用最重要的方法”;snapshot.format为jcode.page_snapshot.v1,响应含elements可操作列表 |
page.click | 点击元素 | 支持element_ref、selector、text_query、position四种定位,至少给一个;响应含clicked布尔值 |
page.type | 向输入类目标输入或设置文本 | text必填;响应含typed布尔值 |
page.wait | 等待条件满足 | 条件字段如text_present、selector_absent、url_matches、navigation_complete、timeout_ms等;响应含satisfied |
page.screenshot | 截图 | 响应含image或image_ref、media_type、width、height;可内联 base64 也可返回 provider 管理的图片引用 |
两点和page.snapshot有关的要求值得注意:
- 快照要归一化进
jcode.page_snapshot.v1最小格式(root+nodes,节点含node_id、role、name、element_ref、actionable);provider 内部表示可以不同,出口要归一化。 - 应尽量同时返回扁平化的
elements可操作列表;如果产不出富 DOM/a11y 数据,可以返回更弱的快照,但必须在 capabilities 中如实声明。
其余标准化方法属于可选但推荐,第一版不参与认证:page.go_back、page.go_forward、page.reload、tab.list、tab.activate、tab.close、page.eval、page.press、page.scroll、page.select、download.list。实现了它们会被标准化处理,但没实现不影响认证。
能力协商:provider.describe 与 provider.status
协商的入口是两个握手方法。provider.describe返回静态元数据,文档示例(节选,core_methods/features等列表均为文档示例值):
{ "provider_id": "firefox_agent_bridge", "provider_label": "Firefox Agent Bridge", "provider_version": "1.2.3", "protocol_version": "0.1", "browser_families": ["firefox"], "transport": "stdio-json", "certification_tier": "candidate", "capabilities": { "core_methods": [ "session.ensure", "session.close", "page.open", "page.snapshot", "page.click", "page.type", "page.wait", "page.screenshot" ], "optional_methods": ["tab.list", "tab.activate", "page.eval"], "features": ["element_refs", "a11y_snapshot", "attach_existing_browser", "persistent_profile"], "custom_methods": [ { "name": "firefox.install_extension", "stability": "experimental", "description": "Install or verify the Firefox extension" } ] } }capabilities里要区分两类声明:
- methods:可直接调用的具体操作(
page.open、tab.list这类); - features:影响 jcode 行为的高层语义,如
element_refs、a11y_snapshot、dom_snapshot、full_page_screenshot、attach_existing_browser、persistent_profile、js_eval、network_observe、file_upload、manual_setup_required、extension_required、remote_debugging_required等。
feature 或 method 可带stable | experimental | deprecated稳定度标签。能力报告的原则是诚实:弱快照、缺功能都要在这里体现,jcode 会依据能力质量选择 provider。
provider.status返回当前可用性与设置状态,文档给出的示例字段包括availability、browser_detected、browser_running、setup_state、requires_manual_setup、recommended_browser、manual_steps、diagnostics。建议的枚举值:
availability:ready | degraded | unavailablesetup_state:complete | partial | required | broken
浏览器 provider 经常需要人工设置(装扩展、注册 native host 等),协议要求把这种状态机器可读地暴露出来:诊断项用level+code+message+manual_steps的结构,例如extension_missing时给出打开浏览器、安装扩展、必要时重启的手动步骤。协议还推荐了两个可选方法:provider.setup_guide(返回浏览器特定的说明、URL、文件路径、权限步骤)和provider.verify。
Provider 特定扩展的命名与暴露规则
协议允许 provider 在核心之外暴露自定义命令(文档列举的例子:firefox.install_extension、chrome.attach_debug_target、cdp.send、webdriver.perform_actions),但定了四条规则:
- 自定义方法必须用命名空间化的方法名;
- 每个自定义方法必须出现在
provider.describe.capabilities.custom_methods中,带name、description、stability,可选input_schema/output_schema; - jcode 核心默认只依赖归一化方法;provider 特定方法只在用户明确要求、jcode 侧适配器知道如何安全使用、或未来高级/调试模式启用时才被调用;
- provider 原生透传(如通过
provider_command直接调cdp.send)是允许的逃生门,但应被视为高级/调试行为,不是主路径。
也就是说:你的差异化能力可以有,但不能靠不声明、不命名空间的方式悄悄混进核心流程。
一致性自检与认证分级
协议给出了最小一致性场景清单,一套未来的 conformance suite 至少要验证以下 10 项——在没有现成测试框架之前,这 10 项就是你自己跑通的验收清单:
provider.describe成功;provider.status报告自洽的状态;session.ensure创建或复用会话;page.open导航到一个测试页;page.snapshot返回可用文本,且适用时至少一个可操作引用;page.click能激活一个已知元素;page.type能填写一个已知输入框;page.wait观察到确定性的页面变化;page.screenshot返回图片;session.close干净地清理或脱离。
对应的分级定义:
- Certified:通过 required core methods 的一致性测试、返回稳定标识符与归一化结果、正确报告设置/诊断、重复运行行为可预期;
- Compatible:支持部分或大部分归一化方法、有缺失或部分行为,可用但尚未完全认证;
- Experimental:适配器存在,但语义不完整或不稳定。
版本规则方面:protocol_version独立于 provider 版本演进,小的增量变更不应破坏已认证 provider,破坏性变更必须升protocol_version。当前统一使用"0.1"。
仓库现状、限制与下一步
对照仓库现状:README 的 Browser Automation 一节说明当前内建后端是 Firefox(经 Firefox Agent Bridge),内建browser工具已包含status、setup、open、snapshot、click、type、wait、screenshot、eval等动作,可用以下命令查看当前内建后端的就绪状态:
jcode browser status jcode browser setupREADME 同时明确:provider/tool 架构已就位以容纳额外后端,Chrome bridge / 远程调试风格的 provider 可以之后加到同一个 browser 工具上;现有 Firefox 后端实现可参考 crates/jcode-base/src/browser.rs。
需要注意的边界:协议文档本身标注为 draft,一致性测试框架还在“Proposed next steps”里(先定义匹配该协议的 Rust trait、实现第一个 provider 适配器、再构建 conformance test harness),所以本文的验证路径是逐项手工执行上述 10 个场景,而不是运行现成的测试套件。文档还留了几个待定问题(截图是否总内联、事件流是否要求、原始 HTML/DOM 归一化到什么程度、page.snapshot是否支持多个命名格式、provider 特定方法能否走同一个 browser 工具、setup 流程是否要标准化),你的适配器实现应以当前 draft 文本为准,并在protocol_version上预留演进空间。
完成实现后,按顺序交付:10 个 certified 方法的实现 →provider.describe/provider.status的诚实能力报告 → 10 项一致性场景逐项跑通。跑通并满足 Certified 定义的四条,你的 provider 才有资格进入 jcode 的认证路径。
【免费下载链接】jcodeThe most RAM efficient harness项目地址: https://gitcode.com/GitHub_Trending/jcod/jcode
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考