How to quit form loop using intent

How to quit a form loop whenever a specific intent is detected in RASA 3.1? Like while using a form if the user doesn’t want to go further and say ‘stop’ or ‘end’ then the form should exit and all the filled slots should become empty. Here is how I have defined my slots…

This is how my form is defined This is my slot validation action any help would be great @anca

@anshu03654 Have you tried looking into using action_deactivate_loop in a story that handles this unhappy path? You can find out more in the docs.

@anca I am using rule to fill up the forms. These are the rules for form activation and submission.

and this is the rule for unhappy path
image
But still its not working

@anshu03654 I have the same problem. I wish I could help. action_deactivate_loop did not work for me, and to be honest your code seems solid… I’m marking this thread as Watching and I hope that someone provides a solution, since I have seen similar questions all the time and in most of which action_deactivate_loop appears to be the solution.

@v_kostis if you get any solution plese tell me…

1 Like

@anshu03654 I was testing a couple of things and I’m quoting below the code that seems to work. As you can see, there are some differences in the submit form. Moreover, I do not use the initial action utter_fill_details in the “Activate Form”, since the form itself is responsible to ask for the required fields (I’m guessing utter_ask_email_id in your occasion). Don’t know it if it plays some part, but you know, just pointing this out.

# Form to fill in the required slot (tracking_number)
- rule: Activate find_tracking_number_form
  steps:
  - intent: deliver_package
  - action: find_tracking_number_form
  - active_loop: find_tracking_number_form

- rule: Submit form
  condition:
  - active_loop: find_tracking_number_form
  steps:
  - action: find_tracking_number_form
  - active_loop: null

- rule: Stop tracking form
  condition:
  - active_loop: find_tracking_number_form
  steps:
    - intent: stop
    - action: action_deactivate_loop
    - active_loop: null
    - slot_was_set:
      - requested_slot: null
    - action: utter_initial_menu

If that’s not working, could you consider that there is something wrong with the validation of email_id? I have used a similar action for email purposes. I present it below, with some minor changes to match your wording. I’m not questionning your code nor the use of fullmatch, it’s just that I recently used the below code.

class ValidateEmailForm(FormValidationAction):
	def name(self) -> Text:
		return "validate_email_form"

	def validate_email_id(self, slot_value: Any, dispatcher: CollectingDispatcher,tracker: Tracker, domain: DomainDict,) -> Dict[Text, Any]:
		email_id = next(tracker.get_latest_entity_values("email_id"), None)
		pattern = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
		if(not pattern.match(email_id)):
			dispatcher.utter_message(text="Please enter a valid email id")
			return {"email_id": None}
		return {"email_id": email_id}

Could you try this and revert?

The financial-demo bot has good examples of how to handle this.

@stephens I was using text mapping to fill up the slots that’s why it was not stopping even after identifying the intent.

Is there a way to do this while mapping from text as subject and message of a mail can’t be mapped using intents or entities.

Hi @anshu03654 ,

I saw you’ve implemented a custom validation rule for email_id, which by default returns a value for that slot - either None or the email_id you’ve validated.

In that case Rasa stops processing intents. If you want to be able to react to the stop intent, you have to make your validation function return {} in case the last utterance has a recognized intent of “stop”:

last_intent = tracker.latest_message.get("intent", {}).get("name")
if last_intent=="stop":
  return {}

If the form validation does not return a slot, Rasa’s standard processing kicks in.

1 Like