Class: LLM::Cost
- Inherits:
-
Object
- Object
- LLM::Cost
- Defined in:
- lib/llm/cost.rb
Overview
The LLM::Cost class represents an approximate cost breakdown for a provider request. It stores input, output, input audio, output audio, input image, cache read, cache write, and reasoning costs separately and can return the total.
Class Method Summary collapse
-
.from(ctx) ⇒ LLM::Cost
Build a cost breakdown from token usage and model pricing.
-
.zero ⇒ LLM::Cost
Build a zero-valued cost breakdown.
Instance Method Summary collapse
-
#to_s ⇒ String
Returns the total cost in a human friendly format.
- #initialize(input_costs: nil, output_costs: nil, input_audio_costs: nil, output_audio_costs: nil, input_image_costs: nil, cache_read_costs: nil, cache_write_costs: nil, reasoning_costs: nil) ⇒ LLM::Cost constructor
-
#==(other) ⇒ Boolean
(also: #eql?)
Returns true when two costs hold the same breakdown.
-
#input ⇒ Float
(also: #input_costs)
Returns the input cost.
-
#output ⇒ Float
(also: #output_costs)
Returns the output cost.
-
#input_audio ⇒ Float
(also: #input_audio_costs)
Returns the input audio cost.
-
#output_audio ⇒ Float
(also: #output_audio_costs)
Returns the output audio cost.
-
#input_image ⇒ Float
(also: #input_image_costs)
Returns the input image cost.
-
#cache_read ⇒ Float
(also: #cache_read_costs)
Returns the cache read cost.
-
#cache_write ⇒ Float
(also: #cache_write_costs)
Returns the cache write cost.
-
#reasoning ⇒ Float
(also: #reasoning_costs)
Returns the reasoning cost.
-
#total ⇒ Float
Returns the total cost.
-
#to_h ⇒ Hash
Returns a hash with the non-nil cost components and the total.
Constructor Details
#initialize(input_costs: nil, output_costs: nil, input_audio_costs: nil, output_audio_costs: nil, input_image_costs: nil, cache_read_costs: nil, cache_write_costs: nil, reasoning_costs: nil) ⇒ LLM::Cost
65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/llm/cost.rb', line 65 def initialize(input_costs: nil, output_costs: nil, input_audio_costs: nil, output_audio_costs: nil, input_image_costs: nil, cache_read_costs: nil, cache_write_costs: nil, reasoning_costs: nil) @input_costs = input_costs @output_costs = output_costs @input_audio_costs = input_audio_costs @output_audio_costs = output_audio_costs @input_image_costs = input_image_costs @cache_read_costs = cache_read_costs @cache_write_costs = cache_write_costs @reasoning_costs = reasoning_costs end |
Class Method Details
.from(ctx) ⇒ LLM::Cost
Build a cost breakdown from token usage and model pricing.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/llm/cost.rb', line 22 def self.from(ctx) pricing = LLM.registry_for(ctx.llm).cost(model: ctx.model) ## # A model may have no known pricing (eg OpenRouter's # `openrouter/auto` auto-router). Fall back to a zero # cost rather than crashing on a nil pricing. return zero if pricing.nil? usage = ctx.usage output = usage.output_tokens - usage.reasoning_tokens input = usage.input_tokens - usage.cache_read_tokens new( input_costs: price(pricing.input, input), output_costs: price(pricing.output, output), input_audio_costs: price(pricing.input_audio, usage.input_audio_tokens), output_audio_costs: price(pricing.output_audio, usage.output_audio_tokens), input_image_costs: price(pricing.input, usage.input_image_tokens), cache_read_costs: price(pricing.cache_read, usage.cache_read_tokens), cache_write_costs: price(pricing.cache_write, usage.cache_write_tokens), reasoning_costs: price(pricing.reasoning || pricing.output, usage.reasoning_tokens) ) rescue LLM::NoSuchModelError, LLM::NoSuchRegistryError new end |
.zero ⇒ LLM::Cost
Build a zero-valued cost breakdown. Every component is nil (treated as no cost), so the total is 0.
13 14 15 |
# File 'lib/llm/cost.rb', line 13 def self.zero new end |
Instance Method Details
#to_s ⇒ String
Returns the total cost in a human friendly format
178 179 180 |
# File 'lib/llm/cost.rb', line 178 def to_s format("%.2f", total) end |
#==(other) ⇒ Boolean Also known as: eql?
Returns true when two costs hold the same breakdown
82 83 84 |
# File 'lib/llm/cost.rb', line 82 def ==(other) other.is_a?(LLM::Cost) and other.to_h == to_h end |
#input ⇒ Float Also known as: input_costs
Returns the input cost
90 91 92 |
# File 'lib/llm/cost.rb', line 90 def input @input_costs || 0.to_f end |
#output ⇒ Float Also known as: output_costs
Returns the output cost
98 99 100 |
# File 'lib/llm/cost.rb', line 98 def output @output_costs || 0.to_f end |
#input_audio ⇒ Float Also known as: input_audio_costs
Returns the input audio cost
106 107 108 |
# File 'lib/llm/cost.rb', line 106 def input_audio @input_audio_costs || 0.to_f end |
#output_audio ⇒ Float Also known as: output_audio_costs
Returns the output audio cost
114 115 116 |
# File 'lib/llm/cost.rb', line 114 def output_audio @output_audio_costs || 0.to_f end |
#input_image ⇒ Float Also known as: input_image_costs
Returns the input image cost
122 123 124 |
# File 'lib/llm/cost.rb', line 122 def input_image @input_image_costs || 0.to_f end |
#cache_read ⇒ Float Also known as: cache_read_costs
Returns the cache read cost
130 131 132 |
# File 'lib/llm/cost.rb', line 130 def cache_read @cache_read_costs || 0.to_f end |
#cache_write ⇒ Float Also known as: cache_write_costs
Returns the cache write cost
138 139 140 |
# File 'lib/llm/cost.rb', line 138 def cache_write @cache_write_costs || 0.to_f end |
#reasoning ⇒ Float Also known as: reasoning_costs
Returns the reasoning cost
146 147 148 |
# File 'lib/llm/cost.rb', line 146 def reasoning @reasoning_costs || 0.to_f end |
#total ⇒ Float
Returns the total cost
154 155 156 157 158 159 160 161 |
# File 'lib/llm/cost.rb', line 154 def total [ input_costs, output_costs, input_audio_costs, output_audio_costs, cache_read_costs, cache_write_costs, input_image_costs, reasoning_costs ].compact.sum end |
#to_h ⇒ Hash
Returns a hash with the non-nil cost components and the total
166 167 168 169 170 171 172 173 |
# File 'lib/llm/cost.rb', line 166 def to_h { input:, output:, cache_read:, cache_write:, input_audio:, output_audio:, input_image:, reasoning:, total: }.compact end |