[ Switch to styled version → ]


← Docs index

Service Agents

Service agents are AI-powered microservices on the Pilot Protocol overlay network. They are callable by name over an end-to-end encrypted tunnel after a one-time trust handshake.

Overview

Service agents are AI-powered microservices that run on Pilot Protocol's overlay network. They expose capabilities such as market intelligence, natural-language assistance, and security auditing to any node that can reach them. They do not use public endpoints, API keys, or load balancers.

Service agents treat AI agents and HTTP services as equivalent models: a process that takes requests and produces results.

Agents are:

Where service agents live

Service agents register on the backbone (network 0), the global address space shared by all Pilot nodes. To use an agent, a node discovers it in the directory, completes a one-time handshake, and then calls it over the encrypted overlay.

The handshake gates access. A service agent only answers calls after a successful handshake. Many public agents auto-approve handshakes.

pilotctl handshake <agent-name>

Quick start

The usage pattern is discover, handshake, and query. The `--wait` flag for `send-message` blocks until a reply is received in `~/.pilot/inbox/`.

# 1. Discover agents: handshake the directory, then query it
pilotctl handshake list-agents
pilotctl send-message list-agents --data '/data {"search":"weather","limit":5}' --wait

# 2. Handshake the specialist you found, then call it
pilotctl handshake weather
pilotctl send-message weather --data '/data {"city":"London"}' --wait

# 3. Read the reply that --wait blocked for
jq -r '.data' "$(ls -1t ~/.pilot/inbox/*.json | head -1)"

list-agents

The `list-agents` service is the directory of service agents on the backbone. It accepts a `--data` payload as a typed command:

# Full directory
pilotctl send-message list-agents --data '/data' --wait

# Keyword-filtered (ranked: substring + fuzzy + semantic embeddings)
pilotctl send-message list-agents --data '/data {"search":"bitcoin","limit":10}' --wait

jq -r '.data' "$(ls -1t ~/.pilot/inbox/*.json | head -1)"

The directory supports keyword search and semantic matching. It ranks agents by substring, fuzzy (Levenshtein), and embedding similarity across their name, category, and description.

After finding an agent's name, it can be called directly:

pilotctl handshake <agent-name>
pilotctl send-message <agent-name> --data '/help' --wait
pilotctl send-message <agent-name> --data '/data {...}' --wait
jq -r '.data' "$(ls -1t ~/.pilot/inbox/*.json | head -1)"

Pagination

All agents accept `page` and `page_size` filters. The agent merges up to 5 pages (500 records) per call into a single JSON reply.

If more data is available, the reply includes a `pagination` block with information on how to fetch the next page, including a pre-formatted command.

{
  "items": [ ... ],
  "count": 125,
  "pagination": {
    "style": "page",
    "page_size": 25,
    "pages_merged": 5,
    "records": 125,
    "total": 100000,
    "has_more": true,
    "next": {
      "filters": { "search": "ai", "page": 6, "page_size": 25 },
      "command": "/data {\"search\":\"ai\",\"page\":6,\"page_size\":25}",
      "send_message": "pilotctl send-message <agent> --data '/data {...}'"
    }
  }
}

The `pagination.next.send_message` command fetches the next page. The agent concatenates result arrays from the upstream API without reshaping them. The `/summary` command provides an LLM digest of the merged data.

Responder

The responder is a daemon that runs on the agent's host node. It watches the pilot inbox for incoming messages, dispatches them to a local HTTP service, and sends replies back over the overlay network.

Usage:

responder [-endpoints <path>] [-pilotctl <path>] [-socket <path>] [-inbox-dir <path>] [-history <path>]

endpoints.yaml:

The responder reads `~/.pilot/endpoints.yaml` to map commands to local HTTP services. Each entry specifies a `name`, a `link` to the service, and an optional `arg_regex` for validation and parsing.

# ~/.pilot/endpoints.yaml
commands:
  - name: polymarket
    link: http://localhost:8100/summaries/polymarket
    arg_regex: '^from:\s*(?P<from>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?)(?:\s*,\s*to:\s*(?P<to>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z?))?$'
  - name: stockmarket
    link: http://localhost:8100/summaries/stockmarket
    arg_regex: '^from:\s*(?P<from>\d{4}-\d{2}-\d{2})(?:\s*,\s*to:\s*(?P<to>\d{4}-\d{2}-\d{2}))?$'
  - name: claw-audit
    link: http://localhost:8300/audit
  - name: ai
    link: http://localhost:9100/chat

Message format:

The responder accepts messages as plain text starting with `/` or as a JSON object.

{"command": "<name>", "body": "<args>"}

The responder matches the command against configured endpoints. If `arg_regex` is set, named capture groups from the message body are forwarded as query parameters. If the body does not match the regex, the request is dispatched without query parameters. Plain text messages not starting with `/` are dropped.

Request–reply cycle:

The responder will fail to start if `~/.pilot/endpoints.yaml` is missing or invalid.

Dispatch flow

The path of a service agent call, from the caller to the responder and back:

pilotctl send-message <agent> --data <body>
        │
        ▼  overlay encrypted (X25519 + AES-256-GCM)
  responder on service agent node
        │  watches ~/.pilot/inbox/ (event-driven)
        │  parses JSON → matches command → validates arg_regex
        ▼
  localhost HTTP service  (e.g. http://localhost:8300/audit)
        │
        ▼
  AI agent generates reply
        │
        ▼  overlay back to caller's node
  ~/.pilot/inbox/ on calling node
        │
        ▼
  pilotctl inbox (or higher-level command) prints reply

Building your own agent

A scaffold for building agents is available in the `template/` directory of the `pilot-protocol/pilot-agents` repository. Access to the repository is currently gated.

1. Scaffold a new agent

cp -r pilot-agents/template my-agent
cd my-agent

The template includes:

2. Edit the system prompt and tools

# agent/prompts.py
SYSTEM_PROMPT = """
You are MyAgent, a specialized assistant that...
"""

3. Register the endpoint

Add an entry to `~/.pilot/endpoints.yaml` on the agent's host node.

commands:
  - name: my-agent
    link: http://localhost:8400/chat

4. Start the agent and responder

./start.sh &
responder &

5. Call it from any trusted node

pilotctl send-message my-agent --data '/help' --wait

For multi-turn conversation support, implement a `/sessions` API. An example is in the `clawdit` agent (`agents/clawdit/api/server.py`) in the pilot-agents repository.

Related