fix(channels,kernel): kill sidecar child on shutdown + forward async delegation result to channel#6267
Merged
Conversation
…delegation result to channel Two fixes found during live testing: 1. Sidecar supervisor never killed the child process on shutdown — it just break'd out of the spawn loop, leaving orphaned processes that survived daemon restart and held the Telegram long-poll connection, blocking the new sidecar from receiving messages. 2. Async delegation callbacks arrived mid-turn via TaskCompleted signal injection, but the delegation result was only surfaced inside the agent session — it was never forwarded to the channel. The wake-idle path already had this forward, but mid-turn injection skipped it. Now the completion text is sent directly via send_channel_message to the agent's home channel on every path (mid-turn and wake-idle).
This was referenced Jun 23, 2026
houko
added a commit
that referenced
this pull request
Jun 23, 2026
…channel (refs #6266) (#6286) * fix(kernel): forward web-UI-initiated delegation results to the home channel (#6266) PR #6267 forwards an async-delegation completion to the agent's home channel mid-turn, but only when the originating turn carries an inbound `chat_id`. A delegation started from a web-UI turn has no `chat_id` (the WS sender sets none and uses the canonical session), so the forward was skipped and the result surfaced only in the web-UI session — never on the agent's channel (the "responds in the web UI instead of forwarding to Telegram" symptom in #6266). The mid-turn forward now resolves its destination as: the inbound `entry.chat_id` when present, else the home channel's configured `default_conversation`. A new optional `[[sidecar_channels]].default_conversation` names that fallback conversation. When neither is available the forward stays a no-op — it never guesses a recipient. `resolve_agent_home_channel`'s contract is unchanged (the trigger-dispatch caller is unaffected); the fallback is a separate `resolve_agent_default_conversation` helper. The "session mixing" sub-claim in #6266 is left for reporter confirmation — web-UI and channel sessions are storage-distinct by construction. * fix(changelog): split two-sentence CHANGELOG continuation onto separate lines One sentence per line in CHANGELOG bullets per project prose rules. Also collapses the redundant `let kernel_arc = arc;` in task_registry.rs into the `if let Some(kernel_arc) = ...` binding directly. * fix(kernel): default_conversation must use the home channel, not a later one review follow-up: sidecar_default_conversation used find_map, so when an agent's first home channel (the one resolve_agent_home_channel picks) had no default_conversation it skipped ahead to a later channel's default. The forward would then pair the home channel with a different channel's conversation id and deliver to the wrong place. Switch to find().and_then() so it reads only the first agent-matching channel's default, and add a regression test. --------- Co-authored-by: Evan <[email protected]> Co-authored-by: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes found and verified during live testing on proteo.
1. Sidecar zombie (channels: sidecar.rs)
The sidecar supervisor never killed the child process on shutdown — it just broke out of the spawn loop. This left orphaned Python processes that survived daemon restart, held the Telegram long-poll connection, and blocked the new sidecar from sending/receiving messages.
Fix: Before breaking the supervisor loop on shutdown/child-closed signals, lock the child guard and call — same pattern already used in the timeout path.
2. Async delegation result not forwarded to channel (kernel: task_registry.rs)
Async delegation callbacks arrived mid-turn via signal injection, but the delegation result was only surfaced inside the agent session. The wake-idle path already forwarded via , but the mid-turn injection path skipped this — the operator never saw the result on the channel unless the agent explicitly echoed it.
Fix: After mid-turn injection, also forward the completion text directly via to the agent's home channel. This fires immediately without waiting for the agent to process the signal.
Verification