Exemplo n.º 1
0
    def __init__(
            self,
            domain: Union[Text, Domain] = None,
            policies: Union[PolicyEnsemble, List[Policy], None] = None,
            interpreter: Optional[NaturalLanguageInterpreter] = None,
            generator: Union[EndpointConfig, 'NLG', None] = None,
            tracker_store: Optional['TrackerStore'] = None,
            action_endpoint: Optional[EndpointConfig] = None,
            fingerprint: Optional[Text] = None
    ):
        # Initializing variables with the passed parameters.
        self.domain = self._create_domain(domain)
        if self.domain:
            self.domain.add_requested_slot()
        self.policy_ensemble = self._create_ensemble(policies)
        if not self._is_form_policy_present():
            raise InvalidDomain(
                "You have defined a form action, but haven't added the "
                "FormPolicy to your policy ensemble."
            )

        self.interpreter = NaturalLanguageInterpreter.create(interpreter)

        self.nlg = NaturalLanguageGenerator.create(generator, self.domain)
        self.tracker_store = self.create_tracker_store(
            tracker_store, self.domain)
        self.action_endpoint = action_endpoint
        self.conversations_in_processing = {}

        self._set_fingerprint(fingerprint)
Exemplo n.º 2
0
    def predict_action_probabilities(self, tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the next action if NLU confidence is low.
        """

        if self.deny_suggestion_intent_name not in domain.intents:
            raise InvalidDomain('The intent {} must be present in the '
                                'domain file to use the '
                                '`TwoStageFallbackPolicy`.'
                                ''.format(self.deny_suggestion_intent_name))

        nlu_data = tracker.latest_message.parse_data
        nlu_confidence = nlu_data["intent"].get("confidence", 1.0)
        last_intent_name = nlu_data['intent'].get('name', None)
        should_nlu_fallback = self.should_nlu_fallback(
            nlu_confidence, tracker.latest_action_name)
        user_rephrased = has_user_rephrased(tracker)

        if self._is_user_input_expected(tracker):
            result = confidence_scores_for(ACTION_LISTEN_NAME, 1.0, domain)
        elif self._has_user_denied(last_intent_name, tracker):
            logger.debug("User '{}' denied suggested intents.".format(
                tracker.sender_id))
            result = self._results_for_user_denied(tracker, domain)
        elif user_rephrased and should_nlu_fallback:
            logger.debug("Ambiguous rephrasing of user '{}' "
                         "for intent '{}'".format(tracker.sender_id,
                                                  last_intent_name))
            result = confidence_scores_for(ACTION_DEFAULT_ASK_AFFIRMATION_NAME,
                                           1.0, domain)
        elif user_rephrased:
            logger.debug("User '{}' rephrased intent".format(
                tracker.sender_id))
            result = confidence_scores_for(ACTION_REVERT_FALLBACK_EVENTS_NAME,
                                           1.0, domain)
        elif tracker.last_executed_action_has(
                ACTION_DEFAULT_ASK_AFFIRMATION_NAME):
            if not should_nlu_fallback:
                logger.debug("User '{}' affirmed intent '{}'"
                             "".format(tracker.sender_id, last_intent_name))
                result = confidence_scores_for(
                    ACTION_REVERT_FALLBACK_EVENTS_NAME, 1.0, domain)
            else:
                result = confidence_scores_for(self.fallback_nlu_action_name,
                                               1.0, domain)
        elif should_nlu_fallback:
            logger.debug("User '{}' has to affirm intent '{}'.".format(
                tracker.sender_id, last_intent_name))
            result = confidence_scores_for(ACTION_DEFAULT_ASK_AFFIRMATION_NAME,
                                           1.0, domain)
        else:
            logger.debug("NLU confidence threshold met, confidence of "
                         "fallback action set to core threshold ({}).".format(
                             self.core_threshold))
            result = self.fallback_scores(domain, self.core_threshold)

        return result
Exemplo n.º 3
0
    def validate_against_domain(cls, ensemble: Optional["PolicyEnsemble"],
                                domain: Optional[Domain]) -> None:
        if not domain:
            return

        has_form_policy = ensemble is not None and any(
            isinstance(p, cls) for p in ensemble.policies)
        if domain.form_names and not has_form_policy:
            raise InvalidDomain(
                "You have defined a form action, but haven't added the "
                "FormPolicy to your policy ensemble. Either remove all "
                "forms from your domain or exclude the FormPolicy from your "
                "policy configuration.")
Exemplo n.º 4
0
    def validate_against_domain(cls, ensemble: Optional["PolicyEnsemble"],
                                domain: Optional[Domain]) -> None:
        if ensemble is None:
            return

        for p in ensemble.policies:
            if isinstance(p, cls):
                fallback_intent = getattr(p, "deny_suggestion_intent_name")
                if domain is None or fallback_intent not in domain.intents:
                    raise InvalidDomain(
                        "The intent '{0}' must be present in the "
                        "domain file to use TwoStageFallbackPolicy. "
                        "Either include the intent '{0}' in your domain "
                        "or exclude the TwoStageFallbackPolicy from your "
                        "policy configuration".format(fallback_intent))
Exemplo n.º 5
0
    def validate_against_domain(cls, ensemble: Optional["PolicyEnsemble"],
                                domain: Optional[Domain]) -> None:
        if ensemble is None:
            return

        rule_policy = next(
            (p for p in ensemble.policies if isinstance(p, RulePolicy)), None)
        if not rule_policy or not rule_policy._enable_fallback_prediction:
            return

        if (domain is None or rule_policy._fallback_action_name
                not in domain.action_names):
            raise InvalidDomain(
                f"The fallback action '{rule_policy._fallback_action_name}' which was "
                f"configured for the {RulePolicy.__name__} must be present in the "
                f"domain.")
Exemplo n.º 6
0
    def validate_against_domain(cls, ensemble: Optional["PolicyEnsemble"],
                                domain: Optional[Domain]) -> None:
        if not domain:
            return

        has_mapping_policy = ensemble is not None and any(
            isinstance(p, cls) for p in ensemble.policies)
        has_triggers_in_domain = any([
            "triggers" in properties
            for intent, properties in domain.intent_properties.items()
        ])
        if has_triggers_in_domain and not has_mapping_policy:
            raise InvalidDomain(
                "You have defined triggers in your domain, but haven't "
                "added the MappingPolicy to your policy ensemble. "
                "Either remove the triggers from your domain or "
                "exclude the MappingPolicy from your policy configuration.")
Exemplo n.º 7
0
def _check_policy_for_forms_available(
        domain: Domain, ensemble: Optional["PolicyEnsemble"]) -> None:
    if not ensemble:
        return

    from rasa.core.policies.form_policy import FormPolicy

    suited_policies_for_forms = (FormPolicy, RulePolicy)

    has_policy_for_forms = ensemble is not None and any(
        isinstance(policy, suited_policies_for_forms)
        for policy in ensemble.policies)

    if domain.form_names and not has_policy_for_forms:
        raise InvalidDomain(
            "You have defined a form action, but haven't added the "
            "FormPolicy to your policy ensemble. Either remove all "
            "forms from your domain or exclude the FormPolicy from your "
            "policy configuration.")
Exemplo n.º 8
0
async def test_pull_model_with_invalid_domain(
    model_server: TestClient, monkeypatch: MonkeyPatch, caplog: LogCaptureFixture
):
    # mock `Domain.load()` as if the domain contains invalid YAML
    error_message = "domain is invalid"
    mock_load = Mock(side_effect=InvalidDomain(error_message))

    monkeypatch.setattr(Domain, "load", mock_load)
    model_endpoint_config = EndpointConfig.from_dict(
        {"url": model_server.make_url("/model"), "wait_time_between_pulls": None}
    )

    agent = Agent()
    await rasa.core.agent.load_from_server(agent, model_server=model_endpoint_config)

    # `Domain.load()` was called
    mock_load.assert_called_once()

    # error was logged
    assert error_message in caplog.text