docs: update README and ARCHITECTURE to reflect current state
README: - Replace cascade/mechanical worker with route/tier-based routing - Replace plan-first discipline with per-agent 9P principals - Remove task tracking from tool list - Add tier-based routing and orchestrator/worker descriptions ARCHITECTURE: - Update tool scripts list (remove task_*, add route/escalate/lsp_*) - Rewrite sub-agents section: fire-and-forget callback protocol - Add u/cascade, u/escalate to script namespaces - Add per-agent 9P principals section (FUSE proxy, permission enforcement) - Mark mcpServers as optional
This commit is contained in:
parent
ace08d1d77
commit
4eddf55e54
|
|
@ -9,11 +9,11 @@ Ollie starts from a simple, slightly silly question: *What might an AI agent loo
|
|||
- **Parallel fan-out** — `s/bfg -parallel 4` spawns N agents on the same prompt and collects results
|
||||
- **Multi-agent workflows in plain shell** — create named sessions, pass prompts between them via files, coordinate with `statewait`; no framework or SDK
|
||||
- **Subagent delegation** — agents can fork ephemeral subagents that run independently and return results
|
||||
- **Model cascading for 90% cost reduction** — `cascade` delegates mechanical work to cheaper models, keeping expensive reasoning for high-level planning
|
||||
- **Orchestrator/worker system** — specialized agents for task decomposition (`orchestrator`) and mechanical execution (`worker`)
|
||||
- **Tier-based routing** — `route` dispatches subtasks to worker or expert models based on complexity; the orchestrator picks the tier, the system picks the backend/model
|
||||
- **Orchestrator/worker system** — specialized agents for task decomposition (`orchestrator`) and scoped execution (`worker`/`expert`); workers read code and reason about implementation within their assigned scope
|
||||
- **Any model, any backend** — Ollama (local), OpenAI, Anthropic, OpenRouter, GitHub Copilot, Kiro; switch per-session with one write
|
||||
- **Sandboxed execution** — every tool call runs inside a Landlock sandbox with configurable filesystem access
|
||||
- **Extensible via plain scripts** — drop executables into a directory and the agent picks them up; built-in tools cover file I/O, LSP (go-to-definition, references, rename, diagnostics), persistent memory, web search, browser screenshots, and task tracking
|
||||
- **Extensible via plain scripts** — drop executables into a directory and the agent picks them up; built-in tools cover file I/O, LSP (go-to-definition, references, rename, diagnostics), persistent memory, web search, and browser screenshots
|
||||
- **Domain skills** — teach the agent your project's conventions with a markdown file; loaded on demand
|
||||
- **AI code completion** — `u/complete` reads a prefix from stdin and prints the completion to stdout; plug it into any editor that can shell out
|
||||
- **Multiple frontends** — terminal (`s/sh`), acme (`ollie-acme` + `Kmpl`), Emacs (`ellie`), and a browser-based web UI; all talk to the same 9P server
|
||||
|
|
@ -21,7 +21,7 @@ Ollie starts from a simple, slightly silly question: *What might an AI agent loo
|
|||
- **Store federation** — point tools or transcripts at a remote 9P mount to share across machines
|
||||
- **Prompt optimization** — `u/optimize` generates N candidate prompts in parallel, then judges them to return the best one
|
||||
- **Automatic context compaction** — long conversations are summarized transparently when approaching the model's context limit
|
||||
- **Plan‑first discipline** — agents write checklists before acting, reducing wasted steps and improving reliability
|
||||
- **Per-agent 9P principals** — each agent session mounts the filesystem as its own user; 9P permission enforcement prevents self-prompting loops and enforces access boundaries
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Agent configs are JSON files in `~/.config/ollie/agents/`. The key fields are:
|
|||
|
||||
**`trustedTools`** — array of tool names allowed to run outside the sandbox.
|
||||
|
||||
**`mcpServers`** — MCP server configurations for external tool providers:
|
||||
**`mcpServers`** (optional) — MCP server configurations for external tool providers:
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -138,7 +138,7 @@ User-facing scripts are organized by the 9P namespace they are hosted under and
|
|||
| Namespace | Purpose | Scripts |
|
||||
|---|---|---|
|
||||
| `s/` | Session management and one-shot queries | `sh`, `ls`, `kill`, `cleanup`, `b`, `bfg`, `bbg` |
|
||||
| `u/` | Utility scripts; compositions of `s/` primitives | `optimize` |
|
||||
| `u/` | Utility scripts; compositions of `s/` primitives | `complete`, `optimize`, `cascade`, `escalate` |
|
||||
| `x/` | System exec and plugins | `elevate`, `elevate-adapter-*`, `bd`, `prime`, `freeloader`, `task` |
|
||||
|
||||
`s/b` is the core one-shot runner. `s/bfg` and `s/bbg` are thin wrappers: `s/bfg` blocks until the agent finishes and writes the result to stdout; `s/bbg` returns immediately and prints the session path. `u/` scripts have no special server backing — they are executable scripts that compose other namespaces via the filesystem.
|
||||
|
|
@ -147,21 +147,32 @@ User-facing scripts are organized by the 9P namespace they are hosted under and
|
|||
|
||||
All capabilities beyond `execute_code` itself are implemented as tool scripts in `OLLIE_TOOLS_PATH`, invoked via `{tool}` steps. The agent discovers available scripts via `s/{sid}/t/idx`.
|
||||
|
||||
Examples from the default install: `file_read`, `file_write`, `file_edit`, `file_glob`, `file_grep`, `memory_remember`, `memory_recall`, `reasoning_think`, `task_add`, `task_check`, `task_clear`, `denote_view`, `browser_screencap`, `subagent_spawn`.
|
||||
Examples from the default install: `file_read`, `file_write`, `file_edit`, `file_glob`, `file_grep`, `memory_remember`, `memory_recall`, `reasoning_think`, `lsp_definition`, `lsp_references`, `lsp_rename`, `lsp_symbols`, `lsp_diagnostics`, `lsp_hover`, `lsp_completion`, `route`, `cascade`, `escalate`, `subagent_generate`, `subagent_spawn`, `denote_view`, `browser_screencap`.
|
||||
|
||||
## Sub-agents
|
||||
|
||||
Sub-agents are implemented as a tool script (`subagent_spawn`) on top of the `s/` namespace. The script writes a session spec to `s/new`, blocks on `s/{id}/statewait` per job in background subshells, joins on all, and concatenates results. The `s/` namespace handles agent lifecycle, cancellation, and result storage.
|
||||
Sub-agents are implemented as tool scripts (`subagent_spawn`, `cascade`, `route`, `escalate`) on top of the `s/` namespace. Each script writes a session spec to `s/new`, waits for the session directory to appear, then submits a prompt. All are fire-and-forget: the parent continues immediately and receives results asynchronously when the child writes to `s/{parent_session_id}/prompt`.
|
||||
|
||||
For heterogeneous parallel delegation (N agents, N different prompts), a `{parallel:[...]}` stage composes with `subagent_spawn` — each parallel step is one shell invocation with a distinct prompt:
|
||||
**Routing and tiers**: `route` is the orchestrator's primary dispatch tool. It accepts `--tier=worker|expert` and `--backend=<name>`, resolving the model from `OLLIE_TIER_{WORKER|EXPERT}_{backend}` env vars. `cascade` and `escalate` are simpler variants with fixed tier semantics (cheap worker and strong expert respectively).
|
||||
|
||||
**Callback protocol**: when a sub-agent finishes, it writes a structured result to the parent's prompt file:
|
||||
|
||||
```
|
||||
execute_code {parallel} stage
|
||||
├── subagent_spawn "prompt A" → s/{id-0}/chat
|
||||
├── subagent_spawn "prompt B" → s/{id-1}/chat
|
||||
└── subagent_spawn "prompt C" → s/{id-2}/chat
|
||||
↓
|
||||
concatenated in submission order
|
||||
[from={session_id}]
|
||||
STATUS: done|error
|
||||
SUMMARY: <result>
|
||||
```
|
||||
|
||||
The parent receives this as its next queued turn — no polling, no blocking, no active waiting.
|
||||
|
||||
For heterogeneous parallel delegation (N agents, N different prompts), multiple `route`/`cascade` calls fan out concurrently (tool scripts are annotated `ollie:parallel read`):
|
||||
|
||||
```
|
||||
call_tool: calls=[
|
||||
{tool: "route", args: ["implement X in /src/a.go"]},
|
||||
{tool: "route", args: ["implement Y in /src/b.go"]},
|
||||
{tool: "route", args: ["redesign Z", "--tier=expert"]}
|
||||
]
|
||||
```
|
||||
|
||||
The architecture boundary is clean: `execute_code` is the only built-in tool in `core`; everything else is a tool script; `s/` is a 9P namespace. No layer knows about the others.
|
||||
|
|
@ -188,7 +199,15 @@ core := agent.NewAgentCore(agent.AgentCoreConfig{
|
|||
|
||||
## Session Lifecycle
|
||||
|
||||
`NewAgentCore` creates `/tmp/ollie/{sessionID}` when a session starts. `Core.Close()` removes it recursively. olliesrv calls `Close()` from `killSession` (individual session removal) and `Shutdown` (server stop — iterates all sessions). `SetSessionID` renames the tmpdir atomically alongside the persisted session files.
|
||||
### Per-Agent 9P Principals
|
||||
|
||||
Each agent session gets its own FUSE mount at `/tmp/ollie-mount-{sessionID}`, created by `ollie-9p-mount -u {sessionID}`. The session ID is used as the 9P user principal, so the server can enforce per-agent file permissions. The agent's `$OLLIE` env var points to this private mount — not the user's global mount.
|
||||
|
||||
This enables 9P permission enforcement: an agent cannot write to its own `prompt` file (preventing self-prompting loops), cannot read other agents' private state unless explicitly permitted, and cannot escalate its own privileges.
|
||||
|
||||
### Tmpdir and Cleanup
|
||||
|
||||
`NewAgentCore` creates `/tmp/ollie/{sessionID}` when a session starts. `Core.Close()` removes it recursively and tears down the FUSE mount. olliesrv calls `Close()` from `killSession` (individual session removal) and `Shutdown` (server stop — iterates all sessions). `SetSessionID` renames the tmpdir atomically alongside the persisted session files.
|
||||
|
||||
`!<cmd>` shell commands run in the session's current working directory (`Core.CWD()`), not the process working directory.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue