Class: OllamaAgent::Providers::Router

Inherits:
Base
  • Object
show all
Defined in:
lib/ollama_agent/providers/router.rb

Overview

Routes chat requests to the first available provider. Falls back through the list on errors or unavailability.

Examples:

router = OllamaAgent::Providers::Router.new(
  providers: [
    OllamaAgent::Providers::Ollama.new,
    OllamaAgent::Providers::OpenAI.new(api_key: ENV["OPENAI_API_KEY"])
  ],
  strategy: :first_available   # or :round_robin, :cheapest
)

Constant Summary collapse

STRATEGIES =
%i[first_available round_robin cheapest].freeze
ProviderUnavailableError =
Class.new(defined?(OllamaAgent::Error) ? OllamaAgent::Error : StandardError)

Instance Attribute Summary

Attributes inherited from Base

#name

Instance Method Summary collapse

Methods inherited from Base

#estimate_cost, #streaming_supported?, #to_s

Constructor Details

#initialize(providers:, strategy: :first_available, on_fallback: nil) ⇒ Router

Returns a new instance of Router.



23
24
25
26
27
28
29
# File 'lib/ollama_agent/providers/router.rb', line 23

def initialize(providers:, strategy: :first_available, on_fallback: nil, **)
  super(name: "router", **)
  @providers  = Array(providers)
  @strategy   = STRATEGIES.include?(strategy.to_sym) ? strategy.to_sym : :first_available
  @on_fallback = on_fallback # optional: lambda(from, to, reason)
  @rr_index = 0
end

Instance Method Details

#available?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/ollama_agent/providers/router.rb', line 49

def available?
  @providers.any?(&:available?)
end

#available_providersObject



53
54
55
# File 'lib/ollama_agent/providers/router.rb', line 53

def available_providers
  @providers.select(&:available?)
end

#chat(messages:, model:, **kwargs) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ollama_agent/providers/router.rb', line 31

def chat(messages:, model:, **kwargs)
  candidates = ordered_providers
  last_error = nil

  candidates.each do |provider|
    next unless provider.available?

    return provider.chat(messages: messages, model: model, **kwargs)
  rescue OllamaAgent::Error, StandardError => e
    last_error = e
    next_provider = candidates[candidates.index(provider).to_i + 1]
    @on_fallback&.call(provider.name, next_provider.name, e.message) if next_provider
    next
  end

  raise ProviderUnavailableError, build_unavailable_message(last_error)
end

#provider_statusObject



57
58
59
60
61
# File 'lib/ollama_agent/providers/router.rb', line 57

def provider_status
  @providers.map do |p|
    { name: p.name, available: p.available?, streaming: p.streaming_supported? }
  end
end