bots-garden/mini-mepublic Fork
⑂ v1.0.8
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 74efbf2 · on v1.0.8 · k33g · 3d ago
acp-client-tools.md · 206 lines · 11.2 KBmarkdown
Blame HistoryOpen raw

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.Tools et ToolDiscovery implémentent en Go le côté client de cette page ; examples/clienttools est 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
206
# 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](../how-to/offer-tools-from-an-acp-client.md).

## 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`](configuration.md#clés-de-acp) dans le fichier d'agent. |
| Espace de noms | `org.mini-me` |
| Mécanisme ACP | [Extensibility](https://agentclientprotocol.com/protocol/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.

```json
{"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é :

```json
"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 :

```json
{"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 :

```json
{"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](acp.md#requêtes-sessionrequest_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

```json
{"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) :

```json
{"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`](../../../demo.acp.sdk/go/README.fr.md) : `minime.Options.Tools` et `ToolDiscovery` implémentent en Go le côté client de cette page ; `examples/clienttools` est une liste de tâches proposée sous forme de deux outils.

## Voir aussi

- [Outils du client ACP — explication](../explanation/acp-client-tools.md) — pourquoi le protocole a cette forme
- [Proposer des outils depuis votre client ACP](../how-to/offer-tools-from-an-acp-client.md)
- [Surface Agent Client Protocol](acp.md)
- [Fichier de configuration — clés de `acp`](configuration.md#clés-de-acp)