Module: LlmCostTracker::Pricing
- Extended by:
- ServiceCharges
- Defined in:
- lib/llm_cost_tracker/pricing.rb,
lib/llm_cost_tracker.rb,
lib/llm_cost_tracker/pricing/mode.rb,
lib/llm_cost_tracker/pricing/sync.rb,
lib/llm_cost_tracker/pricing/lookup.rb,
lib/llm_cost_tracker/pricing/unknown.rb,
lib/llm_cost_tracker/pricing/backfill.rb,
lib/llm_cost_tracker/pricing/registry.rb,
lib/llm_cost_tracker/pricing/estimator.rb,
lib/llm_cost_tracker/pricing/explainer.rb,
lib/llm_cost_tracker/pricing/sync/fetcher.rb,
lib/llm_cost_tracker/pricing/service_charges.rb,
lib/llm_cost_tracker/pricing/effective_prices.rb,
lib/llm_cost_tracker/pricing/sync/registry_diff.rb,
lib/llm_cost_tracker/pricing/sync/change_printer.rb,
lib/llm_cost_tracker/pricing/sync/registry_writer.rb
Overview
rubocop:disable Metrics/ModuleLength
Defined Under Namespace
Modules: EffectivePrices, Estimator, Explainer, Lookup, Registry, ServiceCharges, Sync
Classes: Backfill, Explanation, Mode, Unknown
Constant Summary
collapse
- STANDARD_MODE_VALUES =
%i[auto default standard standard_only].freeze
ServiceCharges::DEFAULT_CURRENCY, ServiceCharges::EMPTY_RATES, ServiceCharges::MUTEX
Class Method Summary
collapse
-
.calculate(provider:, model:, tokens:, line_items:, pricing_mode: nil) ⇒ Object
-
.combine_with_service_lines(cost_data, line_items) ⇒ Object
-
.cost_for(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
-
.explain(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
-
.normalize_mode(value) ⇒ Object
-
.price_line_items(provider:, model:, line_items:, pricing_mode: nil) ⇒ Object
-
.snapshot_for(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
-
.stored_cost_attributes(attributes) ⇒ Object
-
.token_pricing_partial?(token_usage, cost_data) ⇒ Boolean
builtin_rates, charge_rate, file_rates, rates_from_registry, reset!
Class Method Details
.calculate(provider:, model:, tokens:, line_items:, pricing_mode: nil) ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/llm_cost_tracker/pricing.rb', line 50
def calculate(provider:, model:, tokens:, line_items:, pricing_mode: nil)
calculation = calculation_for(
provider: provider,
model: model,
tokens: tokens,
pricing_mode: pricing_mode
)
cost_data = calculation && cost_from(calculation)
snapshot = calculation && snapshot_from(calculation)
priced = apply_calculation_to_line_items(line_items, calculation,
provider: provider, pricing_mode: pricing_mode)
[cost_data, snapshot, priced]
end
|
.combine_with_service_lines(cost_data, line_items) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/llm_cost_tracker/pricing.rb', line 99
def combine_with_service_lines(cost_data, line_items)
priced_services = line_items.reject(&:token?).select(&:priced?)
return cost_data if priced_services.empty?
base_currency = base_currency_for(cost_data, priced_services)
matching, mismatched = priced_services.partition { |line| line.currency.to_s == base_currency.to_s }
warn_currency_mismatch(mismatched, base_currency) if mismatched.any?
cost = cost_data ? cost_data.dup : {}
cost[:currency] ||= base_currency.to_s
return cost if matching.empty?
service_total = matching.sum(BigDecimal("0"), &:cost_value)
base_total = BigDecimal(cost.fetch(:total_cost, 0).to_s)
cost[:total_cost] = (base_total + service_total).round(8)
cost
end
|
.cost_for(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/llm_cost_tracker/pricing.rb', line 38
def cost_for(provider:, model:, tokens:, pricing_mode: nil)
calculation = calculation_for(
provider: provider,
model: model,
tokens: tokens,
pricing_mode: pricing_mode
)
return nil unless calculation
cost_from(calculation)
end
|
.explain(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
85
86
87
88
89
90
91
92
|
# File 'lib/llm_cost_tracker/pricing.rb', line 85
def explain(provider:, model:, tokens:, pricing_mode: nil)
Explainer.call(
provider: provider,
model: model,
tokens: tokens,
pricing_mode: pricing_mode
)
end
|
.normalize_mode(value) ⇒ Object
29
30
31
32
33
34
35
36
|
# File 'lib/llm_cost_tracker/pricing.rb', line 29
def normalize_mode(value)
return nil if value.nil?
mode = normalize_string_mode(value.to_s)
return nil unless mode
STANDARD_MODE_VALUES.include?(mode) ? nil : mode
end
|
.price_line_items(provider:, model:, line_items:, pricing_mode: nil) ⇒ Object
64
65
66
67
68
69
70
71
|
# File 'lib/llm_cost_tracker/pricing.rb', line 64
def price_line_items(provider:, model:, line_items:, pricing_mode: nil)
token_usage = TokenUsage.build_from_tokens(token_attributes_from(line_items))
calculation = calculation_for(provider: provider, model: model, tokens: token_usage, pricing_mode: pricing_mode)
snapshot = calculation && snapshot_from(calculation)
priced = apply_calculation_to_line_items(line_items, calculation,
provider: provider, pricing_mode: pricing_mode)
[priced, snapshot]
end
|
.snapshot_for(provider:, model:, tokens:, pricing_mode: nil) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/llm_cost_tracker/pricing.rb', line 73
def snapshot_for(provider:, model:, tokens:, pricing_mode: nil)
calculation = calculation_for(
provider: provider,
model: model,
tokens: tokens,
pricing_mode: pricing_mode
)
return nil unless calculation
snapshot_from(calculation)
end
|
.stored_cost_attributes(attributes) ⇒ Object
94
95
96
97
|
# File 'lib/llm_cost_tracker/pricing.rb', line 94
def stored_cost_attributes(attributes)
value = attributes.to_h[:total_cost]
value ? { total_cost: value } : {}
end
|
.token_pricing_partial?(token_usage, cost_data) ⇒ Boolean
117
118
119
120
121
122
123
124
125
|
# File 'lib/llm_cost_tracker/pricing.rb', line 117
def token_pricing_partial?(token_usage, cost_data)
return false unless cost_data
token_usage.priced_quantities.any? do |key, quantity|
next false unless quantity.positive?
cost_data[Billing::Components::BY_KEY.fetch(key).cost_key].nil?
end
end
|