UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

107 lines (106 loc) 5.13 kB
import { p as readStringValue } from "./string-coerce-mnp54Vah.js"; //#region src/shared/chat-message-content.ts /** Returns inline string content or the first array text block without scanning later blocks. */ function extractFirstTextBlock(message) { if (!message || typeof message !== "object") return; const content = message.content; const inline = readStringValue(content); if (inline !== void 0) return inline; if (!Array.isArray(content) || content.length === 0) return; const first = content[0]; if (!first || typeof first !== "object") return; return readStringValue(first.text); } /** Narrows unknown phase metadata to assistant text phases that affect visibility. */ function normalizeAssistantPhase(value) { return value === "commentary" || value === "final_answer" ? value : void 0; } /** Parses assistant text block signatures, preserving legacy raw ids when not JSON encoded. */ function parseAssistantTextSignature(value) { if (typeof value !== "string" || value.trim().length === 0) return null; if (!value.startsWith("{")) return { id: value }; try { const parsed = JSON.parse(value); if (parsed.v !== 1) return null; return { ...typeof parsed.id === "string" ? { id: parsed.id } : {}, ...normalizeAssistantPhase(parsed.phase) ? { phase: normalizeAssistantPhase(parsed.phase) } : {} }; } catch { return null; } } /** Resolves a message phase only when the top-level phase or all explicit blocks agree. */ function resolveAssistantMessagePhase(message) { if (!message || typeof message !== "object") return; const entry = message; const directPhase = normalizeAssistantPhase(entry.phase); if (directPhase) return directPhase; if (!Array.isArray(entry.content)) return; const explicitPhases = /* @__PURE__ */ new Set(); for (const block of entry.content) { if (!block || typeof block !== "object") continue; const record = block; if (record.type !== "text") continue; const phase = parseAssistantTextSignature(record.textSignature)?.phase; if (phase) explicitPhases.add(phase); } return explicitPhases.size === 1 ? [...explicitPhases][0] : void 0; } /** Finds assistant phase metadata on event payloads that may wrap message-like records. */ function resolveAssistantEventPhase(data) { if (!data || typeof data !== "object") return; const record = data; return normalizeAssistantPhase(record.phase) ?? resolveAssistantMessagePhase(record.message) ?? resolveAssistantMessagePhase(record.partial) ?? resolveAssistantMessagePhase(record.item) ?? resolveAssistantMessagePhase(record); } /** Extracts assistant text for a requested phase without mixing legacy and explicitly phased text. */ function extractAssistantTextForPhase(message, options) { if (!message || typeof message !== "object") return; const entry = message; const messagePhase = normalizeAssistantPhase(entry.phase); const phase = options?.phase; const shouldIncludeContent = (resolvedPhase) => { if (phase) return resolvedPhase === phase; return resolvedPhase === void 0; }; const sanitizeText = options?.sanitizeText; const joinWith = options?.joinWith ?? "\n"; const sanitizeBlockText = (text) => sanitizeText ? sanitizeText(text) : text; const normalizeJoinedText = (text) => { return text.trim() || void 0; }; if (typeof entry.text === "string") { if (!shouldIncludeContent(messagePhase)) return; return normalizeJoinedText(sanitizeBlockText(entry.text)); } if (typeof entry.content === "string") { if (!shouldIncludeContent(messagePhase)) return; return normalizeJoinedText(sanitizeBlockText(entry.content)); } if (!Array.isArray(entry.content)) return; const hasExplicitPhasedTextBlocks = entry.content.some((block) => { if (!block || typeof block !== "object") return false; const record = block; if (record.type !== "text") return false; return Boolean(parseAssistantTextSignature(record.textSignature)?.phase); }); if (!phase && hasExplicitPhasedTextBlocks) return; const parts = entry.content.map((block) => { if (!block || typeof block !== "object") return null; const record = block; if (record.type !== "text" || typeof record.text !== "string") return null; if (!shouldIncludeContent(parseAssistantTextSignature(record.textSignature)?.phase ?? (hasExplicitPhasedTextBlocks ? void 0 : messagePhase))) return null; const sanitized = sanitizeBlockText(record.text); return sanitized.trim() ? sanitized : null; }).filter((value) => typeof value === "string"); if (parts.length === 0) return; return normalizeJoinedText(parts.join(joinWith)); } /** Returns user-visible assistant text, preferring final answers over legacy unphased text. */ function extractAssistantVisibleText(message) { const finalAnswerText = extractAssistantTextForPhase(message, { phase: "final_answer" }); if (finalAnswerText) return finalAnswerText; return extractAssistantTextForPhase(message); } //#endregion export { parseAssistantTextSignature as a, normalizeAssistantPhase as i, extractAssistantVisibleText as n, resolveAssistantEventPhase as o, extractFirstTextBlock as r, resolveAssistantMessagePhase as s, extractAssistantTextForPhase as t };