When FollowupAction is specified, should all predicted event that has not been executed be reverted?

In FormAction validation, I didn’t want to simply raise ActionExecutionRejection because you have to have good stories and intent data to bring user back to FormAction in case of entity extraction failure. So I added code like this in FormAction.validate

if not entities:
    failed_count = int(tracker.slots.get('failed_counter') or 0)
   if failed_count > 1:
       return [Restarted(), FollowupAction(name='show_menu')]

   dispatcher.utter_message(f"Sorry, I didn't get that. Let's try again. ")
   return [SlotSet('failed_counter', failed_count + 1)]

This allow user to make mistake but still ask same question without writing stories etc. Then after 2 failure, I wanted to show initial menu cause Bot just gave up and wanted user’s attention to what bot can do. This almost works perfectly except that Restarted(), FollowupAction(name='show_menu') happnes AFTER another form_action is predicted. So at the end, user would see Bot message with template from utter_ask_{my_slot} Then immediately after that, it sees show_menu Action. I was wondering, if FollowupAction is detected, should tracker will revert any predicted yet not executed (emitted) event?

The below log shows when if failed_count > 1. I’ve annoted my opinion with line starts with **

[BOT] What is the race distance?
[USER INPUT] meh

2018-12-13 16:31:06 DEBUG    rasa_core.tracker_store  - Recreating tracker for id 'default'
2018-12-13 16:31:06 DEBUG    rasa_core.processor  - Received user message 'meh' with intent '{'name': None, 'confidence': 0.0}' and entities '[]'
2018-12-13 16:31:06 DEBUG    rasa_core.processor  - Logged UserUtterance - tracker now has 79 events

2018-12-13 16:31:06 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, {}, {'prev_action_listen': 1.0, 'select_main_menu_item': 1.0, 'main_menu_0': 1.0, 'main_menu': 1.0}]
2018-12-13 16:31:06 DEBUG    rasa_core.policies.memoization  - There is a memorised next action '24'
2018-12-13 16:31:06 DEBUG    rasa_core.policies.form_policy  - There is an active form 'target_pace_form'
2018-12-13 16:31:07 DEBUG    rasa_core.policies.fallback  - NLU confidence 0.0 is lower than NLU threshold 0.2. Predicting fallback action: action_default_fallback
2018-12-13 16:31:07 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_FormPolicy
2018-12-13 16:31:07 DEBUG    rasa_core.processor  - Predicted next action 'target_pace_form' with prob 1.00.
2018-12-13 16:31:07 DEBUG    rasa_core.actions.action  - Calling action endpoint to run action 'target_pace_form'.

** SETTING FollowupAction BECAUSE I WNAT TO GET OUT OF FORM
2018-12-13 16:31:07 DEBUG    rasa_core.processor  - Action 'target_pace_form' ended with events '['AllSlotsReset()', 'Restarted()', 'FollowupAction(action: utter_show_menu)', 'SlotSet(key: requested_slot, value: distance_to_run)']'
** OH NO, I DON'T WANT THIS EVENT TO BE EMIITED ANYMORE....
2018-12-13 16:31:07 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: What is the race distance?, data: {
  "elements": null,
  "buttons": null,
  "attachment": null
})'

** GOOD! FollowupAction IS WORKING!
2018-12-13 16:31:07 DEBUG    rasa_core.processor  - Predicted next action 'utter_show_menu' with prob 1.00.
2018-12-13 16:31:07 DEBUG    rasa_core.processor  - Action 'utter_show_menu' ended with events '[]'

Maybe above post is not clear enough so I like to re-state the what I expected and actual and hoping to hear the solution.

I have code like this from FormAction

if last_message == '/reset':
    dispatcher.utter_message("Alright, let's start all over.")
    from rasa_core_sdk.events import SlotSet, Form
    return [Form(None), SlotSet(REQUESTED_SLOT, None), FollowupAction(name='show_menu')]
    # return [Restarted(), FollowupAction(name='show_menu')] <== also tried this

What I expected to see is after user enter ‘/reset’

“Alright, let’s start all over.” then take action “show_menu” however, between “Alright, let’s start all over.” and action show_menu, rasa_core inject IMO residual predicted action from FormAction.

Actual Bot Utterances:

Alright, let's start all over. <== this was dispatched from FormAction
What is the race distance? <== this is form FormAction `utter_ask_{slot_name}` which I think is residual
Select one of the options below. <== this is from Action show_menu

Expected Bot Utterances:

Alright, let's start all over. <== this was dispatched from FormAction
Select one of the options below. <== this is from Action show_menu

Here is what Log shows after user enter ‘/reset’…

2018-12-17 10:00:09 DEBUG    rasa_core.processor  - Received user message '/reset' with intent '{'name': 'reset', 'confidence': 1.0}' and entities '[]'

2018-12-17 10:01:23 DEBUG    rasa_core.policies.form_policy  - There is an active form 'target_pace_form'

2018-12-17 10:01:23 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_FormPolicy

2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Predicted next action 'target_pace_form' with prob 1.00.

2018-12-17 10:01:23 DEBUG    rasa_core.actions.action  - Calling action endpoint to run action 'target_pace_form'.

2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Action 'target_pace_form' ended with events '['Form(None)', 'SlotSet(key: requested_slot, value: None)', 'FollowupAction(action: show_menu)', 'SlotSet(key: requested_slot, value: distance_to_run)']'

2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: Alright, let's start all over., data: {
  "elements": null,
  "buttons": null,
  "attachment": null
})'

2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: What is the race distance?, data: {
  "elements": null,
  "buttons": null,
  "attachment": null
})'
2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Predicted next action 'show_menu' with prob 1.00.
2018-12-17 10:01:23 DEBUG    rasa_core.processor  - Action 'show_menu' ended with events '[]'

Is this expected? or should predicted FormAction be reverted?

Thank you

Identified the cause and reported here: Option to not to add Next Slot Events if event includes `Restarted` or maybe Form Deactivation · Issue #32 · RasaHQ/rasa_core_sdk · GitHub

It looks like it behaves as expected. You see utter_ask_{next_slot} before followup action because it is emitted by request_next_slot method. I would suggest to override this method and add counter logic there instead of validate

I had the logic in run as this function gather this session’s events and I needed that info. I did end up adding the logic in request_next_slot but I had to find a way to gather this session’s events which is the info run method already have. So I set the class attributes when I want to get out of Form completely I set that attribute/flag then return None from request_next_slot if the flag is set to true. Thank you for your advice.

request_next_slot @Ghostvv how can I override the this methond. If my slot name is “ask_name”.

just create a method in your custom form with the same name modified from original rasa-sdk/forms.py at 0c55c8b55903b424a410d1421e581d4f9071f5a3 · RasaHQ/rasa-sdk · GitHub to do your logic