ACP: Agent Client Protocol
ACP est un protocole JSON-RPC 2.0 sur stdio qui permet aux éditeurs et aux IDE de piloter un agent ZeroClaw en cours d’exécution en tant qu’hôte de session. JSON délimité par des sauts de ligne, léger, diffusable en continu, facile à connecter à un sous-processus.
Considérez-le comme « LSP pour agents » : l’éditeur lance zeroclaw acp, envoie des prompts via stdin et reçoit les mises à jour de session sur stdout.
Ce à quoi vous l’utiliseriez
- Une extension d’éditeur qui propose une commande « demander à l’agent à propos de ce fichier »
- Une intégration de multiplexeur de terminal qui ouvre un panneau latéral avec une session d’agent
- Un runner CI qui pilote l’agent de manière programmatique sans configuration complète du gateway.
- Tout ce qui souhaite des sessions d’agent sans HTTP et sans lier de port
Forme du protocole : v1
Tous les messages sont au format JSON-RPC 2.0 (délimités par des sauts de ligne). ZeroClaw implémente la version 1 du protocole.
initialize
Poignée de main. Retourne les capacités du serveur.
→ {"jsonrpc":"2.0","id":1,« méthode »:"initialiser"}
← {"jsonrpc":"2.0","id":1,"résultat":{
"protocolVersion": 1,
agentCapabilities: {
loadSession: true,
promptCapabilities: {image: false, audio: false, "embeddedContext": true},
mcpCapabilities: {http: false, sse: false},
sessionCapabilities: {reprendre: {}, « Fermer »: {}}
},
agentInfo: {
« nom »: zeroclaw-acp,
"title": ZeroClaw ACP,
version: 0.7.x
},
authMethods: [],
_meta: {
zeroclaw: {
"modèle par défaut": anthropic/claude-sonnet-4.6,
"maxSessions": 10,
`sessionTimeoutSecs`: 3600
}
}
}}
loadSession: true et sessionCapabilities: {"resume": {}, "close": {}} indiquent que la persistance de session est active. Si le store SQLite n’a pas pu être ouvert au démarrage, les trois sont absents ou définis sur false et session/load, session/resume et session/close renverront des erreurs SESSION_NOT_FOUND.
_meta.zeroclaw contient des champs d’extension spécifiques à ZeroClaw qui ne figurent pas dans la spécification ACP de base. Les clients qui implémentent uniquement la spécification de base peuvent ignorer cet objet.
promptCapabilities.embeddedContext: true signifie que les clients peuvent envoyer des blocs resource intégrés avec un blob en base64 dans session/prompt (voir ci-dessous). image et audio restent à false pour l’instant. Les ContentBlocks Image/Audio natifs d’ACP ne sont pas encore annoncés.
Le serveur répond toujours protocolVersion: 1. Si vous envoyez un protocolVersion: 0 côté client, vous recevez quand même 1 en retour, les clients v0 verront des erreurs d’analyse sur les nouvelles formes de messages ; voir compatibilité des versions ci-dessous.
session/new
Ouvrir une session d’agent isolée.
agentAlias indique quelle entrée [agents.<alias>] configurée utiliser. Ce champ est obligatoire lorsque plusieurs agents sont configurés ; lorsqu’un seul agent existe, il est sélectionné automatiquement et le champ peut être omis. L’alias accepte la forme camelCase agentAlias, la forme snake_case agent_alias ou la forme abrégée agent.
Lors de la connexion via le point de terminaison gateway WebSocket, l’URL de connexion peut également comporter un paramètre de requête ?agent=<alias>. Cette valeur est une valeur par défaut limitée à la connexion, et non une modification de configuration. La résolution d’alias pour session/new suit cet ordre de priorité :
agentAlias/agent_alias/agentexplicite dans les paramètressession/new- passerelle
?agent=<alias>sur l’URL WebSocket [acp].default_agent- seule entrée
[agents.<alias>]configurée lorsqu’il en existe exactement une - erreur lorsqu’aucun alias ne peut être résolu
Tout alias résolu, quelle que soit l’étape qui l’a sélectionné, doit désigner un agent activé et distribuable. Les alias inconnus et les agents configurés mais désactivés font échouer session/new avec -32602 INVALID_PARAMS. Un paramètre ?agent= vide ou composé uniquement d’espaces est considéré comme absent et passe à l’étape suivante.
zeroclaw acp autonome (sous-processus stdio) ne lit pas ?agent= ; utilisez plutôt un agentAlias explicite ou [acp].default_agent à la place.
Le paramètre facultatif cwd (alias : workspaceDir, workspace_dir) fixe la limite d’accès aux fichiers par session ; il devient le workspace_dir au sein de SecurityPolicy, à laquelle se conforment tous les outils de fichiers. Il ne déplace pas l’état persistant propre à l’agent : l’état en texte brut par agent (MEMORY.md, IDENTITY.md, SOUL.md) réside dans l’espace de travail de l’agent résolu (agent_workspace_dir(<alias>), c’est-à-dire l’espace de travail [agents.<alias>]), qui reste une racine autorisée supplémentaire ; les stockages SQLite partagés et l’état des tâches cron résident sous config.data_dir. Aucun de ces éléments ne constitue un workspace_dir unique au niveau du daemon.
→ {"jsonrpc":"2.0","id":2,« méthode »:"session/new","paramètres":{
agentAlias: "myagent",
"répertoire de travail courant": "/path/to/project"
}}
← {"jsonrpc":"2.0","id":2,"résultat":{
"sessionId": "s-ab12cd",
workspaceDir: "/path/to/project"
}}
cwd est canonisé lors de la prise en charge, le parcours ../ ne peut pas sortir de la racine prévue. Un cwd explicite est respecté exactement comme limite de la session, y compris un sous-répertoire plus restreint de l’espace de travail de l’agent.
Si cwd est omis, le serveur utilise le répertoire d’espace de travail de l’agent résolu (l’espace de travail de [agents.<alias>]), et non le répertoire de lancement du démon. Le seul cas particulier est un cwd dont la forme canonique est la racine d’installation elle-même : les clients tels que Thunderbolt envoient . comme espace réservé, ce qui se résout vers le répertoire de travail du démon. Cet unique espace réservé est traité comme “aucun cwd significatif” et utilise également comme solution de repli l’espace de travail propre à l’agent, afin que les téléversements et le bac à sable de l’outil restent en dehors de la racine du démon. Tout autre chemin explicite, y compris un chemin situé sous la racine d’installation, est fixé tel quel et n’est jamais élargi.
session/prompt
Envoyez une invite. La réponse est une séquence de notifications session/update renvoyées en flux, terminée par le résultat session/prompt.
Le paramètre prompt accepte soit une chaîne de caractères simple, soit un tableau de parties de contenu :
"prompt": "Résume les modifications du dernier commit."- Tableau : chaque élément est une partie de texte
{"text": "..."}ou un bloc de ressource ACP :- Ressource textuelle :
{"type": "resource", "resource": {"uri": "file:///path/to/file.rs", "text": "<file contents>"}}. Pièces jointes de l’éditeur avec notation@- et texte intégré. - Ressource blob :
{"type": "resource", "resource": {"uri": "file:///path/to/report.pdf", "mimeType": "application/pdf", "blob": "<base64>"}}. Inclusions binaires (PDF, DOCX, images, etc.). ZeroClaw décode le blob, l’écrit sous{session.workspaceDir}/uploads/(nommé par son SHA) et affiche un marqueur dans l’invite de l’agent ([Document: …]ou[IMAGE: …]pour image/*). La taille maximale décodée est de 10 MB ; les blobs dont le base64 est invalide ou qui dépassent cette taille renvoientINVALID_PARAMS.
- Ressource textuelle :
Les parties sont jointes par des doubles sauts de ligne dans l’ordre où elles apparaissent. L’ingestion de blob est indépendante du store (elle n’appelle pas le RPC file/attach). Le même utilitaire de matérialisation est utilisé lorsque les résultats d’outil MCP contiennent du contenu resource+blob (voir blobs de ressources embarqués MCP).
→ {"jsonrpc":"2.0","id":3,« méthode »:"session/prompt","paramètres":{
"sessionId": "s-ab12cd",
"invite": Résumez les modifications du dernier commit.
}}
← {"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{
"sessionId": "s-ab12cd",
mettre à jour: {sessionUpdate: agent_message_chunk, "contenu": {"type":« texte »,« texte »:« Le dernier commit... »}}
}}
← {"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{
"sessionId": "s-ab12cd",
mettre à jour: {sessionUpdate: "tool_call", toolCallId: "tc-1", "title": "shell",
"type": exécuter, "statut": "pending", rawInput: {...}}
}}
← {"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{
"sessionId": "s-ab12cd",
mettre à jour: {sessionUpdate: tool_call_update, toolCallId: "tc-1",
"statut": terminé, rawOutput: "..."}
}}
← {"jsonrpc":"2.0","id":3,"résultat":{
"sessionId": "s-ab12cd",
"stopReason": "end_turn",
"contenu": « Le dernier commit introduit... »
}}
stopReason vaut "end_turn" à la fin normale et "cancelled" lorsque le tour a été interrompu par session/cancel. Le signal de fin ACP est stopReason ; ZeroClaw inclut également la chaîne content finale actuelle pour les clients existants.
Erreurs :
| Code | Signification |
|---|---|
-32000 SESSION_NOT_FOUND | Aucune session active avec le sessionId indiqué |
-32002 SESSION_BUSY | Un tour de prompt est déjà en cours pour cette session, attendez qu’il se termine ou annulez-le d’abord |
-32602 INVALID_PARAMS | sessionId / prompt manquant ou mal formé |
-32603 INTERNAL_ERROR | La tâche de l’agent a paniqué ou le tour a échoué |
Notifications session/update (agent → client)
ZeroClaw envoie quatre types de notification session/update au cours d’un tour d’invite. Le discriminant est le champ sessionUpdate dans update :
valeur sessionUpdate | Lors de l’émission | Champs clés |
|---|---|---|
agent_message_chunk | Chaque jeton de texte en streaming | content.type = "text", content.text |
agent_thought_chunk | Jetons de raisonnement interne (lorsqu’activé) | content.type = "text", content.text |
tool_call | Appel d’outil initié | toolCallId, title, kind, status: "pending", rawInput |
tool_call_update | Appel d’outil terminé | toolCallId, status: "completed", rawOutput, content[] |
toolCallId sur tool_call et tool_call_update sont stables et corrélés, la mise à jour qui complète un appel porte le même toolCallId que celui qui l’a ouvert.
Le champ name sur tool_call_update est une extension ZeroClaw (non requise par la spécification ACP de base). Les clients peuvent l’utiliser pour l’affichage ; il peut être ignoré sans risque.
Livrer des fichiers au client (deliver_file)
Lorsque l’agent doit renvoyer un fichier de l’espace de travail pour téléchargement ou aperçu, il appelle l’outil deliver_file (path, mimeType facultatif, title facultatif). À la fin, ZeroClaw émet un tool_call_update normal dont les champs rawOutput / body restent petits (un court résumé lisible, aucun dump base64 et aucun marqueur de fin machine ; chaque champ de livraison transite de manière structurelle sur l’artefact d’outil typé). Le tool_call_update.title standard porte une étiquette de chat lisible : le title de l’appelant (n’importe quel texte, par ex. "Quarterly report") ou le nom de fichier par défaut. Le tableau content inclut en outre une ressource intégrée ACP standard :
{
"type": "contenu",
"contenu": {
"type": "ressource",
"ressource": {
"uri": "attachment://deliver/9f2c1a7b0e4d5f6a3b8c2d1e0f4a5b6c7d8e9f0a1b2c3d4e5f60718293a4b5c6d.pdf",
"mimeType": "application/pdf",
"blob": "<base64>"
}
}
}
Le uri est une identité opaque adressée par contenu : attachment://deliver/<sha256>.<ext>, le condensé SHA-256 complet en hexadécimal des octets du fichier. Il est sûr pour les URI et résistant aux collisions à la pleine force de condensé 256 bits, et n’est jamais dérivé du nom de fichier fourni par l’appelant. Ce même condensé complet est le nom de stockage sur disque dans uploads/, de sorte que des contenus distincts n’ont jamais d’alias vers un même fichier ou un même uri. Le même uri est porté structurellement sur le résultat de l’outil (champ JSON uri) et sur l’artefact d’outil typé ; il n’y a pas de remorque machine dans le texte exposé au modèle. Avant d’incorporer le blob, la couche ACP relit le fichier et recalcule ce condensé, refusant de joindre le fichier s’il ne correspond plus ; une substitution entre la validation et la livraison de l’outil est détectée, non approuvée. Les clients tels que Thunderbolt matérialisent le blob sortant et construisent une table de références de citations indexée par cet uri ; les agents doivent copier le uri retourné dans les citations <widget:document-result fileId="…"> / [N] et ne doivent pas inventer de préfixes. Le nom d’affichage dans le chat est le tool_call_update.title standard (le title de l’appelant, sinon le nom de fichier). Il n’y a pas de champ filename sur l’objet ACP resource, et le title est uniquement destiné à l’affichage, jamais au nom sur disque.
Le fichier doit rester dans l’espace de travail de la session (même environnement isolé que file_read) ; les fichiers trop volumineux (>10 Mo) sont rejetés par l’outil.
session/request_permission (agent → client, requête sortante)
Lorsqu’un outil nécessite l’approbation de l’utilisateur (via always_ask dans la configuration d’autonomie, ou les outils ask_user/escalate_to_human), ZeroClaw émet une requête JSON-RPC de l’agent vers le client. Le client doit répondre avec un résultat avant que l’appel d’outil ne se poursuive.
← {"jsonrpc":"2.0","id":zc-out-0,« méthode »:"session/request_permission","paramètres":{
"sessionId": "s-ab12cd",
options: [
{optionId: allow-once, « nom »: Autoriser une fois, "type": allow_once},
{optionId: allow-always,« nom »: « Toujours autoriser »,"type": allow_always},
{optionId: "reject-once", « nom »: « Rejeter », "type": reject_once}
],
toolCall: {
toolCallId: "approval-...",
"title": « Approuver le shell ? »,
"type": exécuter,
"statut": "pending",
rawInput: {outil: "shell", résumé: git status --short},
"contenu": [{"type": "contenu", "contenu": {"type": « texte », « texte »: git status --short}}]
}
}}
→ {"jsonrpc":"2.0","id":zc-out-0,"résultat":{
résultat: {résultat: sélectionné, optionId: allow-once}
}}
L’identifiant attribué par le serveur ("zc-out-N") est toujours une chaîne préfixée par zc-out-. La corrélation est directionnelle : chaque pair ne fait correspondre les réponses qu’avec sa propre table des requêtes en attente, de sorte que le même identifiant textuel peut être en cours de traitement indépendamment dans les deux directions.
Forme de la réponse :
{"outcome": {"outcome": "selected", "optionId": "<id>"}}, l’utilisateur a sélectionné une option{"outcome": {"outcome": "cancelled"}}, l’utilisateur a fermé l’invite
Si le client ne répond jamais (plantage, coupure réseau, fermeture de l’IDE par l’utilisateur), la requête expire après sessionTimeoutSecs et l’appel de l’outil est refusé.
ask_user utilise le même mécanisme session/request_permission, en associant les choices de la question aux options d’autorisation. Le mode libre (sans choix) d’ask_user n’est pas pris en charge tant que la RFD d’élicitation ACP n’est pas disponible. L’appel d’ask_user sans choices sur une session ACP échoue immédiatement avec une erreur claire.
session/cancel (extension ZeroClaw)
Interrompt un tour session/prompt en cours. Cette méthode est une extension ZeroClaw, et ne fait pas partie de la spécification ACP de base. Si ACP standardise ultérieurement une méthode session/cancel conflictuelle, ZeroClaw déplacera son extension vers _meta/session/cancel.
Cancel vs. stop : session/cancel interrompt un tour de prompt en cours et renvoie stopReason: "cancelled" avec tout le texte diffusé en streaming accumulé jusqu’au point d’interruption. session/stop met fin à la session de manière progressive une fois le tour en cours terminé : il attend la fin du tour au lieu de l’interrompre.
Le paramètre canonique est sessionId ; session_id est accepté comme alias de compatibilité.
→ {"jsonrpc":"2.0",« méthode »:"session/cancel","paramètres":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{
"sessionId": "s-ab12cd",
mettre à jour: {sessionUpdate: agent_message_chunk, "contenu": {"type":« texte »,« texte »:"partiel..."}}
}}
← {"jsonrpc":"2.0","id":3,"résultat":{
"sessionId": "s-ab12cd",
"stopReason": "cancelled",
"contenu": "partiel...\n\n[tour annulé via le client]"
}}
Si aucun tour n’est actif pour la session, l’annulation est une opération sans effet (noop), elle réussit silencieusement sans erreur. Cela suit la sémantique des notifications ACP : les notifications ne doivent pas produire d’erreurs.
session/stop (extension ZeroClaw)
Terminer proprement une session. Ne fait pas partie de la spécification ACP de base : spécifique à ZeroClaw. Si une future révision de la spécification ACP ajoute session/stop avec une sémantique différente, ceci sera renommé _meta/session/stop.
→ {"jsonrpc":"2.0","id":4,« méthode »:"session/stop","paramètres":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":4,"résultat":{"sessionId": "s-ab12cd", « arrêté »:true}}
session/update (client → serveur) (extension ZeroClaw)
ZeroClaw accepte également les notifications entrantes session/update (et l’alias hérité session/event) provenant du client pour l’injection d’événements personnalisés. Ne fait pas partie de la spécification ACP de base : spécifique à ZeroClaw. Si la spécification ACP définit ultérieurement un session/update entrant avec une sémantique différente, celui-ci sera renommé _meta/session/update.
Persistance de session
ZeroClaw persiste automatiquement les sessions ACP dans SQLite. Aucune configuration n’est requise, le magasin s’ouvre à <workspace_dir>/sessions/acp-sessions.db chaque fois que zeroclaw acp démarre ou qu’une connexion ACP WebSocket de passerelle est acceptée. Si le fichier ne peut pas être créé (système de fichiers en lecture seule, permissions incorrectes), le serveur se rabat sur des sessions uniquement en mémoire et loadSession renvoie false dans la réponse initialize.
Ce qui est conservé :
- Métadonnées de session :
sessionId,workspaceDir,created_at,last_activity - Historique complet de la conversation : chaque
ConversationMessageécrit après chaque tour desession/promptterminé, dans une transaction atomique par tour
Les sessions persistent après le redémarrage du processus. Une session créée lors d’une invocation zeroclaw acp peut être chargée ou reprise dans une invocation ultérieure, tant que le même workspace_dir est utilisé (et donc le même fichier acp-sessions.db).
Les sessions ne sont pas supprimées automatiquement. Utilisez session/close pour désactiver une session sans la supprimer, puis session/load ou session/resume pour la restaurer.
session/load (extension ZeroClaw)
Restaure une session précédemment persistée avec relecture complète de l’historique. Le serveur initialise l’agent avec l’historique de conversation stocké, puis renvoie cet historique au client sous forme d’une séquence de notifications session/update avant de retourner. Le client reçoit le même flux de mises à jour qu’il aurait vu si la session ne s’était jamais terminée.
→ {"jsonrpc":"2.0","id":5,« méthode »:"session/load","paramètres":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0",« méthode »:"session/mise à jour","paramètres":{
"sessionId": "s-ab12cd",
mettre à jour: {sessionUpdate: agent_message_chunk, "contenu": {"type":« texte »,« texte »:« Le dernier commit... »}}
}}
← ... (remaining stored messages replayed as session/update notifications)
← {"jsonrpc":"2.0","id":5,"résultat":{}}
Une fois que session/load a retourné, la session est active et prête à accepter les appels session/prompt.
Lors de la restauration d’une session persistée, le serveur réutilise l’alias propriétaire stocké uniquement si cet agent est toujours distribuable. Sinon, il effectue un repli en parcourant la chaîne [acp].default_agent contrôlée par l’opérateur → agent unique, en ignorant les alias désactivés au passage. Le paramètre ?agent= de la passerelle constitue uniquement une valeur par défaut pour session/new et ne rebinde pas la restauration.
session_id est accepté comme alias en snake_case pour sessionId.
Erreurs :
| Code | Signification |
|---|---|
-32000 SESSION_NOT_FOUND | Aucun enregistrement n’existe pour le sessionId indiqué dans le store |
-32001 SESSION_LIMIT_REACHED | max_sessions sessions actives déjà en cours |
-32602 INVALID_PARAMS | La session est déjà active, appelez d’abord session/close |
-32603 INTERNAL_ERROR | Échec de lecture SQLite |
session/resume (extension ZeroClaw)
Restaure une session précédemment persistée sans relecture de l’historique. L’agent est initialisé avec l’historique de conversation stocké afin de disposer du contexte complet pour le prochain tour, mais aucune notification session/update n’est émise. Utilisez cette option lorsque le client dispose déjà de l’historique d’une connexion précédente et n’a besoin que de restaurer l’état de l’agent.
→ {"jsonrpc":"2.0","id":5,« méthode »:"session/resume","paramètres":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":5,"résultat":{}}
Une fois que session/resume a renvoyé une réponse, la session est active et prête à accepter les appels session/prompt. Mêmes erreurs que session/load. La sélection de l’alias de restauration suit les mêmes règles de repli sur le propriétaire dispatchable que session/load.
Load vs. resume : utilisez session/load lors d’une reconnexion après une déconnexion inattendue, lorsque le client doit reconstruire son interface à partir de l’historique stocké. Utilisez session/resume lorsque le client dispose déjà de l’historique (par exemple, s’il l’a stocké localement) et qu’il a uniquement besoin de restaurer l’état de l’agent côté serveur.
session/close (extension ZeroClaw)
Désactive une session active : annule tout tour en cours, retire la session de l’ensemble actif en mémoire et désenregistre le canal de retour ACP. L’enregistrement de session dans le magasin SQLite n’est pas supprimé, la session peut toujours être restaurée ultérieurement avec session/load ou session/resume.
→ {"jsonrpc":"2.0","id":6,« méthode »:"session/close","paramètres":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":6,"résultat":{}}
session_id est accepté comme alias en snake_case pour sessionId.
Renvoie SESSION_NOT_FOUND (-32000) si la session n’est pas actuellement active (elle peut toujours exister dans le magasin).
Close vs. stop : session/close désactive la session tout en préservant son enregistrement persistant pour un rechargement ultérieur. session/stop supprime également la session de la mémoire mais a le même effet sur le store. Ni l’un ni l’autre ne supprime l’enregistrement SQLite.
Configuration
default_agent
Alias d’agent à utiliser lorsque session/new omet agentAlias et que plusieurs agents sont configurés. Lorsqu’il existe exactement un agent, il est sélectionné automatiquement quel que soit ce champ.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/acp et définissez le champ acp.default_agent.
zerocode
Dans le volet Config, définissez le champ acp.default_agent.
zeroclaw config
zeroclaw config set acp.default_agent <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_acp__default_agent=
max_sessions
Nombre maximal de sessions ACP simultanées. Par défaut : 10.
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/acp et définissez le champ acp.max_sessions.
zerocode
Dans le volet Config, définissez le champ acp.max_sessions.
zeroclaw config
zeroclaw config set acp.max_sessions <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_acp__max_sessions=
session_timeout_secs
Délai d’expiration des sessions inactives en secondes. Les sessions sans activité pendant cette durée peuvent être supprimées. Par défaut : 3600 (1 heure).
Posez-le sur n’importe quelle surface :
Tableau de bord de la passerelle
Ouvrez /config/acp et définissez le champ acp.session_timeout_secs.
zerocode
Dans le volet Config, définissez le champ acp.session_timeout_secs.
zeroclaw config
zeroclaw config set acp.session_timeout_secs <value>
Variable d’environnement
Exportez le remplacement (shells POSIX ; à placer dans ~/.bashrc, ~/.zshrc, .env ou un Dockerfile). Remplacez <alias> par l’alias littéral :
export ZEROCLAW_acp__session_timeout_secs=
default_agent est consulté lorsque session/new omet agentAlias et que plusieurs agents sont configurés ; s’il est absent et qu’il existe exactement une entrée [agents.<alias>], cet agent est sélectionné automatiquement.
Lors de l’exécution de zeroclaw acp en tant que sous-processus, la commande démarre le serveur de manière inconditionnelle. Lors de l’exécution en tant que démon, la passerelle expose ACP via WebSocket sur /acp sans configuration supplémentaire requise. Les clients de la passerelle peuvent ajouter ?agent=<alias> à cette URL afin que chaque agent configuré puisse être adressé depuis un client conforme à la spécification, avec un agent par point de terminaison ; l’authentification (Authorization, Sec-WebSocket-Protocol ou ?token=) est appliquée avant que la connexion ne soit mise à niveau, et le paramètre de requête n’accorde aucun accès au-delà de la sélection parmi les agents déjà configurés.
En cours
En tant que sous-processus (intégration IDE typique) :
sh
zeroclaw acp
Le binaire lit l’entrée standard, écrit sur la sortie standard et se termine sur EOF.
Via la passerelle du démon (distante ou sur le même hôte) :
Démarrez le daemon normalement. La passerelle expose toujours ACP sur WebSocket à l’adresse /acp, aucun indicateur de configuration supplémentaire n’est requis. Les clients se connectent directement : pour les installations multi-agents, utilisez une URL telle que ws://127.0.0.1:8080/acp?agent=myagent afin que session/new puisse omettre agentAlias, ou via zeroclaw-acp-bridge, qui fait le pont entre le protocole ACP stdio et le WebSocket de la passerelle :
sh
zeroclaw-acp-bridge
Le bridge lit l’adresse de la passerelle et le jeton d’authentification depuis la même configuration que le daemon. Lorsque le daemon s’exécute avec un répertoire de configuration autre que celui par défaut (par ex. --config-dir /tmp/zeroclaw), pointez le bridge vers le même répertoire :
sh
zeroclaw-acp-bridge --config-dir /tmp/zeroclaw
# ou de manière équivalente :
zeroclaw-acp-bridge --config-dir=/tmp/zeroclaw
Vous pouvez également fournir le bearer token directement via ZEROCLAW_ACP_BRIDGE_TOKEN si vous préférez ne pas dépendre du fichier de token mis en cache.
Compatibilité des versions
Les clients ACP v0 (utilisant la réponse d’initialisation à plat {streaming, maxSessions, ...} et la forme session/update kind: "text"|"tool_call") rencontreront des erreurs de désérialisation lors de la connexion à un serveur v1. Les discriminants et les formes d’enveloppe ont changé de manière incompatible. Étapes de mise à niveau :
- Utilisez
sessionUpdate(et nonkind) pour distinguer les notificationssession/update. - Analyser les résultats de
session/promptcomme{sessionId, stopReason, content}(et non{finished, usage}). - Implémenter la gestion des réponses
session/request_permission: le mécanisme d’approbation est passé d’une notification du serveur à un appel RPC traité par le client. - Supprimez le paramètre
systemPromptdesession/new, il n’est pas lu.
Sécurité
ACP hérite du niveau d’autonomie de la configuration en cours d’exécution. Lorsque [autonomy] level = "supervised", les appels d’outils à risque moyen déclenchent une approbation via le canal de retour ACP, une requête sortante session/request_permission que le client doit acquitter. En mode full, les appels d’outils s’exécutent sans approbation et workspace_only est implicitement désactivé (l’agent peut accéder à des chemins en dehors du cwd de la session) ; les forbidden_paths restent applicables.
Le cwd de session/new devient la limite de l’espace de travail de SecurityPolicy utilisée par tous les outils de fichiers et d’interpréteur de commandes pour cette session. L’invite système de l’agent reflète ce même espace de travail effectif de la session : le « Working directory » de l’invite est généré à partir de SecurityPolicy.workspace_dir (le cwd de la session, ou l’espace de travail de l’agent lorsque cwd est omis), tandis que l’identité et la personnalité de l’agent (IDENTITY.md, SOUL.md) sont chargées depuis l’espace de travail distinct de l’agent. Le modèle voit donc le répertoire à la racine duquel se trouvent réellement ses outils de fichiers et d’interpréteur de commandes.
Autorité des fichiers à deux racines. Le paramètre cwd de la session limite les chemins de l’outil de fichiers et de shell (lecture/écriture/énumération, CWD de lancement du shell et ressources intégrées uploads/) à ce répertoire. Cela ne fait pas de la session un environnement de confinement exclusif : l’espace de travail résolu de l’agent reste une racine autorisée, de sorte que les ressources propres à l’agent (compétences, identité et état propre à chaque agent sous [agents.<alias>]) restent accessibles quel que soit le cwd de la session. En d’autres termes, workspaceDir contrôle la racine des opérations sur les fichiers de la session, tandis que l’espace de travail de l’agent continue de servir de base aux ressources propres à l’agent et définies par la configuration. Lorsque cwd est omis (ou correspond à l’espace réservé de la racine d’installation), les deux coïncident, car la session est elle-même enracinée dans l’espace de travail de l’agent.
Mémoire
Les sessions ACP n’interagissent pas avec le système de mémoire persistante de l’agent. Il s’agit d’un choix de conception délibéré : ACP est destiné aux tâches de codage pilotées par l’IDE, et non à l’établissement de relations à long terme.
Ce dont héritent les sessions ACP depuis la configuration de l’agent : personnalité, compétences, profil de risque, profil d’exécution, fournisseur de modèle et tous les outils hors mémoire.
Ce que les sessions ACP excluent :
- Les outils de mémoire (
memory_recall,memory_store,memory_forget,memory_export,memory_purge) ne sont pas disponibles - Le rappel automatique de la mémoire (le préambule de contexte construit à partir de la mémoire à long terme à chaque tour) est désactivé
- La sauvegarde automatique des conversations dans la mémoire de l’agent est désactivée
Le contexte de session provient de l’historique de conversation persisté dans acp-sessions.db. Les sessions sont persistantes, reprenables et supprimables ; l’historique de session sert de contexte de travail, et non de mémoire à long terme de l’agent.
Cette séparation garantit que les conversations éphémères d’assistance au codage ne polluent pas la mémoire à long terme de l’agent, et que les connaissances sans rapport provenant des canaux de discussion ne se propagent pas dans les sessions ACP.
Référence du code
- Serveur ACP :
crates/zeroclaw-channels/src/orchestrator/acp_server.rs - ACP back-channel :
crates/zeroclaw-channels/src/acp_channel.rs - Stockage de session (SQLite) :
crates/zeroclaw-infra/src/acp_session_store.rs - Point de terminaison ACP-over-WebSocket de la passerelle :
crates/zeroclaw-gateway/src/acp.rs - Application des chemins par session :
crates/zeroclaw-config/src/policy.rs(SecurityPolicy::from_config),crates/zeroclaw-runtime/src/agent/agent.rs(from_config_with_session_cwd_and_mcp) - Détection/backends de sandbox au niveau de l’OS :
crates/zeroclaw-runtime/src/security/detect.rs,landlock.rs,bubblewrap.rs,seatbelt.rs
Voir aussi
- Chaînes → Vue d’ensemble
- Tools → MCP : clients fournissant des outils à l’agent ; ACP est l’inverse
- Sécurité → Autonomie
- Sécurité → Aperçu