Yggdra is an experimental, rapidly evolving project. Interfaces are unstable and may change dramatically without notice. Features, APIs, CLI flags, and behavior are subject to breaking changes between releases. Use at your own risk, especially with important or sensitive files.
Yggdra is an airgapped agentic TUI β a Rust app that connects to Ollama, gives your model a toolbox (ripgrep, git, python, file editing, even nested sub-agents), and lets it operate on your filesystem. No cloud. No API keys. No phoning home. Just you, a terminal, and a local model.
βββββββββββββββββββββββββββββββββ yggdra ββββββββββββββββββββββββββββββββββ
β π· session a1b2c3 Β· qwen3:8b Β· build mode Β· 3 tasks remaining β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β user: find all the TODO comments and summarize them β
β assistant: on it β searching with rg firstβ¦ β
β [TOOL_OUTPUT: rg = src/ui.rs:42: // TODO: dark mode toggle] β
β assistant: found 7 TODOs across 4 files. here's the summaryβ¦ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β > β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
~6k lines of Rust Β· 4.8 MB binary Β· <50 MB RAM Β· zero network dependencies
Optimized for small language models β tested against sub-2B models from Qwen, Llama, Gemma, SmolLM, and DeepSeek. If it works on qwen3.5:0.8b, it works.
- Alpha/Beta Stage: Yggdra is under active development. Expect breaking changes, missing features, and rough edges.
- Unstable Interfaces: CLI arguments, configuration formats, data structures, and behavior may change without deprecation warnings.
- Experimental Features: Features like thinking block display, sub-agents, and persistence mechanisms are prototype-grade.
- Use at Your Own Risk: This tool gives an AI direct access to your filesystem. Always review what the agent is about to do before executing in non-Plan mode. Back up your data.
- No Backwards Compatibility Guarantees: Session formats, config files, and stored data may become incompatible with future releases.
If you need stability, mature tooling, or production guarantees, consider cloud-based alternatives. Yggdra is for explorers and people who value local-first automation over stability.
Most agentic coding tools need the cloud. Yggdra doesn't. It's built for the scenario where you can't β or won't β send your code to someone else's servers. Plug in an Ollama instance (local or on your tailnet), point it at a project, and let it work. The TUI is clean, sessions persist, and the model can spawn sub-agents to parallelize work.
You need: Ollama running somewhere reachable, and Rust 1.70+ to build.
git clone https://github.com/cutecycle/yggdra.git
cd yggdra
cargo build --release
./target/release/yggdra # or: make install β ~/.local/bin/yggdraFirst run? Pull a model and go:
ollama pull qwen3:8b # or whatever you like
yggdra # that's it| Flag | Mode | What it does |
|---|---|---|
--ask |
Ask | Read-only. Answers questions, no autonomous actions, can't touch your files. |
--plan |
Plan (default) | Interactive. Agent proposes; you drive. |
--build |
Build | Autonomous. Agent kicks itself to keep working until you stop it. |
--one |
One | Like Build, but stops with an OS notification when the task is complete ([DONE] or no tool calls in a turn). |
Mode persists across sessions (saved to ~/.yggdra/config.json or
.yggdra/config.json), so you only set it once. Cycle in-app: Plan β Build β
One β Ask.
Available tools (all local, no network):
| Tool | What it does |
|---|---|
| rg | Ripgrep search across files |
| exec | Run local commands (PATH-resolved, no network binaries) |
| shell | Run a shell command (sh -c wrapper) |
| setfile | Write entire file β creates if missing, git-tracked |
| patchfile | Line-range replacement (targeted patch without full-file overwrite) |
| commit | Stage and commit with git |
| python | Execute Python snippets |
| ruste | Compile and run Rust snippets |
| spawn | Spawn a child sub-agent (up to 10 levels deep) |
Tool calls default to JSON (OpenWebUI-style). Legacy <|tool>β¦<|end_tool> and
[TOOL: β¦] formats are still parsed for backward compatibility.
Results come back as [TOOL_OUTPUT: name = ...] and the model keeps going.
The model can spawn child agents to handle subtasks in parallel β up to 10 levels deep. Each sub-agent gets the same tools (minus the ability to spawn further agents, to prevent infinite recursion).
Every directory gets its own session. Walk into a project, launch yggdra, and your conversation is right where you left it.
.yggdra_session_id β marker file (add to .gitignore)
~/.yggdra/
βββ sessions/<uuid>/
βββ messages.db β SQLite β fast, transactional
βββ metadata.json β model, timestamps, etc.
Open two terminals in the same project? Both instances share the same SQLite DB and sync via polling β you'll see messages appear in both windows.
Symlink .yggdra/knowledge to any local docs folder and the model can search
it with rg β no indexing server, no vector DB.
ln -s ~/my-docs .yggdra/knowledgeThe model treats it like any other directory. Point it at API references, textbooks, man pages, whatever you've got locally.
After every response, yggdra quietly asks the model: "what did you wish you
knew?" The answers get logged to .yggdra/gaps. Over time, you build a map
of what your local model struggles with β handy for knowing what to add to
your knowledge base.
| Variable | Default | What it does |
|---|---|---|
OLLAMA_ENDPOINT |
http://localhost:11434 |
Where your Ollama lives |
OLLAMA_MODEL |
auto-detect | Which model to use |
Config files (~/.yggdra/config.json for global, .yggdra/config.json for
per-project) override env vars and persist mode/model/endpoint between runs.
Both are watched live β edit and the running TUI picks it up.
export OLLAMA_ENDPOINT=http://10.0.0.5:11434 # tailnet box
export OLLAMA_MODEL=qwen3:8b
yggdra --buildCreate ~/AGENTS.md to define your personal preferences, persona, or
constraints that apply across every project:
# My global instructions
- Prefer short, direct answers
- Always write tests for Rust code
- My name is Nina β address me by nameWhen yggdra starts, it reads ~/AGENTS.md first, then appends the
project-local AGENTS.md (if any) after a # --- project AGENTS.md ---
separator. Both files are watched live β edits are picked up without restart.
Yggdra speaks Ollama's API by default and also supports the OpenAI chat
completions API via the async-openai library (with SSE streaming). Point
endpoint in ~/.yggdra/config.json at any OpenAI-compatible server β
OpenRouter, a local proxy, or anything that speaks /v1/chat/completions.
Useful for hosted models when you're not strictly airgapped.
/help,/models,/quit/oneβ switch to One mode for a single autonomous task/abortβ kill stuck streams, async tasks, and in-flight tool execution/shell CMDβ run a shell command inline without going through the agent/test_notificationβ fire a test OS notification to verify your setup
yggdra uses osascript for native notifications (notify-rust silently fails on
unbundled CLIs). To allow them:
- System Settings β Notifications β Script Editor
- Enable Allow Notifications
Run /test_notification inside yggdra to confirm.
- Native notifications β OS notifications on new session and model response.
- Adaptive theming β detects light/dark terminal and picks colors accordingly. Solarized-inspired palette.
- Structured logging β every message written to
.yggdra/log/YYYY/MM/DD/HHMM/SS-role.mdfor full auditability. - Task tracking β built-in SQLite-backed task graph with checkpoints and dependency tracking. The model manages its own todo list.
- Steering directives β inject system-level constraints (be concise, output JSON, etc.) that get prepended to every prompt.
cargo build --release # optimized binary (LTO, stripped)
cargo test --lib # 450 tests β keep them green
make install # copy to ~/.local/bin/The test suite includes terminal integrity tests (ratatui TestBackend for
cell-level garbage detection), rendering pipeline tests, and the model
gauntlet. See CONTRIBUTING.md for the full dev guide and
ARCHITECTURE.md for the deep dive.
src/bin/test_models.rs runs 26 capability tests per model β XML tool calls,
discipline (no preamble, no hallucination, no code fences), multi-call,
thinking, and humor/personality.
The default model set covers mainline OSS models β€2B parameters, one from each major provider:
| Provider | Model | Params | Released |
|---|---|---|---|
| Alibaba / Qwen | qwen3.5:0.8b-bf16 |
873M | May 2026 |
| Alibaba / Qwen | qwen2.5:1.5b |
1.5B | Sep 2024 |
| Alibaba / Qwen | qwen3.5:2b-q4_K_M |
2.3B | May 2026 |
| Meta | llama3.2:1b |
1.24B | Sep 2024 |
gemma3:1b |
1B | Mar 2025 | |
| HuggingFace | smollm2:1.7b |
1.7B | Nov 2024 |
| DeepSeek | deepseek-r1:1.5b |
1.5B | Jan 2025 |
Run it with:
./target/release/test_models http://localhost:11434 # all default models
./target/release/test_models http://host:11434 model:tag # specific modelResults below are updated by the gauntlet itself after each run:
| Model | Params | Quant | Score | |
|---|---|---|---|---|
qwen3.5:2b-q4_K_M |
2.3B | Q4_K_M | 19/26 | ββββββββββββββββββββββββββ |
gemma:2b |
3B | Q4_0 | 3/26 | ββββββββββββββββββββββββββ |
qwen3.5:4b-q4_K_M |
4.7B | Q4_K_M | 21/26 | ββββββββββββββββββββββββββ |
gemma4:latest |
8.0B | Q4_K_M | 20/26 | ββββββββββββββββββββββββββ |
qwen3.5:9b-q4_K_M |
9.7B | Q4_K_M | 21/26 | ββββββββββββββββββββββββββ |
All crates are committed to vendor/ via cargo vendor. Building requires
zero network access β cargo build --release resolves everything locally.
- Offline by design: perfect for air-gapped machines; no crates.io reach required at build time.
- Reproducible: the exact dependency tree is in the repo β no registry
surprises, no yanked crates, no
Cargo.lockdrift between machines. - CI-friendly: pipelines without internet access build cleanly.
This is wired up in .cargo/config.toml:
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "vendor"To update a dependency: run cargo update then cargo vendor and commit the
changes to vendor/.
"Ollama is offline" β Start it (ollama serve) or point
OLLAMA_ENDPOINT at the right address.
"Model not found" β ollama pull <model> or type /models inside yggdra
to see what's available.
Slow responses β That's your GPU talking, not yggdra. Try a smaller model
or check ollama ps.
Session weirdness β Delete .yggdra_session_id in the project dir to
start fresh.
MIT