Module: Legion::Extensions::Llm::Gateway::Runners::Metering

Defined in:
lib/legion/extensions/llm/gateway/runners/metering.rb

Class Method Summary collapse

Class Method Details

.build_event(**opts) ⇒ Object



11
12
13
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 11

def build_event(**opts)
  identity_fields(opts).merge(token_fields(opts)).merge(timing_and_context(opts))
end

.flush_spoolObject



56
57
58
59
60
61
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 56

def flush_spool
  return 0 unless spool_available? && transport_connected?

  spool = Legion::Data::Spool.for(Legion::Extensions::Llm::Gateway)
  spool.flush(:metering) { |event| publish_event(event) }
end

.identity_fields(opts) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 15

def identity_fields(opts)
  {
    node_id:      opts[:node_id],
    worker_id:    opts[:worker_id],
    agent_id:     opts[:agent_id],
    request_type: opts[:request_type],
    tier:         opts[:tier],
    provider:     opts[:provider],
    model_id:     opts[:model_id]
  }
end

.publish_event(event) ⇒ Object



73
74
75
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 73

def publish_event(event)
  Legion::Extensions::Llm::Gateway::Transport::Messages::MeteringEvent.new(**event).publish
end

.publish_or_spool(event) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 44

def publish_or_spool(event)
  if transport_connected?
    publish_event(event)
    :published
  elsif spool_available?
    spool_event(event)
    :spooled
  else
    :dropped
  end
end

.spool_available?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 69

def spool_available?
  !!defined?(Legion::Data::Spool)
end

.spool_event(event) ⇒ Object



77
78
79
80
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 77

def spool_event(event)
  spool = Legion::Data::Spool.for(Legion::Extensions::Llm::Gateway)
  spool.write(:metering, event)
end

.timing_and_context(opts) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 35

def timing_and_context(opts)
  {
    latency_ms:     opts.fetch(:latency_ms, 0),
    wall_clock_ms:  opts.fetch(:wall_clock_ms, 0),
    routing_reason: opts[:routing_reason],
    recorded_at:    Time.now.utc.iso8601
  }
end

.token_fields(opts) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 27

def token_fields(opts)
  input    = opts.fetch(:input_tokens, 0)
  output   = opts.fetch(:output_tokens, 0)
  thinking = opts.fetch(:thinking_tokens, 0)
  { input_tokens: input, output_tokens: output, thinking_tokens: thinking,
    total_tokens: input + output + thinking }
end

.transport_connected?Boolean

Returns:

  • (Boolean)


63
64
65
66
67
# File 'lib/legion/extensions/llm/gateway/runners/metering.rb', line 63

def transport_connected?
  !!(defined?(Legion::Transport) && # rubocop:disable Legion/HelperMigration/DefinedTransportGuard
    Legion::Transport.respond_to?(:connected?) &&
    Legion::Transport.connected?)
end