📦 Mini Me
ab6a77c parent: 59269a2 modified
.gitignore +2 -2 | @@ -1,8 +1,8 @@ | ||
| 1 | -kits | |
| 1 | +/kits | |
| 2 | 2 | notes.txt |
| 3 | 3 | tmp |
| 4 | 4 | mm |
| 5 | -mm-* | |
| 5 | +/mm-* | |
| 6 | 6 | .mm/ |
| 7 | 7 | blog |
| 8 | 8 | ebook |
| @@ -1,8 +1,8 @@ | |||
| 1 | -kits | 1 | +/kits |
| 2 | notes.txt | 2 | notes.txt |
| 3 | tmp | 3 | tmp |
| 4 | mm | 4 | mm |
| 5 | -mm-* | 5 | +/mm-* |
| 6 | .mm/ | 6 | .mm/ |
| 7 | blog | 7 | blog |
| 8 | ebook | 8 | ebook |
modified
INSTALL.MACOS.md +64 -2 | @@ -6,6 +6,68 @@ VERSION=0.2.1 | ||
| 6 | 6 | curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64" |
| 7 | 7 | chmod +x ./mm-${VERSION}-darwin-arm64 |
| 8 | 8 | xattr -cr ./mm-${VERSION}-darwin-arm64 |
| 9 | -sudo rm /usr/local/bin/mm | |
| 9 | +sudo rm -f /usr/local/bin/mm | |
| 10 | 10 | sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm |
| 11 | -``` | |
| \ No newline at end of file | ||
| 11 | +``` | |
| 12 | + | |
| 13 | +## Use `mm` in a Docker Sandbox (the two kits) | |
| 14 | + | |
| 15 | +Instead of installing the binary, `mm` can run inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/): every command the model runs and every file it edits then happens in a container, on your mounted project. Two kits are published on Docker Hub at mm's version; each one brings the `k33g/mm-sandbox` image with `mm` in it, so nothing is built on your Mac. | |
| 16 | + | |
| 17 | +| Kit | For | | |
| 18 | +|---|---| | |
| 19 | +| `k33g/mm-tui:0.2.1` | the window mode (`mm -tui`) in your terminal | | |
| 20 | +| `k33g/mm-acp:0.2.1` | an editor that speaks the Agent Client Protocol (Zed, …) | | |
| 21 | + | |
| 22 | +You need Docker Desktop with the `sbx` command, and your model server (Docker Model Runner or llama-server) running on the Mac. Inside the sandbox, `localhost` is the sandbox itself: `agent.dmr.yaml` already falls back to `host.docker.internal`, which reaches the Mac. | |
| 23 | + | |
| 24 | +### Window mode: `mm-tui` | |
| 25 | + | |
| 26 | +From the project you want `mm` to work on: | |
| 27 | + | |
| 28 | +```bash | |
| 29 | +cd /path/to/your/project | |
| 30 | +sbx kit inspect k33g/mm-tui:0.2.1 # optional: what the kit declares | |
| 31 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 32 | +``` | |
| 33 | + | |
| 34 | +What follows `--` is `mm`'s own command line (here the configuration file, relative to the project). `sbx ls` lists the sandboxes; `sbx run --name <name>` re-attaches to one. | |
| 35 | + | |
| 36 | +### From an editor: `mm-acp` | |
| 37 | + | |
| 38 | +Create the sandbox once, from the project the editor will open, with the configuration file baked in: | |
| 39 | + | |
| 40 | +```bash | |
| 41 | +cd /path/to/your/project | |
| 42 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 43 | +``` | |
| 44 | + | |
| 45 | +Then register it in Zed's `settings.json`: | |
| 46 | + | |
| 47 | +```json | |
| 48 | +{ | |
| 49 | + "agent_servers": { | |
| 50 | + "mini-me (sandbox)": { | |
| 51 | + "type": "custom", | |
| 52 | + "command": "sbx", | |
| 53 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | |
| 54 | + } | |
| 55 | + } | |
| 56 | +} | |
| 57 | +``` | |
| 58 | + | |
| 59 | +If Zed cannot find `sbx`, put the absolute path given by `which sbx` in `"command"`. One sandbox per project: give each one its own `--name` and its own entry in Zed. `sbx rm mm-acp` removes a sandbox; your project directory is not touched. | |
| 60 | + | |
| 61 | +### The v3 kits | |
| 62 | + | |
| 63 | +The same two kits also exist for the kit specification v3, in `docker-sbx-v3/` (not published yet, and not yet tried with `sbx`). From a clone of this repository: | |
| 64 | + | |
| 65 | +```bash | |
| 66 | +cd /path/to/your/project | |
| 67 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 68 | +sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml | |
| 69 | +``` | |
| 70 | + | |
| 71 | +With the v3 kits, give `config` a path relative to the project: the workspace is mounted at `/home/agent/workspace`, so a `/Users/…` path does not exist inside the sandbox. | |
| 72 | + | |
| 73 | +Full guides: [Run mini-me in a Docker Sandbox](docs/en/how-to/run-in-a-docker-sandbox.md) (v2 kits, MCP, variants) and [Run mini-me with the v3 sandbox kits](docs/en/how-to/run-with-sandbox-kits-v3.md). | |
| @@ -6,6 +6,68 @@ VERSION=0.2.1 | |||
| 6 | curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64" | 6 | curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64" |
| 7 | chmod +x ./mm-${VERSION}-darwin-arm64 | 7 | chmod +x ./mm-${VERSION}-darwin-arm64 |
| 8 | xattr -cr ./mm-${VERSION}-darwin-arm64 | 8 | xattr -cr ./mm-${VERSION}-darwin-arm64 |
| 9 | -sudo rm /usr/local/bin/mm | 9 | +sudo rm -f /usr/local/bin/mm |
| 10 | sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm | 10 | sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm |
| 11 | -``` | ||
| \ No newline at end of file | \ No newline at end of file | ||
| 11 | +``` | ||
| 12 | + | ||
| 13 | +## Use `mm` in a Docker Sandbox (the two kits) | ||
| 14 | + | ||
| 15 | +Instead of installing the binary, `mm` can run inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/): every command the model runs and every file it edits then happens in a container, on your mounted project. Two kits are published on Docker Hub at mm's version; each one brings the `k33g/mm-sandbox` image with `mm` in it, so nothing is built on your Mac. | ||
| 16 | + | ||
| 17 | +| Kit | For | | ||
| 18 | +|---|---| | ||
| 19 | +| `k33g/mm-tui:0.2.1` | the window mode (`mm -tui`) in your terminal | | ||
| 20 | +| `k33g/mm-acp:0.2.1` | an editor that speaks the Agent Client Protocol (Zed, …) | | ||
| 21 | + | ||
| 22 | +You need Docker Desktop with the `sbx` command, and your model server (Docker Model Runner or llama-server) running on the Mac. Inside the sandbox, `localhost` is the sandbox itself: `agent.dmr.yaml` already falls back to `host.docker.internal`, which reaches the Mac. | ||
| 23 | + | ||
| 24 | +### Window mode: `mm-tui` | ||
| 25 | + | ||
| 26 | +From the project you want `mm` to work on: | ||
| 27 | + | ||
| 28 | +```bash | ||
| 29 | +cd /path/to/your/project | ||
| 30 | +sbx kit inspect k33g/mm-tui:0.2.1 # optional: what the kit declares | ||
| 31 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml | ||
| 32 | +``` | ||
| 33 | + | ||
| 34 | +What follows `--` is `mm`'s own command line (here the configuration file, relative to the project). `sbx ls` lists the sandboxes; `sbx run --name <name>` re-attaches to one. | ||
| 35 | + | ||
| 36 | +### From an editor: `mm-acp` | ||
| 37 | + | ||
| 38 | +Create the sandbox once, from the project the editor will open, with the configuration file baked in: | ||
| 39 | + | ||
| 40 | +```bash | ||
| 41 | +cd /path/to/your/project | ||
| 42 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | ||
| 43 | +``` | ||
| 44 | + | ||
| 45 | +Then register it in Zed's `settings.json`: | ||
| 46 | + | ||
| 47 | +```json | ||
| 48 | +{ | ||
| 49 | + "agent_servers": { | ||
| 50 | + "mini-me (sandbox)": { | ||
| 51 | + "type": "custom", | ||
| 52 | + "command": "sbx", | ||
| 53 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | +} | ||
| 57 | +``` | ||
| 58 | + | ||
| 59 | +If Zed cannot find `sbx`, put the absolute path given by `which sbx` in `"command"`. One sandbox per project: give each one its own `--name` and its own entry in Zed. `sbx rm mm-acp` removes a sandbox; your project directory is not touched. | ||
| 60 | + | ||
| 61 | +### The v3 kits | ||
| 62 | + | ||
| 63 | +The same two kits also exist for the kit specification v3, in `docker-sbx-v3/` (not published yet, and not yet tried with `sbx`). From a clone of this repository: | ||
| 64 | + | ||
| 65 | +```bash | ||
| 66 | +cd /path/to/your/project | ||
| 67 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 68 | +sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml | ||
| 69 | +``` | ||
| 70 | + | ||
| 71 | +With the v3 kits, give `config` a path relative to the project: the workspace is mounted at `/home/agent/workspace`, so a `/Users/…` path does not exist inside the sandbox. | ||
| 72 | + | ||
| 73 | +Full guides: [Run mini-me in a Docker Sandbox](docs/en/how-to/run-in-a-docker-sandbox.md) (v2 kits, MCP, variants) and [Run mini-me with the v3 sandbox kits](docs/en/how-to/run-with-sandbox-kits-v3.md). | ||
added
config.samples/agent.dmr.gemma.yaml +182 -0 | new file mode 100644 | ||
| @@ -0,0 +1,182 @@ | ||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | |
| 2 | + | |
| 3 | +provider: dmr | |
| 4 | + | |
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | |
| 6 | +model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | |
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | |
| 8 | + | |
| 9 | +baseUrl: http://localhost:12434/engines/v1 | |
| 10 | +fallback: http://host.docker.internal:12434/engines/v1 | |
| 11 | + | |
| 12 | +# Only when llama-server was started with --api-key; unset otherwise. | |
| 13 | +# apiKeyEnv: LLAMA_API_KEY | |
| 14 | + | |
| 15 | +# The `bash` tool. | |
| 16 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | |
| 17 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | |
| 18 | +bashTool: true | |
| 19 | + | |
| 20 | +# The built-in file tools: read_file, write_file, edit_file. | |
| 21 | +editTools: true | |
| 22 | + | |
| 23 | +# The built-in plan tool for managing multi-step plans. | |
| 24 | +# Set to false to disable plan creation and tracking via the `plan` tool. | |
| 25 | +planTool: true | |
| 26 | + | |
| 27 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | |
| 28 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | |
| 29 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | |
| 30 | +# lsp: | |
| 31 | +# servers: | |
| 32 | +# - name: gopls | |
| 33 | +# command: gopls | |
| 34 | +# extensions: [".go"] | |
| 35 | +# - name: typescript | |
| 36 | +# command: typescript-language-server | |
| 37 | +# args: ["--stdio"] | |
| 38 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | |
| 39 | +# - name: python | |
| 40 | +# command: pyright-langserver | |
| 41 | +# args: ["--stdio"] | |
| 42 | +# extensions: [".py"] | |
| 43 | +# - name: rust | |
| 44 | +# command: rust-analyzer | |
| 45 | +# extensions: [".rs"] | |
| 46 | + | |
| 47 | +# How many tokens the server actually serves. | |
| 48 | +# 0 = ask the server (llama-server tells it on /props) | |
| 49 | +contextWindow: 0 | |
| 50 | + | |
| 51 | +# Max number of characters a tool returns to the model. | |
| 52 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | |
| 53 | +maxOutput: 16000 | |
| 54 | + | |
| 55 | +# Max number of model <-> tools round trips for a single question. | |
| 56 | +# Raise it for tasks that need long chains of commands. | |
| 57 | +maxTurns: 40 | |
| 58 | + | |
| 59 | +# Where the `read_skill` tool looks for its markdown procedures. | |
| 60 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | |
| 61 | +skillsDir: skills | |
| 62 | + | |
| 63 | +# Persistent sessions, per project. | |
| 64 | +# When enabled, every conversation is saved as one JSON file under `dir`. | |
| 65 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | |
| 66 | +sessions: | |
| 67 | + enabled: true | |
| 68 | + dir: .mm/sessions | |
| 69 | + | |
| 70 | +# How many lines of a command's output are echoed to the terminal. | |
| 71 | +# 0 disables it. | |
| 72 | +previewLines: 20 | |
| 73 | + | |
| 74 | +displayCommands: true | |
| 75 | +# Show what a thinking model reasons about before it answers (dim italic in the | |
| 76 | +# terminal, its own style in the window, a thought chunk in an editor). | |
| 77 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | |
| 78 | +# model thinks — this only says whether to show it. | |
| 79 | +showThinking: true | |
| 80 | + | |
| 81 | + | |
| 82 | +# The system prompt: what the agent is, and what it is allowed to do. | |
| 83 | +# This is the knob to play with — it is the shortest path to changing behaviour. | |
| 84 | +system: | | |
| 85 | + Your name is Bob. | |
| 86 | + You are a coding agent working in a terminal. | |
| 87 | + You have a "bash" tool to run shell commands. | |
| 88 | + Use it to explore files, run tests, inspect the repository, etc. | |
| 89 | + Chain several commands if needed, then answer clearly in English. | |
| 90 | + | |
| 91 | + A request often mixes things you answer from yourself ("say hello") with | |
| 92 | + things only a command can answer ("list the files"). Handle every part, in | |
| 93 | + the order asked, and run a command for each part that needs one. | |
| 94 | + Never state the contents of a file, the output of a command, or the state of | |
| 95 | + the repository unless a command in THIS answer returned it. What you did not | |
| 96 | + read, you do not know: run the command instead of recalling it. | |
| 97 | + | |
| 98 | + SKILLS | |
| 99 | + You have a second tool, `read_skill`. Its description lists the procedures | |
| 100 | + available for this project — one per kind of task. | |
| 101 | + | |
| 102 | + Any request to DO something to a Go project is a skill, not a shell command | |
| 103 | + you invent. Match the request against that list, call `read_skill` FIRST, | |
| 104 | + before any bash command, and then follow what it says step by step. | |
| 105 | + | |
| 106 | + FILE EDITING | |
| 107 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | |
| 108 | + They are how a file gets read and changed here: each change is exact, | |
| 109 | + checked before it is written, and comes back as a diff with line numbers. | |
| 110 | + bash is for running things — building, testing, listing, searching. | |
| 111 | + | |
| 112 | + - Read before you write: call `read_file` on the file (numbered=true when | |
| 113 | + you need line numbers). You cannot target text you have not seen; never | |
| 114 | + rely on what you think you remember about a file. | |
| 115 | + - To change an existing file, call `edit_file` with one or more {old, new} | |
| 116 | + pairs. `old` is copied from the file character for character — same | |
| 117 | + spaces, same indentation, same line breaks — and appears exactly once: | |
| 118 | + add the surrounding lines until it is unique. Several pairs are applied | |
| 119 | + together, against the original file. An empty `new` deletes the text. | |
| 120 | + - Call `write_file` only to create a file, or to rewrite one entirely and | |
| 121 | + on purpose. On an existing file it replaces everything, including what | |
| 122 | + you did not intend to touch. | |
| 123 | + - Read the diff the tool returns: it says exactly what changed and on which | |
| 124 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | |
| 125 | + edits — read the file again and fix `old`. Do not fall back to | |
| 126 | + `write_file` to force the change through. | |
| 127 | + - After editing code, run the narrowest check with bash: the formatter, the | |
| 128 | + compiler, or the test covering that file. | |
| 129 | + | |
| 130 | + RULES | |
| 131 | + - Keep everything the file already does, unless the user asked to remove it. | |
| 132 | + - Touch only the files the request is about. Do not add tests, files or | |
| 133 | + features that were not asked for. | |
| 134 | + - Never run a git command unless the user says git, commit or push. | |
| 135 | + - Never move, rename or delete a file unless the user asked for it. | |
| 136 | + - Then answer in English, in a few lines. | |
| 137 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | |
| 138 | + to understand the options, then run the command. | |
| 139 | + | |
| 140 | + BACKGROUND JOBS | |
| 141 | + Never let a command block the answer. Anything that serves, watches or runs | |
| 142 | + long goes to the background, with BOTH streams redirected and its pid kept: | |
| 143 | + | |
| 144 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | |
| 145 | + | |
| 146 | + Redirecting only stdout still blocks until the process exits. Read the | |
| 147 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | |
| 148 | + rule you cannot guess. Stop every job you started before you finish, and say | |
| 149 | + which ones you left running. | |
| 150 | + | |
| 151 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | |
| 152 | +# we want precise and reproducible answers, not creativity. | |
| 153 | +sampling: | |
| 154 | + temperature: 0.0 | |
| 155 | + parallel_tool_calls: false | |
| 156 | + top_p: 0.9 | |
| 157 | + max_tokens: 32768 | |
| 158 | + | |
| 159 | +# llama-server processes the whole prompt before the first token; | |
| 160 | +# on a laptop a 32k context can take a while. Raise it if it fires. | |
| 161 | +watchdogTimeout: 300s | |
| 162 | + | |
| 163 | +# Context compression. | |
| 164 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | |
| 165 | +context: | |
| 166 | + enabled: true | |
| 167 | + | |
| 168 | + # Compress when the history reaches this share of the window. | |
| 169 | + threshold: 75 | |
| 170 | + | |
| 171 | + # Fallback on the message count, for when the window is unknown. | |
| 172 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | |
| 173 | + maxMessages: 80 | |
| 174 | + | |
| 175 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | |
| 176 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | |
| 177 | + keepLastTurns: 3 | |
| 178 | + | |
| 179 | + # max_tokens of the summary request. | |
| 180 | + summaryMaxTokens: 1200 | |
| 181 | + | |
| 182 | + showStats: true | |
| new file mode 100644 | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | ||
| 2 | + | ||
| 3 | +provider: dmr | ||
| 4 | + | ||
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | ||
| 6 | +model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | ||
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | ||
| 8 | + | ||
| 9 | +baseUrl: http://localhost:12434/engines/v1 | ||
| 10 | +fallback: http://host.docker.internal:12434/engines/v1 | ||
| 11 | + | ||
| 12 | +# Only when llama-server was started with --api-key; unset otherwise. | ||
| 13 | +# apiKeyEnv: LLAMA_API_KEY | ||
| 14 | + | ||
| 15 | +# The `bash` tool. | ||
| 16 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | ||
| 17 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | ||
| 18 | +bashTool: true | ||
| 19 | + | ||
| 20 | +# The built-in file tools: read_file, write_file, edit_file. | ||
| 21 | +editTools: true | ||
| 22 | + | ||
| 23 | +# The built-in plan tool for managing multi-step plans. | ||
| 24 | +# Set to false to disable plan creation and tracking via the `plan` tool. | ||
| 25 | +planTool: true | ||
| 26 | + | ||
| 27 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | ||
| 28 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | ||
| 29 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | ||
| 30 | +# lsp: | ||
| 31 | +# servers: | ||
| 32 | +# - name: gopls | ||
| 33 | +# command: gopls | ||
| 34 | +# extensions: [".go"] | ||
| 35 | +# - name: typescript | ||
| 36 | +# command: typescript-language-server | ||
| 37 | +# args: ["--stdio"] | ||
| 38 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | ||
| 39 | +# - name: python | ||
| 40 | +# command: pyright-langserver | ||
| 41 | +# args: ["--stdio"] | ||
| 42 | +# extensions: [".py"] | ||
| 43 | +# - name: rust | ||
| 44 | +# command: rust-analyzer | ||
| 45 | +# extensions: [".rs"] | ||
| 46 | + | ||
| 47 | +# How many tokens the server actually serves. | ||
| 48 | +# 0 = ask the server (llama-server tells it on /props) | ||
| 49 | +contextWindow: 0 | ||
| 50 | + | ||
| 51 | +# Max number of characters a tool returns to the model. | ||
| 52 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | ||
| 53 | +maxOutput: 16000 | ||
| 54 | + | ||
| 55 | +# Max number of model <-> tools round trips for a single question. | ||
| 56 | +# Raise it for tasks that need long chains of commands. | ||
| 57 | +maxTurns: 40 | ||
| 58 | + | ||
| 59 | +# Where the `read_skill` tool looks for its markdown procedures. | ||
| 60 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | ||
| 61 | +skillsDir: skills | ||
| 62 | + | ||
| 63 | +# Persistent sessions, per project. | ||
| 64 | +# When enabled, every conversation is saved as one JSON file under `dir`. | ||
| 65 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | ||
| 66 | +sessions: | ||
| 67 | + enabled: true | ||
| 68 | + dir: .mm/sessions | ||
| 69 | + | ||
| 70 | +# How many lines of a command's output are echoed to the terminal. | ||
| 71 | +# 0 disables it. | ||
| 72 | +previewLines: 20 | ||
| 73 | + | ||
| 74 | +displayCommands: true | ||
| 75 | +# Show what a thinking model reasons about before it answers (dim italic in the | ||
| 76 | +# terminal, its own style in the window, a thought chunk in an editor). | ||
| 77 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | ||
| 78 | +# model thinks — this only says whether to show it. | ||
| 79 | +showThinking: true | ||
| 80 | + | ||
| 81 | + | ||
| 82 | +# The system prompt: what the agent is, and what it is allowed to do. | ||
| 83 | +# This is the knob to play with — it is the shortest path to changing behaviour. | ||
| 84 | +system: | | ||
| 85 | + Your name is Bob. | ||
| 86 | + You are a coding agent working in a terminal. | ||
| 87 | + You have a "bash" tool to run shell commands. | ||
| 88 | + Use it to explore files, run tests, inspect the repository, etc. | ||
| 89 | + Chain several commands if needed, then answer clearly in English. | ||
| 90 | + | ||
| 91 | + A request often mixes things you answer from yourself ("say hello") with | ||
| 92 | + things only a command can answer ("list the files"). Handle every part, in | ||
| 93 | + the order asked, and run a command for each part that needs one. | ||
| 94 | + Never state the contents of a file, the output of a command, or the state of | ||
| 95 | + the repository unless a command in THIS answer returned it. What you did not | ||
| 96 | + read, you do not know: run the command instead of recalling it. | ||
| 97 | + | ||
| 98 | + SKILLS | ||
| 99 | + You have a second tool, `read_skill`. Its description lists the procedures | ||
| 100 | + available for this project — one per kind of task. | ||
| 101 | + | ||
| 102 | + Any request to DO something to a Go project is a skill, not a shell command | ||
| 103 | + you invent. Match the request against that list, call `read_skill` FIRST, | ||
| 104 | + before any bash command, and then follow what it says step by step. | ||
| 105 | + | ||
| 106 | + FILE EDITING | ||
| 107 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | ||
| 108 | + They are how a file gets read and changed here: each change is exact, | ||
| 109 | + checked before it is written, and comes back as a diff with line numbers. | ||
| 110 | + bash is for running things — building, testing, listing, searching. | ||
| 111 | + | ||
| 112 | + - Read before you write: call `read_file` on the file (numbered=true when | ||
| 113 | + you need line numbers). You cannot target text you have not seen; never | ||
| 114 | + rely on what you think you remember about a file. | ||
| 115 | + - To change an existing file, call `edit_file` with one or more {old, new} | ||
| 116 | + pairs. `old` is copied from the file character for character — same | ||
| 117 | + spaces, same indentation, same line breaks — and appears exactly once: | ||
| 118 | + add the surrounding lines until it is unique. Several pairs are applied | ||
| 119 | + together, against the original file. An empty `new` deletes the text. | ||
| 120 | + - Call `write_file` only to create a file, or to rewrite one entirely and | ||
| 121 | + on purpose. On an existing file it replaces everything, including what | ||
| 122 | + you did not intend to touch. | ||
| 123 | + - Read the diff the tool returns: it says exactly what changed and on which | ||
| 124 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | ||
| 125 | + edits — read the file again and fix `old`. Do not fall back to | ||
| 126 | + `write_file` to force the change through. | ||
| 127 | + - After editing code, run the narrowest check with bash: the formatter, the | ||
| 128 | + compiler, or the test covering that file. | ||
| 129 | + | ||
| 130 | + RULES | ||
| 131 | + - Keep everything the file already does, unless the user asked to remove it. | ||
| 132 | + - Touch only the files the request is about. Do not add tests, files or | ||
| 133 | + features that were not asked for. | ||
| 134 | + - Never run a git command unless the user says git, commit or push. | ||
| 135 | + - Never move, rename or delete a file unless the user asked for it. | ||
| 136 | + - Then answer in English, in a few lines. | ||
| 137 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | ||
| 138 | + to understand the options, then run the command. | ||
| 139 | + | ||
| 140 | + BACKGROUND JOBS | ||
| 141 | + Never let a command block the answer. Anything that serves, watches or runs | ||
| 142 | + long goes to the background, with BOTH streams redirected and its pid kept: | ||
| 143 | + | ||
| 144 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | ||
| 145 | + | ||
| 146 | + Redirecting only stdout still blocks until the process exits. Read the | ||
| 147 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | ||
| 148 | + rule you cannot guess. Stop every job you started before you finish, and say | ||
| 149 | + which ones you left running. | ||
| 150 | + | ||
| 151 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | ||
| 152 | +# we want precise and reproducible answers, not creativity. | ||
| 153 | +sampling: | ||
| 154 | + temperature: 0.0 | ||
| 155 | + parallel_tool_calls: false | ||
| 156 | + top_p: 0.9 | ||
| 157 | + max_tokens: 32768 | ||
| 158 | + | ||
| 159 | +# llama-server processes the whole prompt before the first token; | ||
| 160 | +# on a laptop a 32k context can take a while. Raise it if it fires. | ||
| 161 | +watchdogTimeout: 300s | ||
| 162 | + | ||
| 163 | +# Context compression. | ||
| 164 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | ||
| 165 | +context: | ||
| 166 | + enabled: true | ||
| 167 | + | ||
| 168 | + # Compress when the history reaches this share of the window. | ||
| 169 | + threshold: 75 | ||
| 170 | + | ||
| 171 | + # Fallback on the message count, for when the window is unknown. | ||
| 172 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | ||
| 173 | + maxMessages: 80 | ||
| 174 | + | ||
| 175 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | ||
| 176 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | ||
| 177 | + keepLastTurns: 3 | ||
| 178 | + | ||
| 179 | + # max_tokens of the summary request. | ||
| 180 | + summaryMaxTokens: 1200 | ||
| 181 | + | ||
| 182 | + showStats: true | ||
added
config.samples/agent.dmr.gpt-oss.yaml +183 -0 | new file mode 100644 | ||
| @@ -0,0 +1,183 @@ | ||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | |
| 2 | + | |
| 3 | +provider: dmr | |
| 4 | + | |
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | |
| 6 | +#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | |
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | |
| 8 | +model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL | |
| 9 | + | |
| 10 | +baseUrl: http://localhost:12434/engines/v1 | |
| 11 | +fallback: http://host.docker.internal:12434/engines/v1 | |
| 12 | + | |
| 13 | +# Only when llama-server was started with --api-key; unset otherwise. | |
| 14 | +# apiKeyEnv: LLAMA_API_KEY | |
| 15 | + | |
| 16 | +# The `bash` tool. | |
| 17 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | |
| 18 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | |
| 19 | +bashTool: true | |
| 20 | + | |
| 21 | +# The built-in file tools: read_file, write_file, edit_file. | |
| 22 | +editTools: true | |
| 23 | + | |
| 24 | +# The built-in plan tool for managing multi-step plans. | |
| 25 | +# Set to false to disable plan creation and tracking via the `plan` tool. | |
| 26 | +planTool: true | |
| 27 | + | |
| 28 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | |
| 29 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | |
| 30 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | |
| 31 | +# lsp: | |
| 32 | +# servers: | |
| 33 | +# - name: gopls | |
| 34 | +# command: gopls | |
| 35 | +# extensions: [".go"] | |
| 36 | +# - name: typescript | |
| 37 | +# command: typescript-language-server | |
| 38 | +# args: ["--stdio"] | |
| 39 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | |
| 40 | +# - name: python | |
| 41 | +# command: pyright-langserver | |
| 42 | +# args: ["--stdio"] | |
| 43 | +# extensions: [".py"] | |
| 44 | +# - name: rust | |
| 45 | +# command: rust-analyzer | |
| 46 | +# extensions: [".rs"] | |
| 47 | + | |
| 48 | +# How many tokens the server actually serves. | |
| 49 | +# 0 = ask the server (llama-server tells it on /props) | |
| 50 | +contextWindow: 0 | |
| 51 | + | |
| 52 | +# Max number of characters a tool returns to the model. | |
| 53 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | |
| 54 | +maxOutput: 16000 | |
| 55 | + | |
| 56 | +# Max number of model <-> tools round trips for a single question. | |
| 57 | +# Raise it for tasks that need long chains of commands. | |
| 58 | +maxTurns: 40 | |
| 59 | + | |
| 60 | +# Where the `read_skill` tool looks for its markdown procedures. | |
| 61 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | |
| 62 | +skillsDir: skills | |
| 63 | + | |
| 64 | +# Persistent sessions, per project. | |
| 65 | +# When enabled, every conversation is saved as one JSON file under `dir`. | |
| 66 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | |
| 67 | +sessions: | |
| 68 | + enabled: true | |
| 69 | + dir: .mm/sessions | |
| 70 | + | |
| 71 | +# How many lines of a command's output are echoed to the terminal. | |
| 72 | +# 0 disables it. | |
| 73 | +previewLines: 20 | |
| 74 | + | |
| 75 | +displayCommands: true | |
| 76 | +# Show what a thinking model reasons about before it answers (dim italic in the | |
| 77 | +# terminal, its own style in the window, a thought chunk in an editor). | |
| 78 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | |
| 79 | +# model thinks — this only says whether to show it. | |
| 80 | +showThinking: true | |
| 81 | + | |
| 82 | + | |
| 83 | +# The system prompt: what the agent is, and what it is allowed to do. | |
| 84 | +# This is the knob to play with — it is the shortest path to changing behaviour. | |
| 85 | +system: | | |
| 86 | + Your name is Bob. | |
| 87 | + You are a coding agent working in a terminal. | |
| 88 | + You have a "bash" tool to run shell commands. | |
| 89 | + Use it to explore files, run tests, inspect the repository, etc. | |
| 90 | + Chain several commands if needed, then answer clearly in English. | |
| 91 | + | |
| 92 | + A request often mixes things you answer from yourself ("say hello") with | |
| 93 | + things only a command can answer ("list the files"). Handle every part, in | |
| 94 | + the order asked, and run a command for each part that needs one. | |
| 95 | + Never state the contents of a file, the output of a command, or the state of | |
| 96 | + the repository unless a command in THIS answer returned it. What you did not | |
| 97 | + read, you do not know: run the command instead of recalling it. | |
| 98 | + | |
| 99 | + SKILLS | |
| 100 | + You have a second tool, `read_skill`. Its description lists the procedures | |
| 101 | + available for this project — one per kind of task. | |
| 102 | + | |
| 103 | + Any request to DO something to a Go project is a skill, not a shell command | |
| 104 | + you invent. Match the request against that list, call `read_skill` FIRST, | |
| 105 | + before any bash command, and then follow what it says step by step. | |
| 106 | + | |
| 107 | + FILE EDITING | |
| 108 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | |
| 109 | + They are how a file gets read and changed here: each change is exact, | |
| 110 | + checked before it is written, and comes back as a diff with line numbers. | |
| 111 | + bash is for running things — building, testing, listing, searching. | |
| 112 | + | |
| 113 | + - Read before you write: call `read_file` on the file (numbered=true when | |
| 114 | + you need line numbers). You cannot target text you have not seen; never | |
| 115 | + rely on what you think you remember about a file. | |
| 116 | + - To change an existing file, call `edit_file` with one or more {old, new} | |
| 117 | + pairs. `old` is copied from the file character for character — same | |
| 118 | + spaces, same indentation, same line breaks — and appears exactly once: | |
| 119 | + add the surrounding lines until it is unique. Several pairs are applied | |
| 120 | + together, against the original file. An empty `new` deletes the text. | |
| 121 | + - Call `write_file` only to create a file, or to rewrite one entirely and | |
| 122 | + on purpose. On an existing file it replaces everything, including what | |
| 123 | + you did not intend to touch. | |
| 124 | + - Read the diff the tool returns: it says exactly what changed and on which | |
| 125 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | |
| 126 | + edits — read the file again and fix `old`. Do not fall back to | |
| 127 | + `write_file` to force the change through. | |
| 128 | + - After editing code, run the narrowest check with bash: the formatter, the | |
| 129 | + compiler, or the test covering that file. | |
| 130 | + | |
| 131 | + RULES | |
| 132 | + - Keep everything the file already does, unless the user asked to remove it. | |
| 133 | + - Touch only the files the request is about. Do not add tests, files or | |
| 134 | + features that were not asked for. | |
| 135 | + - Never run a git command unless the user says git, commit or push. | |
| 136 | + - Never move, rename or delete a file unless the user asked for it. | |
| 137 | + - Then answer in English, in a few lines. | |
| 138 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | |
| 139 | + to understand the options, then run the command. | |
| 140 | + | |
| 141 | + BACKGROUND JOBS | |
| 142 | + Never let a command block the answer. Anything that serves, watches or runs | |
| 143 | + long goes to the background, with BOTH streams redirected and its pid kept: | |
| 144 | + | |
| 145 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | |
| 146 | + | |
| 147 | + Redirecting only stdout still blocks until the process exits. Read the | |
| 148 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | |
| 149 | + rule you cannot guess. Stop every job you started before you finish, and say | |
| 150 | + which ones you left running. | |
| 151 | + | |
| 152 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | |
| 153 | +# we want precise and reproducible answers, not creativity. | |
| 154 | +sampling: | |
| 155 | + temperature: 0.0 | |
| 156 | + parallel_tool_calls: false | |
| 157 | + top_p: 0.9 | |
| 158 | + max_tokens: 32768 | |
| 159 | + | |
| 160 | +# llama-server processes the whole prompt before the first token; | |
| 161 | +# on a laptop a 32k context can take a while. Raise it if it fires. | |
| 162 | +watchdogTimeout: 300s | |
| 163 | + | |
| 164 | +# Context compression. | |
| 165 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | |
| 166 | +context: | |
| 167 | + enabled: true | |
| 168 | + | |
| 169 | + # Compress when the history reaches this share of the window. | |
| 170 | + threshold: 75 | |
| 171 | + | |
| 172 | + # Fallback on the message count, for when the window is unknown. | |
| 173 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | |
| 174 | + maxMessages: 80 | |
| 175 | + | |
| 176 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | |
| 177 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | |
| 178 | + keepLastTurns: 3 | |
| 179 | + | |
| 180 | + # max_tokens of the summary request. | |
| 181 | + summaryMaxTokens: 1200 | |
| 182 | + | |
| 183 | + showStats: true | |
| new file mode 100644 | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | ||
| 2 | + | ||
| 3 | +provider: dmr | ||
| 4 | + | ||
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | ||
| 6 | +#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | ||
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | ||
| 8 | +model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL | ||
| 9 | + | ||
| 10 | +baseUrl: http://localhost:12434/engines/v1 | ||
| 11 | +fallback: http://host.docker.internal:12434/engines/v1 | ||
| 12 | + | ||
| 13 | +# Only when llama-server was started with --api-key; unset otherwise. | ||
| 14 | +# apiKeyEnv: LLAMA_API_KEY | ||
| 15 | + | ||
| 16 | +# The `bash` tool. | ||
| 17 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | ||
| 18 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | ||
| 19 | +bashTool: true | ||
| 20 | + | ||
| 21 | +# The built-in file tools: read_file, write_file, edit_file. | ||
| 22 | +editTools: true | ||
| 23 | + | ||
| 24 | +# The built-in plan tool for managing multi-step plans. | ||
| 25 | +# Set to false to disable plan creation and tracking via the `plan` tool. | ||
| 26 | +planTool: true | ||
| 27 | + | ||
| 28 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | ||
| 29 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | ||
| 30 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | ||
| 31 | +# lsp: | ||
| 32 | +# servers: | ||
| 33 | +# - name: gopls | ||
| 34 | +# command: gopls | ||
| 35 | +# extensions: [".go"] | ||
| 36 | +# - name: typescript | ||
| 37 | +# command: typescript-language-server | ||
| 38 | +# args: ["--stdio"] | ||
| 39 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | ||
| 40 | +# - name: python | ||
| 41 | +# command: pyright-langserver | ||
| 42 | +# args: ["--stdio"] | ||
| 43 | +# extensions: [".py"] | ||
| 44 | +# - name: rust | ||
| 45 | +# command: rust-analyzer | ||
| 46 | +# extensions: [".rs"] | ||
| 47 | + | ||
| 48 | +# How many tokens the server actually serves. | ||
| 49 | +# 0 = ask the server (llama-server tells it on /props) | ||
| 50 | +contextWindow: 0 | ||
| 51 | + | ||
| 52 | +# Max number of characters a tool returns to the model. | ||
| 53 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | ||
| 54 | +maxOutput: 16000 | ||
| 55 | + | ||
| 56 | +# Max number of model <-> tools round trips for a single question. | ||
| 57 | +# Raise it for tasks that need long chains of commands. | ||
| 58 | +maxTurns: 40 | ||
| 59 | + | ||
| 60 | +# Where the `read_skill` tool looks for its markdown procedures. | ||
| 61 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | ||
| 62 | +skillsDir: skills | ||
| 63 | + | ||
| 64 | +# Persistent sessions, per project. | ||
| 65 | +# When enabled, every conversation is saved as one JSON file under `dir`. | ||
| 66 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | ||
| 67 | +sessions: | ||
| 68 | + enabled: true | ||
| 69 | + dir: .mm/sessions | ||
| 70 | + | ||
| 71 | +# How many lines of a command's output are echoed to the terminal. | ||
| 72 | +# 0 disables it. | ||
| 73 | +previewLines: 20 | ||
| 74 | + | ||
| 75 | +displayCommands: true | ||
| 76 | +# Show what a thinking model reasons about before it answers (dim italic in the | ||
| 77 | +# terminal, its own style in the window, a thought chunk in an editor). | ||
| 78 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | ||
| 79 | +# model thinks — this only says whether to show it. | ||
| 80 | +showThinking: true | ||
| 81 | + | ||
| 82 | + | ||
| 83 | +# The system prompt: what the agent is, and what it is allowed to do. | ||
| 84 | +# This is the knob to play with — it is the shortest path to changing behaviour. | ||
| 85 | +system: | | ||
| 86 | + Your name is Bob. | ||
| 87 | + You are a coding agent working in a terminal. | ||
| 88 | + You have a "bash" tool to run shell commands. | ||
| 89 | + Use it to explore files, run tests, inspect the repository, etc. | ||
| 90 | + Chain several commands if needed, then answer clearly in English. | ||
| 91 | + | ||
| 92 | + A request often mixes things you answer from yourself ("say hello") with | ||
| 93 | + things only a command can answer ("list the files"). Handle every part, in | ||
| 94 | + the order asked, and run a command for each part that needs one. | ||
| 95 | + Never state the contents of a file, the output of a command, or the state of | ||
| 96 | + the repository unless a command in THIS answer returned it. What you did not | ||
| 97 | + read, you do not know: run the command instead of recalling it. | ||
| 98 | + | ||
| 99 | + SKILLS | ||
| 100 | + You have a second tool, `read_skill`. Its description lists the procedures | ||
| 101 | + available for this project — one per kind of task. | ||
| 102 | + | ||
| 103 | + Any request to DO something to a Go project is a skill, not a shell command | ||
| 104 | + you invent. Match the request against that list, call `read_skill` FIRST, | ||
| 105 | + before any bash command, and then follow what it says step by step. | ||
| 106 | + | ||
| 107 | + FILE EDITING | ||
| 108 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | ||
| 109 | + They are how a file gets read and changed here: each change is exact, | ||
| 110 | + checked before it is written, and comes back as a diff with line numbers. | ||
| 111 | + bash is for running things — building, testing, listing, searching. | ||
| 112 | + | ||
| 113 | + - Read before you write: call `read_file` on the file (numbered=true when | ||
| 114 | + you need line numbers). You cannot target text you have not seen; never | ||
| 115 | + rely on what you think you remember about a file. | ||
| 116 | + - To change an existing file, call `edit_file` with one or more {old, new} | ||
| 117 | + pairs. `old` is copied from the file character for character — same | ||
| 118 | + spaces, same indentation, same line breaks — and appears exactly once: | ||
| 119 | + add the surrounding lines until it is unique. Several pairs are applied | ||
| 120 | + together, against the original file. An empty `new` deletes the text. | ||
| 121 | + - Call `write_file` only to create a file, or to rewrite one entirely and | ||
| 122 | + on purpose. On an existing file it replaces everything, including what | ||
| 123 | + you did not intend to touch. | ||
| 124 | + - Read the diff the tool returns: it says exactly what changed and on which | ||
| 125 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | ||
| 126 | + edits — read the file again and fix `old`. Do not fall back to | ||
| 127 | + `write_file` to force the change through. | ||
| 128 | + - After editing code, run the narrowest check with bash: the formatter, the | ||
| 129 | + compiler, or the test covering that file. | ||
| 130 | + | ||
| 131 | + RULES | ||
| 132 | + - Keep everything the file already does, unless the user asked to remove it. | ||
| 133 | + - Touch only the files the request is about. Do not add tests, files or | ||
| 134 | + features that were not asked for. | ||
| 135 | + - Never run a git command unless the user says git, commit or push. | ||
| 136 | + - Never move, rename or delete a file unless the user asked for it. | ||
| 137 | + - Then answer in English, in a few lines. | ||
| 138 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | ||
| 139 | + to understand the options, then run the command. | ||
| 140 | + | ||
| 141 | + BACKGROUND JOBS | ||
| 142 | + Never let a command block the answer. Anything that serves, watches or runs | ||
| 143 | + long goes to the background, with BOTH streams redirected and its pid kept: | ||
| 144 | + | ||
| 145 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | ||
| 146 | + | ||
| 147 | + Redirecting only stdout still blocks until the process exits. Read the | ||
| 148 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | ||
| 149 | + rule you cannot guess. Stop every job you started before you finish, and say | ||
| 150 | + which ones you left running. | ||
| 151 | + | ||
| 152 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | ||
| 153 | +# we want precise and reproducible answers, not creativity. | ||
| 154 | +sampling: | ||
| 155 | + temperature: 0.0 | ||
| 156 | + parallel_tool_calls: false | ||
| 157 | + top_p: 0.9 | ||
| 158 | + max_tokens: 32768 | ||
| 159 | + | ||
| 160 | +# llama-server processes the whole prompt before the first token; | ||
| 161 | +# on a laptop a 32k context can take a while. Raise it if it fires. | ||
| 162 | +watchdogTimeout: 300s | ||
| 163 | + | ||
| 164 | +# Context compression. | ||
| 165 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | ||
| 166 | +context: | ||
| 167 | + enabled: true | ||
| 168 | + | ||
| 169 | + # Compress when the history reaches this share of the window. | ||
| 170 | + threshold: 75 | ||
| 171 | + | ||
| 172 | + # Fallback on the message count, for when the window is unknown. | ||
| 173 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | ||
| 174 | + maxMessages: 80 | ||
| 175 | + | ||
| 176 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | ||
| 177 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | ||
| 178 | + keepLastTurns: 3 | ||
| 179 | + | ||
| 180 | + # max_tokens of the summary request. | ||
| 181 | + summaryMaxTokens: 1200 | ||
| 182 | + | ||
| 183 | + showStats: true | ||
added
config.samples/agent.dmr.qwen3.6.yaml +185 -0 | new file mode 100644 | ||
| @@ -0,0 +1,185 @@ | ||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | |
| 2 | + | |
| 3 | +provider: dmr | |
| 4 | + | |
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | |
| 6 | +#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | |
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | |
| 8 | +#model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL | |
| 9 | + | |
| 10 | +model: huggingface.co/unsloth/qwen3.6-35b-a3b-gguf:UD-Q4_K_M | |
| 11 | + | |
| 12 | +baseUrl: http://localhost:12434/engines/v1 | |
| 13 | +fallback: http://host.docker.internal:12434/engines/v1 | |
| 14 | + | |
| 15 | +# Only when llama-server was started with --api-key; unset otherwise. | |
| 16 | +# apiKeyEnv: LLAMA_API_KEY | |
| 17 | + | |
| 18 | +# The `bash` tool. | |
| 19 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | |
| 20 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | |
| 21 | +bashTool: true | |
| 22 | + | |
| 23 | +# The built-in file tools: read_file, write_file, edit_file. | |
| 24 | +editTools: true | |
| 25 | + | |
| 26 | +# The built-in plan tool for managing multi-step plans. | |
| 27 | +# Set to false to disable plan creation and tracking via the `plan` tool. | |
| 28 | +planTool: true | |
| 29 | + | |
| 30 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | |
| 31 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | |
| 32 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | |
| 33 | +# lsp: | |
| 34 | +# servers: | |
| 35 | +# - name: gopls | |
| 36 | +# command: gopls | |
| 37 | +# extensions: [".go"] | |
| 38 | +# - name: typescript | |
| 39 | +# command: typescript-language-server | |
| 40 | +# args: ["--stdio"] | |
| 41 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | |
| 42 | +# - name: python | |
| 43 | +# command: pyright-langserver | |
| 44 | +# args: ["--stdio"] | |
| 45 | +# extensions: [".py"] | |
| 46 | +# - name: rust | |
| 47 | +# command: rust-analyzer | |
| 48 | +# extensions: [".rs"] | |
| 49 | + | |
| 50 | +# How many tokens the server actually serves. | |
| 51 | +# 0 = ask the server (llama-server tells it on /props) | |
| 52 | +contextWindow: 0 | |
| 53 | + | |
| 54 | +# Max number of characters a tool returns to the model. | |
| 55 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | |
| 56 | +maxOutput: 16000 | |
| 57 | + | |
| 58 | +# Max number of model <-> tools round trips for a single question. | |
| 59 | +# Raise it for tasks that need long chains of commands. | |
| 60 | +maxTurns: 40 | |
| 61 | + | |
| 62 | +# Where the `read_skill` tool looks for its markdown procedures. | |
| 63 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | |
| 64 | +skillsDir: skills | |
| 65 | + | |
| 66 | +# Persistent sessions, per project. | |
| 67 | +# When enabled, every conversation is saved as one JSON file under `dir`. | |
| 68 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | |
| 69 | +sessions: | |
| 70 | + enabled: true | |
| 71 | + dir: .mm/sessions | |
| 72 | + | |
| 73 | +# How many lines of a command's output are echoed to the terminal. | |
| 74 | +# 0 disables it. | |
| 75 | +previewLines: 20 | |
| 76 | + | |
| 77 | +displayCommands: true | |
| 78 | +# Show what a thinking model reasons about before it answers (dim italic in the | |
| 79 | +# terminal, its own style in the window, a thought chunk in an editor). | |
| 80 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | |
| 81 | +# model thinks — this only says whether to show it. | |
| 82 | +showThinking: true | |
| 83 | + | |
| 84 | + | |
| 85 | +# The system prompt: what the agent is, and what it is allowed to do. | |
| 86 | +# This is the knob to play with — it is the shortest path to changing behaviour. | |
| 87 | +system: | | |
| 88 | + Your name is Bob. | |
| 89 | + You are a coding agent working in a terminal. | |
| 90 | + You have a "bash" tool to run shell commands. | |
| 91 | + Use it to explore files, run tests, inspect the repository, etc. | |
| 92 | + Chain several commands if needed, then answer clearly in English. | |
| 93 | + | |
| 94 | + A request often mixes things you answer from yourself ("say hello") with | |
| 95 | + things only a command can answer ("list the files"). Handle every part, in | |
| 96 | + the order asked, and run a command for each part that needs one. | |
| 97 | + Never state the contents of a file, the output of a command, or the state of | |
| 98 | + the repository unless a command in THIS answer returned it. What you did not | |
| 99 | + read, you do not know: run the command instead of recalling it. | |
| 100 | + | |
| 101 | + SKILLS | |
| 102 | + You have a second tool, `read_skill`. Its description lists the procedures | |
| 103 | + available for this project — one per kind of task. | |
| 104 | + | |
| 105 | + Any request to DO something to a Go project is a skill, not a shell command | |
| 106 | + you invent. Match the request against that list, call `read_skill` FIRST, | |
| 107 | + before any bash command, and then follow what it says step by step. | |
| 108 | + | |
| 109 | + FILE EDITING | |
| 110 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | |
| 111 | + They are how a file gets read and changed here: each change is exact, | |
| 112 | + checked before it is written, and comes back as a diff with line numbers. | |
| 113 | + bash is for running things — building, testing, listing, searching. | |
| 114 | + | |
| 115 | + - Read before you write: call `read_file` on the file (numbered=true when | |
| 116 | + you need line numbers). You cannot target text you have not seen; never | |
| 117 | + rely on what you think you remember about a file. | |
| 118 | + - To change an existing file, call `edit_file` with one or more {old, new} | |
| 119 | + pairs. `old` is copied from the file character for character — same | |
| 120 | + spaces, same indentation, same line breaks — and appears exactly once: | |
| 121 | + add the surrounding lines until it is unique. Several pairs are applied | |
| 122 | + together, against the original file. An empty `new` deletes the text. | |
| 123 | + - Call `write_file` only to create a file, or to rewrite one entirely and | |
| 124 | + on purpose. On an existing file it replaces everything, including what | |
| 125 | + you did not intend to touch. | |
| 126 | + - Read the diff the tool returns: it says exactly what changed and on which | |
| 127 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | |
| 128 | + edits — read the file again and fix `old`. Do not fall back to | |
| 129 | + `write_file` to force the change through. | |
| 130 | + - After editing code, run the narrowest check with bash: the formatter, the | |
| 131 | + compiler, or the test covering that file. | |
| 132 | + | |
| 133 | + RULES | |
| 134 | + - Keep everything the file already does, unless the user asked to remove it. | |
| 135 | + - Touch only the files the request is about. Do not add tests, files or | |
| 136 | + features that were not asked for. | |
| 137 | + - Never run a git command unless the user says git, commit or push. | |
| 138 | + - Never move, rename or delete a file unless the user asked for it. | |
| 139 | + - Then answer in English, in a few lines. | |
| 140 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | |
| 141 | + to understand the options, then run the command. | |
| 142 | + | |
| 143 | + BACKGROUND JOBS | |
| 144 | + Never let a command block the answer. Anything that serves, watches or runs | |
| 145 | + long goes to the background, with BOTH streams redirected and its pid kept: | |
| 146 | + | |
| 147 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | |
| 148 | + | |
| 149 | + Redirecting only stdout still blocks until the process exits. Read the | |
| 150 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | |
| 151 | + rule you cannot guess. Stop every job you started before you finish, and say | |
| 152 | + which ones you left running. | |
| 153 | + | |
| 154 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | |
| 155 | +# we want precise and reproducible answers, not creativity. | |
| 156 | +sampling: | |
| 157 | + temperature: 0.0 | |
| 158 | + parallel_tool_calls: false | |
| 159 | + top_p: 0.9 | |
| 160 | + max_tokens: 32768 | |
| 161 | + | |
| 162 | +# llama-server processes the whole prompt before the first token; | |
| 163 | +# on a laptop a 32k context can take a while. Raise it if it fires. | |
| 164 | +watchdogTimeout: 300s | |
| 165 | + | |
| 166 | +# Context compression. | |
| 167 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | |
| 168 | +context: | |
| 169 | + enabled: true | |
| 170 | + | |
| 171 | + # Compress when the history reaches this share of the window. | |
| 172 | + threshold: 75 | |
| 173 | + | |
| 174 | + # Fallback on the message count, for when the window is unknown. | |
| 175 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | |
| 176 | + maxMessages: 80 | |
| 177 | + | |
| 178 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | |
| 179 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | |
| 180 | + keepLastTurns: 3 | |
| 181 | + | |
| 182 | + # max_tokens of the summary request. | |
| 183 | + summaryMaxTokens: 1200 | |
| 184 | + | |
| 185 | + showStats: true | |
| new file mode 100644 | |||
| @@ -0,0 +1,185 @@ | |||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | ||
| 2 | + | ||
| 3 | +provider: dmr | ||
| 4 | + | ||
| 5 | +#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | ||
| 6 | +#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M | ||
| 7 | +#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M | ||
| 8 | +#model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL | ||
| 9 | + | ||
| 10 | +model: huggingface.co/unsloth/qwen3.6-35b-a3b-gguf:UD-Q4_K_M | ||
| 11 | + | ||
| 12 | +baseUrl: http://localhost:12434/engines/v1 | ||
| 13 | +fallback: http://host.docker.internal:12434/engines/v1 | ||
| 14 | + | ||
| 15 | +# Only when llama-server was started with --api-key; unset otherwise. | ||
| 16 | +# apiKeyEnv: LLAMA_API_KEY | ||
| 17 | + | ||
| 18 | +# The `bash` tool. | ||
| 19 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | ||
| 20 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | ||
| 21 | +bashTool: true | ||
| 22 | + | ||
| 23 | +# The built-in file tools: read_file, write_file, edit_file. | ||
| 24 | +editTools: true | ||
| 25 | + | ||
| 26 | +# The built-in plan tool for managing multi-step plans. | ||
| 27 | +# Set to false to disable plan creation and tracking via the `plan` tool. | ||
| 28 | +planTool: true | ||
| 29 | + | ||
| 30 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | ||
| 31 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | ||
| 32 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | ||
| 33 | +# lsp: | ||
| 34 | +# servers: | ||
| 35 | +# - name: gopls | ||
| 36 | +# command: gopls | ||
| 37 | +# extensions: [".go"] | ||
| 38 | +# - name: typescript | ||
| 39 | +# command: typescript-language-server | ||
| 40 | +# args: ["--stdio"] | ||
| 41 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | ||
| 42 | +# - name: python | ||
| 43 | +# command: pyright-langserver | ||
| 44 | +# args: ["--stdio"] | ||
| 45 | +# extensions: [".py"] | ||
| 46 | +# - name: rust | ||
| 47 | +# command: rust-analyzer | ||
| 48 | +# extensions: [".rs"] | ||
| 49 | + | ||
| 50 | +# How many tokens the server actually serves. | ||
| 51 | +# 0 = ask the server (llama-server tells it on /props) | ||
| 52 | +contextWindow: 0 | ||
| 53 | + | ||
| 54 | +# Max number of characters a tool returns to the model. | ||
| 55 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | ||
| 56 | +maxOutput: 16000 | ||
| 57 | + | ||
| 58 | +# Max number of model <-> tools round trips for a single question. | ||
| 59 | +# Raise it for tasks that need long chains of commands. | ||
| 60 | +maxTurns: 40 | ||
| 61 | + | ||
| 62 | +# Where the `read_skill` tool looks for its markdown procedures. | ||
| 63 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | ||
| 64 | +skillsDir: skills | ||
| 65 | + | ||
| 66 | +# Persistent sessions, per project. | ||
| 67 | +# When enabled, every conversation is saved as one JSON file under `dir`. | ||
| 68 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | ||
| 69 | +sessions: | ||
| 70 | + enabled: true | ||
| 71 | + dir: .mm/sessions | ||
| 72 | + | ||
| 73 | +# How many lines of a command's output are echoed to the terminal. | ||
| 74 | +# 0 disables it. | ||
| 75 | +previewLines: 20 | ||
| 76 | + | ||
| 77 | +displayCommands: true | ||
| 78 | +# Show what a thinking model reasons about before it answers (dim italic in the | ||
| 79 | +# terminal, its own style in the window, a thought chunk in an editor). | ||
| 80 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | ||
| 81 | +# model thinks — this only says whether to show it. | ||
| 82 | +showThinking: true | ||
| 83 | + | ||
| 84 | + | ||
| 85 | +# The system prompt: what the agent is, and what it is allowed to do. | ||
| 86 | +# This is the knob to play with — it is the shortest path to changing behaviour. | ||
| 87 | +system: | | ||
| 88 | + Your name is Bob. | ||
| 89 | + You are a coding agent working in a terminal. | ||
| 90 | + You have a "bash" tool to run shell commands. | ||
| 91 | + Use it to explore files, run tests, inspect the repository, etc. | ||
| 92 | + Chain several commands if needed, then answer clearly in English. | ||
| 93 | + | ||
| 94 | + A request often mixes things you answer from yourself ("say hello") with | ||
| 95 | + things only a command can answer ("list the files"). Handle every part, in | ||
| 96 | + the order asked, and run a command for each part that needs one. | ||
| 97 | + Never state the contents of a file, the output of a command, or the state of | ||
| 98 | + the repository unless a command in THIS answer returned it. What you did not | ||
| 99 | + read, you do not know: run the command instead of recalling it. | ||
| 100 | + | ||
| 101 | + SKILLS | ||
| 102 | + You have a second tool, `read_skill`. Its description lists the procedures | ||
| 103 | + available for this project — one per kind of task. | ||
| 104 | + | ||
| 105 | + Any request to DO something to a Go project is a skill, not a shell command | ||
| 106 | + you invent. Match the request against that list, call `read_skill` FIRST, | ||
| 107 | + before any bash command, and then follow what it says step by step. | ||
| 108 | + | ||
| 109 | + FILE EDITING | ||
| 110 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | ||
| 111 | + They are how a file gets read and changed here: each change is exact, | ||
| 112 | + checked before it is written, and comes back as a diff with line numbers. | ||
| 113 | + bash is for running things — building, testing, listing, searching. | ||
| 114 | + | ||
| 115 | + - Read before you write: call `read_file` on the file (numbered=true when | ||
| 116 | + you need line numbers). You cannot target text you have not seen; never | ||
| 117 | + rely on what you think you remember about a file. | ||
| 118 | + - To change an existing file, call `edit_file` with one or more {old, new} | ||
| 119 | + pairs. `old` is copied from the file character for character — same | ||
| 120 | + spaces, same indentation, same line breaks — and appears exactly once: | ||
| 121 | + add the surrounding lines until it is unique. Several pairs are applied | ||
| 122 | + together, against the original file. An empty `new` deletes the text. | ||
| 123 | + - Call `write_file` only to create a file, or to rewrite one entirely and | ||
| 124 | + on purpose. On an existing file it replaces everything, including what | ||
| 125 | + you did not intend to touch. | ||
| 126 | + - Read the diff the tool returns: it says exactly what changed and on which | ||
| 127 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | ||
| 128 | + edits — read the file again and fix `old`. Do not fall back to | ||
| 129 | + `write_file` to force the change through. | ||
| 130 | + - After editing code, run the narrowest check with bash: the formatter, the | ||
| 131 | + compiler, or the test covering that file. | ||
| 132 | + | ||
| 133 | + RULES | ||
| 134 | + - Keep everything the file already does, unless the user asked to remove it. | ||
| 135 | + - Touch only the files the request is about. Do not add tests, files or | ||
| 136 | + features that were not asked for. | ||
| 137 | + - Never run a git command unless the user says git, commit or push. | ||
| 138 | + - Never move, rename or delete a file unless the user asked for it. | ||
| 139 | + - Then answer in English, in a few lines. | ||
| 140 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | ||
| 141 | + to understand the options, then run the command. | ||
| 142 | + | ||
| 143 | + BACKGROUND JOBS | ||
| 144 | + Never let a command block the answer. Anything that serves, watches or runs | ||
| 145 | + long goes to the background, with BOTH streams redirected and its pid kept: | ||
| 146 | + | ||
| 147 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | ||
| 148 | + | ||
| 149 | + Redirecting only stdout still blocks until the process exits. Read the | ||
| 150 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | ||
| 151 | + rule you cannot guess. Stop every job you started before you finish, and say | ||
| 152 | + which ones you left running. | ||
| 153 | + | ||
| 154 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | ||
| 155 | +# we want precise and reproducible answers, not creativity. | ||
| 156 | +sampling: | ||
| 157 | + temperature: 0.0 | ||
| 158 | + parallel_tool_calls: false | ||
| 159 | + top_p: 0.9 | ||
| 160 | + max_tokens: 32768 | ||
| 161 | + | ||
| 162 | +# llama-server processes the whole prompt before the first token; | ||
| 163 | +# on a laptop a 32k context can take a while. Raise it if it fires. | ||
| 164 | +watchdogTimeout: 300s | ||
| 165 | + | ||
| 166 | +# Context compression. | ||
| 167 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | ||
| 168 | +context: | ||
| 169 | + enabled: true | ||
| 170 | + | ||
| 171 | + # Compress when the history reaches this share of the window. | ||
| 172 | + threshold: 75 | ||
| 173 | + | ||
| 174 | + # Fallback on the message count, for when the window is unknown. | ||
| 175 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | ||
| 176 | + maxMessages: 80 | ||
| 177 | + | ||
| 178 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | ||
| 179 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | ||
| 180 | + keepLastTurns: 3 | ||
| 181 | + | ||
| 182 | + # max_tokens of the summary request. | ||
| 183 | + summaryMaxTokens: 1200 | ||
| 184 | + | ||
| 185 | + showStats: true | ||
added
config.samples/agent.llamacpp.ornith.yaml +188 -0 | new file mode 100644 | ||
| @@ -0,0 +1,188 @@ | ||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | |
| 2 | +# | |
| 3 | +# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 4 | +# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | |
| 5 | +#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | |
| 6 | +# | |
| 7 | +provider: llamacpp | |
| 8 | + | |
| 9 | +#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | |
| 10 | +model: ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | |
| 11 | + | |
| 12 | +# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1. | |
| 13 | +baseUrl: http://127.0.0.1:8080/v1 | |
| 14 | + | |
| 15 | +# No fallback: llama-server is wherever you started it. | |
| 16 | +fallback: "" | |
| 17 | + | |
| 18 | +# Only when llama-server was started with --api-key; unset otherwise. | |
| 19 | +# apiKeyEnv: LLAMA_API_KEY | |
| 20 | + | |
| 21 | +# The `bash` tool. | |
| 22 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | |
| 23 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | |
| 24 | +bashTool: true | |
| 25 | + | |
| 26 | +# The built-in file tools: read_file, write_file, edit_file. | |
| 27 | +editTools: true | |
| 28 | + | |
| 29 | +# The built-in plan tool for managing multi-step plans. | |
| 30 | +# Set to false to disable plan creation and tracking via the `plan` tool. | |
| 31 | +planTool: true | |
| 32 | + | |
| 33 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | |
| 34 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | |
| 35 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | |
| 36 | +# lsp: | |
| 37 | +# servers: | |
| 38 | +# - name: gopls | |
| 39 | +# command: gopls | |
| 40 | +# extensions: [".go"] | |
| 41 | +# - name: typescript | |
| 42 | +# command: typescript-language-server | |
| 43 | +# args: ["--stdio"] | |
| 44 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | |
| 45 | +# - name: python | |
| 46 | +# command: pyright-langserver | |
| 47 | +# args: ["--stdio"] | |
| 48 | +# extensions: [".py"] | |
| 49 | +# - name: rust | |
| 50 | +# command: rust-analyzer | |
| 51 | +# extensions: [".rs"] | |
| 52 | + | |
| 53 | +# How many tokens the server actually serves. | |
| 54 | +# 0 = ask the server (llama-server tells it on /props) | |
| 55 | +contextWindow: 0 | |
| 56 | + | |
| 57 | +# Max number of characters a tool returns to the model. | |
| 58 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | |
| 59 | +maxOutput: 16000 | |
| 60 | + | |
| 61 | +# Max number of model <-> tools round trips for a single question. | |
| 62 | +# Raise it for tasks that need long chains of commands. | |
| 63 | +maxTurns: 40 | |
| 64 | + | |
| 65 | +# Where the `read_skill` tool looks for its markdown procedures. | |
| 66 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | |
| 67 | +skillsDir: skills | |
| 68 | + | |
| 69 | +# Persistent sessions, per project. | |
| 70 | +# When enabled, every conversation is saved as one JSON file under `dir`. | |
| 71 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | |
| 72 | +sessions: | |
| 73 | + enabled: true | |
| 74 | + dir: .mm/sessions | |
| 75 | + | |
| 76 | +# How many lines of a command's output are echoed to the terminal. | |
| 77 | +# 0 disables it. | |
| 78 | +previewLines: 20 | |
| 79 | + | |
| 80 | +displayCommands: true | |
| 81 | +# Show what a thinking model reasons about before it answers (dim italic in the | |
| 82 | +# terminal, its own style in the window, a thought chunk in an editor). | |
| 83 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | |
| 84 | +# model thinks — this only says whether to show it. | |
| 85 | +showThinking: true | |
| 86 | + | |
| 87 | + | |
| 88 | +# The system prompt: what the agent is, and what it is allowed to do. | |
| 89 | +# This is the knob to play with — it is the shortest path to changing behaviour. | |
| 90 | +system: | | |
| 91 | + Your name is Bob. | |
| 92 | + You are a coding agent working in a terminal. | |
| 93 | + You have a "bash" tool to run shell commands. | |
| 94 | + Use it to explore files, run tests, inspect the repository, etc. | |
| 95 | + Chain several commands if needed, then answer clearly in English. | |
| 96 | + | |
| 97 | + A request often mixes things you answer from yourself ("say hello") with | |
| 98 | + things only a command can answer ("list the files"). Handle every part, in | |
| 99 | + the order asked, and run a command for each part that needs one. | |
| 100 | + Never state the contents of a file, the output of a command, or the state of | |
| 101 | + the repository unless a command in THIS answer returned it. What you did not | |
| 102 | + read, you do not know: run the command instead of recalling it. | |
| 103 | + | |
| 104 | + SKILLS | |
| 105 | + You have a second tool, `read_skill`. Its description lists the procedures | |
| 106 | + available for this project — one per kind of task. | |
| 107 | + | |
| 108 | + Any request to DO something to a Go project is a skill, not a shell command | |
| 109 | + you invent. Match the request against that list, call `read_skill` FIRST, | |
| 110 | + before any bash command, and then follow what it says step by step. | |
| 111 | + | |
| 112 | + FILE EDITING | |
| 113 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | |
| 114 | + They are how a file gets read and changed here: each change is exact, | |
| 115 | + checked before it is written, and comes back as a diff with line numbers. | |
| 116 | + bash is for running things — building, testing, listing, searching. | |
| 117 | + | |
| 118 | + - Read before you write: call `read_file` on the file (numbered=true when | |
| 119 | + you need line numbers). You cannot target text you have not seen; never | |
| 120 | + rely on what you think you remember about a file. | |
| 121 | + - To change an existing file, call `edit_file` with one or more {old, new} | |
| 122 | + pairs. `old` is copied from the file character for character — same | |
| 123 | + spaces, same indentation, same line breaks — and appears exactly once: | |
| 124 | + add the surrounding lines until it is unique. Several pairs are applied | |
| 125 | + together, against the original file. An empty `new` deletes the text. | |
| 126 | + - Call `write_file` only to create a file, or to rewrite one entirely and | |
| 127 | + on purpose. On an existing file it replaces everything, including what | |
| 128 | + you did not intend to touch. | |
| 129 | + - Read the diff the tool returns: it says exactly what changed and on which | |
| 130 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | |
| 131 | + edits — read the file again and fix `old`. Do not fall back to | |
| 132 | + `write_file` to force the change through. | |
| 133 | + - After editing code, run the narrowest check with bash: the formatter, the | |
| 134 | + compiler, or the test covering that file. | |
| 135 | + | |
| 136 | + RULES | |
| 137 | + - Keep everything the file already does, unless the user asked to remove it. | |
| 138 | + - Touch only the files the request is about. Do not add tests, files or | |
| 139 | + features that were not asked for. | |
| 140 | + - Never run a git command unless the user says git, commit or push. | |
| 141 | + - Never move, rename or delete a file unless the user asked for it. | |
| 142 | + - Then answer in English, in a few lines. | |
| 143 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | |
| 144 | + to understand the options, then run the command. | |
| 145 | + | |
| 146 | + BACKGROUND JOBS | |
| 147 | + Never let a command block the answer. Anything that serves, watches or runs | |
| 148 | + long goes to the background, with BOTH streams redirected and its pid kept: | |
| 149 | + | |
| 150 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | |
| 151 | + | |
| 152 | + Redirecting only stdout still blocks until the process exits. Read the | |
| 153 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | |
| 154 | + rule you cannot guess. Stop every job you started before you finish, and say | |
| 155 | + which ones you left running. | |
| 156 | + | |
| 157 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | |
| 158 | +# we want precise and reproducible answers, not creativity. | |
| 159 | +sampling: | |
| 160 | + temperature: 0.0 | |
| 161 | + parallel_tool_calls: false | |
| 162 | + top_p: 0.9 | |
| 163 | + max_tokens: 32768 | |
| 164 | + | |
| 165 | +# llama-server processes the whole prompt before the first token; | |
| 166 | +# on a laptop a 32k context can take a while. Raise it if it fires. | |
| 167 | +watchdogTimeout: 300s | |
| 168 | + | |
| 169 | +# Context compression. | |
| 170 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | |
| 171 | +context: | |
| 172 | + enabled: true | |
| 173 | + | |
| 174 | + # Compress when the history reaches this share of the window. | |
| 175 | + threshold: 75 | |
| 176 | + | |
| 177 | + # Fallback on the message count, for when the window is unknown. | |
| 178 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | |
| 179 | + maxMessages: 80 | |
| 180 | + | |
| 181 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | |
| 182 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | |
| 183 | + keepLastTurns: 3 | |
| 184 | + | |
| 185 | + # max_tokens of the summary request. | |
| 186 | + summaryMaxTokens: 1200 | |
| 187 | + | |
| 188 | + showStats: true | |
| new file mode 100644 | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | ||
| 2 | +# | ||
| 3 | +# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | ||
| 4 | +# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | ||
| 5 | +#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | ||
| 6 | +# | ||
| 7 | +provider: llamacpp | ||
| 8 | + | ||
| 9 | +#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | ||
| 10 | +model: ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | ||
| 11 | + | ||
| 12 | +# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1. | ||
| 13 | +baseUrl: http://127.0.0.1:8080/v1 | ||
| 14 | + | ||
| 15 | +# No fallback: llama-server is wherever you started it. | ||
| 16 | +fallback: "" | ||
| 17 | + | ||
| 18 | +# Only when llama-server was started with --api-key; unset otherwise. | ||
| 19 | +# apiKeyEnv: LLAMA_API_KEY | ||
| 20 | + | ||
| 21 | +# The `bash` tool. | ||
| 22 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | ||
| 23 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | ||
| 24 | +bashTool: true | ||
| 25 | + | ||
| 26 | +# The built-in file tools: read_file, write_file, edit_file. | ||
| 27 | +editTools: true | ||
| 28 | + | ||
| 29 | +# The built-in plan tool for managing multi-step plans. | ||
| 30 | +# Set to false to disable plan creation and tracking via the `plan` tool. | ||
| 31 | +planTool: true | ||
| 32 | + | ||
| 33 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | ||
| 34 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | ||
| 35 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | ||
| 36 | +# lsp: | ||
| 37 | +# servers: | ||
| 38 | +# - name: gopls | ||
| 39 | +# command: gopls | ||
| 40 | +# extensions: [".go"] | ||
| 41 | +# - name: typescript | ||
| 42 | +# command: typescript-language-server | ||
| 43 | +# args: ["--stdio"] | ||
| 44 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | ||
| 45 | +# - name: python | ||
| 46 | +# command: pyright-langserver | ||
| 47 | +# args: ["--stdio"] | ||
| 48 | +# extensions: [".py"] | ||
| 49 | +# - name: rust | ||
| 50 | +# command: rust-analyzer | ||
| 51 | +# extensions: [".rs"] | ||
| 52 | + | ||
| 53 | +# How many tokens the server actually serves. | ||
| 54 | +# 0 = ask the server (llama-server tells it on /props) | ||
| 55 | +contextWindow: 0 | ||
| 56 | + | ||
| 57 | +# Max number of characters a tool returns to the model. | ||
| 58 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | ||
| 59 | +maxOutput: 16000 | ||
| 60 | + | ||
| 61 | +# Max number of model <-> tools round trips for a single question. | ||
| 62 | +# Raise it for tasks that need long chains of commands. | ||
| 63 | +maxTurns: 40 | ||
| 64 | + | ||
| 65 | +# Where the `read_skill` tool looks for its markdown procedures. | ||
| 66 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | ||
| 67 | +skillsDir: skills | ||
| 68 | + | ||
| 69 | +# Persistent sessions, per project. | ||
| 70 | +# When enabled, every conversation is saved as one JSON file under `dir`. | ||
| 71 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | ||
| 72 | +sessions: | ||
| 73 | + enabled: true | ||
| 74 | + dir: .mm/sessions | ||
| 75 | + | ||
| 76 | +# How many lines of a command's output are echoed to the terminal. | ||
| 77 | +# 0 disables it. | ||
| 78 | +previewLines: 20 | ||
| 79 | + | ||
| 80 | +displayCommands: true | ||
| 81 | +# Show what a thinking model reasons about before it answers (dim italic in the | ||
| 82 | +# terminal, its own style in the window, a thought chunk in an editor). | ||
| 83 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | ||
| 84 | +# model thinks — this only says whether to show it. | ||
| 85 | +showThinking: true | ||
| 86 | + | ||
| 87 | + | ||
| 88 | +# The system prompt: what the agent is, and what it is allowed to do. | ||
| 89 | +# This is the knob to play with — it is the shortest path to changing behaviour. | ||
| 90 | +system: | | ||
| 91 | + Your name is Bob. | ||
| 92 | + You are a coding agent working in a terminal. | ||
| 93 | + You have a "bash" tool to run shell commands. | ||
| 94 | + Use it to explore files, run tests, inspect the repository, etc. | ||
| 95 | + Chain several commands if needed, then answer clearly in English. | ||
| 96 | + | ||
| 97 | + A request often mixes things you answer from yourself ("say hello") with | ||
| 98 | + things only a command can answer ("list the files"). Handle every part, in | ||
| 99 | + the order asked, and run a command for each part that needs one. | ||
| 100 | + Never state the contents of a file, the output of a command, or the state of | ||
| 101 | + the repository unless a command in THIS answer returned it. What you did not | ||
| 102 | + read, you do not know: run the command instead of recalling it. | ||
| 103 | + | ||
| 104 | + SKILLS | ||
| 105 | + You have a second tool, `read_skill`. Its description lists the procedures | ||
| 106 | + available for this project — one per kind of task. | ||
| 107 | + | ||
| 108 | + Any request to DO something to a Go project is a skill, not a shell command | ||
| 109 | + you invent. Match the request against that list, call `read_skill` FIRST, | ||
| 110 | + before any bash command, and then follow what it says step by step. | ||
| 111 | + | ||
| 112 | + FILE EDITING | ||
| 113 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | ||
| 114 | + They are how a file gets read and changed here: each change is exact, | ||
| 115 | + checked before it is written, and comes back as a diff with line numbers. | ||
| 116 | + bash is for running things — building, testing, listing, searching. | ||
| 117 | + | ||
| 118 | + - Read before you write: call `read_file` on the file (numbered=true when | ||
| 119 | + you need line numbers). You cannot target text you have not seen; never | ||
| 120 | + rely on what you think you remember about a file. | ||
| 121 | + - To change an existing file, call `edit_file` with one or more {old, new} | ||
| 122 | + pairs. `old` is copied from the file character for character — same | ||
| 123 | + spaces, same indentation, same line breaks — and appears exactly once: | ||
| 124 | + add the surrounding lines until it is unique. Several pairs are applied | ||
| 125 | + together, against the original file. An empty `new` deletes the text. | ||
| 126 | + - Call `write_file` only to create a file, or to rewrite one entirely and | ||
| 127 | + on purpose. On an existing file it replaces everything, including what | ||
| 128 | + you did not intend to touch. | ||
| 129 | + - Read the diff the tool returns: it says exactly what changed and on which | ||
| 130 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | ||
| 131 | + edits — read the file again and fix `old`. Do not fall back to | ||
| 132 | + `write_file` to force the change through. | ||
| 133 | + - After editing code, run the narrowest check with bash: the formatter, the | ||
| 134 | + compiler, or the test covering that file. | ||
| 135 | + | ||
| 136 | + RULES | ||
| 137 | + - Keep everything the file already does, unless the user asked to remove it. | ||
| 138 | + - Touch only the files the request is about. Do not add tests, files or | ||
| 139 | + features that were not asked for. | ||
| 140 | + - Never run a git command unless the user says git, commit or push. | ||
| 141 | + - Never move, rename or delete a file unless the user asked for it. | ||
| 142 | + - Then answer in English, in a few lines. | ||
| 143 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | ||
| 144 | + to understand the options, then run the command. | ||
| 145 | + | ||
| 146 | + BACKGROUND JOBS | ||
| 147 | + Never let a command block the answer. Anything that serves, watches or runs | ||
| 148 | + long goes to the background, with BOTH streams redirected and its pid kept: | ||
| 149 | + | ||
| 150 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | ||
| 151 | + | ||
| 152 | + Redirecting only stdout still blocks until the process exits. Read the | ||
| 153 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | ||
| 154 | + rule you cannot guess. Stop every job you started before you finish, and say | ||
| 155 | + which ones you left running. | ||
| 156 | + | ||
| 157 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | ||
| 158 | +# we want precise and reproducible answers, not creativity. | ||
| 159 | +sampling: | ||
| 160 | + temperature: 0.0 | ||
| 161 | + parallel_tool_calls: false | ||
| 162 | + top_p: 0.9 | ||
| 163 | + max_tokens: 32768 | ||
| 164 | + | ||
| 165 | +# llama-server processes the whole prompt before the first token; | ||
| 166 | +# on a laptop a 32k context can take a while. Raise it if it fires. | ||
| 167 | +watchdogTimeout: 300s | ||
| 168 | + | ||
| 169 | +# Context compression. | ||
| 170 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | ||
| 171 | +context: | ||
| 172 | + enabled: true | ||
| 173 | + | ||
| 174 | + # Compress when the history reaches this share of the window. | ||
| 175 | + threshold: 75 | ||
| 176 | + | ||
| 177 | + # Fallback on the message count, for when the window is unknown. | ||
| 178 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | ||
| 179 | + maxMessages: 80 | ||
| 180 | + | ||
| 181 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | ||
| 182 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | ||
| 183 | + keepLastTurns: 3 | ||
| 184 | + | ||
| 185 | + # max_tokens of the summary request. | ||
| 186 | + summaryMaxTokens: 1200 | ||
| 187 | + | ||
| 188 | + showStats: true | ||
added
config.samples/agent.llamacpp.qwen3.8.yaml +188 -0 | new file mode 100644 | ||
| @@ -0,0 +1,188 @@ | ||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | |
| 2 | +# | |
| 3 | +# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | |
| 4 | +# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | |
| 5 | +#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | |
| 6 | +# | |
| 7 | +provider: llamacpp | |
| 8 | + | |
| 9 | +#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | |
| 10 | +model: unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | |
| 11 | + | |
| 12 | +# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1. | |
| 13 | +baseUrl: http://127.0.0.1:8080/v1 | |
| 14 | + | |
| 15 | +# No fallback: llama-server is wherever you started it. | |
| 16 | +fallback: "" | |
| 17 | + | |
| 18 | +# Only when llama-server was started with --api-key; unset otherwise. | |
| 19 | +# apiKeyEnv: LLAMA_API_KEY | |
| 20 | + | |
| 21 | +# The `bash` tool. | |
| 22 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | |
| 23 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | |
| 24 | +bashTool: true | |
| 25 | + | |
| 26 | +# The built-in file tools: read_file, write_file, edit_file. | |
| 27 | +editTools: true | |
| 28 | + | |
| 29 | +# The built-in plan tool for managing multi-step plans. | |
| 30 | +# Set to false to disable plan creation and tracking via the `plan` tool. | |
| 31 | +planTool: true | |
| 32 | + | |
| 33 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | |
| 34 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | |
| 35 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | |
| 36 | +# lsp: | |
| 37 | +# servers: | |
| 38 | +# - name: gopls | |
| 39 | +# command: gopls | |
| 40 | +# extensions: [".go"] | |
| 41 | +# - name: typescript | |
| 42 | +# command: typescript-language-server | |
| 43 | +# args: ["--stdio"] | |
| 44 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | |
| 45 | +# - name: python | |
| 46 | +# command: pyright-langserver | |
| 47 | +# args: ["--stdio"] | |
| 48 | +# extensions: [".py"] | |
| 49 | +# - name: rust | |
| 50 | +# command: rust-analyzer | |
| 51 | +# extensions: [".rs"] | |
| 52 | + | |
| 53 | +# How many tokens the server actually serves. | |
| 54 | +# 0 = ask the server (llama-server tells it on /props) | |
| 55 | +contextWindow: 0 | |
| 56 | + | |
| 57 | +# Max number of characters a tool returns to the model. | |
| 58 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | |
| 59 | +maxOutput: 16000 | |
| 60 | + | |
| 61 | +# Max number of model <-> tools round trips for a single question. | |
| 62 | +# Raise it for tasks that need long chains of commands. | |
| 63 | +maxTurns: 40 | |
| 64 | + | |
| 65 | +# Where the `read_skill` tool looks for its markdown procedures. | |
| 66 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | |
| 67 | +skillsDir: skills | |
| 68 | + | |
| 69 | +# Persistent sessions, per project. | |
| 70 | +# When enabled, every conversation is saved as one JSON file under `dir`. | |
| 71 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | |
| 72 | +sessions: | |
| 73 | + enabled: true | |
| 74 | + dir: .mm/sessions | |
| 75 | + | |
| 76 | +# How many lines of a command's output are echoed to the terminal. | |
| 77 | +# 0 disables it. | |
| 78 | +previewLines: 20 | |
| 79 | + | |
| 80 | +displayCommands: true | |
| 81 | +# Show what a thinking model reasons about before it answers (dim italic in the | |
| 82 | +# terminal, its own style in the window, a thought chunk in an editor). | |
| 83 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | |
| 84 | +# model thinks — this only says whether to show it. | |
| 85 | +showThinking: true | |
| 86 | + | |
| 87 | + | |
| 88 | +# The system prompt: what the agent is, and what it is allowed to do. | |
| 89 | +# This is the knob to play with — it is the shortest path to changing behaviour. | |
| 90 | +system: | | |
| 91 | + Your name is Bob. | |
| 92 | + You are a coding agent working in a terminal. | |
| 93 | + You have a "bash" tool to run shell commands. | |
| 94 | + Use it to explore files, run tests, inspect the repository, etc. | |
| 95 | + Chain several commands if needed, then answer clearly in English. | |
| 96 | + | |
| 97 | + A request often mixes things you answer from yourself ("say hello") with | |
| 98 | + things only a command can answer ("list the files"). Handle every part, in | |
| 99 | + the order asked, and run a command for each part that needs one. | |
| 100 | + Never state the contents of a file, the output of a command, or the state of | |
| 101 | + the repository unless a command in THIS answer returned it. What you did not | |
| 102 | + read, you do not know: run the command instead of recalling it. | |
| 103 | + | |
| 104 | + SKILLS | |
| 105 | + You have a second tool, `read_skill`. Its description lists the procedures | |
| 106 | + available for this project — one per kind of task. | |
| 107 | + | |
| 108 | + Any request to DO something to a Go project is a skill, not a shell command | |
| 109 | + you invent. Match the request against that list, call `read_skill` FIRST, | |
| 110 | + before any bash command, and then follow what it says step by step. | |
| 111 | + | |
| 112 | + FILE EDITING | |
| 113 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | |
| 114 | + They are how a file gets read and changed here: each change is exact, | |
| 115 | + checked before it is written, and comes back as a diff with line numbers. | |
| 116 | + bash is for running things — building, testing, listing, searching. | |
| 117 | + | |
| 118 | + - Read before you write: call `read_file` on the file (numbered=true when | |
| 119 | + you need line numbers). You cannot target text you have not seen; never | |
| 120 | + rely on what you think you remember about a file. | |
| 121 | + - To change an existing file, call `edit_file` with one or more {old, new} | |
| 122 | + pairs. `old` is copied from the file character for character — same | |
| 123 | + spaces, same indentation, same line breaks — and appears exactly once: | |
| 124 | + add the surrounding lines until it is unique. Several pairs are applied | |
| 125 | + together, against the original file. An empty `new` deletes the text. | |
| 126 | + - Call `write_file` only to create a file, or to rewrite one entirely and | |
| 127 | + on purpose. On an existing file it replaces everything, including what | |
| 128 | + you did not intend to touch. | |
| 129 | + - Read the diff the tool returns: it says exactly what changed and on which | |
| 130 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | |
| 131 | + edits — read the file again and fix `old`. Do not fall back to | |
| 132 | + `write_file` to force the change through. | |
| 133 | + - After editing code, run the narrowest check with bash: the formatter, the | |
| 134 | + compiler, or the test covering that file. | |
| 135 | + | |
| 136 | + RULES | |
| 137 | + - Keep everything the file already does, unless the user asked to remove it. | |
| 138 | + - Touch only the files the request is about. Do not add tests, files or | |
| 139 | + features that were not asked for. | |
| 140 | + - Never run a git command unless the user says git, commit or push. | |
| 141 | + - Never move, rename or delete a file unless the user asked for it. | |
| 142 | + - Then answer in English, in a few lines. | |
| 143 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | |
| 144 | + to understand the options, then run the command. | |
| 145 | + | |
| 146 | + BACKGROUND JOBS | |
| 147 | + Never let a command block the answer. Anything that serves, watches or runs | |
| 148 | + long goes to the background, with BOTH streams redirected and its pid kept: | |
| 149 | + | |
| 150 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | |
| 151 | + | |
| 152 | + Redirecting only stdout still blocks until the process exits. Read the | |
| 153 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | |
| 154 | + rule you cannot guess. Stop every job you started before you finish, and say | |
| 155 | + which ones you left running. | |
| 156 | + | |
| 157 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | |
| 158 | +# we want precise and reproducible answers, not creativity. | |
| 159 | +sampling: | |
| 160 | + temperature: 0.0 | |
| 161 | + parallel_tool_calls: false | |
| 162 | + top_p: 0.9 | |
| 163 | + max_tokens: 32768 | |
| 164 | + | |
| 165 | +# llama-server processes the whole prompt before the first token; | |
| 166 | +# on a laptop a 32k context can take a while. Raise it if it fires. | |
| 167 | +watchdogTimeout: 300s | |
| 168 | + | |
| 169 | +# Context compression. | |
| 170 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | |
| 171 | +context: | |
| 172 | + enabled: true | |
| 173 | + | |
| 174 | + # Compress when the history reaches this share of the window. | |
| 175 | + threshold: 75 | |
| 176 | + | |
| 177 | + # Fallback on the message count, for when the window is unknown. | |
| 178 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | |
| 179 | + maxMessages: 80 | |
| 180 | + | |
| 181 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | |
| 182 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | |
| 183 | + keepLastTurns: 3 | |
| 184 | + | |
| 185 | + # max_tokens of the summary request. | |
| 186 | + summaryMaxTokens: 1200 | |
| 187 | + | |
| 188 | + showStats: true | |
| new file mode 100644 | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | +# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner. | ||
| 2 | +# | ||
| 3 | +# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M | ||
| 4 | +# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | ||
| 5 | +#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M | ||
| 6 | +# | ||
| 7 | +provider: llamacpp | ||
| 8 | + | ||
| 9 | +#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M | ||
| 10 | +model: unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M | ||
| 11 | + | ||
| 12 | +# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1. | ||
| 13 | +baseUrl: http://127.0.0.1:8080/v1 | ||
| 14 | + | ||
| 15 | +# No fallback: llama-server is wherever you started it. | ||
| 16 | +fallback: "" | ||
| 17 | + | ||
| 18 | +# Only when llama-server was started with --api-key; unset otherwise. | ||
| 19 | +# apiKeyEnv: LLAMA_API_KEY | ||
| 20 | + | ||
| 21 | +# The `bash` tool. | ||
| 22 | +# `false` removes it: the model can still read and edit files (editTools) and load skills, | ||
| 23 | +# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool". | ||
| 24 | +bashTool: true | ||
| 25 | + | ||
| 26 | +# The built-in file tools: read_file, write_file, edit_file. | ||
| 27 | +editTools: true | ||
| 28 | + | ||
| 29 | +# The built-in plan tool for managing multi-step plans. | ||
| 30 | +# Set to false to disable plan creation and tracking via the `plan` tool. | ||
| 31 | +planTool: true | ||
| 32 | + | ||
| 33 | +# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename). | ||
| 34 | +# The file extension picks the server. A server missing from the PATH is skipped with a warning. | ||
| 35 | +# No server listed = no `lsp` tool. Examples (uncomment what you have installed): | ||
| 36 | +# lsp: | ||
| 37 | +# servers: | ||
| 38 | +# - name: gopls | ||
| 39 | +# command: gopls | ||
| 40 | +# extensions: [".go"] | ||
| 41 | +# - name: typescript | ||
| 42 | +# command: typescript-language-server | ||
| 43 | +# args: ["--stdio"] | ||
| 44 | +# extensions: [".ts", ".tsx", ".js", ".jsx"] | ||
| 45 | +# - name: python | ||
| 46 | +# command: pyright-langserver | ||
| 47 | +# args: ["--stdio"] | ||
| 48 | +# extensions: [".py"] | ||
| 49 | +# - name: rust | ||
| 50 | +# command: rust-analyzer | ||
| 51 | +# extensions: [".rs"] | ||
| 52 | + | ||
| 53 | +# How many tokens the server actually serves. | ||
| 54 | +# 0 = ask the server (llama-server tells it on /props) | ||
| 55 | +contextWindow: 0 | ||
| 56 | + | ||
| 57 | +# Max number of characters a tool returns to the model. | ||
| 58 | +# Context safeguard: beyond that, the output is truncated (beginning + end kept). | ||
| 59 | +maxOutput: 16000 | ||
| 60 | + | ||
| 61 | +# Max number of model <-> tools round trips for a single question. | ||
| 62 | +# Raise it for tasks that need long chains of commands. | ||
| 63 | +maxTurns: 40 | ||
| 64 | + | ||
| 65 | +# Where the `read_skill` tool looks for its markdown procedures. | ||
| 66 | +# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills. | ||
| 67 | +skillsDir: skills | ||
| 68 | + | ||
| 69 | +# Persistent sessions, per project. | ||
| 70 | +# When enabled, every conversation is saved as one JSON file under `dir`. | ||
| 71 | +# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread. | ||
| 72 | +sessions: | ||
| 73 | + enabled: true | ||
| 74 | + dir: .mm/sessions | ||
| 75 | + | ||
| 76 | +# How many lines of a command's output are echoed to the terminal. | ||
| 77 | +# 0 disables it. | ||
| 78 | +previewLines: 20 | ||
| 79 | + | ||
| 80 | +displayCommands: true | ||
| 81 | +# Show what a thinking model reasons about before it answers (dim italic in the | ||
| 82 | +# terminal, its own style in the window, a thought chunk in an editor). | ||
| 83 | +# The reasoning is always READ — it is what keeps the watchdog alive while the | ||
| 84 | +# model thinks — this only says whether to show it. | ||
| 85 | +showThinking: true | ||
| 86 | + | ||
| 87 | + | ||
| 88 | +# The system prompt: what the agent is, and what it is allowed to do. | ||
| 89 | +# This is the knob to play with — it is the shortest path to changing behaviour. | ||
| 90 | +system: | | ||
| 91 | + Your name is Bob. | ||
| 92 | + You are a coding agent working in a terminal. | ||
| 93 | + You have a "bash" tool to run shell commands. | ||
| 94 | + Use it to explore files, run tests, inspect the repository, etc. | ||
| 95 | + Chain several commands if needed, then answer clearly in English. | ||
| 96 | + | ||
| 97 | + A request often mixes things you answer from yourself ("say hello") with | ||
| 98 | + things only a command can answer ("list the files"). Handle every part, in | ||
| 99 | + the order asked, and run a command for each part that needs one. | ||
| 100 | + Never state the contents of a file, the output of a command, or the state of | ||
| 101 | + the repository unless a command in THIS answer returned it. What you did not | ||
| 102 | + read, you do not know: run the command instead of recalling it. | ||
| 103 | + | ||
| 104 | + SKILLS | ||
| 105 | + You have a second tool, `read_skill`. Its description lists the procedures | ||
| 106 | + available for this project — one per kind of task. | ||
| 107 | + | ||
| 108 | + Any request to DO something to a Go project is a skill, not a shell command | ||
| 109 | + you invent. Match the request against that list, call `read_skill` FIRST, | ||
| 110 | + before any bash command, and then follow what it says step by step. | ||
| 111 | + | ||
| 112 | + FILE EDITING | ||
| 113 | + You have three tools for files: `read_file`, `edit_file` and `write_file`. | ||
| 114 | + They are how a file gets read and changed here: each change is exact, | ||
| 115 | + checked before it is written, and comes back as a diff with line numbers. | ||
| 116 | + bash is for running things — building, testing, listing, searching. | ||
| 117 | + | ||
| 118 | + - Read before you write: call `read_file` on the file (numbered=true when | ||
| 119 | + you need line numbers). You cannot target text you have not seen; never | ||
| 120 | + rely on what you think you remember about a file. | ||
| 121 | + - To change an existing file, call `edit_file` with one or more {old, new} | ||
| 122 | + pairs. `old` is copied from the file character for character — same | ||
| 123 | + spaces, same indentation, same line breaks — and appears exactly once: | ||
| 124 | + add the surrounding lines until it is unique. Several pairs are applied | ||
| 125 | + together, against the original file. An empty `new` deletes the text. | ||
| 126 | + - Call `write_file` only to create a file, or to rewrite one entirely and | ||
| 127 | + on purpose. On an existing file it replaces everything, including what | ||
| 128 | + you did not intend to touch. | ||
| 129 | + - Read the diff the tool returns: it says exactly what changed and on which | ||
| 130 | + line. If `edit_file` refuses — text not found, ambiguous, overlapping | ||
| 131 | + edits — read the file again and fix `old`. Do not fall back to | ||
| 132 | + `write_file` to force the change through. | ||
| 133 | + - After editing code, run the narrowest check with bash: the formatter, the | ||
| 134 | + compiler, or the test covering that file. | ||
| 135 | + | ||
| 136 | + RULES | ||
| 137 | + - Keep everything the file already does, unless the user asked to remove it. | ||
| 138 | + - Touch only the files the request is about. Do not add tests, files or | ||
| 139 | + features that were not asked for. | ||
| 140 | + - Never run a git command unless the user says git, commit or push. | ||
| 141 | + - Never move, rename or delete a file unless the user asked for it. | ||
| 142 | + - Then answer in English, in a few lines. | ||
| 143 | + - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`) | ||
| 144 | + to understand the options, then run the command. | ||
| 145 | + | ||
| 146 | + BACKGROUND JOBS | ||
| 147 | + Never let a command block the answer. Anything that serves, watches or runs | ||
| 148 | + long goes to the background, with BOTH streams redirected and its pid kept: | ||
| 149 | + | ||
| 150 | + nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid | ||
| 151 | + | ||
| 152 | + Redirecting only stdout still blocks until the process exits. Read the | ||
| 153 | + `bg-jobs` skill before you wait on, inspect or stop such a job — each has a | ||
| 154 | + rule you cannot guess. Stop every job you started before you finish, and say | ||
| 155 | + which ones you left running. | ||
| 156 | + | ||
| 157 | +# Generation settings (OpenAI API keys). Low temperature for a coding agent: | ||
| 158 | +# we want precise and reproducible answers, not creativity. | ||
| 159 | +sampling: | ||
| 160 | + temperature: 0.0 | ||
| 161 | + parallel_tool_calls: false | ||
| 162 | + top_p: 0.9 | ||
| 163 | + max_tokens: 32768 | ||
| 164 | + | ||
| 165 | +# llama-server processes the whole prompt before the first token; | ||
| 166 | +# on a laptop a 32k context can take a while. Raise it if it fires. | ||
| 167 | +watchdogTimeout: 300s | ||
| 168 | + | ||
| 169 | +# Context compression. | ||
| 170 | +# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to. | ||
| 171 | +context: | ||
| 172 | + enabled: true | ||
| 173 | + | ||
| 174 | + # Compress when the history reaches this share of the window. | ||
| 175 | + threshold: 75 | ||
| 176 | + | ||
| 177 | + # Fallback on the message count, for when the window is unknown. | ||
| 178 | + # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history. | ||
| 179 | + maxMessages: 80 | ||
| 180 | + | ||
| 181 | + # How many recent questions (with their commands and answers) are kept as-is instead of being summarised. | ||
| 182 | + # The model works on the last few turns, so summarising them would make it redo what it just did. | ||
| 183 | + keepLastTurns: 3 | ||
| 184 | + | ||
| 185 | + # max_tokens of the summary request. | ||
| 186 | + summaryMaxTokens: 1200 | ||
| 187 | + | ||
| 188 | + showStats: true | ||
added
docker-sbx-v3/README.md +154 -0 | new file mode 100644 | ||
| @@ -0,0 +1,154 @@ | ||
| 1 | +# mm in a Docker Sandbox — kits v3 | |
| 2 | + | |
| 3 | +The same two kits as [`../docker-sbx`](../docker-sbx/README.md), rewritten for the [kit specification v3](https://github.com/docker/sandbox-kit-spec) (`schemaVersion: "3"`). `docker-sbx/` (v2) is left untouched and keeps working: sbx still loads `spec.yaml` kits. | |
| 4 | + | |
| 5 | +- **mm-tui** — `sbx run` opens mm's window mode (`mm -tui`) on the workspace. | |
| 6 | +- **mm-acp** — `sbx create` once, then an editor that speaks the Agent Client Protocol runs `sbx exec -i … mm -acp`. | |
| 7 | + | |
| 8 | +``` | |
| 9 | +docker-sbx-v3/ | |
| 10 | +├── publish.sh build + push the image, then build + push the kits — the one command to release | |
| 11 | +├── build.sh builds the template image, k33g/mm-sandbox:<version> (PUSH=1: multi-arch, pushed) | |
| 12 | +├── sync-kits.sh points the kits at one image: owner + version | |
| 13 | +├── check-kits.sh builds the kits locally (no push, no sbx) and checks them with kit-tck if present | |
| 14 | +├── push-kits.sh builds and pushes the kits with buildx: <owner>/sbx-kit-mm-tui, <owner>/sbx-kit-mm-acp | |
| 15 | +├── template/ | |
| 16 | +│ ├── Dockerfile docker/sandbox-templates:shell + mm (built from this checkout) — same image as v2 | |
| 17 | +│ ├── mm-tui entry point of the mm-tui kit: `mm -tui "$@"` | |
| 18 | +│ └── mm-acp-info entry point of the mm-acp kit: prints the editor wiring, opens a shell | |
| 19 | +└── kits/ | |
| 20 | + ├── mm-tui/ | |
| 21 | + │ ├── mm-tui.yaml the descriptor: kind: workload, args, capabilities | |
| 22 | + │ └── mm-tui.dockerfile the content: FROM <image>:<tag>, ENV, ENTRYPOINT ["mm-tui"] | |
| 23 | + └── mm-acp/ | |
| 24 | + ├── mm-acp.yaml | |
| 25 | + └── mm-acp.dockerfile … ENTRYPOINT ["mm-acp-info"] | |
| 26 | +``` | |
| 27 | + | |
| 28 | +## What changed from the v2 kits | |
| 29 | + | |
| 30 | +| | v2 (`docker-sbx/kits/*/spec.yaml`) | v3 (`docker-sbx-v3/kits/*/`) | | |
| 31 | +|---|---|---| | |
| 32 | +| Files | one `spec.yaml` | `<kit>.yaml` (descriptor) + `<kit>.dockerfile` (content) | | |
| 33 | +| Kind | `kind: sandbox` | `kind: workload` | | |
| 34 | +| Name | `name: mm-tui` | none: a kit's identity is the reference it is consumed by | | |
| 35 | +| Image, entry point, env | `sandbox.image`, `sandbox.entrypoint`, `environment.variables` | `FROM`, `ENTRYPOINT`, `ENV` in the Dockerfile — the descriptor restates nothing the image config carries | | |
| 36 | +| Network | `permissions.network.allow` | `capabilities: - type: com.docker.sandbox/network-policy@1` (`runtime.allow`) | | |
| 37 | +| Agent launch | implicit | `capabilities: - type: com.docker.sandbox/sbx@1`: the host runs the ENTRYPOINT under bash, as the image's user (`agent`) | | |
| 38 | +| `tag` arg | substituted into `sandbox.image` at create | **build-phase** (`buildArg: MM_TAG`): baked in when the kit is built; also the kit's `version` and its `provides: mm@<tag>` | | |
| 39 | +| `config` arg | substituted into `environment.variables` | **create-phase** (`env: AGENT_CONFIG`): exported to the container at `sbx run` / `sbx create` | | |
| 40 | +| Owner of the image | rewritten in `sandbox.image` | its own build-phase arg, `image` (`k33g/mm-sandbox`) | | |
| 41 | +| Published as | `sbx kit push` → `k33g/mm-tui`, `k33g/mm-acp` | `docker buildx build --push` → `k33g/sbx-kit-mm-tui`, `k33g/sbx-kit-mm-acp` (an ordinary multi-arch image, with SBOM and provenance) | | |
| 42 | + | |
| 43 | +The repositories differ on purpose: pushing a v3 kit to `k33g/mm-tui:<version>` would replace the v2 kit published under that tag. `sbx-kit-<name>` is the naming Docker's own kits use. | |
| 44 | + | |
| 45 | +## Two things behave differently | |
| 46 | + | |
| 47 | +**The workspace is `/home/agent/workspace`.** The template's base image declares that `WORKDIR`, and `sbx@1` requires the host to mount the workspace at the image's working directory when it is absolute. A relative configuration path (`config=agent.dmr.yaml`) works as before. An absolute **host** path in `AGENT_CONFIG` (`/Users/…/agent.dmr.yaml`) does not: use the path relative to the workspace, or `/home/agent/workspace/…`. (Stated by the specification; not yet observed with sbx.) | |
| 48 | + | |
| 49 | +**The template image must be on a registry to run the kits from source.** A v3 kit is built on top of the template (`FROM k33g/mm-sandbox:<tag>`), and `sbx run ./docker-sbx-v3/kits/…` builds it in sbx's builder sandbox, whose own Docker engine pulls that image from the registry. `--pull never` and `sbx template load` no longer help. Push the image (`PUSH=1 ./docker-sbx-v3/build.sh`) before running a kit from source, or check the kits without sbx with `check-kits.sh`. | |
| 50 | + | |
| 51 | +## 0. Use the published kits (no build) | |
| 52 | + | |
| 53 | +Once `publish.sh` has run for a version: | |
| 54 | + | |
| 55 | +```bash | |
| 56 | +sbx kit inspect k33g/sbx-kit-mm-tui:0.2.1 # look before you run | |
| 57 | + | |
| 58 | +cd /path/to/your/project | |
| 59 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 60 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 61 | +``` | |
| 62 | + | |
| 63 | +What follows `--` is mm's own command line. Without it, mm reads the `config` argument, then `./agent.yaml` in the workspace, then its built-in defaults. | |
| 64 | + | |
| 65 | +From an editor, create the sandbox once, from the project the editor will open: | |
| 66 | + | |
| 67 | +```bash | |
| 68 | +cd /path/to/your/project | |
| 69 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 70 | +``` | |
| 71 | + | |
| 72 | +then register it — in Zed's `settings.json`: | |
| 73 | + | |
| 74 | +```json | |
| 75 | +{ | |
| 76 | + "agent_servers": { | |
| 77 | + "mini-me (sandbox)": { | |
| 78 | + "type": "custom", | |
| 79 | + "command": "sbx", | |
| 80 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | |
| 81 | + } | |
| 82 | + } | |
| 83 | +} | |
| 84 | +``` | |
| 85 | + | |
| 86 | +**Kit arguments.** On a published kit only `config` can be set: `image` and `tag` are build-phase and were fixed when the kit was built, so a published kit always names the image it was built on. To use another mm version, take the kit of that version. | |
| 87 | + | |
| 88 | +| `--kit-arg` | Default | Phase | Effect | | |
| 89 | +|---|---|---|---| | |
| 90 | +| `config=<path>` | empty | create | The file mm reads (its `AGENT_CONFIG`): relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. | | |
| 91 | +| `tag=<version>` | mm's version (`0.2.1`) | build | Which `<image>:<tag>` the kit is built FROM; also the kit's version. No `v`. | | |
| 92 | +| `image=<repo>` | `k33g/mm-sandbox` | build | Which repository the kit is built FROM. | | |
| 93 | + | |
| 94 | +## 1. Build the template | |
| 95 | + | |
| 96 | +From the repository root: | |
| 97 | + | |
| 98 | +```bash | |
| 99 | +./docker-sbx-v3/build.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, local store | |
| 100 | +PUSH=1 ./docker-sbx-v3/build.sh # multi-arch, pushed — needed before running a kit from source | |
| 101 | +``` | |
| 102 | + | |
| 103 | +Same image, same rules as v2's `build.sh`; it then rewrites the kits' `image` and `tag` defaults (`sync-kits.sh`), so the kits always name the image just built. | |
| 104 | + | |
| 105 | +## 2. Check the kits without sbx | |
| 106 | + | |
| 107 | +```bash | |
| 108 | +./docker-sbx-v3/check-kits.sh # both kits | |
| 109 | +./docker-sbx-v3/check-kits.sh mm-tui # one | |
| 110 | +``` | |
| 111 | + | |
| 112 | +Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit frontend, which validates the descriptor (unknown keys and arg patterns included), builds the companion Dockerfile and writes the published form to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (or `KIT_TCK=/path/to/kit-tck`), the result is also checked against the specification: | |
| 113 | + | |
| 114 | +```bash | |
| 115 | +git clone https://github.com/docker/sandbox-kit-spec && cd sandbox-kit-spec | |
| 116 | +go build -o ~/.local/bin/kit-tck ./cmd/kit-tck | |
| 117 | +``` | |
| 118 | + | |
| 119 | +## 3. Run the kits from source | |
| 120 | + | |
| 121 | +With the template pushed (section 1): | |
| 122 | + | |
| 123 | +```bash | |
| 124 | +cd /path/to/your/project | |
| 125 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 126 | +sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml | |
| 127 | +``` | |
| 128 | + | |
| 129 | +sbx recognizes a v3 kit directory by its single `*.yaml` declaring `schemaVersion: "3"` (and no `spec.yaml`), builds it in its builder sandbox (`sbx kit builder status`), and caches the result by the directory's content. From source, the build-phase args can be set too: `--kit-arg tag=0.2.2`. | |
| 130 | + | |
| 131 | +## 4. Publishing a version | |
| 132 | + | |
| 133 | +```bash | |
| 134 | +export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner | |
| 135 | +export DOCKER_PAT=dckr_pat_… # an access token with read/write scope | |
| 136 | +./docker-sbx-v3/publish.sh # TAG from release.env: k33g/mm-sandbox:0.2.1, k33g/sbx-kit-mm-tui:0.2.1, k33g/sbx-kit-mm-acp:0.2.1 | |
| 137 | +``` | |
| 138 | + | |
| 139 | +It is two steps you can also run alone: | |
| 140 | + | |
| 141 | +```bash | |
| 142 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.1 # the image, multi-arch, pushed | |
| 143 | +./docker-sbx-v3/push-kits.sh v0.2.1 # the kits: buildx build --push, linux/amd64 + linux/arm64 | |
| 144 | +``` | |
| 145 | + | |
| 146 | +`push-kits.sh` refuses to start when the image is not on the registry yet, runs `sync-kits.sh`, then builds each kit with the `mm-sandbox-builder` buildx instance (created by `build.sh` if needed) with SBOM and provenance attestations, and validates the pushed kits with `kit-tck` when it is available. No `sbx` is needed to publish. `IMAGE_OWNER`, `REGISTRY`, `KIT_PREFIX` and `PLATFORMS` override the defaults. The descriptors end up naming the new version — commit them. | |
| 147 | + | |
| 148 | +## The model server stays on the host | |
| 149 | + | |
| 150 | +Unchanged from v2: inside a sandbox `localhost` is the sandbox itself, and Docker Model Runner or llama-server are reached through `host.docker.internal`. Both kits allow ports 12434 (Docker Model Runner) and 8080 (llama-server) on the host. Another port: `sbx policy allow network host.docker.internal:<port>`. | |
| 151 | + | |
| 152 | +## Status | |
| 153 | + | |
| 154 | +Checked here: both kits build with the `docker/sandbox-kit:3` frontend (3.0.0-m.6), single- and multi-arch with attestations, and pass `kit-tck validate` (18/18); the published config is `User: agent`, `Entrypoint: [mm-tui]` (or `[mm-acp-info]`), no `Cmd`, `WorkingDir: /home/agent/workspace`. Not yet checked: running them with `sbx` (`sbx run`, `sbx create`, `sbx exec -i … mm -acp`), and pushing to Docker Hub. The kit specification itself is still marked experimental. | |
| new file mode 100644 | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | +# mm in a Docker Sandbox — kits v3 | ||
| 2 | + | ||
| 3 | +The same two kits as [`../docker-sbx`](../docker-sbx/README.md), rewritten for the [kit specification v3](https://github.com/docker/sandbox-kit-spec) (`schemaVersion: "3"`). `docker-sbx/` (v2) is left untouched and keeps working: sbx still loads `spec.yaml` kits. | ||
| 4 | + | ||
| 5 | +- **mm-tui** — `sbx run` opens mm's window mode (`mm -tui`) on the workspace. | ||
| 6 | +- **mm-acp** — `sbx create` once, then an editor that speaks the Agent Client Protocol runs `sbx exec -i … mm -acp`. | ||
| 7 | + | ||
| 8 | +``` | ||
| 9 | +docker-sbx-v3/ | ||
| 10 | +├── publish.sh build + push the image, then build + push the kits — the one command to release | ||
| 11 | +├── build.sh builds the template image, k33g/mm-sandbox:<version> (PUSH=1: multi-arch, pushed) | ||
| 12 | +├── sync-kits.sh points the kits at one image: owner + version | ||
| 13 | +├── check-kits.sh builds the kits locally (no push, no sbx) and checks them with kit-tck if present | ||
| 14 | +├── push-kits.sh builds and pushes the kits with buildx: <owner>/sbx-kit-mm-tui, <owner>/sbx-kit-mm-acp | ||
| 15 | +├── template/ | ||
| 16 | +│ ├── Dockerfile docker/sandbox-templates:shell + mm (built from this checkout) — same image as v2 | ||
| 17 | +│ ├── mm-tui entry point of the mm-tui kit: `mm -tui "$@"` | ||
| 18 | +│ └── mm-acp-info entry point of the mm-acp kit: prints the editor wiring, opens a shell | ||
| 19 | +└── kits/ | ||
| 20 | + ├── mm-tui/ | ||
| 21 | + │ ├── mm-tui.yaml the descriptor: kind: workload, args, capabilities | ||
| 22 | + │ └── mm-tui.dockerfile the content: FROM <image>:<tag>, ENV, ENTRYPOINT ["mm-tui"] | ||
| 23 | + └── mm-acp/ | ||
| 24 | + ├── mm-acp.yaml | ||
| 25 | + └── mm-acp.dockerfile … ENTRYPOINT ["mm-acp-info"] | ||
| 26 | +``` | ||
| 27 | + | ||
| 28 | +## What changed from the v2 kits | ||
| 29 | + | ||
| 30 | +| | v2 (`docker-sbx/kits/*/spec.yaml`) | v3 (`docker-sbx-v3/kits/*/`) | | ||
| 31 | +|---|---|---| | ||
| 32 | +| Files | one `spec.yaml` | `<kit>.yaml` (descriptor) + `<kit>.dockerfile` (content) | | ||
| 33 | +| Kind | `kind: sandbox` | `kind: workload` | | ||
| 34 | +| Name | `name: mm-tui` | none: a kit's identity is the reference it is consumed by | | ||
| 35 | +| Image, entry point, env | `sandbox.image`, `sandbox.entrypoint`, `environment.variables` | `FROM`, `ENTRYPOINT`, `ENV` in the Dockerfile — the descriptor restates nothing the image config carries | | ||
| 36 | +| Network | `permissions.network.allow` | `capabilities: - type: com.docker.sandbox/network-policy@1` (`runtime.allow`) | | ||
| 37 | +| Agent launch | implicit | `capabilities: - type: com.docker.sandbox/sbx@1`: the host runs the ENTRYPOINT under bash, as the image's user (`agent`) | | ||
| 38 | +| `tag` arg | substituted into `sandbox.image` at create | **build-phase** (`buildArg: MM_TAG`): baked in when the kit is built; also the kit's `version` and its `provides: mm@<tag>` | | ||
| 39 | +| `config` arg | substituted into `environment.variables` | **create-phase** (`env: AGENT_CONFIG`): exported to the container at `sbx run` / `sbx create` | | ||
| 40 | +| Owner of the image | rewritten in `sandbox.image` | its own build-phase arg, `image` (`k33g/mm-sandbox`) | | ||
| 41 | +| Published as | `sbx kit push` → `k33g/mm-tui`, `k33g/mm-acp` | `docker buildx build --push` → `k33g/sbx-kit-mm-tui`, `k33g/sbx-kit-mm-acp` (an ordinary multi-arch image, with SBOM and provenance) | | ||
| 42 | + | ||
| 43 | +The repositories differ on purpose: pushing a v3 kit to `k33g/mm-tui:<version>` would replace the v2 kit published under that tag. `sbx-kit-<name>` is the naming Docker's own kits use. | ||
| 44 | + | ||
| 45 | +## Two things behave differently | ||
| 46 | + | ||
| 47 | +**The workspace is `/home/agent/workspace`.** The template's base image declares that `WORKDIR`, and `sbx@1` requires the host to mount the workspace at the image's working directory when it is absolute. A relative configuration path (`config=agent.dmr.yaml`) works as before. An absolute **host** path in `AGENT_CONFIG` (`/Users/…/agent.dmr.yaml`) does not: use the path relative to the workspace, or `/home/agent/workspace/…`. (Stated by the specification; not yet observed with sbx.) | ||
| 48 | + | ||
| 49 | +**The template image must be on a registry to run the kits from source.** A v3 kit is built on top of the template (`FROM k33g/mm-sandbox:<tag>`), and `sbx run ./docker-sbx-v3/kits/…` builds it in sbx's builder sandbox, whose own Docker engine pulls that image from the registry. `--pull never` and `sbx template load` no longer help. Push the image (`PUSH=1 ./docker-sbx-v3/build.sh`) before running a kit from source, or check the kits without sbx with `check-kits.sh`. | ||
| 50 | + | ||
| 51 | +## 0. Use the published kits (no build) | ||
| 52 | + | ||
| 53 | +Once `publish.sh` has run for a version: | ||
| 54 | + | ||
| 55 | +```bash | ||
| 56 | +sbx kit inspect k33g/sbx-kit-mm-tui:0.2.1 # look before you run | ||
| 57 | + | ||
| 58 | +cd /path/to/your/project | ||
| 59 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | ||
| 60 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . --kit-arg config=agent.dmr.yaml | ||
| 61 | +``` | ||
| 62 | + | ||
| 63 | +What follows `--` is mm's own command line. Without it, mm reads the `config` argument, then `./agent.yaml` in the workspace, then its built-in defaults. | ||
| 64 | + | ||
| 65 | +From an editor, create the sandbox once, from the project the editor will open: | ||
| 66 | + | ||
| 67 | +```bash | ||
| 68 | +cd /path/to/your/project | ||
| 69 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +then register it — in Zed's `settings.json`: | ||
| 73 | + | ||
| 74 | +```json | ||
| 75 | +{ | ||
| 76 | + "agent_servers": { | ||
| 77 | + "mini-me (sandbox)": { | ||
| 78 | + "type": "custom", | ||
| 79 | + "command": "sbx", | ||
| 80 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | +} | ||
| 84 | +``` | ||
| 85 | + | ||
| 86 | +**Kit arguments.** On a published kit only `config` can be set: `image` and `tag` are build-phase and were fixed when the kit was built, so a published kit always names the image it was built on. To use another mm version, take the kit of that version. | ||
| 87 | + | ||
| 88 | +| `--kit-arg` | Default | Phase | Effect | | ||
| 89 | +|---|---|---|---| | ||
| 90 | +| `config=<path>` | empty | create | The file mm reads (its `AGENT_CONFIG`): relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. | | ||
| 91 | +| `tag=<version>` | mm's version (`0.2.1`) | build | Which `<image>:<tag>` the kit is built FROM; also the kit's version. No `v`. | | ||
| 92 | +| `image=<repo>` | `k33g/mm-sandbox` | build | Which repository the kit is built FROM. | | ||
| 93 | + | ||
| 94 | +## 1. Build the template | ||
| 95 | + | ||
| 96 | +From the repository root: | ||
| 97 | + | ||
| 98 | +```bash | ||
| 99 | +./docker-sbx-v3/build.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, local store | ||
| 100 | +PUSH=1 ./docker-sbx-v3/build.sh # multi-arch, pushed — needed before running a kit from source | ||
| 101 | +``` | ||
| 102 | + | ||
| 103 | +Same image, same rules as v2's `build.sh`; it then rewrites the kits' `image` and `tag` defaults (`sync-kits.sh`), so the kits always name the image just built. | ||
| 104 | + | ||
| 105 | +## 2. Check the kits without sbx | ||
| 106 | + | ||
| 107 | +```bash | ||
| 108 | +./docker-sbx-v3/check-kits.sh # both kits | ||
| 109 | +./docker-sbx-v3/check-kits.sh mm-tui # one | ||
| 110 | +``` | ||
| 111 | + | ||
| 112 | +Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit frontend, which validates the descriptor (unknown keys and arg patterns included), builds the companion Dockerfile and writes the published form to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (or `KIT_TCK=/path/to/kit-tck`), the result is also checked against the specification: | ||
| 113 | + | ||
| 114 | +```bash | ||
| 115 | +git clone https://github.com/docker/sandbox-kit-spec && cd sandbox-kit-spec | ||
| 116 | +go build -o ~/.local/bin/kit-tck ./cmd/kit-tck | ||
| 117 | +``` | ||
| 118 | + | ||
| 119 | +## 3. Run the kits from source | ||
| 120 | + | ||
| 121 | +With the template pushed (section 1): | ||
| 122 | + | ||
| 123 | +```bash | ||
| 124 | +cd /path/to/your/project | ||
| 125 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 126 | +sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml | ||
| 127 | +``` | ||
| 128 | + | ||
| 129 | +sbx recognizes a v3 kit directory by its single `*.yaml` declaring `schemaVersion: "3"` (and no `spec.yaml`), builds it in its builder sandbox (`sbx kit builder status`), and caches the result by the directory's content. From source, the build-phase args can be set too: `--kit-arg tag=0.2.2`. | ||
| 130 | + | ||
| 131 | +## 4. Publishing a version | ||
| 132 | + | ||
| 133 | +```bash | ||
| 134 | +export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner | ||
| 135 | +export DOCKER_PAT=dckr_pat_… # an access token with read/write scope | ||
| 136 | +./docker-sbx-v3/publish.sh # TAG from release.env: k33g/mm-sandbox:0.2.1, k33g/sbx-kit-mm-tui:0.2.1, k33g/sbx-kit-mm-acp:0.2.1 | ||
| 137 | +``` | ||
| 138 | + | ||
| 139 | +It is two steps you can also run alone: | ||
| 140 | + | ||
| 141 | +```bash | ||
| 142 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.1 # the image, multi-arch, pushed | ||
| 143 | +./docker-sbx-v3/push-kits.sh v0.2.1 # the kits: buildx build --push, linux/amd64 + linux/arm64 | ||
| 144 | +``` | ||
| 145 | + | ||
| 146 | +`push-kits.sh` refuses to start when the image is not on the registry yet, runs `sync-kits.sh`, then builds each kit with the `mm-sandbox-builder` buildx instance (created by `build.sh` if needed) with SBOM and provenance attestations, and validates the pushed kits with `kit-tck` when it is available. No `sbx` is needed to publish. `IMAGE_OWNER`, `REGISTRY`, `KIT_PREFIX` and `PLATFORMS` override the defaults. The descriptors end up naming the new version — commit them. | ||
| 147 | + | ||
| 148 | +## The model server stays on the host | ||
| 149 | + | ||
| 150 | +Unchanged from v2: inside a sandbox `localhost` is the sandbox itself, and Docker Model Runner or llama-server are reached through `host.docker.internal`. Both kits allow ports 12434 (Docker Model Runner) and 8080 (llama-server) on the host. Another port: `sbx policy allow network host.docker.internal:<port>`. | ||
| 151 | + | ||
| 152 | +## Status | ||
| 153 | + | ||
| 154 | +Checked here: both kits build with the `docker/sandbox-kit:3` frontend (3.0.0-m.6), single- and multi-arch with attestations, and pass `kit-tck validate` (18/18); the published config is `User: agent`, `Entrypoint: [mm-tui]` (or `[mm-acp-info]`), no `Cmd`, `WorkingDir: /home/agent/workspace`. Not yet checked: running them with `sbx` (`sbx run`, `sbx create`, `sbx exec -i … mm -acp`), and pushing to Docker Hub. The kit specification itself is still marked experimental. | ||
added
docker-sbx-v3/build.sh +105 -0 | new file mode 100755 | ||
| @@ -0,0 +1,105 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Build the mm sandbox template image, <owner>/mm-sandbox:<version>, from this | |
| 3 | +# checkout — the image both v3 kits are built FROM. The image tag follows mm's | |
| 4 | +# own tag, minus the "v": release.env says TAG="v0.2.1", the image is | |
| 5 | +# k33g/mm-sandbox:0.2.1 and `mm --version` inside it reports v0.2.1 — the | |
| 6 | +# same rule as the release assets. | |
| 7 | +# | |
| 8 | +# Usage: | |
| 9 | +# ./docker-sbx-v3/build.sh # TAG from release.env, image for this machine | |
| 10 | +# ./docker-sbx-v3/build.sh v0.2.2 # override the tag for this run | |
| 11 | +# PUSH=1 ./docker-sbx-v3/build.sh # multi-arch (linux/amd64 + linux/arm64) built | |
| 12 | +# # with buildx and PUSHED to the registry — | |
| 13 | +# # needs `docker login`; publish.sh does this | |
| 14 | +# IMAGE_OWNER=someone ./docker-sbx-v3/build.sh # another image owner (default k33g) | |
| 15 | +# PLATFORMS=linux/amd64 PUSH=1 … # narrower multi-arch set | |
| 16 | +# SHELL_TEMPLATE=docker/sandbox-templates:shell-docker ./docker-sbx-v3/build.sh | |
| 17 | +# # base it on the Docker-in-Docker shell | |
| 18 | +# | |
| 19 | +# Whatever the mode, the two kits under docker-sbx-v3/kits/ are then pointed | |
| 20 | +# at the image just built (docker-sbx-v3/sync-kits.sh), so kits and image move | |
| 21 | +# together. Publishing the kits themselves is docker-sbx-v3/push-kits.sh, and | |
| 22 | +# docker-sbx-v3/publish.sh chains the two. | |
| 23 | +# | |
| 24 | +# Unlike v2, a v3 kit is BUILT on top of this image (FROM), and sbx builds a | |
| 25 | +# source-form kit in its builder sandbox, whose Docker engine pulls from a | |
| 26 | +# registry: an image that is only in the local store is not enough for | |
| 27 | +# `sbx run ./docker-sbx-v3/kits/…`. Push it (PUSH=1) first. | |
| 28 | +set -euo pipefail | |
| 29 | + | |
| 30 | +cd "$(dirname "$0")/.." | |
| 31 | + | |
| 32 | +# release.env carries TAG ("v0.2.1"). It is git-ignored, so a checkout without | |
| 33 | +# it names the tag on the command line. A tag given on the command line wins. | |
| 34 | +if [ -f release.env ]; then | |
| 35 | + # shellcheck source=/dev/null | |
| 36 | + source release.env | |
| 37 | +fi | |
| 38 | +TAG="${1:-${TAG:-}}" | |
| 39 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | |
| 40 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/build.sh v1.2.3)" | |
| 41 | + exit 1 | |
| 42 | +fi | |
| 43 | + | |
| 44 | +# Not OWNER: release.env uses that name for the git owner (bots-garden), and | |
| 45 | +# the image owner is a different thing — the Docker Hub account, k33g. | |
| 46 | +IMAGE_OWNER="${IMAGE_OWNER:-k33g}" | |
| 47 | +VERSION="${TAG#v}" | |
| 48 | +IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}" | |
| 49 | +PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" | |
| 50 | + | |
| 51 | +build_args=(--build-arg "MM_VERSION=${TAG}") | |
| 52 | +if [ -n "${SHELL_TEMPLATE:-}" ]; then | |
| 53 | + build_args+=(--build-arg "SHELL_TEMPLATE=${SHELL_TEMPLATE}") | |
| 54 | +fi | |
| 55 | + | |
| 56 | +if [ -n "${PUSH:-}" ]; then | |
| 57 | + # Multi-arch needs buildx's container driver: the classic builder can | |
| 58 | + # neither assemble a manifest list nor build for a foreign platform. The | |
| 59 | + # Go stage cross-compiles on the build platform; only the final stage's | |
| 60 | + # `RUN mm --version` runs under emulation (Docker Desktop ships QEMU). | |
| 61 | + echo "🐳 Building and pushing ${IMAGE} for ${PLATFORMS} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})" | |
| 62 | + if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then | |
| 63 | + docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null | |
| 64 | + fi | |
| 65 | + docker buildx build --builder mm-sandbox-builder \ | |
| 66 | + --platform "${PLATFORMS}" \ | |
| 67 | + -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" \ | |
| 68 | + -t "${IMAGE}" --push . | |
| 69 | + # The proof that ships: the registry holds one manifest per platform. | |
| 70 | + docker buildx imagetools inspect "${IMAGE}" | grep -E '^Name:|Platform:' | sed 's/^/ /' | |
| 71 | +else | |
| 72 | + echo "🐳 Building ${IMAGE} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})" | |
| 73 | + docker build -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" -t "${IMAGE}" . | |
| 74 | + | |
| 75 | + # The one proof that what was built starts: --version needs no config and | |
| 76 | + # no model server. It also confirms the stamp reached the binary. | |
| 77 | + reported="$(docker run --rm "${IMAGE}" mm --version)" | |
| 78 | + if ! grep -q -- "${TAG}" <<<"${reported}"; then | |
| 79 | + echo "❌ the image does not report ${TAG}: ${reported}" | |
| 80 | + exit 1 | |
| 81 | + fi | |
| 82 | + echo "✅ ${reported}" | |
| 83 | +fi | |
| 84 | + | |
| 85 | +./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}" | |
| 86 | + | |
| 87 | +if [ -n "${PUSH:-}" ]; then | |
| 88 | + cat <<NEXT | |
| 89 | + | |
| 90 | +Image on the registry. Next: | |
| 91 | + | |
| 92 | + try the kits from source sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 93 | + publish them ./docker-sbx-v3/push-kits.sh ${TAG} | |
| 94 | +NEXT | |
| 95 | +else | |
| 96 | + cat <<NEXT | |
| 97 | + | |
| 98 | +${IMAGE} is in the local image store only. That is enough for | |
| 99 | +./docker-sbx-v3/check-kits.sh (which builds the kits with your docker), not | |
| 100 | +for sbx: its builder sandbox pulls the FROM image from the registry. To run | |
| 101 | +the kits from source with sbx, push the image first: | |
| 102 | + | |
| 103 | + PUSH=1 ./docker-sbx-v3/build.sh ${TAG} | |
| 104 | +NEXT | |
| 105 | +fi | |
| new file mode 100755 | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Build the mm sandbox template image, <owner>/mm-sandbox:<version>, from this | ||
| 3 | +# checkout — the image both v3 kits are built FROM. The image tag follows mm's | ||
| 4 | +# own tag, minus the "v": release.env says TAG="v0.2.1", the image is | ||
| 5 | +# k33g/mm-sandbox:0.2.1 and `mm --version` inside it reports v0.2.1 — the | ||
| 6 | +# same rule as the release assets. | ||
| 7 | +# | ||
| 8 | +# Usage: | ||
| 9 | +# ./docker-sbx-v3/build.sh # TAG from release.env, image for this machine | ||
| 10 | +# ./docker-sbx-v3/build.sh v0.2.2 # override the tag for this run | ||
| 11 | +# PUSH=1 ./docker-sbx-v3/build.sh # multi-arch (linux/amd64 + linux/arm64) built | ||
| 12 | +# # with buildx and PUSHED to the registry — | ||
| 13 | +# # needs `docker login`; publish.sh does this | ||
| 14 | +# IMAGE_OWNER=someone ./docker-sbx-v3/build.sh # another image owner (default k33g) | ||
| 15 | +# PLATFORMS=linux/amd64 PUSH=1 … # narrower multi-arch set | ||
| 16 | +# SHELL_TEMPLATE=docker/sandbox-templates:shell-docker ./docker-sbx-v3/build.sh | ||
| 17 | +# # base it on the Docker-in-Docker shell | ||
| 18 | +# | ||
| 19 | +# Whatever the mode, the two kits under docker-sbx-v3/kits/ are then pointed | ||
| 20 | +# at the image just built (docker-sbx-v3/sync-kits.sh), so kits and image move | ||
| 21 | +# together. Publishing the kits themselves is docker-sbx-v3/push-kits.sh, and | ||
| 22 | +# docker-sbx-v3/publish.sh chains the two. | ||
| 23 | +# | ||
| 24 | +# Unlike v2, a v3 kit is BUILT on top of this image (FROM), and sbx builds a | ||
| 25 | +# source-form kit in its builder sandbox, whose Docker engine pulls from a | ||
| 26 | +# registry: an image that is only in the local store is not enough for | ||
| 27 | +# `sbx run ./docker-sbx-v3/kits/…`. Push it (PUSH=1) first. | ||
| 28 | +set -euo pipefail | ||
| 29 | + | ||
| 30 | +cd "$(dirname "$0")/.." | ||
| 31 | + | ||
| 32 | +# release.env carries TAG ("v0.2.1"). It is git-ignored, so a checkout without | ||
| 33 | +# it names the tag on the command line. A tag given on the command line wins. | ||
| 34 | +if [ -f release.env ]; then | ||
| 35 | + # shellcheck source=/dev/null | ||
| 36 | + source release.env | ||
| 37 | +fi | ||
| 38 | +TAG="${1:-${TAG:-}}" | ||
| 39 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | ||
| 40 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/build.sh v1.2.3)" | ||
| 41 | + exit 1 | ||
| 42 | +fi | ||
| 43 | + | ||
| 44 | +# Not OWNER: release.env uses that name for the git owner (bots-garden), and | ||
| 45 | +# the image owner is a different thing — the Docker Hub account, k33g. | ||
| 46 | +IMAGE_OWNER="${IMAGE_OWNER:-k33g}" | ||
| 47 | +VERSION="${TAG#v}" | ||
| 48 | +IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}" | ||
| 49 | +PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" | ||
| 50 | + | ||
| 51 | +build_args=(--build-arg "MM_VERSION=${TAG}") | ||
| 52 | +if [ -n "${SHELL_TEMPLATE:-}" ]; then | ||
| 53 | + build_args+=(--build-arg "SHELL_TEMPLATE=${SHELL_TEMPLATE}") | ||
| 54 | +fi | ||
| 55 | + | ||
| 56 | +if [ -n "${PUSH:-}" ]; then | ||
| 57 | + # Multi-arch needs buildx's container driver: the classic builder can | ||
| 58 | + # neither assemble a manifest list nor build for a foreign platform. The | ||
| 59 | + # Go stage cross-compiles on the build platform; only the final stage's | ||
| 60 | + # `RUN mm --version` runs under emulation (Docker Desktop ships QEMU). | ||
| 61 | + echo "🐳 Building and pushing ${IMAGE} for ${PLATFORMS} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})" | ||
| 62 | + if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then | ||
| 63 | + docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null | ||
| 64 | + fi | ||
| 65 | + docker buildx build --builder mm-sandbox-builder \ | ||
| 66 | + --platform "${PLATFORMS}" \ | ||
| 67 | + -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" \ | ||
| 68 | + -t "${IMAGE}" --push . | ||
| 69 | + # The proof that ships: the registry holds one manifest per platform. | ||
| 70 | + docker buildx imagetools inspect "${IMAGE}" | grep -E '^Name:|Platform:' | sed 's/^/ /' | ||
| 71 | +else | ||
| 72 | + echo "🐳 Building ${IMAGE} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})" | ||
| 73 | + docker build -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" -t "${IMAGE}" . | ||
| 74 | + | ||
| 75 | + # The one proof that what was built starts: --version needs no config and | ||
| 76 | + # no model server. It also confirms the stamp reached the binary. | ||
| 77 | + reported="$(docker run --rm "${IMAGE}" mm --version)" | ||
| 78 | + if ! grep -q -- "${TAG}" <<<"${reported}"; then | ||
| 79 | + echo "❌ the image does not report ${TAG}: ${reported}" | ||
| 80 | + exit 1 | ||
| 81 | + fi | ||
| 82 | + echo "✅ ${reported}" | ||
| 83 | +fi | ||
| 84 | + | ||
| 85 | +./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}" | ||
| 86 | + | ||
| 87 | +if [ -n "${PUSH:-}" ]; then | ||
| 88 | + cat <<NEXT | ||
| 89 | + | ||
| 90 | +Image on the registry. Next: | ||
| 91 | + | ||
| 92 | + try the kits from source sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 93 | + publish them ./docker-sbx-v3/push-kits.sh ${TAG} | ||
| 94 | +NEXT | ||
| 95 | +else | ||
| 96 | + cat <<NEXT | ||
| 97 | + | ||
| 98 | +${IMAGE} is in the local image store only. That is enough for | ||
| 99 | +./docker-sbx-v3/check-kits.sh (which builds the kits with your docker), not | ||
| 100 | +for sbx: its builder sandbox pulls the FROM image from the registry. To run | ||
| 101 | +the kits from source with sbx, push the image first: | ||
| 102 | + | ||
| 103 | + PUSH=1 ./docker-sbx-v3/build.sh ${TAG} | ||
| 104 | +NEXT | ||
| 105 | +fi | ||
added
docker-sbx-v3/check-kits.sh +60 -0 | new file mode 100755 | ||
| @@ -0,0 +1,60 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Build the two v3 kits locally, without pushing and without sbx, and check | |
| 3 | +# them against the kit specification when kit-tck is available. | |
| 4 | +# | |
| 5 | +# Usage: | |
| 6 | +# ./docker-sbx-v3/check-kits.sh # every kit under docker-sbx-v3/kits/ | |
| 7 | +# ./docker-sbx-v3/check-kits.sh mm-tui # one kit | |
| 8 | +# KIT_TCK=/path/to/kit-tck … # the conformance tool, if not on the PATH | |
| 9 | +# | |
| 10 | +# Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's | |
| 11 | +# first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit | |
| 12 | +# frontend, which validates the descriptor (arg patterns included), builds | |
| 13 | +# <kit>.dockerfile and writes the published form — an OCI image whose | |
| 14 | +# manifest annotation carries the descriptor. The result lands in | |
| 15 | +# tmp/kits-v3/<kit>/ as an OCI layout, for the host platform only. | |
| 16 | +# | |
| 17 | +# The args are the descriptors' defaults, so run build.sh (or sync-kits.sh) | |
| 18 | +# first to point them at the image you want. That image is resolved by your | |
| 19 | +# BuildKit: from the local store with Docker Desktop's default builder, | |
| 20 | +# otherwise from the registry. | |
| 21 | +# | |
| 22 | +# kit-tck is the specification's conformance tool | |
| 23 | +# (github.com/docker/sandbox-kit-spec, `go build ./cmd/kit-tck`). Without it | |
| 24 | +# the build itself is the check: the frontend refuses a descriptor that does | |
| 25 | +# not validate. | |
| 26 | +set -euo pipefail | |
| 27 | + | |
| 28 | +cd "$(dirname "$0")/.." | |
| 29 | + | |
| 30 | +KIT_TCK="${KIT_TCK:-kit-tck}" | |
| 31 | +if [ $# -gt 0 ]; then | |
| 32 | + kits=("$@") | |
| 33 | +else | |
| 34 | + kits=() | |
| 35 | + for dir in docker-sbx-v3/kits/*/; do | |
| 36 | + kits+=("$(basename "${dir}")") | |
| 37 | + done | |
| 38 | +fi | |
| 39 | + | |
| 40 | +for kit in "${kits[@]}"; do | |
| 41 | + dir="docker-sbx-v3/kits/${kit}" | |
| 42 | + if [ ! -f "${dir}/${kit}.yaml" ]; then | |
| 43 | + echo "❌ no kit named '${kit}': expected ${dir}/${kit}.yaml" >&2 | |
| 44 | + exit 1 | |
| 45 | + fi | |
| 46 | + out="tmp/kits-v3/${kit}" | |
| 47 | + rm -rf "${out}" | |
| 48 | + mkdir -p "$(dirname "${out}")" | |
| 49 | + | |
| 50 | + echo "🧰 ${kit}: building ${dir}/${kit}.yaml" | |
| 51 | + docker buildx build "${dir}" -f "${dir}/${kit}.yaml" \ | |
| 52 | + --output "type=oci,dest=${out},tar=false,name=${kit}:check" | |
| 53 | + | |
| 54 | + if command -v "${KIT_TCK}" >/dev/null 2>&1; then | |
| 55 | + "${KIT_TCK}" validate --layout "${out}" check | |
| 56 | + else | |
| 57 | + echo " (kit-tck not found: built and validated by the frontend only)" | |
| 58 | + fi | |
| 59 | + echo "✅ ${kit} → ${out}" | |
| 60 | +done | |
| new file mode 100755 | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Build the two v3 kits locally, without pushing and without sbx, and check | ||
| 3 | +# them against the kit specification when kit-tck is available. | ||
| 4 | +# | ||
| 5 | +# Usage: | ||
| 6 | +# ./docker-sbx-v3/check-kits.sh # every kit under docker-sbx-v3/kits/ | ||
| 7 | +# ./docker-sbx-v3/check-kits.sh mm-tui # one kit | ||
| 8 | +# KIT_TCK=/path/to/kit-tck … # the conformance tool, if not on the PATH | ||
| 9 | +# | ||
| 10 | +# Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's | ||
| 11 | +# first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit | ||
| 12 | +# frontend, which validates the descriptor (arg patterns included), builds | ||
| 13 | +# <kit>.dockerfile and writes the published form — an OCI image whose | ||
| 14 | +# manifest annotation carries the descriptor. The result lands in | ||
| 15 | +# tmp/kits-v3/<kit>/ as an OCI layout, for the host platform only. | ||
| 16 | +# | ||
| 17 | +# The args are the descriptors' defaults, so run build.sh (or sync-kits.sh) | ||
| 18 | +# first to point them at the image you want. That image is resolved by your | ||
| 19 | +# BuildKit: from the local store with Docker Desktop's default builder, | ||
| 20 | +# otherwise from the registry. | ||
| 21 | +# | ||
| 22 | +# kit-tck is the specification's conformance tool | ||
| 23 | +# (github.com/docker/sandbox-kit-spec, `go build ./cmd/kit-tck`). Without it | ||
| 24 | +# the build itself is the check: the frontend refuses a descriptor that does | ||
| 25 | +# not validate. | ||
| 26 | +set -euo pipefail | ||
| 27 | + | ||
| 28 | +cd "$(dirname "$0")/.." | ||
| 29 | + | ||
| 30 | +KIT_TCK="${KIT_TCK:-kit-tck}" | ||
| 31 | +if [ $# -gt 0 ]; then | ||
| 32 | + kits=("$@") | ||
| 33 | +else | ||
| 34 | + kits=() | ||
| 35 | + for dir in docker-sbx-v3/kits/*/; do | ||
| 36 | + kits+=("$(basename "${dir}")") | ||
| 37 | + done | ||
| 38 | +fi | ||
| 39 | + | ||
| 40 | +for kit in "${kits[@]}"; do | ||
| 41 | + dir="docker-sbx-v3/kits/${kit}" | ||
| 42 | + if [ ! -f "${dir}/${kit}.yaml" ]; then | ||
| 43 | + echo "❌ no kit named '${kit}': expected ${dir}/${kit}.yaml" >&2 | ||
| 44 | + exit 1 | ||
| 45 | + fi | ||
| 46 | + out="tmp/kits-v3/${kit}" | ||
| 47 | + rm -rf "${out}" | ||
| 48 | + mkdir -p "$(dirname "${out}")" | ||
| 49 | + | ||
| 50 | + echo "🧰 ${kit}: building ${dir}/${kit}.yaml" | ||
| 51 | + docker buildx build "${dir}" -f "${dir}/${kit}.yaml" \ | ||
| 52 | + --output "type=oci,dest=${out},tar=false,name=${kit}:check" | ||
| 53 | + | ||
| 54 | + if command -v "${KIT_TCK}" >/dev/null 2>&1; then | ||
| 55 | + "${KIT_TCK}" validate --layout "${out}" check | ||
| 56 | + else | ||
| 57 | + echo " (kit-tck not found: built and validated by the frontend only)" | ||
| 58 | + fi | ||
| 59 | + echo "✅ ${kit} → ${out}" | ||
| 60 | +done | ||
added
docker-sbx-v3/kits/mm-acp/mm-acp.dockerfile +20 -0 | new file mode 100644 | ||
| @@ -0,0 +1,20 @@ | ||
| 1 | +# syntax=docker/dockerfile:1 | |
| 2 | +# check=skip=InvalidDefaultArgInFrom | |
| 3 | +# Content of the mm-acp kit (descriptor: mm-acp.yaml). Same template image as | |
| 4 | +# mm-tui; only the launch contract differs. No default on purpose (hence the | |
| 5 | +# skipped check above): the frontend always passes the kit's `image` and `tag` | |
| 6 | +# args — see kits/mm-tui/mm-tui.dockerfile. | |
| 7 | +ARG MM_IMAGE | |
| 8 | +ARG MM_TAG | |
| 9 | +FROM ${MM_IMAGE}:${MM_TAG} | |
| 10 | + | |
| 11 | +# v2's environment.variables. `sbx exec` inherits the image environment, so | |
| 12 | +# the editor's settings need not repeat them. AGENT_CONFIG comes from the kit's | |
| 13 | +# `config` arg (env:). | |
| 14 | +ENV LANG=C.UTF-8 | |
| 15 | + | |
| 16 | +# v2's sandbox.entrypoint. Not `mm -acp`: nothing useful comes of speaking | |
| 17 | +# JSON-RPC to a terminal. Attaching with `sbx run` prints the editor wiring | |
| 18 | +# with this sandbox's real name, then opens a shell; the editor itself runs | |
| 19 | +# `sbx exec -i <sandbox> mm -acp`. | |
| 20 | +ENTRYPOINT ["mm-acp-info"] | |
| new file mode 100644 | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | +# syntax=docker/dockerfile:1 | ||
| 2 | +# check=skip=InvalidDefaultArgInFrom | ||
| 3 | +# Content of the mm-acp kit (descriptor: mm-acp.yaml). Same template image as | ||
| 4 | +# mm-tui; only the launch contract differs. No default on purpose (hence the | ||
| 5 | +# skipped check above): the frontend always passes the kit's `image` and `tag` | ||
| 6 | +# args — see kits/mm-tui/mm-tui.dockerfile. | ||
| 7 | +ARG MM_IMAGE | ||
| 8 | +ARG MM_TAG | ||
| 9 | +FROM ${MM_IMAGE}:${MM_TAG} | ||
| 10 | + | ||
| 11 | +# v2's environment.variables. `sbx exec` inherits the image environment, so | ||
| 12 | +# the editor's settings need not repeat them. AGENT_CONFIG comes from the kit's | ||
| 13 | +# `config` arg (env:). | ||
| 14 | +ENV LANG=C.UTF-8 | ||
| 15 | + | ||
| 16 | +# v2's sandbox.entrypoint. Not `mm -acp`: nothing useful comes of speaking | ||
| 17 | +# JSON-RPC to a terminal. Attaching with `sbx run` prints the editor wiring | ||
| 18 | +# with this sandbox's real name, then opens a shell; the editor itself runs | ||
| 19 | +# `sbx exec -i <sandbox> mm -acp`. | ||
| 20 | +ENTRYPOINT ["mm-acp-info"] | ||
added
docker-sbx-v3/kits/mm-acp/mm-acp.yaml +82 -0 | new file mode 100644 | ||
| @@ -0,0 +1,82 @@ | ||
| 1 | +# syntax=docker/sandbox-kit:3 | |
| 2 | +# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json | |
| 3 | +# | |
| 4 | +# Docker Sandboxes kit (spec v3): mm as an editor's agent (Agent Client | |
| 5 | +# Protocol), on the mm sandbox template. The v2 twin is | |
| 6 | +# docker-sbx/kits/mm-acp/spec.yaml. | |
| 7 | +# | |
| 8 | +# sbx create --name mm-acp ./docker-sbx-v3/kits/mm-acp . \ | |
| 9 | +# --kit-arg config=agent.dmr.yaml | |
| 10 | +# | |
| 11 | +# then, in the editor (Zed settings.json): | |
| 12 | +# | |
| 13 | +# "agent_servers": { "mini-me (sandbox)": { "type": "custom", | |
| 14 | +# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } } | |
| 15 | +# | |
| 16 | +# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the | |
| 17 | +# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the | |
| 18 | +# sandbox is created without attaching, and the editor starts `mm -acp` inside | |
| 19 | +# it for every conversation (sbx starts a stopped sandbox first). Attaching | |
| 20 | +# with `sbx run` runs the entry point (mm-acp.dockerfile), which prints this | |
| 21 | +# wiring with the sandbox's real name and opens a shell. | |
| 22 | +# | |
| 23 | +# sbx builds this source form in its builder sandbox, whose own Docker engine | |
| 24 | +# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the | |
| 25 | +# local image store (see docker-sbx-v3/README.md). | |
| 26 | +schemaVersion: "3" | |
| 27 | +kind: workload | |
| 28 | +displayName: Mini Me (editor, ACP) | |
| 29 | +description: > | |
| 30 | + Holds mm, a minimal coding agent for local LLMs, for an editor that speaks | |
| 31 | + the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox> | |
| 32 | + mm -acp`; every command and file edit the model asks for happens inside the | |
| 33 | + sandbox, on the mounted workspace. The model server stays on the host, | |
| 34 | + reached through host.docker.internal. | |
| 35 | +sourceUrl: https://git.rickub.com/bots-garden/mini-me | |
| 36 | +# The kit's version is mm's: the image tag it is built on. A published kit is | |
| 37 | +# versioned by its OCI tag anyway, which wins over this field. | |
| 38 | +version: "${{ kit.args.tag }}" | |
| 39 | +provides: ["mm@${{ kit.args.tag }}"] | |
| 40 | + | |
| 41 | +args: | |
| 42 | + # Build-phase (buildArg): see kits/mm-tui/mm-tui.yaml. | |
| 43 | + image: | |
| 44 | + default: "k33g/mm-sandbox" | |
| 45 | + description: >- | |
| 46 | + Repository of the mm sandbox template image, without the tag. Kept equal | |
| 47 | + to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh. | |
| 48 | + pattern: '^[a-z0-9][a-z0-9._/:-]*$' | |
| 49 | + buildArg: MM_IMAGE | |
| 50 | + tag: | |
| 51 | + default: "0.2.1" | |
| 52 | + description: >- | |
| 53 | + Tag of the template image: mm's version without the "v", as | |
| 54 | + docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the | |
| 55 | + kit's version, hence version-shaped. | |
| 56 | + pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$' | |
| 57 | + buildArg: MM_TAG | |
| 58 | + # Create-phase (env): baked into the container at `sbx create`, so | |
| 59 | + # `sbx exec` inherits it and the editor's settings need not repeat the path. | |
| 60 | + # `sbx exec -e AGENT_CONFIG=…` overrides it for one session. | |
| 61 | + config: | |
| 62 | + default: "" | |
| 63 | + description: >- | |
| 64 | + Configuration file mm reads (its AGENT_CONFIG): a path relative to the | |
| 65 | + workspace, which is where `sbx exec` starts mm, or an absolute path | |
| 66 | + inside the sandbox. Empty: ./agent.yaml in the workspace, then the | |
| 67 | + built-in defaults. | |
| 68 | + env: AGENT_CONFIG | |
| 69 | + | |
| 70 | +capabilities: | |
| 71 | + # A sandbox-agent workload — see kits/mm-tui/mm-tui.yaml. | |
| 72 | + - type: com.docker.sandbox/sbx@1 | |
| 73 | + | |
| 74 | + # The model server on the host — see kits/mm-tui/mm-tui.yaml. | |
| 75 | + - type: com.docker.sandbox/network-policy@1 | |
| 76 | + config: | |
| 77 | + runtime: | |
| 78 | + allow: | |
| 79 | + - "host.docker.internal:12434" | |
| 80 | + - "localhost:12434" | |
| 81 | + - "host.docker.internal:8080" | |
| 82 | + - "localhost:8080" | |
| new file mode 100644 | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | +# syntax=docker/sandbox-kit:3 | ||
| 2 | +# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json | ||
| 3 | +# | ||
| 4 | +# Docker Sandboxes kit (spec v3): mm as an editor's agent (Agent Client | ||
| 5 | +# Protocol), on the mm sandbox template. The v2 twin is | ||
| 6 | +# docker-sbx/kits/mm-acp/spec.yaml. | ||
| 7 | +# | ||
| 8 | +# sbx create --name mm-acp ./docker-sbx-v3/kits/mm-acp . \ | ||
| 9 | +# --kit-arg config=agent.dmr.yaml | ||
| 10 | +# | ||
| 11 | +# then, in the editor (Zed settings.json): | ||
| 12 | +# | ||
| 13 | +# "agent_servers": { "mini-me (sandbox)": { "type": "custom", | ||
| 14 | +# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } } | ||
| 15 | +# | ||
| 16 | +# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the | ||
| 17 | +# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the | ||
| 18 | +# sandbox is created without attaching, and the editor starts `mm -acp` inside | ||
| 19 | +# it for every conversation (sbx starts a stopped sandbox first). Attaching | ||
| 20 | +# with `sbx run` runs the entry point (mm-acp.dockerfile), which prints this | ||
| 21 | +# wiring with the sandbox's real name and opens a shell. | ||
| 22 | +# | ||
| 23 | +# sbx builds this source form in its builder sandbox, whose own Docker engine | ||
| 24 | +# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the | ||
| 25 | +# local image store (see docker-sbx-v3/README.md). | ||
| 26 | +schemaVersion: "3" | ||
| 27 | +kind: workload | ||
| 28 | +displayName: Mini Me (editor, ACP) | ||
| 29 | +description: > | ||
| 30 | + Holds mm, a minimal coding agent for local LLMs, for an editor that speaks | ||
| 31 | + the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox> | ||
| 32 | + mm -acp`; every command and file edit the model asks for happens inside the | ||
| 33 | + sandbox, on the mounted workspace. The model server stays on the host, | ||
| 34 | + reached through host.docker.internal. | ||
| 35 | +sourceUrl: https://git.rickub.com/bots-garden/mini-me | ||
| 36 | +# The kit's version is mm's: the image tag it is built on. A published kit is | ||
| 37 | +# versioned by its OCI tag anyway, which wins over this field. | ||
| 38 | +version: "${{ kit.args.tag }}" | ||
| 39 | +provides: ["mm@${{ kit.args.tag }}"] | ||
| 40 | + | ||
| 41 | +args: | ||
| 42 | + # Build-phase (buildArg): see kits/mm-tui/mm-tui.yaml. | ||
| 43 | + image: | ||
| 44 | + default: "k33g/mm-sandbox" | ||
| 45 | + description: >- | ||
| 46 | + Repository of the mm sandbox template image, without the tag. Kept equal | ||
| 47 | + to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh. | ||
| 48 | + pattern: '^[a-z0-9][a-z0-9._/:-]*$' | ||
| 49 | + buildArg: MM_IMAGE | ||
| 50 | + tag: | ||
| 51 | + default: "0.2.1" | ||
| 52 | + description: >- | ||
| 53 | + Tag of the template image: mm's version without the "v", as | ||
| 54 | + docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the | ||
| 55 | + kit's version, hence version-shaped. | ||
| 56 | + pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$' | ||
| 57 | + buildArg: MM_TAG | ||
| 58 | + # Create-phase (env): baked into the container at `sbx create`, so | ||
| 59 | + # `sbx exec` inherits it and the editor's settings need not repeat the path. | ||
| 60 | + # `sbx exec -e AGENT_CONFIG=…` overrides it for one session. | ||
| 61 | + config: | ||
| 62 | + default: "" | ||
| 63 | + description: >- | ||
| 64 | + Configuration file mm reads (its AGENT_CONFIG): a path relative to the | ||
| 65 | + workspace, which is where `sbx exec` starts mm, or an absolute path | ||
| 66 | + inside the sandbox. Empty: ./agent.yaml in the workspace, then the | ||
| 67 | + built-in defaults. | ||
| 68 | + env: AGENT_CONFIG | ||
| 69 | + | ||
| 70 | +capabilities: | ||
| 71 | + # A sandbox-agent workload — see kits/mm-tui/mm-tui.yaml. | ||
| 72 | + - type: com.docker.sandbox/sbx@1 | ||
| 73 | + | ||
| 74 | + # The model server on the host — see kits/mm-tui/mm-tui.yaml. | ||
| 75 | + - type: com.docker.sandbox/network-policy@1 | ||
| 76 | + config: | ||
| 77 | + runtime: | ||
| 78 | + allow: | ||
| 79 | + - "host.docker.internal:12434" | ||
| 80 | + - "localhost:12434" | ||
| 81 | + - "host.docker.internal:8080" | ||
| 82 | + - "localhost:8080" | ||
added
docker-sbx-v3/kits/mm-tui/mm-tui.dockerfile +25 -0 | new file mode 100644 | ||
| @@ -0,0 +1,25 @@ | ||
| 1 | +# syntax=docker/dockerfile:1 | |
| 2 | +# check=skip=InvalidDefaultArgInFrom | |
| 3 | +# Content of the mm-tui kit (descriptor: mm-tui.yaml). The kit's build context | |
| 4 | +# is this directory, so mm itself cannot be built here: the template image | |
| 5 | +# (docker-sbx-v3/template/Dockerfile, built from the repository root) carries | |
| 6 | +# mm, its wrappers and the toolchains, and this layer only sets the launch | |
| 7 | +# contract. No default on purpose (hence the skipped check above): the frontend | |
| 8 | +# always passes the kit's `image` and `tag` args, and a default here would be a | |
| 9 | +# second copy of the descriptor's to keep in sync. | |
| 10 | +ARG MM_IMAGE | |
| 11 | +ARG MM_TAG | |
| 12 | +FROM ${MM_IMAGE}:${MM_TAG} | |
| 13 | + | |
| 14 | +# v2's environment.variables. tcell needs a terminal type and a UTF-8 locale | |
| 15 | +# to draw the window. AGENT_CONFIG comes from the kit's `config` arg (env:). | |
| 16 | +ENV TERM=xterm-256color \ | |
| 17 | + COLORTERM=truecolor \ | |
| 18 | + LANG=C.UTF-8 | |
| 19 | + | |
| 20 | +# v2's sandbox.entrypoint. A wrapper, not `mm -tui` directly: it always adds | |
| 21 | +# -tui, whatever the user passes after "--". Setting ENTRYPOINT also drops the | |
| 22 | +# base template's CMD, so the launch argv is exactly mm-tui + the user's args. | |
| 23 | +# USER (agent) and WORKDIR (/home/agent/workspace) are inherited from the | |
| 24 | +# template, which is what sbx@1 reads. | |
| 25 | +ENTRYPOINT ["mm-tui"] | |
| new file mode 100644 | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | +# syntax=docker/dockerfile:1 | ||
| 2 | +# check=skip=InvalidDefaultArgInFrom | ||
| 3 | +# Content of the mm-tui kit (descriptor: mm-tui.yaml). The kit's build context | ||
| 4 | +# is this directory, so mm itself cannot be built here: the template image | ||
| 5 | +# (docker-sbx-v3/template/Dockerfile, built from the repository root) carries | ||
| 6 | +# mm, its wrappers and the toolchains, and this layer only sets the launch | ||
| 7 | +# contract. No default on purpose (hence the skipped check above): the frontend | ||
| 8 | +# always passes the kit's `image` and `tag` args, and a default here would be a | ||
| 9 | +# second copy of the descriptor's to keep in sync. | ||
| 10 | +ARG MM_IMAGE | ||
| 11 | +ARG MM_TAG | ||
| 12 | +FROM ${MM_IMAGE}:${MM_TAG} | ||
| 13 | + | ||
| 14 | +# v2's environment.variables. tcell needs a terminal type and a UTF-8 locale | ||
| 15 | +# to draw the window. AGENT_CONFIG comes from the kit's `config` arg (env:). | ||
| 16 | +ENV TERM=xterm-256color \ | ||
| 17 | + COLORTERM=truecolor \ | ||
| 18 | + LANG=C.UTF-8 | ||
| 19 | + | ||
| 20 | +# v2's sandbox.entrypoint. A wrapper, not `mm -tui` directly: it always adds | ||
| 21 | +# -tui, whatever the user passes after "--". Setting ENTRYPOINT also drops the | ||
| 22 | +# base template's CMD, so the launch argv is exactly mm-tui + the user's args. | ||
| 23 | +# USER (agent) and WORKDIR (/home/agent/workspace) are inherited from the | ||
| 24 | +# template, which is what sbx@1 reads. | ||
| 25 | +ENTRYPOINT ["mm-tui"] | ||
added
docker-sbx-v3/kits/mm-tui/mm-tui.yaml +86 -0 | new file mode 100644 | ||
| @@ -0,0 +1,86 @@ | ||
| 1 | +# syntax=docker/sandbox-kit:3 | |
| 2 | +# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json | |
| 3 | +# | |
| 4 | +# Docker Sandboxes kit (spec v3): mm in its window mode, on the mm sandbox | |
| 5 | +# template. The v2 twin is docker-sbx/kits/mm-tui/spec.yaml. | |
| 6 | +# | |
| 7 | +# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 8 | +# | |
| 9 | +# What follows "--" reaches mm as its own arguments (here the configuration | |
| 10 | +# file, relative to the workspace). Without it, the `config` argument below is | |
| 11 | +# read, then ./agent.yaml, then the built-in defaults: | |
| 12 | +# | |
| 13 | +# sbx run ./docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |
| 14 | +# | |
| 15 | +# v3 layout: this file is the descriptor (declarations only), mm-tui.dockerfile | |
| 16 | +# beside it is the content. What v2 wrote in `sandbox.image`, | |
| 17 | +# `sandbox.entrypoint` and `environment.variables` is now in that Dockerfile's | |
| 18 | +# FROM, ENTRYPOINT and ENV — the descriptor restates nothing the image config | |
| 19 | +# already carries. | |
| 20 | +# | |
| 21 | +# sbx builds this source form in its builder sandbox, whose own Docker engine | |
| 22 | +# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the | |
| 23 | +# local image store (see docker-sbx-v3/README.md). | |
| 24 | +schemaVersion: "3" | |
| 25 | +kind: workload | |
| 26 | +displayName: Mini Me (window mode) | |
| 27 | +description: > | |
| 28 | + Runs mm, a minimal coding agent for local LLMs, in its single-window terminal | |
| 29 | + mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or | |
| 30 | + llama-server) stays on the host: inside the sandbox `localhost` is the sandbox | |
| 31 | + itself, so the configuration file must reach the host through | |
| 32 | + host.docker.internal — agent.dmr.yaml already falls back to it. | |
| 33 | +sourceUrl: https://git.rickub.com/bots-garden/mini-me | |
| 34 | +# The kit's version is mm's: the image tag it is built on. A published kit is | |
| 35 | +# versioned by its OCI tag anyway, which wins over this field. | |
| 36 | +version: "${{ kit.args.tag }}" | |
| 37 | +provides: ["mm@${{ kit.args.tag }}"] | |
| 38 | + | |
| 39 | +args: | |
| 40 | + # Build-phase (buildArg): resolved when the kit is built, handed to | |
| 41 | + # mm-tui.dockerfile as --build-arg, and baked into the published descriptor. | |
| 42 | + # A published kit therefore always names the image it was built on. | |
| 43 | + image: | |
| 44 | + default: "k33g/mm-sandbox" | |
| 45 | + description: >- | |
| 46 | + Repository of the mm sandbox template image, without the tag. Kept equal | |
| 47 | + to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh. | |
| 48 | + pattern: '^[a-z0-9][a-z0-9._/:-]*$' | |
| 49 | + buildArg: MM_IMAGE | |
| 50 | + tag: | |
| 51 | + default: "0.2.1" | |
| 52 | + description: >- | |
| 53 | + Tag of the template image: mm's version without the "v", as | |
| 54 | + docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the | |
| 55 | + kit's version, hence version-shaped. | |
| 56 | + pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$' | |
| 57 | + buildArg: MM_TAG | |
| 58 | + # Create-phase (env): resolved at `sbx run` / `sbx create`, exported to the | |
| 59 | + # container. Private otherwise — an arg without env: never reaches it. | |
| 60 | + config: | |
| 61 | + default: "" | |
| 62 | + description: >- | |
| 63 | + Configuration file mm reads (its AGENT_CONFIG): a path relative to the | |
| 64 | + workspace, or an absolute path inside the sandbox. Empty: ./agent.yaml in | |
| 65 | + the workspace, then the built-in defaults. | |
| 66 | + env: AGENT_CONFIG | |
| 67 | + | |
| 68 | +capabilities: | |
| 69 | + # A sandbox-agent workload: the host launches the image ENTRYPOINT (mm-tui) | |
| 70 | + # under bash as the image's user (agent), and mounts the workspace at the | |
| 71 | + # image's WORKDIR, /home/agent/workspace. | |
| 72 | + - type: com.docker.sandbox/sbx@1 | |
| 73 | + | |
| 74 | + # The model server on the host. Requests leave the sandbox through its proxy, | |
| 75 | + # which maps host.docker.internal to the host's localhost; both spellings are | |
| 76 | + # listed so the rule matches whichever one the policy is checked against. | |
| 77 | + # 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own | |
| 78 | + # port with `sbx policy allow network host.docker.internal:<port>`. | |
| 79 | + - type: com.docker.sandbox/network-policy@1 | |
| 80 | + config: | |
| 81 | + runtime: | |
| 82 | + allow: | |
| 83 | + - "host.docker.internal:12434" | |
| 84 | + - "localhost:12434" | |
| 85 | + - "host.docker.internal:8080" | |
| 86 | + - "localhost:8080" | |
| new file mode 100644 | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | +# syntax=docker/sandbox-kit:3 | ||
| 2 | +# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json | ||
| 3 | +# | ||
| 4 | +# Docker Sandboxes kit (spec v3): mm in its window mode, on the mm sandbox | ||
| 5 | +# template. The v2 twin is docker-sbx/kits/mm-tui/spec.yaml. | ||
| 6 | +# | ||
| 7 | +# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 8 | +# | ||
| 9 | +# What follows "--" reaches mm as its own arguments (here the configuration | ||
| 10 | +# file, relative to the workspace). Without it, the `config` argument below is | ||
| 11 | +# read, then ./agent.yaml, then the built-in defaults: | ||
| 12 | +# | ||
| 13 | +# sbx run ./docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 14 | +# | ||
| 15 | +# v3 layout: this file is the descriptor (declarations only), mm-tui.dockerfile | ||
| 16 | +# beside it is the content. What v2 wrote in `sandbox.image`, | ||
| 17 | +# `sandbox.entrypoint` and `environment.variables` is now in that Dockerfile's | ||
| 18 | +# FROM, ENTRYPOINT and ENV — the descriptor restates nothing the image config | ||
| 19 | +# already carries. | ||
| 20 | +# | ||
| 21 | +# sbx builds this source form in its builder sandbox, whose own Docker engine | ||
| 22 | +# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the | ||
| 23 | +# local image store (see docker-sbx-v3/README.md). | ||
| 24 | +schemaVersion: "3" | ||
| 25 | +kind: workload | ||
| 26 | +displayName: Mini Me (window mode) | ||
| 27 | +description: > | ||
| 28 | + Runs mm, a minimal coding agent for local LLMs, in its single-window terminal | ||
| 29 | + mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or | ||
| 30 | + llama-server) stays on the host: inside the sandbox `localhost` is the sandbox | ||
| 31 | + itself, so the configuration file must reach the host through | ||
| 32 | + host.docker.internal — agent.dmr.yaml already falls back to it. | ||
| 33 | +sourceUrl: https://git.rickub.com/bots-garden/mini-me | ||
| 34 | +# The kit's version is mm's: the image tag it is built on. A published kit is | ||
| 35 | +# versioned by its OCI tag anyway, which wins over this field. | ||
| 36 | +version: "${{ kit.args.tag }}" | ||
| 37 | +provides: ["mm@${{ kit.args.tag }}"] | ||
| 38 | + | ||
| 39 | +args: | ||
| 40 | + # Build-phase (buildArg): resolved when the kit is built, handed to | ||
| 41 | + # mm-tui.dockerfile as --build-arg, and baked into the published descriptor. | ||
| 42 | + # A published kit therefore always names the image it was built on. | ||
| 43 | + image: | ||
| 44 | + default: "k33g/mm-sandbox" | ||
| 45 | + description: >- | ||
| 46 | + Repository of the mm sandbox template image, without the tag. Kept equal | ||
| 47 | + to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh. | ||
| 48 | + pattern: '^[a-z0-9][a-z0-9._/:-]*$' | ||
| 49 | + buildArg: MM_IMAGE | ||
| 50 | + tag: | ||
| 51 | + default: "0.2.1" | ||
| 52 | + description: >- | ||
| 53 | + Tag of the template image: mm's version without the "v", as | ||
| 54 | + docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the | ||
| 55 | + kit's version, hence version-shaped. | ||
| 56 | + pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$' | ||
| 57 | + buildArg: MM_TAG | ||
| 58 | + # Create-phase (env): resolved at `sbx run` / `sbx create`, exported to the | ||
| 59 | + # container. Private otherwise — an arg without env: never reaches it. | ||
| 60 | + config: | ||
| 61 | + default: "" | ||
| 62 | + description: >- | ||
| 63 | + Configuration file mm reads (its AGENT_CONFIG): a path relative to the | ||
| 64 | + workspace, or an absolute path inside the sandbox. Empty: ./agent.yaml in | ||
| 65 | + the workspace, then the built-in defaults. | ||
| 66 | + env: AGENT_CONFIG | ||
| 67 | + | ||
| 68 | +capabilities: | ||
| 69 | + # A sandbox-agent workload: the host launches the image ENTRYPOINT (mm-tui) | ||
| 70 | + # under bash as the image's user (agent), and mounts the workspace at the | ||
| 71 | + # image's WORKDIR, /home/agent/workspace. | ||
| 72 | + - type: com.docker.sandbox/sbx@1 | ||
| 73 | + | ||
| 74 | + # The model server on the host. Requests leave the sandbox through its proxy, | ||
| 75 | + # which maps host.docker.internal to the host's localhost; both spellings are | ||
| 76 | + # listed so the rule matches whichever one the policy is checked against. | ||
| 77 | + # 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own | ||
| 78 | + # port with `sbx policy allow network host.docker.internal:<port>`. | ||
| 79 | + - type: com.docker.sandbox/network-policy@1 | ||
| 80 | + config: | ||
| 81 | + runtime: | ||
| 82 | + allow: | ||
| 83 | + - "host.docker.internal:12434" | ||
| 84 | + - "localhost:12434" | ||
| 85 | + - "host.docker.internal:8080" | ||
| 86 | + - "localhost:8080" | ||
added
docker-sbx-v3/publish.sh +75 -0 | new file mode 100755 | ||
| @@ -0,0 +1,75 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Build and publish everything to Docker Hub, by hand, in one go: | |
| 3 | +# <owner>/mm-sandbox:<version> the template image, linux/amd64 + linux/arm64 | |
| 4 | +# <owner>/sbx-kit-mm-tui:<version> the window-mode kit (v3) | |
| 5 | +# <owner>/sbx-kit-mm-acp:<version> the editor (ACP) kit (v3) | |
| 6 | +# | |
| 7 | +# Usage: | |
| 8 | +# ./docker-sbx-v3/publish.sh # TAG from release.env (v0.2.1 → 0.2.1) | |
| 9 | +# ./docker-sbx-v3/publish.sh v0.2.2 # another tag | |
| 10 | +# | |
| 11 | +# Credentials, two environment variables: | |
| 12 | +# DOCKER_HANDLE the Docker Hub account — also the image owner (default k33g) | |
| 13 | +# DOCKER_PAT an access token with read/write scope | |
| 14 | +# With both set, the script logs in with them (and out at the end). With | |
| 15 | +# neither, it uses the login you already have (`docker login` done earlier). | |
| 16 | +# | |
| 17 | +# Needs: docker with buildx (Docker Desktop has it). No sbx: v3 kits are | |
| 18 | +# published with buildx. Pieces, runnable alone: | |
| 19 | +# PUSH=1 ./docker-sbx-v3/build.sh TAG image only | |
| 20 | +# ./docker-sbx-v3/push-kits.sh TAG kits only | |
| 21 | +set -euo pipefail | |
| 22 | + | |
| 23 | +cd "$(dirname "$0")/.." | |
| 24 | + | |
| 25 | +if [ -f release.env ]; then | |
| 26 | + # shellcheck source=/dev/null | |
| 27 | + source release.env | |
| 28 | +fi | |
| 29 | +TAG="${1:-${TAG:-}}" | |
| 30 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | |
| 31 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/publish.sh v1.2.3)" | |
| 32 | + exit 1 | |
| 33 | +fi | |
| 34 | + | |
| 35 | +# Secrets pasted with a trailing newline or stray spaces are a classic. | |
| 36 | +DOCKER_HANDLE="$(printf '%s' "${DOCKER_HANDLE:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')" | |
| 37 | +DOCKER_PAT="$(printf '%s' "${DOCKER_PAT:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')" | |
| 38 | +case "${DOCKER_HANDLE}" in | |
| 39 | +*@* | *:*) | |
| 40 | + echo "❌ DOCKER_HANDLE must be the Docker ID (username), not an e-mail: access tokens only pair with the username" | |
| 41 | + exit 1 | |
| 42 | + ;; | |
| 43 | +esac | |
| 44 | +export IMAGE_OWNER="${IMAGE_OWNER:-${DOCKER_HANDLE:-k33g}}" | |
| 45 | +VERSION="${TAG#v}" | |
| 46 | + | |
| 47 | +logged_in_here="" | |
| 48 | +if [ -n "${DOCKER_HANDLE}" ] && [ -n "${DOCKER_PAT}" ]; then | |
| 49 | + echo "🔐 docker login as ${DOCKER_HANDLE}" | |
| 50 | + printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin | |
| 51 | + logged_in_here=1 | |
| 52 | +elif [ -n "${DOCKER_HANDLE}${DOCKER_PAT}" ]; then | |
| 53 | + echo "❌ set both DOCKER_HANDLE and DOCKER_PAT, or neither (to reuse an existing docker login)" | |
| 54 | + exit 1 | |
| 55 | +else | |
| 56 | + echo "🔐 no DOCKER_HANDLE/DOCKER_PAT: using the existing docker login, publishing under ${IMAGE_OWNER}" | |
| 57 | +fi | |
| 58 | +# Whatever happens below, a login made here does not outlive the script. | |
| 59 | +cleanup() { | |
| 60 | + if [ -n "${logged_in_here}" ]; then | |
| 61 | + docker logout >/dev/null 2>&1 || true | |
| 62 | + fi | |
| 63 | +} | |
| 64 | +trap cleanup EXIT | |
| 65 | + | |
| 66 | +echo | |
| 67 | +echo "═══ 1/2 image ${IMAGE_OWNER}/mm-sandbox:${VERSION}" | |
| 68 | +PUSH=1 ./docker-sbx-v3/build.sh "${TAG}" | |
| 69 | + | |
| 70 | +echo | |
| 71 | +echo "═══ 2/2 kits ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-tui:${VERSION} and ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-acp:${VERSION}" | |
| 72 | +./docker-sbx-v3/push-kits.sh "${TAG}" | |
| 73 | + | |
| 74 | +echo | |
| 75 | +echo "✨ Published ${TAG}. The kits' descriptors now name version ${VERSION} — commit them." | |
| new file mode 100755 | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Build and publish everything to Docker Hub, by hand, in one go: | ||
| 3 | +# <owner>/mm-sandbox:<version> the template image, linux/amd64 + linux/arm64 | ||
| 4 | +# <owner>/sbx-kit-mm-tui:<version> the window-mode kit (v3) | ||
| 5 | +# <owner>/sbx-kit-mm-acp:<version> the editor (ACP) kit (v3) | ||
| 6 | +# | ||
| 7 | +# Usage: | ||
| 8 | +# ./docker-sbx-v3/publish.sh # TAG from release.env (v0.2.1 → 0.2.1) | ||
| 9 | +# ./docker-sbx-v3/publish.sh v0.2.2 # another tag | ||
| 10 | +# | ||
| 11 | +# Credentials, two environment variables: | ||
| 12 | +# DOCKER_HANDLE the Docker Hub account — also the image owner (default k33g) | ||
| 13 | +# DOCKER_PAT an access token with read/write scope | ||
| 14 | +# With both set, the script logs in with them (and out at the end). With | ||
| 15 | +# neither, it uses the login you already have (`docker login` done earlier). | ||
| 16 | +# | ||
| 17 | +# Needs: docker with buildx (Docker Desktop has it). No sbx: v3 kits are | ||
| 18 | +# published with buildx. Pieces, runnable alone: | ||
| 19 | +# PUSH=1 ./docker-sbx-v3/build.sh TAG image only | ||
| 20 | +# ./docker-sbx-v3/push-kits.sh TAG kits only | ||
| 21 | +set -euo pipefail | ||
| 22 | + | ||
| 23 | +cd "$(dirname "$0")/.." | ||
| 24 | + | ||
| 25 | +if [ -f release.env ]; then | ||
| 26 | + # shellcheck source=/dev/null | ||
| 27 | + source release.env | ||
| 28 | +fi | ||
| 29 | +TAG="${1:-${TAG:-}}" | ||
| 30 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | ||
| 31 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/publish.sh v1.2.3)" | ||
| 32 | + exit 1 | ||
| 33 | +fi | ||
| 34 | + | ||
| 35 | +# Secrets pasted with a trailing newline or stray spaces are a classic. | ||
| 36 | +DOCKER_HANDLE="$(printf '%s' "${DOCKER_HANDLE:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')" | ||
| 37 | +DOCKER_PAT="$(printf '%s' "${DOCKER_PAT:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')" | ||
| 38 | +case "${DOCKER_HANDLE}" in | ||
| 39 | +*@* | *:*) | ||
| 40 | + echo "❌ DOCKER_HANDLE must be the Docker ID (username), not an e-mail: access tokens only pair with the username" | ||
| 41 | + exit 1 | ||
| 42 | + ;; | ||
| 43 | +esac | ||
| 44 | +export IMAGE_OWNER="${IMAGE_OWNER:-${DOCKER_HANDLE:-k33g}}" | ||
| 45 | +VERSION="${TAG#v}" | ||
| 46 | + | ||
| 47 | +logged_in_here="" | ||
| 48 | +if [ -n "${DOCKER_HANDLE}" ] && [ -n "${DOCKER_PAT}" ]; then | ||
| 49 | + echo "🔐 docker login as ${DOCKER_HANDLE}" | ||
| 50 | + printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin | ||
| 51 | + logged_in_here=1 | ||
| 52 | +elif [ -n "${DOCKER_HANDLE}${DOCKER_PAT}" ]; then | ||
| 53 | + echo "❌ set both DOCKER_HANDLE and DOCKER_PAT, or neither (to reuse an existing docker login)" | ||
| 54 | + exit 1 | ||
| 55 | +else | ||
| 56 | + echo "🔐 no DOCKER_HANDLE/DOCKER_PAT: using the existing docker login, publishing under ${IMAGE_OWNER}" | ||
| 57 | +fi | ||
| 58 | +# Whatever happens below, a login made here does not outlive the script. | ||
| 59 | +cleanup() { | ||
| 60 | + if [ -n "${logged_in_here}" ]; then | ||
| 61 | + docker logout >/dev/null 2>&1 || true | ||
| 62 | + fi | ||
| 63 | +} | ||
| 64 | +trap cleanup EXIT | ||
| 65 | + | ||
| 66 | +echo | ||
| 67 | +echo "═══ 1/2 image ${IMAGE_OWNER}/mm-sandbox:${VERSION}" | ||
| 68 | +PUSH=1 ./docker-sbx-v3/build.sh "${TAG}" | ||
| 69 | + | ||
| 70 | +echo | ||
| 71 | +echo "═══ 2/2 kits ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-tui:${VERSION} and ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-acp:${VERSION}" | ||
| 72 | +./docker-sbx-v3/push-kits.sh "${TAG}" | ||
| 73 | + | ||
| 74 | +echo | ||
| 75 | +echo "✨ Published ${TAG}. The kits' descriptors now name version ${VERSION} — commit them." | ||
added
docker-sbx-v3/push-kits.sh +94 -0 | new file mode 100755 | ||
| @@ -0,0 +1,94 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Build and publish the two v3 kits to Docker Hub: | |
| 3 | +# <owner>/sbx-kit-mm-tui:<version> and <owner>/sbx-kit-mm-acp:<version> | |
| 4 | +# | |
| 5 | +# Usage: | |
| 6 | +# ./docker-sbx-v3/push-kits.sh # TAG from release.env | |
| 7 | +# ./docker-sbx-v3/push-kits.sh v0.2.2 # override the tag | |
| 8 | +# IMAGE_OWNER=someone … # another owner (default k33g); the kits | |
| 9 | +# # are re-pointed at someone/mm-sandbox too | |
| 10 | +# REGISTRY=localhost:5000 … # another registry (default docker.io) | |
| 11 | +# KIT_PREFIX=mm-v3- … # repository prefix (default sbx-kit-) | |
| 12 | +# PLATFORMS=linux/amd64 … # narrower multi-arch set | |
| 13 | +# | |
| 14 | +# A v3 kit is an ordinary OCI image, so publishing is a buildx build: the | |
| 15 | +# descriptor's `# syntax=docker/sandbox-kit:3` line makes BuildKit run the kit | |
| 16 | +# frontend, which validates the descriptor, builds the companion Dockerfile | |
| 17 | +# FROM <owner>/mm-sandbox:<version> and pushes one image per platform with the | |
| 18 | +# descriptor in its manifest annotations. No sbx needed (v2 used | |
| 19 | +# `sbx kit push`, which only knows spec.yaml). | |
| 20 | +# | |
| 21 | +# The repositories are sbx-kit-<kit>, the naming Docker's own kits use, and | |
| 22 | +# NOT the v2 ones (<owner>/mm-tui, <owner>/mm-acp): pushing a v3 kit there at | |
| 23 | +# the same version would replace the published v2 kit. | |
| 24 | +# | |
| 25 | +# Needs a login: `docker login -u <handle>` with a Docker Hub access token. | |
| 26 | +# publish.sh runs this after the image. Push the image first: the kits are | |
| 27 | +# built FROM <owner>/mm-sandbox:<version>, pulled from the registry. | |
| 28 | +set -euo pipefail | |
| 29 | + | |
| 30 | +cd "$(dirname "$0")/.." | |
| 31 | + | |
| 32 | +if [ -f release.env ]; then | |
| 33 | + # shellcheck source=/dev/null | |
| 34 | + source release.env | |
| 35 | +fi | |
| 36 | +TAG="${1:-${TAG:-}}" | |
| 37 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | |
| 38 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/push-kits.sh v1.2.3)" | |
| 39 | + exit 1 | |
| 40 | +fi | |
| 41 | + | |
| 42 | +IMAGE_OWNER="${IMAGE_OWNER:-k33g}" | |
| 43 | +REGISTRY="${REGISTRY:-docker.io}" | |
| 44 | +KIT_PREFIX="${KIT_PREFIX:-sbx-kit-}" | |
| 45 | +PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" | |
| 46 | +VERSION="${TAG#v}" | |
| 47 | +IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}" | |
| 48 | + | |
| 49 | +# Fail here rather than in the middle of a multi-arch build. | |
| 50 | +if ! docker buildx imagetools inspect "${IMAGE}" >/dev/null 2>&1; then | |
| 51 | + echo "❌ ${IMAGE} is not on the registry: the kits are built FROM it. Push it first: PUSH=1 ./docker-sbx-v3/build.sh ${TAG}" | |
| 52 | + exit 1 | |
| 53 | +fi | |
| 54 | + | |
| 55 | +./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}" | |
| 56 | + | |
| 57 | +# Same builder as build.sh: multi-arch needs the container driver. | |
| 58 | +if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then | |
| 59 | + docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null | |
| 60 | +fi | |
| 61 | + | |
| 62 | +refs=() | |
| 63 | +for dir in docker-sbx-v3/kits/*/; do | |
| 64 | + kit="$(basename "${dir}")" | |
| 65 | + ref="${REGISTRY}/${IMAGE_OWNER}/${KIT_PREFIX}${kit}:${VERSION}" | |
| 66 | + echo "🧰 ${kit} → ${ref}" | |
| 67 | + # The build args are the kit's own arg names; the frontend validates them | |
| 68 | + # against the descriptor and hands the Dockerfile the declared buildArg. | |
| 69 | + # They repeat what sync-kits.sh just wrote, so the file and the push agree. | |
| 70 | + docker buildx build --builder mm-sandbox-builder "${dir}" -f "${dir}${kit}.yaml" \ | |
| 71 | + --build-arg "image=${IMAGE_OWNER}/mm-sandbox" \ | |
| 72 | + --build-arg "tag=${VERSION}" \ | |
| 73 | + --platform "${PLATFORMS}" \ | |
| 74 | + --provenance=true --sbom=true \ | |
| 75 | + -t "${ref}" --push | |
| 76 | + docker buildx imagetools inspect "${ref}" | grep -E '^Name:|Platform:' | sed 's/^/ /' | |
| 77 | + refs+=("${ref}") | |
| 78 | +done | |
| 79 | + | |
| 80 | +# The specification's own check of what was pushed, when available. | |
| 81 | +if command -v "${KIT_TCK:-kit-tck}" >/dev/null 2>&1; then | |
| 82 | + for ref in "${refs[@]}"; do | |
| 83 | + "${KIT_TCK:-kit-tck}" validate "${ref}" | |
| 84 | + done | |
| 85 | +fi | |
| 86 | + | |
| 87 | +cat <<NEXT | |
| 88 | + | |
| 89 | +Published. From any machine with Docker Sandboxes (docker.io is an allowed kit source by default): | |
| 90 | + | |
| 91 | + window mode sbx run ${IMAGE_OWNER}/${KIT_PREFIX}mm-tui:${VERSION} . -- agent.dmr.yaml | |
| 92 | + editor (ACP) sbx create --name mm-acp ${IMAGE_OWNER}/${KIT_PREFIX}mm-acp:${VERSION} . --kit-arg config=agent.dmr.yaml | |
| 93 | + then register sbx exec -i mm-acp mm -acp in the editor | |
| 94 | +NEXT | |
| new file mode 100755 | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Build and publish the two v3 kits to Docker Hub: | ||
| 3 | +# <owner>/sbx-kit-mm-tui:<version> and <owner>/sbx-kit-mm-acp:<version> | ||
| 4 | +# | ||
| 5 | +# Usage: | ||
| 6 | +# ./docker-sbx-v3/push-kits.sh # TAG from release.env | ||
| 7 | +# ./docker-sbx-v3/push-kits.sh v0.2.2 # override the tag | ||
| 8 | +# IMAGE_OWNER=someone … # another owner (default k33g); the kits | ||
| 9 | +# # are re-pointed at someone/mm-sandbox too | ||
| 10 | +# REGISTRY=localhost:5000 … # another registry (default docker.io) | ||
| 11 | +# KIT_PREFIX=mm-v3- … # repository prefix (default sbx-kit-) | ||
| 12 | +# PLATFORMS=linux/amd64 … # narrower multi-arch set | ||
| 13 | +# | ||
| 14 | +# A v3 kit is an ordinary OCI image, so publishing is a buildx build: the | ||
| 15 | +# descriptor's `# syntax=docker/sandbox-kit:3` line makes BuildKit run the kit | ||
| 16 | +# frontend, which validates the descriptor, builds the companion Dockerfile | ||
| 17 | +# FROM <owner>/mm-sandbox:<version> and pushes one image per platform with the | ||
| 18 | +# descriptor in its manifest annotations. No sbx needed (v2 used | ||
| 19 | +# `sbx kit push`, which only knows spec.yaml). | ||
| 20 | +# | ||
| 21 | +# The repositories are sbx-kit-<kit>, the naming Docker's own kits use, and | ||
| 22 | +# NOT the v2 ones (<owner>/mm-tui, <owner>/mm-acp): pushing a v3 kit there at | ||
| 23 | +# the same version would replace the published v2 kit. | ||
| 24 | +# | ||
| 25 | +# Needs a login: `docker login -u <handle>` with a Docker Hub access token. | ||
| 26 | +# publish.sh runs this after the image. Push the image first: the kits are | ||
| 27 | +# built FROM <owner>/mm-sandbox:<version>, pulled from the registry. | ||
| 28 | +set -euo pipefail | ||
| 29 | + | ||
| 30 | +cd "$(dirname "$0")/.." | ||
| 31 | + | ||
| 32 | +if [ -f release.env ]; then | ||
| 33 | + # shellcheck source=/dev/null | ||
| 34 | + source release.env | ||
| 35 | +fi | ||
| 36 | +TAG="${1:-${TAG:-}}" | ||
| 37 | +if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | ||
| 38 | + echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/push-kits.sh v1.2.3)" | ||
| 39 | + exit 1 | ||
| 40 | +fi | ||
| 41 | + | ||
| 42 | +IMAGE_OWNER="${IMAGE_OWNER:-k33g}" | ||
| 43 | +REGISTRY="${REGISTRY:-docker.io}" | ||
| 44 | +KIT_PREFIX="${KIT_PREFIX:-sbx-kit-}" | ||
| 45 | +PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}" | ||
| 46 | +VERSION="${TAG#v}" | ||
| 47 | +IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}" | ||
| 48 | + | ||
| 49 | +# Fail here rather than in the middle of a multi-arch build. | ||
| 50 | +if ! docker buildx imagetools inspect "${IMAGE}" >/dev/null 2>&1; then | ||
| 51 | + echo "❌ ${IMAGE} is not on the registry: the kits are built FROM it. Push it first: PUSH=1 ./docker-sbx-v3/build.sh ${TAG}" | ||
| 52 | + exit 1 | ||
| 53 | +fi | ||
| 54 | + | ||
| 55 | +./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}" | ||
| 56 | + | ||
| 57 | +# Same builder as build.sh: multi-arch needs the container driver. | ||
| 58 | +if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then | ||
| 59 | + docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null | ||
| 60 | +fi | ||
| 61 | + | ||
| 62 | +refs=() | ||
| 63 | +for dir in docker-sbx-v3/kits/*/; do | ||
| 64 | + kit="$(basename "${dir}")" | ||
| 65 | + ref="${REGISTRY}/${IMAGE_OWNER}/${KIT_PREFIX}${kit}:${VERSION}" | ||
| 66 | + echo "🧰 ${kit} → ${ref}" | ||
| 67 | + # The build args are the kit's own arg names; the frontend validates them | ||
| 68 | + # against the descriptor and hands the Dockerfile the declared buildArg. | ||
| 69 | + # They repeat what sync-kits.sh just wrote, so the file and the push agree. | ||
| 70 | + docker buildx build --builder mm-sandbox-builder "${dir}" -f "${dir}${kit}.yaml" \ | ||
| 71 | + --build-arg "image=${IMAGE_OWNER}/mm-sandbox" \ | ||
| 72 | + --build-arg "tag=${VERSION}" \ | ||
| 73 | + --platform "${PLATFORMS}" \ | ||
| 74 | + --provenance=true --sbom=true \ | ||
| 75 | + -t "${ref}" --push | ||
| 76 | + docker buildx imagetools inspect "${ref}" | grep -E '^Name:|Platform:' | sed 's/^/ /' | ||
| 77 | + refs+=("${ref}") | ||
| 78 | +done | ||
| 79 | + | ||
| 80 | +# The specification's own check of what was pushed, when available. | ||
| 81 | +if command -v "${KIT_TCK:-kit-tck}" >/dev/null 2>&1; then | ||
| 82 | + for ref in "${refs[@]}"; do | ||
| 83 | + "${KIT_TCK:-kit-tck}" validate "${ref}" | ||
| 84 | + done | ||
| 85 | +fi | ||
| 86 | + | ||
| 87 | +cat <<NEXT | ||
| 88 | + | ||
| 89 | +Published. From any machine with Docker Sandboxes (docker.io is an allowed kit source by default): | ||
| 90 | + | ||
| 91 | + window mode sbx run ${IMAGE_OWNER}/${KIT_PREFIX}mm-tui:${VERSION} . -- agent.dmr.yaml | ||
| 92 | + editor (ACP) sbx create --name mm-acp ${IMAGE_OWNER}/${KIT_PREFIX}mm-acp:${VERSION} . --kit-arg config=agent.dmr.yaml | ||
| 93 | + then register sbx exec -i mm-acp mm -acp in the editor | ||
| 94 | +NEXT | ||
added
docker-sbx-v3/sync-kits.sh +44 -0 | new file mode 100755 | ||
| @@ -0,0 +1,44 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Point the two v3 kits at one image: <owner>/mm-sandbox:<version>. | |
| 3 | +# | |
| 4 | +# Usage: ./docker-sbx-v3/sync-kits.sh OWNER VERSION (e.g. k33g 0.2.1) | |
| 5 | +# | |
| 6 | +# Rewrites, in docker-sbx-v3/kits/*/*.yaml (the descriptors), only two values: | |
| 7 | +# args.image.default: "<owner>/mm-sandbox" which repository the kit is built FROM | |
| 8 | +# args.tag.default: "<version>" which tag — and the kit's version, | |
| 9 | +# since `version:` and `provides:` | |
| 10 | +# reference ${{ kit.args.tag }} | |
| 11 | +# Everything else — comments included — is left byte-for-byte alone, so a | |
| 12 | +# kit that already matches is not changed at all. build.sh and push-kits.sh | |
| 13 | +# call this, so the kits always name the image just built or pushed. | |
| 14 | +set -euo pipefail | |
| 15 | + | |
| 16 | +if [ $# -ne 2 ]; then | |
| 17 | + echo "usage: $0 OWNER VERSION" >&2 | |
| 18 | + exit 2 | |
| 19 | +fi | |
| 20 | +OWNER="$1" | |
| 21 | +VERSION="$2" | |
| 22 | + | |
| 23 | +# The kits' `tag` arg is also their version, so it carries the spec's version | |
| 24 | +# grammar: dotted segments, no "v" (the frontend refuses anything else). | |
| 25 | +if ! [[ "${VERSION}" =~ ^[0-9]+(\.[0-9A-Za-z-]+)*$ ]]; then | |
| 26 | + echo "❌ VERSION must be version-shaped without a \"v\" (0.2.1, 0.2.2-rc.1), got '${VERSION}'" >&2 | |
| 27 | + exit 2 | |
| 28 | +fi | |
| 29 | + | |
| 30 | +cd "$(dirname "$0")/.." | |
| 31 | + | |
| 32 | +for kit in docker-sbx-v3/kits/*/*.yaml; do | |
| 33 | + if ! grep -q '^ image:$' "${kit}" || ! grep -q '^ tag:$' "${kit}"; then | |
| 34 | + echo "❌ ${kit}: expected an 'args.image' and an 'args.tag' — not updated" >&2 | |
| 35 | + exit 1 | |
| 36 | + fi | |
| 37 | + # sed -i.bak works on both GNU and BSD sed; the backup is removed at once. | |
| 38 | + sed -i.bak -E \ | |
| 39 | + -e "/^ image:\$/,/^ default:/ s|^( default: )\"[^\"/]*(/mm-sandbox)\"|\1\"${OWNER}\2\"|" \ | |
| 40 | + -e "/^ tag:\$/,/^ default:/ s|^( default: )\"[^\"]*\"|\1\"${VERSION}\"|" \ | |
| 41 | + "${kit}" | |
| 42 | + rm -f "${kit}.bak" | |
| 43 | + echo "✅ ${kit} → image ${OWNER}/mm-sandbox, tag (and version) \"${VERSION}\"" | |
| 44 | +done | |
| new file mode 100755 | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | +#!/usr/bin/env bash | ||
| 2 | +# Point the two v3 kits at one image: <owner>/mm-sandbox:<version>. | ||
| 3 | +# | ||
| 4 | +# Usage: ./docker-sbx-v3/sync-kits.sh OWNER VERSION (e.g. k33g 0.2.1) | ||
| 5 | +# | ||
| 6 | +# Rewrites, in docker-sbx-v3/kits/*/*.yaml (the descriptors), only two values: | ||
| 7 | +# args.image.default: "<owner>/mm-sandbox" which repository the kit is built FROM | ||
| 8 | +# args.tag.default: "<version>" which tag — and the kit's version, | ||
| 9 | +# since `version:` and `provides:` | ||
| 10 | +# reference ${{ kit.args.tag }} | ||
| 11 | +# Everything else — comments included — is left byte-for-byte alone, so a | ||
| 12 | +# kit that already matches is not changed at all. build.sh and push-kits.sh | ||
| 13 | +# call this, so the kits always name the image just built or pushed. | ||
| 14 | +set -euo pipefail | ||
| 15 | + | ||
| 16 | +if [ $# -ne 2 ]; then | ||
| 17 | + echo "usage: $0 OWNER VERSION" >&2 | ||
| 18 | + exit 2 | ||
| 19 | +fi | ||
| 20 | +OWNER="$1" | ||
| 21 | +VERSION="$2" | ||
| 22 | + | ||
| 23 | +# The kits' `tag` arg is also their version, so it carries the spec's version | ||
| 24 | +# grammar: dotted segments, no "v" (the frontend refuses anything else). | ||
| 25 | +if ! [[ "${VERSION}" =~ ^[0-9]+(\.[0-9A-Za-z-]+)*$ ]]; then | ||
| 26 | + echo "❌ VERSION must be version-shaped without a \"v\" (0.2.1, 0.2.2-rc.1), got '${VERSION}'" >&2 | ||
| 27 | + exit 2 | ||
| 28 | +fi | ||
| 29 | + | ||
| 30 | +cd "$(dirname "$0")/.." | ||
| 31 | + | ||
| 32 | +for kit in docker-sbx-v3/kits/*/*.yaml; do | ||
| 33 | + if ! grep -q '^ image:$' "${kit}" || ! grep -q '^ tag:$' "${kit}"; then | ||
| 34 | + echo "❌ ${kit}: expected an 'args.image' and an 'args.tag' — not updated" >&2 | ||
| 35 | + exit 1 | ||
| 36 | + fi | ||
| 37 | + # sed -i.bak works on both GNU and BSD sed; the backup is removed at once. | ||
| 38 | + sed -i.bak -E \ | ||
| 39 | + -e "/^ image:\$/,/^ default:/ s|^( default: )\"[^\"/]*(/mm-sandbox)\"|\1\"${OWNER}\2\"|" \ | ||
| 40 | + -e "/^ tag:\$/,/^ default:/ s|^( default: )\"[^\"]*\"|\1\"${VERSION}\"|" \ | ||
| 41 | + "${kit}" | ||
| 42 | + rm -f "${kit}.bak" | ||
| 43 | + echo "✅ ${kit} → image ${OWNER}/mm-sandbox, tag (and version) \"${VERSION}\"" | ||
| 44 | +done | ||
added
docker-sbx-v3/template/Dockerfile +143 -0 | new file mode 100644 | ||
| @@ -0,0 +1,143 @@ | ||
| 1 | +# syntax=docker/dockerfile:1 | |
| 2 | +# | |
| 3 | +# The mm sandbox template: Docker Sandboxes' `shell` image with mm installed. | |
| 4 | +# | |
| 5 | +# Build it from the REPOSITORY ROOT (the context is the mm sources), or run | |
| 6 | +# docker-sbx-v3/build.sh, which does exactly that and stamps mm's tag — the | |
| 7 | +# image tag is that tag without the "v", k33g/mm-sandbox:0.0.2 for v0.0.2: | |
| 8 | +# | |
| 9 | +# docker build -f docker-sbx-v3/template/Dockerfile \ | |
| 10 | +# --build-arg MM_VERSION=v0.0.2 -t k33g/mm-sandbox:0.0.2 . | |
| 11 | +# | |
| 12 | +# The two v3 kits under docker-sbx-v3/kits/ are thin workloads built FROM this | |
| 13 | +# image: each one sets its own ENTRYPOINT (mm-tui, mm-acp-info), which the | |
| 14 | +# sandbox runtime reads as the agent's launch command (sbx@1). ENTRYPOINT and | |
| 15 | +# CMD are therefore deliberately not set here: the template stays agnostic. | |
| 16 | + | |
| 17 | +ARG GO_VERSION=1.26 | |
| 18 | +ARG SHELL_TEMPLATE=docker/sandbox-templates:shell | |
| 19 | + | |
| 20 | +# ---- build stage: cross-compile mm for the target platform ----------------- | |
| 21 | +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build | |
| 22 | +ARG TARGETOS | |
| 23 | +ARG TARGETARCH | |
| 24 | +# What `mm --version` reports: the tag, as 02-build-releases.sh stamps it. | |
| 25 | +ARG MM_VERSION=dev | |
| 26 | + | |
| 27 | +WORKDIR /src | |
| 28 | +COPY go.mod go.sum ./ | |
| 29 | +RUN --mount=type=cache,target=/go/pkg/mod go mod download | |
| 30 | +COPY . . | |
| 31 | +# Same flags as 02-build-releases.sh: no C, no local paths, no symbols, the | |
| 32 | +# version stamped into internal/version. | |
| 33 | +RUN --mount=type=cache,target=/go/pkg/mod \ | |
| 34 | + --mount=type=cache,target=/root/.cache/go-build \ | |
| 35 | + CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ | |
| 36 | + go build -trimpath -ldflags "-s -w -X mm/internal/version.stamped=${MM_VERSION}" -o /out/mm . | |
| 37 | + | |
| 38 | +# ---- template: the shell sandbox plus mm ----------------------------------- | |
| 39 | +FROM ${SHELL_TEMPLATE} | |
| 40 | + | |
| 41 | +COPY --from=build --chmod=0755 /out/mm /usr/local/bin/mm | |
| 42 | +# The two kit entry points. mm-tui runs `mm -tui "$@"`; mm-acp-info prints how | |
| 43 | +# an editor reaches this sandbox and opens a shell (see docker-sbx-v3/README.md). | |
| 44 | +COPY --chmod=0755 docker-sbx-v3/template/mm-tui docker-sbx-v3/template/mm-acp-info /usr/local/bin/ | |
| 45 | + | |
| 46 | +# tcell (the window mode) needs a terminal type and a UTF-8 locale; the kits | |
| 47 | +# set them too, this is the fallback for a plain `docker run`. | |
| 48 | +ENV TERM=xterm-256color \ | |
| 49 | + COLORTERM=truecolor \ | |
| 50 | + LANG=C.UTF-8 | |
| 51 | + | |
| 52 | +# The pinned toolchains (/usr/local/go/bin, /usr/local/node/bin) must come | |
| 53 | +# before /usr/bin so they win over any Go or Node the base image ships. | |
| 54 | +ENV PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH | |
| 55 | + | |
| 56 | +# Without this, a go.mod whose `go` directive is newer than GO_VERSION makes the | |
| 57 | +# toolchain download and run a different Go, silently defeating the pin. | |
| 58 | +ENV GOTOOLCHAIN=local | |
| 59 | + | |
| 60 | +# ------------------------------------ | |
| 61 | +# Shared curl options for every download below. | |
| 62 | +# | |
| 63 | +# ARG, not ENV: this is build-time only and must not leak into the image. | |
| 64 | +# ------------------------------------ | |
| 65 | +ARG CURL_RETRY="--retry 5 --retry-all-errors --retry-delay 3 --connect-timeout 15" | |
| 66 | + | |
| 67 | +USER root | |
| 68 | + | |
| 69 | +# ------------------------------------ | |
| 70 | +# Install Go toolchain and Node.js | |
| 71 | +# ------------------------------------ | |
| 72 | +ARG GO_VERSION=1.26.0 | |
| 73 | +ARG NODE_VERSION=24.21.0 | |
| 74 | +ARG TARGETARCH | |
| 75 | + | |
| 76 | +RUN <<EOF | |
| 77 | +set -eux | |
| 78 | +apt-get update | |
| 79 | +apt-get install -y curl build-essential xz-utils | |
| 80 | +rm -rf /var/lib/apt/lists/* | |
| 81 | +EOF | |
| 82 | + | |
| 83 | +RUN <<EOF | |
| 84 | +set -eux | |
| 85 | +apt-get remove -y golang-go golang-doc | |
| 86 | +apt-get autoremove -y | |
| 87 | +curl ${CURL_RETRY} -C - -fsSL -o /tmp/go.tgz "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz" | |
| 88 | +rm -rf /usr/local/go | |
| 89 | +tar -C /usr/local -xzf /tmp/go.tgz | |
| 90 | +rm /tmp/go.tgz | |
| 91 | +/usr/local/go/bin/go version | |
| 92 | +EOF | |
| 93 | + | |
| 94 | +RUN <<EOF | |
| 95 | +set -eux | |
| 96 | +case "${TARGETARCH}" in | |
| 97 | + amd64) node_arch=x64 ;; | |
| 98 | + arm64) node_arch=arm64 ;; | |
| 99 | + *) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; | |
| 100 | +esac | |
| 101 | +curl ${CURL_RETRY} -C - -fsSL -o /tmp/node.tar.xz "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" | |
| 102 | +rm -rf /usr/local/node | |
| 103 | +mkdir -p /usr/local/node | |
| 104 | +tar -C /usr/local/node --strip-components=1 -xJf /tmp/node.tar.xz | |
| 105 | +rm /tmp/node.tar.xz | |
| 106 | +/usr/local/node/bin/node --version | |
| 107 | +/usr/local/node/bin/npm --version | |
| 108 | +EOF | |
| 109 | + | |
| 110 | +# ------------------------------------ | |
| 111 | +# Persist the Go and Node environment for sandbox shells. | |
| 112 | +# /etc/sandbox-persistent.sh is sourced before every bash command in the sbx. | |
| 113 | +# ------------------------------------ | |
| 114 | +RUN <<EOF | |
| 115 | +{ | |
| 116 | + echo 'export PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH' | |
| 117 | + echo 'export GOTOOLCHAIN=local' | |
| 118 | +} >> /etc/sandbox-persistent.sh | |
| 119 | +EOF | |
| 120 | + | |
| 121 | +# Switch to agent user for Go tools installation (they go to /home/agent/go/bin) | |
| 122 | +USER agent | |
| 123 | + | |
| 124 | +# ------------------------------------ | |
| 125 | +# Install Go developer tools | |
| 126 | +# ------------------------------------ | |
| 127 | +ARG GOPLS_VERSION=v0.23.0 | |
| 128 | +ARG X_TOOLS_VERSION=v0.49.0 | |
| 129 | +ARG STATICCHECK_VERSION=v0.7.0 | |
| 130 | + | |
| 131 | +# Retried: parallel multi-arch builds occasionally hit DNS timeouts on | |
| 132 | +# Docker Desktop's resolver. The module cache survives within this RUN, | |
| 133 | +# so a retry only fetches what's still missing. | |
| 134 | +RUN for i in 1 2 3 4 5; do \ | |
| 135 | + go install golang.org/x/tools/gopls@${GOPLS_VERSION} \ | |
| 136 | + && go install golang.org/x/tools/cmd/goimports@${X_TOOLS_VERSION} \ | |
| 137 | + && go install honnef.co/go/tools/cmd/staticcheck@${STATICCHECK_VERSION} \ | |
| 138 | + && exit 0; \ | |
| 139 | + echo "go install failed (attempt $i), retrying..." >&2; sleep $((i * 5)); \ | |
| 140 | + done; exit 1 | |
| 141 | + | |
| 142 | +# Prove the binary runs on this platform before the image is tagged. | |
| 143 | +RUN mm --version && mm-tui --version | |
| new file mode 100644 | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | +# syntax=docker/dockerfile:1 | ||
| 2 | +# | ||
| 3 | +# The mm sandbox template: Docker Sandboxes' `shell` image with mm installed. | ||
| 4 | +# | ||
| 5 | +# Build it from the REPOSITORY ROOT (the context is the mm sources), or run | ||
| 6 | +# docker-sbx-v3/build.sh, which does exactly that and stamps mm's tag — the | ||
| 7 | +# image tag is that tag without the "v", k33g/mm-sandbox:0.0.2 for v0.0.2: | ||
| 8 | +# | ||
| 9 | +# docker build -f docker-sbx-v3/template/Dockerfile \ | ||
| 10 | +# --build-arg MM_VERSION=v0.0.2 -t k33g/mm-sandbox:0.0.2 . | ||
| 11 | +# | ||
| 12 | +# The two v3 kits under docker-sbx-v3/kits/ are thin workloads built FROM this | ||
| 13 | +# image: each one sets its own ENTRYPOINT (mm-tui, mm-acp-info), which the | ||
| 14 | +# sandbox runtime reads as the agent's launch command (sbx@1). ENTRYPOINT and | ||
| 15 | +# CMD are therefore deliberately not set here: the template stays agnostic. | ||
| 16 | + | ||
| 17 | +ARG GO_VERSION=1.26 | ||
| 18 | +ARG SHELL_TEMPLATE=docker/sandbox-templates:shell | ||
| 19 | + | ||
| 20 | +# ---- build stage: cross-compile mm for the target platform ----------------- | ||
| 21 | +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build | ||
| 22 | +ARG TARGETOS | ||
| 23 | +ARG TARGETARCH | ||
| 24 | +# What `mm --version` reports: the tag, as 02-build-releases.sh stamps it. | ||
| 25 | +ARG MM_VERSION=dev | ||
| 26 | + | ||
| 27 | +WORKDIR /src | ||
| 28 | +COPY go.mod go.sum ./ | ||
| 29 | +RUN --mount=type=cache,target=/go/pkg/mod go mod download | ||
| 30 | +COPY . . | ||
| 31 | +# Same flags as 02-build-releases.sh: no C, no local paths, no symbols, the | ||
| 32 | +# version stamped into internal/version. | ||
| 33 | +RUN --mount=type=cache,target=/go/pkg/mod \ | ||
| 34 | + --mount=type=cache,target=/root/.cache/go-build \ | ||
| 35 | + CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ | ||
| 36 | + go build -trimpath -ldflags "-s -w -X mm/internal/version.stamped=${MM_VERSION}" -o /out/mm . | ||
| 37 | + | ||
| 38 | +# ---- template: the shell sandbox plus mm ----------------------------------- | ||
| 39 | +FROM ${SHELL_TEMPLATE} | ||
| 40 | + | ||
| 41 | +COPY --from=build --chmod=0755 /out/mm /usr/local/bin/mm | ||
| 42 | +# The two kit entry points. mm-tui runs `mm -tui "$@"`; mm-acp-info prints how | ||
| 43 | +# an editor reaches this sandbox and opens a shell (see docker-sbx-v3/README.md). | ||
| 44 | +COPY --chmod=0755 docker-sbx-v3/template/mm-tui docker-sbx-v3/template/mm-acp-info /usr/local/bin/ | ||
| 45 | + | ||
| 46 | +# tcell (the window mode) needs a terminal type and a UTF-8 locale; the kits | ||
| 47 | +# set them too, this is the fallback for a plain `docker run`. | ||
| 48 | +ENV TERM=xterm-256color \ | ||
| 49 | + COLORTERM=truecolor \ | ||
| 50 | + LANG=C.UTF-8 | ||
| 51 | + | ||
| 52 | +# The pinned toolchains (/usr/local/go/bin, /usr/local/node/bin) must come | ||
| 53 | +# before /usr/bin so they win over any Go or Node the base image ships. | ||
| 54 | +ENV PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH | ||
| 55 | + | ||
| 56 | +# Without this, a go.mod whose `go` directive is newer than GO_VERSION makes the | ||
| 57 | +# toolchain download and run a different Go, silently defeating the pin. | ||
| 58 | +ENV GOTOOLCHAIN=local | ||
| 59 | + | ||
| 60 | +# ------------------------------------ | ||
| 61 | +# Shared curl options for every download below. | ||
| 62 | +# | ||
| 63 | +# ARG, not ENV: this is build-time only and must not leak into the image. | ||
| 64 | +# ------------------------------------ | ||
| 65 | +ARG CURL_RETRY="--retry 5 --retry-all-errors --retry-delay 3 --connect-timeout 15" | ||
| 66 | + | ||
| 67 | +USER root | ||
| 68 | + | ||
| 69 | +# ------------------------------------ | ||
| 70 | +# Install Go toolchain and Node.js | ||
| 71 | +# ------------------------------------ | ||
| 72 | +ARG GO_VERSION=1.26.0 | ||
| 73 | +ARG NODE_VERSION=24.21.0 | ||
| 74 | +ARG TARGETARCH | ||
| 75 | + | ||
| 76 | +RUN <<EOF | ||
| 77 | +set -eux | ||
| 78 | +apt-get update | ||
| 79 | +apt-get install -y curl build-essential xz-utils | ||
| 80 | +rm -rf /var/lib/apt/lists/* | ||
| 81 | +EOF | ||
| 82 | + | ||
| 83 | +RUN <<EOF | ||
| 84 | +set -eux | ||
| 85 | +apt-get remove -y golang-go golang-doc | ||
| 86 | +apt-get autoremove -y | ||
| 87 | +curl ${CURL_RETRY} -C - -fsSL -o /tmp/go.tgz "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz" | ||
| 88 | +rm -rf /usr/local/go | ||
| 89 | +tar -C /usr/local -xzf /tmp/go.tgz | ||
| 90 | +rm /tmp/go.tgz | ||
| 91 | +/usr/local/go/bin/go version | ||
| 92 | +EOF | ||
| 93 | + | ||
| 94 | +RUN <<EOF | ||
| 95 | +set -eux | ||
| 96 | +case "${TARGETARCH}" in | ||
| 97 | + amd64) node_arch=x64 ;; | ||
| 98 | + arm64) node_arch=arm64 ;; | ||
| 99 | + *) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; | ||
| 100 | +esac | ||
| 101 | +curl ${CURL_RETRY} -C - -fsSL -o /tmp/node.tar.xz "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz" | ||
| 102 | +rm -rf /usr/local/node | ||
| 103 | +mkdir -p /usr/local/node | ||
| 104 | +tar -C /usr/local/node --strip-components=1 -xJf /tmp/node.tar.xz | ||
| 105 | +rm /tmp/node.tar.xz | ||
| 106 | +/usr/local/node/bin/node --version | ||
| 107 | +/usr/local/node/bin/npm --version | ||
| 108 | +EOF | ||
| 109 | + | ||
| 110 | +# ------------------------------------ | ||
| 111 | +# Persist the Go and Node environment for sandbox shells. | ||
| 112 | +# /etc/sandbox-persistent.sh is sourced before every bash command in the sbx. | ||
| 113 | +# ------------------------------------ | ||
| 114 | +RUN <<EOF | ||
| 115 | +{ | ||
| 116 | + echo 'export PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH' | ||
| 117 | + echo 'export GOTOOLCHAIN=local' | ||
| 118 | +} >> /etc/sandbox-persistent.sh | ||
| 119 | +EOF | ||
| 120 | + | ||
| 121 | +# Switch to agent user for Go tools installation (they go to /home/agent/go/bin) | ||
| 122 | +USER agent | ||
| 123 | + | ||
| 124 | +# ------------------------------------ | ||
| 125 | +# Install Go developer tools | ||
| 126 | +# ------------------------------------ | ||
| 127 | +ARG GOPLS_VERSION=v0.23.0 | ||
| 128 | +ARG X_TOOLS_VERSION=v0.49.0 | ||
| 129 | +ARG STATICCHECK_VERSION=v0.7.0 | ||
| 130 | + | ||
| 131 | +# Retried: parallel multi-arch builds occasionally hit DNS timeouts on | ||
| 132 | +# Docker Desktop's resolver. The module cache survives within this RUN, | ||
| 133 | +# so a retry only fetches what's still missing. | ||
| 134 | +RUN for i in 1 2 3 4 5; do \ | ||
| 135 | + go install golang.org/x/tools/gopls@${GOPLS_VERSION} \ | ||
| 136 | + && go install golang.org/x/tools/cmd/goimports@${X_TOOLS_VERSION} \ | ||
| 137 | + && go install honnef.co/go/tools/cmd/staticcheck@${STATICCHECK_VERSION} \ | ||
| 138 | + && exit 0; \ | ||
| 139 | + echo "go install failed (attempt $i), retrying..." >&2; sleep $((i * 5)); \ | ||
| 140 | + done; exit 1 | ||
| 141 | + | ||
| 142 | +# Prove the binary runs on this platform before the image is tagged. | ||
| 143 | +RUN mm --version && mm-tui --version | ||
added
docker-sbx-v3/template/mm-acp-info +52 -0 | new file mode 100644 | ||
| @@ -0,0 +1,52 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# Entry point of the mm-acp sandbox kit (docker-sbx-v3/kits/mm-acp). | |
| 3 | +# | |
| 4 | +# An editor never runs this script. It reaches mm with | |
| 5 | +# | |
| 6 | +# sbx exec -i <sandbox> mm -acp | |
| 7 | +# | |
| 8 | +# because an ACP client needs raw stdin/stdout and `sbx run` always allocates | |
| 9 | +# a terminal. So attaching to this sandbox with `sbx run` prints the wiring | |
| 10 | +# for the editor, with this sandbox's real name and paths, then opens a shell. | |
| 11 | +set -u | |
| 12 | + | |
| 13 | +name="${SANDBOX_NAME:-$(hostname)}" | |
| 14 | +workspace="${WORKSPACE_DIR:-$PWD}" | |
| 15 | +config="${AGENT_CONFIG:-}" | |
| 16 | +if [ -z "$config" ]; then | |
| 17 | + config_note="none set — mm reads ./agent.yaml in the workspace, then its built-in defaults" | |
| 18 | +elif [ "${config#/}" = "$config" ]; then | |
| 19 | + config_note="$config (relative to the workspace: ${workspace%/}/$config)" | |
| 20 | +else | |
| 21 | + config_note="$config" | |
| 22 | +fi | |
| 23 | + | |
| 24 | +cat <<INFO | |
| 25 | + | |
| 26 | + mm $(mm --version 2>/dev/null | awk '{print $2}') in sandbox "$name" | |
| 27 | + workspace : $workspace | |
| 28 | + config : $config_note | |
| 29 | + | |
| 30 | + This sandbox is meant for an editor (Agent Client Protocol). Register it in | |
| 31 | + Zed's settings.json — the editor starts mm inside the sandbox on every | |
| 32 | + conversation, and sbx starts the sandbox first when it is stopped: | |
| 33 | + | |
| 34 | + { | |
| 35 | + "agent_servers": { | |
| 36 | + "mini-me (sandbox)": { | |
| 37 | + "type": "custom", | |
| 38 | + "command": "sbx", | |
| 39 | + "args": ["exec", "-i", "$name", "mm", "-acp"] | |
| 40 | + } | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | + Use the absolute path of sbx as "command" if the editor cannot find it | |
| 45 | + (\`which sbx\` on the host). To change the configuration file for one | |
| 46 | + session, add "-e", "AGENT_CONFIG=/path/in/workspace/agent.yaml" before | |
| 47 | + "$name" in "args". Full guide: docker-sbx-v3/README.md | |
| 48 | + | |
| 49 | + You are now in a shell inside the sandbox. \`mm agent.yaml\` works here too. | |
| 50 | + | |
| 51 | +INFO | |
| 52 | +exec bash -l | |
| new file mode 100644 | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# Entry point of the mm-acp sandbox kit (docker-sbx-v3/kits/mm-acp). | ||
| 3 | +# | ||
| 4 | +# An editor never runs this script. It reaches mm with | ||
| 5 | +# | ||
| 6 | +# sbx exec -i <sandbox> mm -acp | ||
| 7 | +# | ||
| 8 | +# because an ACP client needs raw stdin/stdout and `sbx run` always allocates | ||
| 9 | +# a terminal. So attaching to this sandbox with `sbx run` prints the wiring | ||
| 10 | +# for the editor, with this sandbox's real name and paths, then opens a shell. | ||
| 11 | +set -u | ||
| 12 | + | ||
| 13 | +name="${SANDBOX_NAME:-$(hostname)}" | ||
| 14 | +workspace="${WORKSPACE_DIR:-$PWD}" | ||
| 15 | +config="${AGENT_CONFIG:-}" | ||
| 16 | +if [ -z "$config" ]; then | ||
| 17 | + config_note="none set — mm reads ./agent.yaml in the workspace, then its built-in defaults" | ||
| 18 | +elif [ "${config#/}" = "$config" ]; then | ||
| 19 | + config_note="$config (relative to the workspace: ${workspace%/}/$config)" | ||
| 20 | +else | ||
| 21 | + config_note="$config" | ||
| 22 | +fi | ||
| 23 | + | ||
| 24 | +cat <<INFO | ||
| 25 | + | ||
| 26 | + mm $(mm --version 2>/dev/null | awk '{print $2}') in sandbox "$name" | ||
| 27 | + workspace : $workspace | ||
| 28 | + config : $config_note | ||
| 29 | + | ||
| 30 | + This sandbox is meant for an editor (Agent Client Protocol). Register it in | ||
| 31 | + Zed's settings.json — the editor starts mm inside the sandbox on every | ||
| 32 | + conversation, and sbx starts the sandbox first when it is stopped: | ||
| 33 | + | ||
| 34 | + { | ||
| 35 | + "agent_servers": { | ||
| 36 | + "mini-me (sandbox)": { | ||
| 37 | + "type": "custom", | ||
| 38 | + "command": "sbx", | ||
| 39 | + "args": ["exec", "-i", "$name", "mm", "-acp"] | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + Use the absolute path of sbx as "command" if the editor cannot find it | ||
| 45 | + (\`which sbx\` on the host). To change the configuration file for one | ||
| 46 | + session, add "-e", "AGENT_CONFIG=/path/in/workspace/agent.yaml" before | ||
| 47 | + "$name" in "args". Full guide: docker-sbx-v3/README.md | ||
| 48 | + | ||
| 49 | + You are now in a shell inside the sandbox. \`mm agent.yaml\` works here too. | ||
| 50 | + | ||
| 51 | +INFO | ||
| 52 | +exec bash -l | ||
added
docker-sbx-v3/template/mm-tui +11 -0 | new file mode 100644 | ||
| @@ -0,0 +1,11 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +# Entry point of the mm-tui sandbox kit (docker-sbx-v3/kits/mm-tui). | |
| 3 | +# | |
| 4 | +# `sbx run` forwards whatever follows "--" as this script's arguments, so | |
| 5 | +# | |
| 6 | +# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 7 | +# | |
| 8 | +# runs `mm -tui agent.dmr.yaml` in the workspace. Without an argument mm reads | |
| 9 | +# $AGENT_CONFIG (the kit's `config` argument), then ./agent.yaml, then its | |
| 10 | +# built-in defaults. Flags pass through too: `-- -config other.yaml`. | |
| 11 | +exec mm -tui "$@" | |
| new file mode 100644 | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# Entry point of the mm-tui sandbox kit (docker-sbx-v3/kits/mm-tui). | ||
| 3 | +# | ||
| 4 | +# `sbx run` forwards whatever follows "--" as this script's arguments, so | ||
| 5 | +# | ||
| 6 | +# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 7 | +# | ||
| 8 | +# runs `mm -tui agent.dmr.yaml` in the workspace. Without an argument mm reads | ||
| 9 | +# $AGENT_CONFIG (the kit's `config` argument), then ./agent.yaml, then its | ||
| 10 | +# built-in defaults. Flags pass through too: `-- -config other.yaml`. | ||
| 11 | +exec mm -tui "$@" | ||
added
docker-sbx/kits/mm-acp/spec.yaml +69 -0 | new file mode 100644 | ||
| @@ -0,0 +1,69 @@ | ||
| 1 | +# Docker Sandboxes kit: mm as an editor's agent (Agent Client Protocol), inside | |
| 2 | +# the mm sandbox template. | |
| 3 | +# | |
| 4 | +# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version> | |
| 5 | +# sbx create --pull never --name mm-acp ./docker-sbx/kits/mm-acp . \ | |
| 6 | +# --kit-arg config=agent.dmr.yaml | |
| 7 | +# | |
| 8 | +# then, in the editor (Zed settings.json): | |
| 9 | +# | |
| 10 | +# "agent_servers": { "mini-me (sandbox)": { "type": "custom", | |
| 11 | +# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } } | |
| 12 | +# | |
| 13 | +# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the | |
| 14 | +# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the | |
| 15 | +# sandbox is created without attaching, and the editor starts `mm -acp` inside | |
| 16 | +# it for every conversation (sbx starts a stopped sandbox first). Attaching | |
| 17 | +# with `sbx run` runs the entry point below, which prints this wiring with the | |
| 18 | +# sandbox's real name and opens a shell. | |
| 19 | +schemaVersion: "2" | |
| 20 | +kind: sandbox | |
| 21 | +name: mm-acp | |
| 22 | +displayName: Mini Me (editor, ACP) | |
| 23 | +description: > | |
| 24 | + Holds mm, a minimal coding agent for local LLMs, for an editor that speaks | |
| 25 | + the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox> | |
| 26 | + mm -acp`; every command and file edit the model asks for happens inside the | |
| 27 | + sandbox, on the mounted workspace. The model server stays on the host, | |
| 28 | + reached through host.docker.internal. | |
| 29 | +# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the | |
| 30 | +# vnd.docker.sandbox.kit.version annotation of the published kit. | |
| 31 | +version: "0.2.1" | |
| 32 | +sourceURL: https://git.rickub.com/bots-garden/mini-me | |
| 33 | + | |
| 34 | +args: | |
| 35 | + tag: | |
| 36 | + default: "0.2.1" | |
| 37 | + description: >- | |
| 38 | + Tag of the k33g/mm-sandbox image: mm's version without the "v", as | |
| 39 | + docker-sbx/build.sh tags it (and rewrites this default to). | |
| 40 | + pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$' | |
| 41 | + config: | |
| 42 | + default: "" | |
| 43 | + description: >- | |
| 44 | + Configuration file mm reads (its AGENT_CONFIG): an absolute path inside | |
| 45 | + the sandbox, or a path relative to the workspace, which is where | |
| 46 | + `sbx exec` starts mm. Empty: ./agent.yaml in the workspace, then the | |
| 47 | + built-in defaults. | |
| 48 | + | |
| 49 | +sandbox: | |
| 50 | + image: "k33g/mm-sandbox:${{ kit.args.tag }}" | |
| 51 | + # Not `mm -acp`: nothing useful comes of speaking JSON-RPC to a terminal. | |
| 52 | + entrypoint: [mm-acp-info] | |
| 53 | + | |
| 54 | +environment: | |
| 55 | + variables: | |
| 56 | + # Baked into the container, so `sbx exec` inherits it and the editor's | |
| 57 | + # settings need not repeat the path. `sbx exec -e AGENT_CONFIG=…` overrides | |
| 58 | + # it for one session. | |
| 59 | + AGENT_CONFIG: "${{ kit.args.config }}" | |
| 60 | + LANG: C.UTF-8 | |
| 61 | + | |
| 62 | +# The model server on the host — see docker-sbx/kits/mm-tui/spec.yaml. | |
| 63 | +permissions: | |
| 64 | + network: | |
| 65 | + allow: | |
| 66 | + - "host.docker.internal:12434" | |
| 67 | + - "localhost:12434" | |
| 68 | + - "host.docker.internal:8080" | |
| 69 | + - "localhost:8080" | |
| new file mode 100644 | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | +# Docker Sandboxes kit: mm as an editor's agent (Agent Client Protocol), inside | ||
| 2 | +# the mm sandbox template. | ||
| 3 | +# | ||
| 4 | +# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version> | ||
| 5 | +# sbx create --pull never --name mm-acp ./docker-sbx/kits/mm-acp . \ | ||
| 6 | +# --kit-arg config=agent.dmr.yaml | ||
| 7 | +# | ||
| 8 | +# then, in the editor (Zed settings.json): | ||
| 9 | +# | ||
| 10 | +# "agent_servers": { "mini-me (sandbox)": { "type": "custom", | ||
| 11 | +# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } } | ||
| 12 | +# | ||
| 13 | +# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the | ||
| 14 | +# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the | ||
| 15 | +# sandbox is created without attaching, and the editor starts `mm -acp` inside | ||
| 16 | +# it for every conversation (sbx starts a stopped sandbox first). Attaching | ||
| 17 | +# with `sbx run` runs the entry point below, which prints this wiring with the | ||
| 18 | +# sandbox's real name and opens a shell. | ||
| 19 | +schemaVersion: "2" | ||
| 20 | +kind: sandbox | ||
| 21 | +name: mm-acp | ||
| 22 | +displayName: Mini Me (editor, ACP) | ||
| 23 | +description: > | ||
| 24 | + Holds mm, a minimal coding agent for local LLMs, for an editor that speaks | ||
| 25 | + the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox> | ||
| 26 | + mm -acp`; every command and file edit the model asks for happens inside the | ||
| 27 | + sandbox, on the mounted workspace. The model server stays on the host, | ||
| 28 | + reached through host.docker.internal. | ||
| 29 | +# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the | ||
| 30 | +# vnd.docker.sandbox.kit.version annotation of the published kit. | ||
| 31 | +version: "0.2.1" | ||
| 32 | +sourceURL: https://git.rickub.com/bots-garden/mini-me | ||
| 33 | + | ||
| 34 | +args: | ||
| 35 | + tag: | ||
| 36 | + default: "0.2.1" | ||
| 37 | + description: >- | ||
| 38 | + Tag of the k33g/mm-sandbox image: mm's version without the "v", as | ||
| 39 | + docker-sbx/build.sh tags it (and rewrites this default to). | ||
| 40 | + pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$' | ||
| 41 | + config: | ||
| 42 | + default: "" | ||
| 43 | + description: >- | ||
| 44 | + Configuration file mm reads (its AGENT_CONFIG): an absolute path inside | ||
| 45 | + the sandbox, or a path relative to the workspace, which is where | ||
| 46 | + `sbx exec` starts mm. Empty: ./agent.yaml in the workspace, then the | ||
| 47 | + built-in defaults. | ||
| 48 | + | ||
| 49 | +sandbox: | ||
| 50 | + image: "k33g/mm-sandbox:${{ kit.args.tag }}" | ||
| 51 | + # Not `mm -acp`: nothing useful comes of speaking JSON-RPC to a terminal. | ||
| 52 | + entrypoint: [mm-acp-info] | ||
| 53 | + | ||
| 54 | +environment: | ||
| 55 | + variables: | ||
| 56 | + # Baked into the container, so `sbx exec` inherits it and the editor's | ||
| 57 | + # settings need not repeat the path. `sbx exec -e AGENT_CONFIG=…` overrides | ||
| 58 | + # it for one session. | ||
| 59 | + AGENT_CONFIG: "${{ kit.args.config }}" | ||
| 60 | + LANG: C.UTF-8 | ||
| 61 | + | ||
| 62 | +# The model server on the host — see docker-sbx/kits/mm-tui/spec.yaml. | ||
| 63 | +permissions: | ||
| 64 | + network: | ||
| 65 | + allow: | ||
| 66 | + - "host.docker.internal:12434" | ||
| 67 | + - "localhost:12434" | ||
| 68 | + - "host.docker.internal:8080" | ||
| 69 | + - "localhost:8080" | ||
added
docker-sbx/kits/mm-tui/spec.yaml +68 -0 | new file mode 100644 | ||
| @@ -0,0 +1,68 @@ | ||
| 1 | +# Docker Sandboxes kit: mm in its window mode, inside the mm sandbox template. | |
| 2 | +# | |
| 3 | +# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version> | |
| 4 | +# sbx run --pull never ./docker-sbx/kits/mm-tui . -- agent.dmr.yaml | |
| 5 | +# | |
| 6 | +# What follows "--" reaches mm as its own arguments (here the configuration | |
| 7 | +# file, relative to the workspace). Without it, the `config` argument below is | |
| 8 | +# read, then ./agent.yaml, then the built-in defaults: | |
| 9 | +# | |
| 10 | +# sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |
| 11 | +# | |
| 12 | +# --pull never: the image is built locally; drop it once it is pushed. | |
| 13 | +schemaVersion: "2" | |
| 14 | +kind: sandbox | |
| 15 | +name: mm-tui | |
| 16 | +displayName: Mini Me (window mode) | |
| 17 | +description: > | |
| 18 | + Runs mm, a minimal coding agent for local LLMs, in its single-window terminal | |
| 19 | + mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or | |
| 20 | + llama-server) stays on the host: inside the sandbox `localhost` is the sandbox | |
| 21 | + itself, so the configuration file must reach the host through | |
| 22 | + host.docker.internal — agent.dmr.yaml already falls back to it. | |
| 23 | +# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the | |
| 24 | +# vnd.docker.sandbox.kit.version annotation of the published kit. | |
| 25 | +version: "0.2.1" | |
| 26 | +sourceURL: https://git.rickub.com/bots-garden/mini-me | |
| 27 | + | |
| 28 | +args: | |
| 29 | + tag: | |
| 30 | + default: "0.2.1" | |
| 31 | + description: >- | |
| 32 | + Tag of the k33g/mm-sandbox image: mm's version without the "v", as | |
| 33 | + docker-sbx/build.sh tags it (and rewrites this default to). | |
| 34 | + pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$' | |
| 35 | + config: | |
| 36 | + default: "" | |
| 37 | + description: >- | |
| 38 | + Configuration file mm reads (its AGENT_CONFIG): an absolute path inside | |
| 39 | + the sandbox, or a path relative to the workspace. Empty: ./agent.yaml in | |
| 40 | + the workspace, then the built-in defaults. | |
| 41 | + | |
| 42 | +sandbox: | |
| 43 | + image: "k33g/mm-sandbox:${{ kit.args.tag }}" | |
| 44 | + # A wrapper, not `mm -tui` directly: the start script drops the fixed | |
| 45 | + # options when the first user argument is not a flag, so `-- agent.yaml` | |
| 46 | + # would otherwise lose -tui. The wrapper always adds it. | |
| 47 | + entrypoint: [mm-tui] | |
| 48 | + | |
| 49 | +environment: | |
| 50 | + variables: | |
| 51 | + AGENT_CONFIG: "${{ kit.args.config }}" | |
| 52 | + # tcell needs a terminal type and a UTF-8 locale to draw the window. | |
| 53 | + TERM: xterm-256color | |
| 54 | + COLORTERM: truecolor | |
| 55 | + LANG: C.UTF-8 | |
| 56 | + | |
| 57 | +# The model server on the host. Requests leave the sandbox through its proxy, | |
| 58 | +# which maps host.docker.internal to the host's localhost; both spellings are | |
| 59 | +# listed so the rule matches whichever one the policy is checked against. | |
| 60 | +# 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own | |
| 61 | +# port with `sbx policy allow network host.docker.internal:<port>`. | |
| 62 | +permissions: | |
| 63 | + network: | |
| 64 | + allow: | |
| 65 | + - "host.docker.internal:12434" | |
| 66 | + - "localhost:12434" | |
| 67 | + - "host.docker.internal:8080" | |
| 68 | + - "localhost:8080" | |
| new file mode 100644 | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | +# Docker Sandboxes kit: mm in its window mode, inside the mm sandbox template. | ||
| 2 | +# | ||
| 3 | +# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version> | ||
| 4 | +# sbx run --pull never ./docker-sbx/kits/mm-tui . -- agent.dmr.yaml | ||
| 5 | +# | ||
| 6 | +# What follows "--" reaches mm as its own arguments (here the configuration | ||
| 7 | +# file, relative to the workspace). Without it, the `config` argument below is | ||
| 8 | +# read, then ./agent.yaml, then the built-in defaults: | ||
| 9 | +# | ||
| 10 | +# sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 11 | +# | ||
| 12 | +# --pull never: the image is built locally; drop it once it is pushed. | ||
| 13 | +schemaVersion: "2" | ||
| 14 | +kind: sandbox | ||
| 15 | +name: mm-tui | ||
| 16 | +displayName: Mini Me (window mode) | ||
| 17 | +description: > | ||
| 18 | + Runs mm, a minimal coding agent for local LLMs, in its single-window terminal | ||
| 19 | + mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or | ||
| 20 | + llama-server) stays on the host: inside the sandbox `localhost` is the sandbox | ||
| 21 | + itself, so the configuration file must reach the host through | ||
| 22 | + host.docker.internal — agent.dmr.yaml already falls back to it. | ||
| 23 | +# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the | ||
| 24 | +# vnd.docker.sandbox.kit.version annotation of the published kit. | ||
| 25 | +version: "0.2.1" | ||
| 26 | +sourceURL: https://git.rickub.com/bots-garden/mini-me | ||
| 27 | + | ||
| 28 | +args: | ||
| 29 | + tag: | ||
| 30 | + default: "0.2.1" | ||
| 31 | + description: >- | ||
| 32 | + Tag of the k33g/mm-sandbox image: mm's version without the "v", as | ||
| 33 | + docker-sbx/build.sh tags it (and rewrites this default to). | ||
| 34 | + pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$' | ||
| 35 | + config: | ||
| 36 | + default: "" | ||
| 37 | + description: >- | ||
| 38 | + Configuration file mm reads (its AGENT_CONFIG): an absolute path inside | ||
| 39 | + the sandbox, or a path relative to the workspace. Empty: ./agent.yaml in | ||
| 40 | + the workspace, then the built-in defaults. | ||
| 41 | + | ||
| 42 | +sandbox: | ||
| 43 | + image: "k33g/mm-sandbox:${{ kit.args.tag }}" | ||
| 44 | + # A wrapper, not `mm -tui` directly: the start script drops the fixed | ||
| 45 | + # options when the first user argument is not a flag, so `-- agent.yaml` | ||
| 46 | + # would otherwise lose -tui. The wrapper always adds it. | ||
| 47 | + entrypoint: [mm-tui] | ||
| 48 | + | ||
| 49 | +environment: | ||
| 50 | + variables: | ||
| 51 | + AGENT_CONFIG: "${{ kit.args.config }}" | ||
| 52 | + # tcell needs a terminal type and a UTF-8 locale to draw the window. | ||
| 53 | + TERM: xterm-256color | ||
| 54 | + COLORTERM: truecolor | ||
| 55 | + LANG: C.UTF-8 | ||
| 56 | + | ||
| 57 | +# The model server on the host. Requests leave the sandbox through its proxy, | ||
| 58 | +# which maps host.docker.internal to the host's localhost; both spellings are | ||
| 59 | +# listed so the rule matches whichever one the policy is checked against. | ||
| 60 | +# 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own | ||
| 61 | +# port with `sbx policy allow network host.docker.internal:<port>`. | ||
| 62 | +permissions: | ||
| 63 | + network: | ||
| 64 | + allow: | ||
| 65 | + - "host.docker.internal:12434" | ||
| 66 | + - "localhost:12434" | ||
| 67 | + - "host.docker.internal:8080" | ||
| 68 | + - "localhost:8080" | ||
modified
docs/en/README.md +1 -0 | @@ -13,6 +13,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr) | ||
| 13 | 13 | - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md) |
| 14 | 14 | - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md) |
| 15 | 15 | - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor |
| 16 | +- [Run mini-me with the v3 sandbox kits](how-to/run-with-sandbox-kits-v3.md) — the same two kits for the kit specification v3, under `docker-sbx-v3/` | |
| 16 | 17 | - [Add a skill](how-to/add-a-skill.md) |
| 17 | 18 | - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after |
| 18 | 19 | - [Keep a long session inside the context window](how-to/manage-the-context-window.md) |
| @@ -13,6 +13,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr) | |||
| 13 | - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md) | 13 | - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md) |
| 14 | - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md) | 14 | - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md) |
| 15 | - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor | 15 | - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor |
| 16 | +- [Run mini-me with the v3 sandbox kits](how-to/run-with-sandbox-kits-v3.md) — the same two kits for the kit specification v3, under `docker-sbx-v3/` | ||
| 16 | - [Add a skill](how-to/add-a-skill.md) | 17 | - [Add a skill](how-to/add-a-skill.md) |
| 17 | - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after | 18 | - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after |
| 18 | - [Keep a long session inside the context window](how-to/manage-the-context-window.md) | 19 | - [Keep a long session inside the context window](how-to/manage-the-context-window.md) |
modified
docs/en/how-to/run-in-a-docker-sandbox.md +12 -9 | @@ -2,6 +2,8 @@ | ||
| 2 | 2 | |
| 3 | 3 | This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine. |
| 4 | 4 | |
| 5 | +> These are the **v2** kits (`spec.yaml`). The same two kits also exist for the kit specification v3, under `docker-sbx-v3/`: see [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md). | |
| 6 | + | |
| 5 | 7 | Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository: |
| 6 | 8 | |
| 7 | 9 | | Piece | What it is | |
| @@ -14,20 +16,20 @@ Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the rep | ||
| 14 | 16 | |
| 15 | 17 | ## Use the published kits |
| 16 | 18 | |
| 17 | -Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`: | |
| 19 | +Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`: | |
| 18 | 20 | |
| 19 | 21 | ```bash |
| 20 | 22 | cd /path/to/your/project |
| 21 | -sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml | |
| 23 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 22 | 24 | ``` |
| 23 | 25 | |
| 24 | 26 | for the window mode, and for an editor: |
| 25 | 27 | |
| 26 | 28 | ```bash |
| 27 | -sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml | |
| 29 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 28 | 30 | ``` |
| 29 | 31 | |
| 30 | -then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.1.7` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.1.7` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm. | |
| 32 | +then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.2.1` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.2.1` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm. | |
| 31 | 33 | |
| 32 | 34 | ## Steps |
| 33 | 35 | |
| @@ -39,9 +41,9 @@ From the repository root: | ||
| 39 | 41 | ./docker-sbx/build.sh |
| 40 | 42 | ``` |
| 41 | 43 | |
| 42 | -This reads mm's tag from `release.env` (`v0.1.7`) and builds `k33g/mm-sandbox:0.1.7`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.1.7`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`. | |
| 44 | +This reads mm's tag from `release.env` (`v0.2.1`) and builds `k33g/mm-sandbox:0.2.1`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.2.1`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`. | |
| 43 | 45 | |
| 44 | -The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.1.7`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.1.7.tar`, to load there with `sbx template load`. | |
| 46 | +The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.2.1`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.2.1.tar`, to load there with `sbx template load`. | |
| 45 | 47 | |
| 46 | 48 | ### 2. Window mode in the terminal (kit `mm-tui`) |
| 47 | 49 | |
| @@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 62 | 64 | | `--kit-arg` | Default | Effect | |
| 63 | 65 | |---|---|---| |
| 64 | 66 | | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. | |
| 65 | -| `tag=<version>` | the version last built (`0.1.7`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. | | |
| 67 | +| `tag=<version>` | the version last built (`0.2.1`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. | | |
| 66 | 68 | |
| 67 | 69 | The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox. |
| 68 | 70 | |
| @@ -118,10 +120,10 @@ Publishing is a manual step, from a machine with Docker Desktop (buildx and the | ||
| 118 | 120 | ```bash |
| 119 | 121 | export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner |
| 120 | 122 | export DOCKER_PAT=dckr_pat_… # an access token with read/write scope |
| 121 | -./docker-sbx/publish.sh # TAG from release.env: v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7 | |
| 123 | +./docker-sbx/publish.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1 | |
| 122 | 124 | ``` |
| 123 | 125 | |
| 124 | -With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.1.7` (image) and `./docker-sbx/push-kits.sh v0.1.7` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account. | |
| 126 | +With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.2.1` (image) and `./docker-sbx/push-kits.sh v0.2.1` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account. | |
| 125 | 127 | |
| 126 | 128 | ## MCP servers through the sbx gateway (GitHub as the example) |
| 127 | 129 | |
| @@ -175,5 +177,6 @@ Name the repository in your requests, for example "list the open issues of k33g/ | ||
| 175 | 177 | ## See also |
| 176 | 178 | |
| 177 | 179 | - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources. |
| 180 | +- The same kits for the kit specification v3: [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md). | |
| 178 | 181 | - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md). |
| 179 | 182 | - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md). |
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine. | 3 | This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine. |
| 4 | 4 | ||
| 5 | +> These are the **v2** kits (`spec.yaml`). The same two kits also exist for the kit specification v3, under `docker-sbx-v3/`: see [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md). | ||
| 6 | + | ||
| 5 | Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository: | 7 | Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository: |
| 6 | 8 | ||
| 7 | | Piece | What it is | | 9 | | Piece | What it is | |
| @@ -14,20 +16,20 @@ Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the rep | |||
| 14 | 16 | ||
| 15 | ## Use the published kits | 17 | ## Use the published kits |
| 16 | 18 | ||
| 17 | -Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`: | 19 | +Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`: |
| 18 | 20 | ||
| 19 | ```bash | 21 | ```bash |
| 20 | cd /path/to/your/project | 22 | cd /path/to/your/project |
| 21 | -sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml | 23 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml |
| 22 | ``` | 24 | ``` |
| 23 | 25 | ||
| 24 | for the window mode, and for an editor: | 26 | for the window mode, and for an editor: |
| 25 | 27 | ||
| 26 | ```bash | 28 | ```bash |
| 27 | -sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml | 29 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml |
| 28 | ``` | 30 | ``` |
| 29 | 31 | ||
| 30 | -then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.1.7` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.1.7` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm. | 32 | +then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.2.1` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.2.1` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm. |
| 31 | 33 | ||
| 32 | ## Steps | 34 | ## Steps |
| 33 | 35 | ||
| @@ -39,9 +41,9 @@ From the repository root: | |||
| 39 | ./docker-sbx/build.sh | 41 | ./docker-sbx/build.sh |
| 40 | ``` | 42 | ``` |
| 41 | 43 | ||
| 42 | -This reads mm's tag from `release.env` (`v0.1.7`) and builds `k33g/mm-sandbox:0.1.7`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.1.7`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`. | 44 | +This reads mm's tag from `release.env` (`v0.2.1`) and builds `k33g/mm-sandbox:0.2.1`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.2.1`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`. |
| 43 | 45 | ||
| 44 | -The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.1.7`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.1.7.tar`, to load there with `sbx template load`. | 46 | +The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.2.1`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.2.1.tar`, to load there with `sbx template load`. |
| 45 | 47 | ||
| 46 | ### 2. Window mode in the terminal (kit `mm-tui`) | 48 | ### 2. Window mode in the terminal (kit `mm-tui`) |
| 47 | 49 | ||
| @@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |||
| 62 | | `--kit-arg` | Default | Effect | | 64 | | `--kit-arg` | Default | Effect | |
| 63 | |---|---|---| | 65 | |---|---|---| |
| 64 | | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. | | 66 | | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. | |
| 65 | -| `tag=<version>` | the version last built (`0.1.7`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. | | 67 | +| `tag=<version>` | the version last built (`0.2.1`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. | |
| 66 | 68 | ||
| 67 | The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox. | 69 | The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox. |
| 68 | 70 | ||
| @@ -118,10 +120,10 @@ Publishing is a manual step, from a machine with Docker Desktop (buildx and the | |||
| 118 | ```bash | 120 | ```bash |
| 119 | export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner | 121 | export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner |
| 120 | export DOCKER_PAT=dckr_pat_… # an access token with read/write scope | 122 | export DOCKER_PAT=dckr_pat_… # an access token with read/write scope |
| 121 | -./docker-sbx/publish.sh # TAG from release.env: v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7 | 123 | +./docker-sbx/publish.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1 |
| 122 | ``` | 124 | ``` |
| 123 | 125 | ||
| 124 | -With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.1.7` (image) and `./docker-sbx/push-kits.sh v0.1.7` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account. | 126 | +With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.2.1` (image) and `./docker-sbx/push-kits.sh v0.2.1` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account. |
| 125 | 127 | ||
| 126 | ## MCP servers through the sbx gateway (GitHub as the example) | 128 | ## MCP servers through the sbx gateway (GitHub as the example) |
| 127 | 129 | ||
| @@ -175,5 +177,6 @@ Name the repository in your requests, for example "list the open issues of k33g/ | |||
| 175 | ## See also | 177 | ## See also |
| 176 | 178 | ||
| 177 | - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources. | 179 | - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources. |
| 180 | +- The same kits for the kit specification v3: [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md). | ||
| 178 | - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md). | 181 | - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md). |
| 179 | - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md). | 182 | - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md). |
added
docs/en/how-to/run-with-sandbox-kits-v3.md +111 -0 | new file mode 100644 | ||
| @@ -0,0 +1,111 @@ | ||
| 1 | +# How to run mini-me with the v3 sandbox kits | |
| 2 | + | |
| 3 | +This guide shows how to run `mm` in a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) with the kits written for the [kit specification v3](https://github.com/docker/sandbox-kit-spec), under [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). They do the same job as the v2 kits of [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md) — the window mode with `mm-tui`, an editor with `mm-acp` — and the v2 kits keep working beside them. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine. | |
| 4 | + | |
| 5 | +> **Status.** The v3 kits build with the `docker/sandbox-kit:3` frontend and pass the specification's conformance check (`kit-tck validate`), but they have not yet been run with `sbx`, and they are not published yet. The kit specification itself is still marked experimental. | |
| 6 | + | |
| 7 | +| Piece | What it is | | |
| 8 | +|---|---| | |
| 9 | +| `template/Dockerfile` | The **template** image, `k33g/mm-sandbox:<version>` — the same image as v2. | | |
| 10 | +| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | The window-mode kit: a descriptor (declarations) and a Dockerfile (content: `FROM` the template, `ENTRYPOINT ["mm-tui"]`). | | |
| 11 | +| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | The editor kit, same shape, `ENTRYPOINT ["mm-acp-info"]`. | | |
| 12 | +| `build.sh`, `sync-kits.sh` | Build the template, and point the kits at it. | | |
| 13 | +| `check-kits.sh` | Builds the kits locally and checks them, with no `sbx` and no push. | | |
| 14 | +| `push-kits.sh`, `publish.sh` | Publish the kits (and the template) to Docker Hub with `docker buildx`. | | |
| 15 | + | |
| 16 | +## Before you start: two differences with v2 | |
| 17 | + | |
| 18 | +- **The template image must be on a registry.** A v3 kit is *built* on top of the template. When you run a kit from its directory, `sbx` builds it in its builder sandbox, and that sandbox's Docker engine pulls the template from the registry. An image that exists only in your local image store is not enough, and `--pull never` or `sbx template load` do not help. `k33g/mm-sandbox:0.2.1` is already on Docker Hub; for another version, push it first (step 1). | |
| 19 | +- **The workspace is `/home/agent/workspace`.** The template's base image declares that working directory, and a v3 agent workload (`sbx@1`) is mounted there. Give `config` a path relative to the workspace (`agent.dmr.yaml`, `demo/agent.dmr.yaml`); an absolute path of your Mac (`/Users/…`) does not exist inside the sandbox. | |
| 20 | + | |
| 21 | +## Steps | |
| 22 | + | |
| 23 | +### 1. Make the template available | |
| 24 | + | |
| 25 | +For the version in `release.env` (`v0.2.1`), nothing to do: `k33g/mm-sandbox:0.2.1` is on Docker Hub. For a work-in-progress `mm`, build and push the template from the repository root: | |
| 26 | + | |
| 27 | +```bash | |
| 28 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.2 | |
| 29 | +``` | |
| 30 | + | |
| 31 | +The script builds `k33g/mm-sandbox:0.2.2` for linux/amd64 and linux/arm64, pushes it, then rewrites the kits' `image` and `tag` defaults so they name that image. `IMAGE_OWNER=<handle>` pushes under your own account instead. | |
| 32 | + | |
| 33 | +### 2. Check the kits (optional) | |
| 34 | + | |
| 35 | +```bash | |
| 36 | +./docker-sbx-v3/check-kits.sh | |
| 37 | +``` | |
| 38 | + | |
| 39 | +Each kit is built with `docker buildx build -f <kit>.yaml`, which runs the kit frontend: it refuses an unknown key or an argument that does not match its pattern. The result goes to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (`go build ./cmd/kit-tck` in a clone of the specification), the script also runs the conformance check and prints `✓ conforms`. | |
| 40 | + | |
| 41 | +### 3. Window mode in the terminal (kit `mm-tui`) | |
| 42 | + | |
| 43 | +From the project you want `mm` to work on: | |
| 44 | + | |
| 45 | +```bash | |
| 46 | +cd /path/to/your/project | |
| 47 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 48 | +``` | |
| 49 | + | |
| 50 | +The first run builds the kit (a few seconds: one layer over the template), creates the sandbox, mounts the current directory and runs `mm -tui agent.dmr.yaml`. What follows `--` is `mm`'s own command line. Without it, `mm` reads the kit's `config` argument, then `./agent.yaml`, then its built-in defaults: | |
| 51 | + | |
| 52 | +```bash | |
| 53 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |
| 54 | +``` | |
| 55 | + | |
| 56 | +### 4. From an editor (kit `mm-acp`) | |
| 57 | + | |
| 58 | +1. Create the sandbox once, from the project the editor will open: | |
| 59 | + | |
| 60 | + ```bash | |
| 61 | + cd /path/to/your/project | |
| 62 | + sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . \ | |
| 63 | + --kit-arg config=agent.dmr.yaml | |
| 64 | + ``` | |
| 65 | + | |
| 66 | +2. Register it in the editor. In Zed's `settings.json`: | |
| 67 | + | |
| 68 | + ```json | |
| 69 | + { | |
| 70 | + "agent_servers": { | |
| 71 | + "mini-me (sandbox)": { | |
| 72 | + "type": "custom", | |
| 73 | + "command": "sbx", | |
| 74 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | |
| 75 | + } | |
| 76 | + } | |
| 77 | + } | |
| 78 | + ``` | |
| 79 | + | |
| 80 | +3. Open the agent panel and pick **mini-me (sandbox)**. As with v2, the editor runs `sbx exec -i`, because an ACP client needs raw stdin and stdout and `sbx run` always allocates a terminal. `sbx run --name mm-acp` prints this wiring and opens a shell. | |
| 81 | + | |
| 82 | +### 5. Once the kits are published | |
| 83 | + | |
| 84 | +After `./docker-sbx-v3/publish.sh` (or `push-kits.sh`) has run for a version, the kits are ordinary images on Docker Hub, and no directory is needed: | |
| 85 | + | |
| 86 | +```bash | |
| 87 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 88 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 89 | +``` | |
| 90 | + | |
| 91 | +The repositories are `sbx-kit-<kit>`, not the v2 `k33g/mm-tui` / `k33g/mm-acp`, so that publishing a v3 kit never replaces a v2 one. | |
| 92 | + | |
| 93 | +## Kit arguments | |
| 94 | + | |
| 95 | +| `--kit-arg` | Default | When it applies | Effect | | |
| 96 | +|---|---|---|---| | |
| 97 | +| `config=<path>` | empty | at `sbx run` / `sbx create` | `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. | | |
| 98 | +| `tag=<version>` | mm's version (`0.2.1`) | when the kit is built | Which template tag the kit is built on; also the kit's version. No `v`. | | |
| 99 | +| `image=<repository>` | `k33g/mm-sandbox` | when the kit is built | Which template repository the kit is built on. | | |
| 100 | + | |
| 101 | +`tag` and `image` are build-phase arguments: they are fixed in a published kit, which always names the image it was built on. To use another `mm` version, take the kit of that version. | |
| 102 | + | |
| 103 | +## The model server stays on the host | |
| 104 | + | |
| 105 | +Unchanged from v2: Docker Model Runner and llama-server run on your machine and are reached through `host.docker.internal`. `agent.dmr.yaml` already falls back to it; for llama-server see [the v2 guide](run-in-a-docker-sandbox.md#the-model-server-stays-on-the-host). Both kits allow ports 12434 and 8080 on the host; for another port, `sbx policy allow network host.docker.internal:<port>`. | |
| 106 | + | |
| 107 | +## See also | |
| 108 | + | |
| 109 | +- What changed from the v2 kits, field by field: [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md). | |
| 110 | +- The v2 kits, the MCP gateway and the editor variants: [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md). | |
| 111 | +- The kit format: [specification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md). | |
| new file mode 100644 | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | +# How to run mini-me with the v3 sandbox kits | ||
| 2 | + | ||
| 3 | +This guide shows how to run `mm` in a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) with the kits written for the [kit specification v3](https://github.com/docker/sandbox-kit-spec), under [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). They do the same job as the v2 kits of [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md) — the window mode with `mm-tui`, an editor with `mm-acp` — and the v2 kits keep working beside them. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine. | ||
| 4 | + | ||
| 5 | +> **Status.** The v3 kits build with the `docker/sandbox-kit:3` frontend and pass the specification's conformance check (`kit-tck validate`), but they have not yet been run with `sbx`, and they are not published yet. The kit specification itself is still marked experimental. | ||
| 6 | + | ||
| 7 | +| Piece | What it is | | ||
| 8 | +|---|---| | ||
| 9 | +| `template/Dockerfile` | The **template** image, `k33g/mm-sandbox:<version>` — the same image as v2. | | ||
| 10 | +| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | The window-mode kit: a descriptor (declarations) and a Dockerfile (content: `FROM` the template, `ENTRYPOINT ["mm-tui"]`). | | ||
| 11 | +| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | The editor kit, same shape, `ENTRYPOINT ["mm-acp-info"]`. | | ||
| 12 | +| `build.sh`, `sync-kits.sh` | Build the template, and point the kits at it. | | ||
| 13 | +| `check-kits.sh` | Builds the kits locally and checks them, with no `sbx` and no push. | | ||
| 14 | +| `push-kits.sh`, `publish.sh` | Publish the kits (and the template) to Docker Hub with `docker buildx`. | | ||
| 15 | + | ||
| 16 | +## Before you start: two differences with v2 | ||
| 17 | + | ||
| 18 | +- **The template image must be on a registry.** A v3 kit is *built* on top of the template. When you run a kit from its directory, `sbx` builds it in its builder sandbox, and that sandbox's Docker engine pulls the template from the registry. An image that exists only in your local image store is not enough, and `--pull never` or `sbx template load` do not help. `k33g/mm-sandbox:0.2.1` is already on Docker Hub; for another version, push it first (step 1). | ||
| 19 | +- **The workspace is `/home/agent/workspace`.** The template's base image declares that working directory, and a v3 agent workload (`sbx@1`) is mounted there. Give `config` a path relative to the workspace (`agent.dmr.yaml`, `demo/agent.dmr.yaml`); an absolute path of your Mac (`/Users/…`) does not exist inside the sandbox. | ||
| 20 | + | ||
| 21 | +## Steps | ||
| 22 | + | ||
| 23 | +### 1. Make the template available | ||
| 24 | + | ||
| 25 | +For the version in `release.env` (`v0.2.1`), nothing to do: `k33g/mm-sandbox:0.2.1` is on Docker Hub. For a work-in-progress `mm`, build and push the template from the repository root: | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.2 | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +The script builds `k33g/mm-sandbox:0.2.2` for linux/amd64 and linux/arm64, pushes it, then rewrites the kits' `image` and `tag` defaults so they name that image. `IMAGE_OWNER=<handle>` pushes under your own account instead. | ||
| 32 | + | ||
| 33 | +### 2. Check the kits (optional) | ||
| 34 | + | ||
| 35 | +```bash | ||
| 36 | +./docker-sbx-v3/check-kits.sh | ||
| 37 | +``` | ||
| 38 | + | ||
| 39 | +Each kit is built with `docker buildx build -f <kit>.yaml`, which runs the kit frontend: it refuses an unknown key or an argument that does not match its pattern. The result goes to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (`go build ./cmd/kit-tck` in a clone of the specification), the script also runs the conformance check and prints `✓ conforms`. | ||
| 40 | + | ||
| 41 | +### 3. Window mode in the terminal (kit `mm-tui`) | ||
| 42 | + | ||
| 43 | +From the project you want `mm` to work on: | ||
| 44 | + | ||
| 45 | +```bash | ||
| 46 | +cd /path/to/your/project | ||
| 47 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 48 | +``` | ||
| 49 | + | ||
| 50 | +The first run builds the kit (a few seconds: one layer over the template), creates the sandbox, mounts the current directory and runs `mm -tui agent.dmr.yaml`. What follows `--` is `mm`'s own command line. Without it, `mm` reads the kit's `config` argument, then `./agent.yaml`, then its built-in defaults: | ||
| 51 | + | ||
| 52 | +```bash | ||
| 53 | +sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 54 | +``` | ||
| 55 | + | ||
| 56 | +### 4. From an editor (kit `mm-acp`) | ||
| 57 | + | ||
| 58 | +1. Create the sandbox once, from the project the editor will open: | ||
| 59 | + | ||
| 60 | + ```bash | ||
| 61 | + cd /path/to/your/project | ||
| 62 | + sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . \ | ||
| 63 | + --kit-arg config=agent.dmr.yaml | ||
| 64 | + ``` | ||
| 65 | + | ||
| 66 | +2. Register it in the editor. In Zed's `settings.json`: | ||
| 67 | + | ||
| 68 | + ```json | ||
| 69 | + { | ||
| 70 | + "agent_servers": { | ||
| 71 | + "mini-me (sandbox)": { | ||
| 72 | + "type": "custom", | ||
| 73 | + "command": "sbx", | ||
| 74 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + ``` | ||
| 79 | + | ||
| 80 | +3. Open the agent panel and pick **mini-me (sandbox)**. As with v2, the editor runs `sbx exec -i`, because an ACP client needs raw stdin and stdout and `sbx run` always allocates a terminal. `sbx run --name mm-acp` prints this wiring and opens a shell. | ||
| 81 | + | ||
| 82 | +### 5. Once the kits are published | ||
| 83 | + | ||
| 84 | +After `./docker-sbx-v3/publish.sh` (or `push-kits.sh`) has run for a version, the kits are ordinary images on Docker Hub, and no directory is needed: | ||
| 85 | + | ||
| 86 | +```bash | ||
| 87 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | ||
| 88 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | ||
| 89 | +``` | ||
| 90 | + | ||
| 91 | +The repositories are `sbx-kit-<kit>`, not the v2 `k33g/mm-tui` / `k33g/mm-acp`, so that publishing a v3 kit never replaces a v2 one. | ||
| 92 | + | ||
| 93 | +## Kit arguments | ||
| 94 | + | ||
| 95 | +| `--kit-arg` | Default | When it applies | Effect | | ||
| 96 | +|---|---|---|---| | ||
| 97 | +| `config=<path>` | empty | at `sbx run` / `sbx create` | `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. | | ||
| 98 | +| `tag=<version>` | mm's version (`0.2.1`) | when the kit is built | Which template tag the kit is built on; also the kit's version. No `v`. | | ||
| 99 | +| `image=<repository>` | `k33g/mm-sandbox` | when the kit is built | Which template repository the kit is built on. | | ||
| 100 | + | ||
| 101 | +`tag` and `image` are build-phase arguments: they are fixed in a published kit, which always names the image it was built on. To use another `mm` version, take the kit of that version. | ||
| 102 | + | ||
| 103 | +## The model server stays on the host | ||
| 104 | + | ||
| 105 | +Unchanged from v2: Docker Model Runner and llama-server run on your machine and are reached through `host.docker.internal`. `agent.dmr.yaml` already falls back to it; for llama-server see [the v2 guide](run-in-a-docker-sandbox.md#the-model-server-stays-on-the-host). Both kits allow ports 12434 and 8080 on the host; for another port, `sbx policy allow network host.docker.internal:<port>`. | ||
| 106 | + | ||
| 107 | +## See also | ||
| 108 | + | ||
| 109 | +- What changed from the v2 kits, field by field: [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md). | ||
| 110 | +- The v2 kits, the MCP gateway and the editor variants: [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md). | ||
| 111 | +- The kit format: [specification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md). | ||
modified
docs/fr/README.md +1 -0 | @@ -13,6 +13,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https: | ||
| 13 | 13 | - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md) |
| 14 | 14 | - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md) |
| 15 | 15 | - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur |
| 16 | +- [Faire tourner mini-me avec les kits sandbox v3](how-to/run-with-sandbox-kits-v3.md) — les deux mêmes kits pour la spécification de kit v3, sous `docker-sbx-v3/` | |
| 16 | 17 | - [Ajouter un skill](how-to/add-a-skill.md) |
| 17 | 18 | - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après |
| 18 | 19 | - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md) |
| @@ -13,6 +13,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https: | |||
| 13 | - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md) | 13 | - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md) |
| 14 | - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md) | 14 | - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md) |
| 15 | - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur | 15 | - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur |
| 16 | +- [Faire tourner mini-me avec les kits sandbox v3](how-to/run-with-sandbox-kits-v3.md) — les deux mêmes kits pour la spécification de kit v3, sous `docker-sbx-v3/` | ||
| 16 | - [Ajouter un skill](how-to/add-a-skill.md) | 17 | - [Ajouter un skill](how-to/add-a-skill.md) |
| 17 | - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après | 18 | - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après |
| 18 | - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md) | 19 | - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md) |
modified
docs/fr/how-to/run-in-a-docker-sandbox.md +12 -9 | @@ -2,6 +2,8 @@ | ||
| 2 | 2 | |
| 3 | 3 | Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine. |
| 4 | 4 | |
| 5 | +> Ce sont les kits **v2** (`spec.yaml`). Les deux mêmes kits existent aussi pour la spécification de kit v3, sous `docker-sbx-v3/` : voir [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md). | |
| 6 | + | |
| 5 | 7 | Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt : |
| 6 | 8 | |
| 7 | 9 | | Élément | Ce que c'est | |
| @@ -14,20 +16,20 @@ Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt : | ||
| 14 | 16 | |
| 15 | 17 | ## Utiliser les kits publiés |
| 16 | 18 | |
| 17 | -Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` : | |
| 19 | +Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` : | |
| 18 | 20 | |
| 19 | 21 | ```bash |
| 20 | 22 | cd /chemin/de/votre/projet |
| 21 | -sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml | |
| 23 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 22 | 24 | ``` |
| 23 | 25 | |
| 24 | 26 | pour le mode fenêtre, et pour un éditeur : |
| 25 | 27 | |
| 26 | 28 | ```bash |
| 27 | -sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml | |
| 29 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 28 | 30 | ``` |
| 29 | 31 | |
| 30 | -puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.1.7` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.1.7` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail. | |
| 32 | +puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.2.1` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.2.1` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail. | |
| 31 | 33 | |
| 32 | 34 | ## Étapes |
| 33 | 35 | |
| @@ -39,9 +41,9 @@ Depuis la racine du dépôt : | ||
| 39 | 41 | ./docker-sbx/build.sh |
| 40 | 42 | ``` |
| 41 | 43 | |
| 42 | -Cela lit le tag de mm dans `release.env` (`v0.1.7`) et construit `k33g/mm-sandbox:0.1.7` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.1.7`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`. | |
| 44 | +Cela lit le tag de mm dans `release.env` (`v0.2.1`) et construit `k33g/mm-sandbox:0.2.1` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.2.1`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`. | |
| 43 | 45 | |
| 44 | -L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.1.7`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.1.7.tar`, à charger là-bas avec `sbx template load`. | |
| 46 | +L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.2.1`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.2.1.tar`, à charger là-bas avec `sbx template load`. | |
| 45 | 47 | |
| 46 | 48 | ### 2. Mode fenêtre dans le terminal (kit `mm-tui`) |
| 47 | 49 | |
| @@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 62 | 64 | | `--kit-arg` | Défaut | Effet | |
| 63 | 65 | |---|---|---| |
| 64 | 66 | | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. | |
| 65 | -| `tag=<version>` | la dernière version construite (`0.1.7`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. | | |
| 67 | +| `tag=<version>` | la dernière version construite (`0.2.1`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. | | |
| 66 | 68 | |
| 67 | 69 | Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox. |
| 68 | 70 | |
| @@ -118,10 +120,10 @@ La publication est une étape manuelle, depuis une machine avec Docker Desktop ( | ||
| 118 | 120 | ```bash |
| 119 | 121 | export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image |
| 120 | 122 | export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture |
| 121 | -./docker-sbx/publish.sh # TAG depuis release.env : v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7 | |
| 123 | +./docker-sbx/publish.sh # TAG depuis release.env : v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1 | |
| 122 | 124 | ``` |
| 123 | 125 | |
| 124 | -Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.1.7` (l'image) et `./docker-sbx/push-kits.sh v0.1.7` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte. | |
| 126 | +Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.2.1` (l'image) et `./docker-sbx/push-kits.sh v0.2.1` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte. | |
| 125 | 127 | |
| 126 | 128 | ## Serveurs MCP via la passerelle sbx (exemple : GitHub) |
| 127 | 129 | |
| @@ -175,5 +177,6 @@ Nommez le dépôt dans vos demandes, par exemple « liste les issues ouvertes de | ||
| 175 | 177 | ## Voir aussi |
| 176 | 178 | |
| 177 | 179 | - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`. |
| 180 | +- Les mêmes kits pour la spécification de kit v3 : [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md). | |
| 178 | 181 | - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md). |
| 179 | 182 | - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md). |
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine. | 3 | Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine. |
| 4 | 4 | ||
| 5 | +> Ce sont les kits **v2** (`spec.yaml`). Les deux mêmes kits existent aussi pour la spécification de kit v3, sous `docker-sbx-v3/` : voir [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md). | ||
| 6 | + | ||
| 5 | Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt : | 7 | Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt : |
| 6 | 8 | ||
| 7 | | Élément | Ce que c'est | | 9 | | Élément | Ce que c'est | |
| @@ -14,20 +16,20 @@ Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt : | |||
| 14 | 16 | ||
| 15 | ## Utiliser les kits publiés | 17 | ## Utiliser les kits publiés |
| 16 | 18 | ||
| 17 | -Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` : | 19 | +Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` : |
| 18 | 20 | ||
| 19 | ```bash | 21 | ```bash |
| 20 | cd /chemin/de/votre/projet | 22 | cd /chemin/de/votre/projet |
| 21 | -sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml | 23 | +sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml |
| 22 | ``` | 24 | ``` |
| 23 | 25 | ||
| 24 | pour le mode fenêtre, et pour un éditeur : | 26 | pour le mode fenêtre, et pour un éditeur : |
| 25 | 27 | ||
| 26 | ```bash | 28 | ```bash |
| 27 | -sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml | 29 | +sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml |
| 28 | ``` | 30 | ``` |
| 29 | 31 | ||
| 30 | -puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.1.7` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.1.7` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail. | 32 | +puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.2.1` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.2.1` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail. |
| 31 | 33 | ||
| 32 | ## Étapes | 34 | ## Étapes |
| 33 | 35 | ||
| @@ -39,9 +41,9 @@ Depuis la racine du dépôt : | |||
| 39 | ./docker-sbx/build.sh | 41 | ./docker-sbx/build.sh |
| 40 | ``` | 42 | ``` |
| 41 | 43 | ||
| 42 | -Cela lit le tag de mm dans `release.env` (`v0.1.7`) et construit `k33g/mm-sandbox:0.1.7` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.1.7`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`. | 44 | +Cela lit le tag de mm dans `release.env` (`v0.2.1`) et construit `k33g/mm-sandbox:0.2.1` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.2.1`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`. |
| 43 | 45 | ||
| 44 | -L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.1.7`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.1.7.tar`, à charger là-bas avec `sbx template load`. | 46 | +L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.2.1`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.2.1.tar`, à charger là-bas avec `sbx template load`. |
| 45 | 47 | ||
| 46 | ### 2. Mode fenêtre dans le terminal (kit `mm-tui`) | 48 | ### 2. Mode fenêtre dans le terminal (kit `mm-tui`) |
| 47 | 49 | ||
| @@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |||
| 62 | | `--kit-arg` | Défaut | Effet | | 64 | | `--kit-arg` | Défaut | Effet | |
| 63 | |---|---|---| | 65 | |---|---|---| |
| 64 | | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. | | 66 | | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. | |
| 65 | -| `tag=<version>` | la dernière version construite (`0.1.7`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. | | 67 | +| `tag=<version>` | la dernière version construite (`0.2.1`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. | |
| 66 | 68 | ||
| 67 | Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox. | 69 | Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox. |
| 68 | 70 | ||
| @@ -118,10 +120,10 @@ La publication est une étape manuelle, depuis une machine avec Docker Desktop ( | |||
| 118 | ```bash | 120 | ```bash |
| 119 | export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image | 121 | export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image |
| 120 | export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture | 122 | export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture |
| 121 | -./docker-sbx/publish.sh # TAG depuis release.env : v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7 | 123 | +./docker-sbx/publish.sh # TAG depuis release.env : v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1 |
| 122 | ``` | 124 | ``` |
| 123 | 125 | ||
| 124 | -Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.1.7` (l'image) et `./docker-sbx/push-kits.sh v0.1.7` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte. | 126 | +Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.2.1` (l'image) et `./docker-sbx/push-kits.sh v0.2.1` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte. |
| 125 | 127 | ||
| 126 | ## Serveurs MCP via la passerelle sbx (exemple : GitHub) | 128 | ## Serveurs MCP via la passerelle sbx (exemple : GitHub) |
| 127 | 129 | ||
| @@ -175,5 +177,6 @@ Nommez le dépôt dans vos demandes, par exemple « liste les issues ouvertes de | |||
| 175 | ## Voir aussi | 177 | ## Voir aussi |
| 176 | 178 | ||
| 177 | - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`. | 179 | - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`. |
| 180 | +- Les mêmes kits pour la spécification de kit v3 : [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md). | ||
| 178 | - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md). | 181 | - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md). |
| 179 | - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md). | 182 | - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md). |
added
docs/fr/how-to/run-with-sandbox-kits-v3.md +111 -0 | new file mode 100644 | ||
| @@ -0,0 +1,111 @@ | ||
| 1 | +# Faire tourner mini-me avec les kits sandbox v3 | |
| 2 | + | |
| 3 | +Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) avec les kits écrits pour la [spécification de kit v3](https://github.com/docker/sandbox-kit-spec), sous [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). Ils font le même travail que les kits v2 de [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md) — le mode fenêtre avec `mm-tui`, un éditeur avec `mm-acp` — et les kits v2 continuent de fonctionner à côté. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine. | |
| 4 | + | |
| 5 | +> **État.** Les kits v3 se construisent avec le frontend `docker/sandbox-kit:3` et passent le contrôle de conformité de la spécification (`kit-tck validate`), mais ils n'ont pas encore été lancés avec `sbx`, et ne sont pas encore publiés. La spécification de kit elle-même est encore marquée expérimentale. | |
| 6 | + | |
| 7 | +| Élément | Ce que c'est | | |
| 8 | +|---|---| | |
| 9 | +| `template/Dockerfile` | L'image **template**, `k33g/mm-sandbox:<version>` — la même image qu'en v2. | | |
| 10 | +| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | Le kit du mode fenêtre : un descripteur (les déclarations) et un Dockerfile (le contenu : `FROM` le template, `ENTRYPOINT ["mm-tui"]`). | | |
| 11 | +| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | Le kit pour un éditeur, même forme, `ENTRYPOINT ["mm-acp-info"]`. | | |
| 12 | +| `build.sh`, `sync-kits.sh` | Construisent le template, et alignent les kits dessus. | | |
| 13 | +| `check-kits.sh` | Construit les kits en local et les vérifie, sans `sbx` et sans push. | | |
| 14 | +| `push-kits.sh`, `publish.sh` | Publient les kits (et le template) sur Docker Hub avec `docker buildx`. | | |
| 15 | + | |
| 16 | +## Avant de commencer : deux différences avec la v2 | |
| 17 | + | |
| 18 | +- **L'image template doit être sur un registre.** Un kit v3 est *construit* au-dessus du template. Quand vous lancez un kit depuis son dossier, `sbx` le construit dans son sandbox de build, dont le moteur Docker télécharge le template depuis le registre. Une image présente seulement dans votre stockage local ne suffit pas, et `--pull never` ou `sbx template load` n'y changent rien. `k33g/mm-sandbox:0.2.1` est déjà sur Docker Hub ; pour une autre version, poussez-la d'abord (étape 1). | |
| 19 | +- **L'espace de travail est `/home/agent/workspace`.** L'image de base du template déclare ce répertoire de travail, et un workload d'agent v3 (`sbx@1`) y est monté. Donnez à `config` un chemin relatif à l'espace de travail (`agent.dmr.yaml`, `demo/agent.dmr.yaml`) ; un chemin absolu de votre Mac (`/Users/…`) n'existe pas dans le sandbox. | |
| 20 | + | |
| 21 | +## Étapes | |
| 22 | + | |
| 23 | +### 1. Rendre le template disponible | |
| 24 | + | |
| 25 | +Pour la version de `release.env` (`v0.2.1`), rien à faire : `k33g/mm-sandbox:0.2.1` est sur Docker Hub. Pour un `mm` en cours de travail, construisez et poussez le template depuis la racine du dépôt : | |
| 26 | + | |
| 27 | +```bash | |
| 28 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.2 | |
| 29 | +``` | |
| 30 | + | |
| 31 | +Le script construit `k33g/mm-sandbox:0.2.2` pour linux/amd64 et linux/arm64, la pousse, puis réécrit les valeurs par défaut `image` et `tag` des kits pour qu'ils nomment cette image. `IMAGE_OWNER=<compte>` la pousse sous votre propre compte. | |
| 32 | + | |
| 33 | +### 2. Vérifier les kits (facultatif) | |
| 34 | + | |
| 35 | +```bash | |
| 36 | +./docker-sbx-v3/check-kits.sh | |
| 37 | +``` | |
| 38 | + | |
| 39 | +Chaque kit est construit avec `docker buildx build -f <kit>.yaml`, qui passe par le frontend des kits : il refuse une clé inconnue ou un argument qui ne respecte pas son motif. Le résultat va dans `tmp/kits-v3/<kit>/`. Avec [`kit-tck`](https://github.com/docker/sandbox-kit-spec) dans le `PATH` (`go build ./cmd/kit-tck` dans un clone de la spécification), le script lance aussi le contrôle de conformité et affiche `✓ conforms`. | |
| 40 | + | |
| 41 | +### 3. Mode fenêtre dans le terminal (kit `mm-tui`) | |
| 42 | + | |
| 43 | +Depuis le projet sur lequel `mm` doit travailler : | |
| 44 | + | |
| 45 | +```bash | |
| 46 | +cd /chemin/de/votre/projet | |
| 47 | +sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | |
| 48 | +``` | |
| 49 | + | |
| 50 | +Le premier lancement construit le kit (quelques secondes : une couche au-dessus du template), crée le sandbox, monte le répertoire courant et lance `mm -tui agent.dmr.yaml`. Ce qui suit `--` est la ligne de commande de `mm`. Sans rien après `--`, `mm` lit l'argument `config` du kit, puis `./agent.yaml`, puis ses valeurs par défaut : | |
| 51 | + | |
| 52 | +```bash | |
| 53 | +sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | |
| 54 | +``` | |
| 55 | + | |
| 56 | +### 4. Depuis un éditeur (kit `mm-acp`) | |
| 57 | + | |
| 58 | +1. Créez le sandbox une fois, depuis le projet que l'éditeur ouvrira : | |
| 59 | + | |
| 60 | + ```bash | |
| 61 | + cd /chemin/de/votre/projet | |
| 62 | + sbx create --name mm-acp /chemin/de/mini-me/docker-sbx-v3/kits/mm-acp . \ | |
| 63 | + --kit-arg config=agent.dmr.yaml | |
| 64 | + ``` | |
| 65 | + | |
| 66 | +2. Déclarez-le dans l'éditeur. Dans le `settings.json` de Zed : | |
| 67 | + | |
| 68 | + ```json | |
| 69 | + { | |
| 70 | + "agent_servers": { | |
| 71 | + "mini-me (sandbox)": { | |
| 72 | + "type": "custom", | |
| 73 | + "command": "sbx", | |
| 74 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | |
| 75 | + } | |
| 76 | + } | |
| 77 | + } | |
| 78 | + ``` | |
| 79 | + | |
| 80 | +3. Ouvrez le panneau d'agent et choisissez **mini-me (sandbox)**. Comme en v2, l'éditeur passe par `sbx exec -i`, parce qu'un client ACP a besoin de stdin et stdout bruts et que `sbx run` alloue toujours un terminal. `sbx run --name mm-acp` affiche ce branchement et ouvre un shell. | |
| 81 | + | |
| 82 | +### 5. Une fois les kits publiés | |
| 83 | + | |
| 84 | +Après `./docker-sbx-v3/publish.sh` (ou `push-kits.sh`) pour une version, les kits sont des images ordinaires sur Docker Hub, et aucun dossier n'est nécessaire : | |
| 85 | + | |
| 86 | +```bash | |
| 87 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | |
| 88 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | |
| 89 | +``` | |
| 90 | + | |
| 91 | +Les dépôts sont `sbx-kit-<kit>`, pas les `k33g/mm-tui` / `k33g/mm-acp` de la v2 : publier un kit v3 ne remplace jamais un kit v2. | |
| 92 | + | |
| 93 | +## Arguments des kits | |
| 94 | + | |
| 95 | +| `--kit-arg` | Défaut | Quand il s'applique | Effet | | |
| 96 | +|---|---|---|---| | |
| 97 | +| `config=<chemin>` | vide | à `sbx run` / `sbx create` | L'`AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. Vide : `./agent.yaml`, puis les valeurs par défaut. | | |
| 98 | +| `tag=<version>` | la version de mm (`0.2.1`) | à la construction du kit | Le tag du template sur lequel le kit est construit ; c'est aussi la version du kit. Sans `v`. | | |
| 99 | +| `image=<dépôt>` | `k33g/mm-sandbox` | à la construction du kit | Le dépôt du template sur lequel le kit est construit. | | |
| 100 | + | |
| 101 | +`tag` et `image` sont des arguments de construction : ils sont figés dans un kit publié, qui nomme toujours l'image sur laquelle il a été construit. Pour une autre version de `mm`, prenez le kit de cette version. | |
| 102 | + | |
| 103 | +## Le serveur de modèles reste sur l'hôte | |
| 104 | + | |
| 105 | +Rien ne change par rapport à la v2 : Docker Model Runner et llama-server tournent sur votre machine et sont joints par `host.docker.internal`. `agent.dmr.yaml` s'y replie déjà ; pour llama-server, voir [le guide v2](run-in-a-docker-sandbox.md#le-serveur-de-modèles-reste-sur-lhôte). Les deux kits autorisent les ports 12434 et 8080 de l'hôte ; pour un autre port, `sbx policy allow network host.docker.internal:<port>`. | |
| 106 | + | |
| 107 | +## Voir aussi | |
| 108 | + | |
| 109 | +- Ce qui change par rapport aux kits v2, champ par champ : [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md). | |
| 110 | +- Les kits v2, la passerelle MCP et les variantes pour éditeur : [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md). | |
| 111 | +- Le format des kits : [spécification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md). | |
| new file mode 100644 | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | +# Faire tourner mini-me avec les kits sandbox v3 | ||
| 2 | + | ||
| 3 | +Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) avec les kits écrits pour la [spécification de kit v3](https://github.com/docker/sandbox-kit-spec), sous [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). Ils font le même travail que les kits v2 de [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md) — le mode fenêtre avec `mm-tui`, un éditeur avec `mm-acp` — et les kits v2 continuent de fonctionner à côté. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine. | ||
| 4 | + | ||
| 5 | +> **État.** Les kits v3 se construisent avec le frontend `docker/sandbox-kit:3` et passent le contrôle de conformité de la spécification (`kit-tck validate`), mais ils n'ont pas encore été lancés avec `sbx`, et ne sont pas encore publiés. La spécification de kit elle-même est encore marquée expérimentale. | ||
| 6 | + | ||
| 7 | +| Élément | Ce que c'est | | ||
| 8 | +|---|---| | ||
| 9 | +| `template/Dockerfile` | L'image **template**, `k33g/mm-sandbox:<version>` — la même image qu'en v2. | | ||
| 10 | +| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | Le kit du mode fenêtre : un descripteur (les déclarations) et un Dockerfile (le contenu : `FROM` le template, `ENTRYPOINT ["mm-tui"]`). | | ||
| 11 | +| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | Le kit pour un éditeur, même forme, `ENTRYPOINT ["mm-acp-info"]`. | | ||
| 12 | +| `build.sh`, `sync-kits.sh` | Construisent le template, et alignent les kits dessus. | | ||
| 13 | +| `check-kits.sh` | Construit les kits en local et les vérifie, sans `sbx` et sans push. | | ||
| 14 | +| `push-kits.sh`, `publish.sh` | Publient les kits (et le template) sur Docker Hub avec `docker buildx`. | | ||
| 15 | + | ||
| 16 | +## Avant de commencer : deux différences avec la v2 | ||
| 17 | + | ||
| 18 | +- **L'image template doit être sur un registre.** Un kit v3 est *construit* au-dessus du template. Quand vous lancez un kit depuis son dossier, `sbx` le construit dans son sandbox de build, dont le moteur Docker télécharge le template depuis le registre. Une image présente seulement dans votre stockage local ne suffit pas, et `--pull never` ou `sbx template load` n'y changent rien. `k33g/mm-sandbox:0.2.1` est déjà sur Docker Hub ; pour une autre version, poussez-la d'abord (étape 1). | ||
| 19 | +- **L'espace de travail est `/home/agent/workspace`.** L'image de base du template déclare ce répertoire de travail, et un workload d'agent v3 (`sbx@1`) y est monté. Donnez à `config` un chemin relatif à l'espace de travail (`agent.dmr.yaml`, `demo/agent.dmr.yaml`) ; un chemin absolu de votre Mac (`/Users/…`) n'existe pas dans le sandbox. | ||
| 20 | + | ||
| 21 | +## Étapes | ||
| 22 | + | ||
| 23 | +### 1. Rendre le template disponible | ||
| 24 | + | ||
| 25 | +Pour la version de `release.env` (`v0.2.1`), rien à faire : `k33g/mm-sandbox:0.2.1` est sur Docker Hub. Pour un `mm` en cours de travail, construisez et poussez le template depuis la racine du dépôt : | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +PUSH=1 ./docker-sbx-v3/build.sh v0.2.2 | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +Le script construit `k33g/mm-sandbox:0.2.2` pour linux/amd64 et linux/arm64, la pousse, puis réécrit les valeurs par défaut `image` et `tag` des kits pour qu'ils nomment cette image. `IMAGE_OWNER=<compte>` la pousse sous votre propre compte. | ||
| 32 | + | ||
| 33 | +### 2. Vérifier les kits (facultatif) | ||
| 34 | + | ||
| 35 | +```bash | ||
| 36 | +./docker-sbx-v3/check-kits.sh | ||
| 37 | +``` | ||
| 38 | + | ||
| 39 | +Chaque kit est construit avec `docker buildx build -f <kit>.yaml`, qui passe par le frontend des kits : il refuse une clé inconnue ou un argument qui ne respecte pas son motif. Le résultat va dans `tmp/kits-v3/<kit>/`. Avec [`kit-tck`](https://github.com/docker/sandbox-kit-spec) dans le `PATH` (`go build ./cmd/kit-tck` dans un clone de la spécification), le script lance aussi le contrôle de conformité et affiche `✓ conforms`. | ||
| 40 | + | ||
| 41 | +### 3. Mode fenêtre dans le terminal (kit `mm-tui`) | ||
| 42 | + | ||
| 43 | +Depuis le projet sur lequel `mm` doit travailler : | ||
| 44 | + | ||
| 45 | +```bash | ||
| 46 | +cd /chemin/de/votre/projet | ||
| 47 | +sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml | ||
| 48 | +``` | ||
| 49 | + | ||
| 50 | +Le premier lancement construit le kit (quelques secondes : une couche au-dessus du template), crée le sandbox, monte le répertoire courant et lance `mm -tui agent.dmr.yaml`. Ce qui suit `--` est la ligne de commande de `mm`. Sans rien après `--`, `mm` lit l'argument `config` du kit, puis `./agent.yaml`, puis ses valeurs par défaut : | ||
| 51 | + | ||
| 52 | +```bash | ||
| 53 | +sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml | ||
| 54 | +``` | ||
| 55 | + | ||
| 56 | +### 4. Depuis un éditeur (kit `mm-acp`) | ||
| 57 | + | ||
| 58 | +1. Créez le sandbox une fois, depuis le projet que l'éditeur ouvrira : | ||
| 59 | + | ||
| 60 | + ```bash | ||
| 61 | + cd /chemin/de/votre/projet | ||
| 62 | + sbx create --name mm-acp /chemin/de/mini-me/docker-sbx-v3/kits/mm-acp . \ | ||
| 63 | + --kit-arg config=agent.dmr.yaml | ||
| 64 | + ``` | ||
| 65 | + | ||
| 66 | +2. Déclarez-le dans l'éditeur. Dans le `settings.json` de Zed : | ||
| 67 | + | ||
| 68 | + ```json | ||
| 69 | + { | ||
| 70 | + "agent_servers": { | ||
| 71 | + "mini-me (sandbox)": { | ||
| 72 | + "type": "custom", | ||
| 73 | + "command": "sbx", | ||
| 74 | + "args": ["exec", "-i", "mm-acp", "mm", "-acp"] | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + ``` | ||
| 79 | + | ||
| 80 | +3. Ouvrez le panneau d'agent et choisissez **mini-me (sandbox)**. Comme en v2, l'éditeur passe par `sbx exec -i`, parce qu'un client ACP a besoin de stdin et stdout bruts et que `sbx run` alloue toujours un terminal. `sbx run --name mm-acp` affiche ce branchement et ouvre un shell. | ||
| 81 | + | ||
| 82 | +### 5. Une fois les kits publiés | ||
| 83 | + | ||
| 84 | +Après `./docker-sbx-v3/publish.sh` (ou `push-kits.sh`) pour une version, les kits sont des images ordinaires sur Docker Hub, et aucun dossier n'est nécessaire : | ||
| 85 | + | ||
| 86 | +```bash | ||
| 87 | +sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml | ||
| 88 | +sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml | ||
| 89 | +``` | ||
| 90 | + | ||
| 91 | +Les dépôts sont `sbx-kit-<kit>`, pas les `k33g/mm-tui` / `k33g/mm-acp` de la v2 : publier un kit v3 ne remplace jamais un kit v2. | ||
| 92 | + | ||
| 93 | +## Arguments des kits | ||
| 94 | + | ||
| 95 | +| `--kit-arg` | Défaut | Quand il s'applique | Effet | | ||
| 96 | +|---|---|---|---| | ||
| 97 | +| `config=<chemin>` | vide | à `sbx run` / `sbx create` | L'`AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. Vide : `./agent.yaml`, puis les valeurs par défaut. | | ||
| 98 | +| `tag=<version>` | la version de mm (`0.2.1`) | à la construction du kit | Le tag du template sur lequel le kit est construit ; c'est aussi la version du kit. Sans `v`. | | ||
| 99 | +| `image=<dépôt>` | `k33g/mm-sandbox` | à la construction du kit | Le dépôt du template sur lequel le kit est construit. | | ||
| 100 | + | ||
| 101 | +`tag` et `image` sont des arguments de construction : ils sont figés dans un kit publié, qui nomme toujours l'image sur laquelle il a été construit. Pour une autre version de `mm`, prenez le kit de cette version. | ||
| 102 | + | ||
| 103 | +## Le serveur de modèles reste sur l'hôte | ||
| 104 | + | ||
| 105 | +Rien ne change par rapport à la v2 : Docker Model Runner et llama-server tournent sur votre machine et sont joints par `host.docker.internal`. `agent.dmr.yaml` s'y replie déjà ; pour llama-server, voir [le guide v2](run-in-a-docker-sandbox.md#le-serveur-de-modèles-reste-sur-lhôte). Les deux kits autorisent les ports 12434 et 8080 de l'hôte ; pour un autre port, `sbx policy allow network host.docker.internal:<port>`. | ||
| 106 | + | ||
| 107 | +## Voir aussi | ||
| 108 | + | ||
| 109 | +- Ce qui change par rapport aux kits v2, champ par champ : [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md). | ||
| 110 | +- Les kits v2, la passerelle MCP et les variantes pour éditeur : [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md). | ||
| 111 | +- Le format des kits : [spécification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md). | ||