Class: PromptObjects::LLM::Factory
- Inherits:
-
Object
- Object
- PromptObjects::LLM::Factory
- Defined in:
- lib/prompt_objects/llm/factory.rb
Overview
Factory for creating LLM adapters based on provider name. Provides a unified interface for switching between providers.
Constant Summary collapse
- PROVIDERS =
{ "openai" => { adapter: "OpenAIAdapter", env_key: "OPENAI_API_KEY", default_model: "gpt-5.6-luna", models: %w[gpt-5.6-luna gpt-5.6-terra gpt-5.6-sol gpt-5.4-mini gpt-5.4-nano gpt-5.2 gpt-4.1 gpt-4.1-mini] }, "anthropic" => { adapter: "AnthropicAdapter", env_key: "ANTHROPIC_API_KEY", default_model: "claude-haiku-4-5", models: %w[claude-haiku-4-5 claude-sonnet-4-5 claude-opus-4] }, "gemini" => { adapter: "GeminiAdapter", env_key: "GEMINI_API_KEY", default_model: "gemini-3.5-flash", models: %w[gemini-3.5-flash gemini-3.1-flash-lite gemini-3-flash-preview gemini-2.5-pro gemini-2.5-flash] }, "ollama" => { adapter: "OpenAIAdapter", env_key: nil, api_key_default: "ollama", default_model: "llama3.2", models: [], # Dynamic — populated from Ollama API base_url: "http://localhost:11434/v1", local: true }, "openrouter" => { adapter: "OpenAIAdapter", env_key: "OPENROUTER_API_KEY", default_model: "meta-llama/llama-3.3-70b-instruct", models: %w[ meta-llama/llama-3.3-70b-instruct meta-llama/llama-4-scout meta-llama/llama-4-maverick mistralai/mistral-large-2411 google/gemma-3-27b-it deepseek/deepseek-r1 qwen/qwen-2.5-72b-instruct ], base_url: "https://openrouter.ai/api/v1", extra_headers: { "HTTP-Referer" => "https://github.com/prompt-objects", "X-Title" => "PromptObjects" } } }.freeze
- DEFAULT_PROVIDER =
"anthropic"
Class Method Summary collapse
-
.available_providers ⇒ Hash<String, Boolean>
Check which providers are available (have API keys or are local).
-
.create(provider: nil, model: nil, api_key: nil) ⇒ OpenAIAdapter, ...
Create an adapter for the given provider.
-
.default_model(provider) ⇒ String?
Get the default model for a provider.
-
.discover_ollama_models(base_url = "http://localhost:11434/v1") ⇒ Array<String>
Discover installed Ollama models.
-
.models_for(provider) ⇒ Array<String>
Get available models for a provider.
-
.provider_info(provider) ⇒ Hash?
Get info about a provider.
-
.providers ⇒ Array<String>
List available providers.
Class Method Details
.available_providers ⇒ Hash<String, Boolean>
Check which providers are available (have API keys or are local).
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/prompt_objects/llm/factory.rb', line 105 def available_providers PROVIDERS.transform_values do |config| if config[:local] check_local_provider(config[:base_url]) elsif config[:env_key] ENV.key?(config[:env_key]) else true end end end |
.create(provider: nil, model: nil, api_key: nil) ⇒ OpenAIAdapter, ...
Create an adapter for the given provider.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/prompt_objects/llm/factory.rb', line 68 def create(provider: nil, model: nil, api_key: nil) provider_name = (provider || DEFAULT_PROVIDER).to_s.downcase config = PROVIDERS[provider_name] raise Error, "Unknown LLM provider: #{provider_name}" unless config # Resolve API key: explicit > env var > default resolved_key = api_key || (config[:env_key] && ENV[config[:env_key]]) || config[:api_key_default] adapter_class = LLM.const_get(config[:adapter]) adapter_args = { api_key: resolved_key, model: model || config[:default_model] } adapter_args[:base_url] = config[:base_url] if config[:base_url] adapter_args[:extra_headers] = config[:extra_headers] if config[:extra_headers] # Pass provider name for usage tracking (OpenAI adapter handles multiple providers) adapter_args[:provider_name] = provider_name if config[:adapter] == "OpenAIAdapter" adapter_class.new(**adapter_args) end |
.default_model(provider) ⇒ String?
Get the default model for a provider.
120 121 122 |
# File 'lib/prompt_objects/llm/factory.rb', line 120 def default_model(provider) PROVIDERS.dig(provider.to_s.downcase, :default_model) end |
.discover_ollama_models(base_url = "http://localhost:11434/v1") ⇒ Array<String>
Discover installed Ollama models.
144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/prompt_objects/llm/factory.rb', line 144 def discover_ollama_models(base_url = "http://localhost:11434/v1") # Ollama's model list endpoint is at /api/tags (not under /v1) = base_url.sub(%r{/v1\z}, "") + "/api/tags" uri = URI() response = Net::HTTP.get_response(uri) return [] unless response.is_a?(Net::HTTPSuccess) data = JSON.parse(response.body) (data["models"] || []).map { |m| m["name"] } rescue StandardError [] end |
.models_for(provider) ⇒ Array<String>
Get available models for a provider. For Ollama, dynamically discovers installed models.
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/prompt_objects/llm/factory.rb', line 128 def models_for(provider) config = PROVIDERS[provider.to_s.downcase] return [] unless config # Dynamic model discovery for Ollama if config[:local] && provider.to_s.downcase == "ollama" models = discover_ollama_models(config[:base_url]) return models unless models.empty? end config[:models] || [] end |
.provider_info(provider) ⇒ Hash?
Get info about a provider.
99 100 101 |
# File 'lib/prompt_objects/llm/factory.rb', line 99 def provider_info(provider) PROVIDERS[provider.to_s.downcase] end |
.providers ⇒ Array<String>
List available providers.
92 93 94 |
# File 'lib/prompt_objects/llm/factory.rb', line 92 def providers PROVIDERS.keys end |