跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Gateway 网关 WS 协议是 OpenClaw 的单一控制平面 + 节点传输协议。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明它们的角色 + 作用域

传输

  • WebSocket,使用带 JSON 载荷的文本帧。
  • 第一帧必须connect 请求。
  • 连接前帧大小上限为 64 KiB。握手成功后,客户端应遵循 hello-ok.policy.maxPayloadhello-ok.policy.maxBufferedBytes 限制。启用诊断后,过大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 payload.large 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或秘密值。

握手(connect)

Gateway 网关 → 客户端(连接前质询):
{
  "type": "event",
  "event": "connect.challenge",
  "payload": { "nonce": "…", "ts": 1737264000000 }
}
客户端 → Gateway 网关:
{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 4,
    "client": {
      "id": "cli",
      "version": "1.2.3",
      "platform": "macos",
      "mode": "operator"
    },
    "role": "operator",
    "scopes": ["operator.read", "operator.write"],
    "caps": [],
    "commands": [],
    "permissions": {},
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-cli/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}
Gateway 网关 → 客户端:
{
  "type": "res",
  "id": "…",
  "ok": true,
  "payload": {
    "type": "hello-ok",
    "protocol": 4,
    "server": { "version": "…", "connId": "…" },
    "features": { "methods": ["…"], "events": ["…"] },
    "snapshot": { "…": "…" },
    "auth": {
      "role": "operator",
      "scopes": ["operator.read", "operator.write"]
    },
    "policy": {
      "maxPayload": 26214400,
      "maxBufferedBytes": 52428800,
      "tickIntervalMs": 15000
    }
  }
}
当 Gateway 网关仍在完成启动 sidecar 时,connect 请求可能返回可重试的 UNAVAILABLE 错误,其中 details.reason 设为 "startup-sidecars" 并带有 retryAfterMs。客户端应在其整体连接预算内重试该响应,而不是将其呈现为终止性握手失败。 serverfeaturessnapshotpolicy 都是 schema(src/gateway/protocol/schema/frames.ts)要求的字段。auth 也是必填字段,并报告协商后的角色/作用域。pluginSurfaceUrls 是可选字段,会将插件表面名称(例如 canvas)映射到带作用域的托管 URL。 带作用域的插件表面 URL 可能会过期。节点可以调用 node.pluginSurface.refresh,并传入 { "surface": "canvas" },以在 pluginSurfaceUrls 中接收新的条目。实验性的 Canvas 插件重构不支持已弃用的 canvasHostUrlcanvasCapabilitynode.canvas.capability.refresh 兼容路径;当前原生客户端和 Gateway 网关必须使用插件表面。 未签发设备令牌时,hello-ok.auth 会报告协商后的权限,不包含令牌字段:
{
  "auth": {
    "role": "operator",
    "scopes": ["operator.read", "operator.write"]
  }
}
受信任的同进程后端客户端(client.id: "gateway-client"client.mode: "backend")在使用共享 Gateway 网关令牌/密码进行认证时,可在直接 loopback 连接上省略 device。此路径保留用于内部控制平面 RPC,并防止过期的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器来源客户端、节点客户端,以及显式设备令牌/设备身份客户端,仍使用正常的配对和作用域升级检查。 签发设备令牌时,hello-ok 还会包含:
{
  "auth": {
    "deviceToken": "…",
    "role": "operator",
    "scopes": ["operator.read", "operator.write"]
  }
}
在受信任的 bootstrap 交接期间,hello-ok.auth 还可能在 deviceTokens 中包含额外的有界角色条目:
{
  "auth": {
    "deviceToken": "…",
    "role": "node",
    "scopes": [],
    "deviceTokens": [
      {
        "deviceToken": "…",
        "role": "operator",
        "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]
      }
    ]
  }
}
对于内置的节点/操作员 bootstrap 流程,主节点令牌保持 scopes: [],任何被交接的操作员令牌都保持限制在 bootstrap 操作员允许列表内(operator.approvalsoperator.readoperator.talk.secretsoperator.write)。Bootstrap 作用域检查保持角色前缀:操作员条目只满足操作员请求,非操作员角色仍需要其自身角色前缀下的作用域。

节点示例

{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 4,
    "client": {
      "id": "ios-node",
      "version": "1.2.3",
      "platform": "ios",
      "mode": "node"
    },
    "role": "node",
    "scopes": [],
    "caps": ["camera", "canvas", "screen", "location", "voice"],
    "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],
    "permissions": { "camera.capture": true, "screen.record": false },
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-ios/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}

成帧

  • 请求{type:"req", id, method, params}
  • 响应{type:"res", id, ok, payload|error}
  • 事件{type:"event", event, payload, seq?, stateVersion?}
有副作用的方法需要幂等键(见 schema)。

角色 + 作用域

