Files
claw/docs/L2-核心模块与接口契约层.md

10 KiB
Raw Permalink Blame History

L2 — 核心模块与接口契约层

文档版本: 2.1
适用项目: sgClawZeroClaw 重构版)
编制日期: 2026-03-29

读者: 架构工程师、实现工程师、联调工程师


1. 模块地图

当前仓库中的有效模块结构如下:

src/
├── main.rs
├── lib.rs
├── agent/
├── compat/
├── config/
├── llm/
├── pipe/
└── security/

模块边界按职责划分为五层:

层级 模块 责任
传输层 pipe 定义消息、握手、序列号、收发与命令等待
安全层 securityresources/rules.json 域名、动作与 pipe 命令边界控制
运行时入口层 lib.rsagent 接收任务、选择执行路径、回传日志与结果
适配层 compatconfig 把 sgClaw 宿主环境映射到 zeroclaw 运行时;当前仍带有过渡性限制
核心能力层 third_party/zeroclaw prompt、skills、memory、tool loop、provider 抽象

本轮冻结后还需要一组跨仓统一术语:

  • host 指 SuperRPA 浏览器宿主,只拥有安全边界、进程托管和展示装配权。
  • launch config 指由 host 读取的启动描述文件。
  • runtime config 指由 sgClaw 读取的运行时策略文件。
  • frontend bundle 指由 host 装载的前端展示资源。
  • planner-first 指 sgClaw / zeroclaw 先产生计划、前端先展示计划、随后再执行的运行时行为。

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 时优先尝试读取 SgClawSettings
  • 环境配置存在,则走 compat::runtime::execute_task_with_sgclaw_settings
  • 环境配置不存在,则直接返回“未配置大语言模型”,而不是再把生产 submit 流量导回旧 planner。

这就是当前系统的“路由器”。但文档上应把它理解为过渡性 runtime selector而不是最终产品架构中心。长期看planner-first、provider 选择与 backend 选择都应由 runtime config 显式驱动。

2.3 src/agent/runtime.rs

该文件现在应被视为 legacy/dev-only 模块,只保留仓库内的轻量 LLM/tool 调用逻辑用于局部验证,核心特点:

  • 工具名固定为 browser_action
  • schema 只允许 click/type/navigate/getText
  • 每次工具调用前后发送 log_entry
  • 结果失败时直接返回 PipeError::Protocol
  • 不参与当前生产浏览器 submit 路由。

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.7 host / launch config / runtime config 契约

跨仓接口收口后,host 与 sgClaw 的最小契约应为:

对象 读取方 责任 失败时兜底
launch config host 解析 binaryargsenvworking_dirruntime_config_pathfrontend_bundle_dir 回退到浏览器内置默认启动策略
runtime config sgClaw 解析 provider、model、planner mode、backend、skills policy 回退到 sgClaw 默认运行时配置
frontend bundle host 提供浮窗/面板展示资源 回退到浏览器内置 WebUI 资源

这里的关键点是:host 只负责校验和装配,不负责决定 planner、model routing 或 business behavior。

2.8 launch config 文件路径与回退规则

设计冻结口径如下:

  • profile-local launch config 路径:<profile>/superrpa/sgclaw_launch_config.json
  • profile-local runtime config 路径:<profile>/superrpa/sgclaw_config.json
  • profile-local hooks / rules 仍沿用:
    • <profile>/superrpa/hooks.json
    • <profile>/superrpa/rules.json

launch config 的回退规则必须保持稳定:

  1. 优先读取 <profile>/superrpa/sgclaw_launch_config.json
  2. 缺失或解析失败时,回退到当前浏览器内置默认启动参数
  3. runtime_config_path 缺失时,回退到 <profile>/superrpa/sgclaw_config.json
  4. frontend_bundle_dir 缺失、无效或校验失败时,回退到 bundled frontend resources

2.9 frontend bundle 与 planner-first 契约

frontend bundle 只能消费这些由 host 转发的运行时状态:

  • 当前状态与日志
  • planner 输出
  • 会话消息
  • 最终执行结果

frontend bundle 不能直接拥有:

  • provider 切换决策权
  • planner 开关控制权
  • executor 旁路能力

因此 planner-first 的契约应是:

  1. sgClaw / zeroclaw 产生计划
  2. frontend bundle 先展示计划
  3. 经运行时确认后再执行

这是一条 runtime contract不是一条前端内部约定。

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.comerp.example.comhr.example.com 及 demo 域名。
  • 允许动作:clicktypenavigategetText
  • 显式阻断:evalexecuteJsInPage

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

握手字段:

  • version
  • hmac_seed
  • capabilities

Rust 返回:

  • version
  • agent_id
  • supported_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 协议枚举

协议层已经定义了以下动作枚举:

  • click
  • type
  • navigate
  • getText
  • getHtml
  • waitForSelector
  • pageScreenshot
  • select
  • scrollTo
  • getAomSnapshot
  • storageSet
  • storageGet
  • zombieSpawn
  • zombieKill

4.2 当前生效动作

当前文档、规则和工具 schema 必须以“生效动作”为准,而不是“预留枚举”为准。
生效动作只有 4 个:

  • click
  • type
  • navigate
  • getText

约束来源有三处,三者必须一致:

  1. resources/rules.json
  2. src/agent/runtime.rs 的 tool definition
  3. src/compat/browser_tool_adapter.rsparameters_schemaparse_action

这三者表达的是“当前特权浏览器工具面”的开放范围,而不是 sgClaw 整体 runtime 的长期能力上限。


5. browser_action 工具契约

5.1 工具名

固定为:

browser_action

5.2 参数 schema

当前有效参数:

  • action
  • expected_domain
  • selector
  • text
  • url
  • clear_first

其中:

  • click 通常需要 selector
  • type 通常需要 selectortext
  • navigate 通常需要 url
  • getText 通常需要 selector

5.3 失败语义

工具执行失败分两类:

  1. 参数级失败
    说明:缺少必填字段、动作不支持、参数类型错误。

  2. 协议级失败
    说明MAC 不通过、浏览器回包 success=false、响应超时、序列号异常。

这两类失败最终都会转为任务失败并通过 task_complete 回传。


6. 接口演进原则

L2 之后的扩展应遵守以下原则:

  • 新增动作先进入协议枚举,再补规则白名单,再开放给 tool schema。
  • 不允许只改文档或只改提示词就宣称动作可用。
  • 兼容层与 fallback 路径必须对外保持同一工具名和同一主契约。
  • 浏览器宿主联调时以 wire contract 为最高优先级,不把模型行为假设写进协议。