bots-garden/mini-mepublic Fork
⑂ v0.5.0
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. 5b2f986 · on v0.5.0 · k33g · 7d ago
configuration.md · 237 lines · 26.0 KBmarkdown
Blame HistoryOpen raw

Référence : fichier de configuration

Description neutre et exhaustive du fichier YAML lu par mm. Chaque clé est optionnelle ; une clé omise garde sa valeur par défaut intégrée. Le fichier est décodé par-dessus les valeurs par défaut, donc les clés inconnues sont ignorées.

Clés de premier niveau

Clé Type Défaut Description
provider chaîne dmr Clé du registre du serveur LLM : dmr, llamacpp, llmman ou ollama. Surchargée par AGENT_PROVIDER.
model chaîne huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M Identifiant du modèle dans la nomenclature du fournisseur. Surchargé par AGENT_MODEL.
baseUrl chaîne "" (défaut du fournisseur) Point d'accès compatible OpenAI essayé en premier. Surchargé par AGENT_BASE_URL.
fallback chaîne ou absente absente (défaut du fournisseur) Point d'accès utilisé quand baseUrl ne répond pas sur /models en 2 s. Absente = défaut du fournisseur ; "" = pas de repli.
apiKeyEnv chaîne "" (défaut du fournisseur) Nom de la variable d'environnement qui contient la clé d'API.
contextWindow entier 0 Tokens servis par le serveur. 0 = demander au serveur, sinon inconnu. Doit être ≥ 0.
maxOutput entier 16000 Nombre maximal de caractères qu'un outil renvoie au modèle ; au-delà, la sortie garde son début et jusqu'à 2000 caractères de fin. Doit être > 0.
maxTurns entier 10 Nombre maximal d'allers-retours modèle ↔ outils par question. Doit être > 0.
previewLines entier 20 Lignes de la sortie d'une commande affichées dans le terminal. 0 désactive l'affichage. Doit être ≥ 0.
displayCommands booléen false Affiche la liste numérotée des commandes et opérations sur fichiers après chaque réponse.
showThinking booléen true Affiche ce qu'un modèle à raisonnement réfléchit avant de répondre. Seul l'affichage est optionnel : le raisonnement est toujours lu sur le fil, car c'est lui qui maintient le chien de garde en vie pendant que le modèle réfléchit. Voir Modèles à raisonnement.
system chaîne prompt intégré Le prompt système, premier message de chaque historique.
structuredOutput chaîne (déclarations Go) "" La forme que doit suivre chaque réponse, en JSON : des déclarations type Go et une var qui nomme la racine de la réponse. Voir structuredOutput ci-dessous. Vide = réponses en texte libre. Incompatible avec tout outil déclaré.
skillsDir chaîne skills Répertoire des skills, sous forme de fichiers <nom>.md ou de répertoires <nom>/SKILL.md. Un chemin relatif est résolu depuis le répertoire de lancement de mm (mode terminal, ou mode ACP sans fichier de configuration), ou à côté du fichier de configuration (mode ACP avec fichier) ; la bannière avertit avec le chemin absolu quand rien n'y est trouvé.
bashTool booléen true Déclare bash. false le retire : le modèle peut encore lire et modifier des fichiers (editTools) et charger des skills, mais n'exécute jamais de commande. Reformulez un prompt système qui annonce encore un outil bash.
editTools booléen true Déclare read_file, write_file, edit_file. false ne laisse que bash et read_skill.
fetchContentTool booléen false Déclare fetch_content, qui récupère des pages web en Markdown. Désactivé par défaut : c'est le seul outil intégré qui accède au réseau.
askUserTool booléen true Déclare ask_user, par lequel le modèle pose des questions à l'utilisateur (choisir une option, en choisir plusieurs, taper un texte, oui ou non) et attend les réponses. false le retire : le modèle ne peut pas demander. Jamais déclaré à côté d'un structuredOutput. Surchargé par AGENT_ASK_USER ; pour un agent interrogé par un autre, aussi par le mmConfigs.<nom>.askUser de celui qui l'interroge. Voir outils.
sampling dictionnaire temperature: 0.0, top_p: 0.9, max_tokens: 4096 Paramètres de génération, noms de l'API OpenAI, transmis au serveur. Une clé que l'API OpenAI ne déclare pas est envoyée telle quelle, au premier niveau de la requête — par exemple chat_template_kwargs: {enable_thinking: false}, qui demande à un serveur llama.cpp (dmr, llamacpp, llmman) de ne pas raisonner ; reasoning_effort: none fait de même avec Ollama. messages, tools, tool_choice (et les anciens functions, function_call) sont ignorées : Genkit les construit à partir de la conversation. L'agent.yaml livré ajoute parallel_tool_calls: false. max_tokens borne aussi un appel d'outil : un write_file de long document (ou le raisonnement d'un modèle « thinking » plus l'appel) peut l'atteindre, et l'appel est alors coupé. mm le rend deux fois au modèle en lui demandant de procéder par morceaux, puis s'arrête avec the model hit max_tokens (N) while writing a tool call ; augmentez la valeur si cela arrive. En streaming, mm demande aussi au serveur le compte des tokens (stream_options.include_usage).
watchdogTimeout durée 20s Silence toléré entre deux tokens diffusés avant de déclarer la connexion bloquée. Doublé pour les requêtes de résumé.
firstTokenTimeout durée 3m Silence toléré avant le premier token d'un appel au modèle, pendant que le serveur lit le prompt (chaque aller-retour d'un tour en a un). Jamais plus court que watchdogTimeout ; doit être >= 0. Avec un serveur llama.cpp (dmr, llamacpp, llmman — dont les modèles GGUF locaux tournent dans llama-server), mm demande return_progress : chaque rapport d'avancement relance ce délai, et le spinner affiche Reading the prompt 12.0k/25.3k tokens. Ollama n'envoie pas d'avancement : cette seule attente couvre tout le prompt (et le chargement du modèle). À l'expiration, le watchdog dit no first token from the server after … (avant le premier token) ou connection hang detected after … (après).
bashTimeout durée 30s Durée maximale d'une commande bash avant qu'elle soit tuée ; l'outil répond alors [error: <bashTimeout> timeout exceeded]. Doit être > 0. Le watchdog continue de compter pendant qu'une commande tourne (ticket 57) : une commande plus longue que watchdogTimeout termine le tour, donc relevez les deux ensemble.
context dictionnaire voir ci-dessous Compression automatique de l'historique.
sessions dictionnaire voir ci-dessous Sessions persistantes, par projet.
agentsMd dictionnaire voir ci-dessous Ajoute le AGENTS.md du projet au prompt système de chaque conversation. Actif par défaut.
trace dictionnaire voir ci-dessous Écrit chaque requête au modèle et chaque réponse dans des fichiers.
acp dictionnaire voir ci-dessous La façon dont mm -acp se présente à l'éditeur.
lsp dictionnaire voir ci-dessous Serveurs de langage derrière l'outil lsp. Aucun serveur listé = pas d'outil.
hooks dictionnaire événement → liste aucun Commandes lancées avant qu'une question atteigne le modèle (preGeneration), avant et après chaque appel d'outil (preToolCall, postToolCall) après le tour (postGeneration), et avant et après chaque relais vers un autre agent (preAsk, postAsk) ; chacune lit un objet JSON sur stdin et peut en répondre un sur stdout. Clés d'une entrée : command (obligatoire), matcher (événements d'outil et d'agent seulement : un nom d'outil, ou un nom d'agent), timeout (défaut 10s), onError (fail | warn | ignore, défaut warn). Voir les hooks.
tui bool false Démarre dans le mode fenêtre unique sans l'option -tui. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal ; ignoré avec -acp.
yolo booléen true true : les outils s'exécutent sans demander. false : chaque appel qui modifie quelque chose — bash, write_file, edit_file, fetch_content avec output, rename de lsp, create/update/next/delete de plan — attend la réponse de l'utilisateur dans toutes les façades (mode ligne, fenêtre, éditeur), de même que chaque outil MCP, quoi que dise mcp.permissions. Réponses : autoriser une fois, autoriser cet outil pour la session, refuser cet appel, jamais (cet outil, pour la session). read_file, read_skill, fetch_content sans output et les actions de navigation de lsp ne demandent jamais. Avec -p et mm --ask, personne ne peut répondre : ces appels sont refusés. Un agent lancé par /ask, ask_agent ou mm --ask tourne avec AGENT_YOLO=false et soumet ses appels à l'agent qui l'interroge : le yolo de son entrée mmConfigs décide s'il est fixé, sinon le yolo de l'agent qui interroge. Surchargée par AGENT_YOLO. bashTool, editTools, fetchContentTool décident toujours quels outils existent. Voir Confirmer les appels d'outils.
permissions chaîne absente Obsolète, remplacée par yolo. ask = yolo: false (et l'emporte sur yolo: true) ; auto ne change rien. Les deux valeurs ajoutent un avertissement au démarrage. Doit valoir auto ou ask.
mmConfigs dictionnaire nom → chemin, ou nom → {path, description, yolo, askUser} aucun Les autres agents mm que celui-ci peut interroger. Chaque nom génère /ask-<nom> et /ask-with-context-<nom> (voir les commandes slash), et la liste déclare l'outil ask_agent, par lequel le modèle les appelle lui-même. La forme longue ajoute description (quand appeler cet agent ; affichée dans la description d'ask_agent, à défaut l'acp.title du fichier de l'agent) et yolo (décide des appels d'outils de cet agent quand il est interrogé, par /ask, ask_agent ou mm --ask, à la place du yolo de cet agent-ci : true ils s'exécutent, false chacun est demandé ; absent, le yolo de cet agent-ci décide) et askUser (si cet agent peut poser des questions à l'utilisateur quand il est interrogé : true ses questions ask_user remontent à l'utilisateur de cet agent-ci, false son outil ask_user n'est pas déclaré ; absent, le askUserTool de cet agent décide). path ne doit pas être vide. Un chemin relatif l'est au dossier du fichier qui le déclare. Noms : lettres minuscules, chiffres et -, commençant par une lettre ou un chiffre, ne commençant pas par with-context. Un chemin dont le fichier n'existe pas donne un avertissement au démarrage, pas une erreur.

Clés de context

Clé Type Défaut Description
enabled booléen false Active la compression automatique. /compact fonctionne dans tous les cas.
threshold entier 75 Pourcentage de la fenêtre de contexte au-delà duquel l'historique est compressé avant la question suivante. Entre 1 et 100.
maxMessages entier 80 Nombre de messages qui déclenche une compression quand la fenêtre est inconnue ou l'estimation trop basse. 0 désactive. Doit être ≥ 0.
keepLastTurns entier 3 Tours de question conservés bruts en fin d'historique. Doit être ≥ 1.
summaryMaxTokens entier 1200 max_tokens de la requête de résumé. Doit être > 0. Le raisonnement d'un modèle qui réfléchit est décompté de ce budget : sur dmr, llamacpp et llmman, la requête de résumé désactive le raisonnement (chat_template_kwargs.enable_thinking: false), sur ollama aussi (reasoning_effort: "none", le seul interrupteur qu'Ollama respecte) — quoi que dise sampling ; les autres chat_template_kwargs sont gardés, et un reasoning_effort qui y est fixé est ramené à low (gpt-oss n'a pas d'« arrêt ») ; ailleurs, si l'erreur dit que le modèle « reasoned until the limit », augmentez-le.
prompt chaîne "" Remplace le prompt de résumé intégré quand non vide.
showStats booléen true Affiche le rapport 🗜️ d'une ligne après chaque compression.

