#17694: fix(telegram): send reasoning before main text in stream mode
channel: telegram
size: XS
Cluster:
Telegram Message Handling Fixes
## Summary
- Telegram's `/reasoning stream` mode was not displaying thinking content because the `onReasoningStream` callback was never provided
- When set to `/reasoning on`, thinking appeared **after** the main text due to block streaming delivering text in real-time while reasoning was appended post-run
- Added `onReasoningStream` callback to Telegram's reply options that buffers reasoning text and flushes it before the first block/final reply delivery
## How it works
1. `onReasoningStream` callback accumulates reasoning text into a buffer during the model's thinking phase
2. Before the first `deliver()` call (block or final), `flushReasoning()` sends the buffered reasoning as a separate Telegram message
3. In `stream` mode, the core layer automatically suppresses block streaming when `onReasoningStream` is present, so the main text arrives as a final payload after reasoning
## Test plan
- [x] Set `/reasoning stream` in Telegram DM
- [x] Send a message and verify thinking content appears **before** the main text reply
- [x] Verify `/reasoning off` still works (no reasoning displayed)
- [x] Verify `/reasoning on` still works (reasoning displayed after text, existing behavior)
- [x] TypeScript compilation passes with no new errors
- [x] Lint passes with 0 warnings/errors
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed `/reasoning stream` mode in Telegram by adding `onReasoningStream` callback that buffers and flushes reasoning text before the main reply.
- Added `reasoningBuffer` to accumulate thinking text as it streams from the model
- Added `flushReasoning()` function that sends buffered reasoning as a separate message before the first block/final reply
- Hook `flushReasoning()` is called at the start of the `deliver()` callback to ensure ordering
- The core layer automatically suppresses block streaming when `onReasoningStream` is present (per `agent-runner-execution.ts:105-107`), ensuring the main text arrives as a final payload after reasoning
<h3>Confidence Score: 5/5</h3>
- Safe to merge with no issues found
- The implementation correctly integrates with the existing reasoning stream infrastructure. The buffer correctly stores cumulative reasoning text (not deltas), the flush guard prevents duplicates, and the integration point in the deliver callback ensures proper ordering. The approach aligns with the core layer's behavior of suppressing block streaming when onReasoningStream is present.
- No files require special attention
<sub>Last reviewed commit: e337497</sub>
<!-- 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
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
78.9%
#18935: fix(agents): suppress reasoning blocks from channel delivery
by BinHPdev · 2026-02-17
78.7%
#19673: fix(telegram): avoid starting streaming replies with only 1-2 words
by emanuelst · 2026-02-18
77.9%
#18187: fix: tool summaries silently dropped when reasoningLevel is stream
by ayanesakura · 2026-02-16
77.8%
#13235: feat: stream reasoning_content via /v1/chat/completions SSE
by mode80 · 2026-02-10
77.8%
#14977: fix(telegram): remove ack reaction after block-streamed replies
by Diaspar4u · 2026-02-12
75.0%
#5764: fix(telegram): enable streaming in private chats without topics
by garnetlyx · 2026-01-31
74.1%
#19479: fix(telegram): skip redundant final edit in partial streaming mode
by v8hid · 2026-02-17
74.0%
#11273: fix(telegram): prevent status command crash during thinking
by avirweb · 2026-02-07
73.8%
#17316: fix: ack reaction not removed when block streaming is enabled (Tele...
by czmathew · 2026-02-15
73.8%