docs: update README and usage for current architecture
This commit is contained in:
parent
23f3a6092b
commit
31d550a94b
55
README.md
55
README.md
|
|
@ -53,15 +53,15 @@ Everything lives under `$XDG_CONFIG_HOME/ollie/` (default: `~/.config/ollie/`)
|
||||||
|
|
||||||
| Capability | How |
|
| Capability | How |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **CLI** | `o` — unified namespace CLI: `read`, `write`, `ls`, `ctl`, `prompt`, `tui`, `env`, `generate` |
|
| **CLI** | `o` — unified namespace CLI: `read`, `write`, `ls`, `new`, `ctl`, `prompt`, `tui`, `env`, `generate` |
|
||||||
| **Terminal TUI** | `o tui` — tmux layout, no widgets |
|
| **Terminal TUI** | `o tui` — tmux layout, no widgets |
|
||||||
| **One-shot LLM** | `o generate "explain monads"` or `echo "prompt" \| o generate` |
|
| **One-shot LLM** | `o generate "explain monads"` or `echo "prompt" \| o generate` |
|
||||||
| **Run an agent** | Create a session + agent via 9P — then connect with any frontend ([ellie](doc/ellie.md), KDE (GUI/KRunner/Kate), `o tui`) |
|
| **Run an agent** | Create a session + agent via 9P — then connect with any frontend ([ellie](doc/ellie.md), KDE (GUI/KRunner/Kate), acme, `o tui`) |
|
||||||
| **Remote execution** | Set `remote=user@host` in session config |
|
| **Remote execution** | Set `remote=user@host` in session config |
|
||||||
| **Background processes** | Pass `"background": true` to any tool — runs with no timeout, output pushed to agent prompt on completion |
|
| **Background processes** | Pass `"background": true` to any tool — runs with no timeout, output pushed to agent prompt on completion |
|
||||||
| **Parallel execution** | Non-conflicting tool calls within a turn run in parallel (scope-based conflict scheduling) |
|
| **Parallel execution** | Non-conflicting tool calls within a turn run in parallel (scope-based conflict scheduling) |
|
||||||
| **Agents** | Write a JSON config in `data/agents/` with agent prompt in `data/prompts/` |
|
| **Agents** | Write a JSON config in `~/.config/ollie/agents/` with agent prompt in `~/.config/ollie/prompts/` |
|
||||||
| **Tools** | Drop an executable + `.meta` in `~/.config/ollie/tools/` — load at runtime via `/tool_load` |
|
| **Tools** | Drop an executable + `.meta` in `~/.config/ollie/tools/` — load at runtime via `tool_load` |
|
||||||
| **Domain skills** | Load markdown skill modules at runtime |
|
| **Domain skills** | Load markdown skill modules at runtime |
|
||||||
|
|
||||||
## Repository layout
|
## Repository layout
|
||||||
|
|
@ -70,28 +70,42 @@ Single Go module with one Git submodule (kde).
|
||||||
|
|
||||||
| Directory | Language | Description |
|
| Directory | Language | Description |
|
||||||
|-----------|----------|-------------|
|
|-----------|----------|-------------|
|
||||||
| `agent/` | Go | Agent loop, history, prompt resolution, context compaction |
|
|
||||||
| `backend/` | Go | LLM providers (Anthropic, OpenAI, Ollama, Gemini, Copilot, CodeWhisperer) |
|
|
||||||
| `toolsrv/` | Go | Tool server client library (9P client for toolsrv) |
|
|
||||||
| `cmd/toolsrv/` | Go | Tool execution server (separate 9P server, sandboxed execution) |
|
|
||||||
| `tools/lsp/` | Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
|
|
||||||
| `session/` | Go | Session lifecycle, config, persistence |
|
|
||||||
| `fs/` | Go | 9P filesystem tree (EDSL-declared namespace, ctl dispatch) |
|
|
||||||
| `fsedsl/` | Go | Filesystem declaration EDSL (generic, reusable) |
|
|
||||||
| `bypass/` | Go | Bypass broker (sandbox escape approval) |
|
|
||||||
| `sandbox/` | Go | Landlock sandbox config |
|
|
||||||
| `lib9p/` | Go | 9P protocol library + native C client |
|
|
||||||
| `cmd/olliesrv/` | Go | The main server binary (session/agent 9P namespace) |
|
| `cmd/olliesrv/` | Go | The main server binary (session/agent 9P namespace) |
|
||||||
| `cmd/toolsrv/` | Go | Tool execution server (spawned by olliesrv, separate 9P server) |
|
| `cmd/toolsrv/` | Go | Tool execution server (separate 9P server, sandboxed execution) |
|
||||||
| `cmd/ollie-9p/` | Go | 9P client CLI |
|
| `cmd/ollie-9p/` | Go | 9P client CLI |
|
||||||
| `cmd/ollie-remote/` | Go | Remote execution binary |
|
| `toolsrv/` | Go | Tool server client library + tool discovery (9P client for toolsrv) |
|
||||||
|
| `virtfs/` | Go | Filesystem declaration EDSL (generic, reusable) |
|
||||||
|
| `lib9p/` | Go | 9P protocol library + native C client |
|
||||||
|
| `tools/lsp/` | Go | LSP bridge daemon + client library (gopls, clangd, intelephense) |
|
||||||
|
| `env/` | Go | Environment variable defaults |
|
||||||
|
| `format/` | Go | Output formatting |
|
||||||
|
| `log/` | Go | Structured logging |
|
||||||
|
| `paths/` | Go | XDG path resolution |
|
||||||
| `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner *(submodule)* |
|
| `kde/` | C++/Qt6 | KDE plasmoid, GUI, Kate plugin, KRunner *(submodule)* |
|
||||||
| `data/agents/` | JSON | Agent configs |
|
| `contrib/elisp/` | Emacs Lisp | ellie.el — Emacs frontend |
|
||||||
|
| `data/agents/` | JSON | Agent configs (installed to `~/.config/ollie/agents/`) |
|
||||||
| `data/prompts/` | Markdown | System prompt templates |
|
| `data/prompts/` | Markdown | System prompt templates |
|
||||||
| `data/tools/` | Mixed | Tool executables (scripts + compiled) + `.meta` sidecar files |
|
| `data/tools/` | Mixed | Tool executables (scripts + compiled) + `.meta` sidecar files |
|
||||||
| `data/skills/` | Markdown | Domain knowledge modules |
|
| `data/skills/` | Markdown | Domain knowledge modules |
|
||||||
|
| `data/scripts/` | Shell | CLI scripts (`o`, `ollie-remount`, acme helpers) |
|
||||||
| `doc/` | Markdown | Architecture docs, usage guide |
|
| `doc/` | Markdown | Architecture docs, usage guide |
|
||||||
|
|
||||||
|
### Internal packages (not importable outside their command)
|
||||||
|
|
||||||
|
| Package | Parent | Description |
|
||||||
|
|---------|--------|-------------|
|
||||||
|
| `agent` | `cmd/olliesrv` | Agent loop, history, prompt resolution, context compaction |
|
||||||
|
| `backend` | `cmd/olliesrv` | LLM providers (Anthropic, OpenAI/OpenRouter, Ollama, Gemini, Copilot, Kiro) |
|
||||||
|
| `session` | `cmd/olliesrv` | Session lifecycle, config, persistence |
|
||||||
|
| `fs` | `cmd/olliesrv` | 9P filesystem tree (virtfs-declared namespace, ctl dispatch) |
|
||||||
|
| `bypass` | `cmd/olliesrv` | Bypass broker (sandbox escape approval) |
|
||||||
|
| `toolclient` | `cmd/olliesrv` | Spawns and connects to toolsrv |
|
||||||
|
| `prompts` | `cmd/olliesrv` | Prompt template resolution |
|
||||||
|
| `registry` | `cmd/toolsrv` | Per-agent tool registry |
|
||||||
|
| `exec` | `cmd/toolsrv` | Sandboxed tool execution |
|
||||||
|
| `sandbox` | `cmd/toolsrv` | Landlock sandbox config and wrapper |
|
||||||
|
| `server` | `cmd/toolsrv` | 9P filesystem + proc management |
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
|
|
@ -126,6 +140,7 @@ graph TB
|
||||||
ANT[Anthropic]
|
ANT[Anthropic]
|
||||||
COP[Copilot]
|
COP[Copilot]
|
||||||
KIRO[Kiro]
|
KIRO[Kiro]
|
||||||
|
GEM[Gemini]
|
||||||
end
|
end
|
||||||
|
|
||||||
TUI & SCRIPTS & ACME --> O
|
TUI & SCRIPTS & ACME --> O
|
||||||
|
|
@ -135,7 +150,7 @@ graph TB
|
||||||
SESS --> AG
|
SESS --> AG
|
||||||
SESS -->|9P over Unix socket| TOOLS
|
SESS -->|9P over Unix socket| TOOLS
|
||||||
|
|
||||||
AG -->|streaming| OLL & OAI & ANT & COP & KIRO
|
AG -->|streaming| OLL & OAI & ANT & COP & KIRO & GEM
|
||||||
|
|
||||||
TOOLS --> EXEC
|
TOOLS --> EXEC
|
||||||
```
|
```
|
||||||
|
|
@ -156,4 +171,4 @@ filesystem, see [`doc/9p.md`](doc/9p.md).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
GPLv3
|
GPLv3
|
||||||
|
|
|
||||||
166
doc/usage.md
166
doc/usage.md
|
|
@ -32,20 +32,21 @@ Valid levels: `debug`, `info`, `warn`, `error`.
|
||||||
## `o` — Terminal CLI
|
## `o` — Terminal CLI
|
||||||
|
|
||||||
`o` is a multi-call shell script that wraps the 9P namespace into a human-friendly interface.
|
`o` is a multi-call shell script that wraps the 9P namespace into a human-friendly interface.
|
||||||
Installed to `~/bin/o` by `just install-data`.
|
Installed to `~/.local/bin/o` by `just install-data`.
|
||||||
|
|
||||||
### Quick start
|
### Quick start
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
eval $(o env myproject default) # set session + agent context
|
o new myproject # create a session
|
||||||
o prompt # interactive prompt REPL
|
o myproject new default # create an agent in that session
|
||||||
|
o myproject/default tui # launch the tmux TUI
|
||||||
```
|
```
|
||||||
|
|
||||||
In another terminal:
|
Or without the TUI:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
eval $(o env myproject default)
|
o myproject/default prompt # interactive prompt REPL (one terminal)
|
||||||
o read chat # stream chat output
|
o myproject/default read chat # stream chat output (another terminal)
|
||||||
```
|
```
|
||||||
|
|
||||||
<table align="center" width="90%">
|
<table align="center" width="90%">
|
||||||
|
|
@ -61,59 +62,70 @@ o read chat # stream chat output
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
### Context model
|
||||||
|
|
||||||
|
Context is determined by the first argument — not by environment variables:
|
||||||
|
|
||||||
|
```
|
||||||
|
o <cmd> Root level (no context)
|
||||||
|
o <session> <cmd> Session level
|
||||||
|
o <session>/<agent> <cmd> Agent level
|
||||||
|
```
|
||||||
|
|
||||||
|
The slash in `<session>/<agent>` disambiguates session-only from session+agent.
|
||||||
|
If no command follows the context, `o` defaults to `ls`.
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Context | Description |
|
||||||
|---|---|
|
|---|---|---|
|
||||||
| `o prompt` | Interactive multi-line prompt REPL |
|
| `o ls` | root | List sessions, models, backends |
|
||||||
| `o read [-l] <path>` | Read a file (-l: loop, re-read after each return) |
|
| `o new <session> [cwd]` | root | Create a new session |
|
||||||
| `o write <path> [data]` | Write to any file |
|
| `o generate <prompt>` | root | One-shot generation (no session needed) |
|
||||||
| `o ls [path]` | List namespace entries |
|
| `o <sess> ls` | session | List session contents |
|
||||||
| `o ctl <cmd> [args]` | Send control command (rdwr: gets response) |
|
| `o <sess> new <agent> [cwd]` | session | Create a new agent |
|
||||||
| `o generate <prompt>` | One-shot generation (no session needed) |
|
| `o <sess> ctl <cmd>` | session | Session control |
|
||||||
| `o tui` | Launch tmux TUI |
|
| `o <sess>/<agent> prompt` | agent | Interactive multi-line prompt REPL |
|
||||||
| `o env [session] [agent]` | Print export statements for context |
|
| `o <sess>/<agent> tui` | agent | Launch tmux TUI |
|
||||||
|
| `o <sess>/<agent> ctl <cmd>` | agent | Agent control (stop, compact, model, etc.) |
|
||||||
### Context
|
| `o <sess>/<agent> log [-n N]` | agent | Show last N lines of agent log |
|
||||||
|
| `o read [-l] <path>` | any | Read a file (-l: loop) |
|
||||||
Context is set via `$session` and `$agent` environment variables:
|
| `o write <path> [data]` | any | Write to a file (args or stdin) |
|
||||||
|
| `o env` | any | Print export statements for current context |
|
||||||
```sh
|
| `o help` | any | Show help |
|
||||||
eval $(o env myproject default) # export session=myproject agent=default
|
|
||||||
|
|
||||||
# Now every o command addresses the right agent automatically:
|
|
||||||
o ctl model # → shows current model
|
|
||||||
o read -l statewait
|
|
||||||
```
|
|
||||||
|
|
||||||
### Path resolution
|
### Path resolution
|
||||||
|
|
||||||
Paths are slash-delimited 9P namespace paths. The `o` CLI resolves them based
|
When you supply a context, `o` sets a **prefix**:
|
||||||
on context:
|
- Session: `session/<sess>`
|
||||||
|
- Agent: `session/<sess>/agent/<agent>`
|
||||||
|
|
||||||
| Path type | Example | Resolves to |
|
Paths given to `read`, `write`, and `ls` are resolved relative to this prefix.
|
||||||
|---|---|---|
|
A leading `/` escapes the prefix and addresses the root namespace directly:
|
||||||
| Root-level | `o read models` | `models` (no context needed) |
|
|
||||||
| Agent file | `o read state` | `session/$session/agent/$agent/state` |
|
|
||||||
| Session file | `o read env` | `session/$session/env` |
|
|
||||||
| Full path | `o read session/foo/agent/bar/chat` | Used as-is |
|
|
||||||
|
|
||||||
Root-level paths (`session/`, `agents`, `models`, `help`, `ctl`, `tools`) and
|
| Invocation | Resolves to |
|
||||||
absolute paths (starting with `session/`) bypass context resolution entirely.
|
|---|---|
|
||||||
Agent-level files (`chat`, `state`, `prompt`, `statewait`, `cfg`, `plan`,
|
| `o myproj/coding read chat` | `session/myproj/agent/coding/chat` |
|
||||||
`log`, `cost`, `offset`, `context`, `systemprompt`) require both `$session`
|
| `o myproj/coding read cfg` | `session/myproj/agent/coding/cfg` |
|
||||||
and `$agent`. Session-level files (`env`, `ctl`, `id`, `name`, `paused`)
|
| `o myproj read env` | `session/myproj/env` |
|
||||||
require only `$session`.
|
| `o myproj/coding read /models` | `models` (root) |
|
||||||
|
| `o myproj/coding ls /bypass` | `bypass` (root) |
|
||||||
|
| `o read models` | `models` (no context, no prefix) |
|
||||||
|
|
||||||
|
The leading slash is necessary when you want to access root-level paths
|
||||||
|
(like `models`, `backends`, `bypass/`) while in session or agent context.
|
||||||
|
Without it, the path is concatenated with the context prefix.
|
||||||
|
|
||||||
### Prompt REPL
|
### Prompt REPL
|
||||||
|
|
||||||
`o prompt` is an interactive multi-line REPL with readline editing:
|
`o <session>/<agent> prompt` is an interactive multi-line REPL:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ o prompt
|
$ o myproj/coding prompt
|
||||||
[myproject/default]
|
[myproj/coding]
|
||||||
Type . on a blank line to send, Ctrl+D to exit.
|
Type . on a blank line to send, Ctrl+D to exit.
|
||||||
Slash commands: /stop /compact /kill /clear /model /backend /cwd /help
|
/ prefix runs ctl: /stop, /compact, /model X, /inject X
|
||||||
|
!q exits the TUI.
|
||||||
|
|
||||||
> write a fibonacci function in python
|
> write a fibonacci function in python
|
||||||
and include a test case
|
and include a test case
|
||||||
|
|
@ -127,13 +139,16 @@ Slash commands control the agent without sending a prompt:
|
||||||
|---|---|
|
|---|---|
|
||||||
| `/stop` | Interrupt running agent |
|
| `/stop` | Interrupt running agent |
|
||||||
| `/compact` | Compact context window |
|
| `/compact` | Compact context window |
|
||||||
| `/kill` | Kill the session (exits REPL) |
|
|
||||||
| `/clear` | Clear history |
|
|
||||||
| `/model X` | Switch model |
|
| `/model X` | Switch model |
|
||||||
| `/backend X` | Switch backend |
|
|
||||||
| `/cwd X` | Change working directory |
|
| `/cwd X` | Change working directory |
|
||||||
| `/quit` or `/q` | Kill the tmux TUI |
|
| `!q` | Kill the tmux TUI session and exit |
|
||||||
| `/help` | List commands |
|
|
||||||
|
Piped input is also supported:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo "explain this error" | o myproj/coding prompt
|
||||||
|
cat file.go | o myproj/coding write prompt
|
||||||
|
```
|
||||||
|
|
||||||
### One-shot generation
|
### One-shot generation
|
||||||
|
|
||||||
|
|
@ -145,18 +160,13 @@ cat error.log | o generate # pipe content as the prompt
|
||||||
echo "write a haiku about filesystems" | o generate | wc -w
|
echo "write a haiku about filesystems" | o generate | wc -w
|
||||||
```
|
```
|
||||||
|
|
||||||
Chain multiple steps:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
echo "list 5 blog post ideas" | o generate | head -3 | o generate
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## `o tui` — tmux Terminal UI
|
## `o tui` — tmux Terminal UI
|
||||||
|
|
||||||
`o tui` composes `o read chat` and `o prompt` into a single tmux layout — two shell
|
`o <session>/<agent> tui` composes `o read chat` and `o prompt` into a single
|
||||||
commands in two panes, with agent state in the tmux status bar:
|
tmux layout — two shell commands in two panes, with agent state in the tmux
|
||||||
|
status bar:
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="img/ollie-tui.png"><img src="img/ollie-tui.png" alt="Screenshot of the o tui tmux layout: chat pane on top, prompt REPL on bottom, agent state in status bar" width="75%"></a>
|
<a href="img/ollie-tui.png"><img src="img/ollie-tui.png" alt="Screenshot of the o tui tmux layout: chat pane on top, prompt REPL on bottom, agent state in status bar" width="75%"></a>
|
||||||
|
|
@ -165,17 +175,15 @@ commands in two panes, with agent state in the tmux status bar:
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
eval $(o env myproject default)
|
o myproj/coding tui
|
||||||
o tui
|
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Requires `$session` and `$agent` to be set.
|
1. Creates a tmux session named `o-<session>`.
|
||||||
2. Creates a tmux session named `o-<session>`.
|
2. Two panes:
|
||||||
3. Two panes:
|
- **Pane 0** (top, 80%): streams chat output (log tail + live `read chat`).
|
||||||
- **Pane 0** (top, 80%): `o read chat` — streams filtered chat output (markers stripped server-side).
|
|
||||||
- **Pane 1** (bottom, 20%): `o prompt` — multi-line REPL (`/` prefix runs ctl commands).
|
- **Pane 1** (bottom, 20%): `o prompt` — multi-line REPL (`/` prefix runs ctl commands).
|
||||||
4. A background loop reads `statewait` and updates the tmux status bar instantly.
|
3. A background loop reads `statewait` and updates the tmux status bar on each state transition.
|
||||||
5. Focuses the prompt pane and attaches.
|
4. Focuses the prompt pane and attaches.
|
||||||
|
|
||||||
No polling. Each read blocks until data arrives. The status bar updates on every
|
No polling. Each read blocks until data arrives. The status bar updates on every
|
||||||
state transition via `statewait` — zero CPU when idle.
|
state transition via `statewait` — zero CPU when idle.
|
||||||
|
|
@ -189,10 +197,28 @@ state transition via `statewait` — zero CPU when idle.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## `o env` — Context export
|
||||||
|
|
||||||
|
`o env` prints export statements for the current context. This is useful for
|
||||||
|
other tools (raw `ollie-9p` commands, scripts) that need to know which session
|
||||||
|
and agent are being addressed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
eval $(o myproj/coding env)
|
||||||
|
# exports OLLIE_SESSION=myproj OLLIE_AGENT=coding
|
||||||
|
ollie-9p read session/$OLLIE_SESSION/agent/$OLLIE_AGENT/stats
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: `o` itself does not read these environment variables — it determines
|
||||||
|
context purely from its positional arguments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Other front-ends
|
## Other front-ends
|
||||||
|
|
||||||
- **[ellie](ellie.md)** — Emacs session tree, chat, multi-agent
|
- **[ellie](ellie.md)** — Emacs session tree, chat, multi-agent
|
||||||
- **KDE** — plasmoid, standalone GUI, Kate plugin, KRunner
|
- **[KDE](kde-gui.md)** — plasmoid, standalone GUI, Kate plugin, KRunner
|
||||||
|
- **acme** — Plan 9 editor (scripts in `data/scripts/acme/`)
|
||||||
|
|
||||||
For technical details (generation parameters, sandboxing, multi-agent workflows,
|
For technical details on the raw 9P filesystem, see [`doc/9p.md`](9p.md).
|
||||||
tool discovery, and the raw 9P filesystem), see [doc/whitepaper.md](whitepaper.md).
|
For tool authoring, see [`doc/writing-tools.md`](writing-tools.md).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue