Référence : outils du client ACP (spécification)
Le protocole qu'un client ACP suit pour proposer ses propres outils à mini-me. En mode ACP (
mm -acp), mm découvre les outils qu'un client expose sous forme de méthodes d'extension, et le modèle les appelle comme ses outils intégrés. Cette page est la spécification qu'un client implémente ; les étapes en Go sont dans Proposer des outils depuis votre client ACP.
Périmètre
| Élément | Valeur |
|---|---|
| Front end | Mode ACP seulement (mm -acp). Le terminal, la fenêtre (-tui) et -p n'ont pas de client : aucun outil client n'y existe. |
| Configuration | acp.clientTools dans le fichier d'agent. |
| Espace de noms | org.mini-me |
| Mécanisme ACP | Extensibility : méthodes dont le nom commence par _, capacités dans _meta. ACP ne définit aucun moyen de décrire les paramètres d'une méthode ; cette page définit celui de mm. |
| Qui appelle qui | mm (l'agent) envoie les requêtes ; le client y répond. |
Identifiants
| Identifiant | Nature | Où |
|---|---|---|
org.mini-me/tools |
clé de _meta |
clientCapabilities._meta de la requête initialize. |
_org.mini-me/tools/list |
méthode de requête, agent → client | Découverte request seulement. |
org.mini-me/sessionId |
clé de _meta |
params._meta de chaque appel d'outil. |
client_<name> |
nom d'outil | Le nom que voit le modèle pour l'outil <name>. |
Description d'un outil
Un objet JSON par outil. Le même objet sert dans les deux modes de découverte.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name |
chaîne | oui | Le nom de l'outil, unique dans la liste. Le modèle voit client_<name>, où chaque caractère hors de [A-Za-z0-9] devient _, les suites de _ sont réduites à un seul, et les _ en début et en fin sont retirés (open buffers → client_open_buffers). |
description |
chaîne | non | Ce que le modèle lit pour décider quand appeler l'outil. Absente : Tool provided by the editor (<method>). |
method |
chaîne | oui | La méthode d'extension que mm appelle pour cet outil. Doit commencer par _. Forme conseillée : _<dns-inversé>/<chemin>, par exemple _com.example/workspace/buffers. |
inputSchema |
objet | non | Schéma JSON des arguments. S'il est présent, type doit valoir "object" (ou être absent). Absent : l'outil n'a pas de paramètre. |
Le schéma tel que le voit le modèle
Le schéma est transmis au modèle avec ces modifications (les mêmes que pour les outils MCP) :
Dans inputSchema |
Déclaré au modèle |
|---|---|
required |
Retiré du schéma ; les noms sont ajoutés à la description sous la forme Required parameters: a, b. mm les vérifie avant l'appel. |
enum |
Retiré ; les valeurs sont ajoutées à la description de la propriété sous la forme One of: x, y. |
additionalProperties: false, $schema |
Retirés. |
type, properties |
Toujours présents : type: "object", properties: {} s'ils manquent. |
Validation d'une liste
Chaque entrée est validée séparément. Une entrée invalide est ignorée et une ligne est écrite sur le stderr de mm ([acp] client tools: entry <i> skipped: <raison>) ; les autres entrées sont gardées, et la session n'échoue jamais à cause de la liste.
| Raison | Cause |
|---|---|
not a tool description: … |
L'entrée n'est pas un objet JSON de la forme ci-dessus. |
no name |
name est absent ou vide. |
method "…" must start with "_" (an ACP extension method) |
method est absente ou n'est pas une méthode d'extension. |
inputSchema.type must be "object", got … |
Le schéma décrit autre chose qu'un objet. |
duplicate tool name "client_…" |
Deux entrées donnent le même nom côté modèle ; la première est gardée. |
Les outils sont triés par nom côté modèle.
Découverte
Le mode est fixé par acp.clientTools.discovery dans le fichier d'agent. Le client doit utiliser le mode que nomme le fichier d'agent.
Mode meta (par défaut)
Le client met la liste dans sa requête initialize. La liste vaut pour toutes les sessions de la connexion.
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{
"protocolVersion":1,
"clientInfo":{"name":"my-client","version":"1.0.0"},
"clientCapabilities":{
"_meta":{
"org.mini-me/tools":[
{"name":"open_buffers",
"description":"List the files open in the editor.",
"method":"_com.example/workspace/buffers",
"inputSchema":{"type":"object",
"properties":{"language":{"type":"string","description":"Only the buffers of this language."}},
"required":["language"]}}
]
}
}
}}
En mode meta, la valeur true à la place d'une liste ne donne aucun outil, et la ligne stderr "org.mini-me/tools" is not a list of tools; a client that answers _org.mini-me/tools/list needs acp.clientTools.discovery: request.
Mode request
Le client annonce seulement la capacité :
"clientCapabilities":{"_meta":{"org.mini-me/tools":true}}
mm envoie alors _org.mini-me/tools/list pendant qu'il traite session/new, session/load et session/resume, avant d'y répondre. Le client doit donc répondre à cette requête pendant qu'il attend sa propre réponse à session/new (les SDK ACP traitent chaque requête entrante en parallèle).
Requête :
{"jsonrpc":"2.0","id":7,"method":"_org.mini-me/tools/list",
"params":{"sessionId":"20261110-224507-1f3a9c2e","cwd":"/home/me/project"}}
| Paramètre | Type | Description |
|---|---|---|
sessionId |
chaîne | L'id de la session en cours d'ouverture ; la réponse à session/new qui le porte n'est pas encore envoyée. |
cwd |
chaîne | Le répertoire de travail de la session, tel que le client l'a envoyé. |
Réponse :
{"jsonrpc":"2.0","id":7,"result":{"tools":[
{"name":"open_buffers","method":"_com.example/workspace/buffers"}
]}}
| Résultat | Effet |
|---|---|
Un tableau tools |
Ces outils, validés comme ci-dessus, pour cette session seulement. |
Une erreur, pas de réponse dans le délai acp.clientTools.timeout, ou pas de tableau tools |
Aucun outil client pour cette session ; une ligne sur stderr ; la session s'ouvre normalement. |
Chaque session redemande la liste : deux sessions d'une même connexion peuvent avoir des outils différents.
Appel d'un outil
Quand le modèle appelle client_<name>, mm envoie une requête à la method de l'outil.
Avant la requête
| Vérification | Résultat en cas d'échec |
|---|---|
Chaque paramètre de required est présent dans les arguments du modèle. |
Aucune requête n'est envoyée ; le modèle lit [client tool error: missing required parameters: a, b]. |
Permission : avec acp.clientTools.permissions: ask, ou avec auto quand yolo vaut false, mm envoie d'abord session/request_permission au client (voir Requêtes session/request_permission envoyées). Le titre de l'appel d'outil est client: <name>, son type other. |
Le modèle lit [client_<name> rejected by user]. |
Requête
{"jsonrpc":"2.0","id":12,"method":"_com.example/workspace/buffers",
"params":{"language":"go",
"_meta":{"org.mini-me/sessionId":"20261110-224507-1f3a9c2e"}}}
| Paramètre | Description |
|---|---|
| les arguments du modèle | Copiés tels que le modèle les a envoyés, au premier niveau de params. |
_meta["org.mini-me/sessionId"] |
La session à laquelle appartient l'appel. Un _meta que le modèle aurait mis dans ses arguments est remplacé. |
Réponse
Deux formes sont acceptées.
Liste de contenus (la forme du résultat de tools/call dans MCP) :
{"jsonrpc":"2.0","id":12,"result":{
"content":[{"type":"text","text":"main.go\nutil.go"}],
"isError":false}}
| Champ | Type | Effet |
|---|---|---|
content |
tableau | Le text de chaque bloc de type text, concaténés sans séparateur, est ce que lit le modèle. Un bloc d'un autre type est remplacé par [client tool: non-text content of type <type> skipped]. |
isError |
booléen, optionnel | true : l'appel est un appel en échec ; le modèle lit [client tool error: <le texte>]. |
Toute autre valeur JSON : une chaîne JSON est donnée au modèle sans les guillemets ; toute autre valeur (objet, nombre, tableau sans content) est donnée sous forme de texte JSON.
Erreurs
| Situation | Ce que lit le modèle | Tour |
|---|---|---|
Erreur JSON-RPC (par exemple -32601 Method not found) |
[client tool error: {"code":-32601,"message":"Method not found"}] |
Continue. |
Pas de réponse dans le délai acp.clientTools.timeout |
[client tool error: …], avec l'erreur du SDK pour le délai dépassé. mm envoie $/cancel_request pour la requête. |
Continue. |
Le tour est annulé (session/cancel) |
mm envoie $/cancel_request pour la requête. |
Se termine comme annulé. |
isError: true |
[client tool error: <texte>] |
Continue. |
Chaque résultat, en échec ou non, est coupé à maxOutput caractères (début et fin conservés), signalé à l'éditeur comme fin de l'appel d'outil (session/update, tool_call_update), et compté par le détecteur de boucles comme tout appel d'outil : le même appel répété avec la même réponse est signalé, puis arrête le tour.
Configuration
| Clé | Défaut | Effet sur ce protocole |
|---|---|---|
acp.clientTools.enabled |
true |
false : org.mini-me/tools est ignoré ; pas de requête de liste, pas d'outil client. |
acp.clientTools.discovery |
meta |
meta ou request, comme décrit plus haut. |
acp.clientTools.permissions |
auto |
auto : un appel ne demande la permission au client que si yolo vaut false. ask : chaque appel la demande. |
acp.clientTools.timeout |
30s |
Limite d'un appel d'outil, et de la requête de liste. |
Lignes de journal (stderr de mm)
| Ligne | Quand |
|---|---|
[acp] client tools (meta): client_a, client_b |
Après initialize, en mode meta, quand le client a annoncé une liste. |
[acp] session <id> client tools (request): client_a |
Après une réponse à la requête de liste. |
[acp] client tools: … |
Une entrée ignorée, une requête de liste en échec, un true seul en mode meta. |
Implémentations
demo.acp.sdk/go:minime.Options.ToolsetToolDiscoveryimplémentent en Go le côté client de cette page ;examples/clienttoolsest une liste de tâches proposée sous forme de deux outils.
Voir aussi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
|