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).
47 lines
1.6 KiB
Ruby
47 lines
1.6 KiB
Ruby
# 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
|