* feat(telegram): add child thread-binding placement via createForumTopic
Enable ACP subagent spawn on Telegram by adding "child" placement
support to the thread-bindings adapter. When a child binding is
requested, the adapter creates a new forum topic via the Telegram
Bot API and binds the subagent session to it using the canonical
chatId:topic:topicId conversation ID format.
When the ACP spawn context provides only a topic ID (not a full
group chat ID), the adapter resolves the group from the configured
Telegram groups in openclaw.json.
This mirrors the Discord adapter's child placement behavior
(thread creation + session binding) and unblocks the orchestrator
pattern on Telegram forum-enabled groups.
Closes#5737
Ref #23414
* fix(telegram): return null with warning instead of silent group fallback for bare topic IDs in child bind
* telegram: fix ACP child thread spawn with group chat ID from agentGroupId
* telegram: scope agentGroupId substitution to telegram channel only
* Telegram: fix forum topic replies routing to root chat instead of topic thread
* fix: clean up dead guard in child bind + add explicit threadId override test
- Simplify bare-topic-ID guards in thread-bindings.ts: split into
separate !chatId and !chatId.startsWith("-") checks, removing
unreachable second condition
- Add regression test confirming explicit turnSourceThreadId overrides
session lastThreadId on same channel
* fix: guard threadId fallback against shared-session race
Codex review P1: when turnSourceTo differs from the session's stored
to, the session threadId may belong to a different chat/topic. Only
fall back to context.threadId when the destination also matches.
* fix(telegram): enable ACP spawn from forum topics without thread binding
extractExplicitGroupId returned topic-qualified IDs (-100...:topic:1264)
instead of bare group chat IDs, breaking agentGroupId resolution.
agentGroupId was also never wired in the inline actions path.
For Telegram forum topics, skip thread binding entirely — the delivery
plan already routes correctly via requester origin (to + threadId).
Creating new forum topics per child session is unnecessary; output goes
back to the same topic the user asked from.
* fix(acp): bind Telegram forum sessions to current topic
* fix: restore Telegram forum-topic routing (#56060) (thanks @one27001)
---------
Co-authored-by: openclaw <mgabrie.dev@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(acp): implicit streamToParent for mode=run without thread
When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.
The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.
Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.
* fix: use resolved spawnMode instead of params.mode
Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.
This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.
* fix: tighten implicit ACP parent relay gating (#42404) (thanks @davidguttman)
---------
Co-authored-by: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>