Transporte y enmarcado
- WebSocket, tramas de texto, cargas JSON.
- La primera trama debe ser una solicitud
connect. - Las tramas previas a la conexión tienen un límite de 64 KiB (
MAX_PREAUTH_PAYLOAD_BYTES). Después del handshake, siguenhello-ok.policy.maxPayloadyhello-ok.policy.maxBufferedBytes. Con los diagnósticos activados, las tramas entrantes sobredimensionadas y los búferes salientes lentos emiten eventospayload.largeantes de que el Gateway cierre o descarte la trama. Estos eventos incluyensurface, tamaños en bytes, límites y un código de motivo seguro, nunca cuerpos de mensajes, contenido de adjuntos, bytes de tramas sin procesar, tokens, cookies ni secretos.
- Solicitud:
{type:"req", id, method, params} - Respuesta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Handshake
Gateway envía un desafío previo a la conexión:connect:
hello-ok:
server, features, snapshot, policy y auth son todos requeridos por
HelloOkSchema (packages/gateway-protocol/src/schema/frames.ts). auth
informa el rol/alcances negociados incluso cuando no se emite ningún token de
dispositivo (forma anterior). pluginSurfaceUrls es opcional y asigna nombres
de superficies de Plugin (por ejemplo, canvas) a URL alojadas con alcance;
puede caducar, por lo que los nodos llaman a node.pluginSurface.refresh con
{ "surface": "canvas" } para obtener una entrada nueva. La ruta obsoleta
canvasHostUrl / canvasCapability / node.canvas.capability.refresh no es
compatible; usa superficies de Plugin.
Mientras el Gateway todavía termina sidecars de inicio, connect puede devolver
un error UNAVAILABLE reintentable con details.reason: "startup-sidecars" y
retryAfterMs. Reintenta dentro de tu presupuesto de conexión en lugar de
tratarlo como un fallo terminal de handshake.
Cuando se emite un token de dispositivo, hello-ok.auth lo añade:
operator.talk.secrets para lecturas de configuración de Talk, pero sin alcances
de mutación de emparejamiento y sin operator.admin. El acceso más amplio de
emparejamiento/administración necesita un emparejamiento aprobado aparte o un
flujo de token. Persiste hello-ok.auth.deviceTokens solo cuando la autenticación
de bootstrap se ejecutó sobre un transporte de confianza (wss:// o
emparejamiento local/local loopback).
Los clientes backend de confianza en el mismo proceso (client.id: "gateway-client",
client.mode: "backend") pueden omitir device en conexiones directas de
loopback al autenticarse con el token/contraseña compartidos del Gateway. Esta
ruta está reservada para RPC internos del plano de control (por ejemplo,
actualizaciones de sesión de subagentes) y evita que referencias base obsoletas
de emparejamiento CLI/dispositivo bloqueen el trabajo local de backend. Los
clientes remotos, de origen navegador, de nodo y de token de dispositivo/identidad
de dispositivo explícitos siguen pasando por las comprobaciones normales de
emparejamiento y mejora de alcance.
Ejemplo de conexión de nodo
caps: categorías de alto nivel comocamera,canvas,screen,location,voice,talk.commands: lista de comandos permitidos para invocar.permissions: conmutadores granulares (por ejemplo,screen.record,camera.capture).
Roles y alcances
Para ver el modelo completo de alcances de operador, las comprobaciones en el momento de aprobación y la semántica de secreto compartido, consulta Alcances de operador. Roles:operator: cliente de plano de control (CLI/UI/automatización).node: host de capacidades (camera/screen/canvas/system.run).
src/gateway/operator-scopes.ts), el conjunto cerrado completo:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config con includeSecrets: true requiere operator.talk.secrets (u
operator.admin). Cuando se incluyen secretos, lee la credencial del proveedor
Talk activo desde talk.resolved.config.apiKey; talk.providers.<id>.apiKey
mantiene la forma de origen y puede ser un objeto SecretRef o una cadena
redactada.
Los métodos RPC del Gateway registrados por Plugins pueden solicitar su propio
alcance de operador, pero estos prefijos reservados del núcleo siempre se
resuelven a operator.admin (src/shared/gateway-method-policy.ts): config.*,
exec.approvals.*, wizard.*, update.*.
El alcance de método es solo la primera puerta. Algunos comandos slash alcanzados
mediante chat.send aplican comprobaciones más estrictas a nivel de comando: las
escrituras persistentes /config set y /config unset requieren
operator.admin incluso para clientes del Gateway que ya tienen un alcance de
operador inferior.
node.pair.approve tiene una comprobación adicional de alcance en el momento de
aprobación además del alcance base del método (operator.pairing), basada en
los commands declarados por la solicitud pendiente
(src/infra/node-pairing-authz.ts):
| Comandos declarados | Alcances requeridos |
|---|---|
| ninguno | operator.pairing |
| comandos que no son exec | operator.pairing + operator.write |
incluye system.run, system.run.prepare o system.which | operator.pairing + operator.admin |
Presencia
system-presencedevuelve entradas indexadas por identidad de dispositivo, incluidosdeviceId,rolesyscopes, para que las UI puedan mostrar una fila por dispositivo incluso cuando se conecta como operador y como nodo.node.listincluyelastSeenAtMsylastSeenReasonopcionales. Los nodos conectados informan la hora de conexión actual con motivoconnect; los nodos emparejados también pueden informar presencia en segundo plano durable mediante un evento de nodo de confianza.
Evento de nodo vivo en segundo plano
Los nodos llaman anode.event con event: "node.presence.alive" para registrar
que un nodo emparejado estuvo vivo durante una activación en segundo plano, sin
marcarlo como conectado:
trigger es un enum cerrado: background, silent_push, bg_app_refresh,
significant_location, manual, connect. Los valores desconocidos se
normalizan a background (src/shared/node-presence.ts). El evento solo se
persiste para sesiones autenticadas de dispositivo de nodo; las sesiones sin
dispositivo o sin emparejar devuelven handled: false.
Los Gateways correctos devuelven un resultado estructurado:
{ "ok": true } para node.event;
trátalo como un RPC reconocido, no como persistencia durable de presencia.
Alcance de eventos de difusión
Los eventos de difusión enviados por el servidor tienen puertas de alcance para que las sesiones con alcance solo de emparejamiento o solo de nodo no reciban contenido de sesión de forma pasiva (src/gateway/server-broadcast.ts):
- Las tramas de chat, agente y resultados de herramientas (eventos
agenttransmitidos, eventos de resultados de herramientas) requieren al menosoperator.read. Las sesiones sin ese alcance omiten estas tramas por completo. - Las difusiones
plugin.*definidas por Plugins se restringen de forma predeterminada aoperator.writeuoperator.admin; las entradas explícitas comoplugin.approval.requested/plugin.approval.resolvedusanoperator.approvalsen su lugar. - Los eventos de estado/transporte (
heartbeat,presence,tick, ciclo de vida de conexión/desconexión) permanecen sin restricciones para que la salud del transporte sea observable para toda sesión autenticada. - Las familias de eventos de difusión desconocidas se restringen por alcance de forma predeterminada (fail-closed), salvo que un handler registrado las relaje explícitamente.
Familias de métodos RPC
hello-ok.features.methods es una lista conservadora de descubrimiento creada a
partir de src/gateway/server-methods-list.ts más las exportaciones de métodos
de Plugin/canal cargadas; no es un volcado generado de todos los métodos, y
algunos métodos (por ejemplo, push.test, web.login.start, web.login.wait,
sessions.usage) se excluyen intencionadamente del descubrimiento aunque sean
métodos reales e invocables. Trátalo como descubrimiento de funciones, no como
una enumeración completa de src/gateway/server-methods/*.ts.
Sistema e identidad
Sistema e identidad
healthdevuelve la instantánea de estado del gateway en caché o recién sondeada.diagnostics.stabilitydevuelve el registrador de estabilidad de diagnósticos acotado reciente: nombres de eventos, recuentos, tamaños en bytes, lecturas de memoria, estado de colas/sesiones, nombres de canales/plugins, ids de sesión. Sin texto de chat, cuerpos de webhook, salidas de herramientas, cuerpos sin procesar de solicitud/respuesta, tokens, cookies ni secretos. Requiereoperator.read.statusdevuelve el resumen del gateway con estilo/status; los campos sensibles solo para clientes operadores con ámbito de administrador.gateway.identity.getdevuelve la identidad del dispositivo gateway usada por los flujos de relé y emparejamiento.system-presencedevuelve la instantánea de presencia actual para dispositivos de operador/nodo conectados.system-eventañade un evento del sistema y puede actualizar/difundir el contexto de presencia.last-heartbeatdevuelve el último evento de heartbeat persistido.set-heartbeatsactiva o desactiva el procesamiento de heartbeat en el gateway.
Modelos y uso
Modelos y uso
models.listdevuelve el catálogo de modelos permitido por el entorno de ejecución. Consulta las vistas de “models.list” a continuación.usage.statusdevuelve ventanas de uso del proveedor/resúmenes de cuota restante.usage.costdevuelve resúmenes agregados del uso de costes para un intervalo de fechas. PasaagentIdpara un agente, oagentScope: "all"para agregar agentes configurados.doctor.memory.statusdevuelve la preparación de memoria vectorial / embedding en caché para el espacio de trabajo del agente predeterminado activo. Pasa{ "probe": true }o{ "deep": true }solo para un ping explícito en vivo al proveedor de embedding. Pasa{ "agentId": "agent-id" }para limitar las estadísticas del almacén Dreaming a un espacio de trabajo de agente; omitirlo agrega los espacios de trabajo Dreaming configurados.doctor.memory.dreamDiary,doctor.memory.backfillDreamDiary,doctor.memory.resetDreamDiary,doctor.memory.resetGroundedShortTerm,doctor.memory.repairDreamingArtifactsydoctor.memory.dedupeDreamDiaryaceptan{ "agentId": "agent-id" }opcional; si se omite, operan sobre el espacio de trabajo del agente predeterminado configurado.doctor.memory.remHarnessdevuelve una vista previa acotada y de solo lectura del arnés REM para clientes remotos del plano de control, incluidos rutas de espacios de trabajo, fragmentos de memoria, markdown grounded renderizado y candidatos de promoción profunda. Requiereoperator.read.sessions.usagedevuelve resúmenes de uso por sesión. PasaagentIdpara un agente, oagentScope: "all"para listar juntos los agentes configurados.sessions.usage.timeseriesdevuelve el uso en serie temporal de una sesión.sessions.usage.logsdevuelve entradas del registro de uso de una sesión.
Canales y asistentes de inicio de sesión
Canales y asistentes 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 lo admite.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 se complete e inicia el canal si tiene éxito.push.testenvía una notificación push APNs de prueba a un nodo iOS registrado.voicewake.getdevuelve los disparadores de palabra de activación almacenados.voicewake.setactualiza los disparadores de palabra de activación y difunde el cambio.
Mensajería y registros
Mensajería y registros
sendes el RPC de entrega saliente directa para envíos dirigidos a canal/cuenta/hilo fuera del ejecutor de chat.logs.taildevuelve la cola del registro de archivo configurado del gateway con controles de cursor/límite y bytes máximos.
Terminal de operador
Terminal de operador
terminal.openinicia un PTY de host para unagentIdexplícito o el agente predeterminado y devuelve el agente resuelto, el directorio de trabajo, el shell y el estado de confinamiento.terminal.input,terminal.resizeyterminal.closeoperan solo sobre sesiones propiedad de la conexión que llama.- Los eventos
terminal.datayterminal.exitse transmiten solo a la conexión que posee la sesión. - Las sesiones cuya conexión se pierde se desacoplan, no se eliminan: permanecen disponibles para volver a adjuntarse durante
gateway.terminal.detachedSessionTimeoutSeconds(predeterminado 300;0restaura eliminar al desconectar) mientras la salida reciente se acumula en un búfer acotado del lado del servidor. terminal.listdevuelve sesiones adjuntables;terminal.attachvuelve a vincular una sesión activa o desacoplada a la conexión que llama y devuelve el búfer de reproducción (toma de control estilo tmux — un propietario activo anterior recibeterminal.exitcon motivodetached);terminal.textlee el búfer como texto sin formato sin adjuntarse.- Cada método de terminal requiere
operator.admin;gateway.terminal.enableddebe ser true explícitamente. Los agentes completamente aislados se rechazan, y un cambio de política de agente cierra los PTY existentes y en curso, incluidos los desacoplados.
Talk y TTS
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: ids de proveedor canónicos, alias de registro, etiquetas, estado configurado, un resultadoreadyopcional a nivel de grupo, ids de modelos/voces expuestos, modos canónicos, transportes, estrategias de cerebro y flags de audio/capacidad en tiempo real, sin devolver secretos del proveedor ni mutar la configuración global. Los gateways actuales establecenreadydespués de aplicar la selección de proveedor en tiempo de ejecución; trata su ausencia como no verificada en gateways anteriores.talk.configdevuelve la carga útil de configuración efectiva de Talk;includeSecretsrequiereoperator.talk.secrets(uoperator.admin).talk.session.createcrea una sesión Talk propiedad del gateway pararealtime/gateway-relay,transcription/gateway-relayostt-tts/managed-room. Parastt-tts/managed-room, los llamadoresoperator.writeque pasensessionKeytambién deben pasarspawnedBypara la visibilidad con ámbito de la clave de sesión; la creación desessionKeysin ámbito ybrain: "direct-tools"requierenoperator.admin.talk.session.joinvalida un token de sesión de sala administrada, emitesession.readyosession.replacedsegún sea necesario y devuelve metadatos de sala/sesión más eventos Talk recientes, nunca el token en texto plano ni su hash.talk.session.appendAudioañade audio de entrada PCM en base64 a sesiones de relé 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 administrada 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 relé del gateway.talk.session.submitToolResultcompleta una llamada a herramienta de proveedor emitida por una sesión de relé en tiempo real propiedad del gateway. Pasaoptions: { willContinue: true }para salida provisional de herramienta cuando seguirá un resultado final, uoptions: { suppressResponse: true }cuando el resultado de la herramienta deba satisfacer la llamada del proveedor sin iniciar otra respuesta en tiempo real.talk.session.steerenvía control de voz de ejecución activa a una sesión Talk respaldada por agente y propiedad del gateway:{ sessionId, text, mode? }, dondemodeesstatus,steer,cancelofollowup; el modo omitido se clasifica a partir del texto hablado.talk.session.closecierra una sesión de relé, transcripción o sala administrada propiedad del gateway y emite eventos Talk terminales.talk.modeestablece/difunde el estado del modo Talk actual para clientes WebChat/Control UI.talk.client.createcrea una sesión de proveedor en tiempo real propiedad del cliente usandowebrtcoprovider-websocketmientras el gateway posee la configuración, credenciales, instrucciones y política de herramientas.talk.client.toolCallpermite que transportes en tiempo real propiedad del cliente reenvíen llamadas a herramientas del proveedor a la política del gateway. La primera herramienta admitida 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.client.steerenvía control de voz de ejecución activa para transportes en tiempo real propiedad del cliente. El gateway resuelve la ejecución embebida activa desdesessionKeyy devuelve un resultado estructurado aceptado/rechazado en lugar de descartar silenciosamente el direccionamiento.talk.eventes el único canal de eventos Talk para adaptadores en tiempo real, transcripción, STT/TTS, sala administrada, telefonía y reuniones.talk.speaksintetiza voz mediante el proveedor de voz Talk activo.tts.statusdevuelve el estado de habilitación 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.disableactivan o desactivan el estado de preferencias de TTS.tts.setProvideractualiza el proveedor TTS preferido.tts.convertejecuta una conversión puntual de texto a voz.tts.speak(operator.write) renderizatextno vacío con la cadena configurada de proveedores TTS generales y devuelve un clip completo en línea comoaudioBase64, además de metadatosprovidery opcionalesoutputFormat,mimeTypeyfileExtension. A diferencia detts.convert, no devuelve una ruta local al Gateway; a diferencia detalk.speak, no requiere un proveedor Talk. El texto que superamessages.tts.maxTextLengthdevuelveINVALID_REQUEST; los fallos de síntesis devuelvenUNAVAILABLE.
Secretos, configuración, actualización y asistente
Secretos, configuración, actualización y asistente
secrets.reloadvuelve a resolver las SecretRefs activas e intercambia el estado de secretos en tiempo de ejecución solo si todo se completa correctamente.secrets.resolveresuelve las asignaciones de secretos dirigidas a comandos para un conjunto específico de comando/destino.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 la configuración. El reemplazo destructivo de arrays requiere la ruta afectada enreplacePaths; los arrays anidados bajo entradas de array usan rutas con[], comoagents.list[].skills.config.applyvalida + reemplaza la carga útil completa de configuración.config.schemadevuelve la carga útil del esquema de configuración activo que usan Control UI y las herramientas CLI: esquema,uiHints, versión, metadatos de generación, y metadatos de esquema de plugin + canal cuando se pueden cargar. Incluye metadatos detitle/descriptiondel mismo texto de etiquetas/ayuda que la UI, incluidas ramas de composición de objetos anidados, comodines, elementos de array yanyOf/oneOf/allOfcuando existe documentación de campo coincidente.config.schema.lookupdevuelve una carga útil de búsqueda acotada a una ruta para una ruta de configuración: ruta normalizada, un nodo de esquema superficial, pista coincidente +hintPath,reloadKindopcional y resúmenes de hijos inmediatos para exploración detallada en UI/CLI.reloadKindes uno derestart,hotonone(src/config/schema.ts) y refleja el planificador de recarga de configuración del gateway para la ruta solicitada. Los nodos de esquema de búsqueda conservan la documentación orientada al usuario y los campos comunes de validación (title,description,type,enum,const,format,pattern, límites numéricos/de cadena/array/objeto,additionalProperties,deprecated,readOnly,writeOnly). Los resúmenes de hijos exponenkey,pathnormalizada,type,required,hasChildren,reloadKindopcional, además dehint/hintPathcoincidentes.update.runejecuta el flujo de actualización del gateway y programa un reinicio solo si la actualización tuvo éxito; los llamadores con una sesión pueden incluircontinuationMessagepara que el arranque reanude un turno de agente de seguimiento mediante la cola de continuación de reinicio. Las actualizaciones del gestor de paquetes y las actualizaciones supervisadas de checkout de git desde el plano de control usan una transferencia a servicio gestionado desacoplada en lugar de reemplazar el árbol de paquetes o mutar la salida de checkout/build dentro del gateway en vivo. Una transferencia iniciada devuelveok: trueconresult.reason: "managed-service-handoff-started"yhandoff.status: "started"; las transferencias no disponibles o fallidas devuelvenok: falseconmanaged-service-handoff-unavailableomanaged-service-handoff-failed, además dehandoff.commandcuando se requiere una actualización manual desde shell. No disponible significa que OpenClaw no tiene un límite de supervisor seguro o una identidad de servicio durable, comoOPENCLAW_SYSTEMD_UNITpara systemd. Durante una transferencia iniciada, el centinela de reinicio puede informar brevementestats.reason: "restart-health-pending"; la continuación se retrasa hasta que la CLI verifica el gateway reiniciado y escribe el centinela finalok.update.statusactualiza y devuelve el centinela de reinicio de actualización 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 WS RPC.
Ayudantes de agente y espacio de trabajo
Ayudantes de agente y espacio de trabajo
agents.listdevuelve las entradas de agentes configuradas, incluidos el modelo efectivo y los metadatos de tiempo de ejecución.agents.create,agents.updateyagents.deleteadministran registros de agentes y cableado de espacios de trabajo.agents.files.list,agents.files.getyagents.files.setadministran los archivos de espacio de trabajo de arranque expuestos para un agente.audit.listdevuelve un registro acotado solo de metadatos de eventos de ejecución de agente y acciones de herramientas.agents.workspace.listyagents.workspace.get(operator.read) exponen exploración paginada de solo lectura del directorio de espacio de trabajo de un agente para clientes del dominio de operador de confianza descrito en Ámbitos de operador. Las solicitudes aceptan solo rutas relativas al espacio de trabajo; las lecturas permanecen confinadas a la raíz realpathed del espacio de trabajo (se rechazan escapes por symlink y hardlink), con límite de tamaño y limitadas a texto UTF-8 más tipos de imagen comunes (base64). Las respuestas no exponen la ruta del espacio de trabajo del host. No hay operaciones de escritura en este namespace.tasks.list,tasks.getytasks.cancelexponen el registro de tareas del gateway a clientes SDK y operadores. Consulta RPCs del registro de tareas más abajo.artifacts.list,artifacts.getyartifacts.downloadexponen resúmenes de artefactos derivados de transcripciones y descargas para un alcance 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 URL inseguras o locales devuelven descargas no admitidas en lugar de obtenerse del lado del servidor.environments.listyenvironments.statusexponen descubrimiento de entornos locales del gateway y de Node en modo de solo lectura para clientes SDK.agent.identity.getdevuelve la identidad efectiva del asistente para un agente o una sesión.agent.waitespera a que una ejecución finalice y devuelve la instantánea terminal cuando está disponible.
Control de sesión
Control de sesión
sessions.listdevuelve el índice de sesiones actual, incluidos metadatosagentRuntimepor fila cuando hay un backend de runtime de agente configurado.sessions.subscribeysessions.unsubscribealternan las suscripciones a eventos de cambio de sesión para el cliente WS actual.sessions.messages.subscribeysessions.messages.unsubscribealternan las suscripciones a eventos de transcripción/mensaje para una sesión.sessions.previewdevuelve vistas previas acotadas de transcripciones 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 canoniza un destino 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 interrupción y dirección para una sesión activa.sessions.abortcancela trabajo activo para una sesión. PasakeymásrunIdopcional, o solorunIdpara ejecuciones activas que el gateway puede resolver a una sesión.sessions.patchactualiza metadatos/anulaciones 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 directiva en línea se eliminan del texto visible, las cargas útiles XML de llamadas a herramientas en texto plano (<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>y bloques truncados de llamadas a herramientas) y tokens de control de modelo ASCII/ancho completo filtrados se eliminan, las filas de asistente con tokens puramente silenciosos (NO_REPLY/no_replyexactos) se omiten, y las filas sobredimensionadas pueden reemplazarse por marcadores de posición. chat.message.getes el lector aditivo acotado de mensaje completo para una sola entrada visible de transcripción. PasasessionKey,agentIdopcional cuando la selección de sesión está acotada al agente, y unmessageIdde transcripción expuesto previamente mediantechat.history; el gateway devuelve la misma proyección normalizada para visualización sin el límite de truncamiento del historial ligero cuando la entrada almacenada sigue disponible y no está sobredimensionada.chat.sendaceptafastMode: "auto"de un turno para usar el modo rápido en llamadas al modelo iniciadas antes del corte automático, y luego iniciar llamadas posteriores de reintento, fallback, resultado de herramienta o continuación sin modo rápido. El corte predeterminado es de 60 segundos (DEFAULT_FAST_MODE_AUTO_ON_SECONDS) y puede configurarse por modelo conagents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. Un llamador dechat.sendpuede pasarfastAutoOnSecondsde un turno para anular el corte de esa solicitud.
Emparejamiento de dispositivos y tokens de dispositivo
Emparejamiento de dispositivos y tokens de dispositivo
device.pair.listdevuelve dispositivos emparejados pendientes y aprobados.device.pair.setupCodecrea un código de configuración móvil y, de forma predeterminada, una URL de datos QR PNG. Requiereoperator.adminy se omite intencionalmente del descubrimiento anunciado. El resultado incluyesetupCode,qrDataUrlopcional,gatewayUrl, la etiqueta no secretaauthyurlSource.device.pair.approve,device.pair.rejectydevice.pair.removeadministran registros de emparejamiento de dispositivos.device.token.rotaterota un token de dispositivo emparejado dentro de los límites de su rol aprobado y el alcance del llamador.device.token.revokerevoca un token de dispositivo emparejado dentro de los límites de su rol aprobado y el alcance del llamador.
Emparejamiento de Node, invocación y trabajo pendiente
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 Node conocido/conectado.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.drainadministran trabajo pendiente durable para Nodes sin conexión/desconectados.
Familias de aprobación
Familias de aprobación
exec.approval.request,exec.approval.get,exec.approval.listyexec.approval.resolvecubren solicitudes de aprobación de ejecución de un solo uso, además de búsqueda/reproducción de aprobaciones pendientes.exec.approval.waitDecisionespera una aprobación de ejecución pendiente y devuelve la decisión final (onullal agotarse el tiempo de espera).exec.approvals.getyexec.approvals.setadministran instantáneas de políticas de aprobación de ejecución del gateway.exec.approvals.node.getyexec.approvals.node.setadministran la política de aprobación de ejecución local de Node mediante comandos de retransmisión de Node.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionyplugin.approval.resolvecubren flujos de aprobación definidos por plugins.
Automatización, Skills y herramientas
Automatización, Skills y herramientas
- Automatización:
wakeprograma una inyección de texto de activación inmediata o en el siguiente Heartbeat;cron.get,cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsadministran trabajo programado. cron.runsigue siendo un RPC de estilo encolado para ejecuciones manuales. Los clientes que necesitan semántica de finalización deben leer elrunIddevuelto y sondearcron.runs.cron.runsacepta un filtrorunIdopcional no vacío para que los clientes puedan seguir una ejecución manual encolada sin competir con otras entradas de historial del mismo trabajo.- Skills y herramientas:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke. Consulta Métodos auxiliares de operador más abajo.
Familias de eventos comunes
chat: actualizaciones de chat de la UI comochat.injecty otros eventos de chat solo de transcripción. En el protocolo v4, las cargas útiles delta llevandeltaText;messagesigue siendo la instantánea acumulativa del asistente. Los reemplazos que no son de prefijo establecenreplace=truey usandeltaTextcomo texto de reemplazo.session.message,session.operation,session.tool: transcripción, operación de sesión en curso y actualizaciones de flujo de eventos para una sesión suscrita.sessions.changed: cambió el índice de sesiones o los metadatos.presence: actualizaciones de instantánea de presencia del sistema.tick: evento periódico de mantenimiento de conexión/actividad.health: actualización de instantánea de salud del Gateway.heartbeat: actualización del flujo de eventos de heartbeat.cron: evento de cambio de ejecución/trabajo cron.shutdown: notificación de apagado del Gateway.node.pair.requested/node.pair.resolved: ciclo de vida de emparejamiento de Node.node.invoke.request: difusión de solicitud de invocación de Node.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 Node
Los Nodes pueden llamar askills.bins para obtener la lista actual de
ejecutables de skill para comprobaciones de autorización automática.
RPC del libro de auditoría
audit.list proporciona a los clientes operadores una vista estable, de más
reciente a más antigua, de los metadatos de ejecuciones de agentes y acciones de
herramientas. Requiere operator.read. Las consultas excluyen registros con
más de 30 días de antigüedad, y el libro SQLite compartido tiene un límite de
100.000 registros. Las filas caducadas se eliminan durante el inicio del
Gateway, el mantenimiento horario y las escrituras posteriores.
- Parámetros:
agentId,sessionKeyorunIdexactos opcionales;kindopcional ("agent_run"o"tool_action");statusopcional ("started","succeeded","failed","cancelled","timed_out","blocked"o"unknown"); límites inclusivos opcionalesafter/beforeen milisegundos Unix;limitopcional de1a500; y cadenacursoropcional de la página anterior. - Resultado:
{ "events": AuditEvent[], "nextCursor"?: string }.
redaction siempre es
"metadata_only": el libro no almacena prompts, mensajes, argumentos de
herramientas, resultados de herramientas, salida de comandos ni texto de error
sin procesar.
El registro está activado de forma predeterminada y lo controla
audit.enabled; cuando se desactiva,
audit.list sigue sirviendo los registros escritos anteriormente hasta que
caduquen.
Usa openclaw audit para consultas de texto y exportaciones JSON
acotadas.
RPCs del libro de tareas
Los clientes operadores inspeccionan y cancelan registros de tareas en segundo plano del Gateway mediante los RPCs del libro de tareas (packages/gateway-protocol/src/schema/tasks.ts). Estos devuelven resúmenes de
tareas saneados, no estado de runtime sin procesar.
tasks.listrequiereoperator.read.- Parámetros:
statusopcional ("queued","running","completed","failed","cancelled"o"timed_out") o un arreglo de esos estados,agentIdopcional,sessionKeyopcional,limitopcional de1a500y cadenacursoropcional. - Resultado:
{ "tasks": TaskSummary[], "nextCursor"?: string }.
- Parámetros:
tasks.getrequiereoperator.read.- Parámetros:
{ "taskId": string }. - Resultado:
{ "task": TaskSummary }. - Los ids de tarea faltantes devuelven la forma de error not-found del Gateway.
- Parámetros:
tasks.cancelrequiereoperator.write.- Parámetros:
{ "taskId": string, "reason"?: string }. - Resultado:
{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }. foundinforma si el libro tenía una tarea coincidente.cancelledinforma si el runtime aceptó o registró la cancelación.
- Parámetros:
TaskSummary incluye id, status y metadatos opcionales: kind, runtime,
title, agentId, sessionKey, childSessionKey, ownerKey, runId,
taskId, flowId, parentTaskId, sourceId, marcas temporales, progreso,
resumen terminal y texto de error saneado. agentId identifica el agente que
ejecuta la tarea; sessionKey y ownerKey conservan el contexto de solicitante
y control.
Métodos auxiliares de operador
commands.list(operator.read) obtiene el inventario de comandos de runtime para un agente.agentIdes opcional; omítelo para leer el espacio de trabajo del agente predeterminado.scopecontrola a qué superficie apunta elnameprincipal:textdevuelve el token principal de comando de texto sin la/inicial;nativey la ruta predeterminadabothdevuelven nombres nativos conscientes del proveedor cuando están disponibles.textAliaseslleva alias de barra exactos como/modely/m.nativeNamelleva el nombre de comando nativo consciente del proveedor cuando existe.provideres opcional y solo afecta la nomenclatura nativa y la disponibilidad de comandos nativos de Plugin.includeArgs=falseomite de la respuesta los metadatos de argumentos serializados.
tools.catalog(operator.read) obtiene el catálogo de herramientas de runtime para 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
tools.effective(operator.read) obtiene el inventario de herramientas efectivo en runtime para una sesión.sessionKeyes obligatorio.- El Gateway deriva el contexto de runtime confiable de la sesión del lado del servidor en lugar de aceptar autenticación o contexto de entrega proporcionados por el llamador.
- La respuesta es una proyección con alcance de sesión, derivada por el servidor, del inventario activo, incluidas herramientas de core, Plugin, canal y servidores MCP ya descubiertos.
tools.effectivees de solo lectura para MCP: puede proyectar un catálogo MCP de sesión caliente a través de la política final de herramientas, pero no crea runtimes MCP, no conecta transportes ni emitetools/list. Si no existe un catálogo caliente coincidente, la respuesta puede incluir un aviso comomcp-not-yet-connected,mcp-not-yet-listedomcp-stale-catalog.- Las entradas de herramientas efectivas usan
source="core",source="plugin",source="channel"osource="mcp".
tools.invoke(operator.write) invoca una herramienta disponible mediante la misma ruta de política del Gateway que/tools/invoke.namees obligatorio.args,sessionKey,agentId,confirmeidempotencyKeyson opcionales.- Si tanto
sessionKeycomoagentIdestán presentes, el agente de sesión resuelto debe coincidir conagentId. - Los wrappers de core solo para propietario, como
cron,gatewayynodes, requieren identidad de propietario/admin (operator.admin) aunquetools.invokeen sí seaoperator.write. - La respuesta es un sobre orientado al SDK con
ok,toolName,outputopcional y camposerrortipados. Las negativas por aprobación o política devuelvenok:falseen la carga útil en lugar de omitir la canalización de política de herramientas del Gateway.
skills.status(operator.read) obtiene el inventario visible de skills para un agente.agentIdes opcional; omítelo para leer el espacio de trabajo del agente predeterminado.- La respuesta incluye elegibilidad, requisitos faltantes, comprobaciones de configuración y opciones de instalación saneadas sin exponer valores secretos sin procesar.
skills.searchyskills.detail(operator.read) devuelven metadatos de descubrimiento de ClawHub.skills.upload.begin,skills.upload.chunkyskills.upload.commit(operator.admin) preparan un archivo privado de skill antes de instalarlo. Esta es una ruta de carga de admin separada para clientes confiables, no el flujo normal de instalación de skills de ClawHub, y está desactivada de forma predeterminada a menos queskills.install.allowUploadedArchivesesté activado.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })crea una carga vinculada a ese slug y valor de force.skills.upload.chunk({ uploadId, offset, dataBase64 })anexa bytes en el desplazamiento decodificado exacto.skills.upload.commit({ uploadId, sha256? })verifica el tamaño final y SHA-256. Commit solo finaliza la carga; no instala la skill.- Los archivos de skill cargados son archivos zip que contienen una raíz
SKILL.md. El nombre de directorio interno del archivo nunca selecciona el destino de instalación.
skills.install(operator.admin) tiene tres modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala una carpeta de skill en el directorioskills/del espacio de trabajo del agente predeterminado. - Modo de carga:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }instala una carga confirmada en el directorioskills/<slug>del espacio de trabajo del agente predeterminado. El slug y el valor de force deben coincidir con la solicitud originalskills.upload.begin. Se rechaza a menos queskills.install.allowUploadedArchivesesté activado; la configuración no afecta a las instalaciones de ClawHub. - Modo instalador del Gateway:
{ name, installId, timeoutMs? }ejecuta una acción declaradametadata.openclaw.installen el host del Gateway. Los clientes más antiguos aún pueden enviardangerouslyForceUnsafeInstall; este campo está obsoleto, se acepta solo por compatibilidad de protocolo y se ignora. Usasecurity.installPolicypara decisiones de instalación propiedad del operador.
- Modo ClawHub:
skills.update(operator.admin) tiene dos modos:- El modo ClawHub actualiza un slug rastreado o todas las instalaciones de ClawHub rastreadas en el espacio de trabajo del agente predeterminado.
- El modo configuración parchea valores
skills.entries.<skillKey>comoenabled,apiKeyyenv.
Vistas de models.list
models.list acepta un parámetro view opcional
(src/agents/model-catalog-visibility.ts):
- Omitido o
"default": siagents.defaults.modelsestá configurado, la respuesta es el catálogo permitido, incluidos los modelos descubiertos dinámicamente para entradasprovider/*. De lo contrario, la respuesta es el catálogo completo del Gateway. "configured": comportamiento del tamaño de un selector. Siagents.defaults.modelsestá configurado, sigue teniendo prioridad, incluido el descubrimiento con alcance de proveedor para entradasprovider/*. Sin una lista de permitidos, la respuesta usa entradas explícitasmodels.providers.<provider>.models, recurriendo al catálogo completo solo cuando no existen filas de modelos configuradas."all": catálogo completo del Gateway, omitiendoagents.defaults.models. Úsalo para UIs de diagnóstico/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 operadores resuelven llamando a
exec.approval.resolve(requiereoperator.approvals). - Para
host=node,exec.approval.requestdebe incluirsystemRunPlan(argv/cwd/rawCommand/metadatos de sesión canónicos). Las solicitudes que no tengansystemRunPlanse 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 un llamador 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.
Fallback de entrega de agente
- Las solicitudes
agentpueden incluirdeliver=truepara solicitar entrega saliente. bestEffortDeliver=false(el valor predeterminado) mantiene 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).- Los resultados finales de
agentpueden incluirresult.deliveryStatuscuando se solicitó entrega, usando los mismos estadossent,suppressed,partial_failedyfaileddocumentados paraopenclaw agent --json --deliver.
Versionado
PROTOCOL_VERSION,MIN_CLIENT_PROTOCOL_VERSION,MIN_NODE_PROTOCOL_VERSIONyMIN_PROBE_PROTOCOL_VERSIONviven enpackages/gateway-protocol/src/version.ts.- Los clientes envían
minProtocol+maxProtocol. Los clientes de operador y de UI deben incluir el protocolo actual en ese rango; los clientes y servidores actuales ejecutan el protocolo v4. - Los clientes autenticados con
role: "node"yclient.mode: "node"pueden usar el protocolo de Node N-1 (actualmente v3). Las sondas ligeras de reinicio usan la misma ventana N-1. La autenticación de dispositivos, el emparejamiento, los ámbitos, la política de comandos y las aprobaciones de ejecución no cambian por esta ventana de compatibilidad. Las capacidades y comandos de Node propiedad del Plugin se retienen hasta que el Node se actualiza al protocolo actual porque sus superficies alojadas no forman parte del contrato N-1. - Los esquemas y modelos se generan desde definiciones de TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes de cliente
La implementación de cliente de referencia vive enpackages/gateway-client/src/
(OpenClaw la envuelve mediante la fachada delgada src/gateway/client.ts). Estos
valores predeterminados son estables en el protocolo v4 y son la base esperada para
clientes de terceros.
| Constante | Valor predeterminado | Fuente |
|---|---|---|
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 |
| Tiempo de espera de solicitud (por RPC) | 30_000 ms | packages/gateway-client/src/client.ts (requestTimeoutMs) |
| Tiempo de espera de preautenticación / desafío de conexión | 15_000 ms | packages/gateway-client/src/timeouts.ts (OPENCLAW_HANDSHAKE_TIMEOUT_MS env puede aumentar el presupuesto emparejado de servidor/cliente) |
| Retroceso inicial de reconexión | 1_000 ms | packages/gateway-client/src/client.ts (backoffMs) |
| Retroceso máximo de reconexión | 30_000 ms | packages/gateway-client/src/client.ts (scheduleReconnect) |
| Límite de reintento rápido tras cierre por token de dispositivo | 250 ms | packages/gateway-client/src/client.ts |
Gracia de parada 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 | packages/gateway-client/src/client.ts |
| Cierre por tiempo de espera de tick | código 4000 cuando el silencio supera tickIntervalMs * 2 | packages/gateway-client/src/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
policy.tickIntervalMs,
policy.maxPayload y policy.maxBufferedBytes en hello-ok; los clientes
deben respetar esos valores en lugar de los valores predeterminados previos al handshake.
Autenticación
- La autenticación de Gateway con secreto compartido usa
connect.params.auth.tokenoconnect.params.auth.password, según elgateway.auth.modeconfigurado ("none" | "token" | "password" | "trusted-proxy"). - Los modos que portan identidad, como Tailscale Serve (
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"sin loopback, satisfacen la comprobación de autenticación de conexión desde los encabezados de la solicitud en lugar deconnect.params.auth.*. gateway.auth.mode: "none"de ingreso privado omite por completo la autenticación de conexión con secreto compartido; no expongas ese modo en ingresos públicos/no confiables.- Tras el emparejamiento, el Gateway emite un token de dispositivo limitado al rol de conexión
- ámbitos, devuelto en
hello-ok.auth.deviceToken. Los clientes deben persistirlo después de cualquier conexión correcta.
- ámbitos, devuelto en
- Reconectar con ese token de dispositivo almacenado también debe reutilizar el conjunto de ámbitos aprobados almacenado para ese token. Esto conserva el acceso de lectura/sonda/estado ya concedido y evita reducir silenciosamente las reconexiones a un ámbito implícito más estrecho solo de administrador.
- Ensamblaje de autenticación de conexión del lado del cliente (
selectConnectAuthenpackages/gateway-client/src/client.ts):auth.passwordes ortogonal y siempre se reenvía cuando está establecido.auth.tokense rellena por orden de prioridad: primero el token compartido explícito, luego undeviceTokenexplícito, luego un token almacenado por dispositivo (indexado pordeviceId+role).auth.bootstrapTokense envía solo cuando ninguno de los anteriores resolvióauth.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 solo a endpoints confiables: loopback, owss://con unatlsFingerprintfijada.wss://público sin fijación no califica.
- El bootstrap integrado con código de configuración devuelve el
hello-ok.auth.deviceTokendel Node primario más un token de operador acotado enhello-ok.auth.deviceTokenspara transferencia móvil confiable. El token de operador incluyeoperator.talk.secretspara lecturas de configuración nativa de Talk, pero excluye ámbitos de mutación de emparejamiento yoperator.admin. - Mientras un bootstrap con código de configuración no base espera aprobación,
los detalles de
PAIRING_REQUIREDincluyenrecommendedNextStep: "wait_then_retry",retryable: trueypauseReconnect: false. Sigue reconectando con el mismo token de bootstrap hasta que la solicitud se apruebe o el token deje de ser válido. - Persiste
hello-ok.auth.deviceTokenssolo cuando la conexión usó autenticación de bootstrap en un transporte confiable comowss://o emparejamiento local/loopback. - Si un cliente proporciona un
deviceTokenexplícito oscopesexplícitos, ese conjunto de ámbitos solicitado por el llamador sigue siendo autoritativo; los ámbitos en caché solo se reutilizan cuando el cliente reutiliza el token almacenado por dispositivo. - Los tokens de dispositivo se pueden rotar/revocar mediante
device.token.rotateydevice.token.revoke(requiereoperator.pairing). Rotar o revocar un Node u otro rol no operador también requiereoperator.admin. device.token.rotatedevuelve metadatos de rotación. Hace eco del token portador de reemplazo solo para llamadas del mismo dispositivo ya autenticadas con ese token de dispositivo, para que los clientes solo con token puedan persistir su reemplazo antes de reconectar. Las rotaciones compartidas/de administrador no hacen eco del token portador.- La emisión, rotación y revocación de tokens permanecen 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 con 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 solo pueden administrar el token de operador de su propia entrada de dispositivo. La administración de tokens de Node y otros no operadores es solo de administrador, incluso para el propio dispositivo del llamador. device.token.rotateydevice.token.revoketambién comprueban el conjunto de ámbitos del token de operador de destino frente a los ámbitos de sesión actuales 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 sugerencias de recuperación:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep: uno deretry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration(packages/gateway-protocol/src/connect-error-details.ts).
- 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, detén los bucles de reconexión automática y muestra la guía de acción para el operador.
AUTH_SCOPE_MISMATCHsignifica que el token de dispositivo fue reconocido pero no cubre el rol/los ámbitos solicitados. No lo presentes como un token incorrecto; pide al operador volver a emparejar o aprobar el contrato de ámbitos más estrecho/más amplio.
Identidad de dispositivo y emparejamiento
- Los Nodes deben incluir una identidad de dispositivo estable (
device.id) derivada de una huella de keypair. - Los Gateways emiten tokens por dispositivo + rol.
- Se requieren aprobaciones de emparejamiento para nuevos IDs 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 local al backend/contenedor para flujos auxiliares confiables con secreto compartido.
- Las conexiones de tailnet del mismo host o LAN se siguen tratando como remotas para el emparejamiento y requieren aprobación.
- Los clientes WS normalmente incluyen identidad
deviceduranteconnect(operador + Node). Las únicas excepciones de operador sin dispositivo son rutas de confianza explícitas:gateway.controlUi.allowInsecureAuth=truepara compatibilidad HTTP insegura solo en localhost.- autenticación correcta de Control UI de operador con
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(emergencia, degradación de seguridad severa).- RPCs de backend de
gateway-clientpor loopback directo en la ruta auxiliar interna reservada.
- Omitir la identidad de dispositivo tiene consecuencias de ámbito. Cuando una conexión de
operador sin dispositivo se permite mediante una ruta de confianza explícita, OpenClaw
aún limpia los ámbitos autodeclarados a un conjunto vacío salvo que esa ruta tenga una
excepción de preservación de ámbitos nombrada. Los métodos protegidos por ámbito fallan entonces con
missing scope. gateway.controlUi.dangerouslyDisableDeviceAuth=truees una ruta de preservación de ámbitos de emergencia de Control UI. No concede ámbitos a clientes WebSocket de backend personalizados arbitrarios ni con forma de CLI.- La ruta auxiliar reservada de backend de
gateway-clientpor loopback directo preserva ámbitos solo para RPCs internas de plano de control local; los IDs de backend personalizados no reciben esta excepción. - Todas las conexiones deben firmar el nonce
connect.challengeproporcionado por el servidor.
Diagnósticos de migración de autenticación de dispositivos
Para clientes heredados que todavía usan el comportamiento de firma previo al desafío,connect
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ó en blanco). |
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 la 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 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. |
- Espera siempre
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(buildDeviceAuthPayloadV3enpackages/gateway-client/src/device-auth.ts), que vinculaplatformydeviceFamily, además de los campos de dispositivo/cliente/rol/alcances/token/nonce. - Las firmas heredadas
v2siguen aceptándose por compatibilidad, pero la fijación de metadatos de dispositivos emparejados sigue controlando la política de comandos al reconectar.
TLS y fijación
- TLS es compatible con conexiones WS (configuración
gateway.tls). - Los clientes pueden fijar opcionalmente la huella del certificado del gateway mediante
gateway.remote.tlsFingerprinto la CLI--tls-fingerprint.
Alcance
Este protocolo expone la API completa del gateway: estado, canales, modelos, chat, agente, sesiones, nodos, aprobaciones y más. La superficie exacta la definen los esquemas TypeBox reexportados desdepackages/gateway-protocol/src/schema.ts.