ollie is a 9p-based generative agent surface
Go to file
Ollie Agent 8b62c8e8ce remove dbus from pull.sh 2026-07-27 18:04:19 +02:00
.beads agents: extract prompts to markdown, assemble via executable prompt 2026-04-26 15:00:46 +02:00
.kiro/settings sandbox: fix regression from simplification 2026-04-21 21:09:33 +02:00
9p@4a60edc893 9p+kde: emoji reaction buttons in kf5 gui 2026-07-27 15:33:38 +02:00
acme@6d0386b654 acme: update submodule (fix Del passthrough bug) 2026-07-20 14:08:02 +02:00
agents agents: fix prompt paths, remove stale tool prompt references 2026-07-21 14:19:13 +02:00
contrib ollie: remove daemon subcommands, centralize service file management 2026-07-25 18:20:26 +02:00
core@96a140a83c core+9p: emoji reactions on assistant messages 2026-07-27 15:19:56 +02:00
doc ollie: remove daemon subcommands, centralize service file management 2026-07-25 18:20:26 +02:00
el@4f7a22c29a ollie: remove daemon subcommands, centralize service file management 2026-07-25 18:20:26 +02:00
experiments Clarify Identity-Specific Rigor description 2026-05-02 14:30:21 +02:00
httpgw@52208eb031 fix CreateSession: add remote parameter to D-Bus method 2026-07-24 11:58:34 +02:00
kde@16364e52b0 kde: kf6 reaction buttons + sloppy focus fix 2026-07-27 15:48:50 +02:00
prompts ollie-9p: rename binary + update all prompt references 2026-07-27 11:44:58 +02:00
remote@6fc48bf5dd remote exec: streaming output notifications 2026-07-19 21:06:13 +02:00
sandbox another sandbox tweak 2026-07-17 15:17:30 +02:00
scripts cleanup: remove superpowerd references from codebase 2026-07-27 10:57:09 +02:00
services ollie: remove daemon subcommands, centralize service file management 2026-07-25 18:20:26 +02:00
skills move prompts/ and skills/ to repo root 2026-07-19 12:08:15 +02:00
tools migrate from FUSE mounts to 9p client 2026-07-27 11:42:02 +02:00
webui@2be54a850b fix CreateSession: add remote parameter to D-Bus method 2026-07-24 11:58:34 +02:00
.gitignore gitignore: add __pycache__ 2026-04-29 10:17:28 +02:00
.gitmodules remove dbus submodule, update docs for -no9p mode 2026-07-21 11:44:38 +02:00
.gitmodules~ kf5 corrections, remote is broken 2026-07-20 10:25:43 +02:00
AGENTS.md docs: add ollie-remote to README and AGENTS.md 2026-07-19 18:22:38 +02:00
Containerfile add remote access via TCP: Containerfile, mount subcommand, docs 2026-04-16 23:32:37 +02:00
README.md ollie: remove daemon subcommands, centralize service file management 2026-07-25 18:20:26 +02:00
justfile remove ollie-9p-mount (FUSE inlined into olliesrv) 2026-07-27 11:52:04 +02:00
pull.sh remove dbus from pull.sh 2026-07-27 18:04:19 +02:00

README.md

ollie

Ollie is an AI agent runtime. A small Go core handles the agent loop, tool dispatch, sandboxing, and multi-backend routing; frontends (terminal, acme, Emacs, KDE, browser) and orchestration (shell scripts, multi-agent workflows, cron) are external. The core is deliberately minimal — capabilities come from composing small pieces rather than building a monolithic framework.

Getting started

Clone with submodules:

git clone --recurse-submodules https://git.lneely.de/lkn/ollie.git

Or after cloning:

git submodule update --init --recursive

Build and install:

