diff --git a/AGENTS.md b/AGENTS.md index bc1f3bc..e4f54ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,23 +55,21 @@ Prompt and tool files live in `data/`. The `just install-data` target copies the | `kde/` | KDE-specific tool scripts (`gui_*`) | `just install-kde` | ## Build System ```bash -# Build everything: +# Build and install everything: just -# Individual targets: +# Individual build targets: just ninep # olliesrv + ollie-9p -just acme # acme frontend +just toolsrv # tool server binary +just core # core Go packages just kde # KDE integration (cmake with ~/.local prefix) -just ollie-remote # remote execution binary -# Install targets (run automatically by the top-level paths): +just lsp-tools # LSP tool binaries +# Install targets: just install-data # agents, prompts, tools, skills → ~/.config/ollie/ -just install-scripts # CLI scripts → ~/.config/ollie/scripts/ -just install-contrib # contrib scripts → ~/bin/ -just install-kde # KDE plugins, desktop file, env → ~/.local/ just install-el # ellie.el → ~/.config/emacs/ellie/ # Test: just test # run all tests -just test-core # core tests only -just test-9p # 9p tests only +just test-core # core Go tests +just test-9p # 9p integration tests # Lifecycle: just uninstall # remove all installed files just clean # remove build artifacts @@ -103,12 +101,13 @@ just test-remote - Prompts: markdown, concise, example-driven. Follow the pattern in existing `tools-*.md` files. ## Architecture (key concepts) 1. **One integration surface**: 9P filesystem. Sessions at `session/{sname}/agent/{aname}/`. All control via `ctl` (rdwr: write command, read response). Tools, skills, memory on physical filesystem via env vars. -2. **Agent loop** (`cmd/olliesrv/internal/agent/loop.go`): Streaming LLM call → parse tool calls → dispatch → loop until no more tool calls or max steps. -3. **Tool dispatch** (`cmd/toolsrv/`): All tools execute remotely through a per-session tool server process. Tools are external scripts resolved from `$XDG_CONFIG_HOME/ollie/tools`. Load via `ctl tool_load `. -4. **Sandbox** (`cmd/toolsrv/internal/sandbox/`): Landlock-based. Config in `sandbox/*.yaml` defines filesystem access per profile. Escape via bypass broker (`cmd/olliesrv/internal/bypass/`). -5. **Backends** (`cmd/olliesrv/internal/backend/`): Ollama, OpenAI-compatible, Anthropic, Copilot, Kiro, Gemini. Selectable per-session. -6. **Prompts assembled at runtime**: Agent JSON `prompt` array specifies which prompt files to concatenate. Static prompt files can be included directly; the base system prompt is embedded in the binary and always prepended. -7. **9P namespace declared via virtfs EDSL**: The entire filesystem is a single recursive `FsNodeDecl` tree in `cmd/olliesrv/internal/fs/spec.go`, built by `virtfs.BuildTree()`. Every handler is an inline closure — no indirection. +2. **Two-process model**: Each session runs an `olliesrv` (the 9P namespace, agent loop, backends) and a per-session `toolsrv` (sandboxed tool execution). They communicate over a Unix socket using 9P. The toolsrv is spawned by olliesrv at session creation and has its own namespace (`/proc/new`, `/ctl`, `/tools`, etc.). +3. **Agent loop** (`cmd/olliesrv/internal/agent/loop.go`): Streaming LLM call → parse tool calls → dispatch to toolsrv → loop until no more tool calls or max steps. +4. **Tool dispatch**: ALL tools (including `reasoning_think`, `file_read`, `shell`) execute through the per-session toolsrv. The agent holds a `*toolsrv.Conn` (9P client) and calls `CallTool(name, args)` which writes to `proc/new` and reads the result. Tool registry is per-agent, keyed by agent ID in the protocol. +5. **Sandbox** (`cmd/toolsrv/internal/sandbox/`): Landlock-based. Config in `sandbox/*.yaml` defines filesystem access per profile. Escape via bypass broker (`cmd/olliesrv/internal/bypass/`). +6. **Backends** (`cmd/olliesrv/internal/backend/`): Ollama, OpenAI-compatible, Anthropic, Copilot, Kiro, Gemini. Selectable per-session. +7. **Prompts assembled at runtime**: Agent JSON `prompt` array specifies which prompt files to concatenate. The base system prompt is embedded in the binary and always prepended. +8. **9P namespace declared via virtfs EDSL**: The entire filesystem is a single recursive `FsNodeDecl` tree in `cmd/olliesrv/internal/fs/spec.go`, built by `virtfs.BuildTree()`. Every handler is an inline closure — no indirection. Same pattern in `cmd/toolsrv/internal/fs/spec.go`. ## Key Files | What | Where | |------|-------| @@ -155,7 +154,7 @@ Both paths produce the same result: an executable + `.meta` in `$XDG_CONFIG_HOME The registry doesn't distinguish between scripts and binaries. ## Adding a new prompt 1. Write the markdown file in `data/prompts/` -2. If it should be loaded by default, reference it in `agents/default.json` +2. If it should be loaded by default, reference it in `data/agents/default.json` 3. Run `just install-data` to install ## Submodule workflow The only remaining submodule is `kde/`. For KDE: @@ -172,18 +171,3 @@ git commit -m "update kde submodule" ``` Each submodule has its own remote at `ssh://lkn@lneely.de:44220/lkn/ollie-{name}.git`. When cloning, use `--recurse-submodules` or run `git submodule update --init --recursive`. -## Environment -The only remaining submodule is `kde/`. For KDE: -```bash -# Update KDE submodule: -git submodule update --remote --merge kde -# Work in the KDE submodule: -cd kde -# ... make changes, commit ... -git push -cd .. -git add kde -git commit -m "update kde submodule" -``` -Each submodule has its own remote at `ssh://lkn@lneely.de:44220/lkn/ollie-{name}.git`. -When cloning, use `--recurse-submodules` or run `git submodule update --init --recursive`.