From 673878188d033aa5b707d31b90c35dde564fe7e2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 6 Apr 2026 18:12:48 +0100 Subject: [PATCH] refactor: dedupe preview streaming helpers --- extensions/discord/src/preview-streaming.ts | 47 +----------------- extensions/telegram/src/preview-streaming.ts | 50 +------------------- src/plugin-sdk/channel-streaming.ts | 43 +++++++++++++++++ 3 files changed, 47 insertions(+), 93 deletions(-) diff --git a/extensions/discord/src/preview-streaming.ts b/extensions/discord/src/preview-streaming.ts index 67e2b982280..bda6efdbaf5 100644 --- a/extensions/discord/src/preview-streaming.ts +++ b/extensions/discord/src/preview-streaming.ts @@ -1,55 +1,12 @@ -import { getChannelStreamingConfigObject } from "openclaw/plugin-sdk/channel-streaming"; +import { resolveChannelPreviewStreamMode } from "openclaw/plugin-sdk/channel-streaming"; export type DiscordPreviewStreamMode = "off" | "partial" | "block"; -function normalizeStreamingMode(value: unknown): string | null { - if (typeof value !== "string") { - return null; - } - const normalized = value.trim().toLowerCase(); - return normalized || null; -} - -function parseStreamingMode(value: unknown): "off" | "partial" | "block" | "progress" | null { - const normalized = normalizeStreamingMode(value); - if ( - normalized === "off" || - normalized === "partial" || - normalized === "block" || - normalized === "progress" - ) { - return normalized; - } - return null; -} - -function parseDiscordPreviewStreamMode(value: unknown): DiscordPreviewStreamMode | null { - const parsed = parseStreamingMode(value); - if (!parsed) { - return null; - } - return parsed === "progress" ? "partial" : parsed; -} - export function resolveDiscordPreviewStreamMode( params: { streamMode?: unknown; streaming?: unknown; } = {}, ): DiscordPreviewStreamMode { - const parsedStreaming = parseDiscordPreviewStreamMode( - getChannelStreamingConfigObject(params)?.mode ?? params.streaming, - ); - if (parsedStreaming) { - return parsedStreaming; - } - - const legacy = parseDiscordPreviewStreamMode(params.streamMode); - if (legacy) { - return legacy; - } - if (typeof params.streaming === "boolean") { - return params.streaming ? "partial" : "off"; - } - return "off"; + return resolveChannelPreviewStreamMode(params, "off"); } diff --git a/extensions/telegram/src/preview-streaming.ts b/extensions/telegram/src/preview-streaming.ts index f9e17e93dfb..d575c7a9492 100644 --- a/extensions/telegram/src/preview-streaming.ts +++ b/extensions/telegram/src/preview-streaming.ts @@ -1,58 +1,12 @@ -import { getChannelStreamingConfigObject } from "openclaw/plugin-sdk/channel-streaming"; +import { resolveChannelPreviewStreamMode } from "openclaw/plugin-sdk/channel-streaming"; export type TelegramPreviewStreamMode = "off" | "partial" | "block"; -function normalizeStreamingMode(value: unknown): string | null { - if (typeof value !== "string") { - return null; - } - const normalized = value.trim().toLowerCase(); - return normalized || null; -} - -function parseStreamingMode(value: unknown): "off" | "partial" | "block" | "progress" | null { - const normalized = normalizeStreamingMode(value); - if ( - normalized === "off" || - normalized === "partial" || - normalized === "block" || - normalized === "progress" - ) { - return normalized; - } - return null; -} - -function parseTelegramPreviewStreamMode(value: unknown): TelegramPreviewStreamMode | null { - const parsed = parseStreamingMode(value); - if (!parsed) { - return null; - } - return parsed === "progress" ? "partial" : parsed; -} - export function resolveTelegramPreviewStreamMode( params: { streamMode?: unknown; streaming?: unknown; } = {}, ): TelegramPreviewStreamMode { - const parsedStreaming = parseStreamingMode( - getChannelStreamingConfigObject(params)?.mode ?? params.streaming, - ); - if (parsedStreaming) { - if (parsedStreaming === "progress") { - return "partial"; - } - return parsedStreaming; - } - - const legacy = parseTelegramPreviewStreamMode(params.streamMode); - if (legacy) { - return legacy; - } - if (typeof params.streaming === "boolean") { - return params.streaming ? "partial" : "off"; - } - return "partial"; + return resolveChannelPreviewStreamMode(params, "partial"); } diff --git a/src/plugin-sdk/channel-streaming.ts b/src/plugin-sdk/channel-streaming.ts index 7dfa7277a16..304366f583d 100644 --- a/src/plugin-sdk/channel-streaming.ts +++ b/src/plugin-sdk/channel-streaming.ts @@ -21,6 +21,7 @@ export type { type StreamingCompatEntry = { streaming?: unknown; + streamMode?: unknown; chunkMode?: unknown; blockStreaming?: unknown; draftChunk?: unknown; @@ -42,6 +43,27 @@ function asBoolean(value: unknown): boolean | undefined { return typeof value === "boolean" ? value : undefined; } +function normalizeStreamingMode(value: unknown): string | null { + if (typeof value !== "string") { + return null; + } + const normalized = value.trim().toLowerCase(); + return normalized || null; +} + +function parsePreviewStreamingMode(value: unknown): "off" | "partial" | "block" | null { + const normalized = normalizeStreamingMode(value); + if ( + normalized === "off" || + normalized === "partial" || + normalized === "block" || + normalized === "progress" + ) { + return normalized === "progress" ? "partial" : normalized; + } + return null; +} + function asBlockStreamingCoalesceConfig(value: unknown): BlockStreamingCoalesceConfig | undefined { return asObjectRecord(value) as BlockStreamingCoalesceConfig | undefined; } @@ -99,3 +121,24 @@ export function resolveChannelStreamingNativeTransport( const config = getChannelStreamingConfigObject(entry); return asBoolean(config?.nativeTransport) ?? asBoolean(entry?.nativeStreaming); } + +export function resolveChannelPreviewStreamMode( + entry: StreamingCompatEntry | null | undefined, + defaultMode: "off" | "partial", +): "off" | "partial" | "block" { + const parsedStreaming = parsePreviewStreamingMode( + getChannelStreamingConfigObject(entry)?.mode ?? entry?.streaming, + ); + if (parsedStreaming) { + return parsedStreaming; + } + + const legacy = parsePreviewStreamingMode(entry?.streamMode); + if (legacy) { + return legacy; + } + if (typeof entry?.streaming === "boolean") { + return entry.streaming ? "partial" : "off"; + } + return defaultMode; +}