Class: OllamaAgent::Providers::HealthMonitor

Inherits:
Object
  • Object
show all
Defined in:
lib/ollama_agent/providers/health_monitor.rb

Overview

Aggregates health events emitted by the CredentialRouter and exposes a live snapshot consumed by the TUI providers dashboard.

Also emits :on_provider_switch and :on_credential_disabled events through the agent’s Streaming::Hooks bus when a hooks instance is injected.

Examples:

monitor = HealthMonitor.new(max_events: 50)
monitor.record_success(credential, latency_ms: 240)
monitor.record_failure(credential, OllamaAgent::RateLimitError.new("429"))
monitor.routing_decisions(5)
# => ["openai/key-1 → success (240ms)", "openai/key-1 → failure RateLimitError"]

Defined Under Namespace

Classes: Event

Instance Method Summary collapse

Constructor Details

#initialize(max_events: 100, hooks: nil) ⇒ HealthMonitor

Returns a new instance of HealthMonitor.



26
27
28
29
30
31
# File 'lib/ollama_agent/providers/health_monitor.rb', line 26

def initialize(max_events: 100, hooks: nil)
  @max_events = max_events
  @hooks      = hooks
  @events     = []
  @mutex      = Mutex.new
end

Instance Method Details

#recent_events(n = 20) ⇒ Array<Event>

Parameters:

  • n (Integer) (defaults to: 20)

Returns:



89
90
91
# File 'lib/ollama_agent/providers/health_monitor.rb', line 89

def recent_events(n = 20)
  @mutex.synchronize { @events.last(n).dup }
end

#recent_failure_rate(window: 20) ⇒ Float

Failure rate (0.0–1.0) over the last N events.

Returns:

  • (Float)


95
96
97
98
99
100
# File 'lib/ollama_agent/providers/health_monitor.rb', line 95

def recent_failure_rate(window: 20)
  events = recent_events(window)
  return 0.0 if events.empty?

  events.count { |e| e.kind == :failure }.to_f / events.size
end

#record_failure(credential, error) ⇒ Object

Record a failed attempt.

Parameters:



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/ollama_agent/providers/health_monitor.rb', line 50

def record_failure(credential, error)
  push Event.new(
    at: Time.now,
    credential_id: credential.id,
    provider: credential.provider,
    kind: :failure,
    error_class: error.class.name,
    latency_ms: nil
  )

  emit_hook(:on_credential_failure, credential, error) if error.is_a?(OllamaAgent::AuthenticationError)
end

#record_success(credential, latency_ms: nil) ⇒ Object

Record a successful response.

Parameters:

  • credential (Credential)
  • latency_ms (Integer, nil) (defaults to: nil)


36
37
38
39
40
41
42
43
44
45
# File 'lib/ollama_agent/providers/health_monitor.rb', line 36

def record_success(credential, latency_ms: nil)
  push Event.new(
    at: Time.now,
    credential_id: credential.id,
    provider: credential.provider,
    kind: :success,
    error_class: nil,
    latency_ms: latency_ms
  )
end

#record_switch(from, to, reason) ⇒ Object

Record a provider switch (credential failover).

Parameters:



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ollama_agent/providers/health_monitor.rb', line 67

def record_switch(from, to, reason)
  push Event.new(
    at: Time.now,
    credential_id: "#{from.id}#{to.id}",
    provider: from.provider,
    kind: :switch,
    error_class: reason,
    latency_ms: nil
  )

  emit_hook(:on_provider_switch, from, to, reason)
end

#routing_decisions(n = 10) ⇒ Array<String>

Last N events as human-readable routing strings for the TUI panel.

Parameters:

  • n (Integer) (defaults to: 10)

Returns:

  • (Array<String>)


83
84
85
# File 'lib/ollama_agent/providers/health_monitor.rb', line 83

def routing_decisions(n = 10)
  recent_events(n).map { |e| format_event(e) }
end