
【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI agent.项目地址https://gitcode.com/GitHub_Trending/br/BrowserSkill点击查看免费下载bsk-protocol 是 BrowserSkill 项目中的 Rust 协议定义库负责为「CLI ↔ 守护进程daemon↔ 浏览器扩展extension」三端之间的所有 RPC 通信提供类型化帧结构、方法命名、握手协商、错误码与工具负载tool payload并借助 schemars 把 Rust 类型自动生成成 JSON Schema 文件。本文以 crates/bsk-protocol/README.md 为主线深入其源码实现帮助读者理解这套线路协议如何组织帧、如何做协议版本兼容、如何对工具方法进行副作用分级以及如何一键生成和维护 Schema 文件读完你既能读懂任意一条线上消息的形态也能自行扩展一个新的tool.*方法而不破坏三端契约。一、bsk-protocol 在 BrowserSkill 中的位置BrowserSkill 的核心价值是让 AI Agent 操作用户真实、已登录的浏览器同时不打断用户的工作。要实现这一点CLIAgent 侧、守护进程管理浏览器连接与会话与浏览器扩展真正通过 CDP 驱动页面三者必须跨越进程边界协同工作而它们之间所有通信都走同一套线路协议wire protocol。bsk-protocol 就是这套协议的单一事实来源它定义了三端共享的Rust 类型请求/响应/事件帧、方法枚举、工具参数与结果结构体它通过 schemars 把类型自动生成JSON Schema产物落在 crates/bsk-protocol/schema/ 目录下供 TypeScript 侧扩展与工具链复用三端各自实现同一套线格式保证「daemon 接受 ⇒ extension 接受」的对称契约。从 crates/bsk-protocol/Cargo.toml 可以看到该 crate 依赖serde/serde_json做序列化、semver做版本比较、schemars生成 Schema、thiserror定义解码错误并声明了一个名为dump-schema的二进制入口。crate 的模块组织见 src/lib.rs分为六大块frame帧结构、method方法枚举、system握手与系统方法、tools工具负载、error错误模型、cancel取消信封。二、三态帧结构Request / Response / Event线路上的所有消息都统一封装为三种帧之一定义在 src/frame.rs 中pub enum Frame { Request(RequestFrame), Response(ResponseFrame), Event(EventFrame), } pub struct RequestFrame { pub id: RpcId, // 请求唯一标识RpcId String pub method: Method, // 命名空间方法如 tool.click pub params: Optionserde_json::Value, // 参数可为空 } pub struct ResponseFrame { pub id: RpcId, pub body: ResponseBody, // Ok(Value) 或 Err(RpcError) } pub struct EventFrame { pub event: EventKind, // 点分命名的事件名 pub payload: serde_json::Value, }线格式要点请求帧序列化为{id: ..., method: ..., params: {...}}响应帧通过自定义Serialize见 src/frame.rs把Ok写成result字段、Err写成error字段即标准的 JSON-RPC 风格反序列化时若result与error同时存在或同时缺失会抛出DecodeError::AmbiguousResponseexpected exactly one of result or error杜绝二义性事件帧形如{event: system.heartbeat, payload: {}}采用点分命名以与请求/响应区分。FrameVisitorsrc/frame.rs实现了一个宽容的手写反序列化器它逐个字段扫描容忍未知字段IgnoredAny丢弃并按「先 event、再 method、最后 result/error」的优先级把 JSON 对象判别为事件、请求或响应帧——这使新旧版本在线上可以渐进共存。EventKind扩展侧主动上报的事件事件由扩展侧主动推送EventKind枚举src/frame.rs定义了全部八种线格式名称语义audit.context审计上下文更新system.heartbeat应用级心跳约每 20s 一次session.activity会话活动变化session.window_closed会话关联的 Agent Window 被关闭session.user_interrupt用户主动打断会话session.interaction_changed交互策略变化browser.connected/browser.disconnected浏览器连接状态变化其中system.heartbeat有明确的工程动机源码注释记录了它的双重作用一是通过持续的收发活动重置 MV3 Service Worker 的空闲计时器Chrome 116避免后台 worker 被回收导致 WebSocket 断开二是让守护进程把它当作存活信号从而可以回收静默死亡的浏览器。为锁定线格式不被误改frame.rs 的测试 专门断言EventKind::SystemHeartbeat序列化后必须是字面量字符串system.heartbeat。三、方法命名空间与副作用分级MethodEffect所有 RPC 方法统一定义为Method枚举src/method.rs线格式为点分字符串。按命名空间划分系统类system.handshake、system.ping、system.status、browser.list、audit.request会话生命周期session.start、session.stop、session.stop_all、session.list、tool.session_start、tool.session_stop工具类tool.*tool.navigate、tool.click、tool.fill、tool.snapshot、tool.observe、tool.screenshot、tool.evaluate、tool.console、tool.network、tool.record_start/stop/await等四十余个传输类transfer.begin、transfer.chunk、transfer.finish、transfer.read、transfer.release大文件分块传输取消cancel携带rpc_id取消另一条在途 RPC见 src/cancel.rs。每个方法都有副作用分类Method::effect()src/method.rs把每个方法归入四种MethodEffect分类含义示例PassiveRead只读不派发页面输入tool.snapshot、tool.get_html、tool.console、tool.wait_msTransientInput派发临时输入如 hover 探测不提交状态但触发事件tool.hover、tool.observe、tool.screenshot_full_pageBrowserMutation驱动浏览器/页面状态变更tool.click、tool.navigate、tool.fill、tool.evaluateControlPlane控制面/会话生命周期操作session.*、system.*、cancel、transfer.*这套分类驱动着守护进程的待处理中断pending-interrupt机制当用户在 Agent Window 遮罩上点击停止按钮后下一个会派发浏览器输入的方法将被以ErrorCode::UserAborted拒绝而被动读取与控制面 RPC 则透明放行。值得注意的是 match 语句是穷尽的没有_ 兜底分支——新增一个Method变体若未在此分类直接编译报错从编译期强制作者为每个方法做出副作用决策。源码注释还记录了几个关键判断tool.evaluate被归为变异守护进程无法静态区分读document.title与写form.submit()tool.observe虽是只读探测但会派发真实页面事件因此必须纳入中断门控session.stop与cancel故意不设门控否则 Agent 无法在用户中断后优雅收尾。pub fn requires_interrupt_gate(self) - bool { matches!(self.effect(), MethodEffect::TransientInput | MethodEffect::BrowserMutation) }对应测试见 src/method.rs覆盖了全页截图是输入、导出读取不是只读工具非变异会话生命周期非变异等边界。四、握手与协议版本兼容evaluate_handshake_compat三端独立发版CLI 与扩展的 app semver 各自演进因此协议层需要独立的协议版本号如1.0、1.3并据此判断对端是否可兼容。相关逻辑集中在 src/system.rsHandshakeParamsclient、versionapp semver、protocol_version逻辑协议版本、instance_id浏览器实例稳定标识、browser名称版本、label、以及可选的min_compatible_protocol本方接受的最低对端协议版本其中min_compatible_peer已标记deprecated是遗留的 app-semver 下限新代码发送0.0.0并在读取时忽略HandshakeResult对端回以server、version、protocol_version、min_compatible_protocol同样保留兼容旧版的min_compatible_peer可选字段。evaluate_handshake_compat()src/system.rs是兼容性判定的核心其决策规则在源码注释中以伪代码形式给出protocol unparseable or major differs → Reject peer_protocol our_min_compatible_protocol → Reject our_protocol peer_min_compatible_protocol → Reject (peer 省略下限时跳过) peer_protocol ! our_protocol (same major) → Skew (警告但放行) otherwise → Ok即HandshakeCompat三态Ok完全匹配、Skew同 major 但 minor 漂移连接照常建立仅 UI 层渲染 warn but allow 提示、Reject { reason }必须拒绝连接reason可直接放入 WS 错误帧。测试用例src/system.rs覆盖了全部路径包括app_version_drift_does_not_affect_verdict——应用版本差异如 CLI 0.1.0 对扩展 9.9.9只要协议版本匹配就判Ok。解析严格性与 TypeScript 侧逐位对齐协议字段的解析有极其严格的要求daemon 接受什么extension 就必须接受什么daemon 拒绝什么extension 就必须拒绝什么源码注释中的 hard contract。为此parse_major()src/system.rs拒绝1、-1、前导空格、1e3科学计数、空段.1、尾随非数字等一切非^\d$形态——因为 TS 侧的parseProtocolMajor见 apps/extension/src/lib/semver.ts就是基于/^\d$/构建的Rust 侧必须同样严格MAX_PROTOCOL_MAJOR被限制为2^53 - 1Number.MAX_SAFE_INTEGER与 TS 侧!Number.isSafeInteger(...)的拒绝行为保持一致避免u64::MAX这种值daemon 接受、extension 拒绝的不对称实际线上protocol_version只携带0/1/2这类小值该上限对真实流量零影响配套测试src/system.rs逐条锁定了上述接受集合测试名与扩展侧semver.test.ts一一对应方便跨语言维护。compare_protocol()按(major, minor)字典序比较两个协议版本字符串缺 minor 视为 01等价1.0任一侧不可解析则返回None。system.ping / system.status / browser.listsystem.ping空参数返回{pong: true}PingParams {}/PingResultsystem.status返回守护进程元信息与运行快照。StatusResult包含daemon_version、protocol_version、pid、uptime_secs、ws_port、sock_path以及browsers连接中的扩展快照BrowserStatusEntryinstance_id、浏览器名/版本、扩展版本、label、session_count、connected_at_ms、version_skew、extension_protocol_version和sessions活动会话快照SessionStatusEntry。另有version_skew_browsersVecVersionSkewEntry专门汇总同 major 但协议 minor 漂移的浏览器供bsk status、bsk doctor与扩展弹窗的 warn but allow UI 使用且该字段与VersionSkewEntry的协议字段均带#[serde(default)]可兼容旧守护进程的载荷有专门的反向兼容测试browser.list与StatusParams类似二者都支持可选的wait_for_browser_ms——当没有任何浏览器注册时守护进程会轮询浏览器注册表最多该毫秒数再返回便于 CLI 等待用户打开扩展。五、统一错误模型错误统一封装为 JSON-RPC 风格的RpcErrorsrc/error.rs序列化为 snake_case{ code: user_aborted, message: ..., data: null }稳定错误码ErrorCode共 13 种unknown_method、unsupported、invalid_params、not_found、permission_denied、timeout、cdp_failed、protocol_error、cancelled、user_aborted、version_too_old、multiple_browsers_online、no_browser_connected。其中user_aborted与cancelled在语义上有明确区分并有专门测试src/error.rs前者是用户主动打断后者是显式取消请求。解码侧的DecodeError提供AmbiguousResponse与InvalidFrame(String)两种错误。六、工具负载tool.*的类型化参数与结果tools子模块src/tools/mod.rs按领域划分interaction、navigation、scroll、wheel、window、emulate、tabs、session、observation、network、console、script、record、waits、file_transfer、human_loop、dialog。每个工具都有*Params/*Result一对结构体统一遵循以下约定元素定位ref 与 selector 二选一交互类工具click / hover / focus / blur / fill / press / select都支持两种定位方式见 src/tools/interaction.rsref上次tool.snapshot/tool.observe分配的元素引用形如e3也接受e3对会话内的 RefStore 归一化selector调用时实时解析的 CSS 选择器。两者互斥调用方必须恰好提供一个。字段在 Rust 侧叫ref_但通过#[serde(rename ref, alias ref_)]在线上序列化为ref同时兼容历史客户端发送的ref_拼写测试click_params_accept_legacy_ref_alias锁定了这一点。可选字段一律#[serde(default, skip_serializing_if Option::is_none)]保证载荷最小化。以tool.click为例ClickParams支持capture_idimage_x/image_y视觉引用截图的单次捕获坐标、buttonMouseButtonleft/middle/right默认 left、click_count双击传 2、modifiersKeyModifieralt/ctrl/meta/shift扩展侧折叠为 CDP 位域alt1, ctrl2, meta4, shift8、timeout_ms。ClickResult除了返回命中的tab_id、实际使用的used_ref/used_selector、视口坐标x/y外还携带dialogs数组——调用过程中自动处理掉的 JS 原生对话框会逐条记录在案方便 Agent 事后核对。tool.fill的clear_before默认true不传即先清空再输入传false则追加FillResult.value_length报告最终输入内容的 UTF-16 长度与页面input.value.length一致。tool.select的values对select整体替换选中项多选可传多个空列表清空全部结果返回multiple、selected_values与对应的selected_labels。导航与等待语义导航方法src/tools/navigation.rs统一支持wait_until与timeout_ms。WaitUntil枚举映射到 CDPPage.lifecycleEventWaitUntil线格式CDP 事件Load默认loadloadDomContentLoadeddomcontentloadedDOMContentLoadedNetworkIdlenetworkidlenetworkIdleCommitcommitcommit导航提交到新文档的最早事件timeout_ms缺省 30s。关键设计是结果中的reached字段它是扩展实际观察到的生命周期阶段名——若--wait-untilload超时结果仍会如实报告reached: commit而不是空泛的成功让 CLI/Agent 能区分真到达与部分到达。NavigateResult还提供final_url导航落定后的最终 URL可反映 http→https 重定向与error_text。tool.reload额外支持hard: true以绕过 HTTP 缓存CDPPage.reload(ignoreCachetrue)。会话与交互策略tool.session_startsrc/tools/session.rs以session_id开启会话可选browser_instance_id、Agent Window 尺寸width/height100..7680、focused缺省沿用扩展默认 true。遗留的unattended字段被标记为接受但忽略并永不转发测试验证它不会出现在 Schema 与序列化输出中——从协议 1.3 起借出确认borrow confirmation与请求帮助request help提示由浏览器端的InteractionPolicyborrow_confirmation、request_help两个策略统一裁决supports_interaction_policy()通过compare_protocol判定协议版本是否 ≥1.3且 2.0。tool.session_stop的结果会报告自动归还的标签页returned_tab_ids与逐条失败的return_failures含ErrorCode与 message。记录record与追踪tracetool.record_start/tool.record_stop/tool.record_await承载用户操作录制dump-schema.rs中还为TraceV2/TraceV3、StepV2/StepV3及兼容旧版的trace/trace_step分别生成了 Schema 文件见 crates/bsk-protocol/schema/trace_v3.json、crates/bsk-protocol/schema/trace_step_v3.json 等表明协议对录制轨迹做了 v2/v3 双版本演进并保留向后兼容。七、JSON Schema 生成一行命令、四十余份 SchemaREADME 提供的生成命令是cargo run -p bsk-protocol --bin dump-schema --locked该命令对应 src/bin/dump-schema.rs。它遍历系统方法handshake / ping / status / browser.list、取消信封、会话、窗口、模拟、标签页、导航、交互、观察、截图、控制台、网络、求值、等待、录制与轨迹等全部类型对每个类型调用schema_for!宏以serde_json::to_string_pretty输出到 crates/bsk-protocol/schema/ 目录dump!(HandshakeParams, handshake_params); dump!(ClickParams, tool_click_params); dump!(ClickResult, tool_click_result); // ... 共 70 个文件每个文件以$type名.json命名如 handshake_params.json遵循 JSON Schema draft-07包含required字段列表、带description的属性说明直接来自 Rust 文档注释如protocol_version的 Logical protocol revision, independent of SemVer app releases以及嵌套的definitions。Schema 与#[serde]属性严格联动被skip_serializing_if或schemars(skip)标记的字段不会进入 Schemaschemars(range(min 1))会生成minimum约束schemars(with String)让semver::Version以字符串形式出现在 Schema 中。这套类型 → Schema的单向生成机制保证了三端契约始终以 Rust 类型为唯一权威源协议演进 修改 Rust 类型 跑一遍 dump-schema 提交新的 Schema 文件人工手写 Schema 容易漂移的问题被彻底避免。八、质量保障跨语言对称测试bsk-protocol 的质量保障体现在三层测试策略上线格式锁定每个枚举的序列化拼写都有测试钉死例如system.heartbeat、session.user_interrupt的点分名src/frame.rs、wait_until的小写形态src/tools/navigation.rs、ErrorCode::UserAborted的 snake_casesrc/error.rs往返一致性绝大多数 Params/Result 都有serde_json::to_value后再from_value的 round-trip 测试保证 Rust 内部表示与线上 JSON 双向一致跨语言判定对称parse_major的接受集合测试与扩展侧semver.test.ts逐条对应源码注释明确要求任一输入 daemon 接受则扩展必须接受拒绝则必须往返为 null从测试层面把 Rust/TypeScript 双端判定锁成硬契约。九、如何在仓库中阅读与验证想从整体把握协议先读 crates/bsk-protocol/README.md再按frame → method → system → tools → error顺序通读 src/想看某条消息的确切形状直接在 crates/bsk-protocol/schema/ 中查找对应tool_*_params.json/tool_*_result.json想验证当前 Schema 是否与源码同步执行cargo run -p bsk-protocol --bin dump-schema --locked后git diff查看差异注意仓库只读本命令用于本地阅读验证;想追踪三端如何消费这套协议守护进程端可看 crates/bsk-cli/src/daemon/如 ws.rs扩展端可看 apps/extension/src/lib/ 下的popup-bridge.ts、record-bridge.ts等桥接模块以及 crates/bsk-protocol/schema/trace_v3.json 对应的录制轨迹格式。综上bsk-protocol 以一组紧凑的 Rust 类型统一了 CLI、守护进程与扩展三端的线上语言三态帧承载一切消息点分方法名 副作用分级支撑安全的用户中断协议版本号与严格解析保证异构版本共存不失控而 JSON Schema 的单向生成让契约永远可校验、可演进。理解了它就等于拿到了整个 BrowserSkill 自动化链路的线路图。赞分享【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI agent.项目地址https://gitcode.com/GitHub_Trending/br/BrowserSkill点击查看免费下载相关推荐HumanLayer HLD 守护进程协议全解基于 Unix Socket 的 JSON-RPC 2.0 通信规范HumanLayer HLD 守护进程协议全解基于 Unix Socket 的 JSON RPC 2.0 通信规范 HumanLayer DaemonHLD人工智能AI Agent后端MCP 服务CLI桌面应用BrowserSkill 浏览器自动化技能实战bsk CLI 驱动的 AI Agent 浏览器操作指南BrowserSkill 浏览器自动化技能实战bsk CLI 驱动的 AI Agent 浏览器操作指南 skill/SKILL.md 是 BrowserSkiQwen Code 浏览器端实战用 Chrome 扩展把 qwen serve 守护进程接入真实浏览器Qwen Code 浏览器端实战用 Chrome 扩展把 qwen serve 守护进程接入真实浏览器 本文基于 Qwen Code 仓库中的 package人工智能AI Agent代码智能体工具调用交互助手CLIQwen创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考