import { LLMObsTracer } from "../../llmobs/tracer.js";
import { extractTextFromMessage } from "../client.js";
import { toStoredMessage } from "./types.js";
const MAX_TURNS_TO_SHOW = 10;
const MAX_USER_MESSAGE_LENGTH = 1000;
const MAX_ASSISTANT_MESSAGE_LENGTH = 1000;
function truncateText(text, maxLength) {
    const normalized = text.replace(/\s+/g, " ").trim();
    if (normalized.length <= maxLength) {
        return normalized;
    }
    return normalized.slice(0, maxLength) + "...";
}
function extractTurnSummaries(messages) {
    const summaries = [];
    let currentUserMessage = null;
    let lastAssistantText = null;
    for (const msg of messages) {
        if (msg.role === "user") {
            const userText = extractTextFromMessage(msg, "last");
            if (userText) {
                if (currentUserMessage !== null) {
                    summaries.push({
                        userMessage: currentUserMessage,
                        assistantMessage: lastAssistantText,
                    });
                }
                currentUserMessage = userText;
                lastAssistantText = null;
            }
        }
        else if (msg.role === "assistant" && currentUserMessage !== null) {
            const text = extractTextFromMessage(msg);
            if (text) {
                lastAssistantText = text;
            }
        }
    }
    if (currentUserMessage !== null) {
        summaries.push({
            userMessage: currentUserMessage,
            assistantMessage: lastAssistantText,
        });
    }
    return summaries;
}
function formatTimeline(summaries, totalMessages) {
    const totalTurns = summaries.length;
    const turnsToShow = summaries.slice(-MAX_TURNS_TO_SHOW);
    const startNumber = totalTurns - turnsToShow.length + 1;
    const isLimited = totalTurns > MAX_TURNS_TO_SHOW;
    let header = `[Context limit reached - ${totalMessages} messages were dropped. Falling back to session summary.]\n\n`;
    header += isLimited
        ? `## Session History (showing last ${turnsToShow.length} of ${totalTurns} turns)\n\n`
        : `## Session History\n\n`;
    const lines = turnsToShow.map((turn, i) => {
        const turnNumber = startNumber + i;
        const isLast = i === turnsToShow.length - 1;
        const userLabel = isLast ? "**Current request:**" : "User:";
        // Preserve the full text for the current/last user message so the task context is not lost.
        const userText = isLast
            ? truncateText(turn.userMessage, Infinity)
            : truncateText(turn.userMessage, MAX_USER_MESSAGE_LENGTH);
        let line = `${turnNumber}. ${userLabel} "${userText}"`;
        if (turn.assistantMessage) {
            line += `\n    Assistant: "${truncateText(turn.assistantMessage, MAX_ASSISTANT_MESSAGE_LENGTH)}"`;
        }
        else if (!isLast) {
            line += `\n    Assistant: "(no response)"`;
        }
        return line;
    });
    return header + lines.join("\n\n");
}
/**
 * Creates a truncation-based fallback when LLM summarization fails.
 * Generates a timeline summary of the conversation without returning
 * the actual messages, which can cause provider errors.
 */
export function createTruncationFallback(messages, tracer = LLMObsTracer.instance) {
    return tracer.trace({ name: "session.summarize.fallback", kind: "task" }, (fallbackSpan) => {
        const summaries = extractTurnSummaries(messages);
        if (summaries.length === 0) {
            const fallbackContent = `[Context limit reached - ${messages.length} messages were dropped. ` +
                `No user messages found to summarize.]`;
            tracer.annotate(fallbackSpan, {
                metadata: {
                    input: {
                        messageCount: messages.length,
                    },
                    result: {
                        summaryLength: fallbackContent.length,
                        turnCount: 0,
                    },
                },
            });
            return {
                summary: fallbackContent,
                messages: [
                    toStoredMessage({ role: "user", content: fallbackContent }, { isSummary: true }),
                ],
            };
        }
        const summaryText = formatTimeline(summaries, messages.length);
        const summaryMessage = toStoredMessage({ role: "user", content: summaryText }, { isSummary: true });
        tracer.annotate(fallbackSpan, {
            metadata: {
                input: {
                    messageCount: messages.length,
                },
                result: {
                    summaryLength: summaryText.length,
                    turnCount: summaries.length,
                },
            },
        });
        return {
            summary: summaryText,
            messages: [summaryMessage],
        };
    });
}
//# sourceMappingURL=truncation-fallback.js.map