docs/channels/broadcast-groups.md
Broadcast groups run multiple agents on the same inbound message. Each agent processes the message in its own isolated session and posts its own reply, so one WhatsApp number can host a team of specialized agents in a single group chat or DM.
Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, broadcasts happen when OpenClaw would normally reply (for example: on mention, depending on your group settings). They only change which agents run, never whether a message is eligible for processing.
The live WhatsApp QA lane includes whatsapp-broadcast-group-fanout, which verifies that one mentioned group message can produce distinct visible replies from two configured agents.
Add a top-level broadcast section (next to bindings). Keys are WhatsApp peer ids, values are arrays of agent ids:
[email protected])+15551234567){
"broadcast": {
"[email protected]": ["alfred", "baerbel", "assistant3"]
}
}
Result: when OpenClaw would reply in this chat, it runs all three agents.
Every listed agent id must exist in agents.list: config validation reports unknown ids, and the runtime skips them with a Broadcast agent <id> not found in agents.list; skipping warning.
broadcast.strategy sets how agents process the message:
| Strategy | Behavior |
|---|---|
parallel (default) | All agents process simultaneously; replies arrive in any order. |
sequential | Agents process in array order; each waits for the previous to finish. |
{
"broadcast": {
"strategy": "sequential",
"[email protected]": ["alfred", "baerbel"]
}
}
{
"agents": {
"list": [
{
"id": "code-reviewer",
"name": "Code Reviewer",
"workspace": "/path/to/code-reviewer",
"sandbox": { "mode": "all" }
},
{
"id": "security-auditor",
"name": "Security Auditor",
"workspace": "/path/to/security-auditor",
"sandbox": { "mode": "all" }
},
{
"id": "docs-generator",
"name": "Documentation Generator",
"workspace": "/path/to/docs-generator",
"sandbox": { "mode": "all" }
}
]
},
"broadcast": {
"strategy": "parallel",
"[email protected]": ["code-reviewer", "security-auditor", "docs-generator"],
"[email protected]": ["support-en", "support-de"],
"+15555550123": ["assistant", "logger"]
}
}
Each agent in a broadcast group maintains completely separate:
agent:alfred:whatsapp:group:120363... vs agent:baerbel:whatsapp:group:120363...)IDENTITY.md, SOUL.md, etc.)One exception is shared on purpose: the group context buffer (recent group messages used for context) is shared per peer, so all broadcast agents see the same context when triggered. It is cleared once after the fan-out completes.
This allows each agent to have different personalities, models, skills, and tool access (for example read-only vs. read-write).
In group [email protected] with agents ["alfred", "baerbel"]:
code-reviewer, security-auditor, test-generator, and docs-checker each answer the same message from their own angle.support-en, support-de, support-es responding in their languages.support-agent answers while qa-agent reviews and only responds when it finds issues.task-tracker, time-logger, and report-generator all consume the same status update.`reviewer` is read-only. `fixer` can read and write.
Broadcast groups are currently implemented for WhatsApp (web channel) only. Other channels ignore the broadcast config.
Broadcast groups work alongside existing routing:
{
"bindings": [
{
"match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "GROUP_A" } },
"agentId": "alfred"
}
],
"broadcast": {
"GROUP_B": ["agent1", "agent2"]
}
}
GROUP_A: only alfred responds (normal routing).GROUP_B: agent1 AND agent2 respond (broadcast).1. Agent IDs exist in `agents.list` (config validation rejects unknown ids).
2. Peer ID format is correct (group JID like `[email protected]`, or E.164 like `+15551234567` for DMs).
3. The message passed normal gating (mention/activation rules still apply).
**Debug:**
```bash
openclaw logs --follow | grep -i broadcast
```
A successful fan-out logs `Broadcasting message to <n> agents (<strategy>)`.
**Fix:** add ordinary route-bound peers to the broadcast config, or remove/change the configured ACP binding if fan-out broadcast is desired.
One code snippet in the group produces four replies: formatting fixes, a security finding, a coverage gap, and a docs nit.
interface OpenClawConfig {
broadcast?: {
strategy?: "parallel" | "sequential";
[peerId: string]: string[];
};
}