Configuration
Broadcast groups
Overview
Agent group threads run multiple agents on the same inbound message, using the top-level broadcast config. Each agent runs in its own session. Channel-qualified entries can select participants by mention and allow a bounded number of follow-up rounds so agents can build on sibling replies.
Channel allowlists and group activation rules still apply. For qualified entries on Discord, Slack, and Telegram, an explicit mention of any configured participant can satisfy the room’s mention gate, even when that participant is not the ordinary routed agent. Legacy WhatsApp entries keep their existing admission behavior.
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.
Configuration
Agent group threads
Use a key in the form "<channel>:<peerId>", such as
"discord:123456789", "slack:C0123", "telegram:-100123", or
"whatsapp:1203@g.us". The value can be an agent ID array or a strict object:
{ agents: { ownership: "explicit", entries: { reviewer: { name: "Reviewer", groupChat: { mentionPatterns: ["@reviewer\\b"] }, }, writer: { name: "Writer", groupChat: { mentionPatterns: ["@writer\\b"] }, }, }, }, bindings: [{ agentId: "reviewer", match: { channel: "telegram" } }], broadcast: { "telegram:-100123": { agents: ["reviewer", "writer"], mentionGating: true, maxRounds: 2, maxTurns: 4, }, },}The ordinary channel route still needs an agent; the binding above selects
Reviewer for admission before group dispatch. After the room is allowed by its
channel config, send @reviewer @writer Review this draft. Both participants can answer the initial message and, within the
budget, add something new in one follow-up round. Send @writer to select only
Writer for the initial round.
| Object field | Default | Contract |
|---|---|---|
agents |
Required | Configured agent IDs; at most 16 participants. |
mentionGating |
true |
Select explicitly mentioned participants; if none match, select all. |
maxRounds |
1 |
Integer from 1 to 4, including the initial round. |
maxTurns |
agents.length |
Integer from 1 to 32; total participant turns started for one inbound message. |
Unknown object fields are rejected. Qualified arrays use the same defaults:
"slack:C0123": ["reviewer", "writer"] runs one initial round with mention
selection. A qualified WhatsApp key takes precedence over an unqualified key
for the same peer. Unqualified object entries are not supported.
maxTurns counts agent runs started by the coordinator, including runs
that pass or fail. Slots are reserved synchronously before parallel launch, so
parallel participants cannot overspend the budget. If the budget is smaller
than the eligible participant count, configured order determines which turns
start. A turn can produce multiple platform messages through chunks, previews,
or message-tool sends. Those deliveries are governed by the agent run and
channel transport; maxTurns does not count, buffer, or cap physical messages.
Telegram, Discord, and Slack disable their shared preview and progress drafts for qualified group threads so concurrent participants do not overwrite each other's drafts. Final replies, block replies, and message-tool sends remain available.
The default turn budget covers one turn per configured agent. To let every
agent run twice, set maxRounds: 2 and maxTurns to twice the participant count.
Mention selection
Selection uses only explicit @-style matches in the current inbound text,
computed once for the participant set. A name in prose or a bare emoji does not
select a participant. Mention patterns resolve from the agent’s
groupChat.mentionPatterns, then messages.groupChat.mentionPatterns, then its
identity-derived patterns. Give participants distinct patterns when you want
to address them separately.
With mentionGating: true, a match selects only the matching participants for
round 1; no matches selects all. With mentionGating: false, all participants
are selected. This option does not turn off the channel’s requireMention
policy, sender allowlists, or command authorization.
Bounded follow-up rounds
After a completed round, another round can run only within both maxRounds
and maxTurns. Eligible participants are those that produced a final reply
in the previous round or were addressed by name in a sibling’s final reply.
Each participant's final text is limited to 4,000 characters in the digest;
the combined sibling text is limited to 16,000 characters.
Each receives an attributed, size-bounded digest of sibling finals from that
round, with an instruction to reply only when adding something new and otherwise
return NO_REPLY. Passing does not produce a visible final reply.
All participants passing ends the thread. Reaching either limit or cancellation also stops further turns. Each continuation has its own internal identity; it is not a replay of the physical inbound message. Sequential strategy changes launch order within a round; it does not turn that round into a pipeline where each participant sees earlier replies from the same round.
Budget state is in memory, scoped to the channel, account, conversation, thread, and root inbound message. It is not restart-resumable: a Gateway restart loses the active round and budget state. Ordinary inbound deduplication remains a separate protection.
Participant labels
When a qualified entry configures more than one participant, Discord, Slack, and Telegram replies begin with the participant name in bold. The configured count controls labeling, even if mention selection, the turn budget, or silence leaves only one responder. WhatsApp presentation remains unchanged.
Basic setup
Legacy single-pass setup uses unqualified WhatsApp peer IDs as keys and arrays of agent IDs as values:
- group chats: group JID (e.g.
120363403215116621@g.us) - DMs: sender E.164 phone number (e.g.
+15551234567)
{ "broadcast": { "120363403215116621@g.us": ["alfred", "baerbel", "assistant3"] }}Result: when OpenClaw would reply in this chat, it runs all three agents.
Every listed agent ID must exist in the configured roster: config validation rejects unknown IDs in both arrays and objects. Deleting an agent prunes it from both forms.
Runtime membership uses the canonical agents.entries roster when present, including an empty roster. Legacy agents.list is used only when agents.entries is absent.
Processing strategy
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", "120363403215116621@g.us": ["alfred", "baerbel"] }}Complete example
{ "agents": { "entries": { "code-reviewer": { "default": true, "name": "Code Reviewer", "workspace": "/path/to/code-reviewer", "sandbox": { "mode": "all" } }, "security-auditor": { "name": "Security Auditor", "workspace": "/path/to/security-auditor", "sandbox": { "mode": "all" } }, "docs-generator": { "name": "Documentation Generator", "workspace": "/path/to/docs-generator", "sandbox": { "mode": "all" } } } }, "broadcast": { "strategy": "parallel", "120363403215116621@g.us": ["code-reviewer", "security-auditor", "docs-generator"] }}How it works
Message flow
Incoming message arrives
A channel message arrives.
Route and admission
OpenClaw applies channel allowlists, group activation rules, and configured ACP binding ownership.
Broadcast check
If no configured ACP binding owns the route, OpenClaw checks the qualified channel/peer key, then the legacy peer key for WhatsApp.
If broadcast applies
- Selected participants process the message within the round and turn limits.
- Each agent has its own session key and isolated context.
- Agents process in parallel (default) or sequentially.
- WhatsApp audio attachments are transcribed once before fan-out, so agents share one transcript instead of making separate STT calls.
If broadcast does not apply
OpenClaw dispatches the ordinary route or the configured ACP session route selected during routing.
Session isolation
Each agent in a broadcast group maintains completely separate:
- Session keys (
agent:alfred:whatsapp:group:120363...vsagent:baerbel:whatsapp:group:120363...) - Conversation history (sibling replies are shared only through bounded follow-up digests)
- Workspace (separate sandboxes if configured)
- Tool access (different allow/deny lists)
- Memory/context (separate
IDENTITY.md,SOUL.md, etc.)
On Discord, Slack, and Telegram, reply delivery and completion hooks use the responding participant's session, and local media resolves with that participant's media roots. This also applies to qualified entries with one participant, whose replies do not have a participant name label.
On WhatsApp, one input 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).
Example: isolated sessions
In group 120363403215116621@g.us with agents ["alfred", "baerbel"]:
Alfred's context
Session: agent:alfred:whatsapp:group:120363403215116621@g.usHistory: [user message, alfred's previous responses]Workspace: ~/openclaw-alfred/Tools: read, write, execBaerbel's context
Session: agent:baerbel:whatsapp:group:120363403215116621@g.usHistory: [user message, baerbel's previous responses]Workspace: ~/openclaw-baerbel/Tools: read onlyUse cases
- Specialized agent teams: a dev group where
code-reviewer,security-auditor,test-generator, anddocs-checkereach answer the same message from their own angle. - Multi-language support: one support chat with
support-en,support-de,support-esresponding in their languages. - Quality assurance:
support-agentanswers whileqa-agentreviews and only responds when it finds issues. - Task automation:
task-tracker,time-logger, andreport-generatorall consume the same status update.
Best practices
1. Keep agents focused
Give each agent a single, clear responsibility (formatter, linter, tester) instead of one generic "dev-helper" agent.
2. Use descriptive ids and names
{ "agents": { "entries": { "security-scanner": { "default": true, "name": "Security Scanner" }, "code-formatter": { "name": "Code Formatter" }, "test-generator": { "name": "Test Generator" } } }}3. Configure different tool access
{ "agents": { "entries": { "reviewer": { "default": true, "tools": { "allow": ["read", "exec"] } }, "fixer": { "tools": { "allow": ["read", "write", "edit", "exec"] } } } }}reviewer is read-only. fixer can read and write.
4. Monitor performance
With many agents, prefer "strategy": "parallel" (default), keep broadcast groups to a handful of agents, and use faster models for simpler agents.
5. Failures stay isolated
Agents fail independently. One agent's error is logged (Broadcast agent <id> failed: ...) and does not block the others.
Compatibility
Providers
Channel-qualified entries use the shared core dispatch path across channel plugins. Discord, Slack, and Telegram additionally support participant mention admission and name labels. Legacy unqualified entries apply only to WhatsApp (web channel).
Routing
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).
Troubleshooting
Agents not responding
Check:
- Agent IDs exist in
agents.entries(config validation rejects unknown ids). - The qualified channel/peer key matches the room. Legacy WhatsApp keys use a group JID like
120363403215116621@g.us, or E.164 like+15551234567for DMs. - The message passed normal gating (mention/activation rules still apply).
Debug:
openclaw logs --follow | grep -i broadcastA successful fan-out logs Broadcasting message to <n> agents (<strategy>).
Only one agent responding
Check: explicit mentions may select one participant, maxTurns may allow only one run, or the others may pass. Also check whether the peer is only in ordinary route bindings or matches an exclusive configured ACP binding.
Fix: add ordinary route-bound peers to the broadcast config, or remove/change the configured ACP binding if fan-out broadcast is desired.
Performance issues
If slow with many agents: reduce the number of agents per group, use lighter models, and check sandbox startup time.
Examples
Example 1: Code review team
{ "broadcast": { "strategy": "parallel", "120363403215116621@g.us": [ "code-formatter", "security-scanner", "test-coverage", "docs-checker" ] }, "agents": { "entries": { "code-formatter": { "default": true, "workspace": "~/agents/formatter", "tools": { "allow": ["read", "write"] } }, "security-scanner": { "workspace": "~/agents/security", "tools": { "allow": ["read", "exec"] } }, "test-coverage": { "workspace": "~/agents/testing", "tools": { "allow": ["read", "exec"] } }, "docs-checker": { "workspace": "~/agents/docs", "tools": { "allow": ["read"] } } } }}One code snippet in the group can produce four perspectives: formatting fixes, a security finding, a coverage gap, and a docs nit.
Example 2: Multi-language pipeline
{ "broadcast": { "strategy": "sequential", "+15555550123": ["detect-language", "translator-en", "translator-de"] }, "agents": { "entries": { "detect-language": { "default": true, "workspace": "~/agents/lang-detect" }, "translator-en": { "workspace": "~/agents/translate-en" }, "translator-de": { "workspace": "~/agents/translate-de" } } }}API reference
Config schema
type BroadcastGroupConfig = { agents: string[]; mentionGating?: boolean; maxRounds?: number; maxTurns?: number;}; type BroadcastConfig = { strategy?: "parallel" | "sequential"; [key: string]: string[] | BroadcastGroupConfig | "parallel" | "sequential" | undefined;};Fields
strategy"parallel" | "sequential"default: "parallel"How to process eligible agents within each round. parallel launches reserved turns together; sequential runs them in configured order.
[channel:peerId]string[] | BroadcastGroupConfigChannel-qualified peer ID. Arrays use the group-thread defaults; objects configure mention selection, rounds, and participant-turn budgets. At most 16 agents.
[peerId]string[]Legacy WhatsApp group JID or E.164 phone number. Every listed agent processes one turn, with no internal follow-up rounds or participant selection.
Limitations
- Shared context: follow-up digests contain bounded sibling finals, not full sibling sessions or tool histories.
- Message ordering: parallel responses may arrive in any order.
- Rate limits: participants share the channel account’s transport limits; one turn can produce several platform messages.
- Recovery: round and turn-budget state is in memory and cannot resume after a Gateway restart.
- Control UI: a dedicated team-thread session is not yet available. Each participant keeps its own session.