ollie/doc/architecture-tools.md

7.8 KiB
Raw Blame History

Tools Architecture and Authoring

A tool is declared by a .meta file. It may also have an accompanying executable, but neither form is required in every case:

  • Metadata plus binary/script: place <name>.meta beside an executable named <name>.
  • Metadata only: set cmd in <name>.meta to a shell command. The registry executes that command directly.

Both approaches are valid. The .meta file is always the source of discovery, model-facing documentation, and the JSON argument schema.

The registry reads the metadata, presents the tool to the model, and executes the resolved command when called. No integration with the Ollie source tree is required. Put the .meta file in $OLLIE_TOOLS_PATH; the tool is available on the next discovery or session start.

Quick start

Metadata plus an executable

~/.config/ollie/tools/
├── my_tool        # executable in any language
└── my_tool.meta   # JSON metadata

Metadata-only tool

{
  "description": "Extract a value from JSON.",
  "prompt": "## json_value\n\nRead `.path` from JSON input.",
  "cmd": "input=$(cat); echo \"$input\" | jq -r '.path'",
  "args": {
    "type": "object",
    "required": ["path"],
    "properties": {"path": {"type": "string"}}
  }
}

A metadata-only tool needs no script or binary. Its cmd is run through the shell with the tool-call JSON on standard input.

The .meta sidecar

The .meta file is the sole source of discovery and schema. The registry never inspects an accompanying executable to infer its interface.

{
  "description": "One-liner shown in tool listings.",
  "prompt": "## my_tool\n\nFull documentation shown when loaded.",
  "args": {
    "type": "object",
    "required": ["path"],
    "properties": {
      "path": {"type": "string", "description": "File path"}
    }
  },
  "tier": "hot",
  "cmd": "my_tool"
}
Field Type Purpose
description string One-liner shown in the tool listing.
prompt string Documentation injected when the tool is loaded.
keywords array of strings Additional user-language phrases used only for semantic discovery. Include synonyms, task verbs, file types, domains, and representative requests.
args JSON Schema Input schema exposed to the model.
tier hot, warm, or cold Context retention tier.
cmd string Shell command or executable path/name.
variants array Conditional definitions for heterogeneous hosts.
scope string Tool scope metadata.
outputFormat string Output format metadata.
resetsCounter bool Marks tools that reset the relevant counter.

Tool and skill discovery

Tool discovery remains metadata-driven: toolsrv scans .meta files and manages which tools are loaded for an agent. Ollie adds a separate semantic ranking layer before prompt assembly. The ranking text combines description, prompt, and optional keywords. Keywords are discovery-only vocabulary: they should contain the words users use to request the operation, including synonyms, workflow phrases, file types, and domain terms. They are not shown as a second model-facing schema and do not change execution. See architecture-embedding.md for the embedding model, index lifecycle, matching thresholds, and failure behavior.

Command resolution

When the registry resolves a tool named name, it checks:

  1. $OLLIE_TOOLS_PATH/name — a co-located executable or script.
  2. The resolved .meta cmd field — an absolute path, bare executable name, or shell command.
  3. name through $PATH.

A co-located executable takes precedence over cmd. Metadata-only tools use the cmd value directly through the shell. This supports scripts, compiled binaries, wrappers, system commands, and pipelines.

Variants

The first variant whose conditions all match determines the tool’s schema, documentation, and command. If no variant matches, the tool is hidden.

Key Semantics Example
binary Binary exists in $PATH or at an absolute path. journalctl
file File or directory exists. /var/log/syslog
os Matches runtime.GOOS. linux
arch Matches runtime.GOARCH. amd64
env Environment variable is non-empty. DISPLAY
nenv Environment variable is empty or unset. SSH_CONNECTION

All keys in one match object use AND logic. An array value uses OR logic. Variant fields override top-level fields; unset fields inherit. If a remote toolsrv receives the metadata, it evaluates variants against the remote host.

{
  "description": "Read system logs.",
  "variants": [
    {"match": {"binary": "journalctl"}, "cmd": "system_logs_journald"},
    {"match": {"file": "/var/log/syslog"}, "cmd": "system_logs_syslog"}
  ]
}

Input and output contract

Both tool forms use the same contract:

  • Input is one JSON object on standard input.
  • Successful output is written to standard output and exits with status 0.
  • Errors may be written to standard output or standard error and exit non-zero.
  • Structured output may be returned as {"content": [...]} JSON.

The dispatcher does not require flags, argv conventions, or language-specific integration.

Executable example

#!/usr/bin/env python3
import json
import sys

args = json.load(sys.stdin)
print(f"result: {args['path']}")

Metadata-only example

{
  "description": "Search with ripgrep.",
  "cmd": "input=$(cat); p=$(echo \"$input\" | jq -r '.pattern'); rg \"$p\"",
  "args": {
    "type": "object",
    "required": ["pattern"],
    "properties": {"pattern": {"type": "string"}}
  }
}

For subcommand-style tools, parse the JSON with jq and construct the command explicitly. Avoid unsafe eval when arguments can be passed as arrays or quoted shell parameters.

Sandboxing and bypass

Toolsrv owns sandbox enforcement and the bypass approval path. See architecture-toolsrv.md. Tool metadata declares the command interface; it does not define the complete security policy.

Environment

Tools may receive:

Variable Purpose
OLLIE_TOOLS_PATH Tool metadata and executable directory.
OLLIE_BYPASS_SOCKET Bypass broker socket.
PWD Session working directory.

Installation and testing

Copy a .meta file and, when using the binary approach, its executable to the tools directory:

cp my_tool.meta ~/.config/ollie/tools/
cp my_tool ~/.config/ollie/tools/
chmod +x ~/.config/ollie/tools/my_tool

A metadata-only tool needs only the first command. Test its command contract with JSON on standard input:

echo '{"pattern":"TODO"}' | bash -c 'YOUR_CMD'

Agent profiles load tools at startup with autoLoad. Each profile specifies the tools it needs — there is no lazy loading or automatic tool discovery at call time:

{
  "autoLoad": ["shell", "file_read", "file_edit", "file_grep", "file_glob"]
}

To add a tool to a running agent, use the ctl file:

client_9p(op="rdwr", path="session/$OLLIE_SESSION_ID/agent/$OLLIE_UNAME/ctl", data="tool_load <name>")

After loading, the agent refreshes its model-facing schemas when the toolsrv registry revision changes. See architecture-toolsrv.md for discovery, loading, registry, and execution architecture.

Repository examples

The repository includes executable and metadata-backed tools under data/tools/, including filesystem, GUI, LSP, and memory tools. Compiled tools are valid alongside scripts and metadata-only definitions.

See architecture.md for the design rationale, including why Ollie does not implement native MCP, embedded tool frameworks, workflow engines, parallel frontend control planes, or competing memory stores.