Gateway
Protocolo do Gateway
O protocolo WS do Gateway é o único plano de controle e transporte de nós do OpenClaw. Clientes operadores e nós (CLI, interface web, aplicativo para macOS, nós iOS/Android, nós headless) conectam-se por WebSocket e declaram uma função e um escopo no momento do handshake.
Transporte e enquadramento
- WebSocket, quadros de texto, cargas JSON.
- O primeiro quadro deve ser uma solicitação
connect. - Os quadros anteriores à conexão são limitados a 64 KiB (
MAX_PREAUTH_PAYLOAD_BYTES). Após o handshake, sigahello-ok.policy.maxPayloadehello-ok.policy.maxBufferedBytes. Com o diagnóstico ativado, quadros de entrada grandes demais e buffers de saída lentos emitem eventospayload.largeantes que o gateway feche ou descarte o quadro. Esses eventos incluemsurface, tamanhos em bytes, limites e um código de motivo seguro, nunca corpos de mensagens, conteúdo de anexos, bytes brutos de quadros, tokens, cookies ou segredos.
Formatos dos quadros:
- Solicitação:
{type:"req", id, method, params} - Resposta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Métodos com efeitos colaterais exigem chaves de idempotência (consulte o esquema).
Handshake
O Gateway envia um desafio anterior à conexão:
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}O cliente responde com connect:
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 4, "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": "…" } }}O Gateway responde com hello-ok:
{ "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 } }}server, features, snapshot, policy e auth são todos exigidos por
HelloOkSchema (packages/gateway-protocol/src/schema/frames.ts). auth
informa a função/os escopos negociados mesmo quando nenhum token de dispositivo é emitido (formato
acima). pluginSurfaceUrls é opcional e mapeia nomes de superfícies de plugins (por exemplo,
canvas) para URLs hospedadas com escopo; ele pode expirar, portanto os nós chamam
node.pluginSurface.refresh com { "surface": "canvas" } para obter uma entrada atualizada.
O caminho obsoleto canvasHostUrl / canvasCapability / node.canvas.capability.refresh
não é compatível; use superfícies de plugins.
O campo opcional appliedConfigHash do snapshot é a revisão resolvida da configuração de origem
aceita pelo runtime ativo do Gateway. Os clientes podem compará-la com
config.get.configRevisionHash para determinar se uma configuração salva mais recente ainda
exige uma reinicialização. config.get.hash continua sendo a revisão bruta do arquivo raiz usada pelas
proteções contra conflitos de gravação da configuração.
Enquanto o gateway ainda estiver concluindo a inicialização dos processos auxiliares, connect poderá retornar um
erro recuperável UNAVAILABLE com details.reason: "startup-sidecars" e
retryAfterMs. Tente novamente dentro do orçamento da conexão em vez de tratá-lo como
uma falha terminal do handshake.
Quando um token de dispositivo é emitido, hello-ok.auth o adiciona:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}A inicialização integrada por QR/código de configuração é um caminho de transferência para dispositivos móveis. Uma conexão bem-sucedida com o código de configuração básico retorna um token de nó primário mais um token de operador limitado:
{ "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] }}Essa transferência de operador é intencionalmente limitada: suficiente para iniciar o ciclo do
operador móvel e a configuração nativa, incluindo operator.talk.secrets para leituras da
configuração do Talk, mas sem escopos de mutação de pareamento e sem operator.admin. Um acesso
mais amplo de pareamento/administração exige um fluxo separado de pareamento ou token aprovado. Persista
hello-ok.auth.deviceTokens somente quando a autenticação de inicialização tiver sido executada por um transporte
confiável (wss:// ou pareamento de loopback/local).
Clientes de backend confiáveis no mesmo processo (client.id: "gateway-client",
client.mode: "backend") podem omitir device em conexões diretas de loopback ao
se autenticarem com o token/senha compartilhado do gateway. Esse caminho é reservado
para RPCs internos do plano de controle (por exemplo, atualizações de sessão de subagentes) e evita que
linhas de base obsoletas de pareamento de CLI/dispositivo bloqueiem o trabalho local do backend. Clientes
remotos, com origem no navegador, nós e clientes explícitos com token de dispositivo/identidade de dispositivo ainda
passam pelas verificações normais de pareamento e elevação de escopo.
Função de worker e protocolo fechado
Workers na nuvem usam uma entrada dedicada de loopback pelo túnel SSH pertencente ao gateway,
com a chave do host fixada. Ela aceita somente a identidade do worker e nunca despacha
autenticação geral, eventos de nós, RPCs de operadores ou métodos de plugins. Um connect rigoroso
verifica uma credencial de curta duração, armazenada como hash e vinculada ao ambiente, ao hash do
pacote, à época do proprietário, à versão do conjunto de RPCs, à expiração e a uma sessão anulável; ele
verifica separadamente a versão atual e o conjunto de recursos. O sucesso retorna um
worker-hello-ok mínimo; a negociação de recursos é independente da versão geral do
protocolo. Os quadros permanecem abaixo de 64 KiB, exceto por um quadro worker.inference.start
negociado, que pode ter até 25 MiB. A lista de permissões fechada contém worker.heartbeat,
worker.transcript.commit, worker.live-event, worker.inference.start e
worker.inference.cancel.
Os commits de transcrição usam delimitação por época do proprietário, uma vinculação de sessão pertencente ao gateway, comparação e troca da folha base e repetição durável da sequência; o gateway gera IDs de entradas e pais da transcrição pelo gravador normal de sessões. A propriedade e a expiração são verificadas novamente em cada RPC.
Recursos do cliente
Clientes operadores podem anunciar recursos opcionais em connect.params.caps:
tool-events: aceita eventos estruturados do ciclo de vida de ferramentas.inline-widgets: pode renderizar resultados de ferramentas de widgets inline hospedados.
Os recursos do cliente descrevem o cliente conectado, não a autorização. As ferramentas do agente podem declarar recursos obrigatórios; o Gateway omite essas ferramentas, a menos que todos os requisitos apareçam em caps do cliente de origem. Execuções originadas em canais não têm recursos de cliente do Gateway, portanto ferramentas controladas por recursos ficam indisponíveis mesmo quando a política de ferramentas as permite explicitamente.
Exemplo de conexão de nó
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 4, "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": "…" } }}Os nós declaram reivindicações de recursos no momento da conexão:
caps: categorias de alto nível, comocamera,canvas,screen,location,voice,talk.commands: lista de permissões de comandos para invocação.permissions: controles granulares (por exemplo,screen.record,camera.capture).
O gateway trata essas declarações como reivindicações e aplica listas de permissões no lado do servidor.
Funções e escopos
Para conhecer o modelo completo de escopos do operador, as verificações no momento da aprovação e a semântica de segredo compartilhado, consulte Escopos do operador.
Funções:
operator: cliente do plano de controle (CLI/interface/automação).node: host de recursos (câmera/tela/canvas/system.run).worker: host de execução na nuvem no protocolo dedicado e fechado de workers.
Escopos do operador (src/gateway/operator-scopes.ts), o conjunto fechado completo:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config com includeSecrets: true exige operator.talk.secrets (ou
operator.admin). Quando os segredos forem incluídos, leia a credencial ativa do provedor do Talk
em talk.resolved.config.apiKey; talk.providers.<id>.apiKey
mantém o formato da origem e pode ser um objeto SecretRef ou uma string ocultada.
Os métodos RPC do gateway registrados por plugins podem solicitar seu próprio escopo de operador,
mas estes prefixos reservados do núcleo sempre são resolvidos como operator.admin
(src/shared/gateway-method-policy.ts): config.*, exec.approvals.*,
wizard.*, update.*.
O escopo do método é apenas a primeira verificação. Alguns comandos com barra acessados por
chat.send aplicam verificações mais rigorosas no nível do comando: gravações persistentes de /config set e
/config unset exigem operator.admin mesmo para clientes do gateway que
já tenham um escopo de operador inferior.
node.pair.approve tem uma verificação adicional de escopo no momento da aprovação, além do escopo
básico do método (operator.pairing), com base no commands declarado pela
solicitação pendente (src/infra/node-pairing-authz.ts):
| Comandos declarados | Escopos obrigatórios |
|---|---|
| nenhum | operator.pairing |
| comandos comuns | operator.pairing + operator.write |
inclui system.run, system.run.prepare, system.which, browser.proxy, fs.listDir ou system.execApprovals.get/set |
operator.pairing + operator.admin |
Recursos/comandos/permissões (nó)
Os nós declaram reivindicações de recursos no momento da conexão:
caps: categorias de recursos de alto nível, comocamera,canvas,screen,location,voiceetalk.commands: lista de permissões de comandos para invocação.permissions: controles granulares (por exemplo,screen.record,camera.capture).
O Gateway trata isso como declarações e aplica listas de permissões no lado do servidor.
Os nodes conectados podem publicar descritores opcionais de Plugin ou de ferramentas MCP visíveis ao agente
com node.pluginTools.update após uma conexão ou
reconexão bem-sucedida. Hosts de nodes sem interface reiniciam para aplicar alterações declarativas
ao inventário MCP. Esse método de atualização é o único caminho de publicação; descritores de ferramentas de Plugin não são aceitos nos
parâmetros de connect. Cada descritor deve usar um name de ferramenta seguro para o provedor e indicar
um command presente na lista atual de comandos permitidos do node. O Gateway confia nos metadados
do descritor provenientes do node pareado, filtra descritores fora da superfície de comandos
aprovada, remove-os quando o node se desconecta e rejeita tentativas do operador
de modificar o catálogo de outro node. Defina gateway.nodes.pluginTools.enabled: false
para ignorar descritores publicados por nodes.
Hosts de nodes conectados publicam seu catálogo completo de substituição de Skills com
node.skills.update. Esse método da função de node é o único caminho de publicação
de Skills do node; Skills não são aceitas nos parâmetros de connect. Cada descritor contém
um nome seguro, uma descrição e conteúdo SKILL.md limitado. O Gateway analisa esse
conteúdo com o carregador normal de Skills, inclui-o nos snapshots de Skills do agente
enquanto o node está conectado e o remove na desconexão. Defina
gateway.nodes.skills.enabled: false para ignorar Skills publicadas por nodes.
Presença
system-presenceretorna entradas indexadas pela identidade do dispositivo, incluindodeviceId,rolesescopes, para que as interfaces possam exibir uma linha por dispositivo mesmo quando ele se conecta como operador e como node.node.listincluilastSeenAtMselastSeenReasonopcionais. Nodes conectados informam o horário atual da conexão com o motivoconnect; nodes pareados também podem informar presença durável em segundo plano por meio de um evento de node confiável.
Nodes nativos do macOS também podem enviar eventos node.presence.activity autenticados
com tempo de inatividade de entrada limitado. O Gateway deriva os timestamps de atividade usando seu
próprio relógio, expõe o Mac conectado mais recente por meio de node.list e
node.describe e transmite atualizações de node.presence para clientes com escopo de leitura.
Consulte Presença do computador ativo para saber sobre seleção, privacidade, contexto
do modelo e comportamento de roteamento de notificações.
Evento de atividade do node em segundo plano
Os nodes chamam node.event com event: "node.presence.alive" para registrar que um
node pareado estava ativo durante uma ativação em segundo plano, sem marcá-lo como conectado:
{ "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 é uma enumeração fechada: background, silent_push, bg_app_refresh,
significant_location, manual, connect. Valores desconhecidos são normalizados para
background (src/shared/node-presence.ts). O evento só é persistido para
sessões autenticadas de dispositivos de node; sessões sem dispositivo ou não pareadas retornam
handled: false.
Gateways bem-sucedidos retornam um resultado estruturado:
{ "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted"}Gateways mais antigos podem retornar apenas { "ok": true } para node.event; trate isso
como uma RPC confirmada, não como persistência durável da presença.
Escopo de eventos de transmissão
Os eventos de transmissão enviados pelo servidor são controlados por escopo para que sessões
restritas ao pareamento ou exclusivas de nodes não recebam passivamente conteúdo de sessão
(src/gateway/server-broadcast.ts):
- Quadros de chat, agente e resultado de ferramenta (eventos
agenttransmitidos, eventos de resultado de ferramenta) exigem pelo menosoperator.read. Sessões sem esse escopo ignoram completamente esses quadros. - As transmissões
plugin.*definidas por Plugins são restritas por padrão aoperator.writeouoperator.admin; entradas explícitas, comoplugin.approval.requested/plugin.approval.resolved, usamoperator.approvalsem vez disso. - Eventos de status/transporte (
heartbeat,presence,tick, ciclo de vida de conexão/desconexão) permanecem irrestritos para que a integridade do transporte seja observável por todas as sessões autenticadas. - Famílias desconhecidas de eventos de transmissão são controladas por escopo por padrão (falha fechada), a menos que um manipulador registrado as flexibilize explicitamente.
Cada conexão de cliente mantém seu próprio número de sequência por cliente, portanto as transmissões permanecem em ordem monotônica nesse socket, mesmo quando clientes diferentes veem subconjuntos distintos do fluxo de eventos filtrados por escopo.
Famílias de métodos RPC
hello-ok.features.methods é uma lista de descoberta conservadora criada a partir de
src/gateway/server-methods-list.ts e das exportações de métodos de Plugins/canais
carregados — não é um despejo gerado de todos os métodos, e alguns métodos (por
exemplo, push.test, web.login.start, web.login.wait, sessions.usage)
são intencionalmente excluídos da descoberta, embora sejam métodos reais e
invocáveis. Trate isso como descoberta de recursos, não como uma enumeração completa de
src/gateway/server-methods/*.ts.
Sistema e identidade
healthretorna o snapshot de integridade do Gateway armazenado em cache ou verificado recentemente.diagnostics.stabilityretorna o registrador recente e limitado de estabilidade de diagnóstico: nomes de eventos, contagens, tamanhos em bytes, leituras de memória, estado de filas/sessões, nomes de canais/Plugins e IDs de sessão. Não inclui texto de chat, corpos de Webhooks, saídas de ferramentas, corpos brutos de solicitações/respostas, tokens, cookies ou segredos. Exigeoperator.read.statusretorna o resumo do Gateway no estilo/status; campos confidenciais somente para clientes operadores com escopo de administrador.gateway.identity.getretorna a identidade de dispositivo do Gateway usada pelos fluxos de retransmissão e pareamento.system-presenceretorna o snapshot de presença atual dos dispositivos de operador/node conectados.system-eventacrescenta um evento de sistema e pode atualizar/transmitir o contexto de presença.last-heartbeatretorna o evento de Heartbeat persistido mais recente.set-heartbeatsativa ou desativa o processamento de Heartbeat no Gateway.gateway.suspend.preparecria uma concessão curta de suspensão cooperativa somente quando o trabalho monitorado do Gateway está ocioso.gateway.suspend.statusverifica essa concessão, egateway.suspend.resumea libera após a retomada ou uma operação de host abortada.
Modelos e uso
models.listretorna o catálogo de modelos permitidos em tempo de execução. Consulte as visualizações de “models.list” abaixo.usage.statusretorna resumos das janelas de uso/cotas restantes dos provedores.usage.costretorna resumos agregados do uso de custos para um intervalo de datas. PasseagentIdpara um agente ouagentScope: "all"para agregar os agentes configurados.doctor.memory.statusretorna a prontidão da memória vetorial/dos embeddings em cache para o workspace do agente padrão ativo. Passe{ "probe": true }ou{ "deep": true }apenas para realizar um ping explícito no provedor de embeddings ativo. Passe{ "agentId": "agent-id" }para restringir as estatísticas do armazenamento do Dreaming ao workspace de um agente; omiti-lo agrega os workspaces do Dreaming configurados.doctor.memory.dreamDiary,doctor.memory.backfillDreamDiary,doctor.memory.resetDreamDiary,doctor.memory.resetGroundedShortTerm,doctor.memory.repairDreamingArtifactsedoctor.memory.dedupeDreamDiaryaceitam{ "agentId": "agent-id" }opcional; quando omitido, operam no workspace do agente padrão configurado.doctor.memory.remHarnessretorna uma prévia limitada e somente leitura do ambiente REM para clientes remotos do plano de controle, incluindo caminhos do workspace, trechos da memória, Markdown fundamentado renderizado e candidatos a promoção profunda. Exigeoperator.read.sessions.usageretorna resumos de uso por sessão. PasseagentIdpara um agente ouagentScope: "all"para listar os agentes configurados em conjunto. Ambos os métodos de uso aceitammode: "specific"com umtimeZoneda IANA para limites e agrupamentos de dias do calendário compatíveis com o horário de verão.utcOffsetcontinua compatível com clientes mais antigos e serve como alternativa quando o runtime do Gateway não reconhece o fuso solicitado.sessions.usage.timeseriesretorna o uso em série temporal de uma sessão.sessions.usage.logsretorna entradas do log de uso de uma sessão.
Canais e auxiliares de login
channels.statusretorna resumos de status de canais/Plugins integrados e incluídos.channels.logoutencerra a sessão de um canal/conta específico quando o canal oferece suporte.web.login.startinicia um fluxo de login por QR/web para o provedor atual de canal web compatível com QR.web.login.waitaguarda a conclusão desse fluxo e inicia o canal em caso de sucesso.push.testenvia uma notificação push de teste por APNs para um node iOS registrado.voicewake.getretorna os acionadores de palavra de ativação armazenados.voicewake.setatualiza os acionadores de palavra de ativação e transmite a alteração.
Gerenciamento de Plugins
plugins.list(operator.read) retorna o inventário de Plugins instalados, além de seleções oficiais organizadas localmente, diagnósticos e se o modo de instalação atual permite modificações.plugins.search(operator.read) pesquisa famílias de Plugins de código e Plugins de pacote instaláveis do ClawHub. Passequerynão vazio elimitopcional de 1 a 100.plugins.install(operator.admin) instala uma entrada oficial do catálogo com{ source: "official", pluginId }ou um pacote do ClawHub com{ source: "clawhub", packageName, version?, acknowledgeClawHubRisk? }. As instalações do ClawHub preservam as verificações de confiança, integridade e política de instalação do Gateway. Instalações bem-sucedidas exigem a reinicialização do Gateway.plugins.setEnabled(operator.admin) altera a política de ativação de um Plugin instalado usando{ pluginId, enabled }. A resposta inclui a entrada atualizada do catálogo, metadados de reinicialização e quaisquer avisos de seleção de slot.plugins.uninstall(operator.admin) remove um Plugin instalado externamente com{ pluginId }: referências de configuração, o registro de instalação e os arquivos gerenciados. Plugins incluídos não podem ser desinstalados, apenas desativados. A resposta lista as ações de remoção e sempre exige a reinicialização do Gateway.
Mensagens e logs
sendé a RPC de entrega de saída direta para envios direcionados a canal/conta/thread fora do executor de chat.logs.tailretorna o final configurado do log de arquivo do Gateway, com controles de cursor/limite e máximo de bytes.
Terminal do operador
terminal.openinicia um PTY do host para umagentIdexplícito ou para o agente padrão e retorna o agente resolvido, o diretório de trabalho, o shell e o estado de confinamento.terminal.input,terminal.resizeeterminal.closeoperam somente em sessões pertencentes à conexão que faz a chamada.terminal.uploadaceita um arquivo em base64 de até 16 MiB, armazena-o em um diretório temporário privado por 24 horas no Gateway da sessão ou no host do nó emparelhado e retorna o caminho absoluto. O chamador ainda precisa colar ou usar esse caminho de outra forma; a RPC nunca grava uma entrada no terminal nem executa um comando.- Os eventos
terminal.dataeterminal.exitsão transmitidos somente para a conexão que possui a sessão. - As sessões cuja conexão é interrompida são desanexadas, não encerradas: elas permanecem disponíveis para reanexação por
gateway.terminal.detachedSessionTimeoutSeconds(padrão 300;0restaura o encerramento ao desconectar), enquanto a saída recente se acumula em um buffer limitado no lado do servidor. terminal.listretorna sessões que podem ser anexadas;terminal.attachvincula novamente uma sessão ativa ou desanexada à conexão que faz a chamada e retorna o buffer de reprodução (assunção de controle no estilo tmux — um proprietário ativo anterior recebeterminal.exitcom o motivodetached);terminal.textlê o buffer como texto simples sem anexar.- Cada método de terminal exige
operator.admin;gateway.terminal.enableddeve ser explicitamente verdadeiro. Agentes totalmente isolados são recusados, e uma alteração na política do agente fecha os PTYs existentes e em andamento, inclusive os desanexados.
Talk e TTS
talk.catalogretorna o catálogo somente leitura de provedores do Talk para fala, transcrição por streaming e voz em tempo real: IDs canônicos de provedores, aliases do registro, rótulos, estado de configuração, um resultado opcionalreadyno nível do grupo, IDs expostos de modelos/vozes, modos canônicos, transportes, estratégias do cérebro e sinalizadores de áudio/recursos em tempo real, sem retornar segredos dos provedores nem alterar a configuração global. Os gateways atuais definemreadyapós aplicar a seleção de provedor em tempo de execução; em gateways mais antigos, trate sua ausência como não verificada.talk.configretorna o payload efetivo de configuração do Talk;includeSecretsexigeoperator.talk.secrets(ouoperator.admin).talk.session.createcria uma sessão do Talk pertencente ao Gateway pararealtime/gateway-relay,transcription/gateway-relayoustt-tts/managed-room. Parastt-tts/managed-room, os chamadores deoperator.writeque passamsessionKeytambém devem passarspawnedBypara obter visibilidade da chave de sessão com escopo; a criação desessionKeysem escopo ebrain: "direct-tools"exigemoperator.admin.talk.session.joinvalida um token de sessão de sala gerenciada, emitesession.readyousession.replacedconforme necessário e retorna metadados da sala/sessão, além de eventos recentes do Talk, mas nunca o token em texto simples nem seu hash.talk.session.appendAudioacrescenta áudio de entrada PCM em base64 às sessões de retransmissão em tempo real e transcrição pertencentes ao Gateway.talk.session.startTurn,talk.session.endTurnetalk.session.cancelTurncontrolam o ciclo de vida dos turnos de salas gerenciadas, com rejeição de turnos obsoletos antes da limpeza do estado.talk.session.cancelOutputinterrompe a saída de áudio do assistente, principalmente para interrupção de fala condicionada por VAD em sessões de retransmissão do Gateway.talk.session.submitToolResultconclui uma chamada de ferramenta do provedor emitida por uma sessão de retransmissão em tempo real pertencente ao Gateway. A solicitação aguarda qualquer sinal de conclusão assíncrona exposto pela ponte do provedor; envios com falha mantêm a execução vinculada ativa e não emitem um evento de resultado de ferramenta bem-sucedido. Passeoptions: { willContinue: true }para uma saída intermediária da ferramenta ouoptions: { suppressResponse: true }quando a ponte do provedor anunciar compatibilidade com supressão e o resultado não deva iniciar outra resposta.talk.session.steerenvia o controle de voz da execução ativa para uma sessão do Talk baseada em agente e pertencente ao Gateway:{ sessionId, text, mode? }, em quemodeéstatus,steer,canceloufollowup; quando omitido, o modo é classificado com base no texto falado.talk.session.closefecha uma sessão de retransmissão, transcrição ou sala gerenciada pertencente ao Gateway e emite eventos terminais do Talk.talk.modedefine/transmite o estado atual do modo Talk para clientes da WebChat/Control UI.talk.client.createcria uma sessão de provedor em tempo real pertencente ao cliente usandowebrtcouprovider-websocket, enquanto o Gateway controla a configuração, as credenciais, as instruções e a política de ferramentas.talk.client.toolCallpermite que transportes em tempo real pertencentes ao cliente encaminhem chamadas de ferramentas do provedor para a política do Gateway. A primeira ferramenta compatível éopenclaw_agent_consult; os clientes recebem um ID de execução e aguardam os eventos normais do ciclo de vida do chat antes de enviar o resultado da ferramenta específico do provedor.talk.client.steerenvia o controle de voz da execução ativa para transportes em tempo real pertencentes ao cliente. O Gateway resolve a execução incorporada ativa com base emsessionKeye retorna um resultado estruturado de aceitação/rejeição, em vez de descartar silenciosamente o direcionamento.talk.eventé o único canal de eventos do Talk para adaptadores em tempo real, transcrição, STT/TTS, salas gerenciadas, telefonia e reuniões.talk.speaksintetiza fala por meio do provedor de fala ativo do Talk.tts.statusretorna o estado de ativação do TTS, o provedor ativo, os provedores alternativos e o estado de configuração dos provedores.tts.providersretorna o inventário visível de provedores de TTS.tts.enableetts.disablealternam o estado das preferências de TTS.tts.setProvideratualiza o provedor de TTS preferencial.tts.convertexecuta uma conversão avulsa de texto em fala.tts.speak(operator.write) renderizatextnão vazio com a cadeia configurada de provedores gerais de TTS e retorna um clipe inteiro em linha comoaudioBase64, além dos metadadosprovidere, opcionalmente,outputFormat,mimeTypeefileExtension. Ao contrário detts.convert, ele não retorna um caminho local do Gateway; ao contrário detalk.speak, ele não exige um provedor do Talk. Texto acima demessages.tts.maxTextLengthretornaINVALID_REQUEST; falhas de síntese retornamUNAVAILABLE.
Segredos, configuração, atualização e assistente
secrets.reloadresolve novamente as SecretRefs ativas e substitui o estado dos segredos em tempo de execução somente em caso de sucesso completo.secrets.resolveresolve atribuições de segredos de destino de comando para um conjunto específico de comandos/destinos.config.getretorna o snapshot atual da configuração em disco, ohashbruto do arquivo raiz, oconfigRevisionHashresolvido e oappliedConfigHashopcional da revisão resolvida aceita pelo runtime ativo do Gateway.config.setgrava um payload de configuração validado.config.patchmescla uma atualização parcial da configuração. A substituição destrutiva de arrays exige o caminho afetado emreplacePaths; arrays aninhados sob entradas de array usam caminhos[], comoagents.list[].skills.config.applyvalida e substitui o payload completo da configuração.config.schemaretorna o payload do esquema de configuração ativo usado pela Control UI e pelas ferramentas da CLI: esquema,uiHints, versão, metadados de geração e metadados de esquema de plugins e canais quando podem ser carregados. Ele inclui metadadostitle/descriptionprovenientes dos mesmos rótulos/textos de ajuda da UI, incluindo ramificações de composição de objeto aninhado, curinga, item de array eanyOf/oneOf/allOfquando há documentação de campo correspondente.config.schema.lookupretorna um payload de consulta com escopo de caminho para um caminho de configuração: caminho normalizado, um nó de esquema superficial, dica correspondente +hintPath,reloadKindopcional e resumos dos filhos imediatos para detalhamento na UI/CLI.reloadKindérestart,hotounone(src/config/schema.ts) e reflete o planejador de recarregamento da configuração do Gateway para o caminho solicitado. Os nós do esquema de consulta mantêm a documentação voltada ao usuário e os campos comuns de validação (title,description,type,enum,const,format,pattern, limites numéricos/de string/de array/de objeto,additionalProperties,deprecated,readOnly,writeOnly). Os resumos dos filhos expõemkey,pathnormalizado,type,required,hasChildren,reloadKindopcional, além doshint/hintPathcorrespondentes.update.runexecuta o fluxo de atualização do Gateway e agenda uma reinicialização somente se a atualização for bem-sucedida; chamadores com uma sessão podem incluircontinuationMessagepara que a inicialização retome um turno adicional do agente por meio da fila de continuação da reinicialização. As atualizações do gerenciador de pacotes e as atualizações supervisionadas do checkout do Git pelo plano de controle usam uma transferência desanexada para um serviço gerenciado, em vez de substituir a árvore de pacotes ou alterar o checkout/resultado da compilação dentro do Gateway ativo. Uma transferência iniciada retornaok: truecomresult.reason: "managed-service-handoff-started"ehandoff.status: "started"; transferências indisponíveis ou com falha retornamok: falsecommanaged-service-handoff-unavailableoumanaged-service-handoff-failed, além dehandoff.commandquando é necessária uma atualização manual pelo shell. Indisponível significa que o OpenClaw não possui um limite de supervisão seguro ou uma identidade de serviço durável, comoOPENCLAW_SYSTEMD_UNITpara systemd. Durante uma transferência iniciada, o sentinela de reinicialização pode informar brevementestats.reason: "restart-health-pending"; a continuação é adiada até que a CLI verifique o Gateway reiniciado e grave o sentinela finalok.update.statusatualiza e retorna o sentinela mais recente de reinicialização de atualização, incluindo a versão em execução após a reinicialização, quando disponível.wizard.start,wizard.next,wizard.statusewizard.cancelexpõem o assistente de integração por RPC via WS.
Auxiliares de agente e espaço de trabalho
agents.listretorna as entradas de agente configuradas, incluindo metadados efetivos de modelo e runtime.agents.create,agents.updateeagents.deletegerenciam registros de agentes e a vinculação do espaço de trabalho.agents.files.list,agents.files.geteagents.files.setgerenciam os arquivos de inicialização do espaço de trabalho expostos a um agente.audit.activity.listretorna o registro de atividades versionado que contém apenas metadados;audit.listcontinua sendo o RPC de execução/ferramenta seguro para compatibilidade.agents.workspace.listeagents.workspace.get(operator.read) fornecem navegação paginada e somente leitura pelo diretório do espaço de trabalho de um agente para clientes no domínio de operadores confiáveis descrito em Escopos de operador. As solicitações aceitam apenas caminhos relativos ao espaço de trabalho; as leituras permanecem confinadas à raiz do espaço de trabalho após a resolução do caminho real (escapes por links simbólicos e links físicos são rejeitados), têm limite de tamanho e são restritas a texto UTF-8 e tipos de imagem comuns (base64). As respostas não expõem o caminho do espaço de trabalho no host. Não há operações de gravação neste namespace.tasks.list,tasks.getetasks.cancelexpõem o registro de tarefas do Gateway a clientes SDK e operadores. Consulte RPCs do registro de tarefas abaixo.artifacts.list,artifacts.geteartifacts.downloadexpõem resumos e downloads de artefatos derivados da transcrição para um escopo explícitosessionKey,runIdoutaskId. As consultas de execução e tarefa determinam no servidor a sessão proprietária e retornam apenas mídia da transcrição com procedência correspondente; fontes de URL locais ou não seguras retornam downloads não compatíveis em vez de serem buscadas pelo servidor.environments.listeenvironments.statuspreservam a descoberta de ambientes locais do Gateway e de Node. Workers de nuvem configurados e registros duráveis deixados por perfis anteriores adicionam metadadosworkercomproviderId,leaseIdopcional,state,ageMs,idleMsopcional eattachedSessionIds. Os estados do ciclo de vida do worker sãorequested,provisioning,bootstrapping,ready,attached,idle,draining,destroying,destroyed,failedeorphaned.environments.create({ profileId, idempotencyKey }) provisiona um worker usando um perfil configurado de provedor de plugin; novas tentativas com a mesma chave reutilizam a operação durável.environments.destroy({ environmentId }) solicita o desprovisionamento idempotente de um ambiente de worker durável. Ambos exigemoperator.admin, são gravações do plano de controle e retornam o mesmo formato de resumo de ambiente usado pelas respostas de status.agent.identity.getretorna a identidade efetiva do assistente para um agente ou uma sessão.agent.waitaguarda a conclusão de uma execução e retorna o snapshot terminal quando disponível.
Controle de sessões
sessions.listretorna o índice atual de sessões, incluindo metadadosagentRuntimepor linha quando um backend de runtime de agente está configurado. Quando o posicionamento em workers de nuvem está habilitado ou existe um estado de recuperação durável, as linhas de sessão também incluem um estado fechadoplacement(local,requested,provisioning,syncing,starting,active,draining,reconciling,reclaimedoufailed), além de campos específicos do estado referentes a ambiente, época do proprietário, espaço de trabalho, pacote, cursor de ACK ou recuperação.sessions.subscribeesessions.unsubscribeativam ou desativam as assinaturas de eventos de alteração de sessão para o cliente WS atual.sessions.messages.subscribeesessions.messages.unsubscribeativam ou desativam as assinaturas de eventos de transcrição/mensagem para uma sessão. PasseincludeApprovals: truepara também receber eventos de ciclo de vidasession.approvalsanitizados referentes a aprovações cujo público persistido inclua exatamente essa sessão e cuja vinculação de revisor autorize o cliente assinante. A resposta da assinatura passa então a incluir umapprovalReplaypendente e limitado; ele é autoritativo quandotruncatedé falso. A adesão é feita por chamada de assinatura, não é persistente: assinar novamente a mesma sessão semincludeApprovals: trueremove uma assinatura de aprovação existente. Além da autoridade normal de leitura da sessão, essa adesão exigeoperator.adminouoperator.approvalsem um dispositivo pareado.sessions.previewretorna visualizações prévias limitadas de transcrições para chaves de sessão específicas.sessions.describeretorna uma linha de sessão do Gateway para uma chave de sessão exata.sessions.resolveresolve ou canonicaliza um destino de sessão.sessions.createcria uma nova entrada de sessão. Os valores opcionaismodelethinkingLevelpersistem atomicamente as substituições iniciais de modelo e raciocínio.worktree: trueprovisiona uma árvore de trabalho gerenciada;worktreeBaseRef/worktreeNameopcionais selecionam a referência base e o nome da branch, eexecNode(operator.admin) vincula a execução da sessão a um host Node. A árvore de trabalho criada é reproduzida no resultado e persistida na linha da sessão (worktree: { id, branch, repoRoot }). Quando a entrada é criada, mas seuchat.sendinicial aninhado é rejeitado, o resultado bem-sucedido incluirunStarted: falseerunError; os clientes podem preservar o prompt e tentar novamente usando a chave de sessão retornada.sessions.dispatch(operator.admin) move uma sessão local existente do OpenClaw com uma árvore de trabalho gerenciada pertencente à sessão para um perfil configurado de worker de nuvem. Passe{ key, profileId, agentId? }. O método não existe quando nenhum perfil de worker está configurado, encerra a admissão de turnos locais antes de aguardar a conclusão do trabalho ativo e só retorna depois que o posicionamento atinge a propriedade do workeractive. O despacho é unidirecional; o retorno do worker para o ambiente local não faz parte deste RPC.sessions.groups.list,sessions.groups.put,sessions.groups.renameesessions.groups.deletegerenciam o catálogo de grupos de sessões personalizados pertencente ao Gateway (nomes + ordem de exibição). A associação permanece no campocategoryde cada sessão; renomear e excluir atualizam as sessões integrantes no servidor.sessions.sendenvia uma mensagem para uma sessão existente.sessions.steeré a variante de interrupção e redirecionamento para uma sessão ativa.sessions.abortinterrompe o trabalho ativo de uma sessão. PassekeycomrunIdopcional, ou apenasrunIdpara execuções ativas que o Gateway consiga associar a uma sessão.sessions.patchatualiza metadados/substituições da sessão e informa o modelo canônico resolvido, além doagentRuntimeefetivo.sessions.reset,sessions.deleteesessions.compactrealizam a manutenção da sessão.sessions.getretorna a linha completa da sessão armazenada.- A execução do chat ainda usa
chat.history,chat.send,chat.abortechat.inject.chat.historyé normalizado para exibição em clientes de UI: tags de diretivas embutidas são removidas do texto visível; payloads XML de chamadas de ferramenta em texto simples (<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e blocos truncados de chamadas de ferramenta) e tokens de controle de modelo ASCII/de largura completa que tenham vazado são removidos; linhas do assistente contendo exclusivamente tokens de silêncio (NO_REPLY/no_replyexatos) são omitidas; e linhas grandes demais podem ser substituídas por placeholders. chat.message.geté o leitor aditivo e limitado da mensagem completa para uma única entrada visível da transcrição. PassesessionKey,agentIdopcional quando a seleção da sessão tiver escopo de agente e ummessageIdde transcrição anteriormente exposto porchat.history; o Gateway retorna a mesma projeção normalizada para exibição sem o limite de truncamento do histórico leve, quando a entrada armazenada ainda estiver disponível e não for grande demais.chat.toolTitlesretorna títulos curtos de finalidade para chamadas de ferramenta renderizadas na UI de Controle (em lote, no máximo 24 itens com entradas limitadas). O recurso exige adesão por meio degateway.controlUi.toolTitles(desativado por padrão); Gateways desativados respondem{ titles: {}, disabled: true }sem chamar o modelo para que os clientes parem de solicitar. Quando ativados, os títulos usam o roteamento padrão do modelo utilitário: umutilityModelconfigurado explicitamente (uma decisão do operador que, como todas as tarefas utilitárias, pode enviar conteúdo limitado da tarefa ao provedor escolhido) ou, caso contrário, o modelo pequeno padrão declarado pelo provedor da sessão, para que nenhum novo destino de saída surja implicitamente; umutilityModelvazio os desativa por completo. Os títulos nunca recorrem ao modelo principal. Os resultados são armazenados em cache no banco de dados de estado por agente, usando como chave o nome da ferramenta + entrada, portanto visualizações repetidas nunca geram nova cobrança pelas mesmas chamadas.chat.sendaceitafastMode: "auto"de um único turno para usar o modo rápido em chamadas de modelo iniciadas antes do limite automático e, depois, iniciar novas tentativas, fallbacks, resultados de ferramenta ou chamadas de continuação posteriores sem o modo rápido. O limite padrão é de 60 segundos (DEFAULT_FAST_MODE_AUTO_ON_SECONDS) e pode ser configurado por modelo comagents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. Um chamadorchat.sendpode passarfastAutoOnSecondsde um único turno para substituir o limite nessa solicitação. PassequeueMode(steer,followup,collectouinterrupt) para substituir o modo de fila armazenado apenas nesta solicitação; ações explícitas de redirecionamento da UI de Controle usamqueueMode: "steer".
Pareamento de dispositivos e tokens de dispositivos
device.pair.listretorna dispositivos pareados pendentes e aprovados.device.pair.setupCodecria um código de configuração móvel e, por padrão, uma URL de dados de QR code em PNG. Ele exigeoperator.admine é intencionalmente omitido da descoberta anunciada. O resultado incluisetupCode,qrDataUrlopcional,gatewayUrl, o rótulo não secretoautheurlSource.device.pair.approve,device.pair.rejectedevice.pair.removegerenciam registros de pareamento de dispositivos.device.pair.renameatribui um rótulo de operador ({ deviceId, label }) que tem preferência sobre o nome de exibição informado pelo cliente e persiste após o reparo ou a nova aprovação do dispositivo.device.token.rotatefaz a rotação de um token de dispositivo pareado dentro dos limites de sua função aprovada e do escopo do chamador.device.token.revokerevoga um token de dispositivo pareado dentro dos limites de sua função aprovada e do escopo do chamador.
O código de configuração incorpora uma credencial de inicialização de curta duração. Os clientes não devem registrá-la em logs nem mantê-la após o fluxo de pareamento.
Emparelhamento de Node, invocação e trabalho pendente
node.pair.list,node.pair.approve,node.pair.rejectenode.pair.removeabrangem as aprovações de recursos do Node.node.pair.requestenode.pair.verifyforam removidos na versão 2026.7 junto com o armazenamento independente de emparelhamento de Node; as solicitações pendentes são criadas pelo Gateway durante as conexões dos Nodes.node.listenode.describeretornam o estado conhecido/conectado do Node.node.renameatualiza o rótulo de um Node emparelhado.node.invokeencaminha um comando para um Node conectado.node.invoke.resultretorna o resultado de uma solicitação de invocação.mcp.tools.call.v1é o comando do host de Node sem interface gráfica para chamar uma ferramenta MCP local do Node configurada. Ele é transportado pornode.invoke, exige que o Node declare o comando e permanece sujeito à aprovação de emparelhamento e agateway.nodes.denyCommands.node.eventtransporta eventos originados pelo Node de volta ao Gateway.node.pluginTools.updateé o único caminho de publicação para substituir os descritores de ferramentas de Plugin/MCP visíveis ao agente do Node conectado; os parâmetros deconnectnão os transportam.node.pending.pullenode.pending.acksão as APIs de fila do Node conectado.node.pending.enqueueenode.pending.draingerenciam trabalho pendente durável para Nodes offline/desconectados.
Famílias de aprovação
approval.geteapproval.resolvesão os métodos de aprovação durável independentes de tipo (escopooperator.approvals).approval.getretorna uma projeção sanitizada, pendente ou terminal retida, com umurlPathestável;approval.resolveaceita o ID de aprovação canônico, umkindexplícito e uma decisão, aplica a resolução em que a primeira resposta prevalece e sempre retorna o resultado canônico registrado.exec.approval.request,exec.approval.get,exec.approval.listeexec.approval.resolveabrangem solicitações de aprovação de execução de uso único, além da consulta/reprodução de aprovações pendentes. Eles são adaptadores de limite de protocolo sobre o mesmo registro de aprovações durável.exec.approval.waitDecisionaguarda uma aprovação de execução pendente e retorna a decisão final (ounullem caso de tempo limite).exec.approvals.geteexec.approvals.setgerenciam instantâneos da política de aprovação de execução do Gateway.exec.approvals.node.geteexec.approvals.node.setgerenciam a política de aprovação de execução local do Node por meio de comandos de retransmissão do Node.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisioneplugin.approval.resolveabrangem fluxos de aprovação definidos por Plugins.
Automação, Skills e ferramentas
- Automação:
wakeagenda uma injeção imediata ou no próximo Heartbeat de texto de ativação;cron.get,cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsgerenciam trabalho agendado. cron.runcontinua sendo uma RPC no estilo de enfileiramento para execuções manuais. Os clientes que precisam de semântica de conclusão devem ler orunIdretornado e consultarcron.runsperiodicamente.cron.runsaceita um filtrorunIdopcional e não vazio para que os clientes possam acompanhar uma execução manual enfileirada sem disputar com outras entradas do histórico referentes ao mesmo trabalho.- Skills e ferramentas:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke. Consulte Métodos auxiliares do operador abaixo.
Famílias comuns de eventos
chat: atualizações de conversa da interface, comochat.inject, e outros eventos de conversa exclusivos da transcrição. No protocolo v4, as cargas úteis delta transportamdeltaText;messagecontinua sendo o instantâneo cumulativo do assistente. Substituições que não são prefixos definemreplace=truee usamdeltaTextcomo texto de substituição.session.message,session.operation,session.tool: atualizações de transcrição, operação de sessão em andamento e fluxo de eventos de uma sessão assinada.session.approval: estado sanitizado de aprovações pendentes e terminais para um assinante de sessão exata que aderiu explicitamente. As aprovações filhas usam o público ancestral persistido; os eventos nunca alteram transcrições nem ativam agentes.sessions.changed: o índice ou os metadados da sessão foram alterados.presence: atualizações do instantâneo de presença do sistema.tick: evento periódico de manutenção de conexão/vitalidade.health: atualização do instantâneo de integridade do Gateway.heartbeat: atualização do fluxo de eventos de Heartbeat.cron: evento de alteração de execução/trabalho Cron.shutdown: notificação de encerramento do Gateway.node.pair.requested/node.pair.resolved: ciclo de vida do emparelhamento de Node.node.invoke.request: difusão de solicitação de invocação de Node.device.pair.requested/device.pair.resolved: ciclo de vida de dispositivo emparelhado.voicewake.changed: a configuração do acionador por palavra de ativação foi alterada.exec.approval.requested/exec.approval.resolved: ciclo de vida da aprovação de execução.plugin.approval.requested/plugin.approval.resolved: ciclo de vida da aprovação de Plugin.
Métodos auxiliares de Node
Os Nodes podem chamar skills.bins para obter a lista atual de executáveis de Skills
para verificações de permissão automática.
RPC do livro-razão de auditoria
audit.activity.list oferece aos clientes operadores uma visualização estável, da mais recente para a mais antiga, dos metadados do ciclo de vida
de execuções de agentes, ações de ferramentas e mensagens com adesão opcional. Ela exige
operator.read. As consultas excluem registros com mais de 30 dias, e o livro-razão
SQLite compartilhado é limitado a 100.000 registros. As linhas expiradas são excluídas durante
a inicialização do Gateway, a manutenção a cada hora e gravações posteriores. Consulte
Histórico de auditoria para conhecer o modelo de dados e a semântica de privacidade.
- Parâmetros:
agentId,sessionKeyourunIdexato e opcional;kindopcional ("agent_run","tool_action"ou"message");statusopcional ("started","succeeded","failed","cancelled","timed_out","blocked"ou"unknown");directionde mensagem opcional ("inbound"ou"outbound") echannelexato; limites inclusivos opcionaisafter/beforeem milissegundos Unix;limitopcional de1a500; e a stringcursoropcional da página anterior. - Resultado:
{ "events": AuditActivityEventV1[], "nextCursor"?: string }.
A união nomeada de resultados V1 tem esquemas separados para execução de agente, ação de ferramenta, mensagem recebida
e mensagem enviada. O discriminador eventType é, respectivamente,
agent_run, tool_action, inbound_message ou outbound_message; kind e
direction de mensagem permanecem disponíveis para filtragem e exibição. Cada evento tem
schemaVersion: 1 inteiro. As referências de identidade de mensagem usam o formato
hmac-sha256:v1:<32 hex key id>:<64 hex digest> exato; um ID de ator remetente do canal
usa o mesmo formato.
Todas as variantes exigem eventType, schemaVersion, eventId, sequence,
sourceSequence, occurredAt, kind, action, status, actor e
redaction. Os campos das variantes são:
eventType |
Campos obrigatórios | Campos opcionais |
|---|---|---|
agent_run |
agentId, runId; kind: "agent_run" |
sessionKey, sessionId, errorCode |
tool_action |
agentId, runId; kind: "tool_action" |
sessionKey, sessionId, toolCallId, toolName, errorCode |
inbound_message |
direction: "inbound", channel, conversationKind, outcome |
agentId, runId, durationMs, resultCount, referências de identidade, reasonCode, errorCode |
outbound_message |
direction: "outbound", channel, conversationKind, outcome |
agentId, runId, durationMs, resultCount, referências de identidade, reasonCode, deliveryKind, failureStage, errorCode |
Os enums fechados de mensagem são:
conversationKind:direct,group,channelouunknown.outcomede entrada:completed,skippedoufailed;reasonCodeopcional:duplicate,reply_operation_active,reply_operation_aborted,fast_abort,plugin_bound_handled,plugin_bound_unavailable,plugin_bound_declined,plugin_bound_error,before_dispatch_handled,acp_dispatch_completed,acp_dispatch_failed,acp_dispatch_emptyouacp_dispatch_aborted.outcomede saída:sent,suppressed,failedouunknown;reasonCodeopcional:cancelled_by_message_sending_hook,cancelled_by_reply_payload_sending_hook,empty_after_message_sending_hook,empty_after_reply_payload_sending_hookouno_visible_payload. Um adaptador que não retorna identidade da plataforma éunknown, pois o efeito colateral externo não pode ser refutado.deliveryKind:text,mediaouother;failureStage:platform_send,queueouunknown.
Os campos terminais são correlacionados, não opcionalmente independentes:
| Variante | Mapeamento terminal |
|---|---|
| Execução de agente | started não tem errorCode; cada status concluído sem sucesso exige seu código run_* correspondente. |
| Ação de ferramenta | started e sucesso não têm errorCode; cada outro status concluído exige seu código tool_* correspondente. |
| Mensagem recebida | sucesso = completed; bloqueio = skipped; falha = failed mais message_processing_failed. reasonCode, quando presente, deve pertencer a essa família terminal. |
| Mensagem enviada | sucesso = sent; bloqueio = suppressed mais reasonCode; falha = failed mais errorCode e failureStage; desconhecido = unknown mais failureStage. |
Cada evento de atividade inclui um id de evento estável, uma sequência monotônica do ledger,
uma sequência do evento de origem, carimbo de data/hora, ator, ação, status, inteiro
schemaVersion: 1 e redaction: "metadata_only". Registros de execução e ferramenta
exigem a proveniência do agente e da execução e podem incluir a proveniência da sessão. Registros de
mensagens podem incluir ids do agente e da execução, mas intencionalmente nunca incluem
sessionKey ou sessionId; portanto, o filtro de consulta sessionKey se aplica
somente às linhas de execução e ferramenta. Eventos de ferramenta podem incluir o id da chamada da ferramenta e o nome da ferramenta.
Registros de mensagens usam message.inbound.processed ou
message.outbound.finished e adicionam direção, canal, tipo de conversa,
resultado normalizado e, opcionalmente, tipo de entrega, estágio da falha, duração,
contagem de resultados, código do motivo e pseudônimos com chave, locais da instalação,
para conta/conversa/mensagem/destino. Esses pseudônimos auxiliam na
correlação, mas não constituem anonimização: o banco de dados de estado contém a chave deles,
enquanto as exportações de RPC e CLI não. O ledger não armazena prompts, corpos de mensagens,
argumentos de ferramentas, resultados de ferramentas, saída de comandos ou texto bruto de erros.
Os valores sessionKey de execução/ferramenta permanecem como metadados brutos de correlação e podem incorporar
ids de contas ou pares da plataforma; os registros de mensagens omitem chaves de sessão.
Para linhas de entrada, durationMs mede o despacho do núcleo até seu estado terminal e
resultCount conta payloads finalizados de ferramenta, bloco e resposta na fila. Para
linhas de saída, durationMs abrange a responsabilidade pela entrega até a confirmação,
fila de mensagens mortas ou reconciliação (incluindo o tempo de espera na fila), e resultCount
conta envios físicos identificados à plataforma. deliveryKind, quando presente,
descreve o payload efetivo após hooks e renderização; linhas suprimidas ou
ambíguas devido a falha omitem esse valor.
A cobertura atual de mensagens inclui mensagens de entrada aceitas que chegam ao
despacho do núcleo, incluindo resultados de duplicação/terminais do núcleo. A cobertura de saída grava
uma linha terminal por payload de resposta lógico original que chega à entrega durável
compartilhada; a fragmentação e a distribuição em leque do adaptador são agregadas em resultCount. Envios
enfileirados, passíveis de nova tentativa ou ambíguos são registrados somente após confirmação, fila
de mensagens mortas ou reconciliação. Caminhos locais de Plugin e de envio direto que ignoram esses
limites compartilhados ainda não são cobertos. A fila limitada de workers funciona em regime de melhor esforço
e pode descartar registros em caso de falha ou saturação; portanto, essa superfície não é um
arquivo de conformidade sem perdas.
O registro fica ativado por padrão e é controlado por
audit.enabled. O registro de mensagens é
controlado separadamente por audit.messages e usa "off" como padrão. Quando
o registro está desativado, audit.activity.list continua fornecendo registros gravados
anteriormente até que expirem.
Os esquemas fornecidos de solicitação e resultado de audit.list e de AuditEvent
permanecem inalterados e retornam somente registros de execução do agente e de ações de ferramentas. Novos
clientes de operador devem chamar audit.activity.list quando o Gateway o anunciar. Gateways mais
antigos podem informar unknown method: audit.activity.list ou, como
a autorização precedia a busca do método nas versões fornecidas, missing scope: operator.admin para uma solicitação com escopo de leitura. Trate o último como ausência do método
somente quando o método não tiver sido anunciado. Um cliente poderá então tentar novamente audit.list
somente quando seus filtros não exigirem compatibilidade com tipo, direção ou canal
da mensagem.
Use openclaw audit para consultas de texto e exportações JSON limitadas.
RPCs do ledger de tarefas
Clientes de operador inspecionam e cancelam registros de tarefas em segundo plano do gateway por meio
dos RPCs do ledger de tarefas (packages/gateway-protocol/src/schema/tasks.ts). Eles
retornam resumos de tarefas sanitizados, não o estado bruto do runtime.
tasks.listexigeoperator.read.- Parâmetros:
statusopcional ("queued","running","completed","failed","cancelled"ou"timed_out") ou uma matriz desses status,agentIdopcional,sessionKeyopcional,limitopcional de1a500e a string opcionalcursor. - Resultado:
{ "tasks": TaskSummary[], "nextCursor"?: string }.
- Parâmetros:
tasks.getexigeoperator.read.- Parâmetros:
{ "taskId": string }. - Resultado:
{ "task": TaskSummary }. - Ids de tarefas ausentes retornam o formato de erro de não encontrado do gateway.
- Parâmetros:
tasks.cancelexigeoperator.write.- Parâmetros:
{ "taskId": string, "reason"?: string }. - Resultado:
{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }. foundinforma se o ledger tinha uma tarefa correspondente.cancelledinforma se o runtime aceitou ou registrou o cancelamento.
- Parâmetros:
TaskSummary inclui id, status e metadados opcionais: kind,
runtime, title, agentId, sessionKey, childSessionKey, ownerKey,
runId, taskId, flowId, parentTaskId, sourceId, carimbos de data/hora, progresso,
resumo terminal e texto de erro sanitizado. agentId identifica o agente
que executa a tarefa; sessionKey e ownerKey preservam o contexto do solicitante e de
controle.
Métodos auxiliares do operador
commands.list(operator.read) obtém o inventário de comandos do runtime para um agente.agentIdé opcional; omita-o para ler o workspace padrão do agente.scopecontrola qual superfície é o destino donameprimário:textretorna o token do comando de texto primário sem o/inicial;nativee o caminho padrãobothretornam nomes nativos que consideram o provedor, quando disponíveis.textAliasescontém aliases exatos de barra, como/modele/m.nativeNamecontém o nome do comando nativo que considera o provedor, quando existe.provideré opcional e afeta somente a nomenclatura nativa e a disponibilidade de comandos nativos de Plugin.includeArgs=falseomite da resposta os metadados serializados de argumentos.
tools.catalog(operator.read) obtém o catálogo de ferramentas do runtime para um agente. A resposta inclui ferramentas agrupadas e metadados de proveniência:source:coreoupluginpluginId: Plugin proprietário quandosource="plugin"optional: se uma ferramenta de Plugin é opcional
tools.effective(operator.read) obtém o inventário efetivo de ferramentas do runtime para uma sessão.sessionKeyé obrigatório.- O gateway deriva o contexto confiável do runtime da sessão no lado do servidor em vez de aceitar contexto de autenticação ou entrega fornecido pelo chamador.
- A resposta é uma projeção derivada pelo servidor e com escopo de sessão do inventário ativo, incluindo ferramentas do núcleo, de Plugins, de canais e de servidores MCP já descobertos.
tools.effectiveé somente leitura para MCP: pode projetar um catálogo MCP de sessão já inicializada por meio da política final de ferramentas, mas não cria runtimes MCP, conecta transportes nem emitetools/list. Se não existir um catálogo já inicializado correspondente, a resposta poderá incluir um aviso comomcp-not-yet-connected,mcp-not-yet-listedoumcp-stale-catalog.- As entradas efetivas de ferramentas usam
source="core",source="plugin",source="channel"ousource="mcp".
tools.invoke(operator.write) invoca uma ferramenta disponível por meio do mesmo caminho de política do gateway que/tools/invoke.nameé obrigatório.args,sessionKey,agentId,confirmeidempotencyKeysão opcionais.- Se
sessionKeyeagentIdestiverem presentes, o agente da sessão resolvida deverá corresponder aagentId. - Wrappers do núcleo exclusivos do proprietário, como
cron,gatewayenodes, exigem identidade de proprietário/administrador (operator.admin), embora o própriotools.invokesejaoperator.write. - A resposta é um envelope voltado ao SDK com
ok,toolName, ooutputopcional e camposerrortipados. Recusas de aprovação ou política retornamok:falseno payload em vez de contornar o pipeline de políticas de ferramentas do gateway.
skills.status(operator.read) obtém o inventário de Skills visível para um agente.agentIdé opcional; omita-o para ler o workspace padrão do agente.- A resposta inclui elegibilidade, requisitos ausentes, verificações de configuração e opções de instalação sanitizadas, sem expor valores brutos de segredos.
skills.searcheskills.detail(operator.read) retornam metadados de descoberta do ClawHub.skills.upload.begin,skills.upload.chunkeskills.upload.commit(operator.admin) preparam um arquivo privado de skill antes de instalá-lo. Esse é um caminho separado de upload administrativo para clientes confiáveis, não o fluxo normal de instalação de skill do ClawHub, e fica desativado por padrão, a menos queskills.install.allowUploadedArchivesesteja ativado.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })cria um upload vinculado a esse slug e valor de imposição.skills.upload.chunk({ uploadId, offset, dataBase64 })anexa bytes no deslocamento decodificado exato.skills.upload.commit({ uploadId, sha256? })verifica o tamanho final e o SHA-256. O commit apenas finaliza o upload; ele não instala a skill.- Os arquivos de skill enviados são arquivos zip que contêm uma raiz
SKILL.md. O nome do diretório interno do arquivo nunca seleciona o destino da instalação.
skills.install(operator.admin) tem três modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala uma pasta de skill no diretórioskills/do workspace padrão do agente. - Modo de upload:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }instala um upload confirmado no diretórioskills/<slug>do workspace padrão do agente. O slug e o valor de imposição devem corresponder à solicitaçãoskills.upload.beginoriginal. A operação é rejeitada, a menos queskills.install.allowUploadedArchivesesteja ativado; a configuração não afeta instalações do ClawHub. - Modo de instalador do Gateway:
{ name, installId, timeoutMs? }executa uma açãometadata.openclaw.installdeclarada no host do gateway. Clientes mais antigos ainda podem enviardangerouslyForceUnsafeInstall; esse campo está obsoleto, é aceito somente para compatibilidade de protocolo e é ignorado. Usesecurity.installPolicypara decisões de instalação pertencentes ao operador.
- Modo ClawHub:
skills.update(operator.admin) tem dois modos:- O modo ClawHub atualiza um slug rastreado ou todas as instalações rastreadas do ClawHub no workspace padrão do agente.
- O modo de configuração aplica patches aos valores de
skills.entries.<skillKey>, comoenabled,apiKeyeenv.
Visualizações de models.list
models.list aceita um parâmetro view opcional
(src/agents/model-catalog-visibility.ts):
- Omitido ou
"default": seagents.defaults.modelsestiver configurado, a resposta será o catálogo permitido, incluindo modelos descobertos dinamicamente para entradasprovider/*. Caso contrário, a resposta será o catálogo completo do Gateway. "configured": comportamento dimensionado para seletores. Seagents.defaults.modelsestiver configurado, ele ainda terá precedência, incluindo a descoberta com escopo de provedor para entradasprovider/*. Sem uma lista de permissões, a resposta usará entradasmodels.providers.<provider>.modelsexplícitas, recorrendo ao catálogo completo somente quando não houver linhas de modelo configuradas."provider-config": inventáriomodels.providers.*.modelsdefinido na origem, independente das listas de permissões do seletor. As linhas incluem recursos públicos dos modelos e disponibilidade que considera as rotas, mas omitem endpoints de provedores, material de autenticação e configuração de solicitações em tempo de execução."all": catálogo completo do Gateway, ignorandoagents.defaults.models. Use em interfaces de diagnóstico/descoberta, não em seletores de modelo comuns.
Aprovações de execução
- Quando uma solicitação de execução exige aprovação, o Gateway transmite
exec.approval.requested. - Os clientes do operador resolvem a solicitação chamando
exec.approval.resolve(requeroperator.approvals). - Para
host=node,exec.approval.requestdeve incluirsystemRunPlan(metadados canônicos deargv/cwd/rawCommand/sessão). Solicitações semsystemRunPlansão rejeitadas. - Após a aprovação, as chamadas
node.invoke system.runencaminhadas reutilizam essesystemRunPlancanônico como o contexto autoritativo de comando/cwd/sessão. - Se um chamador modificar
command,rawCommand,cwd,agentIdousessionKeyentre a preparação e o encaminhamento final aprovado desystem.run, o Gateway rejeitará a execução em vez de confiar no conteúdo modificado.
Fallback de entrega do agente
- As solicitações
agentpodem incluirdeliver=truepara solicitar entrega de saída. bestEffortDeliver=false(o padrão) mantém um comportamento estrito: destinos de entrega não resolvidos ou exclusivamente internos retornamINVALID_REQUEST.bestEffortDeliver=truepermite o fallback para execução somente na sessão quando nenhuma rota externa de entrega puder ser resolvida (por exemplo, sessões internas/de webchat ou configurações ambíguas com vários canais).- Os resultados finais de
agentpodem incluirresult.deliveryStatusquando a entrega tiver sido solicitada, usando os mesmos statussent,suppressed,partial_failedefaileddocumentados emopenclaw agent --json --deliver.
Versionamento
PROTOCOL_VERSION,MIN_CLIENT_PROTOCOL_VERSION,MIN_NODE_PROTOCOL_VERSIONeMIN_PROBE_PROTOCOL_VERSIONficam empackages/gateway-protocol/src/version.ts.- Os clientes enviam
minProtocol+maxProtocol. Os clientes de operador e de interface devem incluir o protocolo atual nesse intervalo; os clientes e servidores atuais executam o protocolo v4. - Clientes autenticados com
role: "node"eclient.mode: "node"podem usar o protocolo de Node N-1 (atualmente v3). Sondas leves de reinicialização usam a mesma janela N-1. A autenticação de dispositivo, o pareamento, os escopos, a política de comandos e as aprovações de execução não são alterados por essa janela de compatibilidade. Os recursos e comandos de Node pertencentes a Plugins ficam indisponíveis até que o Node seja atualizado para o protocolo atual, pois suas superfícies hospedadas não fazem parte do contrato N-1. - Os esquemas e modelos são gerados a partir de definições TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes do cliente
A implementação de referência do cliente fica em packages/gateway-client/src/
(o OpenClaw a encapsula por meio da fachada mínima src/gateway/client.ts). Esses
valores padrão são estáveis em todo o protocolo v4 e constituem a linha de base esperada para
clientes de terceiros.
| Constante | Padrão | Origem |
|---|---|---|
PROTOCOL_VERSION |
4 |
packages/gateway-protocol/src/version.ts |
MIN_CLIENT_PROTOCOL_VERSION |
4 |
packages/gateway-protocol/src/version.ts |
MIN_NODE_PROTOCOL_VERSION |
3 |
packages/gateway-protocol/src/version.ts |
MIN_PROBE_PROTOCOL_VERSION |
3 |
packages/gateway-protocol/src/version.ts |
| Tempo limite da solicitação (por RPC) | 30_000 ms |
packages/gateway-client/src/client.ts (requestTimeoutMs) |
| Tempo limite de pré-autenticação/desafio de conexão | 15_000 ms |
packages/gateway-client/src/timeouts.ts (a variável de ambiente OPENCLAW_HANDSHAKE_TIMEOUT_MS pode aumentar o limite conjunto do servidor/cliente) |
| Backoff inicial de reconexão | 1_000 ms |
packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY) |
| Backoff máximo de reconexão | 30_000 ms |
packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY) |
| Limite de repetição rápida após fechamento por token do dispositivo | 250 ms |
packages/gateway-client/src/client.ts |
Período de tolerância para interrupção forçada antes de terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Tempo limite padrão de stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Intervalo padrão de tick (antes de hello-ok) |
30_000 ms |
packages/gateway-client/src/client.ts |
| Fechamento por tempo limite de tick | código 4000 quando o silêncio excede tickIntervalMs * 2 |
packages/gateway-client/src/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
O servidor anuncia os valores efetivos de policy.tickIntervalMs,
policy.maxPayload e policy.maxBufferedBytes em hello-ok; os clientes
devem respeitar esses valores em vez dos padrões anteriores ao handshake.
O cliente de referência permite que solicitações finitas controlem o próprio prazo configurado quando
cada solicitação pendente possui um. Uma solicitação expectFinal sem um
timeoutMs finito, qualquer solicitação com timeoutMs: null ou uma combinação de solicitações
finitas e ilimitadas mantém o watchdog de tick ativo. Se os eventos e
as respostas recebidos permanecerem silenciosos além do limite de tempo do tick, o cliente fechará o
socket com o código 4000, rejeitará todas as solicitações pendentes e se reconectará. Ele
não repetirá as solicitações rejeitadas após a reconexão.
Autenticação
- A autenticação do gateway por segredo compartilhado usa
connect.params.auth.tokenouconnect.params.auth.password, dependendo dogateway.auth.modeconfigurado ("none" | "token" | "password" | "trusted-proxy"). - Modos que contêm identidade, como o Tailscale Serve (
gateway.auth.allowTailscale: true) ougateway.auth.mode: "trusted-proxy"fora do loopback, atendem à verificação de autenticação da conexão por meio dos cabeçalhos da solicitação, em vez deconnect.params.auth.*. - O
gateway.auth.mode: "none"de ingresso privado ignora completamente a autenticação da conexão por segredo compartilhado; não exponha esse modo em um ingresso público/não confiável. - Após o pareamento, o gateway emite um token de dispositivo com escopo limitado
à função + aos escopos da conexão, retornado em
hello-ok.auth.deviceToken. Os clientes devem persistir esse token após qualquer conexão bem-sucedida. - Ao se reconectar com esse token de dispositivo armazenado, também se deve reutilizar o conjunto de escopos aprovado e armazenado para esse token. Isso preserva o acesso de leitura/sondagem/status já concedido e evita que as reconexões sejam silenciosamente reduzidas a um escopo implícito mais restrito, exclusivo para administradores.
- Montagem da autenticação de conexão no cliente (
selectConnectAuthempackages/gateway-client/src/client.ts):auth.passwordé independente e sempre é encaminhado quando definido.auth.tokené preenchido na seguinte ordem de prioridade: primeiro o token compartilhado explícito, depois umdeviceTokenexplícito e, em seguida, um token armazenado por dispositivo (indexado pordeviceId+role).auth.bootstrapTokené enviado somente quando nenhuma das opções anteriores resolveuauth.token. Um token compartilhado ou qualquer token de dispositivo resolvido o suprime.- A promoção automática de um token de dispositivo armazenado na única
nova tentativa de
AUTH_TOKEN_MISMATCHé restrita somente a endpoints confiáveis: loopback ouwss://com umtlsFingerprintfixado. Umwss://público sem fixação não se qualifica.
- A inicialização integrada por código de configuração retorna o
hello-ok.auth.deviceTokendo Node primário, além de um token de operador com limites definidos emhello-ok.auth.deviceTokens, para transferência móvel confiável. O token de operador incluioperator.talk.secretspara leituras da configuração nativa do Talk, mas exclui os escopos de alteração de pareamento eoperator.admin. - Enquanto uma inicialização por código de configuração fora da linha de base aguarda aprovação,
os detalhes de
PAIRING_REQUIREDincluemrecommendedNextStep: "wait_then_retry",retryable: trueepauseReconnect: false. Continue se reconectando com o mesmo token de inicialização até que a solicitação seja aprovada ou o token se torne inválido. - Persista
hello-ok.auth.deviceTokenssomente quando a conexão tiver usado autenticação de inicialização em um transporte confiável, comowss://ou pareamento por loopback/local. - Se um cliente fornecer um
deviceTokenexplícito ou umscopesexplícito, esse conjunto de escopos solicitado pelo chamador continuará sendo autoritativo; os escopos armazenados em cache só serão reutilizados quando o cliente estiver reutilizando o token armazenado por dispositivo. - Os tokens de dispositivo podem ser rotacionados/revogados por meio de
device.token.rotateedevice.token.revoke(requeroperator.pairing). Rotacionar ou revogar um Node ou outra função que não seja de operador também requeroperator.admin. device.token.rotateretorna metadados de rotação. Ele retorna o token de portador substituto somente para chamadas do mesmo dispositivo já autenticadas com esse token de dispositivo, para que clientes que usam apenas tokens possam persistir o substituto antes de se reconectarem. Rotações compartilhadas/de administrador não retornam o token de portador.- A emissão, a rotação e a revogação de tokens permanecem limitadas ao conjunto de funções aprovado registrado na entrada de pareamento desse dispositivo; a alteração de tokens não pode expandir nem ter como alvo uma função de dispositivo que nunca tenha sido concedida pela aprovação do pareamento.
- Em sessões de token de dispositivo pareado, o gerenciamento de dispositivos fica restrito ao próprio dispositivo,
a menos que o chamador também tenha
operator.admin: chamadores que não sejam administradores podem gerenciar somente o token de operador da própria entrada de dispositivo. O gerenciamento de tokens de Node e de outras funções que não sejam de operador é exclusivo para administradores, mesmo no próprio dispositivo do chamador. device.token.rotateedevice.token.revoketambém verificam o conjunto de escopos do token de operador de destino em relação aos escopos da sessão atual do chamador. Chamadores que não sejam administradores não podem rotacionar nem revogar um token de operador mais amplo do que aquele que já possuem.- As falhas de autenticação incluem
error.details.code, além de orientações de recuperação:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep: um deretry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration(packages/gateway-protocol/src/connect-error-details.ts).
- Comportamento do cliente para
AUTH_TOKEN_MISMATCH:- Clientes confiáveis podem realizar uma única nova tentativa limitada com um token armazenado em cache por dispositivo.
- Se essa nova tentativa falhar, interrompa os ciclos de reconexão automática e apresente orientações sobre a ação necessária do operador.
AUTH_SCOPE_MISMATCHsignifica que o token de dispositivo foi reconhecido, mas não abrange a função/os escopos solicitados. Não apresente isso como um token inválido; solicite que o operador refaça o pareamento ou aprove o contrato de escopo mais restrito/amplo.
Identidade e pareamento de dispositivos
- Os Nodes devem incluir uma identidade de dispositivo estável (
device.id) derivada da impressão digital de um par de chaves. - Os Gateways emitem tokens por dispositivo + função.
- As aprovações de pareamento são obrigatórias para novos IDs de dispositivo, a menos que a aprovação automática local esteja habilitada.
- A aprovação automática de pareamento é voltada para conexões locais diretas por loopback.
- O OpenClaw também tem um caminho restrito de autoconexão local ao backend/contêiner para fluxos auxiliares confiáveis com segredo compartilhado.
- As conexões da tailnet ou da LAN no mesmo host ainda são tratadas como remotas para fins de pareamento e exigem aprovação.
- Os clientes WS normalmente incluem a identidade
deviceduranteconnect(operador + Node). As únicas exceções de operador sem dispositivo são caminhos de confiança explícitos:gateway.controlUi.allowInsecureAuth=truepara compatibilidade com HTTP inseguro restrita ao localhost.- autenticação bem-sucedida da Control UI do operador por
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(último recurso, redução grave da segurança).- RPCs de backend
gateway-clientpor loopback direto no caminho auxiliar interno reservado.
- A omissão da identidade do dispositivo tem consequências para os escopos. Quando uma conexão
de operador sem dispositivo é permitida por um caminho de confiança explícito, o OpenClaw
ainda limpa os escopos autodeclarados, deixando um conjunto vazio, a menos que esse caminho tenha uma
exceção nomeada de preservação de escopos. Os métodos restritos por escopo falham, então, com
missing scope. gateway.controlUi.dangerouslyDisableDeviceAuth=trueé um caminho de preservação de escopos de último recurso da Control UI. Ele não concede escopos a clientes WebSocket arbitrários de backends personalizados ou com formato de CLI.- O caminho auxiliar de backend
gateway-clientreservado por loopback direto preserva escopos somente para RPCs internas do plano de controle local; IDs de backend personalizados não recebem essa exceção. - Todas as conexões devem assinar o nonce
connect.challengefornecido pelo servidor.
Diagnóstico da migração da autenticação de dispositivos
Para clientes legados que ainda usam o comportamento de assinatura anterior ao desafio, connect
retorna códigos de detalhes DEVICE_AUTH_* em error.details.code, com um
error.details.reason estável.
Falhas comuns de migração:
| Mensagem | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
O cliente omitiu device.nonce (ou enviou em branco). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
O cliente assinou com um nonce obsoleto/incorreto. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
A carga útil da assinatura não corresponde à carga útil v2. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
O carimbo de data/hora assinado está fora da defasagem permitida. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id não corresponde à impressão digital da chave pública. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
Falha no formato/na canonicalização da chave pública. |
Destino da migração:
- Sempre aguarde
connect.challenge. - Assine a carga útil v2 que inclui o nonce do servidor.
- Envie o mesmo nonce em
connect.params.device.nonce. - A carga útil de assinatura preferencial é
v3(buildDeviceAuthPayloadV3empackages/gateway-client/src/device-auth.ts), que vinculaplatformedeviceFamily, além dos campos de dispositivo/cliente/função/escopos/token/nonce. - As assinaturas
v2legadas continuam sendo aceitas para compatibilidade, mas a fixação de metadados de dispositivos pareados ainda controla a política de comandos na reconexão.
TLS e fixação
- Há suporte a TLS para conexões WS (configuração
gateway.tls). - Os clientes podem, opcionalmente, fixar a impressão digital do certificado do gateway por meio de
gateway.remote.tlsFingerprintou da CLI--tls-fingerprint.
Escopo
Este protocolo expõe toda a API do gateway: status, canais, modelos, chat,
agente, sessões, Nodes, aprovações e muito mais. A superfície exata é definida pelos
esquemas TypeBox reexportados de packages/gateway-protocol/src/schema.ts.