turbo-editors/turbo-jspublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-js.git
git clone ssh://git@rickub.com/turbo-editors/turbo-js.git

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

📦 Turbo JS 91999d1 · on main · k33g · 12h ago
talk-to-an-agent.md · 177 lines · 11.9 KBmarkdown
Blame HistoryOpen raw

Dialoguer avec un agent de code depuis l'éditeur

Ce guide montre comment pointer Turbo JS vers un agent qui parle l'Agent Client Protocol, ouvrir une fenêtre dessus, et tenir une conversation sur le code en cours d'édition. Il suppose que Turbo JS est déjà lancé dans un projet.

Turbo JS est un client ACP. Il lance l'agent comme processus fils et lui parle en JSON-RPC sur son entrée et sa sortie standard — le même montage que Zed, donc un agent qui fonctionne là-bas fonctionne ici.

Déclarer un agent à l'éditeur

Les agents sont listés dans acp.toml. Choisissez Agent ▸ Create agents file et l'éditeur écrit un fichier de départ dans .turbo-js/acp.toml, puis l'ouvre.

Un agent, c'est un bloc [[agent]] :

[[agent]]
name    = "Bob (llama.cpp)"
command = "docker"
args    = ["agent", "serve", "acp", ".turbo-js/agent.yaml"]
env     = { TELEMETRY_ENABLED = "false" }

name est ce qu'affiche le menu Agent et le nom de la fenêtre. command et args disent comment démarrer l'agent. C'est tout — le fichier est relu à chaque ouverture de fenêtre, donc on ne redémarre jamais l'éditeur pour essayer une modification.

Listez-en autant que vous voulez. Chacun devient une ligne du menu, et chaque fenêtre ouverte depuis cette ligne est un processus distinct avec sa propre conversation.

Placer la configuration de l'agent à côté

La plupart des agents ont leur propre fichier de configuration, et .turbo-js/ est un endroit raisonnable pour le garder afin qu'il voyage avec le projet. Pour docker agent, l'enregistrer sous .turbo-js/agent.yaml correspond aux args ci-dessus :

providers:
  llamacpp:
    api_type: openai_chatcompletions
    base_url: http://localhost:8080/v1

models:
  mellum2:
    provider: llamacpp
    model: JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
    temperature: 0.7
    provider_opts:
      context_size: 262144

agents:
  root:
    model: mellum2
    description: A helpful AI assistant running on a local llama.cpp server
    instruction: |
      You name is Bob 🤓, you are a knowledgeable code assistant.
      Be helpful, accurate, and concise in your responses.
      You have access to the local filesystem and shell: use these tools
    toolsets:
      - type: filesystem
      - type: shell

Ouvrir une fenêtre dessus

Appuyez sur Alt-A, ou choisissez Agent dans la barre de menus, puis l'agent par son nom.

Une fenêtre s'ouvre, coupée en deux : la conversation en haut, une zone de saisie en bas. L'agent est démarré à l'ouverture de la fenêtre et arrêté à sa fermeture.

┌ Bob (llama.cpp) ───────────────────────────────[■]┐
│ ‣ Vous                                            │
│   Que fait buildMenus ?                           │
│                                                   │
│ ‣ Shell  ls -1 src/                      ✓ fini   │
│   menus.js                                        │
│                                                   │
│ ‣ Bob                                             │
│   Elle assemble la barre de menus. Sa forme :     │
│                                                   │
│   ```javascript                                   │
│   export function buildMenus(app) {               │
│     return new MenuBar(...app.allMenus());        │
│   }                                               │
│   ```                                             │
├───────────────────────────────────────────────────┤
│ > _                                               │
└───────────────────────────────────────────────────┘

Le code que l'agent envoie dans un bloc délimité est coloré par les mêmes analyseurs que l'éditeur utilise pour les fichiers : une réponse en JavaScript est colorée comme du JavaScript, une réponse en shell comme du shell. Un bloc annonçant un langage que l'éditeur ne colore pas est laissé brut plutôt que deviné.

