mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-14 10:41:23 +00:00
146 lines
4.4 KiB
TypeScript
146 lines
4.4 KiB
TypeScript
import type {
|
|
BlockStreamingChunkConfig,
|
|
BlockStreamingCoalesceConfig,
|
|
ChannelDeliveryStreamingConfig,
|
|
ChannelPreviewStreamingConfig,
|
|
ChannelStreamingConfig,
|
|
SlackChannelStreamingConfig,
|
|
TextChunkMode,
|
|
} from "../config/types.base.js";
|
|
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
|
|
|
export type {
|
|
ChannelDeliveryStreamingConfig,
|
|
ChannelPreviewStreamingConfig,
|
|
ChannelStreamingBlockConfig,
|
|
ChannelStreamingConfig,
|
|
ChannelStreamingPreviewConfig,
|
|
SlackChannelStreamingConfig,
|
|
StreamingMode,
|
|
TextChunkMode,
|
|
} from "../config/types.base.js";
|
|
|
|
type StreamingCompatEntry = {
|
|
streaming?: unknown;
|
|
streamMode?: unknown;
|
|
chunkMode?: unknown;
|
|
blockStreaming?: unknown;
|
|
draftChunk?: unknown;
|
|
blockStreamingCoalesce?: unknown;
|
|
nativeStreaming?: unknown;
|
|
};
|
|
|
|
function asObjectRecord(value: unknown): Record<string, unknown> | null {
|
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
? (value as Record<string, unknown>)
|
|
: null;
|
|
}
|
|
|
|
function asTextChunkMode(value: unknown): TextChunkMode | undefined {
|
|
return value === "length" || value === "newline" ? value : undefined;
|
|
}
|
|
|
|
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 = normalizeOptionalLowercaseString(value);
|
|
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;
|
|
}
|
|
|
|
function asBlockStreamingChunkConfig(value: unknown): BlockStreamingChunkConfig | undefined {
|
|
return asObjectRecord(value) as BlockStreamingChunkConfig | undefined;
|
|
}
|
|
|
|
export function getChannelStreamingConfigObject(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): ChannelStreamingConfig | undefined {
|
|
const streaming = asObjectRecord(entry?.streaming);
|
|
return streaming ? (streaming as ChannelStreamingConfig) : undefined;
|
|
}
|
|
|
|
export function resolveChannelStreamingChunkMode(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): TextChunkMode | undefined {
|
|
return (
|
|
asTextChunkMode(getChannelStreamingConfigObject(entry)?.chunkMode) ??
|
|
asTextChunkMode(entry?.chunkMode)
|
|
);
|
|
}
|
|
|
|
export function resolveChannelStreamingBlockEnabled(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): boolean | undefined {
|
|
const config = getChannelStreamingConfigObject(entry);
|
|
return asBoolean(config?.block?.enabled) ?? asBoolean(entry?.blockStreaming);
|
|
}
|
|
|
|
export function resolveChannelStreamingBlockCoalesce(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): BlockStreamingCoalesceConfig | undefined {
|
|
const config = getChannelStreamingConfigObject(entry);
|
|
return (
|
|
asBlockStreamingCoalesceConfig(config?.block?.coalesce) ??
|
|
asBlockStreamingCoalesceConfig(entry?.blockStreamingCoalesce)
|
|
);
|
|
}
|
|
|
|
export function resolveChannelStreamingPreviewChunk(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): BlockStreamingChunkConfig | undefined {
|
|
const config = getChannelStreamingConfigObject(entry);
|
|
return (
|
|
asBlockStreamingChunkConfig(config?.preview?.chunk) ??
|
|
asBlockStreamingChunkConfig(entry?.draftChunk)
|
|
);
|
|
}
|
|
|
|
export function resolveChannelStreamingNativeTransport(
|
|
entry: StreamingCompatEntry | null | undefined,
|
|
): boolean | undefined {
|
|
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;
|
|
}
|