refactor(captain): route conversation completion by feature (#15317)

Conversation completion evaluations now use a dedicated internal LLM
feature with GPT 4.1 as the default. The internal route keeps the
completion model separate from the installation wide Captain model
override and from the assistant route, which can use GPT 5.2 for Captain
V2 accounts. Evaluations continue to use the installation API key and do
not consume Captain response credits.

## What changed

Added an internal `conversation_completion` feature to the LLM model
config and excluded internal features from account preferences, the
Captain settings API, and Super Admin model overrides.

Updated `Captain::ConversationCompletionService` to resolve its model
through `Llm::FeatureRouter`.

Added focused service and request coverage for model routing and
settings visibility.
This commit is contained in:
Aakash Bakhle
2026-08-13 13:54:35 +05:30
committed by GitHub
parent eff7ce2898
commit 13de83d1dc
7 changed files with 66 additions and 4 deletions

View File

@@ -16,7 +16,8 @@ class Captain::ConversationCompletionService < Captain::BaseTaskService
return default_incomplete_response('No messages found') if content.blank?
response = make_api_call(
model: InstallationConfig.find_by(name: 'CAPTAIN_OPEN_AI_MODEL')&.value.presence || GPT_MODEL,
feature: 'conversation_completion',
model: self_hosted_model_override,
messages: [
{ role: 'system', content: prompt_from_file('conversation_completion') },
{ role: 'user', content: content }
@@ -31,6 +32,12 @@ class Captain::ConversationCompletionService < Captain::BaseTaskService
private
def self_hosted_model_override
return unless ChatwootApp.self_hosted_enterprise?
InstallationConfig.find_by(name: 'CAPTAIN_OPEN_AI_MODEL')&.value.presence
end
def prompt_from_file(file_name)
Rails.root.join('enterprise/lib/captain/prompts', "#{file_name}.liquid").read
end