An open-source terminal coding agent.
Powered by local LLMs — your code, prompts, and tool calls never leave your machine. Rust single-binary. No runtime dependencies.
Whet is an open-source local-LLM terminal coding agent in the same category as Claude Code, but local-first by design. It lives in your terminal, understands your codebase, and writes code for you using a model that runs on your machine.
What makes it different:
- Local-only — Ollama, llama.cpp, LM Studio, vLLM, or any OpenAI-compatible local server. Your code, prompts, and tool calls never leave the box.
- Open source (MIT) — you own the code, the data, and the workflow
- Single binary —
cargo installand you're done, no Node.js, no Python, no Docker - Tuned for ~16 GB GPUs —
qwen3.6:35b-a3b(UD-Q3_K_M) reaches 11/11 on the bench while fitting in consumer VRAM
# 1. Install (from source)
git clone https://github.com/kuroko1t/whet.git
cd whet && cargo install --path .
# 2. Pull a local model
ollama pull qwen3.6:35b-a3b-q4_K_M # recommended for 16GB+ GPUs; see Benchmark below
# 3. Start coding
whet -m qwen3.6:35b-a3b-q4_K_MPicking a model:
qwen3.6:35b-a3b-q4_K_Mwas the strongest open-weight model that ran on a 16GB GPU in our benchmark — see Benchmark Results for the data, and for an even faster setup using theUD-Q3_K_Mvariant + KV cache quantization.
Already running LM Studio, llama.cpp, or vLLM? Point Whet at it via the OpenAI-compatible provider — see Configuration.
$ whet
whet v0.1.0
Model: qwen3.5:9b
Permission: default
Type Ctrl+D to exit.
you> Find all deprecation warnings and fix them
Grep(deprecated)
I found 3 deprecation warnings. Let me fix them one by one.
Read(src/main.rs)
Edit(src/main.rs)
- use old_module::deprecated_fn;
+ use new_module::updated_fn;
Tool 'edit_file' wants to execute:
path: src/main.rs
old_text: use old_module::deprecated_fn;
new_text: use new_module::updated_fn;
Allow? [y/N/a(lways)] y
Done! Fixed all 3 deprecation warnings.
(2.3s)
Tool calls render in compact form (
Read(path),Edit(path)). Each successfuledit_file/apply_diffshows a colored unified-style diff. A braille spinner indicates "thinking…" while waiting for the first streamed token. All TTY-aware — non-interactive runs (whet -p ... 2>file) stay clean.
Like CLAUDE.md for Claude Code — place a WHET.md (or .whet.md) in your project root to give Whet project-specific context. It is automatically loaded and injected into the system prompt.
whet # in a project with WHET.md → instructions are loaded automaticallyUse /init to generate a starter template.
Concrete directives are acted on immediately. Open-ended questions get a short option list with tradeoffs and a recommendation, and no edits, until you pick.
you> What should we do next?
Three options:
A. Hooks — extensible but adds a config surface
B. Parallel subagent — better latency, more memory pressure
C. Devstral verification — confirms the current behavior, no new code
Recommendation: B. The latency win directly addresses the recent complaint.
Which would you like?
you> Edit main.rs to print "hello"
Read(src/main.rs)
Edit(src/main.rs)
Detection is heuristic-based on the user's input ("what should we…", "どっちがいい?", "X or Y?", …) so the harness's act-don't-ask re-prompt stays out of the way only when you actually asked a strategic question. Vague directives ("something feels slow") are still treated as directives — Whet investigates instead of asking back.
| Tool | Category | Description |
|---|---|---|
read_file |
File | Read file contents |
write_file |
File | Create or overwrite a file |
edit_file |
File | Replace an exact text match in a file |
apply_diff |
File | Apply a unified diff patch (multi-hunk supported) |
list_dir |
File | List directory contents (recursive option) |
grep |
Search | Search for regex patterns recursively |
repo_map |
Search | Show project structure with definitions |
shell |
System | Execute a shell command |
git |
System | Git commands with safety tiers |
subagent |
Agent | Delegate a focused subtask to a child agent (isolated context) |
web_fetch |
Web | Fetch and extract text from a URL |
web_search |
Web | Search the web via DuckDuckGo |
Web tools are disabled by default. Enable with
web_enabled = truein config.
For investigations or self-contained subtasks, the agent can delegate to a child loop with isolated memory and read-tracking:
you> /agent enumerate every place process_event() is called
Subagent: enumerate every place process_event() is called
Grep(process_event\()
Read(handlers/login.py)
Read(handlers/payment.py)
...
Subagent result:
- handlers/login.py:6
- handlers/payment.py:6, :12
...
The model itself can also call subagent autonomously when it judges the subtask large enough. The child:
- shares the parent's LLM, tools, and stats accumulator
- gets a fresh memory + read_paths so its work doesn't pollute parent context
- returns a single summary string back to the parent
- cannot spawn further subagents (depth cap = 1)
A SubagentGuard RAII struct restores parent state on Drop, so even if the child loop panics the parent stays consistent.
you> /doctor
Whet diagnostics:
✓ ollama reachable — http://localhost:11434 responded
✓ model available — `qwen3.5:9b` is pulled
✓ config parses — /home/you/.whet/config.toml OK
✓ ~/.whet writable — /home/you/.whet OK
✓ MCP servers — all 2 server binaries on PATH
Overall: PASS
Five checks: ollama reachable, active -m model is pulled (handles implicit :latest tag), ~/.whet/config.toml parses, ~/.whet writable, all configured MCP server binaries are on $PATH.
| Tier | Commands | Behavior |
|---|---|---|
| Always allowed | status, diff, log, show, branch, stash |
No approval needed |
| Approval required | add, commit, checkout, switch, pull, fetch, push, merge, tag, cherry-pick, remote, reset |
User must approve |
| Always blocked | reset --hard, clean, push --force, rebase |
Blocked for safety |
Extend Whet with external tools via MCP (Model Context Protocol) servers:
[[mcp.servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]| Mode | File reads | File writes | Shell / Git |
|---|---|---|---|
default |
Auto | Ask | Ask |
accept_edits |
Auto | Auto | Ask |
yolo |
Auto | Auto | Auto |
Conversations are saved per working directory and can be resumed later.
| Flag | Short | Description |
|---|---|---|
--resume |
-r |
Interactive session picker for the current directory |
--resume <id> |
-r <id> |
Resume a specific session by ID |
--continue |
-c |
Resume the most recent session in the current directory |
When resuming, previous user/assistant messages are displayed so you can see the conversation context at a glance.
Automatic conversation summarization prevents unbounded memory growth. Use /compact for manual compression.
| Command | Description |
|---|---|
/model <name> |
Switch LLM model at runtime |
/mode <mode> |
Change permission mode (default / accept_edits / yolo) |
/plan |
Toggle plan mode (read-only analysis) |
/test [cmd] |
Auto test-fix loop (default: cargo test, max 5 rounds) |
/doctor |
Run diagnostics: ollama, model, config, MCP, ~/.whet |
/agent <task> |
Run a focused subagent on <task> in isolated context |
/init |
Generate WHET.md template in current directory |
/compact [msg] |
Compress conversation context (optional custom instruction) |
/skills |
List loaded skill files |
/clear |
Clear conversation and start fresh |
/help |
Show all commands |
Ctrl+D |
Exit |
| Provider | Network | API Key | Config provider |
|---|---|---|---|
| Ollama | Local | Not required | "ollama" |
| OpenAI-compatible (llama.cpp, LM Studio, vLLM, …) | Local | Optional | "openai_compat" |
Whet is local-only by design — there is no cloud-provider integration. If you want to compare a local agent against a hosted frontier model, run a separate tool side by side; the project intentionally doesn't ship API keys in any code path.
Config file: ~/.whet/config.toml
[llm]
provider = "ollama"
model = "qwen3:8b"
base_url = "http://localhost:11434"
# api_key = "sk-..."
# streaming = true
[agent]
max_iterations = 10
# permission_mode = "default"
# web_enabled = false
# context_compression = true
# skills_dir = "~/.whet/skills"
[memory]
database_path = "~/.whet/memory.db"OpenAI-compatible (llama.cpp, LM Studio, vLLM)
[llm]
provider = "openai_compat"
model = "your-model-name"
base_url = "http://localhost:8080"
api_key = "sk-..."Custom prompt templates loaded from ~/.whet/skills/:
mkdir -p ~/.whet/skills
echo "Always write tests for new code." > ~/.whet/skills/testing.mdSkills are injected into the system prompt automatically. Use /skills to list them.
whet # start interactive chat
whet "fix the bug" # single-shot mode
whet -m llama3.2:3b # use a specific model
whet --resume # pick a session to resume (current directory)
whet --resume <id> # resume a specific session by ID
whet --continue # resume the most recent session
whet -p "explain main.rs" # single-shot via -p flag
whet -y # skip all permission prompts
whet tools # list available tools
whet config # show current configuration| Whet | Claude Code | |
|---|---|---|
| License | MIT (open source) | Proprietary |
| LLM providers | Local only (Ollama, llama.cpp, LM Studio, vLLM via OpenAI-compat) | Anthropic only (cloud) |
| Offline mode | Yes (always — no cloud calls in any path) | No |
| Runtime | Single Rust binary | Node.js |
| Project instructions | WHET.md |
CLAUDE.md |
| MCP support | Yes | Yes |
| Permission system | 3 modes | Yes |
| Session management | --resume / --continue |
--resume / --continue |
| Context compression | Yes (auto + manual) | Yes |
| Subagents (isolated context) | Sequential, model- and /agent-callable |
Yes (parallel) |
| Diagnostics | /doctor (ollama / model / config / MCP) |
/doctor |
| Diff preview after edits | Yes (red - / green +, TTY-gated) |
Yes |
| Plan-first on open-ended questions | Yes (auto-detected, EN + JA) | Yes |
Whet ships with a reproducible benchmark suite of 12 coding tasks covering single-file edits, multi-file refactors, planning chains, security fixes, TDD-style test generation, one TypeScript task, and one delegation-friendly callsite-enumeration task across 16 files. Each task has a tamper-proof verifier (SHA-pinned source pins where applicable, mutation testing for task12, false-positive rejection for task14_callsites).
The numbers below are from a single RTX 5060 Ti (16GB VRAM) running
scripts/run_bench.sh -n 3 with temperature=0, seed=42,
OLLAMA_KV_CACHE_TYPE=q8_0, OLLAMA_FLASH_ATTENTION=1.
| Model | Pass rate | Tasks fully passed | Avg time / task |
|---|---|---|---|
qwen3.6:35b-a3b-q4_K_M (recommended) |
100% (29/29) | 11/11 | 82s |
gemma4:26b |
61% (20/33) | 6/11 | 32s |
devstral:24b |
39% (13/33) | 4/11 | 71s |
The UD-Q3_K_M variant of Qwen3.6-35B-A3B from
unsloth/Qwen3.6-35B-A3B-GGUF
fits cleanly into 16GB VRAM (vs. ~7GB CPU offload for the standard Q4_K_M) and
runs ~25% faster while retaining the same 11/11 pass rate. To use it:
# 1. Download the GGUF (~15GB)
mkdir -p ~/models && curl -L -o ~/models/Qwen3.6-35B-A3B-UD-Q3_K_M.gguf \
"https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/resolve/main/Qwen3.6-35B-A3B-UD-Q3_K_M.gguf"
# 2. Register a Modelfile pointing at it
printf 'FROM ~/models/Qwen3.6-35B-A3B-UD-Q3_K_M.gguf\nTEMPLATE {{ .Prompt }}\nRENDERER qwen3.5\nPARSER qwen3.5\n' \
| ollama create qwen3.6-q3 -f -
# 3. Use it
whet -m qwen3.6-q3Caveats: the rankings are tied to this specific GPU + 16GB VRAM. On a
24GB+ GPU the standard Q4_K_M is faster; on smaller GPUs only the lighter
quants (e.g. gemma4:e4b) will fit. See benchmarks/README.md for the task
spec, and benchmarks/results/leaderboard.md for the full per-task breakdown
including tokens, iterations, and tool failures.
To reproduce on your machine:
scripts/run_bench.sh -m <model[,model2,...]> -n 3
cat benchmarks/results/leaderboard.mdwhet (single binary)
Terminal (REPL) <--> Agent Loop
|
+-- LLM Provider (local only)
| Ollama / OpenAI-compat (llama.cpp, LM Studio, vLLM)
|
+-- Tool Executor
| 12 built-in (incl. subagent) + MCP + Skills
|
+-- Security Layer
| Path safety, Permissions, Git safety tiers
|
+-- SQLite Memory
Chat history, Resume, Compression
cargo test # run tests
cargo fmt -- --check # check formatting
cargo clippy --all-targets # lintAll pull requests are checked by GitHub Actions: format, clippy, test, and build.
Contributions are welcome!
- Issues — Use GitHub Issues for bug reports and feature requests
- Pull Requests — Fork, create a feature branch, ensure all checks pass, and submit a clear PR
- Commits — Use imperative mood with prefix:
feat:,fix:,docs:,refactor:,test:,chore: