bots-garden/mini-mepublic Fork
⑂ 9a5c4ec
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.

k33g committed 2026-10-25T06:23:41+01:00 Browse files
9a5c4ec parent: cd2a817
modified .tickets/epics.yaml +3 -0
@@ -51,3 +51,6 @@ epics:
5151 - title: Decision models
5252 state: open
5353 color: "#c5def5"
54+ - title: WASM Module
55+ state: open
56+ color: "#5319e7"
@@ -51,3 +51,6 @@ epics:
51 - title: Decision models51 - title: Decision models
52 state: open52 state: open
53 color: "#c5def5"53 color: "#c5def5"
54+ - title: WASM Module
55+ state: open
56+ color: "#5319e7"
modified .tickets/issues/0056-blog-post-idea-how-to-query-a-decision-model-fro.yaml +2 -2
@@ -1,12 +1,12 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 56
33 title: "Blog post idea: how to query a decision model from a coding agent (skill?)"
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-30T06:50:30.091Z
9-updatedAt: 2026-10-06T13:12:26.692Z
9+updatedAt: 2026-10-25T04:16:19.984Z
1010 labels: []
1111 epic: ToDo
1212 body: ""
@@ -1,12 +1,12 @@
1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.1 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2 id: 562 id: 56
3 title: "Blog post idea: how to query a decision model from a coding agent (skill?)"3 title: "Blog post idea: how to query a decision model from a coding agent (skill?)"
4-state: open4+state: closed
5 author:5 author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-30T06:50:30.091Z8 createdAt: 2026-09-30T06:50:30.091Z
9-updatedAt: 2026-10-06T13:12:26.692Z9+updatedAt: 2026-10-25T04:16:19.984Z
10 labels: []10 labels: []
11 epic: ToDo11 epic: ToDo
12 body: ""12 body: ""
modified .tickets/issues/0075-add-gronk-provider.yaml +2 -2
@@ -6,10 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-06T03:58:37.611Z
9-updatedAt: 2026-10-22T17:11:08.086Z
9+updatedAt: 2026-10-25T04:15:36.796Z
1010 labels: []
1111 milestone: v1.0.1
12-epic: Providers (LLM Engine)
12+epic: Providers
1313 body: ""
1414 tasks: []
1515 comments: []
@@ -6,10 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-06T03:58:37.611Z8 createdAt: 2026-10-06T03:58:37.611Z
9-updatedAt: 2026-10-22T17:11:08.086Z9+updatedAt: 2026-10-25T04:15:36.796Z
10 labels: []10 labels: []
11 milestone: v1.0.111 milestone: v1.0.1
12-epic: Providers (LLM Engine)12+epic: Providers
13 body: ""13 body: ""
14 tasks: []14 tasks: []
15 comments: []15 comments: []
added .tickets/issues/0142-memory-how-it-works.yaml +76 -0
new file mode 100644
@@ -0,0 +1,76 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 142
3+title: "Memory: how it works ?"
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T11:48:07.733Z
9+updatedAt: 2026-10-24T14:00:00.000Z
10+labels: []
11+milestone: v1.0.1
12+body: |
13+ How mm keeps things in the conversation history ("memory"), answered from the
14+ code on 2026-10-24. Nothing changed yet; candidate for a docs page.
15+
16+ ## Skills in the history: does a used skill disappear?
17+
18+ No. Three pieces, each kept differently:
19+
20+ 1. The catalogue (name, description, up to 8 keywords per skill) is the
21+ DESCRIPTION of the `read_skill` tool (`internal/skills/skills.go`,
22+ `Catalogue`), not a system-prompt paragraph. It goes out with every
23+ request, is never a message, never compressed, and is paid for on every
24+ turn (hence `maxKeywords`).
25+ 2. `$greetings Bob`, or a skill picked by the decider, appends a line to the
26+ USER message (`internal/skills/refs.go`, `internal/decide/route.go`):
27+ `[skill: greetings — load it with read_skill and carry out its steps now; parameters: Bob]`.
28+ It stays in the history like the rest of the question.
29+ 3. The skill's markdown enters the history as the `read_skill` TOOL RESPONSE,
30+ truncated at `maxOutput` (16000 by default). The user only sees
31+ `📖 read_skill: greetings`.
32+
33+ How long it stays:
34+
35+ - Next turns, no compression: as is, re-read on every request. The model may
36+ still call `read_skill` again, which adds a second copy.
37+ - Automatic compression (`context.enabled`, false by default) or `/compact`:
38+ the last `keepLastTurns` (3) question turns stay raw; older turns, their
39+ `read_skill` calls included, become the summary. The skill text is gone, at
40+ best mentioned in the notes; the catalogue is still there, so it can be
41+ reloaded.
42+ - `/new`, `/quit`: history emptied. `mm -p`: one question, nothing persists.
43+
44+ docs/*/explanation/context-compression.md already says that every bash
45+ output and every loaded skill stay until `/quit`. Consequence: several skills
46+ loaded over a long session fill the window; on a local model, a reason to
47+ turn `context.enabled` on.
48+
49+ ## Sessions on: does ↑ reload the whole history?
50+
51+ No. ↑ (window only, `sessions.enabled: true`) puts the TEXT of a past
52+ question in the input box (`internal/tui/recall.go`,
53+ `internal/store/questions.go` `Keeper.Questions`): the current session's
54+ questions first, then the project's other stored sessions, newest first, 200
55+ at most. Sent, it is a new question in the CURRENT conversation; the model
56+ sees none of the old answers, tool outputs or loaded skills.
57+
58+ - A recalled question is what the model read: with its `[attached file: …]`
59+ lines and pastes in full. Left out: a hook's context, `/compact` summaries,
60+ mm's notes, `/` commands.
61+ - Without sessions, ↑ scrolls the conversation.
62+
63+ What does reload a conversation:
64+
65+ | Action | Model history |
66+ |---|---|
67+ | starting `mm` | a NEW empty session; never resumes the last one by itself |
68+ | ↑ | untouched, only the input box changes |
69+ | `/resume [id]` | ALL the session's messages (questions, answers, tool calls, loaded skills); today's system prompt and AGENTS.md |
70+ | `session/load` (ACP) | the same, replayed to the editor |
71+ | `/new` | emptied, new file |
72+
73+ So a skill loaded in an old session comes back with `/resume`, as a tool
74+ result in the history.
75+tasks: []
76+comments: []
new file mode 100644
@@ -0,0 +1,76 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 142
3+title: "Memory: how it works ?"
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T11:48:07.733Z
9+updatedAt: 2026-10-24T14:00:00.000Z
10+labels: []
11+milestone: v1.0.1
12+body: |
13+ How mm keeps things in the conversation history ("memory"), answered from the
14+ code on 2026-10-24. Nothing changed yet; candidate for a docs page.
15+
16+ ## Skills in the history: does a used skill disappear?
17+
18+ No. Three pieces, each kept differently:
19+
20+ 1. The catalogue (name, description, up to 8 keywords per skill) is the
21+ DESCRIPTION of the `read_skill` tool (`internal/skills/skills.go`,
22+ `Catalogue`), not a system-prompt paragraph. It goes out with every
23+ request, is never a message, never compressed, and is paid for on every
24+ turn (hence `maxKeywords`).
25+ 2. `$greetings Bob`, or a skill picked by the decider, appends a line to the
26+ USER message (`internal/skills/refs.go`, `internal/decide/route.go`):
27+ `[skill: greetings — load it with read_skill and carry out its steps now; parameters: Bob]`.
28+ It stays in the history like the rest of the question.
29+ 3. The skill's markdown enters the history as the `read_skill` TOOL RESPONSE,
30+ truncated at `maxOutput` (16000 by default). The user only sees
31+ `📖 read_skill: greetings`.
32+
33+ How long it stays:
34+
35+ - Next turns, no compression: as is, re-read on every request. The model may
36+ still call `read_skill` again, which adds a second copy.
37+ - Automatic compression (`context.enabled`, false by default) or `/compact`:
38+ the last `keepLastTurns` (3) question turns stay raw; older turns, their
39+ `read_skill` calls included, become the summary. The skill text is gone, at
40+ best mentioned in the notes; the catalogue is still there, so it can be
41+ reloaded.
42+ - `/new`, `/quit`: history emptied. `mm -p`: one question, nothing persists.
43+
44+ docs/*/explanation/context-compression.md already says that every bash
45+ output and every loaded skill stay until `/quit`. Consequence: several skills
46+ loaded over a long session fill the window; on a local model, a reason to
47+ turn `context.enabled` on.
48+
49+ ## Sessions on: does ↑ reload the whole history?
50+
51+ No. ↑ (window only, `sessions.enabled: true`) puts the TEXT of a past
52+ question in the input box (`internal/tui/recall.go`,
53+ `internal/store/questions.go` `Keeper.Questions`): the current session's
54+ questions first, then the project's other stored sessions, newest first, 200
55+ at most. Sent, it is a new question in the CURRENT conversation; the model
56+ sees none of the old answers, tool outputs or loaded skills.
57+
58+ - A recalled question is what the model read: with its `[attached file: …]`
59+ lines and pastes in full. Left out: a hook's context, `/compact` summaries,
60+ mm's notes, `/` commands.
61+ - Without sessions, ↑ scrolls the conversation.
62+
63+ What does reload a conversation:
64+
65+ | Action | Model history |
66+ |---|---|
67+ | starting `mm` | a NEW empty session; never resumes the last one by itself |
68+ | ↑ | untouched, only the input box changes |
69+ | `/resume [id]` | ALL the session's messages (questions, answers, tool calls, loaded skills); today's system prompt and AGENTS.md |
70+ | `session/load` (ACP) | the same, replayed to the editor |
71+ | `/new` | emptied, new file |
72+
73+ So a skill loaded in an old session comes back with `/resume`, as a tool
74+ result in the history.
75+tasks: []
76+comments: []
added .tickets/issues/0143-improve-management-of-the-skills-in-memory.yaml +92 -0
new file mode 100644
@@ -0,0 +1,92 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 143
3+title: Improve management of the skills in memory
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T11:49:03.667Z
9+updatedAt: 2026-10-24T15:00:00.000Z
10+labels: []
11+milestone: v1.0.1
12+related:
13+ - 142
14+ - 53
15+body: |
16+ Should a loaded skill stay in the history, be removed, or be removed when the
17+ context is compressed? Reflection of 2026-10-24, nothing implemented or
18+ measured yet. How it works today: see ticket 142.
19+
20+ ## Facts it rests on (checked in the code)
21+
22+ - A skill's markdown enters the history as the `read_skill` tool response
23+ (truncated at `maxOutput`) and stays until `/new`, `/quit` or a
24+ compression. The catalogue is the tool description, sent every request,
25+ so a skill can ALWAYS be loaded again.
26+ - Size: the repo's skills go from 0.4 KB (what-time-is-it) to 12.5 KB
27+ (plan-manager), i.e. ~100 to ~3000 tokens each, against 8k–32k windows on
28+ the local models mm targets.
29+ - Compression (`internal/compact`) already drops the skill text of the old
30+ turns, but its summary prompt has no section for skills: after a
31+ compression the model is not told which procedure it was following.
32+ - llama.cpp reuses the prompt prefix between requests. Rewriting an OLD
33+ message makes it re-read everything after it (ticket 53 measured
34+ ~3,400–3,900 tokens / 7–9 s per re-read on a 12B). A compression rewrites
35+ everything anyway, so it is the free moment to change the history.
36+ - The loop detector keeps a sliding list of actions (reset by `/new` and
37+ `/resume`); a skill reloaded on a later turn may count as a repeat — to
38+ check before relying on reloads.
39+
40+ ## The three options
41+
42+ 1. Keep it (today). + multi-turn procedures keep working ("do X", "now fix",
43+ "and test" all read the same steps); + the prefix cache is never broken;
44+ + a resumed session holds it. − every turn pays for it; − loading the
45+ same skill twice stores it twice; − several skills in a long session fill
46+ the window and trigger compressions sooner.
47+ 2. Remove it after the turn (replace the tool response with a stub such as
48+ `[skill greetings was loaded here; call read_skill again to follow it]`).
49+ + the cheapest history. − breaks the follow-up turns of a multi-step
50+ skill: a small model may NOT reload and improvise instead (mm already
51+ added `📖 0 skill(s)` and decider skill routing because models skip
52+ read_skill); − every reload costs one
53+ more tool round trip; − the session file and the ACP replay show a stub,
54+ not what the model read. Rewriting just after the turn is cheap for the
55+ cache (only the turn's tail is re-read); doing it later is not.
56+ 3. Remove it at compression only (today's behaviour) — but then say so.
57+ + no cache cost, the only moment the history is rewritten anyway; + the
58+ recent turns (`keepLastTurns`) keep their skills, which is where a
59+ procedure is usually still running. − without compression on
60+ (`context.enabled` is false by default) nothing is ever removed.
61+
62+ ## Recommendation
63+
64+ Option 3 as the rule, plus two small changes, and no option 2 by default:
65+
66+ a. At compression, the summary pair gets a line written BY THE CODE (not by
67+ the summarizer, so it cannot be forgotten): the skills loaded in the
68+ compressed turns, e.g. `Skills used before this summary: go-rename,
69+ bg-jobs — call read_skill again to follow one.` Optionally a `## Skills`
70+ section in DefaultPrompt saying which one was in progress and at which
71+ step.
72+ b. Dedup at load time instead of rewriting the past: when `read_skill` is
73+ asked for a skill whose full text is still in the (uncompressed) history,
74+ answer `[skill X is already loaded above; follow it]` instead of a second
75+ copy. No old message changes, so no cache cost. Risk: a small model may
76+ attend poorly to a copy far up — measure before making it the default;
77+ a skill edited on disk since the first load must get the new text.
78+ c. Option 2 only as an opt-in setting, for very small windows (e.g.
79+ `skills.keep: session | turn`, default `session`), and only if a
80+ measurement shows a gain.
81+
82+ ## To measure before deciding
83+
84+ - Multi-turn skill (e.g. a 3-step procedure over 3 questions) with options
85+ 1/2/3 on Qwen3.5-4B: does the model finish the steps, does it reload?
86+ - Token cost per turn of options 1 and b on a session loading the same skill
87+ 3 times (server `input_tokens`).
88+ - After a compression, with and without line a: does the model reload the
89+ skill it was following?
90+ - Whether the loop detector fires on a reload across turns.
91+tasks: []
92+comments: []
new file mode 100644
@@ -0,0 +1,92 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 143
3+title: Improve management of the skills in memory
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T11:49:03.667Z
9+updatedAt: 2026-10-24T15:00:00.000Z
10+labels: []
11+milestone: v1.0.1
12+related:
13+ - 142
14+ - 53
15+body: |
16+ Should a loaded skill stay in the history, be removed, or be removed when the
17+ context is compressed? Reflection of 2026-10-24, nothing implemented or
18+ measured yet. How it works today: see ticket 142.
19+
20+ ## Facts it rests on (checked in the code)
21+
22+ - A skill's markdown enters the history as the `read_skill` tool response
23+ (truncated at `maxOutput`) and stays until `/new`, `/quit` or a
24+ compression. The catalogue is the tool description, sent every request,
25+ so a skill can ALWAYS be loaded again.
26+ - Size: the repo's skills go from 0.4 KB (what-time-is-it) to 12.5 KB
27+ (plan-manager), i.e. ~100 to ~3000 tokens each, against 8k–32k windows on
28+ the local models mm targets.
29+ - Compression (`internal/compact`) already drops the skill text of the old
30+ turns, but its summary prompt has no section for skills: after a
31+ compression the model is not told which procedure it was following.
32+ - llama.cpp reuses the prompt prefix between requests. Rewriting an OLD
33+ message makes it re-read everything after it (ticket 53 measured
34+ ~3,400–3,900 tokens / 7–9 s per re-read on a 12B). A compression rewrites
35+ everything anyway, so it is the free moment to change the history.
36+ - The loop detector keeps a sliding list of actions (reset by `/new` and
37+ `/resume`); a skill reloaded on a later turn may count as a repeat — to
38+ check before relying on reloads.
39+
40+ ## The three options
41+
42+ 1. Keep it (today). + multi-turn procedures keep working ("do X", "now fix",
43+ "and test" all read the same steps); + the prefix cache is never broken;
44+ + a resumed session holds it. − every turn pays for it; − loading the
45+ same skill twice stores it twice; − several skills in a long session fill
46+ the window and trigger compressions sooner.
47+ 2. Remove it after the turn (replace the tool response with a stub such as
48+ `[skill greetings was loaded here; call read_skill again to follow it]`).
49+ + the cheapest history. − breaks the follow-up turns of a multi-step
50+ skill: a small model may NOT reload and improvise instead (mm already
51+ added `📖 0 skill(s)` and decider skill routing because models skip
52+ read_skill); − every reload costs one
53+ more tool round trip; − the session file and the ACP replay show a stub,
54+ not what the model read. Rewriting just after the turn is cheap for the
55+ cache (only the turn's tail is re-read); doing it later is not.
56+ 3. Remove it at compression only (today's behaviour) — but then say so.
57+ + no cache cost, the only moment the history is rewritten anyway; + the
58+ recent turns (`keepLastTurns`) keep their skills, which is where a
59+ procedure is usually still running. − without compression on
60+ (`context.enabled` is false by default) nothing is ever removed.
61+
62+ ## Recommendation
63+
64+ Option 3 as the rule, plus two small changes, and no option 2 by default:
65+
66+ a. At compression, the summary pair gets a line written BY THE CODE (not by
67+ the summarizer, so it cannot be forgotten): the skills loaded in the
68+ compressed turns, e.g. `Skills used before this summary: go-rename,
69+ bg-jobs — call read_skill again to follow one.` Optionally a `## Skills`
70+ section in DefaultPrompt saying which one was in progress and at which
71+ step.
72+ b. Dedup at load time instead of rewriting the past: when `read_skill` is
73+ asked for a skill whose full text is still in the (uncompressed) history,
74+ answer `[skill X is already loaded above; follow it]` instead of a second
75+ copy. No old message changes, so no cache cost. Risk: a small model may
76+ attend poorly to a copy far up — measure before making it the default;
77+ a skill edited on disk since the first load must get the new text.
78+ c. Option 2 only as an opt-in setting, for very small windows (e.g.
79+ `skills.keep: session | turn`, default `session`), and only if a
80+ measurement shows a gain.
81+
82+ ## To measure before deciding
83+
84+ - Multi-turn skill (e.g. a 3-step procedure over 3 questions) with options
85+ 1/2/3 on Qwen3.5-4B: does the model finish the steps, does it reload?
86+ - Token cost per turn of options 1 and b on a session loading the same skill
87+ 3 times (server `input_tokens`).
88+ - After a compression, with and without line a: does the model reload the
89+ skill it was following?
90+ - Whether the loop detector fires on a reload across turns.
91+tasks: []
92+comments: []
added .tickets/issues/0144-when-you-use-memory-how-to-use-the-result.yaml +58 -0
new file mode 100644
@@ -0,0 +1,58 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 144
3+title: When you use /memory how to use the result
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T16:59:56.623Z
9+updatedAt: 2026-10-24T17:30:00.000Z
10+labels: []
11+milestone: v1.0.1
12+related:
13+ - 48
14+ - 142
15+body: |
16+ How to use what `/memory <words>` finds. Answered from the docs on
17+ 2026-10-24 (docs/*/how-to/search-earlier-sessions.md, the slash-commands
18+ reference); nothing changed yet.
19+
20+ `/memory` is display-only: the model is not called and the history is not
21+ touched, so the model never sees the hits. Three ways to use one:
22+
23+ 1. Resume the conversation it comes from. Each hit starts with its session
24+ id:
25+
26+ 🔎 2 hit(s) for "port api" in /work/project/.mm/sessions
27+ 20261010-090000-aaaaaaaa · 2026-10-10 09:30 · turn 1 · question
28+ Which port should the API server listen on?
29+ → Let's use port 8417 for the API server: 8080 is already taken by the admin UI.
30+
31+ `/resume 20261010-090000-aaaaaaaa` reloads that whole conversation
32+ (terminal and window; in an editor, through its session list,
33+ `session/load`).
34+ 2. Quote the passage in the next question, keeping the current
35+ conversation: `We decided "port 8417 for the API server". Write
36+ config.go with that port.` Simplest when one decision matters. Not
37+ checked: whether `/copy` / Ctrl-Y copy a `/memory` output — they copy the
38+ last model ANSWER.
39+ 3. Let the model search: `sessions.autoSearchMemory: true` declares
40+ `search_memory`; "write config.go with the port agreed last time" makes
41+ the model call it, and the hits enter the history as a tool result.
42+ `searchMemory` (the command) and `autoSearchMemory` (the tool) are
43+ independent.
44+
45+ Limits: words, not meanings (use the words actually written, often
46+ English); the conversation in progress and tool calls are not searched —
47+ questions, answers and `/compact` summaries are.
48+
49+ ## Possible improvements (not decided)
50+
51+ - A way to hand a hit to the model without retyping it, e.g. `/memory`
52+ followed by a pick (`/memory use 2`) that adds the hit, as quoted context,
53+ to the next question — like `@path` does for a file.
54+ - Make `/copy` able to copy the last `/memory` output (check first what it
55+ does today).
56+ - Say in the `/memory` output itself how to use it (`/resume <id>` hint).
57+tasks: []
58+comments: []
new file mode 100644
@@ -0,0 +1,58 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 144
3+title: When you use /memory how to use the result
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-24T16:59:56.623Z
9+updatedAt: 2026-10-24T17:30:00.000Z
10+labels: []
11+milestone: v1.0.1
12+related:
13+ - 48
14+ - 142
15+body: |
16+ How to use what `/memory <words>` finds. Answered from the docs on
17+ 2026-10-24 (docs/*/how-to/search-earlier-sessions.md, the slash-commands
18+ reference); nothing changed yet.
19+
20+ `/memory` is display-only: the model is not called and the history is not
21+ touched, so the model never sees the hits. Three ways to use one:
22+
23+ 1. Resume the conversation it comes from. Each hit starts with its session
24+ id:
25+
26+ 🔎 2 hit(s) for "port api" in /work/project/.mm/sessions
27+ 20261010-090000-aaaaaaaa · 2026-10-10 09:30 · turn 1 · question
28+ Which port should the API server listen on?
29+ → Let's use port 8417 for the API server: 8080 is already taken by the admin UI.
30+
31+ `/resume 20261010-090000-aaaaaaaa` reloads that whole conversation
32+ (terminal and window; in an editor, through its session list,
33+ `session/load`).
34+ 2. Quote the passage in the next question, keeping the current
35+ conversation: `We decided "port 8417 for the API server". Write
36+ config.go with that port.` Simplest when one decision matters. Not
37+ checked: whether `/copy` / Ctrl-Y copy a `/memory` output — they copy the
38+ last model ANSWER.
39+ 3. Let the model search: `sessions.autoSearchMemory: true` declares
40+ `search_memory`; "write config.go with the port agreed last time" makes
41+ the model call it, and the hits enter the history as a tool result.
42+ `searchMemory` (the command) and `autoSearchMemory` (the tool) are
43+ independent.
44+
45+ Limits: words, not meanings (use the words actually written, often
46+ English); the conversation in progress and tool calls are not searched —
47+ questions, answers and `/compact` summaries are.
48+
49+ ## Possible improvements (not decided)
50+
51+ - A way to hand a hit to the model without retyping it, e.g. `/memory`
52+ followed by a pick (`/memory use 2`) that adds the hit, as quoted context,
53+ to the next question — like `@path` does for a file.
54+ - Make `/copy` able to copy the last `/memory` output (check first what it
55+ does today).
56+ - Say in the `/memory` output itself how to use it (`/resume <id>` hint).
57+tasks: []
58+comments: []
added .tickets/issues/0145-oss-closed-source-and-commercial-modules.yaml +15 -0
new file mode 100644
@@ -0,0 +1,15 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 145
3+title: OSS, Closed source and commercial modules [???]
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:19:37.267Z
9+updatedAt: 2026-10-25T04:19:49.790Z
10+labels:
11+ - question
12+epic: WASM Module
13+body: ""
14+tasks: []
15+comments: []
new file mode 100644
@@ -0,0 +1,15 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 145
3+title: OSS, Closed source and commercial modules [???]
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:19:37.267Z
9+updatedAt: 2026-10-25T04:19:49.790Z
10+labels:
11+ - question
12+epic: WASM Module
13+body: ""
14+tasks: []
15+comments: []
added .tickets/issues/0146-pii-module-in-and-out.yaml +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 146
3+title: PII module (in and out)
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:20:26.498Z
9+updatedAt: 2026-10-25T04:20:26.498Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 146
3+title: PII module (in and out)
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:20:26.498Z
9+updatedAt: 2026-10-25T04:20:26.498Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
added .tickets/issues/0147-secrets-modules-i-m-not-sure-it-s-even-possible.yaml +15 -0
new file mode 100644
@@ -0,0 +1,15 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 147
3+title: Secrets modules (I'm not sure it's even possible)
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:21:21.430Z
9+updatedAt: 2026-10-25T04:27:06.279Z
10+labels: []
11+epic: WASM Module
12+body: |
13+ Secrets detection
14+tasks: []
15+comments: []
new file mode 100644
@@ -0,0 +1,15 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 147
3+title: Secrets modules (I'm not sure it's even possible)
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:21:21.430Z
9+updatedAt: 2026-10-25T04:27:06.279Z
10+labels: []
11+epic: WASM Module
12+body: |
13+ Secrets detection
14+tasks: []
15+comments: []
added .tickets/issues/0148-prompt-injection-module.yaml +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 148
3+title: Prompt injection module
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:22:10.628Z
9+updatedAt: 2026-10-25T04:22:10.628Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 148
3+title: Prompt injection module
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:22:10.628Z
9+updatedAt: 2026-10-25T04:22:10.628Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
added .tickets/issues/0149-safety-module.yaml +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 149
3+title: Safety module
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:22:22.136Z
9+updatedAt: 2026-10-25T04:22:22.136Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 149
3+title: Safety module
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:22:22.136Z
9+updatedAt: 2026-10-25T04:22:22.136Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
added .tickets/issues/0150-blog-post-to-explain-how-to-create-a-wam-hook.yaml +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 150
3+title: Blog post to explain how to create a wam hook
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:23:22.576Z
9+updatedAt: 2026-10-25T04:23:22.576Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 150
3+title: Blog post to explain how to create a wam hook
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:23:22.576Z
9+updatedAt: 2026-10-25T04:23:22.576Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
added .tickets/issues/0151-blog-post-to-explain-how-to-create-a-wasm-declar.yaml +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 151
3+title: Blog post to explain how to create a wasm declared tool
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:23:41.209Z
9+updatedAt: 2026-10-25T04:23:41.209Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
new file mode 100644
@@ -0,0 +1,14 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 151
3+title: Blog post to explain how to create a wasm declared tool
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:23:41.209Z
9+updatedAt: 2026-10-25T04:23:41.209Z
10+labels: []
11+epic: WASM Module
12+body: ""
13+tasks: []
14+comments: []
added .tickets/issues/0152-dev-team.yaml +174 -0
new file mode 100644
@@ -0,0 +1,174 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 152
3+title: Dev team
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:44:30.351Z
9+updatedAt: 2026-10-25T05:15:11.308Z
10+labels: []
11+epic: Demos
12+body: |+
13+ ### Objectifs
14+
15+ Faire une équipe d'agents (sur le même principe que les projets dans ./demos) qui permettrait d'aider à coder.
16+
17+
18+ ### Contraintes
19+
20+ - On reste avec des modèles de taille raisonnable (on pense à un MacBook air et 32 GB RAM), il faudra aussi en tenir compte pour les réglages.
21+ - lorsque l'on change d'agent (ou revient à l'agent principal), on décharge de la mémoire le modèle en cours (toujours parce qu l'on est sur une machine limitée en mémoire).
22+ - Dossier de travail: ./dev.team
23+ - Tout ce que tu génères (config, noms, ...) est en anglais
24+ - Le nom des agents qui s'affiche dans le header de la TUI doit commencer par un emojii
25+
26+ ### Agents
27+
28+ - Un coordinateur
29+ - Un reformulateur (qui peut aussi poser des question à l'utilisateur) pour améliorer les demande de l'utilisateurs pour le reste de l'équipe
30+ - un prof (pour demander des conseils, des lecons, ...) sur le même principe que la configuration mis dans le commentaire "### prof"
31+ - un codeur
32+ - un reviewer/testeur
33+
34+ ### Modèles
35+
36+ - unsloth/gemma-4-12b-it-GGUF pour reformmulateur et reviewer/testeur
37+ - JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M pour prof et codeur
38+ - unsloth/Qwen3.5-4B-GGUF pour le coordinateur
39+
40+
41+ ### Consignes
42+
43+ - pour chaque tu te poseras la question: quels sont les outils appropriés à activer (prompt, ask_user, ...)
44+ - tu as le droit de remettre en question mes choix de modèles
45+ - tu documenteras cette demo (dans son dossier) (et créeras des fancy diagrams pour expliquer tous les fonctionnements)
46+ - tu donneras des exemples d'utilisation pour permettre de tester les agents
47+
48+
49+ ### Questions à te poser
50+
51+ - a-t-on besoin d'utiliser un modèle de décision ? Si oui dans quels cas et pourquoi ?
52+
53+
54+
55+
56+tasks: []
57+comments:
58+ - id: 1
59+ author:
60+ name: k33g
61+ email: ph.charriere@gmail.com
62+ createdAt: 2026-10-25T04:56:03.359Z
63+ body: |
64+ ### prof
65+
66+ ```yaml
67+ # Tuto — an agent that answers with mini tutorials
68+ provider: llmman
69+ #model: hf.co/JetBrains/Mellum2.1-12B-A2.5B-Thinking-GGUF:Q4_K_M
70+ model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q8_0:Q8_0
71+ baseUrl: http://127.0.0.1:17434/v1
72+ fallback: http://host.docker.internal:17434/v1
73+
74+ # mm's budget for compression; llmman served 131072 during the measurements.
75+ contextWindow: 32768
76+
77+ sampling:
78+ # Explanations, not code edits: a little more freedom than a coder's 0.2,
79+ # never 0.0 with reasoning on (thinking models loop when greedy).
80+ temperature: 0.3
81+ top_p: 0.9
82+ # Measured in wip/: 16384 holds the reasoning plus a long answer; 24576 made
83+ # things worse (the model reasons longer).
84+ max_tokens: 16384
85+ parallel_tool_calls: false
86+ # The template's only reasoning switch (no effort level — see wip/README).
87+ chat_template_kwargs:
88+ enable_thinking: false
89+
90+ showThinking: true
91+ firstTokenTimeout: 3m
92+ watchdogTimeout: 2m
93+
94+ # A mini tutorial is one answer, maybe after one fetch, maybe one save.
95+ maxTurns: 8
96+ maxOutput: 8000
97+ previewLines: 10
98+
99+ # ─── Tools: the documentation, and saving on request ─────────────────────────
100+ yolo: true
101+ bashTool: true # change: 2026 10 21
102+ editTools: true # change: 2026 10 21
103+ planTool: false
104+ askUserTool: false
105+ fetchContentTool: true
106+ saveAnswerTool: true
107+ skillsDir: no-skills
108+
109+ docSearch:
110+ #searchDocs: true
111+ autoSearchDocs: true
112+ dirs: [docs]
113+ extensions: [.md]
114+ maxFileSize: 1MB
115+
116+ # change: 2026 10 21
117+ lsp:
118+ servers:
119+ - name: rust
120+ command: rust-analyzer
121+ extensions: [".rs"]
122+
123+ agentsMd:
124+ enabled: false
125+
126+ sessions:
127+ enabled: true
128+ dir: .mm/sessions
129+
130+ context:
131+ enabled: true
132+ threshold: 60
133+ keepLastTurns: 2
134+ summaryMaxTokens: 1200
135+
136+ acp:
137+ name: tuto
138+ title: 📘 Tuto
139+
140+ system: |
141+ You are Tuto. You answer questions about programming languages, shells and
142+ developer tools with a MINI TUTORIAL, in the language of the question.
143+
144+ HOW TO ANSWER
145+ 1. Decide whether you need the documentation. Fetch ONE page with
146+ fetch_content only when the subject is a recent or niche tool (for
147+ example Nushell, a young framework), when the user names a version, or
148+ when you are not sure a command or an option exists. For well-known
149+ topics (Go, Rust, Python, Kotlin, Java basics) answer from what you know.
150+ 2. Write the mini tutorial directly in your reply, in Markdown:
151+ - a title (#)
152+ - one sentence: what the reader will be able to do
153+ - Prerequisites: a short list
154+ - 3 to 6 numbered steps, each with a code block and, when it prints
155+ something, the expected output
156+ - Pitfalls: 2 or 3 short points
157+ - To go further: one or two lines
158+ Between 300 and 600 words. Short snippets; a complete program only when
159+ the user asks for one.
160+ 3. A follow-up question ("and in Go?") refers to your previous answer:
161+ answer the same need for the new language or tool.
162+
163+ SAVING TO A FILE
164+ - Never save unless the user asks to save, write or export to a file.
165+ - When asked, call save_answer with the file name the user gave (or a short
166+ name made from the subject, ending in .md). Do NOT write the tutorial
167+ again: save_answer saves your previous answer by itself — call it alone,
168+ with no text in your reply.
169+ - When the request is "explain X and save it", write the tutorial in your
170+ reply AND call save_answer in that same reply.
171+ - If save_answer says the file exists, tell the user and ask for another
172+ name.
173+
174+ ```
new file mode 100644
@@ -0,0 +1,174 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 152
3+title: Dev team
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-25T04:44:30.351Z
9+updatedAt: 2026-10-25T05:15:11.308Z
10+labels: []
11+epic: Demos
12+body: |+
13+ ### Objectifs
14+
15+ Faire une équipe d'agents (sur le même principe que les projets dans ./demos) qui permettrait d'aider à coder.
16+
17+
18+ ### Contraintes
19+
20+ - On reste avec des modèles de taille raisonnable (on pense à un MacBook air et 32 GB RAM), il faudra aussi en tenir compte pour les réglages.
21+ - lorsque l'on change d'agent (ou revient à l'agent principal), on décharge de la mémoire le modèle en cours (toujours parce qu l'on est sur une machine limitée en mémoire).
22+ - Dossier de travail: ./dev.team
23+ - Tout ce que tu génères (config, noms, ...) est en anglais
24+ - Le nom des agents qui s'affiche dans le header de la TUI doit commencer par un emojii
25+
26+ ### Agents
27+
28+ - Un coordinateur
29+ - Un reformulateur (qui peut aussi poser des question à l'utilisateur) pour améliorer les demande de l'utilisateurs pour le reste de l'équipe
30+ - un prof (pour demander des conseils, des lecons, ...) sur le même principe que la configuration mis dans le commentaire "### prof"
31+ - un codeur
32+ - un reviewer/testeur
33+
34+ ### Modèles
35+
36+ - unsloth/gemma-4-12b-it-GGUF pour reformmulateur et reviewer/testeur
37+ - JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M pour prof et codeur
38+ - unsloth/Qwen3.5-4B-GGUF pour le coordinateur
39+
40+
41+ ### Consignes
42+
43+ - pour chaque tu te poseras la question: quels sont les outils appropriés à activer (prompt, ask_user, ...)
44+ - tu as le droit de remettre en question mes choix de modèles
45+ - tu documenteras cette demo (dans son dossier) (et créeras des fancy diagrams pour expliquer tous les fonctionnements)
46+ - tu donneras des exemples d'utilisation pour permettre de tester les agents
47+
48+
49+ ### Questions à te poser
50+
51+ - a-t-on besoin d'utiliser un modèle de décision ? Si oui dans quels cas et pourquoi ?
52+
53+
54+
55+
56+tasks: []
57+comments:
58+ - id: 1
59+ author:
60+ name: k33g
61+ email: ph.charriere@gmail.com
62+ createdAt: 2026-10-25T04:56:03.359Z
63+ body: |
64+ ### prof
65+
66+ ```yaml
67+ # Tuto — an agent that answers with mini tutorials
68+ provider: llmman
69+ #model: hf.co/JetBrains/Mellum2.1-12B-A2.5B-Thinking-GGUF:Q4_K_M
70+ model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q8_0:Q8_0
71+ baseUrl: http://127.0.0.1:17434/v1
72+ fallback: http://host.docker.internal:17434/v1
73+
74+ # mm's budget for compression; llmman served 131072 during the measurements.
75+ contextWindow: 32768
76+
77+ sampling:
78+ # Explanations, not code edits: a little more freedom than a coder's 0.2,
79+ # never 0.0 with reasoning on (thinking models loop when greedy).
80+ temperature: 0.3
81+ top_p: 0.9
82+ # Measured in wip/: 16384 holds the reasoning plus a long answer; 24576 made
83+ # things worse (the model reasons longer).
84+ max_tokens: 16384
85+ parallel_tool_calls: false
86+ # The template's only reasoning switch (no effort level — see wip/README).
87+ chat_template_kwargs:
88+ enable_thinking: false
89+
90+ showThinking: true
91+ firstTokenTimeout: 3m
92+ watchdogTimeout: 2m
93+
94+ # A mini tutorial is one answer, maybe after one fetch, maybe one save.
95+ maxTurns: 8
96+ maxOutput: 8000
97+ previewLines: 10
98+
99+ # ─── Tools: the documentation, and saving on request ─────────────────────────
100+ yolo: true
101+ bashTool: true # change: 2026 10 21
102+ editTools: true # change: 2026 10 21
103+ planTool: false
104+ askUserTool: false
105+ fetchContentTool: true
106+ saveAnswerTool: true
107+ skillsDir: no-skills
108+
109+ docSearch:
110+ #searchDocs: true
111+ autoSearchDocs: true
112+ dirs: [docs]
113+ extensions: [.md]
114+ maxFileSize: 1MB
115+
116+ # change: 2026 10 21
117+ lsp:
118+ servers:
119+ - name: rust
120+ command: rust-analyzer
121+ extensions: [".rs"]
122+
123+ agentsMd:
124+ enabled: false
125+
126+ sessions:
127+ enabled: true
128+ dir: .mm/sessions
129+
130+ context:
131+ enabled: true
132+ threshold: 60
133+ keepLastTurns: 2
134+ summaryMaxTokens: 1200
135+
136+ acp:
137+ name: tuto
138+ title: 📘 Tuto
139+
140+ system: |
141+ You are Tuto. You answer questions about programming languages, shells and
142+ developer tools with a MINI TUTORIAL, in the language of the question.
143+
144+ HOW TO ANSWER
145+ 1. Decide whether you need the documentation. Fetch ONE page with
146+ fetch_content only when the subject is a recent or niche tool (for
147+ example Nushell, a young framework), when the user names a version, or
148+ when you are not sure a command or an option exists. For well-known
149+ topics (Go, Rust, Python, Kotlin, Java basics) answer from what you know.
150+ 2. Write the mini tutorial directly in your reply, in Markdown:
151+ - a title (#)
152+ - one sentence: what the reader will be able to do
153+ - Prerequisites: a short list
154+ - 3 to 6 numbered steps, each with a code block and, when it prints
155+ something, the expected output
156+ - Pitfalls: 2 or 3 short points
157+ - To go further: one or two lines
158+ Between 300 and 600 words. Short snippets; a complete program only when
159+ the user asks for one.
160+ 3. A follow-up question ("and in Go?") refers to your previous answer:
161+ answer the same need for the new language or tool.
162+
163+ SAVING TO A FILE
164+ - Never save unless the user asks to save, write or export to a file.
165+ - When asked, call save_answer with the file name the user gave (or a short
166+ name made from the subject, ending in .md). Do NOT write the tutorial
167+ again: save_answer saves your previous answer by itself — call it alone,
168+ with no text in your reply.
169+ - When the request is "explain X and save it", write the tutorial in your
170+ reply AND call save_answer in that same reply.
171+ - If save_answer says the file exists, tell the user and ask for another
172+ name.
173+
174+ ```
modified docs/en/README.md +1 -0
@@ -79,6 +79,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
7979
8080 - [Architecture: one loop, three front ends](explanation/architecture.md)
8181 - [Providers: one implementation per protocol](explanation/providers.md)
82+- [`mm init`: where a generated agent's settings come from](explanation/mm-init.md) — the server's facts, the sourced family table, the usage profiles, the settings guide's machine rows; the order of trust, the origin tags, what was rejected
8283 - [Context compression](explanation/context-compression.md)
8384 - [Persistent sessions](explanation/persistent-sessions.md) — files per project, why a start is a new session, `session/load` versus docker agent's `session/resume`
8485 - [Documentation search](explanation/document-search.md) — `/docs` and `search_docs`: why BM25 and no model, why no index, passages as sections, prefixes instead of stemming
@@ -79,6 +79,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
79 79
80 - [Architecture: one loop, three front ends](explanation/architecture.md)80 - [Architecture: one loop, three front ends](explanation/architecture.md)
81 - [Providers: one implementation per protocol](explanation/providers.md)81 - [Providers: one implementation per protocol](explanation/providers.md)
82+- [`mm init`: where a generated agent's settings come from](explanation/mm-init.md) — the server's facts, the sourced family table, the usage profiles, the settings guide's machine rows; the order of trust, the origin tags, what was rejected
82 - [Context compression](explanation/context-compression.md)83 - [Context compression](explanation/context-compression.md)
83 - [Persistent sessions](explanation/persistent-sessions.md) — files per project, why a start is a new session, `session/load` versus docker agent's `session/resume`84 - [Persistent sessions](explanation/persistent-sessions.md) — files per project, why a start is a new session, `session/load` versus docker agent's `session/resume`
84 - [Documentation search](explanation/document-search.md) — `/docs` and `search_docs`: why BM25 and no model, why no index, passages as sections, prefixes instead of stemming85 - [Documentation search](explanation/document-search.md) — `/docs` and `search_docs`: why BM25 and no model, why no index, passages as sections, prefixes instead of stemming
added docs/en/explanation/mm-init.md +119 -0
new file mode 100644
@@ -0,0 +1,119 @@
1+# `mm init`: where a generated agent's settings come from — explanation
2+
3+## What is this about?
4+
5+`mm init` (or `mm --init`) writes a commented `agent.yaml` from a few answers: the model server, the model, the usage (developer, translator, docs…), the machine, and whether to ask before each change. No model runs while the wizard runs. Every value in the file comes from one of four sources, and each value says which one in its comment. This page explains what those sources are, how they were put together, and why the wizard trusts them in that order. The steps are in [Create an agent with `mm init`](../how-to/create-an-agent.md) and the flags in the [command line reference](../reference/cli.md#mm-init--the-agentyaml-wizard).
6+
7+## The four sources, most specific first
8+
9+The code is in `internal/agentinit`. `Decide` (`decide.go`) applies the sources in a fixed order of trust: **the server's facts about this model, then the family table, then the usage profile, then the machine row.** Each source only fills in what the sources before it do not know.
10+
11+### 1. What the model server says about the model (`facts.go`)
12+
13+The server knows the exact model that is loaded, so it is the most specific source there is. The wizard asks it before choosing anything else:
14+
15+| Provider | Asked | What it gives |
16+|---|---|---|
17+| `llmman`, `ollama` | `/api/tags`, then `/api/show` | the model list, the family the server reports (`details.family`), the native context window, the sampling written in the GGUF (`temperature`, `top_p`, `top_k`, `min_p`), the chat template |
18+| `llamacpp` | `/props` | the window and the chat template |
19+| `dmr` | `/models` | the model list only |
20+| `openai` | `/models` (with the key) | the model list only |
21+
22+From the chat template, `templateThinking` reads how the model's reasoning is switched on or off. It finds `enable_thinking` and its default (on or off), or `reasoning_effort` and the values the template accepts. A model whose template knows neither gets no reasoning switch.
23+
24+These rules were not written for `mm init`. They are a Go port of `skills/create-agent/model_facts.py`, the script the agent-creating agent (`agent.creator.yaml`) already used to read a model from llmman: the same endpoints, the same way of reading the template.
25+
26+When the server gives the GGUF's own sampling, those numbers **replace** the family table's. The GGUF is the most specific source, because it was written for that very file. When the server says nothing beyond the model's name (DMR, the generic `openai` provider, an unknown model), the file says so in its closing notes, and the family table decides.
27+
28+### 2. The family table (`presets.yaml`)
29+
30+The family is guessed from the model id: the first family whose `match` words all appear in the lower-cased name wins. `qwen-coder` (`qwen` + `coder`) therefore comes before `qwen`, and `other` matches anything. The server's family is used when the name does not tell. A family gives:
31+
32+- the sampling for normal use (`general`) and with reasoning on (`thinking`);
33+- a `precise` temperature, for agents that use tools without reasoning;
34+- the reasoning switch;
35+- sometimes a note, for example "a guard model, not a general agent".
36+
37+Every number has a `source` line, and the table was filled from two kinds of source only:
38+
39+- **Model cards and published files.** The Qwen cards (thinking 0.6 / 0.95 / 20, non-thinking 0.7 / 0.8 / 20), the Gemma 4 GGUF sampling, Llama 3.1 8B Instruct's `generation_config.json` (0.6 / 0.9, read from a mirror because Meta's repository needs a login), the Mistral Small 3.1 card ("a relatively low temperature, such as temperature=0.15"), and the OpenAI API reference for hosted models.
40+- **This repository's measured demos.** For each family, the demos that run the model were searched for the sampling they use (`demos/*/agent*.yaml`). For example, `demos/qwen-style` (Qwen3-Coder-Next), `demos/coding-helpers` (Mellum2 12B Thinking, MiniCPM5 2B), `demos/team` (Ornith 1.5 9B), `demos/guard` (Granite Guardian), `demos/codex-style` (gpt-oss 20B) and `demos/llmman` (Jan-nano, Lucy). Qwen's `precise` 0.0 comes from runs with Qwen3.5 4B, reasoning off (`demos/docs-search`, `memory-search`, `plans`).
41+
42+When nothing is published, `other` uses the rule of the `skills/create-agent` skill: 0.7 / 0.9, and 0.2 for a code agent that does not reason.
43+
44+### 3. The usage profile (`presets.yaml`, `usages`)
45+
46+The usage says what the agent is for, which the model cannot tell. A profile sets:
47+
48+- which tool switches are on (a translator has no tool at all; a developer has bash, the file tools and the plan tool);
49+- whether to reason when the model can;
50+- whether to use the family's precise temperature;
51+- `maxTurns`;
52+- the default for asking before each change (`yolo`);
53+- a starting system prompt.
54+
55+Some usages switch on one feature each: `docs` turns on the documentation search, `json` writes a `structuredOutput` example (which forbids every tool), and `coordinator` hands the questions to other agents. The prompts are in English, by the user's choice in ticket 97. They repeat rules the demos' prompts share, for example "Never state the output of a command you did not run in this answer".
56+
57+### 4. The machine row (`presets.yaml`, `machines`)
58+
59+The timeouts and the size of tool outputs depend on the machine, not on the model. The three rows `small`, `medium` and `large` (`firstTokenTimeout`, `watchdogTimeout`, `bashTimeout`, `maxOutput`) are copied from the "Summary: typical profiles" table of [the settings guide](../../../guides/agent-settings-for-small-models.md), written for ticket 98.
60+
61+## The rules the code adds
62+
63+A few values follow from the answers rather than from a table. Each rule writes its reason above the value it sets:
64+
65+- **Reasoning on means a temperature of at least 0.6 and `max_tokens: 16384`.** A thinking model loops at a low temperature, and its thoughts need room besides the tool call. With reasoning off, the limit is 4096.
66+- **The precise temperature applies only without reasoning.** It is used when the usage asks for it (developer, reviewer, docs, json…).
67+- **With bash on, `watchdogTimeout` is aligned on `bashTimeout`**, as section 3 of the settings guide says. Otherwise a long command would look like a stalled model.
68+- **`parallel_tool_calls: false` for any agent with tools.** Otherwise small models run a check before the change it checks has landed.
69+- **`contextWindow: 0` and `context.threshold: 75`.** mm asks the server for the window it actually serves. The proposal planned a threshold computed from the model's native window. It was dropped while writing the code: Ollama often serves 4k–8k, so a percentage of the native window would compress almost at once.
70+- **`skillsDir: no-skills`.** A new agent starts without skills, and the comment says how to add some.
71+
72+## Every number says how it was obtained
73+
74+Since ticket 121, each number about the model carries a tag in its comment. The file's header explains the tags it uses:
75+
76+| Tag | Meaning | After a model or quantization change |
77+|---|---|---|
78+| `[server]` | read from the model server when the file was written | run `mm init` again |
79+| `[measured]` | a demo of this repository ran with it | measure again |
80+| `[card]` | copied from the model card, the GGUF or the API reference, not measured here | read the card again |
81+| `[rule]` | a rule of thumb, nothing specific to the model | check it still fits |
82+| `[guide]` | the settings guide's row for the machine | — |
83+
84+A comment above `model:` lists what to redo when the model changes. The comments make the file teach as it configures, the way the demos' `agent.yaml` files are written: a reader sees which numbers were measured on a real run and which were only copied.
85+
86+## The file is checked before the wizard says it is done
87+
88+The wizard never overwrites an existing file. After writing, it loads the file with mm's own `config.Load`, so a file mm would refuse is reported at once. With `--check`, it also runs the same mm on the new file with one question (`Say hello in one line.`), to prove the model answers.
89+
90+## Why it is designed this way
91+
92+**A generator with no model.** Ticket 97 asked for an `agent.yaml` from the command line, by model family and usage. The proposal written for the ticket first listed what already existed: `agent.creator.yaml` with its `create-agent` skill, `model_facts.py`, the settings guide, `config.samples/` and the demos' tested settings. Instead of a new source of knowledge, `mm init` puts those pieces together in deterministic Go code. It is instant and works before any agent exists.
93+
94+**A server first, a table second.** A table can only know a family, while the server knows the very file that is loaded: its window, its GGUF sampling, its template. The table covers the servers that say nothing, such as Docker Model Runner.
95+
96+**Sourced values only.** The user decided that the family table would use model cards **and** measured demos. A number with no source does not go in. A family with neither falls back to `other`, and the file says that its sampling is only a starting point.
97+
98+**One table.** `presets.yaml` is embedded in the binary. Its header says it is meant to be shared with the Claude skill of ticket 111 (a skill built from the settings guide). That ticket is still open, and the `mm-agent-creator` skill does not read the file today.
99+
100+## Rejected alternatives
101+
102+- **Generating the file with a model** (`agent.creator.yaml`). Kept for the unusual cases, but not the default: it needs a 27B model loaded and minutes per agent.
103+- **A threshold computed from the native window.** Rejected, see above: it would compress almost at once on the windows Ollama serves.
104+- **Skills, MCP servers, hooks and `mmConfigs` in the wizard.** Left out of the first version. The file's closing comment points to the how-to guides instead.
105+- **Prompts in the user's language.** Rejected by the user's choice: the generated prompts are in English.
106+
107+## Known limits
108+
109+- Live checks were run against llmman only (Qwen3.5 4B, gemma-4-E4B). Ollama, Docker Model Runner and llama-server were tested against fake servers recorded in the tests. The OpenAI API itself was not tried; its constraints come from its reference.
110+- A `[card]` number was copied, not measured in this repository.
111+- The families are matched on words in the model id: a model renamed by its publisher may land in `other`.
112+
113+## How it relates to the rest
114+
115+- [Providers](providers.md): the five servers the wizard can ask, and why each has its own entry.
116+- [Thinking models](thinking-models.md): what the reasoning switch the wizard sets does at run time.
117+- [Context compression](context-compression.md): what `context.threshold` triggers.
118+- [Structured output](structured-output.md): why the `json` usage has no tools.
119+- [Asking another agent](asking-another-agent.md): what the `coordinator` usage relies on.
new file mode 100644
@@ -0,0 +1,119 @@
1+# `mm init`: where a generated agent's settings come from — explanation
2+
3+## What is this about?
4+
5+`mm init` (or `mm --init`) writes a commented `agent.yaml` from a few answers: the model server, the model, the usage (developer, translator, docs…), the machine, and whether to ask before each change. No model runs while the wizard runs. Every value in the file comes from one of four sources, and each value says which one in its comment. This page explains what those sources are, how they were put together, and why the wizard trusts them in that order. The steps are in [Create an agent with `mm init`](../how-to/create-an-agent.md) and the flags in the [command line reference](../reference/cli.md#mm-init--the-agentyaml-wizard).
6+
7+## The four sources, most specific first
8+
9+The code is in `internal/agentinit`. `Decide` (`decide.go`) applies the sources in a fixed order of trust: **the server's facts about this model, then the family table, then the usage profile, then the machine row.** Each source only fills in what the sources before it do not know.
10+
11+### 1. What the model server says about the model (`facts.go`)
12+
13+The server knows the exact model that is loaded, so it is the most specific source there is. The wizard asks it before choosing anything else:
14+
15+| Provider | Asked | What it gives |
16+|---|---|---|
17+| `llmman`, `ollama` | `/api/tags`, then `/api/show` | the model list, the family the server reports (`details.family`), the native context window, the sampling written in the GGUF (`temperature`, `top_p`, `top_k`, `min_p`), the chat template |
18+| `llamacpp` | `/props` | the window and the chat template |
19+| `dmr` | `/models` | the model list only |
20+| `openai` | `/models` (with the key) | the model list only |
21+
22+From the chat template, `templateThinking` reads how the model's reasoning is switched on or off. It finds `enable_thinking` and its default (on or off), or `reasoning_effort` and the values the template accepts. A model whose template knows neither gets no reasoning switch.
23+
24+These rules were not written for `mm init`. They are a Go port of `skills/create-agent/model_facts.py`, the script the agent-creating agent (`agent.creator.yaml`) already used to read a model from llmman: the same endpoints, the same way of reading the template.
25+
26+When the server gives the GGUF's own sampling, those numbers **replace** the family table's. The GGUF is the most specific source, because it was written for that very file. When the server says nothing beyond the model's name (DMR, the generic `openai` provider, an unknown model), the file says so in its closing notes, and the family table decides.
27+
28+### 2. The family table (`presets.yaml`)
29+
30+The family is guessed from the model id: the first family whose `match` words all appear in the lower-cased name wins. `qwen-coder` (`qwen` + `coder`) therefore comes before `qwen`, and `other` matches anything. The server's family is used when the name does not tell. A family gives:
31+
32+- the sampling for normal use (`general`) and with reasoning on (`thinking`);
33+- a `precise` temperature, for agents that use tools without reasoning;
34+- the reasoning switch;
35+- sometimes a note, for example "a guard model, not a general agent".
36+
37+Every number has a `source` line, and the table was filled from two kinds of source only:
38+
39+- **Model cards and published files.** The Qwen cards (thinking 0.6 / 0.95 / 20, non-thinking 0.7 / 0.8 / 20), the Gemma 4 GGUF sampling, Llama 3.1 8B Instruct's `generation_config.json` (0.6 / 0.9, read from a mirror because Meta's repository needs a login), the Mistral Small 3.1 card ("a relatively low temperature, such as temperature=0.15"), and the OpenAI API reference for hosted models.
40+- **This repository's measured demos.** For each family, the demos that run the model were searched for the sampling they use (`demos/*/agent*.yaml`). For example, `demos/qwen-style` (Qwen3-Coder-Next), `demos/coding-helpers` (Mellum2 12B Thinking, MiniCPM5 2B), `demos/team` (Ornith 1.5 9B), `demos/guard` (Granite Guardian), `demos/codex-style` (gpt-oss 20B) and `demos/llmman` (Jan-nano, Lucy). Qwen's `precise` 0.0 comes from runs with Qwen3.5 4B, reasoning off (`demos/docs-search`, `memory-search`, `plans`).
41+
42+When nothing is published, `other` uses the rule of the `skills/create-agent` skill: 0.7 / 0.9, and 0.2 for a code agent that does not reason.
43+
44+### 3. The usage profile (`presets.yaml`, `usages`)
45+
46+The usage says what the agent is for, which the model cannot tell. A profile sets:
47+
48+- which tool switches are on (a translator has no tool at all; a developer has bash, the file tools and the plan tool);
49+- whether to reason when the model can;
50+- whether to use the family's precise temperature;
51+- `maxTurns`;
52+- the default for asking before each change (`yolo`);
53+- a starting system prompt.
54+
55+Some usages switch on one feature each: `docs` turns on the documentation search, `json` writes a `structuredOutput` example (which forbids every tool), and `coordinator` hands the questions to other agents. The prompts are in English, by the user's choice in ticket 97. They repeat rules the demos' prompts share, for example "Never state the output of a command you did not run in this answer".
56+
57+### 4. The machine row (`presets.yaml`, `machines`)
58+
59+The timeouts and the size of tool outputs depend on the machine, not on the model. The three rows `small`, `medium` and `large` (`firstTokenTimeout`, `watchdogTimeout`, `bashTimeout`, `maxOutput`) are copied from the "Summary: typical profiles" table of [the settings guide](../../../guides/agent-settings-for-small-models.md), written for ticket 98.
60+
61+## The rules the code adds
62+
63+A few values follow from the answers rather than from a table. Each rule writes its reason above the value it sets:
64+
65+- **Reasoning on means a temperature of at least 0.6 and `max_tokens: 16384`.** A thinking model loops at a low temperature, and its thoughts need room besides the tool call. With reasoning off, the limit is 4096.
66+- **The precise temperature applies only without reasoning.** It is used when the usage asks for it (developer, reviewer, docs, json…).
67+- **With bash on, `watchdogTimeout` is aligned on `bashTimeout`**, as section 3 of the settings guide says. Otherwise a long command would look like a stalled model.
68+- **`parallel_tool_calls: false` for any agent with tools.** Otherwise small models run a check before the change it checks has landed.
69+- **`contextWindow: 0` and `context.threshold: 75`.** mm asks the server for the window it actually serves. The proposal planned a threshold computed from the model's native window. It was dropped while writing the code: Ollama often serves 4k–8k, so a percentage of the native window would compress almost at once.
70+- **`skillsDir: no-skills`.** A new agent starts without skills, and the comment says how to add some.
71+
72+## Every number says how it was obtained
73+
74+Since ticket 121, each number about the model carries a tag in its comment. The file's header explains the tags it uses:
75+
76+| Tag | Meaning | After a model or quantization change |
77+|---|---|---|
78+| `[server]` | read from the model server when the file was written | run `mm init` again |
79+| `[measured]` | a demo of this repository ran with it | measure again |
80+| `[card]` | copied from the model card, the GGUF or the API reference, not measured here | read the card again |
81+| `[rule]` | a rule of thumb, nothing specific to the model | check it still fits |
82+| `[guide]` | the settings guide's row for the machine | — |
83+
84+A comment above `model:` lists what to redo when the model changes. The comments make the file teach as it configures, the way the demos' `agent.yaml` files are written: a reader sees which numbers were measured on a real run and which were only copied.
85+
86+## The file is checked before the wizard says it is done
87+
88+The wizard never overwrites an existing file. After writing, it loads the file with mm's own `config.Load`, so a file mm would refuse is reported at once. With `--check`, it also runs the same mm on the new file with one question (`Say hello in one line.`), to prove the model answers.
89+
90+## Why it is designed this way
91+
92+**A generator with no model.** Ticket 97 asked for an `agent.yaml` from the command line, by model family and usage. The proposal written for the ticket first listed what already existed: `agent.creator.yaml` with its `create-agent` skill, `model_facts.py`, the settings guide, `config.samples/` and the demos' tested settings. Instead of a new source of knowledge, `mm init` puts those pieces together in deterministic Go code. It is instant and works before any agent exists.
93+
94+**A server first, a table second.** A table can only know a family, while the server knows the very file that is loaded: its window, its GGUF sampling, its template. The table covers the servers that say nothing, such as Docker Model Runner.
95+
96+**Sourced values only.** The user decided that the family table would use model cards **and** measured demos. A number with no source does not go in. A family with neither falls back to `other`, and the file says that its sampling is only a starting point.
97+
98+**One table.** `presets.yaml` is embedded in the binary. Its header says it is meant to be shared with the Claude skill of ticket 111 (a skill built from the settings guide). That ticket is still open, and the `mm-agent-creator` skill does not read the file today.
99+
100+## Rejected alternatives
101+
102+- **Generating the file with a model** (`agent.creator.yaml`). Kept for the unusual cases, but not the default: it needs a 27B model loaded and minutes per agent.
103+- **A threshold computed from the native window.** Rejected, see above: it would compress almost at once on the windows Ollama serves.
104+- **Skills, MCP servers, hooks and `mmConfigs` in the wizard.** Left out of the first version. The file's closing comment points to the how-to guides instead.
105+- **Prompts in the user's language.** Rejected by the user's choice: the generated prompts are in English.
106+
107+## Known limits
108+
109+- Live checks were run against llmman only (Qwen3.5 4B, gemma-4-E4B). Ollama, Docker Model Runner and llama-server were tested against fake servers recorded in the tests. The OpenAI API itself was not tried; its constraints come from its reference.
110+- A `[card]` number was copied, not measured in this repository.
111+- The families are matched on words in the model id: a model renamed by its publisher may land in `other`.
112+
113+## How it relates to the rest
114+
115+- [Providers](providers.md): the five servers the wizard can ask, and why each has its own entry.
116+- [Thinking models](thinking-models.md): what the reasoning switch the wizard sets does at run time.
117+- [Context compression](context-compression.md): what `context.threshold` triggers.
118+- [Structured output](structured-output.md): why the `json` usage has no tools.
119+- [Asking another agent](asking-another-agent.md): what the `coordinator` usage relies on.
modified docs/en/how-to/create-an-agent.md +1 -0
@@ -90,4 +90,5 @@ This guide shows how to write a new agent.yaml for a model and a job, with mm's
9090 - [Command line reference — `mm init`](../reference/cli.md#mm-init--the-agentyaml-wizard): every flag, the sources, the exit codes
9191 - [Configuration reference](../reference/configuration.md): every key the file holds
9292 - [Agent settings for small models](../../../guides/agent-settings-for-small-models.md): what each setting does, the machine rows
93+- [Where the settings come from](../explanation/mm-init.md): the four sources, their order, the origin tags
9394 - `agent.creator.yaml`: an agent that creates agents with a model, for the unusual cases
@@ -90,4 +90,5 @@ This guide shows how to write a new agent.yaml for a model and a job, with mm's
90 - [Command line reference — `mm init`](../reference/cli.md#mm-init--the-agentyaml-wizard): every flag, the sources, the exit codes90 - [Command line reference — `mm init`](../reference/cli.md#mm-init--the-agentyaml-wizard): every flag, the sources, the exit codes
91 - [Configuration reference](../reference/configuration.md): every key the file holds91 - [Configuration reference](../reference/configuration.md): every key the file holds
92 - [Agent settings for small models](../../../guides/agent-settings-for-small-models.md): what each setting does, the machine rows92 - [Agent settings for small models](../../../guides/agent-settings-for-small-models.md): what each setting does, the machine rows
93+- [Where the settings come from](../explanation/mm-init.md): the four sources, their order, the origin tags
93 - `agent.creator.yaml`: an agent that creates agents with a model, for the unusual cases94 - `agent.creator.yaml`: an agent that creates agents with a model, for the unusual cases
modified docs/fr/README.md +1 -0
@@ -79,6 +79,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https:
7979
8080 - [Architecture : une boucle, trois façades](explanation/architecture.md)
8181 - [Fournisseurs : une implémentation par protocole](explanation/providers.md)
82+- [`mm init` : d'où viennent les réglages d'un agent généré](explanation/mm-init.md) — ce que dit le serveur, la table des familles sourcée, les profils d'usage, les lignes machine du guide des réglages ; l'ordre de confiance, les étiquettes d'origine, ce qui a été écarté
8283 - [Compression du contexte](explanation/context-compression.md)
8384 - [Les sessions persistantes](explanation/persistent-sessions.md) — des fichiers par projet, pourquoi un lancement est une nouvelle session, `session/load` face au `session/resume` de docker agent
8485 - [La recherche dans la documentation](explanation/document-search.md) — `/docs` et `search_docs` : pourquoi BM25 et aucun modèle, pourquoi pas d'index, des passages qui sont des sections, des préfixes plutôt qu'une racinisation
@@ -79,6 +79,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https:
79 79
80 - [Architecture : une boucle, trois façades](explanation/architecture.md)80 - [Architecture : une boucle, trois façades](explanation/architecture.md)
81 - [Fournisseurs : une implémentation par protocole](explanation/providers.md)81 - [Fournisseurs : une implémentation par protocole](explanation/providers.md)
82+- [`mm init` : d'où viennent les réglages d'un agent généré](explanation/mm-init.md) — ce que dit le serveur, la table des familles sourcée, les profils d'usage, les lignes machine du guide des réglages ; l'ordre de confiance, les étiquettes d'origine, ce qui a été écarté
82 - [Compression du contexte](explanation/context-compression.md)83 - [Compression du contexte](explanation/context-compression.md)
83 - [Les sessions persistantes](explanation/persistent-sessions.md) — des fichiers par projet, pourquoi un lancement est une nouvelle session, `session/load` face au `session/resume` de docker agent84 - [Les sessions persistantes](explanation/persistent-sessions.md) — des fichiers par projet, pourquoi un lancement est une nouvelle session, `session/load` face au `session/resume` de docker agent
84 - [La recherche dans la documentation](explanation/document-search.md) — `/docs` et `search_docs` : pourquoi BM25 et aucun modèle, pourquoi pas d'index, des passages qui sont des sections, des préfixes plutôt qu'une racinisation85 - [La recherche dans la documentation](explanation/document-search.md) — `/docs` et `search_docs` : pourquoi BM25 et aucun modèle, pourquoi pas d'index, des passages qui sont des sections, des préfixes plutôt qu'une racinisation
added docs/fr/explanation/mm-init.md +119 -0
new file mode 100644
@@ -0,0 +1,119 @@
1+# `mm init` : d'où viennent les réglages d'un agent généré — explication
2+
3+## De quoi s'agit-il ?
4+
5+`mm init` (ou `mm --init`) écrit un `agent.yaml` commenté à partir de quelques réponses : le serveur de modèles, le modèle, l'usage (développeur, traducteur, docs…), la machine, et s'il faut demander avant chaque modification. Aucun modèle ne tourne pendant l'assistant. Chaque valeur du fichier vient de l'une de quatre sources, et son commentaire dit laquelle. Cette page explique ces sources, comment elles ont été réunies et pourquoi l'assistant leur fait confiance dans cet ordre. Les étapes sont dans [Créer un agent avec `mm init`](../how-to/create-an-agent.md) et les options dans la [référence de la ligne de commande](../reference/cli.md#mm-init--lassistant-agentyaml).
6+
7+## Les quatre sources, de la plus précise à la plus générale
8+
9+Le code est dans `internal/agentinit`. `Decide` (`decide.go`) applique les sources dans un ordre de confiance fixe : **ce que dit le serveur de ce modèle, puis la table des familles, puis le profil d'usage, puis la ligne de la machine.** Chaque source ne complète que ce que les précédentes ne savent pas.
10+
11+### 1. Ce que dit le serveur du modèle (`facts.go`)
12+
13+Le serveur connaît le modèle exact qui est chargé : c'est la source la plus précise qui existe. L'assistant l'interroge avant de choisir quoi que ce soit :
14+
15+| Fournisseur | Interrogé | Ce qu'il donne |
16+|---|---|---|
17+| `llmman`, `ollama` | `/api/tags`, puis `/api/show` | la liste des modèles, la famille annoncée par le serveur (`details.family`), la fenêtre de contexte native, l'échantillonnage écrit dans le GGUF (`temperature`, `top_p`, `top_k`, `min_p`), le template de chat |
18+| `llamacpp` | `/props` | la fenêtre et le template de chat |
19+| `dmr` | `/models` | la liste des modèles seulement |
20+| `openai` | `/models` (avec la clé) | la liste des modèles seulement |
21+
22+Dans le template de chat, `templateThinking` lit comment le raisonnement du modèle s'active et se désactive. Il trouve `enable_thinking` et sa valeur par défaut (activé ou non), ou `reasoning_effort` et les valeurs que le template accepte. Un modèle dont le template ne connaît ni l'un ni l'autre n'a pas d'interrupteur de raisonnement.
23+
24+Ces règles n'ont pas été écrites pour `mm init`. Ce sont celles de `skills/create-agent/model_facts.py`, portées en Go. Ce script servait déjà à l'agent qui crée des agents (`agent.creator.yaml`) pour lire un modèle dans llmman : mêmes points d'accès, même lecture du template.
25+
26+Quand le serveur donne l'échantillonnage propre au GGUF, ces valeurs **remplacent** celles de la table des familles. Le GGUF est la source la plus précise, puisqu'il a été écrit pour ce fichier-là. Quand le serveur ne dit rien de plus que le nom du modèle (DMR, le fournisseur générique `openai`, un modèle inconnu), le fichier le signale dans ses notes de fin, et c'est la table des familles qui décide.
27+
28+### 2. La table des familles (`presets.yaml`)
29+
30+La famille est déduite de l'identifiant du modèle : la première famille dont tous les mots de `match` apparaissent dans le nom en minuscules l'emporte. `qwen-coder` (`qwen` + `coder`) passe donc avant `qwen`, et `other` correspond à tout. La famille annoncée par le serveur sert quand le nom ne dit rien. Une famille donne :
31+
32+- l'échantillonnage pour un usage normal (`general`) et raisonnement activé (`thinking`) ;
33+- une température `precise`, pour les agents qui utilisent des outils sans raisonner ;
34+- l'interrupteur de raisonnement ;
35+- parfois une note, par exemple « un modèle de garde, pas un agent généraliste ».
36+
37+Chaque valeur a une ligne `source`, et la table n'a été remplie qu'à partir de deux sortes de sources :
38+
39+- **Les fiches de modèles et les fichiers publiés.** Les fiches Qwen (avec raisonnement 0.6 / 0.95 / 20, sans raisonnement 0.7 / 0.8 / 20), l'échantillonnage du GGUF de Gemma 4, le `generation_config.json` de Llama 3.1 8B Instruct (0.6 / 0.9, lu sur un miroir parce que le dépôt de Meta demande une connexion), la fiche de Mistral Small 3.1 (« a relatively low temperature, such as temperature=0.15 »), et la référence de l'API OpenAI pour les modèles hébergés.
40+- **Les démos mesurées de ce dépôt.** Pour chaque famille, on a cherché dans les démos qui font tourner le modèle l'échantillonnage qu'elles utilisent (`demos/*/agent*.yaml`). Par exemple `demos/qwen-style` (Qwen3-Coder-Next), `demos/coding-helpers` (Mellum2 12B Thinking, MiniCPM5 2B), `demos/team` (Ornith 1.5 9B), `demos/guard` (Granite Guardian), `demos/codex-style` (gpt-oss 20B) et `demos/llmman` (Jan-nano, Lucy). Le `precise` à 0.0 de Qwen vient d'exécutions avec Qwen3.5 4B sans raisonnement (`demos/docs-search`, `memory-search`, `plans`).
41+
42+Quand rien n'est publié, `other` applique la règle du skill `skills/create-agent` : 0.7 / 0.9, et 0.2 pour un agent de code qui ne raisonne pas.
43+
44+### 3. Le profil d'usage (`presets.yaml`, `usages`)
45+
46+L'usage dit à quoi sert l'agent, ce que le modèle ne peut pas savoir. Un profil fixe :
47+
48+- les outils activés (un traducteur n'a aucun outil, un développeur a bash, les outils de fichiers et l'outil de plan) ;
49+- s'il faut raisonner quand le modèle le peut ;
50+- s'il faut utiliser la température précise de la famille ;
51+- `maxTurns` ;
52+- la valeur par défaut de la demande avant chaque modification (`yolo`) ;
53+- un prompt système de départ.
54+
55+Certains usages activent chacun une fonction : `docs` active la recherche dans la documentation, `json` écrit un exemple de `structuredOutput` (qui interdit tout outil), et `coordinator` confie les questions à d'autres agents. Les prompts sont en anglais, selon le choix de l'utilisateur dans le ticket 97. Ils reprennent des règles communes aux prompts des démos, par exemple « Never state the output of a command you did not run in this answer ».
56+
57+### 4. La ligne de la machine (`presets.yaml`, `machines`)
58+
59+Les délais et la taille des sorties d'outils dépendent de la machine, pas du modèle. Les trois lignes `small`, `medium` et `large` (`firstTokenTimeout`, `watchdogTimeout`, `bashTimeout`, `maxOutput`) sont copiées du tableau « Summary: typical profiles » [du guide des réglages](../../../guides/reglages-agents-petits-modeles.md), écrit pour le ticket 98.
60+
61+## Les règles ajoutées par le code
62+
63+Quelques valeurs découlent des réponses plutôt que d'une table. Chaque règle écrit sa raison au-dessus de la valeur qu'elle fixe :
64+
65+- **Raisonnement activé : une température d'au moins 0.6 et `max_tokens: 16384`.** Un modèle qui raisonne tourne en boucle à basse température, et ses pensées ont besoin de place en plus de l'appel d'outil. Sans raisonnement, la limite est 4096.
66+- **La température précise ne s'applique que sans raisonnement.** Elle sert quand l'usage la demande (developer, reviewer, docs, json…).
67+- **Avec bash, `watchdogTimeout` est aligné sur `bashTimeout`**, comme le dit la section 3 du guide des réglages. Sinon une commande longue passerait pour un modèle bloqué.
68+- **`parallel_tool_calls: false` dès que l'agent a des outils.** Sinon les petits modèles lancent une vérification avant que la modification qu'elle vérifie soit faite.
69+- **`contextWindow: 0` et `context.threshold: 75`.** mm demande au serveur la fenêtre qu'il sert vraiment. La proposition prévoyait un seuil calculé sur la fenêtre native du modèle. Il a été abandonné pendant l'écriture du code : Ollama sert souvent 4k à 8k, donc un pourcentage de la fenêtre native compresserait presque tout de suite.
70+- **`skillsDir: no-skills`.** Un nouvel agent démarre sans skills, et le commentaire dit comment en ajouter.
71+
72+## Chaque valeur dit comment elle a été obtenue
73+
74+Depuis le ticket 121, chaque valeur liée au modèle porte une étiquette dans son commentaire. L'en-tête du fichier explique celles qu'il utilise :
75+
76+| Étiquette | Sens | Après un changement de modèle ou de quantification |
77+|---|---|---|
78+| `[server]` | lue sur le serveur au moment de l'écriture du fichier | relancer `mm init` |
79+| `[measured]` | une démo de ce dépôt a tourné avec | mesurer à nouveau |
80+| `[card]` | copiée de la fiche du modèle, du GGUF ou de la référence de l'API, pas mesurée ici | relire la fiche |
81+| `[rule]` | une règle générale, rien de propre au modèle | vérifier qu'elle convient encore |
82+| `[guide]` | la ligne du guide des réglages pour la machine | — |
83+
84+Un commentaire au-dessus de `model:` liste ce qu'il faut refaire quand on change de modèle. Les commentaires font que le fichier explique en même temps qu'il configure, à la manière des `agent.yaml` des démos : on voit quelles valeurs ont été mesurées sur une vraie exécution et lesquelles ont seulement été recopiées.
85+
86+## Le fichier est vérifié avant que l'assistant ait fini
87+
88+L'assistant n'écrase jamais un fichier existant. Après l'écriture, il charge le fichier avec le `config.Load` de mm, donc un fichier que mm refuserait est signalé tout de suite. Avec `--check`, il lance aussi le même mm sur le nouveau fichier avec une question (`Say hello in one line.`), pour prouver que le modèle répond.
89+
90+## Pourquoi c'est conçu ainsi
91+
92+**Un générateur sans modèle.** Le ticket 97 demandait un `agent.yaml` depuis la ligne de commande, selon la famille du modèle et l'usage. La proposition écrite pour le ticket a d'abord listé ce qui existait déjà : `agent.creator.yaml` et son skill `create-agent`, `model_facts.py`, le guide des réglages, `config.samples/` et les réglages testés des démos. Au lieu d'une nouvelle source de connaissances, `mm init` assemble ces morceaux dans du Go déterministe. C'est instantané et cela marche avant qu'aucun agent n'existe.
93+
94+**Le serveur d'abord, la table ensuite.** Une table ne peut connaître qu'une famille, alors que le serveur connaît le fichier exact qui est chargé : sa fenêtre, l'échantillonnage de son GGUF, son template. La table couvre les serveurs qui ne disent rien, comme Docker Model Runner.
95+
96+**Seulement des valeurs sourcées.** L'utilisateur a décidé que la table des familles utiliserait les fiches de modèles **et** les démos mesurées. Une valeur sans source n'y entre pas. Une famille qui n'a ni l'un ni l'autre retombe sur `other`, et le fichier dit que son échantillonnage n'est qu'un point de départ.
97+
98+**Une seule table.** `presets.yaml` est intégré au binaire. Son en-tête dit qu'il doit être partagé avec le skill Claude du ticket 111 (un skill construit à partir du guide des réglages). Ce ticket est encore ouvert, et le skill `mm-agent-creator` ne lit pas ce fichier aujourd'hui.
99+
100+## Alternatives écartées
101+
102+- **Générer le fichier avec un modèle** (`agent.creator.yaml`). Conservé pour les cas qui sortent de l'ordinaire, mais pas par défaut : il faut un modèle de 27B chargé et plusieurs minutes par agent.
103+- **Un seuil calculé sur la fenêtre native.** Écarté, voir plus haut : il compresserait presque tout de suite avec les fenêtres que sert Ollama.
104+- **Les skills, les serveurs MCP, les hooks et les `mmConfigs` dans l'assistant.** Laissés hors de la première version. Le commentaire de fin du fichier renvoie aux guides pratiques.
105+- **Des prompts dans la langue de l'utilisateur.** Écarté par le choix de l'utilisateur : les prompts générés sont en anglais.
106+
107+## Limites connues
108+
109+- Les vérifications en direct n'ont été faites qu'avec llmman (Qwen3.5 4B, gemma-4-E4B). Ollama, Docker Model Runner et llama-server ont été testés contre de faux serveurs enregistrés dans les tests. L'API OpenAI elle-même n'a pas été essayée ; ses contraintes viennent de sa référence.
110+- Une valeur `[card]` a été recopiée, pas mesurée dans ce dépôt.
111+- Les familles sont reconnues sur des mots de l'identifiant du modèle : un modèle renommé par son éditeur peut tomber dans `other`.
112+
113+## Liens avec le reste
114+
115+- [Fournisseurs](providers.md) : les cinq serveurs que l'assistant peut interroger, et pourquoi chacun a sa propre entrée.
116+- [Modèles à raisonnement](thinking-models.md) : ce que fait à l'exécution l'interrupteur de raisonnement que fixe l'assistant.
117+- [Compression du contexte](context-compression.md) : ce que déclenche `context.threshold`.
118+- [Sortie structurée](structured-output.md) : pourquoi l'usage `json` n'a pas d'outils.
119+- [Interroger un autre agent](asking-another-agent.md) : ce sur quoi s'appuie l'usage `coordinator`.
new file mode 100644
@@ -0,0 +1,119 @@
1+# `mm init` : d'où viennent les réglages d'un agent généré — explication
2+
3+## De quoi s'agit-il ?
4+
5+`mm init` (ou `mm --init`) écrit un `agent.yaml` commenté à partir de quelques réponses : le serveur de modèles, le modèle, l'usage (développeur, traducteur, docs…), la machine, et s'il faut demander avant chaque modification. Aucun modèle ne tourne pendant l'assistant. Chaque valeur du fichier vient de l'une de quatre sources, et son commentaire dit laquelle. Cette page explique ces sources, comment elles ont été réunies et pourquoi l'assistant leur fait confiance dans cet ordre. Les étapes sont dans [Créer un agent avec `mm init`](../how-to/create-an-agent.md) et les options dans la [référence de la ligne de commande](../reference/cli.md#mm-init--lassistant-agentyaml).
6+
7+## Les quatre sources, de la plus précise à la plus générale
8+
9+Le code est dans `internal/agentinit`. `Decide` (`decide.go`) applique les sources dans un ordre de confiance fixe : **ce que dit le serveur de ce modèle, puis la table des familles, puis le profil d'usage, puis la ligne de la machine.** Chaque source ne complète que ce que les précédentes ne savent pas.
10+
11+### 1. Ce que dit le serveur du modèle (`facts.go`)
12+
13+Le serveur connaît le modèle exact qui est chargé : c'est la source la plus précise qui existe. L'assistant l'interroge avant de choisir quoi que ce soit :
14+
15+| Fournisseur | Interrogé | Ce qu'il donne |
16+|---|---|---|
17+| `llmman`, `ollama` | `/api/tags`, puis `/api/show` | la liste des modèles, la famille annoncée par le serveur (`details.family`), la fenêtre de contexte native, l'échantillonnage écrit dans le GGUF (`temperature`, `top_p`, `top_k`, `min_p`), le template de chat |
18+| `llamacpp` | `/props` | la fenêtre et le template de chat |
19+| `dmr` | `/models` | la liste des modèles seulement |
20+| `openai` | `/models` (avec la clé) | la liste des modèles seulement |
21+
22+Dans le template de chat, `templateThinking` lit comment le raisonnement du modèle s'active et se désactive. Il trouve `enable_thinking` et sa valeur par défaut (activé ou non), ou `reasoning_effort` et les valeurs que le template accepte. Un modèle dont le template ne connaît ni l'un ni l'autre n'a pas d'interrupteur de raisonnement.
23+
24+Ces règles n'ont pas été écrites pour `mm init`. Ce sont celles de `skills/create-agent/model_facts.py`, portées en Go. Ce script servait déjà à l'agent qui crée des agents (`agent.creator.yaml`) pour lire un modèle dans llmman : mêmes points d'accès, même lecture du template.
25+
26+Quand le serveur donne l'échantillonnage propre au GGUF, ces valeurs **remplacent** celles de la table des familles. Le GGUF est la source la plus précise, puisqu'il a été écrit pour ce fichier-là. Quand le serveur ne dit rien de plus que le nom du modèle (DMR, le fournisseur générique `openai`, un modèle inconnu), le fichier le signale dans ses notes de fin, et c'est la table des familles qui décide.
27+
28+### 2. La table des familles (`presets.yaml`)
29+
30+La famille est déduite de l'identifiant du modèle : la première famille dont tous les mots de `match` apparaissent dans le nom en minuscules l'emporte. `qwen-coder` (`qwen` + `coder`) passe donc avant `qwen`, et `other` correspond à tout. La famille annoncée par le serveur sert quand le nom ne dit rien. Une famille donne :
31+
32+- l'échantillonnage pour un usage normal (`general`) et raisonnement activé (`thinking`) ;
33+- une température `precise`, pour les agents qui utilisent des outils sans raisonner ;
34+- l'interrupteur de raisonnement ;
35+- parfois une note, par exemple « un modèle de garde, pas un agent généraliste ».
36+
37+Chaque valeur a une ligne `source`, et la table n'a été remplie qu'à partir de deux sortes de sources :
38+
39+- **Les fiches de modèles et les fichiers publiés.** Les fiches Qwen (avec raisonnement 0.6 / 0.95 / 20, sans raisonnement 0.7 / 0.8 / 20), l'échantillonnage du GGUF de Gemma 4, le `generation_config.json` de Llama 3.1 8B Instruct (0.6 / 0.9, lu sur un miroir parce que le dépôt de Meta demande une connexion), la fiche de Mistral Small 3.1 (« a relatively low temperature, such as temperature=0.15 »), et la référence de l'API OpenAI pour les modèles hébergés.
40+- **Les démos mesurées de ce dépôt.** Pour chaque famille, on a cherché dans les démos qui font tourner le modèle l'échantillonnage qu'elles utilisent (`demos/*/agent*.yaml`). Par exemple `demos/qwen-style` (Qwen3-Coder-Next), `demos/coding-helpers` (Mellum2 12B Thinking, MiniCPM5 2B), `demos/team` (Ornith 1.5 9B), `demos/guard` (Granite Guardian), `demos/codex-style` (gpt-oss 20B) et `demos/llmman` (Jan-nano, Lucy). Le `precise` à 0.0 de Qwen vient d'exécutions avec Qwen3.5 4B sans raisonnement (`demos/docs-search`, `memory-search`, `plans`).
41+
42+Quand rien n'est publié, `other` applique la règle du skill `skills/create-agent` : 0.7 / 0.9, et 0.2 pour un agent de code qui ne raisonne pas.
43+
44+### 3. Le profil d'usage (`presets.yaml`, `usages`)
45+
46+L'usage dit à quoi sert l'agent, ce que le modèle ne peut pas savoir. Un profil fixe :
47+
48+- les outils activés (un traducteur n'a aucun outil, un développeur a bash, les outils de fichiers et l'outil de plan) ;
49+- s'il faut raisonner quand le modèle le peut ;
50+- s'il faut utiliser la température précise de la famille ;
51+- `maxTurns` ;
52+- la valeur par défaut de la demande avant chaque modification (`yolo`) ;
53+- un prompt système de départ.
54+
55+Certains usages activent chacun une fonction : `docs` active la recherche dans la documentation, `json` écrit un exemple de `structuredOutput` (qui interdit tout outil), et `coordinator` confie les questions à d'autres agents. Les prompts sont en anglais, selon le choix de l'utilisateur dans le ticket 97. Ils reprennent des règles communes aux prompts des démos, par exemple « Never state the output of a command you did not run in this answer ».
56+
57+### 4. La ligne de la machine (`presets.yaml`, `machines`)
58+
59+Les délais et la taille des sorties d'outils dépendent de la machine, pas du modèle. Les trois lignes `small`, `medium` et `large` (`firstTokenTimeout`, `watchdogTimeout`, `bashTimeout`, `maxOutput`) sont copiées du tableau « Summary: typical profiles » [du guide des réglages](../../../guides/reglages-agents-petits-modeles.md), écrit pour le ticket 98.
60+
61+## Les règles ajoutées par le code
62+
63+Quelques valeurs découlent des réponses plutôt que d'une table. Chaque règle écrit sa raison au-dessus de la valeur qu'elle fixe :
64+
65+- **Raisonnement activé : une température d'au moins 0.6 et `max_tokens: 16384`.** Un modèle qui raisonne tourne en boucle à basse température, et ses pensées ont besoin de place en plus de l'appel d'outil. Sans raisonnement, la limite est 4096.
66+- **La température précise ne s'applique que sans raisonnement.** Elle sert quand l'usage la demande (developer, reviewer, docs, json…).
67+- **Avec bash, `watchdogTimeout` est aligné sur `bashTimeout`**, comme le dit la section 3 du guide des réglages. Sinon une commande longue passerait pour un modèle bloqué.
68+- **`parallel_tool_calls: false` dès que l'agent a des outils.** Sinon les petits modèles lancent une vérification avant que la modification qu'elle vérifie soit faite.
69+- **`contextWindow: 0` et `context.threshold: 75`.** mm demande au serveur la fenêtre qu'il sert vraiment. La proposition prévoyait un seuil calculé sur la fenêtre native du modèle. Il a été abandonné pendant l'écriture du code : Ollama sert souvent 4k à 8k, donc un pourcentage de la fenêtre native compresserait presque tout de suite.
70+- **`skillsDir: no-skills`.** Un nouvel agent démarre sans skills, et le commentaire dit comment en ajouter.
71+
72+## Chaque valeur dit comment elle a été obtenue
73+
74+Depuis le ticket 121, chaque valeur liée au modèle porte une étiquette dans son commentaire. L'en-tête du fichier explique celles qu'il utilise :
75+
76+| Étiquette | Sens | Après un changement de modèle ou de quantification |
77+|---|---|---|
78+| `[server]` | lue sur le serveur au moment de l'écriture du fichier | relancer `mm init` |
79+| `[measured]` | une démo de ce dépôt a tourné avec | mesurer à nouveau |
80+| `[card]` | copiée de la fiche du modèle, du GGUF ou de la référence de l'API, pas mesurée ici | relire la fiche |
81+| `[rule]` | une règle générale, rien de propre au modèle | vérifier qu'elle convient encore |
82+| `[guide]` | la ligne du guide des réglages pour la machine | — |
83+
84+Un commentaire au-dessus de `model:` liste ce qu'il faut refaire quand on change de modèle. Les commentaires font que le fichier explique en même temps qu'il configure, à la manière des `agent.yaml` des démos : on voit quelles valeurs ont été mesurées sur une vraie exécution et lesquelles ont seulement été recopiées.
85+
86+## Le fichier est vérifié avant que l'assistant ait fini
87+
88+L'assistant n'écrase jamais un fichier existant. Après l'écriture, il charge le fichier avec le `config.Load` de mm, donc un fichier que mm refuserait est signalé tout de suite. Avec `--check`, il lance aussi le même mm sur le nouveau fichier avec une question (`Say hello in one line.`), pour prouver que le modèle répond.
89+
90+## Pourquoi c'est conçu ainsi
91+
92+**Un générateur sans modèle.** Le ticket 97 demandait un `agent.yaml` depuis la ligne de commande, selon la famille du modèle et l'usage. La proposition écrite pour le ticket a d'abord listé ce qui existait déjà : `agent.creator.yaml` et son skill `create-agent`, `model_facts.py`, le guide des réglages, `config.samples/` et les réglages testés des démos. Au lieu d'une nouvelle source de connaissances, `mm init` assemble ces morceaux dans du Go déterministe. C'est instantané et cela marche avant qu'aucun agent n'existe.
93+
94+**Le serveur d'abord, la table ensuite.** Une table ne peut connaître qu'une famille, alors que le serveur connaît le fichier exact qui est chargé : sa fenêtre, l'échantillonnage de son GGUF, son template. La table couvre les serveurs qui ne disent rien, comme Docker Model Runner.
95+
96+**Seulement des valeurs sourcées.** L'utilisateur a décidé que la table des familles utiliserait les fiches de modèles **et** les démos mesurées. Une valeur sans source n'y entre pas. Une famille qui n'a ni l'un ni l'autre retombe sur `other`, et le fichier dit que son échantillonnage n'est qu'un point de départ.
97+
98+**Une seule table.** `presets.yaml` est intégré au binaire. Son en-tête dit qu'il doit être partagé avec le skill Claude du ticket 111 (un skill construit à partir du guide des réglages). Ce ticket est encore ouvert, et le skill `mm-agent-creator` ne lit pas ce fichier aujourd'hui.
99+
100+## Alternatives écartées
101+
102+- **Générer le fichier avec un modèle** (`agent.creator.yaml`). Conservé pour les cas qui sortent de l'ordinaire, mais pas par défaut : il faut un modèle de 27B chargé et plusieurs minutes par agent.
103+- **Un seuil calculé sur la fenêtre native.** Écarté, voir plus haut : il compresserait presque tout de suite avec les fenêtres que sert Ollama.
104+- **Les skills, les serveurs MCP, les hooks et les `mmConfigs` dans l'assistant.** Laissés hors de la première version. Le commentaire de fin du fichier renvoie aux guides pratiques.
105+- **Des prompts dans la langue de l'utilisateur.** Écarté par le choix de l'utilisateur : les prompts générés sont en anglais.
106+
107+## Limites connues
108+
109+- Les vérifications en direct n'ont été faites qu'avec llmman (Qwen3.5 4B, gemma-4-E4B). Ollama, Docker Model Runner et llama-server ont été testés contre de faux serveurs enregistrés dans les tests. L'API OpenAI elle-même n'a pas été essayée ; ses contraintes viennent de sa référence.
110+- Une valeur `[card]` a été recopiée, pas mesurée dans ce dépôt.
111+- Les familles sont reconnues sur des mots de l'identifiant du modèle : un modèle renommé par son éditeur peut tomber dans `other`.
112+
113+## Liens avec le reste
114+
115+- [Fournisseurs](providers.md) : les cinq serveurs que l'assistant peut interroger, et pourquoi chacun a sa propre entrée.
116+- [Modèles à raisonnement](thinking-models.md) : ce que fait à l'exécution l'interrupteur de raisonnement que fixe l'assistant.
117+- [Compression du contexte](context-compression.md) : ce que déclenche `context.threshold`.
118+- [Sortie structurée](structured-output.md) : pourquoi l'usage `json` n'a pas d'outils.
119+- [Interroger un autre agent](asking-another-agent.md) : ce sur quoi s'appuie l'usage `coordinator`.
modified docs/fr/how-to/create-an-agent.md +1 -0
@@ -90,4 +90,5 @@ Ce guide montre comment écrire un nouvel agent.yaml pour un modèle et une tâc
9090 - [Référence de la ligne de commande — `mm init`](../reference/cli.md#mm-init--lassistant-agentyaml) : chaque option, les sources, les codes de sortie
9191 - [Référence de la configuration](../reference/configuration.md) : chaque clé du fichier
9292 - [Réglages des agents pour petits modèles](../../../guides/reglages-agents-petits-modeles.md) : ce que fait chaque réglage, les lignes par machine
93+- [D'où viennent les réglages](../explanation/mm-init.md) : les quatre sources, leur ordre, les étiquettes d'origine
9394 - `agent.creator.yaml` : un agent qui crée des agents avec un modèle, pour les cas qui sortent de l'ordinaire
@@ -90,4 +90,5 @@ Ce guide montre comment écrire un nouvel agent.yaml pour un modèle et une tâc
90 - [Référence de la ligne de commande — `mm init`](../reference/cli.md#mm-init--lassistant-agentyaml) : chaque option, les sources, les codes de sortie90 - [Référence de la ligne de commande — `mm init`](../reference/cli.md#mm-init--lassistant-agentyaml) : chaque option, les sources, les codes de sortie
91 - [Référence de la configuration](../reference/configuration.md) : chaque clé du fichier91 - [Référence de la configuration](../reference/configuration.md) : chaque clé du fichier
92 - [Réglages des agents pour petits modèles](../../../guides/reglages-agents-petits-modeles.md) : ce que fait chaque réglage, les lignes par machine92 - [Réglages des agents pour petits modèles](../../../guides/reglages-agents-petits-modeles.md) : ce que fait chaque réglage, les lignes par machine
93+- [D'où viennent les réglages](../explanation/mm-init.md) : les quatre sources, leur ordre, les étiquettes d'origine
93 - `agent.creator.yaml` : un agent qui crée des agents avec un modèle, pour les cas qui sortent de l'ordinaire94 - `agent.creator.yaml` : un agent qui crée des agents avec un modèle, pour les cas qui sortent de l'ordinaire
modified internal/agentinit/wizard.go +6 -0
@@ -175,6 +175,12 @@ func (f *Flow) takeDefaults() error {
175175 if err := f.Set(st.Key, st.Default); err != nil {
176176 return err
177177 }
178+ // Set records the default as an answer, but nobody answered: leave
179+ // yolo to the usage, so the file says "usage X's default", not
180+ // "your answer". The value is the same either way.
181+ if st.Key == "yolo" {
182+ f.c.Yolo = nil
183+ }
178184 }
179185 }
180186
@@ -175,6 +175,12 @@ func (f *Flow) takeDefaults() error {
175 if err := f.Set(st.Key, st.Default); err != nil {175 if err := f.Set(st.Key, st.Default); err != nil {
176 return err176 return err
177 }177 }
178+ // Set records the default as an answer, but nobody answered: leave
179+ // yolo to the usage, so the file says "usage X's default", not
180+ // "your answer". The value is the same either way.
181+ if st.Key == "yolo" {
182+ f.c.Yolo = nil
183+ }
178 }184 }
179 }185 }
180 186
modified internal/agentinit/wizard_test.go +20 -0
@@ -45,6 +45,26 @@ func TestMainWithFlagsOnly(t *testing.T) {
4545 }
4646 }
4747
48+// --yes without --yolo: the value is the usage's default, and the comment
49+// says so — not "your answer", which nobody gave.
50+func TestMainYesKeepsTheUsageDefaultForYolo(t *testing.T) {
51+ keepConfig(t)
52+ out := filepath.Join(t.TempDir(), "agent.yaml")
53+ var stdout bytes.Buffer
54+ code := Main([]string{"--provider", "llmman", "--base-url", llmmanStub(t), "--usage", "developer", "--machine", "small", "--name", "bob", "-o", out, "--yes"}, strings.NewReader(""), &stdout)
55+ if code != 0 {
56+ t.Fatalf("exit %d:\n%s", code, stdout.String())
57+ }
58+ data, _ := os.ReadFile(out)
59+ text := string(data)
60+ if !strings.Contains(text, "# usage developer's default: every command") || !strings.Contains(text, "\nyolo: false\n") {
61+ t.Errorf("yolo is not the usage's default with its reason:\n%s", text)
62+ }
63+ if strings.Contains(text, "# your answer") {
64+ t.Errorf("--yes answered nothing, yet the file says \"your answer\":\n%s", text)
65+ }
66+}
67+
4868 // Questions answered on stdin: the model from the server's list, the usage
4969 // and machine by number, yolo, the name, the file.
5070 func TestMainAsksTheQuestions(t *testing.T) {
@@ -45,6 +45,26 @@ func TestMainWithFlagsOnly(t *testing.T) {
45 }45 }
46 }46 }
47 47
48+// --yes without --yolo: the value is the usage's default, and the comment
49+// says so — not "your answer", which nobody gave.
50+func TestMainYesKeepsTheUsageDefaultForYolo(t *testing.T) {
51+ keepConfig(t)
52+ out := filepath.Join(t.TempDir(), "agent.yaml")
53+ var stdout bytes.Buffer
54+ code := Main([]string{"--provider", "llmman", "--base-url", llmmanStub(t), "--usage", "developer", "--machine", "small", "--name", "bob", "-o", out, "--yes"}, strings.NewReader(""), &stdout)
55+ if code != 0 {
56+ t.Fatalf("exit %d:\n%s", code, stdout.String())
57+ }
58+ data, _ := os.ReadFile(out)
59+ text := string(data)
60+ if !strings.Contains(text, "# usage developer's default: every command") || !strings.Contains(text, "\nyolo: false\n") {
61+ t.Errorf("yolo is not the usage's default with its reason:\n%s", text)
62+ }
63+ if strings.Contains(text, "# your answer") {
64+ t.Errorf("--yes answered nothing, yet the file says \"your answer\":\n%s", text)
65+ }
66+}
67+
48 // Questions answered on stdin: the model from the server's list, the usage68 // Questions answered on stdin: the model from the server's list, the usage
49 // and machine by number, yolo, the name, the file.69 // and machine by number, yolo, the name, the file.
50 func TestMainAsksTheQuestions(t *testing.T) {70 func TestMainAsksTheQuestions(t *testing.T) {