Module: LlmCostTracker::Pricing

Defined in:
lib/llm_cost_tracker/pricing.rb

Constant Summary collapse

PRICES =
PriceRegistry.builtin_prices
MUTEX =
Monitor.new

Class Method Summary collapse

Class Method Details

.cost_for(provider:, model:, input_tokens:, output_tokens:, cache_read_input_tokens: 0, cache_write_input_tokens: 0, pricing_mode: nil) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/llm_cost_tracker/pricing.rb', line 11

def cost_for(provider:, model:, input_tokens:, output_tokens:, cache_read_input_tokens: 0,
             cache_write_input_tokens: 0, pricing_mode: nil)
  prices = lookup(provider: provider, model: model)
  return nil unless prices

  usage = UsageBreakdown.build(
    input_tokens: input_tokens,
    output_tokens: output_tokens,
    cache_read_input_tokens: cache_read_input_tokens,
    cache_write_input_tokens: cache_write_input_tokens
  )
  costs = calculate_costs(usage, prices, pricing_mode: pricing_mode)

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

.lookup(provider:, model:) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/llm_cost_tracker/pricing.rb', line 34

def lookup(provider:, model:)
  table = prices
  provider_name = provider.to_s
  model_name = model.to_s
  provider_model = provider_name.empty? ? model_name : "#{provider_name}/#{model_name}"
  normalized_model = normalize_model_name(model_name)

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

.metadataObject



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

def 
  PriceRegistry.
end

.modelsObject



47
48
49
# File 'lib/llm_cost_tracker/pricing.rb', line 47

def models
  prices.keys
end

.pricesObject



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

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]

  cached = @prices_cache
  return cached[:value] if cached && cached[:key] == cache_key

  MUTEX.synchronize do
    cached = @prices_cache
    return cached[:value] if cached && cached[:key] == cache_key

    value = PRICES.merge(file_prices).merge(overrides).freeze
    @prices_cache = { key: cache_key, value: value }.freeze
    value
  end
end