/** * kosha-discovery — Zero-dependency token usage + cost tally primitives. * * Pure functions only: no fs/network/process imports, so this module is * safe to import in a browser, a Workers/edge runtime, or any bundle that * cares about staying isomorphic. Node-only concerns (ledger I/O, budget * gates) live in ./cost.js instead — import that separately if you need them. * * Mirrors the normalize → resolve pricing → estimate → tally shape so * consumers (tokmeter, Runic, a browser cost calculator) don't each * reinvent cross-provider usage normalization or rate math. * @module */ import type { ModelPricing } from "./types.js"; /** Canonical, provider-agnostic token usage shape. */ export interface TokenUsage { inputTokens: number; outputTokens: number; /** Cache-read ("hit") input tokens, if the provider reports them separately. */ cachedInputTokens?: number; /** Cache-write input tokens (Anthropic-style cache creation), if reported. */ cacheWriteTokens?: number; /** * The share of `cacheWriteTokens` written with a 1-hour TTL, when the * provider breaks the lifetime down. A SUBSET of `cacheWriteTokens`, never * an additional bucket — it changes which rate applies, not how many tokens * were written. */ cacheWrite1hTokens?: number; /** Reasoning/thinking output tokens, if the provider bills or reports them separately. */ reasoningTokens?: number; } /** `TokenUsage` plus a derived total. Returned by `normalizeTokenUsage`. */ export interface NormalizedTokenUsage extends TokenUsage { totalTokens: number; } /** * Normalize a raw, provider-shaped usage object (OpenAI `prompt_tokens` / * `completion_tokens`, Anthropic `input_tokens` / `output_tokens` / * `cache_read_input_tokens`, etc.) into the canonical `TokenUsage` shape. * * Returns `null` when neither an input nor output token count can be found — * that's "not a usage object," not "zero usage." */ export declare function normalizeTokenUsage(raw: Record | null | undefined): NormalizedTokenUsage | null; /** USD breakdown returned by `estimateUsdCost`. */ export interface UsdCostBreakdown { inputUsd: number; outputUsd: number; cachedInputUsd: number; cacheWriteUsd: number; reasoningUsd: number; totalUsd: number; } /** * Estimate USD cost for one usage record against one model's pricing. * Reasoning tokens price against `reasoningOutputPerMillion` when the model * has it, falling back to the plain output rate otherwise — most providers * that report reasoning tokens separately still bill them at the output rate. */ export declare function estimateUsdCost(usage: TokenUsage, pricing: ModelPricing): UsdCostBreakdown; /** One call record as consumed by `tallyCosts`. */ export interface TallyCall { modelId: string; usage: TokenUsage; } /** Per-model subtotal within a `tallyCosts` result. */ export interface TallyModelSubtotal extends UsdCostBreakdown { modelId: string; calls: number; usage: TokenUsage; } /** Aggregate result of `tallyCosts`. */ export interface TallyResult extends UsdCostBreakdown { calls: number; byModel: TallyModelSubtotal[]; /** modelIds `resolvePricing` returned `null` for — cost for these is excluded from the totals. */ unpriced: string[]; } /** * Aggregate USD cost and token totals across heterogeneous calls, grouped by * model. Pricing is resolved per model via the injected `resolvePricing` * callback so the caller decides the source (kosha's live registry, a * static map, a cached snapshot) — this function does no I/O of its own. */ export declare function tallyCosts(calls: readonly TallyCall[], resolvePricing: (modelId: string) => ModelPricing | null | undefined): TallyResult; //# sourceMappingURL=tally.d.ts.map