export interface SavingsBreakdownItem { key: string; label: string; monthlyUsd: number; } /** Progress toward a frozen baseline (displayed when ready=false). */ export interface BaselineBuilding { /** Sessions collected in the early window so far. */ sessionsInWindow: number; /** Sessions needed before the baseline locks in. */ sessionsNeeded: number; /** Length of the early-window in days (matches BASELINE_EARLY_WINDOW_DAYS). */ earlyWindowDays: number; /** Calendar days until the early window closes (0 once it has closed). */ daysLeft: number; /** ISO date of the user's very first tracked session. */ firstDate: string; } export interface RealizedSavings { ready: boolean; status: string; monthlySavingsUsd: number; /** Monthly $ at the user's CURRENT model mix + cache pattern ("now" arm). */ actualMonthlyUsd: number; /** Monthly $ at the user's BASELINE mix + cache pattern ("the old way" arm). */ counterfactualMonthlyUsd: number; /** Transformation as a fraction: (counterfactual − actual) / counterfactual. */ transformationPct: number; /** * Metered compression floor — tokens TO removed from context, repriced to the * baseline input mix. This is the PROVEN subset of compressionAddback and is * NEVER summed into the transformation headline. Render it as a separate card. */ compressionMeasuredUsd: number; /** * RAW metered compression $ over the lookback window, BEFORE the 30/days * monthly scaling that compressionMeasuredUsd carries. The dashboard's * young-install guard renders this as the cumulative "so far" figure. * Same INVARIANT as compressionMeasuredUsd: never summed into the headline. */ compressionMeasuredWindowUsd: number; /** * RAW metered compression TOKENS saved over the lookback window (the * `totalTokensSaved` from TrendsStore.getCompressionSavings). Window-summed, * NOT monthly-scaled. Exposed so the Tokens Saved card can show a * token-denominated SAVED figure alongside the SPENT model-mix token total * (both share the same window). Never summed into any $ headline. */ compressionMeasuredWindowTokens: number; /** Estimated verbosity-steer $ before the baseline-output reprice. */ verbosityMeasuredUsd: number; /** * RAW estimated verbosity-steer $ over the lookback window, BEFORE the * 30/days monthly scaling that verbosityMeasuredUsd carries. The dashboard's * action-savings card renders this as the period-total estimated figure * (the actual selected-period savings_events sum), never a monthly run-rate. * Same INVARIANT as compressionMeasuredWindowUsd: never summed into the * transformation headline. */ verbosityMeasuredWindowUsd: number; /** Repriced verbosity-steer $ (estimated output reduction at baseline mix). */ verbosityTransformationUsd: number; savingsPerSession: number; beforeCostPerSession: number; afterCostPerSession: number; /** Baseline session's native cache-read fraction (0..1) -- explains why identical * tokens+mix can price differently across the arms (the cache-hit pricing contradiction). */ beforeCacheHit: number; /** Current pool cache-hit rate (0..1). */ afterCacheHit: number; sessionsPerMonth: number; /** * Days of post-baseline history behind the monthly projection (floor of the * after-window span, clamped >= 1). Drives the dashboard's young-install * guard: < 30 -> show the measured cumulative ("so far") instead of the * "/mo" run-rate. 0 when not ready. */ trackedDays: number; beforeMixLabel: string; afterMixLabel: string; cumulativeSavedUsd: number; installDate: string | null; breakdown: SavingsBreakdownItem[]; /** * Populated when ready=false and the user has at least one session. Gives the * dashboard enough data to render a progress card + bar instead of a dead end. * null when there are zero sessions (no installDate yet). */ baselineBuilding: BaselineBuilding | null; } /** * Compute realized savings via the current-volume counterfactual. * `now` injectable for testing. * `rowsOverride` bypasses the DB (raw session_log rows) for tests. * `compressionOverride` injects the measured compression dollars when the DB * is bypassed (rowsOverride present); default 0. * `compressionTokensOverride` injects the measured compression TOKENS saved * over the window when the DB is bypassed; default 0. * Plumbs through to `compressionMeasuredWindowTokens`. */ export declare function computeRealizedSavings(dataDir: string, days?: number, now?: number, rowsOverride?: Array>, compressionOverride?: number, compressionTokensOverride?: number): RealizedSavings; //# sourceMappingURL=savings.d.ts.map