Module: Rubino::LLM::CredentialCheck
- Defined in:
- lib/rubino/llm/credential_check.rb
Overview
Single source of truth for “does the configured model have a usable credential?” — shared by the chat boot preflight (fail-fast before the ~80s retry storm, #93), the onboarding wizard, and ‘doctor`.
It answers two questions the same way the adapter resolves them at call time (ProviderResolver + RubyLLMAdapter#*_compatible_api_key!), so a preflight “no key” verdict matches what the model call would actually hit:
* resolved_provider(config) — the concrete provider the model id /
model.provider resolves to (interprets "auto").
* usable?(config) — true when a key for that provider is
resolvable from config (providers.<name>.api_key) or the native ENV
var, false otherwise.
Class Method Summary collapse
-
.missing_key_message(config = Rubino.configuration) ⇒ Object
A clear, actionable message for an unconfigured provider/model — the text surfaced on the fail-fast path and in non-interactive contexts.
- .present?(value) ⇒ Boolean
-
.provider_env_key(provider) ⇒ Object
The native ENV credential a provider reads when no config key is set.
-
.provider_env_var_name(provider) ⇒ Object
The ENV var NAME we’d suggest the user set for a given provider — used by the actionable error message and the wizard.
-
.resolved_provider(config = Rubino.configuration) ⇒ Object
The concrete provider the configured model will be routed to.
-
.usable?(config = Rubino.configuration) ⇒ Boolean
True when a credential for the resolved provider is available.
Class Method Details
.missing_key_message(config = Rubino.configuration) ⇒ Object
A clear, actionable message for an unconfigured provider/model — the text surfaced on the fail-fast path and in non-interactive contexts.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rubino/llm/credential_check.rb', line 76 def (config = Rubino.configuration) provider = resolved_provider(config) env_var = provider_env_var_name(provider) <<~MSG.strip No API key configured for provider '#{provider}' (model #{config.model_default}). Set it up one of these ways: • run `rubino setup` for a guided first-run setup, or • add #{env_var}=<your-key> to #{Config::Loader.new.env_path}, or • set providers.#{provider}.api_key in #{Config::Loader.new.config_path}. MSG end |
.present?(value) ⇒ Boolean
88 89 90 |
# File 'lib/rubino/llm/credential_check.rb', line 88 def present?(value) !value.nil? && !value.to_s.empty? end |
.provider_env_key(provider) ⇒ Object
The native ENV credential a provider reads when no config key is set.
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/rubino/llm/credential_check.rb', line 48 def provider_env_key(provider) case provider when "openai" then ENV.fetch("OPENAI_API_KEY", nil) when "anthropic" then ENV.fetch("ANTHROPIC_API_KEY", nil) when "google" then ENV["GEMINI_API_KEY"] || ENV.fetch("GOOGLE_API_KEY", nil) when "bedrock" then ENV.fetch("BEDROCK_API_KEY", nil) when "minimax" then ENV.fetch("MINIMAX_API_KEY", nil) else # Unknown / self-hosted provider: no native ENV mapping. Fall back to # the OpenAI key, which most openai-compatible backends accept. ENV.fetch("OPENAI_API_KEY", nil) end end |
.provider_env_var_name(provider) ⇒ Object
The ENV var NAME we’d suggest the user set for a given provider — used by the actionable error message and the wizard.
64 65 66 67 68 69 70 71 72 |
# File 'lib/rubino/llm/credential_check.rb', line 64 def provider_env_var_name(provider) { "openai" => "OPENAI_API_KEY", "anthropic" => "ANTHROPIC_API_KEY", "google" => "GEMINI_API_KEY", "bedrock" => "BEDROCK_API_KEY", "minimax" => "MINIMAX_API_KEY" }.fetch(provider, "#{provider.to_s.upcase}_API_KEY") end |
.resolved_provider(config = Rubino.configuration) ⇒ Object
The concrete provider the configured model will be routed to. Mirrors DoctorCommand#resolved_provider and the adapter’s resolution: an explicit model.provider (not “auto”) wins; otherwise derive from the model id.
24 25 26 27 28 29 |
# File 'lib/rubino/llm/credential_check.rb', line 24 def resolved_provider(config = Rubino.configuration) configured = config.model_provider return configured if configured && configured != "auto" ProviderResolver.resolve(config.model_default.to_s) end |
.usable?(config = Rubino.configuration) ⇒ Boolean
True when a credential for the resolved provider is available. The “fake” provider needs no upstream key. Honours providers.<name>.api_key first (custom / openai-compatible / anthropic-compatible gateways), then the provider’s native ENV var — the same order RubyLLMAdapter uses.
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rubino/llm/credential_check.rb', line 35 def usable?(config = Rubino.configuration) provider = resolved_provider(config) return true if provider == "fake" prov_cfg = config.provider_config(provider) return true if present?(prov_cfg["api_key"]) return present?(ENV.fetch("OPENAI_API_KEY", nil)) if prov_cfg["openai_compatible"] == true return present?(ENV.fetch("ANTHROPIC_API_KEY", nil)) if prov_cfg["anthropic_compatible"] == true present?(provider_env_key(provider)) end |