Tenir la conversation

Touche Effet
Entrée Envoyer ce qui est saisi
Alt-Entrée Passer à la ligne au lieu d'envoyer
Tab Passer de la conversation à la zone de saisie, et retour
PgUp PgDn Faire défiler la conversation d'un écran
Échap Arrêter le tour en cours
Ctrl-W Fermer la fenêtre, et arrêter l'agent avec elle

Pendant que l'agent répond, sa réponse s'affiche au fil de l'écriture plutôt que d'un bloc, et la règle entre les deux zones fait tourner un indicateur à côté du mot thinking. Échap l'interrompt — l'agent reçoit l'ordre de s'arrêter, et ce qu'il avait déjà dit reste dans la fenêtre.

Utiliser les commandes propres à l'agent

Certains agents répondent à des commandes — /compact, /web, /plan — et disent à l'éditeur lesquelles. Tapez / comme premier caractère de la zone de saisie et la liste s'ouvre par-dessus la conversation : chaque commande, ce qu'elle fait, et entre chevrons ce qu'elle attend après son nom.

Continuez à taper pour la réduire, pour vous déplacer, puis Tab pour compléter. Une commande qui attend quelque chose est complétée avec une espace après elle, prête à recevoir la suite ; appuyez sur Entrée quand la ligne dit ce que vous voulez. Si rien n'apparaît quand vous tapez /, l'agent n'a annoncé aucune commande — Agent ▸ Agent status le dit — et / n'est qu'un caractère.

Désigner un fichier à l'agent

Tapez @ n'importe où dans la zone de saisie et les fichiers du projet apparaissent. Tapez quelques lettres du nom du fichier pour réduire la liste, Tab pour prendre celui en surbrillance :

> explique ce que fait @src/menus.js

Quand vous appuyez sur Entrée, l'agent reçoit le fichier, et pas seulement son nom : son texte quand l'agent accepte le contexte incorporé, un lien vers lui sinon. Si le fichier est ouvert dans l'éditeur avec des modifications non enregistrées, c'est votre version non enregistrée qui part. La ligne reste dans la conversation telle que vous l'avez tapée.

Plusieurs fichiers dans une invite, c'est plusieurs @. Un mot qui commence par @ mais n'est pas un fichier — une adresse électronique — est laissé en texte.

Récupérer un morceau de la conversation

Appuyez sur Tab pour placer le curseur dans la conversation. La règle change et annonce ce que font désormais les touches.

Touche Effet
PgUp PgDn Déplacer le curseur dans ce qui a été dit
Shift-↑ Shift-↓ Sélectionner des lignes entières
Glisser à la souris Pareil, à la main
Ctrl-C Copier
Échap Abandonner la sélection
Tab Revenir à la zone de saisie

Sans rien de sélectionné, Ctrl-C copie le bloc sur lequel est le curseur — un bloc de code délimité, un paragraphe, la sortie d'un outil — sans le libellé de l'interlocuteur au-dessus ni la phrase qui suit. C'est presque toujours ce que vous vouliez, et cela évite de le sélectionner à la main.

Ce qui est copié va dans deux presse-papiers : celui de l'éditeur, pour que Shift-Ins le colle dans un fichier ouvert ici, et celui du système, pour que Ctrl-V le colle n'importe où ailleurs. L'indentation d'affichage de la conversation est retirée, donc le code collé arrive collé à la marge.

