mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix: address telegram follow-up review comments
This commit is contained in:
@@ -505,6 +505,42 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
||||
expect(deliverReplies).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("preserves earlier inline buttons when a later final only changes text", async () => {
|
||||
const answerDraftStream = createSequencedDraftStream(1001);
|
||||
const reasoningDraftStream = createDraftStream();
|
||||
const buttons = [[{ text: "Open", callback_data: "open" }]];
|
||||
createTelegramDraftStream
|
||||
.mockImplementationOnce(() => answerDraftStream)
|
||||
.mockImplementationOnce(() => reasoningDraftStream);
|
||||
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(
|
||||
async ({ dispatcherOptions, replyOptions }) => {
|
||||
await replyOptions?.onPartialReply?.({ text: "Message A partial" });
|
||||
await replyOptions?.onAssistantMessageStart?.();
|
||||
await replyOptions?.onPartialReply?.({ text: "Message B partial" });
|
||||
await dispatcherOptions.deliver(
|
||||
{
|
||||
text: "Message A final",
|
||||
channelData: { telegram: { buttons } },
|
||||
},
|
||||
{ kind: "final" },
|
||||
);
|
||||
await dispatcherOptions.deliver({ text: "Message B final" }, { kind: "final" });
|
||||
return { queuedFinal: true };
|
||||
},
|
||||
);
|
||||
deliverReplies.mockResolvedValue({ delivered: true });
|
||||
editMessageTelegram.mockResolvedValue({ ok: true, chatId: "123", messageId: "1001" });
|
||||
|
||||
await dispatchWithContext({ context: createContext(), streamMode: "partial" });
|
||||
|
||||
expect(editMessageTelegram).toHaveBeenCalledWith(
|
||||
123,
|
||||
1001,
|
||||
"Message A final Message B final",
|
||||
expect.objectContaining({ buttons }),
|
||||
);
|
||||
});
|
||||
|
||||
it.each(["partial", "block"] as const)(
|
||||
"keeps finalized text preview when the next assistant message is media-only (%s mode)",
|
||||
async (streamMode) => {
|
||||
@@ -1230,6 +1266,21 @@ describe("dispatchTelegramMessage draft streaming", () => {
|
||||
expect(draftStream.clear).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("clears stale reasoning preview when streamed turn ends without a final", async () => {
|
||||
const { reasoningDraftStream } = setupDraftStreams({
|
||||
answerMessageId: 999,
|
||||
reasoningMessageId: 111,
|
||||
});
|
||||
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ replyOptions }) => {
|
||||
await replyOptions?.onReasoningStream?.({ text: "Reasoning:\n_step one_" });
|
||||
return { queuedFinal: false };
|
||||
});
|
||||
|
||||
await dispatchWithContext({ context: createReasoningStreamContext(), streamMode: "partial" });
|
||||
|
||||
expect(reasoningDraftStream.clear).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("falls back when all finals are skipped and clears preview", async () => {
|
||||
const draftStream = createDraftStream(999);
|
||||
createTelegramDraftStream.mockReturnValue(draftStream);
|
||||
|
||||
@@ -309,8 +309,22 @@ export const dispatchTelegramMessage = async ({
|
||||
const getCurrentAnswerText = () => composeAnswerSegmentsText();
|
||||
const getLastAnswerSegment = () => answerSegments[answerSegments.length - 1];
|
||||
const getUnfinalizedAnswerSegments = () => answerSegments.filter((segment) => !segment.finalized);
|
||||
const hasBufferedAnswerPayloadMetadata = (payload: ReplyPayload) => {
|
||||
const previewButtons = (
|
||||
payload.channelData?.telegram as { buttons?: TelegramInlineButtons } | undefined
|
||||
)?.buttons;
|
||||
return (
|
||||
Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0 || Boolean(previewButtons)
|
||||
);
|
||||
};
|
||||
const bufferAnswerFinal = (payload: ReplyPayload) => {
|
||||
bufferedAnswerFinal = { payload, text: composeAnswerSegmentsText() };
|
||||
const bufferedPayload =
|
||||
bufferedAnswerFinal &&
|
||||
hasBufferedAnswerPayloadMetadata(bufferedAnswerFinal.payload) &&
|
||||
!hasBufferedAnswerPayloadMetadata(payload)
|
||||
? bufferedAnswerFinal.payload
|
||||
: payload;
|
||||
bufferedAnswerFinal = { payload: bufferedPayload, text: composeAnswerSegmentsText() };
|
||||
};
|
||||
const createAnswerSegment = (segmentStartsAfterFinal: boolean): AnswerSegmentState => {
|
||||
const segment: AnswerSegmentState = {
|
||||
@@ -754,7 +768,7 @@ export const dispatchTelegramMessage = async ({
|
||||
},
|
||||
}));
|
||||
await flushBufferedAnswerFinal();
|
||||
if (reasoningLane.hasStreamedMessage) {
|
||||
if (queuedFinal && reasoningLane.hasStreamedMessage) {
|
||||
finalizedPreviewByLane.reasoning = true;
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user