Class: Labimotion::UserAiSettings
- Inherits:
-
Object
- Object
- Labimotion::UserAiSettings
- Defined in:
- lib/labimotion/libs/user_ai_settings.rb
Overview
Per-user LabIMotion AI settings: the model, an optional personal API key and an optional provider endpoint of one's own.
These used to sit in the host's profile jsonb. They now live in our own user_settings table under the 'ai' key, because the settings are LabIMotion's and the host's profile is not a good place to keep growing them — see Labimotion::UserSetting.
The API key is stored ENCRYPTED and never returned to a client: only whether
one is set. Encryption stays the HOST's — key management is a deployment
concern and a gem has no business inventing one. Chemotion supplies it as an
Encryptor concern, pulled in below when present. A host that names its
encryption differently defines encrypt_value / decrypt_value instead.
settings = Labimotion::UserAiSettings.for(current_user)
settings.model # => 'azure.gpt-4.1'
settings.api_key? # => true (never the key itself, to a client)
settings.update(model: 'azure.gpt-5')
store is injectable so the shape can be exercised without a database.
Constant Summary collapse
- KEY =
Labimotion::Constants::UserSettingKey::AI
Instance Attribute Summary collapse
-
#user_id ⇒ Object
readonly
rubocop:enable Layout/EmptyLinesAfterModuleInclusion.
Class Method Summary collapse
-
.for(user, store: Labimotion::UserSetting) ⇒ Object
From whatever the host calls a user.
Instance Method Summary collapse
-
#api_key ⇒ Object
Decrypted personal API key, or nil when none is stored.
- #api_key? ⇒ Boolean
- #api_path ⇒ Object
-
#base_url ⇒ Object
Personal provider endpoint (BYO-Provider).
-
#initialize(user_id, store: Labimotion::UserSetting) ⇒ UserAiSettings
constructor
A new instance of UserAiSettings.
- #model ⇒ Object
- #settings ⇒ Object
-
#summary ⇒ Object
What is safe to hand a client: everything but the key, which is reported only as set-or-not.
-
#update(model: nil, api_key: nil, base_url: nil, api_path: nil) ⇒ Object
Persist the settings.
Constructor Details
#initialize(user_id, store: Labimotion::UserSetting) ⇒ UserAiSettings
Returns a new instance of UserAiSettings.
40 41 42 43 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 40 def initialize(user_id, store: Labimotion::UserSetting) @user_id = user_id @store = store end |
Instance Attribute Details
#user_id ⇒ Object (readonly)
rubocop:enable Layout/EmptyLinesAfterModuleInclusion
38 39 40 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 38 def user_id @user_id end |
Class Method Details
.for(user, store: Labimotion::UserSetting) ⇒ Object
From whatever the host calls a user. Accepts the record or a bare id.
46 47 48 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 46 def self.for(user, store: Labimotion::UserSetting) new(user.respond_to?(:id) ? user.id : user, store: store) end |
Instance Method Details
#api_key ⇒ Object
Decrypted personal API key, or nil when none is stored.
74 75 76 77 78 79 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 74 def api_key enc = settings['api_key'] return nil if enc.blank? decrypt_value(enc).presence end |
#api_key? ⇒ Boolean
69 70 71 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 69 def api_key? settings['api_key'].present? end |
#api_path ⇒ Object
65 66 67 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 65 def api_path settings['api_path'].presence end |
#base_url ⇒ Object
Personal provider endpoint (BYO-Provider). Honored only alongside a personal key, and SSRF-validated by Labimotion::AiEgressGuard before any request is made.
61 62 63 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 61 def base_url settings['base_url'].presence end |
#model ⇒ Object
54 55 56 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 54 def model settings['model'].presence end |
#settings ⇒ Object
50 51 52 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 50 def settings @store.settings_for(@user_id, KEY) end |
#summary ⇒ Object
What is safe to hand a client: everything but the key, which is reported only as set-or-not.
83 84 85 86 87 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 83 def summary stored = settings { model: stored['model'], api_key_set: stored['api_key'].present?, base_url: stored['base_url'], api_path: stored['api_path'] } end |
#update(model: nil, api_key: nil, base_url: nil, api_path: nil) ⇒ Object
Persist the settings. For every field: nil leaves it unchanged, a blank string clears it, anything else is stored (the api_key encrypted). Returns the safe summary — never the key itself.
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/labimotion/libs/user_ai_settings.rb', line 92 def update(model: nil, api_key: nil, base_url: nil, api_path: nil) @store.update_settings(@user_id, KEY) do |ai| set_or_clear(ai, 'model', model) set_or_clear_api_key(ai, api_key) set_or_clear(ai, 'base_url', base_url) set_or_clear(ai, 'api_path', api_path) ai end summary end |