--- summary: "Multi-agent routing: isolated agents, provider accounts, and bindings" title: Multi-Agent Routing read_when: "You want multiple isolated agents (workspaces + auth) in one gateway process." status: active --- # Multi-Agent Routing Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple provider accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings. ## What is “one agent”? An **agent** is a fully scoped brain with its own: - **Workspace** (files, AGENTS.md/SOUL.md/USER.md, local notes, persona rules). - **State directory** (`agentDir`) for auth profiles, model registry, and per-agent config. - **Session store** (chat history + routing state) under `~/.clawdbot/agents//sessions`. The Gateway can host **one agent** (default) or **many agents** side-by-side. ### Single-agent mode (default) If you do nothing, Clawdbot runs a single agent: - `agentId` defaults to **`main`**. - Sessions are keyed as `agent:main:`. - Workspace defaults to `~/clawd` (or `~/clawd-` when `CLAWDBOT_PROFILE` is set). - State defaults to `~/.clawdbot/agents/main/agent`. ## Multiple agents = multiple people, multiple personalities With **multiple agents**, each `agentId` becomes a **fully isolated persona**: - **Different phone numbers/accounts** (per provider `accountId`). - **Different personalities** (per-agent workspace files like `AGENTS.md` and `SOUL.md`). - **Separate auth + sessions** (no cross-talk unless explicitly enabled). This lets **multiple people** share one Gateway server while keeping their AI “brains” and data isolated. ## Routing rules (how messages pick an agent) Bindings are **deterministic** and **most-specific wins**: 1. `peer` match (exact DM/group/channel id) 2. `guildId` (Discord) 3. `teamId` (Slack) 4. `accountId` match for a provider 5. provider-level match (`accountId: "*"`) 6. fallback to `routing.defaultAgentId` (default: `main`) ## Multiple accounts / phone numbers Providers that support **multiple accounts** (e.g. WhatsApp) use `accountId` to identify each login. Each `accountId` can be routed to a different agent, so one server can host multiple phone numbers without mixing sessions. ## Concepts - `agentId`: one “brain” (workspace, per-agent auth, per-agent session store). - `accountId`: one provider account instance (e.g. WhatsApp account `"personal"` vs `"biz"`). - `binding`: routes inbound messages to an `agentId` by `(provider, accountId, peer)` and optionally guild/team ids. - Direct chats collapse to `agent::` (per-agent “main”; `session.mainKey`). ## Example: two WhatsApps → two agents `~/.clawdbot/clawdbot.json` (JSON5): ```js { routing: { defaultAgentId: "home", agents: { home: { workspace: "~/clawd-home", agentDir: "~/.clawdbot/agents/home/agent", }, work: { workspace: "~/clawd-work", agentDir: "~/.clawdbot/agents/work/agent", }, }, // Deterministic routing: first match wins (most-specific first). bindings: [ { agentId: "home", match: { provider: "whatsapp", accountId: "personal" } }, { agentId: "work", match: { provider: "whatsapp", accountId: "biz" } }, // Optional per-peer override (example: send a specific group to work agent). { agentId: "work", match: { provider: "whatsapp", accountId: "personal", peer: { kind: "group", id: "1203630...@g.us" }, }, }, ], // Off by default: agent-to-agent messaging must be explicitly enabled + allowlisted. agentToAgent: { enabled: false, allow: ["home", "work"], }, }, whatsapp: { accounts: { personal: { // Optional override. Default: ~/.clawdbot/credentials/whatsapp/personal // authDir: "~/.clawdbot/credentials/whatsapp/personal", }, biz: { // Optional override. Default: ~/.clawdbot/credentials/whatsapp/biz // authDir: "~/.clawdbot/credentials/whatsapp/biz", }, }, }, } ```