diff --git a/9p b/9p index 2d4ce13..c19c8d0 160000 --- a/9p +++ b/9p @@ -1 +1 @@ -Subproject commit 2d4ce132723d38ce3362242785f9b628730fee76 +Subproject commit c19c8d0cb52729b86f45cf4ed5e1e760a72f9dca diff --git a/AGENTS.md b/AGENTS.md index 6c08ab4..8654bab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -117,7 +117,7 @@ cd kde && ./test-e2e.sh 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`. +3. **Tool dispatch** (`core/pkg/tools/`): `shell` 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. diff --git a/agents/copilot.json b/agents/copilot.json index 302fe3a..7ec2e3c 100644 --- a/agents/copilot.json +++ b/agents/copilot.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-copilot.md", ], "tools": true, diff --git a/agents/default.json b/agents/default.json index 3cd97fc..f62e119 100644 --- a/agents/default.json +++ b/agents/default.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-coding.md", "bash -c 'd=$PWD; while [ \"$d\" != / ]; do [ -d \"$d/.beads\" ] && exec bd prime; [ ! -e \"$d/.git\" ] && break; d=$(dirname \"$d\"); done' 2>/dev/null || true" ], diff --git a/agents/driver.json b/agents/driver.json index 61888b5..6e5aac9 100644 --- a/agents/driver.json +++ b/agents/driver.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-coding.md", "bash -c 'd=$PWD; while [ \"$d\" != / ]; do [ -d \"$d/.beads\" ] && exec bd prime; [ ! -e \"$d/.git\" ] && break; d=$(dirname \"$d\"); done' 2>/dev/null || true" ], diff --git a/agents/explorer.json b/agents/explorer.json index 7478a8f..de961b6 100644 --- a/agents/explorer.json +++ b/agents/explorer.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-explorer.md", ], "maxSteps": 40, diff --git a/agents/librarian.json b/agents/librarian.json index c6efb59..c9ee15e 100644 --- a/agents/librarian.json +++ b/agents/librarian.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-librarian.md", ], "maxSteps": 20, diff --git a/agents/navigator.json b/agents/navigator.json index fcfa9b1..25b0124 100644 --- a/agents/navigator.json +++ b/agents/navigator.json @@ -1,8 +1,8 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-navigator.md", ], - "systemPrompt": "$OLLIE_CFG_PATH/prompts/SYSTEM_PROMPT_QWEN.md", "temperature": 0.3, "maxTokens": 8192, "maxSteps": 30, diff --git a/agents/taskmanager.json b/agents/taskmanager.json index c9a436c..78df5db 100644 --- a/agents/taskmanager.json +++ b/agents/taskmanager.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-taskmanager.md", ], "maxSteps": 20, diff --git a/agents/theo.json b/agents/theo.json index 48cd4e3..007b0bd 100644 --- a/agents/theo.json +++ b/agents/theo.json @@ -1,5 +1,6 @@ { "prompt": [ + "$OLLIE_CFG_PATH/prompts/user-preferences.md", "$OLLIE_CFG_PATH/prompts/agent-theo.md", ], "maxSteps": 30, diff --git a/core b/core index 38db3db..c051a72 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 38db3db4f2f253e02d0c69bdee566e6c59c3decc +Subproject commit c051a72ba44c5ac23210b7f636898e55e5eded95 diff --git a/doc/ARCHITECTURE.md b/doc/ARCHITECTURE.md index f392626..cf8cdbd 100644 --- a/doc/ARCHITECTURE.md +++ b/doc/ARCHITECTURE.md @@ -2,7 +2,7 @@ ## Philosophy -ollie's design philosophy is Emacs: a small, extensible core. The Go runtime (`agent.Core`) defines what an agent *is* — an event loop, a backend connection, a message history, and a single built-in tool (`execute_code`). Everything else — orchestration, scheduling, workflows, UIs — is pushed out to the surrounding environment. +ollie's design philosophy is Emacs: a small, extensible core. The Go runtime (`agent.Core`) defines what an agent *is* — an event loop, a backend connection, a message history, and seven built-in primitives (`shell`, `tool_*`, `skill_*`). Everything else — orchestration, scheduling, workflows, UIs — is pushed out to the surrounding environment. The primary integration philosophy is Plan 9's "everything is a file." `olliesrv` exposes agent state and behaviors as files in a 9P namespace. Any program that can read and write files can drive an agent: shell scripts, editors, web apps, cron, containers. @@ -10,7 +10,7 @@ For desktop-native integration, `olliesrv` embeds a D-Bus adapter (`org.ollie.Se Design principles: - **Small extensible core.** The agent runtime is minimal; capabilities come from composing external scripts. -- **One built-in tool.** `execute_code` is the only tool compiled into the core. Everything else is a script. +- **Seven built-in primitives.** `shell`, `tool_load`/`tool_list`/`tool_active`, `skill_load`/`skill_list`/`skill_active` are the only tools compiled into the core. Everything else is a script. - **Two integration paths.** 9P filesystem (canonical) and/or D-Bus (conventional). Same core, different surfaces, selectable via flags. - **No framework lock-in.** Frontends are decoupled via whichever interface they prefer; the core doesn't know or care. @@ -66,8 +66,8 @@ D-Bus-only mode: olliesrv -no9p (same interface, no filesystem listener) │ │ Agent Loop │ │ Session │ │ tools.Dispatcher │ │ │ │ (loop.go) │ │ (messages, │ │ ┌──────────────────┐ │ │ │ │ │ │ task state, │ │ │ execute.Server │ │ │ -│ │ stream ←────┼──┤ compaction) │ │ │ (execute_code, │ │ │ -│ │ dispatch ───┼──┼───────────────┼──┤ │ execute_code) │ │ │ +│ │ stream ←────┼──┤ compaction) │ │ │ (shell, │ │ │ +│ │ dispatch ───┼──┼───────────────┼──┤ │ tool_*, skill_*)│ │ │ │ └─────────────┘ └──────────────┘ │ └────────┬─────────┘ │ │ │ └───────────┼────────────┘ │ └──────────────────────────────────────────────────┼──────────────┘ @@ -103,7 +103,7 @@ The core is a Go library (`ollie/pkg/`) with no binary. Frontends import it as a | `pkg/log/` | Structured logging | | `pkg/paths/` | Config and data directory resolution | | `pkg/tools/` | Server and Dispatcher interfaces | -| `pkg/tools/execute/` | The execute.Server (execute_code) | +| `pkg/tools/execute/` | The execute.Server (shell + primitives) | | `pkg/tools/execute/tool.go` | Named tool script discovery and execution | | `internal/sandbox/` | Landlock sandbox config and command wrapper | @@ -276,9 +276,9 @@ All KDE components use `QDBusServiceWatcher` to handle daemon restarts gracefull The tool system has exactly one built-in server (`execute.Server`) that exposes three executors: -| Executor | Purpose | +| Primitive | Purpose | |---|---| -| `execute_code` | Run inline code steps (bash, python3, perl, lua, ...) | +| `shell` | Run a bash command in a sandbox | All other capabilities are **tool scripts** — executable files discovered from `OLLIE_TOOLS_PATH` (default: `~/.config/ollie/tools`). @@ -457,7 +457,7 @@ Frontend reads s/{id}/chat (streaming) ## Key Design Decisions 1. **Two integration surfaces** — 9P filesystem (canonical, Unix philosophy) and D-Bus (conventional, for GUI/web consumers). Both are thin adapters over the same core. -2. **Single built-in tool** — `execute_code` is the only compiled-in capability. This keeps the core small and makes all other tools equal citizens. +2. **Seven built-in primitives** — `shell`, `tool_*`, `skill_*` are the only compiled-in capabilities. This keeps the core small and makes all other tools equal citizens. 3. **Mandatory sandboxing** — no unsandboxed fallback. Security is not optional. 4. **Streaming-only backends** — simplifies the interface; blocking APIs wrap as single-event streams. 5. **Fire-and-forget sub-agents** — no active waiting, no polling. Results arrive as filesystem writes. diff --git a/doc/CORE.md b/doc/CORE.md index c76bf25..f5ba3e3 100644 --- a/doc/CORE.md +++ b/doc/CORE.md @@ -386,23 +386,22 @@ Servers may implement additional interfaces for runtime configuration: ### execute.Server (`pkg/tools/execute/`) -The single built-in server exposes three executors: +The built-in server exposes seven primitives: `shell`, `tool_load`, `tool_list`, `tool_active`, `skill_load`, `skill_list`, `skill_active`. -#### execute_code +#### shell -Runs inline code steps sequentially (or parallel via `{parallel: [...]}`). +Runs a single bash command in a sandbox. **Input schema:** ```json { - "steps": [{"code": "...", "language": "bash"}], + "cmd": "...", "timeout": 30, - "sandbox": "default" + "sandbox": "default", + "elevated": false } ``` -**Supported languages:** bash, python3, perl, lua, awk, sed, jq, ed, expect, bc. - ### Code Validation Before execution, inline code is checked against dangerous patterns: diff --git a/doc/MULTI_AGENT.md b/doc/MULTI_AGENT.md index 0745ea6..fbc7ca3 100644 --- a/doc/MULTI_AGENT.md +++ b/doc/MULTI_AGENT.md @@ -95,7 +95,7 @@ done wait # wait for all subagent_spawn calls to return session paths ``` -Or from within `execute_code` using parallel steps: +Or from within `shell`: ```json { diff --git a/doc/NO_MCP.md b/doc/NO_MCP.md index 479bc67..1c00833 100644 --- a/doc/NO_MCP.md +++ b/doc/NO_MCP.md @@ -6,7 +6,7 @@ ollie removed its MCP client implementation after observing that the protocol ad ## The argument -ollie exposes exactly one built-in tool: `execute_code`. Every other capability — file operations, memory, search, sub-agents — is a shell script in `t/` invoked via `execute_code {tool: "name", args: [...]}`. Skills in `sk/` teach the agent when and how to use each tool. +ollie exposes exactly one built-in tool: `shell`. Every other capability — file operations, memory, search, sub-agents — is a tool script promoted to a native callable function via the tool registry. Skills teach the agent when and how to use each tool. This means any operation an MCP server can perform, a tool script can also perform: @@ -21,7 +21,7 @@ The `x/elevate` plugin is a concrete example: it replaced an MCP server that ran | MCP feature | ollie equivalent | |---|---| | `tools/list` (structured discovery) | `ls $OLLIE_TOOLS_PATH/` + `grep` for descriptions | -| `tools/call` (invoke a tool) | `execute_code {tool: "name"}` | +| `tools/call` (invoke a tool) | `shell` or promoted tool call | | JSON-RPC framing | stdin/stdout/exit code | | Subprocess lifecycle management | The sandbox manages process lifecycle | | Typed tool schemas | Tool scripts are self-documenting; skills describe usage | diff --git a/doc/REMOTE_EXECUTION.md b/doc/REMOTE_EXECUTION.md index 6901c88..49f33cf 100644 --- a/doc/REMOTE_EXECUTION.md +++ b/doc/REMOTE_EXECUTION.md @@ -189,7 +189,7 @@ Option 2 is simplest and matches goq's philosophy of "the remote is a mirror of | Component | Location | Why | |---|---|---| -| execute_code | Remote | Needs remote filesystem, build tools | +| shell | Remote | Needs remote filesystem, build tools | | Named tool scripts | Remote | File I/O targets remote tree | | Sandbox | Remote | Landrun enforces on the execution host | | Working directory | Remote | The project lives there | @@ -217,7 +217,7 @@ All five phases are implemented: - `remote/` submodule with `main.go` - Wraps `execute.Server` with JSON-RPC stdio interface - Embeds `sandbox-remote.yaml` and tool scripts via `go:embed` -- RPC methods: `execute_code`, `list_tools`, `host_info`, `ping` +- RPC methods: `shell`, `list_tools`, `host_info`, `ping` ### Phase 2: SSH bootstrap ✓ - `core/pkg/remote/bootstrap.sh` embedded template @@ -228,7 +228,7 @@ All five phases are implemented: ### Phase 3: RemoteServer adapter ✓ - `core/pkg/remote/remote.go` implements `tools.Server` - `ListTools()` calls remote `list_tools` RPC -- `CallTool()` passes tool name as RPC method (routes execute_code) +- `CallTool()` passes tool name as RPC method (routes shell) - `HostInfo` fetched after connect (platform, arch, is_git_repo) ### Phase 4: Session integration ✓ diff --git a/doc/USAGE.md b/doc/USAGE.md index 1804f13..389684c 100644 --- a/doc/USAGE.md +++ b/doc/USAGE.md @@ -202,7 +202,7 @@ echo "topP=0.9" > $OLLIE/s/mysession/cfg ### Sandbox -Every `execute_code` invocation runs inside a Landlock sandbox configured by `~/.config/ollie/sandbox/.yaml`. The sandbox wraps each invocation as a new command, so config changes (e.g. granting access to an additional directory) take effect on the next `execute_code` call without restarting the server or session. +Every `shell` invocation (and promoted tool call) runs inside a Landlock sandbox configured by `~/.config/ollie/sandbox/.yaml`. The sandbox wraps each invocation as a new command, so config changes (e.g. granting access to an additional directory) take effect on the next call without restarting the server or session. ## AI pipelines @@ -300,7 +300,7 @@ waits for all to finish, and returns their results concatenated in submission or is the right tool when work can be split into independent subtasks that don't need to talk to each other. -The agent invokes it via `execute_code`: +The agent invokes it via `shell`: ```json { @@ -448,7 +448,7 @@ Each agent can use a different `agent=`, `backend=`, or `model=` — set them in ### Self-generating workflows -Because agents have access to `execute_code`, a session can write and run a workflow +Because agents have access to `shell`, a session can write and run a workflow script without any human involvement. Given a task description and knowledge of the filesystem layout, an agent can decompose the work, create the named sessions, write the coordination script to a temp file, and execute it — all in a single turn. diff --git a/justfile b/justfile index 61fbe71..c175ca7 100644 --- a/justfile +++ b/justfile @@ -145,6 +145,7 @@ install-data: install -m644 prompts/agent-navigator.md {{cfg}}/prompts/agent-navigator.md install -m644 prompts/agent-taskmanager.md {{cfg}}/prompts/agent-taskmanager.md install -m644 prompts/agent-theo.md {{cfg}}/prompts/agent-theo.md + install -m644 prompts/user-preferences.md {{cfg}}/prompts/user-preferences.md install -m644 prompts/session-9p.md {{cfg}}/prompts/session-9p.md install -m644 prompts/session-dbus.md {{cfg}}/prompts/session-dbus.md # Sandbox diff --git a/prompts/agent-copilot.md b/prompts/agent-copilot.md index 9b4bc86..3d6d477 100644 --- a/prompts/agent-copilot.md +++ b/prompts/agent-copilot.md @@ -14,7 +14,7 @@ Read-only assistant embedded in the editor. You read files, you produce change b # What you CANNOT do -- You have NO access to `file_write`, `file_edit`, or `execute_code` +- You have NO access to `file_write`, `file_edit`, or `shell` - Do NOT attempt to call tools you don't have. They will fail. - Do NOT suggest using tools you don't have access to. diff --git a/prompts/agent-librarian.md b/prompts/agent-librarian.md index fe8efae..a243b1c 100644 --- a/prompts/agent-librarian.md +++ b/prompts/agent-librarian.md @@ -12,7 +12,7 @@ You are a knowledge curator agent. You scan, search, and read documents to answe - **Cite sources.** Reference file paths when presenting information so the user can verify. - **Stay grounded.** Base answers on document content. When synthesizing (code examples, procedures), clearly distinguish what comes from the documents vs. what you are inferring or constructing. - **No modifications.** Do not write, edit, or delete any files. You are read-only. -- **No execute_code.** You do not run shell commands or scripts. +- **No shell execution.** You do not run shell commands or scripts. # Workflow diff --git a/prompts/user-preferences.md b/prompts/user-preferences.md new file mode 100644 index 0000000..51b68d9 --- /dev/null +++ b/prompts/user-preferences.md @@ -0,0 +1,23 @@ +# User Preferences + +This file defines the user's preferred interaction style. Respect these preferences in all responses. + +## Communication style + +- Use direct, active voice. +- Produce direct answers or results without preamble, pleasantries, narration, analytical framing, and concluding remarks. + - BAD: "I'd be happy to help", "I'll", "I will", "I'm going to", "I can", "I've", "Let me", "Let's", "Now let me", "Now I need to", "Now let me understand", "Let me look at", "I need to understand". + - GOOD: [direct answer or result] + - GOOD: [tool call with no preamble] +- Use bullet points, bolded keywords, and numbered lists to make the response scannable. +- Exclude fluff, edge cases, and assumptions. Only provide facts that directly answer the prompt. + +## Visual-first communication + +The user is a visual learner and **strongly prefers** diagrams and illustrations over verbose prose. + +- Default to visual explanations: Mermaid diagrams (sequence, class, flowchart, state), ASCII art, or PlantUML when explaining architecture, data flow, state machines, relationships, or processes. +- Use prose only for what cannot be shown visually (rationale, tradeoffs, caveats). +- When both are needed, lead with the diagram, follow with minimal annotation. +- For code explanations: prefer annotated call-graph or sequence diagrams over paragraph-form walkthroughs. +- When asked "how does X work?" or "explain X", reach for a diagram first. diff --git a/scripts/README.md b/scripts/README.md index a6fbaf6..bf4448e 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -19,8 +19,6 @@ $OLLIE/u/optimize "prompt" # generate and return best optimized prompt Scripts are organized by the filesystem namespace they are hosted under: - `s/` — session management and one-shot query scripts -- `u/` — utility scripts; compositions of other ollie primitives -- `x/` — elevation plugins; called by `execute_code` for privileged steps --- @@ -208,7 +206,7 @@ Outputs to stdout, making it composable with other pipeline stages. ## x/elevate -Sandbox escape hatch invoked by `execute_code` when a step is marked `elevated: true`. +Sandbox escape hatch invoked by `shell` when a command is marked `elevated: true`. The Landlock sandbox is enforced at the kernel level — restrictions apply regardless of user privileges within the sandboxed process. `x/elevate` is a generic client that forwards the command to an adapter running outside the sandbox, which executes it and