Skip to content

Commit bbdfb16

Browse files
committed
fix(discord): preserve previews after tool warnings
1 parent 6f18dec commit bbdfb16

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

extensions/discord/src/monitor/message-handler.process.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,37 @@ describe("processDiscordMessage draft streaming", () => {
20612061
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
20622062
});
20632063

2064+
it("keeps finalized previews when later tool warning finals are delivered", async () => {
2065+
const draftStream = createMockDraftStreamForTest();
2066+
dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
2067+
await params?.dispatcher.sendFinalReply({ text: "delivery survived" });
2068+
await params?.dispatcher.sendFinalReply({
2069+
text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2070+
isError: true,
2071+
} as never);
2072+
return { queuedFinal: true, counts: { final: 2, tool: 0, block: 0 } };
2073+
});
2074+
2075+
const ctx = await createAutomaticSourceDeliveryContext({
2076+
discordConfig: { streamMode: "partial", maxLinesPerMessage: 5 },
2077+
});
2078+
2079+
await runProcessDiscordMessage(ctx);
2080+
2081+
expectPreviewEditContent("delivery survived");
2082+
expect(draftStream.clear).not.toHaveBeenCalled();
2083+
expect(draftStream.messageId()).toBe("preview-1");
2084+
expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
2085+
expect(firstMockArg(deliverDiscordReply, "deliverDiscordReply")).toMatchObject({
2086+
replies: [
2087+
{
2088+
text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2089+
isError: true,
2090+
},
2091+
],
2092+
});
2093+
});
2094+
20642095
it("suppresses reasoning payload delivery to Discord", async () => {
20652096
mockDispatchSingleBlockReply({ text: "thinking...", isReasoning: true });
20662097
await processStreamOffDiscordMessage();

extensions/discord/src/monitor/message-handler.process.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ export async function processDiscordMessage(
513513
const finalPreviewFlags =
514514
(discordConfig?.suppressEmbeds ?? true) ? MessageFlags.SuppressEmbeds : undefined;
515515
let finalReplyStartNotified = false;
516+
let nonErrorFinalDeliveryStarted = false;
516517
const notifyFinalReplyStart = () => {
517518
if (finalReplyStartNotified) {
518519
return;
@@ -550,11 +551,16 @@ export async function processDiscordMessage(
550551
return;
551552
}
552553
}
553-
if (
554+
const followsNonErrorFinalDelivery = payload.isError && nonErrorFinalDeliveryStarted;
555+
if (isFinal && !payload.isError) {
556+
nonErrorFinalDeliveryStarted = true;
557+
}
558+
const shouldFinalizeDraftPreview =
554559
draftStream &&
555560
isFinal &&
556-
(!draftPreview.isProgressMode || draftPreview.hasProgressDraftStarted)
557-
) {
561+
(!draftPreview.isProgressMode || draftPreview.hasProgressDraftStarted) &&
562+
!followsNonErrorFinalDelivery;
563+
if (shouldFinalizeDraftPreview) {
558564
const reply = resolveSendableOutboundReplyParts(effectivePayload);
559565
const hasMedia = reply.hasMedia;
560566
const ttsSupplement = getReplyPayloadTtsSupplement(effectivePayload);

0 commit comments

Comments
 (0)