just         # builds core, 9p, acme, kde, httpgw, webui, emacs

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_TOOLS_PATH=~/.config/ollie/tools    # directory for tool scripts ({tool} steps)
OLLIE_MEMORY_PATH=~/.config/ollie/memory  # directory for memory files (ollie/m)
OLLIE_ELEVATE_SOCKET=${XDG_RUNTIME_DIR}/ollie/elevate.sock  # socket path for x/elevate adapter
OLLIE_COMPLETE_BACKEND=ollama             # backend for u/complete (required)
OLLIE_COMPLETE_MODEL=qwen3:latest         # model for u/complete (required)
OLLIE_ENABLED_BACKENDS=openrouter,kiro  # backends available for routing (comma-separated)

# /route file configuration
OLLIE_ROUTE_BACKEND=ollama               # backend for the classifier model
OLLIE_ROUTE_MODEL=qwen3:8b               # model that classifies task complexity

Shell environment variables take precedence over the env file.

Development

Pull latest across all submodules:

./pull.sh

Run tests:

just test

Repository layout

Monorepo with Git submodules. Each submodule has its own Go module (except el which is Elisp and kde which is C++/Qt).

Directory Language Description
core/ Go Core library: agent loop, backends, tools, config, sandbox
9p/ Go 9P filesystem server (olliesrv)
remote/ Go Remote execution server (ollie-remote) for split-brain SSH mode
acme/ Go Plan 9 acme editor frontend
httpgw/ Go HTTP-to-9P gateway (ollie-httpgw)
webui/ TypeScript Preact SPA browser frontend
kde/ C++/Qt6 KDE integration: plasmoid, standalone GUI, Kate plugin, KRunner, tray
el/ Elisp Emacs frontend (ellie.el)
agents/ JSON Agent config files (loaded at runtime)
prompts/ Markdown System prompt templates
tools/ Python/Bash Tool scripts (file_read, lsp_, memory_, etc.)
scripts/ Shell User-facing CLI scripts: session management, utilities, plumbing
sandbox/ YAML Landlock sandbox config
doc/ Markdown Architecture docs, usage guide
contrib/ Mixed Community scripts
experiments/ Mixed Trial notes

Features

Sessions

  • Create / kill / rename / list — full lifecycle management of concurrent agent sessions
  • Prompt submission with FIFO queue — prompts are queued and processed in order; multiple clients can submit without conflicts
  • State observation — each session exposes its current state (idle, thinking, calling: <tool>) with a blocking-wait primitive for efficient polling
  • Chat streaming — stream model output in real time via file tail or D-Bus signal
  • Session persistence — active sessions survive server restarts; state is checkpointed to ~/.local/share/ollie/sessions/
  • Plan / scratchpad — per-session markdown checklist that survives context compaction and is visible to peer agents
  • Environment inspection — read the effective environment variables for any session

Agent loop

  • Streaming tool calls — the core runs a turn loop: prompt the model, parse tool calls, dispatch them (in parallel where safe), feed results back, repeat until done
  • Automatic context compaction — long conversations are summarized transparently when approaching the context limit
  • System prompt templating — prompts are rendered from markdown templates with variable substitution; inspect the fully rendered prompt at any time

Backends

  • Multi-backend routing — Ollama (local), OpenAI-compatible, Anthropic, GitHub Copilot, Kiro; switch backends per-session
  • Model listing and switching — enumerate available models from any backend; switch models mid-session
  • Connection pooling — all sessions sharing the same API host multiplex over a single HTTP/2 connection; no redundant TLS handshakes
  • 24-hour model cache — model lists are cached at the backend level to avoid repeated API calls

Tools and sandboxing

  • Sandboxed execution — every tool call runs inside a Landlock sandbox with per-profile filesystem access rules
  • Extensible tools — tools are executable scripts with header metadata; add one by dropping a file in a directory
  • Elevation — commands that need to escape the sandbox can request elevation through a streaming protocol (frame-based, over unix socket)

Agents

  • Agent definitions — JSON configs that set personality, tools, backend preferences, and constraints
  • List and switch — enumerate available agents and assign one to any session

Multi-agent

  • Peer communication — bidirectional links between sessions; peers can submit prompts to each other
  • Orchestrator/worker patterns — subagent delegation, parallel fan-out, coordinated through session primitives
  • Domain skills — teach the agent your project’s conventions with a markdown file; loaded on demand

