[ Switch to styled version → ]
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.
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:
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.
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)" 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.
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.
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 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`.