Gateway
Protocollo del Gateway
Il protocollo WS del Gateway è l'unico piano di controllo e trasporto dei nodi per OpenClaw. I client operatore e nodo (CLI, interfaccia web, app macOS, nodi iOS/Android, nodi headless) si connettono tramite WebSocket e dichiarano un ruolo e un ambito al momento dell'handshake.
Trasporto e framing
- WebSocket, frame di testo, payload JSON.
- Il primo frame deve essere una richiesta
connect. - I frame precedenti alla connessione sono limitati a 64 KiB (
MAX_PREAUTH_PAYLOAD_BYTES). Dopo l'handshake, vengono applicatihello-ok.policy.maxPayloadehello-ok.policy.maxBufferedBytes. Con la diagnostica abilitata, i frame in ingresso sovradimensionati e i buffer in uscita lenti emettono eventipayload.largeprima che il Gateway chiuda la connessione o scarti il frame. Questi eventi includonosurface, dimensioni in byte, limiti e un codice motivo sicuro, mai corpi dei messaggi, contenuti degli allegati, byte grezzi dei frame, token, cookie o segreti.
Formati dei frame:
- Richiesta:
{type:"req", id, method, params} - Risposta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
I metodi con effetti collaterali richiedono chiavi di idempotenza (vedere lo schema).
Handshake
Il Gateway invia una richiesta di verifica precedente alla connessione:
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Il client risponde con 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": "…" } }}Il Gateway risponde con 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 sono tutti richiesti da
HelloOkSchema (packages/gateway-protocol/src/schema/frames.ts). auth
riporta il ruolo e gli ambiti negoziati anche quando non viene emesso alcun token del dispositivo (formato
illustrato sopra). pluginSurfaceUrls è facoltativo e associa i nomi delle superfici dei Plugin (ad esempio
canvas) a URL ospitati con ambito; può scadere, quindi i nodi chiamano
node.pluginSurface.refresh con { "surface": "canvas" } per ottenere una nuova voce.
Il percorso deprecato canvasHostUrl / canvasCapability / node.canvas.capability.refresh
non è supportato; utilizzare le superfici dei Plugin.
Il campo facoltativo appliedConfigHash dello snapshot è la revisione risolta della configurazione sorgente
accettata dal runtime Gateway attivo. I client possono confrontarla con
config.get.configRevisionHash per determinare se una configurazione salvata più recente richieda ancora
un riavvio. config.get.hash rimane la revisione non elaborata del file radice utilizzata dalle
protezioni contro i conflitti di scrittura della configurazione.
Mentre il Gateway sta ancora completando l'avvio dei processi ausiliari, connect può restituire un
errore ripetibile UNAVAILABLE con details.reason: "startup-sidecars" e
retryAfterMs. Riprovare entro il budget temporale della connessione anziché considerarlo
un errore terminale dell'handshake.
Quando viene emesso un token del dispositivo, hello-ok.auth lo aggiunge:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}Il bootstrap integrato tramite codice QR/codice di configurazione è un percorso di passaggio ai dispositivi mobili. Una connessione di base riuscita mediante codice di configurazione restituisce un token del nodo principale e un token operatore con ambito limitato:
{ "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] }}Questo passaggio all'operatore è intenzionalmente limitato: è sufficiente per avviare il ciclo
dell'operatore mobile e la configurazione nativa, incluso operator.talk.secrets per le letture della
configurazione Talk, ma non include ambiti per modificare l'associazione né operator.admin. Un accesso
più ampio all'associazione/amministrazione richiede un flusso separato di associazione approvata o di token. Rendere persistente
hello-ok.auth.deviceTokens solo quando l'autenticazione bootstrap è stata eseguita tramite un trasporto
attendibile (wss:// o associazione loopback/locale).
I client backend attendibili nello stesso processo (client.id: "gateway-client",
client.mode: "backend") possono omettere device nelle connessioni loopback dirette quando
si autenticano con il token/la password condivisi del Gateway. Questo percorso è riservato
alle RPC interne del piano di controllo (ad esempio gli aggiornamenti delle sessioni dei sottoagenti) ed evita
che le baseline obsolete di associazione CLI/dispositivo blocchino il lavoro del backend locale. I client remoti,
con origine nel browser, nodo e quelli che usano esplicitamente token del dispositivo/identità del dispositivo continuano
a essere sottoposti ai normali controlli di associazione e aggiornamento degli ambiti.
Ruolo worker e protocollo chiuso
I worker cloud utilizzano un ingresso loopback dedicato tramite il tunnel SSH di proprietà del Gateway
con chiave host fissata. Accetta solo l'identità del worker e non inoltra mai
autenticazione generale, eventi dei nodi, RPC degli operatori o metodi dei Plugin. Un rigoroso connect
verifica una credenziale di breve durata, memorizzata sotto forma di hash e vincolata all'ambiente, all'hash
del bundle, all'epoca del proprietario, alla versione dell'insieme RPC, alla scadenza e a un'unica sessione nullable; inoltre
verifica separatamente la versione corrente e l'insieme di funzionalità. In caso di successo restituisce un
worker-hello-ok minimo; la negoziazione delle funzionalità è indipendente dalla versione generale del
protocollo. I frame rimangono al di sotto di 64 KiB, tranne un frame worker.inference.start
negoziato che può raggiungere 25 MiB. L'elenco consentito chiuso contiene worker.heartbeat,
worker.transcript.commit, worker.live-event, worker.inference.start e
worker.inference.cancel.
I commit delle trascrizioni utilizzano il fencing dell'epoca del proprietario, un'associazione della sessione di proprietà del Gateway, un compare-and-swap della foglia di base e la riproduzione durevole della sequenza; il Gateway genera gli ID delle voci e dei genitori della trascrizione tramite il normale writer di sessione. La proprietà e la scadenza vengono verificate nuovamente a ogni RPC.
Funzionalità dei client
I client operatore possono dichiarare funzionalità facoltative in connect.params.caps:
tool-events: accetta eventi strutturati del ciclo di vita degli strumenti.inline-widgets: può visualizzare i risultati degli strumenti dei widget inline ospitati.
Le funzionalità del client descrivono il client connesso, non l'autorizzazione. Gli strumenti degli agenti possono dichiarare le funzionalità richieste; il Gateway omette tali strumenti a meno che ogni requisito non sia presente in caps del client di origine. Le esecuzioni originate dai canali non hanno funzionalità del client Gateway, quindi gli strumenti vincolati alle funzionalità non sono disponibili anche quando la policy degli strumenti li consente esplicitamente.
Esempio di connessione di un nodo
{ "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": "…" } }}I nodi dichiarano le attestazioni delle funzionalità al momento della connessione:
caps: categorie di alto livello comecamera,canvas,screen,location,voice,talk.commands: elenco consentito dei comandi per l'invocazione.permissions: opzioni granulari (ad esempioscreen.record,camera.capture).
Il Gateway le considera attestazioni e applica elenchi consentiti lato server.
Ruoli e ambiti
Per il modello completo degli ambiti dell'operatore, i controlli al momento dell'approvazione e la semantica dei segreti condivisi, vedere Ambiti dell'operatore.
Ruoli:
operator: client del piano di controllo (CLI/interfaccia utente/automazione).node: host delle funzionalità (camera/schermo/canvas/system.run).worker: host di esecuzione cloud sul protocollo worker dedicato e chiuso.
Ambiti dell'operatore (src/gateway/operator-scopes.ts), l'insieme chiuso completo:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config con includeSecrets: true richiede operator.talk.secrets (oppure
operator.admin). Quando sono inclusi i segreti, leggere la credenziale attiva del provider Talk
da talk.resolved.config.apiKey; talk.providers.<id>.apiKey
mantiene il formato della sorgente e può essere un oggetto SecretRef oppure una stringa oscurata.
I metodi RPC del Gateway registrati dai Plugin possono richiedere un proprio ambito operatore,
ma questi prefissi riservati del core vengono sempre risolti in operator.admin
(src/shared/gateway-method-policy.ts): config.*, exec.approvals.*,
wizard.*, update.*.
L'ambito del metodo è solo il primo controllo. Alcuni comandi slash raggiunti tramite
chat.send applicano controlli più rigorosi a livello di comando: le scritture persistenti /config set e
/config unset richiedono operator.admin anche per i client del Gateway che
dispongono già di un ambito operatore inferiore.
node.pair.approve prevede un ulteriore controllo dell'ambito al momento dell'approvazione, oltre all'ambito
di base del metodo (operator.pairing), in funzione del valore commands dichiarato
dalla richiesta in sospeso (src/infra/node-pairing-authz.ts):
| Comandi dichiarati | Ambiti richiesti |
|---|---|
| nessuno | operator.pairing |
| comandi ordinari | operator.pairing + operator.write |
include system.run, system.run.prepare, system.which, browser.proxy, fs.listDir oppure system.execApprovals.get/set |
operator.pairing + operator.admin |
Funzionalità/comandi/autorizzazioni (nodo)
I nodi dichiarano le attestazioni delle funzionalità al momento della connessione:
caps: categorie di funzionalità di alto livello comecamera,canvas,screen,location,voiceetalk.commands: elenco consentito dei comandi per l'invocazione.permissions: opzioni granulari (ad esempioscreen.record,camera.capture).
Il Gateway tratta questi elementi come dichiarazioni e applica allowlist lato server.
I nodi connessi possono pubblicare descrittori facoltativi, visibili all'agente, di Plugin o strumenti MCP
con node.pluginTools.update dopo una connessione o
riconnessione riuscita. Gli host dei nodi headless vengono riavviati per applicare le modifiche
dichiarative all'inventario MCP. Questo metodo di aggiornamento è l'unico percorso di pubblicazione; i descrittori degli strumenti dei Plugin non sono accettati nei
parametri connect. Ogni descrittore deve usare un name dello strumento sicuro per il provider e indicare
un command presente nell'allowlist dei comandi corrente del nodo. Il Gateway considera attendibili i metadati dei descrittori
provenienti dal nodo associato, filtra i descrittori esterni alla superficie dei comandi
approvata, li rimuove quando il nodo si disconnette e rifiuta i tentativi dell'operatore
di modificare il catalogo di un altro nodo. Impostare gateway.nodes.pluginTools.enabled: false
per ignorare i descrittori pubblicati dai nodi.
Gli host dei nodi connessi pubblicano il proprio catalogo completo di sostituzione delle skill con
node.skills.update. Questo metodo del ruolo nodo è l'unico percorso di pubblicazione
delle skill del nodo; le skill non sono accettate nei parametri connect. Ogni descrittore contiene
un nome sicuro, una descrizione e contenuto SKILL.md limitato. Il Gateway analizza tale
contenuto con il normale caricatore delle skill, lo include nelle istantanee delle skill dell'agente
mentre il nodo è connesso e lo rimuove alla disconnessione. Impostare
gateway.nodes.skills.enabled: false per ignorare le skill pubblicate dai nodi.
Presenza
system-presencerestituisce voci indicizzate per identità del dispositivo, inclusideviceId,rolesescopes, affinché le UI possano mostrare una riga per dispositivo anche quando si connette sia come operatore sia come nodo.node.listincludelastSeenAtMselastSeenReasonfacoltativi. I nodi connessi segnalano l'ora della connessione corrente con il motivoconnect; i nodi associati possono inoltre segnalare una presenza persistente in background tramite un evento attendibile del nodo.
I nodi macOS nativi possono inoltre inviare eventi node.presence.activity autenticati
con un tempo di inattività dell'input limitato. Il Gateway ricava i timestamp dell'attività usando il
proprio orologio, espone il Mac connesso più recente tramite node.list e
node.describe e trasmette gli aggiornamenti node.presence ai client con ambito di lettura.
Consultare Presenza del computer attivo per il comportamento relativo a selezione, privacy, contesto del modello
e instradamento delle notifiche.
Evento di attività in background del nodo
I nodi chiamano node.event con event: "node.presence.alive" per registrare che un
nodo associato era attivo durante una riattivazione in background, senza contrassegnarlo come connesso:
{ "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 è un'enumerazione chiusa: background, silent_push, bg_app_refresh,
significant_location, manual, connect. I valori sconosciuti vengono normalizzati in
background (src/shared/node-presence.ts). L'evento viene reso persistente solo per
sessioni autenticate di dispositivi nodo; le sessioni senza dispositivo o non associate restituiscono
handled: false.
I Gateway che completano correttamente l'operazione restituiscono un risultato strutturato:
{ "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted"}I Gateway meno recenti possono restituire solo { "ok": true } per node.event; considerarlo
un RPC confermato, non una persistenza durevole della presenza.
Definizione dell'ambito degli eventi broadcast
Gli eventi broadcast inviati dal server sono vincolati all'ambito, affinché le sessioni
limitate all'associazione o riservate ai nodi non ricevano passivamente il contenuto delle sessioni
(src/gateway/server-broadcast.ts):
- I frame di chat, agente e risultati degli strumenti (eventi
agenttrasmessi in streaming, eventi dei risultati degli strumenti) richiedono almenooperator.read. Le sessioni che ne sono prive ignorano completamente questi frame. - I broadcast
plugin.*definiti dai Plugin sono limitati per impostazione predefinita aoperator.writeooperator.admin; le voci esplicite comeplugin.approval.requested/plugin.approval.resolvedusano inveceoperator.approvals. - Gli eventi di stato/trasporto (
heartbeat,presence,tick, ciclo di vita di connessione/disconnessione) rimangono senza restrizioni, affinché l'integrità del trasporto sia osservabile da ogni sessione autenticata. - Le famiglie sconosciute di eventi broadcast sono vincolate all'ambito per impostazione predefinita (chiusura in caso di errore), salvo che un gestore registrato non le renda esplicitamente meno restrittive.
Ogni connessione client mantiene il proprio numero di sequenza per client, quindi i broadcast rimangono ordinati in modo monotono su quel socket anche quando client diversi vedono sottoinsiemi differenti del flusso di eventi filtrati per ambito.
Famiglie di metodi RPC
hello-ok.features.methods è un elenco di rilevamento prudenziale costruito da
src/gateway/server-methods-list.ts più le esportazioni dei metodi dei Plugin/canali
caricati: non è un dump generato di ogni metodo e alcuni metodi (ad
esempio push.test, web.login.start, web.login.wait, sessions.usage)
sono intenzionalmente esclusi dal rilevamento, sebbene siano metodi reali e
richiamabili. Va considerato come rilevamento delle funzionalità, non come enumerazione completa di
src/gateway/server-methods/*.ts.
Sistema e identità
healthrestituisce l'istantanea dello stato del Gateway memorizzata nella cache o appena verificata.diagnostics.stabilityrestituisce il recente registro diagnostico limitato della stabilità: nomi degli eventi, conteggi, dimensioni in byte, letture della memoria, stato di code/sessioni, nomi di canali/Plugin e ID delle sessioni. Non include testo delle chat, corpi dei Webhook, output degli strumenti, corpi non elaborati di richieste/risposte, token, cookie o segreti. Richiedeoperator.read.statusrestituisce il riepilogo del Gateway in stile/status; i campi sensibili sono disponibili solo per i client operatore con ambito amministrativo.gateway.identity.getrestituisce l'identità del dispositivo Gateway usata dai flussi di inoltro e associazione.system-presencerestituisce l'istantanea della presenza corrente per i dispositivi operatore/nodo connessi.system-eventaggiunge un evento di sistema e può aggiornare/trasmettere il contesto della presenza.last-heartbeatrestituisce l'ultimo evento Heartbeat reso persistente.set-heartbeatsattiva o disattiva l'elaborazione degli Heartbeat sul Gateway.gateway.suspend.preparecrea una breve concessione di sospensione cooperativa solo quando il lavoro del Gateway monitorato è inattivo.gateway.suspend.statusverifica tale concessione egateway.suspend.resumela rilascia dopo la riattivazione o l'interruzione di un'operazione dell'host.
Modelli e utilizzo
models.listrestituisce il catalogo dei modelli consentiti in fase di runtime. Consultare le viste "models.list" di seguito.usage.statusrestituisce riepiloghi delle finestre di utilizzo e della quota rimanente dei provider.usage.costrestituisce riepiloghi aggregati dei costi di utilizzo per un intervallo di date. PassareagentIdper un agente oppureagentScope: "all"per aggregare gli agenti configurati.doctor.memory.statusrestituisce lo stato di preparazione della memoria vettoriale / degli embedding memorizzati nella cache per lo spazio di lavoro dell'agente predefinito attivo. Passare{ "probe": true }o{ "deep": true }solo per un ping esplicito in tempo reale del provider di embedding. Passare{ "agentId": "agent-id" }per limitare le statistiche dell'archivio Dreaming allo spazio di lavoro di un agente; omettendolo, vengono aggregati gli spazi di lavoro Dreaming configurati.doctor.memory.dreamDiary,doctor.memory.backfillDreamDiary,doctor.memory.resetDreamDiary,doctor.memory.resetGroundedShortTerm,doctor.memory.repairDreamingArtifactsedoctor.memory.dedupeDreamDiaryaccettano{ "agentId": "agent-id" }facoltativo; se omesso, operano sullo spazio di lavoro dell'agente predefinito configurato.doctor.memory.remHarnessrestituisce un'anteprima limitata e di sola lettura dell'harness REM per i client remoti del piano di controllo, inclusi percorsi degli spazi di lavoro, frammenti di memoria, Markdown renderizzato e fondato e candidati alla promozione approfondita. Richiedeoperator.read.sessions.usagerestituisce riepiloghi dell'utilizzo per sessione. PassareagentIdper un agente oppureagentScope: "all"per elencare insieme gli agenti configurati. Entrambi i metodi di utilizzo accettanomode: "specific"con untimeZoneIANA per limiti e intervalli dei giorni di calendario che tengono conto dell'ora legale.utcOffsetrimane supportato per i client meno recenti e come fallback quando il runtime del Gateway non riconosce il fuso orario richiesto.sessions.usage.timeseriesrestituisce l'utilizzo in serie temporale per una sessione.sessions.usage.logsrestituisce le voci del registro di utilizzo per una sessione.
Canali e strumenti di accesso
channels.statusrestituisce i riepiloghi dello stato dei canali/Plugin integrati e inclusi nel bundle.channels.logoutdisconnette un canale/account specifico, se il canale lo supporta.web.login.startavvia un flusso di accesso tramite QR/Web per il provider corrente del canale Web compatibile con QR.web.login.waitattende il completamento di tale flusso e, in caso di esito positivo, avvia il canale.push.testinvia una notifica push APNs di prova a un nodo iOS registrato.voicewake.getrestituisce le parole di attivazione memorizzate.voicewake.setaggiorna le parole di attivazione e trasmette la modifica.
Gestione dei Plugin
plugins.list(operator.read) restituisce l'inventario dei Plugin installati, oltre a una selezione locale curata di opzioni ufficiali, la diagnostica e l'indicazione se la modalità di installazione corrente consente modifiche.plugins.search(operator.read) cerca famiglie installabili di Plugin di codice e Plugin bundle di ClawHub. Passare unquerynon vuoto e unlimitfacoltativo da 1 a 100.plugins.install(operator.admin) installa una voce del catalogo ufficiale con{ source: "official", pluginId }oppure un pacchetto ClawHub con{ source: "clawhub", packageName, version?, acknowledgeClawHubRisk? }. Le installazioni ClawHub mantengono i controlli del Gateway relativi ad attendibilità, integrità e criteri di installazione. Le installazioni riuscite richiedono il riavvio del Gateway.plugins.setEnabled(operator.admin) modifica i criteri di abilitazione di un Plugin installato tramite{ pluginId, enabled }. La risposta include la voce di catalogo aggiornata, i metadati del riavvio e gli eventuali avvisi relativi alla selezione degli slot.plugins.uninstall(operator.admin) rimuove un Plugin installato esternamente tramite{ pluginId }: riferimenti di configurazione, record di installazione e file gestiti. I Plugin inclusi nel bundle non possono essere disinstallati, ma solo disabilitati. La risposta elenca le azioni di rimozione e richiede sempre il riavvio del Gateway.
Messaggistica e registri
sendè l'RPC di consegna diretta in uscita per invii destinati a canali/account/thread al di fuori dell'esecutore della chat.logs.tailrestituisce la coda del registro su file configurato del Gateway, con controlli su cursore/limite e numero massimo di byte.
Terminale dell'operatore
terminal.openavvia una PTY host per unagentIdesplicito o per l'agente predefinito e restituisce l'agente risolto, la directory di lavoro, la shell e lo stato di confinamento.terminal.input,terminal.resizeeterminal.closeoperano solo sulle sessioni appartenenti alla connessione chiamante.terminal.uploadaccetta un file in base64 fino a 16 MiB, lo deposita in una directory temporanea privata con durata di 24 ore sull'host del Gateway della sessione o del nodo associato e restituisce il percorso assoluto. Il chiamante deve comunque incollare o utilizzare in altro modo tale percorso; l'RPC non scrive mai input nel terminale né esegue un comando.- Gli eventi
terminal.dataeterminal.exitvengono trasmessi solo alla connessione proprietaria della sessione. - Le sessioni la cui connessione si interrompe vengono disconnesse, non terminate: rimangono ricollegabili per
gateway.terminal.detachedSessionTimeoutSeconds(valore predefinito 300;0ripristina la terminazione alla disconnessione), mentre l'output recente si accumula in un buffer limitato lato server. terminal.listrestituisce le sessioni collegabili;terminal.attachriassegna una sessione attiva o disconnessa alla connessione chiamante e restituisce il buffer di riproduzione (subentro in stile tmux: un precedente proprietario attivo riceveterminal.exitcon motivodetached);terminal.textlegge il buffer come testo normale senza collegarsi.- Ogni metodo del terminale richiede
operator.admin;gateway.terminal.enableddeve essere esplicitamente impostato su true. Gli agenti completamente isolati vengono rifiutati e una modifica dei criteri dell'agente chiude le PTY esistenti e in corso, incluse quelle disconnesse.
Conversazione e TTS
talk.catalogrestituisce il catalogo di sola lettura dei provider di conversazione per sintesi vocale, trascrizione in streaming e voce in tempo reale: ID canonici dei provider, alias del registro, etichette, stato di configurazione, un risultato facoltativoreadya livello di gruppo, ID esposti di modelli e voci, modalità canoniche, trasporti, strategie del motore e indicatori delle funzionalità e dell'audio in tempo reale, senza restituire i segreti dei provider né modificare la configurazione globale. I Gateway attuali impostanoreadydopo aver applicato la selezione del provider in fase di esecuzione; sui Gateway meno recenti, la sua assenza va considerata come non verificata.talk.configrestituisce il payload effettivo della configurazione di conversazione;includeSecretsrichiedeoperator.talk.secrets(ooperator.admin).talk.session.createcrea una sessione di conversazione gestita dal Gateway perrealtime/gateway-relay,transcription/gateway-relayostt-tts/managed-room. Perstt-tts/managed-room, i chiamantioperator.writeche passanosessionKeydevono passare anchespawnedByper la visibilità con ambito della chiave di sessione; la creazione disessionKeysenza ambito ebrain: "direct-tools"richiedonooperator.admin.talk.session.joinconvalida un token di sessione di una stanza gestita, emettesession.readyosession.replacedsecondo necessità e restituisce i metadati della stanza e della sessione insieme agli eventi di conversazione recenti, senza mai restituire il token in testo normale né il relativo hash.talk.session.appendAudioaggiunge audio di ingresso PCM in base64 alle sessioni di inoltro in tempo reale e di trascrizione gestite dal Gateway.talk.session.startTurn,talk.session.endTurnetalk.session.cancelTurngestiscono il ciclo di vita dei turni delle stanze gestite, rifiutando i turni obsoleti prima dell'azzeramento dello stato.talk.session.cancelOutputinterrompe l'output audio dell'assistente, principalmente per l'interruzione tramite voce regolata da VAD nelle sessioni di inoltro del Gateway.talk.session.submitToolResultcompleta una chiamata a uno strumento del provider emessa da una sessione di inoltro in tempo reale gestita dal Gateway. La richiesta attende qualsiasi segnale di completamento asincrono esposto dal bridge del provider; gli invii non riusciti mantengono attiva l'esecuzione collegata e non emettono un evento di risultato dello strumento riuscito. Passareoptions: { willContinue: true }per l'output intermedio dello strumento oppureoptions: { suppressResponse: true }quando il bridge del provider dichiara il supporto alla soppressione e il risultato non deve avviare un'altra risposta.talk.session.steerinvia il controllo vocale dell'esecuzione attiva a una sessione di conversazione basata su agente e gestita dal Gateway:{ sessionId, text, mode? }, dovemodeèstatus,steer,cancelofollowup; se la modalità viene omessa, viene classificata in base al testo pronunciato.talk.session.closechiude una sessione di inoltro, trascrizione o stanza gestita appartenente al Gateway ed emette gli eventi terminali di conversazione.talk.modeimposta e trasmette lo stato corrente della modalità di conversazione ai client WebChat/Control UI.talk.client.createcrea una sessione del provider in tempo reale appartenente al client tramitewebrtcoprovider-websocket, mentre il Gateway gestisce configurazione, credenziali, istruzioni e criteri degli strumenti.talk.client.toolCallconsente ai trasporti in tempo reale appartenenti al client di inoltrare le chiamate agli strumenti del provider ai criteri del Gateway. Il primo strumento supportato èopenclaw_agent_consult; i client ricevono un ID di esecuzione e attendono i normali eventi del ciclo di vita della chat prima di inviare il risultato dello strumento specifico del provider.talk.client.steerinvia il controllo vocale dell'esecuzione attiva per i trasporti in tempo reale appartenenti al client. Il Gateway risolve l'esecuzione incorporata attiva dasessionKeye restituisce un risultato strutturato di accettazione o rifiuto invece di ignorare silenziosamente il controllo.talk.eventè l'unico canale degli eventi di conversazione per gli adattatori in tempo reale, trascrizione, STT/TTS, stanze gestite, telefonia e riunioni.talk.speaksintetizza la voce tramite il provider vocale di conversazione attivo.tts.statusrestituisce lo stato di abilitazione del TTS, il provider attivo, i provider di ripiego e lo stato di configurazione dei provider.tts.providersrestituisce l'inventario visibile dei provider TTS.tts.enableetts.disableattivano o disattivano lo stato delle preferenze TTS.tts.setProvideraggiorna il provider TTS preferito.tts.convertesegue una conversione una tantum da testo a voce.tts.speak(operator.write) elabora untextnon vuoto tramite la catena configurata dei provider TTS generali e restituisce un intero clip inline comeaudioBase64, oltre aprovidere ai metadati facoltativioutputFormat,mimeTypeefileExtension. A differenza ditts.convert, non restituisce un percorso locale al Gateway; a differenza ditalk.speak, non richiede un provider di conversazione. Il testo oltremessages.tts.maxTextLengthrestituisceINVALID_REQUEST; gli errori di sintesi restituisconoUNAVAILABLE.
Segreti, configurazione, aggiornamento e procedura guidata
secrets.reloadrisolve nuovamente i SecretRef attivi e sostituisce lo stato dei segreti in fase di esecuzione solo in caso di successo completo.secrets.resolverisolve le assegnazioni dei segreti delle destinazioni dei comandi per uno specifico insieme di comandi e destinazioni.config.getrestituisce l'istantanea corrente della configurazione su disco, ilhashgrezzo del file radice, ilconfigRevisionHashrisolto e ilappliedConfigHashfacoltativo per la revisione risolta accettata dal runtime del Gateway attivo.config.setscrive un payload di configurazione convalidato.config.patchunisce un aggiornamento parziale della configurazione. La sostituzione distruttiva di un array richiede il percorso interessato inreplacePaths; gli array annidati nelle voci di un array usano percorsi[], comeagents.list[].skills.config.applyconvalida e sostituisce l'intero payload di configurazione.config.schemarestituisce il payload dello schema di configurazione attivo utilizzato da Control UI e dagli strumenti CLI: schema,uiHints, versione, metadati di generazione e, quando caricabili, metadati degli schemi dei Plugin e dei canali. Include i metadatititle/descriptionprovenienti dalle stesse etichette e dallo stesso testo della guida dell'interfaccia utente, incluse le diramazioni di composizione per oggetti annidati, caratteri jolly, elementi di array eanyOf/oneOf/allOfquando esiste documentazione corrispondente per i campi.config.schema.lookuprestituisce un payload di ricerca con ambito limitato a un percorso per un singolo percorso di configurazione: percorso normalizzato, nodo dello schema superficiale, suggerimento corrispondente ehintPath,reloadKindfacoltativo e riepiloghi dei figli immediati per l'esplorazione dettagliata tramite interfaccia utente/CLI.reloadKindè uno trarestart,hotonone(src/config/schema.ts) e rispecchia il pianificatore di ricaricamento della configurazione del Gateway per il percorso richiesto. I nodi dello schema di ricerca mantengono la documentazione rivolta all'utente e i comuni campi di convalida (title,description,type,enum,const,format,pattern, limiti numerici, di stringa, array e oggetti,additionalProperties,deprecated,readOnly,writeOnly). I riepiloghi dei figli espongonokey,pathnormalizzato,type,required,hasChildren,reloadKindfacoltativo, oltre ai corrispondentihint/hintPath.update.runesegue il flusso di aggiornamento del Gateway e pianifica un riavvio solo se l'aggiornamento riesce; i chiamanti con una sessione possono includerecontinuationMessageaffinché, all'avvio, venga ripreso un turno successivo dell'agente tramite la coda di continuazione del riavvio. Gli aggiornamenti del gestore dei pacchetti e gli aggiornamenti supervisionati di un checkout Git dal piano di controllo utilizzano un passaggio di consegne a un servizio gestito separato, anziché sostituire l'albero dei pacchetti o modificare il checkout o l'output di compilazione all'interno del Gateway attivo. Un passaggio di consegne avviato restituisceok: trueconresult.reason: "managed-service-handoff-started"ehandoff.status: "started"; i passaggi di consegne non disponibili o non riusciti restituisconook: falseconmanaged-service-handoff-unavailableomanaged-service-handoff-failed, oltre ahandoff.commandquando è necessario un aggiornamento manuale dalla shell. Non disponibile significa che OpenClaw non dispone di un confine di supervisione sicuro o di un'identità di servizio persistente, ad esempioOPENCLAW_SYSTEMD_UNITper systemd. Durante un passaggio di consegne avviato, la sentinella di riavvio può segnalare brevementestats.reason: "restart-health-pending"; la continuazione viene ritardata finché la CLI non verifica il Gateway riavviato e scrive la sentinella finaleok.update.statusaggiorna e restituisce la sentinella più recente del riavvio per aggiornamento, inclusa la versione in esecuzione dopo il riavvio, quando disponibile.wizard.start,wizard.next,wizard.statusewizard.cancelespongono la procedura guidata di onboarding tramite RPC WS.
Helper per agent e workspace
agents.listrestituisce le voci degli agent configurati, inclusi il modello effettivo e i metadati di runtime.agents.create,agents.updateeagents.deletegestiscono i record degli agent e il collegamento dei workspace.agents.files.list,agents.files.geteagents.files.setgestiscono i file del workspace di bootstrap esposti a un agent.audit.activity.listrestituisce il registro delle attività con versione e contenente solo metadati;audit.listrimane l'RPC di esecuzione/strumento compatibile in modo sicuro.agents.workspace.listeagents.workspace.get(operator.read) consentono ai client nel dominio dell'operatore attendibile descritto in Ambiti dell'operatore di esplorare in sola lettura e con paginazione la directory del workspace di un agent. Le richieste accettano solo percorsi relativi al workspace; le letture restano confinate alla radice del workspace risolta nel percorso reale (i tentativi di evasione tramite collegamenti simbolici e hard link vengono rifiutati), sono soggette a un limite di dimensione e sono limitate al testo UTF-8 e ai tipi di immagine comuni (base64). Le risposte non espongono il percorso del workspace sull'host. In questo namespace non sono presenti operazioni di scrittura.tasks.list,tasks.getetasks.cancelespongono il registro delle attività del Gateway ai client SDK e operatore. Consultare RPC del registro delle attività di seguito.artifacts.list,artifacts.geteartifacts.downloadespongono riepiloghi e download degli artefatti derivati dalla trascrizione per un ambito esplicitosessionKey,runIdotaskId. Le query di esecuzione e attività risolvono lato server la sessione proprietaria e restituiscono solo i contenuti multimediali della trascrizione con provenienza corrispondente; le origini URL non sicure o locali restituiscono download non supportati anziché essere recuperate lato server.environments.listeenvironments.statuspreservano il rilevamento dell'ambiente locale del Gateway e del Node. I worker cloud configurati e i record durevoli lasciati da profili precedenti aggiungono metadatiworkerconproviderId,leaseIdfacoltativo,state,ageMs,idleMsfacoltativo eattachedSessionIds. Gli stati del ciclo di vita dei worker sonorequested,provisioning,bootstrapping,ready,attached,idle,draining,destroying,destroyed,failedeorphaned.environments.create({ profileId, idempotencyKey }) effettua il provisioning di un worker da un profilo configurato del provider del plugin; i nuovi tentativi con la stessa chiave riutilizzano l'operazione durevole.environments.destroy({ environmentId }) richiede la dismissione idempotente di un ambiente worker durevole. Entrambe richiedonooperator.admin, sono scritture del piano di controllo e restituiscono la stessa struttura di riepilogo dell'ambiente utilizzata dalle risposte di stato.agent.identity.getrestituisce l'identità effettiva dell'assistente per un agent o una sessione.agent.waitattende il completamento di un'esecuzione e restituisce l'istantanea terminale, quando disponibile.
Controllo delle sessioni
sessions.listrestituisce l'indice corrente delle sessioni, inclusi i metadatiagentRuntimeper ogni riga quando è configurato un backend di runtime per agent. Quando è abilitato il posizionamento sui worker cloud o esiste uno stato di ripristino durevole, le righe delle sessioni includono anche uno stato chiusoplacement(local,requested,provisioning,syncing,starting,active,draining,reconciling,reclaimedofailed) oltre a campi specifici dello stato relativi ad ambiente, epoca del proprietario, workspace, bundle, cursore ACK o ripristino.sessions.subscribeesessions.unsubscribeattivano o disattivano le sottoscrizioni agli eventi di modifica delle sessioni per il client WS corrente.sessions.messages.subscribeesessions.messages.unsubscribeattivano o disattivano le sottoscrizioni agli eventi di trascrizione/messaggio per una sessione. PassareincludeApprovals: trueper ricevere anche eventi del ciclo di vitasession.approvalsanificati relativi alle approvazioni il cui pubblico persistente include esattamente tale sessione e il cui vincolo del revisore autorizza il client sottoscritto. La risposta alla sottoscrizione include quindi un elemento in sospesoapprovalReplaycon dimensione limitata; è autorevole quandotruncatedè false. L'adesione si applica alla singola chiamata di sottoscrizione e non è persistente: una nuova sottoscrizione alla stessa sessione senzaincludeApprovals: truerimuove una sottoscrizione alle approvazioni esistente. Oltre alla normale autorità di lettura della sessione, questa adesione richiedeoperator.admin, oppureoperator.approvalssu un dispositivo associato.sessions.previewrestituisce anteprime limitate delle trascrizioni per chiavi di sessione specifiche.sessions.describerestituisce una riga di sessione del Gateway per una chiave di sessione esatta.sessions.resolverisolve o rende canonica una destinazione di sessione.sessions.createcrea una nuova voce di sessione. I valori facoltativimodelethinkingLevelrendono persistenti in modo atomico le impostazioni iniziali sostitutive del modello e del ragionamento.worktree: trueeffettua il provisioning di un worktree gestito; i valori facoltativiworktreeBaseRef/worktreeNameselezionano il riferimento di base e il nome del branch, mentreexecNode(operator.admin) associa l'esecuzione della sessione a un host Node. Il worktree creato viene riportato nel risultato e reso persistente nella riga della sessione (worktree: { id, branch, repoRoot }). Quando la voce viene creata ma il relativochat.sendiniziale annidato viene rifiutato, il risultato positivo includerunStarted: falseerunError; i client possono conservare il prompt e riprovare usando la chiave di sessione restituita.sessions.dispatch(operator.admin) sposta una sessione OpenClaw locale esistente, dotata di un worktree gestito di proprietà della sessione, in un profilo worker cloud configurato. Passare{ key, profileId, agentId? }. Il metodo non è disponibile quando non è configurato alcun profilo worker, interrompe l'ammissione locale dei turni prima di attendere il completamento del lavoro attivo e restituisce il risultato solo dopo che il posizionamento ha raggiunto la proprietà del workeractive. L'invio è unidirezionale; il trasferimento di ritorno dal worker all'ambiente locale non fa parte di questa RPC.sessions.groups.list,sessions.groups.put,sessions.groups.renameesessions.groups.deletegestiscono il catalogo personalizzato dei gruppi di sessioni di proprietà del Gateway (nomi + ordine di visualizzazione). L'appartenenza rimane nel campocategorydi ciascuna sessione; la ridenominazione e l'eliminazione aggiornano lato server le sessioni appartenenti al gruppo.sessions.sendinvia un messaggio a una sessione esistente.sessions.steerè la variante che interrompe e reindirizza una sessione attiva.sessions.abortinterrompe il lavoro attivo di una sessione. PassarekeyconrunIdfacoltativo, oppure soltantorunIdper le esecuzioni attive che il Gateway può ricondurre a una sessione.sessions.patchaggiorna i metadati e le impostazioni sostitutive della sessione e restituisce il modello canonico risolto insieme al valore effettivo diagentRuntime.sessions.reset,sessions.deleteesessions.compacteseguono la manutenzione delle sessioni.sessions.getrestituisce l'intera riga di sessione archiviata.- L'esecuzione della chat continua a usare
chat.history,chat.send,chat.abortechat.inject.chat.historyviene normalizzato per la visualizzazione nei client UI: i tag delle direttive inline vengono rimossi dal testo visibile; vengono rimossi i payload XML delle chiamate agli strumenti in testo normale (<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e i blocchi di chiamata agli strumenti troncati) e i token di controllo del modello ASCII/a larghezza intera fuoriusciti; le righe dell'assistente contenenti esclusivamente token silenziosi (NO_REPLY/no_replyesatti) vengono omesse e le righe di dimensioni eccessive possono essere sostituite da segnaposto. chat.message.getè il lettore aggiuntivo e limitato dei messaggi completi per una singola voce visibile della trascrizione. PassaresessionKey,agentIdfacoltativo quando la selezione della sessione è limitata all'agent e unmessageIddella trascrizione precedentemente esposto tramitechat.history; il Gateway restituisce la stessa proiezione normalizzata per la visualizzazione senza il limite di troncamento della cronologia leggera, purché la voce archiviata sia ancora disponibile e non abbia dimensioni eccessive.chat.toolTitlesrestituisce brevi titoli descrittivi per le chiamate agli strumenti visualizzate nella Control UI (in batch, massimo 24 elementi con input limitati). La funzionalità richiede l'adesione tramitegateway.controlUi.toolTitles(disattivata per impostazione predefinita); i Gateway in cui è disabilitata rispondono a{ titles: {}, disabled: true }senza effettuare chiamate al modello, in modo che i client smettano di inviare richieste. Quando è abilitata, i titoli utilizzano l'instradamento standard del modello di utilità: unutilityModelconfigurato esplicitamente (una decisione dell'operatore che, come per tutte le attività di utilità, può inviare contenuti limitati dell'attività al provider selezionato), altrimenti il modello piccolo predefinito dichiarato dal provider della sessione, affinché non venga introdotta implicitamente una nuova destinazione di uscita; unutilityModelvuoto li disabilita completamente. I titoli non ricorrono mai al modello principale. I risultati vengono memorizzati nella cache del database di stato per agent, indicizzati per nome dello strumento + input, quindi le visualizzazioni ripetute non addebitano mai nuovamente le stesse chiamate.chat.sendaccettafastMode: "auto"per un singolo turno per utilizzare la modalità rapida nelle chiamate al modello avviate prima del limite automatico, quindi avviare senza modalità rapida i tentativi successivi, i fallback, i risultati degli strumenti o le chiamate di continuazione. Il limite predefinito è 60 secondi (DEFAULT_FAST_MODE_AUTO_ON_SECONDS) e può essere configurato per ogni modello conagents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. Un chiamantechat.sendpuò passarefastAutoOnSecondsper un singolo turno per sostituire il limite per tale richiesta. PassarequeueMode(steer,followup,collectointerrupt) per sostituire la modalità della coda archiviata soltanto per questa richiesta; le azioni di reindirizzamento esplicite della Control UI utilizzanoqueueMode: "steer".
Associazione dei dispositivi e token dei dispositivi
device.pair.listrestituisce i dispositivi associati in sospeso e approvati.device.pair.setupCodecrea un codice di configurazione per dispositivi mobili e, per impostazione predefinita, un URL dati di un codice QR PNG. Richiedeoperator.admined è intenzionalmente omesso dal rilevamento pubblicizzato. Il risultato includesetupCode,qrDataUrlfacoltativo,gatewayUrl, l'etichetta non segretaautheurlSource.device.pair.approve,device.pair.rejectedevice.pair.removegestiscono i record di associazione dei dispositivi.device.pair.renameassegna un'etichetta dell'operatore ({ deviceId, label }) che ha la precedenza sul nome visualizzato comunicato dal client e viene mantenuta dopo la riparazione o la nuova approvazione del dispositivo.device.token.rotateruota il token di un dispositivo associato entro i limiti del ruolo approvato e dell'ambito del chiamante.device.token.revokerevoca il token di un dispositivo associato entro i limiti del ruolo approvato e dell'ambito del chiamante.
Il codice di configurazione incorpora una credenziale di bootstrap di breve durata. I client non devono registrarla né renderla persistente oltre il flusso di associazione.
Associazione dei Node, invocazione e lavoro in sospeso
node.pair.list,node.pair.approve,node.pair.rejectenode.pair.removegestiscono le approvazioni delle funzionalità dei Node.node.pair.requestenode.pair.verifysono stati rimossi nella versione 2026.7 insieme all'archivio autonomo per l'associazione dei Node; le richieste in sospeso vengono create dal Gateway durante le connessioni dei Node.node.listenode.describerestituiscono lo stato dei Node noti/connessi.node.renameaggiorna l'etichetta di un Node associato.node.invokeinoltra un comando a un Node connesso.node.invoke.resultrestituisce il risultato di una richiesta di invocazione.mcp.tools.call.v1è il comando dell'host Node headless per chiamare uno strumento MCP locale del Node configurato. Viene trasmesso tramitenode.invoke, richiede che il Node dichiari il comando e rimane soggetto all'approvazione dell'associazione e agateway.nodes.denyCommands.node.eventriporta nel Gateway gli eventi originati dai Node.node.pluginTools.updateè l'unico percorso di pubblicazione per sostituire i descrittori degli strumenti Plugin/MCP del Node connesso visibili all'agente; i parametriconnectnon li includono.node.pending.pullenode.pending.acksono le API della coda dei Node connessi.node.pending.enqueueenode.pending.draingestiscono il lavoro durevole in sospeso per i Node offline/disconnessi.
Famiglie di approvazioni
approval.geteapproval.resolvesono i metodi di approvazione durevole indipendenti dal tipo (ambitooperator.approvals).approval.getrestituisce una proiezione sanificata, in sospeso o terminale conservata, con un valoreurlPathstabile;approval.resolveaccetta l'ID di approvazione canonico, un valorekindesplicito e una decisione, applica la risoluzione in cui prevale la prima risposta e restituisce sempre il risultato canonico registrato.exec.approval.request,exec.approval.get,exec.approval.listeexec.approval.resolvegestiscono le richieste di approvazione una tantum per l'esecuzione, oltre alla ricerca e alla riproduzione delle approvazioni in sospeso. Sono adattatori al confine del protocollo basati sullo stesso registro durevole delle approvazioni.exec.approval.waitDecisionattende una singola approvazione di esecuzione in sospeso e restituisce la decisione finale (onullin caso di timeout).exec.approvals.geteexec.approvals.setgestiscono le istantanee dei criteri di approvazione dell'esecuzione del Gateway.exec.approvals.node.geteexec.approvals.node.setgestiscono i criteri di approvazione dell'esecuzione locali del Node tramite comandi di inoltro del Node.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisioneplugin.approval.resolvegestiscono i flussi di approvazione definiti dai Plugin.
Automazione, Skills e strumenti
- Automazione:
wakepianifica l'inserimento immediato o al prossimo Heartbeat di un testo di riattivazione;cron.get,cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsgestiscono il lavoro pianificato. cron.runrimane una RPC di tipo accodamento per le esecuzioni manuali. I client che richiedono una semantica di completamento devono leggere il valorerunIdrestituito ed eseguire il polling dicron.runs.cron.runsaccetta un filtrorunIdfacoltativo e non vuoto, così i client possono seguire una singola esecuzione manuale accodata senza condizioni di competizione con altre voci della cronologia relative allo stesso processo.- Skills e strumenti:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke. Vedere Metodi ausiliari per gli operatori più avanti.
Famiglie di eventi comuni
chat: aggiornamenti della chat dell'interfaccia utente, comechat.inject, e altri eventi di chat limitati alla trascrizione. Nel protocollo v4, i payload delta includonodeltaText;messagerimane l'istantanea cumulativa dell'assistente. Le sostituzioni che non sono prefissi impostanoreplace=truee utilizzanodeltaTextcome testo sostitutivo.session.message,session.operation,session.tool: aggiornamenti della trascrizione, delle operazioni di sessione in corso e del flusso di eventi per una sessione sottoscritta.session.approval: stato effettivo sanificato delle approvazioni in sospeso e terminali per un sottoscrittore di sessione esatta che ha aderito esplicitamente. Le approvazioni figlie utilizzano il pubblico dell'antenato persistito; gli eventi non modificano mai le trascrizioni né riattivano gli agenti.sessions.changed: indice o metadati della sessione modificati.presence: aggiornamenti dell'istantanea della presenza di sistema.tick: evento periodico di keepalive/verifica dell'attività.health: aggiornamento dell'istantanea dello stato del Gateway.heartbeat: aggiornamento del flusso di eventi Heartbeat.cron: evento di modifica di un'esecuzione/processo Cron.shutdown: notifica di arresto del Gateway.node.pair.requested/node.pair.resolved: ciclo di vita dell'associazione dei Node.node.invoke.request: trasmissione della richiesta di invocazione del Node.device.pair.requested/device.pair.resolved: ciclo di vita dei dispositivi associati.voicewake.changed: configurazione dell'attivazione tramite parola chiave modificata.exec.approval.requested/exec.approval.resolved: ciclo di vita dell'approvazione dell'esecuzione.plugin.approval.requested/plugin.approval.resolved: ciclo di vita dell'approvazione dei Plugin.
Metodi ausiliari dei Node
I Node possono chiamare skills.bins per recuperare l'elenco corrente degli eseguibili delle Skills
per i controlli di autorizzazione automatica.
RPC del registro di audit
audit.activity.list offre ai client degli operatori una vista stabile, dal più recente al meno recente, dei metadati del ciclo di vita
delle esecuzioni degli agenti, delle azioni degli strumenti e dei messaggi soggetti ad adesione esplicita. Richiede
operator.read. Le query escludono i record più vecchi di 30 giorni e il registro
SQLite condiviso è limitato a 100,000 record. Le righe scadute vengono eliminate durante
l'avvio del Gateway, la manutenzione oraria e le scritture successive. Vedere
Cronologia di audit per il modello dati e la semantica della privacy.
- Parametri: valori esatti facoltativi
agentId,sessionKeyorunId; valore facoltativokind("agent_run","tool_action"o"message"); valore facoltativostatus("started","succeeded","failed","cancelled","timed_out","blocked"o"unknown"); valore facoltativo del messaggiodirection("inbound"o"outbound") e valore esattochannel; limiti inclusivi facoltativiafter/beforein millisecondi Unix; valore facoltativolimitda1a500; e stringa facoltativacursordella pagina precedente. - Risultato:
{ "events": AuditActivityEventV1[], "nextCursor"?: string }.
L'unione dei risultati V1 denominata dispone di schemi distinti per le esecuzioni degli agenti, le azioni degli strumenti, i messaggi in entrata
e i messaggi in uscita. Il discriminatore eventType è rispettivamente
agent_run, tool_action, inbound_message o outbound_message; kind e
il valore direction del messaggio rimangono disponibili per il filtraggio e la visualizzazione. Ogni evento dispone di
un valore intero schemaVersion: 1. I riferimenti all'identità del messaggio utilizzano il formato esatto
hmac-sha256:v1:<32 hex key id>:<64 hex digest>; l'ID dell'attore mittente del canale
utilizza lo stesso formato.
Tutte le varianti richiedono eventType, schemaVersion, eventId, sequence,
sourceSequence, occurredAt, kind, action, status, actor e
redaction. I campi delle varianti sono:
eventType |
Campi obbligatori | Campi facoltativi |
|---|---|---|
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, riferimenti all'identità, reasonCode, errorCode |
outbound_message |
direction: "outbound", channel, conversationKind, outcome |
agentId, runId, durationMs, resultCount, riferimenti all'identità, reasonCode, deliveryKind, failureStage, errorCode |
Le enumerazioni chiuse dei messaggi sono:
conversationKind:direct,group,channelounknown.outcomein entrata:completed,skippedofailed; valore facoltativoreasonCode: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_emptyoacp_dispatch_aborted.outcomein uscita:sent,suppressed,failedounknown; valore facoltativoreasonCode:cancelled_by_message_sending_hook,cancelled_by_reply_payload_sending_hook,empty_after_message_sending_hook,empty_after_reply_payload_sending_hookono_visible_payload. Un adattatore che non restituisce alcuna identità della piattaforma èunknown, poiché l'effetto collaterale esterno non può essere escluso.deliveryKind:text,mediaoother;failureStage:platform_send,queueounknown.
I campi terminali sono correlati, non facoltativi in modo indipendente:
| Variante | Mappatura terminale |
|---|---|
| Esecuzione agente | started non dispone di errorCode; ogni stato concluso diverso da quello di successo richiede il codice run_* corrispondente. |
| Azione strumento | started e lo stato riuscito non dispongono di errorCode; ogni altro stato concluso richiede il codice tool_* corrispondente. |
| Messaggio in entrata | riuscito = completed; bloccato = skipped; non riuscito = failed più message_processing_failed. reasonCode, se presente, deve appartenere a tale famiglia terminale. |
| Messaggio in uscita | riuscito = sent; bloccato = suppressed più reasonCode; non riuscito = failed più errorCode e failureStage; sconosciuto = unknown più failureStage. |
Ogni evento di attività include un id evento stabile, una sequenza monotona del registro,
una sequenza dell'evento di origine, un timestamp, un attore, un'azione, uno stato, un valore intero
schemaVersion: 1 e redaction: "metadata_only". I record di esecuzione e degli strumenti
richiedono la provenienza dell'agente e dell'esecuzione e possono includere la provenienza della sessione. I record dei
messaggi possono includere gli id dell'agente e dell'esecuzione, ma intenzionalmente non includono mai
sessionKey o sessionId; il filtro di query sessionKey si applica pertanto
solo alle righe delle esecuzioni e degli strumenti. Gli eventi degli strumenti possono includere l'id della chiamata dello strumento e il nome dello strumento.
I record dei messaggi usano message.inbound.processed o
message.outbound.finished e aggiungono direzione, canale, tipo di conversazione,
esito normalizzato e, facoltativamente, tipo di consegna, fase dell'errore, durata,
numero di risultati, codice del motivo e pseudonimi basati su chiave e locali all'installazione
per account/conversazione/messaggio/destinazione. Questi pseudonimi agevolano
la correlazione, ma non costituiscono anonimizzazione: il database di stato contiene la relativa chiave,
mentre le esportazioni RPC e CLI non la contengono. Il registro non memorizza prompt, corpi dei messaggi,
argomenti degli strumenti, risultati degli strumenti, output dei comandi o testo grezzo degli errori.
I valori sessionKey di esecuzioni/strumenti restano metadati grezzi di correlazione e possono incorporare
id di account o peer della piattaforma; i record dei messaggi omettono le chiavi di sessione.
Per le righe in entrata, durationMs misura il dispatch del core fino al relativo stato terminale e
resultCount conta i payload finalizzati di strumenti, blocchi e risposte in coda. Per
le righe in uscita, durationMs copre la responsabilità della consegna fino alla conferma,
alla dead letter o alla riconciliazione (incluso il tempo di attesa in coda), mentre resultCount
conta gli invii fisici identificati sulla piattaforma. deliveryKind, quando presente,
descrive il payload effettivo dopo gli hook e il rendering; le righe soppresse o
ambigue a causa di un arresto anomalo lo omettono.
L'attuale copertura dei messaggi include i messaggi in entrata accettati che raggiungono il
dispatch del core, inclusi gli esiti di duplicazione/terminali del core. La copertura in uscita scrive
una riga terminale per ogni payload di risposta logico originale che raggiunge la consegna durevole
condivisa; la suddivisione in blocchi e il fan-out dell'adattatore sono aggregati in resultCount. Gli invii
in coda ritentabili o ambigui vengono registrati solo dopo la conferma, la dead
letter o la riconciliazione. I percorsi locali ai Plugin e di invio diretto che eludono tali
confini condivisi non sono ancora coperti. La coda limitata del worker opera secondo il principio del massimo sforzo
e può perdere record in caso di errore o saturazione, pertanto questa superficie non è un
archivio di conformità senza perdite.
La registrazione è attiva per impostazione predefinita ed è controllata da
audit.enabled. La registrazione dei messaggi è
controllata separatamente da audit.messages e il valore predefinito è "off". Quando
la registrazione è disabilitata, audit.activity.list continua a fornire i record scritti
in precedenza fino alla loro scadenza.
Gli schemi distribuiti di richiesta, risultato e AuditEvent di audit.list restano
invariati e restituiscono solo record delle esecuzioni dell'agente e delle azioni degli strumenti. I nuovi client
operatore devono chiamare audit.activity.list quando il Gateway ne segnala la disponibilità. I Gateway meno recenti
possono restituire unknown method: audit.activity.list oppure, poiché
nelle versioni distribuite l'autorizzazione precedeva la ricerca del metodo, missing scope: operator.admin a una richiesta con ambito di lettura. Quest'ultimo va considerato come assenza del metodo
solo quando il metodo non era segnalato. Un client può quindi ritentare audit.list
solo quando i suoi filtri non richiedono il supporto per tipo di messaggio, direzione o canale.
Usare openclaw audit per query testuali ed esportazioni JSON limitate.
RPC del registro delle attività
I client operatore esaminano e annullano i record delle attività in background del Gateway tramite
gli RPC del registro delle attività (packages/gateway-protocol/src/schema/tasks.ts). Questi
restituiscono riepiloghi sanificati delle attività, non lo stato grezzo del runtime.
tasks.listrichiedeoperator.read.- Parametri:
statusfacoltativo ("queued","running","completed","failed","cancelled"o"timed_out") oppure un array di tali stati,agentIdfacoltativo,sessionKeyfacoltativo,limitfacoltativo da1a500e la stringa facoltativacursor. - Risultato:
{ "tasks": TaskSummary[], "nextCursor"?: string }.
- Parametri:
tasks.getrichiedeoperator.read.- Parametri:
{ "taskId": string }. - Risultato:
{ "task": TaskSummary }. - Gli id attività mancanti restituiscono il formato dell'errore «non trovato» del Gateway.
- Parametri:
tasks.cancelrichiedeoperator.write.- Parametri:
{ "taskId": string, "reason"?: string }. - Risultato:
{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }. foundindica se il registro conteneva un'attività corrispondente.cancelledindica se il runtime ha accettato o registrato l'annullamento.
- Parametri:
TaskSummary include id, status e metadati facoltativi: kind,
runtime, title, agentId, sessionKey, childSessionKey, ownerKey,
runId, taskId, flowId, parentTaskId, sourceId, timestamp, avanzamento,
riepilogo terminale e testo sanificato dell'errore. agentId identifica l'agente
che esegue l'attività; sessionKey e ownerKey conservano il contesto del richiedente e di controllo.
Metodi di supporto per gli operatori
commands.list(operator.read) recupera l'inventario dei comandi del runtime per un agente.agentIdè facoltativo; ometterlo per leggere lo spazio di lavoro dell'agente predefinito.scopecontrolla a quale superficie è destinato il valore primarioname:textrestituisce il token primario del comando testuale senza il carattere iniziale/;nativee il percorso predefinitobothrestituiscono nomi nativi che tengono conto del provider, quando disponibili.textAliasescontiene alias slash esatti come/modele/m.nativeNamecontiene il nome del comando nativo che tiene conto del provider, quando esiste.providerè facoltativo e influisce solo sulla denominazione nativa e sulla disponibilità dei comandi nativi dei Plugin.includeArgs=falseomette dalla risposta i metadati serializzati degli argomenti.
tools.catalog(operator.read) recupera il catalogo degli strumenti del runtime per un agente. La risposta include strumenti raggruppati e metadati sulla provenienza:source:coreopluginpluginId: Plugin proprietario quandosource="plugin"optional: indica se uno strumento del Plugin è facoltativo
tools.effective(operator.read) recupera l'inventario degli strumenti effettivo nel runtime per una sessione.sessionKeyè obbligatorio.- Il Gateway deriva il contesto attendibile del runtime dalla sessione lato server anziché accettare dal chiamante un contesto di autenticazione o consegna.
- La risposta è una proiezione derivata dal server e circoscritta alla sessione dell'inventario attivo, inclusi gli strumenti del core, dei Plugin, dei canali e dei server MCP già individuati.
tools.effectiveè di sola lettura per MCP: può proiettare un catalogo MCP di una sessione attiva attraverso la policy finale degli strumenti, ma non crea runtime MCP, non connette trasporti e non emettetools/list. Se non esiste un catalogo attivo corrispondente, la risposta può includere un avviso comemcp-not-yet-connected,mcp-not-yet-listedomcp-stale-catalog.- Le voci degli strumenti effettivi usano
source="core",source="plugin",source="channel"osource="mcp".
tools.invoke(operator.write) richiama uno strumento disponibile attraverso lo stesso percorso di policy del Gateway di/tools/invoke.nameè obbligatorio.args,sessionKey,agentId,confirmeidempotencyKeysono facoltativi.- Se sono presenti sia
sessionKeysiaagentId, l'agente della sessione risolto deve corrispondere aagentId. - I wrapper del core riservati al proprietario, come
cron,gatewayenodes, richiedono un'identità del proprietario/amministratore (operator.admin), anche setools.invokeèoperator.write. - La risposta è un envelope destinato all'SDK con
ok,toolName, il valore facoltativooutpute i campi tipizzatierror. I rifiuti dovuti all'approvazione o alla policy restituisconook:falsenel payload anziché eludere la pipeline delle policy degli strumenti del Gateway.
skills.status(operator.read) recupera l'inventario delle skill visibili per un agente.agentIdè facoltativo; ometterlo per leggere lo spazio di lavoro dell'agente predefinito.- La risposta include idoneità, requisiti mancanti, verifiche della configurazione e opzioni di installazione sanificate senza esporre valori segreti grezzi.
skills.searcheskills.detail(operator.read) restituiscono i metadati di individuazione di ClawHub.skills.upload.begin,skills.upload.chunkeskills.upload.commit(operator.admin) preparano un archivio privato di skill prima di installarlo. Questo è un percorso di caricamento amministrativo separato per client attendibili, non il normale flusso di installazione delle skill di ClawHub, ed è disabilitato per impostazione predefinita a meno cheskills.install.allowUploadedArchivesnon sia abilitato.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })crea un caricamento associato a tale slug e al valore force.skills.upload.chunk({ uploadId, offset, dataBase64 })aggiunge byte all'offset decodificato esatto.skills.upload.commit({ uploadId, sha256? })verifica la dimensione finale e SHA-256. Il commit finalizza soltanto il caricamento; non installa la skill.- Gli archivi di skill caricati sono archivi zip contenenti una radice
SKILL.md. Il nome della directory interna dell'archivio non seleziona mai la destinazione dell'installazione.
skills.install(operator.admin) dispone di tre modalità:- Modalità ClawHub:
{ source: "clawhub", slug, version?, force? }installa una cartella di skill nella directoryskills/dello spazio di lavoro dell'agente predefinito. - Modalità di caricamento:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }installa un caricamento sottoposto a commit nella directoryskills/<slug>dello spazio di lavoro dell'agente predefinito. Lo slug e il valore force devono corrispondere alla richiestaskills.upload.beginoriginale. La richiesta viene rifiutata a meno cheskills.install.allowUploadedArchivesnon sia abilitato; l'impostazione non influisce sulle installazioni da ClawHub. - Modalità programma di installazione del Gateway:
{ name, installId, timeoutMs? }esegue un'azionemetadata.openclaw.installdichiarata sull'host del Gateway. I client meno recenti possono continuare a inviaredangerouslyForceUnsafeInstall; questo campo è deprecato, accettato solo per compatibilità del protocollo e ignorato. Usaresecurity.installPolicyper le decisioni di installazione di competenza dell'operatore.
- Modalità ClawHub:
skills.update(operator.admin) dispone di due modalità:- La modalità ClawHub aggiorna uno slug monitorato o tutte le installazioni ClawHub monitorate nello spazio di lavoro dell'agente predefinito.
- La modalità di configurazione modifica i valori
skills.entries.<skillKey>, comeenabled,apiKeyeenv.
Viste di models.list
models.list accetta un parametro facoltativo view
(src/agents/model-catalog-visibility.ts):
- Omesso oppure
"default": seagents.defaults.modelsè configurato, la risposta è il catalogo consentito, inclusi i modelli rilevati dinamicamente per le vociprovider/*. Altrimenti, la risposta è il catalogo completo del gateway. "configured": comportamento adatto a un selettore. Seagents.defaults.modelsè configurato, continua ad avere la precedenza, incluso il rilevamento specifico del provider per le vociprovider/*. Senza un elenco di elementi consentiti, la risposta usa le vocimodels.providers.<provider>.modelsesplicite, ricorrendo al catalogo completo solo quando non esistono righe di modelli configurate."provider-config": inventariomodels.providers.*.modelsdefinito nell'origine, indipendente dagli elenchi consentiti del selettore. Le righe includono le funzionalità pubbliche dei modelli e la disponibilità in base alla route, ma omettono gli endpoint dei provider, il materiale di autenticazione e la configurazione delle richieste di runtime."all": catalogo completo del gateway, ignorandoagents.defaults.models. Da usare per le interfacce di diagnostica/rilevamento, non per i normali selettori di modelli.
Approvazioni di esecuzione
- Quando una richiesta di esecuzione necessita di approvazione, il gateway trasmette
exec.approval.requested. - I client dell'operatore risolvono la richiesta chiamando
exec.approval.resolve(richiedeoperator.approvals). - Per
host=node,exec.approval.requestdeve includeresystemRunPlan(metadati canonici diargv/cwd/rawCommand/sessione). Le richieste prive disystemRunPlanvengono rifiutate. - Dopo l'approvazione, le chiamate
node.invoke system.runinoltrate riutilizzano talesystemRunPlancanonico come contesto autorevole di comando/cwd/sessione. - Se un chiamante modifica
command,rawCommand,cwd,agentIdosessionKeytra la preparazione e l'inoltro finale approvato disystem.run, il gateway rifiuta l'esecuzione anziché considerare attendibile il payload modificato.
Fallback per la consegna dell'agente
- Le richieste
agentpossono includeredeliver=trueper richiedere la consegna in uscita. bestEffortDeliver=false(valore predefinito) mantiene un comportamento rigoroso: le destinazioni di consegna non risolte o esclusivamente interne restituisconoINVALID_REQUEST.bestEffortDeliver=trueconsente il fallback all'esecuzione limitata alla sessione quando non è possibile risolvere alcuna route esterna utilizzabile per la consegna (ad esempio, sessioni interne/webchat o configurazioni multicanale ambigue).- I risultati finali di
agentpossono includereresult.deliveryStatusquando è stata richiesta la consegna, usando gli stessi statisent,suppressed,partial_failedefaileddocumentati peropenclaw agent --json --deliver.
Controllo delle versioni
PROTOCOL_VERSION,MIN_CLIENT_PROTOCOL_VERSION,MIN_NODE_PROTOCOL_VERSIONeMIN_PROBE_PROTOCOL_VERSIONsi trovano inpackages/gateway-protocol/src/version.ts.- I client inviano
minProtocol+maxProtocol. I client operatore e dell'interfaccia utente devono includere il protocollo corrente in tale intervallo; i client e i server correnti usano il protocollo v4. - I client autenticati con entrambi
role: "node"eclient.mode: "node"possono usare il protocollo Node N-1 (attualmente v3). Le sonde leggere di riavvio usano la stessa finestra N-1. L'autenticazione del dispositivo, l'associazione, gli ambiti, i criteri dei comandi e le approvazioni di esecuzione non sono modificati da questa finestra di compatibilità. Le funzionalità e i comandi Node di proprietà dei Plugin non sono resi disponibili finché il Node non viene aggiornato al protocollo corrente, perché le superfici che li ospitano non fanno parte del contratto N-1. - Gli schemi e i modelli vengono generati dalle definizioni TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Costanti del client
L'implementazione client di riferimento si trova in packages/gateway-client/src/
(OpenClaw la racchiude tramite la sottile facciata src/gateway/client.ts). Questi
valori predefiniti sono stabili nel protocollo v4 e costituiscono la base di riferimento prevista per
i client di terze parti.
| Costante | Valore predefinito | Origine |
|---|---|---|
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 |
| Timeout della richiesta (per RPC) | 30_000 ms |
packages/gateway-client/src/client.ts (requestTimeoutMs) |
| Timeout di preautenticazione/challenge di connessione | 15_000 ms |
packages/gateway-client/src/timeouts.ts (la variabile di ambiente OPENCLAW_HANDSHAKE_TIMEOUT_MS può aumentare il budget associato di server/client) |
| Backoff iniziale di riconnessione | 1_000 ms |
packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY) |
| Backoff massimo di riconnessione | 30_000 ms |
packages/gateway-client/src/client.ts (GATEWAY_RECONNECT_POLICY) |
| Limite per il nuovo tentativo rapido dopo la chiusura dovuta al token del dispositivo | 250 ms |
packages/gateway-client/src/client.ts |
Periodo di tolleranza dell'arresto forzato prima di terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Timeout predefinito di stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Intervallo di tick predefinito (prima di hello-ok) |
30_000 ms |
packages/gateway-client/src/client.ts |
| Chiusura per timeout del tick | codice 4000 quando il silenzio supera tickIntervalMs * 2 |
packages/gateway-client/src/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
Il server comunica i valori effettivi di policy.tickIntervalMs,
policy.maxPayload e policy.maxBufferedBytes in hello-ok; i client
devono rispettare tali valori anziché i valori predefiniti precedenti all'handshake.
Il client di riferimento consente alle richieste finite di gestire la propria scadenza configurata quando
ogni richiesta in sospeso ne ha una. Una richiesta expectFinal senza un valore finito di
timeoutMs, qualsiasi richiesta con timeoutMs: null o una combinazione di richieste finite e
senza limite mantiene attivo il watchdog del tick. Se gli eventi e le
risposte in ingresso rimangono assenti oltre la soglia di timeout del tick, il client chiude il
socket con il codice 4000, rifiuta ogni richiesta in sospeso e si riconnette. Non
riesegue le richieste rifiutate dopo la riconnessione.
Autenticazione
- L'autenticazione del Gateway tramite segreto condiviso usa
connect.params.auth.tokenoppureconnect.params.auth.password, a seconda del valore configurato pergateway.auth.mode("none" | "token" | "password" | "trusted-proxy"). - Le modalità che includono l'identità, come Tailscale Serve (
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"non loopback, soddisfano il controllo di autenticazione della connessione tramite le intestazioni della richiesta anzichéconnect.params.auth.*. - Il
gateway.auth.mode: "none"con ingresso privato ignora completamente l'autenticazione della connessione tramite segreto condiviso; non esporre questa modalità su ingressi pubblici/non attendibili. - Dopo l'associazione, il Gateway emette un token del dispositivo limitato al ruolo
e agli ambiti della connessione, restituito in
hello-ok.auth.deviceToken. I client devono conservarlo dopo ogni connessione riuscita. - Quando ci si riconnette con il token del dispositivo memorizzato, deve essere riutilizzato anche l'insieme di ambiti approvato e memorizzato per tale token. Ciò mantiene l'accesso già concesso a lettura/verifica/stato ed evita che le riconnessioni vengano silenziosamente ridotte a un ambito implicito più ristretto riservato ai soli amministratori.
- Composizione dell'autenticazione della connessione lato client (
selectConnectAuthinpackages/gateway-client/src/client.ts):auth.passwordè indipendente e viene sempre inoltrato quando impostato.auth.tokenviene valorizzato in ordine di priorità: prima il token condiviso esplicito, poi undeviceTokenesplicito, quindi un token memorizzato per dispositivo (indicizzato dadeviceId+role).auth.bootstrapTokenviene inviato solo quando nessuna delle opzioni precedenti ha determinatoauth.token. Un token condiviso o qualsiasi token del dispositivo determinato ne impedisce l'invio.- La promozione automatica di un token del dispositivo memorizzato nel singolo
nuovo tentativo
AUTH_TOKEN_MISMATCHè limitata ai soli endpoint attendibili: loopback oppurewss://con untlsFingerprintbloccato. Unwss://pubblico senza pinning non è idoneo.
- Il bootstrap integrato tramite codice di configurazione restituisce il
hello-ok.auth.deviceTokendel Node primario e un token operatore limitato inhello-ok.auth.deviceTokensper il trasferimento attendibile a dispositivi mobili. Il token operatore includeoperator.talk.secretsper le letture della configurazione nativa di Talk, ma esclude gli ambiti di modifica dell'associazione eoperator.admin. - Mentre un bootstrap tramite codice di configurazione non di base attende l'approvazione,
i dettagli di
PAIRING_REQUIREDincludonorecommendedNextStep: "wait_then_retry",retryable: trueepauseReconnect: false. Continuare a riconnettersi con lo stesso token di bootstrap finché la richiesta non viene approvata o il token non diventa non valido. - Conservare
hello-ok.auth.deviceTokenssolo quando la connessione ha usato l'autenticazione bootstrap su un trasporto attendibile, comewss://, oppure tramite associazione loopback/locale. - Se un client fornisce un
deviceTokenesplicito o unscopesesplicito, tale insieme di ambiti richiesto dal chiamante rimane autorevole; gli ambiti memorizzati nella cache vengono riutilizzati solo quando il client riutilizza il token memorizzato per dispositivo. - I token dei dispositivi possono essere ruotati/revocati tramite
device.token.rotateedevice.token.revoke(richiedeoperator.pairing). La rotazione o la revoca di un Node o di un altro ruolo non operatore richiede ancheoperator.admin. device.token.rotaterestituisce i metadati di rotazione. Ripete il token bearer sostitutivo solo per le chiamate dello stesso dispositivo già autenticate con tale token del dispositivo, affinché i client che usano solo token possano conservarne il sostituto prima di riconnettersi. Le rotazioni condivise/amministrative non ripetono il token bearer.- L'emissione, la rotazione e la revoca dei token restano limitate all'insieme di ruoli approvato e registrato nella voce di associazione del dispositivo; la modifica dei token non può ampliare né prendere di mira un ruolo del dispositivo mai concesso dall'approvazione dell'associazione.
- Per le sessioni con token di dispositivi associati, la gestione dei dispositivi è limitata al proprio dispositivo, salvo
che il chiamante disponga anche di
operator.admin: i chiamanti non amministratori possono gestire solo il token operatore della propria voce dispositivo. La gestione dei token di Node e di altri ruoli non operatore è riservata agli amministratori, anche per il dispositivo del chiamante. device.token.rotateedevice.token.revokeverificano inoltre l'insieme di ambiti del token operatore di destinazione rispetto agli ambiti della sessione corrente del chiamante. I chiamanti non amministratori non possono ruotare o revocare un token operatore con ambiti più ampi di quelli già posseduti.- Gli errori di autenticazione includono
error.details.codee indicazioni per il ripristino:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep: uno traretry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration(packages/gateway-protocol/src/connect-error-details.ts).
- Comportamento del client per
AUTH_TOKEN_MISMATCH:- I client attendibili possono tentare una sola volta con un token memorizzato nella cache per dispositivo.
- Se tale nuovo tentativo non riesce, interrompere i cicli di riconnessione automatica e mostrare le indicazioni sulle azioni richieste all'operatore.
AUTH_SCOPE_MISMATCHindica che il token del dispositivo è stato riconosciuto, ma non copre il ruolo o gli ambiti richiesti. Non presentarlo come token errato; richiedere all'operatore di ripetere l'associazione o approvare il contratto di ambiti più ristretto/ampio.
Identità e associazione dei dispositivi
- I Node devono includere un'identità stabile del dispositivo (
device.id) derivata dall'impronta digitale di una coppia di chiavi. - I Gateway emettono token per dispositivo e ruolo.
- Le approvazioni dell'associazione sono necessarie per i nuovi ID dispositivo, salvo che sia abilitata l'approvazione automatica locale.
- L'approvazione automatica dell'associazione è incentrata sulle connessioni loopback locali dirette.
- OpenClaw dispone inoltre di un percorso ristretto di connessione automatica locale al backend/contenitore per flussi helper attendibili tramite segreto condiviso.
- Le connessioni tailnet o LAN dello stesso host sono comunque considerate remote ai fini dell'associazione e richiedono l'approvazione.
- I client WS normalmente includono l'identità
deviceduranteconnect(operatore + Node). Le uniche eccezioni per operatori senza dispositivo sono percorsi di attendibilità espliciti:gateway.controlUi.allowInsecureAuth=trueper la compatibilità HTTP non sicura limitata a localhost.- autenticazione riuscita dell'operatore nella Control UI tramite
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(misura di emergenza, grave riduzione della sicurezza).- RPC del backend
gateway-clienttramite loopback diretto nel percorso helper interno riservato.
- L'omissione dell'identità del dispositivo ha conseguenze sugli ambiti. Quando una connessione
operatore senza dispositivo è consentita tramite un percorso di attendibilità esplicito, OpenClaw
azzera comunque gli ambiti autodichiarati impostandoli su un insieme vuoto, salvo che tale percorso disponga di
un'eccezione denominata per la conservazione degli ambiti. I metodi vincolati agli ambiti hanno quindi esito negativo con
missing scope. gateway.controlUi.dangerouslyDisableDeviceAuth=trueè un percorso di emergenza della Control UI che conserva gli ambiti. Non concede ambiti a client WebSocket arbitrari con backend personalizzati o strutturati come CLI.- Il percorso helper riservato del backend
gateway-clienttramite loopback diretto conserva gli ambiti solo per le RPC interne del piano di controllo locale; gli ID backend personalizzati non ricevono questa eccezione. - Tutte le connessioni devono firmare il nonce
connect.challengefornito dal server.
Diagnostica della migrazione dell'autenticazione dei dispositivi
Per i client legacy che usano ancora il comportamento di firma precedente alla challenge, connect
restituisce codici di dettaglio DEVICE_AUTH_* in error.details.code con un
error.details.reason stabile.
Errori di migrazione comuni:
| Messaggio | details.code | details.reason | Significato |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
Il client ha omesso device.nonce (o lo ha inviato vuoto). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
Il client ha firmato con un nonce obsoleto/errato. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
Il payload della firma non corrisponde al payload v2. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
Il timestamp firmato non rientra nello scarto consentito. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id non corrisponde all'impronta digitale della chiave pubblica. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
Il formato o la canonicalizzazione della chiave pubblica non è riuscito. |
Obiettivo della migrazione:
- Attendere sempre
connect.challenge. - Firmare il payload v2 che include il nonce del server.
- Inviare lo stesso nonce in
connect.params.device.nonce. - Il payload di firma preferito è
v3(buildDeviceAuthPayloadV3inpackages/gateway-client/src/device-auth.ts), che vincolaplatformedeviceFamily, oltre ai campi dispositivo/client/ruolo/ambiti/token/nonce. - Le firme legacy
v2restano accettate per compatibilità, ma il pinning dei metadati dei dispositivi associati continua a controllare i criteri dei comandi alla riconnessione.
TLS e pinning
- TLS è supportato per le connessioni WS (configurazione
gateway.tls). - I client possono facoltativamente applicare il pinning dell'impronta digitale del certificato del Gateway tramite
gateway.remote.tlsFingerprinto l'opzione CLI--tls-fingerprint.
Ambito
Questo protocollo espone l'intera API del Gateway: stato, canali, modelli, chat,
agente, sessioni, Node, approvazioni e altro ancora. La superficie esatta è definita dagli
schemi TypeBox riesportati da packages/gateway-protocol/src/schema.ts.