def run(self, dispatcher, tracker, domain): graph = GraphDatabase() # get entities to compare and their entity type listed_items = tracker.get_slot("listed_items") entity_type = get_entity_type(tracker) if listed_items is None or entity_type is None: dispatcher.utter_template("utter_rephrase", tracker) return [] # get attribute of interest attribute = get_attribute(tracker) if attribute is None: dispatcher.utter_template("utter_rephrase", tracker) return [] # utter response for every entity that shows the value of the attribute for e in listed_items: key_attribute = schema[entity_type]["key"] value = graph.get_attribute_of(entity_type, key_attribute, e, attribute) if value is not None and len(value) == 1: dispatcher.utter_message( f"{e} has the value '{value[0]}' for attribute '{attribute}'." ) return []
def run(self, dispatcher, tracker, domain): graph_database = GraphDatabase() # first need to know the entity type we are looking for entity_type = get_entity_type(tracker) #ip or microservice if entity_type is None: dispatcher.utter_template("utter_rephrase", tracker) return [] # check what attributes the NER found for entity type attributes = get_attributes_of_entity(entity_type, tracker) # ip, cpu, memory value is ** # query knowledge base entities = graph_database.get_entities(entity_type) # filter out transactions that do not belong the set account (if any) # if entity_type == "ip": # account_number = tracker.get_slot("account") # entities = self._filter_transaction_entities(entities, account_number) if not entities: dispatcher.utter_template( "I could not find any entities for '{}'.".format(entity_type), tracker ) return [] # utter a response that contains all found entities # use the 'representation' attributes to print an entity # entity_representation = schema[entity_type]["representation"] dispatcher.utter_message( "Found the following '{}' entities:".format(entity_type) ) # sorted_entities = sorted([to_str(e, entity_representation) for e in entities]) # for i, e in enumerate(sorted_entities): for i, e in enumerate(entities): dispatcher.utter_message(f"{i + 1}: {e}") # set slots # set the entities slot in order to resolve references to one of the found # entites later on entity_key = schema[entity_type]["key"] # slots = [ # SlotSet("entity_type", entity_type), # SlotSet("listed_items", list(map(lambda x: to_str(x, entity_key), entities))), # ] slots = [ SlotSet("entity_type", entity_type), SlotSet("listed_items", entities), ] # if only one entity was found, that the slot of that entity type to the # found entity if len(entities) == 1: slots.append(SlotSet(entity_type, to_str(entities[0], entity_key))) reset_attribute_slots(slots, entity_type, tracker) return slots
def get_attributes_of_entity(entity_type, tracker): # check what attributes the NER found for entity type attributes_res = [] graph_database = GraphDatabase() attributes = graph_database.get_attributes_of_entity(entity_type) for attr in attributes: attr_val = tracker.get_slot(attr.lower()) if attr_val is not None: attributes_res.append({"key": attr, "value": attr_val}) return attributes_res
def get_attribute(tracker: Tracker) -> Text: """ Get the attribute mentioned by the user. As the user may use a synonym for an attribute, we need to map the mentioned attribute to the attribute name used in the knowledge base. :param tracker: tracker :return: attribute (same type as used in the knowledge base) """ graph_database = GraphDatabase() attribute = tracker.get_slot("attribute") return graph_database.map("attribute-mapping", attribute)
def get_entity_type(tracker: Tracker) -> Text: """ Get the entity type mentioned by the user. As the user may speak of an entity type in plural, we need to map the mentioned entity type to the type used in the knowledge base. :param tracker: tracker :return: entity type (same type as used in the knowledge base) """ graph_database = GraphDatabase() entity_type = tracker.get_slot("entity_type") if entity_type is None: for entity in graph_database.entity_list: if tracker.get_slot(entity) is not None: return entity else: return graph_database.map_entity_type(entity_type)
def resolve_mention(tracker: Tracker) -> Text: """ Resolves a mention of an entity, such as first, to the actual entity. If multiple entities are listed during the conversation, the entities are stored in the slot 'listed_items' as a list. We resolve the mention, such as first, to the list index and retrieve the actual entity. :param tracker: tracker :return: name of the actually entity """ graph_database = GraphDatabase() mention = tracker.get_slot("mention") listed_items = tracker.get_slot("listed_items") if mention is not None and listed_items is not None: idx = int(graph_database.map("mention-mapping", mention)) if type(idx) is int and idx < len(listed_items): return listed_items[idx]
def get_entity_name(tracker: Tracker, entity_type: Text): """ Get the name of the entity the user referred to. Either the NER detected the entity and stored its name in the corresponding slot or the user referred to the entity by an ordinal number, such as first or last, or the user refers to an entity by its attributes. :param tracker: Tracker :param entity_type: the entity type :return: the name of the actual entity (value of key attribute in the knowledge base) """ # user referred to an entity by an ordinal number mention = tracker.get_slot("mention") if mention is not None: return resolve_mention(tracker) # user named the entity entity_name = tracker.get_slot(entity_type) if entity_name: return entity_name # user referred to an entity by its attributes listed_items = tracker.get_slot("listed_items") attributes = get_attributes_of_entity(entity_type, tracker) if listed_items and attributes: # filter the listed_items by the set attributes graph_database = GraphDatabase() for entity in listed_items: key_attr = schema[entity_type]["key"] result = graph_database.validate_entity( entity_type, entity, key_attr, attributes ) if result is not None: return to_str(result, key_attr) return None
def required_slots(tracker: Tracker) -> List[Text]: graph_database = GraphDatabase() entity_type = tracker.get_slot("entity_type") number_entity_type = len(tracker.latest_message['entities']) print('2222222222222222222staticmethod2222222222222222222222222', number_entity_type) if number_entity_type == 2: #假设用户直接提供两个entity type了,这个时候随机选择第一个entity作为必填的槽即可 return [entity_type] elif number_entity_type == 1:#只有一个entity type, 那么另外一个必须提供一个具体的entity,所以拿到它即可 requried_entity = "" for entity in graph_database.entity_list: if tracker.get_slot(entity) is not None: requried_entity += entity return [requried_entity] else:#也就是一个entity type都没有,那么必然提供了两个具体的entity,所以不需要填槽了 return []
def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict]: graph_database = GraphDatabase() # get entity type of entity entity_type = tracker.get_slot("entity_type") number_entity_type = len(tracker.latest_message['entities']) print('2222222222222222222222222222222222222222222222222222222222222',number_entity_type) entity_value = {} for entity in graph_database.entity_list: if tracker.get_slot(entity) is not None: entity_value[entity] = tracker.get_slot(entity) if entity_type is None or number_entity_type == 0: if len(entity_value) < 2: #意思输入时不符合格式的,如果没有entity type,那么必须提供2个具体的entity值 dispatcher.utter_template("utter_rephrase", tracker) return [] else: relation_node_list = list(entity_value.values())[0] res = False for value in entity_value.values(): if value in relation_node_list: res = True dispatcher.utter_message( "the relation you want to query between the two nodes is {0}".format(res) ) return [] if number_entity_type == 2: dispatcher.utter_message(template='utter_ask_' + entity_type) return [] #剩下的情况就是一定有某个具体的entity和一个entity type: entity_value = "" for entity in graph_database.entity_list: if tracker.get_slot(entity) is not None: entity_value += tracker.get_slot(entity) res = graph_database.relation[entity_value] dispatcher.utter_message( "according to your request, the reslts us : {0}".format(res) ) return []
def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict]: graph_database = GraphDatabase() # get entity type of entity entity_type = get_entity_type(tracker) attribute_name = tracker.get_slot("attribute") if entity_type is None or attribute_name is None: dispatcher.utter_template("utter_rephrase", tracker) return [] if " " in attribute_name: attribute_name.replace(" ","_") # get name of entity and attribute of interest entity_value = tracker.get_slot(entity_type) if entity_value is None: dispatcher.utter_message(template='utter_ask_' + entity_type) slots = [SlotSet("mention", None)] reset_attribute_slots(slots, entity_type, tracker) return slots # query knowledge base result = graph_database.data[entity_type][entity_value][attribute_name] # utter response if result is not None: dispatcher.utter_message( f"{entity_value} has the value '{result}' for attribute '{attribute_name}'." ) else: dispatcher.utter_message( f"Did not found a valid value for attribute {attribute_name} for entity '{entity_type}'." ) slots = [SlotSet("mention", None), SlotSet(entity_type, entity_value)] reset_attribute_slots(slots, entity_type, tracker) return slots