如需完整的操作员作用域模型、审批时检查和共享秘密语义,请参阅操作员作用域

角色

  • operator = 控制平面客户端(CLI/UI/自动化)。
  • node = 能力宿主(camera/screen/canvas/system.run)。

作用域(操作员)

常用作用域:
  • operator.read
  • operator.write
  • operator.admin
  • operator.approvals
  • operator.pairing
  • operator.talk.secrets
includeSecrets: truetalk.config 需要 operator.talk.secrets(或 operator.admin)。 插件注册的 Gateway 网关 RPC 方法可以请求其自己的操作员作用域,但保留的核心管理员前缀(config.*exec.approvals.*wizard.*update.*)始终解析为 operator.admin 方法作用域只是第一道关口。一些通过 chat.send 到达的斜杠命令会在此之上应用更严格的命令级检查。例如,持久化的 /config set/config unset 写入需要 operator.admin node.pair.approve 在基础方法作用域之外,还会在审批时执行额外的作用域检查:
  • 无命令请求:operator.pairing
  • 带非 exec 节点命令的请求:operator.pairing + operator.write
  • 包含 system.runsystem.run.preparesystem.which 的请求:operator.pairing + operator.admin

能力/命令/权限(节点)

节点在连接时声明能力声明:
  • caps:高级能力类别,例如 cameracanvasscreenlocationvoicetalk
  • commands:用于调用的命令允许列表。
  • permissions:细粒度开关(例如 screen.recordcamera.capture)。
Gateway 网关将这些视为声明,并强制执行服务端允许列表。

在线状态

  • system-presence 返回按设备身份键控的条目。
  • 在线状态条目包含 deviceIdrolesscopes,这样即使设备同时以操作员节点身份连接,UI 也可以为每台设备显示单独一行。
  • node.list 包含可选的 lastSeenAtMslastSeenReason 字段。已连接的节点会以原因 connect 将其当前连接时间报告为 lastSeenAtMs;当受信任的节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。

节点后台存活事件

节点可以调用 node.event 并使用 event: "node.presence.alive",以记录已配对节点在后台唤醒期间处于存活状态,但不将其标记为已连接。
{
  "event": "node.presence.alive",
  "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"
}
trigger 是封闭枚举:backgroundsilent_pushbg_app_refreshsignificant_locationmanualconnect。未知的 trigger 字符串会在持久化前由 Gateway 网关规范化为 background。该事件仅对已认证的节点设备会话持久化;无设备或未配对会话会返回 handled: false 成功的 Gateway 网关会返回结构化结果:
{
  "ok": true,
  "event": "node.presence.alive",
  "handled": true,
  "reason": "persisted"
}
较旧的 Gateway 网关可能仍会为 node.event 返回 { "ok": true };客户端应将其视为已确认的 RPC,而不是持久在线状态已保存。

广播事件作用域

服务端推送的 WebSocket 广播事件受作用域门控,因此配对作用域或仅节点会话不会被动接收会话内容。
  • 聊天、智能体和工具结果帧(包括流式 agent 事件和工具调用结果)至少需要 operator.read。没有 operator.read 的会话会完全跳过这些帧。
  • 插件定义的 plugin.* 广播会根据插件注册方式受 operator.writeoperator.admin 门控。
  • Status 和传输事件heartbeatpresencetick、连接/断开生命周期等)保持不受限制,这样每个已认证会话都能观察传输健康状态。
  • 未知广播事件族默认受作用域门控(失败关闭),除非已注册处理器明确放宽限制。
每个客户端连接都会保留自己的每客户端序列号,因此即使不同客户端看到事件流中不同的作用域过滤子集,广播也能在该套接字上保持单调顺序。

常见 RPC 方法族

