Module: LlmCostTracker::Pricing

Defined in:
lib/llm_cost_tracker/pricing.rb

Overview

Calculates costs from price entries expressed in USD per 1M tokens.

Constant Summary collapse

PRICES =
PriceRegistry.builtin_prices

Class Method Summary collapse

Class Method Details

.cost_for(model:, input_tokens:, output_tokens:, cached_input_tokens: 0, cache_read_input_tokens: 0, cache_creation_input_tokens: 0) ⇒ LlmCostTracker::Cost?

Estimate model cost from token counts.

Parameters:

  • model (String)

    Provider model identifier.

  • input_tokens (Integer)

    Input token count, including cached tokens if reported that way.

  • output_tokens (Integer)

    Output token count.

  • cached_input_tokens (Integer) (defaults to: 0)

    OpenAI-style cached input tokens.

  • cache_read_input_tokens (Integer) (defaults to: 0)

    Anthropic-style cache read tokens.

  • cache_creation_input_tokens (Integer) (defaults to: 0)

    Anthropic-style cache creation tokens.

Returns:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/llm_cost_tracker/pricing.rb', line 23

def cost_for(model:, input_tokens:, output_tokens:, cached_input_tokens: 0,
             cache_read_input_tokens: 0, cache_creation_input_tokens: 0)
  prices = lookup(model)
  return nil unless prices

  token_counts = normalized_token_counts(input_tokens, output_tokens, cached_input_tokens,
                                         cache_read_input_tokens, cache_creation_input_tokens)
  costs = calculate_costs(token_counts, prices)

  Cost.new(
    input_cost: costs[:input].round(8),
    cached_input_cost: costs[:cached_input].round(8),
    cache_read_input_cost: costs[:cache_read_input].round(8),
    cache_creation_input_cost: costs[:cache_creation_input].round(8),
    output_cost: costs[:output].round(8),
    total_cost: costs.values.sum.round(8),
    currency: "USD"
  )
end

.lookup(model) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/llm_cost_tracker/pricing.rb', line 43

def lookup(model)
  table = prices
  model_name = model.to_s
  normalized_model = normalize_model_name(model_name)

  table[model_name] || table[normalized_model] || fuzzy_match(model_name, normalized_model, table)
end

.metadataObject



55
56
57
# File 'lib/llm_cost_tracker/pricing.rb', line 55

def 
  PriceRegistry.
end

.modelsObject



51
52
53
# File 'lib/llm_cost_tracker/pricing.rb', line 51

def models
  prices.keys
end

.pricesObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/llm_cost_tracker/pricing.rb', line 59

def prices
  file_prices = PriceRegistry.file_prices(LlmCostTracker.configuration.prices_file)
  overrides = PriceRegistry.normalize_price_table(LlmCostTracker.configuration.pricing_overrides)
  cache_key = [file_prices.object_id, LlmCostTracker.configuration.pricing_overrides.hash]

  return @prices if @prices_cache_key == cache_key

  PRICES_MUTEX.synchronize do
    return @prices if @prices_cache_key == cache_key

    @prices_cache_key = cache_key
    @prices = PRICES.merge(file_prices).merge(overrides).freeze
  end
end