Class: AgentHarness::Orchestration::ProviderManager

Inherits:
Object
  • Object
show all
Defined in:
lib/agent_harness/orchestration/provider_manager.rb

Overview

Manages provider instances and selection

Handles provider lifecycle, health tracking, circuit breakers, and rate limiters. Provides intelligent provider selection based on availability and health.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ ProviderManager

Create a new provider manager

Parameters:



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 16

def initialize(config)
  @config = config
  @registry = Providers::Registry.instance
  @provider_instances = {}
  @current_provider = config.default_provider

  @circuit_breakers = {}
  @rate_limiters = {}
  @health_monitor = HealthMonitor.new(config.orchestration_config.health_check_config)
  @fallback_chains = {}

  initialize_providers
end

Instance Attribute Details

#current_providerObject (readonly)

Returns the value of attribute current_provider.



11
12
13
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 11

def current_provider
  @current_provider
end

#provider_instancesObject (readonly)

Returns the value of attribute provider_instances.



11
12
13
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 11

def provider_instances
  @provider_instances
end

Instance Method Details

#available_providersArray<Symbol>

Get available providers

Returns:

  • (Array<Symbol>)

    available provider names



125
126
127
128
129
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 125

def available_providers
  @provider_instances.keys.select do |name|
    !circuit_open?(name) && !rate_limited?(name) && healthy?(name)
  end
end

#circuit_open?(provider_name) ⇒ Boolean

Check if circuit is open for provider

Parameters:

  • provider_name (Symbol, String)

    the provider name

Returns:

  • (Boolean)

    true if open



160
161
162
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 160

def circuit_open?(provider_name)
  @circuit_breakers[provider_name.to_sym]&.open? || false
end

#get_provider(name) ⇒ Providers::Base

Get or create provider instance

Parameters:

  • name (Symbol, String)

    the provider name

Returns:



60
61
62
63
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 60

def get_provider(name)
  name = name.to_sym
  @provider_instances[name] ||= create_provider(name)
end

#health_statusArray<Hash>

Get health status for all providers

Returns:

  • (Array<Hash>)

    health status for each provider



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 134

def health_status
  @provider_instances.keys.map do |name|
    {
      provider: name,
      healthy: healthy?(name),
      circuit_open: circuit_open?(name),
      rate_limited: rate_limited?(name),
      metrics: @health_monitor.metrics_for(name)
    }
  end
end

#healthy?(provider_name) ⇒ Boolean

Check if provider is healthy

Parameters:

  • provider_name (Symbol, String)

    the provider name

Returns:

  • (Boolean)

    true if healthy



176
177
178
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 176

def healthy?(provider_name)
  @health_monitor.healthy?(provider_name.to_sym)
end

#mark_rate_limited(provider_name, reset_at: nil) ⇒ void

This method returns an undefined value.

Mark provider as rate limited

Parameters:

  • provider_name (Symbol, String)

    the provider name

  • reset_at (Time, nil) (defaults to: nil)

    when the limit resets



117
118
119
120
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 117

def mark_rate_limited(provider_name, reset_at: nil)
  provider_name = provider_name.to_sym
  @rate_limiters[provider_name]&.mark_limited(reset_at: reset_at)
end

#rate_limited?(provider_name) ⇒ Boolean

Check if provider is rate limited

Parameters:

  • provider_name (Symbol, String)

    the provider name

Returns:

  • (Boolean)

    true if limited



168
169
170
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 168

def rate_limited?(provider_name)
  @rate_limiters[provider_name.to_sym]&.limited? || false
end

#record_failure(provider_name) ⇒ void

This method returns an undefined value.

Record failure for provider

Parameters:

  • provider_name (Symbol, String)

    the provider name



106
107
108
109
110
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 106

def record_failure(provider_name)
  provider_name = provider_name.to_sym
  @health_monitor.record_failure(provider_name)
  @circuit_breakers[provider_name]&.record_failure
end

#record_success(provider_name) ⇒ void

This method returns an undefined value.

Record success for provider

Parameters:

  • provider_name (Symbol, String)

    the provider name



96
97
98
99
100
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 96

def record_success(provider_name)
  provider_name = provider_name.to_sym
  @health_monitor.record_success(provider_name)
  @circuit_breakers[provider_name]&.record_success
end

#reset!void

This method returns an undefined value.

Reset all state



149
150
151
152
153
154
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 149

def reset!
  @circuit_breakers.each_value(&:reset!)
  @rate_limiters.each_value(&:reset!)
  @health_monitor.reset!
  @current_provider = @config.default_provider
end

#select_provider(preferred = nil) ⇒ Providers::Base

Select best available provider

Parameters:

  • preferred (Symbol, nil) (defaults to: nil)

    preferred provider name

Returns:

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 35

def select_provider(preferred = nil)
  preferred ||= @current_provider

  # Check circuit breaker
  if circuit_open?(preferred)
    return select_fallback(preferred, reason: :circuit_open)
  end

  # Check rate limit
  if rate_limited?(preferred)
    return select_fallback(preferred, reason: :rate_limited)
  end

  # Check health
  unless healthy?(preferred)
    return select_fallback(preferred, reason: :unhealthy)
  end

  get_provider(preferred)
end

#switch_provider(reason:, context: {}) ⇒ Providers::Base?

Switch to next available provider

Parameters:

  • reason (Symbol, String)

    reason for switch

  • context (Hash) (defaults to: {})

    additional context

Returns:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 70

def switch_provider(reason:, context: {})
  old_provider = @current_provider

  fallback = select_fallback(@current_provider, reason: reason)
  return nil unless fallback

  @current_provider = fallback.class.provider_name

  AgentHarness.logger&.info(
    "[AgentHarness] Provider switch: #{old_provider} -> #{@current_provider} (#{reason})"
  )

  @config.callbacks.emit(:provider_switch, {
    from: old_provider,
    to: @current_provider,
    reason: reason,
    context: context
  })

  fallback
end