Clés de sessions

Clé Type Défaut Description
sessions.enabled bool false Enregistre chaque conversation dans un fichier, réécrit après chaque tour, /compact et /new. Le fichier enregistre aussi, hors de l'historique, chaque erreur affichée (tableau errors : génération échouée, compression échouée, /resume échoué). Active /sessions et /resume dans le terminal et session/load en ACP.
sessions.dir chaîne .mm/sessions Répertoire des fichiers de session, un <id>.json chacun. Relatif au répertoire de lancement de mm (terminal) ou au cwd de la session (ACP) ; un chemin absolu est utilisé tel quel. Ne doit pas être vide.

Clés de trace

Clé Type Défaut Description
trace.enabled bool false Écrit une paire de fichiers par appel au modèle : le corps de la requête tel qu'envoyé (après les champs ajoutés par mm : stream_options, return_progress, l'interrupteur de raisonnement d'un résumé), indenté, et le corps de la réponse tel que reçu. Surchargé par AGENT_TRACE. Les en-têtes ne sont jamais écrits. La bannière se termine par | trace: <répertoire absolu> tant qu'elle est active ( | trace: <session cwd>/<dir> en mode ACP).
trace.dir chaîne .mm/traces Répertoire des fichiers. Un chemin relatif est résolu à chaque appel dans le répertoire de travail du tour — le cwd de la session en mode ACP, comme sessions.dir — sinon dans le répertoire où mm tourne ; un chemin absolu est utilisé tel quel. Un répertoire impossible à créer affiche une fois [trace: cannot write to <dir>: <erreur> — nothing is traced] (sur stderr en mode ACP) ; les appels continuent. Créé au besoin. Ne doit pas être vide quand la trace est active.

