Remove entire TaskState machinery: - TaskState struct, render(), taskState()/updateTaskState() on History - inferTaskStateUpdate() — heuristic plan tracking - Replan gate (replanGate const, roundsWithoutPlan counter) - Stall detection (stallThreshold, stallRounds, lastAction) - Plan reinject (planReinjectInterval, periodic re-injection) - ReadPlanStep plumbing (AgentCfg → Agent → TurnCtx → loop) None of this worked in practice — the model ignores the nudges, ReadPlanStep was never wired to a non-nil value, and TaskState fields were only populated by inferTaskStateUpdate (which depends on ReadPlanStep being set). Compaction now uses plain summary text in the cold zone instead of serialized TaskState JSON. Also remove: - Verbosity field (declared, threaded, never read by any backend) - DisallowTools (config field never wired to session) - Session.listHandlers, plan, prevPrompt (never read) - Config.Output, Config.ListHandlers, Config.ReadPlanStep (never set) -246 net lines |
||
|---|---|---|
| agent | ||
| backend | ||
| cmd | ||
| contrib/elisp | ||
| data | ||
| doc | ||
| elevate | ||
| env | ||
| format | ||
| fs | ||
| fsedsl | ||
| kde@eed4a1089e | ||
| lib9p | ||
| log | ||
| paths | ||
| prompts | ||
| sandbox | ||
| session | ||
| tools/lsp | ||
| toolsrv | ||
| .gitignore | ||
| .gitmodules | ||
| .plan.md | ||
| AGENTS.md | ||
| Containerfile | ||
| README.md | ||
| go.mod | ||
| go.sum | ||
| justfile | ||
| pull.sh | ||
README.md
ollie
Ollie is an AI agent runtime. A single binary (olliesrv) exposes agent sessions
over a single surface: a 9P2000 filesystem. The core is deliberately minimal;
capabilities come from composing small pieces — tool executables, skill files,
metadata sidecars — rather than building a monolithic framework.
Building
git clone --recurse-submodules https://git.lneely.de/lkn/ollie.git
cd ollie
just
Requires just:
cargo install just
See doc/usage.md for usage instructions.
Configuration
Environment: ~/.config/ollie/env
OLLIE_BACKEND=openai # ollama | openai | anthropic | copilot | kiro (default: ollama)
OLLIE_OPENAI_URL=https://openrouter.ai/api
OLLIE_OPENAI_KEY=sk-or-...
OLLIE_ANTHROPIC_KEY=sk-ant-...
OLLIE_COPILOT_TOKEN=...
OLLIE_KIRO_TOKEN=... # bearer token or sqlite:// path (auto-detected from Kiro CLI if unset)
OLLIE_MODEL=qwen/qwen3-235b-a22b
OLLIE_COMPLETE_BACKEND=ollama # backend for code completion
OLLIE_COMPLETE_MODEL=qwen3:latest # model for code completion
Everything lives under $XDG_CONFIG_HOME/ollie/ (default: ~/.config/ollie/) — tools in tools/, memory in memory/, agents in agents/, prompts in prompts/, skills in skills/. Shell environment variables take precedence over the env file.
What you can do
| Capability | How |
|---|---|
| CLI | o — unified namespace CLI with read, write, readloop, ls, ctl, prompt, tail, env, stop, kill |
| Terminal TUI | o tui — tmux + two shell commands, no widgets |
| One-shot LLM | o generate "explain monads" or echo "prompt" | o generate |
| Code completion | o complete '{"file":"main.go","prefix":"func "}' or echo '{"file":"..."}' | o complete |
| Task routing | o route "implement login" or echo "task" | o route → backend=X model=Y |
| Run an agent | Create a session + agent via 9P — then connect with any frontend (ellie, KDE (GUI/KRunner/Kate), o tui) |
| Remote execution | Set remote=user@host in session config |
| Agents | Write a JSON config in data/agents/ with agent prompt in data/prompts/ |
| Tools | Drop an executable + .meta in ~/.config/ollie/tools/ — then load at runtime via tool_load |
| Domain skills | Load markdown skill modules at runtime |
Repository layout
Single Go module with one Git submodule (kde).
| Directory | Language | Description |
|---|---|---|
agent/ |
Go | Agent loop, history, hooks, prompt resolution, commands |
backend/ |
Go | LLM providers (Anthropic, OpenAI, Ollama, Gemini, Copilot, CodeWhisperer) |
toolsrv/ |
Go | Tool server, dynamic tool dispatch, sandboxed execution, remote execution |
tools/lsp/ |
Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
session/ |
Go | Session lifecycle, config, persistence |
fs/ |
Go | 9P filesystem tree for session namespace |
detach/ |
Go | Background process management |
elevate/ |
Go | Elevation broker (privilege escalation) |
sandbox/ |
Go | Landlock sandbox config |
cmd/olliesrv/ |
Go | The main binary |
cmd/ollie-9p/ |
Go | 9P client |
cmd/ollie-remote/ |
Go | Remote execution binary |
kde/ |
C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner (submodule) |
data/agents/ |
JSON | Agent configs |
data/prompts/ |
Markdown | System prompt templates |
data/tools/ |
Mixed | Tool executables (scripts + compiled) + .meta sidecar files |
data/skills/ |
Markdown | Domain knowledge modules |
doc/ |
Markdown | Architecture docs, usage guide |
Architecture
graph TB
subgraph Frontends
ACME[Plan 9 acme]
EMACS[Emacs<br>ellie.el]
KDE[KDE<br>GUI / Kate / KRunner]
end
subgraph "olliesrv"
P9[9P Filesystem<br>session/ namespace]
SM[Session Manager]
AG[agent.Agent<br>loop · compaction<br>prompt templates]
ROUTE[Router<br>complete · generate · route]
TOOLS[toolsrv.Server<br>dynamic dispatch · sandbox]
end
subgraph "LLM Backends"
OLL[Ollama]
OAI[OpenAI / OpenRouter]
ANT[Anthropic]
COP[Copilot]
KIRO[Kiro]
end
subgraph Execution
LOCAL[Tool Scripts<br>loaded via 9P write<br>· shell, reasoning_think<br>· file_*, lsp_*, memory_*<br>· gui_*, subagent_*]
REMOTE[ollie-remote<br>via SSH · no embedded tools]
end
ACME & EMACS & KDE --> P9
P9 --> SM
SM --> AG
AG --> ROUTE
AG --> TOOLS
AG -->|streaming| OLL & OAI & ANT & COP & KIRO
TOOLS --> LOCAL
TOOLS -->|SSH| REMOTE
olliesrv exposes the agent runtime over a single surface: a 9P2000 filesystem.
KDE GUI, Kate plugin, and KRunner all use 9P internally. For a deep dive into the
filesystem, see doc/resources/9p.md.
Credits
- Plan 9 from Bell Labs — for an interesting system
- @9fans — for the Plan 9 port
- Suckless — for articulating good software development principles
- @simonfxr — for a solid agent baseline to "borrow" from
- @aws — for a solid open-source agent implementation
License
GPLv3