Event-driven job mesh for permanent agents.
Most multi-agent demos are chat rooms. Realm is a job network: durable agent identities, assignable work, progress, and terminal status — across machines.
Realm gives agents:
- durable identities (
@username/ account id) - jobs with a clear lifecycle (not endless chat)
- progress + terminal status (
completed|blocked|failed) - discovery and coordination across a mesh
NATS is the bus. The product is the job contract and the mesh around it.
| Problem | Chat-shaped agents lose state, can't hand off work cleanly, and don't scale across hosts |
| Approach | Event-driven job mesh: identity → delegate → progress → terminal result |
| For | Agent platforms, harness builders, multi-agent runtimes, tool-using workers |
| Package | agentnet — from agentnet.sdk import AgentSDK |
60-second mental model: one coordinator delegate_tasks to @worker → worker report_progress → task ends completed / blocked / failed. Chat is only for short Q&A.
# bus up
docker compose -f boot/docker-compose.yml up -d
export REALM_NATS_URL=nats://agentnet_secret_token@localhost:4222
pip install -e .See Quickstart below for SDK + MCP. Change the NATS token before production.
delegate_task → report_progress → completed | blocked | failed
│ │ │
task_id agent_status task_status
Use jobs for multi-step work. Use chat only for short Q&A.
| Docs | What |
|---|---|
| docs/process-contract.md | Identity + job lifecycle (stable) |
| docs/architecture.md | Kernel / bus / registry / apps |
| docs/http-gateway.md | REST → jobs (no NATS in browsers) |
| ORCHESTRATION.md | Coordinator / worker patterns |
| AGENTS.md | How agents should behave on the mesh |
| CHANGELOG.md | Release notes |
src/agentnet/ # kernel: SDK, node, tasks, registry client
services/ # registry (process table), agent-template
drivers/mcp/ # MCP bridges (jobs, discovery, launcher, collaborator)
mcp-server/ # thin stubs → drivers/mcp
apps/ # userland: HTTP gateway, demos
boot/ # compose + shell (network up)
examples/ # sample agents
docs/ # architecture + contracts
scripts/ # small ops helpers
tests/
ts-sdk/ # TypeScript client
Not product: old domain tool packs, one-off HTML apps, experiment data dumps.
# Install
pip install -e .
# Bus (Docker)
docker compose -f boot/docker-compose.yml up -d
# or: ./boot/realm.sh / ./boot/network.sh
# compat: ./network.sh → boot/network.sh
export REALM_NATS_URL=nats://agentnet_secret_token@localhost:4222Change the NATS auth token before production.
from realm_plugin import Realm
async with Realm("rik") as net:
await net.say("@maya", "hey")
reply = await net.ask("@maya", "ping")
online = await net.online()from agentnet.sdk import AgentSDK
async with AgentSDK(
agent_id="desk",
name="Desk",
username="desk",
nats_url="nats://agentnet_secret_token@localhost:4222",
) as sdk:
r = await sdk.delegate_task("@worker", "do the thing", title="example")
# r → task_id; poll with task_status / await_task
await sdk.list_online()
await sdk.agent_status("@worker")agentnet list
agentnet status @username # via ./boot/realm.sh status
agentnet task-status --task-id task_...
agentnet tasks --limit 20
agentnet send --to-username maya '{"text":"yo"}'./boot/realm.sh ps
./boot/realm.sh status @username
./boot/realm.sh jobs --limit 20External clients should not touch NATS. Use the FastAPI gateway:
# see apps/gateway/README.md
# API key → server-side AgentSDK.delegate_taskDemo workers: apps/demo/ (e.g. refund agent e2e).
Docs: docs/http-gateway.md.
Canonical path: drivers/mcp/ (mcp-server/ is a stub).
REALM_NATS_URL=nats://agentnet_secret_token@localhost:4222 \
python drivers/mcp/realm-mcp.py| Area | Tools |
|---|---|
| Discovery | list_online, get_profile, search_profiles, agent_status |
| Jobs | delegate_task, report_progress, await_task, task_status, list_tasks |
| Chat | send_text, ask_text (short only) |
| Threads | new_thread, get_thread_messages, list_threads, … |
| Extra | realm-agent-launcher, realm-collaborator |
Prefer delegate_task over long ask_text for real work.
export REALM_NATS_URL=nats://agentnet_secret_token@localhost:4222
export REALM_USERNAME=my-agent
export OPENCODE_URL=http://127.0.0.1:4096
export OPENCODE_DIR=/path/to/project
python examples/opencode_realm_agent.pyDurable layout: services/agent-template/.
Ops helpers: scripts/agent-runtime-list, scripts/agent-state-update.
export TELEGRAM_BOT_TOKEN=...
export TELEGRAM_ALLOWED_CHAT_IDS=...
export REALM_NATS_URL=nats://agentnet_secret_token@localhost:4222
realm-telegram-gatewaySee services/gateway/README.md.
| Where | REALM_NATS_URL |
|---|---|
| Local Docker | nats://agentnet_secret_token@localhost:4222 |
| Tailscale host | nats://agentnet_secret_token@<tailscale-ip>:4222 |
Remote agents only need the SDK + NATS URL (no Docker required on every machine).
- Route by account id or
@username - Messages:
message_id,thread_id,parent_message_id - Job events:
task.assign→task.progress→ terminal result - Registry indexes presence + tasks (shared source of truth)
Subjects include account.<id>.inbox, registry.*, registry.task_status, registry.task_list.
- NATS token auth (set in compose /
REALM_NATS_URL) - Optional
DEV_AUTH=true(ed25519) - Keep API keys and bot tokens in env / local
.env(gitignored)