Noms des fichiers : <AAAAMMJJ-HHMMSS.mmm>-<acp.name>-<NNNN>.request.json, puis ….response-<statut>.sse (une réponse en streaming, les lignes SSE du serveur octet pour octet, écrites à leur arrivée), ….response-<statut>.json (un corps JSON entier, indenté), ou ….response-error.txt (pas de réponse : la méthode, l'URL et l'erreur). NNNN compte les appels au modèle du processus ; une nouvelle tentative du client HTTP est un appel à part. Un agent lancé par /ask ou ask_agent hérite de AGENT_TRACE et écrit à côté de celui qui l'interroge, sous son propre acp.name.

Clés de agentsMd

Clé Type Défaut Description
agentsMd.enabled booléen true Lit le fichier au début de chaque conversation : démarrage, /new, /resume, une nouvelle session ACP (session/new), une session rechargée (session/load), -p. Jamais au milieu d'une conversation. Un agent démarré par /ask, ask_agent ou mm --ask ne le lit que si son propre fichier l'active ; il cherche dans le répertoire de travail qu'on lui donne (celui de l'agent qui l'interroge).
agentsMd.path chaîne AGENTS.md Le fichier. Un chemin relatif est résolu par rapport au répertoire de travail de la conversation — le répertoire où tourne mm, le cwd de la session en mode ACP — et non par rapport au fichier de configuration. Un chemin absolu est utilisé tel quel. Ne doit pas être vide quand enabled vaut true.
agentsMd.maxChars entier 0 Au-delà de ce nombre de caractères (caractères Unicode, après suppression des blancs aux extrémités), le fichier n'est pas lu du tout, et la bannière le dit. Jamais tronqué. 0 = pas de limite. Doit être ≥ 0.

Quand le fichier est lu, le message système est le prompt system, une ligne vide, puis :

PROJECT INSTRUCTIONS (from <chemin absolu>)
The instructions of the project you work in. Follow them; when the user asks otherwise in the conversation, the user wins.

<le fichier, sans blancs aux extrémités>

Non lu : un fichier absent, un fichier qui ne contient que des blancs, un fichier au-delà de maxChars, tout fichier quand structuredOutput est défini, un fichier illisible (avertissement de bannière <chemin> cannot be read: …). Une session reprise (/resume, session/load) continue sous le fichier tel qu'il est maintenant.

Clés de acp

Clé Type Défaut Description
acp.name chaîne bob agentInfo.name dans la réponse à initialize. Ne doit pas être vide.
acp.title chaîne Bob (bash-first agent) agentInfo.title, le nom que l'éditeur peut afficher. Vide : non envoyé. Affiché aussi par le mode fenêtre (-tui) à côté de mm, dans son en-tête et au-dessus de chaque réponse — ‣ mm [Homer (coder)] — sauf s'il est vide ou égal à la valeur intégrée. Pendant un /ask, la fenêtre montre à la place l'agent INTERROGÉ : son acp.title (ou son nom dans mmConfigs) au-dessus de sa réponse, et dans l'en-tête avec son modèle et asked by <cet agent>, jusqu'à ce qu'il ait répondu.

La version n'est pas paramétrable : agentInfo.version est toujours celle du binaire, telle qu'affichée par mm --version.

Clés de lsp

Clé Type Défaut Description
lsp.servers liste [] Une entrée par serveur de langage. L'extension du fichier choisit le serveur.
lsp.servers[].name chaîne — Le nom qu'utilisent la bannière, la description de l'outil et les avertissements. Obligatoire.
lsp.servers[].command chaîne — L'exécutable, cherché sur le PATH au démarrage. Obligatoire. Introuvable : avertissement, serveur ignoré.
lsp.servers[].args liste de chaînes [] Ses arguments (beaucoup de serveurs veulent --stdio).
lsp.servers[].extensions liste de chaînes — Les extensions de fichier qu'il sert, avec le point (.go, .ts). Obligatoire, au moins une ; comparaison insensible à la casse ; une extension ne peut être servie que par un serveur.
lsp:
  servers:
    - name: gopls
      command: gopls
      extensions: [".go"]
    - name: typescript
      command: typescript-language-server
      args: ["--stdio"]
      extensions: [".ts", ".tsx", ".js", ".jsx"]

Le fichier livré agent.lsp.yaml est agent.dmr.yaml avec ce bloc actif (gopls, les autres serveurs prêts à décommenter) et un prompt système qui dit quand utiliser l'outil.

Valeurs par défaut des fournisseurs

Fournisseur baseUrl fallback apiKeyEnv Clé requise
dmr http://localhost:12434/engines/v1 http://host.docker.internal:12434/engines/v1 aucune non
llamacpp http://127.0.0.1:8080/v1 aucun LLAMA_API_KEY non
llmman http://127.0.0.1:17434/v1 http://host.docker.internal:17434/v1 LLMMAN_API_KEY non
ollama http://localhost:11434/v1 http://host.docker.internal:11434/v1 OLLAMA_API_KEY non

structuredOutput

Un bloc YAML qui contient des déclarations Go. Chaque type est une définition ; l'unique var (var X T ou var X = T{}) nomme la racine de la réponse. Seules les déclarations type et var sont acceptées.

Go JSON Schema
string {"type": "string"}
bool {"type": "boolean"}
int, int8 … int64, uint … uint64 {"type": "integer"}
float32, float64 {"type": "number"}
[]T {"type": "array", "items": T}
map[string]T {"type": "object", "additionalProperties": T}
struct { … } {"type": "object", "properties": …, "required": [toutes les clés], "additionalProperties": false}, clés dans l'ordre de déclaration
un type déclaré Name {"$ref": "#/$defs/Name"} ; une racine struct est mise en ligne, $defs contient les types qu'atteint la racine
champ *T, ou json:",omitempty" la clé reste obligatoire, sa valeur est anyOf: [T, null]
Élément d'un champ Effet
tag json:"name" la clé ; sans tag, le nom Go du champ tel qu'écrit
tag json:"-" champ ignoré
commentaire // au-dessus ou à côté d'une déclaration ou d'un champ sa description

Refusés, avec structuredOutput:<ligne>:<col>: … compté depuis la première ligne du bloc : func, import, const ; les types génériques ; les alias (type A = B) ; les champs embarqués ; les tableaux de taille fixe ; les clés de map autres que string ; interface, chan, func, les types qualifiés (time.Time) et non définis ; un pointeur hors d'un champ de struct ; un type déclaré deux fois ; une clé utilisée deux fois ; zéro ou plus d'une var ; une var sans type.

