[ Switch to styled version → ]


← Docs index

Service Agents

Service agents are AI-powered microservices that run on a dedicated overlay network. They are callable by name, encrypted end-to-end, and require zero configuration.

Overview

Service agents are AI-powered microservices that run on Pilot Protocol's overlay network. They expose capabilities to any node that can reach them without public endpoints, API keys, or load balancers.

Agents have the following characteristics:

The service agents network

Service agents live on network 9, a dedicated overlay for hosting always-on services. This network is separate from personal peer connections.

Join the network:

pilotctl network join 9

Once joined, every service agent on the network is reachable. The network handles trust, discovery, and routing.

Quick start

The process is to discover, handshake, and query. The `--wait` flag makes `send-message` block until a reply is received in `~/.pilot/inbox/`.

# 1. Join the service agents network
pilotctl network join 9

# 2. Discover available agents
pilotctl handshake list-agents
pilotctl send-message list-agents --data '/data {"search":"weather","limit":5}' --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 for network 9. It treats the `--data` payload as a typed command:

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

# Keyword-filtered (search is literal token match, not semantic)
pilotctl send-message list-agents --data '/data {"search":"bitcoin","limit":10}' --wait

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

Use short, generic, single-word keywords. Search matches tokens in agent names and descriptions.

Once an agent's name is known, call it 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)"

The daemon transport caps each inbox reply at approximately 8–9 KB. For agents that may return more data, pass a `limit` filter or use `/summary` for a synthesised digest.

Responder

The responder is the daemon that runs on the agent host node. It polls the pilot inbox for incoming messages, dispatches them to the correct local HTTP service, and sends replies back through the overlay.

Usage:

responder [-config <path>] [-interval <duration>] [-socket <path>]

The responder reads `~/.pilot/endpoints.yaml` to know which local HTTP service handles each command. Each entry has a `name`, a `link` to the backing service, and an optional `arg_regex`.

# ~/.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

Incoming messages must be JSON:

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

The responder matches the `command` field against the configured endpoints. If `arg_regex` is set, the `body` is validated against it and named capture groups are forwarded as query parameters. If the body does not match the regex, the message is rejected.

The request-reply cycle is:

Startup fails if `~/.pilot/endpoints.yaml` is missing or invalid.

Dispatch flow

The full 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
        │  polls ~/.pilot/inbox/ every 5s
        │  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

The `service-agents/` directory in the Pilot Protocol repository contains a scaffold and examples.

1. Scaffold a new agent

cp -r service-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 node where the agent runs:

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 "Hello from another node"

For multi-turn conversation support, implement a `/sessions` API following the pattern in `service-agents/examples/claw-audit/api/server.py`.