La moitié « système » passe par votre terminal (une séquence d'échappement nommée OSC 52). La plupart des terminaux la gèrent ; quelques-uns la refusent par sécurité, et certains demandent de l'activer. Si Ctrl-V ailleurs ne donne rien, c'est là qu'il faut regarder — le presse-papiers de l'éditeur contient le texte dans tous les cas.

Répondre quand l'agent demande la permission

Un agent doté d'un outil shell ou d'un outil de fichiers demande avant de s'en servir. Une boîte de dialogue nomme l'outil et la commande exacte, et propose les choix que l'agent lui-même a proposés — d'ordinaire Autoriser, Autoriser et retenir mon choix, et Passer.

┌────────── Bob (llama.cpp) veut lancer ──────────┐
│                                                 │
│  Shell                                          │
│    ls -1                                        │
│                                                 │
│    [ Autoriser ] [ Toujours ]  [ Passer ]       │
└─────────────────────────────────────────────────┘

Toujours est retenu par l'agent, pas par l'éditeur : ce que cela couvre et combien de temps cela dure sont l'affaire de l'agent. Échap équivaut à Passer.

Rien ne s'exécute avant votre réponse. Un agent en attente d'une boîte de permission est simplement bloqué, et c'est bien le but.

Laisser l'agent voir ce qui n'est pas encore enregistré

L'éditeur offre à l'agent son propre système de fichiers : quand l'agent lit un fichier que vous avez ouvert avec des modifications non enregistrées, il reçoit le texte du tampon, pas le texte plus ancien du disque. C'est généralement ce qu'on veut — vous posez une question sur la modification que vous venez de faire.

Quand l'agent écrit un fichier, la modification arrive dans le tampon et la fenêtre est marquée modifiée : vous pouvez la lire, l'annuler avec Ctrl-Z, ou l'enregistrer avec F2. Un fichier que vous n'avez pas ouvert est lu et écrit directement sur le disque.

Faire tourner plusieurs agents à la fois

Chaque fenêtre est son propre processus et sa propre conversation. Ouvrir deux fois le même agent donne deux sessions indépendantes, et ouvrir deux agents différents permet de mettre côte à côte un modèle local rapide et un modèle lent et soigneux — Window ▸ Tile les dispose.

Quitter l'éditeur arrête tous les agents.

Variantes

  • Vous voulez que l'agent tourne ailleurs qu'à la racine du projet. Ajoutez cwd = "backend" à son bloc. Le chemin est relatif au projet, et c'est à la fois l'endroit où le processus démarre et le dossier de travail annoncé à l'agent.
  • L'agent a besoin d'un identifiant. Mettez-le dans env, ou comptez sur sa présence dans l'environnement depuis lequel vous lancez l'éditeur — l'agent en hérite.
  • Les commandes de l'agent n'apparaissent pas quand vous tapez /. Ouvrez Agent ▸ Agent status avec la fenêtre devant. S'il ne liste aucune commande, l'agent n'en a annoncé aucune — ou les a annoncées dans une forme que cet éditeur n'a pas su lire, auquel cas la boîte nomme la mise à jour et l'erreur de décodage. Pour voir exactement ce qui est passé sur le fil, lancez l'éditeur avec TURBO_ACP_TRACE=/tmp/acp.log et lisez le fichier : -> est ce que l'éditeur a envoyé, <- ce que l'agent a répondu.
  • L'agent ne démarre pas. Agent ▸ Agent status liste ce qui a été lu dans acp.toml, la ligne de commande obtenue pour chaque agent, et l'erreur de tout ce qui n'a pas démarré. Ce que l'agent écrit sur sa sortie d'erreur y figure aussi, et c'est là qu'un point d'accès de modèle mal configuré se signale.
  • Vous gardez le même agent dans tous les projets. Mettez le bloc [[agent]] dans ~/.config/turbo-js/acp.toml. Le fichier du projet est lu ensuite, et un agent du même name y remplace le vôtre.

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
# Dialoguer avec un agent de code depuis l'éditeur

Ce guide montre comment pointer Turbo JS vers un agent qui parle l'[Agent Client Protocol](https://agentclientprotocol.com), ouvrir une fenêtre dessus, et tenir une conversation sur le code en cours d'édition. Il suppose que Turbo JS est déjà lancé dans un projet.

Turbo JS est un **client** ACP. Il lance l'agent comme processus fils et lui parle en JSON-RPC sur son entrée et sa sortie standard — le même montage que Zed, donc un agent qui fonctionne là-bas fonctionne ici.

## Déclarer un agent à l'éditeur

Les agents sont listés dans `acp.toml`. Choisissez **Agent ▸ Create agents file** et l'éditeur écrit un fichier de départ dans `.turbo-js/acp.toml`, puis l'ouvre.

Un agent, c'est un bloc `[[agent]]` :

```toml
[[agent]]
name    = "Bob (llama.cpp)"
command = "docker"
args    = ["agent", "serve", "acp", ".turbo-js/agent.yaml"]
env     = { TELEMETRY_ENABLED = "false" }
```

`name` est ce qu'affiche le menu Agent et le nom de la fenêtre. `command` et `args` disent comment démarrer l'agent. C'est tout — le fichier est relu à chaque ouverture de fenêtre, donc on ne redémarre jamais l'éditeur pour essayer une modification.

Listez-en autant que vous voulez. Chacun devient une ligne du menu, et chaque fenêtre ouverte depuis cette ligne est un processus distinct avec sa propre conversation.

## Placer la configuration de l'agent à côté

La plupart des agents ont leur propre fichier de configuration, et `.turbo-js/` est un endroit raisonnable pour le garder afin qu'il voyage avec le projet. Pour `docker agent`, l'enregistrer sous `.turbo-js/agent.yaml` correspond aux `args` ci-dessus :

```yaml
providers:
  llamacpp:
    api_type: openai_chatcompletions
    base_url: http://localhost:8080/v1

models:
  mellum2:
    provider: llamacpp
    model: JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
    temperature: 0.7
    provider_opts:
      context_size: 262144

agents:
  root:
    model: mellum2
    description: A helpful AI assistant running on a local llama.cpp server
    instruction: |
      You name is Bob 🤓, you are a knowledgeable code assistant.
      Be helpful, accurate, and concise in your responses.
      You have access to the local filesystem and shell: use these tools
    toolsets:
      - type: filesystem
      - type: shell
```

## Ouvrir une fenêtre dessus

Appuyez sur `Alt-A`, ou choisissez **Agent** dans la barre de menus, puis l'agent par son nom.

Une fenêtre s'ouvre, coupée en deux : la conversation en haut, une zone de saisie en bas. L'agent est démarré à l'ouverture de la fenêtre et arrêté à sa fermeture.

```
┌ Bob (llama.cpp) ───────────────────────────────[■]┐
│ ‣ Vous                                            │
│   Que fait buildMenus ?                           │
│                                                   │
│ ‣ Shell  ls -1 src/                      ✓ fini   │
│   menus.js                                        │
│                                                   │
│ ‣ Bob                                             │
│   Elle assemble la barre de menus. Sa forme :     │
│                                                   │
│   ```javascript                                   │
│   export function buildMenus(app) {               │
│     return new MenuBar(...app.allMenus());        │
│   }                                               │
│   ```                                             │
├───────────────────────────────────────────────────┤
│ > _                                               │
└───────────────────────────────────────────────────┘
```

Le code que l'agent envoie dans un bloc délimité est coloré par les mêmes analyseurs que l'éditeur utilise pour les fichiers : une réponse en JavaScript est colorée comme du JavaScript, une réponse en shell comme du shell. Un bloc annonçant un langage que l'éditeur ne colore pas est laissé brut plutôt que deviné.

## Tenir la conversation

| Touche | Effet |
| --- | --- |
| `Entrée` | Envoyer ce qui est saisi |
| `Alt-Entrée` | Passer à la ligne au lieu d'envoyer |
| `Tab` | Passer de la conversation à la zone de saisie, et retour |
| `PgUp` `PgDn` | Faire défiler la conversation d'un écran |
| `Échap` | Arrêter le tour en cours |
| `Ctrl-W` | Fermer la fenêtre, et arrêter l'agent avec elle |

Pendant que l'agent répond, sa réponse s'affiche au fil de l'écriture plutôt que d'un bloc, et la règle entre les deux zones fait tourner un indicateur à côté du mot *thinking*. `Échap` l'interrompt — l'agent reçoit l'ordre de s'arrêter, et ce qu'il avait déjà dit reste dans la fenêtre.

## Utiliser les commandes propres à l'agent

Certains agents répondent à des commandes — `/compact`, `/web`, `/plan` — et disent à l'éditeur lesquelles. Tapez `/` comme premier caractère de la zone de saisie et la liste s'ouvre par-dessus la conversation : chaque commande, ce qu'elle fait, et entre chevrons ce qu'elle attend après son nom.

Continuez à taper pour la réduire, `↑` `↓` pour vous déplacer, puis `Tab` pour compléter. Une commande qui attend quelque chose est complétée avec une espace après elle, prête à recevoir la suite ; appuyez sur `Entrée` quand la ligne dit ce que vous voulez. Si rien n'apparaît quand vous tapez `/`, l'agent n'a annoncé aucune commande — **Agent ▸ Agent status** le dit — et `/` n'est qu'un caractère.

## Désigner un fichier à l'agent

Tapez `@` n'importe où dans la zone de saisie et les fichiers du projet apparaissent. Tapez quelques lettres du nom du fichier pour réduire la liste, `Tab` pour prendre celui en surbrillance :

```
> explique ce que fait @src/menus.js
```

Quand vous appuyez sur `Entrée`, l'agent reçoit le **fichier**, et pas seulement son nom : son texte quand l'agent accepte le contexte incorporé, un lien vers lui sinon. Si le fichier est ouvert dans l'éditeur avec des modifications non enregistrées, c'est votre version non enregistrée qui part. La ligne reste dans la conversation telle que vous l'avez tapée.

Plusieurs fichiers dans une invite, c'est plusieurs `@`. Un mot qui commence par `@` mais n'est pas un fichier — une adresse électronique — est laissé en texte.

## Récupérer un morceau de la conversation

Appuyez sur `Tab` pour placer le curseur dans la conversation. La règle change et annonce ce que font désormais les touches.

| Touche | Effet |
| --- | --- |
| `↑` `↓` `PgUp` `PgDn` | Déplacer le curseur dans ce qui a été dit |
| `Shift-↑` `Shift-↓` | Sélectionner des lignes entières |
| Glisser à la souris | Pareil, à la main |
| `Ctrl-C` | Copier |
| `Échap` | Abandonner la sélection |
| `Tab` | Revenir à la zone de saisie |

**Sans rien de sélectionné, `Ctrl-C` copie le bloc sur lequel est le curseur** — un bloc de code délimité, un paragraphe, la sortie d'un outil — sans le libellé de l'interlocuteur au-dessus ni la phrase qui suit. C'est presque toujours ce que vous vouliez, et cela évite de le sélectionner à la main.

Ce qui est copié va dans **deux** presse-papiers : celui de l'éditeur, pour que `Shift-Ins` le colle dans un fichier ouvert ici, et celui du système, pour que `Ctrl-V` le colle n'importe où ailleurs. L'indentation d'affichage de la conversation est retirée, donc le code collé arrive collé à la marge.

La moitié « système » passe par votre terminal (une séquence d'échappement nommée OSC 52). La plupart des terminaux la gèrent ; quelques-uns la refusent par sécurité, et certains demandent de l'activer. Si `Ctrl-V` ailleurs ne donne rien, c'est là qu'il faut regarder — le presse-papiers de l'éditeur contient le texte dans tous les cas.

## Répondre quand l'agent demande la permission

Un agent doté d'un outil shell ou d'un outil de fichiers demande avant de s'en servir. Une boîte de dialogue nomme l'outil et la commande exacte, et propose les choix que l'agent lui-même a proposés — d'ordinaire *Autoriser*, *Autoriser et retenir mon choix*, et *Passer*.

```
┌────────── Bob (llama.cpp) veut lancer ──────────┐
│                                                 │
│  Shell                                          │
│    ls -1                                        │
│                                                 │
│    [ Autoriser ] [ Toujours ]  [ Passer ]       │
└─────────────────────────────────────────────────┘
```

*Toujours* est retenu par l'agent, pas par l'éditeur : ce que cela couvre et combien de temps cela dure sont l'affaire de l'agent. Échap équivaut à *Passer*.

Rien ne s'exécute avant votre réponse. Un agent en attente d'une boîte de permission est simplement bloqué, et c'est bien le but.

## Laisser l'agent voir ce qui n'est pas encore enregistré

L'éditeur offre à l'agent son propre système de fichiers : quand l'agent lit un fichier que vous avez ouvert avec des modifications non enregistrées, il reçoit **le texte du tampon**, pas le texte plus ancien du disque. C'est généralement ce qu'on veut — vous posez une question sur la modification que vous venez de faire.

Quand l'agent écrit un fichier, la modification arrive dans le tampon et la fenêtre est marquée modifiée : vous pouvez la lire, l'annuler avec `Ctrl-Z`, ou l'enregistrer avec `F2`. Un fichier que vous n'avez pas ouvert est lu et écrit directement sur le disque.

## Faire tourner plusieurs agents à la fois

Chaque fenêtre est son propre processus et sa propre conversation. Ouvrir deux fois le même agent donne deux sessions indépendantes, et ouvrir deux agents différents permet de mettre côte à côte un modèle local rapide et un modèle lent et soigneux — **Window ▸ Tile** les dispose.

Quitter l'éditeur arrête tous les agents.

## Variantes

- **Vous voulez que l'agent tourne ailleurs qu'à la racine du projet.** Ajoutez `cwd = "backend"` à son bloc. Le chemin est relatif au projet, et c'est à la fois l'endroit où le processus démarre et le dossier de travail annoncé à l'agent.
- **L'agent a besoin d'un identifiant.** Mettez-le dans `env`, ou comptez sur sa présence dans l'environnement depuis lequel vous lancez l'éditeur — l'agent en hérite.
- **Les commandes de l'agent n'apparaissent pas quand vous tapez `/`.** Ouvrez **Agent ▸ Agent status** avec la fenêtre devant. S'il ne liste aucune commande, l'agent n'en a annoncé aucune — ou les a annoncées dans une forme que cet éditeur n'a pas su lire, auquel cas la boîte nomme la mise à jour et l'erreur de décodage. Pour voir exactement ce qui est passé sur le fil, lancez l'éditeur avec `TURBO_ACP_TRACE=/tmp/acp.log` et lisez le fichier : `->` est ce que l'éditeur a envoyé, `<-` ce que l'agent a répondu.
- **L'agent ne démarre pas.** **Agent ▸ Agent status** liste ce qui a été lu dans `acp.toml`, la ligne de commande obtenue pour chaque agent, et l'erreur de tout ce qui n'a pas démarré. Ce que l'agent écrit sur sa sortie d'erreur y figure aussi, et c'est là qu'un point d'accès de modèle mal configuré se signale.
- **Vous gardez le même agent dans tous les projets.** Mettez le bloc `[[agent]]` dans `~/.config/turbo-js/acp.toml`. Le fichier du projet est lu ensuite, et un agent du même `name` y remplace le vôtre.

## Voir aussi

- Chaque clé du fichier, et la part exacte du protocole implémentée : [référence Agents et ACP](../reference/acp.md)
- Pourquoi un agent est une fenêtre et non un panneau, et pourquoi les permissions sont modales : [Fenêtres agent](../explanation/agent-windows.md)
- Le protocole lui-même : [agentclientprotocol.com](https://agentclientprotocol.com)