170 lines
13 KiB
Markdown
170 lines
13 KiB
Markdown
# AGENTS.md
|
|
Project-level context for AI agents working in this repository.
|
|
|
|
> **⚠️ IMPORTANT: All work must be done in THIS source directory (`~/src/ollie/`).**
|
|
> Never edit files under `~/.config/ollie/` — that is an install target.
|
|
> Changes made there are overwritten on the next `just install-data`.
|
|
> Edit source files here, then run `just` to build and install.
|
|
|
|
## Project Overview
|
|
Ollie is an AI agent runtime inspired by Plan 9: agent state and behaviors are exposed as files in a 9P namespace. Orchestration, scheduling, and UIs are external — shell scripts, editors, web apps. The core is minimal; capabilities come from composing scripts.
|
|
## Repository Layout
|
|
Single Go module. KDE integration is part of the repository under `kde/`.
|
|
```
|
|
ollie/ ← you are here
|
|
├── cmd/
|
|
│ ├── olliesrv/ 9P server: sessions, agents, backends
|
|
│ │ └── internal/
|
|
│ │ ├── agent/ Agent loop, history, compaction, prompts
|
|
│ │ ├── backend/ LLM provider implementations
|
|
│ │ ├── bypass/ Sandbox bypass broker
|
|
│ │ ├── fs/ 9P namespace and handlers
|
|
│ │ ├── prompts/ System-prompt resolution
|
|
│ │ ├── session/ Session lifecycle and persistence
|
|
│ │ └── toolclient/ Local/remote toolsrv process management
|
|
│ ├── toolsrv/ Sandboxed tool execution server
|
|
│ │ └── internal/
|
|
│ │ ├── exec/ Tool execution
|
|
│ │ ├── registry/ Per-agent tool registry
|
|
│ │ ├── sandbox/ Landlock configuration and enforcement
|
|
│ │ └── server/ Namespace specification and process state
|
|
│ └── ollie-9p/ 9P client CLI
|
|
├── tools/ Compiled tool implementations
|
|
│ ├── codeintel/ Tree-sitter code-intelligence tools
|
|
│ ├── filetools/ Go file tools
|
|
│ ├── lsp/ LSP bridge and client tools
|
|
│ └── web/ Web-fetch tool
|
|
├── toolsrv/ toolsrv 9P client library and registry types
|
|
├── virtfs/ Virtual filesystem declaration EDSL
|
|
├── lib9p/ 9P protocol library and native client
|
|
├── env/, format/, log/, paths/ Shared Go packages
|
|
├── kde/ KDE GUI, Kate, KRunner, and KIO integration
|
|
├── contrib/elisp/ Emacs frontend (`ellie.el`)
|
|
├── data/agents/ Agent configuration JSON
|
|
├── data/prompts/ Prompt templates
|
|
├── data/tools/ Script tools and `.meta` files
|
|
├── data/skills/ Domain knowledge modules
|
|
├── data/scripts/ CLI and integration scripts
|
|
├── data/services/ User service files
|
|
├── cmd/toolsrv/internal/sandbox/ Installed sandbox configuration source
|
|
├── doc/ Architecture and usage documentation
|
|
└── experiments/ Experimental code
|
|
```
|
|
|
|
### Canonical source for prompts, tools, and skills
|
|
|
|
Do not edit `~/.config/ollie/` directly. It is an install target. Runtime data is copied from `data/` by `just install-data`; compiled tools are built into the same runtime tools directory by their build targets. The installed configuration also contains `backends.conf`, `sandbox.yaml`, agents, prompts, skills, scripts, and tools.
|
|
## Build System
|
|
The default `just` target builds and installs the KF6 variant. Build and install are separate phases.
|
|
```bash
|
|
just # build + test + install (KF6)
|
|
just kf5 # build + install the KF5/Qt5 variant
|
|
just build # build core, 9P, lib9p, tools, and KDE
|
|
just core # go build ./...
|
|
just ninep # olliesrv and ollie-9p
|
|
just lib9p # native lib9p shared library and header
|
|
just toolsrv # toolsrv binary
|
|
just code-tools # Tree-sitter code-intelligence tools
|
|
just file-tools # Go file tools
|
|
just lsp-tools # LSP tools
|
|
just tools-web # web_fetch
|
|
just kde # KDE KF6 integration
|
|
just kde-kf5 # KDE KF5 integration
|
|
just install-data # runtime configuration, prompts, skills, scripts, and tools
|
|
just install-el # Emacs frontend
|
|
just test # core and lib9p tests
|
|
just test-core # cmd/olliesrv, cmd/toolsrv, shared packages, and toolsrv tests
|
|
just test-9p # lib9p tests
|
|
just test-remote # build-check toolsrv (`go build ./cmd/toolsrv/...`)
|
|
just clean # remove build artifacts
|
|
```
|
|
Requires [just](https://github.com/casey/just): `cargo install just`.
|
|
|
|
## Testing
|
|
The supported test entry points are:
|
|
```bash
|
|
just test
|
|
just test-core
|
|
just test-9p
|
|
```
|
|
For direct Go testing, use the packages covered by `just test-core` and `just test-9p`. The current repository does not contain the former `cmd/ollie-remote` package; remote tool execution is implemented by `toolclient.SpawnRemote` and the remote toolsrv deployment path.
|
|
## Language & Conventions
|
|
|
|
- **Go** (root module): Go 1.25+, standard library preferred, minimal dependencies.
|
|
- **C++20/Qt6/KF6** (kde): CMake build, dual Qt5/Qt6 support where noted.
|
|
- **Elisp** (el): single file `ellie.el`.
|
|
- **Tool scripts**: Python 3, Bash, or compiled binaries. Must be executable. Metadata lives in a `.meta` sidecar JSON file (see `data/tools/*.meta`).
|
|
### Code style
|
|
- Go: `gofmt`, short variable names, error returns (no panics), table-driven tests.
|
|
- Tool scripts: emit structured output (`STATUS=ok`, `STATUS=error`). Image/LSP tools return JSON content blocks.
|
|
- Prompts: markdown, concise, example-driven. Follow the pattern in existing `tools-*.md` files.
|
|
## Architecture (key concepts)
|
|
1. **One integration surface**: `olliesrv` exposes sessions and agents through a 9P2000 filesystem. Frontends include `o`, `ollie-9p`, KDE, Kate, Emacs, and scripts. Reads from `chat`, `statewait`, `eventwait`, and `feed` provide blocking/event-driven synchronization.
|
|
2. **Session and tool processes**: Each session owns an agent runtime in `olliesrv` and a separate `toolsrv` process. They communicate over an authenticated Unix socket using 9P. `toolclient` can respawn local toolsrv processes and can deploy/start toolsrv remotely over SSH with socket forwarding.
|
|
3. **Agent loop** (`cmd/olliesrv/internal/agent/loop.go` and `turn.go`): Stream an LLM response, parse native or text tool calls, execute tools, update history, and repeat until a final response, cancellation, or a configured limit. It includes transient retries, context-overflow compaction, error/stall/replan controls, and tool-result caching.
|
|
4. **Dynamic tools**: Tools are external executables described by `.meta` files. `toolsrv` owns discovery and per-agent registries. `olliesrv` refreshes the registry, injects common dispatch flags (`bypass`, `timeout`, `sandbox`, `background`), and calls tools through `toolsrv.Conn`.
|
|
5. **Parallel and background dispatch**: Non-conflicting tool calls in one turn run concurrently. Metadata scopes schedule `read`, `write`, and global operations; shell-like global operations serialize. Any tool may run in the background, producing a process ID whose output is injected when the process changes or exits.
|
|
6. **Sandbox** (`cmd/toolsrv/internal/sandbox/`): Landlock/landrun policies control filesystem and network access. The installed `sandbox.yaml` is sourced from `cmd/toolsrv/internal/sandbox/sandbox.yaml`. The toolsrv namespace and process state live under `cmd/toolsrv/p9.go` and `cmd/toolsrv/internal/server/`. The bypass broker provides policy-controlled escape requests, approval, persistence, and rate limiting.
|
|
7. **Backends** (`cmd/olliesrv/internal/backend/`): Supported names are `ollama`, `openai`, `openrouter`, `anthropic`, `copilot`, `kiro`, and `gemini`. Configuration is read from `~/.config/ollie/backends.conf`; environment variables are fallback inputs.
|
|
8. **Prompt assembly**: `cmd/olliesrv/internal/prompts/system_prompt.md` is embedded as the default system prompt. An agent's `systemPrompt` can override it with a filesystem path. `prompt` and `userPrompts` entries resolve files, expand environment variables, and support legacy `!command` entries. The runtime combines system, environment, agent, and tool sections.
|
|
9. **Context management**: History tracks messages, usage, costs, cache statistics, and structured task state. Cold/warm/hot result tiers and automatic compaction preserve recent context while summarizing older material.
|
|
10. **Sub-agents**: `subagent_spawn` creates a transient child session with an independent runtime and context. The child receives a one-time parent-history snapshot and returns only its final reply. Parent/child IDs are retained for tracing; concurrent children are supported.
|
|
11. **9P namespace declaration**: `cmd/olliesrv/internal/fs/spec.go` declares the olliesrv namespace. The toolsrv namespace is declared by `cmd/toolsrv/p9.go` using `cmd/toolsrv/internal/server.Spec`; process state and handlers are in `cmd/toolsrv/internal/server/`. Both use the `virtfs` EDSL and `virtfs.BuildTree()`.
|
|
## Key Files
|
|
| What | Where |
|
|
|------|-------|
|
|
| 9P namespace (olliesrv) | `cmd/olliesrv/internal/fs/spec.go` |
|
|
| 9P namespace (toolsrv) | `cmd/toolsrv/p9.go`, `cmd/toolsrv/internal/server/server.go` |
|
|
| virtfs EDSL | `virtfs/decl.go`, `virtfs/builder.go` |
|
|
| Agent loop and dispatch | `cmd/olliesrv/internal/agent/loop.go`, `turn.go` |
|
|
| Runtime and prompt assembly | `cmd/olliesrv/internal/agent/runtime.go`, `prompt_resolver.go` |
|
|
| Tool server binary | `cmd/toolsrv/` |
|
|
| Tool server client and process lifecycle | `toolsrv/client9p.go`, `cmd/olliesrv/internal/toolclient/` |
|
|
| Remote tool execution | `cmd/olliesrv/internal/toolclient/spawn.go` |
|
|
| Sandbox enforcement | `cmd/toolsrv/internal/sandbox/` |
|
|
| Bypass broker | `cmd/olliesrv/internal/bypass/` |
|
|
| Session management and persistence | `cmd/olliesrv/internal/session/` |
|
|
| Embedded default system prompt | `cmd/olliesrv/internal/prompts/system_prompt.md` |
|
|
| Agent configs | `data/agents/*.json` |
|
|
| Backend configuration | `data/backends.conf`, `~/.config/ollie/backends.conf` |
|
|
| Compiled tools | `tools/codeintel/`, `tools/filetools/`, `tools/lsp/`, `tools/web/` |
|
|
| KDE GUI | `kde/gui/` |
|
|
| Kate plugin | `kde/kate/` |
|
|
## Environment
|
|
Runtime configuration is read from `~/.config/ollie/` (or `$XDG_CONFIG_HOME/ollie/`). The backend configuration file is `backends.conf`, not `env`.
|
|
- `backend = ...` in `backends.conf` selects the default backend; a session `backend=...` can override it.
|
|
- `OLLIE_BACKEND` is a fallback when no configured backend or session backend is selected.
|
|
- `OLLIE_MODEL` is a legacy/environment model fallback; configured backend sections can set `model = ...`.
|
|
- The runtime path helpers honor `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and `XDG_RUNTIME_DIR`.
|
|
- The current `justfile` install targets use `~/.config/ollie`, `~/.local/share/ollie`, and `~/.local/bin` directly; non-default XDG locations therefore require adjusting the install targets or copying the installed files manually.
|
|
- Runtime tools are discovered from `$XDG_CONFIG_HOME/ollie/tools` (default: `~/.config/ollie/tools`).
|
|
- OptMem runtime data is under `$XDG_DATA_HOME/ollie/optmem` (default: `~/.local/share/ollie/optmem`).
|
|
## Adding a new tool
|
|
|
|
### Script-based tool (Python/Bash)
|
|
1. Create an executable script in `data/tools/<name>`
|
|
2. Create `data/tools/<name>.meta` with JSON metadata:
|
|
```json
|
|
{"description":"...","prompt":"...","args":{...},"tier":"hot","readOnly":false}
|
|
```
|
|
3. Run `just install-data` to install
|
|
|
|
### Compiled tool (Go)
|
|
1. Create a package under `tools/<family>/cmd/<name>/main.go`
|
|
- Read JSON args from stdin, write result to stdout, exit 0/1
|
|
- Share library code in `tools/<family>/` (e.g. `tools/lsp/`)
|
|
2. Create `<name>.meta` alongside `main.go` in the same `cmd/<name>/` directory (same format as above)
|
|
3. Add a build target in the justfile that compiles to `{{cfg}}/tools/<name>` **and** installs the `.meta` file alongside it
|
|
4. Run `just` to build and install
|
|
|
|
The `.meta` file lives with the code that produces the tool, not in `data/tools/`. See the `lsp-tools` just target for the canonical pattern.
|
|
|
|
Both paths produce the same result: an executable + `.meta` in `$XDG_CONFIG_HOME/ollie/tools`.
|
|
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 `data/agents/default.json`
|
|
3. Run `just install-data` to install
|
|
## KDE development
|
|
KDE integration is part of this repository under `kde/`. Build and install it through the root `justfile` targets. The component has its own `kde/justfile` for focused KDE builds.
|