import { messageStartsLlmUserTurn, userLikeContentBlockIsLlmVisible } from "../messages.js";
import { isAssistantThinkingBlockType, messageHasAssistantThinkingContentBlock } from "../thinking-blocks.js";
export function assistantEntryHasThinkingContentBlock(entry) {
    return (entry.role === "assistant" &&
        (entry.contentBlocks.some((block) => isAssistantThinkingBlockType(block.type)) ||
            messageHasAssistantThinkingContentBlock(entry.message)));
}
export function compactableContentBlockIsLlmVisible(entry, block) {
    if (typeof block.llmVisible === "boolean")
        return block.llmVisible;
    const rawContent = entry.message.content;
    return Array.isArray(rawContent) && userLikeContentBlockIsLlmVisible(rawContent[block.blockIndex]);
}
export function transcriptEntryStartsNewTurn(entry, deletedContentBlocks = new Set()) {
    if (entry.role === "user" || entry.role === "custom") {
        const content = entry.message.content;
        if (typeof content === "string" || entry.contentBlocks.length === 0) {
            return messageStartsLlmUserTurn(entry.message, deletedContentBlocks);
        }
        return entry.contentBlocks.some((block) => !deletedContentBlocks.has(block.blockIndex) && compactableContentBlockIsLlmVisible(entry, block));
    }
    return messageStartsLlmUserTurn(entry.message, deletedContentBlocks);
}
export function isTranscriptEntryEffectivelyDeleted(entry, deletedEntryIds, deletedContentBlocks) {
    if (deletedEntryIds.has(entry.entryId))
        return true;
    const deletedBlocks = deletedContentBlocks.get(entry.entryId);
    return (entry.contentBlocks.length > 0 &&
        deletedBlocks !== undefined &&
        entry.contentBlocks.every((block) => deletedBlocks.has(block.blockIndex)));
}
/** Shared adaptation from compactable transcript entries to logical assistant-turn inputs. */
export function compactableTranscriptToAssistantTurnEntries(transcript, deletedEntryIds, deletedContentBlocks) {
    return transcript.entries.map((entry) => ({
        entryId: entry.entryId,
        role: entry.role,
        hasSignedThinking: assistantEntryHasThinkingContentBlock(entry),
        startsNewTurn: !isTranscriptEntryEffectivelyDeleted(entry, deletedEntryIds, deletedContentBlocks) &&
            transcriptEntryStartsNewTurn(entry, deletedContentBlocks.get(entry.entryId)),
    }));
}
/** Analyze assistant turns after projecting a compactable transcript through deletion targets. */
export function analyzeCompactableAssistantTurns(transcript, targets) {
    const deletedEntryIds = new Set();
    const deletedContentBlocks = new Map();
    for (const target of targets) {
        if (target.kind === "entry") {
            deletedEntryIds.add(target.entryId);
            continue;
        }
        const blockIndexes = deletedContentBlocks.get(target.entryId) ?? new Set();
        blockIndexes.add(target.blockIndex);
        deletedContentBlocks.set(target.entryId, blockIndexes);
    }
    return {
        deletedEntryIds,
        deletedContentBlocks,
        turns: analyzeAssistantToolUseTurns(compactableTranscriptToAssistantTurnEntries(transcript, deletedEntryIds, deletedContentBlocks)),
    };
}
/**
 * Analyze chronological LLM-visible entries as logical assistant tool-use turns.
 * Callers adapt each context-visible user-like message into `startsNewTurn`;
 * tool results remain in the current turn. A trailing input-only turn is omitted,
 * intentionally leaving the preceding assistant turn historical rather than active.
 */
export function analyzeAssistantToolUseTurns(entries) {
    const groups = [];
    let current;
    for (const entry of entries) {
        if (entry.startsNewTurn || current === undefined) {
            current = { entryIds: [], assistantEntryIds: [], signedThinkingEntryIds: [] };
            groups.push(current);
        }
        current.entryIds.push(entry.entryId);
        if (entry.role !== "assistant")
            continue;
        current.assistantEntryIds.push(entry.entryId);
        if (entry.hasSignedThinking)
            current.signedThinkingEntryIds.push(entry.entryId);
    }
    const activeIndex = groups.length - 1;
    return groups
        .map((turn, index) => ({ ...turn, active: index === activeIndex }))
        .filter((turn) => turn.assistantEntryIds.length > 0);
}
//# sourceMappingURL=context-assistant-turns.js.map