Module: Durable::Llm::ProviderUtilities

Defined in:
lib/durable/llm/provider_utilities.rb

Overview

Utility methods for provider management and comparison

This module offers helper methods for:

  • Discovering available providers

  • Finding providers that support specific models

  • Comparing provider capabilities

  • Routing requests to appropriate providers

Examples:

Find provider for a model

provider = ProviderUtilities.provider_for_model('gpt-4')
# => :openai

Class Method Summary collapse

Class Method Details

.all_provider_infoArray<Hash>

Lists all providers with their capabilities

Examples:

List all provider capabilities

all = ProviderUtilities.all_provider_info

Returns:

  • (Array<Hash>)

    Array of provider information hashes



194
195
196
# File 'lib/durable/llm/provider_utilities.rb', line 194

def all_provider_info
  available_providers.map { |p| provider_info(p) }
end

.available_providersArray<Symbol>

Lists all available providers

Examples:

List providers

providers = ProviderUtilities.available_providers
# => [:openai, :anthropic, :google, ...]

Returns:

  • (Array<Symbol>)

    Array of provider names



29
30
31
# File 'lib/durable/llm/provider_utilities.rb', line 29

def available_providers
  Providers.available_providers
end

.compare_models(model_ids) ⇒ Hash

Compares models across providers based on common characteristics

Examples:

Compare models

comparison = ProviderUtilities.compare_models(['gpt-4', 'claude-3-opus-20240229'])

Parameters:

  • model_ids (Array<String>)

    Models to compare

Returns:

  • (Hash)

    Comparison data



105
106
107
108
109
110
111
112
113
114
# File 'lib/durable/llm/provider_utilities.rb', line 105

def compare_models(model_ids)
  model_ids.map do |model_id|
    provider = provider_for_model(model_id)
    {
      model: model_id,
      provider: provider,
      streaming: provider ? supports_capability?(provider, :streaming) : false
    }
  end
end

.complete_with_fallback(text, providers:, model_map: {}) ⇒ String?

Executes a completion with automatic provider fallback

Examples:

Completion with fallback

result = ProviderUtilities.complete_with_fallback(
  'Hello!',
  providers: [:openai, :anthropic],
  model_map: { openai: 'gpt-4', anthropic: 'claude-3-opus-20240229' }
)

Parameters:

  • text (String)

    The input text

  • providers (Array<Symbol>)

    Ordered providers to try

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

    Map of provider to model

Returns:

  • (String, nil)

    The completion text or nil if all fail



157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/durable/llm/provider_utilities.rb', line 157

def complete_with_fallback(text, providers:, model_map: {})
  providers.each do |provider|
    begin
      client = Durable::Llm.new(provider, model: model_map[provider])
      return client.complete(text)
    rescue StandardError => e
      warn "Provider #{provider} failed: #{e.message}"
      next
    end
  end

  nil # All providers failed
end

.fallback_chain(providers, options = {}) ⇒ Array<Durable::Llm::Client>

Creates a fallback chain of providers for redundancy

This method helps build resilient systems by providing fallback options when a primary provider is unavailable.

Examples:

Create fallback chain

clients = ProviderUtilities.fallback_chain(
  [:openai, :anthropic, :google],
  model_map: {
    openai: 'gpt-4',
    anthropic: 'claude-3-opus-20240229',
    google: 'gemini-pro'
  }
)

Parameters:

  • providers (Array<Symbol>)

    Ordered list of providers to try

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

    Configuration options

Returns:



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/durable/llm/provider_utilities.rb', line 133

def fallback_chain(providers, options = {})
  model_map = options[:model_map] || {}

  providers.map do |provider|
    model = model_map[provider]
    Durable::Llm.new(provider, model: model)
  rescue StandardError => e
    warn "Failed to create client for #{provider}: #{e.message}"
    nil
  end.compact
end

.models_for_provider(provider_name, **options) ⇒ Array<String>

Gets all models available for a provider

Examples:

Get OpenAI models

models = ProviderUtilities.models_for_provider(:openai)

Parameters:

  • provider_name (Symbol, String)

    The provider name

  • options (Hash)

    Provider configuration options

Returns:

  • (Array<String>)

    Array of model IDs



54
55
56
57
58
# File 'lib/durable/llm/provider_utilities.rb', line 54

def models_for_provider(provider_name, **options)
  Durable::Llm.models(provider_name, **options)
rescue StandardError
  []
end

.provider_for_model(model_id) ⇒ Symbol?

Finds the provider that supports a given model

Examples:

Find provider for GPT-4

provider = ProviderUtilities.provider_for_model('gpt-4')
# => :openai

Find provider for Claude

provider = ProviderUtilities.provider_for_model('claude-3-opus-20240229')
# => :anthropic

Parameters:

  • model_id (String)

    The model identifier

Returns:

  • (Symbol, nil)

    The provider name or nil if not found



43
44
45
# File 'lib/durable/llm/provider_utilities.rb', line 43

def provider_for_model(model_id)
  Providers.model_id_to_provider(model_id)
end

.provider_info(provider_name) ⇒ Hash

Gets provider information including capabilities

Examples:

Get provider info

info = ProviderUtilities.provider_info(:openai)
# => { name: :openai, streaming: true, embeddings: true, ... }

Parameters:

  • provider_name (Symbol, String)

    The provider name

Returns:

  • (Hash)

    Provider information



178
179
180
181
182
183
184
185
186
187
# File 'lib/durable/llm/provider_utilities.rb', line 178

def provider_info(provider_name)
  {
    name: provider_name,
    streaming: supports_capability?(provider_name, :streaming),
    embeddings: supports_capability?(provider_name, :embeddings),
    chat: supports_capability?(provider_name, :chat)
  }
rescue StandardError => e
  { name: provider_name, error: e.message }
end

.providers_with_capability(capability) ⇒ Array<Symbol>

Finds all providers that support a specific capability

Examples:

Find streaming providers

providers = ProviderUtilities.providers_with_capability(:streaming)
# => [:openai, :anthropic, :google, ...]

Parameters:

  • capability (Symbol)

    The capability to filter by

Returns:

  • (Array<Symbol>)

    Providers supporting the capability



93
94
95
96
97
# File 'lib/durable/llm/provider_utilities.rb', line 93

def providers_with_capability(capability)
  available_providers.select do |provider|
    supports_capability?(provider, capability)
  end
end

.supports_capability?(provider_name, capability) ⇒ Boolean

Checks if a provider supports a specific capability

Examples:

Check streaming support

supports = ProviderUtilities.supports_capability?(:openai, :streaming)
# => true

Parameters:

  • provider_name (Symbol, String)

    The provider name

  • capability (Symbol)

    The capability to check (:streaming, :embeddings, :chat)

Returns:

  • (Boolean)

    True if capability is supported



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/durable/llm/provider_utilities.rb', line 68

def supports_capability?(provider_name, capability)
  provider_class = Providers.provider_class_for(provider_name)
  instance = provider_class.new

  case capability
  when :streaming
    instance.respond_to?(:stream?) && instance.stream?
  when :embeddings
    instance.respond_to?(:embedding)
  when :chat, :completion
    instance.respond_to?(:completion)
  else
    false
  end
rescue StandardError
  false
end