From c62b90a2b7000538954268cf7c415f74e43c7224 Mon Sep 17 00:00:00 2001 From: Varun Kruthiventi Date: Mon, 16 Feb 2026 09:57:29 +0530 Subject: [PATCH] fix(telegram): stop block streaming from splitting messages when streamMode is off (#17704) Merged via /review-pr -> /prepare-pr -> /merge-pr. Prepared head SHA: 847162caadc53fe3f983500175f928f28103626f Co-authored-by: saivarunk <2976867+saivarunk@users.noreply.github.com> Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com> Reviewed-by: @obviyus --- CHANGELOG.md | 1 + src/telegram/bot-message-dispatch.test.ts | 25 ++++++++++++++++++++++- src/telegram/bot-message-dispatch.ts | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdb915f02f3..aaaaff174c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Docs: https://docs.openclaw.ai - Telegram: replace inbound `` placeholder with successful preflight voice transcript in message body context, preventing placeholder-only prompt bodies for mention-gated voice messages. (#16789) Thanks @Limitless2023. - Telegram: retry inbound media `getFile` calls (3 attempts with backoff) and gracefully fall back to placeholder-only processing when retries fail, preventing dropped voice/media messages on transient Telegram network errors. (#16154) Thanks @yinghaosang. - Telegram: finalize streaming preview replies in place instead of sending a second final message, preventing duplicate Telegram assistant outputs at stream completion. (#17218) Thanks @obviyus. +- Telegram: disable block streaming when `channels.telegram.streamMode` is `off`, preventing newline/content-block replies from splitting into multiple messages. (#17679) Thanks @saivarunk. - Discord: preserve channel session continuity when runtime payloads omit `message.channelId` by falling back to event/raw `channel_id` values for routing/session keys, so same-channel messages keep history across turns/restarts. Also align diagnostics so active Discord runs no longer appear as `sessionKey=unknown`. (#17622) Thanks @shakkernerd. - Discord: dedupe native skill commands by skill name in multi-agent setups to prevent duplicated slash commands with `_2` suffixes. (#17365) Thanks @seewhyme. - Discord: ensure role allowlist matching uses raw role IDs for message routing authorization. Thanks @xinhuagu. diff --git a/src/telegram/bot-message-dispatch.test.ts b/src/telegram/bot-message-dispatch.test.ts index 2548902072b..c5c98f3e006 100644 --- a/src/telegram/bot-message-dispatch.test.ts +++ b/src/telegram/bot-message-dispatch.test.ts @@ -113,6 +113,7 @@ describe("dispatchTelegramMessage draft streaming", () => { async function dispatchWithContext(params: { context: TelegramMessageContext; telegramCfg?: Parameters[0]["telegramCfg"]; + streamMode?: Parameters[0]["streamMode"]; }) { await dispatchTelegramMessage({ context: params.context, @@ -120,7 +121,7 @@ describe("dispatchTelegramMessage draft streaming", () => { cfg: {}, runtime: createRuntime(), replyToMode: "first", - streamMode: "partial", + streamMode: params.streamMode ?? "partial", textLimit: 4096, telegramCfg: params.telegramCfg ?? {}, opts: { token: "token" }, @@ -236,4 +237,26 @@ describe("dispatchTelegramMessage draft streaming", () => { expect(draftStream.clear).toHaveBeenCalledTimes(1); expect(draftStream.stop).toHaveBeenCalled(); }); + + it("disables block streaming when streamMode is off", async () => { + dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => { + await dispatcherOptions.deliver({ text: "Hello" }, { kind: "final" }); + return { queuedFinal: true }; + }); + deliverReplies.mockResolvedValue({ delivered: true }); + + await dispatchWithContext({ + context: createContext(), + streamMode: "off", + }); + + expect(createTelegramDraftStream).not.toHaveBeenCalled(); + expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledWith( + expect.objectContaining({ + replyOptions: expect.objectContaining({ + disableBlockStreaming: true, + }), + }), + ); + }); }); diff --git a/src/telegram/bot-message-dispatch.ts b/src/telegram/bot-message-dispatch.ts index 3caef30df57..eac21eb82fb 100644 --- a/src/telegram/bot-message-dispatch.ts +++ b/src/telegram/bot-message-dispatch.ts @@ -169,7 +169,7 @@ export const dispatchTelegramMessage = async ({ const disableBlockStreaming = typeof telegramCfg.blockStreaming === "boolean" ? !telegramCfg.blockStreaming - : draftStream + : draftStream || streamMode === "off" ? true : undefined;