After restarting form, submit is not triggered

Hello, I need to run a form N times, where N is chosen by the user before starting the form. The problem I am facing is that after the second iteration, the rule for submitting the form is not triggered. Here is the relevant part of my rules.yml file

- rule: Start form after choosing N
  steps:
  - intent: choose_N
  - action: action_start_form

- rule: Submit form
  condition:
  - active_loop: my_form
  steps:
  - action: my_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  - action: action_end_form

I have defined my_form normally in domain.yml, together with the necessary slots.

Here is the relevant part of my action.py file

class ActionStartForm(Action):
    def name(self) -> Text:
        return "action_start_form"

    def run(
        self, 
        dispatcher: CollectingDispatcher,
        tracker: Tracker, 
        domain: Dict
    ) -> List[EventType]:


       N = int(tracker.get_slot('N'))
       current_iteration = int(tracker.get_slot('current_iteration'))

        ## Here I have custom utterances which depend on N and current_iteration ....

       return [FollowupAction('my_form')]

class ActionEndForm(Action):
    def name(self) -> Text:
        return "action_end_form"

    def run(
        self, 
        dispatcher: CollectingDispatcher,
        tracker: Tracker, 
        domain: Dict
    ) -> List[EventType]:

        N = int(tracker.get_slot('N'))
        current_iteration = int(tracker.get_slot('current_iteration'))

        events = []

        if current_iteration != N:
            form_slots = domain['forms']['my_form']['required_slots']
            
            iteration = {slot: tracker.get_slot(slot) for slot in form_slots}
            iterations = tracker.get_slot('iterations').copy()
            iterations.append(iteration)

            events = [SlotSet(key=slot, value=None) for slot in form_slots]
            events.append(SlotSet(key="current_iteration", value=current_iteration+1))
            events.append(SlotSet(key="iterations", value=iterations))
   
            events.append(FollowupAction(name="action_start_form"))
        else:
            dispatcher.utter_message(response="utter_thanks")
            
        return events

The slots used are defined as

  iterations:
    type: any
    initial_value: []
    mappings:
    - type: custom
  
  N:
    type: float
    min_value: 1
    max_value: 5
    mappings:
    - type: from_entity
      entity: N
      intent: choose_N

  current_iteration:
    type: float
    initial_value: 1
    min_value: 0
    max_value: 10
    mappings:
    - type: custom

What happens is that when choose_N is triggered, the form starts correctly. Once all the required_slots are filled the correct Submit form rule is triggered, and therefore the action_end_form. Such action is then able to trigger action_start_form for the second iteration: form is activated, loop goes on, but once the required_slots are filled, Rasa predicts action_default_fallback instead of entering once again the Submit form rule.

Do you understand why? Or do you see a different and more efficient way of handling this?

I would activate the form in the normal fashion with the rule. You don’t need the custom action just to set current_iteration. You can create a current_iteration slot that is updated in the form action.

Thank you for the reply, but I did not understand your solution. Which custom action I do not need? The action_start_form or the action_end_form? How would I save the filled slots, clean them and restart the form?

Drop action_start_form and activate the form as shown in the docs.

save filled slots

via the form slot mapping definition in the domain.yml and in the form validate

clean them and restart the form

you can do this in required slots. This will allow you to iterate thru the same form any number of times.

I am really sorry, but I still do not get what you mean. Would you be able to write down a very simple example in which you activate a form with only one required slot and iterate thru the same N times? Thanks

You’ll find examples in the financial-demo and helpdesk-assistant.

I am really sorry again, I went throughout the examples but did not find an answer to my questions.

Hi, May be you should give a slot clear or saved command as told by stephens in the return of the function action end form.

I am saving the current iteration slots over here

and cleaning them over here

My custom action returns all these events.

My implementation does start the second iteration correctly, but does not trigger the action_end_form at the end of this second iteration.

Is anyone able to provide a simple working example here? I am still struggling finding the solution.

Thank you for the help!

I think the problem here was a bug in the Rasa version I was using (docker image rasa/rasa:3.2.1-full).

Back in October, I had figured out the incorrect behaviour disappearing when removing the initial_value key from the definition of the slots:

 iterations:
    type: any
    # initial_value: []
    mappings:
    - type: custom
  
  N:
    type: float
    min_value: 1
    max_value: 5
    mappings:
    - type: from_entity
      entity: N
      intent: choose_N

  current_iteration:
    type: float
    # initial_value: 1
    min_value: 0
    max_value: 10
    mappings:
    - type: custom

and defining their initial values in the custom ActionSessionStart

class ActionSessionStart(Action):
    def name(self) -> Text:
        return "action_session_start"

    async def run(
        self, 
        dispatcher: CollectingDispatcher, 
        tracker: Tracker, 
        domain: Dict[Text, Any]
    ) -> List[Dict[Text, Any]]:

        events = [SessionStarted()]

        events.append(SlotSet(key='iterations', value=[]))
        events.append(SlotSet(key='current_iteration', value=1))

        dispatcher.utter_message(response='utter_ask_N')

        events.append(ActionExecuted("action_listen"))

        return events

I am sorry I haven’t found the time to write the solution before.

Moreover, before writing down the solution here, I tested my minimal reproducible example again, and tried the newest Rasa release (docker image rasa/rasa:3.4.4-full). The issue disappeared completely!

I created a repo with the complete working minimal example for future reference. It works with Docker installation as well as with a standard venv.