fix(telegram): prime final preview before stop flush

This commit is contained in:
Ayaan Zaidi
2026-02-26 16:13:24 +05:30
committed by Ayaan Zaidi
parent e273b9851e
commit d9ed2c425a
2 changed files with 40 additions and 0 deletions

View File

@@ -381,6 +381,41 @@ describe("dispatchTelegramMessage draft streaming", () => {
expect(draftStream.stop).toHaveBeenCalled();
});
it("primes stop() with final text when pending partial is below initial threshold", async () => {
let answerMessageId: number | undefined;
const answerDraftStream = {
update: vi.fn(),
flush: vi.fn().mockResolvedValue(undefined),
messageId: vi.fn().mockImplementation(() => answerMessageId),
clear: vi.fn().mockResolvedValue(undefined),
stop: vi.fn().mockImplementation(async () => {
answerMessageId = 777;
}),
forceNewMessage: vi.fn(),
};
const reasoningDraftStream = createDraftStream();
createTelegramDraftStream
.mockImplementationOnce(() => answerDraftStream)
.mockImplementationOnce(() => reasoningDraftStream);
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(
async ({ dispatcherOptions, replyOptions }) => {
await replyOptions?.onPartialReply?.({ text: "no" });
await dispatcherOptions.deliver({ text: "no problem" }, { kind: "final" });
return { queuedFinal: true };
},
);
deliverReplies.mockResolvedValue({ delivered: true });
editMessageTelegram.mockResolvedValue({ ok: true, chatId: "123", messageId: "777" });
await dispatchWithContext({ context: createContext() });
expect(answerDraftStream.update).toHaveBeenCalledWith("no");
expect(answerDraftStream.update).toHaveBeenLastCalledWith("no problem");
expect(editMessageTelegram).toHaveBeenCalledWith(123, 777, "no problem", expect.any(Object));
expect(deliverReplies).not.toHaveBeenCalled();
expect(answerDraftStream.stop).toHaveBeenCalled();
});
it("does not overwrite finalized preview when additional final payloads are sent", async () => {
const draftStream = createDraftStream(999);
createTelegramDraftStream.mockReturnValue(draftStream);

View File

@@ -123,6 +123,11 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
const hadPreviewMessage =
typeof previewMessageIdOverride === "number" || typeof lanePreviewMessageId === "number";
if (stopBeforeEdit) {
if (!hadPreviewMessage && context === "final") {
// If debounce prevented the first preview, replace stale pending partial text
// before final stop() flush sends the first visible preview.
lane.stream.update(text);
}
await params.stopDraftLane(lane);
}
const previewMessageId =