Concept internals

TypeBox

TypeBox is een schema-bibliotheek waarin TypeScript centraal staat. OpenClaw gebruikt deze om het Gateway WebSocket-protocol (handshake, verzoek/antwoord, servergebeurtenissen) te definiëren. Deze schema's sturen runtimevalidatie (AJV), export van JSON Schema en Swift-codegeneratie voor de macOS-app aan. Eén gezaghebbende bron; al het overige wordt gegenereerd.

Begin voor de protocolcontext op hoger niveau bij Gateway-architectuur.

Mentaal model (30 seconden)

Elk Gateway WS-bericht is een van drie frames:

  • Verzoek: { type: "req", id, method, params }
  • Antwoord: { type: "res", id, ok, payload | error }
  • Gebeurtenis: { type: "event", event, payload, seq?, stateVersion? }

Het eerste frame moet een connect-verzoek zijn. Daarna roepen clients methoden aan (bijv. health, send, chat.send) en abonneren ze zich op gebeurtenissen (bijv. presence, tick, agent).

Verbindingsverloop (minimaal):

text
Client                    Gateway  |---- req:connect -------->|  |<---- res:hello-ok --------|  |<---- event:tick ----------|  |---- req:health ---------->|  |<---- res:health ----------|

Veelgebruikte methoden en gebeurtenissen:

Categorie Voorbeelden Opmerkingen
Kern connect, health, status connect moet als eerste komen
Berichten send, agent, agent.wait, system-event, logs.tail methoden met neveneffecten vereisen idempotencyKey
Chat chat.history, chat.send, chat.abort WebChat gebruikt deze
Sessies sessions.list, sessions.patch, sessions.delete sessiebeheer
Automatisering wake, cron.list, cron.run, cron.runs besturing van activering en cron
Nodes node.list, node.invoke, node.pair.* Gateway WS plus node-acties
Gebeurtenissen tick, presence, agent, chat, health, shutdown serverpush

De gezaghebbende geadverteerde inventaris voor detectie bevindt zich in src/gateway/server-methods-list.ts (listGatewayMethods, GATEWAY_EVENTS).

