Class: RubyPi::LLM::BaseProvider
- Inherits:
-
Object
- Object
- RubyPi::LLM::BaseProvider
- Defined in:
- lib/ruby_pi/llm/base_provider.rb
Overview
Abstract base class that defines the contract every LLM provider must fulfill. Provides built-in retry logic with exponential backoff for transient errors and a unified #complete interface for both synchronous and streaming completions.
Subclasses MUST implement:
-
#perform_complete(messages:, tools:, stream:, &block)
-
#model_name
-
#provider_name
Instance Attribute Summary collapse
-
#max_retries ⇒ Integer
readonly
Maximum number of retry attempts.
-
#retry_base_delay ⇒ Float
readonly
Base delay in seconds for exponential backoff.
-
#retry_max_delay ⇒ Float
readonly
Maximum delay in seconds between retries.
Instance Method Summary collapse
-
#complete(messages:, tools: [], stream: false) {|event| ... } ⇒ RubyPi::LLM::Response
Sends a completion request to the LLM provider with automatic retry logic for transient errors.
-
#initialize(config: nil, max_retries: nil, retry_base_delay: nil, retry_max_delay: nil) ⇒ BaseProvider
constructor
Initializes the base provider with retry configuration.
-
#model_name ⇒ String
Returns the model name used by this provider instance.
-
#provider_name ⇒ Symbol
Returns the provider identifier.
Constructor Details
#initialize(config: nil, max_retries: nil, retry_base_delay: nil, retry_max_delay: nil) ⇒ BaseProvider
Initializes the base provider with retry configuration.
51 52 53 54 55 56 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 51 def initialize(config: nil, max_retries: nil, retry_base_delay: nil, retry_max_delay: nil) @config = config || RubyPi.configuration @max_retries = max_retries || @config.max_retries @retry_base_delay = retry_base_delay || @config.retry_base_delay @retry_max_delay = retry_max_delay || @config.retry_max_delay end |
Instance Attribute Details
#max_retries ⇒ Integer (readonly)
Returns maximum number of retry attempts.
34 35 36 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 34 def max_retries @max_retries end |
#retry_base_delay ⇒ Float (readonly)
Returns base delay in seconds for exponential backoff.
37 38 39 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 37 def retry_base_delay @retry_base_delay end |
#retry_max_delay ⇒ Float (readonly)
Returns maximum delay in seconds between retries.
40 41 42 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 40 def retry_max_delay @retry_max_delay end |
Instance Method Details
#complete(messages:, tools: [], stream: false) {|event| ... } ⇒ RubyPi::LLM::Response
Sends a completion request to the LLM provider with automatic retry logic for transient errors. When stream is true and a block is given, yields StreamEvent objects incrementally as they arrive.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 72 def complete(messages:, tools: [], stream: false, &block) attempt = 0 begin attempt += 1 perform_complete(messages: , tools: tools, stream: stream, &block) rescue RubyPi::AuthenticationError # Authentication errors are not retryable — raise immediately raise rescue RubyPi::RateLimitError, RubyPi::ApiError, RubyPi::TimeoutError => e # Retry up to max_retries times AFTER the initial attempt. # With max_retries: 3, attempt goes 1 (initial), 2, 3, 4 — the condition # `attempt <= @max_retries` allows retries on attempts 1..3, so we get # 3 retries + 1 initial = 4 total attempts. Previously used `< @max_retries` # which was off-by-one (only 2 retries with max_retries: 3). if attempt <= @max_retries delay = calculate_backoff(attempt) log_retry(attempt, delay, e) sleep(delay) retry else raise end end end |
#model_name ⇒ String
Returns the model name used by this provider instance. Subclasses MUST override this method.
103 104 105 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 103 def model_name raise RubyPi::AbstractMethodError, :model_name end |
#provider_name ⇒ Symbol
Returns the provider identifier. Subclasses MUST override this method.
112 113 114 |
# File 'lib/ruby_pi/llm/base_provider.rb', line 112 def provider_name raise RubyPi::AbstractMethodError, :provider_name end |