From 77257e0ae44d389dc5150ae645690339ba49a519 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 02:08:41 +0100 Subject: [PATCH 01/13] fix:standardize_lang --- requirements/requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index cc8bf73a38e..9aa020a629b 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -3,12 +3,12 @@ python-dateutil>=2.6, <3.0 watchdog>=2.1, <3.0 combo-lock>=0.2.2, <0.3 -padacioso>=0.2.2,<1.0.0 -ovos-adapt-parser>=0.1.2, <1.0.0 -ovos_ocp_pipeline_plugin>=0.1.2, <1.0.0 -ovos-common-query-pipeline-plugin>=0.1.2, <1.0.0 +padacioso>=0.2.4,<1.0.0 +ovos-adapt-parser>=0.1.3, <1.0.0 +ovos_ocp_pipeline_plugin>=0.1.3, <1.0.0 +ovos-common-query-pipeline-plugin>=0.1.4, <1.0.0 -ovos-utils>=0.1.0,<1.0.0 +ovos-utils>=0.3.5,<1.0.0 ovos_bus_client>=0.1.0,<1.0.0 ovos-plugin-manager>=0.0.26,<1.0.0 ovos-config>=0.0.13,<1.0.0 From 4ebb7b3e958cc615fe454eb56bcb55e0bce9af35 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 02:21:09 +0100 Subject: [PATCH 02/13] fix:standardize_lang --- ovos_core/intent_services/__init__.py | 14 ++++++++------ ovos_core/intent_services/converse_service.py | 5 +++-- ovos_core/intent_services/stop_service.py | 11 ++++++----- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ovos_core/intent_services/__init__.py b/ovos_core/intent_services/__init__.py index 7e51f9fbd44..7cddd4a39fb 100644 --- a/ovos_core/intent_services/__init__.py +++ b/ovos_core/intent_services/__init__.py @@ -29,6 +29,7 @@ from ovos_core.intent_services.stop_service import StopService from ovos_core.transformers import MetadataTransformersService, UtteranceTransformersService from ovos_plugin_manager.templates.pipeline import IntentMatch +from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG, deprecated, log_deprecation from ovos_utils.metrics import Stopwatch from padacioso.opm import PadaciosoPipeline as PadaciosoService @@ -209,7 +210,7 @@ def _load_pipeline_plugins(self): @property def registered_intents(self): - lang = get_message_lang() + lang = standardize_lang_tag(get_message_lang()) return [parser.__dict__ for parser in self._adapt_service.engines[lang].intent_parsers] @@ -263,7 +264,7 @@ def _handle_transformers(self, message): Pipe utterance through transformer plugins to get more metadata. Utterances may be modified by any parser and context overwritten """ - lang = get_message_lang(message) # per query lang or default Configuration lang + lang = standardize_lang_tag(get_message_lang()) # per query lang or default Configuration lang original = utterances = message.data.get('utterances', []) message.context["lang"] = lang utterances, message.context = self.utterance_plugins.transform(utterances, message.context) @@ -281,7 +282,7 @@ def disambiguate_lang(message): 3 - detected_lang -> tagged by transformers (text classification, free form chat) 4 - config lang (or from message.data) """ - default_lang = get_message_lang(message) + default_lang = standardize_lang_tag(get_message_lang()) valid_langs = get_valid_languages() lang_keys = ["stt_lang", "request_lang", @@ -352,6 +353,7 @@ def get_pipeline(self, skips=None, session=None) -> Tuple[str, Callable]: def _validate_session(self, message, lang): # get session + lang = standardize_lang_tag(lang) sess = SessionManager.get(message) if sess.session_id == "default": updated = False @@ -525,7 +527,7 @@ def handle_register_vocab(self, message): entity_type = message.data.get('entity_type') regex_str = message.data.get('regex') alias_of = message.data.get('alias_of') - lang = get_message_lang(message) + lang = standardize_lang_tag(get_message_lang()) self._adapt_service.register_vocabulary(entity_value, entity_type, alias_of, regex_str, lang) self.registered_vocab.append(message.data) @@ -602,7 +604,7 @@ def handle_get_intent(self, message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = get_message_lang(message) + lang = standardize_lang_tag(get_message_lang()) sess = SessionManager.get(message) # Loop through the matching functions until a match is found. @@ -653,7 +655,7 @@ def handle_get_adapt(self, message: Message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = get_message_lang(message) + lang = standardize_lang_tag(get_message_lang()) intent = self._adapt_service.match_intent((utterance,), lang, message.serialize()) intent_data = intent.intent_data if intent else None self.bus.emit(message.reply("intent.service.adapt.reply", diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index 9e51db0285a..2dee8ddd416 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -9,6 +9,7 @@ from ovos_config.locale import setup_locale from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list +from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG from ovos_workshop.permissions import ConverseMode, ConverseActivationMode @@ -279,7 +280,7 @@ def converse(self, utterances, skill_id, lang, message): handled (bool): True if handled otherwise False. """ session = SessionManager.get(message) - session.lang = lang + session.lang = standardize_lang_tag(lang) state = session.utterance_states.get(skill_id, UtteranceState.INTENT) if state == UtteranceState.RESPONSE: @@ -384,7 +385,7 @@ def handle_deactivate_skill_request(self, message): def reset_converse(self, message): """Let skills know there was a problem with speech recognition""" - lang = get_message_lang(message) + lang = standardize_lang_tag(get_message_lang()) try: setup_locale(lang) # restore default lang except Exception as e: diff --git a/ovos_core/intent_services/stop_service.py b/ovos_core/intent_services/stop_service.py index 86a45e3f47c..81f6b1cf8d8 100644 --- a/ovos_core/intent_services/stop_service.py +++ b/ovos_core/intent_services/stop_service.py @@ -10,6 +10,7 @@ from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list from ovos_utils.bracket_expansion import expand_options +from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG from ovos_utils.parse import match_one @@ -25,7 +26,7 @@ def __init__(self, bus): def load_resource_files(self): base = f"{dirname(__file__)}/locale" for lang in os.listdir(base): - lang2 = lang.split("-")[0].lower() + lang2 = standardize_lang_tag(lang) self._voc_cache[lang2] = {} for f in os.listdir(f"{base}/{lang}"): with open(f"{base}/{lang}/{f}", encoding="utf-8") as fi: @@ -127,7 +128,7 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Returns: IntentMatch if handled otherwise None. """ - lang = lang.split("-")[0] + lang = standardize_lang_tag(lang) if lang not in self._voc_cache: return None @@ -178,7 +179,7 @@ def match_stop_medium(self, utterances: List[str], lang: str, message: Message) Returns: IntentMatch if handled otherwise None. """ - lang = lang.split("-")[0] + lang = standardize_lang_tag(lang) if lang not in self._voc_cache: return None @@ -205,7 +206,7 @@ def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Returns: IntentMatch if handled otherwise None. """ - lang = lang.split("-")[0] + lang = standardize_lang_tag(lang) if lang not in self._voc_cache: return None sess = SessionManager.get(message) @@ -266,7 +267,7 @@ def voc_match(self, utt: str, voc_filename: str, lang: str, Returns: bool: True if the utterance has the given vocabulary it """ - lang = lang.split("-")[0].lower() + lang = standardize_lang_tag(lang) if lang not in self._voc_cache: return False From ca7b0e02170a9366fe965c4d5977cac0fdd3525a Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 02:40:59 +0100 Subject: [PATCH 03/13] fix:standardize_lang --- requirements/lgpl.txt | 2 +- requirements/requirements.txt | 2 +- test/end2end/routing/test_sched.py | 2 +- test/end2end/routing/test_session.py | 2 +- test/end2end/session/test_blacklist.py | 6 ++-- test/end2end/session/test_complete_failure.py | 8 ++--- test/end2end/session/test_converse.py | 10 +++---- test/end2end/session/test_fallback.py | 6 ++-- test/end2end/session/test_get_response.py | 30 +++++++++---------- test/end2end/session/test_sched.py | 14 ++++----- test/end2end/session/test_session.py | 10 +++---- test/end2end/session/test_stop.py | 4 +-- test/end2end/session/test_transformers.py | 4 +-- 13 files changed, 50 insertions(+), 50 deletions(-) diff --git a/requirements/lgpl.txt b/requirements/lgpl.txt index 74a4b7a01a4..e92ee3c4a82 100644 --- a/requirements/lgpl.txt +++ b/requirements/lgpl.txt @@ -1,2 +1,2 @@ -ovos_padatious>=0.1.2,<1.0.0 +ovos_padatious>=0.1.3,<1.0.0 fann2>=1.0.7, < 1.1.0 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 9aa020a629b..ec2bdb1a1dd 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -9,7 +9,7 @@ ovos_ocp_pipeline_plugin>=0.1.3, <1.0.0 ovos-common-query-pipeline-plugin>=0.1.4, <1.0.0 ovos-utils>=0.3.5,<1.0.0 -ovos_bus_client>=0.1.0,<1.0.0 +ovos_bus_client>=0.1.4,<1.0.0 ovos-plugin-manager>=0.0.26,<1.0.0 ovos-config>=0.0.13,<1.0.0 ovos-lingua-franca>=0.4.7,<1.0.0 diff --git a/test/end2end/routing/test_sched.py b/test/end2end/routing/test_sched.py index 66a6350fdce..f9bf8000e13 100644 --- a/test/end2end/routing/test_sched.py +++ b/test/end2end/routing/test_sched.py @@ -16,7 +16,7 @@ def setUp(self): def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.pipeline = ["adapt_high"] messages = [] diff --git a/test/end2end/routing/test_session.py b/test/end2end/routing/test_session.py index d1777e13e16..5adce21102a 100644 --- a/test/end2end/routing/test_session.py +++ b/test/end2end/routing/test_session.py @@ -21,7 +21,7 @@ def tearDown(self) -> None: def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.pipeline = ["adapt_high"] messages = [] diff --git a/test/end2end/session/test_blacklist.py b/test/end2end/session/test_blacklist.py index 340bef1869d..11a3df6428e 100644 --- a/test/end2end/session/test_blacklist.py +++ b/test/end2end/session/test_blacklist.py @@ -21,7 +21,7 @@ def tearDown(self) -> None: def test_blacklist(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = ["adapt_high"] SessionManager.default_session.blacklisted_skills = [] SessionManager.default_session.blacklisted_intents = [] @@ -309,7 +309,7 @@ def tearDown(self) -> None: def test_fallback(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "fallback_high" ] @@ -400,7 +400,7 @@ def tearDown(self) -> None: def test_common_qa(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = ["common_qa"] messages = [] diff --git a/test/end2end/session/test_complete_failure.py b/test/end2end/session/test_complete_failure.py index b72c3ff8008..10da8f11d44 100644 --- a/test/end2end/session/test_complete_failure.py +++ b/test/end2end/session/test_complete_failure.py @@ -19,7 +19,7 @@ def tearDown(self) -> None: def test_complete_failure(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.active_skills = [(self.skill_id, time.time())] SessionManager.default_session.pipeline = [ "stop_high", @@ -105,7 +105,7 @@ def wait_for_n_messages(n): def test_complete_failure_lang_detect(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.active_skills = [(self.skill_id, time.time())] SessionManager.default_session.pipeline = [ "stop_high", @@ -144,7 +144,7 @@ def wait_for_n_messages(n): self.core.bus.on("message", new_msg) - SessionManager.default_session.valid_languages = ["en-us", stt_lang_detect, "fr-fr"] + SessionManager.default_session.valid_languages = ["en-US", stt_lang_detect, "fr-fr"] utt = Message("recognizer_loop:utterance", {"utterances": ["hello world"]}, {"session": SessionManager.default_session.serialize(), @@ -247,4 +247,4 @@ def wait_for_n_messages(n): self.assertEqual(messages[18].data["session_data"]["lang"], "pt-pt") self.assertEqual(SessionManager.default_session.lang, "pt-pt") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" diff --git a/test/end2end/session/test_converse.py b/test/end2end/session/test_converse.py index 4dc622c59a0..e7f0e2d3185 100644 --- a/test/end2end/session/test_converse.py +++ b/test/end2end/session/test_converse.py @@ -21,7 +21,7 @@ def tearDown(self) -> None: def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -85,7 +85,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # verify skill is activated self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") @@ -157,7 +157,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # verify that "lang" is injected by converse.ping # (missing in utterance message) and kept in all messages @@ -250,7 +250,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # converse self.assertEqual(messages[1].msg_type, f"{self.other_skill_id}.converse.ping") @@ -339,7 +339,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # converse self.assertEqual(messages[1].msg_type, f"{self.skill_id}.converse.ping") diff --git a/test/end2end/session/test_fallback.py b/test/end2end/session/test_fallback.py index edb0030240a..facdaba0667 100644 --- a/test/end2end/session/test_fallback.py +++ b/test/end2end/session/test_fallback.py @@ -19,7 +19,7 @@ def tearDown(self) -> None: def test_fallback(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "fallback_high", @@ -142,7 +142,7 @@ def wait_for_n_messages(n): def test_fallback_with_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "fallback_high", "fallback_medium", @@ -316,7 +316,7 @@ def tearDown(self) -> None: def test_fallback(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "fallback_medium", "fallback_low" diff --git a/test/end2end/session/test_get_response.py b/test/end2end/session/test_get_response.py index 73f80a1e69e..42fd20cf76c 100644 --- a/test/end2end/session/test_get_response.py +++ b/test/end2end/session/test_get_response.py @@ -20,7 +20,7 @@ def tearDown(self) -> None: def test_no_response(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -100,7 +100,7 @@ def on_speak(msg): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # verify intent triggers self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response.intent") @@ -125,7 +125,7 @@ def on_speak(msg): self.assertEqual(messages[7].msg_type, "enclosure.active_skill") self.assertEqual(messages[7].data["skill_id"], self.skill_id) self.assertEqual(messages[8].msg_type, "speak") - self.assertEqual(messages[8].data["lang"], "en-us") + self.assertEqual(messages[8].data["lang"], "en-US") self.assertTrue(messages[8].data["expect_response"]) # listen after dialog self.assertEqual(messages[8].data["meta"]["skill"], self.skill_id) self.assertEqual(messages[9].msg_type, "recognizer_loop:audio_output_start") @@ -142,7 +142,7 @@ def on_speak(msg): self.assertEqual(messages[14].msg_type, "enclosure.active_skill") self.assertEqual(messages[14].data["skill_id"], self.skill_id) self.assertEqual(messages[15].msg_type, "speak") - self.assertEqual(messages[15].data["lang"], "en-us") + self.assertEqual(messages[15].data["lang"], "en-US") self.assertFalse(messages[15].data["expect_response"]) self.assertEqual(messages[15].data["utterance"], "ERROR") self.assertEqual(messages[15].data["meta"]["skill"], self.skill_id) @@ -163,7 +163,7 @@ def on_speak(msg): def test_with_response(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -279,7 +279,7 @@ def answer_get_response(msg): self.assertEqual(messages[7].data["skill_id"], self.skill_id) self.assertEqual(messages[8].msg_type, "speak") self.assertEqual(messages[8].data["utterance"], "give me an answer", ) - self.assertEqual(messages[8].data["lang"], "en-us") + self.assertEqual(messages[8].data["lang"], "en-US") self.assertTrue(messages[8].data["expect_response"]) # listen after dialog self.assertEqual(messages[8].data["meta"]["skill"], self.skill_id) # ovos-audio speak execution (simulated) @@ -308,7 +308,7 @@ def answer_get_response(msg): self.assertEqual(messages[19].msg_type, "enclosure.active_skill") self.assertEqual(messages[19].data["skill_id"], self.skill_id) self.assertEqual(messages[20].msg_type, "speak") - self.assertEqual(messages[20].data["lang"], "en-us") + self.assertEqual(messages[20].data["lang"], "en-US") self.assertFalse(messages[20].data["expect_response"]) self.assertEqual(messages[20].data["utterance"], "ok") self.assertEqual(messages[20].data["meta"]["skill"], self.skill_id) @@ -329,7 +329,7 @@ def answer_get_response(msg): def test_cancel_response(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -445,7 +445,7 @@ def answer_get_response(msg): self.assertEqual(messages[7].data["skill_id"], self.skill_id) self.assertEqual(messages[8].msg_type, "speak") self.assertEqual(messages[8].data["utterance"], "give me an answer", ) - self.assertEqual(messages[8].data["lang"], "en-us") + self.assertEqual(messages[8].data["lang"], "en-US") self.assertTrue(messages[8].data["expect_response"]) # listen after dialog self.assertEqual(messages[8].data["meta"]["skill"], self.skill_id) # ovos-audio speak execution (simulated) @@ -473,7 +473,7 @@ def answer_get_response(msg): self.assertEqual(messages[19].msg_type, "enclosure.active_skill") self.assertEqual(messages[19].data["skill_id"], self.skill_id) self.assertEqual(messages[20].msg_type, "speak") - self.assertEqual(messages[20].data["lang"], "en-us") + self.assertEqual(messages[20].data["lang"], "en-US") self.assertFalse(messages[20].data["expect_response"]) self.assertEqual(messages[20].data["utterance"], "ERROR") self.assertEqual(messages[20].data["meta"]["skill"], self.skill_id) @@ -494,7 +494,7 @@ def answer_get_response(msg): def test_with_reprompt(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -629,7 +629,7 @@ def answer_get_response(msg): self.assertEqual(messages[18].msg_type, "enclosure.active_skill") self.assertEqual(messages[18].data["skill_id"], self.skill_id) self.assertEqual(messages[19].msg_type, "speak") - self.assertEqual(messages[19].data["lang"], "en-us") + self.assertEqual(messages[19].data["lang"], "en-US") self.assertFalse(messages[19].data["expect_response"]) self.assertEqual(messages[19].data["utterance"], "ok") self.assertEqual(messages[19].data["meta"]["skill"], self.skill_id) @@ -647,7 +647,7 @@ def answer_get_response(msg): def test_nested(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", @@ -801,7 +801,7 @@ def answer_get_response(msg): self.assertEqual(messages[5].msg_type, "enclosure.active_skill") self.assertEqual(messages[5].data["skill_id"], self.skill_id) self.assertEqual(messages[6].msg_type, "speak") - self.assertEqual(messages[6].data["lang"], "en-us") + self.assertEqual(messages[6].data["lang"], "en-US") self.assertFalse(messages[6].data["expect_response"]) self.assertEqual(messages[6].data["utterance"], "give me items") self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) @@ -847,7 +847,7 @@ def answer_get_response(msg): def test_kill_response(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "padatious_high", diff --git a/test/end2end/session/test_sched.py b/test/end2end/session/test_sched.py index ba08b77df4d..ef10a7b6640 100644 --- a/test/end2end/session/test_sched.py +++ b/test/end2end/session/test_sched.py @@ -16,7 +16,7 @@ def setUp(self): def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "adapt_high" ] @@ -74,7 +74,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # verify skill_id is now present in every message.context self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") @@ -94,7 +94,7 @@ def wait_for_n_messages(n): self.assertEqual(messages[5].msg_type, "enclosure.active_skill") self.assertEqual(messages[5].data["skill_id"], self.skill_id) self.assertEqual(messages[6].msg_type, "speak") - self.assertEqual(messages[6].data["lang"], "en-us") + self.assertEqual(messages[6].data["lang"], "en-US") self.assertFalse(messages[6].data["expect_response"]) self.assertEqual(messages[6].data["meta"]["dialog"], "done") self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) @@ -122,7 +122,7 @@ def wait_for_n_messages(n): self.assertEqual(messages[12].msg_type, "enclosure.active_skill") self.assertEqual(messages[12].context, intent_context) self.assertEqual(messages[13].msg_type, "speak") - self.assertEqual(messages[13].data["lang"], "en-us") + self.assertEqual(messages[13].data["lang"], "en-US") self.assertFalse(messages[13].data["expect_response"]) self.assertEqual(messages[13].data["meta"]["dialog"], "trigger") self.assertEqual(messages[13].data["meta"]["skill"], self.skill_id) @@ -131,7 +131,7 @@ def wait_for_n_messages(n): def test_explicit_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "adapt_high" ] @@ -212,7 +212,7 @@ def wait_for_n_messages(n): self.assertEqual(messages[5].msg_type, "enclosure.active_skill") self.assertEqual(messages[5].data["skill_id"], self.skill_id) self.assertEqual(messages[6].msg_type, "speak") - self.assertEqual(messages[6].data["lang"], "en-us") + self.assertEqual(messages[6].data["lang"], "en-US") self.assertFalse(messages[6].data["expect_response"]) self.assertEqual(messages[6].data["meta"]["dialog"], "done") self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) @@ -229,7 +229,7 @@ def wait_for_n_messages(n): self.assertEqual(messages[11].msg_type, "enclosure.active_skill") self.assertEqual(messages[11].context, intent_context) self.assertEqual(messages[12].msg_type, "speak") - self.assertEqual(messages[12].data["lang"], "en-us") + self.assertEqual(messages[12].data["lang"], "en-US") self.assertFalse(messages[12].data["expect_response"]) self.assertEqual(messages[12].data["meta"]["dialog"], "trigger") self.assertEqual(messages[12].data["meta"]["skill"], self.skill_id) diff --git a/test/end2end/session/test_session.py b/test/end2end/session/test_session.py index 14890d5606e..6fcc200ce4d 100644 --- a/test/end2end/session/test_session.py +++ b/test/end2end/session/test_session.py @@ -20,7 +20,7 @@ def tearDown(self) -> None: def test_no_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "adapt_high" ] @@ -73,7 +73,7 @@ def wait_for_n_messages(n): # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - self.assertEqual(m.context["lang"], "en-us") + self.assertEqual(m.context["lang"], "en-US") # verify skill is activated self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") @@ -105,7 +105,7 @@ def wait_for_n_messages(n): def test_explicit_default_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" now = time.time() SessionManager.default_session.active_skills = [(self.skill_id, now)] SessionManager.default_session.pipeline = [ @@ -206,7 +206,7 @@ def wait_for_n_messages(n): def test_explicit_session(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "converse", "adapt_high" @@ -295,7 +295,7 @@ def wait_for_n_messages(n): self.assertEqual(messages[7].msg_type, "enclosure.active_skill") self.assertEqual(messages[7].data["skill_id"], self.skill_id) self.assertEqual(messages[8].msg_type, "speak") - self.assertEqual(messages[8].data["lang"], "en-us") + self.assertEqual(messages[8].data["lang"], "en-US") self.assertFalse(messages[8].data["expect_response"]) self.assertEqual(messages[8].data["meta"]["dialog"], "hello.world") self.assertEqual(messages[8].data["meta"]["skill"], self.skill_id) diff --git a/test/end2end/session/test_stop.py b/test/end2end/session/test_stop.py index ac94f3901e4..c7c6c6c153a 100644 --- a/test/end2end/session/test_stop.py +++ b/test/end2end/session/test_stop.py @@ -20,7 +20,7 @@ def tearDown(self) -> None: def test_old_stop(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "stop_high", "adapt_high" @@ -196,7 +196,7 @@ def wait_for_n_messages(n): def test_new_stop(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.pipeline = [ "stop_high", "adapt_high", diff --git a/test/end2end/session/test_transformers.py b/test/end2end/session/test_transformers.py index 127816940a0..52584027943 100644 --- a/test/end2end/session/test_transformers.py +++ b/test/end2end/session/test_transformers.py @@ -32,7 +32,7 @@ def test_cancel(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.active_skills = [(self.skill_id, time.time())] SessionManager.default_session.pipeline = [ "stop_high", @@ -105,7 +105,7 @@ def test_meta(self): SessionManager.sessions = {} SessionManager.default_session = SessionManager.sessions["default"] = Session("default") - SessionManager.default_session.lang = "en-us" + SessionManager.default_session.lang = "en-US" SessionManager.default_session.active_skills = [(self.skill_id, time.time())] SessionManager.default_session.pipeline = [ "stop_high", From 3c89055bf479e2864550760d0a4ab39a874009bd Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 02:46:33 +0100 Subject: [PATCH 04/13] fix:standardize_lang --- test/unittests/test_intent_service.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unittests/test_intent_service.py b/test/unittests/test_intent_service.py index 023392e79ff..0ccdac65a7e 100644 --- a/test/unittests/test_intent_service.py +++ b/test/unittests/test_intent_service.py @@ -103,17 +103,17 @@ def test_no_lang_in_message(self): """No lang in message should result in lang from active locale.""" setup_locale("it-it") msg = Message('test msg', data={}) - self.assertEqual(get_message_lang(msg), 'it-it') + self.assertEqual(get_message_lang(msg), 'it-IT') setup_locale("en-us") - self.assertEqual(get_message_lang(msg), 'en-us') + self.assertEqual(get_message_lang(msg), 'en-US') @mock.patch.dict(Configuration._Configuration__patch, BASE_CONF) def test_lang_exists(self): """Message has a lang code in data, it should be used.""" msg = Message('test msg', data={'lang': 'de-de'}) - self.assertEqual(get_message_lang(msg), 'de-de') + self.assertEqual(get_message_lang(msg), 'de-DE') msg = Message('test msg', data={'lang': 'sv-se'}) - self.assertEqual(get_message_lang(msg), 'sv-se') + self.assertEqual(get_message_lang(msg), 'sv-SE') def create_old_style_vocab_msg(keyword, value): From 10b4eb7a322e149915a97b05847a7d3a6e5a9e2f Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 02:53:08 +0100 Subject: [PATCH 05/13] fix:standardize_lang --- ovos_core/intent_services/fallback_service.py | 2 ++ ovos_core/intent_services/stop_service.py | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/ovos_core/intent_services/fallback_service.py b/ovos_core/intent_services/fallback_service.py index 165a0b6bf45..5d1c7e8b3d6 100644 --- a/ovos_core/intent_services/fallback_service.py +++ b/ovos_core/intent_services/fallback_service.py @@ -22,6 +22,7 @@ from ovos_config import Configuration from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list +from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG from ovos_workshop.permissions import FallbackMode @@ -171,6 +172,7 @@ def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[Inten Returns: IntentMatch or None """ + lang = standardize_lang_tag(lang) # we call flatten in case someone is sending the old style list of tuples utterances = flatten_list(utterances) message.data["utterances"] = utterances # all transcripts diff --git a/ovos_core/intent_services/stop_service.py b/ovos_core/intent_services/stop_service.py index 81f6b1cf8d8..bdfda9c7c1a 100644 --- a/ovos_core/intent_services/stop_service.py +++ b/ovos_core/intent_services/stop_service.py @@ -4,8 +4,10 @@ from threading import Event from typing import Optional, List +from langcodes import closest_match from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager + from ovos_config.config import Configuration from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list @@ -22,6 +24,7 @@ def __init__(self, bus): self.bus = bus self._voc_cache = {} self.load_resource_files() + super().__init__() def load_resource_files(self): base = f"{dirname(__file__)}/locale" @@ -128,8 +131,8 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Returns: IntentMatch if handled otherwise None. """ - lang = standardize_lang_tag(lang) - if lang not in self._voc_cache: + lang = self._get_closest_lang(lang) + if lang is None: # no vocs registered for this lang return None sess = SessionManager.get(message) @@ -195,6 +198,18 @@ def match_stop_medium(self, utterances: List[str], lang: str, message: Message) return self.match_stop_low(utterances, lang, message) + def _get_closest_lang(self, lang: str) -> Optional[str]: + if self._voc_cache: + lang = standardize_lang_tag(lang) + closest, score = closest_match(lang, list(self._voc_cache.keys())) + # https://langcodes-hickford.readthedocs.io/en/sphinx/index.html#distance-values + # 0 -> These codes represent the same language, possibly after filling in values and normalizing. + # 1- 3 -> These codes indicate a minor regional difference. + # 4 - 10 -> These codes indicate a significant but unproblematic regional difference. + if score < 10: + return closest + return None + def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: """ before fallback_low , fuzzy match stop intent @@ -206,8 +221,8 @@ def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Returns: IntentMatch if handled otherwise None. """ - lang = standardize_lang_tag(lang) - if lang not in self._voc_cache: + lang = self._get_closest_lang(lang) + if lang is None: # no vocs registered for this lang return None sess = SessionManager.get(message) # we call flatten in case someone is sending the old style list of tuples @@ -267,8 +282,8 @@ def voc_match(self, utt: str, voc_filename: str, lang: str, Returns: bool: True if the utterance has the given vocabulary it """ - lang = standardize_lang_tag(lang) - if lang not in self._voc_cache: + lang = self._get_closest_lang(lang) + if lang is None: # no vocs registered for this lang return False _vocs = self._voc_cache[lang].get(voc_filename) or [] From 7ee49c3638f6380209cb75c3d8ce8137a2887fd4 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 03:40:07 +0100 Subject: [PATCH 06/13] fix:standardize_lang --- ovos_core/intent_services/stop_service.py | 14 +++----------- requirements/plugins.txt | 2 +- requirements/requirements.txt | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/ovos_core/intent_services/stop_service.py b/ovos_core/intent_services/stop_service.py index bdfda9c7c1a..54492d0d57c 100644 --- a/ovos_core/intent_services/stop_service.py +++ b/ovos_core/intent_services/stop_service.py @@ -24,7 +24,7 @@ def __init__(self, bus): self.bus = bus self._voc_cache = {} self.load_resource_files() - super().__init__() + super().__init__(config=Configuration().get("skills", {}).get("stop") or {}) def load_resource_files(self): base = f"{dirname(__file__)}/locale" @@ -38,14 +38,6 @@ def load_resource_files(self): n = f.split(".", 1)[0] self._voc_cache[lang2][n] = flatten_list(lines) - @property - def config(self): - """ - Returns: - stop_config (dict): config for stop handling options - """ - return Configuration().get("skills", {}).get("stop") or {} - def get_active_skills(self, message: Optional[Message] = None): """Active skill ids ordered by converse priority this represents the order in which stop will be called @@ -182,8 +174,8 @@ def match_stop_medium(self, utterances: List[str], lang: str, message: Message) Returns: IntentMatch if handled otherwise None. """ - lang = standardize_lang_tag(lang) - if lang not in self._voc_cache: + lang = self._get_closest_lang(lang) + if lang is None: # no vocs registered for this lang return None # we call flatten in case someone is sending the old style list of tuples diff --git a/requirements/plugins.txt b/requirements/plugins.txt index e4305a65330..c5e9c288726 100644 --- a/requirements/plugins.txt +++ b/requirements/plugins.txt @@ -1,5 +1,5 @@ ovos-utterance-corrections-plugin>=0.0.2, <1.0.0 -ovos-utterance-plugin-cancel>=0.2.0, <1.0.0 +ovos-utterance-plugin-cancel>=0.2.2, <1.0.0 ovos-bidirectional-translation-plugin>=0.1.0, <1.0.0 ovos-translate-server-plugin>=0.0.2, <1.0.0 ovos-utterance-normalizer>=0.2.1, <1.0.0 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index ec2bdb1a1dd..14d54b1f630 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -14,4 +14,4 @@ ovos-plugin-manager>=0.0.26,<1.0.0 ovos-config>=0.0.13,<1.0.0 ovos-lingua-franca>=0.4.7,<1.0.0 ovos-backend-client>=0.1.0,<2.0.0 -ovos-workshop>=0.0.16,<2.0.0 \ No newline at end of file +ovos-workshop>=1.0.1,<2.0.0 \ No newline at end of file From 634dbdfccf7ec20595d5bec37dfde6138182847c Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 03:51:29 +0100 Subject: [PATCH 07/13] fix:standardize_lang --- ovos_core/intent_services/converse_service.py | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index 2dee8ddd416..aa08a956956 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -1,17 +1,18 @@ import time from threading import Event -from typing import Optional +from typing import Optional, List from ovos_bus_client.message import Message -from ovos_bus_client.session import SessionManager, UtteranceState +from ovos_bus_client.session import SessionManager, UtteranceState, Session from ovos_bus_client.util import get_message_lang +from ovos_workshop.permissions import ConverseMode, ConverseActivationMode + from ovos_config.config import Configuration from ovos_config.locale import setup_locale from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG -from ovos_workshop.permissions import ConverseMode, ConverseActivationMode class ConverseService(PipelinePlugin): @@ -23,18 +24,10 @@ def __init__(self, bus): self.bus.on('mycroft.speech.recognition.unknown', self.reset_converse) self.bus.on('intent.service.skills.deactivate', self.handle_deactivate_skill_request) self.bus.on('intent.service.skills.activate', self.handle_activate_skill_request) - self.bus.on('active_skill_request', self.handle_activate_skill_request) # TODO backwards compat, deprecate self.bus.on('intent.service.active_skills.get', self.handle_get_active_skills) self.bus.on("skill.converse.get_response.enable", self.handle_get_response_enable) self.bus.on("skill.converse.get_response.disable", self.handle_get_response_disable) - - @property - def config(self): - """ - Returns: - converse_config (dict): config for converse handling options - """ - return Configuration().get("skills", {}).get("converse") or {} + super().__init__(config=Configuration().get("skills", {}).get("converse") or {}) @property def active_skills(self): @@ -48,7 +41,8 @@ def active_skills(self, val): for skill_id, ts in val: session.activate_skill(skill_id) - def get_active_skills(self, message=None): + @staticmethod + def get_active_skills(message: Optional[Message] = None) -> List[str]: """Active skill ids ordered by converse priority this represents the order in which converse will be called @@ -58,12 +52,14 @@ def get_active_skills(self, message=None): session = SessionManager.get(message) return [skill[0] for skill in session.active_skills] - def deactivate_skill(self, skill_id, source_skill=None, message=None): + def deactivate_skill(self, skill_id: str, source_skill: Optional[str] = None, + message: Optional[Message] = None): """Remove a skill from being targetable by converse. Args: skill_id (str): skill to remove source_skill (str): skill requesting the removal + message (Message): the bus message that requested deactivation """ source_skill = source_skill or skill_id if self._deactivate_allowed(skill_id, source_skill): @@ -82,7 +78,8 @@ def deactivate_skill(self, skill_id, source_skill=None, message=None): if skill_id in self._consecutive_activations: self._consecutive_activations[skill_id] = 0 - def activate_skill(self, skill_id, source_skill=None, message=None): + def activate_skill(self, skill_id: str, source_skill: Optional[str] = None, + message: Optional[Message] = None) -> Optional[Session]: """Add a skill or update the position of an active skill. The skill is added to the front of the list, if it's already in the @@ -91,6 +88,7 @@ def activate_skill(self, skill_id, source_skill=None, message=None): Args: skill_id (str): identifier of skill to be added. source_skill (str): skill requesting the removal + message (Message): the bus message that requested activation """ source_skill = source_skill or skill_id if self._activate_allowed(skill_id, source_skill): @@ -109,7 +107,7 @@ def activate_skill(self, skill_id, source_skill=None, message=None): self._consecutive_activations[skill_id] += 1 return session - def _activate_allowed(self, skill_id, source_skill=None): + def _activate_allowed(self, skill_id: str, source_skill: Optional[str] = None) -> bool: """Checks if a skill_id is allowed to jump to the front of active skills list - can a skill activate a different skill @@ -167,7 +165,7 @@ def _activate_allowed(self, skill_id, source_skill=None): return False # skill exceeded authorized consecutive number of activations return True - def _deactivate_allowed(self, skill_id, source_skill=None): + def _deactivate_allowed(self, skill_id: str, source_skill: Optional[str] = None) -> bool: """Checks if a skill_id is allowed to be removed from active skills list - can a skill deactivate a different skill @@ -187,7 +185,7 @@ def _deactivate_allowed(self, skill_id, source_skill=None): return False return True - def _converse_allowed(self, skill_id): + def _converse_allowed(self, skill_id: str) -> bool: """Checks if a skill_id is allowed to converse - is the skill blacklisted from conversing @@ -209,7 +207,7 @@ def _converse_allowed(self, skill_id): return False return True - def _collect_converse_skills(self, message): + def _collect_converse_skills(self, message: Message) -> List[str]: """use the messagebus api to determine which skills want to converse This includes all skills and external applications""" session = SessionManager.get(message) @@ -257,7 +255,7 @@ def handle_ack(msg): self.bus.remove("skill.converse.pong", handle_ack) return want_converse - def _check_converse_timeout(self, message): + def _check_converse_timeout(self, message: Message): """ filter active skill list based on timestamps """ timeouts = self.config.get("skill_timeouts") or {} def_timeout = self.config.get("timeout", 300) @@ -266,7 +264,7 @@ def _check_converse_timeout(self, message): skill for skill in session.active_skills if time.time() - skill[1] <= timeouts.get(skill[0], def_timeout)] - def converse(self, utterances, skill_id, lang, message): + def converse(self, utterances: List[str], skill_id: str, lang: str, message: Message) -> bool: """Call skill and ask if they want to process the utterance. Args: @@ -279,8 +277,9 @@ def converse(self, utterances, skill_id, lang, message): Returns: handled (bool): True if handled otherwise False. """ + lang = standardize_lang_tag(lang) session = SessionManager.get(message) - session.lang = standardize_lang_tag(lang) + session.lang = lang state = session.utterance_states.get(skill_id, UtteranceState.INTENT) if state == UtteranceState.RESPONSE: @@ -313,7 +312,7 @@ def converse(self, utterances, skill_id, lang, message): f'increasing "max_skill_runtime" in mycroft.conf might help alleviate this issue') return False - def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatch]: + def converse_with_skills(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: """Give active skills a chance at the utterance Args: @@ -324,6 +323,7 @@ def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatc Returns: IntentMatch if handled otherwise None. """ + lang = standardize_lang_tag(lang) session = SessionManager.get(message) # we call flatten in case someone is sending the old style list of tuples @@ -345,21 +345,23 @@ def converse_with_skills(self, utterances, lang, message) -> Optional[IntentMatc utterance=utterances[0]) return None - def handle_get_response_enable(self, message): + @staticmethod + def handle_get_response_enable(message: Message): skill_id = message.data["skill_id"] session = SessionManager.get(message) session.enable_response_mode(skill_id) if session.session_id == "default": SessionManager.sync(message) - def handle_get_response_disable(self, message): + @staticmethod + def handle_get_response_disable(message: Message): skill_id = message.data["skill_id"] session = SessionManager.get(message) session.disable_response_mode(skill_id) if session.session_id == "default": SessionManager.sync(message) - def handle_activate_skill_request(self, message): + def handle_activate_skill_request(self, message: Message): # TODO imperfect solution - only a skill can activate itself # someone can forge this message and emit it raw, but in OpenVoiceOS all # skill messages should have skill_id in context, so let's make sure @@ -371,7 +373,7 @@ def handle_activate_skill_request(self, message): if sess.session_id == "default": SessionManager.sync(message) - def handle_deactivate_skill_request(self, message): + def handle_deactivate_skill_request(self, message: Message): # TODO imperfect solution - only a skill can deactivate itself # someone can forge this message and emit it raw, but in ovos-core all # skill message should have skill_id in context, so let's make sure @@ -383,7 +385,7 @@ def handle_deactivate_skill_request(self, message): if sess.session_id == "default": SessionManager.sync(message) - def reset_converse(self, message): + def reset_converse(self, message: Message): """Let skills know there was a problem with speech recognition""" lang = standardize_lang_tag(get_message_lang()) try: @@ -393,7 +395,7 @@ def reset_converse(self, message): self.converse_with_skills([], lang, message) - def handle_get_active_skills(self, message): + def handle_get_active_skills(self, message: Message): """Send active skills to caller. Argument: @@ -406,7 +408,6 @@ def shutdown(self): self.bus.remove('mycroft.speech.recognition.unknown', self.reset_converse) self.bus.remove('intent.service.skills.deactivate', self.handle_deactivate_skill_request) self.bus.remove('intent.service.skills.activate', self.handle_activate_skill_request) - self.bus.remove('active_skill_request', self.handle_activate_skill_request) # TODO backwards compat, deprecate self.bus.remove('intent.service.active_skills.get', self.handle_get_active_skills) self.bus.remove("skill.converse.get_response.enable", self.handle_get_response_enable) self.bus.remove("skill.converse.get_response.disable", self.handle_get_response_disable) From 285dcf547eb0fc7d5b0f68be36c6ddca6a4b21b1 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 03:56:07 +0100 Subject: [PATCH 08/13] fix:standardize_lang --- ovos_core/intent_services/converse_service.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index aa08a956956..e66f1f7f084 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -24,6 +24,7 @@ def __init__(self, bus): self.bus.on('mycroft.speech.recognition.unknown', self.reset_converse) self.bus.on('intent.service.skills.deactivate', self.handle_deactivate_skill_request) self.bus.on('intent.service.skills.activate', self.handle_activate_skill_request) + self.bus.on('active_skill_request', self.handle_activate_skill_request) # TODO backwards compat, deprecate self.bus.on('intent.service.active_skills.get', self.handle_get_active_skills) self.bus.on("skill.converse.get_response.enable", self.handle_get_response_enable) self.bus.on("skill.converse.get_response.disable", self.handle_get_response_disable) @@ -408,6 +409,7 @@ def shutdown(self): self.bus.remove('mycroft.speech.recognition.unknown', self.reset_converse) self.bus.remove('intent.service.skills.deactivate', self.handle_deactivate_skill_request) self.bus.remove('intent.service.skills.activate', self.handle_activate_skill_request) + self.bus.remove('active_skill_request', self.handle_activate_skill_request) # TODO backwards compat, deprecate self.bus.remove('intent.service.active_skills.get', self.handle_get_active_skills) self.bus.remove("skill.converse.get_response.enable", self.handle_get_response_enable) self.bus.remove("skill.converse.get_response.disable", self.handle_get_response_disable) From 6fd140f8500598044fa5e367e1ed5349c5674d63 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 03:57:36 +0100 Subject: [PATCH 09/13] fix:standardize_lang --- ovos_core/intent_services/__init__.py | 12 ++++++------ ovos_core/intent_services/converse_service.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ovos_core/intent_services/__init__.py b/ovos_core/intent_services/__init__.py index 7cddd4a39fb..74952dc8923 100644 --- a/ovos_core/intent_services/__init__.py +++ b/ovos_core/intent_services/__init__.py @@ -210,7 +210,7 @@ def _load_pipeline_plugins(self): @property def registered_intents(self): - lang = standardize_lang_tag(get_message_lang()) + lang = get_message_lang() return [parser.__dict__ for parser in self._adapt_service.engines[lang].intent_parsers] @@ -264,7 +264,7 @@ def _handle_transformers(self, message): Pipe utterance through transformer plugins to get more metadata. Utterances may be modified by any parser and context overwritten """ - lang = standardize_lang_tag(get_message_lang()) # per query lang or default Configuration lang + lang = get_message_lang() # per query lang or default Configuration lang original = utterances = message.data.get('utterances', []) message.context["lang"] = lang utterances, message.context = self.utterance_plugins.transform(utterances, message.context) @@ -282,7 +282,7 @@ def disambiguate_lang(message): 3 - detected_lang -> tagged by transformers (text classification, free form chat) 4 - config lang (or from message.data) """ - default_lang = standardize_lang_tag(get_message_lang()) + default_lang = get_message_lang() valid_langs = get_valid_languages() lang_keys = ["stt_lang", "request_lang", @@ -527,7 +527,7 @@ def handle_register_vocab(self, message): entity_type = message.data.get('entity_type') regex_str = message.data.get('regex') alias_of = message.data.get('alias_of') - lang = standardize_lang_tag(get_message_lang()) + lang = get_message_lang() self._adapt_service.register_vocabulary(entity_value, entity_type, alias_of, regex_str, lang) self.registered_vocab.append(message.data) @@ -604,7 +604,7 @@ def handle_get_intent(self, message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = standardize_lang_tag(get_message_lang()) + lang = get_message_lang() sess = SessionManager.get(message) # Loop through the matching functions until a match is found. @@ -655,7 +655,7 @@ def handle_get_adapt(self, message: Message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = standardize_lang_tag(get_message_lang()) + lang = get_message_lang() intent = self._adapt_service.match_intent((utterance,), lang, message.serialize()) intent_data = intent.intent_data if intent else None self.bus.emit(message.reply("intent.service.adapt.reply", diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index e66f1f7f084..ace8b73725a 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -388,7 +388,7 @@ def handle_deactivate_skill_request(self, message: Message): def reset_converse(self, message: Message): """Let skills know there was a problem with speech recognition""" - lang = standardize_lang_tag(get_message_lang()) + lang = get_message_lang() try: setup_locale(lang) # restore default lang except Exception as e: From 5db192f6e2345924dd067b3a73c49d9786cc44bf Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 03:59:43 +0100 Subject: [PATCH 10/13] fix:standardize_lang --- test/backwards_compat/test_ocp.py | 16 ++++++++-------- .../common_query/test_continuous_dialog.py | 4 ++-- test/integrationtests/test_workshop.py | 16 ++++++++-------- test/unittests/test_intent_service.py | 4 ++-- test/unittests/xformers.py | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/backwards_compat/test_ocp.py b/test/backwards_compat/test_ocp.py index 0a3f704ccf7..8d23ec84bd9 100644 --- a/test/backwards_compat/test_ocp.py +++ b/test/backwards_compat/test_ocp.py @@ -196,36 +196,36 @@ def test_auto_unload(self): # assert that OCP intents registered locale_folder = join(dirname(ovos_plugin_common_play.__file__), - "ocp", "res", "locale", "en-us") + "ocp", "res", "locale", "en-US") ocp_msgs = [ {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/play.intent', - 'name': 'ovos.common_play:play.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:play.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/read.intent', - 'name': 'ovos.common_play:read.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:read.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/open.intent', - 'name': 'ovos.common_play:open.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:open.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/next.intent', - 'name': 'ovos.common_play:next.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:next.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/prev.intent', - 'name': 'ovos.common_play:prev.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:prev.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/pause.intent', - 'name': 'ovos.common_play:pause.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:pause.intent', 'lang': 'en-US'}}, {'type': 'padatious:register_intent', 'data': { 'file_name': f'{locale_folder}/resume.intent', - 'name': 'ovos.common_play:resume.intent', 'lang': 'en-us'}}, + 'name': 'ovos.common_play:resume.intent', 'lang': 'en-US'}}, {'type': 'ovos.common_play.skills.get', 'data': {}} ] diff --git a/test/integrationtests/common_query/test_continuous_dialog.py b/test/integrationtests/common_query/test_continuous_dialog.py index 9b77c05e963..96862b486a6 100644 --- a/test/integrationtests/common_query/test_continuous_dialog.py +++ b/test/integrationtests/common_query/test_continuous_dialog.py @@ -49,7 +49,7 @@ def test_continuous_dialog(self): self.assertEqual(self.bus.emitted_msgs[-1], {'context': {'skill_id': 'wiki.test'}, 'data': {'expect_response': False, - 'lang': 'en-us', + 'lang': 'en-US', 'meta': {'skill': 'wiki.test'}, 'utterance': 'answer 1'}, 'type': 'speak'}) @@ -61,7 +61,7 @@ def test_continuous_dialog(self): self.assertEqual(self.bus.emitted_msgs[-1], {'context': {'skill_id': 'wiki.test'}, 'data': {'expect_response': False, - 'lang': 'en-us', + 'lang': 'en-US', 'meta': {'skill': 'wiki.test'}, 'utterance': 'answer 2'}, 'type': 'speak'}) diff --git a/test/integrationtests/test_workshop.py b/test/integrationtests/test_workshop.py index b3840093ce6..27bdc9be6da 100644 --- a/test/integrationtests/test_workshop.py +++ b/test/integrationtests/test_workshop.py @@ -106,7 +106,7 @@ def test_skills_abort_event(self): speak_msg = {'type': 'speak', 'data': {'utterance': 'still here', 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(start_msg, self.bus.emitted_msgs) self.assertIn(speak_msg, self.bus.emitted_msgs) self.assertTrue(self.skill.instance.my_special_var == "changed") @@ -129,7 +129,7 @@ def test_skills_abort_event(self): speak_msg = {'type': 'speak', 'data': {'utterance': 'I am dead', 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(speak_msg, self.bus.emitted_msgs) self.assertTrue(self.skill.instance.my_special_var == "default") @@ -149,7 +149,7 @@ def test_skill_stop(self): 'data': {'name': 'TestAbortSkill.handle_test_abort_intent'}} speak_msg = {'type': 'speak', 'data': {'utterance': 'still here', 'expect_response': False, - 'meta': {'skill': 'abort.test'}, 'lang': 'en-us'}} + 'meta': {'skill': 'abort.test'}, 'lang': 'en-US'}} self.assertIn(start_msg, self.bus.emitted_msgs) self.assertIn(speak_msg, self.bus.emitted_msgs) self.assertTrue(self.skill.instance.my_special_var == "changed") @@ -171,7 +171,7 @@ def test_skill_stop(self): speak_msg = {'type': 'speak', 'data': {'utterance': 'I am dead', 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(speak_msg, self.bus.emitted_msgs) self.assertTrue(self.skill.instance.my_special_var == "default") @@ -198,7 +198,7 @@ def test_get_response(self): 'data': {'utterance': 'this is a question', 'expect_response': True, 'meta': {'dialog': 'question', 'data': {}, 'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} activate_msg = {'type': 'intent.service.skills.activate', 'data': {'skill_id': 'abort.test'}} self.assertIn(start_msg, self.bus.emitted_msgs) @@ -219,7 +219,7 @@ def test_get_response(self): 'data': {'utterance': 'question aborted', 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(speak_msg, self.bus.emitted_msgs) def test_developer_stop_msg(self): @@ -236,7 +236,7 @@ def test_developer_stop_msg(self): 'data': {'utterance': "you can't abort me", 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(start_msg, self.bus.emitted_msgs) self.assertIn(speak_msg, self.bus.emitted_msgs) @@ -265,7 +265,7 @@ def test_developer_stop_msg(self): speak_msg = {'type': 'speak', 'data': {'utterance': 'I am dead', 'expect_response': False, 'meta': {'skill': 'abort.test'}, - 'lang': 'en-us'}} + 'lang': 'en-US'}} self.assertIn(speak_msg, self.bus.emitted_msgs) self.assertTrue(self.skill.instance.my_special_var == "default") diff --git a/test/unittests/test_intent_service.py b/test/unittests/test_intent_service.py index 0ccdac65a7e..bef2a35143c 100644 --- a/test/unittests/test_intent_service.py +++ b/test/unittests/test_intent_service.py @@ -31,7 +31,7 @@ NO_LANG_CONF = deepcopy(LocalConf(DEFAULT_CONFIG)) NO_LANG_CONF.pop('lang') -setup_locale("en-us") +setup_locale("en-US") class MockEmitter(object): @@ -104,7 +104,7 @@ def test_no_lang_in_message(self): setup_locale("it-it") msg = Message('test msg', data={}) self.assertEqual(get_message_lang(msg), 'it-IT') - setup_locale("en-us") + setup_locale("en-US") self.assertEqual(get_message_lang(msg), 'en-US') @mock.patch.dict(Configuration._Configuration__patch, BASE_CONF) diff --git a/test/unittests/xformers.py b/test/unittests/xformers.py index f64104eb7e8..3f248e77e6d 100644 --- a/test/unittests/xformers.py +++ b/test/unittests/xformers.py @@ -67,7 +67,7 @@ def test_utterance_transformer_service_transform(self): def test_utterance_transformer_service_priority(self): utterances = ["test 1", "test one"] - lang = "en-us" + lang = "en-US" def mod_1_parse(utterances, lang): utterances.append("mod 1 parsed") From 3dba4407ab245a6a0e46e669296d894e39fceae1 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 04:00:55 +0100 Subject: [PATCH 11/13] fix:standardize_lang --- test/backwards_compat/test_ocp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/backwards_compat/test_ocp.py b/test/backwards_compat/test_ocp.py index 8d23ec84bd9..faf389a9c12 100644 --- a/test/backwards_compat/test_ocp.py +++ b/test/backwards_compat/test_ocp.py @@ -196,7 +196,7 @@ def test_auto_unload(self): # assert that OCP intents registered locale_folder = join(dirname(ovos_plugin_common_play.__file__), - "ocp", "res", "locale", "en-US") + "ocp", "res", "locale", "en-us") ocp_msgs = [ {'type': 'padatious:register_intent', 'data': { From ed6f2e4758e6fd5814c3f0fb8bddcfb3513c3b13 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 04:02:37 +0100 Subject: [PATCH 12/13] fix:standardize_lang --- ovos_core/intent_services/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ovos_core/intent_services/__init__.py b/ovos_core/intent_services/__init__.py index 74952dc8923..05d46e143d8 100644 --- a/ovos_core/intent_services/__init__.py +++ b/ovos_core/intent_services/__init__.py @@ -264,7 +264,7 @@ def _handle_transformers(self, message): Pipe utterance through transformer plugins to get more metadata. Utterances may be modified by any parser and context overwritten """ - lang = get_message_lang() # per query lang or default Configuration lang + lang = get_message_lang(message) # per query lang or default Configuration lang original = utterances = message.data.get('utterances', []) message.context["lang"] = lang utterances, message.context = self.utterance_plugins.transform(utterances, message.context) @@ -282,7 +282,7 @@ def disambiguate_lang(message): 3 - detected_lang -> tagged by transformers (text classification, free form chat) 4 - config lang (or from message.data) """ - default_lang = get_message_lang() + default_lang = get_message_lang(message) valid_langs = get_valid_languages() lang_keys = ["stt_lang", "request_lang", @@ -527,7 +527,7 @@ def handle_register_vocab(self, message): entity_type = message.data.get('entity_type') regex_str = message.data.get('regex') alias_of = message.data.get('alias_of') - lang = get_message_lang() + lang = get_message_lang(message) self._adapt_service.register_vocabulary(entity_value, entity_type, alias_of, regex_str, lang) self.registered_vocab.append(message.data) @@ -604,7 +604,7 @@ def handle_get_intent(self, message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = get_message_lang() + lang = get_message_lang(message) sess = SessionManager.get(message) # Loop through the matching functions until a match is found. @@ -655,7 +655,7 @@ def handle_get_adapt(self, message: Message): message (Message): message containing utterance """ utterance = message.data["utterance"] - lang = get_message_lang() + lang = get_message_lang(message) intent = self._adapt_service.match_intent((utterance,), lang, message.serialize()) intent_data = intent.intent_data if intent else None self.bus.emit(message.reply("intent.service.adapt.reply", From 0f1b010707a1b639d857ac69f659bfc7cc8ff299 Mon Sep 17 00:00:00 2001 From: miro Date: Wed, 16 Oct 2024 04:07:25 +0100 Subject: [PATCH 13/13] fix:standardize_lang --- ovos_core/intent_services/fallback_service.py | 26 +++++++++++-------- ovos_core/intent_services/stop_service.py | 7 ++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ovos_core/intent_services/fallback_service.py b/ovos_core/intent_services/fallback_service.py index 5d1c7e8b3d6..ce567ada341 100644 --- a/ovos_core/intent_services/fallback_service.py +++ b/ovos_core/intent_services/fallback_service.py @@ -16,15 +16,17 @@ import operator import time from collections import namedtuple -from typing import Optional +from typing import Optional, List +from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager +from ovos_workshop.permissions import FallbackMode + from ovos_config import Configuration from ovos_plugin_manager.templates.pipeline import IntentMatch, PipelinePlugin from ovos_utils import flatten_list from ovos_utils.lang import standardize_lang_tag from ovos_utils.log import LOG -from ovos_workshop.permissions import FallbackMode FallbackRange = namedtuple('FallbackRange', ['start', 'stop']) @@ -40,7 +42,7 @@ def __init__(self, bus): self.bus.on("ovos.skills.fallback.deregister", self.handle_deregister_fallback) super().__init__(self.fallback_config) - def handle_register_fallback(self, message): + def handle_register_fallback(self, message: Message): skill_id = message.data.get("skill_id") priority = message.data.get("priority") or 101 @@ -53,12 +55,12 @@ def handle_register_fallback(self, message): else: self.registered_fallbacks[skill_id] = priority - def handle_deregister_fallback(self, message): + def handle_deregister_fallback(self, message: Message): skill_id = message.data.get("skill_id") if skill_id in self.registered_fallbacks: self.registered_fallbacks.pop(skill_id) - def _fallback_allowed(self, skill_id): + def _fallback_allowed(self, skill_id: str) -> bool: """Checks if a skill_id is allowed to fallback - is the skill blacklisted from fallback @@ -79,7 +81,8 @@ def _fallback_allowed(self, skill_id): return False return True - def _collect_fallback_skills(self, message, fb_range=FallbackRange(0, 100)): + def _collect_fallback_skills(self, message: Message, + fb_range: FallbackRange = FallbackRange(0, 100)) -> List[str]: """use the messagebus api to determine which skills have registered fallback handlers This includes all skills and external applications""" skill_ids = [] # skill_ids that already answered to ping @@ -117,7 +120,7 @@ def handle_ack(msg): self.bus.remove("ovos.skills.fallback.pong", handle_ack) return fallback_skills - def attempt_fallback(self, utterances, skill_id, lang, message): + def attempt_fallback(self, utterances: List[str], skill_id: str, lang: str, message: Message) -> bool: """Call skill and ask if they want to process the utterance. Args: @@ -159,7 +162,8 @@ def attempt_fallback(self, utterances, skill_id, lang, message): f'increasing "max_skill_runtime" in mycroft.conf might help alleviate this issue') return False - def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[IntentMatch]: + def _fallback_range(self, utterances: List[str], lang: str, + message: Message, fb_range: FallbackRange) -> Optional[IntentMatch]: """Send fallback request for a specified priority range. Args: @@ -197,17 +201,17 @@ def _fallback_range(self, utterances, lang, message, fb_range) -> Optional[Inten utterance=utterances[0]) return None - def high_prio(self, utterances, lang, message) -> Optional[IntentMatch]: + def high_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: """Pre-padatious fallbacks.""" return self._fallback_range(utterances, lang, message, FallbackRange(0, 5)) - def medium_prio(self, utterances, lang, message) -> Optional[IntentMatch]: + def medium_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: """General fallbacks.""" return self._fallback_range(utterances, lang, message, FallbackRange(5, 90)) - def low_prio(self, utterances, lang, message) -> Optional[IntentMatch]: + def low_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: """Low prio fallbacks with general matching such as chat-bot.""" return self._fallback_range(utterances, lang, message, FallbackRange(90, 101)) diff --git a/ovos_core/intent_services/stop_service.py b/ovos_core/intent_services/stop_service.py index 54492d0d57c..bdb1137a75f 100644 --- a/ovos_core/intent_services/stop_service.py +++ b/ovos_core/intent_services/stop_service.py @@ -38,7 +38,8 @@ def load_resource_files(self): n = f.split(".", 1)[0] self._voc_cache[lang2][n] = flatten_list(lines) - def get_active_skills(self, message: Optional[Message] = None): + @staticmethod + def get_active_skills(message: Optional[Message] = None) -> List[str]: """Active skill ids ordered by converse priority this represents the order in which stop will be called @@ -48,7 +49,7 @@ def get_active_skills(self, message: Optional[Message] = None): session = SessionManager.get(message) return [skill[0] for skill in session.active_skills] - def _collect_stop_skills(self, message: Message): + def _collect_stop_skills(self, message: Message) -> List[str]: """use the messagebus api to determine which skills can stop This includes all skills and external applications""" @@ -92,7 +93,7 @@ def handle_ack(msg): self.bus.remove("skill.stop.pong", handle_ack) return want_stop or active_skills - def stop_skill(self, skill_id: str, message: Message): + def stop_skill(self, skill_id: str, message: Message) -> bool: """Tell a skill to stop anything it's doing, taking into account the message Session