From d7163ac7defc4b6da6c42dd1c858a1d5a2339ca0 Mon Sep 17 00:00:00 2001 From: Mathieu B Date: Thu, 29 Jul 2021 20:16:22 +0200 Subject: [PATCH] Complete padatious support for skills and clearer separation between adapt and padatious in various class like intent_manager.py or Skill.class --- jarvis/main.py | 1 - jarvis/skills/__init__.py | 35 ++++++++-- .../skills/entertainement/spotify/__init__.py | 2 +- jarvis/skills/intent_manager.py | 67 ++++++++++++++----- jarvis/utils/test.py | 57 ---------------- 5 files changed, 79 insertions(+), 83 deletions(-) delete mode 100644 jarvis/utils/test.py diff --git a/jarvis/main.py b/jarvis/main.py index 1af6b91..c5fab4e 100644 --- a/jarvis/main.py +++ b/jarvis/main.py @@ -44,7 +44,6 @@ if __name__ == '__main__': # intent_manager.recognise("cherche sur wikipedia Elon Musk") # intent_manager.recognise("raconte moi une blague") intent_manager.recognise("joue le morceau crazy crazy nights de KISS sur spotify") - intent_manager.recognise("joue crazy crazy nights") # start the flask server app.config['JSON_AS_ASCII'] = False diff --git a/jarvis/skills/__init__.py b/jarvis/skills/__init__.py index a25ed72..b8f238f 100644 --- a/jarvis/skills/__init__.py +++ b/jarvis/skills/__init__.py @@ -30,7 +30,7 @@ class Skill: for line in infile.readlines(): filename = file.split("/")[-1].split(".voc")[0] - intent_manager.register_entity(line.replace('\n', ''), filename, self.name) + intent_manager.register_entity_adapt(line.replace('\n', ''), filename, self.name) def register_regex(self): path = os.path.dirname(get_path_file.__file__) + "/skills/" + self.category + "/" + self.skill_folder @@ -40,22 +40,45 @@ class Skill: for file in files: with open(file, "r") as infile: for line in infile.readlines(): - intent_manager.register_regex(line.replace('\n', ''), self.name) + intent_manager.register_regex_adapt(line.replace('\n', ''), self.name) + + +def get_array_for_intent_file(filename, category, skill_folder): + path = os.path.dirname(get_path_file.__file__) + "/skills/" + category + "/" + skill_folder + path = path + "/vocab/" + languages_utils.get_language() + "/" + filename + + with open(file=path, mode="r") as infile: + lines = [] + + for line in infile.readlines(): + lines.append(line.replace('\n', '')) + + return lines class SkillRegistering(type): def __init__(cls, name, bases, attrs): for key, val in attrs.items(): if type(val) is types.FunctionType and not str(val).__contains__("__"): - type = getattr(val, "_type", None) + intent_type = getattr(val, "_type", None) - if type is not None: + if intent_type is not None: properties = getattr(val, "_data", None) if properties is not None: - if type is 'adapt': + if intent_type == 'adapt': intent = properties[0] intent_name = intent.name intent_manager.intents_handlers_adapt[f"{intent_name}"] = [getattr(cls, key), name] - elif type is 'padatious': + elif intent_type == 'padatious': intent_file = properties[0] + intent_name = properties[1] + + intent_category = str(attrs['__module__']).split('.')[2] + skill_folder = str(attrs['__module__']).split('.')[3] + + intent_manager.intents_handlers_padatious[f"{intent_name}"] = [getattr(cls, key), + get_array_for_intent_file( + intent_file, + intent_category, + skill_folder)] diff --git a/jarvis/skills/entertainement/spotify/__init__.py b/jarvis/skills/entertainement/spotify/__init__.py index ee08e64..5f66dd0 100644 --- a/jarvis/skills/entertainement/spotify/__init__.py +++ b/jarvis/skills/entertainement/spotify/__init__.py @@ -6,6 +6,6 @@ class SpotifySkill(Skill, metaclass=SkillRegistering): def __init__(self): super().__init__("SpotifySkill") - @intent_file_handler("play_a_song.intent") + @intent_file_handler("play_a_song.intent", "PlaySongWithSpotifyIntent") def handle_play_a_song(self, data): print("Play song") diff --git a/jarvis/skills/intent_manager.py b/jarvis/skills/intent_manager.py index 6057d8a..2de0e61 100644 --- a/jarvis/skills/intent_manager.py +++ b/jarvis/skills/intent_manager.py @@ -1,51 +1,82 @@ from adapt.engine import DomainIntentDeterminationEngine +from padatious import IntentContainer -engine = DomainIntentDeterminationEngine() +adapt_engine = DomainIntentDeterminationEngine() +padatious_intents_container = IntentContainer('intent_cache') intents_handlers_adapt = dict() intents_handlers_padatious = dict() -def register_entity(entity_value, entity_type, domain): - engine.register_entity(entity_value=entity_value, entity_type=entity_type, domain=domain) +def register_entity_adapt(entity_value, entity_type, domain): + adapt_engine.register_entity(entity_value=entity_value, entity_type=entity_type, domain=domain) # print("[Adapt]: Added entity with type " + entity_type + " for " + domain) -def register_regex(regex, domain): - engine.register_regex_entity(regex, domain) +def register_regex_adapt(regex, domain): + adapt_engine.register_regex_entity(regex, domain) # print("[Adapt]: Added new regex for " + domain) -def register_intent(intent, domain): - engine.register_intent_parser(intent, domain=domain) - print("[Adapt]: Registered new intent " + intent.name + " for skill " + domain) +def register_intent_adapt(intent, domain): + adapt_engine.register_intent_parser(intent, domain=domain) + print("[Adapt]: Registered new intent " + intent.name + " for skill " + domain + ".") + + +def register_intent_padatious(intent_name, list_of_intent_examples): + padatious_intents_container.add_intent(intent_name, list_of_intent_examples) + print("[Padatious]: Registered new intent " + intent_name + " with " + str( + len(list_of_intent_examples)) + " examples.") + + +def train_padatious(): + padatious_intents_container.train() def process_handlers(): for handler in intents_handlers_adapt: function_handler = intents_handlers_adapt.get(handler) - intent_builder = getattr(function_handler[0], "_register", [])[0] + intent_builder = getattr(function_handler[0], "_data", [])[0] skill_name = function_handler[1] - register_intent(intent_builder.build(), domain=skill_name) + register_intent_adapt(intent_builder.build(), domain=skill_name) for handler in intents_handlers_padatious: - # TODO : register file intents - print("") + function_handler = intents_handlers_padatious.get(handler) + intent_data_examples = function_handler[1] + register_intent_padatious(handler, intent_data_examples) -def handle(intent_name): +def handle(intent_name, data): if intent_name in intents_handlers_adapt: method = intents_handlers_adapt.get(intent_name)[0] - method(None, []) + method(None, data) + + if intent_name in intents_handlers_padatious: + method = intents_handlers_padatious.get(intent_name)[0] + method(None, data) def recognise(sentence): sentence = sentence.lower() print(sentence) - best_intents = engine.determine_intent(sentence, 100) - best_intent = next(best_intents) + if len(intents_handlers_adapt) > 0: + try: + best_intents = adapt_engine.determine_intent(sentence, 100) + best_intent = next(best_intents) - print(best_intent) + print(best_intent) # DEBUG - handle(best_intent['intent_type']) + # TODO: add data for adapt + handle(best_intent['intent_type'], []) + except StopIteration as e: + print("No match... (Adapt)") + + if len(intents_handlers_padatious) > 0: + result = padatious_intents_container.calc_intent(sentence) + # print(result) # DEBUG + + if result.conf >= 0.2: + handle(result.name, [result.matches, result.sent]) + else: + print("No match... (Padatious") diff --git a/jarvis/utils/test.py b/jarvis/utils/test.py deleted file mode 100644 index e7ba10a..0000000 --- a/jarvis/utils/test.py +++ /dev/null @@ -1,57 +0,0 @@ -from padatious import IntentContainer - -container = IntentContainer('intent_cache') - -container.add_intent('spotify', - ["Joue {song} sur spotify", - "Joue {song}", - "Joue {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}", - "Mets la chanson {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}", - "Mets la chanson {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify", - "Mets le titre {song}", - "Mets le titre {song} sur spotify", - "Mets le morceau {song}", - "Mets le morceau {song} sur spotify", - "Joue le morceau {song}", - "Joue le morceau {song} sur spotify", - "Mets le titre {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}", - "Mets le titre {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify", - "Joue {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify", - "Joue {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}", - "Joue le morceau {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}" - "Joue le morceau {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify" - "Mets voir {song}", - "Mets voir {song} sur spotify", - "Mets voir {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}", - "Mets voir {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify", - "Fait moi écouter {song}" - "Fait moi écouter {song} sur spotify" - "Fait moi écouter {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer}" - "Fait moi écouter {song} (de|des|du groupe|du chanteur|de la chanteuse) {singer} sur spotify" - ]) - -container.train() - -tests = ["joue time after time sur spotify", - "mets le morceau fortunate son sur spotify", - "joue le morceau crazy crazy nights", - "mets voir crazy crazy nights", - "mets la chanson crazy crazy nights de KISS", - "fait moi écouter bye bye miss american pie", - "joue le morceau bye bye miss american pie", - "joue le morceau bye bye miss american pie du groupe billy cassidy", - "joue hooked on a feeling sur spotify", - "joue le morceau fortunate son de Willy and the Boys sur spotify"] - -for test in tests: - print("Sentence : " + test) - - result = container.calc_intent(test) - if 'song' in result.matches: - print("Song : " + result.matches.get('song')) - - if 'singer' in result.matches: - print("Singer/Group : " + result.matches.get('singer')) - - print("") - print("")