← Back to PRs

#8205: fix: flush followup messages incrementally

by hanxiao open 2026-02-03 18:29 View on GitHub →
stale
Fixes #7698 ## Problem Followup messages were buffered until the entire agent run completed, then delivered all at once. Users saw no incremental feedback during long-running tasks. ## Solution Added `onBlockReply` callback to `runEmbeddedPiAgent` call in `followup-runner.ts`. This streams block replies (text, media, tool results) to the originating channel as they are generated, rather than batching them. Key changes: - Added `handleBlockReply` function that immediately delivers payloads via `deliverOutboundPayloads` - Track streamed payloads with `streamedPayloadKeys` Set to prevent duplicate delivery - Filter already-streamed payloads from final `sendReply` call ## Testing Tested with Telegram channel - messages now appear incrementally as the agent generates them. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR enables incremental delivery of follow-up agent output by wiring an `onBlockReply` callback into `runEmbeddedPiAgent` from `src/auto-reply/reply/followup-runner.ts`. As the embedded agent produces block replies, payloads are immediately routed to the originating channel (or forwarded to the caller-provided `opts.onBlockReply`) instead of waiting for the run to complete. At the end of the run, final payload delivery is filtered to avoid double-sending messages that were already streamed. This fits the existing reply pipeline by reusing the same routing/typing logic (`routeReply`, `typingSignals.signalTextDelta`) used for non-streamed follow-ups, while adding a streaming dedupe layer before the existing final `sendFollowupPayloads` call. <h3>Confidence Score: 3/5</h3> - This PR is likely safe to merge, but the new deduplication and failure-path semantics could cause dropped or mis-deduped payloads in some channel configurations. - Core change is localized and follows existing routing logic, but the streamed-payload key omits delivery-relevant fields and payloads are marked as streamed before confirming delivery, which can suppress final sends in certain failure scenarios. - src/auto-reply/reply/followup-runner.ts <!-- greptile_other_comments_section --> <sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs