bots-garden/mini-mepublic Fork
⑂ main
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

Interactive Prompt #29

Merged@k33g wants to merge feature/interactive-prompt into main
Merged as fcf31f149797.
84 files changed
modified .tickets/issues/0048-add-a-builtin-tool-to-search-into-the-mm-session.yaml +2 -2
@@ -6,9 +6,9 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-27T03:45:48.121Z
9-updatedAt: 2026-10-06T03:59:41.259Z
9+updatedAt: 2026-10-12T09:53:49.053Z
1010 labels: []
11-milestone: v0.3.0
11+milestone: v0.5.0
1212 epic: Agent Memory
1313 body: ""
1414 tasks: []
@@ -6,9 +6,9 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-27T03:45:48.121Z8 createdAt: 2026-09-27T03:45:48.121Z
9-updatedAt: 2026-10-06T03:59:41.259Z9+updatedAt: 2026-10-12T09:53:49.053Z
10 labels: []10 labels: []
11-milestone: v0.3.011+milestone: v0.5.0
12 epic: Agent Memory12 epic: Agent Memory
13 body: ""13 body: ""
14 tasks: []14 tasks: []
modified .tickets/issues/0049-recreate-the-readme.yaml +2 -2
@@ -6,9 +6,9 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-28T18:44:44.821Z
9-updatedAt: 2026-10-06T13:08:12.646Z
9+updatedAt: 2026-10-12T09:54:01.192Z
1010 labels: []
11-milestone: v0.3.0
11+milestone: v0.5.0
1212 epic: ToDo
1313 body: ""
1414 tasks: []
@@ -6,9 +6,9 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-09-28T18:44:44.821Z8 createdAt: 2026-09-28T18:44:44.821Z
9-updatedAt: 2026-10-06T13:08:12.646Z9+updatedAt: 2026-10-12T09:54:01.192Z
10 labels: []10 labels: []
11-milestone: v0.3.011+milestone: v0.5.0
12 epic: ToDo12 epic: ToDo
13 body: ""13 body: ""
14 tasks: []14 tasks: []
modified .tickets/issues/0054-how-to-force-the-json-output.yaml +2 -2
@@ -1,12 +1,12 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 54
33 title: How to force the JSON output?
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-09-30T06:35:54.771Z
9-updatedAt: 2026-10-06T13:11:09.040Z
9+updatedAt: 2026-10-12T09:46:09.037Z
1010 labels: []
1111 epic: Questions
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: 542 id: 54
3 title: How to force the JSON output?3 title: How to force the JSON output?
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:35:54.771Z8 createdAt: 2026-09-30T06:35:54.771Z
9-updatedAt: 2026-10-06T13:11:09.040Z9+updatedAt: 2026-10-12T09:46:09.037Z
10 labels: []10 labels: []
11 epic: Questions11 epic: Questions
12 body: ""12 body: ""
modified .tickets/issues/0066-talk-to-another-mm.yaml +2 -1
@@ -6,9 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-02T18:48:36.275Z
9-updatedAt: 2026-10-06T03:55:28.931Z
9+updatedAt: 2026-10-12T09:52:38.596Z
1010 labels:
1111 - kind::feature
12+milestone: v0.3.0
1213 related:
1314 - 52
1415 - 57
@@ -6,9 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-02T18:48:36.275Z8 createdAt: 2026-10-02T18:48:36.275Z
9-updatedAt: 2026-10-06T03:55:28.931Z9+updatedAt: 2026-10-12T09:52:38.596Z
10 labels:10 labels:
11 - kind::feature11 - kind::feature
12+milestone: v0.3.0
12 related:13 related:
13 - 5214 - 52
14 - 5715 - 57
modified .tickets/issues/0067-enable-disable-reasoning-mode.yaml +2 -1
@@ -6,9 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-02T06:09:42.599Z
9-updatedAt: 2026-10-06T13:13:56.879Z
9+updatedAt: 2026-10-12T09:52:15.875Z
1010 labels:
1111 - kind::feature
12+milestone: v0.3.0
1213 epic: Models
1314 related:
1415 - 62
@@ -6,9 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-02T06:09:42.599Z8 createdAt: 2026-10-02T06:09:42.599Z
9-updatedAt: 2026-10-06T13:13:56.879Z9+updatedAt: 2026-10-12T09:52:15.875Z
10 labels:10 labels:
11 - kind::feature11 - kind::feature
12+milestone: v0.3.0
12 epic: Models13 epic: Models
13 related:14 related:
14 - 6215 - 62
modified .tickets/issues/0069-create-skills-to-search-some-specific-knowlege-o.yaml +4 -2
@@ -6,10 +6,12 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-02T09:26:19.729Z
9-updatedAt: 2026-10-06T13:11:52.354Z
9+updatedAt: 2026-10-12T09:35:03.158Z
1010 labels: []
1111 epic: ToDo
1212 body: |
13- For example Genkit skill with the appropriate links to the documentation (for fetching)
13+ Dans ./demos/news-roundup il y a un exemple d'agent qui fait des recherche duckduckgo avec un seveur MCP
14+
15+ Avec le même modele je voudrais faire la même chose dans ./demos/news-roundup-skill avec une skill au lieu d'utiliser un serveur MCP
1416 tasks: []
1517 comments: []
@@ -6,10 +6,12 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-02T09:26:19.729Z8 createdAt: 2026-10-02T09:26:19.729Z
9-updatedAt: 2026-10-06T13:11:52.354Z9+updatedAt: 2026-10-12T09:35:03.158Z
10 labels: []10 labels: []
11 epic: ToDo11 epic: ToDo
12 body: |12 body: |
13- For example Genkit skill with the appropriate links to the documentation (for fetching)13+ Dans ./demos/news-roundup il y a un exemple d'agent qui fait des recherche duckduckgo avec un seveur MCP
14+
15+ Avec le même modele je voudrais faire la même chose dans ./demos/news-roundup-skill avec une skill au lieu d'utiliser un serveur MCP
14 tasks: []16 tasks: []
15 comments: []17 comments: []
modified .tickets/issues/0071-mini-me-as-a-sdk.yaml +4 -2
@@ -6,8 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-02T05:32:33.878Z
9-updatedAt: 2026-10-06T13:15:18.350Z
10-labels: []
9+updatedAt: 2026-10-12T09:45:33.355Z
10+labels:
11+ - priority::urgent
12+ - kind::feature
1113 epic: SDK
1214 body: ""
1315 tasks: []
@@ -6,8 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-02T05:32:33.878Z8 createdAt: 2026-10-02T05:32:33.878Z
9-updatedAt: 2026-10-06T13:15:18.350Z9+updatedAt: 2026-10-12T09:45:33.355Z
10-labels: []10+labels:
11+ - priority::urgent
12+ - kind::feature
11 epic: SDK13 epic: SDK
12 body: ""14 body: ""
13 tasks: []15 tasks: []
modified .tickets/issues/0073-mm-ask-ask-with-context-ask-another-agent-from-a.yaml +2 -1
@@ -6,9 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-02T23:30:00.000Z
9-updatedAt: 2026-10-06T03:54:22.627Z
9+updatedAt: 2026-10-12T09:51:47.496Z
1010 labels:
1111 - kind::feature
12+milestone: v0.3.0
1213 related:
1314 - 52
1415 - 57
@@ -6,9 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-02T23:30:00.000Z8 createdAt: 2026-10-02T23:30:00.000Z
9-updatedAt: 2026-10-06T03:54:22.627Z9+updatedAt: 2026-10-12T09:51:47.496Z
10 labels:10 labels:
11 - kind::feature11 - kind::feature
12+milestone: v0.3.0
12 related:13 related:
13 - 5214 - 52
14 - 5715 - 57
modified .tickets/issues/0076-upgrade-genkit-go-to-v1-13-1.yaml +7 -7
@@ -1,15 +1,16 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 76
33 title: Upgrade Genkit Go to v1.13.1
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-06T14:30:00.000Z
9-updatedAt: 2026-10-06T16:00:00.000Z
9+updatedAt: 2026-10-12T09:51:20.921Z
1010 labels:
1111 - kind::chore
1212 - priority::medium
13+milestone: v0.3.0
1314 epic: Providers (LLM Engine)
1415 related:
1516 - 67
@@ -93,7 +94,7 @@ body: |
9394 `DefineModel`.
9495 tasks:
9596 - id: 1
96- title: "Branch from main after feature/yolo is merged; go get github.com/firebase/genkit/go@v1.13.1 + go mod tidy"
97+ title: Branch from main after feature/yolo is merged; go get github.com/firebase/genkit/go@v1.13.1 + go mod tidy
9798 state: closed
9899 priority: none
99100 author:
@@ -111,7 +112,7 @@ tasks:
111112 createdAt: 2026-10-06T14:30:00.000Z
112113 updatedAt: 2026-10-06T16:00:00.000Z
113114 - id: 3
114- title: "Register the model explicitly (RegisterAction + DefineModel, or NewModel with a permissive ConfigSchema) — decide which"
115+ title: Register the model explicitly (RegisterAction + DefineModel, or NewModel with a permissive ConfigSchema) — decide which
115116 state: closed
116117 priority: none
117118 author:
@@ -120,7 +121,7 @@ tasks:
120121 createdAt: 2026-10-06T14:30:00.000Z
121122 updatedAt: 2026-10-06T16:00:00.000Z
122123 - id: 4
123- title: "Re-check reasoning.go (Genkit now reads reasoning_content itself), toolargs.go, usage.go against v1.13.1; remove what became redundant"
124+ title: Re-check reasoning.go (Genkit now reads reasoning_content itself), toolargs.go, usage.go against v1.13.1; remove what became redundant
124125 state: closed
125126 priority: none
126127 author:
@@ -129,7 +130,7 @@ tasks:
129130 createdAt: 2026-10-06T14:30:00.000Z
130131 updatedAt: 2026-10-06T16:00:00.000Z
131132 - id: 5
132- title: "Silence Genkit's 'INFO Genkit initialized' start-up log"
133+ title: Silence Genkit's 'INFO Genkit initialized' start-up log
133134 state: closed
134135 priority: none
135136 author:
@@ -204,4 +205,3 @@ comments:
204205 - Docs EN+FR: reference/configuration (`sampling` extra keys),
205206 explanation/thinking-models (Genkit 1.13 delivery, how to turn
206207 reasoning off through sampling).
207-
@@ -1,15 +1,16 @@
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: 762 id: 76
3 title: Upgrade Genkit Go to v1.13.13 title: Upgrade Genkit Go to v1.13.1
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-10-06T14:30:00.000Z8 createdAt: 2026-10-06T14:30:00.000Z
9-updatedAt: 2026-10-06T16:00:00.000Z9+updatedAt: 2026-10-12T09:51:20.921Z
10 labels:10 labels:
11 - kind::chore11 - kind::chore
12 - priority::medium12 - priority::medium
13+milestone: v0.3.0
13 epic: Providers (LLM Engine)14 epic: Providers (LLM Engine)
14 related:15 related:
15 - 6716 - 67
@@ -93,7 +94,7 @@ body: |
93 `DefineModel`.94 `DefineModel`.
94 tasks:95 tasks:
95 - id: 196 - id: 1
96- title: "Branch from main after feature/yolo is merged; go get github.com/firebase/genkit/go@v1.13.1 + go mod tidy"97+ title: Branch from main after feature/yolo is merged; go get github.com/firebase/genkit/go@v1.13.1 + go mod tidy
97 state: closed98 state: closed
98 priority: none99 priority: none
99 author:100 author:
@@ -111,7 +112,7 @@ tasks:
111 createdAt: 2026-10-06T14:30:00.000Z112 createdAt: 2026-10-06T14:30:00.000Z
112 updatedAt: 2026-10-06T16:00:00.000Z113 updatedAt: 2026-10-06T16:00:00.000Z
113 - id: 3114 - id: 3
114- title: "Register the model explicitly (RegisterAction + DefineModel, or NewModel with a permissive ConfigSchema) — decide which"115+ title: Register the model explicitly (RegisterAction + DefineModel, or NewModel with a permissive ConfigSchema) — decide which
115 state: closed116 state: closed
116 priority: none117 priority: none
117 author:118 author:
@@ -120,7 +121,7 @@ tasks:
120 createdAt: 2026-10-06T14:30:00.000Z121 createdAt: 2026-10-06T14:30:00.000Z
121 updatedAt: 2026-10-06T16:00:00.000Z122 updatedAt: 2026-10-06T16:00:00.000Z
122 - id: 4123 - id: 4
123- title: "Re-check reasoning.go (Genkit now reads reasoning_content itself), toolargs.go, usage.go against v1.13.1; remove what became redundant"124+ title: Re-check reasoning.go (Genkit now reads reasoning_content itself), toolargs.go, usage.go against v1.13.1; remove what became redundant
124 state: closed125 state: closed
125 priority: none126 priority: none
126 author:127 author:
@@ -129,7 +130,7 @@ tasks:
129 createdAt: 2026-10-06T14:30:00.000Z130 createdAt: 2026-10-06T14:30:00.000Z
130 updatedAt: 2026-10-06T16:00:00.000Z131 updatedAt: 2026-10-06T16:00:00.000Z
131 - id: 5132 - id: 5
132- title: "Silence Genkit's 'INFO Genkit initialized' start-up log"133+ title: Silence Genkit's 'INFO Genkit initialized' start-up log
133 state: closed134 state: closed
134 priority: none135 priority: none
135 author:136 author:
@@ -204,4 +205,3 @@ comments:
204 - Docs EN+FR: reference/configuration (`sampling` extra keys),205 - Docs EN+FR: reference/configuration (`sampling` extra keys),
205 explanation/thinking-models (Genkit 1.13 delivery, how to turn206 explanation/thinking-models (Genkit 1.13 delivery, how to turn
206 reasoning off through sampling).207 reasoning off through sampling).
207-
modified .tickets/issues/0080-structured-output-from-go-type-declarations-in-t.yaml +2 -1
@@ -6,9 +6,10 @@ author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-08T10:00:00.000Z
9-updatedAt: 2026-10-09T03:16:38.703Z
9+updatedAt: 2026-10-12T09:51:02.307Z
1010 labels:
1111 - enhancement
12+milestone: v0.3.0
1213 epic: Models
1314 related:
1415 - 54
@@ -6,9 +6,10 @@ author:
6 name: k33g6 name: k33g
7 email: ph.charriere@gmail.com7 email: ph.charriere@gmail.com
8 createdAt: 2026-10-08T10:00:00.000Z8 createdAt: 2026-10-08T10:00:00.000Z
9-updatedAt: 2026-10-09T03:16:38.703Z9+updatedAt: 2026-10-12T09:51:02.307Z
10 labels:10 labels:
11 - enhancement11 - enhancement
12+milestone: v0.3.0
12 epic: Models13 epic: Models
13 related:14 related:
14 - 5415 - 54
modified .tickets/issues/0081-support-agents-md-project-instructions-for-the-a.yaml +3 -2
@@ -1,14 +1,15 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 81
33 title: Support AGENTS.md (project instructions for the agent)
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-09T08:00:00.000Z
9-updatedAt: 2026-10-09T15:00:00.000Z
9+updatedAt: 2026-10-12T09:50:43.252Z
1010 labels:
1111 - enhancement
12+milestone: v0.3.0
1213 epic: Agent Memory
1314 related:
1415 - 79
@@ -1,14 +1,15 @@
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: 812 id: 81
3 title: Support AGENTS.md (project instructions for the agent)3 title: Support AGENTS.md (project instructions for the agent)
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-10-09T08:00:00.000Z8 createdAt: 2026-10-09T08:00:00.000Z
9-updatedAt: 2026-10-09T15:00:00.000Z9+updatedAt: 2026-10-12T09:50:43.252Z
10 labels:10 labels:
11 - enhancement11 - enhancement
12+milestone: v0.3.0
12 epic: Agent Memory13 epic: Agent Memory
13 related:14 related:
14 - 7915 - 79
modified .tickets/issues/0083-demo-agent-news-roundup-with-lucy-128k.yaml +11 -3
@@ -1,14 +1,22 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 83
33 title: "demo agent: news roundup with Lucy 128k"
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-12T04:06:03.394Z
9-updatedAt: 2026-10-12T04:07:39.381Z
9+updatedAt: 2026-10-12T09:49:25.499Z
1010 labels: []
11+milestone: v0.4.0
1112 body: |
1213 Use hf.co/Menlo/Lucy-128k-gguf:Q8_0
1314 tasks: []
14-comments: []
15+comments:
16+ - id: 1
17+ author:
18+ name: k33g
19+ email: ph.charriere@gmail.com
20+ createdAt: 2026-10-12T09:27:34.000Z
21+ body: |
22+ Done: demos/news-roundup/ (DuckDuckGo News through a small MCP server, ddg_news.py). Lucy 128k was tried first and replaced by Qwen3.5 9B at the user's request (Lucy looped in 6/12 runs); measured results in the demo's READMEs. Also fixed in mm: MCP tools are now declared with their input schema.
@@ -1,14 +1,22 @@
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: 832 id: 83
3 title: "demo agent: news roundup with Lucy 128k"3 title: "demo agent: news roundup with Lucy 128k"
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-10-12T04:06:03.394Z8 createdAt: 2026-10-12T04:06:03.394Z
9-updatedAt: 2026-10-12T04:07:39.381Z9+updatedAt: 2026-10-12T09:49:25.499Z
10 labels: []10 labels: []
11+milestone: v0.4.0
11 body: |12 body: |
12 Use hf.co/Menlo/Lucy-128k-gguf:Q8_013 Use hf.co/Menlo/Lucy-128k-gguf:Q8_0
13 tasks: []14 tasks: []
14-comments: []15+comments:
16+ - id: 1
17+ author:
18+ name: k33g
19+ email: ph.charriere@gmail.com
20+ createdAt: 2026-10-12T09:27:34.000Z
21+ body: |
22+ Done: demos/news-roundup/ (DuckDuckGo News through a small MCP server, ddg_news.py). Lucy 128k was tried first and replaced by Qwen3.5 9B at the user's request (Lucy looped in 6/12 runs); measured results in the demo's READMEs. Also fixed in mm: MCP tools are now declared with their input schema.
modified .tickets/issues/0084-interactive-prompts-in-a-cli-acp.yaml +16 -6
@@ -1,13 +1,14 @@
11 # Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
22 id: 84
33 title: Interactive prompts in a CLI + ACP
4-state: open
4+state: closed
55 author:
66 name: k33g
77 email: ph.charriere@gmail.com
88 createdAt: 2026-10-12T04:38:05.715Z
9-updatedAt: 2026-10-12T04:41:47.738Z
9+updatedAt: 2026-10-12T09:50:23.536Z
1010 labels: []
11+milestone: v0.4.0
1112 body: |
1213 ## Interactive prompts in a CLI
1314
@@ -50,22 +51,24 @@ body: |
5051 tasks:
5152 - id: 1
5253 title: Implement interactive prompts in mini me CLI
53- state: open
54+ state: closed
5455 priority: high
5556 author:
5657 name: k33g
5758 email: ph.charriere@gmail.com
5859 createdAt: 2026-10-12T04:41:04.171Z
59- updatedAt: 2026-10-12T04:41:43.060Z
60+ updatedAt: 2026-10-12T09:27:34.000Z
61+ closedAt: 2026-10-12T09:27:34.000Z
6062 - id: 2
6163 title: Implement support in ACP
62- state: open
64+ state: closed
6365 priority: medium
6466 author:
6567 name: k33g
6668 email: ph.charriere@gmail.com
6769 createdAt: 2026-10-12T04:41:24.268Z
68- updatedAt: 2026-10-12T04:41:47.731Z
70+ updatedAt: 2026-10-12T09:27:34.000Z
71+ closedAt: 2026-10-12T09:27:34.000Z
6972 comments:
7073 - id: 1
7174 author:
@@ -74,3 +77,10 @@ comments:
7477 createdAt: 2026-10-12T04:40:24.315Z
7578 body: |
7679 ACP (Agent Client Protocol) resources: https://agentclientprotocol.com/get-started/introduction
80+ - id: 2
81+ author:
82+ name: k33g
83+ email: ph.charriere@gmail.com
84+ createdAt: 2026-10-12T09:27:34.000Z
85+ body: |
86+ Done on branch feature/interactive-prompt: the ask_user tool (choice, multi, text, confirm) — numbered answers in the line mode, arrow keys in the window, ACP elicitation forms with a permission-dialog fallback, questions of called agents relayed to the asker's user; askUserTool, AGENT_ASK_USER, mmConfigs.<name>.askUser. Docs EN+FR; demo: demos/project-wizard/.
@@ -1,13 +1,14 @@
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: 842 id: 84
3 title: Interactive prompts in a CLI + ACP3 title: Interactive prompts in a CLI + ACP
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-10-12T04:38:05.715Z8 createdAt: 2026-10-12T04:38:05.715Z
9-updatedAt: 2026-10-12T04:41:47.738Z9+updatedAt: 2026-10-12T09:50:23.536Z
10 labels: []10 labels: []
11+milestone: v0.4.0
11 body: |12 body: |
12 ## Interactive prompts in a CLI13 ## Interactive prompts in a CLI
13 14
@@ -50,22 +51,24 @@ body: |
50 tasks:51 tasks:
51 - id: 152 - id: 1
52 title: Implement interactive prompts in mini me CLI53 title: Implement interactive prompts in mini me CLI
53- state: open54+ state: closed
54 priority: high55 priority: high
55 author:56 author:
56 name: k33g57 name: k33g
57 email: ph.charriere@gmail.com58 email: ph.charriere@gmail.com
58 createdAt: 2026-10-12T04:41:04.171Z59 createdAt: 2026-10-12T04:41:04.171Z
59- updatedAt: 2026-10-12T04:41:43.060Z60+ updatedAt: 2026-10-12T09:27:34.000Z
61+ closedAt: 2026-10-12T09:27:34.000Z
60 - id: 262 - id: 2
61 title: Implement support in ACP63 title: Implement support in ACP
62- state: open64+ state: closed
63 priority: medium65 priority: medium
64 author:66 author:
65 name: k33g67 name: k33g
66 email: ph.charriere@gmail.com68 email: ph.charriere@gmail.com
67 createdAt: 2026-10-12T04:41:24.268Z69 createdAt: 2026-10-12T04:41:24.268Z
68- updatedAt: 2026-10-12T04:41:47.731Z70+ updatedAt: 2026-10-12T09:27:34.000Z
71+ closedAt: 2026-10-12T09:27:34.000Z
69 comments:72 comments:
70 - id: 173 - id: 1
71 author:74 author:
@@ -74,3 +77,10 @@ comments:
74 createdAt: 2026-10-12T04:40:24.315Z77 createdAt: 2026-10-12T04:40:24.315Z
75 body: |78 body: |
76 ACP (Agent Client Protocol) resources: https://agentclientprotocol.com/get-started/introduction79 ACP (Agent Client Protocol) resources: https://agentclientprotocol.com/get-started/introduction
80+ - id: 2
81+ author:
82+ name: k33g
83+ email: ph.charriere@gmail.com
84+ createdAt: 2026-10-12T09:27:34.000Z
85+ body: |
86+ Done on branch feature/interactive-prompt: the ask_user tool (choice, multi, text, confirm) — numbered answers in the line mode, arrow keys in the window, ACP elicitation forms with a permission-dialog fallback, questions of called agents relayed to the asker's user; askUserTool, AGENT_ASK_USER, mmConfigs.<name>.askUser. Docs EN+FR; demo: demos/project-wizard/.
added .tickets/issues/0085-demo-agent-like-gemini.yaml +23 -0
new file mode 100644
@@ -0,0 +1,23 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 85
3+title: demo agent like gemini
4+state: closed
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-12T06:19:14.863Z
9+updatedAt: 2026-10-12T09:49:59.454Z
10+labels: []
11+milestone: v0.4.0
12+body: |
13+ agent homer: creer dans demos un nouvel agent du même style que gemini avec
14+ hf.co/unsloth/gemma-4-26B-A4B-it-GGUF:Q4_K_M
15+tasks: []
16+comments:
17+ - id: 1
18+ author:
19+ name: k33g
20+ email: ph.charriere@gmail.com
21+ createdAt: 2026-10-12T09:41:27.000Z
22+ body: |
23+ Done: demos/gemini-style/ — Gemini CLI's system prompt (interactive variant) adapted to mm, on Gemma 4 26B-A4B (llmman), reads GEMINI.md. Measured on the qwen-style Go set: 12/14 (the commit case asks which files and which message instead of committing). READMEs EN+FR.
new file mode 100644
@@ -0,0 +1,23 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 85
3+title: demo agent like gemini
4+state: closed
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-12T06:19:14.863Z
9+updatedAt: 2026-10-12T09:49:59.454Z
10+labels: []
11+milestone: v0.4.0
12+body: |
13+ agent homer: creer dans demos un nouvel agent du même style que gemini avec
14+ hf.co/unsloth/gemma-4-26B-A4B-it-GGUF:Q4_K_M
15+tasks: []
16+comments:
17+ - id: 1
18+ author:
19+ name: k33g
20+ email: ph.charriere@gmail.com
21+ createdAt: 2026-10-12T09:41:27.000Z
22+ body: |
23+ Done: demos/gemini-style/ — Gemini CLI's system prompt (interactive variant) adapted to mm, on Gemma 4 26B-A4B (llmman), reads GEMINI.md. Measured on the qwen-style Go set: 12/14 (the commit case asks which files and which message instead of committing). READMEs EN+FR.
added .tickets/issues/0086-demo-agent-like-codex.yaml +17 -0
new file mode 100644
@@ -0,0 +1,17 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 86
3+title: demo agent like codex
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-12T09:36:47.030Z
9+updatedAt: 2026-10-12T09:49:39.850Z
10+labels: []
11+milestone: v0.4.0
12+body: |
13+ agent homer: creer dans demos un nouvel agent du même style que codex avec
14+
15+ hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
16+tasks: []
17+comments: []
new file mode 100644
@@ -0,0 +1,17 @@
1+# Managed by IssueSpec. Hand edits are welcome; keep the schema valid.
2+id: 86
3+title: demo agent like codex
4+state: open
5+author:
6+ name: k33g
7+ email: ph.charriere@gmail.com
8+createdAt: 2026-10-12T09:36:47.030Z
9+updatedAt: 2026-10-12T09:49:39.850Z
10+labels: []
11+milestone: v0.4.0
12+body: |
13+ agent homer: creer dans demos un nouvel agent du même style que codex avec
14+
15+ hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
16+tasks: []
17+comments: []
modified .tickets/milestones.yaml +7 -1
@@ -13,5 +13,11 @@ milestones:
1313 state: closed
1414 dueOn: 2026-10-30
1515 - title: v0.3.0
16- state: open
16+ state: closed
1717 dueOn: 2026-11-01
18+ - title: v0.4.0
19+ state: open
20+ dueOn: 2026-10-16
21+ - title: v0.5.0
22+ state: open
23+ dueOn: 2026-10-28
@@ -13,5 +13,11 @@ milestones:
13 state: closed13 state: closed
14 dueOn: 2026-10-3014 dueOn: 2026-10-30
15 - title: v0.3.015 - title: v0.3.0
16- state: open16+ state: closed
17 dueOn: 2026-11-0117 dueOn: 2026-11-01
18+ - title: v0.4.0
19+ state: open
20+ dueOn: 2026-10-16
21+ - title: v0.5.0
22+ state: open
23+ dueOn: 2026-10-28
modified README.md +5 -0
@@ -109,6 +109,8 @@ Anything that speaks ACP can host `mm -acp` the same way: **JetBrains IDEs** (In
109109
110110 - **One prompt and exit**: `mm -p "…"` — for scripts. See [Run a single prompt](docs/en/how-to/run-a-single-prompt.md).
111111 - **Other agents**: list other mm agents under `mmConfigs`; you ask them with `/ask-<name>`, your agent calls them itself with its `ask_agent` tool, a script with `mm --ask <name>`. See [Let your agent call other agents](docs/en/how-to/let-the-agent-call-other-agents.md).
112+- **Questions to you**: the agent asks with its `ask_user` tool — pick one, pick several, type a text, yes or no — as numbered choices in the terminal, an arrow-key box in the window, a form or a dialog in an editor; a called agent's questions come up to you too. `askUserTool: false` turns it off. See [Let the agent ask you questions](docs/en/how-to/let-the-agent-ask-you.md).
113+- **An agent that creates agents**: `./mm -config agent.creator.yaml` (Qwen3.8 27B), then "Create an agent that … with <model>". It reads the model's facts from llmman (`skills/create-agent/model_facts.py`: chat template, reasoning switches, tool-call format, sampling, context), asks what it is missing, writes a commented `agent.yaml` tuned to that model and checks that it loads and answers — the `create-agent` skill.
112114 - **Project instructions**: an `AGENTS.md` in the project directory is added to the system prompt of every conversation. See [Give the agent your project's instructions](docs/en/how-to/give-project-instructions.md).
113115 - **Answers as JSON**: declare the shape of the answer as Go types under `structuredOutput`, and `mm -p "…" | jq` works. See [Get answers as JSON](docs/en/how-to/get-json-answers.md).
114116 - **MCP servers**: their tools, wrapped as mm tools. See the [MCP tutorial](docs/en/tutorials/mcp-getting-started.md).
@@ -133,7 +135,10 @@ The `demos/` directory holds ready-made set-ups (most with a README explaining h
133135 | `demos/blog-team/` | the smallest team: a lead, a coder and a reviewer in 75 lines of YAML, one model (Mellum2 12B Q8_0 on llmman), written for a blog post |
134136 | `demos/translator/` | a French ↔ English translator (Gemma 4 E4B on llmman): `AGENTS.md` for the style, skills for technical texts, e-mails and idioms, `$styles` for professional / informal / Slack versions, `translate.sh` for files |
135137 | `demos/qwen-style/` | a general coding agent whose system prompt follows Qwen Code's, adapted to mm's tools, in three configurations on llmman: Qwen3.8 27B, Qwen3-Coder-Next, Qwen3.6 35B-A3B — Qwen Code's `new-app` and `simplify` skills, measured results |
138+| `demos/gemini-style/` | the same idea with Gemini CLI's system prompt (Research → Strategy → Execution, Directives vs Inquiries, Context Efficiency), adapted to mm and to Gemma 4 26B-A4B on llmman; reads `GEMINI.md`; measured results |
139+| `demos/codex-style/` | the same idea with Codex CLI's default instructions (preambles, plans, ambition vs. precision, final-answer format), adapted to mm and to gpt-oss 20B (harmony format, `reasoning_effort`, `model_identity`) on llmman; measured results |
136140 | `demos/news-roundup/` | a press-review agent: DuckDuckGo News through a small MCP server (Python standard library), Qwen3.5 9B on llmman, ready-made citations so no article is invented, measured results |
141+| `demos/project-wizard/` | the interactive prompts (`ask_user`) in a small agent: a four-question form (text, two choices, several choices), then a yes/no confirmation carrying the plan before any file is written; Qwen3.5 9B on llmman, measured results |
137142
138143 ## Learn more
139144
@@ -109,6 +109,8 @@ Anything that speaks ACP can host `mm -acp` the same way: **JetBrains IDEs** (In
109 109
110 - **One prompt and exit**: `mm -p "…"` — for scripts. See [Run a single prompt](docs/en/how-to/run-a-single-prompt.md).110 - **One prompt and exit**: `mm -p "…"` — for scripts. See [Run a single prompt](docs/en/how-to/run-a-single-prompt.md).
111 - **Other agents**: list other mm agents under `mmConfigs`; you ask them with `/ask-<name>`, your agent calls them itself with its `ask_agent` tool, a script with `mm --ask <name>`. See [Let your agent call other agents](docs/en/how-to/let-the-agent-call-other-agents.md).111 - **Other agents**: list other mm agents under `mmConfigs`; you ask them with `/ask-<name>`, your agent calls them itself with its `ask_agent` tool, a script with `mm --ask <name>`. See [Let your agent call other agents](docs/en/how-to/let-the-agent-call-other-agents.md).
112+- **Questions to you**: the agent asks with its `ask_user` tool — pick one, pick several, type a text, yes or no — as numbered choices in the terminal, an arrow-key box in the window, a form or a dialog in an editor; a called agent's questions come up to you too. `askUserTool: false` turns it off. See [Let the agent ask you questions](docs/en/how-to/let-the-agent-ask-you.md).
113+- **An agent that creates agents**: `./mm -config agent.creator.yaml` (Qwen3.8 27B), then "Create an agent that … with <model>". It reads the model's facts from llmman (`skills/create-agent/model_facts.py`: chat template, reasoning switches, tool-call format, sampling, context), asks what it is missing, writes a commented `agent.yaml` tuned to that model and checks that it loads and answers — the `create-agent` skill.
112 - **Project instructions**: an `AGENTS.md` in the project directory is added to the system prompt of every conversation. See [Give the agent your project's instructions](docs/en/how-to/give-project-instructions.md).114 - **Project instructions**: an `AGENTS.md` in the project directory is added to the system prompt of every conversation. See [Give the agent your project's instructions](docs/en/how-to/give-project-instructions.md).
113 - **Answers as JSON**: declare the shape of the answer as Go types under `structuredOutput`, and `mm -p "…" | jq` works. See [Get answers as JSON](docs/en/how-to/get-json-answers.md).115 - **Answers as JSON**: declare the shape of the answer as Go types under `structuredOutput`, and `mm -p "…" | jq` works. See [Get answers as JSON](docs/en/how-to/get-json-answers.md).
114 - **MCP servers**: their tools, wrapped as mm tools. See the [MCP tutorial](docs/en/tutorials/mcp-getting-started.md).116 - **MCP servers**: their tools, wrapped as mm tools. See the [MCP tutorial](docs/en/tutorials/mcp-getting-started.md).
@@ -133,7 +135,10 @@ The `demos/` directory holds ready-made set-ups (most with a README explaining h
133 | `demos/blog-team/` | the smallest team: a lead, a coder and a reviewer in 75 lines of YAML, one model (Mellum2 12B Q8_0 on llmman), written for a blog post |135 | `demos/blog-team/` | the smallest team: a lead, a coder and a reviewer in 75 lines of YAML, one model (Mellum2 12B Q8_0 on llmman), written for a blog post |
134 | `demos/translator/` | a French ↔ English translator (Gemma 4 E4B on llmman): `AGENTS.md` for the style, skills for technical texts, e-mails and idioms, `$styles` for professional / informal / Slack versions, `translate.sh` for files |136 | `demos/translator/` | a French ↔ English translator (Gemma 4 E4B on llmman): `AGENTS.md` for the style, skills for technical texts, e-mails and idioms, `$styles` for professional / informal / Slack versions, `translate.sh` for files |
135 | `demos/qwen-style/` | a general coding agent whose system prompt follows Qwen Code's, adapted to mm's tools, in three configurations on llmman: Qwen3.8 27B, Qwen3-Coder-Next, Qwen3.6 35B-A3B — Qwen Code's `new-app` and `simplify` skills, measured results |137 | `demos/qwen-style/` | a general coding agent whose system prompt follows Qwen Code's, adapted to mm's tools, in three configurations on llmman: Qwen3.8 27B, Qwen3-Coder-Next, Qwen3.6 35B-A3B — Qwen Code's `new-app` and `simplify` skills, measured results |
138+| `demos/gemini-style/` | the same idea with Gemini CLI's system prompt (Research → Strategy → Execution, Directives vs Inquiries, Context Efficiency), adapted to mm and to Gemma 4 26B-A4B on llmman; reads `GEMINI.md`; measured results |
139+| `demos/codex-style/` | the same idea with Codex CLI's default instructions (preambles, plans, ambition vs. precision, final-answer format), adapted to mm and to gpt-oss 20B (harmony format, `reasoning_effort`, `model_identity`) on llmman; measured results |
136 | `demos/news-roundup/` | a press-review agent: DuckDuckGo News through a small MCP server (Python standard library), Qwen3.5 9B on llmman, ready-made citations so no article is invented, measured results |140 | `demos/news-roundup/` | a press-review agent: DuckDuckGo News through a small MCP server (Python standard library), Qwen3.5 9B on llmman, ready-made citations so no article is invented, measured results |
141+| `demos/project-wizard/` | the interactive prompts (`ask_user`) in a small agent: a four-question form (text, two choices, several choices), then a yes/no confirmation carrying the plan before any file is written; Qwen3.5 9B on llmman, measured results |
137 142
138 ## Learn more143 ## Learn more
139 144
added agent.creator.yaml +104 -0
new file mode 100644
@@ -0,0 +1,104 @@
1+# Agent creator — an mm agent that creates mm agents.
2+#
3+# Give it a model served by llmman and a job; it reads the model's facts
4+# (skills/create-agent/model_facts.py: size, context window, sampling in the
5+# GGUF, the chat template's reasoning switches and tool-call format), asks
6+# what it is missing with ask_user, writes a commented agent.yaml tuned to
7+# that model, and checks that the file loads and answers. The procedure is
8+# the `create-agent` skill (skills/create-agent/SKILL.md).
9+#
10+# Model: Qwen3.8 27B (17.4 GB, dense, reasoning on). Chosen because it is the
11+# one that followed every step in the measurements of demos/qwen-style
12+# (14/14 on seven Go tasks: bash, files, a git workflow, faithful reports) —
13+# this job is a procedure of several steps with bash, a file to write and a
14+# question form. It is slow-ish on a laptop; creating an agent is rare.
15+#
16+# Run it FROM THE REPOSITORY ROOT (the skill and its script are found there):
17+#
18+# llmman pull hf.co/unsloth/Qwen3.8-27B-GGUF:Q4_K_M
19+# llmman serve
20+# ./mm -config agent.creator.yaml
21+# > Create an agent that translates French to English with hf.co/unsloth/gemma-4-E4B-it-GGUF:Q4_K_M
22+#
23+# Every key is optional; reference: docs/en/reference/configuration.md.
24+
25+# ─── Model and server ────────────────────────────────────────────────────────
26+
27+provider: llmman
28+model: hf.co/unsloth/Qwen3.8-27B-GGUF:Q4_K_M
29+baseUrl: http://127.0.0.1:17434/v1
30+fallback: http://host.docker.internal:17434/v1
31+contextWindow: 0
32+
33+sampling:
34+ # Qwen's settings for a thinking model on precise work (the GGUF says 1.0).
35+ temperature: 0.6
36+ top_p: 0.95
37+ top_k: 20
38+ min_p: 0.0
39+ # The reasoning plus a whole agent.yaml in one write_file.
40+ max_tokens: 16384
41+ parallel_tool_calls: false
42+ # Qwen3.8's template: enable_thinking (default on) and reasoning_effort
43+ # low | medium | xhigh — any other value makes every request fail.
44+ chat_template_kwargs:
45+ enable_thinking: true
46+ reasoning_effort: medium
47+
48+showThinking: true
49+
50+# ─── Timeouts ────────────────────────────────────────────────────────────────
51+
52+# Loading ~17 GB on the first question; the check in step 5 starts another
53+# mm, which may load the target model too.
54+firstTokenTimeout: 5m
55+watchdogTimeout: 5m
56+bashTimeout: 5m
57+
58+# ─── Agent loop ──────────────────────────────────────────────────────────────
59+
60+# The questions, the facts, the file, the check, a fix or two.
61+maxTurns: 20
62+maxOutput: 20000
63+displayCommands: true
64+
65+# ─── Tools ───────────────────────────────────────────────────────────────────
66+
67+# Asks before running the script, writing the file and running the check:
68+# [a] once, [s] this tool for the session, [r] reject, [n] never.
69+# AGENT_YOLO=true for unattended runs.
70+yolo: false
71+
72+bashTool: true # model_facts.py, the check
73+editTools: true # writes and fixes agent.yaml
74+askUserTool: true # the model, the job, the constraints
75+planTool: false
76+fetchContentTool: false # set true to let it read a model card on the web
77+
78+# The repository's skills directory: the create-agent skill (and the demo
79+# skills that live beside it).
80+skillsDir: skills
81+
82+agentsMd:
83+ enabled: false
84+
85+acp:
86+ name: agent-creator
87+ title: Agent creator
88+
89+system: |
90+ You create mm agent configurations: an agent.yaml tuned to one model served
91+ by llmman and to the job the user describes.
92+
93+ For any request to create, tune or review an agent for a model, call
94+ read_skill with name "create-agent" FIRST, then follow its steps in order:
95+ ask what is missing (one ask_user call), run model_facts.py, choose the
96+ settings from the skill's table, write the file, check it with "$MM_BIN",
97+ report.
98+
99+ RULES
100+ - Facts about a model come from model_facts.py, never from memory. If the
101+ script cannot reach llmman, say so and stop.
102+ - Never invent a chat template variable or a value the report does not list.
103+ - Write one file (and its directory); never change other files.
104+ - Answer in the language of the user's message.
new file mode 100644
@@ -0,0 +1,104 @@
1+# Agent creator — an mm agent that creates mm agents.
2+#
3+# Give it a model served by llmman and a job; it reads the model's facts
4+# (skills/create-agent/model_facts.py: size, context window, sampling in the
5+# GGUF, the chat template's reasoning switches and tool-call format), asks
6+# what it is missing with ask_user, writes a commented agent.yaml tuned to
7+# that model, and checks that the file loads and answers. The procedure is
8+# the `create-agent` skill (skills/create-agent/SKILL.md).
9+#
10+# Model: Qwen3.8 27B (17.4 GB, dense, reasoning on). Chosen because it is the
11+# one that followed every step in the measurements of demos/qwen-style
12+# (14/14 on seven Go tasks: bash, files, a git workflow, faithful reports) —
13+# this job is a procedure of several steps with bash, a file to write and a
14+# question form. It is slow-ish on a laptop; creating an agent is rare.
15+#
16+# Run it FROM THE REPOSITORY ROOT (the skill and its script are found there):
17+#
18+# llmman pull hf.co/unsloth/Qwen3.8-27B-GGUF:Q4_K_M
19+# llmman serve
20+# ./mm -config agent.creator.yaml
21+# > Create an agent that translates French to English with hf.co/unsloth/gemma-4-E4B-it-GGUF:Q4_K_M
22+#
23+# Every key is optional; reference: docs/en/reference/configuration.md.
24+
25+# ─── Model and server ────────────────────────────────────────────────────────
26+
27+provider: llmman
28+model: hf.co/unsloth/Qwen3.8-27B-GGUF:Q4_K_M
29+baseUrl: http://127.0.0.1:17434/v1
30+fallback: http://host.docker.internal:17434/v1
31+contextWindow: 0
32+
33+sampling:
34+ # Qwen's settings for a thinking model on precise work (the GGUF says 1.0).
35+ temperature: 0.6
36+ top_p: 0.95
37+ top_k: 20
38+ min_p: 0.0
39+ # The reasoning plus a whole agent.yaml in one write_file.
40+ max_tokens: 16384
41+ parallel_tool_calls: false
42+ # Qwen3.8's template: enable_thinking (default on) and reasoning_effort
43+ # low | medium | xhigh — any other value makes every request fail.
44+ chat_template_kwargs:
45+ enable_thinking: true
46+ reasoning_effort: medium
47+
48+showThinking: true
49+
50+# ─── Timeouts ────────────────────────────────────────────────────────────────
51+
52+# Loading ~17 GB on the first question; the check in step 5 starts another
53+# mm, which may load the target model too.
54+firstTokenTimeout: 5m
55+watchdogTimeout: 5m
56+bashTimeout: 5m
57+
58+# ─── Agent loop ──────────────────────────────────────────────────────────────
59+
60+# The questions, the facts, the file, the check, a fix or two.
61+maxTurns: 20
62+maxOutput: 20000
63+displayCommands: true
64+
65+# ─── Tools ───────────────────────────────────────────────────────────────────
66+
67+# Asks before running the script, writing the file and running the check:
68+# [a] once, [s] this tool for the session, [r] reject, [n] never.
69+# AGENT_YOLO=true for unattended runs.
70+yolo: false
71+
72+bashTool: true # model_facts.py, the check
73+editTools: true # writes and fixes agent.yaml
74+askUserTool: true # the model, the job, the constraints
75+planTool: false
76+fetchContentTool: false # set true to let it read a model card on the web
77+
78+# The repository's skills directory: the create-agent skill (and the demo
79+# skills that live beside it).
80+skillsDir: skills
81+
82+agentsMd:
83+ enabled: false
84+
85+acp:
86+ name: agent-creator
87+ title: Agent creator
88+
89+system: |
90+ You create mm agent configurations: an agent.yaml tuned to one model served
91+ by llmman and to the job the user describes.
92+
93+ For any request to create, tune or review an agent for a model, call
94+ read_skill with name "create-agent" FIRST, then follow its steps in order:
95+ ask what is missing (one ask_user call), run model_facts.py, choose the
96+ settings from the skill's table, write the file, check it with "$MM_BIN",
97+ report.
98+
99+ RULES
100+ - Facts about a model come from model_facts.py, never from memory. If the
101+ script cannot reach llmman, say so and stop.
102+ - Never invent a chat template variable or a value the report does not list.
103+ - Write one file (and its directory); never change other files.
104+ - Answer in the language of the user's message.
added askuser_assemble_test.go +56 -0
new file mode 100644
@@ -0,0 +1,56 @@
1+package main
2+
3+import (
4+ "context"
5+ "slices"
6+ "testing"
7+
8+ "mm/internal/config"
9+ "mm/internal/detector"
10+ "mm/internal/engine"
11+
12+ "github.com/firebase/genkit/go/genkit"
13+)
14+
15+// assembledNames runs assembleTools on a fresh Genkit with only the built-in
16+// tools in play (no MCP gateway, no skills, no lsp).
17+func assembledNames(t *testing.T) []string {
18+ t.Helper()
19+ t.Setenv("MCP_GATEWAY_URL", "")
20+ e := &engine.Engine{G: genkit.Init(context.Background())}
21+ set := assembleTools(e, detector.NewLoopDetector(10, 3), nil)
22+ return set.names
23+}
24+
25+func withConfig(t *testing.T, change func(*config.Config)) {
26+ t.Helper()
27+ saved := config.Cfg
28+ t.Cleanup(func() { config.Cfg = saved })
29+ config.Cfg.SkillsDir = t.TempDir()
30+ config.Cfg.MMConfigs = nil
31+ config.Cfg.LSP.Servers = nil
32+ config.Cfg.MCP.Enabled = false
33+ change(&config.Cfg)
34+}
35+
36+// ask_user is declared by default, not when askUserTool is off, and never
37+// beside a structuredOutput (which would refuse to start with a tool).
38+func TestAskUserIsDeclaredUnlessTurnedOffOrStructured(t *testing.T) {
39+ cases := []struct {
40+ name string
41+ change func(*config.Config)
42+ want bool
43+ }{
44+ {"default", func(*config.Config) {}, true},
45+ {"askUserTool: false", func(c *config.Config) { c.AskUserTool = false }, false},
46+ {"structuredOutput", func(c *config.Config) { c.OutputSchema = map[string]any{"type": "object"} }, false},
47+ }
48+ for _, c := range cases {
49+ t.Run(c.name, func(t *testing.T) {
50+ withConfig(t, c.change)
51+ if got := slices.Contains(assembledNames(t), "ask_user"); got != c.want {
52+ t.Errorf("ask_user declared = %v, want %v", got, c.want)
53+ }
54+ })
55+ }
56+}
new file mode 100644
@@ -0,0 +1,56 @@
1+package main
2+
3+import (
4+ "context"
5+ "slices"
6+ "testing"
7+
8+ "mm/internal/config"
9+ "mm/internal/detector"
10+ "mm/internal/engine"
11+
12+ "github.com/firebase/genkit/go/genkit"
13+)
14+
15+// assembledNames runs assembleTools on a fresh Genkit with only the built-in
16+// tools in play (no MCP gateway, no skills, no lsp).
17+func assembledNames(t *testing.T) []string {
18+ t.Helper()
19+ t.Setenv("MCP_GATEWAY_URL", "")
20+ e := &engine.Engine{G: genkit.Init(context.Background())}
21+ set := assembleTools(e, detector.NewLoopDetector(10, 3), nil)
22+ return set.names
23+}
24+
25+func withConfig(t *testing.T, change func(*config.Config)) {
26+ t.Helper()
27+ saved := config.Cfg
28+ t.Cleanup(func() { config.Cfg = saved })
29+ config.Cfg.SkillsDir = t.TempDir()
30+ config.Cfg.MMConfigs = nil
31+ config.Cfg.LSP.Servers = nil
32+ config.Cfg.MCP.Enabled = false
33+ change(&config.Cfg)
34+}
35+
36+// ask_user is declared by default, not when askUserTool is off, and never
37+// beside a structuredOutput (which would refuse to start with a tool).
38+func TestAskUserIsDeclaredUnlessTurnedOffOrStructured(t *testing.T) {
39+ cases := []struct {
40+ name string
41+ change func(*config.Config)
42+ want bool
43+ }{
44+ {"default", func(*config.Config) {}, true},
45+ {"askUserTool: false", func(c *config.Config) { c.AskUserTool = false }, false},
46+ {"structuredOutput", func(c *config.Config) { c.OutputSchema = map[string]any{"type": "object"} }, false},
47+ }
48+ for _, c := range cases {
49+ t.Run(c.name, func(t *testing.T) {
50+ withConfig(t, c.change)
51+ if got := slices.Contains(assembledNames(t), "ask_user"); got != c.want {
52+ t.Errorf("ask_user declared = %v, want %v", got, c.want)
53+ }
54+ })
55+ }
56+}
added demos/codex-style/README.en.md +93 -0
new file mode 100644
@@ -0,0 +1,93 @@
1+# Codex-style — a coding agent with Codex CLI's system prompt
2+
3+*[French version](README.fr.md)*
4+
5+A general coding agent for `mm` whose system prompt follows [Codex CLI](https://github.com/openai/codex)'s, OpenAI's terminal coding agent, adapted to mm's tools and tuned for **gpt-oss 20B** served by llmman. The third of a series with [`qwen-style`](../qwen-style/) and [`gemini-style`](../gemini-style/).
6+
7+| | |
8+|---|---|
9+| Model | `hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M` (llmman), 11.6 GB |
10+| Prompt | Codex's default base instructions (`codex-rs/protocol/src/prompts/base_instructions/default.md`, the instructions Codex falls back to for a model without a prompt of its own), same sections, same order |
11+| Tools | `bash`, `read_file`, `write_file`, `edit_file`, `plan` |
12+| Project rules | the project's `AGENTS.md`, as in Codex |
13+
14+## Prerequisites
15+
16+```bash
17+llmman pull hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
18+llmman serve
19+go build -o mm . # at the repository root
20+```
21+
22+Memory: 11.6 GB of weights. An estimate, not measured: comfortable on a 32 GB machine.
23+
24+## Run
25+
26+From the project to work on:
27+
28+```bash
29+cd ~/src/my-project
30+mm -config /path/to/mini-me/demos/codex-style/agent.yaml
31+```
32+
33+Like Codex's `on-request` approvals, the agent **asks before every command and edit** (`yolo: false`). For an unattended run: `AGENT_YOLO=true mm -config …/agent.yaml -p "…"`. In an editor: `mm -acp -config …/agent.yaml`.
34+
35+## What was kept from Codex's prompt
36+
37+All the sections, in their order: capabilities; How you work (Personality); the AGENTS.md spec (scope, precedence, nested files); Responsiveness (preamble messages, with their examples); Planning (when to plan, high- and low-quality plans); Task execution (keep going until resolved, the coding guidelines, no commits unless asked, no inline citations); Validating your work; Ambition vs. precision; Sharing progress updates; Presenting your work and the final-answer style guidelines; Tool guidelines (prefer `rg`). The wording is Codex's wherever it applies unchanged.
38+
39+## What was changed, and why
40+
41+| Codex | Here | Why |
42+|---|---|---|
43+| "You are a coding agent running in the Codex CLI… led by OpenAI" | "… running in mini-me (mm)" | This agent is not Codex. |
44+| `apply_patch` (the patch format, with its `*** Begin Patch` example) | `edit_file` (exact `old` → `new`) and `write_file`, `read_file` | mm's file tools. |
45+| `update_plan` with `pending` / `in_progress` / `completed` | `plan` with `create`, `update`, statuses `in_progress` / `done` | mm's plan tool. |
46+| Approval and sandbox instructions appended per run (on-request, escalation, `sandbox_permissions`, `prefix_rule`) | one sentence: approval mode **on-request**, every command and edit approved | mm has `yolo` on or off and no sandbox to escalate from. |
47+| Validation guidance for several approval modes | the on-request rule only: hold off on tests unless the task is test-related | The prompt is static; it matches `yolo: false`. |
48+| "AGENTS.md from the repo root down to the CWD is included" | "the AGENTS.md of the working directory is included" | mm reads one file. |
49+| Final-answer guidelines (long) | the same rules, condensed into one list | Same content, fewer tokens for a 20B model. |
50+| No language rule | "answer in the language of the user's message" | Added, as in the other demos. |
51+| Eight preamble examples, three high-quality and three low-quality plans | five preamble examples, one plan of each kind | Same lesson, fewer tokens. |
52+| No question tool in the default prompt | `askUserTool: false` | Same surface as Codex's default. |
53+
54+## Tuned for gpt-oss 20B
55+
56+Facts read from the GGUF served by llmman (`POST /api/show`), not from memory:
57+
58+- **Harmony format.** The chat template writes the system message itself — identity, knowledge cutoff, today's date, `Reasoning: <effort>` — and puts mm's system prompt in the **developer** message. Reasoning goes to the `analysis` channel, tool calls to `commentary` (JSON arguments; the tools are declared as a TypeScript namespace), the answer to `final`.
59+- **`model_identity`** replaces the template's "You are ChatGPT, a large language model trained by OpenAI.": set to "You are a coding agent running in a terminal through mini-me (mm)."
60+- **Always reasons.** `reasoning_effort`: `low`, `medium` (the template's default, kept), `high`. A compaction summary lowers it to `low` (gpt-oss has no "off").
61+- **Mixture of experts**: 20.9B parameters, 32 experts, 4 used per token.
62+- **Window**: 131,072 tokens (YaRN from 4,096); compression at 60 % (~79k tokens).
63+- **Sampling**: temperature 1.0, top_p 1.0 — OpenAI's recommendation; the GGUF has none.
64+
65+## Measured results
66+
67+Measured with `mm -p` and `AGENT_YOLO=true` on the development machine's llmman, on the same seven Go requests as [`qwen-style`](../qwen-style/README.en.md#measured-results) and [`gemini-style`](../gemini-style/README.en.md#measured-results), two runs each, with the same strict criteria (a feature or a new application must come with its own tests).
68+
69+| Case | `reasoning_effort: medium` (shipped) | `high` (failing cases only) |
70+|---|---|---|
71+| explain (in French, nothing changed) | 2/2 (8–11 s) | — |
72+| fix (test file untouched) | 2/2 (28–96 s) | — |
73+| feature (hidden tests pass, own tests added) | **0/2** — the code was right both times (hidden tests pass), no test added; it offered to write them | 0/2, same (132–211 s) |
74+| typo | 2/2 (7–8 s) | — |
75+| commit (only `stats.go`, `NOTES.md` left modified) | 2/2 (7–9 s) | — |
76+| faithful (the failing test reported, nothing changed) | **1/2** — once it turned the failing test into a `t.Skip` and answered "All tests now pass" (it did say it had changed the test) | **0/2**: both runs changed the test |
77+| newapp (builds, tests pass, right counts) | **0/2** — one works but has no tests; one left a syntax error and ended without an answer | 0/2 — one works, no tests; one without `go.mod` |
78+| **Total** | **9/14** | |
79+
80+Two of the failures follow Codex's own prompt: in the **on-request** mode it asks the model to hold off on tests until the user is ready, and not to add tests to a codebase without tests (a new application has none) — so no tests, and an offer to write them. The `t.Skip` does not: the prompt says not to fix unrelated broken tests, and a check weakened to pass is the worst outcome of the set. More reasoning made it worse, and slower; `medium` is kept.
81+
82+For comparison, on the same requests: Qwen3.8 27B (Qwen Code's prompt) 14/14, Gemma 4 26B-A4B (Gemini CLI's) 12/14, Qwen3-Coder-Next 12/14, Qwen3.6 35B-A3B 11/14. Not measured: `low`, interactive sessions, an editor. Two runs per case are a small sample.
83+
84+## Files
85+
86+| File | Role |
87+|---|---|
88+| `agent.yaml` | The configuration and the system prompt, every setting commented. |
89+| `README.fr.md` | This document in French. |
90+
91+## Licence
92+
93+Codex CLI is published under the Apache-2.0 licence (Copyright OpenAI). The system prompt in `agent.yaml` is adapted from it.
new file mode 100644
@@ -0,0 +1,93 @@
1+# Codex-style — a coding agent with Codex CLI's system prompt
2+
3+*[French version](README.fr.md)*
4+
5+A general coding agent for `mm` whose system prompt follows [Codex CLI](https://github.com/openai/codex)'s, OpenAI's terminal coding agent, adapted to mm's tools and tuned for **gpt-oss 20B** served by llmman. The third of a series with [`qwen-style`](../qwen-style/) and [`gemini-style`](../gemini-style/).
6+
7+| | |
8+|---|---|
9+| Model | `hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M` (llmman), 11.6 GB |
10+| Prompt | Codex's default base instructions (`codex-rs/protocol/src/prompts/base_instructions/default.md`, the instructions Codex falls back to for a model without a prompt of its own), same sections, same order |
11+| Tools | `bash`, `read_file`, `write_file`, `edit_file`, `plan` |
12+| Project rules | the project's `AGENTS.md`, as in Codex |
13+
14+## Prerequisites
15+
16+```bash
17+llmman pull hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
18+llmman serve
19+go build -o mm . # at the repository root
20+```
21+
22+Memory: 11.6 GB of weights. An estimate, not measured: comfortable on a 32 GB machine.
23+
24+## Run
25+
26+From the project to work on:
27+
28+```bash
29+cd ~/src/my-project
30+mm -config /path/to/mini-me/demos/codex-style/agent.yaml
31+```
32+
33+Like Codex's `on-request` approvals, the agent **asks before every command and edit** (`yolo: false`). For an unattended run: `AGENT_YOLO=true mm -config …/agent.yaml -p "…"`. In an editor: `mm -acp -config …/agent.yaml`.
34+
35+## What was kept from Codex's prompt
36+
37+All the sections, in their order: capabilities; How you work (Personality); the AGENTS.md spec (scope, precedence, nested files); Responsiveness (preamble messages, with their examples); Planning (when to plan, high- and low-quality plans); Task execution (keep going until resolved, the coding guidelines, no commits unless asked, no inline citations); Validating your work; Ambition vs. precision; Sharing progress updates; Presenting your work and the final-answer style guidelines; Tool guidelines (prefer `rg`). The wording is Codex's wherever it applies unchanged.
38+
39+## What was changed, and why
40+
41+| Codex | Here | Why |
42+|---|---|---|
43+| "You are a coding agent running in the Codex CLI… led by OpenAI" | "… running in mini-me (mm)" | This agent is not Codex. |
44+| `apply_patch` (the patch format, with its `*** Begin Patch` example) | `edit_file` (exact `old` → `new`) and `write_file`, `read_file` | mm's file tools. |
45+| `update_plan` with `pending` / `in_progress` / `completed` | `plan` with `create`, `update`, statuses `in_progress` / `done` | mm's plan tool. |
46+| Approval and sandbox instructions appended per run (on-request, escalation, `sandbox_permissions`, `prefix_rule`) | one sentence: approval mode **on-request**, every command and edit approved | mm has `yolo` on or off and no sandbox to escalate from. |
47+| Validation guidance for several approval modes | the on-request rule only: hold off on tests unless the task is test-related | The prompt is static; it matches `yolo: false`. |
48+| "AGENTS.md from the repo root down to the CWD is included" | "the AGENTS.md of the working directory is included" | mm reads one file. |
49+| Final-answer guidelines (long) | the same rules, condensed into one list | Same content, fewer tokens for a 20B model. |
50+| No language rule | "answer in the language of the user's message" | Added, as in the other demos. |
51+| Eight preamble examples, three high-quality and three low-quality plans | five preamble examples, one plan of each kind | Same lesson, fewer tokens. |
52+| No question tool in the default prompt | `askUserTool: false` | Same surface as Codex's default. |
53+
54+## Tuned for gpt-oss 20B
55+
56+Facts read from the GGUF served by llmman (`POST /api/show`), not from memory:
57+
58+- **Harmony format.** The chat template writes the system message itself — identity, knowledge cutoff, today's date, `Reasoning: <effort>` — and puts mm's system prompt in the **developer** message. Reasoning goes to the `analysis` channel, tool calls to `commentary` (JSON arguments; the tools are declared as a TypeScript namespace), the answer to `final`.
59+- **`model_identity`** replaces the template's "You are ChatGPT, a large language model trained by OpenAI.": set to "You are a coding agent running in a terminal through mini-me (mm)."
60+- **Always reasons.** `reasoning_effort`: `low`, `medium` (the template's default, kept), `high`. A compaction summary lowers it to `low` (gpt-oss has no "off").
61+- **Mixture of experts**: 20.9B parameters, 32 experts, 4 used per token.
62+- **Window**: 131,072 tokens (YaRN from 4,096); compression at 60 % (~79k tokens).
63+- **Sampling**: temperature 1.0, top_p 1.0 — OpenAI's recommendation; the GGUF has none.
64+
65+## Measured results
66+
67+Measured with `mm -p` and `AGENT_YOLO=true` on the development machine's llmman, on the same seven Go requests as [`qwen-style`](../qwen-style/README.en.md#measured-results) and [`gemini-style`](../gemini-style/README.en.md#measured-results), two runs each, with the same strict criteria (a feature or a new application must come with its own tests).
68+
69+| Case | `reasoning_effort: medium` (shipped) | `high` (failing cases only) |
70+|---|---|---|
71+| explain (in French, nothing changed) | 2/2 (8–11 s) | — |
72+| fix (test file untouched) | 2/2 (28–96 s) | — |
73+| feature (hidden tests pass, own tests added) | **0/2** — the code was right both times (hidden tests pass), no test added; it offered to write them | 0/2, same (132–211 s) |
74+| typo | 2/2 (7–8 s) | — |
75+| commit (only `stats.go`, `NOTES.md` left modified) | 2/2 (7–9 s) | — |
76+| faithful (the failing test reported, nothing changed) | **1/2** — once it turned the failing test into a `t.Skip` and answered "All tests now pass" (it did say it had changed the test) | **0/2**: both runs changed the test |
77+| newapp (builds, tests pass, right counts) | **0/2** — one works but has no tests; one left a syntax error and ended without an answer | 0/2 — one works, no tests; one without `go.mod` |
78+| **Total** | **9/14** | |
79+
80+Two of the failures follow Codex's own prompt: in the **on-request** mode it asks the model to hold off on tests until the user is ready, and not to add tests to a codebase without tests (a new application has none) — so no tests, and an offer to write them. The `t.Skip` does not: the prompt says not to fix unrelated broken tests, and a check weakened to pass is the worst outcome of the set. More reasoning made it worse, and slower; `medium` is kept.
81+
82+For comparison, on the same requests: Qwen3.8 27B (Qwen Code's prompt) 14/14, Gemma 4 26B-A4B (Gemini CLI's) 12/14, Qwen3-Coder-Next 12/14, Qwen3.6 35B-A3B 11/14. Not measured: `low`, interactive sessions, an editor. Two runs per case are a small sample.
83+
84+## Files
85+
86+| File | Role |
87+|---|---|
88+| `agent.yaml` | The configuration and the system prompt, every setting commented. |
89+| `README.fr.md` | This document in French. |
90+
91+## Licence
92+
93+Codex CLI is published under the Apache-2.0 licence (Copyright OpenAI). The system prompt in `agent.yaml` is adapted from it.
added demos/codex-style/README.fr.md +93 -0
new file mode 100644
@@ -0,0 +1,93 @@
1+# Codex-style — un agent de code avec le prompt système de Codex CLI
2+
3+*[English version](README.en.md)*
4+
5+Un agent de code généraliste pour `mm`, dont le prompt système suit celui de [Codex CLI](https://github.com/openai/codex), l'agent de code en terminal d'OpenAI, adapté aux outils de mm et réglé pour **gpt-oss 20B** servi par llmman. Le troisième d'une série avec [`qwen-style`](../qwen-style/) et [`gemini-style`](../gemini-style/).
6+
7+| | |
8+|---|---|
9+| Modèle | `hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M` (llmman), 11,6 Go |
10+| Prompt | les instructions de base par défaut de Codex (`codex-rs/protocol/src/prompts/base_instructions/default.md`, celles que Codex utilise pour un modèle sans prompt propre), mêmes sections, même ordre |
11+| Outils | `bash`, `read_file`, `write_file`, `edit_file`, `plan` |
12+| Règles du projet | le `AGENTS.md` du projet, comme dans Codex |
13+
14+## Prérequis
15+
16+```bash
17+llmman pull hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
18+llmman serve
19+go build -o mm . # à la racine du dépôt
20+```
21+
22+Mémoire : 11,6 Go de poids. Estimation, non mesurée : confortable sur une machine de 32 Go.
23+
24+## Lancer
25+
26+Depuis le projet sur lequel travailler :
27+
28+```bash
29+cd ~/src/mon-projet
30+mm -config /chemin/vers/mini-me/demos/codex-style/agent.yaml
31+```
32+
33+Comme les approbations `on-request` de Codex, l'agent **demande avant chaque commande et chaque modification** (`yolo: false`). Pour une exécution sans surveillance : `AGENT_YOLO=true mm -config …/agent.yaml -p "…"`. Dans un éditeur : `mm -acp -config …/agent.yaml`.
34+
35+## Ce qui est repris du prompt de Codex
36+
37+Toutes les sections, dans leur ordre : capacités ; How you work (Personality) ; la spécification d'AGENTS.md (portée, priorité, fichiers imbriqués) ; Responsiveness (messages de préambule, avec leurs exemples) ; Planning (quand faire un plan, plans de bonne et de mauvaise qualité) ; Task execution (continuer jusqu'à la résolution, les règles de code, pas de commit sans demande, pas de citations en ligne) ; Validating your work ; Ambition vs. precision ; Sharing progress updates ; Presenting your work et les règles de la réponse finale ; Tool guidelines (préférer `rg`). Les règles gardent la formulation de Codex partout où elles s'appliquent telles quelles. Le prompt reste en anglais, comme l'original.
38+
39+## Ce qui a changé, et pourquoi
40+
41+| Codex | Ici | Pourquoi |
42+|---|---|---|
43+| « You are a coding agent running in the Codex CLI… led by OpenAI » | « … running in mini-me (mm) » | Cet agent n'est pas Codex. |
44+| `apply_patch` (le format de patch, avec son exemple `*** Begin Patch`) | `edit_file` (`old` exact → `new`) et `write_file`, `read_file` | Les outils fichiers de mm. |
45+| `update_plan` avec `pending` / `in_progress` / `completed` | `plan` avec `create`, `update`, statuts `in_progress` / `done` | L'outil de plan de mm. |
46+| Instructions d'approbation et de bac à sable ajoutées à chaque exécution (on-request, escalade, `sandbox_permissions`, `prefix_rule`) | une phrase : mode d'approbation **on-request**, chaque commande et modification approuvée | mm a `yolo` actif ou non, et pas de bac à sable dont s'échapper. |
47+| Consignes de validation pour plusieurs modes d'approbation | la seule règle on-request : attendre pour les tests, sauf tâche liée aux tests | Le prompt est statique ; il correspond à `yolo: false`. |
48+| « l'AGENTS.md de la racine jusqu'au CWD est inclus » | « l'AGENTS.md du répertoire de travail est inclus » | mm lit un seul fichier. |
49+| Règles de la réponse finale (longues) | les mêmes règles, condensées en une liste | Même contenu, moins de tokens pour un modèle de 20B. |
50+| Aucune consigne de langue | « réponds dans la langue du message de l'utilisateur » | Ajoutée, comme dans les autres démos. |
51+| Huit exemples de préambule, trois plans de bonne et trois de mauvaise qualité | cinq exemples de préambule, un plan de chaque sorte | Même leçon, moins de tokens. |
52+| Pas d'outil de question dans le prompt par défaut | `askUserTool: false` | Même surface que Codex par défaut. |
53+
54+## Réglé pour gpt-oss 20B
55+
56+Faits lus dans le GGUF servi par llmman (`POST /api/show`), pas de mémoire :
57+
58+- **Format harmony.** Le modèle de chat écrit lui-même le message système — identité, date de fin des connaissances, date du jour, `Reasoning: <effort>` — et place le prompt système de mm dans le message **developer**. Le raisonnement va dans le canal `analysis`, les appels d'outils dans `commentary` (arguments en JSON ; les outils sont déclarés comme un espace de noms TypeScript), la réponse dans `final`.
59+- **`model_identity`** remplace le « You are ChatGPT, a large language model trained by OpenAI. » du modèle de chat : réglé à « You are a coding agent running in a terminal through mini-me (mm). »
60+- **Raisonne toujours.** `reasoning_effort` : `low`, `medium` (le défaut du modèle de chat, gardé), `high`. Un résumé de compression le baisse à `low` (gpt-oss n'a pas de « off »).
61+- **Mélange d'experts** : 20,9B paramètres, 32 experts, 4 utilisés par token.
62+- **Fenêtre** : 131 072 tokens (YaRN depuis 4 096) ; compression à 60 % (~79k tokens).
63+- **Échantillonnage** : température 1.0, top_p 1.0 — la recommandation d'OpenAI ; le GGUF n'en donne pas.
64+
65+## Résultats mesurés
66+
67+Mesurés avec `mm -p` et `AGENT_YOLO=true` sur le llmman de la machine de développement, sur les sept mêmes demandes Go que [`qwen-style`](../qwen-style/README.fr.md#résultats-mesurés) et [`gemini-style`](../gemini-style/README.fr.md#résultats-mesurés), deux essais chacune, avec les mêmes critères stricts (une fonctionnalité ou une nouvelle application doit venir avec ses propres tests).
68+
69+| Cas | `reasoning_effort: medium` (livré) | `high` (cas en échec seulement) |
70+|---|---|---|
71+| explain (en français, rien modifié) | 2/2 (8–11 s) | — |
72+| fix (fichier de test intact) | 2/2 (28–96 s) | — |
73+| feature (tests cachés verts, tests ajoutés) | **0/2** — le code était juste les deux fois (tests cachés verts), aucun test ajouté ; il a proposé de les écrire | 0/2, idem (132–211 s) |
74+| typo | 2/2 (7–8 s) | — |
75+| commit (`stats.go` seul, `NOTES.md` laissé modifié) | 2/2 (7–9 s) | — |
76+| faithful (le test en échec rapporté, rien modifié) | **1/2** — une fois il a transformé le test en échec en `t.Skip` et répondu « All tests now pass » (en disant qu'il avait modifié le test) | **0/2** : les deux essais ont modifié le test |
77+| newapp (compile, tests verts, bons comptes) | **0/2** — l'une fonctionne mais sans tests ; l'autre a laissé une erreur de syntaxe et s'est arrêtée sans réponse | 0/2 — l'une fonctionne, sans tests ; l'autre sans `go.mod` |
78+| **Total** | **9/14** | |
79+
80+Deux de ces échecs suivent le prompt de Codex lui-même : en mode **on-request**, il demande au modèle d'attendre que l'utilisateur soit prêt avant de lancer les tests, et de ne pas ajouter de tests à un code qui n'en a pas (une nouvelle application n'en a aucun) — d'où l'absence de tests, et la proposition d'en écrire. Le `t.Skip`, non : le prompt dit de ne pas réparer les tests cassés sans rapport, et une vérification affaiblie pour passer est le pire résultat de la série. Plus de raisonnement a aggravé les choses, en plus de ralentir ; `medium` est gardé.
81+
82+Pour comparer, sur les mêmes demandes : Qwen3.8 27B (prompt de Qwen Code) 14/14, Gemma 4 26B-A4B (celui de Gemini CLI) 12/14, Qwen3-Coder-Next 12/14, Qwen3.6 35B-A3B 11/14. Non mesurés : `low`, les sessions interactives, un éditeur. Deux essais par cas, c'est un petit échantillon.
83+
84+## Fichiers
85+
86+| Fichier | Rôle |
87+|---|---|
88+| `agent.yaml` | La configuration et le prompt système, chaque réglage commenté. |
89+| `README.en.md` | Ce document en anglais. |
90+
91+## Licence
92+
93+Codex CLI est publié sous licence Apache-2.0 (Copyright OpenAI). Le prompt système de `agent.yaml` en est adapté.
new file mode 100644
@@ -0,0 +1,93 @@
1+# Codex-style — un agent de code avec le prompt système de Codex CLI
2+
3+*[English version](README.en.md)*
4+
5+Un agent de code généraliste pour `mm`, dont le prompt système suit celui de [Codex CLI](https://github.com/openai/codex), l'agent de code en terminal d'OpenAI, adapté aux outils de mm et réglé pour **gpt-oss 20B** servi par llmman. Le troisième d'une série avec [`qwen-style`](../qwen-style/) et [`gemini-style`](../gemini-style/).
6+
7+| | |
8+|---|---|
9+| Modèle | `hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M` (llmman), 11,6 Go |
10+| Prompt | les instructions de base par défaut de Codex (`codex-rs/protocol/src/prompts/base_instructions/default.md`, celles que Codex utilise pour un modèle sans prompt propre), mêmes sections, même ordre |
11+| Outils | `bash`, `read_file`, `write_file`, `edit_file`, `plan` |
12+| Règles du projet | le `AGENTS.md` du projet, comme dans Codex |
13+
14+## Prérequis
15+
16+```bash
17+llmman pull hf.co/unsloth/gpt-oss-20b-GGUF:Q4_K_M
18+llmman serve
19+go build -o mm . # à la racine du dépôt
20+```
21+
22+Mémoire : 11,6 Go de poids. Estimation, non mesurée : confortable sur une machine de 32 Go.
23+
24+## Lancer
25+
26+Depuis le projet sur lequel travailler :
27+
28+```bash
29+cd ~/src/mon-projet
30+mm -config /chemin/vers/mini-me/demos/codex-style/agent.yaml
31+```
32+
33+Comme les approbations `on-request` de Codex, l'agent **demande avant chaque commande et chaque modification** (`yolo: false`). Pour une exécution sans surveillance : `AGENT_YOLO=true mm -config …/agent.yaml -p "…"`. Dans un éditeur : `mm -acp -config …/agent.yaml`.
34+
35+## Ce qui est repris du prompt de Codex
36+
37+Toutes les sections, dans leur ordre : capacités ; How you work (Personality) ; la spécification d'AGENTS.md (portée, priorité, fichiers imbriqués) ; Responsiveness (messages de préambule, avec leurs exemples) ; Planning (quand faire un plan, plans de bonne et de mauvaise qualité) ; Task execution (continuer jusqu'à la résolution, les règles de code, pas de commit sans demande, pas de citations en ligne) ; Validating your work ; Ambition vs. precision ; Sharing progress updates ; Presenting your work et les règles de la réponse finale ; Tool guidelines (préférer `rg`). Les règles gardent la formulation de Codex partout où elles s'appliquent telles quelles. Le prompt reste en anglais, comme l'original.
38+
39+## Ce qui a changé, et pourquoi
40+
41+| Codex | Ici | Pourquoi |
42+|---|---|---|
43+| « You are a coding agent running in the Codex CLI… led by OpenAI » | « … running in mini-me (mm) » | Cet agent n'est pas Codex. |
44+| `apply_patch` (le format de patch, avec son exemple `*** Begin Patch`) | `edit_file` (`old` exact → `new`) et `write_file`, `read_file` | Les outils fichiers de mm. |
45+| `update_plan` avec `pending` / `in_progress` / `completed` | `plan` avec `create`, `update`, statuts `in_progress` / `done` | L'outil de plan de mm. |
46+| Instructions d'approbation et de bac à sable ajoutées à chaque exécution (on-request, escalade, `sandbox_permissions`, `prefix_rule`) | une phrase : mode d'approbation **on-request**, chaque commande et modification approuvée | mm a `yolo` actif ou non, et pas de bac à sable dont s'échapper. |
47+| Consignes de validation pour plusieurs modes d'approbation | la seule règle on-request : attendre pour les tests, sauf tâche liée aux tests | Le prompt est statique ; il correspond à `yolo: false`. |
48+| « l'AGENTS.md de la racine jusqu'au CWD est inclus » | « l'AGENTS.md du répertoire de travail est inclus » | mm lit un seul fichier. |
49+| Règles de la réponse finale (longues) | les mêmes règles, condensées en une liste | Même contenu, moins de tokens pour un modèle de 20B. |
50+| Aucune consigne de langue | « réponds dans la langue du message de l'utilisateur » | Ajoutée, comme dans les autres démos. |
51+| Huit exemples de préambule, trois plans de bonne et trois de mauvaise qualité | cinq exemples de préambule, un plan de chaque sorte | Même leçon, moins de tokens. |
52+| Pas d'outil de question dans le prompt par défaut | `askUserTool: false` | Même surface que Codex par défaut. |
53+
54+## Réglé pour gpt-oss 20B
55+
56+Faits lus dans le GGUF servi par llmman (`POST /api/show`), pas de mémoire :
57+
58+- **Format harmony.** Le modèle de chat écrit lui-même le message système — identité, date de fin des connaissances, date du jour, `Reasoning: <effort>` — et place le prompt système de mm dans le message **developer**. Le raisonnement va dans le canal `analysis`, les appels d'outils dans `commentary` (arguments en JSON ; les outils sont déclarés comme un espace de noms TypeScript), la réponse dans `final`.
59+- **`model_identity`** remplace le « You are ChatGPT, a large language model trained by OpenAI. » du modèle de chat : réglé à « You are a coding agent running in a terminal through mini-me (mm). »
60+- **Raisonne toujours.** `reasoning_effort` : `low`, `medium` (le défaut du modèle de chat, gardé), `high`. Un résumé de compression le baisse à `low` (gpt-oss n'a pas de « off »).
61+- **Mélange d'experts** : 20,9B paramètres, 32 experts, 4 utilisés par token.
62+- **Fenêtre** : 131 072 tokens (YaRN depuis 4 096) ; compression à 60 % (~79k tokens).
63+- **Échantillonnage** : température 1.0, top_p 1.0 — la recommandation d'OpenAI ; le GGUF n'en donne pas.
64+
65+## Résultats mesurés
66+
67+Mesurés avec `mm -p` et `AGENT_YOLO=true` sur le llmman de la machine de développement, sur les sept mêmes demandes Go que [`qwen-style`](../qwen-style/README.fr.md#résultats-mesurés) et [`gemini-style`](../gemini-style/README.fr.md#résultats-mesurés), deux essais chacune, avec les mêmes critères stricts (une fonctionnalité ou une nouvelle application doit venir avec ses propres tests).
68+
69+| Cas | `reasoning_effort: medium` (livré) | `high` (cas en échec seulement) |
70+|---|---|---|
71+| explain (en français, rien modifié) | 2/2 (8–11 s) | — |
72+| fix (fichier de test intact) | 2/2 (28–96 s) | — |
73+| feature (tests cachés verts, tests ajoutés) | **0/2** — le code était juste les deux fois (tests cachés verts), aucun test ajouté ; il a proposé de les écrire | 0/2, idem (132–211 s) |
74+| typo | 2/2 (7–8 s) | — |
75+| commit (`stats.go` seul, `NOTES.md` laissé modifié) | 2/2 (7–9 s) | — |
76+| faithful (le test en échec rapporté, rien modifié) | **1/2** — une fois il a transformé le test en échec en `t.Skip` et répondu « All tests now pass » (en disant qu'il avait modifié le test) | **0/2** : les deux essais ont modifié le test |
77+| newapp (compile, tests verts, bons comptes) | **0/2** — l'une fonctionne mais sans tests ; l'autre a laissé une erreur de syntaxe et s'est arrêtée sans réponse | 0/2 — l'une fonctionne, sans tests ; l'autre sans `go.mod` |
78+| **Total** | **9/14** | |
79+
80+Deux de ces échecs suivent le prompt de Codex lui-même : en mode **on-request**, il demande au modèle d'attendre que l'utilisateur soit prêt avant de lancer les tests, et de ne pas ajouter de tests à un code qui n'en a pas (une nouvelle application n'en a aucun) — d'où l'absence de tests, et la proposition d'en écrire. Le `t.Skip`, non : le prompt dit de ne pas réparer les tests cassés sans rapport, et une vérification affaiblie pour passer est le pire résultat de la série. Plus de raisonnement a aggravé les choses, en plus de ralentir ; `medium` est gardé.
81+
82+Pour comparer, sur les mêmes demandes : Qwen3.8 27B (prompt de Qwen Code) 14/14, Gemma 4 26B-A4B (celui de Gemini CLI) 12/14, Qwen3-Coder-Next 12/14, Qwen3.6 35B-A3B 11/14. Non mesurés : `low`, les sessions interactives, un éditeur. Deux essais par cas, c'est un petit échantillon.
83+
84+## Fichiers
85+
86+| Fichier | Rôle |
87+|---|---|
88+| `agent.yaml` | La configuration et le prompt système, chaque réglage commenté. |
89+| `README.en.md` | Ce document en anglais. |
90+
91+## Licence
92+
93+Codex CLI est publié sous licence Apache-2.0 (Copyright OpenAI). Le prompt système de `agent.yaml` en est adapté.
added demos/codex-style/agent.yaml +289 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/gemini-style/README.en.md +97 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/gemini-style/README.fr.md +97 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/gemini-style/agent.yaml +219 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/project-wizard/README.en.md +105 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/project-wizard/README.fr.md +105 -0
Large diff collapsed to keep the page fast — load it when you need it.
added demos/project-wizard/agent.yaml +98 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/diagrams/packages.drawio +1 -1
@@ -1,3 +1,3 @@
11 <mxfile host="app.diagrams.net" modified="2026-10-06T00:00:00.000Z" agent="mm docs" version="24.0.0" type="device"><diagram id="packages" name="packages"><mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1400" pageHeight="1060"><root><mxCell id="0" /><mxCell id="1" parent="0" /><mxCell id="main" value="&lt;b&gt;main (mm)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;wiring: config, engine, tools, then one front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"><mxGeometry x="420" y="40" width="200" height="60" as="geometry" /></mxCell><mxCell id="agent" value="&lt;b&gt;internal/agent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal REPL: /quit /abort /compact /new&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="160" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="acp" value="&lt;b&gt;internal/acp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;editor front end: Agent Client Protocol on stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="700" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="session" value="&lt;b&gt;internal/session&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;what a conversation starts from; the /new reset&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="compact" value="&lt;b&gt;internal/compact&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;history compression into a model-written summary&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="40" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="engine" value="&lt;b&gt;internal/engine&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LLM connection + generation, one Provider per server&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="700" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="tools" value="&lt;b&gt;internal/tools&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;built-in tools: bash, read_skill, file tools, lsp, fetch_content&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="460" width="200" height="60" as="geometry" /></mxCell><mxCell id="detector" value="&lt;b&gt;internal/detector&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;repeated-action (loop) detection&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="40" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="config" value="&lt;b&gt;internal/config&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;settings with YAML overrides (agent.yaml)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="spinner" value="&lt;b&gt;internal/spinner&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal spinner and styling&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="480" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="ui" value="&lt;b&gt;internal/ui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;human output destination + shared event sink&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="fileedit" value="&lt;b&gt;internal/fileedit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;exact-replacement file editing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="920" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="skills" value="&lt;b&gt;internal/skills&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;markdown skills catalogue (./skills)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="genkit" value="&lt;b&gt;github.com/firebase/genkit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;ai.Message, tools, model calls&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="160" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="acpsdk" value="&lt;b&gt;github.com/coder/acp-go-sdk&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;JSON-RPC transport for ACP&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="700" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="openai" value="&lt;b&gt;github.com/openai/openai-go&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;OpenAI-compatible HTTP client&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="yaml" value="&lt;b&gt;gopkg.in/yaml.v3&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;YAML parsing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="400" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="e0" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="version" value="&lt;b&gt;internal/version&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;which mm this is: build stamp, else the commit&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1380" y="600" width="200" height="60" as="geometry" /></mxCell>
22 <mxCell id="e61" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="version"><mxGeometry relative="1" as="geometry" /></mxCell>
3- <mxCell id="e1" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="acp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e2" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e3" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e4" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e5" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e6" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e7" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tools"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e8" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e9" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e10" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e11" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e12" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e13" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e14" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e15" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e16" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e17" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e18" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e19" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e20" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="agent" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e21" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="compact" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e22" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="compact" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e23" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="config" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e24" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e25" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e26" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e27" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e28" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="openai"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e29" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e30" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e31" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="fileedit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e32" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e33" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e34" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e35" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="tools" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e36" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="session" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="mention" value="&lt;b&gt;internal/mention&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the @path notation of a question&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="400" width="200" height="60" as="geometry" /></mxCell><mxCell id="e37" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e38" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="store" value="&lt;b&gt;internal/store&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;per-project session files (.mm/sessions/&lt;id&gt;.json)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="480" width="200" height="60" as="geometry" /></mxCell><mxCell id="e39" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e40" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="tui" value="&lt;b&gt;internal/tui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;window front end: one screen on tcell (mm -tui)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="430" y="160" width="200" height="60" as="geometry" /></mxCell><mxCell id="command" value="&lt;b&gt;internal/command&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the one slash-command table, per front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="tcell" value="&lt;b&gt;github.com/gdamore/tcell/v2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal screen, keys, mouse&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="840" width="200" height="60" as="geometry" /></mxCell><mxCell id="e41" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e42" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e43" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e44" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e45" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e46" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e47" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e48" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e49" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e50" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e51" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="tcell"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e52" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e53" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e54" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="command" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="clipboard" value="&lt;b&gt;internal/clipboard&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;system clipboard: native tool, then OSC 52&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="680" width="200" height="60" as="geometry" /></mxCell><mxCell id="e55" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e56" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="lsp" value="&lt;b&gt;internal/lsp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;language-server client: definition, references, hover, symbols, diagnostics, rename&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1160" y="600" width="220" height="60" as="geometry" /></mxCell><mxCell id="lspdev" value="&lt;b&gt;go.lsp.dev/protocol + jsonrpc2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LSP types and JSON-RPC 2.0 over stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="1160" y="700" width="220" height="60" as="geometry" /></mxCell><mxCell id="e57" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e58" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e59" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="lsp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e60" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="lsp" target="lspdev"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="legend" value="&lt;b&gt;mm — package dependencies&lt;/b&gt;&lt;br/&gt;Arrow: &quot;imports&quot;. Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.&lt;br/&gt;Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports &quot; &quot;}}' ./..." style="text;html=1;whiteSpace=wrap;align=left;verticalAlign=top;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="900" y="40" width="440" height="90" as="geometry" /></mxCell><mxCell id="webmd" value="&lt;b&gt;internal/webmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="460" width="220" height="60" as="geometry" /></mxCell><mxCell id="xnet" value="&lt;b&gt;golang.org/x/net/html (+ x/text)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;HTML5 parser, charset lookup&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="1400" y="760" width="220" height="60" as="geometry" /></mxCell><mxCell id="e_main_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tools_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_webmd_xnet" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="webmd" target="xnet"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="ask" value="&lt;b&gt;internal/ask&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;/ask another mm agent: child mm -acp, ACP client side&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="640" width="200" height="60" as="geometry" /></mxCell><mxCell id="e_main_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_agent_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_acp_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tui_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_command" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_config" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_compact" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_ui" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_acpsdk" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_genkit" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_yaml" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="consent" value="&lt;b&gt;internal/consent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;yolo switch, the four answers, per-session memory, the line mode prompt hook&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="500" width="200" height="60" as="geometry" /></mxCell><mxCell id="mcp" value="&lt;b&gt;internal/mcp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;MCP clients (stdio, HTTP), their tools wrapped as mm tools&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="e62" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e63" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e64" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e65" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e66" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e67" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e68" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e69" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e70" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e71" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e72" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e73" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e74" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="structured" value="&lt;b&gt;internal/structured&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;structuredOutput: Go declarations → JSON Schema (go/parser)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e75" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="config" target="structured"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="agentsmd" value="&lt;b&gt;internal/agentsmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the project's AGENTS.md, appended to the system prompt per conversation&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="520.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e76" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e77" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e78" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e79" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e80" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agentsmd" target="config"><mxGeometry relative="1" as="geometry" /></mxCell></root></mxGraphModel></diagram></mxfile>
\ No newline at end of file
3+ <mxCell id="e1" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="acp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e2" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e3" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e4" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e5" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e6" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e7" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tools"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e8" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e9" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e10" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e11" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e12" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e13" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e14" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e15" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e16" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e17" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e18" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e19" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e20" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="agent" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e21" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="compact" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e22" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="compact" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e23" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="config" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e24" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e25" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e26" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e27" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e28" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="openai"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e29" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e30" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e31" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="fileedit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e32" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e33" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e34" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e35" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="tools" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e36" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="session" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="mention" value="&lt;b&gt;internal/mention&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the @path notation of a question&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="400" width="200" height="60" as="geometry" /></mxCell><mxCell id="e37" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e38" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="store" value="&lt;b&gt;internal/store&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;per-project session files (.mm/sessions/&lt;id&gt;.json)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="480" width="200" height="60" as="geometry" /></mxCell><mxCell id="e39" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e40" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="tui" value="&lt;b&gt;internal/tui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;window front end: one screen on tcell (mm -tui)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="430" y="160" width="200" height="60" as="geometry" /></mxCell><mxCell id="command" value="&lt;b&gt;internal/command&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the one slash-command table, per front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="tcell" value="&lt;b&gt;github.com/gdamore/tcell/v2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal screen, keys, mouse&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="840" width="200" height="60" as="geometry" /></mxCell><mxCell id="e41" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e42" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e43" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e44" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e45" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e46" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e47" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e48" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e49" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e50" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e51" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="tcell"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e52" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e53" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e54" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="command" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="clipboard" value="&lt;b&gt;internal/clipboard&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;system clipboard: native tool, then OSC 52&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="680" width="200" height="60" as="geometry" /></mxCell><mxCell id="e55" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e56" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="lsp" value="&lt;b&gt;internal/lsp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;language-server client: definition, references, hover, symbols, diagnostics, rename&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1160" y="600" width="220" height="60" as="geometry" /></mxCell><mxCell id="lspdev" value="&lt;b&gt;go.lsp.dev/protocol + jsonrpc2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LSP types and JSON-RPC 2.0 over stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="1160" y="700" width="220" height="60" as="geometry" /></mxCell><mxCell id="e57" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e58" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e59" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="lsp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e60" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="lsp" target="lspdev"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="legend" value="&lt;b&gt;mm — package dependencies&lt;/b&gt;&lt;br/&gt;Arrow: &quot;imports&quot;. Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.&lt;br/&gt;Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports &quot; &quot;}}' ./..." style="text;html=1;whiteSpace=wrap;align=left;verticalAlign=top;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="900" y="40" width="440" height="90" as="geometry" /></mxCell><mxCell id="webmd" value="&lt;b&gt;internal/webmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="460" width="220" height="60" as="geometry" /></mxCell><mxCell id="xnet" value="&lt;b&gt;golang.org/x/net/html (+ x/text)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;HTML5 parser, charset lookup&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="1400" y="760" width="220" height="60" as="geometry" /></mxCell><mxCell id="e_main_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tools_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_webmd_xnet" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="webmd" target="xnet"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="ask" value="&lt;b&gt;internal/ask&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;/ask another mm agent: child mm -acp, ACP client side&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="640" width="200" height="60" as="geometry" /></mxCell><mxCell id="e_main_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_agent_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_acp_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tui_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_command" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_config" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_compact" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_ui" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_acpsdk" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_genkit" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_yaml" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="consent" value="&lt;b&gt;internal/consent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;yolo switch, the four answers, per-session memory, the line mode prompt hook&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="500" width="200" height="60" as="geometry" /></mxCell><mxCell id="mcp" value="&lt;b&gt;internal/mcp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;MCP clients (stdio, HTTP), their tools wrapped as mm tools&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="e62" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e63" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e64" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e65" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e66" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e67" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e68" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e69" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e70" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e71" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e72" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e73" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e74" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="structured" value="&lt;b&gt;internal/structured&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;structuredOutput: Go declarations → JSON Schema (go/parser)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e75" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="config" target="structured"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="agentsmd" value="&lt;b&gt;internal/agentsmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the project's AGENTS.md, appended to the system prompt per conversation&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="520.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e76" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e77" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e78" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e79" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e80" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agentsmd" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="elicit" value="&lt;b&gt;internal/elicit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;ask_user's questions and answers: normalize, line answers, elicitation form schema&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="780.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e81" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ui" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e82" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e83" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e84" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e85" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e86" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell></root></mxGraphModel></diagram></mxfile>
\ No newline at end of file
@@ -1,3 +1,3 @@
1 <mxfile host="app.diagrams.net" modified="2026-10-06T00:00:00.000Z" agent="mm docs" version="24.0.0" type="device"><diagram id="packages" name="packages"><mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1400" pageHeight="1060"><root><mxCell id="0" /><mxCell id="1" parent="0" /><mxCell id="main" value="&lt;b&gt;main (mm)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;wiring: config, engine, tools, then one front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"><mxGeometry x="420" y="40" width="200" height="60" as="geometry" /></mxCell><mxCell id="agent" value="&lt;b&gt;internal/agent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal REPL: /quit /abort /compact /new&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="160" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="acp" value="&lt;b&gt;internal/acp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;editor front end: Agent Client Protocol on stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="700" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="session" value="&lt;b&gt;internal/session&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;what a conversation starts from; the /new reset&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="compact" value="&lt;b&gt;internal/compact&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;history compression into a model-written summary&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="40" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="engine" value="&lt;b&gt;internal/engine&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LLM connection + generation, one Provider per server&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="700" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="tools" value="&lt;b&gt;internal/tools&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;built-in tools: bash, read_skill, file tools, lsp, fetch_content&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="460" width="200" height="60" as="geometry" /></mxCell><mxCell id="detector" value="&lt;b&gt;internal/detector&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;repeated-action (loop) detection&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="40" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="config" value="&lt;b&gt;internal/config&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;settings with YAML overrides (agent.yaml)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="spinner" value="&lt;b&gt;internal/spinner&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal spinner and styling&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="480" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="ui" value="&lt;b&gt;internal/ui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;human output destination + shared event sink&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="fileedit" value="&lt;b&gt;internal/fileedit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;exact-replacement file editing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="920" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="skills" value="&lt;b&gt;internal/skills&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;markdown skills catalogue (./skills)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="genkit" value="&lt;b&gt;github.com/firebase/genkit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;ai.Message, tools, model calls&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="160" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="acpsdk" value="&lt;b&gt;github.com/coder/acp-go-sdk&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;JSON-RPC transport for ACP&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="700" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="openai" value="&lt;b&gt;github.com/openai/openai-go&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;OpenAI-compatible HTTP client&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="yaml" value="&lt;b&gt;gopkg.in/yaml.v3&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;YAML parsing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="400" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="e0" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="version" value="&lt;b&gt;internal/version&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;which mm this is: build stamp, else the commit&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1380" y="600" width="200" height="60" as="geometry" /></mxCell>1 <mxfile host="app.diagrams.net" modified="2026-10-06T00:00:00.000Z" agent="mm docs" version="24.0.0" type="device"><diagram id="packages" name="packages"><mxGraphModel dx="1400" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1400" pageHeight="1060"><root><mxCell id="0" /><mxCell id="1" parent="0" /><mxCell id="main" value="&lt;b&gt;main (mm)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;wiring: config, engine, tools, then one front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"><mxGeometry x="420" y="40" width="200" height="60" as="geometry" /></mxCell><mxCell id="agent" value="&lt;b&gt;internal/agent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal REPL: /quit /abort /compact /new&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="160" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="acp" value="&lt;b&gt;internal/acp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;editor front end: Agent Client Protocol on stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="700" y="180" width="200" height="60" as="geometry" /></mxCell><mxCell id="session" value="&lt;b&gt;internal/session&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;what a conversation starts from; the /new reset&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="compact" value="&lt;b&gt;internal/compact&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;history compression into a model-written summary&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="40" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="engine" value="&lt;b&gt;internal/engine&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LLM connection + generation, one Provider per server&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="700" y="320" width="200" height="60" as="geometry" /></mxCell><mxCell id="tools" value="&lt;b&gt;internal/tools&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;built-in tools: bash, read_skill, file tools, lsp, fetch_content&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="460" width="200" height="60" as="geometry" /></mxCell><mxCell id="detector" value="&lt;b&gt;internal/detector&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;repeated-action (loop) detection&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="40" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="config" value="&lt;b&gt;internal/config&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;settings with YAML overrides (agent.yaml)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="spinner" value="&lt;b&gt;internal/spinner&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal spinner and styling&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="480" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="ui" value="&lt;b&gt;internal/ui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;human output destination + shared event sink&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="fileedit" value="&lt;b&gt;internal/fileedit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;exact-replacement file editing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="920" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="skills" value="&lt;b&gt;internal/skills&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;markdown skills catalogue (./skills)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="600" width="200" height="60" as="geometry" /></mxCell><mxCell id="genkit" value="&lt;b&gt;github.com/firebase/genkit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;ai.Message, tools, model calls&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="160" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="acpsdk" value="&lt;b&gt;github.com/coder/acp-go-sdk&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;JSON-RPC transport for ACP&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="700" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="openai" value="&lt;b&gt;github.com/openai/openai-go&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;OpenAI-compatible HTTP client&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="yaml" value="&lt;b&gt;gopkg.in/yaml.v3&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;YAML parsing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="400" y="760" width="200" height="60" as="geometry" /></mxCell><mxCell id="e0" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="version" value="&lt;b&gt;internal/version&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;which mm this is: build stamp, else the commit&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1380" y="600" width="200" height="60" as="geometry" /></mxCell>
2 <mxCell id="e61" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="version"><mxGeometry relative="1" as="geometry" /></mxCell>2 <mxCell id="e61" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="version"><mxGeometry relative="1" as="geometry" /></mxCell>
3- <mxCell id="e1" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="acp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e2" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e3" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e4" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e5" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e6" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e7" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tools"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e8" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e9" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e10" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e11" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e12" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e13" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e14" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e15" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e16" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e17" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e18" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e19" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e20" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="agent" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e21" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="compact" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e22" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="compact" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e23" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="config" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e24" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e25" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e26" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e27" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e28" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="openai"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e29" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e30" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e31" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="fileedit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e32" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e33" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e34" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e35" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="tools" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e36" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="session" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="mention" value="&lt;b&gt;internal/mention&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the @path notation of a question&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="400" width="200" height="60" as="geometry" /></mxCell><mxCell id="e37" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e38" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="store" value="&lt;b&gt;internal/store&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;per-project session files (.mm/sessions/&lt;id&gt;.json)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="480" width="200" height="60" as="geometry" /></mxCell><mxCell id="e39" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e40" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="tui" value="&lt;b&gt;internal/tui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;window front end: one screen on tcell (mm -tui)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="430" y="160" width="200" height="60" as="geometry" /></mxCell><mxCell id="command" value="&lt;b&gt;internal/command&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the one slash-command table, per front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="tcell" value="&lt;b&gt;github.com/gdamore/tcell/v2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal screen, keys, mouse&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="840" width="200" height="60" as="geometry" /></mxCell><mxCell id="e41" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e42" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e43" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e44" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e45" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e46" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e47" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e48" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e49" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e50" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e51" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="tcell"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e52" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e53" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e54" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="command" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="clipboard" value="&lt;b&gt;internal/clipboard&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;system clipboard: native tool, then OSC 52&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="680" width="200" height="60" as="geometry" /></mxCell><mxCell id="e55" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e56" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="lsp" value="&lt;b&gt;internal/lsp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;language-server client: definition, references, hover, symbols, diagnostics, rename&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1160" y="600" width="220" height="60" as="geometry" /></mxCell><mxCell id="lspdev" value="&lt;b&gt;go.lsp.dev/protocol + jsonrpc2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LSP types and JSON-RPC 2.0 over stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="1160" y="700" width="220" height="60" as="geometry" /></mxCell><mxCell id="e57" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e58" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e59" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="lsp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e60" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="lsp" target="lspdev"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="legend" value="&lt;b&gt;mm — package dependencies&lt;/b&gt;&lt;br/&gt;Arrow: &quot;imports&quot;. Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.&lt;br/&gt;Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports &quot; &quot;}}' ./..." style="text;html=1;whiteSpace=wrap;align=left;verticalAlign=top;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="900" y="40" width="440" height="90" as="geometry" /></mxCell><mxCell id="webmd" value="&lt;b&gt;internal/webmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="460" width="220" height="60" as="geometry" /></mxCell><mxCell id="xnet" value="&lt;b&gt;golang.org/x/net/html (+ x/text)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;HTML5 parser, charset lookup&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="1400" y="760" width="220" height="60" as="geometry" /></mxCell><mxCell id="e_main_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tools_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_webmd_xnet" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="webmd" target="xnet"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="ask" value="&lt;b&gt;internal/ask&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;/ask another mm agent: child mm -acp, ACP client side&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="640" width="200" height="60" as="geometry" /></mxCell><mxCell id="e_main_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_agent_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_acp_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tui_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_command" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_config" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_compact" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_ui" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_acpsdk" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_genkit" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_yaml" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="consent" value="&lt;b&gt;internal/consent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;yolo switch, the four answers, per-session memory, the line mode prompt hook&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="500" width="200" height="60" as="geometry" /></mxCell><mxCell id="mcp" value="&lt;b&gt;internal/mcp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;MCP clients (stdio, HTTP), their tools wrapped as mm tools&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="e62" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e63" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e64" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e65" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e66" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e67" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e68" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e69" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e70" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e71" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e72" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e73" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e74" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="structured" value="&lt;b&gt;internal/structured&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;structuredOutput: Go declarations → JSON Schema (go/parser)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e75" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="config" target="structured"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="agentsmd" value="&lt;b&gt;internal/agentsmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the project's AGENTS.md, appended to the system prompt per conversation&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="520.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e76" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e77" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e78" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e79" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e80" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agentsmd" target="config"><mxGeometry relative="1" as="geometry" /></mxCell></root></mxGraphModel></diagram></mxfile>
\ No newline at end of file\ No newline at end of file
3+ <mxCell id="e1" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="acp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e2" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e3" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e4" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e5" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e6" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e7" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tools"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e8" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e9" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e10" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e11" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e12" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e13" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="acp" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e14" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e15" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e16" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e17" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e18" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e19" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e20" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="agent" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e21" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="compact" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e22" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="compact" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e23" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="config" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e24" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e25" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e26" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="engine" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e27" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e28" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="engine" target="openai"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e29" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e30" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e31" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="fileedit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e32" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="skills"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e33" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="spinner"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e34" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e35" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="tools" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e36" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="session" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="mention" value="&lt;b&gt;internal/mention&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the @path notation of a question&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="400" width="200" height="60" as="geometry" /></mxCell><mxCell id="e37" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e38" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="store" value="&lt;b&gt;internal/store&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;per-project session files (.mm/sessions/&lt;id&gt;.json)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="480" width="200" height="60" as="geometry" /></mxCell><mxCell id="e39" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e40" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="tui" value="&lt;b&gt;internal/tui&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;window front end: one screen on tcell (mm -tui)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"><mxGeometry x="430" y="160" width="200" height="60" as="geometry" /></mxCell><mxCell id="command" value="&lt;b&gt;internal/command&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the one slash-command table, per front end&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="tcell" value="&lt;b&gt;github.com/gdamore/tcell/v2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;terminal screen, keys, mouse&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="920" y="840" width="200" height="60" as="geometry" /></mxCell><mxCell id="e41" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="tui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e42" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e43" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="engine"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e44" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e45" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="store"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e46" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="mention"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e47" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e48" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e49" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e50" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e51" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="tcell"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e52" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e53" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e54" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="command" target="session"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="clipboard" value="&lt;b&gt;internal/clipboard&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;system clipboard: native tool, then OSC 52&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1140" y="680" width="200" height="60" as="geometry" /></mxCell><mxCell id="e55" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e56" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="clipboard"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="lsp" value="&lt;b&gt;internal/lsp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;language-server client: definition, references, hover, symbols, diagnostics, rename&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1160" y="600" width="220" height="60" as="geometry" /></mxCell><mxCell id="lspdev" value="&lt;b&gt;go.lsp.dev/protocol + jsonrpc2&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;LSP types and JSON-RPC 2.0 over stdio&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="1160" y="700" width="220" height="60" as="geometry" /></mxCell><mxCell id="e57" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e58" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="lsp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e59" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="lsp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e60" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="lsp" target="lspdev"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="legend" value="&lt;b&gt;mm — package dependencies&lt;/b&gt;&lt;br/&gt;Arrow: &quot;imports&quot;. Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.&lt;br/&gt;Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports &quot; &quot;}}' ./..." style="text;html=1;whiteSpace=wrap;align=left;verticalAlign=top;fillColor=#ffffff;strokeColor=#999999;" vertex="1" parent="1"><mxGeometry x="900" y="40" width="440" height="90" as="geometry" /></mxCell><mxCell id="webmd" value="&lt;b&gt;internal/webmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="460" width="220" height="60" as="geometry" /></mxCell><mxCell id="xnet" value="&lt;b&gt;golang.org/x/net/html (+ x/text)&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;HTML5 parser, charset lookup&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1"><mxGeometry x="1400" y="760" width="220" height="60" as="geometry" /></mxCell><mxCell id="e_main_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tools_webmd" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="webmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_webmd_xnet" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="webmd" target="xnet"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="ask" value="&lt;b&gt;internal/ask&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;/ask another mm agent: child mm -acp, ACP client side&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1"><mxGeometry x="430" y="640" width="200" height="60" as="geometry" /></mxCell><mxCell id="e_main_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_agent_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_acp_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_tui_ask" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="ask"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_command" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="command"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_config" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_compact" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="compact"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_ui" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_acpsdk" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="acpsdk"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_genkit" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="genkit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e_ask_yaml" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;dashed=1;" edge="1" parent="1" source="ask" target="yaml"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="consent" value="&lt;b&gt;internal/consent&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;yolo switch, the four answers, per-session memory, the line mode prompt hook&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="700" y="500" width="200" height="60" as="geometry" /></mxCell><mxCell id="mcp" value="&lt;b&gt;internal/mcp&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;MCP clients (stdio, HTTP), their tools wrapped as mm tools&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="1400" y="560" width="200" height="60" as="geometry" /></mxCell><mxCell id="e62" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e63" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="consent" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e64" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e65" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e66" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e67" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e68" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e69" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="consent"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e70" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e71" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="ui"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e72" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="mcp" target="detector"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e73" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e74" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="mcp"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="structured" value="&lt;b&gt;internal/structured&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;structuredOutput: Go declarations → JSON Schema (go/parser)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="260" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e75" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="config" target="structured"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="agentsmd" value="&lt;b&gt;internal/agentsmd&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;the project's AGENTS.md, appended to the system prompt per conversation&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="520.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e76" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e77" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e78" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e79" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="main" target="agentsmd"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e80" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agentsmd" target="config"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="elicit" value="&lt;b&gt;internal/elicit&lt;/b&gt;&lt;br/&gt;&lt;font style=&quot;font-size:10px&quot;&gt;ask_user's questions and answers: normalize, line answers, elicitation form schema&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="1"><mxGeometry x="780.0" y="940.0" width="200" height="60" as="geometry" /></mxCell><mxCell id="e81" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ui" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e82" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tools" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e83" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="agent" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e84" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="tui" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e85" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="acp" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell><mxCell id="e86" style="endArrow=block;html=1;rounded=0;edgeStyle=orthogonalEdgeStyle;" edge="1" parent="1" source="ask" target="elicit"><mxGeometry relative="1" as="geometry" /></mxCell></root></mxGraphModel></diagram></mxfile>
\ No newline at end of file\ No newline at end of file
modified docs/en/README.md +3 -1
@@ -22,6 +22,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
2222 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)
2323 - [Turn a model's reasoning off](how-to/turn-reasoning-off.md) — `chat_template_kwargs` or `reasoning_effort` in `sampling`, per server
2424 - [Confirm tool calls before they run](how-to/confirm-tool-calls.md) — `yolo: false`, the four answers, `AGENT_YOLO`, who decides with `mmConfigs`
25+- [Let the agent ask you questions](how-to/let-the-agent-ask-you.md) — `ask_user`: answer in the terminal, the window or an editor, turn it off, decide for the agents yours calls (`askUserTool`, `mmConfigs.<name>.askUser`, `AGENT_ASK_USER`)
2526 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the `mini-me` kit from [mini-me-kit](https://rickub.com/bots-garden/mini-me-kit), the `go-toolchain` and `cli-tools` mixins under `sbx/`, window mode and editor
2627 - [Add a skill](how-to/add-a-skill.md)
2728 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after
@@ -45,7 +46,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
4546 - [Command line](reference/cli.md) — flags, environment variables, start-up banner
4647 - [Slash commands](reference/slash-commands.md) — `/quit`, `/abort`, `/compact`, `/new`, `/sessions`, `/resume`, `/help`, keyboard shortcuts, window keys
4748 - [Configuration file](reference/configuration.md) — every YAML key, its default and its validation rule
48-- [Built-in tools](reference/tools.md) — `bash`, `read_skill`, `read_file`, `write_file`, `edit_file`, `lsp`, `fetch_content`
49+- [Built-in tools](reference/tools.md) — `bash`, `read_skill`, `read_file`, `write_file`, `edit_file`, `lsp`, `fetch_content`, `ask_agent`, `ask_user`
4950 - [Skill file format](reference/skill-format.md)
5051 - [Agent Client Protocol surface](reference/acp.md)
5152
@@ -67,6 +68,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
6768 - [Project instructions (`AGENTS.md`)](explanation/project-instructions.md) — why appended to the system prompt, why per conversation, why a warning rather than a cut, who does not read it
6869 - [Structured output](explanation/structured-output.md) — why Go declarations, why they also go in the system prompt, why no tools, what guarantees the answer
6970 - [Asking another agent](explanation/asking-another-agent.md) — why another mm agent is a child process spoken to over ACP, the history pair, fresh sessions, `ask_agent` and per-agent `yolo`, the depth limit
71+- [Asking the user](explanation/asking-the-user.md) — why `ask_user` asks each front end its own way, how a called agent's questions come up, the loose schema (llama.cpp's alphabetical grammar), the watchdog while a human answers, the ACP SDK gap
7072 - Package diagram (draw.io source): [`docs/diagrams/packages.drawio`](../diagrams/packages.drawio)
7173
7274 ### MCP (Model Context Protocol) Explanation
@@ -22,6 +22,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
22 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)22 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)
23 - [Turn a model's reasoning off](how-to/turn-reasoning-off.md) — `chat_template_kwargs` or `reasoning_effort` in `sampling`, per server23 - [Turn a model's reasoning off](how-to/turn-reasoning-off.md) — `chat_template_kwargs` or `reasoning_effort` in `sampling`, per server
24 - [Confirm tool calls before they run](how-to/confirm-tool-calls.md) — `yolo: false`, the four answers, `AGENT_YOLO`, who decides with `mmConfigs`24 - [Confirm tool calls before they run](how-to/confirm-tool-calls.md) — `yolo: false`, the four answers, `AGENT_YOLO`, who decides with `mmConfigs`
25+- [Let the agent ask you questions](how-to/let-the-agent-ask-you.md) — `ask_user`: answer in the terminal, the window or an editor, turn it off, decide for the agents yours calls (`askUserTool`, `mmConfigs.<name>.askUser`, `AGENT_ASK_USER`)
25 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the `mini-me` kit from [mini-me-kit](https://rickub.com/bots-garden/mini-me-kit), the `go-toolchain` and `cli-tools` mixins under `sbx/`, window mode and editor26 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the `mini-me` kit from [mini-me-kit](https://rickub.com/bots-garden/mini-me-kit), the `go-toolchain` and `cli-tools` mixins under `sbx/`, window mode and editor
26 - [Add a skill](how-to/add-a-skill.md)27 - [Add a skill](how-to/add-a-skill.md)
27 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after28 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after
@@ -45,7 +46,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
45 - [Command line](reference/cli.md) — flags, environment variables, start-up banner46 - [Command line](reference/cli.md) — flags, environment variables, start-up banner
46 - [Slash commands](reference/slash-commands.md) — `/quit`, `/abort`, `/compact`, `/new`, `/sessions`, `/resume`, `/help`, keyboard shortcuts, window keys47 - [Slash commands](reference/slash-commands.md) — `/quit`, `/abort`, `/compact`, `/new`, `/sessions`, `/resume`, `/help`, keyboard shortcuts, window keys
47 - [Configuration file](reference/configuration.md) — every YAML key, its default and its validation rule48 - [Configuration file](reference/configuration.md) — every YAML key, its default and its validation rule
48-- [Built-in tools](reference/tools.md) — `bash`, `read_skill`, `read_file`, `write_file`, `edit_file`, `lsp`, `fetch_content`49+- [Built-in tools](reference/tools.md) — `bash`, `read_skill`, `read_file`, `write_file`, `edit_file`, `lsp`, `fetch_content`, `ask_agent`, `ask_user`
49 - [Skill file format](reference/skill-format.md)50 - [Skill file format](reference/skill-format.md)
50 - [Agent Client Protocol surface](reference/acp.md)51 - [Agent Client Protocol surface](reference/acp.md)
51 52
@@ -67,6 +68,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
67 - [Project instructions (`AGENTS.md`)](explanation/project-instructions.md) — why appended to the system prompt, why per conversation, why a warning rather than a cut, who does not read it68 - [Project instructions (`AGENTS.md`)](explanation/project-instructions.md) — why appended to the system prompt, why per conversation, why a warning rather than a cut, who does not read it
68 - [Structured output](explanation/structured-output.md) — why Go declarations, why they also go in the system prompt, why no tools, what guarantees the answer69 - [Structured output](explanation/structured-output.md) — why Go declarations, why they also go in the system prompt, why no tools, what guarantees the answer
69 - [Asking another agent](explanation/asking-another-agent.md) — why another mm agent is a child process spoken to over ACP, the history pair, fresh sessions, `ask_agent` and per-agent `yolo`, the depth limit70 - [Asking another agent](explanation/asking-another-agent.md) — why another mm agent is a child process spoken to over ACP, the history pair, fresh sessions, `ask_agent` and per-agent `yolo`, the depth limit
71+- [Asking the user](explanation/asking-the-user.md) — why `ask_user` asks each front end its own way, how a called agent's questions come up, the loose schema (llama.cpp's alphabetical grammar), the watchdog while a human answers, the ACP SDK gap
70 - Package diagram (draw.io source): [`docs/diagrams/packages.drawio`](../diagrams/packages.drawio)72 - Package diagram (draw.io source): [`docs/diagrams/packages.drawio`](../diagrams/packages.drawio)
71 73
72 ### MCP (Model Context Protocol) Explanation74 ### MCP (Model Context Protocol) Explanation
added docs/en/explanation/asking-the-user.md +54 -0
new file mode 100644
@@ -0,0 +1,54 @@
1+# Asking the user — explanation
2+
3+## What is this about?
4+
5+An agent often reaches a point where the next step is the user's decision: which framework, which environment, whether to go ahead. Without a way to ask, a model either guesses — and builds on a guess — or ends its turn with a question in prose, which loses the work in progress and gives the user nothing to click. The `ask_user` tool (ticket 84) lets the model ask in the middle of a turn and carry on with the answer.
6+
7+The ticket names the familiar shapes of an interactive prompt: pick one option, pick several, type a text, confirm. They are exactly the field types of ACP's elicitation forms, which made them the tool's four kinds: `choice`, `multi`, `text`, `confirm`.
8+
9+## One question, four front ends
10+
11+mm has four ways to be used, and the question must reach a person in each — or say clearly that nobody is there. The design keeps everything that does not depend on a screen in one package, `internal/elicit`: the questions, the answers, what the model reads back, how a typed line answers a question, and the conversion to and from an elicitation form. Each front end only asks:
12+
13+- the **line mode** prints numbered options and reads the next typed line, through the same waiting room as the a/s/r/n permission prompt — which is why `/abort` and Ctrl-C keep working while a question waits. Arrow-key menus were considered and left to the window: the line mode reads whole lines, and switching the terminal to raw mode for one question would fight its own input reader;
14+- the **window** draws the options over the conversation, as its completion popup does, and takes every key while the form stands;
15+- an **editor** gets an ACP `elicitation/create` form when it advertised the form mode; otherwise each choice or yes/no question becomes a permission dialog whose buttons are the options, because every ACP editor can show that dialog. Free text and several choices cannot be buttons: the model is told nobody can be asked;
16+- **nobody**: `mm -p` and `mm --ask` answer at once that the user cannot be asked, and the model is told to assume and say what it assumed. Waiting for an answer that cannot come would hang a script.
17+
18+A front end that can ask implements one optional interface, `ui.Elicitor`, beside the `ui.Sink` it already is — the same pattern as the token counts (`UsageSink`) and the speaker label (`Speaker`).
19+
20+## Agents asked by other agents
21+
22+An agent called through `/ask` or `ask_agent` is a child `mm -acp`, and its permission requests already come up to its asker. Its questions take the same road: the asker's ACP client advertises the form mode, receives the child's `elicitation/create`, and asks its own user through its own front end, naming the child (`homer asks: …`). A coordinator in an editor therefore shows its helper's questions as editor forms, and one in the terminal as numbered lines.
23+
24+Whether a called agent may ask at all is the user's decision, per agent: its own `askUserTool`, or the asker's `mmConfigs.<name>.askUser`, passed to the child process as `AGENT_ASK_USER` the way `yolo` travels as `AGENT_YOLO`. A worker that should never interrupt anyone simply does not get the tool.
25+
26+## A loose schema, on purpose
27+
28+The tool declares its input loosely: no enum, nothing required, and each question described in words rather than with `properties`. Two measured reasons:
29+
30+- Genkit validates a call against the declared schema before running the tool, and a rejected call ends the turn. A small model that writes `"type": "single"` would lose its turn; read by `elicit.Normalize`, the synonym simply works, and a real mistake comes back as a sentence the model corrects.
31+- llama.cpp turns the schema into a grammar, and that grammar imposes an object's properties in **alphabetical order**. With `properties` declared, a question's fields had to come as `default`, `options`, `question`, `type`; a model that starts with `question` — every model does — can then never write its `options`. Measured with Qwen3.5 9B: the options were lost 3 times out of 3 with the properties declared, and written 3 times out of 3 without. The raw completion, outside the grammar, always had them.
32+
33+The tool's description ends with a complete example call, which the schema can no longer show.
34+
35+## Waiting for a human
36+
37+mm's watchdog keeps counting while a tool runs (ticket 57), so a question left unanswered for 20 seconds would have ended the turn as a hung server. While a question waits, the tool beats the watchdog every second; a stopped turn still cancels the question. For a called agent's question, the asker's watchdog is beaten the same way.
38+
39+## An SDK gap
40+
41+ACP ties a form to its session and tool call with top-level `sessionId` and `toolCallId`, but acp-go-sdk v0.13.5 has no such fields on either side. mm parks the scope in the form's `_meta` and writes the top-level fields as the line goes out; an mm client relaying the question reads the tool call back from `_meta`. Both halves are marked to go once the SDK carries the fields.
42+
43+## Rejected alternatives
44+
45+- **One question per call.** Simpler, but a form of related questions (framework, TypeScript, package manager) is the ticket's own example, and an editor shows it as one form.
46+- **A question asked in prose, answered by the next message.** It ends the turn, and nothing distinguishes the answer from a new request.
47+- **Declining when nobody can answer.** "Declined" tells the model the user refused; "cannot be asked" tells it to assume. The difference changes what a model does next.
48+- **Declaring the tool beside a `structuredOutput`.** Any declared tool stops such an agent from starting, and one that answers once, in JSON, cannot hold a conversation anyway.
49+
50+## How it relates to the rest
51+
52+- Permissions (`yolo`) decide whether a tool may run; `ask_user` collects information. The two never mix: asking changes nothing, so the tool is not gated, and the editor's permission dialog is only borrowed as a fallback when no form can be shown. See [yolo and permissions](yolo-and-permissions.md).
53+- Called agents: [asking another agent](asking-another-agent.md).
54+- Reference: [the tool](../reference/tools.md#ask_user), [ACP](../reference/acp.md); how to use it: [let the agent ask you](../how-to/let-the-agent-ask-you.md).
new file mode 100644
@@ -0,0 +1,54 @@
1+# Asking the user — explanation
2+
3+## What is this about?
4+
5+An agent often reaches a point where the next step is the user's decision: which framework, which environment, whether to go ahead. Without a way to ask, a model either guesses — and builds on a guess — or ends its turn with a question in prose, which loses the work in progress and gives the user nothing to click. The `ask_user` tool (ticket 84) lets the model ask in the middle of a turn and carry on with the answer.
6+
7+The ticket names the familiar shapes of an interactive prompt: pick one option, pick several, type a text, confirm. They are exactly the field types of ACP's elicitation forms, which made them the tool's four kinds: `choice`, `multi`, `text`, `confirm`.
8+
9+## One question, four front ends
10+
11+mm has four ways to be used, and the question must reach a person in each — or say clearly that nobody is there. The design keeps everything that does not depend on a screen in one package, `internal/elicit`: the questions, the answers, what the model reads back, how a typed line answers a question, and the conversion to and from an elicitation form. Each front end only asks:
12+
13+- the **line mode** prints numbered options and reads the next typed line, through the same waiting room as the a/s/r/n permission prompt — which is why `/abort` and Ctrl-C keep working while a question waits. Arrow-key menus were considered and left to the window: the line mode reads whole lines, and switching the terminal to raw mode for one question would fight its own input reader;
14+- the **window** draws the options over the conversation, as its completion popup does, and takes every key while the form stands;
15+- an **editor** gets an ACP `elicitation/create` form when it advertised the form mode; otherwise each choice or yes/no question becomes a permission dialog whose buttons are the options, because every ACP editor can show that dialog. Free text and several choices cannot be buttons: the model is told nobody can be asked;
16+- **nobody**: `mm -p` and `mm --ask` answer at once that the user cannot be asked, and the model is told to assume and say what it assumed. Waiting for an answer that cannot come would hang a script.
17+
18+A front end that can ask implements one optional interface, `ui.Elicitor`, beside the `ui.Sink` it already is — the same pattern as the token counts (`UsageSink`) and the speaker label (`Speaker`).
19+
20+## Agents asked by other agents
21+
22+An agent called through `/ask` or `ask_agent` is a child `mm -acp`, and its permission requests already come up to its asker. Its questions take the same road: the asker's ACP client advertises the form mode, receives the child's `elicitation/create`, and asks its own user through its own front end, naming the child (`homer asks: …`). A coordinator in an editor therefore shows its helper's questions as editor forms, and one in the terminal as numbered lines.
23+
24+Whether a called agent may ask at all is the user's decision, per agent: its own `askUserTool`, or the asker's `mmConfigs.<name>.askUser`, passed to the child process as `AGENT_ASK_USER` the way `yolo` travels as `AGENT_YOLO`. A worker that should never interrupt anyone simply does not get the tool.
25+
26+## A loose schema, on purpose
27+
28+The tool declares its input loosely: no enum, nothing required, and each question described in words rather than with `properties`. Two measured reasons:
29+
30+- Genkit validates a call against the declared schema before running the tool, and a rejected call ends the turn. A small model that writes `"type": "single"` would lose its turn; read by `elicit.Normalize`, the synonym simply works, and a real mistake comes back as a sentence the model corrects.
31+- llama.cpp turns the schema into a grammar, and that grammar imposes an object's properties in **alphabetical order**. With `properties` declared, a question's fields had to come as `default`, `options`, `question`, `type`; a model that starts with `question` — every model does — can then never write its `options`. Measured with Qwen3.5 9B: the options were lost 3 times out of 3 with the properties declared, and written 3 times out of 3 without. The raw completion, outside the grammar, always had them.
32+
33+The tool's description ends with a complete example call, which the schema can no longer show.
34+
35+## Waiting for a human
36+
37+mm's watchdog keeps counting while a tool runs (ticket 57), so a question left unanswered for 20 seconds would have ended the turn as a hung server. While a question waits, the tool beats the watchdog every second; a stopped turn still cancels the question. For a called agent's question, the asker's watchdog is beaten the same way.
38+
39+## An SDK gap
40+
41+ACP ties a form to its session and tool call with top-level `sessionId` and `toolCallId`, but acp-go-sdk v0.13.5 has no such fields on either side. mm parks the scope in the form's `_meta` and writes the top-level fields as the line goes out; an mm client relaying the question reads the tool call back from `_meta`. Both halves are marked to go once the SDK carries the fields.
42+
43+## Rejected alternatives
44+
45+- **One question per call.** Simpler, but a form of related questions (framework, TypeScript, package manager) is the ticket's own example, and an editor shows it as one form.
46+- **A question asked in prose, answered by the next message.** It ends the turn, and nothing distinguishes the answer from a new request.
47+- **Declining when nobody can answer.** "Declined" tells the model the user refused; "cannot be asked" tells it to assume. The difference changes what a model does next.
48+- **Declaring the tool beside a `structuredOutput`.** Any declared tool stops such an agent from starting, and one that answers once, in JSON, cannot hold a conversation anyway.
49+
50+## How it relates to the rest
51+
52+- Permissions (`yolo`) decide whether a tool may run; `ask_user` collects information. The two never mix: asking changes nothing, so the tool is not gated, and the editor's permission dialog is only borrowed as a fallback when no form can be shown. See [yolo and permissions](yolo-and-permissions.md).
53+- Called agents: [asking another agent](asking-another-agent.md).
54+- Reference: [the tool](../reference/tools.md#ask_user), [ACP](../reference/acp.md); how to use it: [let the agent ask you](../how-to/let-the-agent-ask-you.md).
added docs/en/how-to/let-the-agent-ask-you.md +93 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/en/reference/acp.md +26 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/en/reference/cli.md +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/en/reference/configuration.md +2 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/en/reference/tools.md +25 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/fr/README.md +3 -1
Large diff collapsed to keep the page fast — load it when you need it.
added docs/fr/explanation/asking-the-user.md +54 -0
Large diff collapsed to keep the page fast — load it when you need it.
added docs/fr/how-to/let-the-agent-ask-you.md +93 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/fr/reference/acp.md +26 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/fr/reference/cli.md +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/fr/reference/configuration.md +2 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified docs/fr/reference/tools.md +25 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/acp/acp.go +16 -5
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/acp/acp_test.go +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/acp/elicit.go +167 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/acp/elicit_test.go +194 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/acp/sink.go +2 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/agent/agent.go +3 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/agent/prompt.go +164 -51
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/agent/prompt_test.go +78 -1
Large diff collapsed to keep the page fast — load it when you need it.
added internal/ask/elicit.go +78 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/ask/elicit_test.go +116 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/ask/env.go +20 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/ask/linesink.go +10 -2
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/ask/pool.go +3 -1
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/config/agents.go +6 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/config/askuser_test.go +61 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/config/config.go +21 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/config/structured.go +3 -1
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/elicit.go +264 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/elicit_test.go +235 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/example_test.go +33 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/line.go +141 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/prompter.go +45 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/elicit/schema.go +224 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/mcp/tool_wrapper.go +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tools/askagent.go +14 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/tools/askuser.go +141 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/tools/askuser_test.go +158 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/draw.go +10 -3
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/events.go +4 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/tui/question.go +305 -0
Large diff collapsed to keep the page fast — load it when you need it.
added internal/tui/question_test.go +153 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/render.go +2 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/sink.go +12 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/transcript.go +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/tui.go +9 -7
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/turn.go +1 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/tui/view.go +4 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified internal/ui/ui.go +13 -0
Large diff collapsed to keep the page fast — load it when you need it.
modified main.go +9 -1
Large diff collapsed to keep the page fast — load it when you need it.
added skills/create-agent/SKILL.md +123 -0
Large diff collapsed to keep the page fast — load it when you need it.
added skills/create-agent/model_facts.py +197 -0
Large diff collapsed to keep the page fast — load it when you need it.