import { DEFAULT_CODE_MODE_OUTPUT_TOKENS, MAX_CODE_MODE_OUTPUT_TOKENS, } from "./host-protocol.js";
const MAX_OUTPUT_IMAGE_COUNT = 4;
const MAX_OUTPUT_IMAGE_CHARS = 16 * 1024 * 1024;
export function toCodeModeToolResult(response, maxTokens) {
    const scriptError = response.kind === "result" ? response.errorText : undefined;
    const status = scriptError
        ? `Script error: ${scriptError}`
        : response.kind === "yielded"
            ? `Script running with cell ID ${response.cellId}`
            : response.kind === "terminated"
                ? "Script terminated"
                : "Script completed";
    let imageChars = 0;
    let imageCount = 0;
    let omittedImages = 0;
    const output = response.contentItems
        .map((item) => {
        const content = toPiContent(item);
        if (content?.type !== "image")
            return content;
        if (imageCount >= MAX_OUTPUT_IMAGE_COUNT ||
            imageChars + content.data.length > MAX_OUTPUT_IMAGE_CHARS) {
            omittedImages += 1;
            return undefined;
        }
        imageCount += 1;
        imageChars += content.data.length;
        return content;
    })
        .filter((item) => Boolean(item));
    if (omittedImages > 0)
        output.push({
            type: "text",
            text: `[${omittedImages} code-mode image${omittedImages === 1 ? "" : "s"} omitted]`,
        });
    const outputTokens = Math.min(MAX_CODE_MODE_OUTPUT_TOKENS, Math.max(1, maxTokens ?? response.maxOutputTokens ?? DEFAULT_CODE_MODE_OUTPUT_TOKENS));
    return {
        content: [
            { type: "text", text: status },
            ...truncateTextContent(output, outputTokens * 4),
        ],
        details: {
            codeMode: true,
            cellId: response.cellId,
            status: response.kind,
            ...(response.traces ? { traces: response.traces } : {}),
            ...(response.droppedTraceCount
                ? { droppedTraceCount: response.droppedTraceCount }
                : {}),
            ...(scriptError ? { scriptError } : {}),
        },
    };
}
function toPiContent(item) {
    if (item.type === "input_text" && typeof item.text === "string")
        return { type: "text", text: item.text };
    if (item.type === "input_image" && typeof item.image_url === "string") {
        const match = item.image_url.match(/^data:([^;,]+);base64,(.+)$/s);
        if (match)
            return { type: "image", mimeType: match[1], data: match[2] };
    }
    return undefined;
}
function truncateTextContent(content, maxChars) {
    let remaining = maxChars;
    let truncated = false;
    const output = [];
    for (const item of content) {
        if (item.type !== "text" || typeof item.text !== "string") {
            output.push(item);
            continue;
        }
        if (remaining <= 0) {
            if (!truncated)
                output.push({ ...item, text: "[Output truncated]" });
            truncated = true;
            continue;
        }
        if (item.text.length <= remaining) {
            remaining -= item.text.length;
            output.push(item);
            continue;
        }
        const text = `${item.text.slice(0, remaining)}\n[Output truncated]`;
        remaining = 0;
        truncated = true;
        output.push({ ...item, text });
    }
    return output;
}
