import { type UsageMetricsAccessInput, type UsageMetricsScope } from "./metrics-store.js"; /** Run insights are always read for one app, never across all apps. */ type RunAccessInput = UsageMetricsAccessInput & { app: string; }; /** Spend split by how the provider billed each token, in cents. */ export interface UsageCostBreakdown { cacheReadCents: number; cacheWriteCents: number; uncachedInputCents: number; outputCents: number; /** Recorded spend for the rows; the category splits above are token-priced estimates. */ totalCents: number; /** The same tokens priced at list rates, so it is comparable to `noCacheCents`. */ estimatedCents: number; /** What the same tokens would have cost with no prompt caching. */ noCacheCents: number; } export interface UsageTokenTotals { inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; } export type UsageScoreSource = "heuristic" | "judge" | "human"; export interface UsageRunScore { source: UsageScoreSource; criteria: string; score: number; reasoning: string | null; } export interface UsageRunTool { name: string; calls: number; failed: number; error: string | null; } /** * The context was re-sent in full when the cache could have been re-used. * `tool-lookup`: new tools were loaded; `prefix-changed`: something else at * the start of the prompt changed. */ export type UsageRestartCause = "tool-lookup" | "prefix-changed"; export interface UsageRunRestarts { count: number; cents: number; byCause: Record; } export interface UsageRunListItem { runId: string; threadId: string | null; createdAt: number; ownerEmail: string; label: string; model: string; prompt: string | null; /** `unknown` when the trace was never written or has been cleaned up. */ status: "success" | "error" | "unknown"; tokens: UsageTokenTotals; cost: UsageCostBreakdown; modelCalls: number; tools: UsageRunTool[]; restarts: UsageRunRestarts; /** Tool calls that overlapped another call in the same step, and the time that saved. */ parallel: { calls: number; savedMs: number; }; /** Failed tool calls in a run that still finished. */ recoveredErrors: number; durationMs: number | null; feedback: "up" | "down" | null; } export interface UsagePeriodTotals { runs: number; tokens: UsageTokenTotals; cost: UsageCostBreakdown; } export interface UsageInsights { sinceDays: number; current: UsagePeriodTotals; previous: UsagePeriodTotals; runs: UsageRunListItem[]; } export interface UsageRunToolCall { name: string; startedAt: number; durationMs: number; status: string; errorMessage: string | null; } /** One model call and the tools it asked for. */ export interface UsageRunTurn { index: number; model: string; durationMs: number; tokens: UsageTokenTotals; cost: UsageCostBreakdown; status: string; /** Set only when re-sending the context cost a meaningful amount. */ restart: { cause: UsageRestartCause; cents: number; } | null; /** The provider cache had expired after an idle gap; expected, not a fault. */ cacheExpired: boolean; toolCalls: UsageRunToolCall[]; } export interface UsageRunDetail extends UsageRunListItem { billing: { providerCostUsd: number | null; providerCostSource: "reported" | "estimated" | "mixed" | null; builderCredits: number | null; builderCreditsSource: "reported" | "estimated" | "mixed" | null; incomplete: boolean; }; reply: string | null; turns: UsageRunTurn[]; scores: UsageRunScore[]; } export declare function getUsageInsights(input: { sinceDays?: number; scope?: UsageMetricsScope; userEmail?: string | null; }, accessInput: RunAccessInput): Promise; export declare function getUsageRun(input: { runId: string; scope?: UsageMetricsScope; userEmail?: string | null; }, accessInput: RunAccessInput): Promise; export {};