Gateway architecture
最后更新:2026-01-22
概览
- 一个长生命周期的 Gateway 负责所有消息表面(WhatsApp via Baileys、Telegram via grammY、Slack、Discord、Signal、iMessage、WebChat)。
- 控制面客户端(macOS app、CLI、web UI、automations)通过 WebSocket 连接到 Gateway(绑定 host 默认
127.0.0.1:18789)。 - Nodes(macOS/iOS/Android/headless)也通过 WebSocket 连接,但会在
connect中声明role: node,并提供明确的 caps/commands。 - 每台主机一个 Gateway;它是唯一会打开 WhatsApp session 的地方。
- 一个 canvas host(默认
18793)提供可由 agent 编辑的 HTML 与 A2UI。
组件与流程
Gateway(daemon)
- 维护各 provider 连接。
- 暴露强类型 WS API(requests、responses、server‑push events)。
- 以 JSON Schema 校验入站 frames。
- 发出
agent、chat、presence、health、heartbeat、cron等 events。
Clients(mac app / CLI / web admin)
- 每个 client 一条 WS 连接。
- 发送 requests(
health、status、send、agent、system-presence)。 - 订阅 events(
tick、agent、presence、shutdown)。
Nodes(macOS / iOS / Android / headless)
- 以
role: node连接到同一台 WS server。 - 在
connect中提供 device identity;pairing 以设备为单位(rolenode),审批记录保存在设备配对 store 中。 - 暴露
canvas.*、camera.*、screen.record、location.get等 commands。
协议细节:
WebChat
- 静态 UI,使用 Gateway WS API 获取 chat history 与发送消息。
- 远端部署时,会通过与其他 clients 相同的 SSH/Tailscale tunnel 连接。
连接生命周期(单个 client)
Client Gateway
| |
|---- req:connect -------->|
|<------ res (ok) ---------| (or res error + close)
| (payload=hello-ok carries snapshot: presence + health)
| |
|<------ event:presence ---|
|<------ event:tick -------|
| |
|------- req:agent ------->|
|<------ res:agent --------| (ack: {runId,status:"accepted"})
|<------ event:agent ------| (streaming)
|<------ res:agent --------| (final: {runId,status,summary})
| |Wire protocol(摘要)
- Transport:WebSocket,JSON text frames。
- 第一条 frame 必须是
connect。 - 握手完成后:
- Requests:
{type:"req", id, method, params}→{type:"res", id, ok, payload|error} - Events:
{type:"event", event, payload, seq?, stateVersion?}
- Requests:
- 如果设置了
openclaw_GATEWAY_TOKEN(或--token),则connect.params.auth.token必须匹配,否则 socket 会关闭。 - 对有副作用的方法(
send、agent)需要 idempotency keys 以便安全重试;server 会维护一个短生命周期的去重 cache。 - Nodes 必须在
connect中包含role: "node",并提供 caps/commands/permissions。
Pairing + 本地信任
- 所有 WS clients(operators + nodes)都会在
connect中包含 device identity。 - 新 device IDs 需要配对审批;Gateway 会签发一个 device token 用于后续连接。
- 本地连接(loopback 或 gateway host 自身的 tailnet 地址)可以自动审批,以保持同主机体验顺畅。
- 非本地连接必须对
connect.challenge的 nonce 签名,并需要显式审批。 - Gateway auth(
gateway.auth.*)对所有连接都生效(本地或远端)。
细节参见:Gateway protocol、Pairing、Security。
协议类型与 codegen
- TypeBox schemas 定义协议。
- 从 schemas 生成 JSON Schema。
- 从 JSON Schema 生成 Swift models。
远端访问
首选:Tailscale 或 VPN。
备选:SSH tunnel
bashssh -N -L 18789:127.0.0.1:18789 user@hosttunnel 上仍使用同一套 handshake + auth token。
远端部署下可为 WS 启用 TLS + 可选 pinning。
运维速览
- 启动:
moltbot gateway(前台运行,日志输出到 stdout)。 - 健康检查:通过 WS 调用
health(也会包含在hello-ok中)。 - 监督:用 launchd/systemd 做自动重启。
不变量(Invariants)
- 每台主机恰好一个 Gateway 控制单个 Baileys session。
- handshake 是强制的;任何非 JSON 或“第一条不是 connect”的 frame 都会被强制关闭。
- events 不会被回放;clients 必须在出现缺口时自行刷新。