Class: Insika::LLMProviderStore
- Inherits:
-
Object
- Object
- Insika::LLMProviderStore
- Includes:
- Coercion
- Defined in:
- lib/insika/llm_provider_store.rb
Overview
LLM providers authored at runtime. One record per
provider in the ConfigStore (scope "llm_providers"), keyed by the API slug
(deepseek, openai, ...). Holds base_url/auth_header/models and the api_key.
The api_key NEVER leaves here in plaintext to the UI: the display reads
(get/all) mask it with the __OCULTO__ sentinel. Only all_raw/get_raw
(consumed by the LLMConfigurator, never by the screen) return the real key.
On write, the sentinel coming back preserves the key; a new string replaces it; ""
clears it (see Insika::SecretMasking).
Constant Summary collapse
- SCOPE =
"llm_providers"
Instance Method Summary collapse
-
#all ⇒ Object
-> [Hash] all MASKED (for the UI).
-
#all_raw ⇒ Object
-> [Hash] all with REAL api_key (for the configurator).
-
#apis ⇒ Object
-> [String] slugs, lexicographic order.
-
#delete(api) ⇒ Object
-> bool (did it exist?).
-
#get(api) ⇒ Object
-> MASKED Hash | nil.
-
#get_raw(api) ⇒ Object
-> Hash with REAL api_key | nil.
-
#initialize(config_store:) ⇒ LLMProviderStore
constructor
A new instance of LLMProviderStore.
-
#upsert(attrs) ⇒ Object
Upsert with secret reconciliation.
Methods included from Coercion
blank?, deep_stringify, presence, present?, utf8
Constructor Details
#initialize(config_store:) ⇒ LLMProviderStore
Returns a new instance of LLMProviderStore.
18 19 20 |
# File 'lib/insika/llm_provider_store.rb', line 18 def initialize(config_store:) @cs = config_store end |
Instance Method Details
#all ⇒ Object
-> [Hash] all MASKED (for the UI).
36 37 38 |
# File 'lib/insika/llm_provider_store.rb', line 36 def all apis.filter_map { |a| get(a) } end |
#all_raw ⇒ Object
-> [Hash] all with REAL api_key (for the configurator). Never goes to the screen.
41 42 43 |
# File 'lib/insika/llm_provider_store.rb', line 41 def all_raw apis.filter_map { |a| raw(a) } end |
#apis ⇒ Object
-> [String] slugs, lexicographic order.
33 |
# File 'lib/insika/llm_provider_store.rb', line 33 def apis = @cs.keys(SCOPE) |
#delete(api) ⇒ Object
-> bool (did it exist?).
66 |
# File 'lib/insika/llm_provider_store.rb', line 66 def delete(api) = @cs.delete(SCOPE, api.to_s) |
#get(api) ⇒ Object
-> MASKED Hash | nil.
23 24 25 |
# File 'lib/insika/llm_provider_store.rb', line 23 def get(api) mask(raw(api)) end |
#get_raw(api) ⇒ Object
-> Hash with REAL api_key | nil. Internal use (LLMConfigurator).
28 29 30 |
# File 'lib/insika/llm_provider_store.rb', line 28 def get_raw(api) raw(api) end |
#upsert(attrs) ⇒ Object
Upsert with secret reconciliation. attrs (string|symbol keys):
api (required), base_url, auth_header, api_key (sentinel-aware), models[]
-> MASKED Hash (the stored record).
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/insika/llm_provider_store.rb', line 48 def upsert(attrs) h = symbolize(attrs) api = presence(h[:api]) raise Insika::ValidationError, "api is required" if api.nil? existing = raw(api) record = { "api" => api, "base_url" => presence(h[:base_url]), "auth_header" => presence(h[:auth_header]), "api_key" => SecretMasking.reconcile(h[:api_key], existing&.fetch("api_key", nil)), "models" => Array(h[:models]).map(&:to_s) } @cs.put(SCOPE, api, record) mask(record) end |