# Pull Request Template ## Description Adjusts the Captain LLM feature defaults after feature routing so the defaults stay intentional and avoid unintended high-cost model upgrades. Assistant, copilot, and onboarding content generation now default to `gpt-4.1`; audio transcription keeps `gpt-4o-mini-transcribe` as the default while exposing `whisper-1` as an available account override option. Related: https://linear.app/chatwoot/issue/CW-7425/test-new-models ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - `ruby -ryaml -e 'yaml = YAML.load_file("config/llm.yml"); features = yaml.fetch("features"); models = yaml.fetch("models"); features.each { |name, cfg| missing = Array(cfg["models"]) - models.keys; raise "#{name}: missing #{missing.join(",")}" if missing.any?; raise "#{name}: default not in models" unless Array(cfg["models"]).include?(cfg["default"]) }'` - `node -e "JSON.parse(require('fs').readFileSync('app/javascript/dashboard/i18n/locale/en/settings.json', 'utf8'))"` - `pnpm exec prettier --check app/javascript/dashboard/i18n/locale/en/settings.json` - `bundle exec rspec spec/lib/llm/feature_router_spec.rb spec/enterprise/services/llm/base_ai_service_spec.rb spec/enterprise/models/concerns/agentable_spec.rb spec/enterprise/services/messages/audio_transcription_service_spec.rb spec/models/concerns/captain_featurable_spec.rb spec/models/account_spec.rb spec/controllers/api/v1/accounts/captain/preferences_controller_spec.rb spec/controllers/super_admin/accounts_controller_spec.rb` - `bundle exec rspec spec/enterprise/services/captain/llm/article_translation_service_spec.rb spec/enterprise/services/messages/audio_transcription_service_spec.rb spec/enterprise/services/llm/base_ai_service_spec.rb` - `RUBOCOP_CACHE_ROOT=/private/tmp/rubocop_cache bundle exec rubocop enterprise/app/services/captain/llm/article_translation_service.rb enterprise/app/services/messages/audio_transcription_service.rb spec/enterprise/services/captain/llm/article_translation_service_spec.rb spec/enterprise/services/llm/base_ai_service_spec.rb spec/enterprise/services/messages/audio_transcription_service_spec.rb` - `git diff --check` ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules
84 lines
3.2 KiB
Ruby
84 lines
3.2 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe Captain::Llm::ArticleTranslationService do
|
|
let(:account) { create(:account) }
|
|
let(:target_language) { 'Spanish' }
|
|
|
|
before do
|
|
InstallationConfig.where(name: %w[CAPTAIN_OPEN_AI_API_KEY CAPTAIN_OPEN_AI_MODEL]).destroy_all
|
|
create(:installation_config, name: 'CAPTAIN_OPEN_AI_API_KEY', value: 'test-key')
|
|
allow(account).to receive(:feature_enabled?).and_call_original
|
|
allow(account).to receive(:feature_enabled?).with('captain_tasks').and_return(true)
|
|
end
|
|
|
|
describe '#perform with type: :title' do
|
|
let(:service) do
|
|
described_class.new(account: account, text: 'Getting Started', target_language: target_language, type: :title)
|
|
end
|
|
|
|
it 'returns the stripped translated title' do
|
|
expect(service).to receive(:make_api_call) do |args|
|
|
expect(args[:feature]).to eq('help_center_article_generation')
|
|
expect(args[:model]).to eq(Llm::Config::DEFAULT_MODEL)
|
|
expect(args[:messages][0][:content]).to include('professional translator')
|
|
expect(args[:messages][0][:content]).to include(target_language)
|
|
expect(args[:messages][1][:content]).to eq('Getting Started')
|
|
{ message: " Primeros pasos \n" }
|
|
end
|
|
|
|
expect(service.perform).to include(message: 'Primeros pasos')
|
|
end
|
|
|
|
it 'uses the installation model when no account override is configured' do
|
|
create(:installation_config, name: 'CAPTAIN_OPEN_AI_MODEL', value: 'gpt-4.1-nano')
|
|
|
|
expect(service).to receive(:make_api_call).with(
|
|
hash_including(
|
|
feature: 'help_center_article_generation',
|
|
model: 'gpt-4.1-nano'
|
|
)
|
|
).and_return(message: 'Primeros pasos')
|
|
|
|
expect(service.perform).to include(message: 'Primeros pasos')
|
|
end
|
|
end
|
|
|
|
describe '#perform with type: :content' do
|
|
let(:content) { "# Welcome\nSome markdown." }
|
|
let(:service) do
|
|
described_class.new(account: account, text: content, target_language: target_language, type: :content)
|
|
end
|
|
|
|
it 'returns the stripped translated content using the markdown system prompt' do
|
|
expect(service).to receive(:make_api_call) do |args|
|
|
expect(args[:messages][0][:content]).to include('markdown')
|
|
expect(args[:messages][0][:content]).to include('Preserve ALL HTML tags')
|
|
expect(args[:messages][1][:content]).to eq(content)
|
|
{ message: "# Bienvenido\nAlgo de markdown.\n" }
|
|
end
|
|
|
|
expect(service.perform).to include(message: "# Bienvenido\nAlgo de markdown.")
|
|
end
|
|
end
|
|
|
|
describe '#perform with an invalid type' do
|
|
it 'raises ArgumentError' do
|
|
service = described_class.new(account: account, text: 'hi', target_language: target_language, type: :invalid)
|
|
|
|
expect { service.perform }.to raise_error(ArgumentError, /Invalid type/)
|
|
end
|
|
end
|
|
|
|
describe '#perform when the API call fails' do
|
|
let(:service) do
|
|
described_class.new(account: account, text: 'Getting Started', target_language: target_language, type: :title)
|
|
end
|
|
|
|
it 'returns the error hash unchanged' do
|
|
allow(service).to receive(:make_api_call).and_return(error: 'LLM timeout', error_code: 500)
|
|
|
|
expect(service.perform).to eq(error: 'LLM timeout', error_code: 500)
|
|
end
|
|
end
|
|
end
|