Custom fallback/actions from within FormAction

I have a form which during validation i check in a custom way, and if that validation fails i want to ask them to check the formatting of particular entities.

Based on the FormBot example i do the check in validate() and then if this fails, submit an utterance to the tracker and set the corresponding slots to None so that they will get refilled.

However, this results in both the new utterance and original question (for those slots) being asked.

How do i go about just asking the new custom one? I’m afraid I’m not familiar enough yet with custom fallbacks and UserUtterance() stuff yet, though it seems custom fallbacks are usually based on thresholds which this is not (also, for example, it might get the confidence of intent correct but not extract any entities, so i would need to deal with that within the python not as a confidence thing, i.e. length of entity list)

A simple example of the kind of thing i am talking about is i want the user to input text (in one string) which contains 3 numbers, if they don’t i want to point out that they didn’t do this and get them to do it again. However, this input is part of a larger form being filled and I’m not sure how to interrupt forms from within the paradigm (or if that is even a good idea).

Am I forced to replace the FormAction with a series of stories to extract each bit? This would be unfortunate as I would lose the nice feature of the form checking what’s missing each time, no?


Hey @Zylatis

This doesn’t sound like you need to interrupt your form. Check out the validating user input section in the docs and let me know if you have any further questions.

Your validate function could look something like this:

import re

def validate_textwith3numbers(self,
                         value: Text,
                         dispatcher: CollectingDispatcher,
                         tracker: Tracker,
                         domain: Dict[Text, Any]) -> Optional[Text]:
        """Validate  textwith3numbers value."""
        digits = re.findall('\d+', value)
        if len(digits) == 3:
            # validation succeeded
            return value
            dispatcher.utter_template('utter_wrong_textwith3numbers', tracker)
            # validation failed, set this slot to None, meaning the
            # user will be asked for the slot again using the utter_wrong_textwith3numbers template
            return None