#Inter agent communication does not work.
1 messages · Page 1 of 1 (latest)
What youâre seeing is (usually) expected on Discord:
- Discord bot-authored messages are ignored by default, so a âdoneâ message coming from another bot/agent wonât start a new agent turn unless you opt in.
- Even if you opt in, OpenClaw still filters the botâs own messages (loop prevention), so an agent canât âtrigger itselfâ by posting a message in the channel.
From the config reference (Discord section): bot-authored messages are ignored by default; allowBots enables them, but âown messages still filteredâ.
https://docs.openclaw.ai/gateway/configuration-reference (search for allowBots)
Fix / options
A) If âdoneâ is coming from a different Discord bot
Enable bot inbound messages:
{
channels: {
discord: {
allowBots: "mentions", // or true
},
},
}
Then make sure the âdoneâ message mentions the receiving bot if you use "mentions".
Docs: https://docs.openclaw.ai/channels/discord
B) If âdoneâ is coming from the same bot identity
That will never trigger a new run (itâll show up as context next time you talk, which matches your âask status â it can read the signoffâ observation).
In that case you need to either:
- use two Discord bots/accounts (one per agent) and route them via multi-agent bindings, or
- donât use Discord messages as the signaling mechanismâuse internal session messaging/orchestration instead.
Multi-agent doc (one bot per agent is the recommended pattern): https://docs.openclaw.ai/concepts/multi-agent
Quick questions to confirm
- Is the âdoneâ message posted by the same Discord bot user as the one you expect to respond?
- Whatâs your
openclaw --versionand yourchannels.discord+ guild/channelrequireMentionsettings (token removed)?
I do not use discort, I use telegram, I talk to my main agent who deligates to an orchistrator agent, the orchistrator agent has a team
the innitial send command works, the agents receive this direct and answers or start doing whatever they need to do. but when a task is completed the confirmation that its done does not get picked up
On Telegram (and really for all channels), an agent run only starts when either:
- the gateway receives a real inbound message from the channel (you typing in Telegram), or
- another agent explicitly triggers it via session tools (e.g.
sessions_send), not by posting a âdoneâ message back into Telegram.
So the behavior you described matches this exactly:
- Orchestrator/team finishes â OpenClaw posts a signoff/announce message into Telegram
- That message is outbound, and Telegram bots donât receive their own outbound messages as new inbound updates
- Therefore it cannot trigger your main agent to run
- Next time you type âstatusâ, that does trigger a run, and the main agent can now âseeâ the signoff in history/pending context
This is also why sessions_spawn completions (and the âannounce stepâ in sessions_send) feel like âthey arrive but donât wake anything upâ.
Docs that describe the announce behavior: https://docs.openclaw.ai/concepts/session-tool
What to do instead (2 workable patterns)
Pattern A (simplest): make the main agent wait for the orchestrator
Have main delegate using sessions_send with a non-zero timeoutSeconds thatâs long enough. Then main continues in the same turn and replies to you.
Pattern B (async): orchestrator calls back into the main session
When orchestrator is done, it should call sessions_send to the main sessionKey (not message.send to Telegram) with âdone + resultsâ. That will trigger a main-agent run internally, and the main agent can then message you.
Quick clarifier so I can point to the exact fix
In your current setup, is the mainâorchestrator delegation implemented with:
sessions_spawn, orsessions_send(and if so, are you usingtimeoutSeconds: 0fire-and-forget), or- just
message.sendback into Telegram?
If you paste the relevant snippet of your agentâs tool call (redact any secrets), I can tell you which pattern fits best.
Thatâs the key detail: the âtask completed / doneâ message youâre seeing is an outbound announce, not an inbound message into the other agentâs session â so nothing âpicks it upâ automatically.
In OpenClaw terms, this almost always happens when you delegate with one of these patterns:
1) sessions_send with timeoutSeconds: 0 (fire-and-forget)
- Initial send works â target agent starts immediately (you observe this)
- When target finishes, OpenClaw may post an announce to your Telegram chat
- But the requester agent is not waiting, so it never gets a tool result to continue from
- And the announce message in Telegram does not trigger an agent run
Fix: donât fire-and-forget if you expect the âdoneâ to be picked up by the delegating agent. Use a non-zero timeout:
timeoutSeconds: 60/300/900depending on how long the delegated task typically takes.
(Ref: sessions_send behavior + announce step: https://docs.openclaw.ai/concepts/session-tool)
2) sessions_spawn (always non-blocking)
sessions_spawn is explicitly non-blocking and only posts results back as an announce when done. Same outcome: youâll see a âdoneâ message, but it wonât wake another agent.
Fix: either (a) have the parent poll / follow up, or (b) use sessions_send when you need a synchronous âdelegate â wait â continueâ flow.
Quick diagnostic question
When your main agent delegates to the orchestrator, is it using:
sessions_sendwithtimeoutSeconds: 0(or a very small value), orsessions_spawn?
If you paste the exact tool call JSON your main agent is making (just that block; redact nothing sensitive), I can tell you precisely which branch youâre on and what to change.
when discussing the issue with the (main) agent should this not be known?
No â the Gateway âknowsâ (because it implements the behavior), but your (main) agent is just an LLM that only knows whatâs in:
- its system prompt + workspace files (AGENTS.md/SOUL.md/etc),
- the current conversation context,
- and any docs it explicitly reads.
The key gotcha here is: the thing youâre calling a âconfirmation that itâs doneâ is typically an announce/outbound delivery step (from sessions_spawn, or from the announce phase of sessions_send). Outbound deliveries donât come back in as inbound events, so they canât âtriggerâ another agent turn.
Unless youâve taught your main agent ânever rely on announce messages to wake another agent; use sessions_send with a real timeout (wait) or implement an explicit callbackâ, it will often assume chat behaves like an event bus â which it isnât.
Practical fix: put a rule in your main agentâs AGENTS.md like:
- âIf you need to act on completion, donât use fire-and-forget. Use
sessions_sendwithtimeoutSeconds > 0(wait), or have the workersessions_sendback into the main sessionKey. Do not assume a âdoneâ Telegram message will wake anyone up.â
If you paste the actual tool call your main agent is using for delegation (sessions_send/sessions_spawn + params), I can tell you exactly what to change (itâs usually just timeoutSeconds).
I have full agents, I do not want to use session_spawn. So main agent talks to Orchistrator, then orchistrator talks to B, (B can spawn itself) ben then needs to report back to orchistrator that then reports back to main.
how does the timeoutSeconds work, and how would it work if my main agents is deligating task to multiple agents?
If youâre not using sessions_spawn, then the rule is pretty strict:
A âdoneâ only gets picked up by the parent agent if the parent is either
- still waiting inside the
sessions_sendcall (timeoutSeconds > 0), or - the child explicitly triggers the parent with another
sessions_send(a real inter-session send), not by posting an outbound âdoneâ message to Telegram.
Right now your chain sounds like itâs doing this somewhere:
- Main â Orchestrator:
sessions_send(..., timeoutSeconds: 0)(fire-and-forget) - Orchestrator â B:
sessions_send(..., timeoutSeconds: 0)(fire-and-forget) - B finishes â you see a âdoneâ message in Telegram
- But Orchestrator is not waiting, so it doesnât âpick upâ anything.
- And the Telegram âdoneâ message is outbound, so it doesnât wake Orchestrator/Main.
Two ways to make your Main â Orchestrator â B â Orchestrator â Main chain work (without sessions_spawn)
Option A (simple + robust): make each hop wait
- Main calls Orchestrator with
timeoutSeconds > 0 - Orchestrator calls B with
timeoutSeconds > 0 - B replies â Orchestrator continues and replies â Main continues and replies to you
This is the âRPCâ style. It works reliably, but Main will be âbusyâ until done.
Option B (async): B must sessions_send back to Orchestrator, then Orchestrator back to Main
This is the âevent/callbackâ style. It only works if B actually uses sessions_send targeting Orchestratorâs session, and Orchestrator then sessions_sends to Mainâs session.
Key gotcha: for callbacks, the agent needs a real sessionKey to send to (and must be allowed to send to it). A Telegram message is not a callback.
The question that decides everything
In your current setup, when B âreports back that itâs doneâ, is B doing:
- (good)
sessions_send({ sessionKey: "<orchestrator session key>", message: "done ..." })
or - (wonât wake anyone)
message.send/ normal chat output to Telegram / relying on an âannounceâ message?
If you paste one real example of the tool call B uses when it âreports backâ, I can tell you exactly what to change (itâs usually either timeoutSeconds being 0, or B using message.send instead of sessions_send).
Is there a way to change the inter agent communication to Event-based (Registry-backed).
timeoutSeconds is only about how long the caller waits for the other session to finish. Itâs not a âkill switchâ and itâs not the workerâs runtime limit.
From the Session Tools docs: https://docs.openclaw.ai/concepts/session-tool
What timeoutSeconds does in sessions_send
When agent A calls:
sessions_send({ sessionKey: B, message: "...", timeoutSeconds: N })
OpenClaw kicks off a run in session B. Then:
timeoutSeconds: 0
âFire-and-forgetâ
â returns immediately with{ status: "accepted", runId }
â B keeps running in the background
â A does not get a result to continue from in that same turn.
timeoutSeconds > 0
âWait for completion (up to N seconds)â
â if B finishes within N seconds:{ status: "ok", reply: ... }
â if B takes longer than N seconds:{ status: "timeout" }(B still continues running)
â you can then usesessions_historylater to see what happened.
So if your orchestration expects âB finished â orchestrator reactsâ, then the orchestrator must either:
- be waiting (
timeoutSeconds > 0) on thatsessions_send, or - be explicitly messaged by B (a callback
sessions_sendinto the orchestrator session).
An outbound âdoneâ message showing up in Telegram isnât a callback and wonât wake anyone.
How this works with âmain delegates to multiple agentsâ
You basically have 3 patterns:
Pattern 1 â Serial (simplest, no extra plumbing)
Main/Orchestrator does:
sessions_sendto agent B withtimeoutSeconds: 300- then
sessions_sendto agent C withtimeoutSeconds: 300 - etc.
Downside: itâs sequential (B then C), not parallel.
Pattern 2 â Parallel start, then gather later (no sessions_spawn, but needs a âjoinâ step)
Orchestrator does:
- Start all workers with
timeoutSeconds: 0:
sessions_send({ sessionKey: B, message: "...", timeoutSeconds: 0 })
sessions_send({ sessionKey: C, message: "...", timeoutSeconds: 0 })
sessions_send({ sessionKey: D, message: "...", timeoutSeconds: 0 })
- Later, orchestrator either:
- polls with
sessions_historyuntil each has replied, or - has each worker callback into orchestrator via
sessions_sendwhen done (best if you want push instead of polling).
- polls with
This is the closest to âfan out / fan inâ without sessions_spawn.
Pattern 3 â Main waits on Orchestrator (recommended shape)
Let the orchestrator handle the multi-worker complexity. Then:
- Main â Orchestrator:
sessions_send(..., timeoutSeconds: big_enough) - Orchestrator does Pattern 1 or 2 internally
- Orchestrator returns one final summary to Main
- Main replies to you
This keeps your âuser-facing brainâ (Main) clean.
One more practical gotcha
Parallelism only helps if your gateway is allowed to run multiple sessions at once (config agents.defaults.maxConcurrent). If itâs 1, youâll still be effectively serialized even if you fire-and-forget multiple runs.
If you tell me which pattern you want (serial vs parallel fan-out), I can suggest the cleanest prompt/AGENTS.md rules for Main/Orchestrator/B so the âdoneâ signals actually wake the next layer.
I think I will ask for a new feature, there should be a "secret" channel where agents can talk between each other, like a different channel.
Not as a built-in âmode switchâ, no.
OpenClawâs inter-agent mechanism is fundamentally message-driven:
- sessions run when they receive an inbound message (from a channel) or an internal send (
sessions_send/agentRPC) - there isnât a native âsubscribe to completion events from other sessionsâ registry/event-bus that automatically wakes other agents when some run ends
What you can do (event-driven-ish options)
1) Use sessions_send as the event (callback)
This is the simplest in-process âeventâ model today:
- Orchestrator â B:
sessions_send(... timeoutSeconds: 0)(kick off) - When B is done: B must
sessions_sendback to Orchestrator (thatâs the event) - When Orchestrator has all results: Orchestrator
sessions_sends back to Main
That gives you true âdone wakes parentâ behavior without relying on Telegram messages.
2) Use Gateway Hooks/Webhooks to build a registry-backed event system (custom)
If by âregistry-backedâ you mean âdurable event log / queueâ, OpenClaw gives you the plumbing:
- Hooks (internal event system: message sent/received, session_end, etc.)
https://docs.openclaw.ai/automation/hooks - Webhooks (HTTP endpoint to wake or run an agent)
https://docs.openclaw.ai/automation/webhook
A common pattern is:
- workers write an event to Redis/DB/file (your registry)
- then hit
POST /hooks/wakeorPOST /hooks/agentto wake the main/orchestrator session to consume events
âŠbut that requires you to implement the registry + handler logic (TypeScript hook or external service). Itâs not just a config flip for agent-to-agent comms.
If you want this as a first-class feature
Thatâs a legit feature request (âsession completion events that can route to other sessions/agentsâ). Best path is to open an issue: https://github.com/openclaw/openclaw/issues
If you tell me whether your agents are in the same agentId (multiple sessions) or truly different agentIds, I can recommend the cleanest callback approach with the least config friction.
Thatâs a totally reasonable feature request â and you can frame it as:
- âGive agents an internal mailbox/busâ (durable, not tied to Telegram/Discord)
- with explicit semantics:
emit(event)/subscribe(filter)/ack() - and no accidental delivery into the user-facing chat.
Worth knowing: you already kind of have a âsecret channelâ today
Inter-agent messages sent via sessions_send are already persisted as inter_session provenance (theyâre not normal user chat messages).
The part that leaks into your Telegram chat is the announce step (the âdoneâ message you see). If you want âagents talk privately, only Main talks to meâ, you can get close today by adopting a rule like:
- Workers + orchestrator must respond with
ANNOUNCE_SKIPduring the announce step unless explicitly told to speak to the user.
(That wonât give you event subscriptions, but it fixes the âconfirmation arrives but nobody picks it upâ spam/confusion.)
For the feature request, Iâd suggest asking for one (or both) of these
- A real internal agent bus / mailbox tool, e.g.
events_emit,events_poll,events_subscribe(registry-backed, ackable).
- A smaller change: add a switch to session tools so they never âannounceâ unless requested, e.g.:
sessions_send(..., announce: false)ordeliverMode: "silent"
Because right now, without a wait/callback, the only âcompletion signalâ you see is that announce â which canât wake other agents.
What to put in the GitHub issue
Include:
openclaw --version- your desired flow: Main â Orchestrator â workers (fan-out) â Orchestrator (fan-in) â Main
- what you want to avoid: âdoneâ messages in Telegram that donât trigger anything
- what you want instead: event-based callback without needing
sessions_spawn
Issue link: https://github.com/openclaw/openclaw/issues
If you paste a sanitized example of the âdoneâ message you see (and whether itâs coming from sessions_send announce), I can help you word the issue so itâs crisp and implementable.
Is there a way to make the agents talk in a rountable like way? Maybe through an external hub?
Yes â if what you want is âroutableâ agent-to-agent messaging (publish to a hub, hub routes to the right agent/session, no need to keep sessionKeys in prompts), the clean way today is to put an external hub in the middle and use OpenClawâs webhook ingress as the entry point back into the gateway.
Recommended architecture (hub + OpenClaw webhooks)
- Enable OpenClaw webhooks on the gateway
Docs + exact config: https://docs.openclaw.ai/automation/webhook
At minimum:
{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
allowedAgentIds: ["main", "orchestrator"] // tighten this
}
}
- Have agents POST events to your hub (HTTP endpoint / queue)
- e.g.
POST /events { from:"B", type:"task_done", correlationId:"..." , payload:{...} }
- Hub routes and wakes the right OpenClaw agent by calling:
POST /hooks/agent(run an agent turn) orPOST /hooks/wake(wake main heartbeat)
This is the part that turns âevent emittedâ into âagent actually runs nowâ.
Why this helps your exact problem
Your current âdoneâ messages are outbound to Telegram, so they donât wake other sessions. A hub â /hooks/agent call is a real inbound trigger into the gateway, so the orchestrator/main will actually run when the event arrives.
Caveats / design choices (important)
/hooks/agentby default runs in an isolated hook session and posts a summary into the main session (good for âevent processingâ).- If you try to route directly into existing long-lived sessions, youâll run into sessionKey policy/security tradeoffs (the webhook docs cover
defaultSessionKeyandallowRequestSessionKeyâbe careful with that).
Quick question so I can suggest the simplest routing setup
Do you want the hub to:
- always wake Main (and Main decides what to do), or
- wake Orchestrator directly (so Main stays clean/user-facing)?
If you answer that, I can outline a minimal âevent envelopeâ format and the safest webhook config knobs to use.
Gave this conversation to my agent and she will implement it and test. Thank you
Nice â if it works out, please mark the solution in this thread (right-click the solution message â Apps â âMark Solutionâ). That helps Answer Overflow index it for the next person.
If your agent hits anything weird during testing, paste:
- the exact tool call it used (
sessions_sendparams /timeoutSeconds) - and the resulting status (
ok/timeout/ etc.)
and we can zero in quickly.
â Works as you described it... But I went further. I did find the sequential "roundtable" not wat I wanted... so I created a app within my command center that can be used to sent messages to everyone part of a roundtable. A sents message to Conference room.. and Conference rooms sends message to all participating Agents with istructions how to answer and were etc. when a agent answers it sends again the answer to everyone. Need to see long term if that works but first tests were promising. App also creates a transcript of the meeting who said what... Now working on the frontend part.