import { TOOL_NAME_BASH, TOOL_NAME_EDIT } from "../tools/tool_names.js";
import { buildLineDiff, collapseLongUnchangedDiffRuns } from "./line_diff.js";
import { truncateForTokens } from "./truncate.js";
import { stripTauUserMetadata } from "./user_metadata.js";
export const COMPACTION_SUMMARY_HEADER = "The conversation history before this point was compacted into the following summary:";
const SUMMARY_OPEN_TAG = "<summary>";
const SUMMARY_CLOSE_TAG = "</summary>";
const LAST_ASSISTANT_OPEN_TAG = "<last-assistant-message-verbatim>";
const LAST_ASSISTANT_CLOSE_TAG = "</last-assistant-message-verbatim>";
const COMPACTION_BASH_TOOL_RESULT_MAX_TOKENS = 4096;
const COMPACTION_EDIT_UNCHANGED_CONTEXT_LINES = 8;
function extractTextFromContent(content) {
    if (typeof content === "string") {
        return content.trim();
    }
    const parts = [];
    for (const block of content) {
        if (typeof block === "string") {
            parts.push(block);
        }
        else if (block.type === "text") {
            parts.push(block.text ?? "");
        }
    }
    return parts.join("\n").trim();
}
function formatCompactionBlock(marker, text) {
    return `${marker}\n${text}`;
}
function formatToolCallArguments(argumentsValue) {
    if (!argumentsValue || typeof argumentsValue !== "object") {
        return JSON.stringify(argumentsValue) ?? "null";
    }
    return Object.entries(argumentsValue)
        .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
        .join(", ");
}
function buildEditCallDiff(argumentsValue) {
    if (!argumentsValue || typeof argumentsValue !== "object") {
        return "(diff unavailable)";
    }
    const args = argumentsValue;
    const oldText = typeof args.oldText === "string" ? args.oldText : "";
    const newText = typeof args.newText === "string" ? args.newText : "";
    const diff = buildLineDiff(oldText, newText);
    if (diff.added === 0 && diff.removed === 0) {
        return "(no textual changes)";
    }
    const collapsed = collapseLongUnchangedDiffRuns({
        diffLines: diff.lines,
        maxUnchangedLines: COMPACTION_EDIT_UNCHANGED_CONTEXT_LINES,
    });
    return collapsed.join("\n").trim() || "(no textual changes)";
}
function serializeToolCall(name, argumentsValue) {
    if (name === TOOL_NAME_EDIT) {
        const args = argumentsValue && typeof argumentsValue === "object"
            ? argumentsValue
            : undefined;
        const path = typeof args?.path === "string" ? args.path : undefined;
        const header = path ? `${TOOL_NAME_EDIT}(path=${JSON.stringify(path)})` : `${TOOL_NAME_EDIT}()`;
        return `${header}\n${buildEditCallDiff(argumentsValue)}`;
    }
    const args = formatToolCallArguments(argumentsValue);
    return `${name}(${args})`;
}
function serializeAssistantMessage(message) {
    const textParts = [];
    const toolCalls = [];
    for (const block of message.content) {
        if (block.type === "text") {
            textParts.push(block.text);
        }
        else if (block.type === "toolCall") {
            toolCalls.push(serializeToolCall(block.name, block.arguments));
        }
    }
    const lines = [];
    if (textParts.length > 0) {
        lines.push(formatCompactionBlock("[Assistant]:", textParts.join("\n")));
    }
    if (toolCalls.length > 0) {
        lines.push(formatCompactionBlock("[Assistant tool calls]:", toolCalls.join("\n\n")));
    }
    return lines;
}
function serializeToolResultMessage(message) {
    const outputText = extractTextFromContent(message.content);
    const status = message.isError ? "error" : "ok";
    let content = outputText || "(no text output)";
    if (message.toolName === TOOL_NAME_BASH) {
        content = truncateForTokens(content, {
            maxTokens: COMPACTION_BASH_TOOL_RESULT_MAX_TOKENS,
            strategy: "middle",
        }).content;
    }
    return formatCompactionBlock(`[Tool result]: ${message.toolName} (${status})`, content);
}
export function formatHistoryForCompaction(history) {
    const lines = [];
    for (const message of history) {
        if (message.role === "user") {
            const text = stripTauUserMetadata(extractTextFromContent(message.content));
            if (text) {
                lines.push(formatCompactionBlock("[User]:", text));
            }
            continue;
        }
        if (message.role === "assistant") {
            lines.push(...serializeAssistantMessage(message));
            continue;
        }
        if (message.role === "toolResult") {
            lines.push(serializeToolResultMessage(message));
        }
    }
    return lines.join("\n\n").trim();
}
export function buildCompactionUserMessage(args) {
    const lines = [
        COMPACTION_SUMMARY_HEADER,
        "",
        SUMMARY_OPEN_TAG,
        args.summary.trim(),
        SUMMARY_CLOSE_TAG,
    ];
    const lastAssistantMessage = args.lastAssistantMessage;
    if (lastAssistantMessage?.trim()) {
        lines.push("", LAST_ASSISTANT_OPEN_TAG, lastAssistantMessage, LAST_ASSISTANT_CLOSE_TAG);
    }
    return lines.join("\n");
}
//# sourceMappingURL=compact.js.map