Disable form action in a custom action

Hello, how do I disable the current active form action through a custom action?

Background: I have a form action that has 4 slots. When the user is replying to one of the ask_slots, he suddenly turns idle. For every validate_slot, I would return a ReminderScheduler to check if the user is inactive for a period of time. When the action gets trigger, I would want to deactive the current form and proceed to ask the user if he wants to continue or not. The user would then replies either Yes or No.

For this to work, I guess I have to disable the current active form so that the user replies would not affect the slot. I have tested this out without having a form and it works. But with form action, the story would still always be in the happy path 1 and not go to user inactive although action_inactive is being triggered.

Conversation:
User: Hi
Bot: Hi, what drink would you like to order?
User: (inactive for 5min)
Bot: Do you want to continue?
User: No
Bot: Thanks for using the service we hope to see you again.

## happy path 1
* greet
- restaurant_form
- form{"name" : "restaurant_form"}
- form{"name": null}

## user inactive
- action_inactive
* deny
- utter_noted
- action_restart

*UPDATE,

class ActionInactivityScheduler(Action):
    def name(self):
        return "action_inactivity_scheduler"

    def run(self, dispatcher, tracker, domain):
        dispatcher.utter_message("Do you want to continue?")
        return [Form(None), SlotSet("requested_slot", None)]

I saw the return from forms.deactivate, not sure if I am able to use it for my custom action or not.

You might be interested in how we handle this in our demobot – we don’t actually deactivate the form before we ask the user if they want to continue. example story here: rasa-demo/closetheloop.md at master · RasaHQ/rasa-demo · GitHub

Forms have a certain breakaway functionality where if the form gets unexpected input, other policies will handle the action. So in our subscribe newsletter form, out slot mapping look like

    def slot_mappings(self):
        return {
            "email": [
                self.from_entity(entity="email"),
                self.from_text(intent="enter_data"),
            ]
        }

which means that it will continue with validation if we get an email entity or we get the enter_data intent. If we get something unexpected, like the intent deny, our stories say that we should do the utter_ask_continue_newsletter stuff – and then if they say yes then we call the subscribe_newsletter_form action again, and if not, we deactivate the form (these are the two separate story 11s)

1 Like

Hey @erohmensing thanks for the help once again. Yes so this means that you only deactivate it base on the user unexpected reply. However what I am trying to achieve is a timeout when the user is half way in the form and he just leave. So I would go by this stories.

* greet
- BookingForm
- ViewForm

For every slot that is in the form, under the validation method I return the value and a ReminderSchedule that would trigger if user in inactive for 10sec(testing).

    def validate(self, dispatcher, tracker, domain):
        # extract other slots that were not requested
        # but set by corresponding entity or trigger intent mapping
        slot_values = self.extract_other_slots(dispatcher, tracker, domain)
        # extract requested slot
        slot_to_fill = tracker.get_slot('requested_slot')
        if slot_to_fill:
            slot_values.update(self.extract_requested_slot(dispatcher, tracker, domain))

        self.validate_slots(slot_values, dispatcher, tracker, domain)
        result = []
        for slot, value in slot_values.items():
            result.append(SlotSet(slot, value))

        result.append(ReminderScheduled(action_name="action_inactivity_scheduler",
                                        trigger_date_time=datetime.datetime.now()
                                        + datetime.timedelta(seconds=60),
                                        kill_on_user_message=True))
        return result

*I am editing the post cause I just realise that the suggestion you gave me was the answer! So this means like upon triggering the ReminderScheduled, I could send an unexpected intent to the bot and the story would then ask the user if he or she would want to continue am I right to say so ? haha.

I think this might work just fine! But thinking ahead, since I have 2 forms with 4 slots each, I would have this ReminderScheduled for every slot. So that at any point of time when the user is inactive, it will trigger the inactivity story like this:

## inactive and don't want to continue
- action_inactivity_scheduler
* deny
- action_deactivate_form
- form {"name" : null }

However, if the user wants to continue, how do I call the current active form action in the story?

## inactive and wants to continue
* affirm
- form that was active

Sorry for being so long winded, was thinking I should provide as much information and question if I needed any help haha.

This is really interesting, I don’t know if I’ve seen anyone implement a form timeout before. Super cool that you got it working! I think you’re correct, you could try returning a UserUttered event in the case of a time out (I believe you can send these from the ask but will have to check, in any case you can send the actual curl request. I would send some sort of /timeout intent payload that you then handle in your stories i.e. timeout leads to the utter_ask_continue.

Hahaha yes that’s what I plan to do but i don’t have payload for wechat(sadly) so no buttons… Just a quick question, I slot map my stuffs:

def slot_mappings(self):
        return {
            "email": [
                self.from_text(not_intent="stop"),
            ]
        }

When I call /stop upon having email slot uttering me the question, it did not stop. It was still in the slot.

## Story stop
* greet
- email_form
- form{"name": email_form}
* stop
- action_deactivate_form
- form{"name": null}
- utter_goodbye

Ah, is the issue that it correctly left the form, but the email slot still filled? Or that it didn’t leave the form correctly?

Hmm not very sure. Feel is something to do with policies! When my policies had augmentation 50, it seems to work. When i change it to 0 because I want the bot to follow closely to my story, it seems to not work at all. hmm

Ah, is the issue that it correctly left the form, but the email slot still filled? Or that it didn’t leave the form correctly?

I just mean which one is the problem you’re experiencing? :smile:Also can you share your config then?

Hello sorry for late reply, it didn’t leave the form correctly !

Strange. Can you post --debug logs from both the rasa server and action server when that occurs?