feat: Add support for multi-language support for Captain (#11068)

This PR implements the following features

- FAQs from conversations will be generated in account language
- Contact notes will be generated in account language
- Copilot chat will respond in user language, unless the agent asks the
question in a different language

## Changes
### Copilot Chat

- Update the prompt to include an instruction for the language, the bot
will reply in asked language, but will default to account language
- Update the `ChatService` class to include pass the language to
`SystemPromptsService`

### FAQ and Contact note generation

- Update contact note generator and conversation generator to include
account locale
- Pass the account locale to `SystemPromptsService`


<details><summary>Screenshots</summary>

#### FAQs being generated in system langauge

![CleanShot 2025-03-12 at 13 32
30@2x](https://github.com/user-attachments/assets/84685bd8-3785-4432-aff3-419f60d96dd3)


#### Copilot responding in system language

![CleanShot 2025-03-12 at 13 47
03@2x](https://github.com/user-attachments/assets/38383293-4228-47bd-b74a-773e9a194f90)


</details>

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
Shivam Mishra
2025-03-20 06:55:33 +05:30
committed by GitHub
parent 51ad80a61e
commit 3a4249da11
13 changed files with 136 additions and 13 deletions

View File

@@ -20,7 +20,8 @@ module Enterprise::Api::V1::Accounts::ConversationsController
response = Captain::Copilot::ChatService.new(
assistant,
previous_messages: copilot_params[:previous_messages],
conversation_history: @conversation.to_llm_text
conversation_history: @conversation.to_llm_text,
language: @conversation.account.locale_english_name
).generate_response(copilot_params[:message])
render json: { message: response['response'] }

View File

@@ -9,6 +9,7 @@ class Captain::Copilot::ChatService < Llm::BaseOpenAiService
@assistant = assistant
@conversation_history = config[:conversation_history]
@previous_messages = config[:previous_messages] || []
@language = config[:language] || 'english'
@messages = [system_message, conversation_history_context] + @previous_messages
@response = ''
end
@@ -27,7 +28,7 @@ class Captain::Copilot::ChatService < Llm::BaseOpenAiService
def system_message
{
role: 'system',
content: Captain::Llm::SystemPromptsService.copilot_response_generator(@assistant.config['product_name'])
content: Captain::Llm::SystemPromptsService.copilot_response_generator(@assistant.config['product_name'], @language)
}
end

View File

@@ -26,7 +26,9 @@ class Captain::Llm::ContactNotesService < Llm::BaseOpenAiService
end
def chat_parameters
prompt = Captain::Llm::SystemPromptsService.notes_generator
account_language = @conversation.account.locale_english_name
prompt = Captain::Llm::SystemPromptsService.notes_generator(account_language)
{
model: @model,
response_format: { type: 'json_object' },

View File

@@ -89,7 +89,9 @@ class Captain::Llm::ConversationFaqService < Llm::BaseOpenAiService
end
def chat_parameters
prompt = Captain::Llm::SystemPromptsService.conversation_faq_generator
account_language = @conversation.account.locale_english_name
prompt = Captain::Llm::SystemPromptsService.conversation_faq_generator(account_language)
{
model: @model,
response_format: { type: 'json_object' },

View File

@@ -56,7 +56,7 @@ class Captain::Llm::SystemPromptsService
SYSTEM_PROMPT_MESSAGE
end
def copilot_response_generator(product_name)
def copilot_response_generator(product_name, language)
<<~SYSTEM_PROMPT_MESSAGE
[Identity]
You are Captain, a helpful and friendly copilot assistant for support agents using the product #{product_name}. Your primary role is to assist support agents by retrieving information, compiling accurate responses, and guiding them through customer interactions.
@@ -67,6 +67,7 @@ class Captain::Llm::SystemPromptsService
[Response Guidelines]
- Use natural, polite, and conversational language that is clear and easy to follow. Keep sentences short and use simple words.
- Reply in the language the agent is using, if you're not able to detect the language, reply in #{language}.
- Provide brief and relevant responsestypically one or two sentences unless a more detailed explanation is necessary.
- Do not use your own training data or assumptions to answer queries. Base responses strictly on the provided information.
- If the query is unclear, ask concise clarifying questions instead of making assumptions.