Interactive Prompt #29
Merged@k33g wants to merge
feature/interactive-prompt into mainMerged 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: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-09-27T03:45:48.121Z |
| 9 | -updatedAt: 2026-10-06T03:59:41.259Z | |
| 9 | +updatedAt: 2026-10-12T09:53:49.053Z | |
| 10 | 10 | labels: [] |
| 11 | -milestone: v0.3.0 | |
| 11 | +milestone: v0.5.0 | |
| 12 | 12 | epic: Agent Memory |
| 13 | 13 | body: "" |
| 14 | 14 | tasks: [] |
| @@ -6,9 +6,9 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-09-27T03:45:48.121Z | 8 | createdAt: 2026-09-27T03:45:48.121Z |
| 9 | -updatedAt: 2026-10-06T03:59:41.259Z | 9 | +updatedAt: 2026-10-12T09:53:49.053Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | -milestone: v0.3.0 | 11 | +milestone: v0.5.0 |
| 12 | epic: Agent Memory | 12 | 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: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-09-28T18:44:44.821Z |
| 9 | -updatedAt: 2026-10-06T13:08:12.646Z | |
| 9 | +updatedAt: 2026-10-12T09:54:01.192Z | |
| 10 | 10 | labels: [] |
| 11 | -milestone: v0.3.0 | |
| 11 | +milestone: v0.5.0 | |
| 12 | 12 | epic: ToDo |
| 13 | 13 | body: "" |
| 14 | 14 | tasks: [] |
| @@ -6,9 +6,9 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-09-28T18:44:44.821Z | 8 | createdAt: 2026-09-28T18:44:44.821Z |
| 9 | -updatedAt: 2026-10-06T13:08:12.646Z | 9 | +updatedAt: 2026-10-12T09:54:01.192Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | -milestone: v0.3.0 | 11 | +milestone: v0.5.0 |
| 12 | epic: ToDo | 12 | 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 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 54 |
| 3 | 3 | title: How to force the JSON output? |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-09-30T06:35:54.771Z |
| 9 | -updatedAt: 2026-10-06T13:11:09.040Z | |
| 9 | +updatedAt: 2026-10-12T09:46:09.037Z | |
| 10 | 10 | labels: [] |
| 11 | 11 | epic: Questions |
| 12 | 12 | 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: 54 | 2 | id: 54 |
| 3 | title: How to force the JSON output? | 3 | title: How to force the JSON output? |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-09-30T06:35:54.771Z | 8 | createdAt: 2026-09-30T06:35:54.771Z |
| 9 | -updatedAt: 2026-10-06T13:11:09.040Z | 9 | +updatedAt: 2026-10-12T09:46:09.037Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | epic: Questions | 11 | epic: Questions |
| 12 | body: "" | 12 | body: "" |
modified
.tickets/issues/0066-talk-to-another-mm.yaml +2 -1 | @@ -6,9 +6,10 @@ author: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-02T18:48:36.275Z |
| 9 | -updatedAt: 2026-10-06T03:55:28.931Z | |
| 9 | +updatedAt: 2026-10-12T09:52:38.596Z | |
| 10 | 10 | labels: |
| 11 | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | |
| 12 | 13 | related: |
| 13 | 14 | - 52 |
| 14 | 15 | - 57 |
| @@ -6,9 +6,10 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-02T18:48:36.275Z | 8 | createdAt: 2026-10-02T18:48:36.275Z |
| 9 | -updatedAt: 2026-10-06T03:55:28.931Z | 9 | +updatedAt: 2026-10-12T09:52:38.596Z |
| 10 | labels: | 10 | labels: |
| 11 | - kind::feature | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | ||
| 12 | related: | 13 | related: |
| 13 | - 52 | 14 | - 52 |
| 14 | - 57 | 15 | - 57 |
modified
.tickets/issues/0067-enable-disable-reasoning-mode.yaml +2 -1 | @@ -6,9 +6,10 @@ author: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-02T06:09:42.599Z |
| 9 | -updatedAt: 2026-10-06T13:13:56.879Z | |
| 9 | +updatedAt: 2026-10-12T09:52:15.875Z | |
| 10 | 10 | labels: |
| 11 | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | |
| 12 | 13 | epic: Models |
| 13 | 14 | related: |
| 14 | 15 | - 62 |
| @@ -6,9 +6,10 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-02T06:09:42.599Z | 8 | createdAt: 2026-10-02T06:09:42.599Z |
| 9 | -updatedAt: 2026-10-06T13:13:56.879Z | 9 | +updatedAt: 2026-10-12T09:52:15.875Z |
| 10 | labels: | 10 | labels: |
| 11 | - kind::feature | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | ||
| 12 | epic: Models | 13 | epic: Models |
| 13 | related: | 14 | related: |
| 14 | - 62 | 15 | - 62 |
modified
.tickets/issues/0069-create-skills-to-search-some-specific-knowlege-o.yaml +4 -2 | @@ -6,10 +6,12 @@ author: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-02T09:26:19.729Z |
| 9 | -updatedAt: 2026-10-06T13:11:52.354Z | |
| 9 | +updatedAt: 2026-10-12T09:35:03.158Z | |
| 10 | 10 | labels: [] |
| 11 | 11 | epic: ToDo |
| 12 | 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 | 16 | tasks: [] |
| 15 | 17 | comments: [] |
| @@ -6,10 +6,12 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-02T09:26:19.729Z | 8 | createdAt: 2026-10-02T09:26:19.729Z |
| 9 | -updatedAt: 2026-10-06T13:11:52.354Z | 9 | +updatedAt: 2026-10-12T09:35:03.158Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | epic: ToDo | 11 | 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: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | 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 | |
| 11 | 13 | epic: SDK |
| 12 | 14 | body: "" |
| 13 | 15 | tasks: [] |
| @@ -6,8 +6,10 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-02T05:32:33.878Z | 8 | createdAt: 2026-10-02T05:32:33.878Z |
| 9 | -updatedAt: 2026-10-06T13:15:18.350Z | 9 | +updatedAt: 2026-10-12T09:45:33.355Z |
| 10 | -labels: [] | 10 | +labels: |
| 11 | + - priority::urgent | ||
| 12 | + - kind::feature | ||
| 11 | epic: SDK | 13 | 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: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-02T23:30:00.000Z |
| 9 | -updatedAt: 2026-10-06T03:54:22.627Z | |
| 9 | +updatedAt: 2026-10-12T09:51:47.496Z | |
| 10 | 10 | labels: |
| 11 | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | |
| 12 | 13 | related: |
| 13 | 14 | - 52 |
| 14 | 15 | - 57 |
| @@ -6,9 +6,10 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-02T23:30:00.000Z | 8 | createdAt: 2026-10-02T23:30:00.000Z |
| 9 | -updatedAt: 2026-10-06T03:54:22.627Z | 9 | +updatedAt: 2026-10-12T09:51:47.496Z |
| 10 | labels: | 10 | labels: |
| 11 | - kind::feature | 11 | - kind::feature |
| 12 | +milestone: v0.3.0 | ||
| 12 | related: | 13 | related: |
| 13 | - 52 | 14 | - 52 |
| 14 | - 57 | 15 | - 57 |
modified
.tickets/issues/0076-upgrade-genkit-go-to-v1-13-1.yaml +7 -7 | @@ -1,15 +1,16 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 76 |
| 3 | 3 | title: Upgrade Genkit Go to v1.13.1 |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-06T14:30:00.000Z |
| 9 | -updatedAt: 2026-10-06T16:00:00.000Z | |
| 9 | +updatedAt: 2026-10-12T09:51:20.921Z | |
| 10 | 10 | labels: |
| 11 | 11 | - kind::chore |
| 12 | 12 | - priority::medium |
| 13 | +milestone: v0.3.0 | |
| 13 | 14 | epic: Providers (LLM Engine) |
| 14 | 15 | related: |
| 15 | 16 | - 67 |
| @@ -93,7 +94,7 @@ body: | | ||
| 93 | 94 | `DefineModel`. |
| 94 | 95 | tasks: |
| 95 | 96 | - 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 | 98 | state: closed |
| 98 | 99 | priority: none |
| 99 | 100 | author: |
| @@ -111,7 +112,7 @@ tasks: | ||
| 111 | 112 | createdAt: 2026-10-06T14:30:00.000Z |
| 112 | 113 | updatedAt: 2026-10-06T16:00:00.000Z |
| 113 | 114 | - 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 | 116 | state: closed |
| 116 | 117 | priority: none |
| 117 | 118 | author: |
| @@ -120,7 +121,7 @@ tasks: | ||
| 120 | 121 | createdAt: 2026-10-06T14:30:00.000Z |
| 121 | 122 | updatedAt: 2026-10-06T16:00:00.000Z |
| 122 | 123 | - 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 | 125 | state: closed |
| 125 | 126 | priority: none |
| 126 | 127 | author: |
| @@ -129,7 +130,7 @@ tasks: | ||
| 129 | 130 | createdAt: 2026-10-06T14:30:00.000Z |
| 130 | 131 | updatedAt: 2026-10-06T16:00:00.000Z |
| 131 | 132 | - 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 | 134 | state: closed |
| 134 | 135 | priority: none |
| 135 | 136 | author: |
| @@ -204,4 +205,3 @@ comments: | ||
| 204 | 205 | - Docs EN+FR: reference/configuration (`sampling` extra keys), |
| 205 | 206 | explanation/thinking-models (Genkit 1.13 delivery, how to turn |
| 206 | 207 | 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: 76 | 2 | id: 76 |
| 3 | title: Upgrade Genkit Go to v1.13.1 | 3 | title: Upgrade Genkit Go to v1.13.1 |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-06T14:30:00.000Z | 8 | createdAt: 2026-10-06T14:30:00.000Z |
| 9 | -updatedAt: 2026-10-06T16:00:00.000Z | 9 | +updatedAt: 2026-10-12T09:51:20.921Z |
| 10 | labels: | 10 | labels: |
| 11 | - kind::chore | 11 | - kind::chore |
| 12 | - priority::medium | 12 | - priority::medium |
| 13 | +milestone: v0.3.0 | ||
| 13 | epic: Providers (LLM Engine) | 14 | epic: Providers (LLM Engine) |
| 14 | related: | 15 | related: |
| 15 | - 67 | 16 | - 67 |
| @@ -93,7 +94,7 @@ body: | | |||
| 93 | `DefineModel`. | 94 | `DefineModel`. |
| 94 | tasks: | 95 | tasks: |
| 95 | - id: 1 | 96 | - 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: closed | 98 | state: closed |
| 98 | priority: none | 99 | priority: none |
| 99 | author: | 100 | author: |
| @@ -111,7 +112,7 @@ tasks: | |||
| 111 | createdAt: 2026-10-06T14:30:00.000Z | 112 | createdAt: 2026-10-06T14:30:00.000Z |
| 112 | updatedAt: 2026-10-06T16:00:00.000Z | 113 | updatedAt: 2026-10-06T16:00:00.000Z |
| 113 | - id: 3 | 114 | - 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: closed | 116 | state: closed |
| 116 | priority: none | 117 | priority: none |
| 117 | author: | 118 | author: |
| @@ -120,7 +121,7 @@ tasks: | |||
| 120 | createdAt: 2026-10-06T14:30:00.000Z | 121 | createdAt: 2026-10-06T14:30:00.000Z |
| 121 | updatedAt: 2026-10-06T16:00:00.000Z | 122 | updatedAt: 2026-10-06T16:00:00.000Z |
| 122 | - id: 4 | 123 | - 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: closed | 125 | state: closed |
| 125 | priority: none | 126 | priority: none |
| 126 | author: | 127 | author: |
| @@ -129,7 +130,7 @@ tasks: | |||
| 129 | createdAt: 2026-10-06T14:30:00.000Z | 130 | createdAt: 2026-10-06T14:30:00.000Z |
| 130 | updatedAt: 2026-10-06T16:00:00.000Z | 131 | updatedAt: 2026-10-06T16:00:00.000Z |
| 131 | - id: 5 | 132 | - 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: closed | 134 | state: closed |
| 134 | priority: none | 135 | 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 turn | 206 | 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: | ||
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-08T10:00:00.000Z |
| 9 | -updatedAt: 2026-10-09T03:16:38.703Z | |
| 9 | +updatedAt: 2026-10-12T09:51:02.307Z | |
| 10 | 10 | labels: |
| 11 | 11 | - enhancement |
| 12 | +milestone: v0.3.0 | |
| 12 | 13 | epic: Models |
| 13 | 14 | related: |
| 14 | 15 | - 54 |
| @@ -6,9 +6,10 @@ author: | |||
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-08T10:00:00.000Z | 8 | createdAt: 2026-10-08T10:00:00.000Z |
| 9 | -updatedAt: 2026-10-09T03:16:38.703Z | 9 | +updatedAt: 2026-10-12T09:51:02.307Z |
| 10 | labels: | 10 | labels: |
| 11 | - enhancement | 11 | - enhancement |
| 12 | +milestone: v0.3.0 | ||
| 12 | epic: Models | 13 | epic: Models |
| 13 | related: | 14 | related: |
| 14 | - 54 | 15 | - 54 |
modified
.tickets/issues/0081-support-agents-md-project-instructions-for-the-a.yaml +3 -2 | @@ -1,14 +1,15 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 81 |
| 3 | 3 | title: Support AGENTS.md (project instructions for the agent) |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-09T08:00:00.000Z |
| 9 | -updatedAt: 2026-10-09T15:00:00.000Z | |
| 9 | +updatedAt: 2026-10-12T09:50:43.252Z | |
| 10 | 10 | labels: |
| 11 | 11 | - enhancement |
| 12 | +milestone: v0.3.0 | |
| 12 | 13 | epic: Agent Memory |
| 13 | 14 | related: |
| 14 | 15 | - 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: 81 | 2 | id: 81 |
| 3 | title: Support AGENTS.md (project instructions for the agent) | 3 | title: Support AGENTS.md (project instructions for the agent) |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-09T08:00:00.000Z | 8 | createdAt: 2026-10-09T08:00:00.000Z |
| 9 | -updatedAt: 2026-10-09T15:00:00.000Z | 9 | +updatedAt: 2026-10-12T09:50:43.252Z |
| 10 | labels: | 10 | labels: |
| 11 | - enhancement | 11 | - enhancement |
| 12 | +milestone: v0.3.0 | ||
| 12 | epic: Agent Memory | 13 | epic: Agent Memory |
| 13 | related: | 14 | related: |
| 14 | - 79 | 15 | - 79 |
modified
.tickets/issues/0083-demo-agent-news-roundup-with-lucy-128k.yaml +11 -3 | @@ -1,14 +1,22 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 83 |
| 3 | 3 | title: "demo agent: news roundup with Lucy 128k" |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-12T04:06:03.394Z |
| 9 | -updatedAt: 2026-10-12T04:07:39.381Z | |
| 9 | +updatedAt: 2026-10-12T09:49:25.499Z | |
| 10 | 10 | labels: [] |
| 11 | +milestone: v0.4.0 | |
| 11 | 12 | body: | |
| 12 | 13 | Use hf.co/Menlo/Lucy-128k-gguf:Q8_0 |
| 13 | 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. | |
| @@ -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: 83 | 2 | id: 83 |
| 3 | title: "demo agent: news roundup with Lucy 128k" | 3 | title: "demo agent: news roundup with Lucy 128k" |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-12T04:06:03.394Z | 8 | createdAt: 2026-10-12T04:06:03.394Z |
| 9 | -updatedAt: 2026-10-12T04:07:39.381Z | 9 | +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_0 | 13 | 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 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 84 |
| 3 | 3 | title: Interactive prompts in a CLI + ACP |
| 4 | -state: open | |
| 4 | +state: closed | |
| 5 | 5 | author: |
| 6 | 6 | name: k33g |
| 7 | 7 | email: ph.charriere@gmail.com |
| 8 | 8 | createdAt: 2026-10-12T04:38:05.715Z |
| 9 | -updatedAt: 2026-10-12T04:41:47.738Z | |
| 9 | +updatedAt: 2026-10-12T09:50:23.536Z | |
| 10 | 10 | labels: [] |
| 11 | +milestone: v0.4.0 | |
| 11 | 12 | body: | |
| 12 | 13 | ## Interactive prompts in a CLI |
| 13 | 14 | |
| @@ -50,22 +51,24 @@ body: | | ||
| 50 | 51 | tasks: |
| 51 | 52 | - id: 1 |
| 52 | 53 | title: Implement interactive prompts in mini me CLI |
| 53 | - state: open | |
| 54 | + state: closed | |
| 54 | 55 | priority: high |
| 55 | 56 | author: |
| 56 | 57 | name: k33g |
| 57 | 58 | email: ph.charriere@gmail.com |
| 58 | 59 | 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 | |
| 60 | 62 | - id: 2 |
| 61 | 63 | title: Implement support in ACP |
| 62 | - state: open | |
| 64 | + state: closed | |
| 63 | 65 | priority: medium |
| 64 | 66 | author: |
| 65 | 67 | name: k33g |
| 66 | 68 | email: ph.charriere@gmail.com |
| 67 | 69 | 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 | |
| 69 | 72 | comments: |
| 70 | 73 | - id: 1 |
| 71 | 74 | author: |
| @@ -74,3 +77,10 @@ comments: | ||
| 74 | 77 | createdAt: 2026-10-12T04:40:24.315Z |
| 75 | 78 | body: | |
| 76 | 79 | 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: 84 | 2 | id: 84 |
| 3 | title: Interactive prompts in a CLI + ACP | 3 | title: Interactive prompts in a CLI + ACP |
| 4 | -state: open | 4 | +state: closed |
| 5 | author: | 5 | author: |
| 6 | name: k33g | 6 | name: k33g |
| 7 | email: ph.charriere@gmail.com | 7 | email: ph.charriere@gmail.com |
| 8 | createdAt: 2026-10-12T04:38:05.715Z | 8 | createdAt: 2026-10-12T04:38:05.715Z |
| 9 | -updatedAt: 2026-10-12T04:41:47.738Z | 9 | +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 CLI | 13 | ## Interactive prompts in a CLI |
| 13 | 14 | ||
| @@ -50,22 +51,24 @@ body: | | |||
| 50 | tasks: | 51 | tasks: |
| 51 | - id: 1 | 52 | - id: 1 |
| 52 | title: Implement interactive prompts in mini me CLI | 53 | title: Implement interactive prompts in mini me CLI |
| 53 | - state: open | 54 | + state: closed |
| 54 | priority: high | 55 | priority: high |
| 55 | author: | 56 | author: |
| 56 | name: k33g | 57 | name: k33g |
| 57 | email: ph.charriere@gmail.com | 58 | email: ph.charriere@gmail.com |
| 58 | createdAt: 2026-10-12T04:41:04.171Z | 59 | 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 | ||
| 60 | - id: 2 | 62 | - id: 2 |
| 61 | title: Implement support in ACP | 63 | title: Implement support in ACP |
| 62 | - state: open | 64 | + state: closed |
| 63 | priority: medium | 65 | priority: medium |
| 64 | author: | 66 | author: |
| 65 | name: k33g | 67 | name: k33g |
| 66 | email: ph.charriere@gmail.com | 68 | email: ph.charriere@gmail.com |
| 67 | createdAt: 2026-10-12T04:41:24.268Z | 69 | 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 | ||
| 69 | comments: | 72 | comments: |
| 70 | - id: 1 | 73 | - id: 1 |
| 71 | author: | 74 | author: |
| @@ -74,3 +77,10 @@ comments: | |||
| 74 | createdAt: 2026-10-12T04:40:24.315Z | 77 | createdAt: 2026-10-12T04:40:24.315Z |
| 75 | body: | | 78 | body: | |
| 76 | ACP (Agent Client Protocol) resources: https://agentclientprotocol.com/get-started/introduction | 79 | 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: | ||
| 13 | 13 | state: closed |
| 14 | 14 | dueOn: 2026-10-30 |
| 15 | 15 | - title: v0.3.0 |
| 16 | - state: open | |
| 16 | + state: closed | |
| 17 | 17 | 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: closed | 13 | state: closed |
| 14 | dueOn: 2026-10-30 | 14 | dueOn: 2026-10-30 |
| 15 | - title: v0.3.0 | 15 | - title: v0.3.0 |
| 16 | - state: open | 16 | + state: closed |
| 17 | dueOn: 2026-11-01 | 17 | 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 | ||
| 109 | 109 | |
| 110 | 110 | - **One prompt and exit**: `mm -p "…"` — for scripts. See [Run a single prompt](docs/en/how-to/run-a-single-prompt.md). |
| 111 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 143 | ## Learn more |
| 139 | 144 | |
| @@ -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 more | 143 | ## 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 @@ | ||
| 1 | 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="<b>main (mm)</b><br/><font style="font-size:10px">wiring: config, engine, tools, then one front end</font>" 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="<b>internal/agent</b><br/><font style="font-size:10px">terminal REPL: /quit /abort /compact /new</font>" 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="<b>internal/acp</b><br/><font style="font-size:10px">editor front end: Agent Client Protocol on stdio</font>" 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="<b>internal/session</b><br/><font style="font-size:10px">what a conversation starts from; the /new reset</font>" 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="<b>internal/compact</b><br/><font style="font-size:10px">history compression into a model-written summary</font>" 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="<b>internal/engine</b><br/><font style="font-size:10px">LLM connection + generation, one Provider per server</font>" 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="<b>internal/tools</b><br/><font style="font-size:10px">built-in tools: bash, read_skill, file tools, lsp, fetch_content</font>" 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="<b>internal/detector</b><br/><font style="font-size:10px">repeated-action (loop) detection</font>" 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="<b>internal/config</b><br/><font style="font-size:10px">settings with YAML overrides (agent.yaml)</font>" 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="<b>internal/spinner</b><br/><font style="font-size:10px">terminal spinner and styling</font>" 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="<b>internal/ui</b><br/><font style="font-size:10px">human output destination + shared event sink</font>" 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="<b>internal/fileedit</b><br/><font style="font-size:10px">exact-replacement file editing</font>" 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="<b>internal/skills</b><br/><font style="font-size:10px">markdown skills catalogue (./skills)</font>" 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="<b>github.com/firebase/genkit</b><br/><font style="font-size:10px">ai.Message, tools, model calls</font>" 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="<b>github.com/coder/acp-go-sdk</b><br/><font style="font-size:10px">JSON-RPC transport for ACP</font>" 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="<b>github.com/openai/openai-go</b><br/><font style="font-size:10px">OpenAI-compatible HTTP client</font>" 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="<b>gopkg.in/yaml.v3</b><br/><font style="font-size:10px">YAML parsing</font>" 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="<b>internal/version</b><br/><font style="font-size:10px">which mm this is: build stamp, else the commit</font>" 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 | 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="<b>internal/mention</b><br/><font style="font-size:10px">the @path notation of a question</font>" 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="<b>internal/store</b><br/><font style="font-size:10px">per-project session files (.mm/sessions/<id>.json)</font>" 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="<b>internal/tui</b><br/><font style="font-size:10px">window front end: one screen on tcell (mm -tui)</font>" 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="<b>internal/command</b><br/><font style="font-size:10px">the one slash-command table, per front end</font>" 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="<b>github.com/gdamore/tcell/v2</b><br/><font style="font-size:10px">terminal screen, keys, mouse</font>" 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="<b>internal/clipboard</b><br/><font style="font-size:10px">system clipboard: native tool, then OSC 52</font>" 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="<b>internal/lsp</b><br/><font style="font-size:10px">language-server client: definition, references, hover, symbols, diagnostics, rename</font>" 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="<b>go.lsp.dev/protocol + jsonrpc2</b><br/><font style="font-size:10px">LSP types and JSON-RPC 2.0 over stdio</font>" 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="<b>mm — package dependencies</b><br/>Arrow: "imports". Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.<br/>Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports " "}}' ./..." 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="<b>internal/webmd</b><br/><font style="font-size:10px">web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert</font>" 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="<b>golang.org/x/net/html (+ x/text)</b><br/><font style="font-size:10px">HTML5 parser, charset lookup</font>" 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="<b>internal/ask</b><br/><font style="font-size:10px">/ask another mm agent: child mm -acp, ACP client side</font>" 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="<b>internal/consent</b><br/><font style="font-size:10px">yolo switch, the four answers, per-session memory, the line mode prompt hook</font>" 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="<b>internal/mcp</b><br/><font style="font-size:10px">MCP clients (stdio, HTTP), their tools wrapped as mm tools</font>" 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="<b>internal/structured</b><br/><font style="font-size:10px">structuredOutput: Go declarations → JSON Schema (go/parser)</font>" 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="<b>internal/agentsmd</b><br/><font style="font-size:10px">the project's AGENTS.md, appended to the system prompt per conversation</font>" 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="<b>internal/mention</b><br/><font style="font-size:10px">the @path notation of a question</font>" 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="<b>internal/store</b><br/><font style="font-size:10px">per-project session files (.mm/sessions/<id>.json)</font>" 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="<b>internal/tui</b><br/><font style="font-size:10px">window front end: one screen on tcell (mm -tui)</font>" 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="<b>internal/command</b><br/><font style="font-size:10px">the one slash-command table, per front end</font>" 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="<b>github.com/gdamore/tcell/v2</b><br/><font style="font-size:10px">terminal screen, keys, mouse</font>" 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="<b>internal/clipboard</b><br/><font style="font-size:10px">system clipboard: native tool, then OSC 52</font>" 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="<b>internal/lsp</b><br/><font style="font-size:10px">language-server client: definition, references, hover, symbols, diagnostics, rename</font>" 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="<b>go.lsp.dev/protocol + jsonrpc2</b><br/><font style="font-size:10px">LSP types and JSON-RPC 2.0 over stdio</font>" 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="<b>mm — package dependencies</b><br/>Arrow: "imports". Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.<br/>Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports " "}}' ./..." 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="<b>internal/webmd</b><br/><font style="font-size:10px">web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert</font>" 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="<b>golang.org/x/net/html (+ x/text)</b><br/><font style="font-size:10px">HTML5 parser, charset lookup</font>" 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="<b>internal/ask</b><br/><font style="font-size:10px">/ask another mm agent: child mm -acp, ACP client side</font>" 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="<b>internal/consent</b><br/><font style="font-size:10px">yolo switch, the four answers, per-session memory, the line mode prompt hook</font>" 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="<b>internal/mcp</b><br/><font style="font-size:10px">MCP clients (stdio, HTTP), their tools wrapped as mm tools</font>" 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="<b>internal/structured</b><br/><font style="font-size:10px">structuredOutput: Go declarations → JSON Schema (go/parser)</font>" 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="<b>internal/agentsmd</b><br/><font style="font-size:10px">the project's AGENTS.md, appended to the system prompt per conversation</font>" 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="<b>internal/elicit</b><br/><font style="font-size:10px">ask_user's questions and answers: normalize, line answers, elicitation form schema</font>" 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="<b>main (mm)</b><br/><font style="font-size:10px">wiring: config, engine, tools, then one front end</font>" 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="<b>internal/agent</b><br/><font style="font-size:10px">terminal REPL: /quit /abort /compact /new</font>" 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="<b>internal/acp</b><br/><font style="font-size:10px">editor front end: Agent Client Protocol on stdio</font>" 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="<b>internal/session</b><br/><font style="font-size:10px">what a conversation starts from; the /new reset</font>" 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="<b>internal/compact</b><br/><font style="font-size:10px">history compression into a model-written summary</font>" 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="<b>internal/engine</b><br/><font style="font-size:10px">LLM connection + generation, one Provider per server</font>" 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="<b>internal/tools</b><br/><font style="font-size:10px">built-in tools: bash, read_skill, file tools, lsp, fetch_content</font>" 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="<b>internal/detector</b><br/><font style="font-size:10px">repeated-action (loop) detection</font>" 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="<b>internal/config</b><br/><font style="font-size:10px">settings with YAML overrides (agent.yaml)</font>" 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="<b>internal/spinner</b><br/><font style="font-size:10px">terminal spinner and styling</font>" 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="<b>internal/ui</b><br/><font style="font-size:10px">human output destination + shared event sink</font>" 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="<b>internal/fileedit</b><br/><font style="font-size:10px">exact-replacement file editing</font>" 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="<b>internal/skills</b><br/><font style="font-size:10px">markdown skills catalogue (./skills)</font>" 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="<b>github.com/firebase/genkit</b><br/><font style="font-size:10px">ai.Message, tools, model calls</font>" 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="<b>github.com/coder/acp-go-sdk</b><br/><font style="font-size:10px">JSON-RPC transport for ACP</font>" 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="<b>github.com/openai/openai-go</b><br/><font style="font-size:10px">OpenAI-compatible HTTP client</font>" 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="<b>gopkg.in/yaml.v3</b><br/><font style="font-size:10px">YAML parsing</font>" 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="<b>internal/version</b><br/><font style="font-size:10px">which mm this is: build stamp, else the commit</font>" 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="<b>main (mm)</b><br/><font style="font-size:10px">wiring: config, engine, tools, then one front end</font>" 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="<b>internal/agent</b><br/><font style="font-size:10px">terminal REPL: /quit /abort /compact /new</font>" 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="<b>internal/acp</b><br/><font style="font-size:10px">editor front end: Agent Client Protocol on stdio</font>" 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="<b>internal/session</b><br/><font style="font-size:10px">what a conversation starts from; the /new reset</font>" 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="<b>internal/compact</b><br/><font style="font-size:10px">history compression into a model-written summary</font>" 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="<b>internal/engine</b><br/><font style="font-size:10px">LLM connection + generation, one Provider per server</font>" 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="<b>internal/tools</b><br/><font style="font-size:10px">built-in tools: bash, read_skill, file tools, lsp, fetch_content</font>" 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="<b>internal/detector</b><br/><font style="font-size:10px">repeated-action (loop) detection</font>" 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="<b>internal/config</b><br/><font style="font-size:10px">settings with YAML overrides (agent.yaml)</font>" 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="<b>internal/spinner</b><br/><font style="font-size:10px">terminal spinner and styling</font>" 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="<b>internal/ui</b><br/><font style="font-size:10px">human output destination + shared event sink</font>" 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="<b>internal/fileedit</b><br/><font style="font-size:10px">exact-replacement file editing</font>" 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="<b>internal/skills</b><br/><font style="font-size:10px">markdown skills catalogue (./skills)</font>" 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="<b>github.com/firebase/genkit</b><br/><font style="font-size:10px">ai.Message, tools, model calls</font>" 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="<b>github.com/coder/acp-go-sdk</b><br/><font style="font-size:10px">JSON-RPC transport for ACP</font>" 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="<b>github.com/openai/openai-go</b><br/><font style="font-size:10px">OpenAI-compatible HTTP client</font>" 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="<b>gopkg.in/yaml.v3</b><br/><font style="font-size:10px">YAML parsing</font>" 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="<b>internal/version</b><br/><font style="font-size:10px">which mm this is: build stamp, else the commit</font>" 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="<b>internal/mention</b><br/><font style="font-size:10px">the @path notation of a question</font>" 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="<b>internal/store</b><br/><font style="font-size:10px">per-project session files (.mm/sessions/<id>.json)</font>" 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="<b>internal/tui</b><br/><font style="font-size:10px">window front end: one screen on tcell (mm -tui)</font>" 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="<b>internal/command</b><br/><font style="font-size:10px">the one slash-command table, per front end</font>" 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="<b>github.com/gdamore/tcell/v2</b><br/><font style="font-size:10px">terminal screen, keys, mouse</font>" 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="<b>internal/clipboard</b><br/><font style="font-size:10px">system clipboard: native tool, then OSC 52</font>" 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="<b>internal/lsp</b><br/><font style="font-size:10px">language-server client: definition, references, hover, symbols, diagnostics, rename</font>" 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="<b>go.lsp.dev/protocol + jsonrpc2</b><br/><font style="font-size:10px">LSP types and JSON-RPC 2.0 over stdio</font>" 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="<b>mm — package dependencies</b><br/>Arrow: "imports". Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.<br/>Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports " "}}' ./..." 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="<b>internal/webmd</b><br/><font style="font-size:10px">web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert</font>" 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="<b>golang.org/x/net/html (+ x/text)</b><br/><font style="font-size:10px">HTML5 parser, charset lookup</font>" 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="<b>internal/ask</b><br/><font style="font-size:10px">/ask another mm agent: child mm -acp, ACP client side</font>" 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="<b>internal/consent</b><br/><font style="font-size:10px">yolo switch, the four answers, per-session memory, the line mode prompt hook</font>" 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="<b>internal/mcp</b><br/><font style="font-size:10px">MCP clients (stdio, HTTP), their tools wrapped as mm tools</font>" 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="<b>internal/structured</b><br/><font style="font-size:10px">structuredOutput: Go declarations → JSON Schema (go/parser)</font>" 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="<b>internal/agentsmd</b><br/><font style="font-size:10px">the project's AGENTS.md, appended to the system prompt per conversation</font>" 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="<b>internal/mention</b><br/><font style="font-size:10px">the @path notation of a question</font>" 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="<b>internal/store</b><br/><font style="font-size:10px">per-project session files (.mm/sessions/<id>.json)</font>" 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="<b>internal/tui</b><br/><font style="font-size:10px">window front end: one screen on tcell (mm -tui)</font>" 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="<b>internal/command</b><br/><font style="font-size:10px">the one slash-command table, per front end</font>" 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="<b>github.com/gdamore/tcell/v2</b><br/><font style="font-size:10px">terminal screen, keys, mouse</font>" 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="<b>internal/clipboard</b><br/><font style="font-size:10px">system clipboard: native tool, then OSC 52</font>" 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="<b>internal/lsp</b><br/><font style="font-size:10px">language-server client: definition, references, hover, symbols, diagnostics, rename</font>" 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="<b>go.lsp.dev/protocol + jsonrpc2</b><br/><font style="font-size:10px">LSP types and JSON-RPC 2.0 over stdio</font>" 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="<b>mm — package dependencies</b><br/>Arrow: "imports". Yellow: entry point. Blue: front ends. Green: shared logic. Grey: leaf packages. Dashed purple: third-party modules.<br/>Regenerate the edge list from: go list -f '{{.ImportPath}}: {{join .Imports " "}}' ./..." 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="<b>internal/webmd</b><br/><font style="font-size:10px">web page → Markdown: fetch (robots.txt, charset → UTF-8), clean, convert</font>" 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="<b>golang.org/x/net/html (+ x/text)</b><br/><font style="font-size:10px">HTML5 parser, charset lookup</font>" 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="<b>internal/ask</b><br/><font style="font-size:10px">/ask another mm agent: child mm -acp, ACP client side</font>" 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="<b>internal/consent</b><br/><font style="font-size:10px">yolo switch, the four answers, per-session memory, the line mode prompt hook</font>" 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="<b>internal/mcp</b><br/><font style="font-size:10px">MCP clients (stdio, HTTP), their tools wrapped as mm tools</font>" 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="<b>internal/structured</b><br/><font style="font-size:10px">structuredOutput: Go declarations → JSON Schema (go/parser)</font>" 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="<b>internal/agentsmd</b><br/><font style="font-size:10px">the project's AGENTS.md, appended to the system prompt per conversation</font>" 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="<b>internal/elicit</b><br/><font style="font-size:10px">ask_user's questions and answers: normalize, line answers, elicitation form schema</font>" 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) | ||
| 22 | 22 | - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md) |
| 23 | 23 | - [Turn a model's reasoning off](how-to/turn-reasoning-off.md) — `chat_template_kwargs` or `reasoning_effort` in `sampling`, per server |
| 24 | 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 | 26 | - [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 | 27 | - [Add a skill](how-to/add-a-skill.md) |
| 27 | 28 | - [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 | 46 | - [Command line](reference/cli.md) — flags, environment variables, start-up banner |
| 46 | 47 | - [Slash commands](reference/slash-commands.md) — `/quit`, `/abort`, `/compact`, `/new`, `/sessions`, `/resume`, `/help`, keyboard shortcuts, window keys |
| 47 | 48 | - [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 | 50 | - [Skill file format](reference/skill-format.md) |
| 50 | 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 | 68 | - [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 | 69 | - [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 | 70 | - [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 | 72 | - Package diagram (draw.io source): [`docs/diagrams/packages.drawio`](../diagrams/packages.drawio) |
| 71 | 73 | |
| 72 | 74 | ### 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 server | 23 | - [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 editor | 26 | - [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-after | 28 | - [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 banner | 46 | - [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 keys | 47 | - [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 rule | 48 | - [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 it | 68 | - [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 answer | 69 | - [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 limit | 70 | - [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) Explanation | 74 | ### 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.