openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
108 lines (107 loc) • 5.33 kB
JavaScript
import { n as sliceUtf16Safe } from "./utf16-slice-D_ngcYKd.js";
import { n as isInsideCode, t as findCodeRegions } from "./code-regions-BXMpZZLd.js";
import { i as stripInlineDirectiveTagsForDelivery } from "./directive-tags-Wp1S72ap.js";
import { t as compactProgressText } from "./text-truncate-DL21A82B.js";
import { u as formatReasoningMessage } from "./embedded-agent-utils-DLNh77Fj.js";
//#region src/channels/progress-draft-status-text.ts
const REASONING_PROGRESS_TAG_RE = /<\s*(\/?)\s*(?:(?:antml:|mm:)?(?:think(?:ing)?|thought)|antthinking)\b[^<>]*>/giu;
const REASONING_PROGRESS_TAG_PREFIXES = [
"think",
"thinking",
"thought",
"antthinking",
"antml:think",
"antml:thinking",
"antml:thought",
"mm:think",
"mm:thinking",
"mm:thought"
].flatMap((name) => [`<${name}`, `</${name}`]);
function normalizeReasoningProgressLine(text) {
const reasoningText = readReasoningProgressTextOutsideCode(text);
if (reasoningText === void 0) return "";
return stripReasoningProgressTagsOutsideCode(reasoningText).replace(/^\s*(?:>\s*)?(?:Reasoning:\s*(?:\r?\n|\r)\s*|Thinking\.{0,3}\s*(?:\r?\n|\r)\s*(?:\r?\n|\r)\s*)/i, "").replace(/\s+/g, " ").trim();
}
function readReasoningProgressTextOutsideCode(text) {
if (isPartialReasoningProgressTagPrefix(text)) return;
const codeRegions = findCodeRegions(text);
let hasTags = false;
let inReasoning = false;
let cursor = 0;
const chunks = [];
for (const match of text.matchAll(REASONING_PROGRESS_TAG_RE)) {
const offset = match.index ?? 0;
if (isInsideCode(offset, codeRegions)) continue;
hasTags = true;
if (match[1]) {
if (inReasoning) chunks.push(text.slice(cursor, offset));
inReasoning = false;
cursor = offset + match[0].length;
continue;
}
if (inReasoning) chunks.push(text.slice(cursor, offset));
inReasoning = true;
cursor = offset + match[0].length;
}
if (!hasTags) return text;
if (inReasoning) chunks.push(text.slice(cursor));
return chunks.join("").trim();
}
function isPartialReasoningProgressTagPrefix(text) {
const normalized = text.trimStart().toLowerCase();
return normalized.startsWith("<") && !normalized.includes(">") && REASONING_PROGRESS_TAG_PREFIXES.some((prefix) => prefix.startsWith(normalized) || normalized.startsWith(prefix));
}
function stripReasoningProgressTagsOutsideCode(text) {
const codeRegions = findCodeRegions(text);
return text.replace(REASONING_PROGRESS_TAG_RE, (match, _closing, offset) => isInsideCode(offset, codeRegions) ? match : "");
}
function normalizeReasoningProgressInput(text) {
const normalized = normalizeReasoningProgressLine(text);
return (normalized.match(/^_(.*)_$/u)?.[1] ?? normalized).trim();
}
function formatReasoningProgressDisplayLine(text, maxChars) {
const normalizedText = normalizeReasoningProgressInput(text);
const formatted = normalizeReasoningProgressLine(formatReasoningMessage(normalizedText));
if (!formatted) return "";
if (Array.from(sliceUtf16Safe(formatted, 0, (Math.max(0, maxChars) + 1) * 2)).length <= maxChars) return formatted;
const italic = formatted.match(/^_(.*)_$/u);
if (!italic) return compactProgressText(formatted, maxChars);
const body = compactProgressText((italic[1] ?? "").trim(), Math.max(1, maxChars - 2));
return body ? `_${body}_` : "";
}
function sanitizeProgressStatusText(text) {
const cleaned = stripInlineDirectiveTagsForDelivery(text).text.trim();
if (!cleaned || isSilentCommentaryProgressText(cleaned)) return "";
return cleaned;
}
function normalizeCommentaryProgressText(text) {
const cleaned = sanitizeProgressStatusText(text);
if (!cleaned) return "";
return cleaned.split(/\r?\n/u).map((line) => line.replace(/\s+/g, " ").trim()).filter(Boolean).map((line) => `_${line}_`).join("\n");
}
function isSilentCommentaryProgressText(text) {
const normalized = text.replace(/^[\s*_`~]+|[\s*_`~]+$/gu, "").trim();
return /^NO_REPLY$/iu.test(normalized);
}
function mergeReasoningProgressText(current, incoming, options) {
if (!current) return incoming;
const normalizedCurrent = normalizeReasoningProgressInput(current);
const normalizedIncoming = normalizeReasoningProgressInput(incoming);
if (!normalizedIncoming) return shouldAppendEmptyReasoningProgressDelta(current, incoming) ? `${current}${incoming}` : current;
if (normalizedIncoming === normalizedCurrent) return current;
if (options?.snapshot === true || isReasoningSnapshotText(incoming) || normalizedCurrent && normalizedIncoming.startsWith(normalizedCurrent)) return incoming;
return `${current}${incoming}`;
}
function isReasoningSnapshotText(text) {
return /^\s*(?:>\s*)?(?:Reasoning:\s*(?:\r?\n|\r)\s*|Thinking\.{0,3}\s*(?:\r?\n|\r)\s*(?:\r?\n|\r)\s*)/i.test(text);
}
function shouldAppendEmptyReasoningProgressDelta(current, incoming) {
return isPartialReasoningProgressTagPrefix(current) || isPartialReasoningProgressTagPrefix(incoming) || hasReasoningProgressTagOutsideCode(incoming);
}
function hasReasoningProgressTagOutsideCode(text) {
const codeRegions = findCodeRegions(text);
for (const match of text.matchAll(REASONING_PROGRESS_TAG_RE)) if (!isInsideCode(match.index ?? 0, codeRegions)) return true;
return false;
}
//#endregion
export { sanitizeProgressStatusText as a, normalizeReasoningProgressLine as i, mergeReasoningProgressText as n, normalizeCommentaryProgressText as r, formatReasoningProgressDisplayLine as t };