UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

623 lines (622 loc) 26.8 kB
import { a as normalizeLowercaseStringOrEmpty, s as normalizeOptionalLowercaseString } from "./string-coerce-mnp54Vah.js"; import { d as normalizeTrimmedStringList } from "./string-normalization-WNUDCpXX.js"; import { h as shortenHomeInString } from "./utils-CCC-BEJH.js"; import { t as asBoolean } from "./boolean-By0bZpFH.js"; import { r as resolveToolDisplay, t as formatToolDetail } from "./tool-display-CX5DV8AV.js"; //#region src/auto-reply/tool-meta.ts /** Formats compact tool metadata labels for auto-reply progress/status messages. */ /** Shortens user-home paths inside arbitrary tool metadata. */ function shortenMeta(meta) { if (!meta) return meta; return shortenHomeInString(meta); } /** Formats one grouped tool-progress label from a tool name and metadata entries. */ function formatToolAggregate(toolName, metas, options) { const filtered = (metas ?? []).filter(Boolean).map(shortenMeta); const display = resolveToolDisplay({ name: toolName }); const normalizedToolName = normalizeLowercaseStringOrEmpty(toolName); const compactCommandSummary = filtered.length > 0 && (normalizedToolName === "exec" || normalizedToolName === "bash"); const prefix = compactCommandSummary ? display.emoji : `${display.emoji} ${display.label}`; if (!filtered.length) return `${display.emoji} ${display.label}`; const rawSegments = []; const grouped = {}; for (const m of filtered) { if (!isPathLike(m)) { rawSegments.push(m); continue; } if (m.includes("→")) { rawSegments.push(m); continue; } const parts = m.split("/"); if (parts.length > 1) { const dir = parts.slice(0, -1).join("/"); const base = parts.at(-1) ?? m; if (!grouped[dir]) grouped[dir] = []; grouped[dir].push(base); } else { if (!grouped["."]) grouped["."] = []; grouped["."].push(m); } } const segments = Object.entries(grouped).map(([dir, files]) => { const brace = files.length > 1 ? `{${files.join(", ")}}` : files[0]; if (dir === ".") return brace; return `${dir}/${brace}`; }); const formattedMeta = formatMetaForDisplay(toolName, [...rawSegments, ...segments].join("; "), options?.markdown); return compactCommandSummary ? `${prefix} ${formattedMeta}` : `${prefix}: ${formattedMeta}`; } function formatMetaForDisplay(toolName, meta, markdown) { const normalized = normalizeLowercaseStringOrEmpty(toolName); if (normalized === "exec" || normalized === "bash") { const { flags, body } = splitExecFlags(meta); if (flags.length > 0) { if (!body) return flags.join(" · "); return `${flags.join(" · ")} · ${maybeWrapMarkdown(body, markdown)}`; } } return maybeWrapMarkdown(meta, markdown); } function splitExecFlags(meta) { const parts = meta.split(" · ").map((part) => part.trim()).filter(Boolean); if (parts.length === 0) return { flags: [], body: "" }; const flags = []; const bodyParts = []; for (const part of parts) { if (part === "elevated" || part === "pty") { flags.push(part); continue; } bodyParts.push(part); } return { flags, body: bodyParts.join(" · ") }; } function isPathLike(value) { if (!value) return false; if (value.includes(" ")) return false; if (value.includes("://")) return false; if (value.includes("·")) return false; if (value.includes("&&") || value.includes("||")) return false; return /^~?(\/[^\s]+)+$/.test(value); } function maybeWrapMarkdown(value, markdown) { if (!markdown) return value; const delimiter = "`".repeat(longestBacktickRun(value) + 1); const padding = value.startsWith("`") || value.endsWith("`") || value.includes("\n") ? " " : ""; return `${delimiter}${padding}${value}${padding}${delimiter}`; } function longestBacktickRun(value) { let longest = 0; let current = 0; for (const char of value) { if (char === "`") { current += 1; longest = Math.max(longest, current); continue; } current = 0; } return longest; } //#endregion //#region src/channels/streaming.ts function asObjectRecord(value) { return value && typeof value === "object" && !Array.isArray(value) ? value : null; } function asTextChunkMode(value) { return value === "length" || value === "newline" ? value : void 0; } function asStringNumberArray(value) { return Array.isArray(value) && value.every((entry) => typeof entry === "string" || typeof entry === "number") ? value : void 0; } function asInteger(value) { return typeof value === "number" && Number.isInteger(value) ? value : void 0; } function normalizeStreamingMode(value) { if (typeof value !== "string") return null; return normalizeOptionalLowercaseString(value) || null; } function parsePreviewStreamingMode(value) { const normalized = normalizeStreamingMode(value); if (normalized === "off" || normalized === "partial" || normalized === "block" || normalized === "progress") return normalized; return null; } function asBlockStreamingCoalesceConfig(value) { return asObjectRecord(value); } function asBlockStreamingChunkConfig(value) { return asObjectRecord(value); } function asProgressConfig(value) { return asObjectRecord(value); } function asCommandTextMode(value) { return value === "raw" || value === "status" ? value : void 0; } const DEFAULT_PROGRESS_DRAFT_LABELS = [ "Working", "Shelling", "Scuttling", "Clawing", "Pinching", "Molting", "Bubbling", "Tiding", "Reefing", "Cracking", "Sifting", "Brining", "Nautiling", "Krilling", "Barnacling", "Lobstering", "Tidepooling", "Pearling", "Snapping", "Surfacing" ]; const DEFAULT_PROGRESS_DRAFT_INITIAL_DELAY_MS = 5e3; const DEFAULT_PROGRESS_DRAFT_MAX_LINE_CHARS = 120; const MIN_TRUNCATED_FINAL_PREFIX_CHARS = 48; const MIN_TRUNCATED_FINAL_CONTINUATION_CHARS = 24; const NON_WORK_PROGRESS_TOOL_NAMES = new Set([ "message", "messages", "reply", "send", "reaction", "react", "typing" ]); function isChannelProgressDraftWorkToolName(name) { const normalized = normalizeOptionalLowercaseString(name); return Boolean(normalized && !NON_WORK_PROGRESS_TOOL_NAMES.has(normalized)); } function stripTrailingEllipsis(text) { return text.replace(/(?:\s*(?:\.{3}|\u2026))+$/u, "").trimEnd(); } function isPotentialTruncatedFinal(finalText) { const trimmedFinal = finalText.trimEnd(); const untruncatedFinal = stripTrailingEllipsis(trimmedFinal); return untruncatedFinal.length >= MIN_TRUNCATED_FINAL_PREFIX_CHARS && untruncatedFinal !== trimmedFinal; } function selectLongerFinalText(params) { const finalText = params.finalText.trimEnd(); if (!isPotentialTruncatedFinal(finalText)) return; const untruncatedFinal = stripTrailingEllipsis(finalText); for (const candidate of params.candidateTexts) { const candidateText = candidate?.trimEnd(); if (!candidateText || candidateText.length <= finalText.length || !candidateText.startsWith(untruncatedFinal)) continue; const continuation = candidateText.slice(untruncatedFinal.length).trimStart(); if (continuation.length >= MIN_TRUNCATED_FINAL_CONTINUATION_CHARS && /^[\p{L}\p{N}]/u.test(continuation)) return candidateText; } } async function resolveTranscriptBackedChannelFinalText(params) { if (!isPotentialTruncatedFinal(params.finalText)) return params.finalText; const candidateText = await params.resolveCandidateText(); return selectLongerFinalText({ finalText: params.finalText, candidateTexts: [candidateText] }) ?? params.finalText; } const EMOJI_PREFIX_RE = /^\p{Extended_Pictographic}/u; function compactStrings(values) { return values.map((value) => value?.replace(/\s+/g, " ").trim()).filter(Boolean); } function inferToolMeta(name, args, detailMode = "explain") { if (!name || !args) return; return formatToolDetail(resolveToolDisplay({ name, args, detailMode })); } function buildNamedProgressLine(kind, name, metas, options, fields) { const normalizedName = name?.trim() || "tool_call"; const compactMetas = compactStrings(metas ?? []); const text = formatToolAggregate(normalizedName, compactMetas.length ? compactMetas : void 0, { markdown: options?.markdown }); const display = resolveToolDisplay({ name: normalizedName }); const prefix = `${display.emoji} ${display.label}`; const compactCommandPrefix = (display.name === "exec" || display.name === "bash") && text.startsWith(`${display.emoji} `) ? text.slice(display.emoji.length + 1).trim() : void 0; const detail = text.startsWith(`${prefix}: `) ? text.slice(prefix.length + 2).trim() : compactCommandPrefix; return { ...fields?.id ? { id: fields.id } : {}, kind, text, label: display.label, icon: display.emoji, ...detail ? { detail } : {}, ...fields?.status ? { status: fields.status } : {}, toolName: display.name }; } function itemKindToToolName(kind) { switch (normalizeOptionalLowercaseString(kind)) { case "command": return "exec"; case "patch": return "apply_patch"; case "search": return "web_search"; case "tool": return "tool_call"; default: return; } } function isCommandToolName(name) { const normalized = normalizeOptionalLowercaseString(name); return normalized === "exec" || normalized === "shell" || normalized === "bash"; } function isCommandProgressItem(input) { return normalizeOptionalLowercaseString(input.itemKind) === "command" || isCommandToolName(input.name); } function isEmptyReasoningProgressItem(input, meta) { return !meta && normalizeOptionalLowercaseString(input.itemKind) === "analysis" && normalizeOptionalLowercaseString(input.title) === "reasoning"; } function patchMetas(input) { const fileMetas = [ ...input.added ?? [], ...input.modified ?? [], ...input.deleted ?? [] ]; return compactStrings([ input.summary, ...fileMetas, input.title ]); } function shouldPrefixProgressLine(line) { return !EMOJI_PREFIX_RE.test(line); } function formatChannelProgressDraftLine(input, options) { return buildChannelProgressDraftLine(input, options)?.text; } function resolveChannelProgressDraftLineOptions(entry, options) { return { ...options, commandText: options?.commandText ?? resolveChannelStreamingPreviewCommandText(entry) }; } function buildChannelProgressDraftLineForEntry(entry, input, options) { return buildChannelProgressDraftLine(input, resolveChannelProgressDraftLineOptions(entry, options)); } function formatChannelProgressDraftLineForEntry(entry, input, options) { return buildChannelProgressDraftLineForEntry(entry, input, options)?.text; } function buildChannelProgressDraftLine(input, options) { switch (input.event) { case "tool": return buildNamedProgressLine(input.event, input.name, [options?.commandText === "status" && isCommandToolName(input.name) ? void 0 : inferToolMeta(input.name, input.args, options?.detailMode), input.phase && !input.name ? input.phase : void 0], options, { id: input.itemId ?? input.toolCallId }); case "item": { const name = input.name ?? itemKindToToolName(input.itemKind); const meta = input.meta ?? input.summary ?? (options?.commandText === "status" && isCommandProgressItem(input) ? void 0 : input.progressText); if (isEmptyReasoningProgressItem(input, meta)) return; if (name) return buildNamedProgressLine(input.event, name, [meta], options, { id: input.itemId, status: input.status }); const text = compactStrings([meta, input.title]).at(0); return text ? { ...input.itemId ? { id: input.itemId } : {}, kind: input.event, text, label: input.title?.trim() || input.itemKind?.trim() || "Update", ...input.status ? { status: input.status } : {} } : void 0; } case "plan": if (input.phase !== void 0 && input.phase !== "update") return; return buildNamedProgressLine(input.event, "update_plan", [ input.explanation, input.steps?.[0], input.title ?? "planning" ], options); case "approval": if (input.phase !== void 0 && input.phase !== "requested") return; return buildNamedProgressLine(input.event, "approval", [ input.command, input.message, input.reason, input.title ?? "approval requested" ], options, { status: "requested" }); case "command-output": { if (input.phase !== void 0 && input.phase !== "end") return; const status = input.exitCode === 0 ? "completed" : input.exitCode != null ? `exit ${input.exitCode}` : input.status; return buildNamedProgressLine(input.event, input.name ?? "exec", [status, input.title], options, { id: input.itemId ?? input.toolCallId, status }); } case "patch": if (input.phase !== void 0 && input.phase !== "end") return; return buildNamedProgressLine(input.event, input.name ?? "apply_patch", patchMetas(input), options, { id: input.itemId ?? input.toolCallId }); } } function createChannelProgressDraftGate(params) { const initialDelayMs = params.initialDelayMs ?? 5e3; const setTimeoutFn = params.setTimeoutFn ?? setTimeout; const clearTimeoutFn = params.clearTimeoutFn ?? clearTimeout; let started = false; let disposed = false; let workEvents = 0; let timer; let startPromise; const clearTimer = () => { if (timer) { clearTimeoutFn(timer); timer = void 0; } }; const start = () => { if (disposed || started) return startPromise ?? Promise.resolve(); if (startPromise) return startPromise; clearTimer(); started = true; const nextStart = Promise.resolve().then(params.onStart).then(() => { if (disposed) started = false; if (startPromise === nextStart) startPromise = void 0; }).catch((error) => { if (startPromise === nextStart) startPromise = void 0; started = false; throw error; }); startPromise = nextStart; return startPromise; }; const schedule = () => { if (timer || started || disposed || initialDelayMs < 0) return; timer = setTimeoutFn(() => { timer = void 0; start().catch(() => {}); }, initialDelayMs); }; return { get hasStarted() { return started; }, get workEvents() { return workEvents; }, async noteWork() { if (disposed) return false; workEvents += 1; if (startPromise) { await startPromise; return started; } if (started) return true; if (workEvents > 1) { await start(); return started; } schedule(); return false; }, async startNow() { await start(); }, cancel() { disposed = true; started = false; clearTimer(); } }; } function getChannelStreamingConfigObject(entry) { const streaming = asObjectRecord(entry?.streaming); return streaming ? streaming : void 0; } function resolveChannelStreamingChunkMode(entry) { return asTextChunkMode(getChannelStreamingConfigObject(entry)?.chunkMode) ?? asTextChunkMode(entry?.chunkMode); } function resolveChannelStreamingBlockEnabled(entry) { return asBoolean(getChannelStreamingConfigObject(entry)?.block?.enabled) ?? asBoolean(entry?.blockStreaming); } function resolveChannelStreamingBlockCoalesce(entry) { return asBlockStreamingCoalesceConfig(getChannelStreamingConfigObject(entry)?.block?.coalesce) ?? asBlockStreamingCoalesceConfig(entry?.blockStreamingCoalesce); } function resolveChannelStreamingPreviewChunk(entry) { return asBlockStreamingChunkConfig(getChannelStreamingConfigObject(entry)?.preview?.chunk) ?? asBlockStreamingChunkConfig(entry?.draftChunk); } function resolveChannelStreamingPreviewToolProgress(entry, defaultValue = true) { const config = getChannelStreamingConfigObject(entry); if (resolveChannelPreviewStreamMode(entry, "partial") === "progress") return asBoolean(config?.progress?.toolProgress) ?? asBoolean(config?.preview?.toolProgress) ?? defaultValue; return asBoolean(config?.preview?.toolProgress) ?? defaultValue; } function resolveChannelStreamingProgressCommentary(entry, defaultValue = false) { const config = getChannelStreamingConfigObject(entry); if (resolveChannelPreviewStreamMode(entry, "partial") !== "progress") return false; return asBoolean(asObjectRecord(config?.progress)?.commentary) ?? defaultValue; } function resolveChannelStreamingPreviewCommandText(entry, defaultValue = "raw") { const config = getChannelStreamingConfigObject(entry); return asCommandTextMode(config?.progress?.commandText) ?? asCommandTextMode(config?.preview?.commandText) ?? defaultValue; } function resolveChannelStreamingPreviewNativeToolProgress(entry, defaultValue = false) { return asBoolean(asObjectRecord(getChannelStreamingConfigObject(entry)?.preview)?.nativeToolProgress) ?? defaultValue; } function resolveChannelStreamingPreviewNativeToolProgressAllowFrom(entry) { return asStringNumberArray(asObjectRecord(getChannelStreamingConfigObject(entry)?.preview)?.nativeToolProgressAllowFrom); } function resolveChannelStreamingSuppressDefaultToolProgressMessages(entry, options) { if (options?.draftStreamActive === false || options?.previewStreamingEnabled === false) return false; const mode = resolveChannelPreviewStreamMode(entry, "off"); if (mode === "off") return false; if (mode === "progress") return true; if (options?.draftStreamActive === true) return true; return options?.previewToolProgressEnabled ?? resolveChannelStreamingPreviewToolProgress(entry); } function resolveChannelStreamingNativeTransport(entry) { return asBoolean(getChannelStreamingConfigObject(entry)?.nativeTransport) ?? asBoolean(entry?.nativeStreaming); } function resolveChannelPreviewStreamMode(entry, defaultMode) { 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; } function resolveChannelProgressDraftConfig(entry) { return asProgressConfig(getChannelStreamingConfigObject(entry)?.progress) ?? {}; } function normalizeProgressLabels(labels) { const normalized = normalizeTrimmedStringList(labels); if (normalized.length === 0) return [...DEFAULT_PROGRESS_DRAFT_LABELS]; return normalized; } function hashProgressSeed(seed) { let hash = 2166136261; for (let index = 0; index < seed.length; index += 1) { hash ^= seed.charCodeAt(index); hash = Math.imul(hash, 16777619); } return hash >>> 0; } function resolveChannelProgressDraftLabel(params) { const progress = resolveChannelProgressDraftConfig(params.entry); if (progress.label === false) return; const normalizedLabel = typeof progress.label === "string" ? normalizeOptionalLowercaseString(progress.label) : null; if (typeof progress.label === "string" && progress.label.trim() && normalizedLabel !== "auto") return progress.label.trim(); const labels = normalizeProgressLabels(progress.labels); return labels[typeof params.seed === "string" && params.seed.length > 0 ? hashProgressSeed(params.seed) % labels.length : Math.floor(Math.max(0, Math.min(.999999, params.random?.() ?? 0)) * labels.length)] ?? labels[0]; } function resolveChannelProgressDraftMaxLines(entry, defaultValue = 8) { const configured = asInteger(resolveChannelProgressDraftConfig(entry).maxLines); return configured && configured > 0 ? configured : defaultValue; } function resolveChannelProgressDraftMaxLineChars(entry, defaultValue = DEFAULT_PROGRESS_DRAFT_MAX_LINE_CHARS) { const configured = asInteger(resolveChannelProgressDraftConfig(entry).maxLineChars); return configured && configured > 0 ? configured : defaultValue; } function resolveChannelProgressDraftRender(entry, defaultValue = "text") { const configured = resolveChannelProgressDraftConfig(entry).render; return configured === "rich" || configured === "text" ? configured : defaultValue; } function sliceCodePoints(value, start, end) { return Array.from(value).slice(start, end).join(""); } function compactProgressLineDetail(detail, maxChars) { const chars = Array.from(detail); if (chars.length <= maxChars) return detail; if (maxChars <= 1) return "…"; const keepStart = Math.max(1, Math.ceil((maxChars - 1) * .45)); const keepEnd = Math.max(1, maxChars - keepStart - 1); const rawStart = chars.slice(0, keepStart).join("").trimEnd(); return `${rawStart.length > 8 && /\s+\S+$/.test(rawStart) ? rawStart.replace(/\s+\S+$/, "") : rawStart}${chars.slice(-keepEnd).join("").trimStart()}`; } function removeUnbalancedInlineBackticks(value) { if (Array.from(value).filter((char) => char === "`").length % 2 === 0) return value; return value.trimStart().startsWith("`") ? value.replaceAll("`", "'") : value.replaceAll("`", ""); } function repairCompactedProgressMarkdown(value) { const withoutDanglingBackticks = removeUnbalancedInlineBackticks(value); const trimmedStart = withoutDanglingBackticks.trimStart(); if (!trimmedStart.startsWith("_") || trimmedStart.endsWith("_")) return withoutDanglingBackticks; if (Array.from(trimmedStart).filter((char) => char === "_").length % 2 === 0) return withoutDanglingBackticks; return `${withoutDanglingBackticks.slice(0, withoutDanglingBackticks.length - trimmedStart.length)}${trimmedStart.slice(1)}`; } function compactPlainProgressLine(line, maxChars) { const head = sliceCodePoints(line, 0, maxChars - 1).trimEnd(); const boundary = head.search(/\s+\S*$/u); if (boundary > Math.floor(maxChars * .6)) return `${head.slice(0, boundary).trimEnd()}…`; return `${head}…`; } function compactChannelProgressDraftLine(line, maxChars) { const normalized = line.replace(/\s+/g, " ").trim(); if (!normalized) return ""; if (Array.from(normalized).length <= maxChars) return normalized; if (maxChars <= 1) return "…"; const compactWithPrefix = (prefix, detail) => { const detailLimit = maxChars - Array.from(prefix).length; if (detailLimit < 8) return; return repairCompactedProgressMarkdown(`${prefix}${compactProgressLineDetail(detail, detailLimit)}`); }; const splitIndex = normalized.indexOf(": "); if (splitIndex > 0) { const compact = compactWithPrefix(normalized.slice(0, splitIndex + 2), normalized.slice(splitIndex + 2)); if (compact) return compact; } const compactCommandPrefixMatch = normalized.match(/^🛠️\s+/u); if (compactCommandPrefixMatch) { const prefix = compactCommandPrefixMatch[0]; const compact = compactWithPrefix(prefix, normalized.slice(prefix.length)); if (compact) return compact; } return repairCompactedProgressMarkdown(compactPlainProgressLine(normalized, maxChars)); } function getProgressDraftLineText(line) { if (typeof line === "string") return line; const icon = line.icon?.trim(); const prefix = icon ? `${icon} ` : ""; const label = line.label.trim(); const detail = line.detail?.trim(); if (detail) { const compactCommandLine = line.toolName === "exec" || line.toolName === "bash" || line.toolName === "shell"; if (line.kind !== "patch" && label && !compactCommandLine) return `${prefix}${label}: ${detail}`; return `${prefix}${detail}`; } const status = line.status?.trim(); if (status) { if (label) return `${prefix}${label}: ${status}`; return `${prefix}${status}`; } const text = line.text.trim(); if (!icon && text && text !== label) return text; return `${prefix}${label}`.trim(); } function normalizeChannelProgressDraftLineIdentity(line) { return (typeof line === "string" ? line : line?.text)?.replace(/\s+/g, " ").trim() ?? ""; } function mergeChannelProgressDraftLine(lines, line, params) { const normalized = normalizeChannelProgressDraftLineIdentity(line); if (!normalized) return lines; const maxLines = Math.max(1, params.maxLines); const lineId = typeof line === "object" ? line.id?.trim() : void 0; if (lineId) { const existingIndex = lines.findIndex((entry) => typeof entry === "object" && entry.id?.trim() === lineId); if (existingIndex >= 0) { if (normalizeChannelProgressDraftLineIdentity(lines[existingIndex]) === normalized) return lines; const next = [...lines]; next[existingIndex] = line; return next.slice(-maxLines); } } if (normalizeChannelProgressDraftLineIdentity(lines.at(-1)) === normalized) return lines; return [...lines, line].slice(-maxLines); } function formatChannelProgressDraftText(params) { const resolvedLabel = resolveChannelProgressDraftLabel({ entry: params.entry, seed: params.seed, random: params.random }); const maxLines = resolveChannelProgressDraftMaxLines(params.entry); const maxLineChars = resolveChannelProgressDraftMaxLineChars(params.entry); const formatLine = params.formatLine ?? ((line) => line); const bullet = params.bullet ?? "•"; const lines = (resolvedLabel ? [{ draftLabel: resolvedLabel }, ...params.lines] : params.lines).map((line) => { const isLabelLine = typeof line === "object" && line !== null && "draftLabel" in line; const prefix = !isLabelLine && typeof line === "object" && line !== null ? line.prefix !== false : true; const text = compactChannelProgressDraftLine(isLabelLine ? line.draftLabel : typeof line === "string" ? line : getProgressDraftLineText(line), maxLineChars); return text ? { text, isLabelLine, prefix } : void 0; }).filter((line) => Boolean(line)).slice(-maxLines).map(({ text, isLabelLine, prefix }) => { const formatted = isLabelLine ? text : formatLine(text); return { text: !isLabelLine && prefix && shouldPrefixProgressLine(text) ? `${bullet} ${formatted}` : formatted, isLabelLine }; }); const renderedLines = lines.map((line) => line.text).filter((line) => Boolean(line)); if (renderedLines.length > 1 && lines[0]?.isLabelLine) return `${renderedLines[0]}\n\n${renderedLines.slice(1).join("\n")}`; return renderedLines.join("\n"); } //#endregion export { resolveChannelStreamingProgressCommentary as A, resolveChannelStreamingChunkMode as C, resolveChannelStreamingPreviewNativeToolProgress as D, resolveChannelStreamingPreviewCommandText as E, resolveTranscriptBackedChannelFinalText as M, selectLongerFinalText as N, resolveChannelStreamingPreviewNativeToolProgressAllowFrom as O, formatToolAggregate as P, resolveChannelStreamingBlockEnabled as S, resolveChannelStreamingPreviewChunk as T, resolveChannelProgressDraftLineOptions as _, createChannelProgressDraftGate as a, resolveChannelProgressDraftRender as b, formatChannelProgressDraftText as c, isPotentialTruncatedFinal as d, mergeChannelProgressDraftLine as f, resolveChannelProgressDraftLabel as g, resolveChannelProgressDraftConfig as h, buildChannelProgressDraftLineForEntry as i, resolveChannelStreamingSuppressDefaultToolProgressMessages as j, resolveChannelStreamingPreviewToolProgress as k, getChannelStreamingConfigObject as l, resolveChannelPreviewStreamMode as m, DEFAULT_PROGRESS_DRAFT_LABELS as n, formatChannelProgressDraftLine as o, normalizeChannelProgressDraftLineIdentity as p, buildChannelProgressDraftLine as r, formatChannelProgressDraftLineForEntry as s, DEFAULT_PROGRESS_DRAFT_INITIAL_DELAY_MS as t, isChannelProgressDraftWorkToolName as u, resolveChannelProgressDraftMaxLineChars as v, resolveChannelStreamingNativeTransport as w, resolveChannelStreamingBlockCoalesce as x, resolveChannelProgressDraftMaxLines as y };