Class: AgentHarness::Providers::Base
- Inherits:
-
Object
- Object
- AgentHarness::Providers::Base
- Includes:
- Adapter
- Defined in:
- lib/agent_harness/providers/base.rb
Overview
Base class for all providers
Provides common functionality for provider implementations including command execution, error handling, and response parsing.
Direct Known Subclasses
Aider, Anthropic, Codex, Cursor, Gemini, GithubCopilot, Kilocode, MistralVibe, Opencode
Constant Summary collapse
- COMMON_ERROR_PATTERNS =
Common error patterns shared across providers that use standard HTTP-style error responses. Providers with unique patterns (e.g. Anthropic, GitHub Copilot) override error_patterns entirely.
{ rate_limited: [ /rate.?limit/i, /too.?many.?requests/i, /429/ ], auth_expired: [ /invalid.*api.*key/i, /unauthorized/i, /authentication/i ], quota_exceeded: [ /quota.*exceeded/i, /insufficient.*quota/i, /billing/i ], transient: [ /timeout/i, /connection.*error/i, /service.*unavailable/i, /503/, /502/ ] }.tap { |patterns| patterns.each_value(&:freeze) }.freeze
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#executor ⇒ Object
Returns the value of attribute executor.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
Instance Method Summary collapse
-
#configure(options = {}) ⇒ self
Configure the provider instance.
-
#display_name ⇒ String
Human-friendly display name.
-
#initialize(config: nil, executor: nil, logger: nil) ⇒ Base
constructor
Initialize the provider.
-
#name ⇒ String
Provider name for display.
-
#sandboxed_environment? ⇒ Boolean
Whether the provider is running inside a sandboxed (Docker) environment.
-
#send_message(prompt:, **options) ⇒ Response
Main send_message implementation.
Methods included from Adapter
#auth_type, #build_mcp_flags, #capabilities, #configuration_schema, #dangerous_mode_flags, #error_patterns, #execution_semantics, #fetch_mcp_servers, #health_status, included, #parse_rate_limit_reset, #session_flags, #supported_mcp_transports, #supports_dangerous_mode?, #supports_mcp?, #supports_sessions?, #validate_config, #validate_mcp_servers!
Constructor Details
#initialize(config: nil, executor: nil, logger: nil) ⇒ Base
Initialize the provider
71 72 73 74 75 |
# File 'lib/agent_harness/providers/base.rb', line 71 def initialize(config: nil, executor: nil, logger: nil) @config = config || ProviderConfig.new(self.class.provider_name) @executor = executor || AgentHarness.configuration.command_executor @logger = logger || AgentHarness.logger end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
63 64 65 |
# File 'lib/agent_harness/providers/base.rb', line 63 def config @config end |
#executor ⇒ Object
Returns the value of attribute executor.
64 65 66 |
# File 'lib/agent_harness/providers/base.rb', line 64 def executor @executor end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
63 64 65 |
# File 'lib/agent_harness/providers/base.rb', line 63 def logger @logger end |
Instance Method Details
#configure(options = {}) ⇒ self
Configure the provider instance
81 82 83 84 |
# File 'lib/agent_harness/providers/base.rb', line 81 def configure( = {}) @config.merge!() self end |
#display_name ⇒ String
Human-friendly display name
157 158 159 |
# File 'lib/agent_harness/providers/base.rb', line 157 def display_name name.capitalize end |
#name ⇒ String
Provider name for display
150 151 152 |
# File 'lib/agent_harness/providers/base.rb', line 150 def name self.class.provider_name.to_s end |
#sandboxed_environment? ⇒ Boolean
Whether the provider is running inside a sandboxed (Docker) environment
Providers can use this to adjust execution flags, e.g. skipping nested sandboxing when already inside a container.
167 168 169 |
# File 'lib/agent_harness/providers/base.rb', line 167 def sandboxed_environment? @executor.is_a?(DockerCommandExecutor) end |
#send_message(prompt:, **options) ⇒ Response
Main send_message implementation
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/agent_harness/providers/base.rb', line 94 def (prompt:, **) log_debug("send_message_start", prompt_length: prompt.length, options: .keys) # Coerce provider_runtime from Hash if needed = normalize_provider_runtime() # Normalize and validate MCP servers = normalize_mcp_servers() validate_mcp_servers!([:mcp_servers]) if [:mcp_servers]&.any? # Build command command = build_command(prompt, ) # Calculate timeout timeout = [:timeout] || @config.timeout || default_timeout # Execute command start_time = Time.now result = execute_with_timeout(command, timeout: timeout, env: build_env()) duration = Time.now - start_time # Parse response response = parse_response(result, duration: duration) runtime = [:provider_runtime] # Runtime model is a per-request override and always takes precedence # over both the config-level model and whatever parse_response returned. # This is intentional: callers use runtime overrides to route a single # provider instance through different backends on each request. if runtime&.model response = Response.new( output: response.output, exit_code: response.exit_code, duration: response.duration, provider: response.provider, model: runtime.model, tokens: response.tokens, metadata: response., error: response.error ) end # Track tokens track_tokens(response) if response.tokens log_debug("send_message_complete", duration: duration, tokens: response.tokens) response rescue McpConfigurationError, McpUnsupportedError, McpTransportUnsupportedError raise rescue => e handle_error(e, prompt: prompt, options: ) end |