外部应用
外部应用通过 Gateway 协议与 OpenClaw 通信:该协议采用 WebSocket 传输并配合 RPC 方法。当脚本、仪表盘、CI 任务、IDE 扩展或其他进程想要启动 agent 运行、流式接收事件、等待结果、取消工作或检查 Gateway 资源时,可使用此协议。
Note
如需了解 npm 包、设备配对、重连恢复、历史记录、订阅和审批,请从
构建 Gateway 客户端 开始。安装指南固定了已验证的稳定版 2026.8.1 包,并解释包版本与线路版本如何影响兼容性。如果你的应用将 Gateway 作为子进程监管,请同时阅读 嵌入 OpenClaw。
Note
本页面面向 OpenClaw 进程外部的代码。在 OpenClaw 内部运行的插件代码应改用文档中记载的 openclaw/plugin-sdk/* 子路径。
当前可用的功能¶
| 接口 | 状态 | 用途 |
|---|---|---|
| Gateway 客户端指南 | 稳定包 | npm 包、认证、重连、历史记录、事件、审批和版本策略。 |
| 嵌入指南 | 发布线 | 子进程环境、就绪性、生命周期、恢复、RPC 所有权和打包。 |
| Gateway 协议 | 就绪 | WebSocket 传输、连接握手、认证范围、协议版本控制和事件。 |
| Gateway 协议 RPC 方法 | 就绪 | 用于 agents、sessions、tasks、models、tools、artifacts 和 approvals 的当前 Gateway 方法。 |
openclaw agent |
就绪 | 当仅需调用 CLI 即可完成一次性脚本集成时使用。 |
openclaw message |
就绪 | 从脚本发送消息或频道操作。 |
推荐路径¶
- 运行或发现一个 Gateway。
- 通过 Gateway 协议 连接。
- 调用 Gateway 协议 RPC 方法 中记载的 RPC 方法。
- 固定你测试所用的 OpenClaw 版本。
- 升级 OpenClaw 时重新检查 RPC 参考文档。
对于 agent 运行,从 agent RPC 开始,并将其与 agent.wait 搭配使用以获取最终结果。如需持久化的对话状态,请使用 sessions.* 方法。对于 UI 集成,请订阅 Gateway 事件,并仅渲染你的应用能够理解的事件族。
agent.wait 在回合排队时可返回 status: "pending"。没有终止元数据的超时响应表示等待已过期;请继续等待或消费生命周期事件。终止 status: "error" 可表示取消:stopReason: "superseded" 表示新会话写入者取代了该运行。在呈现结果时请保留该原因。
协作式主机挂起¶
负责冻结或快照运行中进程的主机控制器可以使用与主机无关的挂起握手:
- 停止接受由主机控制的外部入口流量。
- 使用稳定且唯一的
requestId调用gateway.suspend.prepare。 - 如果响应为
busy,请保持进程运行并稍后重试。若要在已完成准入的工作继续运行期间保持准入关闭,请改为请求可选的 drain 模式,并轮询gateway.suspend.status。 - 如果响应为
ready,请保存返回的suspensionId,然后在expiresAtMs之前冻结或快照进程。 - 解冻后,或如果放弃挂起,请通过现有或新认证的 WebSocket 使用该
suspensionId调用gateway.suspend.resume。对应的 CLI 命令是openclaw gateway suspend和openclaw gateway resume <suspensionId>。
处于 draining 或 prepared 状态的 Gateway 接受经过认证的操作员 WebSocket 连接,使控制器能够重新连接并检查、续订或释放自己的租约。新的节点和工作进程连接仍被隔离。处于 prepared 状态的 Gateway 会隔离除 gateway.suspend.* 和一个精确绑定前任的重启之外的所有方法。该例外需要一个非安全的 gateway.restart.request,其 target 必须与当前运行的 Gateway 锁匹配;安全且未指定目标的重启请求仍被隔离。当 Gateway 仍在 draining 时,该重启 RPC 例外不可用。控制器可在解冻后重新连接并调用 resume。对于完全无法使用 WebSocket 的主机,Admin HTTP RPC 插件 仍然可用。如果所有控制路径都丢失,两分钟的租约到期将自动重新开启准入。
关闭 Gateway 会取消由操作员重连排入队列的后台工作,而无需等待挂起到期。关闭过程仍会等待已在运行的工作完成。
hello 快照包含 suspension: { phase },gateway.suspension 事件会立即发布准入状态变化。phase 为 accepting、preparing、draining 或 prepared;这两个接口均不暴露挂起 ID。Control UI 左下角的连接指示器在 preparing 或 draining 期间显示 挂起中…,在 prepared 状态下显示 已挂起(包括在 Settings 中)。该指示器会在挂起准入重新开启时清除,而不是在请求成功时清除。离线与重启指示器优先。调度器恢复会保持挂起指示器,直到准入实际重新开启;没有单独的恢复中阶段。
RPC 契约如下:
gateway.suspend.prepare—operator.admin;参数{ "requestId": "stable-host-operation-id", "terminalPolicy": "preserve", "drain": true }gateway.suspend.status—operator.read;参数{ "suspensionId": "id-from-prepare", "includeLifecycle": true }gateway.suspend.resume—operator.admin;参数{ "suspensionId": "id-from-prepare" }gateway.suspend.handoff—operator.admin;参数{ "suspensionId": "id-from-prepare", "target": { "pid": 123, "processInstanceId": "id-from-system-info" } }
terminalPolicy 和 drain 是可选的。terminalPolicy 仅接受
"preserve" 或 "terminate",默认为 "preserve";drain 默认为
false。终端策略同时适用于即时准备和 drain 模式:
"preserve":打开的终端会话会阻止挂起。对于必须保留正在运行的进程的主机 冻结/快照操作,请使用此策略。"terminate":打开的进程本地终端会话不会阻止挂起。 对于将重启 Gateway 的发布更新,请使用此策略。准备阶段不会 关闭终端;实际的 Gateway 重启会结束它们的 PTY 和命令。
待处理的最终聊天状态写入(terminal-persistence)以及所有其他受跟踪的工作,
在任一策略下仍会阻止准备。
ID 会去除首尾空白,必须包含非空白字符,且长度限制为
128 个字符。繁忙的准备结果具有 status: "busy"、reason、
retryAfterMs、activeCount 和 blockers。就绪结果具有如下结构:
{
"status": "ready",
"suspensionId": "2c3f...",
"expiresAtMs": 1770000000000,
"activeCount": 0,
"blockers": []
}
如果 drain: true 发现活动工作,准备会获取一个可续租的租约,
暂停新的自动 cron 调度,关闭对无关新工作的准入,
并返回:
{
"status": "draining",
"suspensionId": "2c3f...",
"expiresAtMs": 1770000000000,
"retryAfterMs": 20000,
"activeCount": 2,
"blockers": [
{ "kind": "root-request", "count": 1, "message": "1 active request" },
{ "kind": "terminal-session", "count": 1, "message": "1 open terminal session" }
]
}
已准入的工作及其所属完成操作会自然继续;无关的新运行、会话、计划任务和独立工作仍会被拒绝。在
terminalPolicy: "preserve" 下,打开的终端可使租约保持 draining 状态,直到
其关闭、控制器恢复 Gateway 或租约过期。在
terminalPolicy: "terminate" 下,同一终端仍保持打开,但不会
阻止就绪。两种策略都不会在准备、轮询、续租、恢复或租约过期期间终止或分离终端。
使用返回的 suspensionId 轮询 gateway.suspend.status,并遵守
retryAfterMs。当仍存在阻塞项时,状态会返回 status: "draining",
并附带 expiresAtMs、retryAfterMs、activeCount 和 blockers。
每次状态调用都会刷新活动工作快照。当所有阻塞项都完成后,同一租约会转为 {"status":"ready","expiresAtMs":...}。
状态默认保留原始响应结构,以兼容已发布的验证器。
使用 includeLifecycle: true 选择加入生命周期元数据,以接收 ownerId
和原始 requestId;draining 状态还会包含 phase: "draining"。
请求此元数据时,请使用更新后的响应验证器。
当没有持有挂起时,状态返回 {"status":"running"};查询另一个活动租约会返回冲突,且不暴露其标识符。
恢复返回 {"ok":true,"status":"running","resumed":true};在成功恢复后重复调用会返回 resumed: false。
专用的 openclaw gateway suspend 命令保留其现有的仅拒绝行为。控制器可以通过任意 Gateway
客户端或通用 CLI RPC 命令请求 drain 模式:
openclaw gateway call gateway.suspend.prepare \
--params '{"requestId":"host-operation-1","terminalPolicy":"preserve","drain":true}' \
--json
openclaw gateway call gateway.suspend.status \
--params '{"suspensionId":"<suspension-id>"}' \
--json
openclaw gateway resume '<suspension-id>'
对于发布更新,请使用相同的握手流程并设置 terminalPolicy: "terminate",
以避免打开的终端无限期保持 drain:
openclaw gateway call gateway.suspend.prepare \
--params '{"requestId":"release-update-1","terminalPolicy":"terminate","drain":true}' \
--json
在执行受检重启之前,请等待租约变为 ready。
重启后不会恢复终端命令和滚动回显;参见
重启恢复。
明确授权中断剩余工作的外部部署控制器,可以在其自身的优雅 drain 预算之后,改为调用 gateway.suspend.handoff。目标必须匹配挂起前从
system.info 获取的 pid 和 processInstanceId。这将为
该确切租约和主机迭代的下一次 SIGTERM 武装重启清理;它
不会发送信号或创建继任者。控制器仍负责
原生服务重启。成功响应为
{ "status": "armed", "suspensionId": "...", "expiresAtMs": ... }。
武装状态随租约一起过期。重复 prepare 或 handoff 不会延长
武装权限。恢复、替换、另一个已接受的生命周期操作或
主机退役会使它失效。待处理的最终聊天持久化会拒绝武装,
并会在 SIGTERM 消耗该武装时再次检查。如果该检查拒绝,
Gateway 会记录拒绝并保留普通优雅停止行为。
已接受的 handoff 会使用现有的重启恢复和中止清理,
然后为外部控制器退出。没有武装的普通停止会继续等待活动工作。控制器必须在遇到不支持的方法或被拒绝的 handoff 时推迟;仅凭 draining 租约永远不能授权中断。
一旦关闭提交,包括在持有挂起期间发生的安装替换重启,同一所有者仍可以轮询 status: "draining"。使用
includeLifecycle: true 时,它还会收到 phase: "interrupting"。所有权和
外部令牌冲突在已认证操作员重连期间保持稳定;
节点和工作进程连接仍保持隔离。关闭记录在旧租约过期后仍可用;这是关闭进度,而不是可续租的租约或
冻结进程的权限。关闭提交后,恢复会被拒绝。
所有者会在服务器拆除前记录 phase: "exiting";当该拆除关闭请求准入和传输时,RPC 访问结束。这些事实会保留
在内存中,直到进程退出或下一个进程内生命周期重置它们。
正在运行的 Gateway 提供此契约;预置较新的安装版本不会改变旧驻留实例的响应。仅当支持它的 Gateway 版本正在运行时,才请求生命周期元数据。驱动程序仍必须验证其确切的前驱,并通过其生命周期所有者处理传输关闭。
冲突的请求 ID 或瞬时的调度器恢复失败会返回可重试的 UNAVAILABLE,并附带 retryAfterMs。在调度器恢复期间,prepare、status 和 resume 都会返回该错误,Gateway 保持未就绪且 fail-closed,宿主不得冻结或快照它。OpenClaw 会自动重试调度器,并仅在恢复成功后重新开放准入。不匹配的 resume ID 会返回 INVALID_REQUEST。Prepare 受 Gateway 控制平面写入限制约束,每分钟 30 次尝试;请遵循返回的重试延迟。WebSocket 客户端按设备和 IP 分桶。Admin HTTP 控制器按解析后的客户端 IP 分桶,因此位于同一代理后面的控制器可以共享预算。
如果没有 drain: true,准备阶段保持仅拒绝:OpenClaw 会关闭新的 root/session/command 准入,暂停自动 cron 触发,并同步检查任务。如果有任何活动任务,它会恢复调度器并在返回 busy 之前重新开放准入;它不会中断或排空该任务。如果设置了 drain: true,相同的挂起所有者会保持准入关闭并暂停 cron 调度,直到现有任务结束。已拥有的 cron 完成和对账会继续。
draining 和 ready 租约共享一个两分钟预算,该预算在任务检查之前开始。耗尽该预算的准备操作会恢复调度并失败,而不是返回已过期的租约。时钟回拨不会延长预算。在 expiresAtMs 之前,使用相同的 requestId、terminal policy 和 drain 模式重复 prepare,以续期相同的 suspensionId,除非已启用重启交接;更改其中任何值都会与现有租约冲突。使用 status 进行常规轮询,并保留 prepare 用于续期,以避免消耗写入预算。显式 resume 和租约过期会在重新开放准入之前恢复调度。租约保存在内存中,如果 Gateway 进程退出则会消失。
在 ready 租约期间到期的重启事件会等待租约恢复;进行中的重启会使准备操作返回 busy。
在 draining 或 ready 期间,/healthz 保持存活,/readyz 返回 503。本地或已认证的 readiness 响应包含 gateway-draining;未认证的远程探测仅收到 { "ready": false }。HTTP 健康探测、已认证操作员 WebSocket 连接上的挂起方法,以及已启用的 Admin HTTP RPC 路由仍然可用。其他无关的 RPC 会返回可重试的 UNAVAILABLE。内置 HTTP 用户工作路由和普通插件 HTTP 路由,包括 OpenAI 兼容 API、tool/session 操作、节点监视和已配置的 hooks,会返回 503,并带有 error.code: "gateway_unavailable"。新的插件拥有的 WebSocket 升级也会返回 503;这涵盖升级所有权,而不是之后通过已建立的插件套接字执行的工作。
此握手不会持久化传入消息、停止第三方 channel 传输或控制托管平台。宿主必须在准备之前隔离其入口,并继续负责唤醒、快照/冻结和停止。activeCount 是跟踪任务的聚合计数,而 blockers 包含非零的原生类别计数和有界的摘要消息。类别包括 background-exec、cron-run、agent-run、acp-run 和 media-generation,以及请求、队列、回复、会话和 terminal 任务。类别可能重叠,因此该计数不是唯一任务的数量。这不是一般的进程静默屏障。Blockers 不包含命令文本、输出、操作系统进程 ID 或会话或 scope 标识符。Channel 健康检查、维护、缓存刷新、已建立的插件 WebSocket 会话以及未注册的插件拥有的后台任务可能保持活动。
托管平台必须一致地冻结或快照完整进程树及其文件系统;未注册的任务无法通过此初始契约证明为空闲。
Tip
对于宿主唤醒调度,请将面向 OpenClaw 的部分保留在进程内插件中,并将幂等的完整快照投影到外部宿主适配器。 托管控制器不应导入 Plugin SDK,也不应从事件增量重建 cron 状态。参见 安全的外部 cron 投影。
应用代码与插件代码¶
当代码位于 OpenClaw 外部时,使用 Gateway RPC:
- 启动或观察 agent 运行的 Node 脚本
- 调用 Gateway 的 CI 任务
- 仪表板和管理面板
- IDE 扩展
- 无需成为 channel 插件的外部桥接
- 使用模拟或真实 Gateway 传输的集成测试
当代码在 OpenClaw 内部运行时,使用 Plugin SDK:
- provider 插件
- channel 插件
- 工具或生命周期钩子
- agent harness 插件
- 受信任的运行时辅助工具
外部应用不应导入 openclaw/plugin-sdk/*;这些子路径用于由 OpenClaw 加载的插件。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw