Module: ActiveAgent::Delegation::Pricing

Defined in:
lib/active_agent/delegation/pricing.rb

Overview

Token price registry used to turn usage into dollars for cost budgets.

ActiveAgent deliberately ships no built-in price list: vendor pricing changes far faster than a gem release, and a stale table silently under-reports spend. Register the rates your app actually pays — once, in an initializer — and every cost budget in the app uses them.

Rates are expressed in USD per one million tokens, matching how every major provider publishes them.

Examples:

Register rates for the models you use

# config/initializers/active_agent.rb
ActiveAgent::Delegation::Pricing.register("gpt-4o-mini", input: 0.15, output: 0.60)
ActiveAgent::Delegation::Pricing.register(/\Aclaude-haiku/, input: 1.00, output: 5.00)

Or state rates inline on a single budget

delegate_to SummarizerAgent, budget: { max_cost: 0.05, rates: { input: 0.15, output: 0.60 } }

Defined Under Namespace

Classes: Rate

Class Method Summary collapse

Class Method Details

.cost_for(usage:, model: nil, rates: nil) ⇒ Float?

Computes the dollar cost of a single generation.

Parameters:

  • usage (ActiveAgent::Providers::Common::Usage, nil)
  • model (String, nil) (defaults to: nil)

    used to look up registered rates

  • rates (Hash, nil) (defaults to: nil)

    inline { input:, output: } overriding the registry

Returns:

  • (Float, nil)

    nil when no rates are known for the model



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/active_agent/delegation/pricing.rb', line 79

def cost_for(usage:, model: nil, rates: nil)
  return nil if usage.nil?

  resolved = normalize(rates) || rates_for(model)
  return nil if resolved.nil?

  input  = (usage.input_tokens  || 0) * resolved[:input]
  output = (usage.output_tokens || 0) * resolved[:output]

  (input + output) / 1_000_000.0
end

.ratesArray<Rate>

Returns registered rates, most recently registered first.

Returns:

  • (Array<Rate>)

    registered rates, most recently registered first



37
38
39
# File 'lib/active_agent/delegation/pricing.rb', line 37

def rates
  @rates ||= []
end

.rates_for(model) ⇒ Hash?

Returns { input:, output: } in USD per 1M tokens.

Parameters:

  • model (String, nil)

Returns:

  • (Hash, nil)

    { input:, output: } in USD per 1M tokens



66
67
68
69
70
71
# File 'lib/active_agent/delegation/pricing.rb', line 66

def rates_for(model)
  return nil if model.blank?

  rate = rates.find { |candidate| candidate.matches?(model) }
  { input: rate.input, output: rate.output } if rate
end

.register(pattern, input:, output:) ⇒ Rate

Registers a rate card.

String patterns match by prefix (so "gpt-4o-mini" covers "gpt-4o-mini-2024-07-18"); Regexp patterns match as written. Later registrations win over earlier ones.

Parameters:

  • pattern (String, Regexp)

    matched against the model name

  • input (Float)

    USD per 1M input tokens

  • output (Float)

    USD per 1M output tokens

Returns:



51
52
53
54
55
# File 'lib/active_agent/delegation/pricing.rb', line 51

def register(pattern, input:, output:)
  Rate.new(pattern: pattern, input: input.to_f, output: output.to_f).tap do |rate|
    rates.unshift(rate)
  end
end

.reset!void

This method returns an undefined value.

Clears the registry. Mostly useful in tests.



60
61
62
# File 'lib/active_agent/delegation/pricing.rb', line 60

def reset!
  @rates = []
end