Exemplo n.º 1
0
def _revert_single_affirmation_events() -> List[Event]:
    return [
        UserUtteranceReverted(),  # revert affirmation and request
        # revert original intent (has to be re-added later)
        UserUtteranceReverted(),
        # add action listen intent
        ActionExecuted(action_name=ACTION_LISTEN_NAME)
    ]
Exemplo n.º 2
0
def _revert_rephrasing_events() -> List[Event]:
    return [UserUtteranceReverted(),  # remove rephrasing
            # remove feedback and rephrase request
            UserUtteranceReverted(),
            # remove affirmation request and false intent
            UserUtteranceReverted(),
            # replace action with action listen
            ActionExecuted(action_name=ACTION_LISTEN_NAME)]
  def run(self, dispatcher, tracker, domain):
      from rasa_core.events import UserUtteranceReverted

      dispatcher.utter_template("utter_default", tracker,
                              silent_fail=True)

      return [UserUtteranceReverted()]        
Exemplo n.º 4
0
    def run(self, dispatcher, tracker, domain):
        from rasa_core.events import UserUtteranceReverted

        if domain.random_template_for("utter_default") is not None:
            dispatcher.utter_template("utter_default")

        return [UserUtteranceReverted()]
Exemplo n.º 5
0
    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))
Exemplo n.º 6
0
def test_json_parse_rewind():
    # DOCS MARKER UserUtteranceReverted
    evt = \
        {
            'event': 'rewind'
        }
    # DOCS END
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Exemplo n.º 7
0
    def run(self, dispatcher, tracker, domain):
        email = next(tracker.get_latest_entity_values('email'), None)

        if not email:
            dispatcher.utter_message(
                "We need your email, please enter a valid one.")
            return [UserUtteranceReverted()]

        return [SlotSet('email', email)]
Exemplo n.º 8
0
    def run(self, dispatcher, tracker, domain):
        email = next(tracker.get_latest_entity_values('email'), None)

        # if no email entity was recognised, prompt the user to enter a valid
        # email and go back a turn in the conversation to ensure future
        # predictions aren't affected
        if not email:
            dispatcher.utter_message(
                "We need your email, please enter a valid one.")
            return [UserUtteranceReverted()]

        return [SlotSet('email', email)]
Exemplo n.º 9
0
    def run(self, dispatcher, tracker, domain):
        from rasa_core.events import UserUtteranceReverted

        query = tracker.latest_message.text
        try:
            dispatcher.utter_message(
                output_text_convert(qq_api(tracker.sender_id, query)))
        except Exception as e:
            logger.exception("Caught a qq exception.")
            dispatcher.utter_template("utter_statements", tracker)
        # return []
        return [UserUtteranceReverted()]
Exemplo n.º 10
0
async def test_default_action(default_dispatcher_collecting, default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    fallback_action = action.ActionDefaultFallback()

    events = await fallback_action.run(default_dispatcher_collecting, tracker,
                                       default_domain)

    channel = default_dispatcher_collecting.output_channel
    assert channel.messages == [{
        u'text': u'sorry, I didn\'t get that, can you rephrase it?',
        u'recipient_id': u'my-sender'
    }]
    assert events == [UserUtteranceReverted()]
Exemplo n.º 11
0
def test_default_action(default_dispatcher_collecting, default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots)

    fallback_action = action.ActionDefaultFallback()

    events = fallback_action.run(default_dispatcher_collecting, tracker,
                                 default_domain)

    channel = default_dispatcher_collecting.output_channel
    assert channel.messages == [{
        u'text': u'default message',
        u'recipient_id': u'my-sender'
    }]
    assert events == [UserUtteranceReverted()]
Exemplo n.º 12
0
def test_revert_user_utterance_event(default_domain):
    tracker = DialogueStateTracker("default", default_domain.slots,
                                   default_domain.topics,
                                   default_domain.default_topic)
    # the retrieved tracker should be empty
    assert len(tracker.events) == 0

    intent1 = {"name": "greet", "confidence": 1.0}
    tracker.update(ActionExecuted(ACTION_LISTEN_NAME))
    tracker.update(UserUttered("/greet", intent1, []))
    tracker.update(ActionExecuted("my_action_1"))
    tracker.update(ActionExecuted(ACTION_LISTEN_NAME))

    intent2 = {"name": "goodbye", "confidence": 1.0}
    tracker.update(UserUttered("/goodbye", intent2, []))
    tracker.update(ActionExecuted("my_action_2"))
    tracker.update(ActionExecuted(ACTION_LISTEN_NAME))

    # Expecting count of 6:
    #   +5 executed actions
    #   +1 final state
    assert tracker.latest_action_name == ACTION_LISTEN_NAME
    assert len(list(tracker.generate_all_prior_states())) == 6

    tracker.update(UserUtteranceReverted())

    # Expecting count of 3:
    #   +5 executed actions
    #   +1 final state
    #   -2 rewound actions associated with the /goodbye
    #   -1 rewound action from the listen right before /goodbye
    assert tracker.latest_action_name == "my_action_1"
    assert len(list(tracker.generate_all_prior_states())) == 3

    dialogue = tracker.as_dialogue()

    recovered = DialogueStateTracker("default", default_domain.slots,
                                     default_domain.topics,
                                     default_domain.default_topic)
    recovered.recreate_from_dialogue(dialogue)

    assert recovered.current_state() == tracker.current_state()
    assert tracker.latest_action_name == "my_action_1"
    assert len(list(tracker.generate_all_prior_states())) == 3
Exemplo n.º 13
0
 def run(self, dispatcher, tracker, domain):
     # only utter the template if it is available
     dispatcher.utter_template("utter_back", tracker,
                               silent_fail=True)
     return [UserUtteranceReverted(), UserUtteranceReverted()]
Exemplo n.º 14
0
    def predict_action_probabilities(self, tracker, domain):
        # type: (DialogueStateTracker, Domain) -> List[float]
        """Predicts a confirmation action if NLU confidence is low
        """

        nlu_data = tracker.latest_message.parse_data

        # if NLU interpreter does not provide confidence score,
        # it is set to 1.0 here in order
        # to not override standard behaviour
        nlu_confidence = nlu_data["intent"].get("confidence", 1.0)
        '''
        print("\033[92m Events\033[0m")
        for idx, event in enumerate(tracker.events):
            print(str(idx) + '. ' + str(event))
        print("\033[92m Applied Events\033[0m")
        for idx, event in enumerate(tracker.applied_events()):
            print(str(idx) + '. ' + str(event))
        print("\033[33mLatest action:{}\033[0m".format(tracker.latest_action_name))
        print("\033[33mLatest intent:{}\033[0m".format(nlu_data["intent"]["name"]))
        '''
        # know what bot just did before 'action_listen'
        action_history = [evt.action_name for evt in tracker.events if isinstance(evt, ActionExecuted)]
        proceeding_action = action_history[-2] if len(action_history) > 2 else 'action_listen'

        if proceeding_action == self.confirmation_action_name:
            # Last action is confirmation question
            if nlu_data["intent"]["name"] == self.affirm_intent_name:
                # TODO: The user affirms the intent in confirmation, thus,
                # predict next action based on previous intent 
                # Revert current `confirm (action) <- affirm (intent)`
                # And retrieve cached message for other policy to predict

                from rasa_core.events import UserUtteranceReverted
                tracker.update(UserUtteranceReverted())
                tracker.update(ActionExecuted('action_listen'))
                tracker.update(self.cache_message)
                tracker.latest_message = self.cache_message
                result = [0.0] * domain.num_actions


            elif nlu_data["intent"]["name"] == self.deny_intent_name:
                # TODO: The user denies the intent in confirmation, thus,
                # predict next action as ask for rephrasing 
                # Revert current `confirm (action) <- deny (intent)`.
                from rasa_core.events import UserUtteranceReverted
                result = [0.0] * domain.num_actions
                idx = domain.index_for_action(self.confirmation_rephrase_name)
                result[idx] = FALLBACK_SCORE
                
            else:
                # TODO: The user gives a rephrase, thus,
                # predict next action based on current intent 
                # Just return all 0 and let prediction policy do.
                result = [0.0] * domain.num_actions

        elif proceeding_action == self.confirmation_rephrase_name:
            # TODO: The user shall give another intent after bot ask for rephrase.
            # So predict based on new intent.
            result = [0.0] * domain.num_actions
            
        elif self.should_confirm(nlu_confidence if nlu_confidence else 1, tracker.latest_action_name):
            logger.debug("NLU confidence {} is lower "
                         "than NLU threshold {}. "
                         "Predicting confirmation action: {}"
                         "".format(nlu_confidence, self.nlu_threshold,
                                   self.confirmation_action_name))
            # we set this to 1.1 to make sure confirmation overrides
            # the memoization policy
            # Meanwhile we need to cache the current message for later prediction,
            # then revert input intent and confirmation action.
            self.cache_message = copy.deepcopy(tracker.latest_message)
            self.cache_message.parse_data['intent']['confidence'] = 1.0
            result = self.confirmation_scores(domain)
        elif tracker.latest_action_name == self.confirmation_action_name:
            result = [0.0] * domain.num_actions
            idx = domain.index_for_action('action_listen')
            result[idx] = FALLBACK_SCORE
        else:
            # NLU confidence threshold is met, as well as not in a confirmation process,
            # so predict all 0, let other policies predict.
            result = [0.0] * domain.num_actions
        '''
        print("\033[92m Events\033[0m")
        for idx, event in enumerate(tracker.events):
            print(str(idx) + '. ' + str(event))
        print("\033[92m Applied Events\033[0m")
        for idx, event in enumerate(tracker.applied_events()):
            print(str(idx) + '. ' + str(event))
        '''
        return result
Exemplo n.º 15
0
    def probabilities_using_best_policy(self, tracker, domain, inputQueue, outputQueue):
            # type: (DialogueStateTracker, Domain) -> List[float]
            # given a state, predict next action via asking a human

            recipient_id = "cliniciansID"

            probabilities = self.base_ensemble.probabilities_using_best_policy(
                    tracker, domain)
            logger.info("second!")
            pred_out = int(np.argmax(probabilities))
            # logger.info("third!")
            latest_action_was_listen = self._print_history(tracker, inputQueue=inputQueue, outputQueue=outputQueue)
            # logger.info("fourth!")
            # sys.stdout.flush()
            logger.info("\n\nAll messages (at the top): \n\n")
            logger.info(tracker.export_stories())

            action_name = domain.action_for_index(pred_out).name()
            if latest_action_was_listen:
                msg = ""
                msg = "The bot wants to [{}] due to the intent. \n ⬇ Is this correct? ⬇\n".format(action_name)
                outputQueue.put(["thintBotAction", msg])
                # logger.info(msg)
                sys.stdout.flush()


                user_input = self.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", inputQueue=inputQueue, outputQueue=outputQueue)
            else:
                msg = "The bot wants to [{}].\n ⬇ Is this correct? ⬇\n".format(action_name)
                # logger.info(msg)
                outputQueue.put(["thintBotAction", msg])
                # logger.info(msg)
                sys.stdout.flush()


                user_input = self.request_input(
                        ["1", "2", "0"],
                        "\t1.\tYes.\n" +
                        "\t2.\tNo, the action is wrong.\n" +
                        "\t0.\tExport current conversations as stories and quit\n", inputQueue=inputQueue, outputQueue=outputQueue)

            if user_input == "1":
                # max prob prediction was correct
                if action_name == ACTION_LISTEN_NAME:

                    msg = "⬆ Type in your next message above ⬆"
                    outputQueue.put(["thintBotAction", msg])
                    outputQueue.put(["thintKeyOptions", "\n"]) ## Hack to clear it

                    # logger.info(msg)
                    sys.stdout.flush()

                return probabilities

            elif user_input == "2":
                # max prob prediction was false, new action required
                # action wrong
                y = self._request_action(probabilities, domain, tracker, inputQueue=inputQueue, outputQueue=outputQueue)

                # 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
                logger.info("\n\nJust entered option 3 \n\n")
                intent = self._request_intent(tracker, domain, inputQueue=inputQueue, outputQueue=outputQueue)
                latest_message = copy.copy(tracker.latest_message)
                latest_message.intent = intent

                tracker.update(UserUtteranceReverted())
                tracker.update(latest_message)
                logger.info("\n\nAll messages (now in 3): \n\n")
                logger.info(tracker.export_stories())

                for e in domain.slots_for_entities(latest_message.entities):
                    tracker.update(e)
                return self.probabilities_using_best_policy(tracker, domain, inputQueue, outputQueue)

            elif user_input == "0":

                # file_prompt = ("File to export to (if file exists, this "
                #                "will append the stories) "
                #                "[{}]: ").format(DEFAULT_FILE_EXPORT_PATH)
                # export_file_path = self.request_input(prompt=file_prompt, inputQueue=inputQueue, outputQueue=outputQueue)

                # if not export_file_path:
                #     export_file_path = DEFAULT_FILE_EXPORT_PATH

                export_file_path = '../data/stories/stories.md'

                self._export_stories(tracker, export_file_path)
                outputQueue.put("SHUTDOWN")
                raise TrainingFinishedException()

            else:
                # logger.info("Righty!")
                raise Exception(
                        "Incorrect user input received '{}'".format(user_input))
Exemplo n.º 16
0
@pytest.mark.parametrize("one_event,another_event", [
    (UserUttered("/greet", {
        "name": "greet",
        "confidence": 1.0
    }, []), UserUttered("/goodbye", {
        "name": "goodbye",
        "confidence": 1.0
    }, [])),
    (SlotSet("my_slot", "value"), SlotSet("my__other_slot", "value")),
    (Restarted(), None),
    (AllSlotsReset(), None),
    (ConversationPaused(), None),
    (ConversationResumed(), None),
    (StoryExported(), None),
    (ActionReverted(), None),
    (UserUtteranceReverted(), None),
    (ActionExecuted("my_action"), ActionExecuted("my_other_action")),
    (FollowupAction("my_action"), FollowupAction("my_other_action")),
    (BotUttered("my_text",
                "my_data"), BotUttered("my_other_test", "my_other_data")),
    (AgentUttered("my_text",
                  "my_data"), AgentUttered("my_other_test", "my_other_data")),
    (ReminderScheduled("my_action", datetime.now()),
     ReminderScheduled("my_other_action", datetime.now())),
])
def test_event_has_proper_implementation(one_event, another_event):
    # equals tests
    assert one_event != another_event, \
        "Same events with different values need to be different"
    assert one_event == copy.deepcopy(one_event), \
        "Event copies need to be the same"
Exemplo n.º 17
0
 def run(self, dispatcher, tracker, domain):
     dispatcher.utter_message("Sorry, didn't get that. Try again.")
     return [UserUtteranceReverted()]
Exemplo n.º 18
0
    def run(self, dispatcher, tracker, domain):
        from rasa_core.events import UserUtteranceReverted

        dispatcher.line_template("line_default", tracker)

        return [UserUtteranceReverted()]
Exemplo n.º 19
0
    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))