Quand le bloc n'est pas vide :

  • les déclarations sont ajoutées à system, sous un paragraphe OUTPUT FORMAT ;
  • chaque appel au modèle porte response_format: {"type": "json_schema", "json_schema": {"name": "output", "strict": true, "schema": …}} ;
  • la réponse est validée contre le schéma ; une réponse non conforme fait échouer le tour avec model failed to generate output matching expected schema: …, précédé de the answer was cut off by max_tokens before its JSON was complete … quand le serveur s'est arrêté sur max_tokens ;
  • -p imprime la réponse JSON seule sur stdout (voir Spécificités du mode invite) ;
  • la bannière affiche tools: none (structured output: JSON answers), sans avertissement « no skills » ni « no tool ».

Exemple :

structuredOutput: |
  type Language struct {
      Name     string `json:"name"`     // the language's name, in English
      Official bool   `json:"official"`
  }
  type Country struct {
      Name      string     `json:"name"`
      Capital   *string    `json:"capital"`   // null when unknown
      Languages []Language `json:"languages"` // at most 4
  }
  var Countries = []Country{}

Erreurs de validation

Signalées sur stderr sous la forme [config error: <chemin>: <message>], code de sortie 1 — dans tous les modes, pour que -p … | jq ne prenne jamais une erreur pour la réponse. De même pour [engine error: …] et [usage: …].

Message Cause
provider must not be empty provider: ""
model must not be empty model: ""
contextWindow must be >= 0 valeur négative
maxOutput must be > 0 zéro ou négatif
maxTurns must be > 0 zéro ou négatif
previewLines must be >= 0 valeur négative
context.threshold must be between 1 and 100 hors intervalle
context.keepLastTurns must be >= 1 zéro ou négatif
context.summaryMaxTokens must be > 0 zéro ou négatif
context.maxMessages must be >= 0 valeur négative
sessions.dir must not be empty chaîne vide
agentsMd.path must not be empty chaîne vide avec agentsMd.enabled actif
agentsMd.maxChars must be >= 0 valeur négative
trace.dir must not be empty chaîne vide avec la trace active
acp.name must not be empty chaîne vide ou blanche
lsp.servers[N].name must not be empty un serveur sans name
lsp.servers[N].command must not be empty un serveur sans command
lsp.servers[N].extensions must list at least one extension un serveur sans extensions
lsp.servers[N].extensions: "go" must start with a dot, like ".go" une extension sans son point
lsp.servers[N]: extension ".ts" is already served by "typescript" deux serveurs sur une même extension
permissions must be "auto" or "ask" toute autre valeur de la clé obsolète
AGENT_YOLO="maybe": must be true or false une valeur d'AGENT_YOLO que strconv.ParseBool refuse (acceptées : 1, t, true, 0, f, false, sans distinction de casse)
bashTimeout must be > 0 zéro ou négative
structuredOutput:<ligne>:<col>: … une déclaration que la section structuredOutput ne sait pas traduire
structuredOutput: no var declaration: … aucune var ne nomme la racine
structuredOutput cannot be used with tools — this agent declares: <outils> (…) un structuredOutput avec au moins un outil déclaré (bash, plan, les outils de fichiers, fetch_content, read_skill, ask_agent, lsp, les outils MCP). Signalée après l'assemblage des outils, avant le démarrage de toute interface.
mmConfigs: "Bob" is not a valid name (…) un nom avec des majuscules, des espaces ou d'autres caractères, ou commençant par -
mmConfigs: "with-context-x" is not a valid name (it would read as /ask-with-context-…) un nom commençant par with-context
mmConfigs.<nom>: the path must not be empty <nom>: "", ou une forme longue sans path
hooks: unknown event "x" (…), hooks.<événement>[N]: … un bloc hooks: invalide — voir les hooks
unknown provider "x" (known: dmr, llamacpp, llmman, ollama) Signalée par le moteur, sous la forme [engine error: …].

Un avertissement au démarrage, et non une erreur, est affiché quand context.enabled vaut true, que la fenêtre est inconnue et que context.maxMessages vaut 0, et quand le fichier pose la clé obsolète permissions (permissions: ask is deprecated — use yolo: false instead …).

Fichiers livrés

Fichier Rôle
agent.yaml Configuration Docker Model Runner : provider: dmr, maxTurns: 40, displayCommands: true, compression désactivée, un prompt système nommé « Bob » qui décrit les skills et les règles d'édition de fichiers.
agent.llamacpp.yaml Configuration llama.cpp : provider: llamacpp, baseUrl: http://127.0.0.1:8080/v1, fallback: "", compression activée.

Exemple

provider: llamacpp
model: mon-alias
baseUrl: http://127.0.0.1:8080/v1
fallback: ""
maxTurns: 40
context:
  enabled: true
  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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# Référence : fichier de configuration

> Description neutre et exhaustive du fichier YAML lu par `mm`. Chaque clé est optionnelle ; une clé omise garde sa valeur par défaut intégrée. Le fichier est décodé par-dessus les valeurs par défaut, donc les clés inconnues sont ignorées.

