Module: FlowEngine::LLM
- Defined in:
- lib/flowengine/llm.rb,
lib/flowengine/llm/client.rb,
lib/flowengine/llm/adapter.rb,
lib/flowengine/llm/adapters.rb,
lib/flowengine/llm/provider.rb,
lib/flowengine/llm/auto_client.rb,
lib/flowengine/llm/intake_prompt_builder.rb,
lib/flowengine/llm/sensitive_data_filter.rb,
lib/flowengine/llm/system_prompt_builder.rb,
lib/flowengine/llm/adapters/gemini_adapter.rb,
lib/flowengine/llm/adapters/openai_adapter.rb,
lib/flowengine/llm/adapters/anthropic_adapter.rb
Overview
Namespace for LLM integration: adapters, system prompt building, sensitive data filtering, and the high-level Client.
Defined Under Namespace
Modules: Adapters, SensitiveDataFilter Classes: Adapter, AutoClient, Client, IntakePromptBuilder, Provider, SystemPromptBuilder
Constant Summary collapse
- MODELS_YAML_PATH =
Path to the models.yml file (overridable via env var)
ENV.fetch( "FLOWENGINE_LLM_MODELS_PATH", File.join(::FlowEngine::ROOT, "resources", "models.yml") )
- VENDOR_CONFIG =
Vendor config loaded once from models.yml — used by Adapters module to dynamically generate adapter classes and by auto_client for detection.
(YAML.load_file(MODELS_YAML_PATH).dig("models", "vendors") || {}).freeze
- PROVIDERS =
Provider priority for auto-detection: [kwarg_name, env_var, adapter_class_name]
VENDOR_CONFIG.map do |_vendor, properties| [properties["var"].downcase.to_sym, properties["var"], properties["adapter"]] end.freeze
- ADAPTERS =
Pre-loaded adapters registry: { "vendor" => { "qualifier" => adapter } }
{}
- ADAPTERS_MUTEX =
rubocop:disable Style/MutableConstant -- intentionally mutable registry
Mutex.new
- QUALIFIERS =
%i[top default fastest].freeze
Class Method Summary collapse
-
.[](vendor:, qualifier: :default) ⇒ Object
Looks up a pre-loaded adapter by vendor and qualifier.
-
.auto_client(anthropic_api_key: nil, openai_api_key: nil, gemini_api_key: nil, model: nil) ⇒ Client
Builds an adapter and Client by detecting which API key is available.
-
.load!(file = MODELS_YAML_PATH) ⇒ Object
Pre-loads adapters from models.yml into ADAPTERS registry.
-
.reset! ⇒ Object
Resets the loaded state (useful for testing).
Class Method Details
.[](vendor:, qualifier: :default) ⇒ Object
Looks up a pre-loaded adapter by vendor and qualifier.
87 88 89 |
# File 'lib/flowengine/llm.rb', line 87 def [](vendor:, qualifier: :default) ADAPTERS.dig(vendor.to_s, qualifier.to_s) end |
.auto_client(anthropic_api_key: nil, openai_api_key: nil, gemini_api_key: nil, model: nil) ⇒ Client
Builds an adapter and Client by detecting which API key is available. Priority order matches models.yml vendor order (Anthropic > OpenAI > Gemini).
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/flowengine/llm.rb', line 39 def auto_client(anthropic_api_key: nil, openai_api_key: nil, gemini_api_key: nil, model: nil) explicit_keys = { anthropic_api_key: anthropic_api_key, openai_api_key: openai_api_key, gemini_api_key: gemini_api_key } PROVIDERS.each do |kwarg, env_var, adapter_class_name| key = explicit_keys[kwarg] || ENV.fetch(env_var, nil) next unless key adapter_class = ::FlowEngine.constantize(adapter_class_name) adapter = adapter_class.new(api_key: key) return Client.new(adapter: adapter, model: model || adapter.model) end env_vars = PROVIDERS.map { |_, env_var, _| env_var }.join(", ") raise ::FlowEngine::Errors::LLMError, "No LLM API key found. Set #{env_vars}" end |
.load!(file = MODELS_YAML_PATH) ⇒ Object
Pre-loads adapters from models.yml into ADAPTERS registry. Call explicitly when you want pre-instantiated adapters (e.g. in bin/ask).
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/flowengine/llm.rb', line 61 def load!(file = MODELS_YAML_PATH) return if @adapters_loaded raise ::FlowEngine::Errors::ConfigurationError, "Models file #{file} not found" unless file && File.exist?(file) count = 0 ::YAML.load_file(file)["models"]["vendors"].each_pair do |vendor, properties| api_key = ENV.fetch(properties["var"], nil) unless api_key warn "API key for #{vendor} not found in environment, vendor disabled." next end adapter_class = ::FlowEngine.constantize(properties["adapter"]) QUALIFIERS.each do |qualifier| model = properties[qualifier.to_s] adapter = adapter_class.new(api_key: api_key, model: model, qualifier: qualifier) add_adapter(adapter) count += 1 end end @adapters_loaded = true warn "Loaded #{count} adapters for #{ADAPTERS.keys.size} vendors." end |
.reset! ⇒ Object
Resets the loaded state (useful for testing).
92 93 94 95 |
# File 'lib/flowengine/llm.rb', line 92 def reset! ADAPTERS_MUTEX.synchronize { ADAPTERS.clear } @adapters_loaded = false end |