mingo

A small agent runtime in one Go file.Small enough to understand. Built to do real work.

sandbox: workspace fence: bwrap root: /work/app round 0 / 60 read numbered lines edit one unique block exec go vet, go test say once, verified hi receipt wrote add.go batch closed: not executed .mingo/sessions/20260913-081502-9c1a2f.jsonl (fsync after every line) {"role":"user","content":"Add has a bug. Fix it."} _
space step   enter play   esc cancel the turn one turn: read, edit, exec, then say it once.

1Minimize machinery, not capability.

mingo is a tool loop over any OpenAI-compatible endpoint: a llama-server on your own machine, DeepSeek, OpenRouter, or OpenAI's Responses API. It is built so that a 4B model on a laptop CPU can deliver, not demo. The harness checks what the model claims, refuses what it cannot verify, closes every loop the model leaves open, and keeps the transcript small.

the loop

Tool rounds until the model answers without a tool. Budgets are terminal. A cut reply runs nothing. A batch is judged whole before any of it runs.

the sandbox

An os.Root jail for files, an allowlist that splits commands the way sh does, and an OS fence (bwrap, seatbelt) that the banner names. Asks fail closed.

the session

Append-only JSONL, fsynced per line, locked while open. A torn tail is repaired on disk before anything is appended. Resume, and every open call is closed.

2Run it.

# build, then talk to a model
go build -o mingo . && DEEPSEEK_API_KEY=... ./mingo

# a 4B model on this machine, no key
./mingo -provider local

# one key, a few hundred models
OPENROUTER_API_KEY=... ./mingo -provider openrouter -model openai/gpt-6-astra

# headless: the answer on stdout, the outcome in the exit code
./mingo -json -p "Add has a bug. Fix it, verify with go vet, and report."
{"outcome":"done","written":["add.go"],"requests":5, ...}

3What the loop guarantees.

Properties of the program, not of the model's manners. Each has a test that tries to break it.

4Providers.

providerwiredefault modelthinking
deepseekchat completionsdeepseek-flashreasoning_content replayed, as the API requires
openaiResponses APIgpt-6-astraencrypted reasoning items replayed; nothing stored server-side
openrouterchat completionsdeepseek/deepseek-v4.1-flashunified reasoning switch; any model id
localchat completionswhatever is loadedchat template switch; context read from /props; 4096-token cap