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

@@ -128,6 +128,14 @@ class Account < ApplicationRecord
}
end
def locale_english_name
# the locale can also be something like pt_BR, en_US, fr_FR, etc.
# the format is `<locale_code>_<country_code>`
# we need to extract the language code from the locale
account_locale = locale&.split('_')&.first
ISO_639.find(account_locale)&.english_name&.downcase || 'english'
end
private
def notify_creation

View File

@@ -48,4 +48,8 @@ module AssignmentHandler
create_assignee_change_activity(user_name)
end
end
def self_assign?(assignee_id)
assignee_id.present? && Current.user&.id == assignee_id
end
end

View File

@@ -125,6 +125,10 @@ class Conversation < ApplicationRecord
last_message_in_messaging_window?(messaging_window)
end
def language
additional_attributes&.dig('conversation_language')
end
def last_activity_at
self[:last_activity_at] || created_at
end
@@ -257,10 +261,6 @@ class Conversation < ApplicationRecord
)
end
def self_assign?(assignee_id)
assignee_id.present? && Current.user&.id == assignee_id
end
def load_attributes_created_by_db_triggers
# Display id is set via a trigger in the database
# So we need to specifically fetch it after the record is created