Decider, no tools by default #45
Merged@k33g wants to merge
feature/decider-no-tools into mainMerged as
3656e23be818.70 files changed
modified
.tickets/issues/0141-for-the-decision-agent-deactivate-automatically.yaml +22 -1 | @@ -10,6 +10,27 @@ updatedAt: 2026-10-24T05:19:45.037Z | ||
| 10 | 10 | labels: |
| 11 | 11 | - priority::urgent |
| 12 | 12 | milestone: v1.0.1 |
| 13 | -body: "" | |
| 13 | +body: | | |
| 14 | + A decider (`decision:` block) never calls a tool, yet today every decider | |
| 15 | + file must repeat `bashTool/editTools/planTool/askUserTool/fetchContentTool: | |
| 16 | + false` and point `skillsDir` at an empty folder, or `config.DecisionConflict` | |
| 17 | + refuses to start (default `skillsDir: skills` in a folder with skills = refused). | |
| 18 | + | |
| 19 | + Decision (2026-10-25): | |
| 20 | + - Built-in tools are turned off AUTOMATICALLY for a decider, silently: | |
| 21 | + bash, read_file/write_file/edit_file, plan, ask_user, fetch_content, | |
| 22 | + read_skill, search_docs, search_memory, save_answer (unload_model already is). | |
| 23 | + - What the user declares EXPLICITLY keeps the current error: mcp servers, | |
| 24 | + lsp servers, mmConfigs (ask_agent and /ask-<n>), `tools:` (declared/wasm). | |
| 25 | + - Done in `assembleTools` (main.go), next to the existing unload_model skip — | |
| 26 | + not in config (AGENT_ASK_USER would re-enable ask_user after a config-side | |
| 27 | + force). MCP/LSP servers are not started for a decider. | |
| 28 | + | |
| 29 | + Done when: a decider file with only provider/model/decision starts with no | |
| 30 | + tool; one with mcp/lsp/mmConfigs/tools: still stops with the error; tests | |
| 31 | + updated (TestDecisionConflictListsTheDeclaredTools, | |
| 32 | + TestADeciderDeclaresNoUnloadTool); docs EN+FR (reference/configuration, | |
| 33 | + how-to/ask-a-decision-model) no longer ask for the `…: false` lines; demos | |
| 34 | + cleaned up. | |
| 14 | 35 | tasks: [] |
| 15 | 36 | comments: [] |
| @@ -10,6 +10,27 @@ updatedAt: 2026-10-24T05:19:45.037Z | |||
| 10 | labels: | 10 | labels: |
| 11 | - priority::urgent | 11 | - priority::urgent |
| 12 | milestone: v1.0.1 | 12 | milestone: v1.0.1 |
| 13 | -body: "" | 13 | +body: | |
| 14 | + A decider (`decision:` block) never calls a tool, yet today every decider | ||
| 15 | + file must repeat `bashTool/editTools/planTool/askUserTool/fetchContentTool: | ||
| 16 | + false` and point `skillsDir` at an empty folder, or `config.DecisionConflict` | ||
| 17 | + refuses to start (default `skillsDir: skills` in a folder with skills = refused). | ||
| 18 | + | ||
| 19 | + Decision (2026-10-25): | ||
| 20 | + - Built-in tools are turned off AUTOMATICALLY for a decider, silently: | ||
| 21 | + bash, read_file/write_file/edit_file, plan, ask_user, fetch_content, | ||
| 22 | + read_skill, search_docs, search_memory, save_answer (unload_model already is). | ||
| 23 | + - What the user declares EXPLICITLY keeps the current error: mcp servers, | ||
| 24 | + lsp servers, mmConfigs (ask_agent and /ask-<n>), `tools:` (declared/wasm). | ||
| 25 | + - Done in `assembleTools` (main.go), next to the existing unload_model skip — | ||
| 26 | + not in config (AGENT_ASK_USER would re-enable ask_user after a config-side | ||
| 27 | + force). MCP/LSP servers are not started for a decider. | ||
| 28 | + | ||
| 29 | + Done when: a decider file with only provider/model/decision starts with no | ||
| 30 | + tool; one with mcp/lsp/mmConfigs/tools: still stops with the error; tests | ||
| 31 | + updated (TestDecisionConflictListsTheDeclaredTools, | ||
| 32 | + TestADeciderDeclaresNoUnloadTool); docs EN+FR (reference/configuration, | ||
| 33 | + how-to/ask-a-decision-model) no longer ask for the `…: false` lines; demos | ||
| 34 | + cleaned up. | ||
| 14 | tasks: [] | 35 | tasks: [] |
| 15 | comments: [] | 36 | comments: [] |
modified
.tickets/issues/0144-when-you-use-memory-how-to-use-the-result.yaml +2 -2 | @@ -1,12 +1,12 @@ | ||
| 1 | 1 | # Managed by IssueSpec. Hand edits are welcome; keep the schema valid. |
| 2 | 2 | id: 144 |
| 3 | 3 | title: When you use /memory how to use the result |
| 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-24T16:59:56.623Z |
| 9 | -updatedAt: 2026-10-24T17:30:00.000Z | |
| 9 | +updatedAt: 2026-10-25T16:50:11.990Z | |
| 10 | 10 | labels: [] |
| 11 | 11 | milestone: v1.0.1 |
| 12 | 12 | related: |
| @@ -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: 144 | 2 | id: 144 |
| 3 | title: When you use /memory how to use the result | 3 | title: When you use /memory how to use the result |
| 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-24T16:59:56.623Z | 8 | createdAt: 2026-10-24T16:59:56.623Z |
| 9 | -updatedAt: 2026-10-24T17:30:00.000Z | 9 | +updatedAt: 2026-10-25T16:50:11.990Z |
| 10 | labels: [] | 10 | labels: [] |
| 11 | milestone: v1.0.1 | 11 | milestone: v1.0.1 |
| 12 | related: | 12 | related: |
added
.tickets/issues/0156-docsearch-dirs-relative-to-the-agent-file.yaml +83 -0 | new file mode 100644 | ||
| @@ -0,0 +1,83 @@ | ||
| 1 | +# Managed by IssueSpec. Hand edits are welcome; keep the schema valid. | |
| 2 | +id: 156 | |
| 3 | +title: "docSearch dirs: allow a path relative to the agent file (@agent/ prefix)" | |
| 4 | +state: open | |
| 5 | +author: | |
| 6 | + name: k33g | |
| 7 | + email: ph.charriere@gmail.com | |
| 8 | +createdAt: 2026-10-25T13:38:47.000Z | |
| 9 | +updatedAt: 2026-10-25T13:38:47.000Z | |
| 10 | +labels: | |
| 11 | + - enhancement | |
| 12 | + - kind::feature | |
| 13 | + - builtin tool | |
| 14 | +body: |+ | |
| 15 | + ## Problème | |
| 16 | + | |
| 17 | + Dans `learning-rust/`, mm tourne dans `workspace/` (le dossier ouvert par Zed) et lit son agent depuis `agent-config/agent.yaml` (`AGENT_CONFIG`, workspace additionnel en lecture seule). La doc à chercher est livrée avec l'agent, dans `agent-config/docs`. | |
| 18 | + | |
| 19 | + Avec `docSearch.dirs: [docs]`, `search_docs` ne trouve rien : un chemin relatif de `docSearch.dirs` est résolu par rapport au **répertoire de travail** (`internal/docsearch/walk.go`, documenté dans `internal/config/docsearch.go`), pas par rapport au fichier d'agent. Vérifié : depuis `workspace/`, `docs` → 0 fichier (missing), chemin absolu → 10 fichiers. | |
| 20 | + | |
| 21 | + Contournement actuel : un chemin absolu dans `agent.yaml` (marche parce que le sandbox monte les dossiers au même chemin que sur l'hôte), qui casse si on déplace le dossier. | |
| 22 | + | |
| 23 | + ## Ce qui existe déjà | |
| 24 | + | |
| 25 | + mm ancre déjà certains chemins relatifs sur le dossier du fichier d'agent, au chargement (`internal/config/config.go`, ~l. 715) : `resolveToolPaths` (modules wasm), `resolveAgentPaths` (`mmConfigs`), `resolveHooks`. `docSearch.dirs` est le seul à suivre le répertoire de travail. La config ne fait aucune expansion de variable d'environnement. | |
| 26 | + | |
| 27 | + ## Proposition (recommandée) : un préfixe explicite `@agent/` | |
| 28 | + | |
| 29 | + ```yaml | |
| 30 | + docSearch: | |
| 31 | + dirs: ["@agent/docs", docs] # la doc livrée avec l'agent + celle du projet courant | |
| 32 | + ``` | |
| 33 | + | |
| 34 | + - `@agent/<chemin>` → résolu en absolu sur le dossier du fichier d'agent, au chargement (`resolveDocSearchPaths(path)` à côté des autres `resolve*`). | |
| 35 | + - Sans préfixe : comportement inchangé (répertoire de travail). Chemin absolu : inchangé. | |
| 36 | + - Rien ne casse, et les deux sources se combinent. | |
| 37 | + | |
| 38 | + Alternative écartée : résoudre tous les chemins relatifs sur le dossier de l'agent — casse un `agent.yaml` partagé dont `dirs: [docs]` veut dire « le docs/ du projet où je suis ». | |
| 39 | + | |
| 40 | + ## À décider | |
| 41 | + | |
| 42 | + - Le nom du préfixe (`@agent/`, `agent:`…). Les guillemets sont obligatoires en YAML avec `@`. | |
| 43 | + - Quel nom afficher dans les résultats et dans « missing » : l'entrée telle qu'écrite ou le chemin résolu. | |
| 44 | + | |
| 45 | + ## Fait quand | |
| 46 | + | |
| 47 | + - Résolution au chargement + tests (relatif, préfixé, absolu, dossier manquant). | |
| 48 | + - Commentaire de `DocSearchConfig` et doc de référence EN + FR à jour. | |
| 49 | + - `learning-rust/agent-config/agent.yaml` repasse en `"@agent/docs"`. | |
| 50 | +tasks: | |
| 51 | + - id: 1 | |
| 52 | + title: Resolve "@agent/" entries of docSearch.dirs against the agent file's folder at load time | |
| 53 | + state: open | |
| 54 | + priority: none | |
| 55 | + author: | |
| 56 | + name: k33g | |
| 57 | + email: ph.charriere@gmail.com | |
| 58 | + createdAt: 2026-10-25T13:38:47.000Z | |
| 59 | + - id: 2 | |
| 60 | + title: Tests (relative, prefixed, absolute, missing folder) | |
| 61 | + state: open | |
| 62 | + priority: none | |
| 63 | + author: | |
| 64 | + name: k33g | |
| 65 | + email: ph.charriere@gmail.com | |
| 66 | + createdAt: 2026-10-25T13:38:47.000Z | |
| 67 | + - id: 3 | |
| 68 | + title: Docs EN + FR (DocSearchConfig comment, reference) | |
| 69 | + state: open | |
| 70 | + priority: none | |
| 71 | + author: | |
| 72 | + name: k33g | |
| 73 | + email: ph.charriere@gmail.com | |
| 74 | + createdAt: 2026-10-25T13:38:47.000Z | |
| 75 | + - id: 4 | |
| 76 | + title: Switch learning-rust/agent-config/agent.yaml back to a relative path | |
| 77 | + state: open | |
| 78 | + priority: none | |
| 79 | + author: | |
| 80 | + name: k33g | |
| 81 | + email: ph.charriere@gmail.com | |
| 82 | + createdAt: 2026-10-25T13:38:47.000Z | |
| 83 | +comments: [] | |
| new file mode 100644 | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | +# Managed by IssueSpec. Hand edits are welcome; keep the schema valid. | ||
| 2 | +id: 156 | ||
| 3 | +title: "docSearch dirs: allow a path relative to the agent file (@agent/ prefix)" | ||
| 4 | +state: open | ||
| 5 | +author: | ||
| 6 | + name: k33g | ||
| 7 | + email: ph.charriere@gmail.com | ||
| 8 | +createdAt: 2026-10-25T13:38:47.000Z | ||
| 9 | +updatedAt: 2026-10-25T13:38:47.000Z | ||
| 10 | +labels: | ||
| 11 | + - enhancement | ||
| 12 | + - kind::feature | ||
| 13 | + - builtin tool | ||
| 14 | +body: |+ | ||
| 15 | + ## Problème | ||
| 16 | + | ||
| 17 | + Dans `learning-rust/`, mm tourne dans `workspace/` (le dossier ouvert par Zed) et lit son agent depuis `agent-config/agent.yaml` (`AGENT_CONFIG`, workspace additionnel en lecture seule). La doc à chercher est livrée avec l'agent, dans `agent-config/docs`. | ||
| 18 | + | ||
| 19 | + Avec `docSearch.dirs: [docs]`, `search_docs` ne trouve rien : un chemin relatif de `docSearch.dirs` est résolu par rapport au **répertoire de travail** (`internal/docsearch/walk.go`, documenté dans `internal/config/docsearch.go`), pas par rapport au fichier d'agent. Vérifié : depuis `workspace/`, `docs` → 0 fichier (missing), chemin absolu → 10 fichiers. | ||
| 20 | + | ||
| 21 | + Contournement actuel : un chemin absolu dans `agent.yaml` (marche parce que le sandbox monte les dossiers au même chemin que sur l'hôte), qui casse si on déplace le dossier. | ||
| 22 | + | ||
| 23 | + ## Ce qui existe déjà | ||
| 24 | + | ||
| 25 | + mm ancre déjà certains chemins relatifs sur le dossier du fichier d'agent, au chargement (`internal/config/config.go`, ~l. 715) : `resolveToolPaths` (modules wasm), `resolveAgentPaths` (`mmConfigs`), `resolveHooks`. `docSearch.dirs` est le seul à suivre le répertoire de travail. La config ne fait aucune expansion de variable d'environnement. | ||
| 26 | + | ||
| 27 | + ## Proposition (recommandée) : un préfixe explicite `@agent/` | ||
| 28 | + | ||
| 29 | + ```yaml | ||
| 30 | + docSearch: | ||
| 31 | + dirs: ["@agent/docs", docs] # la doc livrée avec l'agent + celle du projet courant | ||
| 32 | + ``` | ||
| 33 | + | ||
| 34 | + - `@agent/<chemin>` → résolu en absolu sur le dossier du fichier d'agent, au chargement (`resolveDocSearchPaths(path)` à côté des autres `resolve*`). | ||
| 35 | + - Sans préfixe : comportement inchangé (répertoire de travail). Chemin absolu : inchangé. | ||
| 36 | + - Rien ne casse, et les deux sources se combinent. | ||
| 37 | + | ||
| 38 | + Alternative écartée : résoudre tous les chemins relatifs sur le dossier de l'agent — casse un `agent.yaml` partagé dont `dirs: [docs]` veut dire « le docs/ du projet où je suis ». | ||
| 39 | + | ||
| 40 | + ## À décider | ||
| 41 | + | ||
| 42 | + - Le nom du préfixe (`@agent/`, `agent:`…). Les guillemets sont obligatoires en YAML avec `@`. | ||
| 43 | + - Quel nom afficher dans les résultats et dans « missing » : l'entrée telle qu'écrite ou le chemin résolu. | ||
| 44 | + | ||
| 45 | + ## Fait quand | ||
| 46 | + | ||
| 47 | + - Résolution au chargement + tests (relatif, préfixé, absolu, dossier manquant). | ||
| 48 | + - Commentaire de `DocSearchConfig` et doc de référence EN + FR à jour. | ||
| 49 | + - `learning-rust/agent-config/agent.yaml` repasse en `"@agent/docs"`. | ||
| 50 | +tasks: | ||
| 51 | + - id: 1 | ||
| 52 | + title: Resolve "@agent/" entries of docSearch.dirs against the agent file's folder at load time | ||
| 53 | + state: open | ||
| 54 | + priority: none | ||
| 55 | + author: | ||
| 56 | + name: k33g | ||
| 57 | + email: ph.charriere@gmail.com | ||
| 58 | + createdAt: 2026-10-25T13:38:47.000Z | ||
| 59 | + - id: 2 | ||
| 60 | + title: Tests (relative, prefixed, absolute, missing folder) | ||
| 61 | + state: open | ||
| 62 | + priority: none | ||
| 63 | + author: | ||
| 64 | + name: k33g | ||
| 65 | + email: ph.charriere@gmail.com | ||
| 66 | + createdAt: 2026-10-25T13:38:47.000Z | ||
| 67 | + - id: 3 | ||
| 68 | + title: Docs EN + FR (DocSearchConfig comment, reference) | ||
| 69 | + state: open | ||
| 70 | + priority: none | ||
| 71 | + author: | ||
| 72 | + name: k33g | ||
| 73 | + email: ph.charriere@gmail.com | ||
| 74 | + createdAt: 2026-10-25T13:38:47.000Z | ||
| 75 | + - id: 4 | ||
| 76 | + title: Switch learning-rust/agent-config/agent.yaml back to a relative path | ||
| 77 | + state: open | ||
| 78 | + priority: none | ||
| 79 | + author: | ||
| 80 | + name: k33g | ||
| 81 | + email: ph.charriere@gmail.com | ||
| 82 | + createdAt: 2026-10-25T13:38:47.000Z | ||
| 83 | +comments: [] | ||
modified
decision_wiring_test.go +65 -5 | @@ -16,6 +16,7 @@ import ( | ||
| 16 | 16 | "mm/internal/config" |
| 17 | 17 | "mm/internal/decide" |
| 18 | 18 | "mm/internal/engine" |
| 19 | + "mm/internal/skills" | |
| 19 | 20 | ) |
| 20 | 21 | |
| 21 | 22 | const deciderAnswer = `{"model":"d1","answers":{"destructive":{"type":"noul","noul":0.91}}}` |
| @@ -74,16 +75,75 @@ func TestAFailedDecisionPromptExitsOneWithTheReasonOnStderr(t *testing.T) { | ||
| 74 | 75 | } |
| 75 | 76 | } |
| 76 | 77 | |
| 77 | -// A decider declares no tool; unload_model is on by default and would make | |
| 78 | -// DecisionConflict refuse every decider that does not turn it off. | |
| 79 | -func TestADeciderDeclaresNoUnloadTool(t *testing.T) { | |
| 78 | +// Ticket 141: a decider gets no tool and no skill catalogue, even with every | |
| 79 | +// built-in switched on and a skills directory that holds a skill — its file | |
| 80 | +// needs no `bashTool: false` lines. | |
| 81 | +func TestADeciderGetsNoToolWhateverTheBuiltInSwitchesSay(t *testing.T) { | |
| 82 | + skillsDir := t.TempDir() | |
| 83 | + if err := os.WriteFile(filepath.Join(skillsDir, "go-rename.md"), []byte("---\nname: go-rename\ndescription: rename a symbol\n---\n"), 0o644); err != nil { | |
| 84 | + t.Fatal(err) | |
| 85 | + } | |
| 80 | 86 | withConfig(t, func(c *config.Config) { |
| 81 | - c.BashTool, c.EditTools, c.PlanTool, c.FetchContentTool, c.AskUserTool = false, false, false, false, false | |
| 87 | + c.BashTool, c.EditTools, c.PlanTool, c.AskUserTool = true, true, true, true | |
| 88 | + c.FetchContentTool, c.SaveAnswerTool, c.UnloadModels = true, true, true | |
| 82 | 89 | c.Decision = &config.DecisionConfig{} |
| 83 | 90 | }) |
| 84 | - if names := assembledNames(t); slices.Contains(names, "unload_model") || config.DecisionConflict(names) != nil { | |
| 91 | + config.Cfg.SkillsDir = skillsDir | |
| 92 | + if names := assembledNames(t); len(names) != 0 { | |
| 85 | 93 | t.Errorf("a decider declares %v", names) |
| 86 | 94 | } |
| 95 | + if declared := skills.Declared(); len(declared) != 0 { | |
| 96 | + t.Errorf("a decider declares the skills %v", declared) | |
| 97 | + } | |
| 98 | +} | |
| 99 | + | |
| 100 | +// The same switches on a chat agent do declare tools: the short-circuit is | |
| 101 | +// for deciders only. | |
| 102 | +func TestAChatAgentStillGetsItsBuiltInTools(t *testing.T) { | |
| 103 | + withConfig(t, func(c *config.Config) { c.BashTool, c.PlanTool = true, true }) | |
| 104 | + if names := assembledNames(t); !slices.Contains(names, "bash") || !slices.Contains(names, "plan") { | |
| 105 | + t.Errorf("a chat agent declares %v", names) | |
| 106 | + } | |
| 107 | +} | |
| 108 | + | |
| 109 | +// Ticket 141: the decider an agent routes with is not the running agent. | |
| 110 | +// A chat agent whose skillRouting.decider is a decider file written the new | |
| 111 | +// way (no `bashTool: false` lines) keeps every tool and its skill catalogue, | |
| 112 | +// in the order main runs the checks. | |
| 113 | +func TestAChatAgentRoutingThroughADeciderKeepsItsTools(t *testing.T) { | |
| 114 | + dir := t.TempDir() | |
| 115 | + decider := filepath.Join(dir, "agent.decider.yaml") | |
| 116 | + body := "provider: llmman\nmodel: d1\nbaseUrl: http://127.0.0.1:1/v1\nfallback: \"\"\n" + | |
| 117 | + "decision:\n questions:\n destructive:\n type: noul\n instructions: It deletes data.\n" | |
| 118 | + if err := os.WriteFile(decider, []byte(body), 0o644); err != nil { | |
| 119 | + t.Fatal(err) | |
| 120 | + } | |
| 121 | + skillsDir := t.TempDir() | |
| 122 | + if err := os.WriteFile(filepath.Join(skillsDir, "go-rename.md"), []byte("---\nname: go-rename\ndescription: rename a symbol\n---\n"), 0o644); err != nil { | |
| 123 | + t.Fatal(err) | |
| 124 | + } | |
| 125 | + withConfig(t, func(c *config.Config) { | |
| 126 | + c.BashTool, c.EditTools, c.PlanTool = true, true, true | |
| 127 | + c.SkillRouting.Decider = decider | |
| 128 | + }) | |
| 129 | + config.Cfg.SkillsDir = skillsDir | |
| 130 | + t.Cleanup(func() { decide.SetRouter(nil); routing = "" }) | |
| 131 | + | |
| 132 | + if err := config.DecisionConflict(); err != nil { | |
| 133 | + t.Fatal(err) | |
| 134 | + } | |
| 135 | + names := assembledNames(t) | |
| 136 | + if err := installRouter(); err != nil { | |
| 137 | + t.Fatal(err) | |
| 138 | + } | |
| 139 | + for _, want := range []string{"bash", "read_file", "edit_file", "plan", "read_skill"} { | |
| 140 | + if !slices.Contains(names, want) { | |
| 141 | + t.Errorf("the chat agent lost %s: %v", want, names) | |
| 142 | + } | |
| 143 | + } | |
| 144 | + if len(skills.Declared()) != 1 || config.Cfg.Decision != nil { | |
| 145 | + t.Errorf("skills = %v, Decision = %v", skills.Declared(), config.Cfg.Decision) | |
| 146 | + } | |
| 87 | 147 | } |
| 88 | 148 | |
| 89 | 149 | func TestInstallRouterReadsTheDeciderAndNamesItInTheBanner(t *testing.T) { |
| @@ -16,6 +16,7 @@ import ( | |||
| 16 | "mm/internal/config" | 16 | "mm/internal/config" |
| 17 | "mm/internal/decide" | 17 | "mm/internal/decide" |
| 18 | "mm/internal/engine" | 18 | "mm/internal/engine" |
| 19 | + "mm/internal/skills" | ||
| 19 | ) | 20 | ) |
| 20 | 21 | ||
| 21 | const deciderAnswer = `{"model":"d1","answers":{"destructive":{"type":"noul","noul":0.91}}}` | 22 | const deciderAnswer = `{"model":"d1","answers":{"destructive":{"type":"noul","noul":0.91}}}` |
| @@ -74,16 +75,75 @@ func TestAFailedDecisionPromptExitsOneWithTheReasonOnStderr(t *testing.T) { | |||
| 74 | } | 75 | } |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | -// A decider declares no tool; unload_model is on by default and would make | 78 | +// Ticket 141: a decider gets no tool and no skill catalogue, even with every |
| 78 | -// DecisionConflict refuse every decider that does not turn it off. | 79 | +// built-in switched on and a skills directory that holds a skill — its file |
| 79 | -func TestADeciderDeclaresNoUnloadTool(t *testing.T) { | 80 | +// needs no `bashTool: false` lines. |
| 81 | +func TestADeciderGetsNoToolWhateverTheBuiltInSwitchesSay(t *testing.T) { | ||
| 82 | + skillsDir := t.TempDir() | ||
| 83 | + if err := os.WriteFile(filepath.Join(skillsDir, "go-rename.md"), []byte("---\nname: go-rename\ndescription: rename a symbol\n---\n"), 0o644); err != nil { | ||
| 84 | + t.Fatal(err) | ||
| 85 | + } | ||
| 80 | withConfig(t, func(c *config.Config) { | 86 | withConfig(t, func(c *config.Config) { |
| 81 | - c.BashTool, c.EditTools, c.PlanTool, c.FetchContentTool, c.AskUserTool = false, false, false, false, false | 87 | + c.BashTool, c.EditTools, c.PlanTool, c.AskUserTool = true, true, true, true |
| 88 | + c.FetchContentTool, c.SaveAnswerTool, c.UnloadModels = true, true, true | ||
| 82 | c.Decision = &config.DecisionConfig{} | 89 | c.Decision = &config.DecisionConfig{} |
| 83 | }) | 90 | }) |
| 84 | - if names := assembledNames(t); slices.Contains(names, "unload_model") || config.DecisionConflict(names) != nil { | 91 | + config.Cfg.SkillsDir = skillsDir |
| 92 | + if names := assembledNames(t); len(names) != 0 { | ||
| 85 | t.Errorf("a decider declares %v", names) | 93 | t.Errorf("a decider declares %v", names) |
| 86 | } | 94 | } |
| 95 | + if declared := skills.Declared(); len(declared) != 0 { | ||
| 96 | + t.Errorf("a decider declares the skills %v", declared) | ||
| 97 | + } | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +// The same switches on a chat agent do declare tools: the short-circuit is | ||
| 101 | +// for deciders only. | ||
| 102 | +func TestAChatAgentStillGetsItsBuiltInTools(t *testing.T) { | ||
| 103 | + withConfig(t, func(c *config.Config) { c.BashTool, c.PlanTool = true, true }) | ||
| 104 | + if names := assembledNames(t); !slices.Contains(names, "bash") || !slices.Contains(names, "plan") { | ||
| 105 | + t.Errorf("a chat agent declares %v", names) | ||
| 106 | + } | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +// Ticket 141: the decider an agent routes with is not the running agent. | ||
| 110 | +// A chat agent whose skillRouting.decider is a decider file written the new | ||
| 111 | +// way (no `bashTool: false` lines) keeps every tool and its skill catalogue, | ||
| 112 | +// in the order main runs the checks. | ||
| 113 | +func TestAChatAgentRoutingThroughADeciderKeepsItsTools(t *testing.T) { | ||
| 114 | + dir := t.TempDir() | ||
| 115 | + decider := filepath.Join(dir, "agent.decider.yaml") | ||
| 116 | + body := "provider: llmman\nmodel: d1\nbaseUrl: http://127.0.0.1:1/v1\nfallback: \"\"\n" + | ||
| 117 | + "decision:\n questions:\n destructive:\n type: noul\n instructions: It deletes data.\n" | ||
| 118 | + if err := os.WriteFile(decider, []byte(body), 0o644); err != nil { | ||
| 119 | + t.Fatal(err) | ||
| 120 | + } | ||
| 121 | + skillsDir := t.TempDir() | ||
| 122 | + if err := os.WriteFile(filepath.Join(skillsDir, "go-rename.md"), []byte("---\nname: go-rename\ndescription: rename a symbol\n---\n"), 0o644); err != nil { | ||
| 123 | + t.Fatal(err) | ||
| 124 | + } | ||
| 125 | + withConfig(t, func(c *config.Config) { | ||
| 126 | + c.BashTool, c.EditTools, c.PlanTool = true, true, true | ||
| 127 | + c.SkillRouting.Decider = decider | ||
| 128 | + }) | ||
| 129 | + config.Cfg.SkillsDir = skillsDir | ||
| 130 | + t.Cleanup(func() { decide.SetRouter(nil); routing = "" }) | ||
| 131 | + | ||
| 132 | + if err := config.DecisionConflict(); err != nil { | ||
| 133 | + t.Fatal(err) | ||
| 134 | + } | ||
| 135 | + names := assembledNames(t) | ||
| 136 | + if err := installRouter(); err != nil { | ||
| 137 | + t.Fatal(err) | ||
| 138 | + } | ||
| 139 | + for _, want := range []string{"bash", "read_file", "edit_file", "plan", "read_skill"} { | ||
| 140 | + if !slices.Contains(names, want) { | ||
| 141 | + t.Errorf("the chat agent lost %s: %v", want, names) | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + if len(skills.Declared()) != 1 || config.Cfg.Decision != nil { | ||
| 145 | + t.Errorf("skills = %v, Decision = %v", skills.Declared(), config.Cfg.Decision) | ||
| 146 | + } | ||
| 87 | } | 147 | } |
| 88 | 148 | ||
| 89 | func TestInstallRouterReadsTheDeciderAndNamesItInTheBanner(t *testing.T) { | 149 | func TestInstallRouterReadsTheDeciderAndNamesItInTheBanner(t *testing.T) { |
modified
demos/decision-ask-check/agent.decider.yaml +2 -7 | @@ -15,13 +15,8 @@ decision: | ||
| 15 | 15 | type: noul |
| 16 | 16 | instructions: The answer addresses the question that was asked. |
| 17 | 17 | |
| 18 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 19 | -bashTool: false | |
| 20 | -editTools: false | |
| 21 | -planTool: false | |
| 22 | -fetchContentTool: false | |
| 23 | -askUserTool: false | |
| 24 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 18 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 19 | +# skills off by itself (no `…: false` lines needed). | |
| 25 | 20 | agentsMd: |
| 26 | 21 | enabled: false |
| 27 | 22 | |
| @@ -15,13 +15,8 @@ decision: | |||
| 15 | type: noul | 15 | type: noul |
| 16 | instructions: The answer addresses the question that was asked. | 16 | instructions: The answer addresses the question that was asked. |
| 17 | 17 | ||
| 18 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 18 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 19 | -bashTool: false | 19 | +# skills off by itself (no `…: false` lines needed). |
| 20 | -editTools: false | ||
| 21 | -planTool: false | ||
| 22 | -fetchContentTool: false | ||
| 23 | -askUserTool: false | ||
| 24 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 25 | agentsMd: | 20 | agentsMd: |
| 26 | enabled: false | 21 | enabled: false |
| 27 | 22 | ||
modified
demos/decision-chat-golang/agent.decider.yaml +2 -7 | @@ -38,12 +38,7 @@ decision: | ||
| 38 | 38 | type: noul |
| 39 | 39 | instructions: The message asks for code, an example, a function or a snippet. |
| 40 | 40 | |
| 41 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 42 | -bashTool: false | |
| 43 | -editTools: false | |
| 44 | -planTool: false | |
| 45 | -fetchContentTool: false | |
| 46 | -askUserTool: false | |
| 47 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 41 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 42 | +# skills off by itself (no `…: false` lines needed). | |
| 48 | 43 | agentsMd: |
| 49 | 44 | enabled: false |
| @@ -38,12 +38,7 @@ decision: | |||
| 38 | type: noul | 38 | type: noul |
| 39 | instructions: The message asks for code, an example, a function or a snippet. | 39 | instructions: The message asks for code, an example, a function or a snippet. |
| 40 | 40 | ||
| 41 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 41 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 42 | -bashTool: false | 42 | +# skills off by itself (no `…: false` lines needed). |
| 43 | -editTools: false | ||
| 44 | -planTool: false | ||
| 45 | -fetchContentTool: false | ||
| 46 | -askUserTool: false | ||
| 47 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 48 | agentsMd: | 43 | agentsMd: |
| 49 | enabled: false | 44 | enabled: false |
modified
demos/decision-chat/agent.decider.yaml +2 -7 | @@ -34,12 +34,7 @@ decision: | ||
| 34 | 34 | type: noul |
| 35 | 35 | instructions: The person is worried, stressed or upset. |
| 36 | 36 | |
| 37 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 38 | -bashTool: false | |
| 39 | -editTools: false | |
| 40 | -planTool: false | |
| 41 | -fetchContentTool: false | |
| 42 | -askUserTool: false | |
| 43 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 37 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 38 | +# skills off by itself (no `…: false` lines needed). | |
| 44 | 39 | agentsMd: |
| 45 | 40 | enabled: false |
| @@ -34,12 +34,7 @@ decision: | |||
| 34 | type: noul | 34 | type: noul |
| 35 | instructions: The person is worried, stressed or upset. | 35 | instructions: The person is worried, stressed or upset. |
| 36 | 36 | ||
| 37 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 37 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 38 | -bashTool: false | 38 | +# skills off by itself (no `…: false` lines needed). |
| 39 | -editTools: false | ||
| 40 | -planTool: false | ||
| 41 | -fetchContentTool: false | ||
| 42 | -askUserTool: false | ||
| 43 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 44 | agentsMd: | 39 | agentsMd: |
| 45 | enabled: false | 40 | enabled: false |
modified
demos/decision-commands/agent.decider.yaml +2 -7 | @@ -26,12 +26,7 @@ decision: | ||
| 26 | 26 | type: noul |
| 27 | 27 | instructions: The command deletes data that cannot be rebuilt. |
| 28 | 28 | |
| 29 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 30 | -bashTool: false | |
| 31 | -editTools: false | |
| 32 | -planTool: false | |
| 33 | -fetchContentTool: false | |
| 34 | -askUserTool: false | |
| 35 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 29 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 30 | +# skills off by itself (no `…: false` lines needed). | |
| 36 | 31 | agentsMd: |
| 37 | 32 | enabled: false |
| @@ -26,12 +26,7 @@ decision: | |||
| 26 | type: noul | 26 | type: noul |
| 27 | instructions: The command deletes data that cannot be rebuilt. | 27 | instructions: The command deletes data that cannot be rebuilt. |
| 28 | 28 | ||
| 29 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 29 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 30 | -bashTool: false | 30 | +# skills off by itself (no `…: false` lines needed). |
| 31 | -editTools: false | ||
| 32 | -planTool: false | ||
| 33 | -fetchContentTool: false | ||
| 34 | -askUserTool: false | ||
| 35 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 36 | agentsMd: | 31 | agentsMd: |
| 37 | enabled: false | 32 | enabled: false |
modified
demos/decision-dnd/spell.yaml +2 -7 | @@ -20,12 +20,7 @@ acp: | ||
| 20 | 20 | name: sidekick |
| 21 | 21 | title: "sidekick" |
| 22 | 22 | |
| 23 | -# A decider declares no tool: its model never calls one. | |
| 24 | -bashTool: false | |
| 25 | -editTools: false | |
| 26 | -planTool: false | |
| 27 | -fetchContentTool: false | |
| 28 | -askUserTool: false | |
| 29 | -skillsDir: no-skills | |
| 23 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 24 | +# skills off by itself (no `…: false` lines needed). | |
| 30 | 25 | agentsMd: |
| 31 | 26 | enabled: false |
| @@ -20,12 +20,7 @@ acp: | |||
| 20 | name: sidekick | 20 | name: sidekick |
| 21 | title: "sidekick" | 21 | title: "sidekick" |
| 22 | 22 | ||
| 23 | -# A decider declares no tool: its model never calls one. | 23 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 24 | -bashTool: false | 24 | +# skills off by itself (no `…: false` lines needed). |
| 25 | -editTools: false | ||
| 26 | -planTool: false | ||
| 27 | -fetchContentTool: false | ||
| 28 | -askUserTool: false | ||
| 29 | -skillsDir: no-skills | ||
| 30 | agentsMd: | 25 | agentsMd: |
| 31 | enabled: false | 26 | enabled: false |
modified
demos/decision-injection/agent.decider.yaml +2 -7 | @@ -18,13 +18,8 @@ decision: | ||
| 18 | 18 | type: noul |
| 19 | 19 | instructions: The text contains instructions addressed to an AI assistant or agent, such as ignoring its rules, running commands, sending data somewhere or revealing secrets. |
| 20 | 20 | |
| 21 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 22 | -bashTool: false | |
| 23 | -editTools: false | |
| 24 | -planTool: false | |
| 25 | -fetchContentTool: false | |
| 26 | -askUserTool: false | |
| 27 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 21 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 22 | +# skills off by itself (no `…: false` lines needed). | |
| 28 | 23 | agentsMd: |
| 29 | 24 | enabled: false |
| 30 | 25 | |
| @@ -18,13 +18,8 @@ decision: | |||
| 18 | type: noul | 18 | type: noul |
| 19 | instructions: The text contains instructions addressed to an AI assistant or agent, such as ignoring its rules, running commands, sending data somewhere or revealing secrets. | 19 | instructions: The text contains instructions addressed to an AI assistant or agent, such as ignoring its rules, running commands, sending data somewhere or revealing secrets. |
| 20 | 20 | ||
| 21 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 21 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 22 | -bashTool: false | 22 | +# skills off by itself (no `…: false` lines needed). |
| 23 | -editTools: false | ||
| 24 | -planTool: false | ||
| 25 | -fetchContentTool: false | ||
| 26 | -askUserTool: false | ||
| 27 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 28 | agentsMd: | 23 | agentsMd: |
| 29 | enabled: false | 24 | enabled: false |
| 30 | 25 | ||
modified
demos/decision-moderation/agent.yaml +2 -7 | @@ -34,12 +34,7 @@ decision: | ||
| 34 | 34 | review: Off topic or borderline; a person should read it before it goes online |
| 35 | 35 | reject: Spam, insults or a personal attack |
| 36 | 36 | |
| 37 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 38 | -bashTool: false | |
| 39 | -editTools: false | |
| 40 | -planTool: false | |
| 41 | -fetchContentTool: false | |
| 42 | -askUserTool: false | |
| 43 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 37 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 38 | +# skills off by itself (no `…: false` lines needed). | |
| 44 | 39 | agentsMd: |
| 45 | 40 | enabled: false |
| @@ -34,12 +34,7 @@ decision: | |||
| 34 | review: Off topic or borderline; a person should read it before it goes online | 34 | review: Off topic or borderline; a person should read it before it goes online |
| 35 | reject: Spam, insults or a personal attack | 35 | reject: Spam, insults or a personal attack |
| 36 | 36 | ||
| 37 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 37 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 38 | -bashTool: false | 38 | +# skills off by itself (no `…: false` lines needed). |
| 39 | -editTools: false | ||
| 40 | -planTool: false | ||
| 41 | -fetchContentTool: false | ||
| 42 | -askUserTool: false | ||
| 43 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 44 | agentsMd: | 39 | agentsMd: |
| 45 | enabled: false | 40 | enabled: false |
modified
demos/decision-only/agent.yaml +2 -7 | @@ -37,12 +37,7 @@ decision: | ||
| 37 | 37 | type: noul |
| 38 | 38 | instructions: The author of the message is angry or upset. |
| 39 | 39 | |
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 41 | -bashTool: false | |
| 42 | -editTools: false | |
| 43 | -planTool: false | |
| 44 | -fetchContentTool: false | |
| 45 | -askUserTool: false | |
| 46 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 41 | +# skills off by itself (no `…: false` lines needed). | |
| 47 | 42 | agentsMd: |
| 48 | 43 | enabled: false |
| @@ -37,12 +37,7 @@ decision: | |||
| 37 | type: noul | 37 | type: noul |
| 38 | instructions: The author of the message is angry or upset. | 38 | instructions: The author of the message is angry or upset. |
| 39 | 39 | ||
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 41 | -bashTool: false | 41 | +# skills off by itself (no `…: false` lines needed). |
| 42 | -editTools: false | ||
| 43 | -planTool: false | ||
| 44 | -fetchContentTool: false | ||
| 45 | -askUserTool: false | ||
| 46 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 47 | agentsMd: | 42 | agentsMd: |
| 48 | enabled: false | 43 | enabled: false |
modified
demos/decision-questions/dice421.yaml +2 -7 | @@ -20,12 +20,7 @@ decision: | ||
| 20 | 20 | two: Two dice are missing |
| 21 | 21 | all: All three are missing |
| 22 | 22 | |
| 23 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 24 | -bashTool: false | |
| 25 | -editTools: false | |
| 26 | -planTool: false | |
| 27 | -fetchContentTool: false | |
| 28 | -askUserTool: false | |
| 29 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 23 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 24 | +# skills off by itself (no `…: false` lines needed). | |
| 30 | 25 | agentsMd: |
| 31 | 26 | enabled: false |
| @@ -20,12 +20,7 @@ decision: | |||
| 20 | two: Two dice are missing | 20 | two: Two dice are missing |
| 21 | all: All three are missing | 21 | all: All three are missing |
| 22 | 22 | ||
| 23 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 23 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 24 | -bashTool: false | 24 | +# skills off by itself (no `…: false` lines needed). |
| 25 | -editTools: false | ||
| 26 | -planTool: false | ||
| 27 | -fetchContentTool: false | ||
| 28 | -askUserTool: false | ||
| 29 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 30 | agentsMd: | 25 | agentsMd: |
| 31 | enabled: false | 26 | enabled: false |
modified
demos/decision-questions/fight.yaml +2 -7 | @@ -26,12 +26,7 @@ decision: | ||
| 26 | 26 | type: noul |
| 27 | 27 | instructions: My character is badly hurt. |
| 28 | 28 | |
| 29 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 30 | -bashTool: false | |
| 31 | -editTools: false | |
| 32 | -planTool: false | |
| 33 | -fetchContentTool: false | |
| 34 | -askUserTool: false | |
| 35 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 29 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 30 | +# skills off by itself (no `…: false` lines needed). | |
| 36 | 31 | agentsMd: |
| 37 | 32 | enabled: false |
| @@ -26,12 +26,7 @@ decision: | |||
| 26 | type: noul | 26 | type: noul |
| 27 | instructions: My character is badly hurt. | 27 | instructions: My character is badly hurt. |
| 28 | 28 | ||
| 29 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 29 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 30 | -bashTool: false | 30 | +# skills off by itself (no `…: false` lines needed). |
| 31 | -editTools: false | ||
| 32 | -planTool: false | ||
| 33 | -fetchContentTool: false | ||
| 34 | -askUserTool: false | ||
| 35 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 36 | agentsMd: | 31 | agentsMd: |
| 37 | enabled: false | 32 | enabled: false |
modified
demos/decision-questions/spell.yaml +2 -7 | @@ -21,12 +21,7 @@ decision: | ||
| 21 | 21 | misty_step: I am surrounded or grabbed and must get away |
| 22 | 22 | sleep: Several weak enemies, and we would rather not kill them |
| 23 | 23 | |
| 24 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 25 | -bashTool: false | |
| 26 | -editTools: false | |
| 27 | -planTool: false | |
| 28 | -fetchContentTool: false | |
| 29 | -askUserTool: false | |
| 30 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 24 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 25 | +# skills off by itself (no `…: false` lines needed). | |
| 31 | 26 | agentsMd: |
| 32 | 27 | enabled: false |
| @@ -21,12 +21,7 @@ decision: | |||
| 21 | misty_step: I am surrounded or grabbed and must get away | 21 | misty_step: I am surrounded or grabbed and must get away |
| 22 | sleep: Several weak enemies, and we would rather not kill them | 22 | sleep: Several weak enemies, and we would rather not kill them |
| 23 | 23 | ||
| 24 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 24 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 25 | -bashTool: false | 25 | +# skills off by itself (no `…: false` lines needed). |
| 26 | -editTools: false | ||
| 27 | -planTool: false | ||
| 28 | -fetchContentTool: false | ||
| 29 | -askUserTool: false | ||
| 30 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 31 | agentsMd: | 26 | agentsMd: |
| 32 | enabled: false | 27 | enabled: false |
modified
demos/decision-questions/symptoms.yaml +2 -7 | @@ -27,12 +27,7 @@ decision: | ||
| 27 | 27 | specialist: A known long-term condition followed by a specialist |
| 28 | 28 | emergency: A problem that cannot wait |
| 29 | 29 | |
| 30 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 31 | -bashTool: false | |
| 32 | -editTools: false | |
| 33 | -planTool: false | |
| 34 | -fetchContentTool: false | |
| 35 | -askUserTool: false | |
| 36 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 30 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 31 | +# skills off by itself (no `…: false` lines needed). | |
| 37 | 32 | agentsMd: |
| 38 | 33 | enabled: false |
| @@ -27,12 +27,7 @@ decision: | |||
| 27 | specialist: A known long-term condition followed by a specialist | 27 | specialist: A known long-term condition followed by a specialist |
| 28 | emergency: A problem that cannot wait | 28 | emergency: A problem that cannot wait |
| 29 | 29 | ||
| 30 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 30 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 31 | -bashTool: false | 31 | +# skills off by itself (no `…: false` lines needed). |
| 32 | -editTools: false | ||
| 33 | -planTool: false | ||
| 34 | -fetchContentTool: false | ||
| 35 | -askUserTool: false | ||
| 36 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 37 | agentsMd: | 32 | agentsMd: |
| 38 | enabled: false | 33 | enabled: false |
modified
demos/decision-reviews/agent.yaml +2 -7 | @@ -37,12 +37,7 @@ decision: | ||
| 37 | 37 | type: noul |
| 38 | 38 | instructions: The author would recommend this product to a friend. |
| 39 | 39 | |
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 41 | -bashTool: false | |
| 42 | -editTools: false | |
| 43 | -planTool: false | |
| 44 | -fetchContentTool: false | |
| 45 | -askUserTool: false | |
| 46 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 41 | +# skills off by itself (no `…: false` lines needed). | |
| 47 | 42 | agentsMd: |
| 48 | 43 | enabled: false |
| @@ -37,12 +37,7 @@ decision: | |||
| 37 | type: noul | 37 | type: noul |
| 38 | instructions: The author would recommend this product to a friend. | 38 | instructions: The author would recommend this product to a friend. |
| 39 | 39 | ||
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 41 | -bashTool: false | 41 | +# skills off by itself (no `…: false` lines needed). |
| 42 | -editTools: false | ||
| 43 | -planTool: false | ||
| 44 | -fetchContentTool: false | ||
| 45 | -askUserTool: false | ||
| 46 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 47 | agentsMd: | 42 | agentsMd: |
| 48 | enabled: false | 43 | enabled: false |
modified
demos/decision-skills/agent.decider.yaml +2 -7 | @@ -37,12 +37,7 @@ decision: | ||
| 37 | 37 | instructions: How carefully should a person review this command before it runs? |
| 38 | 38 | criteria: [no review needed, a quick look, a careful review] |
| 39 | 39 | |
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 41 | -bashTool: false | |
| 42 | -editTools: false | |
| 43 | -planTool: false | |
| 44 | -fetchContentTool: false | |
| 45 | -askUserTool: false | |
| 46 | -skillsDir: no-skills | |
| 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 41 | +# skills off by itself (no `…: false` lines needed). | |
| 47 | 42 | agentsMd: |
| 48 | 43 | enabled: false |
| @@ -37,12 +37,7 @@ decision: | |||
| 37 | instructions: How carefully should a person review this command before it runs? | 37 | instructions: How carefully should a person review this command before it runs? |
| 38 | criteria: [no review needed, a quick look, a careful review] | 38 | criteria: [no review needed, a quick look, a careful review] |
| 39 | 39 | ||
| 40 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 40 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 41 | -bashTool: false | 41 | +# skills off by itself (no `…: false` lines needed). |
| 42 | -editTools: false | ||
| 43 | -planTool: false | ||
| 44 | -fetchContentTool: false | ||
| 45 | -askUserTool: false | ||
| 46 | -skillsDir: no-skills | ||
| 47 | agentsMd: | 42 | agentsMd: |
| 48 | enabled: false | 43 | enabled: false |
modified
demos/decision-tool-errors/agent.decider.yaml +2 -7 | @@ -23,13 +23,8 @@ decision: | ||
| 23 | 23 | nothing-found: The command worked but found nothing or reported differences |
| 24 | 24 | error: The output shows an error, an exception or a failed test |
| 25 | 25 | |
| 26 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | |
| 27 | -bashTool: false | |
| 28 | -editTools: false | |
| 29 | -planTool: false | |
| 30 | -fetchContentTool: false | |
| 31 | -askUserTool: false | |
| 32 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | |
| 26 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and | |
| 27 | +# skills off by itself (no `…: false` lines needed). | |
| 33 | 28 | agentsMd: |
| 34 | 29 | enabled: false |
| 35 | 30 | |
| @@ -23,13 +23,8 @@ decision: | |||
| 23 | nothing-found: The command worked but found nothing or reported differences | 23 | nothing-found: The command worked but found nothing or reported differences |
| 24 | error: The output shows an error, an exception or a failed test | 24 | error: The output shows an error, an exception or a failed test |
| 25 | 25 | ||
| 26 | -# A decider declares no tool: its model never calls one (mm refuses to start otherwise). | 26 | +# A decider gets no tool: mm turns bash, the file tools, plan, ask_user and |
| 27 | -bashTool: false | 27 | +# skills off by itself (no `…: false` lines needed). |
| 28 | -editTools: false | ||
| 29 | -planTool: false | ||
| 30 | -fetchContentTool: false | ||
| 31 | -askUserTool: false | ||
| 32 | -skillsDir: no-skills # "" would read ./skills of wherever mm runs, and a decider refuses tools | ||
| 33 | agentsMd: | 28 | agentsMd: |
| 34 | enabled: false | 29 | enabled: false |
| 35 | 30 | ||
modified
dev.team/team/agent.coder.yaml +9 -2 | @@ -9,7 +9,9 @@ | ||
| 9 | 9 | # The tutor uses the same model: going from one to the other reloads nothing. |
| 10 | 10 | |
| 11 | 11 | provider: llmman |
| 12 | -model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 12 | +#model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 13 | +#model: hf.co/unsloth/Qwen3.6-35B-A3B-GGUF | |
| 14 | +model: hf.co/unsloth/Qwen3.8-27B-GGUF | |
| 13 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 14 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 15 | 17 | |
| @@ -30,13 +32,18 @@ sampling: | ||
| 30 | 32 | parallel_tool_calls: false |
| 31 | 33 | # No chat_template_kwargs: the Instruct template has no reasoning switch. |
| 32 | 34 | |
| 35 | + chat_template_kwargs: | |
| 36 | + enable_thinking: true | |
| 37 | + reasoning_effort: low | |
| 38 | + | |
| 39 | + | |
| 33 | 40 | firstTokenTimeout: 3m |
| 34 | 41 | # With bash on, the watchdog follows bashTimeout (settings guide, section 3). |
| 35 | 42 | watchdogTimeout: 2m |
| 36 | 43 | bashTimeout: 2m |
| 37 | 44 | |
| 38 | 45 | # Read, change, test, fix: a bug fix takes ~6 calls, a feature ~12. |
| 39 | -maxTurns: 30 | |
| 46 | +maxTurns: 60 | |
| 40 | 47 | maxOutput: 12000 |
| 41 | 48 | previewLines: 10 |
| 42 | 49 | displayCommands: true |
| @@ -9,7 +9,9 @@ | |||
| 9 | # The tutor uses the same model: going from one to the other reloads nothing. | 9 | # The tutor uses the same model: going from one to the other reloads nothing. |
| 10 | 10 | ||
| 11 | provider: llmman | 11 | provider: llmman |
| 12 | -model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | 12 | +#model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M |
| 13 | +#model: hf.co/unsloth/Qwen3.6-35B-A3B-GGUF | ||
| 14 | +model: hf.co/unsloth/Qwen3.8-27B-GGUF | ||
| 13 | baseUrl: http://127.0.0.1:17434/v1 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 14 | fallback: http://host.docker.internal:17434/v1 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 15 | 17 | ||
| @@ -30,13 +32,18 @@ sampling: | |||
| 30 | parallel_tool_calls: false | 32 | parallel_tool_calls: false |
| 31 | # No chat_template_kwargs: the Instruct template has no reasoning switch. | 33 | # No chat_template_kwargs: the Instruct template has no reasoning switch. |
| 32 | 34 | ||
| 35 | + chat_template_kwargs: | ||
| 36 | + enable_thinking: true | ||
| 37 | + reasoning_effort: low | ||
| 38 | + | ||
| 39 | + | ||
| 33 | firstTokenTimeout: 3m | 40 | firstTokenTimeout: 3m |
| 34 | # With bash on, the watchdog follows bashTimeout (settings guide, section 3). | 41 | # With bash on, the watchdog follows bashTimeout (settings guide, section 3). |
| 35 | watchdogTimeout: 2m | 42 | watchdogTimeout: 2m |
| 36 | bashTimeout: 2m | 43 | bashTimeout: 2m |
| 37 | 44 | ||
| 38 | # Read, change, test, fix: a bug fix takes ~6 calls, a feature ~12. | 45 | # Read, change, test, fix: a bug fix takes ~6 calls, a feature ~12. |
| 39 | -maxTurns: 30 | 46 | +maxTurns: 60 |
| 40 | maxOutput: 12000 | 47 | maxOutput: 12000 |
| 41 | previewLines: 10 | 48 | previewLines: 10 |
| 42 | displayCommands: true | 49 | displayCommands: true |
modified
dev.team/team/agent.reformulator.yaml +4 -2 | @@ -10,7 +10,8 @@ | ||
| 10 | 10 | # following a fixed output shape. Same model as the reviewer. |
| 11 | 11 | |
| 12 | 12 | provider: llmman |
| 13 | -model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | |
| 13 | +#model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | |
| 14 | +model: hf.co/unsloth/gemma-4-26B-A4B-it-GGUF | |
| 14 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 15 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 16 | 17 | |
| @@ -24,7 +25,8 @@ sampling: | ||
| 24 | 25 | max_tokens: 4096 |
| 25 | 26 | parallel_tool_calls: false |
| 26 | 27 | chat_template_kwargs: |
| 27 | - enable_thinking: false | |
| 28 | + enable_thinking: true | |
| 29 | + reasoning_effort: low | |
| 28 | 30 | |
| 29 | 31 | firstTokenTimeout: 3m |
| 30 | 32 | # A question to the user may wait as long as they take: ask_user keeps the |
| @@ -10,7 +10,8 @@ | |||
| 10 | # following a fixed output shape. Same model as the reviewer. | 10 | # following a fixed output shape. Same model as the reviewer. |
| 11 | 11 | ||
| 12 | provider: llmman | 12 | provider: llmman |
| 13 | -model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | 13 | +#model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M |
| 14 | +model: hf.co/unsloth/gemma-4-26B-A4B-it-GGUF | ||
| 14 | baseUrl: http://127.0.0.1:17434/v1 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 15 | fallback: http://host.docker.internal:17434/v1 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 16 | 17 | ||
| @@ -24,7 +25,8 @@ sampling: | |||
| 24 | max_tokens: 4096 | 25 | max_tokens: 4096 |
| 25 | parallel_tool_calls: false | 26 | parallel_tool_calls: false |
| 26 | chat_template_kwargs: | 27 | chat_template_kwargs: |
| 27 | - enable_thinking: false | 28 | + enable_thinking: true |
| 29 | + reasoning_effort: low | ||
| 28 | 30 | ||
| 29 | firstTokenTimeout: 3m | 31 | firstTokenTimeout: 3m |
| 30 | # A question to the user may wait as long as they take: ask_user keeps the | 32 | # A question to the user may wait as long as they take: ask_user keeps the |
modified
dev.team/team/agent.reviewer.yaml +5 -3 | @@ -10,7 +10,8 @@ | ||
| 10 | 10 | # blind spots. The reformulator uses the same Gemma: no reload between them. |
| 11 | 11 | |
| 12 | 12 | provider: llmman |
| 13 | -model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | |
| 13 | +#model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | |
| 14 | +model: hf.co/unsloth/gemma-4-26B-A4B-it-GGUF | |
| 14 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 15 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 16 | 17 | |
| @@ -27,7 +28,8 @@ sampling: | ||
| 27 | 28 | # The template's switch, default off. A review is reading and running, not |
| 28 | 29 | # long deliberation; off keeps it fast. |
| 29 | 30 | chat_template_kwargs: |
| 30 | - enable_thinking: false | |
| 31 | + enable_thinking: true | |
| 32 | + reasoning_effort: low | |
| 31 | 33 | |
| 32 | 34 | firstTokenTimeout: 3m |
| 33 | 35 | watchdogTimeout: 2m |
| @@ -37,7 +39,7 @@ bashTimeout: 2m | ||
| 37 | 39 | # calls. Measured: 20 let a loop run (on a feature it rewrote its own test |
| 38 | 40 | # and re-read the same lines until the limit); 12 cut a normal review before |
| 39 | 41 | # its verdict. 16. |
| 40 | -maxTurns: 16 | |
| 42 | +maxTurns: 30 | |
| 41 | 43 | maxOutput: 12000 |
| 42 | 44 | previewLines: 10 |
| 43 | 45 | displayCommands: true |
| @@ -10,7 +10,8 @@ | |||
| 10 | # blind spots. The reformulator uses the same Gemma: no reload between them. | 10 | # blind spots. The reformulator uses the same Gemma: no reload between them. |
| 11 | 11 | ||
| 12 | provider: llmman | 12 | provider: llmman |
| 13 | -model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M | 13 | +#model: hf.co/unsloth/gemma-4-12b-it-GGUF:Q4_K_M |
| 14 | +model: hf.co/unsloth/gemma-4-26B-A4B-it-GGUF | ||
| 14 | baseUrl: http://127.0.0.1:17434/v1 | 15 | baseUrl: http://127.0.0.1:17434/v1 |
| 15 | fallback: http://host.docker.internal:17434/v1 | 16 | fallback: http://host.docker.internal:17434/v1 |
| 16 | 17 | ||
| @@ -27,7 +28,8 @@ sampling: | |||
| 27 | # The template's switch, default off. A review is reading and running, not | 28 | # The template's switch, default off. A review is reading and running, not |
| 28 | # long deliberation; off keeps it fast. | 29 | # long deliberation; off keeps it fast. |
| 29 | chat_template_kwargs: | 30 | chat_template_kwargs: |
| 30 | - enable_thinking: false | 31 | + enable_thinking: true |
| 32 | + reasoning_effort: low | ||
| 31 | 33 | ||
| 32 | firstTokenTimeout: 3m | 34 | firstTokenTimeout: 3m |
| 33 | watchdogTimeout: 2m | 35 | watchdogTimeout: 2m |
| @@ -37,7 +39,7 @@ bashTimeout: 2m | |||
| 37 | # calls. Measured: 20 let a loop run (on a feature it rewrote its own test | 39 | # calls. Measured: 20 let a loop run (on a feature it rewrote its own test |
| 38 | # and re-read the same lines until the limit); 12 cut a normal review before | 40 | # and re-read the same lines until the limit); 12 cut a normal review before |
| 39 | # its verdict. 16. | 41 | # its verdict. 16. |
| 40 | -maxTurns: 16 | 42 | +maxTurns: 30 |
| 41 | maxOutput: 12000 | 43 | maxOutput: 12000 |
| 42 | previewLines: 10 | 44 | previewLines: 10 |
| 43 | displayCommands: true | 45 | displayCommands: true |
modified
dev.team/team/agent.tutor.yaml +5 -1 | @@ -11,7 +11,8 @@ | ||
| 11 | 11 | # cd dev.team/workspace && ../../mm -config ../team/agent.tutor.yaml # alone, with sessions |
| 12 | 12 | |
| 13 | 13 | provider: llmman |
| 14 | -model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 14 | +#model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 15 | +model: hf.co/unsloth/Qwen3.6-35B-A3B-GGUF | |
| 15 | 16 | baseUrl: http://127.0.0.1:17434/v1 |
| 16 | 17 | fallback: http://host.docker.internal:17434/v1 |
| 17 | 18 | |
| @@ -28,6 +29,9 @@ sampling: | ||
| 28 | 29 | parallel_tool_calls: false |
| 29 | 30 | # No chat_template_kwargs: the Instruct template has no reasoning switch |
| 30 | 31 | # (the prof's enable_thinking: false was for the Thinking model). |
| 32 | + chat_template_kwargs: | |
| 33 | + enable_thinking: true | |
| 34 | + reasoning_effort: low | |
| 31 | 35 | |
| 32 | 36 | firstTokenTimeout: 3m |
| 33 | 37 | watchdogTimeout: 2m |
| @@ -11,7 +11,8 @@ | |||
| 11 | # cd dev.team/workspace && ../../mm -config ../team/agent.tutor.yaml # alone, with sessions | 11 | # cd dev.team/workspace && ../../mm -config ../team/agent.tutor.yaml # alone, with sessions |
| 12 | 12 | ||
| 13 | provider: llmman | 13 | provider: llmman |
| 14 | -model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | 14 | +#model: hf.co/JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M |
| 15 | +model: hf.co/unsloth/Qwen3.6-35B-A3B-GGUF | ||
| 15 | baseUrl: http://127.0.0.1:17434/v1 | 16 | baseUrl: http://127.0.0.1:17434/v1 |
| 16 | fallback: http://host.docker.internal:17434/v1 | 17 | fallback: http://host.docker.internal:17434/v1 |
| 17 | 18 | ||
| @@ -28,6 +29,9 @@ sampling: | |||
| 28 | parallel_tool_calls: false | 29 | parallel_tool_calls: false |
| 29 | # No chat_template_kwargs: the Instruct template has no reasoning switch | 30 | # No chat_template_kwargs: the Instruct template has no reasoning switch |
| 30 | # (the prof's enable_thinking: false was for the Thinking model). | 31 | # (the prof's enable_thinking: false was for the Thinking model). |
| 32 | + chat_template_kwargs: | ||
| 33 | + enable_thinking: true | ||
| 34 | + reasoning_effort: low | ||
| 31 | 35 | ||
| 32 | firstTokenTimeout: 3m | 36 | firstTokenTimeout: 3m |
| 33 | watchdogTimeout: 2m | 37 | watchdogTimeout: 2m |
modified
dev.team/team/agent.yaml +2 -1 | @@ -29,7 +29,8 @@ provider: llmman | ||
| 29 | 29 | |
| 30 | 30 | # Qwen3.5 4B, 3.4 GB: picking an agent and copying a request does not need a |
| 31 | 31 | # 12B, and the small model reloads in seconds between hand-offs. |
| 32 | -model: hf.co/unsloth/Qwen3.5-4B-GGUF:Q4_K_M | |
| 32 | +#model: hf.co/unsloth/Qwen3.5-4B-GGUF:Q4_K_M | |
| 33 | +model: hf.co/unsloth/Qwen3.5-9B-GGUF | |
| 33 | 34 | |
| 34 | 35 | baseUrl: http://127.0.0.1:17434/v1 |
| 35 | 36 | fallback: http://host.docker.internal:17434/v1 |
| @@ -29,7 +29,8 @@ provider: llmman | |||
| 29 | 29 | ||
| 30 | # Qwen3.5 4B, 3.4 GB: picking an agent and copying a request does not need a | 30 | # Qwen3.5 4B, 3.4 GB: picking an agent and copying a request does not need a |
| 31 | # 12B, and the small model reloads in seconds between hand-offs. | 31 | # 12B, and the small model reloads in seconds between hand-offs. |
| 32 | -model: hf.co/unsloth/Qwen3.5-4B-GGUF:Q4_K_M | 32 | +#model: hf.co/unsloth/Qwen3.5-4B-GGUF:Q4_K_M |
| 33 | +model: hf.co/unsloth/Qwen3.5-9B-GGUF | ||
| 33 | 34 | ||
| 34 | baseUrl: http://127.0.0.1:17434/v1 | 35 | baseUrl: http://127.0.0.1:17434/v1 |
| 35 | fallback: http://host.docker.internal:17434/v1 | 36 | fallback: http://host.docker.internal:17434/v1 |
added
dev.team/workspace/cmd/issueapp/main.go +29 -0 | new file mode 100644 | ||
| @@ -0,0 +1,29 @@ | ||
| 1 | +package main | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "flag" | |
| 5 | + "fmt" | |
| 6 | + "log" | |
| 7 | + | |
| 8 | + "issueapp/internal/app" | |
| 9 | +) | |
| 10 | + | |
| 11 | +const dbPath = "issues.db" | |
| 12 | + | |
| 13 | +func main() { | |
| 14 | + port := flag.Int("port", 8080, "HTTP port to listen on") | |
| 15 | + flag.Parse() | |
| 16 | + | |
| 17 | + if err := app.InitDB(dbPath); err != nil { | |
| 18 | + log.Fatalf("failed to init database: %v", err) | |
| 19 | + } | |
| 20 | + defer app.CloseDB() | |
| 21 | + | |
| 22 | + r := app.NewRouter() | |
| 23 | + | |
| 24 | + addr := fmt.Sprintf(":%d", *port) | |
| 25 | + log.Println("listening on http://localhost" + addr) | |
| 26 | + if err := r.Run(addr); err != nil { | |
| 27 | + log.Fatalf("server error: %v", err) | |
| 28 | + } | |
| 29 | +} | |
| new file mode 100644 | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | +package main | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "flag" | ||
| 5 | + "fmt" | ||
| 6 | + "log" | ||
| 7 | + | ||
| 8 | + "issueapp/internal/app" | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +const dbPath = "issues.db" | ||
| 12 | + | ||
| 13 | +func main() { | ||
| 14 | + port := flag.Int("port", 8080, "HTTP port to listen on") | ||
| 15 | + flag.Parse() | ||
| 16 | + | ||
| 17 | + if err := app.InitDB(dbPath); err != nil { | ||
| 18 | + log.Fatalf("failed to init database: %v", err) | ||
| 19 | + } | ||
| 20 | + defer app.CloseDB() | ||
| 21 | + | ||
| 22 | + r := app.NewRouter() | ||
| 23 | + | ||
| 24 | + addr := fmt.Sprintf(":%d", *port) | ||
| 25 | + log.Println("listening on http://localhost" + addr) | ||
| 26 | + if err := r.Run(addr); err != nil { | ||
| 27 | + log.Fatalf("server error: %v", err) | ||
| 28 | + } | ||
| 29 | +} | ||
added
dev.team/workspace/go.mod +37 -0 | new file mode 100644 | ||
| @@ -0,0 +1,37 @@ | ||
| 1 | +module issueapp | |
| 2 | + | |
| 3 | +go 1.27 | |
| 4 | + | |
| 5 | +require ( | |
| 6 | + github.com/gin-gonic/gin v1.10.0 | |
| 7 | + github.com/mattn/go-sqlite3 v1.14.22 | |
| 8 | +) | |
| 9 | + | |
| 10 | +require ( | |
| 11 | + github.com/bytedance/sonic v1.11.6 // indirect | |
| 12 | + github.com/bytedance/sonic/loader v0.1.1 // indirect | |
| 13 | + github.com/cloudwego/base64x v0.1.4 // indirect | |
| 14 | + github.com/cloudwego/iasm v0.2.0 // indirect | |
| 15 | + github.com/gabriel-vasile/mimetype v1.4.3 // indirect | |
| 16 | + github.com/gin-contrib/sse v0.1.0 // indirect | |
| 17 | + github.com/go-playground/locales v0.14.1 // indirect | |
| 18 | + github.com/go-playground/universal-translator v0.18.1 // indirect | |
| 19 | + github.com/go-playground/validator/v10 v10.20.0 // indirect | |
| 20 | + github.com/goccy/go-json v0.10.2 // indirect | |
| 21 | + github.com/json-iterator/go v1.1.12 // indirect | |
| 22 | + github.com/klauspost/cpuid/v2 v2.2.7 // indirect | |
| 23 | + github.com/leodido/go-urn v1.4.0 // indirect | |
| 24 | + github.com/mattn/go-isatty v0.0.20 // indirect | |
| 25 | + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | |
| 26 | + github.com/modern-go/reflect2 v1.0.2 // indirect | |
| 27 | + github.com/pelletier/go-toml/v2 v2.2.2 // indirect | |
| 28 | + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | |
| 29 | + github.com/ugorji/go/codec v1.2.12 // indirect | |
| 30 | + golang.org/x/arch v0.8.0 // indirect | |
| 31 | + golang.org/x/crypto v0.23.0 // indirect | |
| 32 | + golang.org/x/net v0.25.0 // indirect | |
| 33 | + golang.org/x/sys v0.20.0 // indirect | |
| 34 | + golang.org/x/text v0.15.0 // indirect | |
| 35 | + google.golang.org/protobuf v1.34.1 // indirect | |
| 36 | + gopkg.in/yaml.v3 v3.0.1 // indirect | |
| 37 | +) | |
| new file mode 100644 | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | +module issueapp | ||
| 2 | + | ||
| 3 | +go 1.27 | ||
| 4 | + | ||
| 5 | +require ( | ||
| 6 | + github.com/gin-gonic/gin v1.10.0 | ||
| 7 | + github.com/mattn/go-sqlite3 v1.14.22 | ||
| 8 | +) | ||
| 9 | + | ||
| 10 | +require ( | ||
| 11 | + github.com/bytedance/sonic v1.11.6 // indirect | ||
| 12 | + github.com/bytedance/sonic/loader v0.1.1 // indirect | ||
| 13 | + github.com/cloudwego/base64x v0.1.4 // indirect | ||
| 14 | + github.com/cloudwego/iasm v0.2.0 // indirect | ||
| 15 | + github.com/gabriel-vasile/mimetype v1.4.3 // indirect | ||
| 16 | + github.com/gin-contrib/sse v0.1.0 // indirect | ||
| 17 | + github.com/go-playground/locales v0.14.1 // indirect | ||
| 18 | + github.com/go-playground/universal-translator v0.18.1 // indirect | ||
| 19 | + github.com/go-playground/validator/v10 v10.20.0 // indirect | ||
| 20 | + github.com/goccy/go-json v0.10.2 // indirect | ||
| 21 | + github.com/json-iterator/go v1.1.12 // indirect | ||
| 22 | + github.com/klauspost/cpuid/v2 v2.2.7 // indirect | ||
| 23 | + github.com/leodido/go-urn v1.4.0 // indirect | ||
| 24 | + github.com/mattn/go-isatty v0.0.20 // indirect | ||
| 25 | + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
| 26 | + github.com/modern-go/reflect2 v1.0.2 // indirect | ||
| 27 | + github.com/pelletier/go-toml/v2 v2.2.2 // indirect | ||
| 28 | + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||
| 29 | + github.com/ugorji/go/codec v1.2.12 // indirect | ||
| 30 | + golang.org/x/arch v0.8.0 // indirect | ||
| 31 | + golang.org/x/crypto v0.23.0 // indirect | ||
| 32 | + golang.org/x/net v0.25.0 // indirect | ||
| 33 | + golang.org/x/sys v0.20.0 // indirect | ||
| 34 | + golang.org/x/text v0.15.0 // indirect | ||
| 35 | + google.golang.org/protobuf v1.34.1 // indirect | ||
| 36 | + gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| 37 | +) | ||
added
dev.team/workspace/go.sum +91 -0 | new file mode 100644 | ||
| @@ -0,0 +1,91 @@ | ||
| 1 | +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= | |
| 2 | +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= | |
| 3 | +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= | |
| 4 | +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= | |
| 5 | +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= | |
| 6 | +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= | |
| 7 | +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= | |
| 8 | +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | |
| 9 | +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
| 10 | +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
| 11 | +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
| 12 | +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= | |
| 13 | +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= | |
| 14 | +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | |
| 15 | +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | |
| 16 | +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= | |
| 17 | +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= | |
| 18 | +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= | |
| 19 | +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= | |
| 20 | +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= | |
| 21 | +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= | |
| 22 | +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= | |
| 23 | +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= | |
| 24 | +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= | |
| 25 | +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= | |
| 26 | +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= | |
| 27 | +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= | |
| 28 | +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= | |
| 29 | +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | |
| 30 | +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | |
| 31 | +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | |
| 32 | +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | |
| 33 | +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | |
| 34 | +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= | |
| 35 | +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= | |
| 36 | +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= | |
| 37 | +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | |
| 38 | +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | |
| 39 | +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | |
| 40 | +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | |
| 41 | +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= | |
| 42 | +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= | |
| 43 | +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | |
| 44 | +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | |
| 45 | +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | |
| 46 | +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | |
| 47 | +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | |
| 48 | +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= | |
| 49 | +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= | |
| 50 | +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |
| 51 | +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
| 52 | +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
| 53 | +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | |
| 54 | +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | |
| 55 | +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= | |
| 56 | +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | |
| 57 | +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
| 58 | +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
| 59 | +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | |
| 60 | +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | |
| 61 | +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | |
| 62 | +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | |
| 63 | +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | |
| 64 | +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= | |
| 65 | +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= | |
| 66 | +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= | |
| 67 | +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= | |
| 68 | +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= | |
| 69 | +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= | |
| 70 | +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | |
| 71 | +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= | |
| 72 | +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= | |
| 73 | +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= | |
| 74 | +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= | |
| 75 | +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
| 76 | +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
| 77 | +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= | |
| 78 | +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | |
| 79 | +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= | |
| 80 | +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | |
| 81 | +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= | |
| 82 | +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | |
| 83 | +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= | |
| 84 | +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= | |
| 85 | +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | |
| 86 | +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
| 87 | +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
| 88 | +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | |
| 89 | +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
| 90 | +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= | |
| 91 | +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= | |
| new file mode 100644 | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= | ||
| 2 | +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= | ||
| 3 | +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= | ||
| 4 | +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= | ||
| 5 | +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= | ||
| 6 | +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= | ||
| 7 | +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= | ||
| 8 | +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | ||
| 9 | +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| 10 | +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
| 11 | +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| 12 | +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= | ||
| 13 | +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= | ||
| 14 | +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | ||
| 15 | +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | ||
| 16 | +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= | ||
| 17 | +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= | ||
| 18 | +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= | ||
| 19 | +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= | ||
| 20 | +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= | ||
| 21 | +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= | ||
| 22 | +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= | ||
| 23 | +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= | ||
| 24 | +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= | ||
| 25 | +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= | ||
| 26 | +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= | ||
| 27 | +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= | ||
| 28 | +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= | ||
| 29 | +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
| 30 | +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||
| 31 | +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||
| 32 | +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||
| 33 | +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | ||
| 34 | +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= | ||
| 35 | +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= | ||
| 36 | +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= | ||
| 37 | +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | ||
| 38 | +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | ||
| 39 | +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | ||
| 40 | +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||
| 41 | +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= | ||
| 42 | +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= | ||
| 43 | +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
| 44 | +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||
| 45 | +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||
| 46 | +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||
| 47 | +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||
| 48 | +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= | ||
| 49 | +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= | ||
| 50 | +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
| 51 | +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| 52 | +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
| 53 | +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
| 54 | +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
| 55 | +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= | ||
| 56 | +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
| 57 | +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
| 58 | +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
| 59 | +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
| 60 | +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||
| 61 | +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||
| 62 | +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
| 63 | +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
| 64 | +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= | ||
| 65 | +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= | ||
| 66 | +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= | ||
| 67 | +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= | ||
| 68 | +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= | ||
| 69 | +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= | ||
| 70 | +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | ||
| 71 | +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= | ||
| 72 | +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= | ||
| 73 | +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= | ||
| 74 | +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= | ||
| 75 | +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| 76 | +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| 77 | +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= | ||
| 78 | +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||
| 79 | +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= | ||
| 80 | +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | ||
| 81 | +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= | ||
| 82 | +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
| 83 | +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= | ||
| 84 | +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= | ||
| 85 | +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
| 86 | +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
| 87 | +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
| 88 | +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
| 89 | +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
| 90 | +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= | ||
| 91 | +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= | ||
added
dev.team/workspace/internal/app/db.go +98 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/internal/app/handlers.go +190 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/internal/app/models.go +17 -0 | new file mode 100644 | ||
| @@ -0,0 +1,17 @@ | ||
| 1 | +package app | |
| 2 | + | |
| 3 | +// Issue represents a project issue tracked in the application. | |
| 4 | +type Issue struct { | |
| 5 | + ID int `json:"id"` | |
| 6 | + Title string `json:"title"` | |
| 7 | + Description string `json:"description"` | |
| 8 | + Status string `json:"status"` | |
| 9 | + Priority string `json:"priority"` | |
| 10 | + Assignee string `json:"assignee"` | |
| 11 | +} | |
| 12 | + | |
| 13 | +// Valid values for the Status and Priority fields. | |
| 14 | +var ( | |
| 15 | + Statuses = []string{"open", "in_progress", "done", "closed"} | |
| 16 | + Priorities = []string{"low", "medium", "high", "critical"} | |
| 17 | +) | |
| new file mode 100644 | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | +package app | ||
| 2 | + | ||
| 3 | +// Issue represents a project issue tracked in the application. | ||
| 4 | +type Issue struct { | ||
| 5 | + ID int `json:"id"` | ||
| 6 | + Title string `json:"title"` | ||
| 7 | + Description string `json:"description"` | ||
| 8 | + Status string `json:"status"` | ||
| 9 | + Priority string `json:"priority"` | ||
| 10 | + Assignee string `json:"assignee"` | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +// Valid values for the Status and Priority fields. | ||
| 14 | +var ( | ||
| 15 | + Statuses = []string{"open", "in_progress", "done", "closed"} | ||
| 16 | + Priorities = []string{"low", "medium", "high", "critical"} | ||
| 17 | +) | ||
added
dev.team/workspace/internal/app/review_test.go +77 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/internal/app/templates.go +38 -0 | new file mode 100644 | ||
| @@ -0,0 +1,38 @@ | ||
| 1 | +package app | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "html/template" | |
| 5 | + "os" | |
| 6 | + "path/filepath" | |
| 7 | +) | |
| 8 | + | |
| 9 | +var ( | |
| 10 | + listTmpl *template.Template | |
| 11 | + formTmpl *template.Template | |
| 12 | + cssContent template.CSS | |
| 13 | +) | |
| 14 | + | |
| 15 | +// templatesDir is the directory that holds the CSS and HTML templates. | |
| 16 | +// It defaults to "templates" and can be overridden (e.g. in tests). | |
| 17 | +var templatesDir = "templates" | |
| 18 | + | |
| 19 | +// loadTemplates reads the CSS and HTML templates from the templates/ directory. | |
| 20 | +func loadTemplates() error { | |
| 21 | + cssBytes, err := os.ReadFile(filepath.Join(templatesDir, "style.css")) | |
| 22 | + if err != nil { | |
| 23 | + return err | |
| 24 | + } | |
| 25 | + cssContent = template.CSS(cssBytes) | |
| 26 | + | |
| 27 | + listTmpl, err = template.ParseFiles(filepath.Join(templatesDir, "layout.html"), filepath.Join(templatesDir, "list.html")) | |
| 28 | + if err != nil { | |
| 29 | + return err | |
| 30 | + } | |
| 31 | + | |
| 32 | + formTmpl, err = template.ParseFiles(filepath.Join(templatesDir, "layout.html"), filepath.Join(templatesDir, "form.html")) | |
| 33 | + if err != nil { | |
| 34 | + return err | |
| 35 | + } | |
| 36 | + | |
| 37 | + return nil | |
| 38 | +} | |
| new file mode 100644 | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | +package app | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "html/template" | ||
| 5 | + "os" | ||
| 6 | + "path/filepath" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +var ( | ||
| 10 | + listTmpl *template.Template | ||
| 11 | + formTmpl *template.Template | ||
| 12 | + cssContent template.CSS | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +// templatesDir is the directory that holds the CSS and HTML templates. | ||
| 16 | +// It defaults to "templates" and can be overridden (e.g. in tests). | ||
| 17 | +var templatesDir = "templates" | ||
| 18 | + | ||
| 19 | +// loadTemplates reads the CSS and HTML templates from the templates/ directory. | ||
| 20 | +func loadTemplates() error { | ||
| 21 | + cssBytes, err := os.ReadFile(filepath.Join(templatesDir, "style.css")) | ||
| 22 | + if err != nil { | ||
| 23 | + return err | ||
| 24 | + } | ||
| 25 | + cssContent = template.CSS(cssBytes) | ||
| 26 | + | ||
| 27 | + listTmpl, err = template.ParseFiles(filepath.Join(templatesDir, "layout.html"), filepath.Join(templatesDir, "list.html")) | ||
| 28 | + if err != nil { | ||
| 29 | + return err | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + formTmpl, err = template.ParseFiles(filepath.Join(templatesDir, "layout.html"), filepath.Join(templatesDir, "form.html")) | ||
| 33 | + if err != nil { | ||
| 34 | + return err | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + return nil | ||
| 38 | +} | ||
added
dev.team/workspace/issueapp +0 -0 | new file mode 100644 | ||
| Binary files /dev/null and b/dev.team/workspace/issueapp differ | ||
| new file mode 100644 | |||
| Binary files /dev/null and b/dev.team/workspace/issueapp differ | Binary files /dev/null and b/dev.team/workspace/issueapp differ | ||
added
dev.team/workspace/issues.db +0 -0 | new file mode 100644 | ||
| Binary files /dev/null and b/dev.team/workspace/issues.db differ | ||
| new file mode 100644 | |||
| Binary files /dev/null and b/dev.team/workspace/issues.db differ | Binary files /dev/null and b/dev.team/workspace/issues.db differ | ||
added
dev.team/workspace/review_test.go +78 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/templates/form.html +50 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/templates/layout.html +20 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/templates/list.html +56 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
dev.team/workspace/templates/style.css +70 -0 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/en/explanation/decision-models.md +1 -1 | @@ -13,7 +13,7 @@ The first use people want is the one Granite Guardian already showed in `demos/g | ||
| 13 | 13 | Two consequences follow, both deliberate: |
| 14 | 14 | |
| 15 | 15 | - **The state is the message alone.** No history, no system prompt, no hooks: a decider judges what it is given, and the previous message is not part of what it judges. That is also what a 2,048-token context leaves room for. |
| 16 | -- **No tools.** A decision model never calls one, so a decider declaring tools is refused at start-up rather than shown with a misleading tools column. | |
| 16 | +- **No tools.** A decision model never calls one, so mm turns the built-in tools off for a decider by itself: a decider file needs no `bashTool: false` lines, and a default `skillsDir` cannot make it refuse to start in a project that has skills. What only a deliberate entry brings — MCP, language servers, `mmConfigs`, declared `tools:` — is still refused at start-up: ignoring it silently would hide a mistake in the file. | |
| 17 | 17 | |
| 18 | 18 | `-p` prints the server's JSON untouched — a field a server adds later still reaches the script. The other front ends show one line per question followed by the same JSON, because the person reads the lines and an asking agent may parse the block. |
| 19 | 19 | |
| @@ -13,7 +13,7 @@ The first use people want is the one Granite Guardian already showed in `demos/g | |||
| 13 | Two consequences follow, both deliberate: | 13 | Two consequences follow, both deliberate: |
| 14 | 14 | ||
| 15 | - **The state is the message alone.** No history, no system prompt, no hooks: a decider judges what it is given, and the previous message is not part of what it judges. That is also what a 2,048-token context leaves room for. | 15 | - **The state is the message alone.** No history, no system prompt, no hooks: a decider judges what it is given, and the previous message is not part of what it judges. That is also what a 2,048-token context leaves room for. |
| 16 | -- **No tools.** A decision model never calls one, so a decider declaring tools is refused at start-up rather than shown with a misleading tools column. | 16 | +- **No tools.** A decision model never calls one, so mm turns the built-in tools off for a decider by itself: a decider file needs no `bashTool: false` lines, and a default `skillsDir` cannot make it refuse to start in a project that has skills. What only a deliberate entry brings — MCP, language servers, `mmConfigs`, declared `tools:` — is still refused at start-up: ignoring it silently would hide a mistake in the file. |
| 17 | 17 | ||
| 18 | `-p` prints the server's JSON untouched — a field a server adds later still reaches the script. The other front ends show one line per question followed by the same JSON, because the person reads the lines and an asking agent may parse the block. | 18 | `-p` prints the server's JSON untouched — a field a server adds later still reaches the script. The other front ends show one line per question followed by the same JSON, because the person reads the lines and an asking agent may parse the block. |
| 19 | 19 | ||
modified
docs/en/how-to/ask-a-decision-model.md +2 -8 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/en/how-to/check-outputs-with-a-decision-model.md +0 -1 | @@ -83,7 +83,6 @@ The check is about relevance, not truth: a wrong answer on the right subject pas | ||
| 83 | 83 | - **Thresholds**: the demos read them from `INJECTION_THRESHOLD` (0.8), `FAILURE_THRESHOLD` (0.95) and `ON_TOPIC_THRESHOLD` (0.4). Measure on your own texts before you move them. |
| 84 | 84 | - **mm is not on the PATH**: set `MM_BIN` to the binary's path. |
| 85 | 85 | - **An asked agent that reasons**: turn its reasoning off (`chat_template_kwargs: {enable_thinking: false}` for Qwen3.5). Otherwise its reasoning can end up in the answer, and the check judges the reasoning — which talks about the question — instead of the answer. |
| 86 | -- **A decider started from a project with skills**: give the decider `skillsDir: no-skills`; with `skillsDir: ""` it reads `./skills` of the directory it runs in, declares `read_skill`, and refuses to start. | |
| 87 | 86 | |
| 88 | 87 | ## See also |
| 89 | 88 | |
| @@ -83,7 +83,6 @@ The check is about relevance, not truth: a wrong answer on the right subject pas | |||
| 83 | - **Thresholds**: the demos read them from `INJECTION_THRESHOLD` (0.8), `FAILURE_THRESHOLD` (0.95) and `ON_TOPIC_THRESHOLD` (0.4). Measure on your own texts before you move them. | 83 | - **Thresholds**: the demos read them from `INJECTION_THRESHOLD` (0.8), `FAILURE_THRESHOLD` (0.95) and `ON_TOPIC_THRESHOLD` (0.4). Measure on your own texts before you move them. |
| 84 | - **mm is not on the PATH**: set `MM_BIN` to the binary's path. | 84 | - **mm is not on the PATH**: set `MM_BIN` to the binary's path. |
| 85 | - **An asked agent that reasons**: turn its reasoning off (`chat_template_kwargs: {enable_thinking: false}` for Qwen3.5). Otherwise its reasoning can end up in the answer, and the check judges the reasoning — which talks about the question — instead of the answer. | 85 | - **An asked agent that reasons**: turn its reasoning off (`chat_template_kwargs: {enable_thinking: false}` for Qwen3.5). Otherwise its reasoning can end up in the answer, and the check judges the reasoning — which talks about the question — instead of the answer. |
| 86 | -- **A decider started from a project with skills**: give the decider `skillsDir: no-skills`; with `skillsDir: ""` it reads `./skills` of the directory it runs in, declares `read_skill`, and refuses to start. | ||
| 87 | 86 | ||
| 88 | ## See also | 87 | ## See also |
| 89 | 88 | ||
modified
docs/en/how-to/triage-commands-with-a-decision-model.md +0 -1 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/en/how-to/write-decision-questions.md +8 -28 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/en/reference/configuration.md +3 -7 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/explanation/decision-models.md +1 -1 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/how-to/ask-a-decision-model.md +2 -8 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/how-to/check-outputs-with-a-decision-model.md +0 -1 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/how-to/triage-commands-with-a-decision-model.md +0 -1 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/how-to/write-decision-questions.md +8 -28 Large diff collapsed to keep the page fast — load it when you need it.
modified
docs/fr/reference/configuration.md +3 -7 Large diff collapsed to keep the page fast — load it when you need it.
modified
internal/config/decision.go +36 -9 Large diff collapsed to keep the page fast — load it when you need it.
modified
internal/config/decision_test.go +52 -4 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/.gitignore +0 -0 | new file mode 100644 |
| new file mode 100644 |
added
learning-rust/agent-config/agent.yaml +109 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/01-getting-started.md +58 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/02-layout.md +82 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/03-blocks-and-paragraphs.md +63 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/04-lists.md +60 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/05-tables.md +63 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/06-gauges-and-ticks.md +56 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/07-tabs.md +64 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/08-app-state-and-events.md +70 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/09-popups.md +67 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/agent-config/docs/README.md +13 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/sbxenv.yaml +60 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/start-zed.sh +8 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/stop-zed.sh +7 -0 Large diff collapsed to keep the page fast — load it when you need it.
added
learning-rust/workspace/.gitkeep +0 -0 Large diff collapsed to keep the page fast — load it when you need it.
modified
main.go +19 -8 Large diff collapsed to keep the page fast — load it when you need it.