From 01f73b6b01caceabc450875b6f0f27ab6c2e3aac Mon Sep 17 00:00:00 2001 From: Kris Gesling Date: Thu, 27 May 2021 15:36:29 +0930 Subject: [PATCH 1/2] Update Adapt parser to v0.4.1 --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c9ccedaf313b..5b024132fb72 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -19,7 +19,7 @@ lingua-franca==0.4.1 msm==0.8.9 msk==0.3.16 mycroft-messagebus-client==0.9.1 -adapt-parser==0.3.7 +adapt-parser==0.4.1 padatious==0.4.8 fann2==1.0.7 padaos==0.1.9 From ad410d4bfc83b9ea3d100726b1e9fb27f1852f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85ke=20Forslund?= Date: Thu, 1 Apr 2021 12:03:06 +0200 Subject: [PATCH 2/2] Remove registered keywords on skill shutdown Uses new drop_*() methods from adapt-parser 0.4.0 --- .../skills/intent_services/adapt_service.py | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/mycroft/skills/intent_services/adapt_service.py b/mycroft/skills/intent_services/adapt_service.py index be69bd9a087a..54fe565e02f3 100644 --- a/mycroft/skills/intent_services/adapt_service.py +++ b/mycroft/skills/intent_services/adapt_service.py @@ -13,6 +13,7 @@ # limitations under the License. # """An intent parsing service using the Adapt parser.""" +from threading import Lock import time from adapt.context import ContextManagerFrame @@ -23,6 +24,21 @@ from .base import IntentMatch +def _entity_skill_id(skill_id): + """Helper converting a skill id to the format used in entities. + + Arguments: + skill_id (str): skill identifier + + Returns: + (str) skill id on the format used by skill entities + """ + skill_id = skill_id[:-1] + skill_id = skill_id.replace('.', '_') + skill_id = skill_id.replace('-', '_') + return skill_id + + class AdaptIntent(IntentBuilder): """Wrapper for IntentBuilder setting a blank name. @@ -161,6 +177,7 @@ def __init__(self, config): self.context_timeout = self.config.get('timeout', 2) self.context_greedy = self.config.get('greedy', False) self.context_manager = ContextManager(self.context_timeout) + self.lock = Lock() def update_context(self, intent): """Updates context with keyword from the intent. @@ -227,11 +244,12 @@ def take_best(intent, utt): def register_vocab(self, start_concept, end_concept, alias_of, regex_str): """Register vocabulary.""" - if regex_str: - self.engine.register_regex_entity(regex_str) - else: - self.engine.register_entity( - start_concept, end_concept, alias_of=alias_of) + with self.lock: + if regex_str: + self.engine.register_regex_entity(regex_str) + else: + self.engine.register_entity( + start_concept, end_concept, alias_of=alias_of) def register_intent(self, intent): """Register new intent with adapt engine. @@ -239,7 +257,8 @@ def register_intent(self, intent): Arguments: intent (IntentParser): IntentParser to register """ - self.engine.register_intent_parser(intent) + with self.lock: + self.engine.register_intent_parser(intent) def detach_skill(self, skill_id): """Remove all intents for skill. @@ -247,11 +266,41 @@ def detach_skill(self, skill_id): Arguments: skill_id (str): skill to process """ - new_parsers = [ - p for p in self.engine.intent_parsers if - not p.name.startswith(skill_id) - ] - self.engine.intent_parsers = new_parsers + with self.lock: + skill_parsers = [ + p.name for p in self.engine.intent_parsers if + p.name.startswith(skill_id) + ] + self.engine.drop_intent_parser(skill_parsers) + self._detach_skill_keywords(skill_id) + self._detach_skill_regexes(skill_id) + + def _detach_skill_keywords(self, skill_id): + """Detach all keywords registered with a particular skill. + + Arguments: + skill_id (str): skill identifier + """ + skill_id = _entity_skill_id(skill_id) + + def match_skill_entities(data): + return data and data[1].startswith(skill_id) + + self.engine.drop_entity(match_func=match_skill_entities) + + def _detach_skill_regexes(self, skill_id): + """Detach all regexes registered with a particular skill. + + Arguments: + skill_id (str): skill identifier + """ + skill_id = _entity_skill_id(skill_id) + + def match_skill_regexes(regexp): + return any([r.startswith(skill_id) + for r in regexp.groupindex.keys()]) + + self.engine.drop_regex_entity(match_func=match_skill_regexes) def detach_intent(self, intent_name): """Detatch a single intent