"use strict";
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024-2026 Gracker (Chris)
// This file is part of SmartPerfetto. See LICENSE for details.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TRACE_AGENT_STATE_VERSION = void 0;
exports.createInitialTraceAgentState = createInitialTraceAgentState;
exports.migrateTraceAgentState = migrateTraceAgentState;
exports.summarizeTraceAgentState = summarizeTraceAgentState;
/**
 * TraceAgentState (v1)
 *
 * A single-source-of-truth state for goal-driven, experiment-based analysis.
 *
 * This file only defines the durable state shape and deterministic helpers.
 * The actual hypothesis/evidence/experiment loop will be implemented incrementally.
 *
 * Design goals:
 * - JSON-safe (no BigInt/Map/Set)
 * - Versioned + migratable
 * - Strictly scoped to a single (sessionId, traceId)
 */
const uuid_1 = require("../../utils/uuid");
// =============================================================================
// Versioning
// =============================================================================
exports.TRACE_AGENT_STATE_VERSION = 1;
// =============================================================================
// Creation / Migration
// =============================================================================
function createInitialTraceAgentState(params) {
    const now = typeof params.now === 'number' ? params.now : Date.now();
    return {
        version: exports.TRACE_AGENT_STATE_VERSION,
        sessionId: params.sessionId,
        traceId: params.traceId,
        createdAt: now,
        updatedAt: now,
        goal: { userGoal: params.userGoal },
        preferences: {
            maxExperimentsPerTurn: 3,
            defaultLoopMode: 'hypothesis_experiment',
            defaultResponseView: 'conclusion_evidence',
            language: 'zh',
            qualityFirst: true,
        },
        coverage: {
            entities: { frames: [], sessions: [] },
            timeRanges: [],
            domains: [],
            packages: [],
        },
        turnLog: [],
        hypotheses: [],
        evidence: [],
        experiments: [],
        contradictions: [],
    };
}
function migrateTraceAgentState(snapshot, expected) {
    // If invalid, return a fresh state.
    if (!snapshot || typeof snapshot !== 'object') {
        return createInitialTraceAgentState({
            sessionId: expected.sessionId,
            traceId: expected.traceId,
            userGoal: '',
        });
    }
    // Trace scoping guard: never accept cross-trace state.
    const snapSessionId = String(snapshot.sessionId || '');
    const snapTraceId = String(snapshot.traceId || '');
    if (snapSessionId && snapSessionId !== expected.sessionId) {
        return createInitialTraceAgentState({
            sessionId: expected.sessionId,
            traceId: expected.traceId,
            userGoal: '',
        });
    }
    if (snapTraceId && snapTraceId !== expected.traceId) {
        return createInitialTraceAgentState({
            sessionId: expected.sessionId,
            traceId: expected.traceId,
            userGoal: '',
        });
    }
    const version = Number(snapshot.version || 0);
    // v1: normalize and fill defaults
    if (version === 1) {
        const now = Date.now();
        const state = {
            version: 1,
            sessionId: expected.sessionId,
            traceId: expected.traceId,
            createdAt: Number(snapshot.createdAt || now),
            updatedAt: Number(snapshot.updatedAt || now),
            goal: {
                userGoal: String(snapshot.goal?.userGoal || ''),
                normalizedGoal: snapshot.goal?.normalizedGoal ? String(snapshot.goal.normalizedGoal) : undefined,
                doneWhen: Array.isArray(snapshot.goal?.doneWhen) ? snapshot.goal.doneWhen.map(String) : undefined,
                stopWhen: Array.isArray(snapshot.goal?.stopWhen) ? snapshot.goal.stopWhen.map(String) : undefined,
            },
            preferences: {
                maxExperimentsPerTurn: Number(snapshot.preferences?.maxExperimentsPerTurn || 3),
                defaultLoopMode: 'hypothesis_experiment',
                defaultResponseView: 'conclusion_evidence',
                language: 'zh',
                qualityFirst: true,
            },
            coverage: {
                entities: {
                    frames: Array.isArray(snapshot.coverage?.entities?.frames) ? snapshot.coverage.entities.frames.map(String) : [],
                    sessions: Array.isArray(snapshot.coverage?.entities?.sessions) ? snapshot.coverage.entities.sessions.map(String) : [],
                },
                timeRanges: Array.isArray(snapshot.coverage?.timeRanges)
                    ? snapshot.coverage.timeRanges
                        .map((r) => ({ start: String(r?.start || ''), end: String(r?.end || '') }))
                        .filter((r) => r.start && r.end)
                    : [],
                domains: Array.isArray(snapshot.coverage?.domains) ? snapshot.coverage.domains.map(String) : [],
                packages: Array.isArray(snapshot.coverage?.packages) ? snapshot.coverage.packages.map(String) : [],
            },
            turnLog: Array.isArray(snapshot.turnLog)
                ? snapshot.turnLog.map((t) => ({
                    id: String(t?.id || (0, uuid_1.uuidv4)()),
                    turnIndex: Number(t?.turnIndex || 0),
                    timestamp: Number(t?.timestamp || now),
                    query: String(t?.query || ''),
                    followUpType: t?.followUpType ? String(t.followUpType) : undefined,
                    intentPrimaryGoal: t?.intentPrimaryGoal ? String(t.intentPrimaryGoal) : undefined,
                    conclusionSummary: t?.conclusionSummary ? String(t.conclusionSummary) : undefined,
                    confidence: typeof t?.confidence === 'number' ? t.confidence : undefined,
                }))
                : [],
            hypotheses: Array.isArray(snapshot.hypotheses) ? snapshot.hypotheses : [],
            evidence: Array.isArray(snapshot.evidence) ? snapshot.evidence : [],
            experiments: Array.isArray(snapshot.experiments) ? snapshot.experiments : [],
            contradictions: Array.isArray(snapshot.contradictions) ? snapshot.contradictions : [],
        };
        // Ensure preferences respect current defaults (user-configured fields may be added later).
        state.preferences.maxExperimentsPerTurn = clampInt(state.preferences.maxExperimentsPerTurn, 1, 10, 3);
        state.updatedAt = now;
        return state;
    }
    // Unknown/older version: start fresh (future: add migrations here).
    return createInitialTraceAgentState({
        sessionId: expected.sessionId,
        traceId: expected.traceId,
        userGoal: '',
    });
}
// =============================================================================
// Utilities
// =============================================================================
function summarizeTraceAgentState(state) {
    return {
        version: state.version,
        goal: state.goal.normalizedGoal || state.goal.userGoal || '',
        maxExperimentsPerTurn: state.preferences.maxExperimentsPerTurn,
        turns: Array.isArray(state.turnLog) ? state.turnLog.length : 0,
        updatedAt: state.updatedAt,
    };
}
function clampInt(value, min, max, fallback) {
    if (!Number.isFinite(value))
        return fallback;
    const v = Math.floor(value);
    if (v < min)
        return min;
    if (v > max)
        return max;
    return v;
}
//# sourceMappingURL=traceAgentState.js.map