Skip to content

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。
  • 发出 agentchatpresencehealthheartbeatcron 等 events。

Clients(mac app / CLI / web admin)

  • 每个 client 一条 WS 连接。
  • 发送 requests(healthstatussendagentsystem-presence)。
  • 订阅 events(tickagentpresenceshutdown)。

Nodes(macOS / iOS / Android / headless)

  • role: node 连接到同一台 WS server
  • connect 中提供 device identity;pairing 以设备为单位(role node),审批记录保存在设备配对 store 中。
  • 暴露 canvas.*camera.*screen.recordlocation.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?}
  • 如果设置了 openclaw_GATEWAY_TOKEN(或 --token),则 connect.params.auth.token 必须匹配,否则 socket 会关闭。
  • 对有副作用的方法(sendagent)需要 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 protocolPairingSecurity

协议类型与 codegen

  • TypeBox schemas 定义协议。
  • 从 schemas 生成 JSON Schema。
  • 从 JSON Schema 生成 Swift models。

远端访问

  • 首选:Tailscale 或 VPN。

  • 备选:SSH tunnel

    bash
    ssh -N -L 18789:127.0.0.1:18789 user@host
  • tunnel 上仍使用同一套 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 必须在出现缺口时自行刷新。