import type { Run, RunKind, TraceStore } from '../types/tracing.js'; /** * Hourly totals of runs, so a dashboard reads a few rows instead of every trace. * * Traces are the forensic record: everything about one run. A chart of cost or errors over a week * needs none of that, only sums, and reading 100,000 traces to draw it is how a dashboard gets slow * as the service grows. A rollup keeps one row per hour, kind, model, provider, and tenant, updated * as runs finish. */ /** What one rollup row is counted by. */ export interface RollupKey { /** The hour, as ISO-8601 truncated to the hour: `2026-10-04T13:00:00.000Z`. */ hour: string; /** The run kind. */ kind: RunKind; /** The run's name, for root runs, such as a graph or an assistant. Empty for others. */ name: string; /** The model, or an empty string. */ model: string; /** The provider, or an empty string. */ provider: string; /** `metadata.tenantId`, or an empty string. */ tenant: string; } /** The totals of one rollup row. */ export interface RollupTotals { /** Runs counted. */ runs: number; /** Of those, runs that failed. */ errors: number; /** Their cost. */ cost: number; /** Input tokens reported. */ inputTokens: number; /** Output tokens reported. */ outputTokens: number; /** Latency counts per bucket of `ROLLUP_LATENCY_BOUNDS_MS`, for percentiles without the runs. */ latency: number[]; } /** One rollup row: its key and its totals. */ export interface RollupRow extends RollupKey, RollupTotals { } /** Which rows to read. Every field narrows; the hour range is inclusive. */ export interface RollupQuery { /** The first hour, ISO-8601. */ since?: string; /** The last hour, ISO-8601. */ until?: string; /** Rows of these kinds. */ kind?: RunKind | RunKind[]; /** Rows of this model. */ model?: string; /** Rows of this provider. */ provider?: string; /** Rows of this tenant. */ tenant?: string; /** Rows of this name. */ name?: string; } /** Where rollup rows live. Adding to a row that does not exist creates it. */ export interface RollupStore { /** Adds totals to the row for `key`. */ add(key: RollupKey, totals: RollupTotals): Promise | void; /** Rows matching a query, oldest hour first. */ query(query?: RollupQuery): Promise | RollupRow[]; } /** * Upper bounds of the latency buckets, in milliseconds; a last bucket holds everything slower. A * percentile read from them is exact to the bucket, which is close enough for a chart. */ export declare const ROLLUP_LATENCY_BOUNDS_MS: readonly [10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000, 60000, 120000, 300000, 600000]; /** The latency at percentile `p`, 0 to 1, from rollup buckets: the bound of the bucket it falls in. */ export declare function rollupPercentile(latency: readonly number[], p: number): number | undefined; /** Rows summed across their keys: a total over a day, a model, or a whole range. */ export declare function sumRollups(rows: readonly RollupTotals[]): RollupTotals; /** Rollup rows in process memory. Rows are small, so a year of hourly rows for a few models fits easily. */ export declare class MemoryRollupStore implements RollupStore { private readonly rows; /** Adds totals to a row. */ add(key: RollupKey, totals: RollupTotals): void; /** Rows matching a query, oldest hour first. */ query(query?: RollupQuery): RollupRow[]; /** Rows held. */ size(): number; } /** Options for `rollupTraceStore()`. */ export interface RollupTraceStoreOptions { /** Which finished runs are counted. Defaults to every root run, and every model and embedding run. */ include?: (run: Run) => boolean; } /** * Wraps a trace store so every run that finishes is also added to a rollup. * * Reads go to the wrapped store unchanged. A run is counted once, when it is saved finished; a save * of a run still running, which an `incremental` tracer makes, is not counted, and neither is * feedback added later. */ export declare function rollupTraceStore(store: TraceStore, rollups: RollupStore, options?: RollupTraceStoreOptions): TraceStore; /** The rollup row a finished run belongs to. */ export declare function rollupKeyOf(run: Run): RollupKey;