From f29e15c05d79d7459821c72fdb5abaf3ee5fe89b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 25 Apr 2026 03:17:31 +0100 Subject: [PATCH] fix(telegram): bound tool progress preview formatting Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com> --- .../telegram/src/bot-message-dispatch.test.ts | 24 +++++++++++++++++++ .../telegram/src/bot-message-dispatch.ts | 17 ++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/extensions/telegram/src/bot-message-dispatch.test.ts b/extensions/telegram/src/bot-message-dispatch.test.ts index ee1697acf4d..ed9ce3563c3 100644 --- a/extensions/telegram/src/bot-message-dispatch.test.ts +++ b/extensions/telegram/src/bot-message-dispatch.test.ts @@ -547,6 +547,30 @@ describe("dispatchTelegramMessage draft streaming", () => { ); }); + it("bounds Telegram tool progress markdown preview formatting", async () => { + const draftStream = createDraftStream(); + createTelegramDraftStream.mockReturnValue(draftStream); + const longProgress = `${"`".repeat(1000)}${"x".repeat(1000)}[label](tg://user?id=123)`; + dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ replyOptions }) => { + await replyOptions?.onItemEvent?.({ progressText: longProgress }); + return { queuedFinal: false }; + }); + + await dispatchWithContext({ + context: createContext(), + streamMode: "partial", + telegramCfg: { streaming: { preview: { toolProgress: true } } }, + }); + + const lastPreviewText = draftStream.update.mock.calls.at(-1)?.[0] ?? ""; + const progressLine = lastPreviewText.split("\n").at(1) ?? ""; + + expect(lastPreviewText.length).toBeLessThan(340); + expect(progressLine).toMatch(/^• `{10}/); + expect(progressLine).toContain("…"); + expect(renderTelegramHtmlText(lastPreviewText)).not.toContain(" { dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => { await dispatcherOptions.deliver({ text: "Hello" }, { kind: "final" }); diff --git a/extensions/telegram/src/bot-message-dispatch.ts b/extensions/telegram/src/bot-message-dispatch.ts index c6249fee333..90fb2800afc 100644 --- a/extensions/telegram/src/bot-message-dispatch.ts +++ b/extensions/telegram/src/bot-message-dispatch.ts @@ -207,13 +207,24 @@ function resolveTelegramReasoningLevel(params: { return "off"; } +const MAX_PROGRESS_MARKDOWN_TEXT_CHARS = 300; +const MAX_PROGRESS_MARKDOWN_FENCE_CHARS = 10; + +function clipProgressMarkdownText(text: string): string { + if (text.length <= MAX_PROGRESS_MARKDOWN_TEXT_CHARS) { + return text; + } + return `${text.slice(0, MAX_PROGRESS_MARKDOWN_TEXT_CHARS - 1).trimEnd()}…`; +} + function formatProgressAsMarkdownCode(text: string): string { + const clipped = clipProgressMarkdownText(text); const maxBacktickRun = Math.max( 0, - ...Array.from(text.matchAll(/`+/g), (match) => match[0].length), + ...Array.from(clipped.matchAll(/`+/g), (match) => match[0].length), ); - const fence = "`".repeat(maxBacktickRun + 1); - return `${fence}${text}${fence}`; + const fence = "`".repeat(Math.min(maxBacktickRun + 1, MAX_PROGRESS_MARKDOWN_FENCE_CHARS)); + return `${fence}${clipped}${fence}`; } export const dispatchTelegramMessage = async ({