From 737780556e5c1039a7ef68f0550c111f46c31d6c Mon Sep 17 00:00:00 2001 From: Daniel McKnight Date: Tue, 24 Oct 2023 15:12:37 -0700 Subject: [PATCH] Troubleshoot FallbackSkill inheritance Update CommonQuerySkill to extend ovos_workshop implementation Mark CommonPlaySkill as deprecated --- neon_utils/skills/common_play_skill.py | 5 ++ neon_utils/skills/common_query_skill.py | 84 +++++++++--------------- neon_utils/skills/neon_fallback_skill.py | 4 +- 3 files changed, 38 insertions(+), 55 deletions(-) diff --git a/neon_utils/skills/common_play_skill.py b/neon_utils/skills/common_play_skill.py index 2b1c8f39..495af6c6 100644 --- a/neon_utils/skills/common_play_skill.py +++ b/neon_utils/skills/common_play_skill.py @@ -44,6 +44,8 @@ from enum import Enum, IntEnum from abc import ABC, abstractmethod from ovos_bus_client import Message +from ovos_utils.log import log_deprecation + from neon_utils.skills.neon_skill import NeonSkill from ovos_utils.skills.audioservice import AudioServiceInterface as AudioService @@ -85,6 +87,9 @@ class CommonPlaySkill(NeonSkill, ABC): is needed. """ def __init__(self, *args, **kwargs): + log_deprecation("This base class is deprecated. Implement " + "`ovos_workshop.skills.common_play." + "OVOSCommonPlaybackSkill`", "2.0.0") NeonSkill.__init__(self, *args, **kwargs) self.audioservice = None self.play_service_string = None diff --git a/neon_utils/skills/common_query_skill.py b/neon_utils/skills/common_query_skill.py index b58af22c..9dfbf641 100644 --- a/neon_utils/skills/common_query_skill.py +++ b/neon_utils/skills/common_query_skill.py @@ -40,23 +40,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -from enum import IntEnum -from abc import ABC, abstractmethod -from neon_utils.skills.neon_skill import NeonSkill - - -class CQSMatchLevel(IntEnum): - EXACT = 1 # Skill could find a specific answer for the question - CATEGORY = 2 # Skill could find an answer from a category in the query - GENERAL = 3 # The query could be processed as a general query - +from abc import abstractmethod +from os.path import dirname -# Copy of CQSMatchLevel to use if the skill returns visual media -CQSVisualMatchLevel = IntEnum('CQSVisualMatchLevel', - [e.name for e in CQSMatchLevel]) +from ovos_workshop.skills.common_query_skill import CQSMatchLevel, CQSVisualMatchLevel +from ovos_workshop.skills.common_query_skill import CommonQuerySkill as _CQS +from ovos_utils.file_utils import resolve_resource_file +from ovos_utils.log import log_deprecation +from neon_utils.skills.neon_skill import NeonSkill def is_CQSVisualMatchLevel(match_level): + log_deprecation("This method is deprecated", "2.0.0") return isinstance(match_level, type(CQSVisualMatchLevel.EXACT)) @@ -64,10 +59,12 @@ def is_CQSVisualMatchLevel(match_level): def handles_visuals(platform): + log_deprecation("This method is deprecated", "2.0.0") return platform in VISUAL_DEVICES -class CommonQuerySkill(NeonSkill, ABC): +# TODO: Consider deprecation and implementing ovos_workshop directly +class CommonQuerySkill(NeonSkill, _CQS): """Question answering skills should be based on this class. The skill author needs to implement `CQS_match_query_phrase` returning an @@ -78,47 +75,28 @@ class CommonQuerySkill(NeonSkill, ABC): answers from several skills presenting the best one available. """ def __init__(self, *args, **kwargs): + # these should probably be configurable + self.level_confidence = { + CQSMatchLevel.EXACT: 0.9, + CQSMatchLevel.CATEGORY: 0.6, + CQSMatchLevel.GENERAL: 0.5 + } NeonSkill.__init__(self, *args, **kwargs) - def bind(self, bus): - """Overrides the default bind method of MycroftSkill. - - This registers messagebus handlers for the skill during startup - but is nothing the skill author needs to consider. - """ - if bus: - super().bind(bus) - self.add_event('question:query', self.__handle_question_query) - self.add_event('question:action', self.__handle_query_action) - - def __handle_question_query(self, message): - search_phrase = message.data["phrase"] - - # First, notify the requestor that we are attempting to handle - # (this extends a timeout while this skill looks for a match) - self.bus.emit(message.response({"phrase": search_phrase, - "skill_id": self.skill_id, - "searching": True})) - - # Now invoke the CQS handler to let the skill perform its search - result = self.CQS_match_query_phrase(search_phrase, message) - - if result: - match = result[0] - level = result[1] - answer = result[2] - callback = result[3] if len(result) > 3 else None - confidence = self.__calc_confidence(match, search_phrase, level) - self.bus.emit(message.response({"phrase": search_phrase, - "skill_id": self.skill_id, - "answer": answer, - "callback_data": callback, - "conf": confidence})) - else: - # Signal we are done (can't handle it) - self.bus.emit(message.response({"phrase": search_phrase, - "skill_id": self.skill_id, - "searching": False})) + noise_words_filepath = f"text/{self.lang}/noise_words.list" + default_res = f"{dirname(dirname(__file__))}/res/text/{self.lang}" \ + f"/noise_words.list" + noise_words_filename = \ + resolve_resource_file(noise_words_filepath, + config=self.config_core) or \ + resolve_resource_file(default_res, config=self.config_core) + + self._translated_noise_words = {} + if noise_words_filename: + with open(noise_words_filename) as f: + translated_noise_words = f.read().strip() + self._translated_noise_words[self.lang] = \ + translated_noise_words.split() def __calc_confidence(self, match, phrase, level): # Assume the more of the words that get consumed, the better the match diff --git a/neon_utils/skills/neon_fallback_skill.py b/neon_utils/skills/neon_fallback_skill.py index 5c16f3cf..d11e85d6 100644 --- a/neon_utils/skills/neon_fallback_skill.py +++ b/neon_utils/skills/neon_fallback_skill.py @@ -27,13 +27,13 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from neon_utils.skills.neon_skill import NeonSkill -from ovos_workshop.skills.ovos import OVOSSkill from ovos_utils.intents import IntentLayers from ovos_workshop.decorators.layers import IntentLayers from ovos_workshop.skills.fallback import FallbackSkillV1 as FallbackSkill -class NeonFallbackSkill(FallbackSkill, NeonSkill, OVOSSkill): +# TODO: Consider deprecation and implementing ovos_workshop directly +class NeonFallbackSkill(FallbackSkill, NeonSkill): """ Class that extends the NeonSkill and FallbackSkill classes to provide NeonSkill functionality to any Fallback skill subclassing this class.