7.4 KiB
L2 — 核心模块与接口契约层
文档版本: 2.0
适用项目: sgClaw(ZeroClaw 重构版)
编制日期: 2026-03-26
读者: 架构工程师、实现工程师、联调工程师
1. 模块地图
当前仓库中的有效模块结构如下:
src/
├── main.rs
├── lib.rs
├── agent/
├── compat/
├── config/
├── llm/
├── pipe/
└── security/
模块边界按职责划分为五层:
| 层级 | 模块 | 责任 |
|---|---|---|
| 传输层 | pipe |
定义消息、握手、序列号、收发与命令等待 |
| 安全层 | security、resources/rules.json |
域名、动作与 pipe 命令边界控制 |
| 运行时入口层 | lib.rs、agent |
接收任务、选择执行路径、回传日志与结果 |
| 适配层 | compat、config |
把 sgClaw 宿主环境映射到 zeroclaw 运行时;当前仍带有过渡性限制 |
| 核心能力层 | third_party/zeroclaw |
prompt、skills、memory、tool loop、provider 抽象 |
2. 核心模块职责
2.1 src/lib.rs
src/lib.rs 是运行时总装入口,负责:
- 创建
StdioTransport。 - 调用
perform_handshake。 - 加载默认规则文件
resources/rules.json。 - 构造
BrowserPipeTool。 - 进入长循环,接收浏览器消息并交给
agent::handle_browser_message。
这里没有业务 UI、任务队列或调度中心逻辑,只有最小可运行闭环。
2.2 src/agent/mod.rs
src/agent/mod.rs 当前决定执行路径:
- 收到
BrowserMessage::SubmitTask时优先尝试读取DeepSeekSettings。 - 环境配置存在,则走
compat::runtime::execute_task。 - 环境配置不存在,则走内置 planner fallback。
这就是当前系统的“路由器”。但文档上应把它理解为过渡性 runtime selector,而不是最终产品架构中心。
2.3 src/agent/runtime.rs
该文件保留了仓库内的轻量 LLM/tool 调用逻辑,核心特点:
- 工具名固定为
browser_action。 - schema 只允许
click/type/navigate/getText。 - 每次工具调用前后发送
log_entry。 - 结果失败时直接返回
PipeError::Protocol。
2.4 src/compat/runtime.rs
src/compat/runtime.rs 是当前 ZeroClaw 接入的关键模块:
- 负责构造 ZeroClaw config。
- 负责创建 provider。
- 负责把
BrowserPipeTool包装成 ZeroClaw Tool。 - 负责消费 ZeroClaw
TurnEvent并桥接为log_entry。
重要事实:
- 当前 compat 层只向 ZeroClaw 注册一个工具。
allowed_tools被收敛到browser_action。- 这意味着当前代码还没有把 sgClaw 做成 zeroclaw-first runtime。
- 这是一种实现限制,不应被文档提升为产品原则。
2.5 src/pipe/browser_tool.rs
该模块承担真实浏览器命令发送职责,也是当前系统中最重要的特权工具面桥接层:
- 为每个命令分配
seq。 - 计算 HMAC。
- 发送
AgentMessage::Command。 - 阻塞等待对应
BrowserMessage::Response。 - 在超时、响应错配、校验失败时返回错误。
它是 Rust 侧最重要的协议执行点。架构上应把它理解为“privileged browser surface adapter”,而不是“整个 runtime 本体”。
2.6 src/security/mac_policy.rs
安全策略只认规则文件与 pipe contract,不认模型意图。
规则来源为 resources/rules.json,当前默认约束是:
- 允许域名:
oa.example.com、erp.example.com、hr.example.com及 demo 域名。 - 允许动作:
click、type、navigate、getText。 - 显式阻断:
eval、executeJsInPage。
3. 协议契约
3.1 消息类型
src/pipe/protocol.rs 定义了三类浏览器到 Rust 的消息:
BrowserMessage::Init
BrowserMessage::SubmitTask
BrowserMessage::Response
以及四类 Rust 到浏览器的消息:
AgentMessage::InitAck
AgentMessage::LogEntry
AgentMessage::TaskComplete
AgentMessage::Command
3.2 Init / InitAck
握手字段:
versionhmac_seedcapabilities
Rust 返回:
versionagent_idsupported_actions
注意:supported_actions 是协议枚举能力,不等于当前策略白名单。
3.3 Command
命令消息结构:
{
"seq": 1,
"type": "command",
"action": "click",
"params": { "selector": "#submit" },
"security": {
"expected_domain": "erp.example.com",
"hmac": "<hex>"
}
}
契约重点:
seq必须单调递增。action必须是协议枚举之一。expected_domain必须参与安全校验。hmac必须由当前会话密钥计算。
3.4 Response
浏览器回包结构:
{
"seq": 1,
"type": "response",
"success": true,
"data": {},
"aom_snapshot": [],
"timing": {
"queue_ms": 0,
"exec_ms": 12
}
}
Rust 侧依赖此消息完成工具调用闭环。
seq 不匹配、超时或缺失都应视为协议错误。
3.5 与浏览器对接标准的关系
docs/浏览器对接标准.md 是联调规范。
L2 是产品内核视角的契约说明。两者关系如下:
- L2 负责解释“为什么有这些字段、这些模块如何依赖它们”。
- 对接标准负责约束“浏览器宿主必须如何实现 wire contract”。
4. 动作契约
4.1 协议枚举
协议层已经定义了以下动作枚举:
clicktypenavigategetTextgetHtmlwaitForSelectorpageScreenshotselectscrollTogetAomSnapshotstorageSetstorageGetzombieSpawnzombieKill
4.2 当前生效动作
当前文档、规则和工具 schema 必须以“生效动作”为准,而不是“预留枚举”为准。
生效动作只有 4 个:
clicktypenavigategetText
约束来源有三处,三者必须一致:
resources/rules.jsonsrc/agent/runtime.rs的 tool definitionsrc/compat/browser_tool_adapter.rs的parameters_schema与parse_action
这三者表达的是“当前特权浏览器工具面”的开放范围,而不是 sgClaw 整体 runtime 的长期能力上限。
5. browser_action 工具契约
5.1 工具名
固定为:
browser_action
5.2 参数 schema
当前有效参数:
actionexpected_domainselectortexturlclear_first
其中:
click通常需要selectortype通常需要selector与textnavigate通常需要urlgetText通常需要selector
5.3 失败语义
工具执行失败分两类:
-
参数级失败
说明:缺少必填字段、动作不支持、参数类型错误。 -
协议级失败
说明:MAC 不通过、浏览器回包success=false、响应超时、序列号异常。
这两类失败最终都会转为任务失败并通过 task_complete 回传。
6. 接口演进原则
L2 之后的扩展应遵守以下原则:
- 新增动作先进入协议枚举,再补规则白名单,再开放给 tool schema。
- 不允许只改文档或只改提示词就宣称动作可用。
- 兼容层与 fallback 路径必须对外保持同一工具名和同一主契约。
- 浏览器宿主联调时以 wire contract 为最高优先级,不把模型行为假设写进协议。