diff --git a/doc/architecture.md b/doc/architecture.md index 9ef042a..7ece908 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -1,104 +1,73 @@ # Ollie Architecture -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. +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`. -## Current system +## Boundaries -```text -9P clients - │ - ▼ -olliesrv ── sessions, agents, prompts, history, backends - │ - └─ authenticated 9P ── toolsrv ── registry, sandbox, processes - └─ executable or metadata-only tools +```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] ``` -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. +### `olliesrv` -## `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. -`olliesrv` constructs the `virtfs` tree and serves the Ollie namespace. It owns: +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. -- 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. +### Agent loop -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. +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 -`toolsrv` runs as a separate process. Its authenticated 9P namespace owns: +`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. -- 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. +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. -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. +## Deliberately unimplemented agent patterns -## 9P surface +Ollie deliberately does not build the following into the agent runtime: -The Ollie namespace exposes sessions and agents as files: +- **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. -| 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. +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. ## Documentation map -- [`architecture-9p.md`](architecture-9p.md) — 9P transport, namespace, clients, permissions, and lifecycle. +The architecture is split by responsibility: + +- [`architecture-9p.md`](architecture-9p.md) — public 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. -- [`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. +- [`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. \ No newline at end of file