diff --git a/jarvis/skills/intent_services/intent_manager.py b/jarvis/skills/intent_services/intent_manager.py index cb30104..1a849da 100644 --- a/jarvis/skills/intent_services/intent_manager.py +++ b/jarvis/skills/intent_services/intent_manager.py @@ -1,13 +1,17 @@ import importlib +import json import types from adapt.engine import DomainIntentDeterminationEngine +from padatious import IntentContainer from jarvis import api adapt_engine = DomainIntentDeterminationEngine() +padatious_intents_container = IntentContainer('intent_cache') intents_handlers_adapt = dict() +intents_handlers_padatious = dict() def register_entity_adapt(entity_value, entity_type, domain): @@ -25,6 +29,22 @@ def register_intent_adapt(intent, domain): print("[Adapt]: Registered new intent " + intent.name + " for skill " + domain + ".") +def register_entity_padatious(entity_name, file_lines_list): + padatious_intents_container.add_entity(entity_name, file_lines_list) + # print("[Padatious]: Added entity with name " + entity_name + " with " str(len(list)) + "examples.") + + +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(): + print("Training PADATIOUS intents models, can take a few minutes (first time) or a few seconds (startup)") + padatious_intents_container.train(timeout=120) + + def load_all_skills(): for handler in intents_handlers_adapt: function_handler = intents_handlers_adapt.get(handler) @@ -33,15 +53,30 @@ def load_all_skills(): register_intent_adapt(intent_builder.build(), domain=skill_name) print("Loaded " + skill_name) + for handler in intents_handlers_padatious: + function_handler = intents_handlers_padatious.get(handler) + intent_data_examples = function_handler[1] + register_intent_padatious(handler, intent_data_examples) + print("Loaded " + intent_data_examples) -def look_for_matching_skill(sentence): + +def look_for_matching_intent(sentence): + best_intent_adapt = get_best_intent_adapt(sentence) + best_intent_padatious = get_best_intent_padatious(sentence) + + confidence_adapt = get_confidence(best_intent_adapt) + confidence_padatious = get_confidence(best_intent_padatious) + + return best_intent_adapt if confidence_adapt > confidence_padatious else best_intent_padatious + + +def get_best_intent_adapt(sentence): if len(intents_handlers_adapt) > 0: try: best_intents = adapt_engine.determine_intent(sentence, 100) best_intent = next(best_intents) - if (get_confidence(best_intent) > 0.2): - return best_intent + return best_intent except StopIteration: pass @@ -49,6 +84,14 @@ def look_for_matching_skill(sentence): return None # No match (Adapt) +def get_best_intent_padatious(sentence): + if len(intents_handlers_padatious) > 0: + result = padatious_intents_container.calc_intent(sentence) + return result + else: + return None # No match (Padatious) + + def get_confidence(intent): if intent is None: return 0 @@ -61,15 +104,23 @@ def get_confidence(intent): return 0 -def handle_adapt_intent(data, intent): - for key, val in intent.items(): - if key != 'intent_type' and key != 'target' and key != 'confidence': - data[key] = val - handle(intent['intent_type'], data=data) - return intent +def handle_intent(data, intent): + # Handle Adapt + if 'intent_type' in intent: + for key, val in intent.items(): + if key != 'intent_type' and key != 'target' and key != 'confidence': + data[key] = val + launch_intent(intent['intent_type'], data=data) + return intent + + # Handle padatious + elif hasattr(intent, 'name'): + data.update(intent.matches) # adding the matches from padatious to the data + launch_intent(intent.name, data) + return json.dumps(str(intent)) -def handle(intent_name, data): +def launch_intent(intent_name, data): module_path_str = None handler_method_name = None @@ -77,14 +128,16 @@ def handle(intent_name, data): handler_method_name = intents_handlers_adapt.get(intent_name)[2] module_path_str = intents_handlers_adapt.get(intent_name)[3] + if intent_name in intents_handlers_padatious: + handler_method_name = intents_handlers_padatious.get(intent_name)[0] + module_path_str = intents_handlers_padatious.get(intent_name)[2] + if module_path_str is not None and handler_method_name is not None: # import the create_skill method from the skill using the skill module path create_skill_method = import_method_from_string(module_path_str, "create_skill") - skill_init_data = {'client_ip': data['client_ip'], 'client_port': data['client_port']} - # create a new object of the right skill for the utterance - skill = create_skill_method(skill_init_data) + skill = create_skill_method(data) # import and call the handler method from the skill getattr(skill, handler_method_name)(data=data) @@ -103,6 +156,9 @@ def import_method_from_string(file, method_name): def recognise(sentence, uuid=None): print("RECOGNISE " + sentence) + + launch_intent(look_for_matching_intent(sentence)) + # TODO: find why not working api.send_jarvis_message_to_room("Not implemented that yet, please wait.", uuid) @@ -116,10 +172,10 @@ class SkillRegistering(type): if intent_type is not None: properties = getattr(val, "_data", None) - if properties is not None: - if intent_type == 'adapt': - intent = properties[0] - intent_name = intent.name + if properties is not None: + if intent_type == 'adapt': + intent = properties[0] + intent_name = intent.name - intents_handlers_adapt[f"{intent_name}"] = [getattr(cls, key), name, key, - attrs['__module__']] + intents_handlers_adapt[f"{intent_name}"] = [getattr(cls, key), name, key, + attrs['__module__']]