Class: RubyLlmMesh::Budget
- Inherits:
-
Object
- Object
- RubyLlmMesh::Budget
- Defined in:
- lib/ruby_llm_mesh/budget.rb
Constant Summary collapse
- DEFAULT_PRICES =
{ input_per_1k: 0.00015, output_per_1k: 0.0006 }.freeze
Instance Attribute Summary collapse
-
#tokens_consumed ⇒ Object
readonly
Returns the value of attribute tokens_consumed.
-
#usd_consumed ⇒ Object
readonly
Returns the value of attribute usd_consumed.
Class Method Summary collapse
- .compute_cost(usage, provider:, model:, config: RubyLlmMesh.configuration) ⇒ Object
- .estimate_tokens(prompt:, system: nil, max_tokens: nil) ⇒ Object
- .estimate_usd(tokens:, model: nil, config: RubyLlmMesh.configuration) ⇒ Object
- .extract_tokens(usage) ⇒ Object
- .instance(config: RubyLlmMesh.configuration) ⇒ Object
- .reset! ⇒ Object
- .resolve_prices(config, model) ⇒ Object
Instance Method Summary collapse
- #check!(estimated_tokens: 0, estimated_usd: 0.0) ⇒ Object
- #consume!(usage:, provider:, model:) ⇒ Object
- #enabled? ⇒ Boolean
-
#initialize(config: RubyLlmMesh.configuration) ⇒ Budget
constructor
A new instance of Budget.
- #reset! ⇒ Object
- #status ⇒ Object
Constructor Details
#initialize(config: RubyLlmMesh.configuration) ⇒ Budget
Returns a new instance of Budget.
12 13 14 15 16 17 |
# File 'lib/ruby_llm_mesh/budget.rb', line 12 def initialize(config: RubyLlmMesh.configuration) @config = config @tokens_consumed = 0 @usd_consumed = 0.0 @mutex = Mutex.new end |
Instance Attribute Details
#tokens_consumed ⇒ Object (readonly)
Returns the value of attribute tokens_consumed.
10 11 12 |
# File 'lib/ruby_llm_mesh/budget.rb', line 10 def tokens_consumed @tokens_consumed end |
#usd_consumed ⇒ Object (readonly)
Returns the value of attribute usd_consumed.
10 11 12 |
# File 'lib/ruby_llm_mesh/budget.rb', line 10 def usd_consumed @usd_consumed end |
Class Method Details
.compute_cost(usage, provider:, model:, config: RubyLlmMesh.configuration) ⇒ Object
94 95 96 97 98 99 100 101 |
# File 'lib/ruby_llm_mesh/budget.rb', line 94 def compute_cost(usage, provider:, model:, config: RubyLlmMesh.configuration) prices = resolve_prices(config, model) prompt_tokens = usage_value(usage, :prompt_tokens, :input_tokens) completion_tokens = usage_value(usage, :completion_tokens, :output_tokens) input_cost = (prompt_tokens / 1000.0) * prices[:input_per_1k] output_cost = (completion_tokens / 1000.0) * prices[:output_per_1k] input_cost + output_cost end |
.estimate_tokens(prompt:, system: nil, max_tokens: nil) ⇒ Object
75 76 77 78 79 80 |
# File 'lib/ruby_llm_mesh/budget.rb', line 75 def estimate_tokens(prompt:, system: nil, max_tokens: nil) text = [system, prompt].compact.join("\n") estimated = (text.length / 4.0).ceil estimated += max_tokens.to_i if max_tokens estimated end |
.estimate_usd(tokens:, model: nil, config: RubyLlmMesh.configuration) ⇒ Object
82 83 84 85 |
# File 'lib/ruby_llm_mesh/budget.rb', line 82 def estimate_usd(tokens:, model: nil, config: RubyLlmMesh.configuration) prices = resolve_prices(config, model) (tokens / 1000.0) * prices[:input_per_1k] end |
.extract_tokens(usage) ⇒ Object
103 104 105 |
# File 'lib/ruby_llm_mesh/budget.rb', line 103 def extract_tokens(usage) usage_value(usage, :total_tokens, :prompt_tokens, :completion_tokens, :input_tokens, :output_tokens) end |
.instance(config: RubyLlmMesh.configuration) ⇒ Object
66 67 68 69 |
# File 'lib/ruby_llm_mesh/budget.rb', line 66 def instance(config: RubyLlmMesh.configuration) @instances ||= {} @instances[config.object_id] ||= new(config: config) end |
.reset! ⇒ Object
71 72 73 |
# File 'lib/ruby_llm_mesh/budget.rb', line 71 def reset! @instances = {} end |
.resolve_prices(config, model) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/ruby_llm_mesh/budget.rb', line 87 def resolve_prices(config, model) table = config.budget_prices || {} entry = model ? table[model.to_s] || table[model.to_sym] : nil entry ||= table[:default] || table["default"] DEFAULT_PRICES.merge(entry || {}) end |
Instance Method Details
#check!(estimated_tokens: 0, estimated_usd: 0.0) ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/ruby_llm_mesh/budget.rb', line 23 def check!(estimated_tokens: 0, estimated_usd: 0.0) return unless enabled? @mutex.synchronize do raise_budget_exceeded!("token", @tokens_consumed, @config.budget_max_tokens) if token_limit? && (@tokens_consumed + estimated_tokens) > @config.budget_max_tokens raise_budget_exceeded!("usd", @usd_consumed, @config.budget_max_usd) if usd_limit? && (@usd_consumed + estimated_usd) > @config.budget_max_usd end end |
#consume!(usage:, provider:, model:) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ruby_llm_mesh/budget.rb', line 32 def consume!(usage:, provider:, model:) return unless enabled? tokens = self.class.extract_tokens(usage) usd = self.class.compute_cost(usage, provider: provider, model: model, config: @config) @mutex.synchronize do @tokens_consumed += tokens @usd_consumed += usd raise_budget_exceeded!("token", @tokens_consumed, @config.budget_max_tokens) if token_limit? && @tokens_consumed > @config.budget_max_tokens raise_budget_exceeded!("usd", @usd_consumed, @config.budget_max_usd) if usd_limit? && @usd_consumed > @config.budget_max_usd end end |
#enabled? ⇒ Boolean
19 20 21 |
# File 'lib/ruby_llm_mesh/budget.rb', line 19 def enabled? @config.budget_enabled end |
#reset! ⇒ Object
58 59 60 61 62 63 |
# File 'lib/ruby_llm_mesh/budget.rb', line 58 def reset! @mutex.synchronize do @tokens_consumed = 0 @usd_consumed = 0.0 end end |
#status ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ruby_llm_mesh/budget.rb', line 46 def status { enabled: enabled?, tokens_consumed: @tokens_consumed, tokens_max: @config.budget_max_tokens, tokens_remaining: tokens_remaining, usd_consumed: @usd_consumed.round(6), usd_max: @config.budget_max_usd, usd_remaining: usd_remaining } end |