Story does not continue after form has ended

Okay I need to make a bigger loop here. I am using the form as the user should inform the chatbot about a course title. The problem I had, which I hoped to solve with a form was, that the course title does not have a structure, so it’s really hard for the chatbot to identify that it is the intent inform. So I was suggested to use a form where the user is asked “which course are you talking about” plus a list of courses he is currently enrolled in. The user then answers with the course title (or nonsense) which ends the form. After that achievements are requested with that course title. So that’s what I am trying to achieve with these stories and rules. However, the story is not continued after the form is deactivated, which means the action after - active_loop: null is not called.

So I am just trying to figure out now, why this is happening.

Before continuing on reading, I wanna point this out:

If we’re talking about courses in a well-defined institution, it most probably has a list of available courses, so you could use a lookup table that list all possible courses.

The problem is now that a same course title can be written in so many ways. So if possible, whether via Rasa buttons or your own frontend application (eg. dropdown list), limit the possibilities of inputs from the user’s side.


Ah, so again, same idea as above :slight_smile:

But now I know you already have a list of courses, so instead of showing this “list of courses” as text, show them as buttons with payloads being the specific intent and entities you want. Example for a custom action for action_ask_current_course_title:

courses = [<list of courses>]
buttons = []

for course in courses:
    buttons.append({
        'payload': '/inform{"course": "' + course + '"}',
        "title": course
    })

dispatcher.utter_message(
    text = 'Which course are you talking about?',
    buttons = buttons
)

In your front end application, you can disable the input text bar if the last message has buttons, and now the user input is 100% controlled :slight_smile: (I suggest using a “stop” button with intent “stop” to stop the form with a story like the last one I shared).


So I assume this what is represented by the following:

Then you don’t need to specify an intent before stopping the form in the stories, since it will automatically stop when all the requested slots have been filled using a rule such as this one:

- rule: Submit course_form
  condition: # Condition that form is active
  - active_loop: course_form
  steps:
  - action: course_form
  - active_loop: null # Stop the form
  - slot_was_set:
    - requested_slot: null
  - action: utter_submit

You only need to mention the intent and make a story similar to the one I shared in my previous post when there is a special intent that stops the form. In that case, it was when the user does not want to continue and tells the bot to stop. No matter what the requested slot is, even if it has from_text mapping, the form will stop when the stop intent is detected.


For now, remove that story and do:

- rule: Activate course_form
  steps:
    intent: get_achievements
  - action: action_get_courses
  - action: course_form
  - active_loop: course_form

- rule: Submit course_form
  condition:
  - active_loop: course_form
  steps:
  - action: course_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  - action: utter_submit

Those are the two basic functions that you need: Activate and submit. There are no special cases in your case that requires more that those two.

Nevertheless, you can still write stories taken from real conversations and add them to the training data.

On top of that, if you feel the need to customize how slots are extracted and/or validated, you can use Custom Actions inside Forms. They’re called FormValidationAction. Instead of run(), it has:

  • extract_slotname(): Write logic to extract the slot from the user’s message and return a dictionary of slot names and their values.
  • validate_slotname(): Write logic to check if the slot slotname is valid and return a dictionary of slot names and their values.
  • required_slots(): Write logic to decide which slots should be asked about and return a list of slot names.

Please see: Forms: Advanced Usage.

Hello @ChrisRahme

Thank you so much for that detailed answer. I will try working through your suggestion and might come back to this post if I still struggle or have follow-up questions. But again, many thanks for that explanation! It helps me a lot.

Best, Theresa

1 Like