Daemon Installation
The daemon executes Agent Runs. Register one or more runtimes to scale execution capacity.
The daemon executes Agent Runs. Register one or more runtimes to scale execution capacity.

Quick Start (Docker)
# 1. Get a registration token
# In Agent Orchestrator: Runtimes → Register Runtime → copy token
# 2. Run the daemon
docker run -d \
--name agenthub-daemon \
-e AGENTHUB_SERVER_URL=http://your-ao-server:8082 \
-e AGENTHUB_TOKEN=<your-token> \
-e AGENTHUB_RUNTIME_NAME="My Runtime" \
-v agenthub-workspaces:/root/agenthub_workspaces \
simplifierag/miri:daemon
Quick Start (Local / Bare Metal)
# 1. Install dependencies
# Python 3.11+, git, opencode (auto-installed by daemon)
# 2. Get registration token from AO UI
export AGENTHUB_SERVER_URL=http://your-ao-server:8082
export AGENTHUB_TOKEN=<your-token>
export AGENTHUB_RUNTIME_NAME="Local Runtime"
# 3. Run
python3 agenthub_daemon.py start --foreground
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
AGENTHUB_SERVER_URL |
Yes | — | Backend URL (e.g., http://localhost:8082) |
AGENTHUB_TOKEN |
Yes | — | Registration token from AO |
AGENTHUB_RUNTIME_NAME |
No | Docker Runtime |
Display name in AO |
AGENTHUB_WORKSPACE_ID |
No | — | Bind to specific workspace |
AGENTHUB_OPENCODE_PATH |
No | opencode |
Path to opencode binary |
AGENTHUB_OPENCODE_MODEL |
No | — | Default model for runs |
AGENTHUB_MAX_CONCURRENT |
No | 3 |
Max parallel runs |
AGENTHUB_POLL_INTERVAL |
No | 5000 |
Backend poll interval (ms) |
AGENTHUB_IDLE_WATCHDOG |
No | 1800000 |
Idle timeout (ms) |
AGENTHUB_RECONNECT_DELAY |
No | 5000 |
Backend reconnect delay (ms) |
AGENTHUB_LOG_MAX_BYTES |
No | 10485760 |
Log rotation size |
AGENTHUB_LOG_BACKUP_COUNT |
No | 5 |
Rotated log files to keep |
AGENTHUB_STATE_DIR |
No | <workspaces dir>/.daemon-state |
Where the daemon keeps its saved runtime credentials |
AGENTHUB_DRAIN_SECONDS |
No | 60 |
How long a stopping daemon waits for running work |
AGENTHUB_WUD_URL |
No | — | Watchtower Update Daemon URL |
Docker Compose (Production)
# docker-compose.daemon.prod.yaml
services:
daemon:
image: simplifierag/miri:daemon
environment:
AGENTHUB_SERVER_URL: https://your-ao.com
AGENTHUB_TOKEN: ${AGENTHUB_TOKEN}
AGENTHUB_RUNTIME_NAME: "Production Runtime"
volumes:
- daemon-workspaces:/root/agenthub_workspaces
restart: unless-stopped
volumes:
daemon-workspaces:
Run: docker compose -f docker-compose.daemon.prod.yaml --env-file .env.daemon.prod up -d
Systemd Service (Linux)
# Install (as root)
curl -fsSL https://raw.githubusercontent.com/simplifierag/sf-agent-os/main/daemon/install.sh | bash -s -- \
--server https://your-ao.com \
--token <token> \
--name "Production Runtime"
# Manage
systemctl status agenthub-daemon
systemctl restart agenthub-daemon
journalctl -u agenthub-daemon -f
opencode Integration
The daemon requires opencode for executing runs. It handles installation automatically:
- Docker image — Pre-installed at
/root/.opencode/bin/opencode - Local — Auto-installs on first run (
curl ... | bash) - Version — Pinned to compatible version in
daemon/Dockerfile
Model Configuration
Set default model per runtime:
export AGENTHUB_OPENCODE_MODEL=anthropic/claude-3-5-sonnet
Agents can override per-run via their execution settings.
Registration Tokens, Restarts and Updates
- A registration token works once and expires. Runtimes → Register Runtime shows the token with an “Expires in …” countdown (24 hours). It is used up the first time a daemon registers with it.
- A daemon needs no new token after that. When it registers, it saves its runtime credentials (
credentials.json, readable only by the daemon’s user) in its state directory — by default.daemon-stateinside the workspaces directory. A restart, a container recreate or an image update (including WUD) then resumes the same runtime from that file. - Keep the state directory on a volume. The compose files keep it in the daemon’s workspaces volume. If that volume is lost — or the daemon is started with another server URL, runtime name or token — it registers anew and needs a fresh token from Register Runtime.
- Stopping drains running work. On stop, the daemon takes no new Runs and waits up to
AGENTHUB_DRAIN_SECONDSfor running ones. Runs still unfinished go back to the queue immediately and are picked up again. Give your container or service a stop timeout above that value — the compose files use 90 seconds; a plaindocker stopwith the default 10 seconds would cut the wait short.
WUD Auto-Update (Watchtower)
Enable automatic daemon updates:
# In daemon compose, add WUD sidecar:
wud:
image: getwud/wud:latest
environment:
WUD_WATCHER_LOCAL_WATCHBYDEFAULT: "false"
WUD_SERVER_ENABLED: "true"
labels:
- "wud.watch.daemon=true"
- "wud.trigger.miri=true"
# In daemon:
environment:
AGENTHUB_WUD_URL: http://wud:3000
How it works:
- Backend sets
pendingUpdateflag on runtime - Daemon heartbeat delivers flag
- Daemon calls WUD locally → WUD pulls new image → restarts daemon
- Also checks every 6 hours for new
:latestdigest
Remote Backend + Local Daemon
Common pattern: AO backend in cloud, daemon on local machine:
# Local machine
export AGENTHUB_SERVER_URL=https://your-cloud-ao.com
export AGENTHUB_TOKEN=<token-from-cloud-ao>
python3 agenthub_daemon.py start
- Daemon polls cloud backend over HTTPS
- Git checkouts happen locally (your machine, your credentials)
- Deliveries pushed from your machine to git remote
Multiple Runtimes
Register multiple daemons for:
- Different environments — Dev / Staging / Prod
- Different hardware — GPU for coding, CPU for analysis
- Different networks — On-prem behind firewall + cloud
- Scaling — Distribute runs across machines
All runtimes appear in Runtimes page with individual health/capacity.
Troubleshooting
| Issue | Fix |
|---|---|
| “Connection refused” | Check AGENTHUB_SERVER_URL reachable from daemon |
| “Invalid token” | Regenerate token in AO → Runtimes → Register Runtime |
| “opencode not found” | Docker: use simplifierag/miri:daemon; Local: check PATH |
| “No models reported” | Ensure opencode version supports model discovery |
| “Workdir permission denied” | Volume mount: -v agenthub-workspaces:/root/agenthub_workspaces |
| “Git clone failed” | Check Git target credentials in Project Detail |
Logs
# Docker
docker logs -f agenthub-daemon
# Local (foreground)
python3 agenthub_daemon.py start --foreground
# Systemd
journalctl -u agenthub-daemon -f
Log file: ~/.agenthub/daemon.log (rotating, 10MB × 5 files by default)
PID File
~/.agenthub/daemon.pid — used by stop/restart/status commands.
Recent Updates
- opencode Integration — Auto-installs, pinned version, model configuration
- WUD Auto-Update — Daemon-mediated remote updates via Watchtower
- Multiple Runtime Support — Register many daemons, individual health tracking
- Remote Backend — Run daemon locally against cloud AO