Gateway service runbook
最后更新:2025-12-09
它是什么
- 一个常驻进程:拥有单一的 Baileys/Telegram 连接,以及控制/事件平面。
- 取代旧的
gateway命令。CLI 入口:openclaw gateway。 - 持续运行直到停止;遇到致命错误会以非 0 退出,以便 supervisor 重启它。
如何运行(本地)
openclaw gateway --port 18789
# 如果你需要在 stdio 中看到完整 debug/trace 日志:
openclaw gateway --port 18789 --verbose
# 如果端口忙,先终止监听再启动:
openclaw gateway --force
# 开发循环(TS 变更自动重载):
pnpm gateway:watch- Config 热重载会监视
~/.openclaw/openclaw.json(或OPENCLAW_CONFIG_PATH)。- 默认模式:
gateway.reload.mode="hybrid"(安全变更热应用;关键变更重启)。 - 需要重启时,热重载会使用进程内重启并发送 SIGUSR1。
- 用
gateway.reload.mode="off"禁用。
- 默认模式:
- WebSocket 控制面默认绑定到
127.0.0.1:<port>(默认 18789)。 - 同一端口也会提供 HTTP(Control UI、hooks、A2UI),单端口复用。
- OpenAI Chat Completions(HTTP):
/v1/chat/completions。 - OpenResponses(HTTP):
/v1/responses。 - Tools Invoke(HTTP):
/tools/invoke。
- OpenAI Chat Completions(HTTP):
- 默认会在
canvasHost.port(默认18793)启动 Canvas 文件服务器:从~/.openclaw/workspace/canvas提供http://<gateway-host>:18793/__openclaw__/canvas/。 通过canvasHost.enabled=false或OPENCLAW_SKIP_CANVAS_HOST=1禁用。 - 日志输出到 stdout;使用 launchd/systemd 保活并做日志轮转。
- 排障时可用
--verbose:把 log file 中的 debug 日志(握手、req/res、events)镜像到 stdio。 --force会用lsof找出选择端口上的 listeners,发送 SIGTERM,记录被杀掉的进程,然后启动 gateway(如果缺少lsof会快速失败)。- 如果你在 supervisor 下运行(launchd/systemd/mac app child-process mode),stop/restart 通常会发送 SIGTERM;旧版本可能会表现为
pnpm的ELIFECYCLE退出码 143(SIGTERM),这是正常关闭而不是崩溃。 - SIGUSR1 在被授权时触发进程内重启(gateway tool/config apply/update,或启用
commands.restart允许手动重启)。 - 默认需要 Gateway auth:设置
gateway.auth.token(或OPENCLAW_GATEWAY_TOKEN)或gateway.auth.password。 客户端必须发送connect.params.auth.token/password,除非使用 Tailscale Serve identity。 - 向导现在默认会生成 token,即使是在 loopback 模式。
- 端口优先级:
--port>OPENCLAW_GATEWAY_PORT>gateway.port> 默认18789。
远程访问
- 优先使用 Tailscale/VPN;否则使用 SSH 隧道:bash
ssh -N -L 18789:127.0.0.1:18789 user@host - 客户端随后通过隧道连接
ws://127.0.0.1:18789。 - 如果配置了 token,即使走隧道客户端也必须在
connect.params.auth.token中携带它。
多个 gateways(同一主机)
通常没必要:一个 Gateway 能服务多个消息 channels 与 agents。只有在冗余或严格隔离(例如 rescue bot)场景下才需要多个 Gateways。
只要你隔离 state + config 并使用唯一端口,该方案就受支持。完整指南见:Multiple gateways。
service 名称会随 profile 变化:
- macOS:
bot.molt.<profile>(可能仍存在 legacycom.openclaw.*) - Linux:
openclaw-gateway-<profile>.service - Windows:
OpenClaw Gateway (<profile>)
安装元信息会写入 service config:
OPENCLAW_SERVICE_MARKER=openclawOPENCLAW_SERVICE_KIND=gatewayOPENCLAW_SERVICE_VERSION=<version>
Rescue-Bot 模式:保持第二个 Gateway 隔离,使用独立 profile/state dir/workspace,并预留足够的 base port 间隔。完整指南见:Rescue-bot guide。
Dev profile(--dev)
快速路径:运行一个完全隔离的 dev 实例(config/state/workspace),不影响你的主配置。
openclaw --dev setup
openclaw --dev gateway --allow-unconfigured
# 然后把 CLI 指向 dev 实例:
openclaw --dev status
openclaw --dev health默认值(可通过 env/flags/config 覆盖):
OPENCLAW_STATE_DIR=~/.openclaw-devOPENCLAW_CONFIG_PATH=~/.openclaw-dev/openclaw.jsonOPENCLAW_GATEWAY_PORT=19001(Gateway WS + HTTP)- browser control service port =
19003(派生:gateway.port+2,仅 loopback) canvasHost.port=19005(派生:gateway.port+4)- 当你在
--dev下运行setup/onboard,agents.defaults.workspace默认会变成~/.openclaw/workspace-dev。
派生端口(经验规则):
- Base port =
gateway.port(或OPENCLAW_GATEWAY_PORT/--port) - browser control service port = base + 2(仅 loopback)
canvasHost.port = base + 4(或OPENCLAW_CANVAS_HOST_PORT/ config 覆盖)- Browser profile CDP 端口从
browser.controlPort + 9 .. + 108自动分配(按 profile 持久化)。
每个实例的检查清单:
- 唯一的
gateway.port - 唯一的
OPENCLAW_CONFIG_PATH - 唯一的
OPENCLAW_STATE_DIR - 唯一的
agents.defaults.workspace - 独立的 WhatsApp 号码(如果使用 WA)
按 profile 安装 service:
openclaw --profile main gateway install
openclaw --profile rescue gateway install示例:
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json OPENCLAW_STATE_DIR=~/.openclaw-a openclaw gateway --port 19001
OPENCLAW_CONFIG_PATH=~/.openclaw/b.json OPENCLAW_STATE_DIR=~/.openclaw-b openclaw gateway --port 19002协议(operator 视角)
- 完整文档:Gateway protocol 与 Bridge protocol(legacy)。
- 客户端必需的第一帧:
req {type:"req", id, method:"connect", params:{minProtocol,maxProtocol,client:{id,displayName?,version,platform,deviceFamily?,modelIdentifier?,mode,instanceId?}, caps, auth?, locale?, userAgent? } }。 - Gateway 回复:
res {type:"res", id, ok:true, payload:hello-ok }(或ok:false带 error,然后关闭连接)。 - 握手完成后:
- Requests:
{type:"req", id, method, params}→{type:"res", id, ok, payload|error} - Events:
{type:"event", event, payload, seq?, stateVersion?}
- Requests:
- 结构化 presence 条目:
{host, ip, version, platform?, deviceFamily?, modelIdentifier?, mode, lastInputSeconds?, ts, reason?, tags?[], instanceId? }(对 WS clients,instanceId来自connect.client.instanceId)。 agent响应是两阶段:先resack{runId,status:"accepted"},run 结束后再返回最终res{runId,status:"ok"|"error",summary};流式输出通过event:"agent"发送。
Methods(初始集合)
health— 完整 health snapshot(与openclaw health --json同结构)。status— 简短摘要。system-presence— 当前 presence 列表。system-event— 发布一条 presence/system note(结构化)。send— 通过活跃 channel(s) 发送消息。agent— 运行一次 agent turn(在同一连接上回传 events)。node.list— 列出已配对 + 当前已连接的 nodes(包含caps、deviceFamily、modelIdentifier、paired、connected与广播的commands)。node.describe— 描述某个 node(capabilities + 支持的node.invokecommands;对已配对 nodes 与当前已连接但未配对 nodes 均可用)。node.invoke— 在 node 上调用命令(例如canvas.*、camera.*)。node.pair.*— 配对生命周期(request、list、approve、reject、verify)。
另见:Presence(解释 presence 如何产生/去重,以及稳定的 client.instanceId 为什么重要)。
Events
agent— agent run 的流式 tool/output events(带 seq)。presence— presence 更新(带 stateVersion 的增量),推送给所有连接的客户端。tick— 周期性 keepalive/no-op,用于确认存活。shutdown— Gateway 即将退出;payload 包含reason与可选的restartExpectedMs。客户端应重连。
WebChat 集成
- WebChat 是一个原生 SwiftUI UI,直接通过 Gateway WebSocket 获取历史、发送、abort 与 events。
- 远程使用走同一条 SSH/Tailscale 隧道;如果配置了 gateway token,客户端会在
connect时携带它。 - macOS app 通过一个共享 WS 连接;它从初始 snapshot 注入 presence,并监听
presenceevents 来更新 UI。
类型与校验
- 服务端用 AJV 对每个入站 frame 做校验,schema 来自协议定义生成的 JSON Schema。
- 客户端(TS/Swift)消费生成的类型(TS 直接使用;Swift 使用仓库里的 generator)。
- 协议定义是事实来源;用以下命令重新生成 schema/models:
pnpm protocol:genpnpm protocol:gen:swift
连接快照(Connection snapshot)
hello-ok会包含一个snapshot,其中含presence、health、stateVersion、uptimeMs,以及policy {maxPayload,maxBufferedBytes,tickIntervalMs},使客户端无需额外请求即可立即渲染。health/system-presence仍可用于手动刷新,但 connect 时不是必需。
错误码(res.error 结构)
- Errors 使用
{ code, message, details?, retryable?, retryAfterMs? }。 - 标准 codes:
NOT_LINKED— WhatsApp 未鉴权。AGENT_TIMEOUT— agent 未在配置的 deadline 内响应。INVALID_REQUEST— schema/参数校验失败。UNAVAILABLE— Gateway 正在关闭或依赖不可用。
Keepalive 行为
- 周期性发出
tickevents(或 WS ping/pong),使客户端在无流量时也能确认 Gateway 存活。 - send/agent 的 acknowledgements 仍是独立的 responses;不要用 ticks 代替 send 的 ack。
Replay / gaps
- events 不会 replay。客户端检测到 seq gap 时,应在继续前刷新(
health+system-presence)。WebChat 与 macOS 客户端现在会在 gap 时自动刷新。
Supervision(macOS 示例)
- 使用 launchd 保持 service 存活:
- Program:
openclaw的路径 - Arguments:
gateway - KeepAlive:true
- StandardOut/Err:文件路径或
syslog
- Program:
- 出错时 launchd 会重启;致命的 misconfig 应持续退出,以便 operator 注意到。
- LaunchAgents 是按用户的,且需要登录态;对 headless 需要自建 LaunchDaemon(不随项目提供)。
openclaw gateway install会写入~/Library/LaunchAgents/bot.molt.gateway.plist(或bot.molt.<profile>.plist;同时会清理 legacycom.openclaw.*)。openclaw doctor会审计 LaunchAgent 配置,并可更新为当前默认值。
Gateway service 管理(CLI)
使用 Gateway CLI 做 install/start/stop/restart/status:
openclaw gateway status
openclaw gateway install
openclaw gateway stop
openclaw gateway restart
openclaw logs --follow备注:
gateway status默认会用 service 解析到的端口/config probe Gateway RPC(可用--url覆盖)。gateway status --deep会增加系统级扫描(LaunchDaemons/system units)。gateway status --no-probe会跳过 RPC probe(网络不通时有用)。gateway status --json对脚本稳定。gateway status会分别报告 supervisor runtime(launchd/systemd 是否在运行)与 RPC reachability(WS connect + status RPC)。gateway status会打印 config path + probe target,避免 “localhost vs LAN bind” 混淆与 profile 不匹配。- 当 service 看似运行但端口关闭时,
gateway status会包含最后一条 gateway 错误行。 logs通过 RPC tail Gateway 文件日志(无需手动tail/grep)。- 如果检测到其它类似 gateway 的 services,CLI 会警告,除非它们是 OpenClaw profile services。 大多数场景仍建议 一机一个 gateway;若要冗余或 rescue bot,请用隔离 profiles/ports。见 Multiple gateways。
- 清理:
openclaw gateway uninstall(当前 service)与openclaw doctor(legacy migrations)。
- 清理:
gateway install在已安装时是 no-op;使用openclaw gateway install --force重装(profile/env/path 变更)。
Bundled mac app:
- OpenClaw.app 可打包一个基于 Node 的 gateway relay,并安装一个 per-user 的 LaunchAgent,label 为
bot.molt.gateway(或bot.molt.<profile>;legacycom.openclaw.*labels 仍会被干净卸载)。 - 要干净停止,使用
openclaw gateway stop(或launchctl bootout gui/$UID/bot.molt.gateway)。 - 要重启,使用
openclaw gateway restart(或launchctl kickstart -k gui/$UID/bot.molt.gateway)。launchctl只有在 LaunchAgent 已安装时可用;否则先运行openclaw gateway install。- 运行命名 profile 时,将 label 替换为
bot.molt.<profile>。
Supervision(systemd user unit)
OpenClaw 在 Linux/WSL2 上默认安装 systemd user service。 对单用户机器推荐 user services(环境更简单、per-user config)。 对多用户或 always-on 服务器推荐 system service(无需 lingering、共享 supervision)。
openclaw gateway install 会写入 user unit。openclaw doctor 会审计 unit 并可更新为当前推荐默认值。
创建 ~/.config/systemd/user/openclaw-gateway[-<profile>].service:
[Unit]
Description=OpenClaw Gateway (profile: <profile>, v<version>)
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/openclaw gateway --port 18789
Restart=always
RestartSec=5
Environment=OPENCLAW_GATEWAY_TOKEN=
WorkingDirectory=/home/youruser
[Install]
WantedBy=default.target启用 lingering(必需:使 user service 在登出/空闲后仍存活):
sudo loginctl enable-linger youruserOnboarding 会在 Linux/WSL2 上执行此操作(可能提示 sudo;写入 /var/lib/systemd/linger)。 然后启用 service:
systemctl --user enable --now openclaw-gateway[-<profile>].service替代方案(system service):对 always-on 或多用户服务器,可以安装 systemd system unit(无需 lingering)。 创建 /etc/systemd/system/openclaw-gateway[-<profile>].service(复制上面的 unit,把 WantedBy 改为 multi-user.target,设置 User= + WorkingDirectory=),然后:
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-gateway[-<profile>].serviceWindows(WSL2)
Windows 安装应使用 WSL2 并遵循上面的 Linux systemd 章节。
运维检查
- 存活性(Liveness):打开 WS 并发送
req:connect→ 期望收到res且payload.type="hello-ok"(带 snapshot)。 - 就绪性(Readiness):调用
health→ 期望ok: true,且linkChannel中存在已连接的 channel(如适用)。 - Debug:订阅
tick与presenceevents;确认status显示 linked/auth age;presence 条目显示 Gateway host 与已连接客户端。
安全保证
- 默认假设一机一个 Gateway;如果你运行多个 profiles,请隔离 ports/state,并指向正确实例。
- 不会 fallback 到直连 Baileys;如果 Gateway down 了,发送会快速失败。
- 非 connect 的首帧或不合法 JSON 会被拒绝并关闭 socket。
- 优雅关闭:在关闭前发出
shutdownevent;客户端必须处理 close + reconnect。
CLI 辅助命令
openclaw gateway health|status— 通过 Gateway WS 请求 health/status。openclaw message send --target <num> --message "hi" [--media ...]— 通过 Gateway 发送(对 WhatsApp 幂等)。openclaw agent --message "hi" --to <num>— 运行一次 agent turn(默认等待最终结果)。openclaw gateway call <method> --params '{"k":"v"}'— 用于排障的原始 method invoker。openclaw gateway stop|restart— 停止/重启被 supervisor 管理的 gateway service(launchd/systemd)。- gateway helper 子命令假设
--url指向一个运行中的 gateway;它们不再自动拉起 gateway。
迁移指引
- 逐步淘汰对旧
openclaw gateway与 legacy TCP control port 的依赖。 - 更新客户端以使用 WS 协议,并要求 mandatory connect 与结构化 presence。