fix(telegram): bound tool progress preview formatting

Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-04-25 03:17:31 +01:00
parent e54a37a91e
commit f29e15c05d
2 changed files with 38 additions and 3 deletions

View File

@@ -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("<a ");
});
it("keeps block streaming enabled when account config enables it", async () => {
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => {
await dispatcherOptions.deliver({ text: "Hello" }, { kind: "final" });

View File

@@ -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 ({