From cdf44c9d722768425c17aec0a7653266f07e981c Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Tue, 10 Oct 2023 18:01:06 +0100 Subject: [PATCH] feat/extend_ovosskill extend skill class to include support for language plugins: - makes it easier to share the underlying object with the solver plugins - TODO - companion PR in OPM - api compat with NeonSkill class to reduce divergence - lazy init on first usage, no extra resource usage in existing skills extend self.activate: - allow skills to specify how long they want to remain active - api compat with NeonSkill class to reduce divergence - TODO - companion PR in core --- ovos_workshop/skills/ovos.py | 42 ++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/ovos_workshop/skills/ovos.py b/ovos_workshop/skills/ovos.py index c75253f3..c6d403bf 100644 --- a/ovos_workshop/skills/ovos.py +++ b/ovos_workshop/skills/ovos.py @@ -15,13 +15,13 @@ from json_database import JsonStorage from lingua_franca.format import pronounce_number, join_list from lingua_franca.parse import yes_or_no, extract_number -from ovos_config.config import Configuration -from ovos_config.locations import get_xdg_config_save_path - from ovos_backend_client.api import EmailApi, MetricsApi from ovos_bus_client import MessageBusClient from ovos_bus_client.message import Message, dig_for_message from ovos_bus_client.session import SessionManager, Session +from ovos_config.config import Configuration +from ovos_config.locations import get_xdg_config_save_path +from ovos_plugin_manager.language import OVOSLangTranslationFactory, OVOSLangDetectionFactory from ovos_utils import camel_case_split, classproperty from ovos_utils.dialog import get_dialog, MustacheDialogRenderer from ovos_utils.enclosure.api import EnclosureAPI @@ -149,6 +149,10 @@ def __init__(self, name: Optional[str] = None, self._bus = bus self._enclosure = EnclosureAPI() + # optional lang translation, lazy inited on first access + self._lang_detector = None + self._translator = None # can be passed to solvers plugins + # Core configuration self.config_core: Configuration = Configuration() @@ -328,6 +332,22 @@ def alphanumeric_skill_id(self) -> str: return ''.join(c if c.isalnum() else '_' for c in str(self.skill_id)) + @property + def lang_detector(self): + """ language detector, lazy init on first access""" + if not self._lang_detector: + # if it's being used, there is no recovery, do not try: except: + self._lang_detector = OVOSLangDetectionFactory.create() + return self._lang_detector + + @property + def translator(self): + """ language translator, lazy init on first access""" + if not self._translator: + # if it's being used, there is no recovery, do not try: except: + self._translator = OVOSLangTranslationFactory.create() + return self._translator + @property def settings_path(self) -> str: """ @@ -1771,7 +1791,7 @@ def _real_wait_response(self, is_cancel, validator, on_fail, num_retries, break # killed externally elif response: reprompt = self._validate_response(response, sess, - is_cancel, validator, on_fail) + is_cancel, validator, on_fail) if reprompt: # reset counter, user said something and we reformulated the question num_fails = 0 @@ -2121,24 +2141,32 @@ def cancel_all_repeating_events(self): self.event_scheduler.cancel_all_repeating_events() # intent/context skill dev facing utils - def activate(self): + def activate(self, duration_minutes=None): """ Mark this skill as active and push to the top of the active skills list. This enables converse method to be called even without skill being used in last 5 minutes. + + :param duration_minutes: duration in minutes for skill to remain active + (-1 for infinite) """ + if duration_minutes is None: + duration_minutes = Configuration().get("converse", {}).get("timeout", 300) / 60 # convert to minutes + msg = dig_for_message() or Message("") if "skill_id" not in msg.context: msg.context["skill_id"] = self.skill_id m1 = msg.forward("intent.service.skills.activate", - data={"skill_id": self.skill_id}) + data={"skill_id": self.skill_id, + "timeout": duration_minutes}) self.bus.emit(m1) # backwards compat with mycroft-core # TODO - remove soon m2 = msg.forward("active_skill_request", - data={"skill_id": self.skill_id}) + data={"skill_id": self.skill_id, + "timeout": duration_minutes}) self.bus.emit(m2) def deactivate(self):