

















@@ -2061,6 +2061,68 @@ describe("processDiscordMessage draft streaming", () => {
20612061expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
20622062});
206320632064+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+2095+it("keeps draft previews when tool warning finals arrive before recovered replies", async () => {
2096+const draftStream = createMockDraftStreamForTest();
2097+dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
2098+await params?.dispatcher.sendFinalReply({
2099+text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2100+isError: true,
2101+} as never);
2102+await params?.dispatcher.sendFinalReply({ text: "delivery recovered" });
2103+return { queuedFinal: true, counts: { final: 2, tool: 0, block: 0 } };
2104+});
2105+2106+const ctx = await createAutomaticSourceDeliveryContext({
2107+discordConfig: { streamMode: "partial", maxLinesPerMessage: 5 },
2108+});
2109+2110+await runProcessDiscordMessage(ctx);
2111+2112+expectPreviewEditContent("delivery recovered");
2113+expect(draftStream.clear).not.toHaveBeenCalled();
2114+expect(draftStream.messageId()).toBe("preview-1");
2115+expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
2116+expect(firstMockArg(deliverDiscordReply, "deliverDiscordReply")).toMatchObject({
2117+replies: [
2118+{
2119+text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2120+isError: true,
2121+},
2122+],
2123+});
2124+});
2125+20642126it("suppresses reasoning payload delivery to Discord", async () => {
20652127mockDispatchSingleBlockReply({ text: "thinking...", isReasoning: true });
20662128await processStreamOffDiscordMessage();
@@ -2210,6 +2272,48 @@ describe("processDiscordMessage draft streaming", () => {
22102272expectPreviewEditContent("done");
22112273});
221222742275+it("keeps finalized progress previews when later tool warning finals are delivered", async () => {
2276+const draftStream = createMockDraftStreamForTest();
2277+2278+dispatchInboundMessage.mockImplementationOnce(async (params?: DispatchInboundParams) => {
2279+await params?.replyOptions?.onToolStart?.({ name: "exec", phase: "start" });
2280+await params?.replyOptions?.onItemEvent?.({ progressText: "exec done" });
2281+await params?.dispatcher.sendFinalReply({ text: "delivery survived" });
2282+await params?.dispatcher.sendFinalReply({
2283+text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2284+isError: true,
2285+} as never);
2286+return { queuedFinal: true, counts: { final: 2, tool: 0, block: 0 } };
2287+});
2288+2289+const ctx = await createAutomaticSourceDeliveryContext({
2290+discordConfig: {
2291+streaming: {
2292+mode: "progress",
2293+progress: {
2294+label: "Shelling",
2295+},
2296+},
2297+},
2298+});
2299+2300+await runProcessDiscordMessage(ctx);
2301+2302+expect(draftStream.update).toHaveBeenCalledWith("Shelling\n\n🛠️ Exec\n• exec done");
2303+expectPreviewEditContent("delivery survived");
2304+expect(draftStream.clear).not.toHaveBeenCalled();
2305+expect(draftStream.messageId()).toBe("preview-1");
2306+expect(deliverDiscordReply).toHaveBeenCalledTimes(1);
2307+expect(firstMockArg(deliverDiscordReply, "deliverDiscordReply")).toMatchObject({
2308+replies: [
2309+{
2310+text: "⚠️ 🛠️ `run openclaw definitely-not-a-real-subcommand (agent)` failed",
2311+isError: true,
2312+},
2313+],
2314+});
2315+});
2316+22132317it("uses raw tool-progress detail in Discord progress drafts", async () => {
22142318const draftStream = createMockDraftStreamForTest();
22152319此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。