fix(telegram): avoid duplicate preview bubbles in partial stream mode (#18956)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: cf4eca71d4
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
This commit is contained in:
Ayaan Zaidi
2026-02-17 12:36:15 +05:30
committed by GitHub
parent 5649e403df
commit 583844ecf6
3 changed files with 48 additions and 9 deletions

View File

@@ -113,6 +113,7 @@ export const dispatchTelegramMessage = async ({
draftStream && streamMode === "block"
? resolveTelegramDraftStreamingChunking(cfg, route.accountId)
: undefined;
const shouldSplitPreviewMessages = streamMode === "block";
const draftChunker = draftChunking ? new EmbeddedBlockChunker(draftChunking) : undefined;
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, route.agentId);
let lastPartialText = "";
@@ -424,13 +425,12 @@ export const dispatchTelegramMessage = async ({
onPartialReply: draftStream ? (payload) => updateDraftFromPartial(payload.text) : undefined,
onAssistantMessageStart: draftStream
? () => {
// When a new assistant message starts (e.g., after tool call),
// force a new Telegram message if we have previous content.
// Only force once per response to avoid excessive splitting.
// Only split preview bubbles in block mode. In partial mode, keep
// editing one preview message to avoid flooding the chat.
logVerbose(
`telegram: onAssistantMessageStart called, hasStreamedMessage=${hasStreamedMessage}`,
);
if (hasStreamedMessage) {
if (shouldSplitPreviewMessages && hasStreamedMessage) {
logVerbose(`telegram: calling forceNewMessage()`);
draftStream.forceNewMessage();
}
@@ -441,13 +441,13 @@ export const dispatchTelegramMessage = async ({
: undefined,
onReasoningEnd: draftStream
? () => {
// When a thinking block ends, force a new Telegram message for the next text output.
if (hasStreamedMessage) {
// Same policy as assistant-message boundaries: split only in block mode.
if (shouldSplitPreviewMessages && hasStreamedMessage) {
draftStream.forceNewMessage();
lastPartialText = "";
draftText = "";
draftChunker?.reset();
}
lastPartialText = "";
draftText = "";
draftChunker?.reset();
}
: undefined,
onModelSelected,