callPromotedTool was hardcoding timeout=30 and sandbox="default" for all promoted tool executions, ignoring the timeout and sandbox parameters provided by the agent in tool call args. Extract these from the JSON args map (same pattern as elevated) and pass them through to the execution functions. |
||
|---|---|---|
| agent | ||
| backend | ||
| cmd | ||
| contrib/elisp | ||
| data | ||
| detach | ||
| doc | ||
| elevate | ||
| env | ||
| fs | ||
| fsedsl | ||
| kde@9a1704d728 | ||
| lib9p | ||
| log | ||
| paths | ||
| prompts | ||
| sandbox | ||
| session | ||
| skills | ||
| 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_OLLAMA_URL= # base URL for Ollama (default: http://localhost:11434)
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
OLLIE_ROUTE_BACKEND=ollama # backend for the /route classifier
OLLIE_ROUTE_MODEL=qwen3:8b # model for task routing
Everything lives under ~/.config/ollie/ by convention — 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