From f3cf41faaf5621f41061520ffcc12b7ed4c625ea Mon Sep 17 00:00:00 2001 From: spandan_mondal Date: Mon, 9 Dec 2024 22:07:48 +0530 Subject: [PATCH 1/2] translation fix for action --- kairon/multilingual/processor.py | 46 ++++++++----- .../multilingual_processor_test.py | 66 ++++++++++++++++++- 2 files changed, 94 insertions(+), 18 deletions(-) diff --git a/kairon/multilingual/processor.py b/kairon/multilingual/processor.py index 2da8ac025..a27a28d3a 100644 --- a/kairon/multilingual/processor.py +++ b/kairon/multilingual/processor.py @@ -9,6 +9,7 @@ from loguru import logger import re from ..exceptions import AppException +from ..shared.data.action_serializer import ActionSerializer from ..shared.data.utils import DataUtility @@ -124,23 +125,29 @@ def translate_responses_for_http_actions(actions: list): action['response']['value'] = str(translated_action[i]) return actions - - action_config[ActionType.http_action] = translate_responses_for_http_actions( - action_config[ActionType.http_action]) - action_config[ActionType.email_action] = translate_responses(action_config[ActionType.email_action]) - action_config[ActionType.jira_action] = translate_responses(action_config[ActionType.jira_action]) - action_config[ActionType.zendesk_action] = translate_responses(action_config[ActionType.zendesk_action]) - action_config[ActionType.pipedrive_leads_action] = translate_responses( - action_config[ActionType.pipedrive_leads_action]) - action_config[ActionType.google_search_action] = translate_responses( - action_config[ActionType.google_search_action], ['failure_response']) - action_config[ActionType.form_validation_action] = translate_responses( - action_config[ActionType.form_validation_action], ['valid_response', 'invalid_response']) + if action_config.get(ActionType.http_action.value): + action_config[ActionType.http_action.value] = translate_responses_for_http_actions( + action_config[ActionType.http_action.value]) + if action_config.get(ActionType.email_action.value): + action_config[ActionType.email_action.value] = translate_responses(action_config[ActionType.email_action.value]) + if action_config.get(ActionType.jira_action.value): + action_config[ActionType.jira_action.value] = translate_responses(action_config[ActionType.jira_action.value]) + if action_config.get(ActionType.zendesk_action.value): + action_config[ActionType.zendesk_action.value] = translate_responses(action_config[ActionType.zendesk_action.value]) + if action_config.get(ActionType.pipedrive_leads_action.value): + action_config[ActionType.pipedrive_leads_action.value] = translate_responses( + action_config[ActionType.pipedrive_leads_action.value]) + if action_config.get(ActionType.google_search_action.value): + action_config[ActionType.google_search_action.value] = translate_responses( + action_config[ActionType.google_search_action.value], ['failure_response']) + if action_config.get(ActionType.form_validation_action.value): + action_config[ActionType.form_validation_action.value] = translate_responses( + action_config[ActionType.form_validation_action.value], ['valid_response', 'invalid_response']) return action_config def __save_bot_files(self, new_bot_id: str, nlu: TrainingData, domain: Domain, actions: dict, configs: dict, - stories: StoryGraph, rules: StoryGraph): + stories: StoryGraph, rules: StoryGraph, other_collections: dict = None): """ Saving translated bot files into new bot :param new_bot_id: id of new bot @@ -149,8 +156,12 @@ def __save_bot_files(self, new_bot_id: str, nlu: TrainingData, domain: Domain, a :return: None """ self.mp.delete_domain(bot=new_bot_id, user=self.user) - - self.mp.save_integrated_actions(actions=actions, bot=new_bot_id, user=self.user) + ActionSerializer.deserialize(bot=new_bot_id, + user=self.user, + actions = actions, + other_collections_data=other_collections, + overwrite=True) + # self.mp.save_integrated_actions(actions=actions, bot=new_bot_id, user=self.user) self.mp.save_domain(domain=domain, bot=new_bot_id, user=self.user) self.mp.save_nlu(nlu=nlu, bot=new_bot_id, user=self.user) self.mp.save_config(configs=configs, bot=new_bot_id, user=self.user) @@ -186,7 +197,8 @@ def create_multilingual_bot(self, base_bot_id: str, base_bot_name: str, s_lang: nlu = self.mp.load_nlu(bot=base_bot_id) domain = self.mp.load_domain(bot=base_bot_id) - actions = self.mp.load_action_configurations(bot=base_bot_id) + actions, other_collections = ActionSerializer.serialize(bot=base_bot_id) + # actions = self.mp.load_action_configurations(bot=base_bot_id) configs = self.mp.load_config(bot=base_bot_id) stories = self.mp.load_stories(bot=base_bot_id).story_steps rules = self.mp.get_rules_for_training(bot=base_bot_id).story_steps @@ -218,7 +230,7 @@ def create_multilingual_bot(self, base_bot_id: str, base_bot_name: str, s_lang: logger.info(f"Created new bot with bot_id: {str(new_bot_id)}") self.__save_bot_files(new_bot_id=new_bot_id, nlu=nlu, domain=domain, actions=actions, configs=configs, - stories=stories, rules=rules) + stories=stories, rules=rules, other_collections=other_collections) logger.info("Saved translated bot files successfully.") except Exception as e: diff --git a/tests/unit_test/multilingual/multilingual_processor_test.py b/tests/unit_test/multilingual/multilingual_processor_test.py index ee81ad4dc..cbdf29afa 100644 --- a/tests/unit_test/multilingual/multilingual_processor_test.py +++ b/tests/unit_test/multilingual/multilingual_processor_test.py @@ -13,7 +13,6 @@ from google.cloud.translate_v3 import TranslationServiceClient from google.oauth2 import service_account from unittest.mock import patch -from mongomock import MongoClient class TestMultilingualProcessor: @@ -618,3 +617,68 @@ def _mock_service_account(*args, **kwargs): translated_text = Translator.translate_text_bulk(['translation text'], 'en', 'es') assert not translated_text + + + @patch('kairon.shared.multilingual.utils.translator.Translator.translate_text_bulk') + def test_translate_responses(self, mock_translate): + mock_translate.side_effect = lambda text, s_lang, d_lang: [f"translated_{t}" for t in text] + + action_config = { + "http_action": [{"response": {"value": "hello"}}], + "email_action": [{"response": "hello"}], + "jira_action": [{"response": "hello"}], + "zendesk_action": [{"response": "hello"}], + "pipedrive_leads_action": [{"response": "hello"}], + "google_search_action": [{"failure_response": "not_found"}], + "form_validation_action": [{"valid_response": "valid", "invalid_response": "invalid"}] + } + + expected = { + "http_action": [{"response": {"value": "translated_hello"}}], + "email_action": [{"response": "translated_hello"}], + "jira_action": [{"response": "translated_hello"}], + "zendesk_action": [{"response": "translated_hello"}], + "pipedrive_leads_action": [{"response": "translated_hello"}], + "google_search_action": [{"failure_response": "translated_not_found"}], + "form_validation_action": [{"valid_response": "translated_valid", "invalid_response": "translated_invalid"}] + } + + s_lang = "en" + d_lang = "fr" + result = MultilingualTranslator._MultilingualTranslator__translate_actions(action_config, s_lang, d_lang) + + assert result == expected + mock_translate.assert_called() + + @patch('kairon.shared.multilingual.utils.translator.Translator.translate_text_bulk') + def test_empty_action_config(self, mock_translate): + mock_translate.return_value = [] + + action_config = {} + s_lang = "en" + d_lang = "fr" + + result = MultilingualTranslator._MultilingualTranslator__translate_actions(action_config, s_lang, d_lang) + + assert result == {} + mock_translate.assert_not_called() + + @patch('kairon.shared.multilingual.utils.translator.Translator.translate_text_bulk') + def test_translate_actions_missing_fields(self, mock_translate): + mock_translate.return_value = ["translated_value"] + + action_config = { + "http_action": [{"response": {}}], + "email_action": [{}], + } + + expected = { + "http_action": [{"response": {}}], + "email_action": [{}], + } + + s_lang = "en" + d_lang = "fr" + with pytest.raises(Exception): + result = MultilingualTranslator._MultilingualTranslator__translate_actions(action_config, s_lang, d_lang) + From 20811b380989802f5bb440cbca10925a541e05f1 Mon Sep 17 00:00:00 2001 From: spandan_mondal Date: Tue, 10 Dec 2024 09:42:03 +0530 Subject: [PATCH 2/2] removed unnecessary comments --- kairon/multilingual/processor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/kairon/multilingual/processor.py b/kairon/multilingual/processor.py index a27a28d3a..01670a2f5 100644 --- a/kairon/multilingual/processor.py +++ b/kairon/multilingual/processor.py @@ -161,7 +161,6 @@ def __save_bot_files(self, new_bot_id: str, nlu: TrainingData, domain: Domain, a actions = actions, other_collections_data=other_collections, overwrite=True) - # self.mp.save_integrated_actions(actions=actions, bot=new_bot_id, user=self.user) self.mp.save_domain(domain=domain, bot=new_bot_id, user=self.user) self.mp.save_nlu(nlu=nlu, bot=new_bot_id, user=self.user) self.mp.save_config(configs=configs, bot=new_bot_id, user=self.user) @@ -198,7 +197,6 @@ def create_multilingual_bot(self, base_bot_id: str, base_bot_name: str, s_lang: nlu = self.mp.load_nlu(bot=base_bot_id) domain = self.mp.load_domain(bot=base_bot_id) actions, other_collections = ActionSerializer.serialize(bot=base_bot_id) - # actions = self.mp.load_action_configurations(bot=base_bot_id) configs = self.mp.load_config(bot=base_bot_id) stories = self.mp.load_stories(bot=base_bot_id).story_steps rules = self.mp.get_rules_for_training(bot=base_bot_id).story_steps