Esempio n. 1
0
    def _is_user_input_expected(self, tracker: DialogueStateTracker) -> bool:
        action_requires_input = tracker.latest_action_name in [
            ACTION_DEFAULT_ASK_AFFIRMATION_NAME,
            ACTION_DEFAULT_ASK_REPHRASE_NAME,
            self.fallback_action_name,
        ]
        try:
            last_utterance_time = tracker.get_last_event_for(UserUttered).timestamp
            last_action_time = tracker.get_last_event_for(ActionExecuted).timestamp
            input_given = last_action_time < last_utterance_time
        except AttributeError:
            input_given = False

        return action_requires_input and not input_given
Esempio n. 2
0
    def _has_session_expired(self, tracker: DialogueStateTracker) -> bool:
        """Determine whether the latest session in `tracker` has expired.

        Args:
            tracker: Tracker to inspect.

        Returns:
            `True` if the session in `tracker` has expired, `False` otherwise.
        """

        if not self.domain.session_config.are_sessions_enabled():
            # tracker has never expired if sessions are disabled
            return False

        user_uttered_event: Optional[UserUttered] = tracker.get_last_event_for(
            UserUttered)

        if not user_uttered_event:
            # there is no user event so far so the session should not be considered
            # expired
            return False

        time_delta_in_seconds = time.time() - user_uttered_event.timestamp
        has_expired = (time_delta_in_seconds / 60 >
                       self.domain.session_config.session_expiration_time)
        if has_expired:
            logger.debug(
                f"The latest session for conversation ID '{tracker.sender_id}' has "
                f"expired.")

        return has_expired
