Class: LlmCostTracker::LlmApiCall

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/llm_cost_tracker/llm_api_call.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.average_latency_msObject



64
65
66
67
68
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 64

def self.average_latency_ms
  return nil unless latency_column?

  average(:latency_ms)&.to_f
end

.cost_by_modelObject



56
57
58
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 56

def self.cost_by_model
  group(:model).sum(:total_cost)
end

.cost_by_providerObject



60
61
62
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 60

def self.cost_by_provider
  group(:provider).sum(:total_cost)
end

.daily_costs(days: 30) ⇒ Object



82
83
84
85
86
87
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 82

def self.daily_costs(days: 30)
  where(tracked_at: days.days.ago..)
    .group("DATE(tracked_at)")
    .sum(:total_cost)
    .transform_keys(&:to_s)
end

.json_tag_fragment(key, value) ⇒ Object



104
105
106
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 104

def self.json_tag_fragment(key, value)
  JSON.generate(key => value).delete_prefix("{").delete_suffix("}")
end

.latency_by_modelObject



70
71
72
73
74
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 70

def self.latency_by_model
  return {} unless latency_column?

  group(:model).average(:latency_ms).transform_values(&:to_f)
end

.latency_by_providerObject



76
77
78
79
80
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 76

def self.latency_by_provider
  return {} unless latency_column?

  group(:provider).average(:latency_ms).transform_values(&:to_f)
end

.latency_column?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 96

def self.latency_column?
  columns_hash.key?("latency_ms")
end

.normalize_tags(tags) ⇒ Object



100
101
102
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 100

def self.normalize_tags(tags)
  (tags || {}).to_h.transform_keys(&:to_s).transform_values(&:to_s)
end

.tags_json_column?Boolean

Returns:

  • (Boolean)


89
90
91
92
93
94
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 89

def self.tags_json_column?
  column = columns_hash["tags"]
  return false unless column

  %i[json jsonb].include?(column.type) || column.sql_type.to_s.downcase == "jsonb"
end

.total_costObject

Aggregations



48
49
50
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 48

def self.total_cost
  sum(:total_cost).to_f
end

.total_tokensObject



52
53
54
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 52

def self.total_tokens
  sum(:total_tokens).to_i
end

Instance Method Details

#featureObject



116
117
118
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 116

def feature
  parsed_tags["feature"]
end

#parsed_tagsObject



108
109
110
111
112
113
114
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 108

def parsed_tags
  return tags.transform_keys(&:to_s) if tags.is_a?(Hash)

  JSON.parse(tags || "{}")
rescue JSON::ParserError
  {}
end

#user_idObject



120
121
122
# File 'lib/llm_cost_tracker/llm_api_call.rb', line 120

def user_id
  parsed_tags["user_id"]
end