6.8 KiB
Ollie Architecture
Ollie is a small Go runtime whose integration boundary is a 9P filesystem. The current architecture has one control-plane service, olliesrv, and a separate tool-execution service, toolsrv.
Boundaries
flowchart TB
C[9P clients and frontends] --> S[olliesrv]
S --> F[fs.Tree and session namespace]
S --> A[agent loop]
A --> B[provider backend]
A --> T[toolsrv]
T --> R[tool registry]
T --> X[landrun / Landlock sandbox]
T --> P[bypass broker]
olliesrv
The daemon constructs an fs.Tree. The tree is the session collection; there is no separate manager abstraction. Session operations are package functions over the tree. A session owns its agents, context, cancellation, and lifecycle. An agent owns history and runs the model/tool loop.
The daemon exposes the 9P namespace directly. Reads and writes are the protocol: writing session/new creates a session, writing an agent's prompt submits work, reading chat observes history, and reading statewait blocks until a state transition.
Agent loop
The loop resolves system and user prompts, renders context, calls the configured backend, parses streamed responses, executes requested tools, appends results to history, and repeats. context.Context cancellation flows from the daemon through the session and agent. Context management handles token statistics, output limits, retries, and compaction.
Toolsrv
toolsrv is a separate process connected through 9P. It owns tool discovery, metadata, lazy registry loading, process lifecycle, output streaming, and sandbox invocation. Tool implementations are installed executables or scripts; they are not compiled into the agent loop. The same service can expose local and remotely deployed tools.
The tool namespace also provides process and sandbox state. Normal execution is restricted by configured Landlock/landrun policy. The bypass broker is a policy-controlled path for explicitly approved operations outside that policy.
Deliberately unimplemented agent patterns
Ollie keeps the core small by refusing several common framework boundaries. The filesystem, external tools, and ordinary processes already provide the required primitives.
No MCP client layer
Ollie does not implement native Model Context Protocol support. MCP adds a JSON-RPC client, transport and initialization handshake, server configuration, connection lifecycle, and another tool adapter. Ollie already has:
| MCP concern | Ollie primitive |
|---|---|
| Structured tool discovery | .meta files and the toolsrv registry |
| Tool invocation | JSON on stdin, stdout, exit status, and toolsrv process files |
| Typed schemas | .meta JSON Schema and tool prompt documentation |
| Subprocess lifecycle | toolsrv and its sandbox |
| Server composition | executable or metadata-only tools |
An MCP server can remain an optional external dependency. A bridge tool can invoke an MCP client CLI when interoperability is required, without making MCP part of the agent runtime.
No embedded tool framework
Capabilities are not compiled into the agent loop as provider-specific or framework-specific tool objects. Tool behavior lives in external executables or metadata-only commands, and toolsrv owns discovery, loading, execution, sandboxing, and process state. See architecture-tools.md and architecture-toolsrv.md.
No external coordination protocol
Ollie does not expose a workflow engine, message bus, actor framework, or master coordinator as an external integration boundary. The runtime does contain an internal session event bus for agent and session observers; it is an implementation detail, not a public coordination API. External multi-agent coordination uses sessions, agents, prompt, chat, statewait, feed, and ctl files. Hub-and-spoke, pipeline, scatter-gather, peer, reactive, and self-directed workflows are scripts or agent conventions over those files.
No separate frontend control plane
UIs, editor integrations, shell clients, and automation are 9P clients. They do not maintain a parallel session store or call a frontend-specific API. The public namespace is documented in architecture-9p.md.
No hidden distributed state layer
Remote execution does not replicate the agent runtime or introduce a second RPC model. The agent loop, prompts, history, and model calls stay local; only toolsrv and tool execution move to the remote host over SSH-forwarded authenticated 9P. See architecture-remote.md.
No competing memory store
Persistent memory is owned by OptMem. Ollie exposes memory through tools rather than maintaining a second memory database or synchronization layer.
These omissions are deliberate composition choices, not missing extension points. New behavior should first be expressed as a tool, a 9P file operation, a session, or a shell workflow before adding a new runtime subsystem.
Documentation map
The architecture is split by responsibility:
architecture-9p.md— public 9P transport, namespace, clients, permissions, and lifecycle.architecture-core.md— agent loop, sessions, history, backends, hooks, and concurrency.architecture-prompting.md— prompt resolution and runtime preamble assembly.architecture-tools.md— tool metadata and authoring, including metadata-only tools.architecture-toolsrv.md— tool registry, 9P service, process execution, sandbox, and cancellation.architecture-remote.md— SSH deployment of a remote toolsrv.architecture-virtfs.md— the declaration DSL and in-memory filesystem tree.
Configuration and data
Installed runtime data includes backend configuration, agent definitions, prompt templates, skills, and tool executables. Backend credentials, endpoints, models, and compaction models are configured in backends.conf. Runtime paths follow XDG configuration and data locations. OptMem owns persistent memory storage; memory tools call it directly.
Multi-agent operation
subagent_spawn creates child agents with independent runtime state. Cascade-style fan-out and observer/feed agents are orchestration patterns built on the same session and 9P primitives, not a second agent runtime. Parent and child sessions exchange prompts and results through files.
Design constraints
The stable integration boundary is the 9P namespace and its blocking read/write behavior. Provider selection, prompt assembly, tool discovery, sandboxing, remote execution, and user interfaces are replaceable boundaries documented separately.