From 09e4c0ab8db679f2e2e16438392b0f7789b29bea Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Sat, 2 Nov 2024 02:13:39 +0000 Subject: [PATCH] fix:move code to dependencies (#571) * fox:update requirements update imports and requirements for latest pipeline plugins signature * remove methods marked for deprecation * fixes * fix re-activation of skills that just deactivated themselves during the match * account for session_id * remove deleted messages from tests * remove deleted messages from tests * update tests * fix converse * update tests * @coderabbitai suggestion * revert change, we still need to update timestamps on active skills * fix get_response * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * fix:workshop2_compat * deprecation logs * deprecation logs * tests moved to adapt repo * fix deprecation warning version * fix adapt init * keep intent api unittest * dont access deprecated stuff in tests --- mycroft/skills/common_play_skill.py | 7 +- mycroft/skills/intent_services/__init__.py | 18 +- .../skills/intent_services/adapt_service.py | 5 +- .../intent_services/commonqa_service.py | 2 +- .../intent_services/padatious_service.py | 2 +- ovos_core/intent_services/__init__.py | 548 +++++++----------- ovos_core/intent_services/adapt_service.py | 2 + ovos_core/intent_services/commonqa_service.py | 2 + ovos_core/intent_services/converse_service.py | 18 +- ovos_core/intent_services/fallback_service.py | 24 +- ovos_core/intent_services/ocp_service.py | 2 + .../intent_services/padacioso_service.py | 2 + .../intent_services/padatious_service.py | 2 + ovos_core/intent_services/stop_service.py | 54 +- ovos_core/skill_manager.py | 62 +- requirements/lgpl.txt | 2 +- requirements/requirements.txt | 12 +- requirements/skills-audio.txt | 10 +- requirements/skills-desktop.txt | 2 +- requirements/skills-essential.txt | 12 +- requirements/skills-gui.txt | 2 +- requirements/skills-internet.txt | 14 +- requirements/skills-media.txt | 4 +- test/end2end/routing/test_sched.py | 5 +- test/end2end/routing/test_session.py | 10 +- test/end2end/session/test_blacklist.py | 28 +- test/end2end/session/test_converse.py | 74 +-- test/end2end/session/test_fallback.py | 74 +-- test/end2end/session/test_get_response.py | 323 +++-------- test/end2end/session/test_ocp.py | 177 +++--- test/end2end/session/test_sched.py | 124 ++-- test/end2end/session/test_session.py | 60 +- test/end2end/session/test_stop.py | 24 +- test/unittests/test_intent_service.py | 268 +-------- 34 files changed, 678 insertions(+), 1297 deletions(-) diff --git a/mycroft/skills/common_play_skill.py b/mycroft/skills/common_play_skill.py index 04a94ec3386..295f0795468 100644 --- a/mycroft/skills/common_play_skill.py +++ b/mycroft/skills/common_play_skill.py @@ -158,17 +158,14 @@ def __handle_play_start(self, message): data = message.data.get("callback_data") # Stop any currently playing audio - if self.audioservice and self.audioservice.is_playing: - self.audioservice.stop() + self.stop() + message.context["skill_id"] = self.skill_id - self.bus.emit(message.forward("mycroft.stop")) # Save for CPS_play() later, e.g. if phrase includes modifiers like # "... on the chromecast" self.play_service_string = phrase - self.activate() - # Invoke derived class to provide playback data self.CPS_start(phrase, data) diff --git a/mycroft/skills/intent_services/__init__.py b/mycroft/skills/intent_services/__init__.py index 8a0355a5d17..72e3cd12717 100644 --- a/mycroft/skills/intent_services/__init__.py +++ b/mycroft/skills/intent_services/__init__.py @@ -1,14 +1,14 @@ -from ovos_core.intent_services import AdaptService,\ - ConverseService, \ - CommonQAService, \ - FallbackService, \ - PadaciosoService -from ovos_core.intent_services import IntentMatch -from mycroft.skills.intent_services.adapt_service import AdaptIntent, IntentBuilder, Intent +from ovos_core.intent_services.fallback_service import FallbackService +from ovos_core.intent_services.converse_service import ConverseService +from ovos_adapt.opm import AdaptPipeline as AdaptService +from padacioso.opm import PadaciosoPipeline as PadaciosoService +from ovos_commonqa.opm import CommonQAService +from ovos_plugin_manager.templates.pipeline import IntentMatch +from ovos_workshop.intents import Intent as AdaptIntent, IntentBuilder, Intent try: - from ovos_core.intent_services.padatious_service import PadatiousService, PadatiousMatcher + from ovos_padatious.opm import PadatiousPipeline as PadatiousService, PadatiousMatcher except ImportError: from ovos_utils.log import LOG LOG.warning("padatious not installed") - from ovos_core.intent_services.padacioso_service import PadaciosoService as PadatiousService + from padacioso.opm import PadaciosoPipeline as PadatiousService diff --git a/mycroft/skills/intent_services/adapt_service.py b/mycroft/skills/intent_services/adapt_service.py index fa8ac0881ab..447e1e3904c 100644 --- a/mycroft/skills/intent_services/adapt_service.py +++ b/mycroft/skills/intent_services/adapt_service.py @@ -13,10 +13,11 @@ # limitations under the License. # """An intent parsing service using the Adapt parser.""" -from ovos_adapt.context import ContextManagerFrame from ovos_adapt.engine import IntentDeterminationEngine from ovos_workshop.intents import IntentBuilder, Intent -from ovos_adapt.opm import ContextManager, AdaptPipeline as AdaptService +from ovos_adapt.opm import AdaptPipeline as AdaptService +from ovos_bus_client.session import IntentContextManagerFrame as ContextManagerFrame, \ + IntentContextManager as ContextManager class AdaptIntent(IntentBuilder): diff --git a/mycroft/skills/intent_services/commonqa_service.py b/mycroft/skills/intent_services/commonqa_service.py index 34f5ac1c7fe..4420ed12b09 100644 --- a/mycroft/skills/intent_services/commonqa_service.py +++ b/mycroft/skills/intent_services/commonqa_service.py @@ -1,2 +1,2 @@ -from ovos_core.intent_services.commonqa_service import CommonQAService +from ovos_commonqa.opm import CommonQAService EXTENSION_TIME = 10 diff --git a/mycroft/skills/intent_services/padatious_service.py b/mycroft/skills/intent_services/padatious_service.py index b5d1809a431..979ab0d9623 100644 --- a/mycroft/skills/intent_services/padatious_service.py +++ b/mycroft/skills/intent_services/padatious_service.py @@ -13,5 +13,5 @@ # limitations under the License. # """Intent service wrapping padatious.""" -from ovos_core.intent_services.padatious_service import PadatiousMatcher, PadatiousService, PadatiousIntent +from ovos_padatious.opm import PadatiousMatcher, PadatiousPipeline as PadatiousService, PadatiousIntent diff --git a/ovos_core/intent_services/__init__.py b/ovos_core/intent_services/__init__.py index 05d46e143d8..d816e3a40e8 100644 --- a/ovos_core/intent_services/__init__.py +++ b/ovos_core/intent_services/__init__.py @@ -12,25 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from typing import Tuple, Callable +from collections import defaultdict +from typing import Tuple, Callable, Union +from ocp_pipeline.opm import OCPPipelineMatcher +from ovos_adapt.opm import AdaptPipeline from ovos_bus_client.message import Message from ovos_bus_client.session import SessionManager from ovos_bus_client.util import get_message_lang -from ovos_workshop.intents import open_intent_envelope - -from ocp_pipeline.opm import OCPPipelineMatcher -from ovos_adapt.opm import AdaptPipeline as AdaptService from ovos_commonqa.opm import CommonQAService from ovos_config.config import Configuration -from ovos_config.locale import setup_locale, get_valid_languages, get_full_lang_code +from ovos_config.locale import setup_locale, get_valid_languages from ovos_core.intent_services.converse_service import ConverseService from ovos_core.intent_services.fallback_service import FallbackService 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_plugin_manager.templates.pipeline import PipelineMatch, IntentHandlerMatch from ovos_utils.lang import standardize_lang_tag -from ovos_utils.log import LOG, deprecated, log_deprecation +from ovos_utils.log import LOG, log_deprecation, deprecated from ovos_utils.metrics import Stopwatch from padacioso.opm import PadaciosoPipeline as PadaciosoService @@ -66,138 +65,34 @@ def __init__(self, bus, config=None): # this will sync default session across all components SessionManager.connect_to_bus(self.bus) - self.bus.on('register_vocab', self.handle_register_vocab) - self.bus.on('register_intent', self.handle_register_intent) self.bus.on('recognizer_loop:utterance', self.handle_utterance) - self.bus.on('detach_intent', self.handle_detach_intent) - self.bus.on('detach_skill', self.handle_detach_skill) + # Context related handlers self.bus.on('add_context', self.handle_add_context) self.bus.on('remove_context', self.handle_remove_context) self.bus.on('clear_context', self.handle_clear_context) - # Converse method - self.bus.on('mycroft.skills.loaded', self.update_skill_name_dict) - # Intents API self.registered_vocab = [] self.bus.on('intent.service.intent.get', self.handle_get_intent) self.bus.on('intent.service.skills.get', self.handle_get_skills) - self.bus.on('intent.service.adapt.get', self.handle_get_adapt) - self.bus.on('intent.service.adapt.manifest.get', self.handle_adapt_manifest) - self.bus.on('intent.service.adapt.vocab.manifest.get', self.handle_vocab_manifest) - self.bus.on('intent.service.padatious.get', self.handle_get_padatious) - self.bus.on('intent.service.padatious.manifest.get', self.handle_padatious_manifest) - self.bus.on('intent.service.padatious.entities.manifest.get', self.handle_entity_manifest) - - @property - def adapt_service(self): - log_deprecation("direct access to self.adapt_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._adapt_service - - @property - def padatious_service(self): - log_deprecation("direct access to self.padatious_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._padatious_service - - @property - def padacioso_service(self): - log_deprecation("direct access to self.padacioso_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._padacioso_service - - @property - def fallback(self): - - log_deprecation("direct access to self.fallback is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._fallback - - @property - def converse(self): - log_deprecation("direct access to self.converse is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._converse - - @property - def common_qa(self): - log_deprecation("direct access to self.common_qa is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._common_qa - - @property - def stop(self): - log_deprecation("direct access to self.stop is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._stop - - @property - def ocp(self): - log_deprecation("direct access to self.ocp is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - return self._ocp - - @adapt_service.setter - def adapt_service(self, value): - log_deprecation("direct access to self.adapt_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._adapt_service = value - - @padatious_service.setter - def padatious_service(self, value): - log_deprecation("direct access to self.padatious_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._padatious_service = value - - @padacioso_service.setter - def padacioso_service(self, value): - log_deprecation("direct access to self.padacioso_service is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._padacioso_service = value - - @fallback.setter - def fallback(self, value): - log_deprecation("direct access to self.fallback is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._fallback = value - - @converse.setter - def converse(self, value): - log_deprecation("direct access to self.converse is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._converse = value - - @common_qa.setter - def common_qa(self, value): - log_deprecation("direct access to self.common_qa is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._common_qa = value + self.bus.on('mycroft.skills.loaded', self.update_skill_name_dict) - @stop.setter - def stop(self, value): - log_deprecation("direct access to self.stop is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._stop = value - - @ocp.setter - def ocp(self, value): - log_deprecation("direct access to self.ocp is deprecated, " - "pipelines are in the progress of being replaced with plugins", "1.0.0") - self._ocp = value + # internal, track skills that call self.deactivate to avoid reactivating them again + self._deactivations = defaultdict(list) + self.bus.on('intent.service.skills.deactivate', self._handle_deactivate) def _load_pipeline_plugins(self): # TODO - replace with plugin loader from OPM - self._adapt_service = AdaptService(config=self.config.get("adapt", {})) + self._adapt_service = AdaptPipeline(bus=self.bus, config=self.config.get("adapt", {})) if "padatious" not in self.config: self.config["padatious"] = Configuration().get("padatious", {}) try: if self.config["padatious"].get("disabled"): LOG.info("padatious forcefully disabled in config") else: - from ovos_padatious.opm import PadatiousPipeline as PadatiousService - self._padatious_service = PadatiousService(self.bus, self.config["padatious"]) + from ovos_padatious.opm import PadatiousPipeline + self._padatious_service = PadatiousPipeline(self.bus, self.config["padatious"]) except ImportError: LOG.error(f'Failed to create padatious intent handlers, padatious not installed') @@ -208,12 +103,6 @@ def _load_pipeline_plugins(self): self._stop = StopService(self.bus) self._ocp = OCPPipelineMatcher(self.bus, config=self.config.get("OCP", {})) - @property - def registered_intents(self): - lang = get_message_lang() - return [parser.__dict__ - for parser in self._adapt_service.engines[lang].intent_parsers] - def update_skill_name_dict(self, message): """Messagebus handler, updates dict of id to skill name conversions.""" self.skill_names[message.data['id']] = message.data['name'] @@ -229,36 +118,6 @@ def get_skill_name(self, skill_id): """ return self.skill_names.get(skill_id, skill_id) - # converse handling - @property - def active_skills(self): - log_deprecation("self.active_skills is deprecated! use Session instead", "0.0.9") - session = SessionManager.get() - return session.active_skills - - @active_skills.setter - def active_skills(self, val): - log_deprecation("self.active_skills is deprecated! use Session instead", "0.0.9") - session = SessionManager.get() - session.active_skills = [] - for skill_id, ts in val: - session.activate_skill(skill_id) - - @deprecated("handle_activate_skill_request moved to ConverseService, overriding this method has no effect, " - "it has been disconnected from the bus event", "0.0.8") - def handle_activate_skill_request(self, message): - self.converse.handle_activate_skill_request(message) - - @deprecated("handle_deactivate_skill_request moved to ConverseService, overriding this method has no effect, " - "it has been disconnected from the bus event", "0.0.8") - def handle_deactivate_skill_request(self, message): - self.converse.handle_deactivate_skill_request(message) - - @deprecated("reset_converse moved to ConverseService, overriding this method has no effect, " - "it has been disconnected from the bus event", "0.0.8") - def reset_converse(self, message): - self.converse.reset_converse(message) - def _handle_transformers(self, message): """ Pipe utterance through transformer plugins to get more metadata. @@ -284,13 +143,14 @@ def disambiguate_lang(message): """ default_lang = get_message_lang(message) valid_langs = get_valid_languages() + valid_langs = [standardize_lang_tag(l) for l in valid_langs] lang_keys = ["stt_lang", "request_lang", "detected_lang"] for k in lang_keys: if k in message.context: - v = get_full_lang_code(message.context[k]) - if v in valid_langs: + v = standardize_lang_tag(message.context[k]) + if v in valid_langs: # TODO - use lang distance instead to choose best dialect if v != default_lang: LOG.info(f"replaced {default_lang} with {k}: {v}") return v @@ -314,8 +174,7 @@ def get_pipeline(self, skips=None, session=None) -> Tuple[str, Callable]: "intent matching will be extremely slow in comparison") padatious_matcher = self._padacioso_service else: - from ovos_core.intent_services.padatious_service import PadatiousMatcher - padatious_matcher = PadatiousMatcher(self._padatious_service) + padatious_matcher = self._padatious_service matchers = { "converse": self._converse.converse_with_skills, @@ -351,7 +210,8 @@ def get_pipeline(self, skips=None, session=None) -> Tuple[str, Callable]: LOG.debug(f"Session pipeline: {pipeline}") return [(k, matchers[k]) for k in pipeline] - def _validate_session(self, message, lang): + @staticmethod + def _validate_session(message, lang): # get session lang = standardize_lang_tag(lang) sess = SessionManager.get(message) @@ -373,42 +233,55 @@ def _validate_session(self, message, lang): sess.touch() return sess - def _emit_match_message(self, match: IntentMatch, message: Message): + def _handle_deactivate(self, message): + """internal helper, track if a skill asked to be removed from active list during intent match + in this case we want to avoid reactivating it again + This only matters in PipelineMatchers, such as fallback and converse + in those cases the activation is only done AFTER the match, not before unlike intents + """ + sess = SessionManager.get(message) + skill_id = message.data.get("skill_id") + self._deactivations[sess.session_id].append(skill_id) + + def _emit_match_message(self, match: Union[IntentHandlerMatch, PipelineMatch], message: Message): """Update the message data with the matched utterance information and activate the corresponding skill if available. Args: - match (IntentMatch): The matched utterance object. + match (IntentHandlerMatch): The matched utterance object. message (Message): The messagebus data. """ - message.data["utterance"] = match.utterance - - if match.skill_id: - # ensure skill_id is present in message.context - message.context["skill_id"] = match.skill_id + reply = None + sess = SessionManager.get(message) - if match.intent_type is True: - # utterance fully handled - reply = message.reply("ovos.utterance.handled", - {"skill_id": match.skill_id}) - self.bus.emit(reply) + # utterance fully handled by pipeline matcher + if isinstance(match, PipelineMatch): + if match.handled: + reply = message.reply("ovos.utterance.handled", {"skill_id": match.skill_id}) # Launch skill if not handled by the match function - elif match.intent_type: + elif isinstance(match, IntentHandlerMatch) and match.match_type: # keep all original message.data and update with intent match data = dict(message.data) - data.update(match.intent_data) - - # NOTE: message.reply to ensure correct message destination - reply = message.reply(match.intent_type, data) - - # let's activate the skill BEFORE the intent is triggered - # to ensure an accurate Session - # NOTE: this was previously done async by the skill, - # but then the skill was missing from Session.active_skills - sess = self.converse.activate_skill(message=reply, - skill_id=match.skill_id) - if sess: - reply.context["session"] = sess.serialize() + data.update(match.match_data) + reply = message.reply(match.match_type, data) + + if reply is not None: + reply.data["utterance"] = match.utterance + + # update active skill list + if match.skill_id: + # ensure skill_id is present in message.context + reply.context["skill_id"] = match.skill_id + + # NOTE: do not re-activate if the skill called self.deactivate + # we could also skip activation if skill is already active, + # but we still want to update the timestamp + was_deactivated = match.skill_id in self._deactivations[sess.session_id] + if not was_deactivated: + sess.activate_skill(match.skill_id) + reply.context["session"] = sess.serialize() + # emit event for skills callback -> self.handle_activate + self.bus.emit(reply.forward(f"{match.skill_id}.activate")) self.bus.emit(reply) @@ -474,6 +347,8 @@ def handle_utterance(self, message: Message): # match match = None with stopwatch: + self._deactivations[sess.session_id] = [] + # Loop through the matching functions until a match is found. for pipeline, match_func in self.get_pipeline(session=sess): match = match_func(utterances, lang, message) @@ -483,9 +358,9 @@ def handle_utterance(self, message: Message): LOG.debug( f"ignoring match, skill_id '{match.skill_id}' blacklisted by Session '{sess.session_id}'") continue - if match.intent_type and match.intent_type in sess.blacklisted_intents: + if isinstance(match, IntentHandlerMatch) and match.match_type in sess.blacklisted_intents: LOG.debug( - f"ignoring match, intent '{match.intent_type}' blacklisted by Session '{sess.session_id}'") + f"ignoring match, intent '{match.match_type}' blacklisted by Session '{sess.session_id}'") continue try: self._emit_match_message(match, message) @@ -503,6 +378,8 @@ def handle_utterance(self, message: Message): # sync any changes made to the default session, eg by ConverseService if sess.session_id == "default": SessionManager.sync(message) + elif sess.session_id in self._deactivations: + self._deactivations.pop(sess.session_id) return match, message.context, stopwatch def send_complete_intent_failure(self, message): @@ -517,49 +394,8 @@ def send_complete_intent_failure(self, message): self.bus.emit(message.reply('complete_intent_failure')) self.bus.emit(message.reply("ovos.utterance.handled")) - def handle_register_vocab(self, message): - """Register adapt vocabulary. - - Args: - message (Message): message containing vocab info - """ - entity_value = message.data.get('entity_value') - 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) - self._adapt_service.register_vocabulary(entity_value, entity_type, - alias_of, regex_str, lang) - self.registered_vocab.append(message.data) - - def handle_register_intent(self, message): - """Register adapt intent. - - Args: - message (Message): message containing intent info - """ - intent = open_intent_envelope(message) - self._adapt_service.register_intent(intent) - - def handle_detach_intent(self, message): - """Remover adapt intent. - - Args: - message (Message): message containing intent info - """ - intent_name = message.data.get('intent_name') - self._adapt_service.detach_intent(intent_name) - - def handle_detach_skill(self, message): - """Remove all intents registered for a specific skill. - - Args: - message (Message): message containing intent info - """ - skill_id = message.data.get('skill_id') - self._adapt_service.detach_skill(skill_id) - - def handle_add_context(self, message): + @staticmethod + def handle_add_context(message: Message): """Add context Args: @@ -581,7 +417,8 @@ def handle_add_context(self, message): sess = SessionManager.get(message) sess.context.inject_context(entity) - def handle_remove_context(self, message): + @staticmethod + def handle_remove_context(message: Message): """Remove specific context Args: @@ -592,7 +429,8 @@ def handle_remove_context(self, message): sess = SessionManager.get(message) sess.context.remove_context(context) - def handle_clear_context(self, message): + @staticmethod + def handle_clear_context(message: Message): """Clears all keywords from context """ sess = SessionManager.get(message) sess.context.clear_context() @@ -615,10 +453,10 @@ def handle_get_intent(self, message): session=sess): match = match_func([utterance], lang, message) if match: - if match.intent_type: - intent_data = match.intent_data - intent_data["intent_name"] = match.intent_type - intent_data["intent_service"] = match.intent_service + if match.match_type: + intent_data = match.match_data + intent_data["intent_name"] = match.match_type + intent_data["intent_service"] = pipeline intent_data["skill_id"] = match.skill_id intent_data["handler"] = match_func.__name__ self.bus.emit(message.reply("intent.service.intent.reply", @@ -638,83 +476,6 @@ def handle_get_skills(self, message): self.bus.emit(message.reply("intent.service.skills.reply", {"skills": self.skill_names})) - @deprecated("handle_get_active_skills moved to ConverseService, overriding this method has no effect, " - "it has been disconnected from the bus event", "0.0.8") - def handle_get_active_skills(self, message): - """Send active skills to caller. - - Argument: - message: query message to reply to. - """ - self.converse.handle_get_active_skills(message) - - def handle_get_adapt(self, message: Message): - """handler getting the adapt response for an utterance. - - Args: - message (Message): message containing utterance - """ - utterance = message.data["utterance"] - 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", - {"intent": intent_data})) - - def handle_adapt_manifest(self, message): - """Send adapt intent manifest to caller. - - Argument: - message: query message to reply to. - """ - self.bus.emit(message.reply("intent.service.adapt.manifest", - {"intents": self.registered_intents})) - - def handle_vocab_manifest(self, message): - """Send adapt vocabulary manifest to caller. - - Argument: - message: query message to reply to. - """ - self.bus.emit(message.reply("intent.service.adapt.vocab.manifest", - {"vocab": self.registered_vocab})) - - def handle_get_padatious(self, message): - """messagebus handler for perfoming padatious parsing. - - Args: - message (Message): message triggering the method - """ - utterance = message.data["utterance"] - norm = message.data.get('norm_utt', utterance) - intent = self.padacioso_service.calc_intent(utterance) - if not intent and norm != utterance: - intent = self.padacioso_service.calc_intent(norm) - if intent: - intent = intent.__dict__ - self.bus.emit(message.reply("intent.service.padatious.reply", - {"intent": intent})) - - def handle_padatious_manifest(self, message): - """Messagebus handler returning the registered padatious intents. - - Args: - message (Message): message triggering the method - """ - self.bus.emit(message.reply( - "intent.service.padatious.manifest", - {"intents": self.padacioso_service.registered_intents})) - - def handle_entity_manifest(self, message): - """Messagebus handler returning the registered padatious entities. - - Args: - message (Message): message triggering the method - """ - self.bus.emit(message.reply( - "intent.service.padatious.entities.manifest", - {"entities": self.padacioso_service.registered_entities})) - def shutdown(self): self.utterance_plugins.shutdown() self.metadata_plugins.shutdown() @@ -728,20 +489,157 @@ def shutdown(self): if self._ocp: self._ocp.shutdown() - self.bus.remove('register_vocab', self.handle_register_vocab) - self.bus.remove('register_intent', self.handle_register_intent) self.bus.remove('recognizer_loop:utterance', self.handle_utterance) - self.bus.remove('detach_intent', self.handle_detach_intent) - self.bus.remove('detach_skill', self.handle_detach_skill) self.bus.remove('add_context', self.handle_add_context) self.bus.remove('remove_context', self.handle_remove_context) self.bus.remove('clear_context', self.handle_clear_context) self.bus.remove('mycroft.skills.loaded', self.update_skill_name_dict) self.bus.remove('intent.service.intent.get', self.handle_get_intent) self.bus.remove('intent.service.skills.get', self.handle_get_skills) - self.bus.remove('intent.service.adapt.get', self.handle_get_adapt) - self.bus.remove('intent.service.adapt.manifest.get', self.handle_adapt_manifest) - self.bus.remove('intent.service.adapt.vocab.manifest.get', self.handle_vocab_manifest) - self.bus.remove('intent.service.padatious.get', self.handle_get_padatious) - self.bus.remove('intent.service.padatious.manifest.get', self.handle_padatious_manifest) - self.bus.remove('intent.service.padatious.entities.manifest.get', self.handle_entity_manifest) + + ########### + # DEPRECATED STUFF + @property + def registered_intents(self): + log_deprecation("direct access to self.adapt_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + lang = get_message_lang() + return [parser.__dict__ + for parser in self._adapt_service.engines[lang].intent_parsers] + + @property + def adapt_service(self): + log_deprecation("direct access to self.adapt_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._adapt_service + + @property + def padatious_service(self): + log_deprecation("direct access to self.padatious_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._padatious_service + + @property + def padacioso_service(self): + log_deprecation("direct access to self.padacioso_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._padacioso_service + + @property + def fallback(self): + + log_deprecation("direct access to self.fallback is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._fallback + + @property + def converse(self): + log_deprecation("direct access to self.converse is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._converse + + @property + def common_qa(self): + log_deprecation("direct access to self.common_qa is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._common_qa + + @property + def stop(self): + log_deprecation("direct access to self.stop is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._stop + + @property + def ocp(self): + log_deprecation("direct access to self.ocp is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + return self._ocp + + @adapt_service.setter + def adapt_service(self, value): + log_deprecation("direct access to self.adapt_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._adapt_service = value + + @padatious_service.setter + def padatious_service(self, value): + log_deprecation("direct access to self.padatious_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._padatious_service = value + + @padacioso_service.setter + def padacioso_service(self, value): + log_deprecation("direct access to self.padacioso_service is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._padacioso_service = value + + @fallback.setter + def fallback(self, value): + log_deprecation("direct access to self.fallback is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._fallback = value + + @converse.setter + def converse(self, value): + log_deprecation("direct access to self.converse is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._converse = value + + @common_qa.setter + def common_qa(self, value): + log_deprecation("direct access to self.common_qa is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._common_qa = value + + @stop.setter + def stop(self, value): + log_deprecation("direct access to self.stop is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._stop = value + + @ocp.setter + def ocp(self, value): + log_deprecation("direct access to self.ocp is deprecated, " + "pipelines are in the progress of being replaced with plugins", "1.0.0") + self._ocp = value + + @deprecated("handle_get_adapt moved to adapt service, this method does nothing", "1.0.0") + def handle_get_adapt(self, message: Message): + """DEPRECATED""" + + @deprecated("handle_adapt_manifest moved to adapt service, this method does nothing", "1.0.0") + def handle_adapt_manifest(self, message): + """DEPRECATED""" + + @deprecated("handle_vocab_manifest moved to adapt service, this method does nothing", "1.0.0") + def handle_vocab_manifest(self, message): + """DEPRECATED""" + + @deprecated("handle_get_padatious moved to padatious service, this method does nothing", "1.0.0") + def handle_get_padatious(self, message): + """DEPRECATED""" + + @deprecated("handle_padatious_manifest moved to padatious service, this method does nothing", "1.0.0") + def handle_padatious_manifest(self, message): + """DEPRECATED""" + + @deprecated("handle_entity_manifest moved to padatious service, this method does nothing", "1.0.0") + def handle_entity_manifest(self, message): + """DEPRECATED""" + + @deprecated("handle_register_vocab moved to individual pipeline services, this method does nothing", "1.0.0") + def handle_register_vocab(self, message): + """DEPRECATED""" + + @deprecated("handle_register_intent moved to individual pipeline services, this method does nothing", "1.0.0") + def handle_register_intent(self, message): + """DEPRECATED""" + + @deprecated("handle_detach_intent moved to individual pipeline services, this method does nothing", "1.0.0") + def handle_detach_intent(self, message): + """DEPRECATED""" + + @deprecated("handle_detach_skill moved to individual pipeline services, this method does nothing", "1.0.0") + def handle_detach_skill(self, message): + """DEPRECATED""" diff --git a/ovos_core/intent_services/adapt_service.py b/ovos_core/intent_services/adapt_service.py index d4342c126dc..53a5612852a 100644 --- a/ovos_core/intent_services/adapt_service.py +++ b/ovos_core/intent_services/adapt_service.py @@ -1,2 +1,4 @@ # backwards compat import from ovos_adapt.opm import AdaptPipeline as AdaptService +from ovos_utils.log import log_deprecation +log_deprecation("adapt service moved to 'ovos-adapt-pipeline-plugin'. this import is deprecated", "1.0.0") diff --git a/ovos_core/intent_services/commonqa_service.py b/ovos_core/intent_services/commonqa_service.py index 2af85e2ab22..00cfd52ac4a 100644 --- a/ovos_core/intent_services/commonqa_service.py +++ b/ovos_core/intent_services/commonqa_service.py @@ -1 +1,3 @@ from ovos_commonqa.opm import Query, CommonQAService +from ovos_utils.log import log_deprecation +log_deprecation("adapt service moved to 'ovos-common-query-pipeline-plugin'. this import is deprecated", "1.0.0") diff --git a/ovos_core/intent_services/converse_service.py b/ovos_core/intent_services/converse_service.py index ace8b73725a..37a9d99ce29 100644 --- a/ovos_core/intent_services/converse_service.py +++ b/ovos_core/intent_services/converse_service.py @@ -5,14 +5,13 @@ from ovos_bus_client.message import Message 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_plugin_manager.templates.pipeline import PipelineMatch, 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): @@ -313,7 +312,7 @@ def converse(self, utterances: List[str], skill_id: str, lang: str, message: Mes f'increasing "max_skill_runtime" in mycroft.conf might help alleviate this issue') return False - def converse_with_skills(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def converse_with_skills(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """Give active skills a chance at the utterance Args: @@ -338,12 +337,11 @@ def converse_with_skills(self, utterances: List[str], lang: str, message: Messag continue if self.converse(utterances, skill_id, lang, message): state = session.utterance_states.get(skill_id, UtteranceState.INTENT) - return IntentMatch(intent_service='Converse', - intent_type=state != UtteranceState.RESPONSE, - # intent_type == True -> emit "ovos.utterance.handled" - intent_data={}, - skill_id=skill_id, - utterance=utterances[0]) + return PipelineMatch(handled=state != UtteranceState.RESPONSE, + # handled == True -> emit "ovos.utterance.handled" + match_data={}, + skill_id=skill_id, + utterance=utterances[0]) return None @staticmethod diff --git a/ovos_core/intent_services/fallback_service.py b/ovos_core/intent_services/fallback_service.py index b4374a56b7e..df2d5cb042f 100644 --- a/ovos_core/intent_services/fallback_service.py +++ b/ovos_core/intent_services/fallback_service.py @@ -20,13 +20,12 @@ 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_plugin_manager.templates.pipeline import PipelineMatch, 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']) @@ -166,7 +165,7 @@ def attempt_fallback(self, utterances: List[str], skill_id: str, lang: str, mess return False def _fallback_range(self, utterances: List[str], lang: str, - message: Message, fb_range: FallbackRange) -> Optional[IntentMatch]: + message: Message, fb_range: FallbackRange) -> Optional[PipelineMatch]: """Send fallback request for a specified priority range. Args: @@ -177,7 +176,7 @@ def _fallback_range(self, utterances: List[str], lang: str, fb_range (FallbackRange): fallback order start and stop. Returns: - IntentMatch or None + PipelineMatch or None """ lang = standardize_lang_tag(lang) # we call flatten in case someone is sending the old style list of tuples @@ -197,24 +196,23 @@ def _fallback_range(self, utterances: List[str], lang: str, continue result = self.attempt_fallback(utterances, skill_id, lang, message) if result: - return IntentMatch(intent_service='Fallback', - intent_type=None, - intent_data={}, - skill_id=skill_id, - utterance=utterances[0]) + return PipelineMatch(handled=True, + match_data={}, + skill_id=skill_id, + utterance=utterances[0]) return None - def high_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def high_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """Pre-padatious fallbacks.""" return self._fallback_range(utterances, lang, message, FallbackRange(0, 5)) - def medium_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def medium_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """General fallbacks.""" return self._fallback_range(utterances, lang, message, FallbackRange(5, 90)) - def low_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def low_prio(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """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/ocp_service.py b/ovos_core/intent_services/ocp_service.py index 91e953bdb19..0a77f8c255f 100644 --- a/ovos_core/intent_services/ocp_service.py +++ b/ovos_core/intent_services/ocp_service.py @@ -1,2 +1,4 @@ # backwards compat imports from ocp_pipeline.opm import OCPPipelineMatcher, OCPFeaturizer, OCPPlayerProxy +from ovos_utils.log import log_deprecation +log_deprecation("adapt service moved to 'ovos-ocp-pipeline-plugin'. this import is deprecated", "1.0.0") diff --git a/ovos_core/intent_services/padacioso_service.py b/ovos_core/intent_services/padacioso_service.py index 8caf454e346..9f6afcda9fa 100644 --- a/ovos_core/intent_services/padacioso_service.py +++ b/ovos_core/intent_services/padacioso_service.py @@ -1,3 +1,5 @@ # backwards compat imports from padacioso.opm import PadaciosoPipeline as PadaciosoService, PadaciosoIntent from padacioso import IntentContainer as FallbackIntentContainer +from ovos_utils.log import log_deprecation +log_deprecation("adapt service moved to 'padacioso.opm'. this import is deprecated", "1.0.0") diff --git a/ovos_core/intent_services/padatious_service.py b/ovos_core/intent_services/padatious_service.py index 3b3d5fefd2d..242d101325c 100644 --- a/ovos_core/intent_services/padatious_service.py +++ b/ovos_core/intent_services/padatious_service.py @@ -1,2 +1,4 @@ # backwards compat imports from ovos_padatious.opm import PadatiousMatcher, PadatiousPipeline as PadatiousService +from ovos_utils.log import log_deprecation +log_deprecation("adapt service moved to 'ovos-padatious-pipeline-plugin'. this import is deprecated", "1.0.0") diff --git a/ovos_core/intent_services/stop_service.py b/ovos_core/intent_services/stop_service.py index bdb1137a75f..f9ba7f17b0b 100644 --- a/ovos_core/intent_services/stop_service.py +++ b/ovos_core/intent_services/stop_service.py @@ -5,11 +5,11 @@ 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_plugin_manager.templates.pipeline import PipelineMatch, PipelinePlugin from ovos_utils import flatten_list from ovos_utils.bracket_expansion import expand_options from ovos_utils.lang import standardize_lang_tag @@ -113,7 +113,7 @@ def stop_skill(self, skill_id: str, message: Message) -> bool: elif result is not None: return result.data.get('result', False) - def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """If utterance is an exact match for "stop" , run before intent stage Args: @@ -122,7 +122,7 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> message (Message): message to use to generate reply Returns: - IntentMatch if handled otherwise None. + PipelineMatch if handled otherwise None. """ lang = self._get_closest_lang(lang) if lang is None: # no vocs registered for this lang @@ -142,11 +142,10 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> if is_global_stop: # emit a global stop, full stop anything OVOS is doing self.bus.emit(message.reply("mycroft.stop", {})) - return IntentMatch(intent_service='Stop', - intent_type=True, - intent_data={"conf": conf}, - skill_id=None, - utterance=utterance) + return PipelineMatch(handled=True, + match_data={"conf": conf}, + skill_id=None, + utterance=utterance) if is_stop: # check if any skill can stop @@ -156,14 +155,13 @@ def match_stop_high(self, utterances: List[str], lang: str, message: Message) -> continue if self.stop_skill(skill_id, message): - return IntentMatch(intent_service='Stop', - intent_type=True, - intent_data={"conf": conf}, - skill_id=skill_id, - utterance=utterance) + return PipelineMatch(handled=True, + match_data={"conf": conf}, + skill_id=skill_id, + utterance=utterance) return None - def match_stop_medium(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def match_stop_medium(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """ if "stop" intent is in the utterance, but it contains additional words not in .intent files @@ -173,7 +171,7 @@ def match_stop_medium(self, utterances: List[str], lang: str, message: Message) message (Message): message to use to generate reply Returns: - IntentMatch if handled otherwise None. + PipelineMatch if handled otherwise None. """ lang = self._get_closest_lang(lang) if lang is None: # no vocs registered for this lang @@ -203,7 +201,7 @@ def _get_closest_lang(self, lang: str) -> Optional[str]: return closest return None - def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Optional[IntentMatch]: + def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> Optional[PipelineMatch]: """ before fallback_low , fuzzy match stop intent Args: @@ -212,7 +210,7 @@ def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> message (Message): message to use to generate reply Returns: - IntentMatch if handled otherwise None. + PipelineMatch if handled otherwise None. """ lang = self._get_closest_lang(lang) if lang is None: # no vocs registered for this lang @@ -236,20 +234,18 @@ def match_stop_low(self, utterances: List[str], lang: str, message: Message) -> continue if self.stop_skill(skill_id, message): - return IntentMatch(intent_service='Stop', - intent_type=True, - # emit instead of intent message - intent_data={"conf": conf}, - skill_id=skill_id, utterance=utterance) + return PipelineMatch(handled=True, + # emit instead of intent message + match_data={"conf": conf}, + skill_id=skill_id, utterance=utterance) # emit a global stop, full stop anything OVOS is doing self.bus.emit(message.reply("mycroft.stop", {})) - return IntentMatch(intent_service='Stop', - intent_type=True, - # emit instead of intent message {"conf": conf}, - intent_data={}, - skill_id=None, - utterance=utterance) + return PipelineMatch(handled=True, + # emit instead of intent message {"conf": conf}, + match_data={"conf": conf}, + skill_id=None, + utterance=utterance) def voc_match(self, utt: str, voc_filename: str, lang: str, exact: bool = False): diff --git a/ovos_core/skill_manager.py b/ovos_core/skill_manager.py index b66f041aec8..50fe0c39050 100644 --- a/ovos_core/skill_manager.py +++ b/ovos_core/skill_manager.py @@ -206,32 +206,6 @@ def _define_message_bus_events(self): self.bus.on("mycroft.internet.disconnected", self.handle_internet_disconnected) self.bus.on("mycroft.gui.unavailable", self.handle_gui_disconnected) - @deprecated("mycroft.ready event has moved to finished booting skill", "0.1.0") - def is_device_ready(self): - """Check if the device is ready by waiting for various services to start. - - Returns: - bool: True if the device is ready, False otherwise. - Raises: - TimeoutError: If the device is not ready within a specified timeout. - """ - return True - - @deprecated("mycroft.ready event has moved to finished booting skill", "0.1.0") - def handle_check_device_readiness(self, message): - pass - - @deprecated("mycroft.ready event has moved to finished booting skill", "0.1.0") - def check_services_ready(self, services): - """Report if all specified services are ready. - - Args: - services (iterable): Service names to check. - Returns: - bool: True if all specified services are ready, False otherwise. - """ - return True - @property def skills_config(self): """Get the skills service configuration. @@ -389,10 +363,6 @@ def _load_plugin_skill(self, skill_id, skill_plugin): return skill_loader if load_status else None - @deprecated("priority skills have been deprecated for a long time", "0.1.0") - def load_priority(self): - pass - def run(self): """Run the skill manager thread.""" self.status.set_alive() @@ -742,3 +712,35 @@ def stop(self): if self._settings_watchdog: self._settings_watchdog.shutdown() + + ############ + # Deprecated stuff + @deprecated("priority skills have been deprecated for a long time", "1.0.0") + def load_priority(self): + pass + + @deprecated("mycroft.ready event has moved to finished booting skill", "1.0.0") + def is_device_ready(self): + """Check if the device is ready by waiting for various services to start. + + Returns: + bool: True if the device is ready, False otherwise. + Raises: + TimeoutError: If the device is not ready within a specified timeout. + """ + return True + + @deprecated("mycroft.ready event has moved to finished booting skill", "1.0.0") + def handle_check_device_readiness(self, message): + pass + + @deprecated("mycroft.ready event has moved to finished booting skill", "1.0.0") + def check_services_ready(self, services): + """Report if all specified services are ready. + + Args: + services (iterable): Service names to check. + Returns: + bool: True if all specified services are ready, False otherwise. + """ + return True diff --git a/requirements/lgpl.txt b/requirements/lgpl.txt index e92ee3c4a82..cf36b2b4d27 100644 --- a/requirements/lgpl.txt +++ b/requirements/lgpl.txt @@ -1,2 +1,2 @@ -ovos_padatious>=0.1.3,<1.0.0 +ovos_padatious>=1.0.3, <2.0.0 fann2>=1.0.7, < 1.1.0 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 14d54b1f630..731ab8a2720 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -3,15 +3,15 @@ python-dateutil>=2.6, <3.0 watchdog>=2.1, <3.0 combo-lock>=0.2.2, <0.3 -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 +padacioso>=1.0.0, <2.0.0 +ovos-adapt-parser>=1.0.4, <2.0.0 +ovos_ocp_pipeline_plugin>=1.0.4, <2.0.0 +ovos-common-query-pipeline-plugin>=1.0.2, <2.0.0 ovos-utils>=0.3.5,<1.0.0 ovos_bus_client>=0.1.4,<1.0.0 -ovos-plugin-manager>=0.0.26,<1.0.0 +ovos-plugin-manager>=0.5.0,<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>=1.0.1,<2.0.0 \ No newline at end of file +ovos-workshop>=2.0.0,<3.0.0 \ No newline at end of file diff --git a/requirements/skills-audio.txt b/requirements/skills-audio.txt index b71f3c7bf63..a14c5181201 100644 --- a/requirements/skills-audio.txt +++ b/requirements/skills-audio.txt @@ -1,7 +1,7 @@ # skills that run in audio enabled devices (require mic/speaker) -ovos-skill-boot-finished>=0.3.0,<1.0.0 +ovos-skill-boot-finished>=0.4.4,<1.0.0 ovos-skill-audio-recording>=0.2.2,<1.0.0 -ovos-skill-dictation>=0.2.0,<1.0.0 -ovos-skill-parrot>=0.1.2,<1.0.0 -ovos-skill-volume>=0.1.1,<1.0.0 -ovos-skill-naptime>=0.3.1,<1.0.0 +ovos-skill-dictation>=0.2.1,<1.0.0 +ovos-skill-parrot>=0.1.3,<1.0.0 +ovos-skill-volume>=0.1.2,<1.0.0 +ovos-skill-naptime>=0.3.3,<1.0.0 diff --git a/requirements/skills-desktop.txt b/requirements/skills-desktop.txt index a5f4295e72d..1e31de3c99f 100644 --- a/requirements/skills-desktop.txt +++ b/requirements/skills-desktop.txt @@ -1,2 +1,2 @@ # skills that require a linux desktop environment -ovos-skill-application-launcher>=0.2.1,<1.0.0 +ovos-skill-application-launcher>=0.5.3,<1.0.0 diff --git a/requirements/skills-essential.txt b/requirements/skills-essential.txt index 9eeea909940..f3b89111218 100644 --- a/requirements/skills-essential.txt +++ b/requirements/skills-essential.txt @@ -1,9 +1,9 @@ # skills providing core functionality (offline) -ovos-skill-fallback-unknown>=0.1.2,<1.0.0 +ovos-skill-fallback-unknown>=0.1.3,<1.0.0 ovos-skill-alerts>=0.1.2,<1.0.0 -ovos-skill-personal>=0.1.4,<1.0.0 -ovos-skill-date-time>=0.3.2,<1.0.0 -ovos-skill-hello-world>=0.1.6,<1.0.0 -skill-wordnet>=0.0.4,<1.0.0 +ovos-skill-personal>=0.1.5,<1.0.0 +ovos-skill-date-time>=0.3.4,<1.0.0 +ovos-skill-hello-world>=0.1.7,<1.0.0 +skill-wordnet>=0.0.6,<1.0.0 #skill-randomness>=0.0.1,<1.0.0 -ovos-skill-spelling>=0.2.2,<1.0.0 +ovos-skill-spelling>=0.2.3,<1.0.0 diff --git a/requirements/skills-gui.txt b/requirements/skills-gui.txt index c0b98856f07..f2c06be2d62 100644 --- a/requirements/skills-gui.txt +++ b/requirements/skills-gui.txt @@ -1 +1 @@ -ovos-skill-homescreen>=1.0.2,<2.0.0 +ovos-skill-homescreen>=1.0.3,<2.0.0 diff --git a/requirements/skills-internet.txt b/requirements/skills-internet.txt index 2bed72e9dc4..13f2cde85d6 100644 --- a/requirements/skills-internet.txt +++ b/requirements/skills-internet.txt @@ -1,9 +1,9 @@ # skills that require internet connectivity, should not be installed in offline devices -ovos-skill-weather>=0.1.1,<1.0.0 -skill-ddg>=0.1.2,<1.0.0 -skill-wolfie>=0.2.3,<1.0.0 -ovos-skill-wikipedia>=0.5.2,<1.0.0 -skill-ovos-fallback-chatgpt>=0.1.2,<1.0.0 -ovos-skill-wikihow>=0.2.3,<1.0.0 -ovos-skill-speedtest>=0.2.1,<1.0.0 +ovos-skill-weather>=0.1.4,<1.0.0 +skill-ddg>=0.1.3,<1.0.0 +skill-wolfie>=0.2.5,<1.0.0 +ovos-skill-wikipedia>=0.5.3,<1.0.0 +skill-ovos-fallback-chatgpt>=0.1.4,<1.0.0 +ovos-skill-wikihow>=0.2.5,<1.0.0 +ovos-skill-speedtest>=0.2.3,<1.0.0 ovos-skill-ip>=0.2.2,<1.0.0 diff --git a/requirements/skills-media.txt b/requirements/skills-media.txt index 1c77abca446..579f7e75a5e 100644 --- a/requirements/skills-media.txt +++ b/requirements/skills-media.txt @@ -1,5 +1,5 @@ # skills for OCP, require audio playback plugins (usually mpv) ovos-skill-somafm>=0.1.1,<1.0.0 -skill-news>=0.1.2,<1.0.0 -ovos-skill-pyradios>=0.1.0,<1.0.0 +skill-news>=0.1.3,<1.0.0 +ovos-skill-pyradios>=0.1.3,<1.0.0 ovos-skill-local-media>=0.2.1,<1.0.0 \ No newline at end of file diff --git a/test/end2end/routing/test_sched.py b/test/end2end/routing/test_sched.py index f9bf8000e13..639b8ed40d9 100644 --- a/test/end2end/routing/test_sched.py +++ b/test/end2end/routing/test_sched.py @@ -47,11 +47,9 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # no session - "intent.service.skills.activated", # response (from core) f"{self.skill_id}.activate", # skill callback f"{self.skill_id}:ScheduleIntent", # intent trigger "mycroft.skill.handler.start", # intent code start - "enclosure.active_skill", "speak", "mycroft.scheduler.schedule_event", @@ -61,7 +59,6 @@ def wait_for_n_messages(n): # skill event triggering after 3 seconds "skill-ovos-schedule.openvoiceos:my_event", - "enclosure.active_skill", "speak" ] wait_for_n_messages(len(expected_messages)) @@ -72,7 +69,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) # verify that source and destination are swapped after intent trigger - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:ScheduleIntent") for m in messages: # messages FOR ovos-core if m.msg_type in ["recognizer_loop:utterance", diff --git a/test/end2end/routing/test_session.py b/test/end2end/routing/test_session.py index 5adce21102a..f1cd842e3d3 100644 --- a/test/end2end/routing/test_session.py +++ b/test/end2end/routing/test_session.py @@ -52,11 +52,9 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # no session - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -75,7 +73,7 @@ def wait_for_n_messages(n): self.assertEqual(m.context["session"]["session_id"], "default") # verify that source and destination are swapped after intent trigger - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:HelloWorldIntent") for m in messages: if m.msg_type in ["recognizer_loop:utterance", "ovos.session.update_default"]: self.assertEqual(messages[0].context["source"], "A") @@ -95,7 +93,7 @@ def tearDown(self) -> None: self.core.stop() def test_no_session(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -123,7 +121,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -135,10 +133,8 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", "speak", "ovos.common_play.search.start", "enclosure.mouth.think", diff --git a/test/end2end/session/test_blacklist.py b/test/end2end/session/test_blacklist.py index 11a3df6428e..b2c9a2e609f 100644 --- a/test/end2end/session/test_blacklist.py +++ b/test/end2end/session/test_blacklist.py @@ -58,13 +58,10 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", # skill code executing - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled" # handle_utterance returned (intent service) @@ -138,7 +135,7 @@ def tearDown(self) -> None: self.core.stop() def test_ocp(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -163,7 +160,7 @@ def wait_for_n_messages(n): pipeline=[ "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -176,10 +173,8 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -222,10 +217,8 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -242,7 +235,6 @@ def wait_for_n_messages(n): "ovos.common_play.search.end", 'ovos.common_play.reset', # playback failure - would play if not blacklisted - "enclosure.active_skill", "speak", # "dialog":"cant.play" "ovos.utterance.handled" ] @@ -266,10 +258,8 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -286,7 +276,6 @@ def wait_for_n_messages(n): "ovos.common_play.search.end", 'ovos.common_play.reset', # playback failure - "enclosure.active_skill", "speak", # "dialog":"cant.play" "ovos.utterance.handled" ] @@ -349,13 +338,9 @@ def wait_for_n_messages(n): # skill executing f"ovos.skills.fallback.{self.skill_id}.request", f"ovos.skills.fallback.{self.skill_id}.start", - "enclosure.active_skill", "speak", - # activated only after skill return True - "intent.service.skills.activate", - "intent.service.skills.activated", - f"{self.skill_id}.activate", f"ovos.skills.fallback.{self.skill_id}.response", + f"{self.skill_id}.activate", "ovos.utterance.handled" ] wait_for_n_messages(len(expected_messages)) @@ -439,13 +424,10 @@ def wait_for_n_messages(n): "question:query.response", # searching "question:query.response", # response "enclosure.mouth.reset", - "question:action", - "intent.service.skills.activate", - "intent.service.skills.activated", f"{self.skill_id}.activate", - "enclosure.active_skill", + "question:action", # similar to an intent triggering + "mycroft.skill.handler.start", "speak", # answer - "enclosure.active_skill", "speak", # callback "mycroft.skill.handler.complete", "ovos.utterance.handled" diff --git a/test/end2end/session/test_converse.py b/test/end2end/session/test_converse.py index e7f0e2d3185..4520d73d67b 100644 --- a/test/end2end/session/test_converse.py +++ b/test/end2end/session/test_converse.py @@ -60,14 +60,12 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # no session - "intent.service.skills.activated", f"{self.skill_id}.activate", # skill selected f"{self.skill_id}:converse_off.intent", # skill triggering "mycroft.skill.handler.start", # intent code executing - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -88,18 +86,18 @@ def wait_for_n_messages(n): self.assertEqual(m.context["lang"], "en-US") # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.activate") # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:converse_off.intent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:converse_off.intent") # verify skill_id is present in every message.context for m in messages[1:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_converse_off") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_converse_off") self.assertEqual(messages[-3].msg_type, "mycroft.skill.handler.complete") self.assertEqual(messages[-3].data["name"], "TestAbortSkill.handle_converse_off") self.assertEqual(messages[-2].msg_type, "ovos.utterance.handled") @@ -133,12 +131,10 @@ def wait_for_n_messages(n): f"{self.skill_id}.converse.request", "skill.converse.response", # does not want to converse # skill selected - "intent.service.skills.activated", f"{self.other_skill_id}.activate", f"{self.other_skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", # skill executing - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -175,17 +171,17 @@ def wait_for_n_messages(n): self.assertFalse(messages[4].data["result"]) # does not want to converse # verify skill is activated - self.assertEqual(messages[5].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[5].data["skill_id"], self.other_skill_id) - self.assertEqual(messages[6].msg_type, f"{self.other_skill_id}.activate") + self.assertEqual(messages[5].msg_type, f"{self.other_skill_id}.activate") # verify intent triggers - self.assertEqual(messages[7].msg_type, f"{self.other_skill_id}:HelloWorldIntent") + self.assertEqual(messages[6].msg_type, f"{self.other_skill_id}:HelloWorldIntent") # verify skill_id is present in every message.context for m in messages[5:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.other_skill_id) - self.assertEqual(messages[8].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[8].data["name"], "HelloWorldSkill.handle_hello_world_intent") + self.assertEqual(messages[7].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[7].data["name"], "HelloWorldSkill.handle_hello_world_intent") # verify intent execution self.assertEqual(messages[-3].msg_type, "mycroft.skill.handler.complete") @@ -220,18 +216,15 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", # no session f"{self.skill_id}.converse.ping", # default session injected - f"{self.other_skill_id}.converse.ping", "skill.converse.pong", + f"{self.other_skill_id}.converse.ping", "skill.converse.pong", f"{self.skill_id}.converse.request", "skill.converse.response", # does not want to converse - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:converse_on.intent", # skill executing "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -268,20 +261,17 @@ def wait_for_n_messages(n): self.assertEqual(messages[6].data["skill_id"], self.skill_id) self.assertFalse(messages[6].data["result"]) # do not want to converse - # verify skill is activated by intent service (intent pipeline matched) - self.assertEqual(messages[7].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[7].data["skill_id"], self.skill_id) - self.assertEqual(messages[8].msg_type, f"{self.skill_id}.activate") - # verify intent triggers - self.assertEqual(messages[9].msg_type, f"{self.skill_id}:converse_on.intent") + self.assertEqual(messages[8].msg_type, f"{self.skill_id}:converse_on.intent") # verify skill_id is now present in every message.context - for m in messages[7:]: + for m in messages[8:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent execution - self.assertEqual(messages[10].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[10].data["name"], "TestAbortSkill.handle_converse_on") + self.assertEqual(messages[9].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[9].data["name"], "TestAbortSkill.handle_converse_on") self.assertEqual(messages[-3].msg_type, "mycroft.skill.handler.complete") self.assertEqual(messages[-3].data["name"], "TestAbortSkill.handle_converse_on") @@ -313,16 +303,12 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", # no session f"{self.skill_id}.converse.ping", # default session injected - f"{self.other_skill_id}.converse.ping", "skill.converse.pong", + f"{self.other_skill_id}.converse.ping", "skill.converse.pong", f"{self.skill_id}.converse.request", - # skill selected - "intent.service.skills.activate", - "intent.service.skills.activated", - f"{self.skill_id}.activate", - "ovos.session.update_default", "skill.converse.response", # CONVERSED + f"{self.skill_id}.activate", "ovos.utterance.handled", # handle_utterance returned (intent service) # session updated "ovos.session.update_default" @@ -354,21 +340,13 @@ def wait_for_n_messages(n): # verify answer from skill that it does not want to converse self.assertEqual(messages[5].msg_type, f"{self.skill_id}.converse.request") - # verify skill is activated by intent service (intent pipeline matched) - self.assertEqual(messages[6].msg_type, "intent.service.skills.activate") - self.assertEqual(messages[6].data["skill_id"], self.skill_id) - self.assertEqual(messages[7].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[7].data["skill_id"], self.skill_id) - self.assertEqual(messages[8].msg_type, f"{self.skill_id}.activate") - self.assertEqual(messages[9].msg_type, "ovos.session.update_default") - # verify skill conversed - self.assertEqual(messages[10].msg_type, "skill.converse.response") - self.assertEqual(messages[10].data["skill_id"], self.skill_id) - self.assertTrue(messages[10].data["result"]) # CONVERSED + self.assertEqual(messages[-4].msg_type, "skill.converse.response") + self.assertEqual(messages[-4].data["skill_id"], self.skill_id) + self.assertTrue(messages[-4].data["result"]) # CONVERSED # verify default session is now updated - self.assertEqual(messages[11].msg_type, "ovos.utterance.handled") + self.assertEqual(messages[-2].msg_type, "ovos.utterance.handled") self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") self.assertEqual(messages[-1].data["session_data"]["session_id"], "default") # test deserialization of payload @@ -472,7 +450,6 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # no session - "intent.service.skills.activated", f"{self.skill_id}.activate", "ovos-tskill-abort.openvoiceos:deactivate.intent", # skill selected @@ -482,7 +459,6 @@ def wait_for_n_messages(n): "intent.service.skills.deactivated", f"{self.skill_id}.deactivate", "ovos.session.update_default", - "enclosure.active_skill", "speak", # "deactivated" "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) diff --git a/test/end2end/session/test_fallback.py b/test/end2end/session/test_fallback.py index 0aca1e32fdf..7b4e33b533d 100644 --- a/test/end2end/session/test_fallback.py +++ b/test/end2end/session/test_fallback.py @@ -61,16 +61,10 @@ def wait_for_n_messages(n): # skill executing f"ovos.skills.fallback.{self.skill_id}.request", f"ovos.skills.fallback.{self.skill_id}.start", - "enclosure.active_skill", "speak", - - # activated only after skill return True - "intent.service.skills.activate", - "intent.service.skills.activated", - f"{self.skill_id}.activate", - "ovos.session.update_default", - f"ovos.skills.fallback.{self.skill_id}.response", + # activated only after skill returns True + f"{self.skill_id}.activate", "ovos.utterance.handled", # handle_utterance returned (intent service) "ovos.session.update_default" ] @@ -86,7 +80,7 @@ def wait_for_n_messages(n): self.assertEqual(m.context["session"]["session_id"], "default") self.assertEqual(m.context["x"], "xx") # verify active skills is empty until "intent.service.skills.activated" - for m in messages[:8]: + for m in messages[:7]: self.assertEqual(m.context["session"]["session_id"], "default") self.assertEqual(m.context["session"]["active_skills"], []) @@ -101,24 +95,14 @@ def wait_for_n_messages(n): self.assertEqual(messages[3].msg_type, f"ovos.skills.fallback.{self.skill_id}.request") self.assertEqual(messages[3].data["skill_id"], self.skill_id) self.assertEqual(messages[4].msg_type, f"ovos.skills.fallback.{self.skill_id}.start") - 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["meta"]["dialog"], "unknown") - self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) - - # verify skill is activated - self.assertEqual(messages[7].msg_type, "intent.service.skills.activate") - self.assertEqual(messages[7].data["skill_id"], self.skill_id) - self.assertEqual(messages[8].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[8].data["skill_id"], self.skill_id) - self.assertEqual(messages[9].msg_type, f"{self.skill_id}.activate") - self.assertEqual(messages[10].msg_type, "ovos.session.update_default") + self.assertEqual(messages[5].msg_type, "speak") + self.assertEqual(messages[5].data["meta"]["dialog"], "unknown") + self.assertEqual(messages[5].data["meta"]["skill"], self.skill_id) # end of fallback - self.assertEqual(messages[11].msg_type, f"ovos.skills.fallback.{self.skill_id}.response") - self.assertTrue(messages[11].data["result"]) - self.assertEqual(messages[11].data["fallback_handler"], "UnknownSkill.handle_fallback") + self.assertEqual(messages[6].msg_type, f"ovos.skills.fallback.{self.skill_id}.response") + self.assertTrue(messages[6].data["result"]) + self.assertEqual(messages[6].data["fallback_handler"], "UnknownSkill.handle_fallback") # verify default session is now updated self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") @@ -131,6 +115,7 @@ def wait_for_n_messages(n): self.core.bus.emit(utt) # converse ping/pong due being active expected_messages.extend([f"{self.skill_id}.converse.ping", "skill.converse.pong"]) + wait_for_n_messages(len(expected_messages)) self.assertEqual(len(expected_messages), len(messages)) @@ -189,14 +174,10 @@ def wait_for_n_messages(n): # skill executing - TODO "mycroft.skill.handler.start" + "mycroft.skill.handler.complete" should be added f"ovos.skills.fallback.{self.skill_id}.request", f"ovos.skills.fallback.{self.skill_id}.start", - "enclosure.active_skill", - "speak", - # activate skill on return True - "intent.service.skills.activate", - "intent.service.skills.activated", - f"{self.skill_id}.activate", + "speak", f"ovos.skills.fallback.{self.skill_id}.response", + f"{self.skill_id}.activate", "ovos.utterance.handled" # handle_utterance returned (intent service) ] wait_for_n_messages(len(expected_messages)) @@ -221,22 +202,12 @@ def wait_for_n_messages(n): self.assertEqual(messages[3].msg_type, f"ovos.skills.fallback.{self.skill_id}.request") self.assertEqual(messages[3].data["skill_id"], self.skill_id) self.assertEqual(messages[4].msg_type, f"ovos.skills.fallback.{self.skill_id}.start") - 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["meta"]["dialog"], "unknown") - self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) - - # verify skill is activated - self.assertEqual(messages[7].msg_type, "intent.service.skills.activate") - self.assertEqual(messages[7].data["skill_id"], self.skill_id) - self.assertEqual(messages[8].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[8].data["skill_id"], self.skill_id) - self.assertEqual(messages[9].msg_type, f"{self.skill_id}.activate") - - self.assertEqual(messages[10].msg_type, f"ovos.skills.fallback.{self.skill_id}.response") - self.assertTrue(messages[10].data["result"]) - self.assertEqual(messages[10].data["fallback_handler"], "UnknownSkill.handle_fallback") + self.assertEqual(messages[5].msg_type, "speak") + self.assertEqual(messages[5].data["meta"]["dialog"], "unknown") + self.assertEqual(messages[5].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[6].msg_type, f"ovos.skills.fallback.{self.skill_id}.response") + self.assertTrue(messages[6].data["result"]) + self.assertEqual(messages[6].data["fallback_handler"], "UnknownSkill.handle_fallback") # test that active skills list has been updated for m in messages[10:]: @@ -286,7 +257,7 @@ def wait_for_n_messages(n): # skill executing f"ovos.skills.fallback.{self.skill_id}.request", f"ovos.skills.fallback.{self.skill_id}.start", - "enclosure.active_skill", + "speak", # deactivate skill in fallback handler "intent.service.skills.deactivate", @@ -369,16 +340,11 @@ def wait_for_n_messages(n): # skill executing f"ovos.skills.fallback.{self.skill_id}.request", f"ovos.skills.fallback.{self.skill_id}.start", - "enclosure.active_skill", "speak", + f"ovos.skills.fallback.{self.skill_id}.response", # activated only after skill return True - "intent.service.skills.activate", - "intent.service.skills.activated", f"{self.skill_id}.activate", - "ovos.session.update_default", - - f"ovos.skills.fallback.{self.skill_id}.response", "ovos.utterance.handled", # handle_utterance returned (intent service) "ovos.session.update_default" ] diff --git a/test/end2end/session/test_get_response.py b/test/end2end/session/test_get_response.py index 42fd20cf76c..b2320d41a16 100644 --- a/test/end2end/session/test_get_response.py +++ b/test/end2end/session/test_get_response.py @@ -61,15 +61,13 @@ def on_speak(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response "ovos.session.update_default", # sync get_response status - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -80,7 +78,7 @@ def on_speak(msg): "skill.converse.get_response.disable", # end of get_response "ovos.session.update_default", # sync get_response status # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + # from speak inside intent "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -102,56 +100,31 @@ def on_speak(msg): self.assertEqual(m.context["session"]["session_id"], "default") self.assertEqual(m.context["lang"], "en-US") - # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response.intent") # verify skill_id is now present in every message.context for m in messages[1:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_test_get_response") - - # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") - - # enable get_response for this session - self.assertEqual(messages[5].msg_type, "skill.converse.get_response.enable") - self.assertEqual(messages[6].msg_type, "ovos.session.update_default") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_test_get_response") # question dialog - 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.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") - self.assertEqual(messages[10].msg_type, "recognizer_loop:audio_output_end") - - # user response would be here - - self.assertEqual(messages[11].msg_type, f"{self.skill_id}.get_response.waiting") - # disable get_response for this session - self.assertEqual(messages[12].msg_type, "skill.converse.get_response.disable") - self.assertEqual(messages[13].msg_type, "ovos.session.update_default") + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["lang"], "en-US") + self.assertTrue(messages[6].data["expect_response"]) # listen after dialog + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) # post self.get_response intent code - 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.assertFalse(messages[15].data["expect_response"]) - self.assertEqual(messages[15].data["utterance"], "ERROR") - self.assertEqual(messages[15].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[12].msg_type, "speak") + self.assertEqual(messages[12].data["lang"], "en-US") + self.assertFalse(messages[12].data["expect_response"]) + self.assertEqual(messages[12].data["utterance"], "ERROR") + self.assertEqual(messages[12].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[16].msg_type, "recognizer_loop:audio_output_start") - self.assertEqual(messages[17].msg_type, "recognizer_loop:audio_output_end") - - self.assertEqual(messages[18].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[19].data["name"], "TestAbortSkill.handle_test_get_response") + self.assertEqual(messages[15].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[15].data["name"], "TestAbortSkill.handle_test_get_response") # verify default session is now updated self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") @@ -211,15 +184,13 @@ def answer_get_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response "ovos.session.update_default", # sync get_response status - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -235,7 +206,7 @@ def answer_get_response(msg): "skill.converse.get_response.disable", # end of get_response "ovos.session.update_default", # sync get_response status # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ok" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -252,72 +223,35 @@ def answer_get_response(msg): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") - # verify that "session" is injected # (missing in utterance message) and kept in all messages for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response.intent") - # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_test_get_response") - - - # enable get_response for this session - self.assertEqual(messages[5].msg_type, "skill.converse.get_response.enable") - self.assertEqual(messages[6].msg_type, "ovos.session.update_default") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_test_get_response") # question dialog - 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["utterance"], "give me an answer", ) - 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) - self.assertEqual(messages[9].msg_type, "recognizer_loop:audio_output_start") - self.assertEqual(messages[10].msg_type, "recognizer_loop:audio_output_end") - - # check utterance goes through converse cycle - self.assertEqual(messages[11].msg_type, "recognizer_loop:utterance") - self.assertEqual(messages[12].msg_type, f"{self.skill_id}.converse.ping") - self.assertEqual(messages[13].msg_type, "skill.converse.pong") + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["utterance"], "give me an answer", ) + self.assertEqual(messages[6].data["lang"], "en-US") + self.assertTrue(messages[6].data["expect_response"]) # listen after dialog + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) # captured utterance sent to get_response handler that is waiting - self.assertEqual(messages[14].msg_type, f"{self.skill_id}.converse.get_response") - self.assertEqual(messages[14].data["utterances"], ["ok"]) - - # converse pipeline activates the skill last_used timestamp - self.assertEqual(messages[15].msg_type, "ovos.session.update_default") - - self.assertEqual(messages[16].msg_type, f"{self.skill_id}.get_response.waiting") - - # disable get_response for this session - self.assertEqual(messages[17].msg_type, "skill.converse.get_response.disable") - self.assertEqual(messages[18].msg_type, "ovos.session.update_default") + self.assertEqual(messages[12].msg_type, f"{self.skill_id}.converse.get_response") + self.assertEqual(messages[12].data["utterances"], ["ok"]) # post self.get_response intent code - 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.assertFalse(messages[20].data["expect_response"]) - self.assertEqual(messages[20].data["utterance"], "ok") - self.assertEqual(messages[20].data["meta"]["skill"], self.skill_id) - # ovos-audio speak execution (simulated) - self.assertEqual(messages[21].msg_type, "recognizer_loop:audio_output_start") - self.assertEqual(messages[22].msg_type, "recognizer_loop:audio_output_end") - - self.assertEqual(messages[23].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[23].data["name"], "TestAbortSkill.handle_test_get_response") + self.assertEqual(messages[17].msg_type, "speak") + self.assertEqual(messages[17].data["lang"], "en-US") + self.assertFalse(messages[17].data["expect_response"]) + self.assertEqual(messages[17].data["utterance"], "ok") + self.assertEqual(messages[17].data["meta"]["skill"], self.skill_id) + + self.assertEqual(messages[20].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[20].data["name"], "TestAbortSkill.handle_test_get_response") # verify default session is now updated self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") @@ -376,15 +310,13 @@ def answer_get_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response "ovos.session.update_default", # sync get_response status - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -401,7 +333,7 @@ def answer_get_response(msg): "skill.converse.get_response.disable", # end of get_response "ovos.session.update_default", # sync get_response status # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -424,65 +356,31 @@ def answer_get_response(msg): for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response.intent") - # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_test_get_response") - - # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") - - # enable get_response for this session - self.assertEqual(messages[5].msg_type, "skill.converse.get_response.enable") - self.assertEqual(messages[6].msg_type, "ovos.session.update_default") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_test_get_response") # question dialog - 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["utterance"], "give me an answer", ) - 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) - self.assertEqual(messages[9].msg_type, "recognizer_loop:audio_output_start") - self.assertEqual(messages[10].msg_type, "recognizer_loop:audio_output_end") - - # check utterance goes through converse cycle - self.assertEqual(messages[11].msg_type, "recognizer_loop:utterance") - self.assertEqual(messages[12].msg_type, f"{self.skill_id}.converse.ping") - self.assertEqual(messages[13].msg_type, "skill.converse.pong") + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["utterance"], "give me an answer", ) + self.assertEqual(messages[6].data["lang"], "en-US") + self.assertTrue(messages[6].data["expect_response"]) # listen after dialog + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) # captured utterance sent to get_response handler that is waiting - self.assertEqual(messages[14].msg_type, f"{self.skill_id}.converse.get_response") - self.assertEqual(messages[14].data["utterances"], ["cancel"]) # was canceled by user, returned None - - # converse pipeline activates the skill last_used timestamp - self.assertEqual(messages[15].msg_type, "ovos.session.update_default") - - self.assertEqual(messages[16].msg_type, f"{self.skill_id}.get_response.waiting") - # disable get_response for this session - self.assertEqual(messages[17].msg_type, "skill.converse.get_response.disable") - self.assertEqual(messages[18].msg_type, "ovos.session.update_default") + self.assertEqual(messages[12].msg_type, f"{self.skill_id}.converse.get_response") + self.assertEqual(messages[12].data["utterances"], ["cancel"]) # was canceled by user, returned None # post self.get_response intent code - 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.assertFalse(messages[20].data["expect_response"]) - self.assertEqual(messages[20].data["utterance"], "ERROR") - self.assertEqual(messages[20].data["meta"]["skill"], self.skill_id) - # ovos-audio speak execution (simulated) - self.assertEqual(messages[21].msg_type, "recognizer_loop:audio_output_start") - self.assertEqual(messages[22].msg_type, "recognizer_loop:audio_output_end") - - self.assertEqual(messages[23].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[23].data["name"], "TestAbortSkill.handle_test_get_response") + self.assertEqual(messages[17].msg_type, "speak") + self.assertEqual(messages[17].data["lang"], "en-US") + self.assertFalse(messages[17].data["expect_response"]) + self.assertEqual(messages[17].data["utterance"], "ERROR") + self.assertEqual(messages[17].data["meta"]["skill"], self.skill_id) + + # vrify handler name + self.assertEqual(messages[20].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[20].data["name"], "TestAbortSkill.handle_test_get_response") # verify default session is now updated self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") @@ -543,8 +441,6 @@ def answer_get_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response3.intent", "mycroft.skill.handler.start", @@ -568,7 +464,7 @@ def answer_get_response(msg): "skill.converse.get_response.disable", # end of get_response "ovos.session.update_default", # sync get_response status # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ok" inside intent "mycroft.skill.handler.complete", # original intent finished executing @@ -589,53 +485,23 @@ def answer_get_response(msg): for m in messages[1:]: self.assertEqual(m.context["session"]["session_id"], "default") - # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response3.intent") - # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_test_get_response3") - - # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") - - # enable get_response for this session - self.assertEqual(messages[5].msg_type, "skill.converse.get_response.enable") - self.assertEqual(messages[6].msg_type, "ovos.session.update_default") - - # 3 sound prompts (no dialog in this test) - self.assertEqual(messages[7].msg_type, "mycroft.mic.listen") - self.assertEqual(messages[8].msg_type, f"{self.skill_id}.get_response.waiting") - self.assertEqual(messages[9].msg_type, "mycroft.mic.listen") - self.assertEqual(messages[10].msg_type, "mycroft.mic.listen") - - # check utterance goes through converse cycle - self.assertEqual(messages[11].msg_type, "recognizer_loop:utterance") - self.assertEqual(messages[12].msg_type, f"{self.skill_id}.converse.ping") - self.assertEqual(messages[13].msg_type, "skill.converse.pong") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_test_get_response3") # captured utterance sent to get_response handler that is waiting - self.assertEqual(messages[14].msg_type, f"{self.skill_id}.converse.get_response") - self.assertEqual(messages[14].data["utterances"], ["ok"]) - self.assertEqual(messages[15].msg_type, "ovos.session.update_default") - - # disable get_response for this session - self.assertEqual(messages[16].msg_type, "skill.converse.get_response.disable") - self.assertEqual(messages[17].msg_type, "ovos.session.update_default") + self.assertEqual(messages[13].msg_type, f"{self.skill_id}.converse.get_response") + self.assertEqual(messages[13].data["utterances"], ["ok"]) # post self.get_response intent code - 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.assertFalse(messages[19].data["expect_response"]) - self.assertEqual(messages[19].data["utterance"], "ok") - self.assertEqual(messages[19].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[17].msg_type, "speak") + self.assertEqual(messages[17].data["lang"], "en-US") + self.assertFalse(messages[17].data["expect_response"]) + self.assertEqual(messages[17].data["utterance"], "ok") + self.assertEqual(messages[17].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[20].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[20].data["name"], "TestAbortSkill.handle_test_get_response3") + self.assertEqual(messages[18].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[18].data["name"], "TestAbortSkill.handle_test_get_response3") # verify default session is now updated self.assertEqual(messages[-1].msg_type, "ovos.session.update_default") @@ -701,15 +567,13 @@ def answer_get_response(msg): expected_messages = [ "recognizer_loop:utterance", # no session - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response_cascade.intent", "mycroft.skill.handler.start", # intent code before self.get_response - "enclosure.active_skill", + "speak", # "give me items" # first get_response @@ -786,29 +650,22 @@ def answer_get_response(msg): self.assertEqual(m.context["session"]["session_id"], "default") # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:test_get_response_cascade.intent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:test_get_response_cascade.intent") # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "TestAbortSkill.handle_test_get_response_cascade") - - # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "TestAbortSkill.handle_test_get_response_cascade") # post self.get_response intent code - 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.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) + self.assertEqual(messages[4].msg_type, "speak") + self.assertEqual(messages[4].data["lang"], "en-US") + self.assertFalse(messages[4].data["expect_response"]) + self.assertEqual(messages[4].data["utterance"], "give me items") + self.assertEqual(messages[4].data["meta"]["skill"], self.skill_id) responses = ["A", "B", "C", "cancel"] for response in responses: - i = 6 + responses.index(response) * 11 + i = 4 + responses.index(response) * 11 print(i, response) # enable get_response for this session self.assertEqual(messages[i + 1].msg_type, "skill.converse.get_response.enable") @@ -893,15 +750,13 @@ def abort_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response "ovos.session.update_default", # sync get_response status - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -913,7 +768,7 @@ def abort_response(msg): "skill.converse.get_response.disable", # end of get_response "ovos.session.update_default", # sync get_response status # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -976,15 +831,13 @@ def abort_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -996,7 +849,7 @@ def abort_response(msg): "skill.converse.get_response.disable", # end of get_response # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -1057,15 +910,13 @@ def abort_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -1078,7 +929,7 @@ def abort_response(msg): "skill.converse.get_response.disable", # end of get_response # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -1140,15 +991,13 @@ def abort_response(msg): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # trigger intent to start the test - # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:test_get_response.intent", "mycroft.skill.handler.start", # intent code "skill.converse.get_response.enable", # start of get_response - "enclosure.active_skill", + "speak", # 'mycroft.mic.listen' if no dialog passed to get_response "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", @@ -1161,7 +1010,7 @@ def abort_response(msg): "skill.converse.get_response.disable", # end of get_response # intent code post self.get_response - "enclosure.active_skill", # from speak inside intent + "speak", # speak "ERROR" inside intent "recognizer_loop:audio_output_start", "recognizer_loop:audio_output_end", diff --git a/test/end2end/session/test_ocp.py b/test/end2end/session/test_ocp.py index 5bba3331f1c..978ad2f1569 100644 --- a/test/end2end/session/test_ocp.py +++ b/test/end2end/session/test_ocp.py @@ -20,7 +20,7 @@ def tearDown(self) -> None: self.core.stop() def test_no_match(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -46,7 +46,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -59,10 +59,9 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -79,7 +78,7 @@ def wait_for_n_messages(n): "ovos.common_play.search.end", # no good results "ovos.common_play.reset", - "enclosure.active_skill", + "speak", # error, "ovos.utterance.handled" # handle_utterance returned (intent service) ] @@ -91,7 +90,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_player_info(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -113,8 +112,8 @@ def wait_for_n_messages(n): self.core.bus.on("message", new_msg) sess = Session("test-session", pipeline=["ocp_high"]) - if sess.session_id in self.core.intent_service.ocp.ocp_sessions: - self.core.intent_service.ocp.ocp_sessions.pop(sess.session_id) + if sess.session_id in self.core.intent_service._ocp.ocp_sessions: + self.core.intent_service._ocp.ocp_sessions.pop(sess.session_id) utt = Message("recognizer_loop:utterance", {"utterances": ["play something"]}, @@ -128,10 +127,9 @@ def wait_for_n_messages(n): "ovos.common_play.status", "ovos.common_play.SEI.get", # request player info # no response - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -146,7 +144,7 @@ def wait_for_n_messages(n): "ovos.common_play.skill.search_end", "ovos.common_play.search.end", "ovos.common_play.reset", - "enclosure.active_skill", + "speak", # nothing to play "ovos.utterance.handled" # handle_utterance returned (intent service) ] @@ -157,8 +155,8 @@ def wait_for_n_messages(n): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - self.assertFalse(self.core.intent_service.ocp.ocp_sessions[sess.session_id].ocp_available) - self.assertEqual(self.core.intent_service.ocp.ocp_sessions[sess.session_id].available_extractors, + self.assertFalse(self.core.intent_service._ocp.ocp_sessions[sess.session_id].ocp_available) + self.assertEqual(self.core.intent_service._ocp.ocp_sessions[sess.session_id].available_extractors, available_extractors()) # stream extractors handled in core before returning result # now test with OCP response @@ -170,8 +168,8 @@ def on_get(m): self.core.bus.on("ovos.common_play.SEI.get", on_get) - if sess.session_id in self.core.intent_service.ocp.ocp_sessions: - self.core.intent_service.ocp.ocp_sessions.pop(sess.session_id) + if sess.session_id in self.core.intent_service._ocp.ocp_sessions: + self.core.intent_service._ocp.ocp_sessions.pop(sess.session_id) self.core.bus.emit(utt) @@ -181,10 +179,9 @@ def on_get(m): "ovos.common_play.status", "ovos.common_play.SEI.get", # request player info "ovos.common_play.SEI.get.response", # OCP response - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -199,7 +196,7 @@ def on_get(m): "ovos.common_play.skill.search_end", "ovos.common_play.search.end", "ovos.common_play.reset", - "enclosure.active_skill", + "speak", # nothing to play "ovos.utterance.handled" # handle_utterance returned (intent service) ] @@ -210,12 +207,12 @@ def on_get(m): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - self.assertTrue(self.core.intent_service.ocp.ocp_sessions[sess.session_id].ocp_available) - self.assertEqual(self.core.intent_service.ocp.ocp_sessions[sess.session_id].available_extractors, + self.assertTrue(self.core.intent_service._ocp.ocp_sessions[sess.session_id].ocp_available) + self.assertEqual(self.core.intent_service._ocp.ocp_sessions[sess.session_id].available_extractors, ["test"]) # test OCP player state sync - self.assertEqual(self.core.intent_service.ocp.ocp_sessions[sess.session_id].player_state, + self.assertEqual(self.core.intent_service._ocp.ocp_sessions[sess.session_id].player_state, PlayerState.STOPPED) messages = [] utt = Message("ovos.common_play.status.response", @@ -224,11 +221,11 @@ def on_get(m): }) self.core.bus.emit(utt) - self.assertEqual(self.core.intent_service.ocp.ocp_sessions[sess.session_id].player_state, + self.assertEqual(self.core.intent_service._ocp.ocp_sessions[sess.session_id].player_state, PlayerState.PLAYING) def test_radio_media_match(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -254,7 +251,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -267,10 +264,9 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -303,7 +299,7 @@ def wait_for_n_messages(n): self.assertEqual(play.data["media"]["uri"], "https://fake_4.mp3") def test_unk_media_match(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -329,7 +325,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -342,10 +338,9 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -358,7 +353,7 @@ def wait_for_n_messages(n): "ovos.common_play.search.end", # no good results "ovos.common_play.reset", - "enclosure.active_skill", + "speak", # error "ovos.utterance.handled" # handle_utterance returned (intent service) ] @@ -370,7 +365,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_skill_name_match(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -396,7 +391,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) utt = Message("recognizer_loop:utterance", @@ -409,10 +404,9 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -442,8 +436,8 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_legacy_match(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] @@ -471,7 +465,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) @@ -485,10 +479,9 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:play", - "enclosure.active_skill", + "speak", "ovos.common_play.search.start", "enclosure.mouth.think", @@ -517,13 +510,13 @@ def wait_for_n_messages(n): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - ocp = self.core.intent_service.ocp.ocp_sessions[sess.session_id] + ocp = self.core.intent_service._ocp.ocp_sessions[sess.session_id] self.assertEqual(ocp.player_state, PlayerState.PLAYING) self.assertEqual(ocp.media_state, MediaState.LOADING_MEDIA) def test_legacy_pause(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] def new_msg(msg): @@ -549,7 +542,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) @@ -563,7 +556,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:pause", 'mycroft.audio.service.pause', # LEGACY api @@ -576,12 +568,12 @@ def wait_for_n_messages(n): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - ocp = self.core.intent_service.ocp.ocp_sessions[sess.session_id] + ocp = self.core.intent_service._ocp.ocp_sessions[sess.session_id] self.assertEqual(ocp.player_state, PlayerState.PAUSED) def test_legacy_resume(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] @@ -609,7 +601,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.PAUSED, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -622,7 +614,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:resume", 'mycroft.audio.service.resume', # LEGACY api @@ -635,12 +626,12 @@ def wait_for_n_messages(n): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - ocp = self.core.intent_service.ocp.ocp_sessions[sess.session_id] + ocp = self.core.intent_service._ocp.ocp_sessions[sess.session_id] self.assertEqual(ocp.player_state, PlayerState.PLAYING) def test_legacy_stop(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] def new_msg(msg): @@ -667,7 +658,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) @@ -681,7 +672,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:media_stop", 'mycroft.audio.service.stop', # LEGACY api @@ -694,12 +684,12 @@ def wait_for_n_messages(n): for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) - ocp = self.core.intent_service.ocp.ocp_sessions[sess.session_id] + ocp = self.core.intent_service._ocp.ocp_sessions[sess.session_id] self.assertEqual(ocp.player_state, PlayerState.STOPPED) def test_legacy_next(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] def new_msg(msg): @@ -726,7 +716,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) @@ -740,7 +730,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:next", 'mycroft.audio.service.next', # LEGACY api @@ -754,8 +743,8 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_legacy_prev(self): - self.assertIsNotNone(self.core.intent_service.ocp) - self.core.intent_service.ocp.config = {"legacy": True} + self.assertIsNotNone(self.core.intent_service._ocp) + self.core.intent_service._ocp.config = {"legacy": True} messages = [] def new_msg(msg): @@ -781,7 +770,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=False, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -794,7 +783,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:prev", 'mycroft.audio.service.prev', # LEGACY api @@ -808,7 +796,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_pause(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -834,7 +822,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -847,7 +835,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:pause", 'ovos.common_play.pause', @@ -861,7 +848,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_resume(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -888,7 +875,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.PAUSED, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -901,7 +888,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:resume", 'ovos.common_play.resume', @@ -915,7 +901,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_stop(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -941,7 +927,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -954,7 +940,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:media_stop", 'ovos.common_play.stop', @@ -969,7 +954,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_next(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -995,7 +980,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -1008,7 +993,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:next", 'ovos.common_play.next', @@ -1022,7 +1006,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_prev(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): @@ -1048,7 +1032,7 @@ def wait_for_n_messages(n): "converse", "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.PLAYING, media_state=MediaState.LOADED_MEDIA) utt = Message("recognizer_loop:utterance", @@ -1061,7 +1045,6 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", "ovos.common_play.status", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:prev", 'ovos.common_play.previous', @@ -1075,7 +1058,7 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_status_matches_not_playing(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) def new_msg(msg): nonlocal messages @@ -1101,7 +1084,7 @@ def wait_for_n_messages(n): "ocp_high" ]) - self.core.intent_service.ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( + self.core.intent_service._ocp.ocp_sessions[sess.session_id] = OCPPlayerProxy( session_id=sess.session_id, available_extractors=[], ocp_available=True, player_state=PlayerState.STOPPED, media_state=MediaState.NO_MEDIA) @@ -1131,16 +1114,16 @@ def wait_for_n_messages(n): self.assertEqual(m.msg_type, expected_messages[idx]) def test_legacy_cps(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) - self.core.intent_service.ocp.config = {"legacy_cps": True} + self.core.intent_service._ocp.config = {"legacy_cps": True} messages = [] def new_msg(msg): nonlocal messages m = Message.deserialize(msg) - if m.msg_type in ["ovos.skills.settings_changed", "gui.status.request"]: + if m.msg_type in ["ovos.skills.settings_changed", "gui.status.request", "register_vocab",]: return # skip these, only happen in 1st run messages.append(m) print(len(messages), msg) @@ -1168,7 +1151,6 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:legacy_cps", # legacy cps api @@ -1189,20 +1171,20 @@ class TestLegacyCPSPipeline(TestCase): def setUp(self): self.skill_id = "skill-fake-fm-legacy.openvoiceos" self.core = get_minicroft(self.skill_id) - self.core.intent_service.ocp.config = {"legacy_cps": True} + self.core.intent_service._ocp.config = {"legacy_cps": True} def tearDown(self) -> None: self.core.stop() def test_legacy_cps(self): - self.assertIsNotNone(self.core.intent_service.ocp) + self.assertIsNotNone(self.core.intent_service._ocp) messages = [] def new_msg(msg): nonlocal messages m = Message.deserialize(msg) - if m.msg_type in ["ovos.skills.settings_changed", "gui.status.request"]: + if m.msg_type in ["ovos.skills.settings_changed", "gui.status.request", "register_vocab"]: return # skip these, only happen in 1st run messages.append(m) print(len(messages), msg) @@ -1230,7 +1212,6 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - "intent.service.skills.activated", "ovos.common_play.activate", "ocp:legacy_cps", # legacy cps api @@ -1238,30 +1219,16 @@ def wait_for_n_messages(n): "play:query.response", # searching "play:query.response", # report results "play:start", # skill selected - "mycroft.audio.service.track_info", # check is legacy audio service is playing - # global stop signal - "mycroft.stop", - "common_query.openvoiceos.stop", - "common_query.openvoiceos.stop.response", - "ovos.common_play.stop", - "ovos.common_play.stop.response", - "skill-fake-fm-legacy.openvoiceos.stop", - "skill-fake-fm-legacy.openvoiceos.stop.response", - "mycroft.audio.service.track_info", # check is legacy audio service is playing - # activate skill - "intent.service.skills.activate", - "intent.service.skills.activated", - f"{self.skill_id}.activate", + "mycroft.audio.service.track_info", # check if legacy audio service is playing # skill callback code "mycroft.audio.service.play", "ovos.utterance.handled" # handle_utterance returned (intent service) ] wait_for_n_messages(len(expected_messages)) - #self.assertEqual(len(expected_messages), len(messages)) - for idx, m in enumerate(messages): self.assertEqual(m.msg_type, expected_messages[idx]) + self.assertEqual(m.context["session"]["session_id"], sess.session_id) play = messages[-2] self.assertEqual(play.data["tracks"], ["https://fake.mp3"]) diff --git a/test/end2end/session/test_sched.py b/test/end2end/session/test_sched.py index ef10a7b6640..e95c5e6b7ef 100644 --- a/test/end2end/session/test_sched.py +++ b/test/end2end/session/test_sched.py @@ -48,11 +48,9 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:ScheduleIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.scheduler.schedule_event", "mycroft.skill.handler.complete", @@ -60,7 +58,6 @@ def wait_for_n_messages(n): "ovos.session.update_default", # event triggering after 3 seconds "skill-ovos-schedule.openvoiceos:my_event", - "enclosure.active_skill", "speak" ] wait_for_n_messages(len(expected_messages)) @@ -77,56 +74,52 @@ def wait_for_n_messages(n): 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") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.activate") for m in messages[1:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:ScheduleIntent") - self.assertEqual(messages[3].data["intent_type"], f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[2].data["intent_type"], f"{self.skill_id}:ScheduleIntent") # verify intent execution - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "ScheduleSkill.handle_sched_intent") - - 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.assertFalse(messages[6].data["expect_response"]) - self.assertEqual(messages[6].data["meta"]["dialog"], "done") - self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[7].msg_type, "mycroft.scheduler.schedule_event") - self.assertEqual(messages[8].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[8].data["name"], "ScheduleSkill.handle_sched_intent") - + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "ScheduleSkill.handle_sched_intent") + + self.assertEqual(messages[4].msg_type, "speak") + self.assertEqual(messages[4].data["lang"], "en-US") + self.assertFalse(messages[4].data["expect_response"]) + self.assertEqual(messages[4].data["meta"]["dialog"], "done") + self.assertEqual(messages[4].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[5].msg_type, "mycroft.scheduler.schedule_event") + self.assertEqual(messages[6].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[6].data["name"], "ScheduleSkill.handle_sched_intent") + + self.assertEqual(messages[7].msg_type, "ovos.utterance.handled") # verify default session is now updated - self.assertEqual(messages[10].msg_type, "ovos.session.update_default") - self.assertEqual(messages[10].data["session_data"]["session_id"], "default") + self.assertEqual(messages[8].msg_type, "ovos.session.update_default") + self.assertEqual(messages[8].data["session_data"]["session_id"], "default") # test deserialization of payload - sess = Session.deserialize(messages[10].data["session_data"]) + sess = Session.deserialize(messages[8].data["session_data"]) self.assertEqual(sess.session_id, "default") # test that active skills list has been updated self.assertEqual(sess.active_skills[0][0], self.skill_id) - self.assertEqual(messages[10].data["session_data"]["active_skills"][0][0], self.skill_id) + self.assertEqual(messages[8].data["session_data"]["active_skills"][0][0], self.skill_id) # ensure context in triggered event is the same from message that triggered the intent - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") intent_context = messages[1].context # when skill added to active list (last context change) - self.assertEqual(messages[11].msg_type, "skill-ovos-schedule.openvoiceos:my_event") - self.assertEqual(messages[11].context, intent_context) - 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.assertFalse(messages[13].data["expect_response"]) - self.assertEqual(messages[13].data["meta"]["dialog"], "trigger") - self.assertEqual(messages[13].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[13].context, intent_context) + self.assertEqual(messages[-2].msg_type, "skill-ovos-schedule.openvoiceos:my_event") + self.assertEqual(messages[-2].context, intent_context) + self.assertEqual(messages[-1].msg_type, "speak") + self.assertEqual(messages[-1].data["lang"], "en-US") + self.assertFalse(messages[-1].data["expect_response"]) + self.assertEqual(messages[-1].data["meta"]["dialog"], "trigger") + self.assertEqual(messages[-1].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[-1].context, intent_context) def test_explicit_session(self): SessionManager.sessions = {} @@ -167,18 +160,15 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:ScheduleIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.scheduler.schedule_event", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) # event triggering after 3 seconds "skill-ovos-schedule.openvoiceos:my_event", - "enclosure.active_skill", "speak" ] wait_for_n_messages(len(expected_messages)) @@ -194,46 +184,38 @@ def wait_for_n_messages(n): self.assertEqual(m.context["session"]["session_id"], sess.session_id) # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.activate") # verify skill_id is now present in every message.context for m in messages[1:]: self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:ScheduleIntent") - self.assertEqual(messages[3].data["intent_type"], f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:ScheduleIntent") + self.assertEqual(messages[2].data["intent_type"], f"{self.skill_id}:ScheduleIntent") - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "ScheduleSkill.handle_sched_intent") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "ScheduleSkill.handle_sched_intent") # verify intent execution - 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.assertFalse(messages[6].data["expect_response"]) - self.assertEqual(messages[6].data["meta"]["dialog"], "done") - self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[7].msg_type, "mycroft.scheduler.schedule_event") - self.assertEqual(messages[8].msg_type, "mycroft.skill.handler.complete") - self.assertEqual(messages[8].data["name"], "ScheduleSkill.handle_sched_intent") + self.assertEqual(messages[4].msg_type, "speak") + self.assertEqual(messages[4].data["lang"], "en-US") + self.assertFalse(messages[4].data["expect_response"]) + self.assertEqual(messages[4].data["meta"]["dialog"], "done") + self.assertEqual(messages[4].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[5].msg_type, "mycroft.scheduler.schedule_event") + self.assertEqual(messages[6].msg_type, "mycroft.skill.handler.complete") + self.assertEqual(messages[6].data["name"], "ScheduleSkill.handle_sched_intent") # ensure context in triggered event is the same from message that triggered the intent - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - intent_context = messages[1].context # when skill added to active list (last context change) - - self.assertEqual(messages[10].msg_type, "skill-ovos-schedule.openvoiceos:my_event") - self.assertEqual(messages[10].context, intent_context) - 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.assertFalse(messages[12].data["expect_response"]) - self.assertEqual(messages[12].data["meta"]["dialog"], "trigger") - self.assertEqual(messages[12].data["meta"]["skill"], self.skill_id) - self.assertEqual(messages[12].context, intent_context) + intent_context = messages[2].context + self.assertEqual(messages[-2].msg_type, "skill-ovos-schedule.openvoiceos:my_event") + self.assertEqual(messages[-2].context, intent_context) + self.assertEqual(messages[-1].msg_type, "speak") + self.assertEqual(messages[-1].data["lang"], "en-US") + self.assertFalse(messages[-1].data["expect_response"]) + self.assertEqual(messages[-1].data["meta"]["dialog"], "trigger") + self.assertEqual(messages[-1].data["meta"]["skill"], self.skill_id) + self.assertEqual(messages[-1].context, intent_context) def tearDown(self) -> None: self.core.stop() diff --git a/test/end2end/session/test_session.py b/test/end2end/session/test_session.py index 6fcc200ce4d..d85fc6c4490 100644 --- a/test/end2end/session/test_session.py +++ b/test/end2end/session/test_session.py @@ -52,11 +52,9 @@ def wait_for_n_messages(n): # confirm all expected messages are sent expected_messages = [ "recognizer_loop:utterance", # no session - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -76,17 +74,17 @@ def wait_for_n_messages(n): self.assertEqual(m.context["lang"], "en-US") # verify skill is activated - self.assertEqual(messages[1].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[1].data["skill_id"], self.skill_id) - self.assertEqual(messages[2].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[1].msg_type, f"{self.skill_id}.activate") # verify skill_id is now present in every message.context for m in messages[1:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent triggers - self.assertEqual(messages[3].msg_type, f"{self.skill_id}:HelloWorldIntent") - self.assertEqual(messages[3].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") - self.assertEqual(messages[4].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[4].data["name"], "HelloWorldSkill.handle_hello_world_intent") + self.assertEqual(messages[2].msg_type, f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[2].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[3].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[3].data["name"], "HelloWorldSkill.handle_hello_world_intent") # intent complete self.assertEqual(messages[-3].msg_type, "mycroft.skill.handler.complete") self.assertEqual(messages[-3].data["name"], "HelloWorldSkill.handle_hello_world_intent") @@ -144,11 +142,9 @@ def wait_for_n_messages(n): "recognizer_loop:utterance", f"{self.skill_id}.converse.ping", "skill.converse.pong", - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -174,17 +170,15 @@ def wait_for_n_messages(n): self.assertFalse(messages[2].data["can_handle"]) # verify skill is activated - self.assertEqual(messages[3].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[3].data["skill_id"], self.skill_id) - self.assertEqual(messages[4].msg_type, f"{self.skill_id}.activate") - # verify intent triggers - self.assertEqual(messages[5].msg_type, f"{self.skill_id}:HelloWorldIntent") - self.assertEqual(messages[5].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[4].msg_type, f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[4].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") # verify skill_id is now present in every message.context - for m in messages[3:]: + for m in messages[4:]: + if m.msg_type == "ovos.session.update_default": + continue self.assertEqual(m.context["skill_id"], self.skill_id) - self.assertEqual(messages[6].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[5].msg_type, "mycroft.skill.handler.start") # intent complete self.assertEqual(messages[-3].msg_type, "mycroft.skill.handler.complete") @@ -250,11 +244,9 @@ def wait_for_n_messages(n): "recognizer_loop:utterance", f"{self.skill_id}.converse.ping", "skill.converse.pong", - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:HelloWorldIntent", "mycroft.skill.handler.start", - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled", # handle_utterance returned (intent service) @@ -278,27 +270,23 @@ def wait_for_n_messages(n): self.assertEqual(messages[2].context["skill_id"], self.skill_id) self.assertFalse(messages[2].data["can_handle"]) # verify skill is activated - self.assertEqual(messages[3].msg_type, "intent.service.skills.activated") - self.assertEqual(messages[3].data["skill_id"], self.skill_id) - self.assertEqual(messages[4].msg_type, f"{self.skill_id}.activate") + self.assertEqual(messages[3].msg_type, f"{self.skill_id}.activate") # verify intent triggers - self.assertEqual(messages[5].msg_type, f"{self.skill_id}:HelloWorldIntent") - self.assertEqual(messages[5].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[4].msg_type, f"{self.skill_id}:HelloWorldIntent") + self.assertEqual(messages[4].data["intent_type"], f"{self.skill_id}:HelloWorldIntent") # verify skill_id is now present in every message.context for m in messages[3:]: self.assertEqual(m.context["skill_id"], self.skill_id) # verify intent execution - self.assertEqual(messages[6].msg_type, "mycroft.skill.handler.start") - self.assertEqual(messages[6].data["name"], "HelloWorldSkill.handle_hello_world_intent") - - 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.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) + self.assertEqual(messages[5].msg_type, "mycroft.skill.handler.start") + self.assertEqual(messages[5].data["name"], "HelloWorldSkill.handle_hello_world_intent") + + self.assertEqual(messages[6].msg_type, "speak") + self.assertEqual(messages[6].data["lang"], "en-US") + self.assertFalse(messages[6].data["expect_response"]) + self.assertEqual(messages[6].data["meta"]["dialog"], "hello.world") + self.assertEqual(messages[6].data["meta"]["skill"], self.skill_id) self.assertEqual(messages[-2].msg_type, "mycroft.skill.handler.complete") self.assertEqual(messages[-2].data["name"], "HelloWorldSkill.handle_hello_world_intent") diff --git a/test/end2end/session/test_stop.py b/test/end2end/session/test_stop.py index c7c6c6c153a..6ccde84ea08 100644 --- a/test/end2end/session/test_stop.py +++ b/test/end2end/session/test_stop.py @@ -67,19 +67,24 @@ def wait_for_n_messages(n): "recognizer_loop:utterance", # global stop trigger "mycroft.stop", + # intent pipelines + "common_query.openvoiceos.stop", + "common_query.openvoiceos.stop.response", # reporting nothing to stop + "ovos.common_play.stop", + "ovos.common_play.stop.response", # reporting nothing to stop # skill reporting f"{self.skill_id}.stop", # internal, @killable_events f"{self.skill_id}.stop.response", # skill reporting nothing to stop # sanity check in test skill that method was indeed called - "enclosure.active_skill", "speak", # "utterance":"old stop called" # NOTE: messages below might show up before enclosure.active_skill f"{self.new_skill_id}.stop", # internal, @killable_events f"{self.new_skill_id}.stop.response", # skill reporting nothing to stop + "ovos.utterance.handled" ] wait_for_n_messages(len(expected_messages)) @@ -107,12 +112,10 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", # skill selected - "intent.service.skills.activated", f"{self.skill_id}.activate", f"{self.skill_id}:OldWorldIntent", "mycroft.skill.handler.start", # skill code executing - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled" # handle_utterance returned (intent service) @@ -162,7 +165,6 @@ def wait_for_n_messages(n): f"{self.skill_id}.stop.response", # apparently fails to stop (old style) # test in skill that global stop was called - "enclosure.active_skill", "speak", # "utterance":"stop" # report old-style stop handled event @@ -171,7 +173,7 @@ def wait_for_n_messages(n): # old style unwanted side effects (global stop is global) f"{self.new_skill_id}.stop", f"{self.new_skill_id}.stop.response", - "enclosure.active_skill", # other test skill also speaks + # other test skill also speaks "speak" # "utterance":"old stop called" ] @@ -250,8 +252,9 @@ def wait_for_n_messages(n): f"{self.new_skill_id}.stop.response", # skill reporting nothing to stop # sanity check in test skill that method was indeed called - "enclosure.active_skill", - "speak" # "utterance":"old stop called" + "speak", # "utterance":"old stop called" + + "ovos.utterance.handled", ] @@ -280,12 +283,10 @@ def wait_for_n_messages(n): expected_messages = [ "recognizer_loop:utterance", # skill selected - "intent.service.skills.activated", f"{self.new_skill_id}.activate", f"{self.new_skill_id}:NewWorldIntent", "mycroft.skill.handler.start", # skill code executing - "enclosure.active_skill", "speak", "mycroft.skill.handler.complete", "ovos.utterance.handled" # handle_utterance returned (intent service) @@ -329,10 +330,10 @@ def wait_for_n_messages(n): f"{self.new_skill_id}.stop", # skill specific stop trigger # test session specific stop was called - "enclosure.active_skill", "speak", # "utterance":"stop 123" f"{self.new_skill_id}.stop.response", # skill reports it stopped (new style), + f"{self.new_skill_id}.activate", # update timestamp of last interaction with skill "ovos.utterance.handled" # handle_utterance returned (intent service) ] @@ -349,7 +350,7 @@ def wait_for_n_messages(n): self.assertEqual(m.data["utterance"], "stop 123") # confirm "skill-new-stop" was the one that reported success - handler = messages[-2] + handler = messages[-3] self.assertEqual(handler.msg_type, f"{self.new_skill_id}.stop.response") self.assertEqual(handler.data["result"], True) @@ -389,7 +390,6 @@ def wait_for_n_messages(n): f"{self.skill_id}.stop.response", # dont want to stop (new style) # check the global stop handlers are called - "enclosure.active_skill", "speak", # "utterance":"old stop called" ] diff --git a/test/unittests/test_intent_service.py b/test/unittests/test_intent_service.py index bef2a35143c..6d4d062112a 100644 --- a/test/unittests/test_intent_service.py +++ b/test/unittests/test_intent_service.py @@ -12,56 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from copy import deepcopy from unittest import TestCase, mock from ovos_bus_client.message import Message +from ovos_bus_client.session import IntentContextManager as ContextManager from ovos_bus_client.util import get_message_lang from ovos_config import Configuration +from ovos_config import LocalConf, DEFAULT_CONFIG from ovos_config.locale import setup_locale from ovos_core.intent_services import IntentService -from ovos_adapt.opm import ContextManager -from ovos_workshop.intents import IntentBuilder, Intent as AdaptIntent -from copy import deepcopy -from ovos_config import LocalConf, DEFAULT_CONFIG +from ovos_utils.fakebus import FakeBus +from ovos_workshop.intents import IntentBuilder # Setup configurations to use with default language tests BASE_CONF = deepcopy(LocalConf(DEFAULT_CONFIG)) BASE_CONF['lang'] = 'it-it' -NO_LANG_CONF = deepcopy(LocalConf(DEFAULT_CONFIG)) -NO_LANG_CONF.pop('lang') - -setup_locale("en-US") - - -class MockEmitter(object): - def __init__(self): - self.reset() - - def emit(self, message): - self.types.append(message.msg_type) - self.results.append(message.data) - - def get_types(self): - return self.types - - def get_results(self): - return self.results - - def remove(self, msg_type, handler): - self.removed.append(msg_type) - - def on(self, msg_type, handler): - pass - - def reset(self): - self.removed = [] - self.types = [] - self.results = [] - class ContextManagerTest(TestCase): - emitter = MockEmitter() def setUp(self): self.context_manager = ContextManager(3) @@ -92,11 +61,6 @@ def test_remove_context(self): self.assertEqual(len(self.context_manager.frame_stack), 0) -def check_converse_request(message, skill_id): - return (message.msg_type == 'skill.converse.request' and - message.data['skill_id'] == skill_id) - - class TestLanguageExtraction(TestCase): @mock.patch.dict(Configuration._Configuration__patch, BASE_CONF) def test_no_lang_in_message(self): @@ -116,225 +80,39 @@ def test_lang_exists(self): self.assertEqual(get_message_lang(msg), 'sv-SE') -def create_old_style_vocab_msg(keyword, value): - """Create a message for registering an adapt keyword.""" - return Message('register_vocab', - {'start': value, 'end': keyword}) - - -def create_vocab_msg(keyword, value): - """Create a message for registering an adapt keyword.""" - return Message('register_vocab', - {'entity_value': value, 'entity_type': keyword}) - - -def get_last_message(bus): - """Get last sent message on mock bus.""" - last = bus.emit.call_args - return last[0][0] - - class TestIntentServiceApi(TestCase): def setUp(self): - self.intent_service = IntentService(mock.Mock()) + self.bus = FakeBus() + self.emitted = [] - def setup_simple_adapt_intent(self, - msg=create_vocab_msg('testKeyword', 'test')): - self.intent_service.handle_register_vocab(msg) + def on_msg(m): + self.emitted.append(Message.deserialize(m)) - intent = IntentBuilder('skill:testIntent').require('testKeyword') - msg = Message('register_intent', intent.__dict__) - self.intent_service.handle_register_intent(msg) + self.bus.on("message", on_msg) - def test_get_adapt_intent(self): - self.setup_simple_adapt_intent() - # Check that the intent is returned - msg = Message('intent.service.adapt.get', - data={'utterance': 'test'}) - self.intent_service.handle_get_adapt(msg) + self.intent_service = IntentService(self.bus) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent']['intent_type'], - 'skill:testIntent') + msg = Message('register_vocab', + {'entity_value': 'test', 'entity_type': 'testKeyword'}) + self.intent_service._adapt_service.handle_register_vocab(msg) - def test_get_adapt_intent_no_match(self): - """Check that if the intent doesn't match at all None is returned.""" - self.setup_simple_adapt_intent() - # Check that no intent is matched - msg = Message('intent.service.adapt.get', - data={'utterance': 'five'}) - self.intent_service.handle_get_adapt(msg) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent'], None) - - def test_get_intent(self): - """Check that the registered adapt intent is triggered.""" - self.setup_simple_adapt_intent() - # Check that the intent is returned - msg = Message('intent.service.adapt.get', - data={'utterance': 'test'}) - self.intent_service.handle_get_intent(msg) - - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent']['intent_type'], - 'skill:testIntent') + intent = IntentBuilder('skill:testIntent').require('testKeyword') + msg = Message('register_intent', intent.__dict__) + self.intent_service._adapt_service.handle_register_intent(msg) def test_get_intent_no_match(self): """Check that if the intent doesn't match at all None is returned.""" - self.setup_simple_adapt_intent() # Check that no intent is matched msg = Message('intent.service.intent.get', data={'utterance': 'five'}) self.intent_service.handle_get_intent(msg) - reply = get_last_message(self.intent_service.bus) + reply = self.emitted[-1] self.assertEqual(reply.data['intent'], None) - def test_get_intent_manifest(self): - """Check that if the intent doesn't match at all None is returned.""" - self.setup_simple_adapt_intent() - # Check that no intent is matched + def test_get_intent_match(self): + # Check that intent is matched msg = Message('intent.service.intent.get', - data={'utterance': 'five'}) + data={'utterance': 'test'}) self.intent_service.handle_get_intent(msg) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent'], None) - - def test_get_adapt_intent_manifest(self): - """Make sure the manifest returns a list of Intent Parser objects.""" - self.setup_simple_adapt_intent() - msg = Message('intent.service.adapt.manifest.get') - self.intent_service.handle_adapt_manifest(msg) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intents'][0]['name'], - 'skill:testIntent') - - def test_get_adapt_vocab_manifest(self): - self.setup_simple_adapt_intent() - msg = Message('intent.service.adapt.vocab.manifest.get') - self.intent_service.handle_vocab_manifest(msg) - reply = get_last_message(self.intent_service.bus) - value = reply.data['vocab'][0]['entity_value'] - keyword = reply.data['vocab'][0]['entity_type'] - self.assertEqual(keyword, 'testKeyword') - self.assertEqual(value, 'test') - - def test_get_no_match_after_detach(self): - """Check that a removed intent doesn't match.""" - self.setup_simple_adapt_intent() - # Check that no intent is matched - msg = Message('detach_intent', - data={'intent_name': 'skill:testIntent'}) - self.intent_service.handle_detach_intent(msg) - msg = Message('intent.service.adapt.get', data={'utterance': 'test'}) - self.intent_service.handle_get_adapt(msg) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent'], None) - - def test_get_no_match_after_detach_skill(self): - """Check that a removed skill's intent doesn't match.""" - self.setup_simple_adapt_intent() - # Check that no intent is matched - msg = Message('detach_intent', - data={'skill_id': 'skill'}) - self.intent_service.handle_detach_skill(msg) - msg = Message('intent.service.adapt.get', data={'utterance': 'test'}) - self.intent_service.handle_get_adapt(msg) - reply = get_last_message(self.intent_service.bus) - self.assertEqual(reply.data['intent'], None) - - def test_shutdown(self): - intent_service = IntentService(MockEmitter(), config={"padatious": {"disabled": True}}) - intent_service.shutdown() - self.assertEqual(set(intent_service.bus.removed), - {'active_skill_request', - 'add_context', - 'clear_context', - 'common_query.openvoiceos.activate', - 'common_query.openvoiceos.converse.get_response', - 'common_query.openvoiceos.converse.ping', - 'common_query.openvoiceos.converse.request', - 'common_query.openvoiceos.deactivate', - 'common_query.openvoiceos.set', - 'common_query.openvoiceos.stop', - 'common_query.openvoiceos.stop.ping', - 'common_query.question', - 'detach_intent', - 'detach_skill', - 'intent.service.active_skills.get', - 'intent.service.adapt.get', - 'intent.service.adapt.manifest.get', - 'intent.service.adapt.vocab.manifest.get', - 'intent.service.intent.get', - 'intent.service.padatious.entities.manifest.get', - 'intent.service.padatious.get', - 'intent.service.padatious.manifest.get', - 'intent.service.skills.activate', - 'intent.service.skills.activated', - 'intent.service.skills.deactivate', - 'intent.service.skills.deactivated', - 'intent.service.skills.get', - 'mycroft.audio.playing_track', - 'mycroft.audio.queue_end', - 'mycroft.audio.service.pause', - 'mycroft.audio.service.resume', - 'mycroft.audio.service.stop', - 'mycroft.skill.disable_intent', - 'mycroft.skill.enable_intent', - 'mycroft.skill.remove_cross_context', - 'mycroft.skill.set_cross_context', - 'mycroft.skills.loaded', - 'mycroft.skills.settings.changed', - 'mycroft.speech.recognition.unknown', - 'mycroft.stop', - 'ocp:legacy_cps', - 'ocp:like_song', - 'ocp:media_stop', - 'ocp:next', - 'ocp:open', - 'ocp:pause', - 'ocp:play', - 'ocp:play_favorites', - 'ocp:prev', - 'ocp:resume', - 'ocp:search_error', - 'ovos.common_play.activate', - 'ovos.common_play.announce', - 'ovos.common_play.converse.get_response', - 'ovos.common_play.converse.ping', - 'ovos.common_play.converse.request', - 'ovos.common_play.deactivate', - 'ovos.common_play.deregister_keyword', - 'ovos.common_play.play_search', - 'ovos.common_play.register_keyword', - 'ovos.common_play.search', - 'ovos.common_play.set', - 'ovos.common_play.status.response', - 'ovos.common_play.stop', - 'ovos.common_play.stop.ping', - 'ovos.common_play.track.state', - 'ovos.common_query.pong', - 'ovos.skills.fallback.deregister', - 'ovos.skills.fallback.register', - 'ovos.skills.settings_changed', - 'padatious:register_entity', - 'padatious:register_intent', - 'play:query.response', - 'question:query.response', - 'recognizer_loop:utterance', - 'register_intent', - 'register_vocab', - 'remove_context', - 'skill.converse.get_response.disable', - 'skill.converse.get_response.enable'}) - - -class TestAdaptIntent(TestCase): - """Test the AdaptIntent wrapper.""" - - def test_named_intent(self): - intent = AdaptIntent("CallEaglesIntent") - self.assertEqual(intent.name, "CallEaglesIntent") - - def test_unnamed_intent(self): - intent = AdaptIntent() - self.assertEqual(intent.name, "") + reply = self.emitted[-1] + self.assertEqual(reply.data['intent']['intent_name'], 'skill:testIntent')