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, ollama, ou openai pour tout autre serveur compatible OpenAI (voir Utiliser n'importe quel serveur compatible OpenAI). 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. |
displayHooks |
booléen | false |
Affiche chaque hook exécuté : événement, commande, outil ou agent, décision, taille du contexte ajouté (jamais son texte). Après chaque réponse en mode ligne, en -p et dans la fenêtre ; sous forme d'appel d'outil terminé, un par hook, dans un éditeur. Voir hooks. |
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é. |
decision |
mapping ou absent | absent | Fait de l'agent un décideur : son modèle est un modèle de décision servi par POST /v1/systemone, et chaque message reçu obtient pour réponse ces questions. Voir decision ci-dessous. Fournisseurs llamacpp, llmman, ollama, openai seulement. |
skillRouting |
mapping | minConfidence: 0.6, timeout: 2s, pas de decider |
Avant chaque tour, demander à un décideur quel skill s'applique, et ajouter la ligne $skill s'il est assez sûr. Voir skillRouting ci-dessous. Désactivé sans decider. |
toolRouting |
mapping | dropBelow: 0.2, timeout: 2s, pas de decider |
Avant chaque tour, demander à un décideur de quels groupes d'outils la demande a besoin, et retirer de la requête les groupes qu'il écarte. Voir toolRouting ci-dessous. Désactivé sans decider. |
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. |
saveAnswerTool |
bool | false |
Déclare save_answer, qui écrit dans un nouveau fichier une réponse que le modèle a déjà donnée : le modèle envoie un nom de fichier, pas le texte une seconde fois. Désactivé par défaut. La commande /save existe dans tous les cas. Voir les outils. |
unloadModels |
bool | true |
La commande /unload [modèle] (terminal, fenêtre, éditeur) et l'outil unload_model, qui libèrent un modèle de la mémoire du serveur : llmman et Ollama, llama-server en mode router. false retire les deux. L'outil n'est jamais déclaré à côté d'une structuredOutput ni d'un bloc decision. Voir les outils et Libérer la mémoire d'un modèle. |
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. |
docSearch |
dictionnaire | voir ci-dessous | Recherche BM25 dans les fichiers texte de dossiers : la commande /docs et l'outil search_docs. |
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 ou wasm (un module WebAssembly, avec ses dossiers read / write), 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. |
tools |
liste | [] |
Des commandes ou des modules WebAssembly déclarés comme outils typés : chaque entrée a un name, une description, ses parameters, et une command exécutée sans shell ou un module wasm exécuté dans un bac à sable. Voir les clés de tools ci-dessous et les outils déclarés. |
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. |
sessions.searchMemory |
booléen | false |
La commande /memory <mots> (terminal, fenêtre, éditeur) : cherche dans les sessions enregistrées du projet. Demande sessions.enabled. Voir commandes et Chercher dans les sessions précédentes. |
sessions.autoSearchMemory |
booléen | false |
L'outil search_memory : la même recherche, appelée par le modèle. Indépendante de searchMemory. Demande sessions.enabled. |
Une clé de mémoire activée alors que sessions.enabled vaut false affiche au démarrage l'avertissement sessions: searchMemory / autoSearchMemory need sessions.enabled: true — /memory and search_memory are off.
Clés de docSearch
| Clé | Type | Défaut | Description |
|---|---|---|---|
docSearch.searchDocs |
booléen | false |
La commande /docs <mots> (terminal, fenêtre, éditeur). Voir commandes et Chercher dans un dossier de documentation. |
docSearch.autoSearchDocs |
booléen | false |
L'outil search_docs : la même recherche, appelée par le modèle. Indépendante de searchDocs. |
docSearch.dirs |
liste de chaînes | [docs] |
Les dossiers cherchés, récursivement. Un dossier relatif est résolu par rapport au répertoire de travail — celui où mm est lancé, le cwd de la session en mode ACP et dans la fenêtre ; un dossier absolu est utilisé tel quel. Un dossier qui n'existe pas est signalé dans le résultat (⚠️ <rép>: no such folder). |
docSearch.extensions |
liste de chaînes | [.md, .markdown, .txt, .adoc, .asciidoc, .rst] |
Les fichiers cherchés, par extension, comparée sans tenir compte de la casse. Seuls ceux-là sont lus. |
docSearch.maxFileSize |
taille | 1MB |
Un fichier plus gros est ignoré. Un nombre d'octets, ou avec KB / MB / GB (puissances de 1024) : 512KB. |
dirs, extensions et maxFileSize ne sont vérifiées que si searchDocs ou autoSearchDocs vaut true. Les dossiers cachés (.git, .mm…) et node_modules sont ignorés, les liens symboliques ne sont pas suivis, un fichier contenant un octet NUL est ignoré comme binaire.
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.
Clés de tools
| Clé | Type | Défaut | Description |
|---|---|---|---|
tools |
liste | [] |
Une entrée par outil déclaré. |
tools[].name |
chaîne | — | Le nom que le modèle appelle. Obligatoire. Commence par une lettre ; lettres, chiffres, _, - ; 64 caractères au plus. Unique. Pas le nom d'un outil intégré (ask_agent, ask_user, bash, edit_file, fetch_content, lsp, plan, read_file, read_skill, save_answer, search_docs, search_memory, unload_model, write_file), même désactivé dans cet agent. |
tools[].description |
chaîne | — | Ce que fait l'outil et quand s'en servir, montré au modèle. Obligatoire. Une ligne Required parameters: … y est ajoutée. |
tools[].parameters |
map nom → paramètre | {} |
Les arguments, dans l'ordre écrit. Les noms suivent les règles de name. |
tools[].parameters.<p>.type |
chaîne | string |
string, number, integer ou boolean. |
tools[].parameters.<p>.description |
chaîne | "" |
Ce qu'est la valeur, montré au modèle. |
tools[].parameters.<p>.enum |
liste | aucune | Les seules valeurs acceptées, chacune du type du paramètre. |
tools[].parameters.<p>.required |
bool | true |
false rend le paramètre facultatif. |
tools[].parameters.<p>.default |
valeur | aucune | La valeur d'un paramètre facultatif que l'appel omet. Seulement avec required: false ; du type du paramètre ; dans l'enum s'il y en a un. |
tools[].command |
liste de chaînes | — | Le programme, puis ses arguments, une entrée argv chacun. Obligatoire sauf si wasm est donné ; pas les deux. {{p}} dans une entrée est remplacé par la valeur du paramètre p. Le programme (première entrée) ne peut pas contenir de placeholder. Chaque placeholder doit nommer un paramètre déclaré. Un programme relatif (./scripts/x.sh) est résolu depuis le répertoire de travail. |
tools[].wasm |
chaîne | "" |
Un module WebAssembly (commande WASI preview 1) exécuté par mm à la place d'une commande. Relatif au fichier d'agent. Le fichier doit exister au chargement. Les arguments de l'appel sont son stdin, en un objet JSON. |
tools[].read |
liste de chaînes | [] |
wasm seulement. Dossiers du répertoire de travail que le module peut lire, montés sous le même nom. Relatifs, dans le répertoire de travail (ni ., ni au-dessus), chacun une seule fois dans read et write réunis. |
tools[].write |
liste de chaînes | [] |
wasm seulement. Dossiers du répertoire de travail que le module peut lire et écrire. Mêmes règles que read. |
tools[].timeout |
durée | 0 (= bashTimeout) |
Durée maximale d'un appel. Doit être ≥ 0. |
tools:
- name: release
description: Prepare a release of the project for a version and a channel.
parameters:
version: { type: string, description: "e.g. 1.4.2" }
channel: { type: string, enum: [stable, beta, nightly] }
dryRun: { type: boolean, required: false, default: false }
command: ["./scripts/release.sh", "{{version}}", "{{channel}}", "--dry-run={{dryRun}}"]
timeout: 60s
- name: search_notes
description: Find the lines of the notes that mention a word.
parameters:
word: { type: string }
wasm: ./tools/search_notes.wasm
read: [notes]
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 |
openai |
https://api.openai.com/v1 |
aucun | OPENAI_API_KEY |
non — un serveur qui en exige une répond 401, et l'avertissement de démarrage nomme la variable |
Le fournisseur openai n'envoie que des champs standard : pas de return_progress (donc pas de progression pendant la lecture d'un long prompt), pas d'interrupteur de raisonnement sur une requête de résumé, pas de /unload. Il ne peut pas demander sa fenêtre au serveur : renseignez contextWindow, sinon la compression compte les messages (context.maxMessages). Sa sonde de démarrage envoie la clé à GET /models ; un 401 ou un 403 est signalé comme une clé refusée, pas comme un serveur qui ne répond pas.
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 paragrapheOUTPUT 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é dethe answer was cut off by max_tokens before its JSON was complete …quand le serveur s'est arrêté surmax_tokens; -pimprime 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{}
decision
| Clé | Type | Défaut | Description |
|---|---|---|---|
timeout |
durée | 60s |
Borne d'une réponse. Doit être ≥ 0 ; 0 = la valeur par défaut. |
questions |
mapping nom → question | — | Au moins une. L'ordre du fichier est conservé : dans la requête, dans les lignes de réponse, et pour les options d'un choix. |
Une question :
| Clé | Type | Description |
|---|---|---|
type |
choice, noul ou score |
choice : une option parmi criteria. noul : la probabilité que instructions, une affirmation sur l'état, soit vraie. score : un niveau parmi criteria. |
instructions |
chaîne | La question (choice, score) ou l'affirmation (noul). Non vide. |
criteria |
mapping ou liste | choice : un mapping option → description, au moins 2 options. score : une liste de 2 à 10 niveaux, du plus bas au plus haut. noul : aucun. |
Réponses, telles que POST /v1/systemone les renvoie sous answers.<nom> :
| Type | Champs |
|---|---|
choice |
choice (l'option), probabilities (option → probabilité), confidence |
noul |
noul (probabilité que l'affirmation soit vraie) |
score |
score (indice de niveau pondéré par les probabilités, de 0 à n−1), legend (indice → niveau), probabilities (indice → probabilité), confidence |
Quand le bloc est présent :
-
le message reçu est l'état, seul : l'historique, le prompt système, les hooks et les outils ne sont pas envoyés ;
-
-pimprime le JSON du serveur seul sur stdout (voir Spécificités du mode invite) ; -
le mode ligne, la fenêtre et un éditeur (donc
/ask-<nom>etmm --ask) affichent une ligne par question, puis le JSON dans un bloc délimité :risk: dangerous (confidence 0.94) — dangerous 0.96 · local-change 0.03 · read-only 0.01 destructive: 0.88 urgency: 1.89 → a careful review (confidence 0.83) — a careful review 0.92 · a quick look 0.06 · no review needed 0.03 -
aucun outil ne peut être déclaré (
unload_modeln'est pas déclaré ;/unloadreste) ; -
la bannière affiche
tools: none (decision model: <n> question(s))et aucun avertissement « no skills » / « no tool ».
Exemple :
provider: llamacpp
model: LiquidAI/d1-3B-GGUF:Q4_K_M
baseUrl: http://127.0.0.1:8090/v1
decision:
questions:
risk:
type: choice
instructions: How risky is running this shell command in the project directory?
criteria:
read-only: Only reads files or prints information
local-change: Changes files inside the project, easy to rebuild or revert
dangerous: Deletes or changes things outside the project, uses sudo, the network, git push or force
destructive:
type: noul
instructions: The command deletes data that cannot be rebuilt.
urgency:
type: score
instructions: How carefully should a person review this command before it runs?
criteria: [no review needed, a quick look, a careful review]
bashTool: false
editTools: false
planTool: false
askUserTool: false
skillsDir: no-skills
Serveurs
| Fournisseur | /v1/systemone (vérifié le 2026-10-22) |
|---|---|
llamacpp |
oui |
llmman |
oui |
ollama |
oui |
openai |
celle du serveur : un serveur sans la route répond 404 |
dmr |
non (404, Docker Model Runner v1.2.8) — refusé au démarrage |
La route sert les modèles qu'elle reconnaît comme modèles de décision : LiquidAI d1 (LiquidAI/d1-3B-GGUF:Q4_K_M) a été accepté par les trois ; decision-4b d'evalengine a été refusé par llmman (501 This model is not a decision model) et Ollama (400 … is not a llama.cpp decision model).
skillRouting
| Clé | Type | Défaut | Description |
|---|---|---|---|
decider |
chemin | "" |
Fichier d'agent du modèle de décision, relatif à ce fichier. Ses provider, model, baseUrl, fallback et apiKeyEnv sont utilisés — pas AGENT_BASE_URL, qui désigne le serveur de cet agent-ci ; pas son bloc decision. Doit exister. Vide = routage désactivé. |
minConfidence |
nombre | 0.6 |
Sous la confidence du serveur pour le skill choisi, rien n'est ajouté. Entre 0 et 1. |
timeout |
durée | 2s |
Borne de la question de routage. Doit être > 0. |
Avant chaque tour — mode ligne, fenêtre, éditeur — quand la question ne nomme aucun $skill et que le catalogue n'est pas vide, mm envoie une question choice : la demande (coupée à 1 500 caractères) comme état, une option par skill (son nom et sa description, dans l'ordre du catalogue), puis none. Le front end affiche ensuite une notice :
| Notice | Signification | Ajouté à la question |
|---|---|---|
🧭 $<skill> (<confidence>) |
choisi à minConfidence ou au-dessus |
[skill: <skill> — load it with read_skill and carry out its steps now] |
🧭 no skill (none <confidence>) |
le décideur a choisi none |
rien |
🧭 no skill (<skill> <confidence> < <minConfidence>) |
choisi sous minConfidence |
rien |
🧭 skill routing skipped: <erreur> |
le décideur a échoué ou dépassé timeout |
rien |
Dans un éditeur, la notice va dans le journal stderr de l'agent ([acp] session <id>: …). -p ne route pas. La bannière ajoute | routing: <fournisseur>/<modèle> ≥ <minConfidence>.
Exemple :
skillRouting:
decider: agent.decider.yaml
minConfidence: 0.6
timeout: 2s
toolRouting
| Clé | Type | Défaut | Description |
|---|---|---|---|
decider |
chemin | "" |
Fichier d'agent du modèle de décision, relatif à ce fichier — lu comme pour skillRouting. Doit exister. Vide = routage désactivé. |
dropBelow |
nombre | 0.2 |
Un groupe dont la probabilité est en dessous est retiré. Entre 0 et 1. |
timeout |
durée | 2s |
Borne de la question de routage. Doit être > 0. |
groups |
mapping | — | Au moins un. Nom → when (l'affirmation que juge le décideur : « répondre à cette demande nécessite … ») et matcher (une expression régulière sur le nom des outils, comme celle d'un hook). Les deux sont obligatoires. Gardés dans l'ordre du fichier. |
Avant chaque tour — dans tous les modes, -p compris, après les hooks preGeneration — mm envoie une question noul par groupe qui correspond à au moins un outil de l'agent, avec la demande (la question que lira le modèle, coupée à 1 500 caractères) comme état. Un outil est retiré de la requête quand il appartient à au moins un groupe et que tous ses groupes ont obtenu moins que dropBelow. Un outil hors de tout groupe est toujours proposé ; tous les outils le sont quand le décideur échoue ou dépasse timeout. Une notice est affichée :
| Notice | Sens |
|---|---|
🧰 tools: dropped <groupe> (<probabilité>), … |
ces groupes ne sont pas proposés pour ce tour |
🧰 tools: all kept |
aucun groupe sous dropBelow |
🧰 tool routing skipped: <erreur> |
le décideur a échoué ou dépassé timeout ; tous les outils sont proposés |
Aucune question n'est envoyée, ni notice affichée, quand aucun groupe ne correspond à un outil de l'agent. Le bandeau ajoute | tool routing: <provider>/<model>, <n> group(s), drop < <dropBelow>.
Exemple :
toolRouting:
decider: agent.decider.yaml
dropBelow: 0.2
timeout: 5s
groups:
shell:
when: Answering this request needs running shell commands (build, test, git, listing files).
matcher: ^bash$
web:
when: Answering this request needs fetching a web page or searching the web.
matcher: ^fetch_content$
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 |
docSearch.dirs must name at least one folder |
dirs: [] avec un interrupteur activé |
docSearch.dirs: a folder must not be empty |
dirs: [""] |
docSearch.extensions must name at least one extension |
extensions: [] avec un interrupteur activé |
docSearch.extensions: "md" must start with a dot, like ".md" |
une extension sans son point |
docSearch.maxFileSize must be > 0 |
maxFileSize: 0 avec un interrupteur activé |
line N: "huge" is not a size: write 1MB, 512KB or a number of bytes |
une maxFileSize qui n'est pas une taille |
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 |
tools[N] (<nom>).name "<nom>" must start with a letter and hold only letters, digits, _ or - (64 characters at most) |
un nom d'outil invalide |
tools[N] (<nom>).name "<nom>" is the name of a built-in tool |
un outil déclaré qui porte le nom d'un outil intégré |
tools[N] (<nom>): another tool is already called "<nom>" |
deux entrées de même nom |
tools[N] (<nom>).description must not be empty: … |
pas de description |
tools[N] (<nom>).command must name a program, … |
ni command ni wasm, ou une première entrée vide |
tools[N] (<nom>): give command or wasm, not both |
une entrée avec les deux |
tools[N] (<nom>): wasm: no module at <chemin> |
le fichier du module n'existe pas, ou c'est un dossier |
tools[N] (<nom>): read and write only apply to a wasm tool — … |
read ou write sur une entrée command |
tools[N] (<nom>): folder "<d>" must be relative to the working directory |
un dossier absolu |
tools[N] (<nom>): folder "<d>" must be a folder inside the working directory, not it or above it |
., .. ou un chemin qui remonte au-dessus |
tools[N] (<nom>): folder "<d>" is given twice |
un dossier listé deux fois, dans read, write ou les deux |
tools[N] (<nom>).command: the program ("{{p}}") cannot come from a parameter |
un placeholder dans la première entrée |
tools[N] (<nom>).command: {{p}} is not a declared parameter |
un placeholder qu'aucun paramètre ne déclare |
tools[N] (<nom>).timeout must be >= 0 |
un timeout négatif |
tools[N] (<nom>).parameters.<p>.type "x" must be one of string, number, integer, boolean |
un type inconnu |
tools[N] (<nom>).parameters.<p>.enum: … |
une valeur d'enum qui n'est pas du type du paramètre |
tools[N] (<nom>).parameters.<p>.default only makes sense with required: false |
un default sur un paramètre obligatoire |
tools[N] (<nom>).parameters.<p>.default: …, ….default <v> is not one of the enum values |
un default du mauvais type, ou hors de l'enum |
tools[N] (<nom>).parameters.<p>: declared twice, …: a parameter name must start with a letter … |
un nom de paramètre répété ou invalide |
line N: parameters must be a mapping of name → {type, description, …} |
parameters: écrit comme une liste |
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 |
decision.questions: at least one question is needed |
un bloc decision sans questions |
line <n>: decision: unknown key "<clé>" (timeout, questions) / line <n>: question "<nom>": unknown key … |
une clé mal orthographiée dans le bloc |
line <n>: question "<nom>": unknown type "<type>" (choice, noul or score) |
type n'est pas l'un des trois |
line <n>: question "<nom>": a choice needs at least 2 options, got <n> / a score needs 2 to 10 levels, got <n> / a noul question takes no criteria |
criteria de mauvaise forme ou taille |
decision: dmr: no /v1/systemone route (…) |
decision avec provider: dmr |
decision and structuredOutput cannot be used together: … |
les deux dans un même fichier |
decision cannot be used with tools — this agent declares: <outils> (…) |
un décideur avec un outil déclaré ; signalé après l'assemblage des outils |
skillRouting.decider: … |
le fichier du décideur manque, n'a pas de provider ou de model, ou nomme dmr |
skillRouting.minConfidence must be between 0 and 1 / skillRouting.timeout must be > 0 |
hors limites |
toolRouting.decider: … |
le fichier du décideur manque, n'a pas de provider ou de model, ou nomme dmr |
toolRouting.dropBelow must be between 0 and 1 / toolRouting.timeout must be > 0 |
hors limites |
toolRouting.groups: at least one group is needed / toolRouting.groups.<nom>: when must not be empty / … matcher must not be empty / toolRouting.groups.<nom>.matcher: … |
un groupe, une affirmation ou un matcher manquant, ou un matcher qui ne compile pas |
line <n>: toolRouting: unknown key "<clé>" (decider, dropBelow, timeout, groups) |
une clé mal orthographiée dans le bloc |
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, les tools déclarés). 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, quand un outil déclaré porte le nom d'un outil MCP (tools: <nom> skipped — an MCP tool already has that name ; l'outil n'est pas déclaré), 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 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
|