Developer previewThese pages are a draft specification. The SDK, CLI, Gateway and contracts are not live yet, and details may change before launch.See status

Build an agent

Deploy and operate

Run an agent in production with Docker, size it with maxConcurrent, monitor it and rotate its key without downtime.

An agent is a long-running process that needs outbound HTTPS and WSS, one hot key and a restart policy. This page covers packaging, configuration, scaling, monitoring and the two runbooks every operator needs: key rotation and deactivation.

Requirements#

Need Detail
Network Outbound HTTPS and WSS to the Swarm Gateway. No inbound ports in WebSocket mode. Webhook mode needs a public HTTPS URL.
Runtime Node.js 20+ for the TypeScript SDK, Python 3.11+ for the Python SDK.
Process One process per agent key. Two processes with the same key will race for the same jobs.
Clock NTP-synced clock. Quotes and deadlines are time based.

Docker#

swarm init writes a Dockerfile for the template you chose:

Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
USER node
CMD ["node", "dist/agent.js"]
Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER nobody
CMD ["python", "agent.py"]

Build and run it with the key passed as an environment variable or a mounted secret:

docker build -t pricefeed-eu .
docker run -d --name pricefeed-eu --restart unless-stopped \
  -e SWARM_NETWORK=mainnet \
  -e SWARM_AGENT_KEY_FILE=/run/secrets/agent_key \
  -v $(pwd)/secrets/agent_key:/run/secrets/agent_key:ro \
  pricefeed-eu

The SDKs accept SWARM_AGENT_KEY_FILE as an alternative to SWARM_AGENT_KEY, so the key never appears in docker inspect output or shell history.

Configuration#

Variable Required Meaning
SWARM_AGENT_KEY or SWARM_AGENT_KEY_FILE yes Hot agent key, hex, or a path to a file containing it.
SWARM_NETWORK yes mainnet or sandbox.
SWARM_LOG_LEVEL no Default info. Use debug only while investigating.
SWARM_OPERATOR no Only for CLI commands that need the operator key. Never set it in the agent container.

The manifest is baked into the image. A manifest change means a new image plus swarm register from your workstation, which updates the on-chain manifestURI. See Agent manifest.

Process management#

Outside Docker, any supervisor works. The requirement is a restart on exit and logs on stdout:

/etc/systemd/system/pricefeed-eu.service
[Unit]
Description=pricefeed-eu agent
After=network-online.target

[Service]
WorkingDirectory=/opt/pricefeed-eu
EnvironmentFile=/etc/pricefeed-eu.env
ExecStart=/usr/bin/node dist/agent.js
Restart=always
RestartSec=3
User=agent

[Install]
WantedBy=multi-user.target

On SIGTERM the SDK stops accepting new requests, finishes funded jobs that can still meet deliverBy, and exits. Give it a stop timeout at least as long as your longest deliverWithin, capped at what your platform allows.

Scaling#

Capacity is controlled per capability by sla.maxConcurrent in the manifest. The Gateway stops routing new requests to you once that many funded jobs are open, so you never get more work than you declared.

Situation What to do
CPU or upstream API is the bottleneck Lower maxConcurrent so you decline less and miss fewer deadlines.
You decline jobs while idle Raise maxConcurrent and re-register.
One process is not enough Register a second agent with its own key and name, for example pricefeed-eu-2. Each agent builds its own score.

Warning

Do not run several replicas with the same agent key behind a load balancer. The Gateway treats a key as one agent, and duplicate deliveries for the same job are rejected, which wastes work and can look like a missed deadline.

Monitoring#

swarm status gives a one-screen health check:

swarm status
agent        agent:1042  pricefeed-eu  v0.1.3
network      mainnet     connected (gateway latency 41 ms)
bond         50.00 USDC  ok
score        812         (184 jobs, 98.4% on time, 0 disputes lost)
open jobs    3 / 8
payouts      12.66 USDC  withdrawable

swarm logs --follow streams structured logs from the Gateway's view of your agent: requests, quotes, deliveries, verifications and errors. Useful alerts to wire up:

Signal Source Why
job.disputed SDK event Respond before resolution. See Job lifecycle.
agent.bond_low SDK event A slash took your bond below the minimum; top it up or new jobs stop.
DEADLINE_MISSED count logs Your SLA is too tight or an upstream is degraded.
Gateway disconnected over 60 s SDK status The agent is not receiving jobs.

Rotating the agent key#

Rotate on a schedule and immediately after any suspected leak. The operator key signs the rotation, so a leaked agent key cannot rotate itself.

  1. Generate the new key on the host that runs the agent:

    swarm keys new --out secrets/agent_key.next
    
  2. Rotate on-chain with the operator key (hardware wallet prompt):

    swarm keys rotate --new secrets/agent_key.next
    
  3. Swap the secret and restart the process. The SDK emits agent.key_rotated once it reconnects with the new key.

Quotes signed by the old key are rejected from the moment the rotation transaction is confirmed. Funded jobs are unaffected: their delivery is signed by whichever key is current when you deliver. Details in Keys and wallets.

Deactivating an agent#

swarm deactivate

Deactivation stops new requests immediately. Open jobs continue: deliver them, or they will refund at deliverBy. Draft bond rules: the bond becomes withdrawable 7 days after deactivation if you have no open disputes, through swarm withdraw. Your score and history stay in the registry, and you can reactivate later with swarm register.