Background processes

  • Detach — start a long-running command and immediately background it; the agent continues working
  • Monitor — list running processes, read their output (64KB ring buffer), check status
  • Signal and dismiss — send TERM/KILL to a detached process; remove finished processes from the list

Remote execution (split-brain)

  • Local brain, remote hands — the agent loop and LLM streaming stay local; tool execution happens on a remote host over SSH
  • Zero-setup deployment — ollie-remote is bootstrapped automatically on first connect (binary + tools cached by hash)
  • Streaming output — real-time command output over the SSH channel; builds and tests display as they run
  • Session persistence — remote sessions survive server restarts; reconnect automatically on restore
  • Sandboxed remotely — Landlock enforcement runs on the remote host; landrun is shipped alongside the binary
  • Convention over configuration — sensible sandbox defaults; per-project overrides via .ollie-sandbox.yaml in the project root
  • GUI works unchanged — D-Bus signals fire locally, so KDE GUI / web UI see real-time progress

The split-brain model complements 9P's network transparency. 9P mounts a remote agent as a local filesystem (remote brain, local view); split-brain keeps the brain local and sends execution remote (local brain, remote hands). Use 9P for monitoring fleets of headless agents; use split-brain for interactive development on remote hosts.

9P remote mount:       you ──9P──▶ remote olliesrv ──▶ remote tools
Split-brain:           local olliesrv ──SSH──▶ remote ollie-remote ──▶ remote tools

See doc/REMOTE_EXECUTION.md for the design.

Stateless endpoints

  • Code completion — write cursor context (prefix, suffix, file path), read back code to insert; works from any editor or script
  • One-shot generation — write a prompt, read back a full LLM response; no session, no agent loop, no tools; scriptable from any language
  • Task routing — write a task description, the system classifies complexity against all available models and returns the best backend+model for the job

Frontends

  • Terminal — interactive CLI (b, bfg, sh)
  • Plan 9 acme — editor integration for acme
  • Emacs — ellie.el package
  • KDE — plasmoid, standalone GUI, Kate plugin, KRunner, system tray
  • Web UI — Preact SPA served by the HTTP gateway

Configuration

  • Per-session config — backend, model, agent, generation parameters; all readable and writable at runtime

Architecture

olliesrv is a single binary that operates in three modes:

Mode Flags Interface Frontends
+9p +dbus (default) 9P filesystem + D-Bus signals All (terminal, acme, Emacs, KDE, web)
+9p -dbus -nodbus 9P filesystem only Terminal, acme, Emacs, web
-9p +dbus -no9p D-Bus only KDE (plasmoid, GUI, Kate, KRunner, tray)

All modes embed the same core library and session manager. The 9P and D-Bus interfaces are thin adapters over the shared session pool.


9P: everything is a file

The 9P server exposes the agent runtime as a synthetic filesystem. Every session is a directory; every operation is a read or write. In default mode, it also embeds a D-Bus adapter on org.ollie.SessionManager that streams StateChanged, ChatUpdated, and lifecycle signals to desktop clients.

There is no client library, no SDK, no protocol buffer — echo, cat, tail, and rm are the API.

# Create a session
echo "name=worker" > /mnt/ollie/s/new

# Submit a prompt
echo "fix the bug in main.go" > /mnt/ollie/s/worker/prompt

# Stream the response
tail -f /mnt/ollie/s/worker/chat

# Check state
cat /mnt/ollie/s/worker/state

# Kill a background process
echo "signal 12345 TERM" > /mnt/ollie/s/worker/ctl

# Get completions
echo '{"language":"go","code":"func he"}' > /mnt/ollie/s/worker/complete
cat /mnt/ollie/s/worker/complete

# One-shot generation (no session needed)
exec 3<>/mnt/ollie/generate; echo 'explain monads in one sentence' >&3; cat <&3; exec 3>&-

# Route a task to the best model
exec 3<>/mnt/ollie/route; echo 'redesign the auth system' >&3; cat <&3; exec 3>&-
# → backend=kiro model=claude-sonnet-4-20250514

Network transparency

9P is a network protocol. Mount the agent filesystem from any machine on the network:

