Class: RubyLLM::Agents::Pipeline::Middleware::Budget

Inherits:
Base
  • Object
show all
Defined in:
lib/ruby_llm/agents/pipeline/middleware/budget.rb

Overview

Checks budget limits before execution and records spend after.

This middleware integrates with the BudgetTracker to:

  • Check if budget limits are exceeded before execution

  • Record spend after successful execution

Budget checking is skipped if:

  • Budgets are disabled globally in configuration

  • The result was served from cache (no API call was made)

Examples:

With budget enforcement

# In config/initializers/ruby_llm_agents.rb
RubyLLM::Agents.configure do |config|
  config.budgets_enabled = true
end

# Budget will be checked before execution
MyAgent.call(query: "test", tenant: { id: "org_123" })

Constant Summary

Constants inherited from Base

RubyLLM::Agents::Pipeline::Middleware::Base::LOG_TAG

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from RubyLLM::Agents::Pipeline::Middleware::Base

Instance Method Details

#call(context) ⇒ Context

Process budget checking and spend recording

Parameters:

  • context (Context)

    The execution context

Returns:

  • (Context)

    The context after budget processing

Raises:

  • (BudgetExceededError)

    If budget is exceeded with hard enforcement



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ruby_llm/agents/pipeline/middleware/budget.rb', line 32

def call(context)
  return @app.call(context) unless budgets_enabled?

  trace(context) do
    # Resolve tenant once for both check and record
    tenant = resolve_tenant(context)

    # Check budget before execution
    check_budget!(context, tenant)

    # Execute the chain
    @app.call(context)

    # Record spend after successful execution (if not cached)
    if context.success? && !context.cached?
      record_spend!(context, tenant)
      emit_budget_notification("ruby_llm_agents.budget.record", context,
        total_cost: context.total_cost,
        total_tokens: context.total_tokens)
    end

    context
  end
end