Esempio n. 3
0
    def predict_action_probabilities(self, tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the assigned action.

        If the current intent is assigned to an action that action will be
        predicted with the highest probability of all policies. If it is not
        the policy will predict zero for every action."""

        prediction = [0.0] * domain.num_actions
        intent = tracker.latest_message.intent.get("name")
        if intent == USER_INTENT_RESTART:
            action = ACTION_RESTART_NAME
        elif intent == USER_INTENT_BACK:
            action = ACTION_BACK_NAME
        else:
            action = domain.intent_properties.get(intent, {}).get("triggers")

        if tracker.latest_action_name == ACTION_LISTEN_NAME:
            if action:
                idx = domain.index_for_action(action)
                if idx is None:
                    warnings.warn(
                        "MappingPolicy tried to predict unknown "
                        f"action '{action}'. Make sure all mapped actions are "
                        "listed in the domain.")
                else:
                    prediction[idx] = 1

            if any(prediction):
                logger.debug("The predicted intent '{}' is mapped to "
                             " action '{}' in the domain."
                             "".format(intent, action))
        elif tracker.latest_action_name == action and action is not None:
            latest_action = tracker.get_last_event_for(ActionExecuted)
            assert latest_action.action_name == action
            if latest_action.policy and latest_action.policy.endswith(
                    type(self).__name__):
                # this ensures that we only predict listen, if we predicted
                # the mapped action
                logger.debug(
                    "The mapped action, '{}', for this intent, '{}', was "
                    "executed last so MappingPolicy is returning to "
                    "action_listen.".format(action, intent))

                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                prediction[idx] = 1
            else:
                logger.debug(
                    "The mapped action, '{}', for this intent, '{}', was "
                    "executed last, but it was predicted by another policy, '{}', so MappingPolicy is not"
                    "predicting any action.".format(action, intent,
                                                    latest_action.policy))
        elif action == ACTION_RESTART_NAME:
            idx = domain.index_for_action(ACTION_RESTART_NAME)
            prediction[idx] = 1
            logger.debug("Restarting the conversation with action_restart.")
        else:
            logger.debug("There is no mapped action for the predicted intent, "
                         "'{}'.".format(intent))
        return prediction
Esempio n. 4
0
    def predict_action_probabilities(self, tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the assigned action.

        If the current intent is assigned to an action that action will be
        predicted with the highest probability of all policies. If it is not
        the policy will predict zero for every action."""

        prediction = [0.0] * domain.num_actions
        intent = tracker.latest_message.intent.get('name')
        action = domain.intent_properties.get(intent, {}).get('triggers')
        if tracker.latest_action_name == ACTION_LISTEN_NAME:
            if action:
                idx = domain.index_for_action(action)
                if idx is None:
                    logger.warning("MappingPolicy tried to predict unkown "
                                   "action '{}'.".format(action))
                else:
                    prediction[idx] = 1
            elif intent == USER_INTENT_RESTART:
                idx = domain.index_for_action(ACTION_RESTART_NAME)
                prediction[idx] = 1
            elif intent == USER_INTENT_BACK:
                idx = domain.index_for_action(ACTION_BACK_NAME)
                prediction[idx] = 1
        elif tracker.latest_action_name == action and action is not None:
            latest_action = tracker.get_last_event_for(ActionExecuted)
            assert latest_action.action_name == action

            if latest_action.policy == type(self).__name__:
                # this ensures that we only predict listen, if we predicted
                # the mapped action
                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                prediction[idx] = 1
        return prediction
def _get_previous_action_name(tracker: DialogueStateTracker) -> Optional[str]:
    previous_action_event = tracker.get_last_event_for(
        ActionExecuted, action_names_to_exclude=[ACTION_LISTEN_NAME]
    )

    return (
        previous_action_event.action_name if previous_action_event is not None else None
    )
Esempio n. 6
0
def _last_n_intent_names(tracker: DialogueStateTracker,
                         number_of_last_intent_names: int) -> List[Text]:
    intent_names = []
    for i in range(number_of_last_intent_names):
        message = tracker.get_last_event_for(
            UserUttered, skip=i, event_verbosity=EventVerbosity.AFTER_RESTART)
        if isinstance(message, UserUttered):
            intent_names.append(message.intent.get("name"))

    return intent_names
Esempio n. 7
0
    def predict_action_probabilities(
        self, tracker: DialogueStateTracker, domain: Domain
    ) -> List[float]:
        logger.debug("Triggers: " + ", ".join(self.triggers.keys()))
        """Predicts the assigned action.

        If the current intent is assigned to an action that action will be
        predicted with the highest probability of all policies. If it is not
        the policy will predict zero for every action."""

        prediction = [0.0] * domain.num_actions
        intent = tracker.latest_message.intent.get("name")
        action = None
        if isinstance(intent, str):
            for trigger in self.triggers:
                match = re.search(trigger, intent)
                if match:
                    action = self.triggers[trigger]
        if tracker.latest_action_name == ACTION_LISTEN_NAME:
            if action:
                idx = domain.index_for_action(action)
                if idx is None:
                    logger.warning("{} is not defined.".format(action))
                else:
                    prediction[idx] = 1
            elif intent == USER_INTENT_RESTART:
                idx = domain.index_for_action(ACTION_RESTART_NAME)
                prediction[idx] = 1
            elif intent == USER_INTENT_BACK:
                idx = domain.index_for_action(ACTION_BACK_NAME)
                prediction[idx] = 1

            if any(prediction):
                logger.debug(
                    "The predicted intent '{}' is being "
                    " handled by BotfrontMappingPolicy."
                    "".format(intent)
                )
        elif tracker.latest_action_name == action and action is not None:
            latest_action = tracker.get_last_event_for(ActionExecuted)
            assert latest_action.action_name == action

            if type(self).__name__ in latest_action.policy:
                # this ensures that we only predict listen, if we predicted
                # the mapped action
                logger.debug(
                    "BotfrontMappingPolicy has just been triggered, "
                    "so now returning to action_listen. "
                )

                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                prediction[idx] = 1
        return prediction
Esempio n. 8
0
    def predict_action_probabilities(self, tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the assigned action.

        If the current intent is assigned to an action that action will be
        predicted with the highest probability of all policies. If it is not
        the policy will predict zero for every action."""

        prediction = [0.0] * domain.num_actions
        active_component = tracker.slots.get("active_component").value
        # if active_component:
        #     idx = domain.index_for_action(active_component)
        #     prediction[idx] = 1
        if tracker.latest_action_name == ACTION_LISTEN_NAME:
            if active_component:
                idx = domain.index_for_action(active_component)
                if idx is None:
                    warnings.warn(
                        "MappingPolicy tried to predict unknown "
                        f"action '{active_component}'. Make sure all mapped actions are "
                        "listed in the domain.")
                else:
                    prediction[idx] = 1

            if any(prediction):
                logger.debug("Continue component exec"
                             " '{}' in the domain."
                             "".format(active_component))
        elif tracker.latest_action_name == active_component and active_component is not None:
            latest_action = tracker.get_last_event_for(ActionExecuted)
            assert latest_action.action_name == active_component
            if latest_action.policy and latest_action.policy.endswith(
                    type(self).__name__):
                # this ensures that we only predict listen, if we predicted
                # the mapped action
                logger.debug(
                    "The mapped action, '{}', for this intent, '{}', was "
                    "executed last so MappingPolicy is returning to "
                    "action_listen.".format(active_component, ""))

                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                prediction[idx] = 1
            else:
                logger.debug(
                    "The mapped action, '{}', for this intent, '{}', was "
                    "executed last, but it was predicted by another policy, '{}', so MappingPolicy is not"
                    "predicting any action.".format(active_component, "",
                                                    latest_action.policy))
        else:
            logger.debug("There is no mapped action for the predicted intent, "
                         "'{}'.".format(""))
        return prediction
Esempio n. 9
0
    def predict_action_probabilities(
        self,
        tracker: DialogueStateTracker,
        domain: Domain,
        interpreter: NaturalLanguageInterpreter,
        **kwargs: Any,
    ) -> List[float]:
        """Predicts the assigned action.

        If the current intent is assigned to an action that action will be
        predicted with the highest probability of all policies. If it is not
        the policy will predict zero for every action."""

        result = self._default_predictions(domain)

        intent = tracker.latest_message.intent.get(INTENT_NAME_KEY)
        if intent == USER_INTENT_RESTART:
            action = ACTION_RESTART_NAME
        elif intent == USER_INTENT_BACK:
            action = ACTION_BACK_NAME
        elif intent == USER_INTENT_SESSION_START:
            action = ACTION_SESSION_START_NAME
        else:
            action = domain.intent_properties.get(intent, {}).get("triggers")

        if tracker.latest_action_name == ACTION_LISTEN_NAME:
            # predict mapped action
            if action:
                idx = domain.index_for_action(action)
                if idx is None:
                    rasa.shared.utils.io.raise_warning(
                        f"MappingPolicy tried to predict unknown "
                        f"action '{action}'. Make sure all mapped actions are "
                        f"listed in the domain.",
                        docs=DOCS_URL_POLICIES + "#mapping-policy",
                    )
                else:
                    result[idx] = 1

            if any(result):
                logger.debug("The predicted intent '{}' is mapped to "
                             " action '{}' in the domain."
                             "".format(intent, action))
        elif tracker.latest_action_name == action and action is not None:
            # predict next action_listen after mapped action
            latest_action = tracker.get_last_event_for(ActionExecuted)
            assert latest_action.action_name == action
            if latest_action.policy and latest_action.policy.endswith(
                    type(self).__name__):
                # this ensures that we only predict listen,
                # if we predicted the mapped action
                logger.debug(
                    "The mapped action, '{}', for this intent, '{}', was "
                    "executed last so MappingPolicy is returning to "
                    "action_listen.".format(action, intent))

                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                result[idx] = 1
            else:
                logger.debug(
                    "The mapped action, '{}', for the intent, '{}', was "
                    "executed last, but it was predicted by another policy, '{}', "
                    "so MappingPolicy is not predicting any action.".format(
                        action, intent, latest_action.policy))
        elif action == ACTION_RESTART_NAME:
            logger.debug("Restarting the conversation with action_restart.")
            idx = domain.index_for_action(ACTION_RESTART_NAME)
            result[idx] = 1
        else:
            logger.debug("There is no mapped action for the predicted intent, "
                         "'{}'.".format(intent))
        return result