Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Transport de socket RPC

Le daemon expose une interface JSON-RPC 2.0 via un flux IPC local, un socket de domaine Unix sous Unix et un tube nommé (named pipe) sous Windows. Il s’agit du transport principal pour les clients locaux comme zerocode. La passerelle HTTP/WS demeure pour les webhooks, le tableau de bord web et les consommateurs REST distants.

Résolution de point de terminaison

Chaque répertoire de données dispose de son propre point de terminaison, de sorte que plusieurs instances de démon sur la même machine n’entrent pas en collision. Le répertoire de données est dérivé du répertoire de configuration (--config-dir / ZEROCLAW_CONFIG_DIR, ou ZEROCLAW_DATA_DIR).

OSPoint de terminaison par défaut
Linux<data_dir>/daemon.sock (socket de domaine Unix)
macOS<data_dir>/daemon.sock (socket de domaine Unix)
Windows\\.\pipe\zeroclaw-<hash><hash> est dérivé de data_dir

Remplacez par la variable d’environnement ZEROCLAW_SOCKET sur l’une ou l’autre plateforme :

sh

export ZEROCLAW_SOCKET=/tmp/my-zeroclaw.sock
zeroclaw daemon

PowerShell

$env:ZEROCLAW_SOCKET = '\\.\pipe\my-zeroclaw'
zeroclaw daemon

Protocole de communication

NDJSON (JSON délimité par des sauts de ligne). Chaque ligne est un message JSON-RPC 2.0 complet. Aucun cadrage HTTP, aucun préfixe de longueur. Le cadrage est identique sur toutes les plateformes ; les canaux nommés transportent le même flux d’octets que les sockets Unix.

