sessions_send: no synchronous wait option + duplicate delivery via async announce after sync tool result already returned
We use sessions_send heavily for a gatekeeper-agent pattern: a "front" agent (rep-facing)
calls a specialized "back" agent (CRM-lookup agent) via sessions_send, then sessions_yields
to end its own turn while the back agent's session runs independently and its answer arrives
later via the framework's async inter-session announce delivery.
This creates two structural problems that have caused repeated production incidents on our side (5 rounds of incident/fix since 2026-07-08, all symptoms of the same root cause):
1. No synchronous "send and truly wait for reply" primitive
sessions_send returns as soon as the target session accepts the message; it does not block
until that session produces a substantive reply. Any caller that needs the real answer within
the same synchronous request/response cycle (e.g. a webhook handler serving a chat client over
HTTP, where the HTTP response must contain the real answer) has no supported way to actually wait
for it — the calling agent's own turn ends at sessions_yield, before the async reply exists.
Workaround we've built: read the target session's own transcript file directly by its
sessionKey (captured from the sessions_send tool-call result) and poll it for a substantive
assistant message. This works, but it's an out-of-band filesystem read of implementation details
(~/.openclaw/agents/<agentId>/sessions/sessions.json → transcript JSONL) that we shouldn't have
to rely on — it broke once before when an internal compaction/format change altered our
assumptions about the transcript layout, and is fragile by construction.
Ask: either (a) a sessions_send mode/flag that blocks the calling turn until the target
session produces its next substantive reply (with a caller-specified timeout), returning that
reply's text directly to the caller instead of only an "accepted" acknowledgment; or (b) a
supported polling API (not raw transcript-file reads) for "has session X replied to message Y
yet, and what did it say" that doesn't require re-implementing transcript parsing/control-token
filtering ourselves.
2. Duplicate delivery: async announce fires even when a synchronous result already existed
When the calling agent's sessions_send tool call itself already returns a result (e.g. an
acceptance/ack payload) within the same turn, the target session's eventual real reply is
also delivered asynchronously via announce to the calling session later — as a second,
separate inter-session message. If the calling session already ended its turn (e.g. moved on to
other work, or a subsequent request started a new turn), this second delivery can land
mid-way through unrelated work, confusing prompt state, or in our case, get silently buried when
multiple retries have stacked overlapping async deliveries in flight at once.
Ask: a sessions_send option to suppress the async announce delivery when the caller
doesn't want a second later delivery — e.g. delivery: { mode: "none" } equivalent already
exists for cron jobs per this framework's own conventions; parity for sessions_send inter-agent
calls would let us opt out of the duplicate-delivery pattern cleanly instead of filtering it out
after the fact on our side.
Supporting evidence (our internal incident history, available on request)
- 2026-07-08: async relay/announce delivery for a
sessions_sendcall sat undelivered 8+ minutes in one observed case; a separate case showed the relay layer erroring outright ("Unknown target ... for Telegram"). Never root-caused on our end since it's framework-internal. - 2026-06-03: documented as a known, currently-unfixable-from-userland issue in our own internal
runbook: "OpenClaw's
delivery.mode: announcefires async AFTER the synchronous tool result is returned, injecting the same CRM data as a second inter-session message. This is framework-level behavior — cannot be suppressed via agent instructions." - 2026-07-22: retry pileup — when a caller doesn't wait long enough and retries with a fresh session, multiple concurrent target sessions' delayed async announces land back-to-back and can bury the real answer in the caller's turn ordering.
What we are NOT asking for
- We are not asking OpenClaw to change the underlying agent-isolation model (separate sessions, separate workspaces) — that's working as intended and is valuable for our use case.
- We are not asking for a change to how
sessions_spawn/subagent completion events work — those already havesessions_yieldas a supported wait primitive; this ask is specifically about the same-tiersessions_send(session-to-session messaging) pattern, which currently has no equivalent supported wait primitive.
Source: openclaw/openclaw