Passer au contenu principal

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

TypeBox est une bibliothèque de schémas conçue d’abord pour TypeScript. Nous l’utilisons pour définir le protocole WebSocket du Gateway (handshake, requête/réponse, événements serveur). Ces schémas alimentent la validation à l’exécution, l’export JSON Schema et la génération de code Swift pour l’application macOS. Une seule source de vérité ; tout le reste est généré. Si vous voulez le contexte de protocole de plus haut niveau, commencez par Architecture du Gateway.

Modèle mental (30 secondes)

Chaque message WS du Gateway est l’une de trois trames :
  • Requête : { type: "req", id, method, params }
  • Réponse : { type: "res", id, ok, payload | error }
  • Événement : { type: "event", event, payload, seq?, stateVersion? }
La première trame doit être une requête connect. Ensuite, les clients peuvent appeler des méthodes (par exemple health, send, chat.send) et s’abonner à des événements (par exemple presence, tick, agent). Flux de connexion (minimal) :
Client                    Gateway
  |---- req:connect -------->|
  |<---- res:hello-ok --------|
  |<---- event:tick ----------|
  |---- req:health ---------->|
  |<---- res:health ----------|
Méthodes + événements courants :
CatégorieExemplesNotes
Noyauconnect, health, statusconnect doit être en premier
Messageriesend, agent, agent.wait, system-event, logs.tailles effets de bord nécessitent idempotencyKey
Chatchat.history, chat.send, chat.abortWebChat les utilise
Sessionssessions.list, sessions.patch, sessions.deleteadministration des sessions
Automatisationwake, cron.list, cron.run, cron.runsréveil + contrôle Cron
Nœudsnode.list, node.invoke, node.pair.*WS du Gateway + actions de nœud
Événementstick, presence, agent, chat, health, shutdownpush serveur
L’inventaire discovery annoncé faisant autorité se trouve dans src/gateway/server-methods-list.ts (listGatewayMethods, GATEWAY_EVENTS).

Où vivent les schémas

  • Source : src/gateway/protocol/schema.ts
  • Validateurs à l’exécution (AJV) : src/gateway/protocol/index.ts
  • Registre annoncé des fonctionnalités/discovery : src/gateway/server-methods-list.ts
  • Handshake serveur + dispatch des méthodes : src/gateway/server.impl.ts
  • Client Node : src/gateway/client.ts
  • JSON Schema généré : dist/protocol.schema.json
  • Modèles Swift générés : apps/macos/Sources/OpenClawProtocol/GatewayModels.swift

Pipeline actuel

  • pnpm protocol:gen
    • écrit le JSON Schema (draft-07) dans dist/protocol.schema.json
  • pnpm protocol:gen:swift
    • génère les modèles Swift du Gateway
  • pnpm protocol:check
    • exécute les deux générateurs et vérifie que la sortie est validée dans le dépôt