{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":1},"id":1}\n
{"jsonrpc":"2.0","result":{"protocolVersion":1,"serverVersion":"0.8.5"},"id":1}\n

Établissement de connexion

Le premier appel RPC doit être initialize. Le démon rejette toutes les autres méthodes jusqu’à ce que initialize réussisse. Une incompatibilité de version du protocole produit une erreur structurée avec le code -32011.

{
  "jsonrpc": "2.0",
  « méthode »: "initialiser",
  "paramètres": {
    "protocolVersion": 1
  },
  "id": 1
}

Le point de terminaison ne nécessite pas de jeton d’appairage. Le contrôle d’accès est géré par le système d’exploitation :

  • Unix : le socket est 0o600, le répertoire parent est 0o700.
  • Windows : l’ACL du canal nommé est par défaut définie sur l’utilisateur créateur et SYSTEM.

Méthodes

MéthodeDirectionDescription
initializeclient -> daemonAuthentifiez-vous et négociez la version du protocole
session/newclient -> daemonCréer une session d’agent (nécessite agentAlias ; cwd et sessionId sont facultatifs ; keep_siblings, également facultatif, désactive l’éviction des sessions sœurs inactives du même mode pour les clients gérant eux-mêmes le cycle de vie de leurs sessions sœurs)
session/closeclient -> daemonFermer et nettoyer une session
session/promptclient -> daemonExécuter un tour (diffusé via les notifications session/update)
session/cancelclient -> daemonAnnuler un tour en cours
statusclient -> daemonVersion du serveur, version du protocole, liste des sessions actives
session/updatedémon -> clientNotification en streaming pendant un tour (fragments de texte, appels d’outils, approbations)
elicitation/createdémon -> clientDemander une saisie interactive pour les flux ask-user et poll

Requêtes bidirectionnelles

Chaque partie peut envoyer une requête sur le socket établi. Le récepteur doit répondre avec le même id et exactement l’un de result ou error. Chaque pair utilise sa propre séquence zc-out-<number> pour les requêtes sortantes ; le préfixe ne constitue pas un espace de noms globalement unique. La corrélation reste directionnelle : chaque pair ne met en correspondance les réponses qu’avec sa propre table des requêtes en attente ; le même ID textuel peut donc être en vol indépendamment dans des directions opposées.

{"jsonrpc":"2.0",« méthode »:"elicitation/create","paramètres":{"message":"Continuer ?"},"id":zc-out-0}
{"jsonrpc":"2.0","résultat":{action:"accepter","contenu":{"réponse":"oui"}},"id":zc-out-0}

Une réponse explicite "result": null est une réussite et résout tout de même l’appelant en attente. Un objet error le résout comme un échec. Si le pair ne répond pas, l’opération ask-user ou poll à l’origine conserve son comportement actuel en matière de délai d’attente.

Chaque trame doit être un objet JSON avec "jsonrpc": "2.0". Les requêtes doivent contenir une chaîne de caractères method ; si params est présent, il doit être un objet ou un tableau. Les réponses doivent contenir un id de type chaîne, numérique ou null, ainsi qu’exactement un membre de réponse. Un JSON non valide produit -32700 (erreur d’analyse). Une enveloppe mal formée de type requête produit -32600 (requête non valide), en utilisant son identifiant de requête valide lorsqu’il est possible de le récupérer. Une enveloppe mal formée de type réponse est consignée sans le contenu de la trame et ignorée sans réponse, car renvoyer son identifiant pourrait faire aboutir une requête sans rapport dans la direction opposée. Les enveloppes dont la direction est ambiguë utilisent id: null. Les identifiants de réponse valides mais inconnus sont également consignés et ignorés plutôt que de recevoir une réponse, ce qui empêche les boucles de réponses.

Activer le streaming

session/prompt retourne le résultat final lorsque le tour se termine. Pendant l’exécution, le démon envoie des notifications session/update avec des événements incrémentaux :

{"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{"sessionId":"...","type":agent_message_chunk,« texte »:Bonjour}}
{"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{"sessionId":"...","type":"tool_call",toolCallId:tc_1,« nom »:bash,rawInput:{...}}}
{"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{"sessionId":"...","type":"résultat_de_l'outil",toolCallId:tc_1,« nom »:bash,rawOutput:"..."}}

Types d’événements : agent_message_chunk, agent_thought_chunk, tool_call, tool_result, approval_request.

Mode éphémère

zeroclaw daemon --ephemeral suit les clients connectés et s’arrête automatiquement lorsque le dernier se déconnecte (après un délai de grâce de 1 seconde). Une reconnexion pendant le délai de grâce annule l’arrêt. Le daemon ne se terminera pas tant qu’au moins un client ne s’est pas connecté.

Les démons démarrés sans --ephemeral ignorent le nombre de clients et s’exécutent jusqu’à leur arrêt explicite.

Sécurité

  • Répertoire du socket Unix : 0o700 (propriétaire uniquement)
  • Fichier de socket Unix : 0o600 (propriétaire uniquement)
  • Canal nommé Windows : l’ACL par défaut accorde l’accès à l’utilisateur créateur et à SYSTEM
  • SO_PEERCRED sous Linux fournit le PID et l’UID du processus de connexion pour la journalisation d’audit ; Windows enregistre pipe:local comme étiquette du pair

Test rapide

Démarrez le daemon dans un terminal :

sh

zeroclaw daemon

Dans un second terminal sous Unix, connectez-vous avec socat :

sh

socat READLINE UNIX-CONNECT:~/.zeroclaw/data/daemon.sock

Collez les lignes une par une :

{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":1},"id":1}
{"jsonrpc":"2.0","method":"status","params":{},"id":2}

Sous Windows, utilisez n’importe quel client de canal nommé (PowerShell [System.IO.Pipes.NamedPipeClientStream], nc via WSL, ou exécutez simplement zerocode).

Composants internes

La couche de répartition se trouve dans crates/zeroclaw-runtime/src/rpc/ :

FichierRôle
transport.rsTrait RpcTransport
turn.rsexecute_turn() exécuteur de tour partagé
session.rsRpcSession, SessionStore
dispatch.rsRoutage de méthode RpcDispatcher
local.rsLocalTransport + écouteur (socket Unix / canal nommé Windows)
wss.rsWSS (WebSocket Secure) transport + accepteur TLS
attachments.rsTraitement des téléchargements de fichiers, déduplication, génération de marqueurs

Le trait RpcTransport est conçu de sorte que des transports supplémentaires (vsock, IPC personnalisé) s’intègrent sans toucher à la logique de dispatch ou de session. Le module local.rs encapsule les primitives Unix et Windows derrière une seule structure LocalTransport à l’aide de tokio::io::split, de sorte que la boucle de lecture/écriture soit partagée entre les deux plateformes.