Refresh current architecture overview

This commit is contained in:
Ollie Agent 2026-08-16 20:48:39 +02:00
parent 5b621dccb8
commit a73f7ef5ca
1 changed files with 82 additions and 51 deletions

View File

@ -1,73 +1,104 @@
# 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`.
Ollie is a Go runtime built around a 9P filesystem. `olliesrv` owns the agent runtime and public control namespace. `toolsrv` is a separate 9P service for tool discovery and execution.
## Boundaries
## Current system
```mermaid
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]
```text
9P clients
│
▼
olliesrv ── sessions, agents, prompts, history, backends
│
└─ authenticated 9P ── toolsrv ── registry, sandbox, processes
└─ executable or metadata-only tools
```
### `olliesrv`
The filesystem is the integration boundary. Editors, shells, GUIs, scripts, and external automation use the same 9P namespace. They do not require a second API or a parallel session store.
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.
## `olliesrv`
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.
`olliesrv` constructs the `virtfs` tree and serves the Ollie namespace. It owns:
### Agent loop
- session and agent lifecycle;
- agent configuration, prompts, history, and context management;
- provider backend selection and model calls;
- the agent turn loop and internal session event bus;
- persistence and restoration of sessions; and
- the public 9P control surface.
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.
An agent turn streams a backend response, executes requested tools through `toolsrv`, appends results to history, and repeats until the turn completes, is interrupted, or reaches a configured limit. History compaction and hot/warm/cold tool-result handling are part of the agent runtime.
### Toolsrv
## `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.
`toolsrv` runs as a separate process. Its authenticated 9P namespace owns:
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.
- metadata discovery and host-specific variants;
- per-agent tool loading and registry revisions;
- executable and metadata-only command resolution;
- foreground and background process lifecycle;
- bounded output and result delivery;
- sandbox and Landlock/landrun policy; and
- bypass requests and approval state.
## Deliberately unimplemented agent patterns
The agent-side `ToolsrvConn` calls toolsrv over authenticated 9P. Tool implementations are not compiled into the agent loop. A session may use a local toolsrv or an SSH-forwarded remote toolsrv; the agent runtime remains local in either case.
Ollie deliberately does not build the following into the agent runtime:
## 9P surface
- **Native MCP client support.** Use executable or metadata-only tools. An external bridge can invoke an MCP client when required.
- **Embedded tool frameworks.** Tools live outside the agent loop; toolsrv owns discovery, loading, execution, sandboxing, and process state. See [`architecture-tools.md`](architecture-tools.md) and [`architecture-toolsrv.md`](architecture-toolsrv.md).
- **Plan-and-execute workflow engines.** Ollie does not own planners, task graphs, schedulers, retries, compensation, or durable workflow state. A system such as [Beads](https://github.com/steveyegge/beads) can expose those capabilities through a tool.
- **External coordination protocols.** Ollie does not expose a workflow engine, actor framework, master coordinator, or public message bus. It does have an internal session event bus for observers. External coordination uses sessions, agents, `prompt`, `chat`, `statewait`, `feed`, and `ctl`.
- **Separate frontend control planes.** UIs, editor integrations, shell clients, and automation are 9P clients. They do not maintain a parallel session store or frontend-specific API. See [`architecture-9p.md`](architecture-9p.md).
- **Distributed agent state.** Remote execution moves toolsrv and tool execution, not the agent loop, prompts, history, or model calls. See [`architecture-remote.md`](architecture-remote.md).
- **A competing memory store.** [OptMem](https://github.com/VictorTaelin/OptMem) owns persistent memory; Ollie exposes it through tools.
The Ollie namespace exposes sessions and agents as files:
All of these are **integration concerns, not built-in concerns**. External systems own their specialized state and semantics; toolsrv provides execution; Ollie provides the agent, sessions, prompts, and 9P observation/control surface. New behavior should first be expressed as a tool, a 9P file operation, a session, or a shell workflow before adding a runtime subsystem.
| Path | Use |
|---|---|
| `session/new` | Create a session. |
| `session/{sname}/agent/new` | Create an agent or child agent. |
| `session/{sname}/agent/{aname}/prompt` | Submit a prompt. |
| `session/{sname}/agent/{aname}/chat` | Read rendered chat. |
| `session/{sname}/agent/{aname}/chat.raw` | Read raw chat events. |
| `session/{sname}/agent/{aname}/statewait` | Block until agent state changes. |
| `session/{sname}/agent/{aname}/feed` | Deliver change-detected observer input. |
| `session/{sname}/agent/{aname}/ctl` | Control the agent. |
| `session/{sname}/agent/{aname}/proc/` | Inspect and control processes. |
| `generate` | Perform one-shot generation with `rdwr`. |
The namespace also exposes root metadata, backend/model listings, help, events, session controls, and agent configuration. See [`architecture-9p.md`](architecture-9p.md) for the complete namespace and client patterns.
A typical request is:
```text
client writes agent/.../prompt
→ olliesrv runs the agent turn
→ agent calls toolsrv when needed
→ toolsrv executes the selected tool
→ agent updates history and chat
→ client reads chat or waits on statewait
```
`feed` and `statewait` support observer and companion patterns without a separate observer service. A client can be a shell command, an editor extension, `ollie-gui`, a terminal, or another 9P client.
## Shared filesystem implementation
`virtfs` provides the declaration API and in-memory tree used to build the 9P namespaces. Ollie declares nodes with closure-based handlers and dynamic bindings, then passes the declaration to `virtfs.BuildTree`. The transport and namespace declaration remain separate.
## Configuration and external integrations
Backend credentials, endpoints, models, and compaction models are configured in `backends.conf`. Runtime paths follow XDG locations. Persistent memory is provided by [OptMem](https://github.com/VictorTaelin/OptMem) through tools.
Remote execution moves toolsrv and tool execution to another host through SSH-forwarded authenticated 9P. The agent loop, prompts, history, and model calls stay local. See [`architecture-remote.md`](architecture-remote.md).
Editors and other clients integrate by obtaining context, writing an agent prompt, and using any convenient client for observation and control. See [`architecture-ide.md`](architecture-ide.md).
## Deliberate boundaries
Ollie does not embed MCP, a tool framework, a planner/executor engine, a task graph, a scheduler, a public coordination bus, a frontend control plane, distributed agent state, or a competing memory store. These are integration concerns. External systems provide their specialized state and semantics through tools, sessions, scripts, and 9P.
## Documentation map
The architecture is split by responsibility:
- [`architecture-9p.md`](architecture-9p.md) — public 9P transport, namespace, clients, permissions, and lifecycle.
- [`architecture-9p.md`](architecture-9p.md) — 9P transport, namespace, clients, permissions, and lifecycle.
- [`architecture-core.md`](architecture-core.md) — agent loop, sessions, history, backends, hooks, and concurrency.
- [`architecture-prompting.md`](architecture-prompting.md) — prompt resolution and runtime preamble assembly.
- [`architecture-tools.md`](architecture-tools.md) — tool metadata and authoring, including metadata-only tools.
- [`architecture-toolsrv.md`](architecture-toolsrv.md) — tool registry, 9P service, process execution, sandbox, and cancellation.
- [`architecture-remote.md`](architecture-remote.md) — SSH deployment of a remote toolsrv.
- [`architecture-virtfs.md`](architecture-virtfs.md) — the declaration DSL and in-memory filesystem tree.
- [`architecture-kde.md`](architecture-kde.md) — KDE/Qt clients and integration.
- [`architecture-ide.md`](architecture-ide.md) — Acme and Kate coding workflows.
## 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](https://github.com/VictorTaelin/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.
- [`architecture-tools.md`](architecture-tools.md) — tool metadata and authoring.
- [`architecture-toolsrv.md`](architecture-toolsrv.md) — tool registry, execution, sandbox, and cancellation.
- [`architecture-remote.md`](architecture-remote.md) — remote toolsrv deployment.
- [`architecture-virtfs.md`](architecture-virtfs.md) — filesystem declarations and tree construction.
- [`architecture-kde.md`](architecture-kde.md) — KDE/Qt clients.
- [`architecture-ide.md`](architecture-ide.md) — editor integration patterns and examples.