← Back to PRs

#23166: fix(agents): restore subagent announce chain from #22223

by tyler6204 open 2026-02-22 02:44 View on GitHub →
agents maintainer size: XL
## Summary Restores the exact subagent announce logic from PR #22223 (commit fe57bea08) which was overwritten by subsequent commits f555835b0 and 8178ea472. ## Problem Two commits landed after #22223 merged and rewrote `subagent-announce.ts`, re-introducing the broken `send` path that bypasses the parent LLM: - f555835b0 (Shadow): "Channels: add thread-aware model overrides" (+387/-144 lines) - 8178ea472 (Onur): "feat: thread-bound subagents on Discord" (+279/-40 lines) This caused: - Raw "✅ Subagent X finished" messages appearing in channels instead of the parent LLM processing results - Cron subagent announces routing to dead isolated sessions - Nested subagent chains breaking at the top level - Intermediate subagent responses leaking to channels before children complete ## Fix Restored `src/agents/subagent-announce.ts` and `src/agents/subagent-registry.ts` to exactly match the working state from fe57bea08. Updated callers/tests to match the restored interface. All subagent completions route through `method: "agent"` only. No `send` path. ## Testing verified - Simple subagent ✓ - Nested subagent (depth 2) ✓ - Depth 3 chain ✓ - Parallel children (parent waits for both) ✓ - Cron targeted ✓ - Cron untargeted (legacy, no to/channel) ✓ - No leaked "✅ Subagent main finished" messages ## Related - Fixes regression from #22099 - Restores behavior from #22223 - Closes #22099 <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR reverts `subagent-announce.ts` and `subagent-registry.ts` to the working state from PR #22223 (commit `fe57bea08`), undoing changes introduced by two subsequent commits that re-introduced a broken `send` delivery path bypassing the parent LLM. **Key changes:** - Removes the `method: "send"` direct delivery path from `subagent-announce.ts`, ensuring all subagent completions route through `method: "agent"` only - Removes `spawnMode` tracking from `SubagentRunRecord` in the registry (session-mode vs run-mode distinction for announce routing) - Removes `subagent_delivery_target` hook integration and `resolveSubagentCompletionOrigin` from the announce flow - Removes lifecycle hook emission (`emitSubagentEndedHookOnce`, `completeSubagentRun`) from the registry — the `subagent_ended` hook is no longer explicitly emitted from the registry module - Inlines helper functions previously extracted into `subagent-registry-cleanup.ts`, `subagent-registry-completion.ts`, `subagent-registry-queries.ts`, and `subagent-registry-state.ts` - Switches from `isDeliverableMessageChannel` to `isInternalMessageChannel` (semantically equivalent) - Updates all test files to match the simplified interface **Notable side-effects:** - `emitLifecycleHooks: false` was removed from two `sessions.delete` calls (sweeper and post-announce cleanup), which changes behavior: lifecycle hooks will now fire during these deletions - The inline `SubagentRunRecord` type in `subagent-registry.ts` now diverges from the version in `subagent-registry.types.ts` (which still includes `spawnMode`, `endedReason`, `endedHookEmittedAt`) — the store module still references the old type and sets `spawnMode` on disk-loaded records <h3>Confidence Score: 3/5</h3> - This PR restores known-working logic but introduces two behavioral side-effects (lifecycle hook emission on delete) that should be verified before merging. - The core revert logic (removing the `send` path, routing all completions through `method: "agent"`) is well-motivated and addresses a real regression. However, the removal of `emitLifecycleHooks: false` from two `sessions.delete` calls changes behavior in a way that could cause duplicate farewell messages or unexpected hook side-effects for channel plugins. Additionally, the `SubagentRunRecord` type now diverges between `subagent-registry.ts` and `subagent-registry.types.ts`/`subagent-registry.store.ts`, creating maintenance risk. The extracted helper modules (`subagent-registry-cleanup.ts`, `subagent-registry-completion.ts`, etc.) are left orphaned without being deleted. - Pay close attention to `src/agents/subagent-registry.ts` (lifecycle hook behavior change in sweeper) and `src/agents/subagent-announce.ts` (lifecycle hook behavior change in post-announce cleanup) <sub>Last reviewed commit: cb9b0a5</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs