/**
 * trajectory-confidence — cumulative confidence tracker for agentic sessions.
 *
 * Reference: Agentic Confidence Calibration (ACC, arXiv:2601.15778).
 *
 * Motivation: per-step confidence fluctuations are noisy. Early low-confidence
 * decisions propagate and poison downstream steps, so the correct interrupt
 * signal is a DROP IN TRAJECTORY CONFIDENCE (the EWMA over recent steps), not
 * a single-step low score. Interrupting only on per-step lows misses cumulative
 * degradation; interrupting on trajectory lows catches compounding uncertainty
 * before it manifests as a hard failure.
 *
 * Design choices:
 * - EWMA (exponentially-weighted moving average) because it is O(1) memory and
 *   naturally up-weights recent observations without a hard window cut-off.
 * - Default alpha=0.3: moderate responsiveness. Higher alpha (e.g. 0.5) is more
 *   reactive; lower alpha (e.g. 0.1) is more inertial. Configurable per caller.
 * - Default tau=0.70: matches ACC paper recommendation for HITL trigger threshold.
 * - Require >=2 observations before recommending interrupt: avoids false positives
 *   on a single uncertain first step.
 *
 * Pure module: no I/O, no imports beyond this file. Stateless except the
 * mutable tracker instance. Thread-safe within a single-threaded JS runtime.
 */
// ─── Tracker ──────────────────────────────────────────────────────────────
/**
 * Tracks cumulative agent confidence across a session using an EWMA.
 *
 * Construct one tracker per session; call {@link observe} after each tool
 * call with the confidence score extracted from the tool's {@link RiskVector}
 * (or any other per-step confidence signal). Call
 * {@link isInterruptRecommended} to decide whether to route to HITL.
 *
 * @example
 * ```ts
 * import { TrajectoryConfidenceTracker } from "@vauban-org/agent-sdk";
 *
 * const tracker = new TrajectoryConfidenceTracker({ tau: 0.70 });
 *
 * for (const step of agentSteps) {
 *   const state = tracker.observe(step.riskVector.confidence);
 *   if (tracker.isInterruptRecommended()) {
 *     await hitlGate.requestApproval({ reason: "trajectory_confidence_low", state });
 *   }
 * }
 * ```
 */
export class TrajectoryConfidenceTracker {
    _alpha;
    _tau;
    _initial;
    _value;
    _observations;
    _peak;
    _trough;
    constructor(config) {
        const initial = config?.initial ?? 1.0;
        const alpha = config?.alpha ?? 0.3;
        const tau = config?.tau ?? 0.7;
        // Validate initial
        if (!Number.isFinite(initial)) {
            throw new RangeError(`TrajectoryConfidenceTracker: initial must be a finite number, got ${String(initial)}`);
        }
        // Validate alpha
        if (!Number.isFinite(alpha) || alpha <= 0 || alpha > 1) {
            throw new RangeError(`TrajectoryConfidenceTracker: alpha must be in (0, 1], got ${String(alpha)}`);
        }
        // Validate tau
        if (!Number.isFinite(tau) || tau < 0 || tau > 1) {
            throw new RangeError(`TrajectoryConfidenceTracker: tau must be in [0, 1], got ${String(tau)}`);
        }
        this._alpha = alpha;
        this._tau = tau;
        this._initial = Math.max(0, Math.min(1, initial));
        this._value = this._initial;
        this._observations = 0;
        this._peak = this._initial;
        this._trough = this._initial;
    }
    /**
     * Record a new per-step confidence score and update the EWMA.
     *
     * The input is clamped to [0, 1]. NaN and non-finite values throw.
     *
     * @param stepConfidence Per-step confidence in [0, 1]. Typically
     *   `riskVector.confidence` from the tool's {@link RiskVector}.
     * @returns The updated {@link TrajectoryConfidenceState}.
     */
    observe(stepConfidence) {
        if (!Number.isFinite(stepConfidence)) {
            throw new RangeError(`TrajectoryConfidenceTracker.observe: stepConfidence must be a finite number, got ${String(stepConfidence)}`);
        }
        const clamped = Math.max(0, Math.min(1, stepConfidence));
        this._value = this._alpha * clamped + (1 - this._alpha) * this._value;
        this._observations++;
        if (this._value > this._peak)
            this._peak = this._value;
        if (this._value < this._trough)
            this._trough = this._value;
        return this.snapshot();
    }
    /**
     * Return the current tracker state without recording a new observation.
     */
    snapshot() {
        return {
            value: this._value,
            observations: this._observations,
            peak: this._peak,
            trough: this._trough,
        };
    }
    /**
     * Returns true when both conditions hold:
     * 1. At least 2 observations have been recorded.
     * 2. The current trajectory confidence is strictly below tau.
     *
     * The 2-observation minimum prevents false positives on a single uncertain
     * first step (no trajectory context yet).
     */
    isInterruptRecommended() {
        return this._observations >= 2 && this._value < this._tau;
    }
    /**
     * Reset all state to the initial configuration values.
     * Useful on `/clear` or new sub-task boundaries within the same session.
     */
    reset() {
        this._value = this._initial;
        this._observations = 0;
        this._peak = this._initial;
        this._trough = this._initial;
    }
}
//# sourceMappingURL=trajectory-confidence.js.map