def run( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], ) -> List[Dict[Text, Any]]: """ Executes this action. If the user ask a question about an attribute, the knowledge base is queried for that attribute. Otherwise, if no attribute was detected in the request or the user is talking about a new object type, multiple objects of the requested type are returned from the knowledge base. Args: dispatcher: the dispatcher tracker: the tracker domain: the domain Returns: list of slots """ logger.info("action_query_attribute_of") object_type = tracker.get_slot(SLOT_OBJECT_TYPE) last_object_type = tracker.get_slot(SLOT_LAST_OBJECT_TYPE) attribute = tracker.get_slot(SLOT_ATTRIBUTE) new_request = object_type != last_object_type if not object_type: self.knowledge_base.default_object_type = 'doctor' logger.info('query attribute attr:' + str(attribute) + ' new_req:' + str(new_request)) return self._query_attribute(dispatcher, tracker) dispatcher.utter_template("utter_ask_rephrase", tracker) return []
def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: address = tracker.get_slot('address') date_time = tracker.get_slot('date-time') if date_time is None: date_time = '今天' date_time_number = get_time_unit(date_time) # 传入时间关键词,返回归一化的时间 if isinstance(date_time_number, str): # parse date_time failed return [ SlotSet("matches", "暂不支持查询 {} 的天气".format([address, date_time_number])) ] elif date_time_number is None: return [ SlotSet("matches", "暂不支持查询 {} 的天气".format([address, date_time])) ] else: print('address', address) print('date_time', date_time) print('date_time_number', date_time_number) weather_data = get_text_weather_date(address, date_time, date_time_number) # 调用天气API return [SlotSet("matches", "{}".format(weather_data))]
def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: address = tracker.get_slot('address') date_time = tracker.get_slot('date-time') if date_time is None: date_time = '今天' date_time_number = get_time_unit(date_time) # 传入时间关键词,返回归一化的时间 if isinstance(date_time_number, str): # parse date_time failed return [ SlotSet("matches", "暂不支持查询 {} 的天气".format([address, date_time_number])) ] elif date_time_number is None: return [ SlotSet("matches", "暂不支持查询 {} 的天气".format([address, date_time])) ] else: condition = sw.get_weather_by_city_and_day( address, date_time_number) # 调用天气API weather_data = forecast_to_text(address, condition) return [SlotSet("matches", "{}".format(weather_data))]
def _query_attribute(self, dispatcher: CollectingDispatcher, tracker: Tracker) -> List[Dict]: """ Queries the knowledge base for the value of the requested attribute of the mentioned object and outputs it to the user. Args: dispatcher: the dispatcher tracker: the tracker Returns: list of slots """ object_type = tracker.get_slot(SLOT_OBJECT_TYPE) attribute = tracker.get_slot(SLOT_ATTRIBUTE) object_name = get_object_name( tracker, self.knowledge_base.ordinal_mention_mapping, self.use_last_object_mention, ) if not object_name or not attribute: dispatcher.utter_message(template="utter_ask_rephrase") return [SlotSet(SLOT_MENTION, None)] object_of_interest = self.knowledge_base.get_object( object_type, object_name) if not object_of_interest or attribute not in object_of_interest: dispatcher.utter_message(template="utter_ask_rephrase") return [SlotSet(SLOT_MENTION, None)] value = object_of_interest[attribute] repr_function = self.knowledge_base.get_representation_function_of_object( object_type) object_representation = repr_function(object_of_interest) key_attribute = self.knowledge_base.get_key_attribute_of_object( object_type) object_identifier = object_of_interest[key_attribute] self.utter_attribute_value(dispatcher, object_representation, attribute, value) slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_ATTRIBUTE, None), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_LAST_OBJECT, object_identifier), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), ] return slots
async def __process_google_search_action(dispatcher: CollectingDispatcher, tracker: Tracker, action_config: dict): exception = None status = "SUCCESS" latest_msg = tracker.latest_message.get('text') bot_response = action_config.get("failure_response") try: if not ActionUtility.is_empty(latest_msg): results = ActionUtility.perform_google_search( action_config['api_key'], action_config['search_engine_id'], latest_msg, num=action_config.get("num_results") ) if results: bot_response = ActionUtility.format_search_result(results) except Exception as e: logger.exception(e) exception = str(e) status = "FAILURE" finally: ActionServerLogs( type=ActionType.google_search_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['name'], bot_response=bot_response, sender=tracker.sender_id, bot=tracker.get_slot("bot"), exception=exception, status=status ).save() dispatcher.utter_message(bot_response) return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
def _query_objects(self, dispatcher: CollectingDispatcher, tracker: Tracker) -> List[Dict]: object_type = tracker.get_slot(SLOT_OBJECT_TYPE) object_attributes = self.knowledge_base.get_attributes_of_object(object_type) attributes = get_attribute_slots(tracker, object_attributes) objects = self.knowledge_base.get_objects(object_type, attributes) self.utter_objects(dispatcher, object_type, objects, attributes) if not objects: return reset_attribute_slots(tracker, object_attributes) key_attribute = self.knowledge_base.get_key_attribute_of_object(object_type) last_object = None if len(objects) > 1 else objects[0][key_attribute] slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_LAST_OBJECT, last_object), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), SlotSet(SLOT_LISTED_OBJECTS, list(map(lambda e: e[key_attribute], objects))) ] return slots + reset_attribute_slots(tracker, object_attributes)
async def __process_zendesk_action(dispatcher: CollectingDispatcher, tracker: Tracker, action_config: dict): status = "SUCCESS" exception = None bot_response = action_config.get("response") subject = f"{tracker.sender_id} {action_config['subject']}" try: comment = ActionUtility.prepare_email_body(tracker.events, action_config['subject']) ActionUtility.create_zendesk_ticket( subdomain=action_config['subdomain'], user_name=action_config['user_name'], api_token=action_config['api_token'], subject=subject, comment=comment, tags=action_config.get('tags') ) except Exception as e: logger.exception(e) logger.debug(e) exception = str(e) status = "FAILURE" bot_response = "I have failed to create issue for you" finally: ActionServerLogs( type=ActionType.zendesk_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['name'], sender=tracker.sender_id, bot=tracker.get_slot("bot"), exception=exception, bot_response=bot_response, status=status ).save() dispatcher.utter_message(bot_response) return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
async def __process_pipedrive_leads_action(dispatcher: CollectingDispatcher, tracker: Tracker, action_config: dict): status = "SUCCESS" exception = None bot_response = action_config.get("response") title = f"{tracker.sender_id} {action_config['title']}" try: conversation_as_str = ActionUtility.prepare_message_trail_as_str(tracker.events) metadata = ActionUtility.prepare_pipedrive_metadata(tracker, action_config) ActionUtility.create_pipedrive_lead( domain=action_config['domain'], api_token=action_config['api_token'], title=title, conversation=conversation_as_str, **metadata ) except Exception as e: logger.exception(e) logger.debug(e) exception = str(e) status = "FAILURE" bot_response = "I have failed to create lead for you" finally: ActionServerLogs( type=ActionType.pipedrive_leads_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['name'], sender=tracker.sender_id, bot=tracker.get_slot("bot"), exception=exception, bot_response=bot_response, status=status ).save() dispatcher.utter_message(bot_response) return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: slot = tracker.get_slot('quality') dispatcher.utter_message(response="utter_result_" + slot) return []
async def __process_form_validation_action(dispatcher: CollectingDispatcher, tracker: Tracker, form_validations): slot = tracker.get_slot(REQUESTED_SLOT) slot_value = tracker.get_slot(slot) msg = [f'slot: {slot} | slot_value: {slot_value}'] status = "FAILURE" if ActionUtility.is_empty(slot): return {} try: validation = form_validations.get(slot=slot) slot_type = ActionUtility.get_slot_type(validation.bot, slot) msg.append(f'slot_type: {slot_type}') semantic = validation.validation_semantic msg.append(f'validation: {semantic}') utter_msg_on_valid = validation.valid_response utter_msg_on_invalid = validation.invalid_response msg.append(f'utter_msg_on_valid: {utter_msg_on_valid}') msg.append(f'utter_msg_on_valid: {utter_msg_on_invalid}') expr_as_str, is_valid = ExpressionEvaluator.is_valid_slot_value(slot_type, slot_value, semantic) msg.append(f'Expression: {expr_as_str}') msg.append(f'is_valid: {is_valid}') if is_valid: status = "SUCCESS" if not ActionUtility.is_empty(utter_msg_on_valid): dispatcher.utter_message(text=utter_msg_on_valid) if not is_valid: slot_value = None if not ActionUtility.is_empty(utter_msg_on_invalid): dispatcher.utter_message(utter_msg_on_invalid) except DoesNotExist as e: logger.exception(e) msg.append(f'Skipping validation as no validation config found for slot: {slot}') logger.debug(e) finally: ActionServerLogs( type=ActionType.form_validation_action.value, intent=tracker.get_intent_of_latest_message(), action=tracker.followup_action, sender=tracker.sender_id, bot=tracker.get_slot("bot"), messages=msg, status=status ).save() return {slot: slot_value}
async def __process_action(dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], action) -> List[Dict[Text, Any]]: slots = {} action_type = None try: logger.info(tracker.current_slot_values()) intent = tracker.get_intent_of_latest_message() logger.info("intent: " + str(intent)) logger.info("tracker.latest_message: " + str(tracker.latest_message)) bot_id = tracker.get_slot("bot") if ActionUtility.is_empty(bot_id) or ActionUtility.is_empty(action): raise ActionFailure("Bot id and action name not found in slot") action_config, action_type = ActionUtility.get_action_config(bot=bot_id, name=action) if action_type == ActionType.http_action.value: slots = await ActionProcessor.__process_http_action(tracker, action_config) dispatcher.utter_message(slots.get(KAIRON_ACTION_RESPONSE_SLOT)) elif action_type == ActionType.slot_set_action.value: slots = await ActionProcessor.__process_slot_set_action(tracker, action_config) elif action_type == ActionType.form_validation_action.value: slots = await ActionProcessor.__process_form_validation_action(dispatcher, tracker, action_config) elif action_type == ActionType.email_action.value: slots = await ActionProcessor.__process_email_action(dispatcher, tracker, action_config) elif action_type == ActionType.google_search_action.value: slots = await ActionProcessor.__process_google_search_action(dispatcher, tracker, action_config) elif action_type == ActionType.jira_action.value: slots = await ActionProcessor.__process_jira_action(dispatcher, tracker, action_config) elif action_type == ActionType.zendesk_action.value: slots = await ActionProcessor.__process_zendesk_action(dispatcher, tracker, action_config) elif action_type == ActionType.pipedrive_leads_action.value: slots = await ActionProcessor.__process_pipedrive_leads_action(dispatcher, tracker, action_config) return [SlotSet(slot, value) for slot, value in slots.items()] except Exception as e: logger.exception(e) ActionServerLogs( type=action_type, intent=tracker.get_intent_of_latest_message(), action=action, sender=tracker.sender_id, exception=str(e), bot=tracker.get_slot("bot"), status="FAILURE" ).save()
def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: address = tracker.get_slot('address') logger.info('Slot Address {}'.format(address)) date_time = tracker.get_slot('date-time') logger.info('Slot Date_time {}'.format(date_time)) if date_time is None: msg = "暂不支持查询 {} 的天气".format([address, date_time]) return [SlotSet("matches", msg)] else: try: date_object = get_time_unit(date_time) weather_data = self.weather_api.get_text_by_city_and_day( address, date_object) except Exception as e: weather_data = str(e) return [SlotSet("matches", "{}".format(weather_data))]
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: response = requests.get("https://db.benita-dietrich.de/api") data = response.json() object_type = tracker.get_slot('object_type') attribute = tracker.get_slot('attribute') specific_info = tracker.get_slot('specific_info') try: data[object_type]['template'] except KeyError: if not object_type == "studiengang" and not attribute is None: if specific_info is None: li = [str(item) for item in data[object_type][attribute]] dispatcher.utter_message(response="utter_" + object_type + "_" + attribute, values=' '.join(li)) else: li = [str(item) for item in data[object_type][attribute]] print("checking li", li) if specific_info in li: dispatcher.utter_message(response="utter_affirm") else: dispatcher.utter_message(response="utter_decline") except TypeError: if attribute is None: li = [item.get('id') for item in data[object_type]] print(li) dispatcher.utter_message(response="utter_studiengang", values=' '.join(li)) elif not specific_info is None: r = data[object_type][attribute][specific_info] dispatcher.utter_message(response="utter_studiengang_" + specific_info, info=attribute, values=r) else: dispatcher.utter_message(response=(data[object_type]['template'])) return [SlotSet("attribute", None)]
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: studiengang = tracker.get_slot('object_type') if studiengang is None: dispatcher.utter_message(response="utter_ask_studiengang") else: dispatcher.utter_message(response="utter_" + studiengang.lower()) return []
async def run( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: "DomainDict", ) -> List[Dict[Text, Any]]: """ Executes this action. If the user ask a question about an attribute, the knowledge base is queried for that attribute. Otherwise, if no attribute was detected in the request or the user is talking about a new object type, multiple objects of the requested type are returned from the knowledge base. Args: dispatcher: the dispatcher tracker: the tracker domain: the domain Returns: list of slots """ object_type = tracker.get_slot(SLOT_OBJECT_TYPE) last_object_type = tracker.get_slot(SLOT_LAST_OBJECT_TYPE) attribute = tracker.get_slot(SLOT_ATTRIBUTE) new_request = object_type != last_object_type if not object_type: # object type always needs to be set as this is needed to query the # knowledge base dispatcher.utter_message(template="utter_ask_rephrase") return [] if not attribute or new_request: return await self._query_objects(dispatcher, object_type, tracker) elif attribute: return await self._query_attribute(dispatcher, object_type, attribute, tracker) dispatcher.utter_message(template="utter_ask_rephrase") return []
def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: location = tracker.get_slot('location') contexts = tracker.latest_message['text'] weather_data = "{}".format(get_text_weather_date(location)) if weather_data is not None: dispatcher.utter_message(text="查询结果为:{}".format(weather_data)) return []
async def __process_http_action(tracker: Tracker, http_action_config: dict): bot_response = None http_response = None exception = None request_body = None status = "SUCCESS" http_url = None request_method = None headers = None try: headers = ActionUtility.prepare_request(tracker, http_action_config.get('headers')) request_body = ActionUtility.prepare_request(tracker, http_action_config['params_list']) logger.info("request_body: " + str(request_body)) request_method = http_action_config['request_method'] http_url = ActionUtility.prepare_url(request_method=request_method, http_url=http_action_config['http_url'], request_body=request_body) http_response = ActionUtility.execute_http_request(headers=headers, http_url=http_url, request_method=request_method, request_body=request_body) logger.info("http response: " + str(http_response)) bot_response = ActionUtility.prepare_response(http_action_config['response'], http_response) logger.info("response: " + str(bot_response)) except ActionFailure as e: exception = str(e) logger.exception(e) status = "FAILURE" bot_response = "I have failed to process your request" except Exception as e: exception = str(e) logger.exception(e) status = "FAILURE" bot_response = "I have failed to process your request" finally: ActionServerLogs( type=ActionType.http_action.value, intent=tracker.get_intent_of_latest_message(), action=http_action_config['action_name'], sender=tracker.sender_id, headers=headers, url=http_url, request_params=None if request_method and request_method.lower() == "get" else request_body, api_response=str(http_response) if http_response else None, bot_response=str(bot_response) if bot_response else None, exception=exception, bot=tracker.get_slot("bot"), status=status ).save() return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
def submit( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], ) -> List[Dict]: """Define what the form has to do after all required slots are filled""" # print("submit------tracker is {}",tracker) slot_to_fill = tracker.get_slot("requested_slot") logger.info("-------submit start slot_to_fill is '{}'" "".format(slot_to_fill)) # utter submit template dispatcher.utter_template("utter_cloth_recommend", tracker) return []
def _query_objects(self, dispatcher: CollectingDispatcher, tracker: Tracker) -> List[Dict]: """ Queries the knowledge base for objects of the requested object type and outputs those to the user. The objects are filtered by any attribute the user mentioned in the request. Args: dispatcher: the dispatcher tracker: the tracker Returns: list of slots """ object_type = tracker.get_slot(SLOT_OBJECT_TYPE) object_attributes = self.knowledge_base.get_attributes_of_object( object_type) # get all set attribute slots of the object type to be able to filter the # list of objects attributes = get_attribute_slots(tracker, object_attributes) # query the knowledge base objects = self.knowledge_base.get_objects(object_type, attributes) self.utter_objects(dispatcher, object_type, objects) if not objects: return reset_attribute_slots(tracker, object_attributes) key_attribute = self.knowledge_base.get_key_attribute_of_object( object_type) last_object = None if len(objects) > 1 else objects[0][key_attribute] slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_ATTRIBUTE, None), SlotSet(SLOT_LAST_OBJECT, last_object), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), SlotSet(SLOT_LISTED_OBJECTS, list(map(lambda e: e[key_attribute], objects))), ] return slots + reset_attribute_slots(tracker, object_attributes)
def validate_slot( self, value: Text, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], ) -> Dict[Text, Any]: """Validate thinking value.""" intent = tracker.latest_message['intent'].get('name') currentResult = tracker.get_slot('result') if intent == "affirm" and (not name_of_slot == "ratgeber" or not name_of_slot == "einstieg"): dispatcher.utter_message(response="utter_" + name_of_slot + "_bad") return {"result": currentResult} else: dispatcher.utter_message(response="utter_" + name_of_slot + "_good") return {"result": currentResult + 1}
async def __process_slot_set_action(tracker: Tracker, action_config: dict): message = [] status = 'SUCCESS' if action_config['type'] == SLOT_SET_TYPE.FROM_VALUE.value: message.append(f"Setting slot '{action_config['slot']}' to '{action_config['value']}'.") value = action_config['value'] else: message.append(f"Resetting slot '{action_config['slot']}' value to None.") value = None ActionServerLogs( type=ActionType.slot_set_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['name'], sender=tracker.sender_id, bot_response=value, messages=message, bot=tracker.get_slot("bot"), status=status ).save() return {action_config['slot']: value}
async def __process_email_action(dispatcher: CollectingDispatcher, tracker: Tracker, action_config: dict): status = "SUCCESS" exception = None bot_response = action_config.get("response") to_email = action_config['to_email'] try: for mail in to_email: body = ActionUtility.prepare_email_body(tracker.events, action_config['subject'], mail) await Utility.trigger_email(email=[mail], subject=f"{tracker.sender_id} {action_config['subject']}", body=body, smtp_url=action_config['smtp_url'], smtp_port=action_config['smtp_port'], sender_email=action_config['from_email'], smtp_password=action_config['smtp_password'], smtp_userid=action_config.get("smtp_userid"), tls=action_config['tls'], ) except Exception as e: logger.exception(e) logger.debug(e) exception = str(e) bot_response = "I have failed to process your request" status = "FAILURE" finally: ActionServerLogs( type=ActionType.email_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['action_name'], sender=tracker.sender_id, bot=tracker.get_slot("bot"), exception=exception, bot_response=bot_response, status=status ).save() dispatcher.utter_message(bot_response) return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: result = tracker.get_slot('result') message = "" quality = "" dispatcher.utter_message("Du hast " + str(result) + " von 6 Punkten erreicht") if result >= 5: message = "Du scheinst viele Fähigkeiten zu besitzen die für ein duales Studium wichtig sind, ein Duales Studium scheint für dich geeignet zu sein." quality = "good" elif result < 5 and result >= 3: message = "Du besitzt schon einige Fähigkeiten zu besitzen, die es für ein duales Studium braucht. Allerdings gibt es auch einige Themenbereiche, bei denen du dich verbessern könntest." quality = "medium" else: message = "Dein Ergebnis scheint etwas kontrovers zu sein, vielleicht ist eine andere Form des Studiums für dich eher geeignet. Wenn du möchtest, kannst du gerne ein persönliches Gespräch vereinbaren um mehr zu erfahren" quality = "bad" dispatcher.utter_message(message) return {quality: quality}
async def __process_jira_action(dispatcher: CollectingDispatcher, tracker: Tracker, action_config: dict): status = "SUCCESS" exception = None bot_response = action_config.get("response") summary = f"{tracker.sender_id} {action_config['summary']}" try: _, msgtrail = ActionUtility.prepare_message_trail_as_str(tracker.events) ActionUtility.create_jira_issue( url=action_config['url'], username=action_config['user_name'], api_token=action_config['api_token'], project_key=action_config['project_key'], issue_type=action_config['issue_type'], summary=summary, description=msgtrail, parent_key=action_config.get('parent_key') ) except Exception as e: logger.exception(e) logger.debug(e) exception = str(e) status = "FAILURE" bot_response = "I have failed to create issue for you" finally: ActionServerLogs( type=ActionType.jira_action.value, intent=tracker.get_intent_of_latest_message(), action=action_config['name'], sender=tracker.sender_id, bot=tracker.get_slot("bot"), exception=exception, bot_response=bot_response, status=status ).save() dispatcher.utter_message(bot_response) return {KAIRON_ACTION_RESPONSE_SLOT: bot_response}
async def __process_http_action(dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], action) -> List[Dict[Text, Any]]: bot_response = None http_response = None exception = None request_body = None status = "SUCCESS" http_url = None request_method = None try: logger.info(tracker.current_slot_values()) intent = tracker.get_intent_of_latest_message() logger.info("intent: " + str(intent)) logger.info("tracker.latest_message: " + str(tracker.latest_message)) bot_id = tracker.get_slot("bot") if ActionUtility.is_empty(bot_id) or ActionUtility.is_empty( action): raise HttpActionFailure( "Bot id and HTTP action configuration name not found in slot" ) http_action_config: HttpActionConfig = ActionUtility.get_http_action_config( bot=bot_id, action_name=action) request_body = ActionUtility.prepare_request( tracker, http_action_config['params_list']) logger.info("request_body: " + str(request_body)) request_method = http_action_config['request_method'] http_response, http_url = ActionUtility.execute_http_request( auth_token=http_action_config['auth_token'], http_url=http_action_config['http_url'], request_method=request_method, request_body=request_body) logger.info("http response: " + str(http_response)) bot_response = ActionUtility.prepare_response( http_action_config['response'], http_response) logger.info("response: " + str(bot_response)) # deepcode ignore W0703: General exceptions are captured to raise application specific exceptions except HttpActionFailure as e: exception = str(e) logger.exception(e) status = "FAILURE" bot_response = "I have failed to process your request" except Exception as e: exception = str(e) logger.exception(e) status = "FAILURE" bot_response = "I have failed to process your request" finally: dispatcher.utter_message(bot_response) HttpActionLog( intent=tracker.get_intent_of_latest_message(), action=action, sender=tracker.sender_id, url=http_url, request_params=None if request_method and request_method.lower() == "get" else request_body, api_response=str(http_response), bot_response=str(bot_response), exception=exception, bot=tracker.get_slot("bot"), status=status).save() return [SlotSet(KAIRON_ACTION_RESPONSE_SLOT, bot_response)]
async def run(self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]) -> List[Dict[Text, Any]]: context = tracker.get_slot('requested_slot') dispatcher.utter_message(response="utter_" + context) return []
def _query_attribute(self, dispatcher: CollectingDispatcher, tracker: Tracker) -> List[Dict]: """ Queries the knowledge base for the value of the requested attribute of the mentioned object and outputs it to the user. Args: dispatcher: the dispatcher tracker: the tracker Returns: list of slots """ object_type = tracker.get_slot(SLOT_OBJECT_TYPE) attribute = tracker.get_slot(SLOT_ATTRIBUTE) object_name = self._get_object_name( tracker, self.knowledge_base.ordinal_mention_mapping, self.use_last_object_mention, ) logger.info("_query_attribute [object_type]:" + str(object_type) + " [attribute]:" + str(attribute) + " [object_name]:" + str(object_name)) if not object_name or not attribute: logger.info("object_name or attribute not available") dispatcher.utter_template("utter_ask_rephrase", tracker) return [SlotSet(SLOT_MENTION, None)] object_attributes = self.knowledge_base.get_attributes_of_object( object_type) # get all set attribute slots of the object type to be able to filter the # list of objects attributes = get_attribute_slots(tracker, object_attributes) # query the knowledge base objects = self.knowledge_base.get_objects(object_type, attributes, object_name) key_attribute = self.knowledge_base.get_key_attribute_of_object( object_type) if not objects or attribute not in objects[0]: logger.info("object not found or attribute not in objects[0]") dispatcher.utter_template("utter_ask_rephrase", tracker) return [SlotSet(SLOT_MENTION, None)] + reset_attribute_slots( tracker, object_attributes) if len(objects) > 1: dispatcher.utter_message("Ho trovato più di un risultato:") for object_of_interest in objects: value = object_of_interest[attribute] repr_function = self.knowledge_base.get_representation_function_of_object( object_type) object_representation = repr_function(object_of_interest) key_attribute = self.knowledge_base.get_key_attribute_of_object( object_type) object_identifier = object_of_interest[key_attribute] self.utter_attribute_value(dispatcher, object_representation, attribute, value) slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_ATTRIBUTE, None), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_LAST_OBJECT, object_identifier), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), ] return slots + reset_attribute_slots(tracker, object_attributes)
def _query_attribute( self, dispatcher: CollectingDispatcher, tracker: Tracker ) -> List[Dict]: """ Queries the knowledge base for the value of the requested attribute of the mentioned object and outputs it to the user. Args: dispatcher: the dispatcher tracker: the tracker Returns: list of slots """ object_type = tracker.get_slot(SLOT_OBJECT_TYPE) attribute = tracker.get_slot(SLOT_ATTRIBUTE) object_name = get_object_name( tracker, self.knowledge_base.ordinal_mention_mapping, self.use_last_object_mention, ) if not object_name or not attribute: dispatcher.utter_message(template="utter_ask_rephrase") return [SlotSet(SLOT_MENTION, None)] object_of_interest = self.knowledge_base.get_object(object_type, object_name) if attribute in ["address", "latitude", "longitude", "url"] : base = "https://www.google.com/maps/search/?api=1&query=" url = base + urllib.parse.quote(object_of_interest["name"]) value = object_of_interest[attribute] repr_function = self.knowledge_base.get_representation_function_of_object( object_type ) object_representation = repr_function(object_of_interest) self.utter_attribute_value(dispatcher, object_representation, attribute, value, custom=True, load=url) key_attribute = self.knowledge_base.get_key_attribute_of_object(object_type) object_identifier = object_of_interest[key_attribute] slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_ATTRIBUTE, None), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_LAST_OBJECT, object_identifier), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), ] return slots else: if not object_of_interest or attribute not in object_of_interest: dispatcher.utter_message(template="utter_ask_rephrase") return [SlotSet(SLOT_MENTION, None)] value = object_of_interest[attribute] repr_function = self.knowledge_base.get_representation_function_of_object( object_type ) object_representation = repr_function(object_of_interest) key_attribute = self.knowledge_base.get_key_attribute_of_object(object_type) object_identifier = object_of_interest[key_attribute] self.utter_attribute_value(dispatcher, object_representation, attribute, value) slots = [ SlotSet(SLOT_OBJECT_TYPE, object_type), SlotSet(SLOT_ATTRIBUTE, None), SlotSet(SLOT_MENTION, None), SlotSet(SLOT_LAST_OBJECT, object_identifier), SlotSet(SLOT_LAST_OBJECT_TYPE, object_type), ] return slots