diff --git a/enterprise/app/services/captain/llm/conversation_faq_service.rb b/enterprise/app/services/captain/llm/conversation_faq_service.rb index de281dee6..aae67cd0d 100644 --- a/enterprise/app/services/captain/llm/conversation_faq_service.rb +++ b/enterprise/app/services/captain/llm/conversation_faq_service.rb @@ -152,11 +152,11 @@ class Captain::Llm::ConversationFaqService < Llm::BaseAiService end def open_suggestions_for_language - assistant.faq_suggestions.open.by_language(faq_language) + assistant.faq_suggestions.where(account_id: conversation.account_id).open.by_language(faq_language) end def approved_faqs_for_language - return assistant.responses.approved if faq_language == account_language + return assistant.responses.approved if base_language(faq_language) == base_language(account_language) assistant.responses.none end @@ -226,8 +226,12 @@ class Captain::Llm::ConversationFaqService < Llm::BaseAiService language.to_s.tr('-', '_') end + def base_language(language) + language.split('_').first + end + def language_name(language) - ISO_639.find(language.split('_').first)&.english_name&.downcase || 'english' + ISO_639.find(base_language(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 b4302447f..554900979 100644 --- a/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb +++ b/spec/enterprise/services/captain/llm/conversation_faq_service_spec.rb @@ -275,6 +275,36 @@ RSpec.describe Captain::Llm::ConversationFaqService do end end + context 'when conversation and account locales share a base language' do + let(:account) { create(:account, locale: 'pt_BR') } + let(:captain_assistant) { create(:captain_assistant, account: account) } + let(:conversation) do + create(:conversation, account: account, first_reply_created_at: Time.zone.now, + additional_attributes: { conversation_language: 'pt' }) + end + let!(:existing_response) do + create(:captain_assistant_response, assistant: captain_assistant, account: account, + question: 'Como ativo o recurso?', answer: 'Ative nas configuracoes.', + embedding: embedding_one) + end + let(:equivalence_response) { instance_double(RubyLLM::Message, content: { same_faq: true }.to_json) } + + before do + existing_response + 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 'deduplicates against approved FAQs in the same base language' do + expect do + service.generate_and_deduplicate + end.to change(Captain::FaqObservation.discarded, :count).by(2) + expect(captain_assistant.faq_suggestions.count).to be_zero + end + end + context 'when LLM API fails' do before do allow(mock_chat).to receive(:ask).and_raise(RubyLLM::Error.new(nil, 'API Error'))