Waar de schema's zich bevinden

  • Bronbarrel: packages/gateway-protocol/src/schema.ts exporteert domeinmodules onder packages/gateway-protocol/src/schema/*.ts opnieuw (frames.ts voor de enveloppen en handshake op het hoogste niveau, agent.ts, sessions.ts, cron.ts, enzovoort per functiegebied). protocol-schemas.ts is het centrale ProtocolSchemas-register dat schemanamen aan hun TypeBox-definities koppelt.
  • Runtimevalidators (AJV): packages/gateway-protocol/src/index.ts
  • Geïntroduceerd functie-/detectieregister: src/gateway/server-methods-list.ts
  • Serverhandshake en methodedispatch: src/gateway/server.impl.ts
  • Node-client: src/gateway/client.ts
  • Gegenereerd JSON Schema: dist/protocol.schema.json (builduitvoer, niet gecommit)
  • Gegenereerde Swift-modellen: apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift

Huidige pijplijn

  • pnpm protocol:gen schrijft JSON Schema (draft-07) naar dist/protocol.schema.json.
  • pnpm protocol:gen:swift genereert de Swift Gateway-modellen.
  • pnpm protocol:check voert beide generatoren uit en verifieert dat de Swift-uitvoer is gecommit (de JSON Schema-uitvoer is een door Git genegeerd buildartefact).

Hoe de schema's tijdens runtime worden gebruikt

  • Serverzijde: elk binnenkomend frame wordt met AJV gevalideerd. De handshake accepteert alleen een connect-verzoek waarvan de parameters overeenkomen met ConnectParams.
  • Clientzijde: de JS-client valideert gebeurtenis- en antwoordframes voordat deze worden gebruikt.
  • Functiedetectie: de Gateway verzendt in hello-ok een conservatieve lijst met features.methods en features.events, afkomstig uit listGatewayMethods() en GATEWAY_EVENTS.
  • Die detectielijst is geen gegenereerde dump van elke aanroepbare helper in coreGatewayHandlers; sommige helper-RPC's zijn geïmplementeerd in src/gateway/server-methods/*.ts zonder dat ze in de geadverteerde functielijst zijn opgenomen.

Voorbeeldframes

Verbinden (eerste bericht):

json
{  "type": "req",  "id": "c1",  "method": "connect",  "params": {    "minProtocol": 3,    "maxProtocol": 4,    "client": {      "id": "openclaw-macos",      "displayName": "macos",      "version": "1.0.0",      "platform": "macos 15.1",      "mode": "ui",      "instanceId": "A1B2"    }  }}

Hello-ok-antwoord:

json
{  "type": "res",  "id": "c1",  "ok": true,  "payload": {    "type": "hello-ok",    "protocol": 4,    "server": { "version": "dev", "connId": "ws-1" },    "features": { "methods": ["health"], "events": ["tick"] },    "snapshot": {      "presence": [],      "health": {},      "stateVersion": { "presence": 0, "health": 0 },      "uptimeMs": 0    },    "auth": { "role": "operator", "scopes": ["operator.read"] },    "policy": { "maxPayload": 1048576, "maxBufferedBytes": 1048576, "tickIntervalMs": 30000 }  }}

Verzoek en antwoord:

json
{ "type": "req", "id": "r1", "method": "health" }
json
{ "type": "res", "id": "r1", "ok": true, "payload": { "ok": true } }

Gebeurtenis:

json
{ "type": "event", "event": "tick", "payload": { "ts": 1730000000 }, "seq": 12 }

Minimale client (Node.js)

Kleinste bruikbare verloop: verbinden + statuscontrole.

ts
 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: 4,        maxProtocol: 4,        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();  }});

Uitgewerkt voorbeeld: een methode van begin tot eind toevoegen

Voorbeeld: voeg een nieuw system.echo-verzoek toe dat { ok: true, text } retourneert.

  1. Schema (gezaghebbende bron)

Voeg het volgende toe aan packages/gateway-protocol/src/schema/system.ts (of de best passende functiemodule):

ts
export const SystemEchoParamsSchema = Type.Object(  { text: NonEmptyString },  { additionalProperties: false },); export const SystemEchoResultSchema = Type.Object(  { ok: Type.Boolean(), text: NonEmptyString },  { additionalProperties: false },);

Importeer beide in packages/gateway-protocol/src/schema/protocol-schemas.ts, voeg ze toe aan het ProtocolSchemas-register en exporteer de afgeleide typen:

ts
  SystemEchoParams: SystemEchoParamsSchema,  SystemEchoResult: SystemEchoResultSchema,
ts
export type SystemEchoParams = Static<typeof SystemEchoParamsSchema>;export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
  1. Validatie

Exporteer in packages/gateway-protocol/src/index.ts een AJV-validator:

ts
export const validateSystemEchoParams = ajv.compile&lt;SystemEchoParams&gt;(SystemEchoParamsSchema);
  1. Servergedrag

Voeg een handler toe in src/gateway/server-methods/system.ts:

ts
export const systemHandlers: GatewayRequestHandlers = {  "system.echo": ({ params, respond }) => {    const text = String(params.text ?? "");    respond(true, { ok: true, text });  },};

Registreer deze in src/gateway/server-methods.ts (voegt systemHandlers al samen) en voeg vervolgens "system.echo" toe aan de listGatewayMethods-invoer in src/gateway/server-methods-list.ts.

Als de methode door operator- of node-clients kan worden aangeroepen, classificeer je deze ook in src/gateway/method-scopes.ts, zodat scopehandhaving en hello-ok-functieadvertenties op elkaar afgestemd blijven.

  1. Opnieuw genereren
bash
pnpm protocol:check
  1. Tests en documentatie

Voeg een servertest toe in src/gateway/server.*.test.ts en vermeld de methode in de documentatie.

Gedrag van Swift-codegeneratie

De Swift-generator produceert:

  • een GatewayFrame-enum met de cases req, res, event en unknown
  • sterk getypeerde payloadstructs/-enums
  • ErrorCode-waarden, GATEWAY_PROTOCOL_VERSION en GATEWAY_MIN_PROTOCOL_VERSION

Onbekende frametypen blijven voor voorwaartse compatibiliteit behouden als onbewerkte payloads.

Versiebeheer en compatibiliteit

  • PROTOCOL_VERSION bevindt zich in packages/gateway-protocol/src/version.ts (huidige waarde: 4).
  • Clients verzenden minProtocol en maxProtocol; de server weigert bereiken die het huidige protocol niet omvatten.
  • De Swift-modellen behouden onbekende frametypen om te voorkomen dat oudere clients niet meer werken.

Schemapatronen en conventies

  • De meeste objecten gebruiken additionalProperties: false voor strikte payloads.
  • NonEmptyString (Type.String({ minLength: 1 })) is de standaard voor ID's en namen van methoden/gebeurtenissen.
  • De GatewayFrame op het hoogste niveau gebruikt een discriminator op type.
  • Methoden met neveneffecten vereisen doorgaans een idempotencyKey in de parameters (voorbeeld: send, poll, agent, chat.send).
  • agent accepteert een optionele internalEvents voor tijdens runtime gegenereerde orkestratiecontext (bijvoorbeeld overdracht na voltooiing van een subagent-/cron-taak); behandel dit als een intern API-oppervlak.

Live schema-JSON

Het gegenereerde JSON Schema is een buildartefact en wordt niet in de repository gecommit. Het gepubliceerde onbewerkte bestand is doorgaans beschikbaar op:

Wanneer je schema's wijzigt

  1. Werk de TypeBox-schema's bij in de verantwoordelijke packages/gateway-protocol/src/schema/*.ts-module en registreer ze in protocol-schemas.ts.
  2. Registreer de methode/gebeurtenis in src/gateway/server-methods-list.ts.
  3. Werk src/gateway/method-scopes.ts bij wanneer de nieuwe RPC een scopeclassificatie voor operators of nodes nodig heeft.
  4. Voer pnpm protocol:check uit.
  5. Commit de opnieuw gegenereerde Swift-modellen.

Gerelateerd

Was this useful?
On this page

On this page