TypeBox como fuente de verdad del protocolo
Seguro que has pasado por esto: cambias un campo en el backend y de repente el cliente móvil deja de funcionar porque los tipos no coinciden. Mantener la sincronización manual entre la documentación, el servidor y las aplicaciones es una tarea pesada que suele terminar en errores de validación difíciles de encontrar.
Tener que escribir el mismo esquema para TypeScript, JSON Schema y modelos en otros lenguajes como Swift quita tiempo y genera inconsistencias. Lo ideal es definir el protocolo una sola vez y que todo lo demás se genere automáticamente.
Requisitos previos
Sección titulada «Requisitos previos»Para trabajar con este sistema, necesitas conocer estas ubicaciones:
- Source:
src/gateway/protocol/schema.ts - Validators en runtime (AJV):
src/gateway/protocol/index.ts - Handshake del servidor:
src/gateway/server.ts - Cliente Node.js:
src/gateway/client.ts - JSON Schema generado:
dist/protocol.schema.json - Modelos Swift generados:
apps/macos/Sources/OpenClawProtocol/GatewayModels.swift
Inicio rápido
Sección titulada «Inicio rápido»El protocolo del Gateway usa TypeBox para definir frames de WebSocket. Cada mensaje es uno de estos cuatro tipos de frame:
- Request:
{ type: "req", id, method, params } - Response:
{ type: "res", id, ok, payload | error } - Event:
{ type: "event", event, payload, seq?, stateVersion? } - Unknown: Frames no reconocidos (útil para compatibilidad)
El flujo mínimo de conexión funciona así:
Client Gateway |---- req:connect -------->| |<---- res:hello-ok --------| |<---- event:tick ----------| |---- req:health ---------->| |<---- res:health ----------|Cliente mínimo (Node.js)
Sección titulada «Cliente mínimo (Node.js)»Este es el flujo más pequeño para conectar y revisar el estado:
import { WebSocket } from "ws";
const ws = new WebSocket("ws://127.0.0.1:18789");
ws.on("open", () => { ws.send( JSON.stringify({ type: "req", id: "c1", method: "connect", params: { minProtocol: 3, maxProtocol: 3, client: { id: "cli", displayName: "example", version: "dev", platform: "node", mode: "cli", }, }, }), );});
ws.on("message", (data) => { const msg = JSON.parse(String(data)); if (msg.type === "res" && msg.id === "c1" && msg.ok) { ws.send(JSON.stringify({ type: "req", id: "h1", method: "health" })); } if (msg.type === "res" && msg.id === "h1") { console.log("health:", msg.payload); ws.close(); }});Cómo añadir un método nuevo
Sección titulada «Cómo añadir un método nuevo»Si quieres añadir un método como system.echo, sigue estos pasos:
- Define el esquema en
src/gateway/protocol/schema.ts:
export const SystemEchoParamsSchema = Type.Object( { text: NonEmptyString }, { additionalProperties: false },);
export const SystemEchoResultSchema = Type.Object( { ok: Type.Boolean(), text: NonEmptyString }, { additionalProperties: false },);- Registra y exporta los tipos:
SystemEchoParams: SystemEchoParamsSchema, SystemEchoResult: SystemEchoResultSchema,export type SystemEchoParams = Static\<typeof SystemEchoParamsSchema\>;export type SystemEchoResult = Static\<typeof SystemEchoResultSchema\>;- Crea el validador en
src/gateway/protocol/index.ts:
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);- Implementa la lógica en el servidor:
En
src/gateway/server-methods/system.ts:
export const systemHandlers: GatewayRequestHandlers = { "system.echo": ({ params, respond }) => { const text = String(params.text ?? ""); respond(true, { ok: true, text }); },};- Actualiza los archivos generados:
pnpm protocol:checkPipeline de generación
Sección titulada «Pipeline de generación»Para mantener todo al día, usamos estos comandos:
pnpm protocol:gen: Escribe el JSON Schema endist/.pnpm protocol:gen:swift: Genera los modelos para la app de macOS.pnpm protocol:check: Ejecuta los generadores y verifica que los cambios estén en el commit.- Validación continua: El servidor usa AJV para validar cada frame entrante.
Solución de problemas
Sección titulada «Solución de problemas»- Error en el handshake: Recuerda que el primer frame debe ser siempre una solicitud
connect. Si envías otro método antes, el Gateway rechazará la conexión. - Versión de protocolo: Si el servidor devuelve un error de versión, revisa que
minProtocolymaxProtocolcoincidan con lo que el Gateway espera. - Campos extra: La mayoría de los esquemas usan
additionalProperties: false. Si envías campos que no están definidos en el esquema de TypeBox, la validación fallará.
¿Necesitas ayuda con la integración? Prueba el AI Setup Assistant.
Próximos pasos
Sección titulada «Próximos pasos»OpenClaw Expert
Sigues atascado?
Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.