export type AiUsageFeature = 'chat' | 'capture' | 'title' | 'caption' | 'event-summary' | 'event-extract';
export interface UsageEventInput {
    feature: AiUsageFeature;
    provider: string;
    modelId: string;
    /** Raw pi-ai Usage object ({ input, output, cacheRead, cacheWrite, totalTokens, cost: { total } }); parsed defensively. */
    usage?: unknown;
    userId?: number | null;
    sessionId?: string | null;
    durationMs?: number | null;
}
export interface UsageEventRow {
    id: number;
    ts: number;
    feature: string;
    provider: string;
    modelId: string;
    inputTokens: number;
    outputTokens: number;
    cacheReadTokens: number;
    cacheWriteTokens: number;
    totalTokens: number;
    /** NULL = usage/cost absent on the call; 0 = the model declared zero cost (e.g. credits gateway). */
    costUsd: number | null;
    userId: number | null;
    sessionId: string | null;
    durationMs: number | null;
}
export interface RollupRow {
    feature?: string;
    modelId?: string;
    day?: string;
    calls: number;
    inputTokens: number;
    outputTokens: number;
    cacheReadTokens: number;
    cacheWriteTokens: number;
    totalTokens: number;
    costUsd: number;
    /** cacheRead / (input + cacheRead); 0 when no input tokens. */
    cacheHitRate: number;
}
export type RollupGroupBy = 'feature' | 'model' | 'day';
interface RangeFilter {
    since?: number;
    until?: number;
    feature?: string;
}
export declare class AiUsageLedger {
    private db;
    private closed;
    private insertStmt;
    constructor(workspacePath: string);
    private runMigrations;
    /** Persist one inference call. NEVER throws — failure degrades to a one-time warning. */
    record(input: UsageEventInput): void;
    queryTotals(filter?: RangeFilter): RollupRow;
    queryRollup(opts: RangeFilter & {
        groupBy: RollupGroupBy[];
    }): RollupRow[];
    queryRecent(opts: RangeFilter & {
        limit: number;
        offset: number;
    }): {
        total: number;
        items: UsageEventRow[];
    };
    /** Delete rows older than the retention window. Returns the number deleted. */
    prune(maxAgeDays?: number): number;
    close(): void;
}
export declare function setAiUsageLedger(ledger: AiUsageLedger | null): void;
/** Fire-and-forget recording hook. No-op when no ledger is set; never throws. */
export declare function recordAiUsage(input: UsageEventInput): void;
export {};
