Module: LlmCostTracker::Budget

Defined in:
lib/llm_cost_tracker/budget.rb

Constant Summary collapse

BUDGET_TYPE_TO_PERIOD =
{ monthly: :month, daily: :day }.freeze

Class Method Summary collapse

Class Method Details

.check!(event) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'lib/llm_cost_tracker/budget.rb', line 30

def check!(event)
  config = LlmCostTracker.configuration
  return unless event.total_cost

  check_per_call_budget(event, config)
  check_windowed({ daily: config.daily_budget, monthly: config.monthly_budget }.compact,
                 time: event.tracked_at) do |budget_type, total, budget|
    handle_exceeded(budget_type: budget_type, total: total, budget: budget, last_event: event)
  end
end

.enforce!(provider: nil, model: nil, request: nil, estimate: nil, force: false) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/llm_cost_tracker/budget.rb', line 13

def enforce!(provider: nil, model: nil, request: nil, estimate: nil, force: false)
  config = LlmCostTracker.configuration
  return unless config.enabled
  return unless force || config.budget_exceeded_behavior == :block_requests

  estimate ||= estimate_cost(provider: provider, model: model, request: request)
  raise_per_call_pre_send(estimate, config.per_call_budget) if config.per_call_budget && estimate.positive?

  check_windowed({ monthly: config.monthly_budget, daily: config.daily_budget }.compact,
                 time: Time.now.utc,
estimate: estimate) do |budget_type, total, budget|
    raise BudgetExceededError.new(**budget_payload(
      budget_type: budget_type, total: total, budget: budget, last_event: nil, stage: :pre_send
    ))
  end
end