194 lines
8.6 KiB
Markdown
194 lines
8.6 KiB
Markdown
# AGENTS.md
|
|
|
|
Project-level context for AI agents working in this repository.
|
|
|
|
## 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
|
|
|
|
Monorepo with Git submodules. Each submodule has its own Go module (except `el` which is Elisp and `kde` which is C++/Qt).
|
|
|
|
```
|
|
ollie/ ← you are here
|
|
├── core/ (Go) Core library: agent loop, backends, tools, config
|
|
├── 9p/ (Go) 9P filesystem server (olliesrv)
|
|
├── dbus/ (Go) D-Bus session manager daemon (ollied)
|
|
├── acme/ (Go) Plan 9 acme editor frontend
|
|
├── httpgw/ (Go) HTTP-to-9P gateway
|
|
├── webui/ (TypeScript) Preact SPA browser frontend
|
|
├── kde/ (C++/Qt6) KDE integration: plasmoid, standalone GUI, Kate plugin, KRunner, tray
|
|
├── el/ (Elisp) Emacs frontend (ellie.el)
|
|
├── agents/ Agent config JSONs (loaded at runtime)
|
|
├── prompts/ System prompt templates (markdown) ← NOT used; see note below
|
|
├── tools/ Tool scripts (file_read, lsp_*, memory_*, etc.)
|
|
├── sandbox/ Landlock sandbox config YAML
|
|
├── scripts/ User-facing CLI scripts:
|
|
│ ├── s/ Session management (sh, bfg, ls, kill, ...)
|
|
│ ├── u/ Utilities (complete, optimize, cascade)
|
|
│ └── x/ Internal/plumbing (elevate, prime, bd, task)
|
|
├── doc/ Architecture docs, usage guide
|
|
├── contrib/ Community scripts
|
|
└── experiments/ Trial notes
|
|
```
|
|
|
|
### Canonical source for prompts/tools/skills
|
|
|
|
Three locations have prompt and tool files. The **source of truth** depends on which component you're editing:
|
|
|
|
| Location | Purpose | Deployed by |
|
|
|----------|---------|-------------|
|
|
| `9p/prompts/`, `9p/tools/` | Canonical source for the 9P server | `just install-data` |
|
|
| `9p/skills/`, `kde/skills/` | Shared `agent-skills` submodule (same repo in both) | `just install-data` |
|
|
| `kde/prompts/`, `kde/tools/` | KDE-specific copies (may diverge for KDE-only tools like `gui_*`) | `just install-kde` |
|
|
| Root `prompts/`, `tools/` | Top-level copies installed by `just install-data` | `just install-data` |
|
|
|
|
The `just install-data` target copies `agents/`, `prompts/`, `tools/`, `sandbox/` (and `skills/` from submodules) into `~/.config/ollie/`. **Do not edit `~/.config/ollie/` directly** — changes are overwritten on next install.
|
|
|
|
When adding a new prompt/tool that should be available to all frontends, add it to both `9p/prompts/` (or `9p/tools/`) and the root `prompts/` (or `tools/`) directory.
|
|
|
|
## Build System
|
|
|
|
```bash
|
|
# From monorepo root (pick one):
|
|
just # 9P path (recommended): core, 9p, acme, kde, httpgw, webui, emacs
|
|
just dbus # D-Bus path (KDE-only): core, ollied, kde, httpgw, webui
|
|
|
|
# Individual build targets:
|
|
just core # core library
|
|
just ninep # 9P server
|
|
just acme # acme frontend
|
|
just kde # KDE integration (cmake with ~/.local prefix)
|
|
just httpgw # HTTP gateway
|
|
just webui # web UI (needs npm)
|
|
just dbus-bin # D-Bus daemon (ollied)
|
|
|
|
# Install targets (run automatically by the top-level paths):
|
|
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/
|
|
just install-dbus-bin # ollied + autostart → ~/.local/bin/, ~/.config/autostart/
|
|
|
|
# Test:
|
|
just test # run all tests (core + 9p)
|
|
just test-core # core tests only
|
|
just test-9p # 9p tests only
|
|
|
|
# Lifecycle:
|
|
just uninstall # remove all installed files
|
|
just clean # remove build artifacts
|
|
```
|
|
|
|
Requires [just](https://github.com/casey/just): `cargo install just`
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
# Go tests (from any Go submodule):
|
|
go test ./...
|
|
|
|
# Core has the most tests:
|
|
cd core && go test ./...
|
|
|
|
# 9P server tests:
|
|
cd 9p && go test ./...
|
|
|
|
# KDE has integration test scripts:
|
|
cd kde && ./test-e2e.sh
|
|
```
|
|
|
|
## Language & Conventions
|
|
|
|
- **Go** (core, 9p, dbus, acme, httpgw): Go 1.25+, standard library preferred, minimal dependencies. Modules are `ollie` (core), `olliesrv` (9p), `ollie-dbus`, `ollie-acme`, `ollie-httpgw`.
|
|
- **C++20/Qt6/KF6** (kde): CMake build, dual Qt5/Qt6 support where noted.
|
|
- **TypeScript** (webui): Vite + Preact.
|
|
- **Elisp** (el): single file `ellie.el`.
|
|
- **Tool scripts**: Python 3 or Bash. Must be executable. Header comments declare metadata (`# ollie:parallel read`, `# ollie:tier cold`, `# description:`, `# args:`).
|
|
|
|
### 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. **Two integration surfaces**: 9P filesystem (sessions at `s/{name}/`) and D-Bus (`org.ollie.SessionManager`). Tools, skills, memory on physical filesystem via env vars.
|
|
2. **Agent loop** (`core/pkg/agent/`): Streaming LLM call → parse tool calls → dispatch → loop until no more tool calls or max steps.
|
|
3. **Tool dispatch** (`core/pkg/tools/`): `execute_code` is built-in. All others are external scripts resolved from `OLLIE_TOOLS_PATH`.
|
|
4. **Sandbox** (`core/internal/sandbox/`): Landlock-based. Config in `sandbox/*.yaml` defines filesystem access per profile.
|
|
5. **Backends** (`core/pkg/backend/`): Ollama, OpenAI-compatible, Anthropic, Copilot, Kiro. Selectable per-session.
|
|
6. **Prompts assembled at runtime**: Agent JSON `prompt` array runs shell commands (via `x/prime`) that cat markdown files together. No static prompt file is used directly.
|
|
7. **D-Bus** (kde/dbus only): `ollied` exposes `org.ollie.SessionManager` for KDE frontends. It's a separate daemon from `olliesrv`.
|
|
|
|
## Key Files
|
|
|
|
| What | Where |
|
|
|------|-------|
|
|
| Agent loop | `core/pkg/agent/loop.go` |
|
|
| Tool dispatcher | `core/pkg/tools/execute/` |
|
|
| Remote execution client | `core/pkg/remote/remote.go` |
|
|
| Remote execution server | `remote/main.go` |
|
|
| Sandbox enforcement | `core/internal/sandbox/` |
|
|
| 9P filesystem | `9p/fs/` |
|
|
| Session management | `9p/session/` |
|
|
| System prompt template | `prompts/SYSTEM_PROMPT.md` |
|
|
| Agent configs | `agents/*.json` |
|
|
| D-Bus daemon | `dbus/main.go` |
|
|
| KDE D-Bus client | `kde/plasmoid/plugin/olliedbusclient.cpp` |
|
|
| Standalone GUI | `kde/gui/` |
|
|
| Kate plugin | `kde/kate/` |
|
|
|
|
## Environment
|
|
|
|
Config lives in `~/.config/ollie/env`. Key variables:
|
|
- `OLLIE_BACKEND` — default backend (ollama, openai, anthropic, copilot, kiro)
|
|
- `OLLIE_MODEL` — default model
|
|
- `OLLIE_TOOLS_PATH` — where tool scripts live (default: `~/.config/ollie/tools`)
|
|
- `OLLIE_MEMORY_PATH` — persistent memory directory
|
|
- `OLLIE_ENABLED_BACKENDS` — backends available for routing
|
|
|
|
|
|
## Adding a new tool
|
|
|
|
1. Create an executable script in `tools/` (and `9p/tools/`, `kde/tools/` if needed)
|
|
2. Add header comments: `# description:`, `# args:`, optionally `# ollie:parallel read` or `# ollie:tier cold`
|
|
3. Create a matching `prompts/tools-*.md` documentation file (and in `9p/prompts/`, `kde/prompts/`)
|
|
4. Run `just install-data` to install
|
|
|
|
## Adding a new prompt
|
|
|
|
1. Write the markdown file in `9p/prompts/` and root `prompts/`
|
|
2. If it should be loaded by default, add a `$OLLIE_CFG_PATH/scripts/x/prime <name>` entry to `agents/default.json`
|
|
3. Run `just install-data` to install
|
|
|
|
## Submodule workflow
|
|
|
|
```bash
|
|
# Update all submodules:
|
|
git submodule update --remote --merge
|
|
|
|
# Work in a submodule (e.g., core):
|
|
cd core
|
|
# ... make changes, commit ...
|
|
git push
|
|
cd ..
|
|
git add core
|
|
git commit -m "update core submodule"
|
|
```
|
|
|
|
Each submodule has its own remote at `ssh://lkn@lneely.de:44220/lkn/ollie-{name}.git`.
|
|
|
|
### Nested submodules
|
|
|
|
Both `9p/` and `kde/` contain a nested `skills/` submodule pointing to the same repo (`agent-skills.git`). There is no root-level `skills/` directory.
|
|
|
|
```
|
|
9p/skills/ → ssh://lkn@lneely.de:44220/lkn/agent-skills.git
|
|
kde/skills/ → ssh://lkn@lneely.de:44220/lkn/agent-skills.git (same repo)
|
|
```
|
|
|
|
When cloning, use `--recurse-submodules` or run `git submodule update --init --recursive` to get these.
|