Class: LittleGhost::ProviderRegistry

Inherits:
Object
  • Object
show all
Defined in:
lib/little_ghost/provider_registry.rb

Overview

Constructs built-in and application provider adapters from named provider connections. Register adapters during application configuration.

Constant Summary collapse

REQUEST_OPTIONS =

:nodoc:

%i[
  app_name max_response_bytes max_retries max_retry_delay open_timeout read_timeout retries
].freeze
BUILT_INS =

:nodoc:

{
  "openai_compatible" => Providers::OpenAICompatible,
  "openai" => Providers::OpenAI,
  "openrouter" => Providers::OpenRouter,
  "anthropic" => Providers::Anthropic,
  "gemini" => Providers::Gemini,
  "vertex_ai" => Providers::VertexAI,
  "bedrock" => Providers::Bedrock
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(adapters: {}) ⇒ ProviderRegistry

Creates a registry with optional adapter factories keyed by adapter name. Application adapters supplement the built-in provider adapters.



24
25
26
# File 'lib/little_ghost/provider_registry.rb', line 24

def initialize(adapters: {})
  @adapters = BUILT_INS.merge(adapters.to_h.transform_keys(&:to_s))
end

Instance Method Details

#build(adapter:, model:, configuration:, request: {}, **context) ⇒ Object

Constructs the configured provider for model.

Connection configuration remains authoritative. The trusted per-profile request mapping may adjust bounded request behavior, but cannot replace endpoints or credentials.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/little_ghost/provider_registry.rb', line 33

def build(adapter:, model:, configuration:, request: {}, **context)
  factory = @adapters.fetch(adapter.to_s) do
    raise AdapterLoadError, "Unknown provider adapter: #{adapter}"
  end
  options = symbolize(configuration).reject { |key, value| key == :adapter || value.nil? }
  request_options = symbolize(request).reject { |_key, value| value.nil? }
  unsupported = request_options.keys - REQUEST_OPTIONS
  unless unsupported.empty?
    raise ConfigurationError, "Unsupported request options for #{adapter}: #{unsupported.join(", ")}"
  end
  if request_options.key?(:retries)
    request_options[:max_retries] ||= request_options[:retries]
    request_options.delete(:retries)
  end
  if factory.is_a?(Class)
    unless factory <= Providers::Base
      raise AdapterLoadError, "Provider adapter #{adapter} must inherit LittleGhost::Providers::Base"
    end

    request_options.select! { |key| factory.request_options.include?(key) }
  end
  options.merge!(request_options)
  provider = if factory.is_a?(Class)
    factory.new(model:, **options)
  else
    factory.call(model:, configuration: options, **context)
  end
  unless provider.is_a?(Providers::Base)
    raise AdapterLoadError, "Provider adapter #{adapter} must return a LittleGhost::Providers::Base"
  end

  provider
rescue ArgumentError => error
  raise unless error.message.match?(/unknown keyword|missing keyword/)

  raise ConfigurationError, "Invalid configuration for #{adapter}: #{error.message}"
end