def test_user_uttered_to_e2e(parse_data: Dict, expected_story_string: Text): event = UserUttered.from_story_string("user", parse_data)[0] assert isinstance(event, UserUttered) assert event.as_story_string(e2e=True) == expected_story_string
default_processor.tracker_store.save(tracker) await default_processor.handle_reminder( reminder, sender_id, default_channel, default_processor.nlg ) # retrieve the updated tracker t = default_processor.tracker_store.retrieve(sender_id) assert len(t.events) == 4 # nothing should have been executed @pytest.mark.parametrize( "event_to_apply,session_expiration_time_in_minutes,has_expired", [ # last user event is way in the past (UserUttered(timestamp=1), 60, True), # user event are very recent (UserUttered("hello", timestamp=time.time()), 120, False), # there is user event (ActionExecuted(ACTION_LISTEN_NAME, timestamp=time.time()), 60, False), # Old event, but sessions are disabled (UserUttered("hello", timestamp=1), 0, False), # there is no event (None, 1, False), ], ) async def test_has_session_expired( event_to_apply: Optional[Event], session_expiration_time_in_minutes: float, has_expired: bool, default_processor: MessageProcessor,
async def test_persist_form_story(): domain = Domain.load("data/test_domains/form.yml") tracker = DialogueStateTracker("", domain.slots) story = ( "* greet\n" " - utter_greet\n" "* start_form\n" " - some_form\n" ' - form{"name": "some_form"}\n' "* default\n" " - utter_default\n" " - some_form\n" "* stop\n" " - utter_ask_continue\n" "* affirm\n" " - some_form\n" "* stop\n" " - utter_ask_continue\n" "* inform\n" " - some_form\n" ' - form{"name": null}\n' "* goodbye\n" " - utter_goodbye\n" ) # simulate talking to the form events = [ UserUttered(intent={"name": "greet"}), ActionExecuted("utter_greet"), ActionExecuted("action_listen"), # start the form UserUttered(intent={"name": "start_form"}), ActionExecuted("some_form"), Form("some_form"), ActionExecuted("action_listen"), # out of form input UserUttered(intent={"name": "default"}), ActionExecutionRejected("some_form"), ActionExecuted("utter_default"), ActionExecuted("some_form"), ActionExecuted("action_listen"), # out of form input UserUttered(intent={"name": "stop"}), ActionExecutionRejected("some_form"), ActionExecuted("utter_ask_continue"), ActionExecuted("action_listen"), # out of form input but continue with the form UserUttered(intent={"name": "affirm"}), FormValidation(False), ActionExecuted("some_form"), ActionExecuted("action_listen"), # out of form input UserUttered(intent={"name": "stop"}), ActionExecutionRejected("some_form"), ActionExecuted("utter_ask_continue"), ActionExecuted("action_listen"), # form input UserUttered(intent={"name": "inform"}), FormValidation(True), ActionExecuted("some_form"), ActionExecuted("action_listen"), Form(None), UserUttered(intent={"name": "goodbye"}), ActionExecuted("utter_goodbye"), ActionExecuted("action_listen"), ] [tracker.update(e) for e in events] assert story in tracker.export_stories()
def user_uttered(text: Text, confidence: float) -> UserUttered: parse_data = {"intent": {"name": text, "confidence": confidence}} return UserUttered( text="Random", intent=parse_data["intent"], parse_data=parse_data )
ActionReverted, BotUttered, FollowupAction, UserUtteranceReverted, AgentUttered, SessionStarted, md_format_message, ) @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), (SessionStarted(), None),
async def test_can_read_test_story_with_entities_slot_autofill( default_domain: Domain): trackers = await training.load_data( "data/test_yaml_stories/story_with_or_and_entities.yml", default_domain, use_story_concatenation=False, tracker_limit=1000, remove_duplicates=False, ) assert len(trackers) == 2 assert trackers[0].events[-3] == UserUttered( "greet", intent={ "name": "greet", "confidence": 1.0 }, parse_data={ "text": "/greet", "intent_ranking": [{ "confidence": 1.0, "name": "greet" }], "intent": { "confidence": 1.0, "name": "greet" }, "entities": [], }, ) assert trackers[0].events[-2] == ActionExecuted("utter_greet") assert trackers[0].events[-1] == ActionExecuted("action_listen") assert trackers[1].events[-4] == UserUttered( "greet", intent={ "name": "greet", "confidence": 1.0 }, entities=[{ "entity": "name", "value": "peter" }], parse_data={ "text": "/greet", "intent_ranking": [{ "confidence": 1.0, "name": "greet" }], "intent": { "confidence": 1.0, "name": "greet" }, "entities": [{ "entity": "name", "value": "peter" }], }, ) assert trackers[1].events[-3] == SlotSet(key="name", value="peter") assert trackers[1].events[-2] == ActionExecuted("utter_greet") assert trackers[1].events[-1] == ActionExecuted("action_listen")
def user_uttered(text: Text, confidence: float) -> UserUttered: parse_data = {'intent': {'name': text, 'confidence': confidence}} return UserUttered(text='Random', intent=parse_data['intent'], parse_data=parse_data)
def _user_string(story_step_element: UserUttered, e2e: bool, prefix: Text = "") -> Text: return "* {}{}\n".format(prefix, story_step_element.as_story_string(e2e))
StoryExported, ActionReverted, BotUttered, FollowupAction, UserUtteranceReverted, AgentUttered, SessionStarted, md_format_message, ) @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), (SessionStarted(), None), (ActionExecuted("my_action"), ActionExecuted("my_other_action")), (FollowupAction("my_action"), FollowupAction("my_other_action")), ( BotUttered("my_text", {"my_data": 1}),
import json import rasa.core.brokers.utils as broker_utils from rasa.core.brokers.file_producer import FileProducer from rasa.core.brokers.kafka import KafkaProducer from rasa.core.brokers.pika import PikaProducer from rasa.core.brokers.sql import SQLProducer from rasa.core.events import Event, Restarted, SlotSet, UserUttered from rasa.utils.endpoints import EndpointConfig, read_endpoint_config from tests.core.conftest import DEFAULT_ENDPOINTS_FILE TEST_EVENTS = [ UserUttered("/greet", { "name": "greet", "confidence": 1.0 }, []), SlotSet("name", "rasa"), Restarted(), ] def test_pika_broker_from_config(): cfg = read_endpoint_config( "data/test_endpoints/event_brokers/pika_endpoint.yml", "event_broker") actual = broker_utils.from_endpoint_config(cfg) assert isinstance(actual, PikaProducer) assert actual.host == "localhost" assert actual.username == "username" assert actual.queue == "queue"
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("haha", {"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("haha", {"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) 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) assert_predicted_action(action_probabilities, domain, UTTER_GREET_ACTION)
async def test_form_unhappy_path_triggering_form_again(): form_name = "some_form" handle_rejection_action_name = "utter_handle_rejection" domain = Domain.from_yaml(f""" intents: - {GREET_INTENT_NAME} actions: - {UTTER_GREET_ACTION} - {handle_rejection_action_name} - some-action slots: {REQUESTED_SLOT}: type: unfeaturized forms: - {form_name} """) unhappy_rule = TrackerWithCachedStates.from_events( "bla", domain=domain, slots=domain.slots, evts=[ # We are in an active form Form(form_name), SlotSet(REQUESTED_SLOT, "bla"), ActionExecuted(RULE_SNIPPET_ACTION_NAME), ActionExecuted(ACTION_LISTEN_NAME), # When a user says "hi", and the form is unhappy, we want to run a specific # action UserUttered("haha", {"name": GREET_INTENT_NAME}), ActionExecuted(handle_rejection_action_name), ActionExecuted(form_name), ActionExecuted(ACTION_LISTEN_NAME), ], is_rule_tracker=True, ) policy = RulePolicy() policy.train([unhappy_rule], domain, RegexInterpreter()) # Check that RulePolicy predicts action to handle unhappy path conversation_events = [ ActionExecuted(form_name), Form(form_name), SlotSet(REQUESTED_SLOT, "some value"), ActionExecuted(ACTION_LISTEN_NAME), UserUttered("haha", {"name": GREET_INTENT_NAME}), ActionExecutionRejected(form_name), ] action_probabilities = policy.predict_action_probabilities( DialogueStateTracker.from_events("casd", evts=conversation_events, slots=domain.slots), domain, ) assert_predicted_action(action_probabilities, domain, handle_rejection_action_name) # Check that RulePolicy triggers form again after handling unhappy path conversation_events.append(ActionExecuted(handle_rejection_action_name)) action_probabilities = policy.predict_action_probabilities( DialogueStateTracker.from_events("casd", evts=conversation_events, slots=domain.slots), domain, ) assert_predicted_action(action_probabilities, domain, form_name)
) from rasa.core.interpreter import RegexInterpreter from rasa.core.nlg import TemplatedNaturalLanguageGenerator from rasa.core.policies.rule_policy import RulePolicy from rasa.core.trackers import DialogueStateTracker from rasa.core.training.generator import TrackerWithCachedStates UTTER_GREET_ACTION = "utter_greet" GREET_INTENT_NAME = "greet" GREET_RULE = DialogueStateTracker.from_events( "bla", evts=[ ActionExecuted(RULE_SNIPPET_ACTION_NAME), ActionExecuted(ACTION_LISTEN_NAME), # Greet is a FAQ here and gets triggered in any context UserUttered("haha", {"name": GREET_INTENT_NAME}), ActionExecuted(UTTER_GREET_ACTION), ], ) GREET_RULE.is_rule_tracker = True def test_rule_policy_has_max_history_none(): policy = RulePolicy() assert policy.featurizer.max_history is None def _form_submit_rule(domain: Domain, submit_action_name: Text, form_name: Text) -> DialogueStateTracker: return TrackerWithCachedStates.from_events( "bla",
async def test_handle_message_with_session_start( default_channel: CollectingOutputChannel, default_processor: MessageProcessor, monkeypatch: MonkeyPatch, ): sender_id = uuid.uuid4().hex entity = "name" slot_1 = {entity: "Core"} await default_processor.handle_message( UserMessage(f"/greet{json.dumps(slot_1)}", default_channel, sender_id) ) assert default_channel.latest_output() == { "recipient_id": sender_id, "text": "hey there Core!", } # patch processor so a session start is triggered monkeypatch.setattr(default_processor, "_has_session_expired", lambda _: True) slot_2 = {entity: "post-session start hello"} # handle a new message await default_processor.handle_message( UserMessage(f"/greet{json.dumps(slot_2)}", default_channel, sender_id) ) tracker = default_processor.tracker_store.get_or_create_tracker(sender_id) # make sure the sequence of events is as expected assert list(tracker.events) == [ ActionExecuted(ACTION_SESSION_START_NAME), SessionStarted(), ActionExecuted(ACTION_LISTEN_NAME), UserUttered( f"/greet{json.dumps(slot_1)}", {"name": "greet", "confidence": 1.0}, [{"entity": entity, "start": 6, "end": 22, "value": "Core"}], ), SlotSet(entity, slot_1[entity]), ActionExecuted("utter_greet"), BotUttered("hey there Core!", metadata={"template_name": "utter_greet"}), ActionExecuted(ACTION_LISTEN_NAME), ActionExecuted(ACTION_SESSION_START_NAME), SessionStarted(), # the initial SlotSet is reapplied after the SessionStarted sequence SlotSet(entity, slot_1[entity]), ActionExecuted(ACTION_LISTEN_NAME), UserUttered( f"/greet{json.dumps(slot_2)}", {"name": "greet", "confidence": 1.0}, [ { "entity": entity, "start": 6, "end": 42, "value": "post-session start hello", } ], ), SlotSet(entity, slot_2[entity]), ActionExecuted(ACTION_LISTEN_NAME), ]
def random_user_uttered_event( timestamp: Optional[float] = None) -> UserUttered: return UserUttered( uuid.uuid4().hex, timestamp=timestamp if timestamp is not None else random.random(), )
from datetime import datetime import copy import pytest from dateutil import parser from rasa.core.events import (Event, UserUttered, SlotSet, Restarted, ActionExecuted, AllSlotsReset, ReminderScheduled, ConversationResumed, ConversationPaused, StoryExported, ActionReverted, BotUttered, FollowupAction, UserUtteranceReverted, AgentUttered) @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",
def _checkpoint_string(story_step_element: UserUttered) -> Text: return "> {}\n".format(story_step_element.as_story_string())