Class: Llmemory::LLM::UsageLedger

Inherits:
Object
  • Object
show all
Defined in:
lib/llmemory/llm/usage_ledger.rb

Overview

Cumulative LLM token usage per user, persisted in the short-term store under a pseudo-session key (same pattern as ForgetLog).

Constant Summary collapse

SESSION_KEY =
"__llm_usage__"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store: nil) ⇒ UsageLedger

Returns a new instance of UsageLedger.



13
14
15
# File 'lib/llmemory/llm/usage_ledger.rb', line 13

def initialize(store: nil)
  @store = store || ShortTerm::Stores.build
end

Class Method Details

.format_text(totals) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/llmemory/llm/usage_ledger.rb', line 56

def self.format_text(totals)
  inv = totals[:invoke]
  emb = totals[:embed]
  lines = [
    "LLM TOKEN USAGE:",
    "  Chat/completions: #{inv[:total_tokens]} total (#{inv[:input_tokens]} in, #{inv[:output_tokens]} out, #{inv[:calls]} calls)",
    "  Embeddings: #{emb[:total_tokens]} total (#{emb[:calls]} calls)"
  ]
  lines << "  Last updated: #{totals[:updated_at]}" if totals[:updated_at]
  lines.join("\n")
end

Instance Method Details

#record(user_id, usage, operation:) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/llmemory/llm/usage_ledger.rb', line 17

def record(user_id, usage, operation:)
  state = load_raw(user_id)
  case operation.to_sym
  when :invoke
    bucket = symbolize_bucket(state[:invoke] || state["invoke"])
    state = state.merge(
      invoke: {
        input_tokens: bucket[:input_tokens] + usage.input_tokens,
        output_tokens: bucket[:output_tokens] + usage.output_tokens,
        total_tokens: bucket[:total_tokens] + usage.total_tokens,
        calls: bucket[:calls] + 1
      }
    )
  when :embed
    bucket = symbolize_bucket(state[:embed] || state["embed"], embed: true)
    state = state.merge(
      embed: {
        total_tokens: bucket[:total_tokens] + usage.total_tokens,
        calls: bucket[:calls] + 1
      }
    )
  else
    return totals(user_id)
  end
  state[:updated_at] = Time.now.iso8601
  @store.save(user_id, SESSION_KEY, stringify(state))
  totals(user_id)
end

#reset!(user_id) ⇒ Object



50
51
52
53
54
# File 'lib/llmemory/llm/usage_ledger.rb', line 50

def reset!(user_id)
  empty = default_state
  @store.save(user_id, SESSION_KEY, stringify(empty))
  empty
end

#totals(user_id) ⇒ Object



46
47
48
# File 'lib/llmemory/llm/usage_ledger.rb', line 46

def totals(user_id)
  normalize(load_raw(user_id))
end