import type { AggregateUsage, AIProviderType } from '@genesislcap/foundation-ai';
/** A model used during a recorded cost session. */
export interface CostSessionModelEntry {
    model: string;
    /** Vendor id from `getStatus()` (e.g. `'anthropic'`, `'gemini'`). */
    provider?: AIProviderType;
}
/** Persisted usage record for one project's assistant work. */
export interface CostSessionRecord {
    id: string;
    /**
     * Stable identity of the work this row stands for — the assistant's session key
     * (a project id, for hosts that key sessions per project). The upsert key: a row
     * is one project's lifetime usage, so re-reporting the same key REPLACES the row
     * rather than adding another.
     */
    projectKey: string;
    title: string;
    /**
     * ISO-8601 timestamp of the most recent usage recorded for this row.
     *
     * Named for what it is: the row is upserted as spend accrues, so this moves. It is
     * NOT an end time — a row has no terminal state, because a project can always be
     * worked on again.
     */
    updatedAt: string;
    /**
     * Cost plus the four token buckets — the same shape the live session tile renders, so
     * a history row can show the identical breakdown instead of a lone merged total that
     * cannot explain a large token count at a small cost.
     *
     * This is the project's **lifetime** usage: `banked` plus whatever the live transcript
     * currently proves.
     */
    usage: AggregateUsage;
    /**
     * Spend that predates the current transcript, and so cannot be re-derived from it.
     *
     * Without this a row could only ever report what the open transcript proves. That is
     * fine when the transcript is restored on load (it *is* the project's history), but
     * where it starts empty every refresh the row would be rewritten downwards on the next
     * turn and the project's earlier spend lost. Banking it keeps `usage` a lifetime figure
     * in both cases.
     *
     * Deliberately part of the row rather than element state: two assistant instances (a
     * docked bubble and a popped-out panel) share one session, and both write this row. A
     * value derived from the row keeps every write idempotent, whereas an element-held
     * accumulator would be applied once per instance.
     *
     * Optional: rows written before this existed have none, which reads as "nothing banked".
     */
    banked?: AggregateUsage;
    models: CostSessionModelEntry[];
}
/** localStorage key for a host-scoped cost history list. */
export declare function costHistoryStorageKey(scope: string): string;
/**
 * Load persisted cost sessions for a scope, in whatever order they were stored — this applies no
 * ordering of its own. Display order is the caller's business; see `sortRecordsByRecency`.
 */
export declare function loadCostSessionHistory(scope: string): CostSessionRecord[];
/** Replace the persisted list for a scope. */
export declare function saveCostSessionHistory(scope: string, records: CostSessionRecord[]): void;
/**
 * Pure upsert — `records` with `record` replacing any row sharing its `projectKey`, or
 * prepended when there is none.
 *
 * An upsert, not an append, because a row stands for a **project's lifetime usage** rather
 * than a visit to it. Appending cut a fresh row per page-hide, so one project accumulated
 * a stack of near-identical rows and its spend was counted once per refresh by anything
 * summing the list.
 *
 * The resulting array order is incidental — it is insertion order, so a project returned to
 * stays where it first landed. Do not read it as recency; `sortRecordsByRecency` is what the
 * Usage tab renders through.
 *
 * Storage-agnostic on purpose: the same merge serves the synchronous `localStorage` path
 * and the async provider-backed one, so the two can never drift on what "upsert" means.
 * The caller owns persistence — see the assistant's `persistCostHistory`.
 */
export declare function upsertRecord(records: readonly CostSessionRecord[], record: CostSessionRecord): CostSessionRecord[];
/**
 * Rows most-recently-worked-on first, as a new array.
 *
 * Applied at read time rather than baked into the stored order, so it covers rows that came from
 * a host provider as well as from `localStorage`, and so no write path has to maintain it.
 *
 * `updatedAt` is ISO-8601, which sorts lexicographically — no date parsing, and no dependence on
 * the strings being valid dates. Sorting by it rather than by insertion order is what makes the
 * list track use: the active project moves to the top on its first upsert and stays there, since
 * its row is rewritten on every transcript change.
 */
export declare function sortRecordsByRecency(records: readonly CostSessionRecord[]): CostSessionRecord[];
/**
 * The spend a project's next row must carry over from before its current transcript.
 *
 * `transcriptIsAuthoritative` means the open transcript already accounts for this project's
 * history — true exactly when a session snapshot is restored on load. The two branches are
 * not interchangeable, and picking the wrong one is silently destructive:
 *
 * - Authoritative: carry the previous row's own `banked` forward. Taking `usage` instead would
 *   re-add the restored history on every reload, the compounding double-count this replaced.
 * - Not authoritative: the whole previous total becomes banked, because nothing in the fresh
 *   transcript accounts for it. Taking `banked` instead would rewrite the row down to the
 *   current page-load and drop the project's earlier spend.
 *
 * Note both branches are idempotent — the result never includes the current transcript — which
 * is what lets two assistant instances sharing a session write the same row.
 */
export declare function resolveBankedUsage(existing: CostSessionRecord | undefined, transcriptIsAuthoritative: boolean): AggregateUsage;
/** Clear all persisted records for a scope. */
export declare function clearCostSessionHistory(scope: string): void;
/** Display date for a history row (e.g. "Jun 14, 2026"). */
export declare function formatCostSessionDate(iso: string): string;
//# sourceMappingURL=cost-session-history.d.ts.map