ollie/README.md

180 lines
7.2 KiB
Markdown

# 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
```sh
git clone --recurse-submodules https://git.lneely.de/lkn/ollie.git
cd ollie
just
```
Requires [just](https://github.com/casey/just):
```sh
cargo install just
```
See [`doc/usage.md`](doc/usage.md) for usage instructions.
## Configuration
### Backends: `~/.config/ollie/backends.conf`
```ini
# Default backend for new sessions
backend = openrouter
[openrouter]
key = sk-or-v1-...
model = qwen/qwen3-235b-a22b
[anthropic]
key = sk-ant-...
model = claude-sonnet-4-20250514
[ollama]
host = http://localhost:11434
model = qwen3:latest
[kiro]
# key auto-detected from Kiro CLI if unset
```
Each section configures a backend. The session selects which backend to use via the `backend` top-level setting or per-agent `backend=` in cfg. See `data/backends.conf` for the full template.
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/`.
## What you can do
| Capability | How |
|---|---|
| **CLI** | `o` — unified namespace CLI: `read`, `write`, `ls`, `new`, `ctl`, `prompt`, `tui`, `env`, `generate` |
| **Terminal TUI** | `o tui` — tmux layout, no widgets |
| **One-shot LLM** | `o generate "explain monads"` or `echo "prompt" \| o generate` |
| **Run an agent** | Create a session + agent via 9P — then connect with any frontend ([ellie](doc/ellie.md), KDE (GUI/KRunner/Kate), acme, `o tui`) |
| **Pair programming** | Wire an observer agent to your coding session via `feed` — real-time observations as you work ([doc](doc/usage.md#pair-programming--observer-agents)) |
| **Remote execution** | Set `remote=user@host` in session config |
| **Background processes** | Pass `"background": true` to any tool — runs with no timeout, output pushed to agent prompt on completion |
| **Parallel execution** | Non-conflicting tool calls within a turn run in parallel (scope-based conflict scheduling) |
| **Sub-agents** | `subagent_spawn` — delegate work to a transient agent, block until done, get the reply. Multiple spawns run in parallel. |
| **Agents** | Write a JSON config in `~/.config/ollie/agents/` with agent prompt in `~/.config/ollie/prompts/` |
| **Tools** | Drop an executable + `.meta` in `~/.config/ollie/tools/` — load at runtime via `tool_load` |
| **Tool definitions** | Define tools with `.meta` files only — no wrapper script needed ([doc](doc/tool-definitions.md)) |
| **Domain skills** | Load markdown skill modules at runtime |
## Repository layout
Single Go module with one Git submodule (kde).
| Directory | Language | Description |
|-----------|----------|-------------|
| `cmd/olliesrv/` | Go | The main server binary (session/agent 9P namespace) |
| `cmd/toolsrv/` | Go | Tool execution server (separate 9P server, sandboxed execution) |
| `cmd/ollie-9p/` | Go | 9P client CLI |
| `toolsrv/` | Go | Tool server client library + tool discovery (9P client for toolsrv) |
| `virtfs/` | Go | Filesystem declaration EDSL (generic, reusable) |
| `lib9p/` | Go | 9P protocol library + native C client |
| `tools/lsp/` | Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
| `env/` | Go | Environment variable defaults |
| `format/` | Go | Output formatting |
| `log/` | Go | Structured logging |
| `paths/` | Go | XDG path resolution |
| `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner *(submodule)* |
| `contrib/elisp/` | Emacs Lisp | ellie.el — Emacs frontend |
| `data/agents/` | JSON | Agent configs (installed to `~/.config/ollie/agents/`) |
| `data/prompts/` | Markdown | System prompt templates |
| `data/tools/` | Mixed | Tool executables (scripts + compiled) + `.meta` sidecar files |
| `data/skills/` | Markdown | Domain knowledge modules |
| `data/scripts/` | Shell | CLI scripts (`o`, `ollie-remount`, acme helpers) |
| `doc/` | Markdown | Architecture docs, usage guide |
### Internal packages (not importable outside their command)
| Package | Parent | Description |
|---------|--------|-------------|
| `agent` | `cmd/olliesrv` | Agent loop, history, prompt resolution, context compaction |
| `backend` | `cmd/olliesrv` | LLM providers (Anthropic, OpenAI/OpenRouter, Ollama, Gemini, Copilot, Kiro) |
| `session` | `cmd/olliesrv` | Session lifecycle, config, persistence |
| `fs` | `cmd/olliesrv` | 9P filesystem tree (virtfs-declared namespace, ctl dispatch) |
| `bypass` | `cmd/olliesrv` | Bypass broker (sandbox escape approval) |
| `toolclient` | `cmd/olliesrv` | Spawns and connects to toolsrv |
| `prompts` | `cmd/olliesrv` | Prompt template resolution |
| `registry` | `cmd/toolsrv` | Per-agent tool registry |
| `exec` | `cmd/toolsrv` | Sandboxed tool execution |
| `sandbox` | `cmd/toolsrv` | Landlock sandbox config and wrapper |
| `server` | `cmd/toolsrv` | 9P filesystem + proc management |
## Architecture
```mermaid
graph TB
subgraph "Frontends (all use o / ollie-9p)"
TUI["o tui<br>(tmux + o read/ctl)"]
KDE[KDE GUI<br>ollie-9p native client]
KATE[Kate plugin]
EMACS[Emacs<br>ellie.el · ollie-9p]
ACME[Plan 9 acme]
SCRIPTS[Shell scripts<br>o read · o ctl · o write]
end
subgraph "o CLI"
O["o<br>path resolution · ctl dispatch<br>prompt REPL · TUI composition"]
end
subgraph "olliesrv"
P9[9P Filesystem<br>session/ namespace]
SESS[session.Session<br>tool server conn · persistence]
AG[agent.Agent<br>loop · compaction<br>prompt assembly]
end
subgraph "toolsrv (separate process)"
TOOLS[9P Filesystem<br>ctl · tools · proc/]
EXEC[Tool Scripts]
end
subgraph "LLM Backends"
OLL[Ollama]
OAI[OpenAI / OpenRouter]
ANT[Anthropic]
COP[Copilot]
KIRO[Kiro]
GEM[Gemini]
end
TUI & SCRIPTS & ACME --> O
O --> P9
KDE & KATE & EMACS --> P9
P9 --> SESS
SESS --> AG
SESS -->|9P over Unix socket| TOOLS
AG -->|streaming| OLL & OAI & ANT & COP & KIRO & GEM
TOOLS --> EXEC
```
`olliesrv` exposes the agent runtime over a single surface: a 9P2000 filesystem.
`o` is the CLI layer that all text-based frontends build on — it handles path
resolution, context, and ctl dispatch. The KDE GUI and Kate plugin use `ollie-9p`
(the native 9P client) directly for performance. For a deep dive into the
filesystem, see [`doc/9p.md`](doc/9p.md).
## Credits
- [Plan 9 from Bell Labs](https://9fans.net) — for proving everything should be a file
- Dennis Ritchie — for the contract
- Ken Thompson — for the tools
- Rob Pike — for the network (and the editor)
- [Suckless](https://suckless.org) — for the conviction that good software comes from subtraction, not addition
- [@simonfxr](https://github.com/simonfxr) — asks "what if" through implementation; the observer agent, feed system, and half the good ideas trace back to his prototypes
- [@aws/amazon-q-developer-cli](https://github.com/aws/amazon-q-developer-cli) — for a solid open-source agent implementation to build on
## License
GPLv3