def run(self, dispatcher, tracker, domain): dispatcher.utter_template(self.template, tracker) # utter error message latest_bot_message = {"text": tracker.latest_bot_utterance.text} # repeat previous question if tracker.latest_bot_utterance.data is not None: for key in tracker.latest_bot_utterance.data.keys(): latest_bot_message[key] = tracker.latest_bot_utterance.data[ key] dispatcher.utter_response(latest_bot_message) return [ActionReverted(), ActionReverted()]
def _create_start_trackers_for_augmentation(self, story_end_trackers): # type: (List[TrackerWithCachedStates]) -> TrackerLookupDict """This is where the augmentation magic happens. We will reuse all the trackers that reached the end checkpoint `None` (which is the end of a story) and start processing all steps again. So instead of starting with a fresh tracker, the second and all following phases will reuse a couple of the trackers that made their way to a story end. We need to do some cleanup before processing them again. """ next_active_trackers = defaultdict(list) if self.config.use_story_concatenation: ending_trackers = utils.subsample_array( story_end_trackers, self.config.augmentation_factor, rand=self.config.rand) for t in ending_trackers: # this is a nasty thing - all stories end and # start with action listen - so after logging the first # actions in the next phase the trackers would # contain action listen followed by action listen. # to fix this we are going to "undo" the last action listen # tracker should be copied, # otherwise original tracker is updated aug_t = t.copy() aug_t.update(ActionReverted()) next_active_trackers[STORY_START].append(aug_t) return next_active_trackers
def test_revert_action_event(default_domain): tracker = DialogueStateTracker("default", default_domain.slots) # the retrieved tracker should be empty assert len(tracker.events) == 0 intent = {"name": "greet", "confidence": 1.0} tracker.update(ActionExecuted(ACTION_LISTEN_NAME)) tracker.update(UserUttered("/greet", intent, [])) tracker.update(ActionExecuted("my_action")) tracker.update(ActionExecuted(ACTION_LISTEN_NAME)) # Expecting count of 4: # +3 executed actions # +1 final state assert tracker.latest_action_name == ACTION_LISTEN_NAME assert len(list(tracker.generate_all_prior_trackers())) == 4 tracker.update(ActionReverted()) # Expecting count of 3: # +3 executed actions # +1 final state # -1 reverted action assert tracker.latest_action_name == "my_action" assert len(list(tracker.generate_all_prior_trackers())) == 3 dialogue = tracker.as_dialogue() recovered = DialogueStateTracker("default", default_domain.slots) recovered.recreate_from_dialogue(dialogue) assert recovered.current_state() == tracker.current_state() assert tracker.latest_action_name == "my_action" assert len(list(tracker.generate_all_prior_trackers())) == 3
def test_revert_action_event(default_domain): tracker = DialogueStateTracker("nlu", default_domain.slots, default_domain.topics, default_domain.default_topic) # the retrieved tracker should be empty assert len(tracker.events) == 0 intent = {"name": "greet", "confidence": 1.0} tracker.update(ActionExecuted(ACTION_LISTEN_NAME)) tracker.update(UserUttered("_greet", intent, [])) tracker.update(ActionExecuted("my_action")) tracker.update(ActionExecuted(ACTION_LISTEN_NAME)) assert tracker.latest_action_name == ACTION_LISTEN_NAME assert len(list(tracker.generate_all_prior_states())) == 4 tracker.update(ActionReverted()) assert tracker.latest_action_name == "my_action" assert len(list(tracker.generate_all_prior_states())) == 3 dialogue = tracker.as_dialogue() recovered = DialogueStateTracker("nlu", 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" assert len(list(tracker.generate_all_prior_states())) == 3
def test_json_parse_undo(): # DOCS MARKER ActionReverted evt = \ { 'event': 'undo', } # DOCS END assert Event.from_parameters(evt) == ActionReverted()
def _create_start_trackers(self, active_trackers): # type: (TrackerLookupDict) -> TrackerLookupDict """One phase is one traversal of all story steps. We need to do some cleanup before processing them again.""" glue_mapping = self.story_graph.story_end_checkpoints if self.config.use_story_concatenation: glue_mapping[STORY_END] = STORY_START next_active_trackers = defaultdict(list) for end, start in glue_mapping.items(): ending_trackers = active_trackers.get(end, []) if start == STORY_START: ending_trackers = utils.subsample_array( ending_trackers, self.config.augmentation_factor, rand=self.config.rand) # This is where the augmentation magic happens. We # will reuse all the trackers that reached the # end checkpoint `None` (which is the end of a # story) and start processing all steps again. So instead # of starting with a fresh tracker, the second and # all following phases will reuse a couple of the trackers # that made their way to a story end. for t in ending_trackers: # this is a nasty thing - all stories end and # start with action listen - so after logging the first # actions in the next phase the trackers would # contain action listen followed by action listen. # to fix this we are going to "undo" the last action listen if start == STORY_START: t.update(ActionReverted()) next_active_trackers[start].append(t) return next_active_trackers
@pytest.mark.parametrize("one_event,another_event", [ (UserUttered("/greet", { "name": "greet", "confidence": 1.0 }, []), UserUttered("/goodbye", { "name": "goodbye", "confidence": 1.0 }, [])), (TopicSet("my_topic"), TopicSet("my_other_topic")), (SlotSet("my_slot", "value"), SlotSet("my__other_slot", "value")), (Restarted(), None), (AllSlotsReset(), None), (ConversationPaused(), None), (ConversationResumed(), None), (StoryExported(), None), (ActionReverted(), None), (ActionExecuted("my_action"), ActionExecuted("my_other_action")), (BotUttered("my_text", "my_data"), BotUttered("my_other_test", "my_other_data")), (ReminderScheduled("my_action", "now"), ReminderScheduled("my_other_action", "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 == deepcopy(one_event), \ "Event copies need to be the same" assert one_event != 42, \ "Events aren't equal to 42!"
def test_get_last_event_with_reverted(): events = [ActionExecuted('one'), ActionReverted(), user_uttered('two', 1)] tracker = get_tracker(events) assert tracker.get_last_event_for(ActionExecuted) is None
def undo_last_action(self): # type: () -> None """Reverts the last action of the tracker (usually action listen).""" self.tracker.update(ActionReverted()) self.featurization.pop()
(Restarted(), None), (AllSlotsReset(), None), (ConversationPaused(), None), (ConversationResumed(), None), (StoryExported(), None), (ActionReverted(), None), (ActionExecuted("my_action"), ActionExecuted("my_other_action")), (BotUttered("my_text", "my_data"), BotUttered("my_other_test", "my_other_data")), (ReminderScheduled("my_action", "now"), ReminderScheduled("my_other_action", "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"