SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
2.1 KB · 48 lines typescript
Raw Blame History
1import type { ModelPricing, Usage } from "./types";23export interface CostBreakdown {4  inputUsd: number;5  cachedInputUsd: number;6  outputUsd: number;7  totalUsd: number;8  /** false when pricing is missing → totalUsd is 0 and should be shown as "n/a". */9  known: boolean;10}1112/**13 * Estimate the cost of one request. Reasoning tokens are billed as output tokens by14 * every current provider; cached input tokens are billed at the cached rate when known15 * (otherwise at the normal input rate). Long-context tiers apply when the prompt exceeds16 * the provider's threshold.17 */18export function estimateCost(usage: Usage | undefined | null, pricing: ModelPricing | null | undefined): CostBreakdown {19  if (!usage || !pricing || (pricing.inputPerMillion === undefined && pricing.outputPerMillion === undefined)) {20    return { inputUsd: 0, cachedInputUsd: 0, outputUsd: 0, totalUsd: 0, known: false };21  }22  let inRate = pricing.inputPerMillion ?? 0;23  let outRate = pricing.outputPerMillion ?? 0;24  let cachedRate = pricing.cachedInputPerMillion ?? inRate;25  if (pricing.longContext && usage.inputTokens > pricing.longContext.thresholdTokens) {26    inRate = pricing.longContext.inputPerMillion ?? inRate;27    outRate = pricing.longContext.outputPerMillion ?? outRate;28    cachedRate = pricing.longContext.cachedInputPerMillion ?? cachedRate;29  }30  const cached = Math.min(usage.cachedInputTokens ?? 0, usage.inputTokens);31  const uncached = Math.max(0, usage.inputTokens - cached);32  const inputUsd = (uncached / 1_000_000) * inRate;33  const cachedInputUsd = (cached / 1_000_000) * cachedRate;34  const outputUsd = (usage.outputTokens / 1_000_000) * outRate;35  const totalUsd = inputUsd + cachedInputUsd + outputUsd;36  return { inputUsd, cachedInputUsd, outputUsd, totalUsd: round(totalUsd), known: true };37}3839function round(n: number): number {40  return Math.round(n * 1e8) / 1e8;41}4243export function tokensPerSecond(outputTokens: number | undefined, latencyMs: number | undefined, ttftMs?: number | undefined): number | null {44  if (!outputTokens || !latencyMs) return null;45  const gen = Math.max(1, latencyMs - (ttftMs ?? 0));46  return Math.round((outputTokens / gen) * 1000 * 10) / 10;47}48