Custom two_stage fallback

Hi, I want to use the Two_Stage Fallback option in rasa, but I want to customize it in such a way that it doesn’t activate action_default_ask_affirmation. I want to have a similar process in my chatbot dialogue:

user: What is your name? (nlu_fallback)
chatbot: Please rephrase your message. (action_ask_rephrase)
user: What is your name? (nlu_fallback)
chatbot: I am passing you to a human. (action_default_fallback)

But in the rasa two_stage fallback, in the beginning, the user is asked for affirmation. I want to deactivate ‘action_default_ask_affirmation’ part. Is there any way to do this?

I appreciate any help.

Hey @ZahraDehghani99, I recommend overwriting the default action_two_stage_fallback action with a custom action where you’ll re-use much of the code present in the default implementation but will adjust the logic to your needs. Let me know how it goes. As the docs page for default actions says: “You may want to customize these to personalize your assistant.” and it’s nothing to be afraid of :slightly_smiling_face:

Hi @SamS thank you for your reply. where can I find the default implementation of action_two_stage_fallback?

I tried to overwrite TwoStageFallbackAction from rasa/core/actions/two_stage_fallback.py with a custom action, But it doesn’t have run method inside it.

I’m a bit confused. Can you please give me a more hint about what should I write in the run method of my custom action? :pray:

Should I change TwoStageFallbackPolicy from rasa/core/policies/two_stage_fallback.py?

Thank you so much.

I wrote a custom action for action_two_stage_fallback as follows and it worked as I expected.

class ActionTwoStageFallback(Action):
    def name(self) -> Text:
        return "action_two_stage_fallback"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: DomainDict):  

        last_action = get_last_utter_action(tracker) 
        last_intent = tracker.latest_message.get("intent", {}).get("name")

        if last_intent == "nlu_fallback":
            # first time this action executed. Ask for rephrase message
            if last_action!="action_two_stage_fallback":
                dispatcher.utter_message(text="Please rephrase your message.")

                return []

            # second time this action executed. Connect to human operator    
            else:   
                dispatcher.utter_message(text="I am passing you to a human")
                # pause the tracker so that the bot stops responding to user input
                return[UserUtteranceReverted(), ConversationPaused()]

I found implementation for get_last_utter_action in this link.

1 Like

@ZahraDehghani99 sorry for not responding earlier; I’m glad you figured it out!

The default TwoStageFallbackAction doesn’t have a run method but its do method has a similar role. In any case, the run method, in a cleanly written custom action, shouldn’t do much :slight_smile: Its role is mainly to be an interface to the outside world – to receive important arguments (the tracker, the dispatcher, etc.) and to delegate work to other helper methods of the custom action, which contain the actual logic. So, in general, to “translate” a default action from rasa/core/actions to a custom action, it should be enough to add a very minimalistic run method. Anyway, it’s great that you managed to solve it and I’m sure things will be easier for you from now on, as you seem to be comfortable with custom actions!

@SamS Thank you so much :slight_smile: