def _print_history(self, tracker): # prints the historical interactions between the bot and the user, # to help with correctly identifying the action latest_listen_flag = False tr_json = [] for tr in tracker.generate_all_prior_states(): tr_json.append({ 'action': tr.latest_action_name, 'intent': tr.latest_message.intent['name'] if tr.latest_message.intent else "", 'entities': tr.latest_message.entities }) print("------") print("Chat history:\n") tr_json = tr_json[-self.max_history:] n_history = len(tr_json) for idx, hist_tracker in enumerate(tr_json): print("\tbot did:\t{}\n".format(hist_tracker['action'])) if hist_tracker['action'] == 'action_listen': if idx < n_history - 1: print("\tuser did:\t{}\n".format(hist_tracker['intent'])) for entity in hist_tracker['entities']: print("\twith {}:\t{}\n".format( entity['entity'], entity['value'])) if idx == n_history - 1: print("\tuser said:\t{}\n".format( utils.wrap_with_color(tracker.latest_message.text, utils.bcolors.OKGREEN))) print("\t\t whose intent is:\t{}\n".format( hist_tracker['intent'])) for entity in hist_tracker['entities']: print("\twith {}:\t{}\n".format( entity['entity'], entity['value'])) latest_listen_flag = True slot_strs = [] for k, s in tracker.slots.items(): colored_value = utils.wrap_with_color(str(s.value), utils.bcolors.WARNING) slot_strs.append("{}: {}".format(k, colored_value)) print("we currently have slots: {}\n".format(", ".join(slot_strs))) print("------") return latest_listen_flag
def replay_events(tracker, agent): # type: (DialogueStateTracker, Agent) -> None """Take a tracker and replay the logged user utterances against an agent. During replaying of the user utterances, the executed actions and events created by the agent are compared to the logged ones of the tracker that is getting replayed. If they differ, a warning is logged. At the end, the tracker stored in the agent's tracker store for the same sender id will have quite the same state as the one that got replayed.""" actions_between_utterances = [] last_prediction = [ACTION_LISTEN_NAME] for i, event in enumerate(tracker.events_after_latest_restart()): if isinstance(event, UserUttered): _check_prediction_aligns_with_story(last_prediction, actions_between_utterances) actions_between_utterances = [] print(utils.wrap_with_color(event.text, utils.bcolors.OKGREEN)) agent.handle_message(event.text, sender_id=tracker.sender_id, output_channel=ConsoleOutputChannel()) tracker = agent.tracker_store.retrieve(tracker.sender_id) last_prediction = evaluate.actions_since_last_utterance(tracker) elif isinstance(event, ActionExecuted): actions_between_utterances.append(event.action_name) _check_prediction_aligns_with_story(last_prediction, actions_between_utterances)
def replay_events(tracker, agent): # type: (DialogueStateTracker, Agent) -> None """Take a tracker and replay the logged user utterances against an agent. During replaying of the user utterances, the executed actions and events created by the agent are compared to the logged ones of the tracker that is getting replayed. If they differ, a warning is logged. At the end, the tracker stored in the agent's tracker store for the same sender id will have quite the same state as the one that got replayed.""" actions_between_utterances = [] last_prediction = [ACTION_LISTEN_NAME] for i, event in enumerate(tracker.events_after_latest_restart()): if isinstance(event, UserUttered): _check_prediction_aligns_with_story(last_prediction, actions_between_utterances) actions_between_utterances = [] print(utils.wrap_with_color(event.text, utils.bcolors.OKGREEN)) agent.handle_message(event.text, sender_id=tracker.sender_id, output_channel=ConsoleOutputChannel()) tracker = agent.tracker_store.retrieve(tracker.sender_id) last_prediction = evaluate.actions_since_last_utterance(tracker) elif isinstance(event, ActionExecuted): actions_between_utterances.append(event.action_name) _check_prediction_aligns_with_story(last_prediction, actions_between_utterances)
def probabilities_using_best_policy(self, tracker, domain): # [feature vector, tracker, domain] -> int # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = np.argmax(probabilities) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") feature_vector = domain.feature_vector_for_tracker( self.featurizer, tracker, self.max_history) X = np.expand_dims(np.array(feature_vector), 0) if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) self._fit_example(X, y, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
def _slot_history(tracker_dump: Dict[Text, Any]) -> List[Text]: """Create an array of slot representations to be displayed.""" slot_strs = [] for k, s in tracker_dump.get("slots").items(): colored_value = utils.wrap_with_color(str(s), utils.bcolors.WARNING) slot_strs.append("{}: {}".format(k, colored_value)) return slot_strs
def _print_history(self, tracker): # prints the historical interactions between the bot and the user, # to help with correctly identifying the action latest_listen_flag = False tr_json = [] for tr in tracker.generate_all_prior_trackers(): tr_json.append({ 'action': tr.latest_action_name, 'intent': tr.latest_message.intent[ 'name'] if tr.latest_message.intent else "", 'entities': tr.latest_message.entities }) print("------") print("Chat history:\n") tr_json = tr_json[-self.max_visual_history:] n_history = len(tr_json) for idx, hist_tracker in enumerate(tr_json): print("\tbot did:\t{}\n".format(hist_tracker['action'])) if hist_tracker['action'] == 'action_listen': if idx < n_history - 1: print("\tuser did:\t{}\n".format(hist_tracker['intent'])) for entity in hist_tracker['entities']: print("\twith {}:\t{}\n".format(entity['entity'], entity['value'])) if idx == n_history - 1: print("\tuser said:\t{}\n".format( utils.wrap_with_color(tracker.latest_message.text, utils.bcolors.OKGREEN))) print("\t\t whose intent is:\t{}\n".format( hist_tracker['intent'])) for entity in hist_tracker['entities']: print("\twith {}:\t{}\n".format(entity['entity'], entity['value'])) latest_listen_flag = True slot_strs = [] for k, s in tracker.slots.items(): colored_value = utils.wrap_with_color(str(s.value), utils.bcolors.WARNING) slot_strs.append("{}: {}".format(k, colored_value)) print("we currently have slots: {}\n".format(", ".join(slot_strs))) print("------") return latest_listen_flag
def _print_history(tracker_dump): # prints the historical interactions between the bot and the user, # to help with correctly identifying the action latest_listen_flag = False tr_json = [] n_history = 0 for tr in reversed(tracker_dump.get("events", [])): tr_json.append(tr) if tr.get("event") == "action": n_history += 1 tr_json = reversed(tr_json) print("------") print("Chat history:\n") for idx, evt in enumerate(tr_json): if evt.get("event") == "action": print("\tbot did:\t{}\n".format(evt['name'])) latest_listen_flag = False if evt.get("event") == 'user': parsed = evt.get('parse_data', {}) print("\tuser said:\t{}\n".format( utils.wrap_with_color(evt.get("text"), utils.bcolors.OKGREEN))) print("\t\t whose intent is:\t{}\n".format( parsed.get('intent'))) for entity in parsed.get('entities'): print("\twith {}:\t{}\n".format(entity['entity'], entity['value'])) latest_listen_flag = True slot_strs = [] for k, s in tracker_dump.get("slots").items(): colored_value = utils.wrap_with_color(str(s), utils.bcolors.WARNING) slot_strs.append("{}: {}".format(k, colored_value)) print("we currently have slots: {}\n".format(", ".join(slot_strs))) print("------") return latest_listen_flag
def _request_intent_from_user(tracker_dump, intents): # take in some argument and ask which intent it should have been # save the intent to a json like file latest_message, _ = revert_latest_message(tracker_dump.get("events", [])) colored_user_msg = utils.wrap_with_color(latest_message.get("text"), utils.bcolors.OKGREEN) print("------\n") print("Message:\n") print(latest_message.get("text")) print("User said:\t {}".format(colored_user_msg)) print("What intent is this?\t") for idx, intent in enumerate(intents): print('\t{}\t{}'.format(idx, intent)) out = int(utils.request_input( utils.str_range_list(0, len(intents)))) return {'name': intents[out], 'confidence': 1.0}
def main(model_directory, nlu_model=None, tracker_dump=None): # type: (Text, Optional[Text], Optional[Text]) -> Agent """Run the agent.""" logger.info("Rasa process starting") agent = Agent.load(model_directory, nlu_model) logger.info("Finished loading agent. Loading stories now.") tracker = _load_tracker_from_json(tracker_dump, agent) _replay_events(tracker, agent) print( utils.wrap_with_color( "You can now continue the dialogue. " "Use '/stop' to exit the conversation.", utils.bcolors.OKGREEN + utils.bcolors.UNDERLINE)) agent.handle_channel(ConsoleInputChannel(tracker.sender_id)) return agent
def _request_intent(self, tracker, domain): # take in some argument and ask which intent it should have been # save the intent to a json like file colored_user_msg = utils.wrap_with_color(tracker.latest_message.text, utils.bcolors.OKGREEN) print("------\n") print("Message:\n") print(tracker.latest_message.text) print("User said:\t {}".format(colored_user_msg)) print("What intent is this?\t") for idx, intent in enumerate(domain.intents): print('\t{}\t{}'.format(idx, intent)) out = int( utils.request_input(utils.str_range_list(0, len(domain.intents)))) json_example = { 'text': tracker.latest_message.text, 'intent': domain.intents[out] } self.extra_intent_examples.append(json_example) intent_name = domain.intents[out] return {'name': intent_name, 'confidence': 1.0}
def _request_intent(self, tracker, domain): # take in some argument and ask which intent it should have been # save the intent to a json like file colored_user_msg = utils.wrap_with_color(tracker.latest_message.text, utils.bcolors.OKGREEN) print("------\n") print("Message:\n") print(tracker.latest_message.text) print("User said:\t {}".format(colored_user_msg)) print("What intent is this?\t") for idx, intent in enumerate(domain.intents): print('\t{}\t{}'.format(idx, intent)) out = int(utils.request_input( utils.str_range_list(0, len(domain.intents)))) json_example = { 'text': tracker.latest_message.text, 'intent': domain.intents[out] } self.extra_intent_examples.append(json_example) intent_name = domain.intents[out] return {'name': intent_name, 'confidence': 1.0}
"""Recreate an agent instance.""" logger.debug("Loading Rasa Core Agent") agent = Agent.load(model_directory, nlu_model) logger.debug("Finished loading agent. Loading stories now.") tracker = load_tracker_from_json(tracker_dump, agent.domain) replay_events(tracker, agent) return agent, tracker if __name__ == '__main__': # Running as standalone python application arg_parser = create_argument_parser() cmdline_args = arg_parser.parse_args() utils.configure_colored_logging(cmdline_args.loglevel) agent, tracker = recreate_agent(cmdline_args.core, cmdline_args.nlu, cmdline_args.tracker_dump) print( utils.wrap_with_color( "You can now continue the dialogue. " "Use '/stop' to exit the conversation.", utils.bcolors.OKGREEN + utils.bcolors.UNDERLINE)) agent.handle_channel(ConsoleInputChannel(tracker.sender_id))
def probabilities_using_best_policy(self, tracker, domain): # type: (DialogueStateTracker, Domain) -> List[float] # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = int(np.argmax(probabilities)) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) # update tracker with new action new_action_name = domain.action_for_index(y).name() # need to copy tracker, because the tracker will be # updated with the new event somewhere else training_tracker = tracker.copy() training_tracker.update(ActionExecuted(new_action_name)) self._fit_example(training_tracker, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) for e in domain.slots_for_entities(latest_message.entities): tracker.update(e) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
logger.debug("Loading Rasa Core Agent") agent = Agent.load(model_directory, nlu_model, generator=nlg_endpoint) logger.debug("Finished loading agent. Loading stories now.") tracker = load_tracker_from_json(tracker_dump, agent.domain) replay_events(tracker, agent) return agent, tracker if __name__ == '__main__': # Running as standalone python application arg_parser = create_argument_parser() cmdline_args = arg_parser.parse_args() utils.configure_colored_logging(cmdline_args.loglevel) agent, tracker = recreate_agent(cmdline_args.core, cmdline_args.nlu, cmdline_args.tracker_dump) print(utils.wrap_with_color( "You can now continue the dialogue. " "Use '/stop' to exit the conversation.", utils.bcolors.OKGREEN + utils.bcolors.UNDERLINE)) agent.handle_channel(ConsoleInputChannel(tracker.sender_id))
def probabilities_using_best_policy(self, tracker, domain): # type: (DialogueStateTracker, Domain) -> List[float] # given a state, predict next action via asking a human probabilities = self.base_ensemble.probabilities_using_best_policy( tracker, domain) pred_out = int(np.argmax(probabilities)) latest_action_was_listen = self._print_history(tracker) action_name = domain.action_for_index(pred_out).name() colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") if user_input == "1": # max prob prediction was correct if action_name == ACTION_LISTEN_NAME: print("Next user input:") return probabilities elif user_input == "2": # max prob prediction was false, new action required # action wrong y = self._request_action(probabilities, domain, tracker) # update tracker with new action new_action_name = domain.action_for_index(y).name() # need to copy tracker, because the tracker will be # updated with the new event somewhere else training_tracker = tracker.copy() training_tracker.update(ActionExecuted(new_action_name)) self._fit_example(training_tracker, domain) self.write_out_story(tracker) return utils.one_hot(y, domain.num_actions) elif user_input == "3": # intent wrong and maybe action wrong intent = self._request_intent(tracker, domain) latest_message = copy.copy(tracker.latest_message) latest_message.intent = intent tracker.update(UserUtteranceReverted()) tracker.update(latest_message) for e in domain.slots_for_entities(latest_message.entities): tracker.update(e) return self.probabilities_using_best_policy(tracker, domain) elif user_input == "0": self._export_stories(tracker) raise TrainingFinishedException() else: raise Exception( "Incorrect user input received '{}'".format(user_input))
agent.domain) run.start_cmdline_io(constants.DEFAULT_SERVER_URL, http_server.stop, sender_id=tracker.sender_id) replay_events(tracker, agent) try: http_server.serve_forever() except Exception as exc: logger.exception(exc) if __name__ == '__main__': # Running as standalone python application arg_parser = create_argument_parser() cmdline_args = arg_parser.parse_args() utils.configure_colored_logging(cmdline_args.loglevel) print(utils.wrap_with_color( "We'll recreate the dialogue state. After that you can chat " "with the bot, continuing the input conversation.", utils.bcolors.OKGREEN + utils.bcolors.UNDERLINE)) serve_application(cmdline_args.core, cmdline_args.nlu, cmdline_args.port, cmdline_args.endpoints, cmdline_args.enable_api)
tracker = load_tracker_from_json(tracker_dump, agent.domain) run.start_cmdline_io(constants.DEFAULT_SERVER_FORMAT.format(port), http_server.stop, sender_id=tracker.sender_id) replay_events(tracker, agent) try: http_server.serve_forever() except Exception as exc: logger.exception(exc) if __name__ == '__main__': # Running as standalone python application arg_parser = create_argument_parser() cmdline_args = arg_parser.parse_args() utils.configure_colored_logging(cmdline_args.loglevel) print( utils.wrap_with_color( "We'll recreate the dialogue state. After that you can chat " "with the bot, continuing the input conversation.", utils.bcolors.OKGREEN + utils.bcolors.UNDERLINE)) serve_application(cmdline_args.core, cmdline_args.nlu, cmdline_args.port, cmdline_args.endpoints, cmdline_args.enable_api)
def predict_till_next_listen(endpoint, # type: EndpointConfig intents, # type: List[Text] sender_id # type: Text ): # type: (...) -> bool # given a state, predict next action via asking a human listen = False while not listen: response = request_prediction(endpoint, sender_id) tracker_dump = response.get("tracker") predictions = response.get("scores") probabilities = [prediction["score"] for prediction in predictions] pred_out = int(np.argmax(probabilities)) latest_action_was_listen = _print_history(tracker_dump) action_name = predictions[pred_out].get("action") colored_name = utils.wrap_with_color(action_name, utils.bcolors.OKBLUE) if latest_action_was_listen: print("The bot wants to [{}] due to the intent. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "3", "0"], "\t1.\tYes\n" + "\t2.\tNo, intent is right but the action is wrong\n" + "\t3.\tThe intent is wrong\n" + "\t0.\tExport current conversations as stories and quit\n") else: print("The bot wants to [{}]. " "Is this correct?\n".format(colored_name)) user_input = utils.request_input( ["1", "2", "0"], "\t1.\tYes.\n" + "\t2.\tNo, the action is wrong.\n" + "\t0.\tExport current conversations as stories and quit\n") if user_input == "1": # max prob prediction was correct response = send_action(endpoint, sender_id, action_name) for response in response.get("messages", []): console.print_bot_output(response) listen = action_name == ACTION_LISTEN_NAME elif user_input == "2": # max prob prediction was false, new action required y = _request_action_from_user(predictions, tracker_dump) new_action_name = predictions[y].get("action") listen = new_action_name == ACTION_LISTEN_NAME response = send_action(endpoint, sender_id, new_action_name) send_finetune(endpoint, response.get("tracker", {}).get("events", [])) for response in response.get("messages", []): console.print_bot_output(response) elif user_input == "3": # intent wrong and maybe action wrong intent = _request_intent_from_user(tracker_dump, intents) evts = tracker_dump.get("events", []) latest_message, corrected_events = revert_latest_message(evts) latest_message.get("parse_data")["intent"] = intent send_events(endpoint, sender_id, corrected_events) send_message(endpoint, sender_id, latest_message.get("text"), latest_message.get("parse_data")) elif user_input == "0": _export_stories(response.get("tracker")) return True else: raise Exception( "Incorrect user input received '{}'".format(user_input)) return False