diff --git a/enterprise/app/services/captain/llm/conversation_faq_service.rb b/enterprise/app/services/captain/llm/conversation_faq_service.rb index 6c046b178..44c9f1960 100644 --- a/enterprise/app/services/captain/llm/conversation_faq_service.rb +++ b/enterprise/app/services/captain/llm/conversation_faq_service.rb @@ -115,7 +115,7 @@ class Captain::Llm::ConversationFaqService < Llm::BaseAiService end def approved_faqs_for_language - return assistant.responses.approved if base_language(faq_language) == base_language(account_language) + return assistant.responses.approved if faq_language == account_language assistant.responses.none end @@ -182,15 +182,11 @@ class Captain::Llm::ConversationFaqService < Llm::BaseAiService end def normalize_language(language) - language.to_s.tr('-', '_') - end - - def base_language(language) - language.split('_').first + language.to_s.tr('-', '_').split('_').first.downcase end def language_name(language) - ISO_639.find(base_language(language))&.english_name&.downcase || 'english' + ISO_639.find(language)&.english_name&.downcase || 'english' end def parse_generation_response(response) diff --git a/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb b/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb index e247f6020..9c2021190 100644 --- a/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb +++ b/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb @@ -248,11 +248,46 @@ RSpec.describe Captain::Llm::ConversationFaqService do service.generate_and_deduplicate end.to change(captain_assistant.faq_suggestions, :count).by(1) - expect(captain_assistant.faq_suggestions.pluck(:language)).to contain_exactly('en', 'pt_BR') + expect(captain_assistant.faq_suggestions.pluck(:language)).to contain_exactly('en', 'pt') expect(existing_suggestion.reload.source_count).to eq(1) end end + context 'when an open suggestion uses another locale variant of the same language' do + let(:account) { create(:account, locale: 'pt_BR') } + let(:captain_assistant) { create(:captain_assistant, account: account) } + let(:conversation) { create(:conversation, account: account, first_reply_created_at: Time.zone.now) } + let(:sample_faqs) { [{ 'question' => 'Como ativo o recurso?', 'answer' => 'Ative nas configuracoes.' }] } + let(:existing_suggestion) do + captain_assistant.faq_suggestions.create!( + question: 'Como habilito o recurso?', + answer: 'Ative nas configuracoes.', + embedding: embedding_one, + language: 'pt', + source_count: 1 + ) + end + let(:equivalence_response) { instance_double(RubyLLM::Message, content: { same_faq: true }.to_json) } + + before do + existing_suggestion + allow(embedding_service).to receive(:get_embedding).and_return(embedding_one) + allow(mock_chat).to receive(:ask) do |input| + input.start_with?('{') ? equivalence_response : mock_response + end + end + + it 'attaches the observation to the existing base-language suggestion' do + expect do + service.generate_and_deduplicate + end.to change(existing_suggestion.observations, :count).by(1) + + expect(existing_suggestion.reload.source_count).to eq(2) + expect(captain_assistant.faq_suggestions.count).to eq(1) + expect(existing_suggestion.observations.last.language).to eq('pt') + end + end + context 'when a similar approved FAQ uses the account language' do let(:sample_faqs) { [{ 'question' => 'Como ativo o recurso?', 'answer' => 'Ative nas configuracoes.' }] } @@ -269,7 +304,7 @@ RSpec.describe Captain::Llm::ConversationFaqService do service.generate_and_deduplicate end.to change(captain_assistant.faq_suggestions, :count).by(1) expect(Captain::FaqObservation.discarded.count).to be_zero - expect(captain_assistant.faq_suggestions.last.language).to eq('pt_BR') + expect(captain_assistant.faq_suggestions.last.language).to eq('pt') end end