import { a as normalizeAssistantPhase, o as parseAssistantTextSignature } from "./chat-message-content-ir65IHKw.js";
import "./pi-embedded-helpers-XZLyX3NH.js";
import { S as sanitizeUserFacingText } from "./errors-BAYY50Ex.js";
import { c as stripReasoningTagsFromText, t as sanitizeAssistantVisibleText } from "./assistant-visible-text-CZBcZ1bS.js";
import { t as extractTextFromChatContent } from "./chat-content-q5-5SpX9.js";
import { r as resolveToolDisplay, t as formatToolDetail } from "./tool-display-C_AaHeLj.js";
//#region src/agents/pi-embedded-utils.ts
function isAssistantMessage(msg) {
	return msg?.role === "assistant";
}
/**
* Strip thinking tags and their content from text.
* This is a safety net for cases where the model outputs <think> tags
* that slip through other filtering mechanisms.
*/
function stripThinkingTagsFromText(text) {
	return stripReasoningTagsFromText(text, {
		mode: "strict",
		trim: "both"
	});
}
function sanitizeAssistantText(text) {
	return sanitizeAssistantVisibleText(text);
}
function finalizeAssistantExtraction(msg, extracted) {
	return sanitizeUserFacingText(extracted, { errorContext: msg.stopReason === "error" });
}
function extractAssistantTextForPhase(msg, phase) {
	const messagePhase = normalizeAssistantPhase(msg.phase);
	const shouldIncludeContent = (resolvedPhase) => {
		if (phase) return resolvedPhase === phase;
		return resolvedPhase === void 0;
	};
	if (typeof msg.content === "string") {
		const hadRequestedPhase = phase ? messagePhase === phase : messagePhase === void 0;
		return {
			text: shouldIncludeContent(messagePhase) ? finalizeAssistantExtraction(msg, sanitizeAssistantText(msg.content)) : "",
			hadRequestedPhase
		};
	}
	if (!Array.isArray(msg.content)) return {
		text: "",
		hadRequestedPhase: false
	};
	const hasExplicitPhasedTextBlocks = msg.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);
	});
	let hadRequestedPhase = false;
	return {
		text: finalizeAssistantExtraction(msg, extractTextFromChatContent(msg.content.filter((block) => {
			if (!block || typeof block !== "object") return false;
			const record = block;
			if (record.type !== "text") return false;
			const resolvedPhase = parseAssistantTextSignature(record.textSignature)?.phase ?? (hasExplicitPhasedTextBlocks ? void 0 : messagePhase);
			if (phase ? resolvedPhase === phase : resolvedPhase === void 0) hadRequestedPhase = true;
			return shouldIncludeContent(resolvedPhase);
		}), {
			sanitizeText: (text) => sanitizeAssistantText(text),
			joinWith: "\n",
			normalizeText: (text) => text.trim()
		}) ?? ""),
		hadRequestedPhase
	};
}
function extractAssistantVisibleText(msg) {
	const finalAnswerExtraction = extractAssistantTextForPhase(msg, "final_answer");
	if (finalAnswerExtraction.hadRequestedPhase) return finalAnswerExtraction.text.trim() ? finalAnswerExtraction.text : "";
	return extractAssistantTextForPhase(msg).text;
}
function extractAssistantText(msg) {
	return finalizeAssistantExtraction(msg, extractTextFromChatContent(msg.content, {
		sanitizeText: (text) => sanitizeAssistantText(text),
		joinWith: "\n",
		normalizeText: (text) => text.trim()
	}) ?? "");
}
function extractAssistantThinking(msg) {
	if (!Array.isArray(msg.content)) return "";
	return msg.content.map((block) => {
		if (!block || typeof block !== "object") return "";
		const record = block;
		if (record.type === "thinking" && typeof record.thinking === "string") return record.thinking.trim();
		return "";
	}).filter(Boolean).join("\n").trim();
}
function formatReasoningMessage(text) {
	const trimmed = text.trim();
	if (!trimmed) return "";
	return `Reasoning:\n${trimmed.split("\n").map((line) => line ? `_${line}_` : line).join("\n")}`;
}
function splitThinkingTaggedText(text) {
	const trimmedStart = text.trimStart();
	if (!trimmedStart.startsWith("<")) return null;
	const openRe = /<\s*(?:think(?:ing)?|thought|antthinking)\s*>/i;
	const closeRe = /<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/i;
	if (!openRe.test(trimmedStart)) return null;
	if (!closeRe.test(text)) return null;
	const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
	let inThinking = false;
	let cursor = 0;
	let thinkingStart = 0;
	const blocks = [];
	const pushText = (value) => {
		if (!value) return;
		blocks.push({
			type: "text",
			text: value
		});
	};
	const pushThinking = (value) => {
		const cleaned = value.trim();
		if (!cleaned) return;
		blocks.push({
			type: "thinking",
			thinking: cleaned
		});
	};
	for (const match of text.matchAll(scanRe)) {
		const index = match.index ?? 0;
		const isClose = Boolean(match[1]?.includes("/"));
		if (!inThinking && !isClose) {
			pushText(text.slice(cursor, index));
			thinkingStart = index + match[0].length;
			inThinking = true;
			continue;
		}
		if (inThinking && isClose) {
			pushThinking(text.slice(thinkingStart, index));
			cursor = index + match[0].length;
			inThinking = false;
		}
	}
	if (inThinking) return null;
	pushText(text.slice(cursor));
	if (!blocks.some((b) => b.type === "thinking")) return null;
	return blocks;
}
function promoteThinkingTagsToBlocks(message) {
	if (!Array.isArray(message.content)) return;
	if (message.content.some((block) => block && typeof block === "object" && block.type === "thinking")) return;
	const next = [];
	let changed = false;
	for (const block of message.content) {
		if (!block || typeof block !== "object" || !("type" in block)) {
			next.push(block);
			continue;
		}
		if (block.type !== "text") {
			next.push(block);
			continue;
		}
		const split = splitThinkingTaggedText(block.text);
		if (!split) {
			next.push(block);
			continue;
		}
		changed = true;
		for (const part of split) if (part.type === "thinking") next.push({
			type: "thinking",
			thinking: part.thinking
		});
		else if (part.type === "text") {
			const cleaned = part.text.trimStart();
			if (cleaned) next.push({
				type: "text",
				text: cleaned
			});
		}
	}
	if (!changed) return;
	message.content = next;
}
function extractThinkingFromTaggedText(text) {
	if (!text) return "";
	const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
	let result = "";
	let lastIndex = 0;
	let inThinking = false;
	for (const match of text.matchAll(scanRe)) {
		const idx = match.index ?? 0;
		if (inThinking) result += text.slice(lastIndex, idx);
		inThinking = !(match[1] === "/");
		lastIndex = idx + match[0].length;
	}
	return result.trim();
}
function extractThinkingFromTaggedStream(text) {
	if (!text) return "";
	const closed = extractThinkingFromTaggedText(text);
	if (closed) return closed;
	const openRe = /<\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
	const closeRe = /<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
	const openMatches = [...text.matchAll(openRe)];
	if (openMatches.length === 0) return "";
	const closeMatches = [...text.matchAll(closeRe)];
	const lastOpen = openMatches[openMatches.length - 1];
	const lastClose = closeMatches[closeMatches.length - 1];
	if (lastClose && (lastClose.index ?? -1) > (lastOpen.index ?? -1)) return closed;
	const start = (lastOpen.index ?? 0) + lastOpen[0].length;
	return text.slice(start).trim();
}
function inferToolMetaFromArgs(toolName, args) {
	return formatToolDetail(resolveToolDisplay({
		name: toolName,
		args
	}));
}
//#endregion
export { extractThinkingFromTaggedText as a, isAssistantMessage as c, stripThinkingTagsFromText as d, extractThinkingFromTaggedStream as i, promoteThinkingTagsToBlocks as l, extractAssistantThinking as n, formatReasoningMessage as o, extractAssistantVisibleText as r, inferToolMetaFromArgs as s, extractAssistantText as t, splitThinkingTaggedText as u };
