From e856932600a38d70247ecbd3de2caea7fee478e1 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Thu, 28 May 2026 13:02:41 +0000 Subject: [PATCH] fix(telegram): clamp partial draft overflow --- extensions/telegram/src/draft-stream.ts | 49 +++++++++++++++++++++---- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/extensions/telegram/src/draft-stream.ts b/extensions/telegram/src/draft-stream.ts index 357e37d633a..b2d0d779d4a 100644 --- a/extensions/telegram/src/draft-stream.ts +++ b/extensions/telegram/src/draft-stream.ts @@ -112,6 +112,7 @@ export function createTelegramDraftStream(params: { let streamVisibleSinceMs: number | undefined; let lastSentText = ""; let lastDeliveredText = ""; + let lastRequestedText = ""; let lastSentParseMode: "HTML" | undefined; let previewRevision = 0; let generation = 0; @@ -184,6 +185,13 @@ export function createTelegramDraftStream(params: { streamVisibleSinceMs = visibleSinceMs; return true; }; + const stopOversizedPreview = (renderedText: string): false => { + streamState.stopped = true; + params.warn?.( + `telegram stream preview stopped (text length ${renderedText.length} > ${maxChars})`, + ); + return false; + }; const sendOrEditStreamMessage = async (text: string): Promise => { if (streamState.stopped && !streamState.final) { @@ -204,6 +212,15 @@ export function createTelegramDraftStream(params: { return false; } if (renderedText.length > maxChars) { + const chunkLength = findTelegramDraftChunkLength(currentText, maxChars, params.renderText); + if (!streamState.final) { + if (chunkLength > 0) { + return await sendOrEditStreamMessage( + trimmed.slice(0, deliveredTextOffset) + currentText.slice(0, chunkLength), + ); + } + return stopOversizedPreview(renderedText); + } if (lastDeliveredText.length > deliveredTextOffset) { const supersededMessageId = streamMessageId; const supersededTextSnapshot = lastSentText; @@ -222,7 +239,6 @@ export function createTelegramDraftStream(params: { } return await sendOrEditStreamMessage(trimmed); } - const chunkLength = findTelegramDraftChunkLength(currentText, maxChars, params.renderText); if (chunkLength > 0) { const sent = await sendOrEditStreamMessage( trimmed.slice(0, deliveredTextOffset) + currentText.slice(0, chunkLength), @@ -232,11 +248,7 @@ export function createTelegramDraftStream(params: { } return await sendOrEditStreamMessage(trimmed); } - streamState.stopped = true; - params.warn?.( - `telegram stream preview stopped (text length ${renderedText.length} > ${maxChars})`, - ); - return false; + return stopOversizedPreview(renderedText); } if (renderedText === lastSentText && renderedParseMode === lastSentParseMode) { return true; @@ -269,12 +281,34 @@ export function createTelegramDraftStream(params: { } }; - const { loop, update, stop, stopForClear } = createFinalizableDraftStreamControlsForState({ + const { + loop, + update: updateDraft, + stopForClear, + } = createFinalizableDraftStreamControlsForState({ throttleMs, state: streamState, sendOrEditStreamMessage, }); + const update = (text: string) => { + if (streamState.stopped || streamState.final) { + return; + } + lastRequestedText = text; + updateDraft(text); + }; + + const stop = async () => { + streamState.final = true; + await loop.flush(); + const finalText = lastRequestedText.trimEnd(); + if (finalText && finalText !== lastDeliveredText.trimEnd()) { + await sendOrEditStreamMessage(finalText); + } + streamState.final = true; + }; + resetStreamToNewMessage = (options) => { streamState.stopped = false; streamState.final = false; @@ -286,6 +320,7 @@ export function createTelegramDraftStream(params: { lastSentParseMode = undefined; if (options?.resetOffset !== false) { deliveredTextOffset = 0; + lastRequestedText = ""; } if (!options?.keepPending) { loop.resetPending();