function getCrypto() {
    const candidate = globalThis.crypto;
    if (!candidate || typeof candidate.randomUUID !== 'function') {
        throw new Error('Embedded runtime requires globalThis.crypto.randomUUID (Web Crypto API or Node 19+).');
    }
    return candidate;
}
function generateId(usedIds) {
    const c = getCrypto();
    for (let i = 0; i < 100; i++) {
        const id = c.randomUUID().slice(0, 8);
        if (!usedIds.has(id)) {
            usedIds.add(id);
            return id;
        }
    }
    const full = c.randomUUID();
    usedIds.add(full);
    return full;
}
/** Append-only `SessionEntry` builder. Maintains the conversational leaf id. */
export class EmbeddedSessionEntryBuilder {
    leafId = null;
    reservedIds = new Set();
    usedIds = new Set();
    seedFromEntries(entries) {
        // Reseeding means the agent state was replaced; pending reservations no longer apply.
        this.reservedIds.clear();
        this.usedIds.clear();
        this.leafId = null;
        for (const entry of entries) {
            this.usedIds.add(entry.id);
            if (entry.type !== 'llm_call') {
                this.leafId = entry.id;
            }
        }
    }
    getLeafId() {
        return this.leafId;
    }
    reserveAssistantMessageEntryId() {
        const id = generateId(this.usedIds);
        this.reservedIds.add(id);
        return id;
    }
    nextBase(timestampOverride, idOverride) {
        const usesReservedId = idOverride !== undefined && idOverride.length > 0 && this.reservedIds.delete(idOverride);
        if (idOverride !== undefined && idOverride.length > 0 && !usesReservedId) {
            if (this.usedIds.has(idOverride)) {
                throw new Error(`Session entry id override '${idOverride}' has already been used.`);
            }
        }
        const usesFreshOverride = idOverride !== undefined && idOverride.length > 0 && !this.usedIds.has(idOverride);
        const id = usesReservedId || usesFreshOverride ? idOverride : generateId(this.usedIds);
        if (usesFreshOverride) {
            this.usedIds.add(id);
        }
        const parentId = this.leafId;
        const timestamp = timestampOverride ?? new Date().toISOString();
        this.leafId = id;
        return { id, parentId, timestamp };
    }
    nextTraceBase() {
        return {
            id: generateId(this.usedIds),
            parentId: this.leafId,
            timestamp: new Date().toISOString()
        };
    }
    buildMessage(message, durationMs, idOverride) {
        return {
            ...this.nextBase(undefined, idOverride),
            type: 'message',
            message,
            durationMs
        };
    }
    buildCustomMessage(customType, content, display, details, timestamp, idOverride) {
        return {
            ...this.nextBase(timestamp, idOverride),
            type: 'custom_message',
            customType,
            content,
            display,
            details
        };
    }
    buildModelChange(provider, modelId) {
        return { ...this.nextBase(), type: 'model_change', provider, modelId };
    }
    buildThinkingLevelChange(thinkingLevel) {
        return { ...this.nextBase(), type: 'thinking_level_change', thinkingLevel };
    }
    buildTurnStart(turnIndex) {
        return { ...this.nextBase(), type: 'turn_start', turnIndex };
    }
    buildTurnEnd(turnIndex, durationMs) {
        return { ...this.nextBase(), type: 'turn_end', turnIndex, durationMs };
    }
    buildSystemPrompt(content) {
        return { ...this.nextBase(), type: 'system_prompt', content };
    }
    buildToolDefinitions(tools) {
        return { ...this.nextBase(), type: 'tool_definitions', tools: [...tools] };
    }
    buildLlmCall(input) {
        return { ...this.nextTraceBase(), type: 'llm_call', ...input };
    }
    buildCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
        return {
            ...this.nextBase(),
            type: 'compaction',
            summary,
            firstKeptEntryId,
            tokensBefore,
            details,
            fromHook
        };
    }
}
//# sourceMappingURL=session-entry-builder.js.map