From dfbdab5a292e6917f78b747f4198cc5cf44ebe03 Mon Sep 17 00:00:00 2001 From: Peter Machona Date: Sun, 1 Mar 2026 16:21:25 +0000 Subject: [PATCH] fix(slack): map legacy streaming=false to off (openclaw#26020) thanks @chilu18 Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: chilu18 <7957943+chilu18@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> --- CHANGELOG.md | 1 + src/commands/doctor-legacy-config.test.ts | 17 +++++++++++++++++ ...-detection.rejects-routing-allowfrom.test.ts | 2 +- src/config/discord-preview-streaming.ts | 4 ++-- src/slack/stream-mode.test.ts | 9 +++++++-- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 858d235c9..f42adebf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ Docs: https://docs.openclaw.ai - Slack/HTTP mode startup: treat Slack HTTP accounts as configured when `botToken` + `signingSecret` are present (without requiring `appToken`) in channel config/runtime status so webhook mode is not silently skipped. (#30567) - Slack/Usage footer formatting: wrap session keys in inline code in full response-usage footers so Slack does not parse colon-delimited session segments as emoji shortcodes. (#30258) Thanks @pushkarsingh32. - Slack/Socket Mode slash startup: treat `app.options()` registration as best-effort and fall back to static arg menus when listener registration fails, preventing Slack monitor startup crash loops on receiver init edge cases. (#21715) +- Slack/Legacy streaming config: map boolean `channels.slack.streaming=false` to unified streaming mode `off` (with `nativeStreaming=false`) so legacy configs correctly disable draft preview/native streaming instead of defaulting to `partial`. (#25990) Thanks @chilu18. - Onboarding/Custom providers: raise default custom-provider model context window to the runtime hard minimum (16k) and auto-heal existing custom model entries below that threshold during reconfiguration, preventing immediate `Model context window too small (4096 tokens)` failures. (#21653) Thanks @r4jiv007. - Web UI/Assistant text: strip internal `...` scaffolding from rendered assistant messages (while preserving code-fence literals), preventing memory-context leakage in chat output for models that echo internal blocks. (#29851) Thanks @Valkster70. - Dashboard/Sessions: allow authenticated Control UI clients to delete and patch sessions while still blocking regular webchat clients from session mutation RPCs, fixing Dashboard session delete failures. (#21264) Thanks @jskoiz. diff --git a/src/commands/doctor-legacy-config.test.ts b/src/commands/doctor-legacy-config.test.ts index acc256c13..89bc93bbc 100644 --- a/src/commands/doctor-legacy-config.test.ts +++ b/src/commands/doctor-legacy-config.test.ts @@ -31,4 +31,21 @@ describe("normalizeCompatibilityConfigValues preview streaming aliases", () => { "Normalized channels.discord.streaming boolean → enum (partial).", ]); }); + + it("normalizes slack boolean streaming aliases to enum and native streaming", () => { + const res = normalizeCompatibilityConfigValues({ + channels: { + slack: { + streaming: false, + }, + }, + }); + + expect(res.config.channels?.slack?.streaming).toBe("off"); + expect(res.config.channels?.slack?.nativeStreaming).toBe(false); + expect(res.config.channels?.slack?.streamMode).toBeUndefined(); + expect(res.changes).toEqual([ + "Moved channels.slack.streaming (boolean) → channels.slack.nativeStreaming (false).", + ]); + }); }); diff --git a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts index 5682fce27..45f51e6a2 100644 --- a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts +++ b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts @@ -597,7 +597,7 @@ describe("legacy config detection", () => { }, }, assert: (config: NonNullable) => { - expect(config.channels?.slack?.streaming).toBe("partial"); + expect(config.channels?.slack?.streaming).toBe("off"); expect(config.channels?.slack?.nativeStreaming).toBe(false); }, }, diff --git a/src/config/discord-preview-streaming.ts b/src/config/discord-preview-streaming.ts index 684c5eff1..5b93b1ccb 100644 --- a/src/config/discord-preview-streaming.ts +++ b/src/config/discord-preview-streaming.ts @@ -121,9 +121,9 @@ export function resolveSlackStreamingMode( if (legacyStreamMode) { return mapSlackLegacyDraftStreamModeToStreaming(legacyStreamMode); } - // Legacy `streaming` was a Slack native-streaming toggle; preview mode stayed replace. + // Legacy boolean `streaming` values map to the unified enum. if (typeof params.streaming === "boolean") { - return "partial"; + return params.streaming ? "partial" : "off"; } return "partial"; } diff --git a/src/slack/stream-mode.test.ts b/src/slack/stream-mode.test.ts index c0146d323..fdbeb70ed 100644 --- a/src/slack/stream-mode.test.ts +++ b/src/slack/stream-mode.test.ts @@ -40,12 +40,17 @@ describe("resolveSlackStreamingConfig", () => { }); }); - it("moves legacy streaming boolean to native streaming toggle", () => { + it("maps legacy streaming booleans to unified mode and native streaming toggle", () => { expect(resolveSlackStreamingConfig({ streaming: false })).toEqual({ - mode: "partial", + mode: "off", nativeStreaming: false, draftMode: "replace", }); + expect(resolveSlackStreamingConfig({ streaming: true })).toEqual({ + mode: "partial", + nativeStreaming: true, + draftMode: "replace", + }); }); it("accepts unified enum values directly", () => {