export interface SessionTrendData { sessionId: string; project: string | null; model: string | null; tokensInput: number; tokensOutput: number; tokensCacheRead: number; tokensCacheWrite: number; costUsd: number; resourceHealth: number | null; sessionEfficiency: number | null; toolCalls: number; compactions: number; mode: string | null; durationSeconds: number; } export declare class TrendsStore { private db; private dbPath; constructor(dataDir: string); private connect; /** * Log a realized-savings event to the savings_events table. * * This is the TypeScript equivalent of Python's `_log_savings_event`. * Model is not known at checkpoint-inject time, so cost_saved_usd is * priced at the Sonnet input fallback rate — same behaviour as Python's * resolver when the session model cannot be determined. * * Guards: * - tokensSaved <= 0 → no-op (never credit zero or negative) * - Any exception → silently swallowed (must never break the caller) */ logSavingsEvent(eventType: string, tokensSaved: number, sessionId: string | null, detail: string | null, model?: string | null): void; /** * True if a savings event of the given type for the given target session was * already credited within the specified window. * * Prevents double-counting when a user opens the same cold session from two * different fresh sessions (cross-session dedup). Mirrors Python's * `_resume_lean_already_credited` which dedups on the TARGET session_uuid. * * Best-effort: returns false on any error so we never block savings accounting. */ hasRecentSavingsEvent(eventType: string, sessionId: string, withinMs: number): boolean; /** * Returns the tokens_cache_write value from session_log for the given session, * or 0 if not found / unavailable. * * This is the closest opencode equivalent to Python's * `cache_create_1h_tokens + cache_create_5m_tokens` — the real cold-rewrite * cost that a lean resume avoids. Used by logResumeLeanSavings for the * primary avoided-cost estimate. * * OVERCOUNT VERIFICATION: tokens_cache_write is populated from * `t?.cache?.write` in the message.updated handler, which maps directly to * OpenCode SDK's `Message.tokens.cache.write` field. Per the SDK type definition * (types.gen.d.ts L120), `cache.write` is the cache CREATION count only — * distinct from `cache.read` (cheap hits). A `--resume` cold rewrite ONLY incurs * write (creation) cost; read hits on an established cache do NOT re-pay write cost. * Therefore tokens_cache_write is write-only and does NOT conflate cache-read tokens. * No discount needed: this column is the correct, non-overcounting avoided-cost metric. * * Best-effort: returns 0 on any error. */ getSessionCacheWrite(sessionId: string): number; /** * Summarize compression/volume-reduction savings_events over the window for * the realized-savings compression add-back (pool #3). * * Mirrors Python's `_get_savings_summary`: the returned `totalCostSavedUsd` is * the MEASURED compression floor with estimated-tier categories relocated OUT * (setup_optimization, mcp_cap, hint_followed) and tool_archive re-expansions * NETTED against tool_archive (a re-popped result didn't stay collapsed, so its * eager credit is reversed, floored at 0). What remains is the directly-metered * removed-token dollars the old way would have re-read. * * Best-effort: returns zeros on any error (never throws). `now` is injectable * for testing. */ getCompressionSavings(days?: number, now?: number): { totalTokensSaved: number; totalCostSavedUsd: number; totalEvents: number; }; /** * Sum the ESTIMATED verbosity_steer savings (cost_saved_usd) over the window. * These are estimated output-token reductions from lean-output conciseness nudges — * the trigger is observed but the magnitude is not metered. Mirrors measure.py * `_get_savings_summary` which relocates verbosity_steer to the estimated tier. * The caller reprices to the baseline OUTPUT rate and adds as a separate pool. * * Best-effort: returns 0 on any error (never throws). `now` is injectable. */ getVerbositySavings(days?: number, now?: number): number; close(): void; recordSession(data: SessionTrendData): void; getRecentSessions(days?: number): Array>; /** All sessions ever recorded, oldest-first. Used to establish the realized- * savings baseline (the earliest stable usage window). */ getAllSessions(): Array>; getDailyStats(days?: number): Array>; } //# sourceMappingURL=trends.d.ts.map