Skip to content
reaatechREAATECH

@reaatech/otel-cost-exporter-calculator

pending npm

Calculates GenAI token costs in USD by normalizing model names and processing token counts from OpenTelemetry semantic convention spans. It provides a `CostCalculator` class that integrates with a pricing table, an LRU cache, and a model normalizer to handle complex pricing logic like prompt caching and provider-specific model variants.

@reaatech/otel-cost-exporter-calculator

npm version License: MIT CI

Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.

LLM token cost calculator with model name normalization, provider detection, and LRU pricing caching. Converts raw token counts from GenAI semantic convention spans into per-model cost breakdowns in USD.

Installation

terminal
npm install @reaatech/otel-cost-exporter-calculator
# or
pnpm add @reaatech/otel-cost-exporter-calculator

Feature Overview

  • Cost calculator engine — full CostCalculator with dependency injection: pricing provider, LRU cache, model normalizer, and optional default price
  • Pure calculation functioncalculateCost() is a side-effect-free function taking a PriceEntry and token counts, returning a CostBreakdown
  • Model name normalization — strips provider prefixes (openai/gpt-4), version suffixes (-v2, :latest), regional variants (-us, -eu), FT prefixes, and resolves common aliases (gpt4gpt-4)
  • Provider detection — infers provider from model name when gen_ai.system is missing (e.g., gpt-*openai, claude-*anthropic)
  • LRU pricing cache — configurable LRU cache with hit/miss statistics; minimizes repeated pricing table lookups in high-throughput pipelines
  • Prompt caching costs — separate tracking for cache read and cache creation token costs (Anthropic)
  • Billable input token calculation — automatically subtracts cache read tokens from input tokens before pricing
  • Default price fallback — optionally assign a USD-per-1M-token default for unknown models
  • Dual ESM/CJS output — works with import and require

Quick Start

typescript
import {
  createCostCalculator,
  createModelNormalizer,
  createPricingCache,
} from "@reaatech/otel-cost-exporter-calculator";
import { loadPricingData, createPricingTable } from "@reaatech/otel-cost-exporter-pricing";
 
// Set up dependencies
const data = await loadPricingData();
const pricing = createPricingTable(data);
const cache = createPricingCache();
const normalizer = createModelNormalizer();
 
const calculator = createCostCalculator({
  pricing,
  cache,
  normalizer,
  defaultPrice: 2.0,    // USD per 1M tokens for unknown models
});
 
// Calculate cost
const result = calculator.calculate("gpt-4", 1_000_000, 500_000, {
  cacheReadTokens: 0,
  cacheCreationTokens: 0,
});
 
console.log(`Input cost: $${result.inputCostUsd}`);
console.log(`Output cost: $${result.outputCostUsd}`);
console.log(`Total cost: $${result.totalCostUsd}`);

API Reference

Cost Calculator Engine

createCostCalculator(deps)

Creates a full cost calculator with caching and normalization.

typescript
function createCostCalculator(deps: CostCalculatorDeps): CostCalculator

CostCalculatorDeps

PropertyTypeDescription
pricing{ getPrice(model, provider): PriceEntry | null }Pricing provider (typically from @reaatech/otel-cost-exporter-pricing)
cachePricingCacheLRU cache instance
normalizerModelNormalizerModel name normalizer instance
defaultPricenumber?Fallback USD-per-1M-token price for unknown models

CostCalculator

MethodDescription
calculate(model, inputTokens, outputTokens, options?)Compute full cost including caching — returns CostResult

CostResult

PropertyTypeDescription
modelstringCanonical model name (after normalization)
providerstringProvider name
inputTokensnumberRaw input token count
outputTokensnumberRaw output token count
cacheReadTokensnumberCache read input tokens (Anthropic)
cacheCreationTokensnumberCache creation input tokens (Anthropic)
inputCostUsdnumberInput cost in USD
outputCostUsdnumberOutput cost in USD
cacheReadCostUsdnumberCache read cost in USD
cacheCreationCostUsdnumberCache creation cost in USD
totalCostUsdnumberSum of all costs, rounded to 6 decimal places

PricingError

Error CodeWhen
MODEL_NOT_FOUNDModel is unknown and no defaultPrice is configured
INVALID_PRICENegative token count provided
TABLE_NOT_LOADEDPricing table was not initialized

Low-Level Calculation

calculateCost(entry, inputTokens, outputTokens, cacheReadTokens?, cacheCreationTokens?)

Pure function that converts token counts to a CostBreakdown:

typescript
function calculateCost(
  entry: PriceEntry,
  inputTokens: number,
  outputTokens: number,
  cacheReadTokens?: number,
  cacheCreationTokens?: number,
): CostBreakdown

Automatically computes billable input tokens as max(0, inputTokens - cacheReadTokens) before pricing.

Model Normalizer

createModelNormalizer()

Creates a model name normalizer with built-in aliases:

typescript
function createModelNormalizer(): ModelNormalizer

ModelNormalizer

MethodDescription
normalize(modelName, system?)Resolve a raw model name to { provider, canonicalName } or null
addAlias(alias, canonical)Register a custom alias

Built-in provider detection

PatternProvider
gpt-*, text-davinci-*openai
claude-*anthropic
gemini-*google
llama-*, titan-*aws-bedrock

Built-in aliases

AliasCanonical
gpt4gpt-4
gpt35gpt-3.5-turbo
gpt-35-turbogpt-3.5-turbo
claude-opusclaude-3-opus-20240229
claude-sonnetclaude-3-5-sonnet-20241022
claude-haikuclaude-3-haiku-20240307
gemini-progemini-1.5-pro
gemini-flashgemini-1.5-flash

Pricing Cache

createPricingCache(maxSize?)

LRU pricing entry cache with configurable size:

typescript
function createPricingCache(maxSize?: number): PricingCache
ParameterDefaultDescription
maxSize1000Maximum cache entries before LRU eviction

PricingCache

MethodDescription
get(model, provider)Retrieve a cached PriceEntry or undefined
set(model, provider, entry)Store a PriceEntry in the cache
has(model, provider)Check if an entry is cached
sizeCurrent number of cached entries
clear()Clear all cached entries and reset stats
stats()Return CacheStats

CacheStats

PropertyDescription
hitsNumber of successful cache retrievals
missesNumber of failed cache retrievals
sizeCurrent cache size
maxSizeMaximum cache size
hitRatehits / (hits + misses)0 when no lookups

Usage Patterns

Cache Statistics Monitoring

typescript
const cache = createPricingCache(5000);
 
// After processing a batch of spans...
const stats = cache.stats();
console.log(`Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`);
console.log(`Entries: ${stats.size}/${stats.maxSize}`);

Custom Model Aliases

typescript
const normalizer = createModelNormalizer();
 
// Register a custom alias for your fine-tuned model
normalizer.addAlias("my-finance-gpt", "gpt-4");
 
const result = normalizer.normalize("my-finance-gpt");
// → { provider: "openai", canonicalName: "gpt-4" }

Unknown Model Fallback

typescript
// With defaultPrice set, unknown models get a fallback price
const calculator = createCostCalculator({
  pricing,
  cache,
  normalizer,
  defaultPrice: 2.0,
});
 
// "nonexistent-model" will use $2.00/1M tokens for both input and output
const result = calculator.calculate("nonexistent-model", 100, 50);
console.log(result.totalCostUsd); // ~0.0003 (very small)

License

MIT