Comment les schémas sont utilisés à l’exécution

  • Côté serveur : chaque trame entrante est validée avec AJV. Le handshake n’accepte qu’une requête connect dont les paramètres correspondent à ConnectParams.
  • Côté client : le client JS valide les trames d’événement et de réponse avant de les utiliser.
  • Discovery des fonctionnalités : le Gateway envoie une liste prudente features.methods et features.events dans hello-ok depuis listGatewayMethods() et GATEWAY_EVENTS.
  • Cette liste de discovery n’est pas un dump généré de chaque helper appelable dans coreGatewayHandlers ; certains RPC helpers sont implémentés dans src/gateway/server-methods/*.ts sans être énumérés dans la liste de fonctionnalités annoncée.

Exemples de trames

Connect (premier message) :
{
  "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"
    }
  }
}
Réponse hello-ok :
{
  "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
    },
    "policy": { "maxPayload": 1048576, "maxBufferedBytes": 1048576, "tickIntervalMs": 30000 }
  }
}
Requête + réponse :
{ "type": "req", "id": "r1", "method": "health" }
{ "type": "res", "id": "r1", "ok": true, "payload": { "ok": true } }
Événement :
{ "type": "event", "event": "tick", "payload": { "ts": 1730000000 }, "seq": 12 }

Client minimal (Node.js)

Plus petit flux utile : connexion + health.
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: 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();
  }
});

Exemple travaillé : ajouter une méthode de bout en bout

Exemple : ajouter une nouvelle requête system.echo qui renvoie { ok: true, text }.
  1. Schéma (source de vérité)
Ajoutez à 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 },
);
Ajoutez les deux à ProtocolSchemas et exportez les types :
  SystemEchoParams: SystemEchoParamsSchema,
  SystemEchoResult: SystemEchoResultSchema,
export type SystemEchoParams = Static<typeof SystemEchoParamsSchema>;
export type SystemEchoResult = Static<typeof SystemEchoResultSchema>;
  1. Validation
Dans src/gateway/protocol/index.ts, exportez un validateur AJV :
export const validateSystemEchoParams = ajv.compile<SystemEchoParams>(SystemEchoParamsSchema);
  1. Comportement serveur
Ajoutez un handler dans src/gateway/server-methods/system.ts :
export const systemHandlers: GatewayRequestHandlers = {
  "system.echo": ({ params, respond }) => {
    const text = String(params.text ?? "");
    respond(true, { ok: true, text });
  },
};
Enregistrez-le dans src/gateway/server-methods.ts (qui fusionne déjà systemHandlers), puis ajoutez "system.echo" à l’entrée listGatewayMethods dans src/gateway/server-methods-list.ts. Si la méthode est appelable par des clients opérateur ou nœud, classez-la aussi dans src/gateway/method-scopes.ts afin que l’application des portées et l’annonce des fonctionnalités hello-ok restent alignées.
  1. Regénération
pnpm protocol:check
  1. Tests + docs
Ajoutez un test serveur dans src/gateway/server.*.test.ts et mentionnez la méthode dans la documentation.

Comportement de la génération de code Swift

Le générateur Swift émet :
  • l’énumération GatewayFrame avec les cas req, res, event et unknown
  • des structs/énumérations de payload fortement typées
  • les valeurs ErrorCode, GATEWAY_PROTOCOL_VERSION et GATEWAY_MIN_PROTOCOL_VERSION
Les types de trame inconnus sont conservés comme payloads bruts pour la compatibilité ascendante.

Versionnement + compatibilité

  • PROTOCOL_VERSION se trouve dans src/gateway/protocol/version.ts.
  • Les clients envoient minProtocol + maxProtocol ; le serveur rejette les plages qui n’incluent pas son protocole actuel.
  • Les modèles Swift conservent les types de trame inconnus afin d’éviter de casser les anciens clients.

Motifs et conventions de schéma

  • La plupart des objets utilisent additionalProperties: false pour des payloads stricts.
  • NonEmptyString est la valeur par défaut pour les ID et les noms de méthode/événement.
  • Le GatewayFrame de premier niveau utilise un discriminateur sur type.
  • Les méthodes avec effets de bord nécessitent généralement un idempotencyKey dans les paramètres (exemple : send, poll, agent, chat.send).
  • agent accepte internalEvents en option pour le contexte d’orchestration généré à l’exécution (par exemple la transmission de fin de tâche subagent/Cron) ; traitez cela comme une surface d’API interne.

JSON de schéma en direct

Le JSON Schema généré se trouve dans le dépôt à dist/protocol.schema.json. Le fichier brut publié est généralement disponible à l’adresse :

Quand vous modifiez des schémas

  1. Mettez à jour les schémas TypeBox.
  2. Enregistrez la méthode/l’événement dans src/gateway/server-methods-list.ts.
  3. Mettez à jour src/gateway/method-scopes.ts quand le nouveau RPC nécessite une classification de portée opérateur ou nœud.
  4. Exécutez pnpm protocol:check.
  5. Validez le schéma regénéré + les modèles Swift.

Connexe