Class: LLM::Cost

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

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

Parameters:

  • input_costs (Float, nil) (defaults to: nil)
  • output_costs (Float, nil) (defaults to: nil)
  • input_audio_costs (Float, nil) (defaults to: nil)
  • output_audio_costs (Float, nil) (defaults to: nil)
  • input_image_costs (Float, nil) (defaults to: nil)
  • cache_read_costs (Float, nil) (defaults to: nil)
  • cache_write_costs (Float, nil) (defaults to: nil)
  • reasoning_costs (Float, nil) (defaults to: nil)


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.

Parameters:

  • ctx (LLM::Context) —

    Context used to resolve provider, model, and token usage

Returns:



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.

Returns:



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

Returns:

  • (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

Returns:

  • (Boolean) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (Float) —

    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

Returns:

  • (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

Returns:

  • (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