Repeat or Loop part of the story till user says stop

I want to ask if the user wants to order more or pay, if the user wants to order more then I want to reshow the menu, I want this to continue repeating till the users chooses to pay. This is what I have so far:

Story.yml

  • intent: ask_chosen_restaurant_name_en entities:
    • chosen_restaurant_name_en: mavo
    • slot_was_set:
      • chosen_restaurant_name_en: mavo ##- action: utter_restaurant_name_en
    • action: action_get_restaurant_menu_categories_en
    • intent: ask_chosen_restaurant_menu_category_en entities:
      • chosen_restaurant_menu_category_en: sandwich
    • slot_was_set:
      • chosen_restaurant_menu_category_en: sandwich

- action: utter_restaurant_menu_category_en

  • action: action_get_restaurant_menu_category_dishes_en
  • intent: ask_chosen_restaurant_menu_category_dish_en entities:
    • chosen_restaurant_menu_category_dish_en: shawarma classic
  • slot_was_set:
    • chosen_restaurant_menu_category_dish_en: shawarma classic
  • action: utter_ask_quantity_of_dish_to_order_en
  • intent: ask_quantity_of_dish_to_order_en entities:
    • quantity_of_dish_to_order_en: 2
  • slot_was_set:
    • quantity_of_dish_to_order_en: 2
  • action: utter_ask_order_more_or_pay_en
  • intent: order_more_en
  • slot_was_set:
    • order_more_or_pay_en: order more
  • action: form_get_restaurant_menu_category_order_more_dishes_en
  • active_loop: form_get_restaurant_menu_category_order_more_dishes_en
  • action: action_get_restaurant_menu_category_dishes_en
  • intent: ask_chosen_restaurant_menu_category_dish_en entities:
    • chosen_restaurant_menu_category_dish_en: shawarma classic
  • slot_was_set:
    • chosen_restaurant_menu_category_dish_en: shawarma classic
  • action: utter_ask_quantity_of_dish_to_order_en
  • intent: ask_quantity_of_dish_to_order_en entities:
    • quantity_of_dish_to_order_en: 2
  • slot_was_set:
    • quantity_of_dish_to_order_en: 2
  • action: utter_ask_order_more_or_pay_en
  • intent: order_more_en
  • slot_was_set:
    • order_more_or_pay_en: order more
  • active_loop: null

action file

class FormGetRestaurantMenuCategoryOrderMoreDishes_en(FormValidationAction):

def name(self):
    return 'form_get_restaurant_menu_category_order_more_dishes_en'

@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    """A list of required slots that the form has to fill"""
    return ["order_more_or_pay_en","chosen_restaurant_menu_category_dish_en" ]

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
    """A dictionary to map required slots to
        - an extracted entity
        - intent: value pairs
        - a whole message
        or a list of them, where a first match will be picked"""
    return {
        "order_more_or_pay_en": [
            self.from_text(),
        ],
        "chosen_restaurant_menu_category_dish_en": [
            self.from_list(),
        ],

    }

def validate(self, dispatcher, tracker, domain):
    chosen_restaurant_menu_category_dish_en = tracker.get_slot("chosen_restaurant_menu_category_dish_en")
    slot_to_fill = tracker.get_slot("order_more_or_pay_en")
    if slot_to_fill == "Order More": 
        return [SlotSet("chosen_restaurant_menu_category_dish_en", chosen_restaurant_menu_category_dish_en)]
    return []

error while training InvalidRule: Contradicting rules or stories found :rotating_light:

  • the prediction of the action ‘action_get_restaurant_menu_category_dishes_en’ in story ‘Searching for restaurants based on location’ is contradicting with rule(s) ‘’ which predicted action ‘action_listen’. Please update your stories and rules so that they don’t contradict each other. You can find more information about the usage of rules at Rules.

I would wrap this entirely in a form. That way, your stories would be much simpler and more reliable. I would edit the form’s validation actions so that all slots are reset if the user wants to place another order, as this would effectively cause the form to run again. Of course, you would need some way of saving all the user’s orders. You might be able to do this with additional slots, but using the tracker directly as memory seems easier. If you created a new attribute tracker.orders of type dictionary with the orders as keys and the quantities ordered as values, then you could simply update this attribute before resetting any slots.

Note: I haven’t actually tried this, but I think it should work. Hope that helps :slight_smile:

thanks Alex, but when you say wrap it up entirely in a form, do you mean all the intents and actions that are in the story? I know that we can call other action using FollowupAction and we can call response using dispatch but how can I call an intent? As for saving the order I am using slot type: list, shouldn’t that add to my slot with reseting it?

Hi @StarBoy01 would you have more information on repeating parts of a story n’y wrapping up in Forms? Thanks!