Skip to content

Repository files navigation

zagent

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.

Quick start

# 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 too

Usage

zagent Interactive mode (default)
zagent "task description" Run task and exit
zagent fix the bug in main.py Unquoted args joined as task

Options

-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

Environment variables

VariableDescription
ANTHROPIC_API_KEYAPI key for Claude models
OPENAI_API_KEYAPI key for OpenAI models
ZAGENT_MODELDefault model name
ZAGENT_API_BASEDefault API base URL
VERS_API_KEYVers platform API key (enables VM tools)
VERS_URLVers API base URL (default: https://api.vers.sh)

What's built in

Git (ziggit)

The agent uses ziggit for version control. Both zagent and ziggit binaries are built together:

zig build # → zig-out/bin/zagent, zig-out/bin/ziggit

The workflow:

  • ziggit start runs before each task (sync with upstream)
  • The LLM uses ziggit progress "description" to save checkpoints mid-task
  • ziggit progress runs after completion (commit + push)

Raw git commands are blocked — the agent is instructed to use ziggit exclusively (and autocorrected if it doesn't).

Autocorrect

Commands are silently fixed instead of rejected:

TypedCorrected to
cmd & / nohup cmd &__bg cmd
git statusziggit status
pip install Xuv add X
python script.pypython3 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.

Output compression

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

Vers VM integration

When VERS_API_KEY is set, zagent gains native tools for managing Vers Firecracker VMs — no external CLI needed:

ToolDescription
vers_vm_createCreate a new VM
vers_vm_deleteDelete a VM
vers_vm_listList all VMs
vers_vm_useSet active VM — routes bash through SSH
vers_vm_branchClone a VM (like git branch for machines)
vers_vm_commitSnapshot VM state
vers_vm_restoreRestore from snapshot
vers_vm_execOne-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:

ToolDescription
vers_repo_createCreate a named repository
vers_repo_listList all repositories
vers_repo_deleteDelete a repository
vers_repo_tagCreate/list tags in a repo

Code cannon (parallel agent orchestration)

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 works

zagent will:

  1. Decompose the task into independent sub-tasks
  2. Spawn parallel agents on Vers VMs from the golden snapshot
  3. Agents work independently, each running:
    ziggit start → pi "sub-task" → ziggit progress → repeat
    
  4. Collect reports — what worked, what failed, what remains
  5. Plan the next iteration using full history (the "infinite context")
  6. 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 agent
  • chess-frontend-state — State management agent
  • chess-backend-api — API server agent
  • chess-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.

Code pirate (strategic review loop)

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:

  1. Read the manifest (~/.zagent/pirate-<slug>.md) — its only memory
  2. Review the actual project with fresh eyes (clone/pull, build, test)
  3. Update the manifest with findings (PASS/FAIL with evidence)
  4. Fire code cannons at the most impactful gaps
  5. 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.

Context management

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

Provider auto-detection

Model containsProtocolAPI base
claude or anthropicAnthropic nativeapi.anthropic.com
anything elseOpenAI-compatibleapi.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.

Platform abstraction (WASM support)

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.

OperationNativeWASM (freestanding)
Shell executionbash -c subprocesshost_exec() JS callback
HTTP (API calls)curl subprocesshost_http_post() JS callback
Filesystemstd.fshost_read_file() / host_write_file() etc.
Stdout/stderrfd 1/2host_write_stdout() / host_write_stderr()
Env varsgetenv()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.

Architecture

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

Building

Requires Zig 0.15.2+:

zig build # debug
zig build -Doptimize=ReleaseFast # release
zig build test# run 96 tests

Acknowledgements

Agent-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.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages