Gateway
Protocolo de Gateway
El protocolo WS del Gateway es el plano de control único + transporte de nodos para OpenClaw. Todos los clientes (CLI, IU web, app de macOS, nodos iOS/Android, nodos sin interfaz) se conectan por WebSocket y declaran su rol + ámbito en el momento de la negociación.
Transporte
- WebSocket, tramas de texto con cargas JSON.
- La primera trama debe ser una solicitud
connect. - Las tramas previas a la conexión tienen un límite de 64 KiB. Después de una negociación correcta, los clientes
deben seguir los límites
hello-ok.policy.maxPayloadyhello-ok.policy.maxBufferedBytes. Con los diagnósticos activados, las tramas entrantes demasiado grandes y los búferes salientes lentos emiten eventospayload.largeantes de que el gateway cierre o descarte la trama afectada. Estos eventos conservan tamaños, límites, superficies y códigos de motivo seguros. No conservan el cuerpo del mensaje, contenidos adjuntos, cuerpo de trama sin procesar, tokens, cookies ni valores secretos.
Negociación (connect)
Gateway → Cliente (desafío previo a la conexión):
{
"type": "event",
"event": "connect.challenge",
"payload": { "nonce": "…", "ts": 1737264000000 }
}
Cliente → Gateway:
{
"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": "…"
}
}
}
Gateway → Cliente:
{
"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
}
}
}
Mientras el Gateway aún termina de iniciar los procesos auxiliares de arranque, la solicitud connect puede
devolver un error reintentable UNAVAILABLE con details.reason establecido en
"startup-sidecars" y retryAfterMs. Los clientes deben reintentar esa respuesta
dentro de su presupuesto general de conexión en lugar de presentarla como un fallo terminal
de negociación.
server, features, snapshot y policy son todos obligatorios según el esquema
(src/gateway/protocol/schema/frames.ts). auth también es obligatorio e informa
el rol/los ámbitos negociados. pluginSurfaceUrls es opcional y asigna nombres de superficies
de plugins, como canvas, a URL alojadas con ámbito.
Las URL de superficies de plugins con ámbito pueden expirar. Los nodos pueden llamar a
node.pluginSurface.refresh con { "surface": "canvas" } para recibir una entrada nueva
en pluginSurfaceUrls. La refactorización experimental del plugin Canvas no
admite la ruta de compatibilidad obsoleta canvasHostUrl, canvasCapability ni
node.canvas.capability.refresh; los clientes nativos y gateways actuales deben usar superficies de plugins.
Cuando no se emite ningún token de dispositivo, hello-ok.auth informa los permisos
negociados sin campos de token:
{
"auth": {
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Los clientes backend de confianza en el mismo proceso (client.id: "gateway-client",
client.mode: "backend") pueden omitir device en conexiones directas de local loopback cuando
se autentican con el token/contraseña compartidos del gateway. Esta ruta está reservada
para RPC internos del plano de control y evita que las líneas base obsoletas de emparejamiento CLI/dispositivo
bloqueen trabajo backend local como actualizaciones de sesiones de subagentes. Los clientes remotos,
clientes con origen en navegador, clientes de nodo y clientes explícitos con token de dispositivo/identidad de dispositivo
siguen usando las comprobaciones normales de emparejamiento y mejora de ámbitos.
Cuando se emite un token de dispositivo, hello-ok también incluye:
{
"auth": {
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Durante la entrega de arranque de confianza, hello-ok.auth también puede incluir entradas
de rol limitadas adicionales en deviceTokens:
{
"auth": {
"deviceToken": "…",
"role": "node",
"scopes": [],
"deviceTokens": [
{
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]
}
]
}
}
Para el flujo de arranque integrado de nodo/operador, el token de nodo principal permanece con
scopes: [] y cualquier token de operador entregado permanece limitado a la lista de permitidos del operador
de arranque (operator.approvals, operator.read,
operator.talk.secrets, operator.write). Las comprobaciones de ámbito de arranque permanecen
prefijadas por rol: las entradas de operador solo satisfacen solicitudes de operador, y los roles
no operadores siguen necesitando ámbitos bajo su propio prefijo de rol.
Ejemplo de Node
{
"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": "…"
}
}
}
Encuadre
- Solicitud:
{type:"req", id, method, params} - Respuesta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Los métodos con efectos secundarios requieren claves de idempotencia (consulta el esquema).
Roles + ámbitos
Para ver el modelo completo de ámbitos de operador, las comprobaciones en tiempo de aprobación y la semántica de secretos compartidos, consulta Ámbitos de operador.
Roles
operator= cliente del plano de control (CLI/IU/automatización).node= host de capacidades (cámara/pantalla/canvas/system.run).
Ámbitos (operador)
Ámbitos comunes:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config con includeSecrets: true requiere operator.talk.secrets
(o operator.admin).
Los métodos RPC de gateway registrados por plugins pueden solicitar su propio ámbito de operador, pero
los prefijos reservados de administración del núcleo (config.*, exec.approvals.*, wizard.*,
update.*) siempre se resuelven a operator.admin.
El ámbito de método es solo la primera barrera. Algunos comandos con barra a los que se llega mediante
chat.send aplican comprobaciones más estrictas a nivel de comando encima. Por ejemplo, las escrituras persistentes
/config set y /config unset requieren operator.admin.
node.pair.approve también tiene una comprobación adicional de ámbito en tiempo de aprobación además del
ámbito base del método:
- solicitudes sin comando:
operator.pairing - solicitudes con comandos de nodo no exec:
operator.pairing+operator.write - solicitudes que incluyen
system.run,system.run.prepareosystem.which:operator.pairing+operator.admin
Capacidades/comandos/permisos (nodo)
Los nodos declaran afirmaciones de capacidad en el momento de la conexión:
caps: categorías de capacidad de alto nivel comocamera,canvas,screen,location,voiceytalk.commands: lista de permitidos de comandos para invocación.permissions: interruptores granulares (por ejemplo,screen.record,camera.capture).
El Gateway trata esto como afirmaciones y aplica listas de permitidos del lado del servidor.
Presencia
system-presencedevuelve entradas indexadas por identidad de dispositivo.- Las entradas de presencia incluyen
deviceId,rolesyscopespara que las IU puedan mostrar una sola fila por dispositivo incluso cuando se conecta como operador y nodo. node.listincluye campos opcionaleslastSeenAtMsylastSeenReason. Los nodos conectados informan su hora de conexión actual comolastSeenAtMscon motivoconnect; los nodos emparejados también pueden informar presencia en segundo plano duradera cuando un evento de nodo de confianza actualiza sus metadatos de emparejamiento.
Evento alive en segundo plano de Node
Los nodos pueden llamar a node.event con event: "node.presence.alive" para registrar que un nodo emparejado estuvo
activo durante una reactivación en segundo plano sin marcarlo 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 es una enumeración cerrada: background, silent_push, bg_app_refresh,
significant_location, manual o connect. Las cadenas de activador desconocidas se normalizan a
background por el gateway antes de la persistencia. El evento solo es duradero para sesiones de dispositivo de nodo
autenticadas; las sesiones sin dispositivo o sin emparejar devuelven handled: false.
Los gateways correctos devuelven un resultado estructurado:
{
"ok": true,
"event": "node.presence.alive",
"handled": true,
"reason": "persisted"
}
Los gateways más antiguos aún pueden devolver { "ok": true } para node.event; los clientes deben tratarlo como una
confirmación de RPC, no como persistencia de presencia duradera.
Ámbito de eventos de difusión
Los eventos de difusión WebSocket enviados por el servidor están protegidos por ámbitos para que las sesiones con ámbito de emparejamiento o solo de nodo no reciban pasivamente contenido de sesión.
- Tramas de chat, agente y resultados de herramientas (incluidos eventos
agenttransmitidos y resultados de llamadas de herramientas) requieren al menosoperator.read. Las sesiones sinoperator.readomiten estas tramas por completo. - Difusiones
plugin.*definidas por plugins están protegidas poroperator.writeuoperator.admin, según cómo las haya registrado el plugin. - Eventos de estado y transporte (
heartbeat,presence,tick, ciclo de vida de conexión/desconexión, etc.) permanecen sin restricciones para que la salud del transporte siga siendo observable para cada sesión autenticada. - Familias de eventos de difusión desconocidas están protegidas por ámbitos de forma predeterminada (fallo cerrado), salvo que un manejador registrado las relaje explícitamente.
Cada conexión de cliente mantiene su propio número de secuencia por cliente para que las difusiones conserven un orden monotónico en ese socket incluso cuando distintos clientes ven distintos subconjuntos filtrados por ámbito del flujo de eventos.
Familias comunes de métodos RPC
La superficie WS pública es más amplia que los ejemplos de negociación/autenticación anteriores. Esta
no es una descarga generada: hello-ok.features.methods es una lista de descubrimiento
conservadora construida a partir de src/gateway/server-methods-list.ts más las exportaciones de métodos de
plugin/canal cargadas. Trátala como descubrimiento de funciones, no como una enumeración completa
de src/gateway/server-methods/*.ts.
Sistema e identidad
healthdevuelve la instantánea de salud del gateway en caché o sondeada recientemente.diagnostics.stabilitydevuelve el registrador de estabilidad diagnóstica reciente y limitado. Conserva metadatos operativos como nombres de eventos, conteos, tamaños en bytes, lecturas de memoria, estado de cola/sesión, nombres de canal/plugin e ids de sesión. No conserva texto de chat, cuerpos de webhook, salidas de herramientas, cuerpos sin procesar de solicitudes o respuestas, tokens, cookies ni valores secretos. Se requiere ámbito de lectura de operador.statusdevuelve el resumen del gateway estilo/status; los campos sensibles se incluyen solo para clientes operadores con ámbito de administración.gateway.identity.getdevuelve la identidad de dispositivo del gateway usada por los flujos de relay y emparejamiento.system-presencedevuelve la instantánea de presencia actual para dispositivos operador/nodo conectados.system-eventagrega un evento del sistema y puede actualizar/difundir contexto de presencia.last-heartbeatdevuelve el último evento Heartbeat persistido.set-heartbeatsactiva o desactiva el procesamiento de Heartbeat en el gateway.
Modelos y uso
models.listdevuelve el catálogo de modelos permitido en tiempo de ejecución. Pasa{ "view": "configured" }para modelos configurados de tamaño selector (agents.defaults.modelsprimero y luegomodels.providers.*.models), o{ "view": "all" }para el catálogo completo.usage.statusdevuelve resúmenes de ventanas de uso del proveedor y cuota restante.usage.costdevuelve resúmenes agregados de uso de costos para un intervalo de fechas.doctor.memory.statusdevuelve la preparación de memoria vectorial / embeddings en caché para el espacio de trabajo activo del agente predeterminado. Pasa{ "probe": true }o{ "deep": true }solo cuando el llamador quiere explícitamente un ping en vivo al proveedor de embeddings.doctor.memory.remHarnessdevuelve una vista previa acotada y de solo lectura del arnés REM para clientes remotos del plano de control. Puede incluir rutas del espacio de trabajo, fragmentos de memoria, markdown fundamentado renderizado y candidatos de promoción profunda, por lo que los llamadores necesitanoperator.read.sessions.usagedevuelve resúmenes de uso por sesión.sessions.usage.timeseriesdevuelve uso de series temporales para una sesión.sessions.usage.logsdevuelve entradas de registro de uso para una sesión.
Canales y ayudantes de inicio de sesión
channels.statusdevuelve resúmenes de estado de canales/Plugins integrados + incluidos.channels.logoutcierra la sesión de un canal/cuenta específico cuando el canal admite cierre de sesión.web.login.startinicia un flujo de inicio de sesión QR/web para el proveedor de canal web actual compatible con QR.web.login.waitespera a que ese flujo de inicio de sesión QR/web se complete e inicia el canal si tiene éxito.push.testenvía una notificación push APNs de prueba a un Node de iOS registrado.voicewake.getdevuelve los activadores de palabra de activación almacenados.voicewake.setactualiza los activadores de palabra de activación y difunde el cambio.
Mensajería y registros
sendes el RPC directo de entrega saliente para envíos dirigidos a canal/cuenta/hilo fuera del ejecutor de chat.logs.taildevuelve la cola configurada del registro de archivo del Gateway con controles de cursor/límite y bytes máximos.
Talk y TTS
talk.catalogdevuelve el catálogo de proveedores Talk de solo lectura para voz, transcripción en streaming y voz en tiempo real. Incluye ids de proveedor, etiquetas, estado configurado, ids de modelo/voz expuestos, modos canónicos, transportes, estrategias de cerebro y flags de audio/capacidad en tiempo real sin devolver secretos de proveedores ni modificar la configuración global.talk.configdevuelve la carga útil efectiva de configuración de Talk;includeSecretsrequiereoperator.talk.secrets(ooperator.admin).talk.session.createcrea una sesión Talk propiedad del Gateway pararealtime/gateway-relay,transcription/gateway-relayostt-tts/managed-room.brain: "direct-tools"requiereoperator.admin.talk.session.joinvalida un token de sesión de sala gestionada, emite eventossession.readyosession.replacedsegún sea necesario, y devuelve metadatos de sala/sesión más eventos recientes de Talk sin el token en texto sin formato ni el hash de token almacenado.talk.session.appendAudioagrega audio de entrada PCM base64 a sesiones de retransmisión en tiempo real y transcripción propiedad del Gateway.talk.session.startTurn,talk.session.endTurnytalk.session.cancelTurncontrolan el ciclo de vida de turnos de sala gestionada con rechazo de turnos obsoletos antes de limpiar el estado.talk.session.cancelOutputdetiene la salida de audio del asistente, principalmente para interrupción controlada por VAD en sesiones de retransmisión del Gateway.talk.session.submitToolResultcompleta una llamada a herramienta de proveedor emitida por una sesión de retransmisión en tiempo real propiedad del Gateway.talk.session.closecierra una sesión de retransmisión, transcripción o sala gestionada propiedad del Gateway y emite eventos terminales de Talk.talk.modeestablece/difunde el estado actual del modo Talk para clientes WebChat/Control UI.talk.client.createcrea una sesión de proveedor en tiempo real propiedad del cliente usandowebrtcoprovider-websocketmientras el Gateway es propietario de la configuración, credenciales, instrucciones y política de herramientas.talk.client.toolCallpermite que los transportes en tiempo real propiedad del cliente reenvíen llamadas a herramientas del proveedor a la política del Gateway. La primera herramienta compatible esopenclaw_agent_consult; los clientes reciben un id de ejecución y esperan los eventos normales del ciclo de vida del chat antes de enviar el resultado de herramienta específico del proveedor.talk.eventes el único canal de eventos Talk para adaptadores en tiempo real, transcripción, STT/TTS, sala gestionada, telefonía y reuniones.talk.speaksintetiza voz mediante el proveedor de voz Talk activo.tts.statusdevuelve el estado habilitado de TTS, el proveedor activo, los proveedores de respaldo y el estado de configuración del proveedor.tts.providersdevuelve el inventario visible de proveedores TTS.tts.enableytts.disablealternan el estado de preferencias de TTS.tts.setProvideractualiza el proveedor TTS preferido.tts.convertejecuta una conversión de texto a voz de una sola vez.
Secretos, configuración, actualización y asistente
secrets.reloadvuelve a resolver los SecretRefs activos e intercambia el estado de secretos en tiempo de ejecución solo si todo tiene éxito.secrets.resolveresuelve asignaciones de secretos dirigidas a comandos para un conjunto específico de comandos/objetivos.config.getdevuelve la instantánea y el hash de la configuración actual.config.setescribe una carga útil de configuración validada.config.patchfusiona una actualización parcial de configuración.config.applyvalida + reemplaza la carga útil de configuración completa.config.schemadevuelve la carga útil del esquema de configuración en vivo usada por Control UI y las herramientas CLI: esquema,uiHints, versión y metadatos de generación, incluidos metadatos de esquema de Plugin + canal cuando el runtime puede cargarlos. El esquema incluye metadatos de campotitle/descriptionderivados de las mismas etiquetas y texto de ayuda usados por la UI, incluidas ramas de composición de objeto anidado, comodín, elemento de arreglo yanyOf/oneOf/allOfcuando existe documentación de campo coincidente.config.schema.lookupdevuelve una carga útil de búsqueda acotada por ruta para una ruta de configuración: ruta normalizada, un nodo de esquema superficial, indicio coincidente +hintPath, y resúmenes de hijos inmediatos para desglose en UI/CLI. Los nodos de esquema de búsqueda conservan la documentación orientada al usuario y los campos de validación comunes (title,description,type,enum,const,format,pattern, límites numéricos/de cadena/arreglo/objeto, y flags comoadditionalProperties,deprecated,readOnly,writeOnly). Los resúmenes de hijos exponenkey,pathnormalizada,type,required,hasChildren, además dehint/hintPathcoincidentes.update.runejecuta el flujo de actualización del Gateway y programa un reinicio solo cuando la actualización en sí tuvo éxito; los llamadores con una sesión pueden incluircontinuationMessagepara que el inicio reanude un turno de agente de seguimiento a través de la cola de continuación de reinicio. Las actualizaciones del gestor de paquetes fuerzan un reinicio de actualización no diferido y sin periodo de enfriamiento después del intercambio de paquetes para que el proceso antiguo del Gateway no siga cargando perezosamente desde un árboldistreemplazado.update.statusdevuelve el sentinel de reinicio de actualización en caché más reciente, incluida la versión en ejecución posterior al reinicio cuando está disponible.wizard.start,wizard.next,wizard.statusywizard.cancelexponen el asistente de incorporación mediante RPC de WS.
Ayudantes de agente y espacio de trabajo
agents.listdevuelve entradas de agente configuradas, incluido el modelo efectivo y metadatos de runtime.agents.create,agents.updateyagents.deletegestionan registros de agente y cableado del espacio de trabajo.agents.files.list,agents.files.getyagents.files.setgestionan los archivos del espacio de trabajo de arranque expuestos para un agente.artifacts.list,artifacts.getyartifacts.downloadexponen resúmenes de artefactos derivados de la transcripción y descargas para un ámbito explícito desessionKey,runIdotaskId. Las consultas de ejecución y tarea resuelven la sesión propietaria del lado del servidor y solo devuelven medios de transcripción con procedencia coincidente; las fuentes de URL inseguras o locales devuelven descargas no compatibles en lugar de obtenerse del lado del servidor.environments.listyenvironments.statusexponen descubrimiento de entornos locales al Gateway y de Node de solo lectura para clientes SDK.agent.identity.getdevuelve la identidad efectiva del asistente para un agente o sesión.agent.waitespera a que una ejecución termine y devuelve la instantánea terminal cuando está disponible.
Control de sesiones
sessions.listdevuelve el índice de sesiones actual, incluidos metadatosagentRuntimepor fila cuando está configurado un backend de runtime de agente.sessions.subscribeysessions.unsubscribealternan suscripciones a eventos de cambio de sesión para el cliente WS actual.sessions.messages.subscribeysessions.messages.unsubscribealternan suscripciones a eventos de transcripción/mensaje para una sesión.sessions.previewdevuelve vistas previas acotadas de transcripción para claves de sesión específicas.sessions.describedevuelve una fila de sesión del Gateway para una clave de sesión exacta.sessions.resolveresuelve o canonicaliza un objetivo de sesión.sessions.createcrea una nueva entrada de sesión.sessions.sendenvía un mensaje a una sesión existente.sessions.steeres la variante de interrumpir y dirigir para una sesión activa.sessions.abortaborta el trabajo activo de una sesión. Un llamador puede pasarkeymásrunIdopcional, o pasar solorunIdpara ejecuciones activas que el Gateway puede resolver a una sesión.sessions.patchactualiza metadatos/invalidaciones de sesión e informa el modelo canónico resuelto más elagentRuntimeefectivo.sessions.reset,sessions.deleteysessions.compactrealizan mantenimiento de sesión.sessions.getdevuelve la fila de sesión almacenada completa.- La ejecución de chat sigue usando
chat.history,chat.send,chat.abortychat.inject.chat.historyse normaliza para visualización en clientes UI: las etiquetas de directivas en línea se eliminan del texto visible, se eliminan las cargas útiles XML de llamadas a herramientas en texto sin formato (incluidos<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>y bloques truncados de llamadas a herramientas) y los tokens de control de modelo ASCII/ancho completo filtrados, se omiten las filas de asistente de token silencioso puro comoNO_REPLY/no_replyexactos, y las filas sobredimensionadas pueden reemplazarse con marcadores de posición.
Emparejamiento de dispositivos y tokens de dispositivo
device.pair.listdevuelve dispositivos emparejados pendientes y aprobados.device.pair.approve,device.pair.rejectydevice.pair.removegestionan registros de emparejamiento de dispositivos.device.token.rotaterota un token de dispositivo emparejado dentro de su rol aprobado y los límites de ámbito del llamador.device.token.revokerevoca un token de dispositivo emparejado dentro de su rol aprobado y los límites de ámbito del llamador.
Emparejamiento de Node, invocación y trabajo pendiente
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.removeynode.pair.verifycubren el emparejamiento de Node y la verificación de arranque.node.listynode.describedevuelven el estado de Nodes conocidos/conectados.node.renameactualiza una etiqueta de Node emparejado.node.invokereenvía un comando a un Node conectado.node.invoke.resultdevuelve el resultado de una solicitud de invocación.node.eventtransporta eventos originados en Node de vuelta al gateway.node.pending.pullynode.pending.ackson las API de cola de Node conectado.node.pending.enqueueynode.pending.draingestionan trabajo pendiente duradero para Nodes sin conexión/desconectados.
Approval families
exec.approval.request,exec.approval.get,exec.approval.listyexec.approval.resolvecubren solicitudes únicas de aprobación de exec, además de la búsqueda/reproducción de aprobaciones pendientes.exec.approval.waitDecisionespera una aprobación de exec pendiente y devuelve la decisión final (onullal agotarse el tiempo de espera).exec.approvals.getyexec.approvals.setgestionan instantáneas de la política de aprobación de exec del Gateway.exec.approvals.node.getyexec.approvals.node.setgestionan la política de aprobación de exec local del nodo mediante comandos de retransmisión del nodo.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionyplugin.approval.resolvecubren flujos de aprobación definidos por Plugin.
Automation, skills, and tools
- Automatización:
wakeprograma una inyección de texto de activación inmediata o en el siguiente Heartbeat;cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsgestionan trabajo programado. - Skills y herramientas:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke.
Familias de eventos comunes
chat: actualizaciones de chat de la UI, comochat.injecty otros eventos de chat solo de transcripción.session.messageysession.tool: actualizaciones de transcripción/flujo de eventos para una sesión suscrita.sessions.changed: el índice de sesiones o los metadatos cambiaron.presence: actualizaciones de instantáneas de presencia del sistema.tick: evento periódico de keepalive / actividad.health: actualización de instantánea de estado del Gateway.heartbeat: actualización del flujo de eventos de Heartbeat.cron: evento de cambio de ejecución/trabajo de Cron.shutdown: notificación de apagado del Gateway.node.pair.requested/node.pair.resolved: ciclo de vida de emparejamiento de nodo.node.invoke.request: difusión de solicitud de invocación de nodo.device.pair.requested/device.pair.resolved: ciclo de vida de dispositivo emparejado.voicewake.changed: cambió la configuración del disparador de palabra de activación.exec.approval.requested/exec.approval.resolved: ciclo de vida de aprobación de exec.plugin.approval.requested/plugin.approval.resolved: ciclo de vida de aprobación de Plugin.
Métodos auxiliares de nodo
- Los nodos pueden llamar a
skills.binspara obtener la lista actual de ejecutables de Skills para comprobaciones de autorización automática.
Métodos auxiliares de operador
- Los operadores pueden llamar a
commands.list(operator.read) para obtener el inventario de comandos en tiempo de ejecución de un agente.agentIdes opcional; omítalo para leer el espacio de trabajo predeterminado del agente.scopecontrola a qué superficie apunta elnameprincipal:textdevuelve el token principal del comando de texto sin la/inicialnativey la ruta predeterminadabothdevuelven nombres nativos conscientes del proveedor cuando están disponibles
textAliasescontiene alias de barra exactos, como/modely/m.nativeNamecontiene el nombre de comando nativo consciente del proveedor cuando existe.provideres opcional y solo afecta a la nomenclatura nativa, además de la disponibilidad de comandos nativos de Plugin.includeArgs=falseomite los metadatos de argumentos serializados en la respuesta.
- Los operadores pueden llamar a
tools.catalog(operator.read) para obtener el catálogo de herramientas en tiempo de ejecución de un agente. La respuesta incluye herramientas agrupadas y metadatos de procedencia:source:coreopluginpluginId: propietario del Plugin cuandosource="plugin"optional: si una herramienta de Plugin es opcional
- Los operadores pueden llamar a
tools.effective(operator.read) para obtener el inventario de herramientas efectivo en tiempo de ejecución de una sesión.sessionKeyes obligatorio.- El Gateway deriva el contexto de tiempo de ejecución de confianza desde la sesión en el servidor, en lugar de aceptar contexto de autenticación o entrega proporcionado por quien llama.
- La respuesta está acotada a la sesión y refleja lo que la conversación activa puede usar ahora mismo, incluidas herramientas principales, de Plugin y de canal.
- Los operadores pueden llamar a
tools.invoke(operator.write) para invocar una herramienta disponible mediante la misma ruta de política del Gateway que/tools/invoke.namees obligatorio.args,sessionKey,agentId,confirmyidempotencyKeyson opcionales.- Si tanto
sessionKeycomoagentIdestán presentes, el agente de la sesión resuelta debe coincidir conagentId. - La respuesta es un sobre orientado al SDK con
ok,toolName,outputopcional y camposerrortipados. Los rechazos por aprobación o política devuelvenok:falseen la carga útil, en lugar de omitir la canalización de políticas de herramientas del Gateway.
- Los operadores pueden llamar a
skills.status(operator.read) para obtener el inventario visible de Skills de un agente.agentIdes opcional; omítalo para leer el espacio de trabajo predeterminado del agente.- La respuesta incluye elegibilidad, requisitos faltantes, comprobaciones de configuración y opciones de instalación saneadas sin exponer valores secretos sin procesar.
- Los operadores pueden llamar a
skills.searchyskills.detail(operator.read) para metadatos de descubrimiento de ClawHub. - Los operadores pueden llamar a
skills.install(operator.admin) en dos modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala una carpeta de Skill en el directorioskills/del espacio de trabajo predeterminado del agente. - Modo instalador del Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }ejecuta una acción declaradametadata.openclaw.installen el host del Gateway.
- Modo ClawHub:
- Los operadores pueden llamar a
skills.update(operator.admin) en dos modos:- El modo ClawHub actualiza un slug rastreado o todas las instalaciones de ClawHub rastreadas en el espacio de trabajo predeterminado del agente.
- El modo de configuración aplica parches a valores de
skills.entries.<skillKey>, comoenabled,apiKeyyenv.
Vistas de models.list
models.list acepta un parámetro opcional view:
- Omitido o
"default": comportamiento actual en tiempo de ejecución. Siagents.defaults.modelsestá configurado, la respuesta es el catálogo permitido; de lo contrario, la respuesta es el catálogo completo del Gateway. "configured": comportamiento con tamaño de selector. Siagents.defaults.modelsestá configurado, sigue teniendo prioridad. De lo contrario, la respuesta usa entradas explícitas demodels.providers.*.modelsy recurre al catálogo completo solo cuando no existen filas de modelos configuradas."all": catálogo completo del Gateway, omitiendoagents.defaults.models. Use esto para diagnósticos y UI de descubrimiento, no para selectores de modelos normales.
Aprobaciones de exec
- Cuando una solicitud de exec necesita aprobación, el Gateway difunde
exec.approval.requested. - Los clientes de operador resuelven llamando a
exec.approval.resolve(requiere el alcanceoperator.approvals). - Para
host=node,exec.approval.requestdebe incluirsystemRunPlan(argv/cwd/rawCommand/metadatos de sesión canónicos). Las solicitudes sinsystemRunPlanse rechazan. - Después de la aprobación, las llamadas reenviadas
node.invoke system.runreutilizan esesystemRunPlancanónico como contexto autoritativo de comando/cwd/sesión. - Si quien llama muta
command,rawCommand,cwd,agentIdosessionKeyentre la preparación y el reenvío final aprobado desystem.run, el Gateway rechaza la ejecución en lugar de confiar en la carga útil mutada.
Reserva de entrega del agente
- Las solicitudes
agentpueden incluirdeliver=truepara solicitar entrega saliente. bestEffortDeliver=falsemantiene el comportamiento estricto: los destinos de entrega no resueltos o solo internos devuelvenINVALID_REQUEST.bestEffortDeliver=truepermite recurrir a ejecución solo de sesión cuando no se puede resolver ninguna ruta entregable externa (por ejemplo, sesiones internas/webchat o configuraciones multicanal ambiguas).
Versionado
PROTOCOL_VERSIONvive ensrc/gateway/protocol/version.ts.- Los clientes envían
minProtocol+maxProtocol; el servidor rechaza las incompatibilidades. - Los esquemas + modelos se generan a partir de definiciones de TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes de cliente
El cliente de referencia en src/gateway/client.ts usa estos valores predeterminados. Los valores son
estables en el protocolo v4 y son la línea base esperada para clientes de terceros.
| Constante | Predeterminado | Fuente |
|---|---|---|
PROTOCOL_VERSION |
4 |
src/gateway/protocol/version.ts |
| Tiempo de espera de solicitud (por RPC) | 30_000 ms |
src/gateway/client.ts (requestTimeoutMs) |
| Tiempo de espera de preautenticación / desafío de conexión | 15_000 ms |
src/gateway/handshake-timeouts.ts (config/env puede aumentar el presupuesto emparejado de servidor/cliente) |
| Backoff de reconexión inicial | 1_000 ms |
src/gateway/client.ts (backoffMs) |
| Backoff máximo de reconexión | 30_000 ms |
src/gateway/client.ts (scheduleReconnect) |
| Límite de reintento rápido tras cierre por token de dispositivo | 250 ms |
src/gateway/client.ts |
Gracia de detención forzada antes de terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Tiempo de espera predeterminado de stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Intervalo de tick predeterminado (antes de hello-ok) |
30_000 ms |
src/gateway/client.ts |
| Cierre por tiempo de espera de tick | código 4000 cuando el silencio supera tickIntervalMs * 2 |
src/gateway/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
El servidor anuncia los valores efectivos de policy.tickIntervalMs, policy.maxPayload
y policy.maxBufferedBytes en hello-ok; los clientes deben respetar esos valores
en lugar de los predeterminados previos al handshake.
Autenticación
- La autenticación del Gateway mediante secreto compartido usa
connect.params.auth.tokenoconnect.params.auth.password, según el modo de autenticación configurado. - Los modos con identidad, como Tailscale Serve
(
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"que no sean local loopback, satisfacen la comprobación de autenticación de conexión a partir de los encabezados de la solicitud en lugar deconnect.params.auth.*. - La entrada privada con
gateway.auth.mode: "none"omite por completo la autenticación de conexión mediante secreto compartido; no expongas ese modo en entradas públicas o no confiables. - Después del emparejamiento, el Gateway emite un token de dispositivo limitado al rol de conexión
- alcances. Se devuelve en
hello-ok.auth.deviceTokeny el cliente debe conservarlo para conexiones futuras.
- alcances. Se devuelve en
- Los clientes deben conservar el
hello-ok.auth.deviceTokenprincipal después de cualquier conexión correcta. - Al reconectar con ese token de dispositivo almacenado, también debe reutilizarse el conjunto de alcances aprobados almacenado para ese token. Esto preserva el acceso de lectura/sondeo/estado que ya se había concedido y evita reducir silenciosamente las reconexiones a un alcance implícito más estrecho solo de administrador.
- Ensamblado de autenticación de conexión del lado del cliente (
selectConnectAuthensrc/gateway/client.ts):auth.passwordes ortogonal y siempre se reenvía cuando está definido.auth.tokense rellena por orden de prioridad: primero el token compartido explícito, luego undeviceTokenexplícito y después un token por dispositivo almacenado (claveado pordeviceId+role).auth.bootstrapTokense envía solo cuando nada de lo anterior resolvió unauth.token. Un token compartido o cualquier token de dispositivo resuelto lo suprime.- La promoción automática de un token de dispositivo almacenado en el reintento único
AUTH_TOKEN_MISMATCHestá limitada a endpoints confiables únicamente: loopback, owss://con untlsFingerprintfijado. Unwss://público sin fijación no cumple los requisitos.
- Las entradas adicionales de
hello-ok.auth.deviceTokensson tokens de traspaso de bootstrap. Consérvalas solo cuando la conexión usó autenticación de bootstrap en un transporte confiable comowss://o emparejamiento loopback/local. - Si un cliente proporciona un
deviceTokenexplícito oscopesexplícitos, ese conjunto de alcances solicitado por el llamador sigue siendo autoritativo; los alcances en caché solo se reutilizan cuando el cliente reutiliza el token por dispositivo almacenado. - Los tokens de dispositivo pueden rotarse o revocarse mediante
device.token.rotateydevice.token.revoke(requiere el alcanceoperator.pairing). device.token.rotatedevuelve metadatos de rotación. Repite el token portador de reemplazo solo para llamadas del mismo dispositivo que ya están autenticadas con ese token de dispositivo, para que los clientes que solo usan token puedan conservar su reemplazo antes de reconectar. Las rotaciones compartidas/de administrador no repiten el token portador.- La emisión, rotación y revocación de tokens se mantienen acotadas al conjunto de roles aprobado registrado en la entrada de emparejamiento de ese dispositivo; la mutación de tokens no puede ampliar ni apuntar a un rol de dispositivo que la aprobación de emparejamiento nunca concedió.
- Para sesiones de token de dispositivo emparejado, la administración de dispositivos se limita a sí misma salvo que el
llamador también tenga
operator.admin: los llamadores no administradores pueden eliminar/revocar/rotar solo su propia entrada de dispositivo. device.token.rotateydevice.token.revoketambién comprueban el conjunto de alcances del token de operador de destino contra los alcances de la sesión actual del llamador. Los llamadores no administradores no pueden rotar ni revocar un token de operador más amplio que el que ya poseen.- Los fallos de autenticación incluyen
error.details.codemás indicaciones de recuperación:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Comportamiento del cliente para
AUTH_TOKEN_MISMATCH:- Los clientes confiables pueden intentar un reintento acotado con un token por dispositivo en caché.
- Si ese reintento falla, los clientes deben detener los bucles de reconexión automática y mostrar orientación para que actúe el operador.
Identidad del dispositivo + emparejamiento
- Los nodos deben incluir una identidad de dispositivo estable (
device.id) derivada de una huella digital de par de claves. - Los Gateway emiten tokens por dispositivo + rol.
- Se requieren aprobaciones de emparejamiento para nuevos ID de dispositivo salvo que la aprobación automática local esté habilitada.
- La aprobación automática de emparejamiento se centra en conexiones directas de local loopback.
- OpenClaw también tiene una ruta estrecha de autoconexión backend/local de contenedor para flujos auxiliares confiables con secreto compartido.
- Las conexiones de la misma máquina mediante tailnet o LAN se siguen tratando como remotas para el emparejamiento y requieren aprobación.
- Los clientes WS normalmente incluyen la identidad
deviceduranteconnect(operador + nodo). Las únicas excepciones de operador sin dispositivo son rutas de confianza explícitas:gateway.controlUi.allowInsecureAuth=truepara compatibilidad con HTTP inseguro solo en localhost.- autenticación correcta de Control UI de operador con
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(medida de emergencia, degradación grave de seguridad).- RPCs de backend
gateway-clientde loopback directo autenticadas con el token/contraseña compartido del Gateway.
- Todas las conexiones deben firmar el nonce
connect.challengeproporcionado por el servidor.
Diagnósticos de migración de autenticación de dispositivo
Para clientes heredados que aún usan el comportamiento de firma anterior al desafío, connect ahora devuelve
códigos de detalle DEVICE_AUTH_* bajo error.details.code con un error.details.reason estable.
Fallos comunes de migración:
| Mensaje | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
El cliente omitió device.nonce (o lo envió vacío). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
El cliente firmó con un nonce obsoleto/incorrecto. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
La carga útil de firma no coincide con la carga útil v2. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
La marca de tiempo firmada está fuera del desfase permitido. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id no coincide con la huella digital de la clave pública. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
Falló el formato/canonicalización de la clave pública. |
Objetivo de migración:
- Espera siempre a
connect.challenge. - Firma la carga útil v2 que incluye el nonce del servidor.
- Envía el mismo nonce en
connect.params.device.nonce. - La carga útil de firma preferida es
v3, que vinculaplatformydeviceFamilyademás de los campos de dispositivo/cliente/rol/alcances/token/nonce. - Las firmas
v2heredadas siguen aceptándose por compatibilidad, pero la fijación de metadatos de dispositivo emparejado sigue controlando la política de comandos al reconectar.
TLS + fijación
- TLS es compatible con conexiones WS.
- Los clientes pueden fijar opcionalmente la huella digital del certificado del Gateway (consulta la configuración
gateway.tlsmásgateway.remote.tlsFingerprinto la CLI--tls-fingerprint).
Alcance
Este protocolo expone la API completa del Gateway (estado, canales, modelos, chat,
agente, sesiones, nodos, aprobaciones, etc.). La superficie exacta está definida por los
esquemas TypeBox en src/gateway/protocol/schema.ts.