Module: LlmCostTracker::Integrations::Base

Included in:
Anthropic, Openai, RubyLlm
Defined in:
lib/llm_cost_tracker/integrations/base.rb

Defined Under Namespace

Classes: Result

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.object_dig(object, *path) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/llm_cost_tracker/integrations/base.rb', line 71

def object_dig(object, *path)
  if object.respond_to?(:dig)
    begin
      value = object.dig(*path)
      return value unless value.nil?
    rescue NameError, TypeError
      nil
    end
  end

  path.reduce(object) do |current, key|
    return nil if current.nil?

    read_object_value(current, key)
  end
end

.object_value(object, *keys) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/llm_cost_tracker/integrations/base.rb', line 63

def object_value(object, *keys)
  keys.each do |key|
    value = read_object_value(object, key)
    return value unless value.nil?
  end
  nil
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/llm_cost_tracker/integrations/base.rb', line 14

def active?
  LlmCostTracker.configuration.instrumented?(integration_name)
end

#elapsed_ms(started_at) ⇒ Object



42
43
44
# File 'lib/llm_cost_tracker/integrations/base.rb', line 42

def elapsed_ms(started_at)
  ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at) * 1000).round
end

#enforce_budget!Object



46
47
48
# File 'lib/llm_cost_tracker/integrations/base.rb', line 46

def enforce_budget!
  LlmCostTracker::Tracker.enforce_budget! if active?
end

#installObject



18
19
20
21
22
23
24
# File 'lib/llm_cost_tracker/integrations/base.rb', line 18

def install
  validate_contract!
  patch_targets.each do |target|
    target_class = target.fetch(:constant_name).to_s.safe_constantize
    install_patch(target_class, target.fetch(:patch)) if target_class
  end
end

#minimum_versionObject



88
# File 'lib/llm_cost_tracker/integrations/base.rb', line 88

def minimum_version = nil

#patch_target(constant_name, with:, methods:, optional: false) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/llm_cost_tracker/integrations/base.rb', line 94

def patch_target(constant_name, with:, methods:, optional: false)
  {
    constant_name: constant_name,
    patch: with,
    method_names: Array(methods),
    optional: optional
  }
end

#patch_targetsObject



92
# File 'lib/llm_cost_tracker/integrations/base.rb', line 92

def patch_targets = []

#record_safelyObject



50
51
52
53
54
55
56
# File 'lib/llm_cost_tracker/integrations/base.rb', line 50

def record_safely
  yield
rescue LlmCostTracker::Error
  raise
rescue StandardError => e
  Logging.warn("#{integration_name} integration failed to record usage: #{e.class}: #{e.message}")
end

#request_params(args, kwargs) ⇒ Object



58
59
60
61
# File 'lib/llm_cost_tracker/integrations/base.rb', line 58

def request_params(args, kwargs)
  params = args.first.is_a?(Hash) ? args.first : {}
  params.merge(kwargs).with_indifferent_access
end

#statusObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/llm_cost_tracker/integrations/base.rb', line 26

def status
  name = integration_name
  problems = version_problems + target_problems
  if problems.any?
    return Result.new(name, :warn, "#{name} integration cannot be installed: #{problems.join('; ')}")
  end

  required_targets = patch_targets.reject { |target| target.fetch(:optional) }
  installed = required_targets.count do |target|
    target.fetch(:constant_name).to_s.safe_constantize&.ancestors&.include?(target.fetch(:patch))
  end
  return Result.new(name, :ok, "#{name} integration installed") if installed == required_targets.count

  Result.new(name, :warn, "#{name} integration is enabled but not installed")
end

#version_constantObject



90
# File 'lib/llm_cost_tracker/integrations/base.rb', line 90

def version_constant = nil