



















@@ -28,6 +28,8 @@ class TestSlackStreamNotDeliveredError extends Error {
2828}
2929}
3030let mockedNativeStreaming = false;
31+let mockedBlockStreamingEnabled: boolean | undefined = false;
32+let capturedReplyOptions: { disableBlockStreaming?: boolean } | undefined;
3133let mockedDispatchSequence: Array<{
3234kind: "tool" | "block" | "final";
3335payload: { text: string; isError?: boolean; mediaUrl?: string; mediaUrls?: string[] };
@@ -129,7 +131,7 @@ vi.mock("openclaw/plugin-sdk/channel-reply-pipeline", () => ({
129131}));
130132131133vi.mock("openclaw/plugin-sdk/channel-streaming", () => ({
132-resolveChannelStreamingBlockEnabled: () => false,
134+resolveChannelStreamingBlockEnabled: () => mockedBlockStreamingEnabled,
133135resolveChannelStreamingNativeTransport: () => mockedNativeStreaming,
134136resolveChannelStreamingPreviewToolProgress: () => true,
135137}));
@@ -266,13 +268,15 @@ vi.mock("../reply.runtime.js", () => ({
266268markDispatchIdle: () => {},
267269}),
268270dispatchInboundMessage: async (params: {
271+replyOptions?: { disableBlockStreaming?: boolean };
269272dispatcher: {
270273deliver: (
271274payload: { text: string; isError?: boolean; mediaUrl?: string; mediaUrls?: string[] },
272275info: { kind: "tool" | "block" | "final" },
273276) => Promise<void>;
274277};
275278}) => {
279+capturedReplyOptions = params.replyOptions;
276280for (const entry of mockedDispatchSequence) {
277281await params.dispatcher.deliver(entry.payload, { kind: entry.kind });
278282}
@@ -305,6 +309,8 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
305309startSlackStreamMock.mockReset();
306310stopSlackStreamMock.mockReset();
307311mockedNativeStreaming = false;
312+mockedBlockStreamingEnabled = false;
313+capturedReplyOptions = undefined;
308314mockedDispatchSequence = [{ kind: "final", payload: { text: FINAL_REPLY_TEXT } }];
309315310316createSlackDraftStreamMock.mockReturnValue(createDraftStreamStub());
@@ -333,6 +339,14 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
333339);
334340});
335341342+it("suppresses block streaming when Slack draft preview streaming is active", async () => {
343+mockedBlockStreamingEnabled = true;
344+345+await dispatchPreparedSlackMessage(createPreparedSlackMessage());
346+347+expect(capturedReplyOptions?.disableBlockStreaming).toBe(true);
348+});
349+336350it("keeps same-content tool and final payloads distinct after preview fallback", async () => {
337351mockedDispatchSequence = [
338352{ kind: "tool", payload: { text: SAME_TEXT } },
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。