A minimal SWE agent written entirely in Zig. Interactive by default.
Built-in knowledge of ziggit for git. No external dependencies — everything is pure Zig.
# Build
zig build
# Interactive mode (default)
zagent
# Single task
zagent "fix the bug in main.py"
zagent fix the bug in main.py # unquoted works toozagent Interactive mode (default)
zagent "task description" Run task and exit
zagent fix the bug in main.py Unquoted args joined as task
-m, --model NAME Model name (default: auto from env)
--api-base URL API base URL
--api-key KEY API key
--cwd PATH Working directory for commands
--step-limit N Max steps per task (0 = unlimited)
--cost-limit F Max cost in USD (default: 3.0)
--temperature F Sampling temperature (default: 0.0)
--cache MODE Prompt cache mode: none, anthropic
--context-limit N Override context window size (tokens, for testing)
--no-start Skip `ziggit start`
--no-progress Skip `ziggit progress`
-v, --verbose Show full command output
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
API key for Claude models |
OPENAI_API_KEY |
API key for OpenAI models |
ZAGENT_MODEL |
Default model name |
ZAGENT_API_BASE |
Default API base URL |
VERS_API_KEY |
Vers platform API key (enables VM tools) |
VERS_URL |
Vers API base URL (default: https://api.vers.sh) |
The agent uses ziggit for version control. Both zagent and ziggit binaries are built together:
zig build # → zig-out/bin/zagent, zig-out/bin/ziggitThe workflow:
ziggit startruns before each task (sync with upstream)- The LLM uses
ziggit progress "description"to save checkpoints mid-task ziggit progressruns after completion (commit + push)
Raw git commands are blocked — the agent is instructed to use ziggit exclusively (and autocorrected if it doesn't).
Commands are silently fixed instead of rejected:
| Typed | Corrected to |
|---|---|
cmd & / nohup cmd & |
__bg cmd |
git status |
ziggit status |
pip install X |
uv add X |
python script.py |
python3 script.py |
sl, gti, grpe, cta, … |
ls, ziggit, grep, cat, … |
Post-execution fixes: command not found retries with typo correction, Permission denied on scripts retries with chmod +x.
Command output is compressed before feeding back to the model to save tokens:
- Test runners: show only failures + summary line (~90% savings)
- Build tools: errors/warnings only (~80% savings)
- Package managers: strip progress bars and noise
- grep/rg: cap results, group by file
- cat/source: strip comments (language-aware)
- env/printenv: mask secrets (API keys, tokens, passwords)
- docker/kubectl: compact listings, dedup logs
- tree/find/ls: filter noise dirs, cap output
- diff: compact unified diff
- General: collapse blanks, dedup repeated lines, cap at ~6K chars
When VERS_API_KEY is set, zagent gains native tools for managing
Vers Firecracker VMs — no external CLI needed:
| Tool | Description |
|---|---|
vers_vm_create |
Create a new VM |
vers_vm_delete |
Delete a VM |
vers_vm_list |
List all VMs |
vers_vm_use |
Set active VM — routes bash through SSH |
vers_vm_branch |
Clone a VM (like git branch for machines) |
vers_vm_commit |
Snapshot VM state |
vers_vm_restore |
Restore from snapshot |
vers_vm_exec |
One-off command on a VM |
After vers_vm_use, all bash tool calls execute on the VM via SSH
(using the Vers SSH-over-TLS transport). Call vers_vm_use with "local"
to switch back.
Repo management tools for organizing commits:
| Tool | Description |
|---|---|
vers_repo_create |
Create a named repository |
vers_repo_list |
List all repositories |
vers_repo_delete |
Delete a repository |
vers_repo_tag |
Create/list tags in a repo |
A Code Cannon is an RLM (Reinforcement Learning from Memory) orchestrator. Use as a subcommand or include "code cannon" in your prompt:
zagent code-cannon "build a chess website with React frontend and Python backend"
zagent "code cannon: fix the flaky test suite" # phrase detection also workszagent will:
- Decompose the task into independent sub-tasks
- Spawn parallel agents on Vers VMs from the golden snapshot
- Agents work independently, each running:
ziggit start → pi "sub-task" → ziggit progress → repeat - Collect reports — what worked, what failed, what remains
- Plan the next iteration using full history (the "infinite context")
- Repeat until done or budget exhausted
Key property: memory. Each iteration builds on the last. The orchestrator knows what was tried, what worked, what failed, and why.
Agents use prefix conventions for organization:
chess-frontend-ui— React component agentchess-frontend-state— State management agentchess-backend-api— API server agentchess-backend-engine— Chess engine agent
Each agent gets a distinct git author name matching its prefix, pushing
to the same repo. ziggit start handles merging across agents.
A Code Pirate is a stateless strategic reviewer that fires Code Cannons. It maintains a living manifest (checklist) tracking what's done, failing, and missing — then fires cannons at the highest-impact gaps:
zagent code-pirate "take sterling to 100% completion"
zagent code-pirate --manifest ~/.zagent/pirate-sterling.md "fix remaining items"zagent will:
- Read the manifest (
~/.zagent/pirate-<slug>.md) — its only memory - Review the actual project with fresh eyes (clone/pull, build, test)
- Update the manifest with findings (PASS/FAIL with evidence)
- Fire code cannons at the most impactful gaps
- Monitor cannons, record results, loop back to 1
Key property: stateless review. Fresh context each round means no accumulated assumptions. The manifest IS the memory — a human-readable, human-editable living document outside the repo.
The manifest lives at ~/.zagent/ — never in the repo, never visible to
subagents. A human can view/edit it between rounds to steer priorities.
Items can only be marked PASS with verification evidence (exact command + output). "I looked at the code and it seems right" is not sufficient.
Works in interactive mode too — type "code pirate" in any prompt to activate.
The agent automatically manages context window usage:
- 70%: truncates old tool observations (age-based — older = more aggressive)
- 80%: summarizes conversation history and rebuilds with summary + recent turns
- Overflow: emergency drop to system + last N messages
- Loop detection: nudges the agent when the same action repeats 3+ times
| Model contains | Protocol | API base |
|---|---|---|
claude or anthropic |
Anthropic native | api.anthropic.com |
| anything else | OpenAI-compatible | api.openai.com |
Prompt caching auto-enabled for Claude models, with adaptive cache breakpoint advancement — instead of writing a new cache entry every API call (paying 1.25× per token each time), the conversation breakpoint only advances every K≈4–15 calls based on an adaptive formula from optimal caching theory. The system prompt is always cached. This typically reduces cache write costs by 60–80% while maintaining high cache read rates.
zagent has a platform abstraction layer (src/platform.zig) that enables it to
run in WebAssembly with a virtual filesystem — e.g. for a browser demo where
ziggit clones a repo into memory and zagent works on those files.
| Operation | Native | WASM (freestanding) |
|---|---|---|
| Shell execution | bash -c subprocess |
host_exec() JS callback |
| HTTP (API calls) | curl subprocess |
host_http_post() JS callback |
| Filesystem | std.fs |
host_read_file() / host_write_file() etc. |
| Stdout/stderr | fd 1/2 | host_write_stdout() / host_write_stderr() |
| Env vars | getenv() |
host_get_env() JS callback |
The JS host implements the env module with these extern functions, backed by
an in-memory filesystem (e.g. ziggit's virtual git repo) and a shell interpreter.
src/
├── main.zig CLI, interactive REPL, ziggit lifecycle
├── agent.zig Agent loop, context management, loop detection
├── model.zig Dual LLM client (OpenAI + Anthropic native)
├── environment.zig Bash execution, autocorrect, background processes
├── compress.zig Output compression (10+ command categories)
├── platform.zig Platform abstraction (native + WASM)
├── vers.zig Vers VM API client (pure Zig, no CLI)
├── git.zig ziggit CLI wrapper
├── config.zig System prompt, observation templates
└── json.zig JSON builder & extractor
Requires Zig 0.15.2+:
zig build # debug
zig build -Doptimize=ReleaseFast # release
zig build test # run 96 testsAgent-level token efficiency improvements — including adaptive cache breakpoint
advancement and the optimal caching theory it's based on — were designed by
Carter Tazio Schonwald. The adaptive formula
(p* ∝ 1/√N) determines when to advance the conversation cache breakpoint,
reducing cache write costs by 60–80% while maintaining high read rates across
long sessions.
MIT