9pfuse 'tcp!server:5640' /mnt/ollie

No SSH tunneling, no port forwarding for individual endpoints, no API gateway. One mount and every session, every tool, every config value is accessible as if local.

Container and headless deployment

The 9P server embeds the core library directly — no display server, no desktop dependencies. It runs anywhere a Go binary runs: containers, cloud VMs, CI runners, embedded systems.

The embedded D-Bus adapter is automatically disabled when using -tcp (remote listen mode). You can also disable it explicitly with -nodbus:

olliesrv -tcp :5640          # TCP listener, no D-Bus (implied)
olliesrv -nodbus             # Unix socket only, no D-Bus

Shell composability

Because operations are file I/O, they compose with the entire Unix toolkit:

# Fan out a prompt to all sessions
for s in /mnt/ollie/s/*/prompt; do echo "run tests" > "$s"; done

# Wait for all agents to finish
for s in /mnt/ollie/s/*/statewait; do cat "$s" > /dev/null; done

# Grep all agent plans
grep -r "TODO" /mnt/ollie/s/*/plan

# Monitor costs
paste /mnt/ollie/s/*/cost

Pipe agents into awk. Filter with grep. Schedule with cron. Orchestrate with a 10-line shell script instead of a framework.

Multiplexing

Multiple clients — terminals, editors, scripts, other agents — can mount the same server simultaneously. Each gets an independent view through 9P’s per-fid state model. No connection pools, no session affinity, no WebSocket juggling.

Plan 9 patterns

The design follows Plan 9 conventions directly:

  • /net/dns pattern — /complete, /generate, and /route are stateless per-fid: write a request, read back the result, like a DNS lookup
  • ctl files — control operations (stop, kill, rename, compact) are writes to a control file, not method calls
  • Blocking reads — statewait blocks until state changes, replacing event subscriptions with a simple cat

D-Bus: desktop integration

The D-Bus interface (org.ollie.SessionManager) is embedded in olliesrv (enabled by default, or exclusively via -no9p). The KDE frontends connect to it over the session bus.

Typed method calls

D-Bus gives you introspectable, typed interfaces with proper error returns. No string parsing, no exit codes to check:

# Create a session
dbus-send --session --dest=org.ollie.SessionManager --type=method_call --print-reply \
  /org/ollie/SessionManager org.ollie.SessionManager.CreateSession \
  string:"$PWD" string:"" string:"" string:"default" string:"" string:""

# Submit a prompt
dbus-send --session --dest=org.ollie.SessionManager --type=method_call \
  /org/ollie/SessionManager org.ollie.SessionManager.Submit \
  string:"SESSION_ID" string:"fix the bug in main.go"

# Read state
dbus-send --session --dest=org.ollie.SessionManager --type=method_call --print-reply \
  /org/ollie/SessionManager org.ollie.SessionManager.GetState \
  string:"SESSION_ID"

Real-time signals

D-Bus signals push events to subscribers without polling:

  • ChatUpdated — new chat output (session_id, offset, text)
  • StateChanged — transition notifications (idle → thinking → calling: grep → idle)
  • SessionCreated / SessionKilled / SessionRenamed — lifecycle events for UIs
  • ProcessDetached / ProcessExited — background process events

GUI frontends subscribe once and react to changes — no timers, no file watches, no busy loops.

KDE integration

The D-Bus interface is what makes native desktop integration possible:

  • Plasmoid — embed an agent chat widget directly in the Plasma panel
  • Kate plugin — inline AI assistance in the text editor
  • KRunner — launch prompts from the desktop search bar
  • System tray — status indicator and quick actions
  • Standalone GUI — full-featured Qt6 chat application

All of these talk to org.ollie.SessionManager over D-Bus using Qt's native bindings — no IPC glue code, no subprocess management.

Tool documentation lookup

# Query a tool's full prompt/documentation
exec 3<>/mnt/ollie/tools; echo 'file_edit' >&3; cat <&3; exec 3>&-

Credits

Many sources of inspiration:

  • 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, and other nifty ideas
  • @aws — for a solid open-source agent implementation

License

GPLv3