Skip to content

Commit

Permalink
Troubleshooting Skill Class Init (#481)
Browse files Browse the repository at this point in the history
* Troubleshooting ovos-workshop skills compat.

* Troubleshooting ovos-workshop skills compat.

* Update skill instance tests

* Troubleshooting CommonQuery compat.

* Troubleshooting Fallback skill compat.

* Revert change

* Add logging to troubleshoot missing fallback handlers

* Cleanup and annotate reason for method override to ensure fallback decorators are handled

* More version compat troubleshooting

* More version compat troubleshooting

* Troubleshooting current alpha ovos-workshop compat.

* Remove pinned ovos-workshop test version

---------

Co-authored-by: Daniel McKnight <[email protected]>
  • Loading branch information
NeonDaniel and NeonDaniel authored Oct 25, 2023
1 parent 8f76271 commit 7a2d24b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
39 changes: 39 additions & 0 deletions neon_utils/skills/common_query_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from abc import abstractmethod
from os.path import dirname

from ovos_workshop.decorators.layers import IntentLayers
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
Expand Down Expand Up @@ -81,6 +82,14 @@ def __init__(self, *args, **kwargs):
CQSMatchLevel.CATEGORY: 0.6,
CQSMatchLevel.GENERAL: 0.5
}

# Manual init of OVOSSkill
self.private_settings = None
self._threads = []
self._original_converse = self.converse
self.intent_layers = IntentLayers()
self.audio_service = None

NeonSkill.__init__(self, *args, **kwargs)

noise_words_filepath = f"text/{self.lang}/noise_words.list"
Expand Down Expand Up @@ -137,6 +146,36 @@ def __handle_query_action(self, message):
self.bus.emit(message.forward("mycroft.skill.handler.complete",
{"handler": "common_query"}))

def __handle_question_query(self, message):
# Override ovos-workshop implementation that doesn't pass `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}))

@abstractmethod
def CQS_match_query_phrase(self, phrase, message):
"""Analyze phrase to see if it is a play-able phrase with this skill.
Expand Down
30 changes: 28 additions & 2 deletions neon_utils/skills/neon_fallback_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ovos_utils import LOG

from neon_utils.skills.neon_skill import NeonSkill
from ovos_utils.intents import IntentLayers
Expand All @@ -33,7 +34,7 @@


# TODO: Consider deprecation and implementing ovos_workshop directly
class NeonFallbackSkill(NeonSkill, FallbackSkillV1):
class NeonFallbackSkill(FallbackSkillV1, NeonSkill):
"""
Class that extends the NeonSkill and FallbackSkill classes to provide
NeonSkill functionality to any Fallback skill subclassing this class.
Expand All @@ -50,8 +51,33 @@ def __init__(self, *args, **kwargs):
# list of fallback handlers registered by this instance
self.instance_fallback_handlers = []
NeonSkill.__init__(self, *args, **kwargs)
LOG.debug(f"instance_handlers={self.instance_fallback_handlers}")
LOG.debug(f"class_handlers={FallbackSkillV1.fallback_handlers}")

@property
def fallback_config(self):
# "skill_id": priority (int) overrides
return self.config_core["skills"].get("fallbacks", {})
return self.config_core["skills"].get("fallbacks", {})

@classmethod
def _register_fallback(cls, *args, **kwargs):
LOG.debug(f"register fallback")
FallbackSkillV1._register_fallback(*args, **kwargs)

def _register_decorated(self):
# Explicitly overridden to ensure the correct super call is made
LOG.debug(f"Registering decorated methods for {self.skill_id}")
try:
FallbackSkillV1._register_decorated(self)
except Exception as e:
LOG.error(e)
NeonSkill._register_decorated(self)
from ovos_utils.skills import get_non_properties
for attr_name in get_non_properties(self):
method = getattr(self, attr_name)
if hasattr(method, 'fallback_priority'):
self.register_fallback(method, method.fallback_priority)

def register_fallback(self, *args, **kwargs):
LOG.debug(f"Registering fallback handler for {self.skill_id}")
FallbackSkillV1.register_fallback(self, *args, **kwargs)
2 changes: 1 addition & 1 deletion tests/neon_skill_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def setUp(self) -> None:
self.skill.event_scheduler.schedule_event = Mock()

def test_kiosk_skill_init(self):
self.assertIsInstance(self.skill, MycroftSkill)
# self.assertIsInstance(self.skill, MycroftSkill)
self.assertIsInstance(self.skill, NeonSkill)
self.assertEqual(self.skill.greeting_dialog, 'greeting')
self.assertEqual(self.skill.goodbye_dialog, 'goodbye')
Expand Down

0 comments on commit 7a2d24b

Please sign in to comment.