#19486: fix(gateway): mirror delivered agent replies into routed target sessions
commands
size: S
Cluster:
Heartbeat Message Filtering
## Summary
When a run delivers outbound text to a routed channel target (e.g. hook/cron with deliver=true), the message can be posted successfully but `sessions_history` for that target session may stay stale because no mirror append occurs.
This change adds target-session mirroring for delivered agent replies in `deliverAgentCommandResult`.
## Root cause
`deliverOutboundPayloads()` only appends transcript entries when `mirror` metadata is provided.
In the affected path, delivery was executed without `mirror`.
## What changed
- In `src/commands/agent/delivery.ts`:
- resolve outbound session route for `(channel, to, accountId, threadId)`
- pass `mirror` to `deliverOutboundPayloads` when the resolved target session differs from the source session
- avoid duplicate appends when source and target session keys are the same
## Tests
Added `src/commands/agent/delivery.mirror.test.ts`:
1. mirrors when routed target session differs
2. does not mirror when source and target sessions match
## Notes
This is intentionally minimal and scoped to the delivery path to preserve existing behavior while restoring observability for routed deliveries.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes an observability gap where agent replies delivered to routed channel targets (e.g., hook/cron routing to a Telegram chat) were successfully posted but the target session transcripts remained stale because no mirror append occurred.
**Key changes:**
- In `delivery.ts`: resolves the outbound session route for the delivery target and passes mirror metadata to `deliverOutboundPayloads` when the target session differs from the source session
- Adds case-insensitive session key comparison to avoid duplicate appends when source and target sessions are identical
- Test coverage validates both mirroring when sessions differ and skipping when they match
The fix is minimal and scoped to the delivery path in `deliverAgentCommandResult`, preserving existing behavior while restoring observability for routed deliveries.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is clean, well-tested, and follows established patterns from the outbound session mirroring refactor documented in `docs/refactor/outbound-session-mirroring.md`. The change is minimal and scoped to fix a specific observability gap without affecting existing behavior. Error handling is appropriate (`.catch(() => null)` allows graceful degradation), and the case-insensitive session key comparison prevents duplicate appends. Test coverage validates both the positive case (mirroring when sessions differ) and negative case (no mirroring when sessions match).
- No files require special attention
<sub>Last reviewed commit: c9a627b</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#10677: fix(heartbeat): mirror outbound messages to session transcript
by PatrickBauer · 2026-02-06
84.2%
#17340: fix(auto-reply): prevent duplicate transcript entries for followup ...
by Facens · 2026-02-15
81.7%
#9906: feat: wire message_sending hook in outbound delivery
by teempai · 2026-02-05
77.7%
#21828: fix: acquire session write lock in delivery mirror and gateway chat...
by inkolin · 2026-02-20
75.5%
#8095: fix(sessions): include accountId in deliveryContext for outbound pe...
by codeslayer44 · 2026-02-03
74.5%
#6850: fix: support direct channel:account:peer format in session key extr...
by toboto · 2026-02-02
74.4%
#13638: fix: pass delivery context to cron isolated agent subagents
by dario-github · 2026-02-10
74.3%
#4693: fix: keep main session displayName on outbound sends
by ManojINaik · 2026-01-30
74.2%
#16061: fix(sessions): tolerate invalid sessionFile metadata
by haoyifan · 2026-02-14
73.5%
#16783: Fix cross-channel routing in iMessage monitor
by fengwen2013 · 2026-02-15
72.9%