公开 WS 表面比上面的握手/认证示例更广。这不是生成的转储,hello-ok.features.methods 是一个保守的发现列表,由 src/gateway/server-methods-list.ts 加载的插件/渠道方法导出构建。请将其视为功能发现,而不是 src/gateway/server-methods/*.ts 的完整枚举。
  • health 返回缓存的或刚探测到的 Gateway 网关健康快照。
  • diagnostics.stability 返回近期有界的诊断稳定性记录器。它会保留操作元数据,例如事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或秘密值。需要操作员读取作用域。
  • status 返回 /status 风格的 Gateway 网关摘要;敏感字段只会包含给具备 admin 作用域的操作员客户端。
  • gateway.identity.get 返回 relay 和配对流程使用的 Gateway 网关设备身份。
  • system-presence 返回已连接操作员/节点设备的当前在线状态快照。
  • system-event 追加系统事件,并可更新/广播在线状态上下文。
  • last-heartbeat 返回最新持久化的心跳事件。
  • set-heartbeats 切换 Gateway 网关上的心跳处理。
  • models.list 返回运行时允许的模型目录。传入 { "view": "configured" } 可获取适合选择器显示的已配置模型(先是 agents.defaults.models,然后是 models.providers.*.models),或传入 { "view": "all" } 获取完整目录。
  • usage.status 返回提供商使用窗口和剩余额度摘要。
  • usage.cost 返回日期范围内的聚合成本使用摘要。
  • doctor.memory.status 返回活动默认 Agent 工作区的向量记忆 / 缓存嵌入就绪状态。仅当调用方明确需要实时嵌入提供商 ping 时,才传入 { "probe": true }{ "deep": true }
  • doctor.memory.remHarness 返回供远程控制平面客户端使用的有界、只读 REM harness 预览。它可以包含工作区路径、记忆片段、渲染后的基于依据的 Markdown,以及深度提升候选项,因此调用方需要 operator.read
  • sessions.usage 返回每个会话的使用摘要。
  • sessions.usage.timeseries 返回一个会话的时间序列使用情况。
  • sessions.usage.logs 返回一个会话的使用日志条目。
  • channels.status 返回内置 + 捆绑渠道/插件状态摘要。
  • channels.logout 在渠道支持登出的情况下,登出特定渠道/账号。
  • web.login.start 为当前支持二维码的 Web 渠道提供商启动二维码/Web 登录流程。
  • web.login.wait 等待该二维码/Web 登录流程完成,并在成功后启动渠道。
  • push.test 向已注册的 iOS 节点发送测试 APNs 推送。
  • voicewake.get 返回已存储的唤醒词触发器。
  • voicewake.set 更新唤醒词触发器并广播变更。
  • send 是用于在聊天运行器之外按渠道/账号/线程目标直接发送的出站投递 RPC。
  • logs.tail 返回已配置 Gateway 网关文件日志尾部,并支持游标/限制和最大字节控制。
  • talk.catalog 返回只读 Talk 提供商目录,用于语音、流式转写和实时语音。它包含提供商 ID、标签、已配置状态、暴露的模型/语音 ID、规范模式、传输协议、brain 策略,以及实时音频/能力标志,但不会返回提供商密钥或修改全局配置。
  • talk.config 返回生效的 Talk 配置载荷;includeSecrets 需要 operator.talk.secrets(或 operator.admin)。
  • talk.session.createrealtime/gateway-relaytranscription/gateway-relaystt-tts/managed-room 创建由 Gateway 网关拥有的 Talk 会话。brain: "direct-tools" 需要 operator.admin
  • talk.session.join 校验托管房间会话令牌,按需发出 session.readysession.replaced 事件,并返回房间/会话元数据以及最近的 Talk 事件,但不包含明文令牌或已存储令牌哈希。
  • talk.session.appendAudio 将 base64 PCM 输入音频追加到由 Gateway 网关拥有的实时中继和转写会话。
  • talk.session.startTurntalk.session.endTurntalk.session.cancelTurn 驱动托管房间轮次生命周期,并在清除状态前拒绝过期轮次。
  • talk.session.cancelOutput 停止助手音频输出,主要用于 Gateway 网关中继会话中受 VAD 门控的打断。
  • talk.session.submitToolResult 完成由 Gateway 网关拥有的实时中继会话发出的提供商工具调用。当最终结果稍后返回时,传入 options: { willContinue: true } 表示临时工具输出;当工具结果应满足提供商调用且不启动另一个实时助手响应时,传入 options: { suppressResponse: true }
  • talk.session.close 关闭由 Gateway 网关拥有的中继、转写或托管房间会话,并发出终止 Talk 事件。
  • talk.mode 为 WebChat/Control UI 客户端设置/广播当前 Talk 模式状态。
  • talk.client.create 使用 webrtcprovider-websocket 创建客户端拥有的实时提供商会话,同时由 Gateway 网关拥有配置、凭证、指令和工具策略。
  • talk.client.toolCall 让客户端拥有的实时传输协议将提供商工具调用转发给 Gateway 网关策略。第一个支持的工具是 openclaw_agent_consult;客户端会收到运行 ID,并等待正常聊天生命周期事件后再提交提供商特定的工具结果。
  • talk.event 是面向实时、转写、STT/TTS、托管房间、电话和会议适配器的单一 Talk 事件频道。
  • talk.speak 通过活动 Talk 语音提供商合成语音。
  • tts.status 返回 TTS 启用状态、活动提供商、回退提供商和提供商配置状态。
  • tts.providers 返回可见的 TTS 提供商清单。
  • tts.enabletts.disable 切换 TTS 偏好状态。
  • tts.setProvider 更新首选 TTS 提供商。
  • tts.convert 执行一次性文本转语音转换。
  • secrets.reload 重新解析活动 SecretRefs,并且只在完全成功时替换运行时密钥状态。
  • secrets.resolve 为特定命令/目标集合解析命令目标密钥分配。
  • config.get 返回当前配置快照和哈希。
  • config.set 写入经过校验的配置载荷。
  • config.patch 合并部分配置更新。
  • config.apply 校验并替换完整配置载荷。
  • config.schema 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、uiHints、版本和生成元数据,包括运行时可以加载时的插件 + 渠道 schema 元数据。该 schema 包含字段 title / description 元数据,这些元数据派生自 UI 使用的相同标签和帮助文本;当存在匹配字段文档时,也包括嵌套对象、通配符、数组项以及 anyOf / oneOf / allOf 组合分支。
  • config.schema.lookup 为一个配置路径返回按路径限定的查找载荷:规范化路径、浅层 schema 节点、匹配的提示 + hintPath,以及用于 UI/CLI 下钻的直接子项摘要。查找 schema 节点保留面向用户的文档和常见校验字段(titledescriptiontypeenumconstformatpattern、数值/字符串/数组/对象边界,以及 additionalPropertiesdeprecatedreadOnlywriteOnly 等标志)。子项摘要暴露 key、规范化 pathtyperequiredhasChildren,以及匹配的 hint / hintPath
  • update.run 运行 Gateway 网关更新流程,并且只在更新本身成功时安排重启;带有会话的调用方可以包含 continuationMessage,这样启动时会通过重启延续队列恢复一个后续 Agent 轮次。包管理器更新会在包替换后强制一次非延迟、无冷却的更新重启,避免旧 Gateway 网关进程继续从已替换的 dist 树中懒加载。
  • update.status 返回最新缓存的更新重启哨兵,包括可用时的重启后运行版本。
  • wizard.startwizard.nextwizard.statuswizard.cancel 通过 WS RPC 暴露新手引导向导。
  • agents.list 返回已配置的 Agent 条目,包括生效模型和运行时元数据。
  • agents.createagents.updateagents.delete 管理 Agent 记录和工作区连接。
  • agents.files.listagents.files.getagents.files.set 管理为 Agent 暴露的引导工作区文件。
  • tasks.listtasks.gettasks.cancel 向 SDK 和操作员客户端暴露 Gateway 网关任务台账。
  • artifacts.listartifacts.getartifacts.download 为显式 sessionKeyrunIdtaskId 作用域暴露由转录记录派生的工件摘要和下载。运行和任务查询会在服务端解析所属会话,并且只返回带有匹配来源的转录记录媒体;不安全或本地 URL 来源会返回不支持的下载,而不是在服务端抓取。
  • environments.listenvironments.status 为 SDK 客户端暴露只读的 Gateway 网关本地和节点环境发现。
  • agent.identity.get 返回 Agent 或会话的生效助手身份。
  • agent.wait 等待运行完成,并在可用时返回终止快照。
  • sessions.list 返回当前会话索引,包括在配置了 Agent 运行时后端时每行的 agentRuntime 元数据。
  • sessions.subscribesessions.unsubscribe 为当前 WS 客户端切换会话变更事件订阅。
  • sessions.messages.subscribesessions.messages.unsubscribe 为一个会话切换转录记录/消息事件订阅。
  • sessions.preview 返回特定会话键的有界转录记录预览。
  • sessions.describe 返回精确会话键对应的一条 Gateway 网关会话行。
  • sessions.resolve 解析或规范化会话目标。
  • sessions.create 创建新的会话条目。
  • sessions.send 向现有会话发送消息。
  • sessions.steer 是活动会话的中断并 Steer 变体。
  • sessions.abort 中止会话的活动工作。调用方可以传入 key 以及可选的 runId,或仅为 Gateway 网关可解析到会话的活动运行传入 runId
  • sessions.patch 更新会话元数据/覆盖项,并报告已解析的规范模型以及生效的 agentRuntime
  • sessions.resetsessions.deletesessions.compact 执行会话维护。
  • sessions.get 返回完整存储的会话行。
  • 聊天执行仍使用 chat.historychat.sendchat.abortchat.injectchat.history 针对 UI 客户端做了显示规范化:内联指令标签会从可见文本中移除,纯文本工具调用 XML 载荷(包括 <tool_call>...</tool_call><function_call>...</function_call><tool_calls>...</tool_calls><function_calls>...</function_calls>,以及被截断的工具调用块)和泄漏的 ASCII/全角模型控制令牌会被移除,精确 NO_REPLY / no_reply 等纯静默令牌助手行会被省略,过大的行可以替换为占位符。
  • device.pair.list 返回待处理和已批准的已配对设备。
  • device.pair.approvedevice.pair.rejectdevice.pair.remove 管理设备配对记录。
  • device.token.rotate 在已批准角色和调用方作用域边界内轮换已配对设备令牌。
  • device.token.revoke 在已批准角色和调用方作用域边界内撤销已配对设备令牌。
  • node.pair.requestnode.pair.listnode.pair.approvenode.pair.rejectnode.pair.removenode.pair.verify 覆盖节点配对和引导校验。
  • node.listnode.describe 返回已知/已连接节点状态。
  • node.rename 更新已配对节点标签。
  • node.invoke 将命令转发到已连接节点。
  • node.invoke.result 返回调用请求的结果。
  • node.event 将节点发起的事件带回 Gateway 网关。
  • node.pending.pullnode.pending.ack 是已连接节点队列 API。
  • node.pending.enqueuenode.pending.drain 管理离线/断开连接节点的持久待处理工作。
  • exec.approval.requestexec.approval.getexec.approval.listexec.approval.resolve 覆盖一次性 exec 审批请求以及待处理审批查询/重放。
  • exec.approval.waitDecision 等待一个待处理的 exec 审批,并返回最终决定(超时时返回 null)。
  • exec.approvals.getexec.approvals.set 管理 Gateway 网关 exec 审批策略快照。
  • exec.approvals.node.getexec.approvals.node.set 通过节点中继命令管理节点本地 exec 审批策略。
  • plugin.approval.requestplugin.approval.listplugin.approval.waitDecisionplugin.approval.resolve 覆盖插件定义的审批流程。
  • 自动化:wake 调度一次立即或下一次 Heartbeat 的唤醒文本注入;cron.getcron.listcron.statuscron.addcron.updatecron.removecron.runcron.runs 管理定时工作。
  • Skills 和工具:commands.listskills.*tools.catalogtools.effectivetools.invoke

常见事件族

  • chat:UI 聊天更新,例如 chat.inject 和其他仅用于转录的聊天 事件。
  • session.messagesession.tool:已订阅会话的转录/事件流更新。
  • sessions.changed:会话索引或元数据已更改。
  • presence:系统在线状态快照更新。
  • tick:周期性 keepalive / 存活事件。
  • health:Gateway 网关健康快照更新。
  • heartbeat:Heartbeat 事件流更新。
  • cron:cron 运行/作业变更事件。
  • shutdown:Gateway 网关关闭通知。
  • node.pair.requested / node.pair.resolved:节点配对生命周期。
  • node.invoke.request:节点调用请求广播。
  • device.pair.requested / device.pair.resolved:已配对设备生命周期。
  • voicewake.changed:唤醒词触发器配置已更改。
  • exec.approval.requested / exec.approval.resolved:exec 审批 生命周期。
  • plugin.approval.requested / plugin.approval.resolved:插件审批 生命周期。

节点辅助方法

  • 节点可以调用 skills.bins 来获取当前技能可执行文件列表, 用于自动允许检查。

任务台账 RPC

操作员客户端可以通过任务台账 RPC 检查并取消 Gateway 网关后台任务记录。 这些方法返回经过净化的任务摘要,而不是原始运行时状态。
  • tasks.list 需要 operator.read
    • 参数:可选的 status"queued""running""completed""failed""cancelled""timed_out")或这些状态的数组, 可选的 agentId、可选的 sessionKey、从 1500 的可选 limit,以及可选字符串 cursor
    • 结果:{ "tasks": TaskSummary[], "nextCursor"?: string }
  • tasks.get 需要 operator.read
    • 参数:{ "taskId": string }
    • 结果:{ "task": TaskSummary }
    • 缺失的任务 ID 会返回 Gateway 网关未找到错误形状。
  • tasks.cancel 需要 operator.write
    • 参数:{ "taskId": string, "reason"?: string }
    • 结果: { "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }
    • found 报告台账中是否有匹配任务。cancelled 报告运行时是否接受或记录了取消。
TaskSummary 包含 idstatus,以及可选元数据,例如 kindruntimetitleagentIdsessionKeychildSessionKeyownerKeyrunIdtaskIdflowIdparentTaskIdsourceId、时间戳、进度、 终止摘要,以及经过净化的错误文本。

操作员辅助方法

  • 操作员可以调用 commands.listoperator.read)来获取某个智能体的运行时 命令清单。
    • agentId 是可选的;省略它会读取默认 Agent 工作区。
    • scope 控制主要 name 面向哪个表面:
      • text 返回不带前导 / 的主要文本命令令牌
      • native 和默认的 both 路径会在可用时返回提供商感知的原生命名
    • textAliases 携带精确的斜杠别名,例如 /model/m
    • nativeName 在存在时携带提供商感知的原生命令名。
    • provider 是可选的,只影响原生命名以及原生插件命令可用性。
    • includeArgs=false 会从响应中省略序列化的参数元数据。
  • 操作员可以调用 tools.catalogoperator.read)来获取某个 智能体的运行时工具目录。响应包含分组工具和来源元数据:
    • sourcecoreplugin
    • pluginId:当 source="plugin" 时的插件所有者
    • optional:插件工具是否可选
  • 操作员可以调用 tools.effectiveoperator.read)来获取某个会话的运行时生效工具 清单。
    • sessionKey 是必需的。
    • Gateway 网关会从服务端会话派生可信运行时上下文,而不是接受 调用方提供的认证或投递上下文。
    • 响应限定在会话范围内,并反映当前活跃对话现在可以使用的内容, 包括核心、插件和渠道工具。
  • 操作员可以调用 tools.invokeoperator.write)来通过与 /tools/invoke 相同的 Gateway 网关策略路径调用一个可用工具。
    • name 是必需的。argssessionKeyagentIdconfirmidempotencyKey 是可选的。
    • 如果同时存在 sessionKeyagentId,解析出的会话智能体必须匹配 agentId
    • 响应是面向 SDK 的封装,包含 oktoolName、可选的 output,以及带类型的 error 字段。审批或策略拒绝会在载荷中返回 ok:false,而不是 绕过 Gateway 网关工具策略管线。
  • 操作员可以调用 skills.statusoperator.read)来获取某个智能体的可见 技能清单。
    • agentId 是可选的;省略它会读取默认 Agent 工作区。
    • 响应包含资格、缺失需求、配置检查,以及经过净化的安装选项, 不会暴露原始秘密值。
  • 操作员可以调用 skills.searchskills.detailoperator.read)来获取 ClawHub 发现元数据。
  • 操作员可以调用 skills.upload.beginskills.upload.chunkskills.upload.commitoperator.admin),在安装前暂存私有技能归档。 这是面向可信客户端的独立管理员上传路径,不是普通的 ClawHub 技能安装流程, 并且默认禁用,除非启用 skills.install.allowUploadedArchives
    • skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? }) 会创建一个绑定到该 slug 和 force 值的上传。
    • skills.upload.chunk({ uploadId, offset, dataBase64 }) 会在精确解码偏移处 追加字节。
    • skills.upload.commit({ uploadId, sha256? }) 会验证最终大小和 SHA-256。提交只会完成上传;它不会安装技能。
    • 上传的技能归档是包含根级 SKILL.md 的 zip 归档。 归档内部目录名绝不会选择安装目标。
  • 操作员可以通过三种模式调用 skills.installoperator.admin):
    • ClawHub 模式:{ source: "clawhub", slug, version?, force? } 将一个 技能文件夹安装到默认 Agent 工作区的 skills/ 目录。
    • 上传模式:{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? } 将已提交的上传安装到默认 Agent 工作区的 skills/<slug> 目录。slug 和 force 值必须匹配原始 skills.upload.begin 请求。除非启用 skills.install.allowUploadedArchives,否则此模式会被拒绝。该设置不会 影响 ClawHub 安装。
    • Gateway 网关安装器模式:{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? } 在 Gateway 网关主机上运行声明的 metadata.openclaw.install 操作。
  • 操作员可以通过两种模式调用 skills.updateoperator.admin):
    • ClawHub 模式会更新默认 Agent 工作区中的一个已跟踪 slug,或所有已跟踪的 ClawHub 安装。
    • 配置模式会修补 skills.entries.<skillKey> 值,例如 enabledapiKeyenv

models.list 视图

models.list 接受可选的 view 参数:
  • 省略或 "default":当前运行时行为。如果配置了 agents.defaults.models,响应将是允许目录,包括针对 provider/* 条目动态发现的模型。否则响应为完整 Gateway 网关目录。
  • "configured":适合选择器大小的行为。如果配置了 agents.defaults.models,它仍然优先,包括针对 provider/* 条目的提供商范围发现。如果没有允许列表,响应会使用显式 models.providers.*.models 条目,并且仅在没有已配置模型行时回退到完整目录。
  • "all":完整 Gateway 网关目录,绕过 agents.defaults.models。将其用于诊断和发现 UI,而不是普通模型选择器。

Exec 审批

  • 当 exec 请求需要审批时,Gateway 网关会广播 exec.approval.requested
  • 操作员客户端通过调用 exec.approval.resolve 进行处理(需要 operator.approvals 作用域)。
  • 对于 host=nodeexec.approval.request 必须包含 systemRunPlan(规范的 argv/cwd/rawCommand/会话元数据)。缺少 systemRunPlan 的请求会被拒绝。
  • 审批后,转发的 node.invoke system.run 调用会复用该规范 systemRunPlan,将其作为权威的命令/cwd/会话上下文。
  • 如果调用方在准备和最终已审批的 system.run 转发之间篡改 commandrawCommandcwdagentIdsessionKey,Gateway 网关会拒绝运行,而不是信任被篡改的载荷。

Agent 投递回退

  • agent 请求可以包含 deliver=true 来请求出站投递。
  • bestEffortDeliver=false 保持严格行为:无法解析或仅限内部的投递目标会返回 INVALID_REQUEST
  • bestEffortDeliver=true 允许在无法解析外部可投递路由时回退到仅会话执行(例如内部/webchat 会话或有歧义的多渠道配置)。
  • 当请求了投递时,最终 agent 结果可能包含 result.deliveryStatus, 使用与 openclaw agent --json --deliver 中记录的相同 sentsuppressedpartial_failedfailed 状态。

版本控制

  • PROTOCOL_VERSION 位于 src/gateway/protocol/version.ts
  • 客户端发送 minProtocol + maxProtocol;服务端会拒绝不包含其当前协议的范围。 原生客户端使用 v3 下界,因此增量式 v4 客户端仍可访问 v3 Gateway 网关。
  • Schema + 模型从 TypeBox 定义生成:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

客户端常量

src/gateway/client.ts 中的参考客户端使用这些默认值。这些值在 协议 v4 中保持稳定,并且是第三方客户端的预期基线。
常量默认值来源
PROTOCOL_VERSION4src/gateway/protocol/version.ts
MIN_CLIENT_PROTOCOL_VERSION3src/gateway/protocol/version.ts
请求超时(每个 RPC)30_000 mssrc/gateway/client.ts (requestTimeoutMs)
预认证 / 连接挑战超时15_000 mssrc/gateway/handshake-timeouts.ts(配置/环境可以提高成对服务器/客户端预算)
初始重连退避1_000 mssrc/gateway/client.ts (backoffMs)
最大重连退避30_000 mssrc/gateway/client.ts (scheduleReconnect)
设备令牌关闭后的快速重试限制250 mssrc/gateway/client.ts
terminate() 前的强制停止宽限期250 msFORCE_STOP_TERMINATE_GRACE_MS
stopAndWait() 默认超时1_000 msSTOP_AND_WAIT_TIMEOUT_MS
默认 tick 间隔(hello-ok 前)30_000 mssrc/gateway/client.ts
tick 超时关闭静默超过 tickIntervalMs * 2 时使用代码 4000src/gateway/client.ts
MAX_PAYLOAD_BYTES25 * 1024 * 1024(25 MB)src/gateway/server-constants.ts
服务器会在 hello-ok 中通告有效的 policy.tickIntervalMspolicy.maxPayloadpolicy.maxBufferedBytes;客户端应遵循这些值, 而不是握手前的默认值。

认证

  • 共享密钥 Gateway 网关认证使用 connect.params.auth.tokenconnect.params.auth.password,具体取决于配置的认证模式。
  • 带有身份的模式(例如 Tailscale Serve (gateway.auth.allowTailscale: true))或非环回 gateway.auth.mode: "trusted-proxy" 会通过请求头满足连接认证检查, 而不是通过 connect.params.auth.*
  • 私有入口 gateway.auth.mode: "none" 会完全跳过共享密钥连接认证; 不要在公共/不可信入口上暴露该模式。
  • 配对后,Gateway 网关会签发一个限定到连接角色 + 范围的设备令牌。 它会在 hello-ok.auth.deviceToken 中返回,客户端应将其持久化以供后续连接使用。
  • 客户端应在任何成功连接后持久化主 hello-ok.auth.deviceToken
  • 使用该已存储设备令牌重新连接时,也应复用为该令牌存储的已批准范围集。 这会保留已授予的读取/探测/状态访问权限,并避免重连被静默收窄为 更窄的隐式仅管理员范围。
  • 客户端连接认证组装(src/gateway/client.ts 中的 selectConnectAuth):
    • auth.password 是正交的,设置后总会转发。
    • auth.token 按优先级填充:显式共享令牌优先, 然后是显式 deviceToken,再然后是已存储的每设备令牌(按 deviceId + role 建键)。
    • 只有在以上都没有解析出 auth.token 时,才会发送 auth.bootstrapToken。 共享令牌或任何已解析设备令牌都会抑制它。
    • 在一次性 AUTH_TOKEN_MISMATCH 重试中自动提升已存储设备令牌, 仅限于可信端点:环回,或带有固定 tlsFingerprintwss://。 未固定的公共 wss:// 不符合条件。
  • 额外的 hello-ok.auth.deviceTokens 条目是引导交接令牌。 只有当连接在可信传输(例如 wss:// 或环回/本地配对)上使用引导认证时, 才持久化它们。
  • 如果客户端提供了显式 deviceToken 或显式 scopes, 该调用方请求的范围集仍然是权威来源;只有在客户端复用已存储的每设备令牌时, 才会复用缓存范围。
  • 设备令牌可以通过 device.token.rotatedevice.token.revoke 轮换/撤销(需要 operator.pairing 范围)。
  • device.token.rotate 返回轮换元数据。它只会在同设备调用且该调用已使用 该设备令牌完成认证时回显替换用 bearer 令牌,因此仅令牌客户端可以在重连前 持久化替换令牌。共享/管理员轮换不会回显 bearer 令牌。
  • 令牌签发、轮换和撤销会受限于该设备配对条目中记录的已批准角色集; 令牌变更不能扩展或指向配对审批从未授予的设备角色。
  • 对于已配对设备令牌会话,除非调用方还拥有 operator.admin, 否则设备管理仅限自身范围:非管理员调用方只能移除/撤销/轮换 自己的设备条目。
  • device.token.rotatedevice.token.revoke 还会根据调用方当前会话范围 检查目标 operator 令牌范围集。非管理员调用方不能轮换或撤销比自己已持有范围 更广的 operator 令牌。
  • 认证失败包含 error.details.code 以及恢复提示:
    • error.details.canRetryWithDeviceToken(布尔值)
    • error.details.recommendedNextStep (retry_with_device_token, update_auth_configuration, update_auth_credentials, wait_then_retry, review_auth_configuration)
  • 客户端针对 AUTH_TOKEN_MISMATCH 的行为:
    • 可信客户端可以尝试一次有界重试,使用缓存的每设备令牌。
    • 如果该重试失败,客户端应停止自动重连循环,并展示 operator 操作指导。
  • AUTH_SCOPE_MISMATCH 表示设备令牌已被识别,但不覆盖 请求的角色/范围。客户端不应将其呈现为错误令牌; 应提示 operator 重新配对或批准更窄/更宽的范围契约。

设备身份 + 配对

  • 节点应包含一个稳定设备身份 (device.id),该身份派生自 密钥对指纹。
  • Gateway 网关按设备 + 角色签发令牌。
  • 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。
  • 配对自动批准以直接 local loopback 连接为中心。
  • OpenClaw 还有一条狭窄的后端/容器本地自连接路径,用于 可信共享密钥辅助流程。
  • 同主机 tailnet 或 LAN 连接在配对时仍被视为远程连接, 并需要批准。
  • WS 客户端通常在 connect 期间包含 device 身份(operator + 节点)。唯一无设备 operator 例外是显式信任路径:
    • gateway.controlUi.allowInsecureAuth=true,用于仅 localhost 的不安全 HTTP 兼容性。
    • 成功的 gateway.auth.mode: "trusted-proxy" operator Control UI 认证。
    • gateway.controlUi.dangerouslyDisableDeviceAuth=true(破窗选项,严重安全降级)。
    • 直接环回的 gateway-client 后端 RPC,使用共享 Gateway 网关令牌/密码认证。
  • 所有连接都必须签名服务器提供的 connect.challenge nonce。

设备认证迁移诊断

对于仍使用挑战前签名行为的旧版客户端,connect 现在会返回 error.details.code 下的 DEVICE_AUTH_* 详情代码,以及稳定的 error.details.reason 常见迁移失败:
消息details.codedetails.reason含义
device nonce requiredDEVICE_AUTH_NONCE_REQUIREDdevice-nonce-missing客户端省略了 device.nonce(或发送了空值)。
device nonce mismatchDEVICE_AUTH_NONCE_MISMATCHdevice-nonce-mismatch客户端使用过期/错误 nonce 进行了签名。
device signature invalidDEVICE_AUTH_SIGNATURE_INVALIDdevice-signature签名载荷与 v2 载荷不匹配。
device signature expiredDEVICE_AUTH_SIGNATURE_EXPIREDdevice-signature-stale签名时间戳超出允许偏移。
device identity mismatchDEVICE_AUTH_DEVICE_ID_MISMATCHdevice-id-mismatchdevice.id 与公钥指纹不匹配。
device public key invalidDEVICE_AUTH_PUBLIC_KEY_INVALIDdevice-public-key公钥格式/规范化失败。
迁移目标:
  • 始终等待 connect.challenge
  • 签名包含服务器 nonce 的 v2 载荷。
  • connect.params.device.nonce 中发送相同 nonce。
  • 首选签名载荷是 v3,它除了绑定 device/client/role/scopes/token/nonce 字段外, 还绑定 platformdeviceFamily
  • 为了兼容性,旧版 v2 签名仍会被接受,但已配对设备的 元数据固定仍会在重连时控制命令策略。

TLS + 固定

  • WS 连接支持 TLS。
  • 客户端可以选择固定 Gateway 网关证书指纹(参见 gateway.tls 配置以及 gateway.remote.tlsFingerprint 或 CLI --tls-fingerprint)。

范围

该协议暴露完整 Gateway 网关 API(状态、渠道、模型、聊天、 智能体、会话、节点、审批等)。确切表面由 src/gateway/protocol/schema.ts 中的 TypeBox schema 定义。

相关