## Clés de premier niveau

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `provider` | chaîne | `dmr` | Clé du registre du serveur LLM : `dmr`, `llamacpp`, `llmman` ou `ollama`. Surchargée par `AGENT_PROVIDER`. |
| `model` | chaîne | `huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M` | Identifiant du modèle dans la nomenclature du fournisseur. Surchargé par `AGENT_MODEL`. |
| `baseUrl` | chaîne | `""` (défaut du fournisseur) | Point d'accès compatible OpenAI essayé en premier. Surchargé par `AGENT_BASE_URL`. |
| `fallback` | chaîne ou absente | absente (défaut du fournisseur) | Point d'accès utilisé quand `baseUrl` ne répond pas sur `/models` en 2 s. Absente = défaut du fournisseur ; `""` = pas de repli. |
| `apiKeyEnv` | chaîne | `""` (défaut du fournisseur) | Nom de la variable d'environnement qui contient la clé d'API. |
| `contextWindow` | entier | `0` | Tokens servis par le serveur. `0` = demander au serveur, sinon inconnu. Doit être ≥ 0. |
| `maxOutput` | entier | `16000` | Nombre maximal de caractères qu'un outil renvoie au modèle ; au-delà, la sortie garde son début et jusqu'à 2000 caractères de fin. Doit être > 0. |
| `maxTurns` | entier | `10` | Nombre maximal d'allers-retours modèle ↔ outils par question. Doit être > 0. |
| `previewLines` | entier | `20` | Lignes de la sortie d'une commande affichées dans le terminal. `0` désactive l'affichage. Doit être ≥ 0. |
| `displayCommands` | booléen | `false` | Affiche la liste numérotée des commandes et opérations sur fichiers après chaque réponse. |
| `showThinking` | booléen | `true` | Affiche ce qu'un modèle à raisonnement réfléchit avant de répondre. Seul l'affichage est optionnel : le raisonnement est toujours lu sur le fil, car c'est lui qui maintient le chien de garde en vie pendant que le modèle réfléchit. Voir [Modèles à raisonnement](../explanation/thinking-models.md). |
| `system` | chaîne | prompt intégré | Le prompt système, premier message de chaque historique. |
| `structuredOutput` | chaîne (déclarations Go) | `""` | La forme que doit suivre chaque réponse, en JSON : des déclarations `type` Go et une `var` qui nomme la racine de la réponse. Voir [`structuredOutput`](#structuredoutput) ci-dessous. Vide = réponses en texte libre. Incompatible avec tout outil déclaré. |
| `skillsDir` | chaîne | `skills` | Répertoire des skills, sous forme de fichiers `<nom>.md` ou de répertoires `<nom>/SKILL.md`. Un chemin relatif est résolu depuis le répertoire de lancement de `mm` (mode terminal, ou mode ACP sans fichier de configuration), ou à côté du fichier de configuration (mode ACP avec fichier) ; la bannière avertit avec le chemin absolu quand rien n'y est trouvé. |
| `bashTool` | booléen | `true` | Déclare `bash`. `false` le retire : le modèle peut encore lire et modifier des fichiers (`editTools`) et charger des skills, mais n'exécute jamais de commande. Reformulez un prompt système qui annonce encore un outil bash. |
| `editTools` | booléen | `true` | Déclare `read_file`, `write_file`, `edit_file`. `false` ne laisse que `bash` et `read_skill`. |
| `fetchContentTool` | booléen | `false` | Déclare `fetch_content`, qui récupère des pages web en Markdown. Désactivé par défaut : c'est le seul outil intégré qui accède au réseau. |
| `askUserTool` | booléen | `true` | Déclare `ask_user`, par lequel le modèle pose des questions à l'utilisateur (choisir une option, en choisir plusieurs, taper un texte, oui ou non) et attend les réponses. `false` le retire : le modèle ne peut pas demander. Jamais déclaré à côté d'un `structuredOutput`. Surchargé par `AGENT_ASK_USER` ; pour un agent interrogé par un autre, aussi par le `mmConfigs.<nom>.askUser` de celui qui l'interroge. Voir [outils](tools.md#ask_user). |
| `sampling` | dictionnaire | `temperature: 0.0`, `top_p: 0.9`, `max_tokens: 4096` | Paramètres de génération, noms de l'API OpenAI, transmis au serveur. Une clé que l'API OpenAI ne déclare pas est envoyée telle quelle, au premier niveau de la requête — par exemple `chat_template_kwargs: {enable_thinking: false}`, qui demande à un serveur llama.cpp (`dmr`, `llamacpp`, `llmman`) de ne pas raisonner ; `reasoning_effort: none` fait de même avec Ollama. `messages`, `tools`, `tool_choice` (et les anciens `functions`, `function_call`) sont ignorées : Genkit les construit à partir de la conversation. L'`agent.yaml` livré ajoute `parallel_tool_calls: false`. `max_tokens` borne aussi un appel d'outil : un `write_file` de long document (ou le raisonnement d'un modèle « thinking » plus l'appel) peut l'atteindre, et l'appel est alors coupé. mm le rend deux fois au modèle en lui demandant de procéder par morceaux, puis s'arrête avec `the model hit max_tokens (N) while writing a tool call` ; augmentez la valeur si cela arrive. En streaming, mm demande aussi au serveur le compte des tokens (`stream_options.include_usage`). |
| `watchdogTimeout` | durée | `20s` | Silence toléré entre deux tokens diffusés avant de déclarer la connexion bloquée. Doublé pour les requêtes de résumé. |
| `firstTokenTimeout` | durée | `3m` | Silence toléré avant le premier token d'un appel au modèle, pendant que le serveur lit le prompt (chaque aller-retour d'un tour en a un). Jamais plus court que `watchdogTimeout` ; doit être >= 0. Avec un serveur llama.cpp (`dmr`, `llamacpp`, `llmman` — dont les modèles GGUF locaux tournent dans llama-server), mm demande `return_progress` : chaque rapport d'avancement relance ce délai, et le spinner affiche `Reading the prompt 12.0k/25.3k tokens`. Ollama n'envoie pas d'avancement : cette seule attente couvre tout le prompt (et le chargement du modèle). À l'expiration, le watchdog dit `no first token from the server after …` (avant le premier token) ou `connection hang detected after …` (après). |
| `bashTimeout` | durée | `30s` | Durée maximale d'une commande `bash` avant qu'elle soit tuée ; l'outil répond alors `[error: <bashTimeout> timeout exceeded]`. Doit être > 0. Le watchdog continue de compter pendant qu'une commande tourne (ticket 57) : une commande plus longue que `watchdogTimeout` termine le tour, donc relevez les deux ensemble. |
| `context` | dictionnaire | voir ci-dessous | Compression automatique de l'historique. |
| `sessions` | dictionnaire | voir ci-dessous | Sessions persistantes, par projet. |
| `agentsMd` | dictionnaire | voir ci-dessous | Ajoute le `AGENTS.md` du projet au prompt système de chaque conversation. Actif par défaut. |
| `trace` | dictionnaire | voir ci-dessous | Écrit chaque requête au modèle et chaque réponse dans des fichiers. |
| `acp` | dictionnaire | voir ci-dessous | La façon dont `mm -acp` se présente à l'éditeur. |
| `lsp` | dictionnaire | voir ci-dessous | Serveurs de langage derrière l'outil `lsp`. Aucun serveur listé = pas d'outil. |
| `hooks` | dictionnaire événement → liste | aucun | Commandes lancées avant qu'une question atteigne le modèle (`preGeneration`), avant et après chaque appel d'outil (`preToolCall`, `postToolCall`) après le tour (`postGeneration`), et avant et après chaque relais vers un autre agent (`preAsk`, `postAsk`) ; chacune lit un objet JSON sur stdin et peut en répondre un sur stdout. Clés d'une entrée : `command` (obligatoire), `matcher` (événements d'outil et d'agent seulement : un nom d'outil, ou un nom d'agent), `timeout` (défaut `10s`), `onError` (`fail` \| `warn` \| `ignore`, défaut `warn`). Voir [les hooks](hooks.md). |
| `tui` | bool | `false` | Démarre dans le mode fenêtre unique sans l'option `-tui`. Retombe sur le mode ligne quand stdin ou stdout n'est pas un terminal ; ignoré avec `-acp`. |
| `yolo` | booléen | `true` | `true` : les outils s'exécutent sans demander. `false` : chaque appel qui modifie quelque chose — `bash`, `write_file`, `edit_file`, `fetch_content` avec `output`, `rename` de `lsp`, `create`/`update`/`next`/`delete` de `plan` — attend la réponse de l'utilisateur dans toutes les façades (mode ligne, fenêtre, éditeur), de même que chaque outil MCP, quoi que dise `mcp.permissions`. Réponses : autoriser une fois, autoriser cet outil pour la session, refuser cet appel, jamais (cet outil, pour la session). `read_file`, `read_skill`, `fetch_content` sans `output` et les actions de navigation de `lsp` ne demandent jamais. Avec `-p` et `mm --ask`, personne ne peut répondre : ces appels sont refusés. Un agent lancé par `/ask`, `ask_agent` ou `mm --ask` tourne avec `AGENT_YOLO=false` et soumet ses appels à l'agent qui l'interroge : le `yolo` de son entrée `mmConfigs` décide s'il est fixé, sinon le `yolo` de l'agent qui interroge. Surchargée par `AGENT_YOLO`. `bashTool`, `editTools`, `fetchContentTool` décident toujours quels outils existent. Voir [Confirmer les appels d'outils](../how-to/confirm-tool-calls.md). |
| `permissions` | chaîne | absente | Obsolète, remplacée par `yolo`. `ask` = `yolo: false` (et l'emporte sur `yolo: true`) ; `auto` ne change rien. Les deux valeurs ajoutent un avertissement au démarrage. Doit valoir `auto` ou `ask`. |
| `mmConfigs` | dictionnaire nom → chemin, ou nom → `{path, description, yolo, askUser}` | aucun | Les autres agents mm que celui-ci peut interroger. Chaque nom génère `/ask-<nom>` et `/ask-with-context-<nom>` (voir les [commandes slash](slash-commands.md#interroger-un-autre-agent)), et la liste déclare l'outil [`ask_agent`](tools.md#ask_agent), par lequel le modèle les appelle lui-même. La forme longue ajoute `description` (quand appeler cet agent ; affichée dans la description d'`ask_agent`, à défaut l'`acp.title` du fichier de l'agent) et `yolo` (décide des appels d'outils de cet agent quand il est interrogé, par `/ask`, `ask_agent` ou `mm --ask`, à la place du `yolo` de cet agent-ci : `true` ils s'exécutent, `false` chacun est demandé ; absent, le `yolo` de cet agent-ci décide) et `askUser` (si cet agent peut poser des questions à l'utilisateur quand il est interrogé : `true` ses questions `ask_user` remontent à l'utilisateur de cet agent-ci, `false` son outil `ask_user` n'est pas déclaré ; absent, le `askUserTool` de cet agent décide). `path` ne doit pas être vide. Un chemin relatif l'est au dossier du fichier qui le déclare. Noms : lettres minuscules, chiffres et `-`, commençant par une lettre ou un chiffre, ne commençant pas par `with-context`. Un chemin dont le fichier n'existe pas donne un avertissement au démarrage, pas une erreur. |

## Clés de `context`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `enabled` | booléen | `false` | Active la compression automatique. `/compact` fonctionne dans tous les cas. |
| `threshold` | entier | `75` | Pourcentage de la fenêtre de contexte au-delà duquel l'historique est compressé avant la question suivante. Entre 1 et 100. |
| `maxMessages` | entier | `80` | Nombre de messages qui déclenche une compression quand la fenêtre est inconnue ou l'estimation trop basse. `0` désactive. Doit être ≥ 0. |
| `keepLastTurns` | entier | `3` | Tours de question conservés bruts en fin d'historique. Doit être ≥ 1. |
| `summaryMaxTokens` | entier | `1200` | `max_tokens` de la requête de résumé. Doit être > 0. Le raisonnement d'un modèle qui réfléchit est décompté de ce budget : sur `dmr`, `llamacpp` et `llmman`, la requête de résumé désactive le raisonnement (`chat_template_kwargs.enable_thinking: false`), sur `ollama` aussi (`reasoning_effort: "none"`, le seul interrupteur qu'Ollama respecte) — quoi que dise `sampling` ; les autres `chat_template_kwargs` sont gardés, et un `reasoning_effort` qui y est fixé est ramené à `low` (gpt-oss n'a pas d'« arrêt ») ; ailleurs, si l'erreur dit que le modèle « reasoned until the limit », augmentez-le. |
| `prompt` | chaîne | `""` | Remplace le prompt de résumé intégré quand non vide. |
| `showStats` | booléen | `true` | Affiche le rapport `🗜️` d'une ligne après chaque compression. |

## Clés de `sessions`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `sessions.enabled` | bool | `false` | Enregistre chaque conversation dans un fichier, réécrit après chaque tour, `/compact` et `/new`. Le fichier enregistre aussi, hors de l'historique, chaque erreur affichée (tableau `errors` : génération échouée, compression échouée, `/resume` échoué). Active `/sessions` et `/resume` dans le terminal et `session/load` en ACP. |
| `sessions.dir` | chaîne | `.mm/sessions` | Répertoire des fichiers de session, un `<id>.json` chacun. Relatif au répertoire de lancement de `mm` (terminal) ou au `cwd` de la session (ACP) ; un chemin absolu est utilisé tel quel. Ne doit pas être vide. |

## Clés de `trace`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `trace.enabled` | bool | `false` | Écrit une paire de fichiers par appel au modèle : le corps de la requête tel qu'envoyé (après les champs ajoutés par mm : `stream_options`, `return_progress`, l'interrupteur de raisonnement d'un résumé), indenté, et le corps de la réponse tel que reçu. Surchargé par `AGENT_TRACE`. Les en-têtes ne sont jamais écrits. La bannière se termine par ` \| trace: <répertoire absolu>` tant qu'elle est active (` \| trace: <session cwd>/<dir>` en mode ACP). |
| `trace.dir` | chaîne | `.mm/traces` | Répertoire des fichiers. Un chemin relatif est résolu à chaque appel dans le répertoire de travail du tour — le `cwd` de la session en mode ACP, comme `sessions.dir` — sinon dans le répertoire où `mm` tourne ; un chemin absolu est utilisé tel quel. Un répertoire impossible à créer affiche une fois `[trace: cannot write to <dir>: <erreur> — nothing is traced]` (sur stderr en mode ACP) ; les appels continuent. Créé au besoin. Ne doit pas être vide quand la trace est active. |

Noms des fichiers : `<AAAAMMJJ-HHMMSS.mmm>-<acp.name>-<NNNN>.request.json`, puis `….response-<statut>.sse` (une réponse en streaming, les lignes SSE du serveur octet pour octet, écrites à leur arrivée), `….response-<statut>.json` (un corps JSON entier, indenté), ou `….response-error.txt` (pas de réponse : la méthode, l'URL et l'erreur). `NNNN` compte les appels au modèle du processus ; une nouvelle tentative du client HTTP est un appel à part. Un agent lancé par `/ask` ou `ask_agent` hérite de `AGENT_TRACE` et écrit à côté de celui qui l'interroge, sous son propre `acp.name`.

## Clés de `agentsMd`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `agentsMd.enabled` | booléen | `true` | Lit le fichier au début de chaque conversation : démarrage, `/new`, `/resume`, une nouvelle session ACP (`session/new`), une session rechargée (`session/load`), `-p`. Jamais au milieu d'une conversation. Un agent démarré par `/ask`, `ask_agent` ou `mm --ask` ne le lit que si son propre fichier l'active ; il cherche dans le répertoire de travail qu'on lui donne (celui de l'agent qui l'interroge). |
| `agentsMd.path` | chaîne | `AGENTS.md` | Le fichier. Un chemin relatif est résolu par rapport au répertoire de travail de la conversation — le répertoire où tourne `mm`, le `cwd` de la session en mode ACP — et non par rapport au fichier de configuration. Un chemin absolu est utilisé tel quel. Ne doit pas être vide quand `enabled` vaut `true`. |
| `agentsMd.maxChars` | entier | `0` | Au-delà de ce nombre de caractères (caractères Unicode, après suppression des blancs aux extrémités), le fichier n'est pas lu du tout, et la bannière le dit. Jamais tronqué. `0` = pas de limite. Doit être ≥ 0. |

Quand le fichier est lu, le message système est le prompt `system`, une ligne vide, puis :

```text
PROJECT INSTRUCTIONS (from <chemin absolu>)
The instructions of the project you work in. Follow them; when the user asks otherwise in the conversation, the user wins.

<le fichier, sans blancs aux extrémités>
```

Non lu : un fichier absent, un fichier qui ne contient que des blancs, un fichier au-delà de `maxChars`, tout fichier quand `structuredOutput` est défini, un fichier illisible (avertissement de bannière `<chemin> cannot be read: …`). Une session reprise (`/resume`, `session/load`) continue sous le fichier tel qu'il est maintenant.

## Clés de `acp`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `acp.name` | chaîne | `bob` | `agentInfo.name` dans la réponse à `initialize`. Ne doit pas être vide. |
| `acp.title` | chaîne | `Bob (bash-first agent)` | `agentInfo.title`, le nom que l'éditeur peut afficher. Vide : non envoyé. Affiché aussi par le mode fenêtre (`-tui`) à côté de `mm`, dans son en-tête et au-dessus de chaque réponse — `‣ mm [Homer (coder)]` — sauf s'il est vide ou égal à la valeur intégrée. Pendant un `/ask`, la fenêtre montre à la place l'agent INTERROGÉ : son `acp.title` (ou son nom dans `mmConfigs`) au-dessus de sa réponse, et dans l'en-tête avec son modèle et `asked by <cet agent>`, jusqu'à ce qu'il ait répondu. |

La version n'est pas paramétrable : `agentInfo.version` est toujours celle du binaire, telle qu'affichée par `mm --version`.

## Clés de `lsp`

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `lsp.servers` | liste | `[]` | Une entrée par serveur de langage. L'extension du fichier choisit le serveur. |
| `lsp.servers[].name` | chaîne | — | Le nom qu'utilisent la bannière, la description de l'outil et les avertissements. Obligatoire. |
| `lsp.servers[].command` | chaîne | — | L'exécutable, cherché sur le `PATH` au démarrage. Obligatoire. Introuvable : avertissement, serveur ignoré. |
| `lsp.servers[].args` | liste de chaînes | `[]` | Ses arguments (beaucoup de serveurs veulent `--stdio`). |
| `lsp.servers[].extensions` | liste de chaînes | — | Les extensions de fichier qu'il sert, avec le point (`.go`, `.ts`). Obligatoire, au moins une ; comparaison insensible à la casse ; une extension ne peut être servie que par un serveur. |

```yaml
lsp:
  servers:
    - name: gopls
      command: gopls
      extensions: [".go"]
    - name: typescript
      command: typescript-language-server
      args: ["--stdio"]
      extensions: [".ts", ".tsx", ".js", ".jsx"]
```

Le fichier livré `agent.lsp.yaml` est `agent.dmr.yaml` avec ce bloc actif (gopls, les autres serveurs prêts à décommenter) et un prompt système qui dit quand utiliser l'outil.

## Valeurs par défaut des fournisseurs

| Fournisseur | `baseUrl` | `fallback` | `apiKeyEnv` | Clé requise |
|-------------|-----------|------------|-------------|-------------|
| `dmr` | `http://localhost:12434/engines/v1` | `http://host.docker.internal:12434/engines/v1` | aucune | non |
| `llamacpp` | `http://127.0.0.1:8080/v1` | aucun | `LLAMA_API_KEY` | non |
| `llmman` | `http://127.0.0.1:17434/v1` | `http://host.docker.internal:17434/v1` | `LLMMAN_API_KEY` | non |
| `ollama` | `http://localhost:11434/v1` | `http://host.docker.internal:11434/v1` | `OLLAMA_API_KEY` | non |

## `structuredOutput`

Un bloc YAML qui contient des déclarations Go. Chaque `type` est une définition ; l'unique `var` (`var X T` ou `var X = T{}`) nomme la racine de la réponse. Seules les déclarations `type` et `var` sont acceptées.

| Go | JSON Schema |
|----|-------------|
| `string` | `{"type": "string"}` |
| `bool` | `{"type": "boolean"}` |
| `int`, `int8` … `int64`, `uint` … `uint64` | `{"type": "integer"}` |
| `float32`, `float64` | `{"type": "number"}` |
| `[]T` | `{"type": "array", "items": T}` |
| `map[string]T` | `{"type": "object", "additionalProperties": T}` |
| `struct { … }` | `{"type": "object", "properties": …, "required": [toutes les clés], "additionalProperties": false}`, clés dans l'ordre de déclaration |
| un type déclaré `Name` | `{"$ref": "#/$defs/Name"}` ; une racine struct est mise en ligne, `$defs` contient les types qu'atteint la racine |
| champ `*T`, ou `json:",omitempty"` | la clé reste obligatoire, sa valeur est `anyOf: [T, null]` |

| Élément d'un champ | Effet |
|--------------------|-------|
| tag `json:"name"` | la clé ; sans tag, le nom Go du champ tel qu'écrit |
| tag `json:"-"` | champ ignoré |
| commentaire `//` au-dessus ou à côté d'une déclaration ou d'un champ | sa `description` |

Refusés, avec `structuredOutput:<ligne>:<col>: …` compté depuis la première ligne du bloc : `func`, `import`, `const` ; les types génériques ; les alias (`type A = B`) ; les champs embarqués ; les tableaux de taille fixe ; les clés de map autres que `string` ; `interface`, `chan`, `func`, les types qualifiés (`time.Time`) et non définis ; un pointeur hors d'un champ de struct ; un type déclaré deux fois ; une clé utilisée deux fois ; zéro ou plus d'une `var` ; une `var` sans type.

Quand le bloc n'est pas vide :

- les déclarations sont ajoutées à `system`, sous un paragraphe `OUTPUT FORMAT` ;
- chaque appel au modèle porte `response_format: {"type": "json_schema", "json_schema": {"name": "output", "strict": true, "schema": …}}` ;
- la réponse est validée contre le schéma ; une réponse non conforme fait échouer le tour avec `model failed to generate output matching expected schema: …`, précédé de `the answer was cut off by max_tokens before its JSON was complete …` quand le serveur s'est arrêté sur `max_tokens` ;
- `-p` imprime la réponse JSON seule sur stdout (voir [Spécificités du mode invite](cli.md#spécificités-du-mode-invite)) ;
- la bannière affiche `tools: none (structured output: JSON answers)`, sans avertissement « no skills » ni « no tool ».

Exemple :

```yaml
structuredOutput: |
  type Language struct {
      Name     string `json:"name"`     // the language's name, in English
      Official bool   `json:"official"`
  }
  type Country struct {
      Name      string     `json:"name"`
      Capital   *string    `json:"capital"`   // null when unknown
      Languages []Language `json:"languages"` // at most 4
  }
  var Countries = []Country{}
```

## Erreurs de validation

Signalées sur stderr sous la forme `[config error: <chemin>: <message>]`, code de sortie 1 — dans tous les modes, pour que `-p … | jq` ne prenne jamais une erreur pour la réponse. De même pour `[engine error: …]` et `[usage: …]`.

| Message | Cause |
|---------|-------|
| `provider must not be empty` | `provider: ""` |
| `model must not be empty` | `model: ""` |
| `contextWindow must be >= 0` | valeur négative |
| `maxOutput must be > 0` | zéro ou négatif |
| `maxTurns must be > 0` | zéro ou négatif |
| `previewLines must be >= 0` | valeur négative |
| `context.threshold must be between 1 and 100` | hors intervalle |
| `context.keepLastTurns must be >= 1` | zéro ou négatif |
| `context.summaryMaxTokens must be > 0` | zéro ou négatif |
| `context.maxMessages must be >= 0` | valeur négative |
| `sessions.dir must not be empty` | chaîne vide |
| `agentsMd.path must not be empty` | chaîne vide avec `agentsMd.enabled` actif |
| `agentsMd.maxChars must be >= 0` | valeur négative |
| `trace.dir must not be empty` | chaîne vide avec la trace active |
| `acp.name must not be empty` | chaîne vide ou blanche |
| `lsp.servers[N].name must not be empty` | un serveur sans `name` |
| `lsp.servers[N].command must not be empty` | un serveur sans `command` |
| `lsp.servers[N].extensions must list at least one extension` | un serveur sans `extensions` |
| `lsp.servers[N].extensions: "go" must start with a dot, like ".go"` | une extension sans son point |
| `lsp.servers[N]: extension ".ts" is already served by "typescript"` | deux serveurs sur une même extension |
| `permissions must be "auto" or "ask"` | toute autre valeur de la clé obsolète |
| `AGENT_YOLO="maybe": must be true or false` | une valeur d'`AGENT_YOLO` que `strconv.ParseBool` refuse (acceptées : `1`, `t`, `true`, `0`, `f`, `false`, sans distinction de casse) |
| `bashTimeout must be > 0` | zéro ou négative |
| `structuredOutput:<ligne>:<col>: …` | une déclaration que la section [`structuredOutput`](#structuredoutput) ne sait pas traduire |
| `structuredOutput: no var declaration: …` | aucune `var` ne nomme la racine |
| `structuredOutput cannot be used with tools — this agent declares: <outils> (…)` | un `structuredOutput` avec au moins un outil déclaré (`bash`, `plan`, les outils de fichiers, `fetch_content`, `read_skill`, `ask_agent`, `lsp`, les outils MCP). Signalée après l'assemblage des outils, avant le démarrage de toute interface. |
| `mmConfigs: "Bob" is not a valid name (…)` | un nom avec des majuscules, des espaces ou d'autres caractères, ou commençant par `-` |
| `mmConfigs: "with-context-x" is not a valid name (it would read as /ask-with-context-…)` | un nom commençant par `with-context` |
| `mmConfigs.<nom>: the path must not be empty` | `<nom>: ""`, ou une forme longue sans `path` |
| `hooks: unknown event "x" (…)`, `hooks.<événement>[N]: …` | un bloc `hooks:` invalide — voir [les hooks](hooks.md#erreurs-de-validation) |
| `unknown provider "x" (known: dmr, llamacpp, llmman, ollama)` | Signalée par le moteur, sous la forme `[engine error: …]`. |

Un avertissement au démarrage, et non une erreur, est affiché quand `context.enabled` vaut `true`, que la fenêtre est inconnue et que `context.maxMessages` vaut `0`, et quand le fichier pose la clé obsolète `permissions` (`permissions: ask is deprecated — use yolo: false instead …`).

## Fichiers livrés

| Fichier | Rôle |
|---------|------|
| `agent.yaml` | Configuration Docker Model Runner : `provider: dmr`, `maxTurns: 40`, `displayCommands: true`, compression désactivée, un prompt système nommé « Bob » qui décrit les skills et les règles d'édition de fichiers. |
| `agent.llamacpp.yaml` | Configuration llama.cpp : `provider: llamacpp`, `baseUrl: http://127.0.0.1:8080/v1`, `fallback: ""`, compression activée. |

### Exemple

```yaml
provider: llamacpp
model: mon-alias
baseUrl: http://127.0.0.1:8080/v1
fallback: ""
maxTurns: 40
context:
  enabled: true
```