diff --git a/doc/architecture.md b/doc/architecture.md index 7ece908..9ef042a 100644 --- a/doc/architecture.md +++ b/doc/architecture.md @@ -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. \ No newline at end of file +- [`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.