def _create_from_endpoint_config( endpoint_config: Optional[EndpointConfig] = None, domain: Optional[Domain] = None ) -> "NaturalLanguageGenerator": """Given an endpoint configuration, create a proper NLG object.""" domain = domain or Domain.empty() if endpoint_config is None: from rasa.core.nlg import TemplatedNaturalLanguageGenerator # this is the default type if no endpoint config is set nlg = TemplatedNaturalLanguageGenerator(domain.responses) elif endpoint_config.type is None or endpoint_config.type.lower() == "callback": from rasa.core.nlg import CallbackNaturalLanguageGenerator # this is the default type if no nlg type is set nlg = CallbackNaturalLanguageGenerator(endpoint_config=endpoint_config) elif endpoint_config.type.lower() == "response": from rasa.core.nlg import TemplatedNaturalLanguageGenerator nlg = TemplatedNaturalLanguageGenerator(domain.responses) elif endpoint_config.type.lower() == "template": rasa.shared.utils.io.raise_deprecation_warning( "Please change the NLG endpoint config type from `template` to `response`.", docs=f"{DOCS_URL_MIGRATION_GUIDE}#rasa-23-to-rasa-24", ) from rasa.core.nlg import TemplatedNaturalLanguageGenerator nlg = TemplatedNaturalLanguageGenerator(domain.responses) else: nlg = _load_from_module_name_in_endpoint_config(endpoint_config, domain) logger.debug(f"Instantiated NLG to '{nlg.__class__.__name__}'.") return nlg
def _create_from_endpoint_config( endpoint_config: Optional[EndpointConfig] = None, domain: Optional[Domain] = None) -> "NaturalLanguageGenerator": """Given an endpoint configuration, create a proper NLG object.""" domain = domain or Domain.empty() if endpoint_config is None: from rasa.core.nlg import ( # pytype: disable=pyi-error TemplatedNaturalLanguageGenerator, ) # this is the default type if no endpoint config is set nlg = TemplatedNaturalLanguageGenerator(domain.templates) elif endpoint_config.type is None or endpoint_config.type.lower( ) == "callback": from rasa.core.nlg import ( # pytype: disable=pyi-error CallbackNaturalLanguageGenerator, ) # this is the default type if no nlg type is set nlg = CallbackNaturalLanguageGenerator(endpoint_config=endpoint_config) elif endpoint_config.type.lower() == "template": from rasa.core.nlg import ( # pytype: disable=pyi-error TemplatedNaturalLanguageGenerator, ) nlg = TemplatedNaturalLanguageGenerator(domain.templates) else: nlg = _load_from_module_name_in_endpoint_config( endpoint_config, domain) logger.debug(f"Instantiated NLG to '{nlg.__class__.__name__}'.") return nlg
def create( obj: Union["NaturalLanguageGenerator", EndpointConfig, None], domain: Optional[Domain], ) -> "NaturalLanguageGenerator": """Factory to create a generator.""" custom_nlg = None if isinstance(obj, EndpointConfig) and obj.type: custom_nlg = NaturalLanguageGenerator.load_nlg_from_module_string( obj) if isinstance(obj, NaturalLanguageGenerator): return obj elif custom_nlg: return custom_nlg(domain=domain, endpoint_config=obj) elif isinstance(obj, EndpointConfig) and obj.url: from rasa.core.nlg import ( # pytype: disable=pyi-error CallbackNaturalLanguageGenerator, ) return CallbackNaturalLanguageGenerator(obj) elif obj is None: from rasa.core.nlg import ( # pytype: disable=pyi-error TemplatedNaturalLanguageGenerator, ) templates = domain.templates if domain else [] return TemplatedNaturalLanguageGenerator(templates) else: raise Exception("Cannot create a NaturalLanguageGenerator " "based on the passed object. Type: `{}`" "".format(type(obj)))
def test_predict_next_action_raises_limit_reached_exception(domain: Domain): interpreter = RegexInterpreter() ensemble = SimplePolicyEnsemble( policies=[RulePolicy(), MemoizationPolicy()]) tracker_store = InMemoryTrackerStore(domain) lock_store = InMemoryLockStore() processor = MessageProcessor( interpreter, ensemble, domain, tracker_store, lock_store, TemplatedNaturalLanguageGenerator(domain.responses), max_number_of_predictions=1, ) tracker = DialogueStateTracker.from_events( "test", evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("Hi!"), ActionExecuted("test_action"), ], ) tracker.set_latest_action({"action_name": "test_action"}) with pytest.raises(ActionLimitReached): processor.predict_next_action(tracker)
async def test_1st_affirmation_is_successful(): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User affirms UserUttered("hi", {"name": "greet", "confidence": 1.0}), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) for events in events: tracker.update(events, domain) applied_events = tracker.applied_events() assert applied_events == [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("hi", {"name": "greet", "confidence": 1.0}), ]
async def test_activate_with_prefilled_slot(): slot_name = "num_people" slot_value = 5 tracker = DialogueStateTracker.from_events( sender_id="bla", evts=[SlotSet(slot_name, slot_value)]) form_name = "my form" action = FormAction(form_name, None) next_slot_to_request = "next slot to request" domain = f""" forms: {form_name}: {slot_name}: - type: from_entity entity: {slot_name} {next_slot_to_request}: - type: from_text slots: {slot_name}: type: unfeaturized """ domain = Domain.from_yaml(domain) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == [ ActiveLoop(form_name), SlotSet(slot_name, slot_value), SlotSet(REQUESTED_SLOT, next_slot_to_request), ]
async def test_ask_affirm_after_rephrasing(): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), # Action asks user to rephrase ActionExecuted(ACTION_TWO_STAGE_FALLBACK_NAME), BotUttered("please rephrase"), # User rephrased with low confidence *_message_requiring_fallback(), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), tracker, domain, ) assert len(events) == 1 assert isinstance(events[0], BotUttered)
def create( obj: Union["NaturalLanguageGenerator", EndpointConfig, None], domain: Optional[Domain], ) -> "NaturalLanguageGenerator": """Factory to create a generator.""" if isinstance(obj, NaturalLanguageGenerator): return obj elif isinstance(obj, EndpointConfig): from rasa.core.nlg import ( # pytype: disable=pyi-error CallbackNaturalLanguageGenerator, ) return CallbackNaturalLanguageGenerator(obj) elif obj is None: from rasa.core.nlg import ( # pytype: disable=pyi-error TemplatedNaturalLanguageGenerator, ) templates = domain.templates if domain else [] return TemplatedNaturalLanguageGenerator(templates) else: raise Exception( "Cannot create a NaturalLanguageGenerator " "based on the passed object. Type: `{}`" "".format(type(obj)) )
async def test_action_rejection(): form_name = "my form" slot_to_fill = "some slot" tracker = DialogueStateTracker.from_events( sender_id="bla", evts=[ ActiveLoop(form_name), SlotSet(REQUESTED_SLOT, slot_to_fill), ActionExecuted(ACTION_LISTEN_NAME), UserUttered("haha", {"name": "greet"}), ], ) form_name = "my form" action = FormAction(form_name, None) domain = f""" forms: {form_name}: {slot_to_fill}: - type: from_entity entity: some_entity slots: {slot_to_fill}: type: unfeaturized """ domain = Domain.from_yaml(domain) with pytest.raises(ActionExecutionRejection): await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, )
async def test_activate(): tracker = DialogueStateTracker.from_events(sender_id="bla", evts=[]) form_name = "my form" action = FormAction(form_name, None) slot_name = "num_people" domain = f""" forms: {form_name}: {slot_name}: - type: from_entity entity: number responses: utter_ask_num_people: - text: "How many people?" """ domain = Domain.from_yaml(domain) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events[:-1] == [ ActiveLoop(form_name), SlotSet(REQUESTED_SLOT, slot_name) ] assert isinstance(events[-1], BotUttered)
async def test_set_slot_and_deactivate(): form_name = "my form" slot_name = "num_people" slot_value = "dasdasdfasdf" events = [ Form(form_name), SlotSet(REQUESTED_SLOT, slot_name), ActionExecuted(ACTION_LISTEN_NAME), UserUttered(slot_value), ] tracker = DialogueStateTracker.from_events(sender_id="bla", evts=events) domain = f""" forms: - {form_name}: {slot_name}: - type: from_text slots: {slot_name}: type: unfeaturized """ domain = Domain.from_yaml(domain) action = FormAction(form_name, None) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == [ SlotSet(slot_name, slot_value), SlotSet(REQUESTED_SLOT, None), Form(None), ]
async def test_2nd_affirmation_failed(intent_which_lets_action_give_up: Text): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), # Action asks user to rephrase *_two_stage_clarification_request(), # User rephrased with low confidence *_message_requiring_fallback(), # Actions asks user to affirm for the last time *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents for the second time UserUttered("hi", {"name": intent_which_lets_action_give_up}), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), tracker, domain, ) assert events == [ActiveLoop(None), UserUtteranceReverted()]
async def test_action_unlikely_intent_metadata( default_processor: MessageProcessor): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ ActionExecuted(ACTION_LISTEN_NAME), ], ) domain = Domain.empty() metadata = {"key1": 1, "key2": "2"} await default_processor._run_action( ActionUnlikelyIntent(), tracker, CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), PolicyPrediction([], "some policy", action_metadata=metadata), ) applied_events = tracker.applied_events() assert applied_events == [ ActionExecuted(ACTION_LISTEN_NAME), ActionExecuted(ACTION_UNLIKELY_INTENT_NAME, metadata=metadata), ] assert applied_events[1].metadata == metadata
async def test_loop_without_activate_and_without_deactivate(): expected_do_events = [ActionExecuted("do")] form_name = "my form" class MyLoop(LoopAction): def name(self) -> Text: return form_name async def activate(self, *args: Any) -> List[Event]: raise ValueError("this shouldn't be called") async def do(self, *args: Any) -> List[Event]: return expected_do_events async def deactivate(self, *args) -> List[Event]: return [SlotSet("deactivated")] async def is_activated(self, *args: Any) -> bool: return True async def is_done(self, *args) -> bool: return False tracker = DialogueStateTracker.from_events("some sender", []) domain = Domain.empty() action = MyLoop() actual = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), tracker, domain, ) assert actual == [*expected_do_events]
async def test_validate_slots_on_activation_with_other_action_after_user_utterance( ): form_name = "my form" slot_name = "num_people" slot_value = "hi" events = [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered(slot_value, entities=[{ "entity": "num_tables", "value": 5 }]), ActionExecuted("action_in_between"), ] tracker = DialogueStateTracker.from_events(sender_id="bla", evts=events) domain = f""" slots: {slot_name}: type: unfeaturized forms: {form_name}: {slot_name}: - type: from_text actions: - validate_{form_name} """ domain = Domain.from_yaml(domain) action_server_url = "http:/my-action-server:5055/webhook" expected_slot_value = "✅" with aioresponses() as mocked: mocked.post( action_server_url, payload={ "events": [{ "event": "slot", "name": slot_name, "value": expected_slot_value }] }, ) action_server = EndpointConfig(action_server_url) action = FormAction(form_name, action_server) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == [ ActiveLoop(form_name), SlotSet(slot_name, expected_slot_value), SlotSet(REQUESTED_SLOT, None), ActiveLoop(None), ]
async def default_processor(default_agent: Agent) -> MessageProcessor: tracker_store = InMemoryTrackerStore(default_agent.domain) return MessageProcessor( default_agent.interpreter, default_agent.policy_ensemble, default_agent.domain, tracker_store, TemplatedNaturalLanguageGenerator(default_agent.domain.templates), )
async def test_2nd_affirm_successful(default_processor: MessageProcessor): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("my name is John", { "name": "say_name", "confidence": 1.0 }), SlotSet("some_slot", "example_value"), # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), # Action asks user to rephrase *_two_stage_clarification_request(), # User rephrased with low confidence *_message_requiring_fallback(), *_two_stage_clarification_request(), # Actions asks user to affirm for the last time ActionExecuted(ACTION_LISTEN_NAME), # User affirms successfully UserUttered("hi", {"name": "greet"}), ], ) domain = Domain.empty() action = TwoStageFallbackAction() await default_processor._run_action( action, tracker, CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), PolicyPrediction([], "some policy"), ) applied_events = tracker.applied_events() assert applied_events == [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("my name is John", { "name": "say_name", "confidence": 1.0 }), SlotSet("some_slot", "example_value"), ActionExecuted(ACTION_LISTEN_NAME), UserUttered("hi", {"name": "greet"}), ]
async def test_dispatcher_template_invalid_vars(): templates = { "my_made_up_template": [ {"text": "a template referencing an invalid {variable}."} ] } bot = CollectingOutputChannel() nlg = TemplatedNaturalLanguageGenerator(templates) dispatcher = Dispatcher("my-sender", bot, nlg) tracker = DialogueStateTracker("my-sender", slots=[]) await dispatcher.utter_template("my_made_up_template", tracker) collected = dispatcher.output_channel.latest_output() assert collected["text"].startswith("a template referencing an invalid {variable}.")
async def test_dispatcher_utter_buttons_from_domain_templ(default_tracker): domain_file = "examples/moodbot/domain.yml" domain = Domain.load(domain_file) bot = CollectingOutputChannel() nlg = TemplatedNaturalLanguageGenerator(domain.templates) dispatcher = Dispatcher("my-sender", bot, nlg) await dispatcher.utter_template("utter_greet", default_tracker) assert len(bot.messages) == 1 assert bot.messages[0]["text"] == "Hey! How are you?" assert bot.messages[0]["buttons"] == [ {"payload": "great", "title": "great"}, {"payload": "super sad", "title": "super sad"}, ]
async def test_validate_slots(validate_return_events: List[Dict], expected_events: List[Event]): form_name = "my form" slot_name = "num_people" slot_value = "hi" events = [ ActiveLoop(form_name), SlotSet(REQUESTED_SLOT, slot_name), ActionExecuted(ACTION_LISTEN_NAME), UserUttered(slot_value, entities=[{ "entity": "num_tables", "value": 5 }]), ] tracker = DialogueStateTracker.from_events(sender_id="bla", evts=events) domain = f""" slots: {slot_name}: type: any num_tables: type: any forms: {form_name}: {slot_name}: - type: from_text num_tables: - type: from_entity entity: num_tables actions: - validate_{form_name} """ domain = Domain.from_yaml(domain) action_server_url = "http:/my-action-server:5055/webhook" with aioresponses() as mocked: mocked.post(action_server_url, payload={"events": validate_return_events}) action_server = EndpointConfig(action_server_url) action = FormAction(form_name, action_server) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == expected_events
async def test_ask_affirmation(events: List[Event]): tracker = DialogueStateTracker.from_events("some-sender", evts=events) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), tracker, domain, ) assert len(events) == 2 assert events[0] == ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME) assert isinstance(events[1], BotUttered)
async def test_activate_and_immediate_deactivate(): slot_name = "num_people" slot_value = 5 tracker = DialogueStateTracker.from_events( sender_id="bla", evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered( "haha", {"name": "greet"}, entities=[{ "entity": slot_name, "value": slot_value }], ), ], ) form_name = "my form" action = FormAction(form_name, None) domain = f""" forms: {form_name}: {slot_name}: - type: from_entity entity: {slot_name} slots: {slot_name}: type: unfeaturized """ domain = Domain.from_yaml(domain) events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert events == [ ActiveLoop(form_name), SlotSet(slot_name, slot_value), SlotSet(REQUESTED_SLOT, None), ActiveLoop(None), ]
async def test_2nd_affirm_successful(): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), # Action asks user to rephrase *_two_stage_clarification_request(), # User rephrased with low confidence *_message_requiring_fallback(), *_two_stage_clarification_request(), # Actions asks user to affirm for the last time ActionExecuted(ACTION_LISTEN_NAME), # User affirms successfully UserUttered("hi", {"name": "greet"}), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) for event in events: tracker.update(event) applied_events = tracker.applied_events() assert applied_events == [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("hi", {"name": "greet"}), ]
async def test_no_slots_extracted_with_custom_slot_mappings( custom_events: List[Event]): form_name = "my form" events = [ ActiveLoop(form_name), SlotSet(REQUESTED_SLOT, "num_tables"), ActionExecuted(ACTION_LISTEN_NAME), UserUttered("off topic"), ] tracker = DialogueStateTracker.from_events(sender_id="bla", evts=events) domain = f""" slots: num_tables: type: any forms: {form_name}: num_tables: - type: from_entity entity: num_tables actions: - validate_{form_name} """ domain = Domain.from_yaml(domain) action_server_url = "http:/my-action-server:5055/webhook" with aioresponses() as mocked: mocked.post(action_server_url, payload={"events": custom_events}) action_server = EndpointConfig(action_server_url) action = FormAction(form_name, action_server) with pytest.raises(ActionExecutionRejection): await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, )
async def test_processor_logs_text_tokens_in_tracker(mood_agent: Agent): text = "Hello there" tokenizer = WhitespaceTokenizer() tokens = tokenizer.tokenize(Message(data={"text": text}), "text") indices = [(t.start, t.end) for t in tokens] message = UserMessage(text) tracker_store = InMemoryTrackerStore(mood_agent.domain) lock_store = InMemoryLockStore() processor = MessageProcessor( mood_agent.interpreter, mood_agent.policy_ensemble, mood_agent.domain, tracker_store, lock_store, TemplatedNaturalLanguageGenerator(mood_agent.domain.responses), ) tracker = await processor.log_message(message) event = tracker.get_last_event_for(event_type=UserUttered) event_tokens = event.as_dict().get("parse_data").get("text_tokens") assert event_tokens == indices
async def test_ask_rephrase_after_failed_affirmation(): rephrase_text = "please rephrase" tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), Form(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), ActionExecuted(ACTION_LISTEN_NAME), # User denies suggested intents UserUttered("hi", {"name": USER_INTENT_OUT_OF_SCOPE}), ], ) domain = Domain.from_yaml( f""" responses: utter_ask_rephrase: - {rephrase_text} """ ) action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) assert len(events) == 1 assert isinstance(events[0], BotUttered) bot_utterance = events[0] assert isinstance(bot_utterance, BotUttered) assert bot_utterance.text == rephrase_text
async def test_give_it_up_after_low_confidence_after_affirm_request(): tracker = DialogueStateTracker.from_events( "some-sender", evts=[ # User sends message with low NLU confidence *_message_requiring_fallback(), ActiveLoop(ACTION_TWO_STAGE_FALLBACK_NAME), # Action asks user to affirm *_two_stage_clarification_request(), # User's affirms with low NLU confidence again *_message_requiring_fallback(), ], ) domain = Domain.empty() action = TwoStageFallbackAction() events = await action.run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.responses), tracker, domain, ) assert events == [ActiveLoop(None), UserUtteranceReverted()]
async def test_one_stage_fallback_rule(): domain = Domain.from_yaml(f""" intents: - {GREET_INTENT_NAME} - {DEFAULT_NLU_FALLBACK_INTENT_NAME} actions: - {UTTER_GREET_ACTION} """) fallback_recover_rule = TrackerWithCachedStates.from_events( "bla", domain=domain, slots=domain.slots, evts=[ ActionExecuted(RULE_SNIPPET_ACTION_NAME), ActionExecuted(ACTION_LISTEN_NAME), UserUttered(intent={"name": DEFAULT_NLU_FALLBACK_INTENT_NAME}), ActionExecuted(ACTION_DEFAULT_FALLBACK_NAME), ActionExecuted(ACTION_LISTEN_NAME), ], is_rule_tracker=True, ) greet_rule_which_only_applies_at_start = TrackerWithCachedStates.from_events( "bla", domain=domain, evts=[ ActionExecuted(ACTION_LISTEN_NAME), UserUttered(intent={"name": GREET_INTENT_NAME}), ActionExecuted(UTTER_GREET_ACTION), ActionExecuted(ACTION_LISTEN_NAME), ], is_rule_tracker=True, ) policy = RulePolicy() policy.train( [greet_rule_which_only_applies_at_start, fallback_recover_rule], domain, RegexInterpreter(), ) # RulePolicy predicts fallback action conversation_events = [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("dasdakl;fkasd", {"name": DEFAULT_NLU_FALLBACK_INTENT_NAME}), ] tracker = DialogueStateTracker.from_events("casd", evts=conversation_events, slots=domain.slots) action_probabilities = policy.predict_action_probabilities( tracker, domain, RegexInterpreter()) assert_predicted_action(action_probabilities, domain, ACTION_DEFAULT_FALLBACK_NAME) # Fallback action reverts fallback events, next action is `ACTION_LISTEN` conversation_events += await ActionDefaultFallback().run( CollectingOutputChannel(), TemplatedNaturalLanguageGenerator(domain.templates), tracker, domain, ) # Rasa is back on track when user rephrased intent conversation_events += [ ActionExecuted(ACTION_LISTEN_NAME), UserUttered("haha", {"name": GREET_INTENT_NAME}), ] tracker = DialogueStateTracker.from_events("casd", evts=conversation_events, slots=domain.slots) action_probabilities = policy.predict_action_probabilities( tracker, domain, RegexInterpreter()) assert_predicted_action(action_probabilities, domain, UTTER_GREET_ACTION)
def default_nlg(default_domain): return TemplatedNaturalLanguageGenerator(default_domain.templates)
def default_nlg(domain: Domain) -> NaturalLanguageGenerator: return TemplatedNaturalLanguageGenerator(domain.responses)