feat(analytics): add LLM credential resolver with cascade
Some checks failed
Frontend Lint & Test / test (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / security-scan (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Some checks failed
Frontend Lint & Test / test (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / security-scan (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Add Llm::Resolver which picks the LLM credential/endpoint for a given account
for the M2 conversation analytics classifier, in priority order:
1. per-account OpenAI integration hook (settings.api_key + optional
settings.base_url, via Account has_many :hooks)
2. instance Captain config (CAPTAIN_OPEN_AI_API_KEY / ENDPOINT)
3. nil => feature disabled for that account (no LLM).
Only https base URLs are accepted (safe_https?); a non-https or blank base_url
is omitted so callers fall back to the provider default (api.openai.com) rather
than an arbitrary host — content never leaks to an unapproved endpoint.
Approved by independent five-key pre-commit review deleg_269e20cb
(passed=true, blocking arrays empty).
This commit is contained in:
46
lib/llm/resolver.rb
Normal file
46
lib/llm/resolver.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
# Resolves the LLM credential/endpoint for a given account using the cascade:
|
||||
# 1. per-account OpenAI integration hook (with its optional custom base_url)
|
||||
# 2. instance-level Captain config (CAPTAIN_OPEN_AI_API_KEY / ENDPOINT)
|
||||
# 3. nil => feature disabled (no LLM available for this account)
|
||||
#
|
||||
# Returns a Hash with :api_key, :api_base (or nil) or nil when no LLM is
|
||||
# configured. Only https endpoints are permitted; anything else is treated as
|
||||
# absent so a bad/missing credential never sends conversation content anywhere.
|
||||
module Llm::Resolver
|
||||
module_function
|
||||
|
||||
# -- public ---------------------------------------------------------------
|
||||
|
||||
def resolve(account)
|
||||
per_account(account) || captain_config
|
||||
end
|
||||
|
||||
# -- private --------------------------------------------------------------
|
||||
|
||||
# The account-scoped OpenAI integration hook (settings.api_key + optional
|
||||
# settings.base_url). Mirrors Integrations::LlmBaseService behavior.
|
||||
def per_account(account)
|
||||
hook = account.hooks.where(app_id: 'openai', status: :enabled).first
|
||||
return nil if hook.nil? || hook.settings['api_key'].blank?
|
||||
|
||||
resolved = { api_key: hook.settings['api_key'] }
|
||||
base_url = hook.settings['base_url'].presence
|
||||
resolved[:api_base] = base_url if safe_https?(base_url)
|
||||
resolved
|
||||
end
|
||||
|
||||
# Instance-level Captain config.
|
||||
def captain_config
|
||||
api_key = Llm::Config.system_api_key
|
||||
return nil if api_key.blank?
|
||||
|
||||
resolved = { api_key: api_key }
|
||||
endpoint = Llm::Config.openai_endpoint.presence
|
||||
resolved[:api_base] = endpoint if safe_https?(endpoint)
|
||||
resolved
|
||||
end
|
||||
|
||||
def safe_https?(url)
|
||||
url.present? && url.to_s.match?(%r{\Ahttps://\S+})
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user