Class: AgentHarness::Orchestration::ProviderManager
- Inherits:
-
Object
- Object
- AgentHarness::Orchestration::ProviderManager
- 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
-
#current_provider ⇒ Object
readonly
Returns the value of attribute current_provider.
-
#provider_instances ⇒ Object
readonly
Returns the value of attribute provider_instances.
Instance Method Summary collapse
-
#available_providers ⇒ Array<Symbol>
Get available providers.
-
#circuit_open?(provider_name) ⇒ Boolean
Check if circuit is open for provider.
-
#get_provider(name, executor: nil) ⇒ Providers::Base
Get or create provider instance.
-
#health_status ⇒ Array<Hash>
Get health status for all providers.
-
#healthy?(provider_name) ⇒ Boolean
Check if provider is healthy.
-
#initialize(config) ⇒ ProviderManager
constructor
Create a new provider manager.
-
#mark_rate_limited(provider_name, reset_at: nil) ⇒ void
Mark provider as rate limited.
-
#rate_limited?(provider_name) ⇒ Boolean
Check if provider is rate limited.
-
#record_failure(provider_name) ⇒ void
Record failure for provider.
-
#record_success(provider_name) ⇒ void
Record success for provider.
-
#reset! ⇒ void
Reset all state.
-
#select_provider(preferred = nil, executor: nil) ⇒ Providers::Base
Select best available provider.
-
#switch_provider(reason:, context: {}, executor: nil, from: @current_provider) ⇒ Providers::Base?
Switch to next available provider.
Constructor Details
#initialize(config) ⇒ ProviderManager
Create a new provider manager
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_provider ⇒ Object (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_instances ⇒ Object (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_providers ⇒ Array<Symbol>
Get available providers
133 134 135 136 137 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 133 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
168 169 170 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 168 def circuit_open?(provider_name) @circuit_breakers[provider_name.to_sym]&.open? || false end |
#get_provider(name, executor: nil) ⇒ Providers::Base
Get or create provider instance
62 63 64 65 66 67 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 62 def get_provider(name, executor: nil) name = name.to_sym return create_provider(name, executor: executor) if executor @provider_instances[name] ||= create_provider(name) end |
#health_status ⇒ Array<Hash>
Get health status for all providers
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 142 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
184 185 186 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 184 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
125 126 127 128 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 125 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
176 177 178 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 176 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
114 115 116 117 118 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 114 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
104 105 106 107 108 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 104 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
157 158 159 160 161 162 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 157 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, executor: nil) ⇒ Providers::Base
Select best available provider
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 36 def select_provider(preferred = nil, executor: nil) preferred ||= @current_provider # Check circuit breaker if circuit_open?(preferred) return select_fallback(preferred, reason: :circuit_open, executor: executor) end # Check rate limit if rate_limited?(preferred) return select_fallback(preferred, reason: :rate_limited, executor: executor) end # Check health unless healthy?(preferred) return select_fallback(preferred, reason: :unhealthy, executor: executor) end get_provider(preferred, executor: executor) end |
#switch_provider(reason:, context: {}, executor: nil, from: @current_provider) ⇒ Providers::Base?
Switch to next available provider
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/agent_harness/orchestration/provider_manager.rb', line 76 def switch_provider(reason:, context: {}, executor: nil, from: @current_provider) old_provider = from.to_sym fallback = select_fallback(old_provider, reason: reason, executor: executor) return nil unless fallback return fallback if executor @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 |