diff --git a/CHANGELOG.md b/CHANGELOG.md index d2a17fd0711..10627da1ac1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Telegram/streaming: keep partial preview streaming enabled for plain reply-to replies, disabling drafts only for real native quote excerpts that require Telegram quote parameters. Fixes #73505. Thanks @choury. - Config: log the "newer OpenClaw" version warning once per process instead of once per config snapshot read. (#75927) Thanks @romneyda. - Telegram/message actions: treat benign delete-message 400s as no-op warnings instead of runtime errors, so stale or already-removed messages do not create noisy delete failures. Fixes #73726. Thanks @Avicennasis. - Telegram: split long default markdown sends and media follow-up text into safe HTML chunks, so outbound messages over Telegram's limit no longer fail as one oversized Bot API request. Fixes #75868. Thanks @zhengsx. diff --git a/extensions/telegram/src/bot-message-dispatch.test.ts b/extensions/telegram/src/bot-message-dispatch.test.ts index 7c92ac2e0d4..66f1ca6342e 100644 --- a/extensions/telegram/src/bot-message-dispatch.test.ts +++ b/extensions/telegram/src/bot-message-dispatch.test.ts @@ -479,7 +479,9 @@ describe("dispatchTelegramMessage draft streaming", () => { ); }); - it("passes native quote candidates for current message replies", async () => { + it("keeps answer draft preview for current message replies with native quote candidates", async () => { + const draftStream = createDraftStream(); + createTelegramDraftStream.mockReturnValue(draftStream); dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => { await dispatcherOptions.deliver({ text: "Hello", replyToId: "1001" }, { kind: "final" }); return { queuedFinal: true }; @@ -499,7 +501,11 @@ describe("dispatchTelegramMessage draft streaming", () => { }), }); - expect(createTelegramDraftStream).not.toHaveBeenCalled(); + expect(createTelegramDraftStream).toHaveBeenCalledWith( + expect.objectContaining({ + replyToMessageId: 1001, + }), + ); expect(deliverReplies).toHaveBeenCalledWith( expect.objectContaining({ replies: [expect.objectContaining({ replyToId: "1001" })], diff --git a/extensions/telegram/src/bot-message-dispatch.ts b/extensions/telegram/src/bot-message-dispatch.ts index 13a0b2384b7..75543013506 100644 --- a/extensions/telegram/src/bot-message-dispatch.ts +++ b/extensions/telegram/src/bot-message-dispatch.ts @@ -396,11 +396,10 @@ export const dispatchTelegramMessage = async ({ ); } } - const hasNativeQuoteReply = - replyToMode !== "off" && Object.keys(replyQuoteByMessageId).length > 0; + const hasTelegramQuoteReply = replyToMode !== "off" && replyQuoteText != null; const canStreamAnswerDraft = previewStreamingEnabled && - !hasNativeQuoteReply && + !hasTelegramQuoteReply && !accountBlockStreamingEnabled && !forceBlockStreamingForReasoning; const canStreamReasoningDraft = streamReasoningDraft;