wrencode
wrencode is a minimal agent harness for coding, in a single Python file. A harness is everything around the model that turns it into an agent: the tool-calling loop, the tools, the system prompt, and context management. Where Claude Code is the batteries-included harness, wrencode is the one you can understand and own: the whole loop fits in one readable file, runs against local or hosted models, and is yours to hack.
Named after Harold Wren, the alias of a genius who built a superintelligent AI and operated quietly in the background.
What’s new in 0.2.0
Section titled “What’s new in 0.2.0”- Headless mode.
-p/--printruns one prompt without the interactive UI, for scripts, CI, and evals. - Typed answers.
--json-schemamakes the answer a JSON value that matches your schema. - Verified runs.
--verify CMDchecks the agent’s claim of being done and sends failures back to it. - Automatic compaction. Long sessions are summarized before they overflow the context window.
- OpenAI-compatible backend. Talk to vLLM, llama.cpp, Hugging Face, or any server that implements OpenAI chat completions.
- NanoGPT backend, with native OpenAI-format tool calls.
- AGENTS.md. Project instructions are loaded into the system prompt.
- Sturdier loop. Retries on dropped connections, timeouts, and HTTP 429/5xx,
recovery from cut-off responses and garbled tool calls, and a more forgiving
edittool.
Full history in the changelog.
Install
Section titled “Install”Standalone binary (recommended)
Section titled “Standalone binary (recommended)”The guided installer detects your OS and architecture, downloads the matching
binary from the latest GitHub Release, and installs it to ~/.local/bin (no
sudo).
curl -LsSf https://almostly.ai/wrencode/install.sh | shPin a version or change the install location:
curl -fsSL https://almostly.ai/wrencode/install.sh \ | WRENCODE_INSTALL_DIR=/usr/local/bin WRENCODE_VERSION=0.2.0 shManual binary download
Section titled “Manual binary download”Grab the binary for your platform from the latest GitHub Release:
- macOS Apple Silicon:
wrencode-macos-arm64 - macOS Intel:
wrencode-macos-x64 - Linux x64:
wrencode-linux-x64
Make it executable and move it onto your PATH:
chmod +x wrencode-macos-arm64sudo mv wrencode-macos-arm64 /usr/local/bin/wrencodeRun from source
Section titled “Run from source”Single file, standard library only (except the backend you choose).
git clone https://github.com/almostly/wrencodecd wrencodepython3 wrencode.pyBackend-specific dependencies, if you need them:
pip install mlx-lm # MLX on Apple Siliconpip install transformers torch # HuggingFace TransformersFirst launch prompts for a backend and saves it to ~/.wrencode/config.json.
Re-pick at any time:
wrencode --configureOverride the saved choice for a single session (useful in CI):
BACKEND=anthropic wrencodeBACKEND=openai MODEL=gpt-4o wrencodeBACKEND=openrouter MODEL=anthropic/claude-3-haiku wrencodeBACKEND=nanogpt MODEL=z-ai/glm-5.3-flash wrencodeBACKEND=bedrock AWS_REGION=us-east-1 wrencodeBACKEND=ollama MODEL=llama3.2 wrencodeBACKEND=openai-compatible wrencodeBACKEND=transformers MODEL=deburky/gpt-oss-claude-code python3 wrencode.pyBACKEND=local LOCAL_PORT=8082 wrencodeSkip the y/N confirmation on writes and shell commands:
wrencode --yes--yes runs writes and shell commands without asking, so use it only in a
workspace you are happy for the agent to change.
Backends
Section titled “Backends”| Backend | Description | Availability |
|---|---|---|
anthropic | Claude via the Anthropic API | binary + source |
openai | GPT models via the OpenAI API | binary + source |
openrouter | Any model via OpenRouter | binary + source |
nanogpt | Any model via NanoGPT | binary + source |
bedrock | Any model on AWS Bedrock via the Converse API, using your AWS credentials | binary + source |
ollama | Local models via a running ollama serve | binary + source |
openai-compatible | vLLM, llama.cpp, Hugging Face, any OpenAI-compatible server | binary + source |
local | Local proxy via an Anthropic-compatible API | binary + source |
transformers | HuggingFace Transformers (CPU / MPS / GPU) | source install only |
mlx | Apple Silicon via MLX | source install, macOS |
The standalone binary can’t bundle the heavy ML stack, so mlx and
transformers are only offered when running from source.
Default local models:
deburky/gpt-oss-claude-code
(transformers) and
deburky/gpt-oss-claude-mlx
(MLX). Override either with MODEL=....
OpenAI-compatible servers
Section titled “OpenAI-compatible servers”openai-compatible talks to any server that implements OpenAI chat completions,
using native tool calls. Point it at the server with
OPENAI_COMPATIBLE_BASE_URL (default http://localhost:8000/v1). If the server
serves exactly one model, wrencode uses it. Otherwise set MODEL.
# vLLM (tool calling needs these flags; pick the parser for your model)vllm serve Qwen/Qwen2.5-Coder-7B-Instruct --enable-auto-tool-choice --tool-call-parser hermesBACKEND=openai-compatible wrencode
# llama.cpp (--jinja enables tool calling)llama-server -m qwen2.5-coder-7b-instruct-q4_k_m.gguf --jinja --port 8080BACKEND=openai-compatible OPENAI_COMPATIBLE_BASE_URL=http://localhost:8080/v1 wrencode
# Hugging Face Inference ProvidersBACKEND=openai-compatible OPENAI_COMPATIBLE_BASE_URL=https://router.huggingface.co/v1 \ OPENAI_COMPATIBLE_API_KEY=$HF_TOKEN MODEL=Qwen/Qwen2.5-Coder-32B-Instruct wrencodeNo GPU to hand? The repo has a Modal script that serves vLLM to test against.
Headless mode
Section titled “Headless mode”-p / --print runs a single prompt without the interactive UI:
wrencode -p "Why is test_parse failing?"git diff | wrencode -p "Review this diff" # prompt from stdinwrencode --yes -p "Fix the lint errors" --max-turns 20wrencode -p "List the TODOs" --output-format json | jq -r .resultwrencode --yes -p "Make the tests pass" --verify "python3 -m unittest -q"- stdout carries only the final answer, or one JSON object with
--output-format json(result,is_error,stop_reason,num_turns,backend,model). Progress and tool output go to stderr. - Each run starts from a fresh history and doesn’t touch the saved one.
- Without
--yes, writes and shell commands are declined (the model is told why) instead of waiting for approval. Read-only tools always work. - The exit code is
0when the agent finishes,1if it errors, hits--max-turns, or stops on repeated tool errors, and2for bad arguments.
Verified runs
Section titled “Verified runs”--verify CMD checks the agent’s claim of being done. wrencode runs CMD in
the workspace when the agent finishes. If it fails, the output goes back to the
agent and it continues, up to 3 attempts in all. The result says
verified: true/false, and a final failure exits 1 with
stop_reason: "verify_failed". --max-turns applies to each attempt.
Structured output
Section titled “Structured output”--json-schema makes the answer a JSON value that matches a schema, given as a
file or inline:
wrencode -p "Review this repo for bugs" --json-schema bugs.schema.jsonwrencode -p "Is the build green?" --json-schema '{"type": "object", "properties": {"green": {"type": "boolean"}}, "required": ["green"]}'The agent gets a respond tool whose arguments are your schema, and the run
ends when it calls respond with a valid answer. If the answer doesn’t match,
the validation errors go back to the model so it can fix them. If it never
calls respond, the run fails with stop_reason: "no_structured_output".
stdout is the JSON value, or with --output-format json the usual object with
a structured_output field. Validation is built in and covers the common
keywords: type, enum, const, properties, required,
additionalProperties, items, length and numeric bounds, pattern, and
anyOf / oneOf / allOf.
The agent has seven tools available in the loop:
- read: read a file with line numbers, or list a directory
- write: write content to a file
- edit: replace a unique string in a file. If the text only matches with its indentation shifted by a consistent amount, the edit is applied with the replacement shifted to match. Otherwise the error shows the closest lines in the file
- glob: find files by pattern, sorted by modification time
- grep: search files for a regex using
rgwhen available, falling back togrep - bash: run a shell command with timeout and streaming output
- task: delegate a self-contained subtask to a fresh subagent (its own context, same tools) that returns only its final result
All file operations are restricted to the workspace root by default. Set
WRENCODE_UNRESTRICTED_PATHS=1 to allow paths outside the workspace.
Subagents
Section titled “Subagents”The task tool runs a nested agent loop on a fresh message history, so the
parent’s context only grows by the returned summary. Useful for context-heavy
subtasks. Recursion is capped by WRENCODE_MAX_SUBAGENT_DEPTH (default 2).
For autonomous runs, enable --yes or WRENCODE_AUTO_APPROVE=1 so sub-tool
calls don’t block on confirmation.
Project instructions (AGENTS.md)
Section titled “Project instructions (AGENTS.md)”wrencode reads AGENTS.md files and adds them to the
system prompt, so conventions you’ve written for other agents apply here too.
It looks in ~/.wrencode/, then in every directory from the git root down to
the workspace (outside a git repo, only the workspace). A directory without an
AGENTS.md falls back to CLAUDE.md. Files closer to the workspace come later
and take precedence. The total is capped at 32,000 characters, and the files
loaded are listed at startup.
Context management
Section titled “Context management”Long sessions are compacted automatically. Before each model call wrencode
estimates the prompt size (about 4 characters per token), and once it passes
WRENCODE_COMPACT_AT (default 75%) of WRENCODE_CONTEXT_TOKENS (default
128,000) it has the model summarize the older messages: the request, files
touched, commands and results, decisions, and what’s left to do. The most
recent messages, about a quarter of the window, are kept verbatim along with
your latest request, so it works mid-task, between tool calls. If a request
still fails with a context-length error, wrencode compacts and retries once.
Set WRENCODE_CONTEXT_TOKENS to your model’s window, especially for local
models with small ones. /compact summarizes on demand.
Synthesize
Section titled “Synthesize”wrencode synthesize fuses chat transcripts into one synthesis, like a
semantic git merge of conversations:
wrencode synthesize # pick from this project's chat historywrencode synthesize notes/ --out synthesis.mdwrencode synthesize diff notes/ # divergences onlywrencode synthesize log # decision timeline--out FILE writes the result to a file, and --all skips the picker.
Slash commands
Section titled “Slash commands”| Command | Description |
|---|---|
/help | Show available commands |
/backend or /configure | Switch backend |
/model | Switch model, or set one directly with /model <id> |
/c | Clear conversation history |
/compact | Summarize history to reduce context |
/q or exit | Quit |
Environment variables
Section titled “Environment variables”| Variable | Default | Description |
|---|---|---|
BACKEND | chooser / saved config | Override the saved inference backend |
MODEL | backend-dependent | Model path or ID |
WRENCODE_CONFIG_DIR | ~/.wrencode | Dir for config.json (saved backend / key) |
WRENCODE_WORKSPACE | cwd | Root directory for file operations |
WRENCODE_HISTORY_FILE | ~/.wrencode/history.json | Conversation history file path |
WRENCODE_UNRESTRICTED_PATHS | 0 | Allow paths outside the workspace |
WRENCODE_AUTO_APPROVE | 0 | Skip y/N confirmation for writes / shell (also --yes) |
WRENCODE_MAX_SUBAGENT_DEPTH | 2 | Max nested subagent recursion depth (task tool) |
MAX_TOKENS | 8192 | Max tokens per response |
WRENCODE_HTTP_TIMEOUT | 600 | Seconds to wait for a model response |
WRENCODE_HTTP_RETRIES | 2 | Retries on HTTP 429/5xx and network errors, with backoff |
WRENCODE_CONTEXT_TOKENS | 128000 | Model context window, for auto-compaction |
WRENCODE_COMPACT_AT | 0.75 | Compact at this fraction of the window (0 disables) |
MAX_READ_BYTES | 4MB | Max file size to read |
MAX_READ_LINES | 800 | Max lines returned per read |
GREP_MAX_MATCHES | 80 | Max grep results |
BASH_TIMEOUT | 120 | Shell command timeout in seconds |
MAX_TOOL_OUTPUT_CHARS | 48000 | Max tool output before truncation |
GLOB_SKIP_DIRS | .git,node_modules,... | Directories to skip in glob |
ANTHROPIC_API_KEY | Anthropic API key | |
OPENAI_API_KEY | OpenAI API key | |
OPENROUTER_API_KEY | OpenRouter API key | |
NANOGPT_API_KEY | NanoGPT API key | |
AWS_REGION, AWS_PROFILE | Region and credentials profile for bedrock (standard AWS credential variables also work) | |
OPENAI_COMPATIBLE_BASE_URL | http://localhost:8000/v1 | OpenAI-compatible server base URL |
OPENAI_COMPATIBLE_API_KEY | Key for that server, if it needs one | |
LOCAL_API_KEY | local | Local proxy API key |
LOCAL_PORT | 8082 | Local proxy port |
OLLAMA_HOST | http://localhost:11434 | Ollama server base URL |
History
Section titled “History”Conversation history is persisted to ~/.wrencode/history.json by default and
restored on the next launch. Override the path with WRENCODE_HISTORY_FILE.
Clear it with /c in-session, or delete the file.
Uninstall
Section titled “Uninstall”wrencode --uninstallRemoves the saved config and shows how to delete the binary.
License
Section titled “License”MIT. Copyright 2026 Almostly.
Subscribe to wrencode updates
We’ll email you when wrencode ships a new release or a notable change. No spam.