Rasa Wellness bot update to v2.4.x struggle [Closed]

I am beginner in rasa chatbot things. I am following Rasa for Beginners Udemy course The course is outdated, so I am trying my best to update things, I am stuck at Forms

After watching some latest Forms tutorials in Rasa Youtube official channel & following RasaHQ/rasa/examples/formbot github example, I was able to create Form with slots mapping :rainbow:

I even learnt how to activate & deactivate forms from this migration doc

But my setup its not working :frowning:, let me show problems below (I was running rasa in interactive mode, to debug things):

Full code in github. For quick glance:

domain.yml

version: '2.0'

intents:
  - greet
  - goodbye
  - affirm
  - deny
  - bot_challenge
  - inform
  - out_of_scope
  - thankyou

slots:
  confirm_exercise:
    type: bool
    influence_conversation: false
  exercise:
    type: text
    influence_conversation: false
  sleep:
    type: text
    influence_conversation: false
  diet:
    type: text
    influence_conversation: false
  stress:
    type: text
    influence_conversation: false
  goal:
    type: text
    influence_conversation: false

entities:
  - exercise
  - sleep
  - stress

responses:
  utter_greet:
  - text: Hi! It's time for your daily wellness check. Tracking healthy habits is a great way to measure your progress over time. Would you like to answer few questions about your health?

  utter_cheer_up:
  - text: 'Here is something to cheer you up:'
    image: https://i.imgur.com/nGF1K8f.jpg

  utter_did_that_help:
  - text: Did that help you?

  utter_happy:
  - text: Great, carry on!

  utter_goodbye:
  - text: Bye

  utter_iamabot:
  - text: I am just another bot trying to help you.

  utter_ask_confirm_exercise:
  - text: Did you exercise yesterday? Don't sweat it if you didn't run a marathon - walks count!

  utter_ask_sleep:
  - text: How much sleep did you get πŸ’€ last night?

  utter_ask_ :
  - text: What kind of exercise did you do?

  utter_ask_diet:
  - text: Did you stick to a healthy diet πŸ₯¦ yesterday?

  utter_ask_stress:
  - text: Is your stress level low, medium or high 🧘🏼?

  utter_ask_goal:
  - text: Setting goals - even small ones - is a great way to focus your day. What do you want to accomplish today πŸ₯‡ ?

  utter_slots_value:
  - text: "Here's your daily wellness log:\n
            - Exercised?: {confirm_exercise}\n
            - Type of exercise: {exercise}\n
            - Sleep: {sleep}\n
            - Stuck to a healthy diet?: {diet}\n
            - Stress level: {stress}\n
            - Goal: {goal}"

  utter_no_worries:
  - text: No Problem :)

  utter_ask_continue:
  - text: Sorry, I don't quire understand. Do you want to continue?

forms:
  health_form:
    confirm_exercise:
    - type: from_intent
      intent: inform
      value: true
    - type: from_intent
      intent: affirm
      value: true
    - type: from_intent
      intent: deny
      value: false
    exercise:
    - type: from_entity
      entity: email
    sleep:
    - type: from_entity
      entity: sleep
    - type: from_intent
      intent: deny
      value: "None"
    diet:
    - type: from_text
      intent: inform
    - type: from_text
      intent: affirm
    - type: from_text
      intent: deny
    stress:
    - type: from_entity
      entity: stress
    goal:
    - type: from_text
      intent: inform

session_config:
  session_expiration_time: 60
  carry_over_slots_to_new_session: true

rules.yml

version: "2.0"

rules:
- rule: Say goodbye anytime the user says goodbye
  steps:
  - intent: goodbye
  - action: utter_goodbye

- rule: Say 'I am a bot' anytime the user challenges
  steps:
  - intent: bot_challenge
  - action: utter_iamabot

- rule: Activate health_form
  steps:
  - intent: affirm
  - action: health_form
  - active_loop: health_form

- rule: Deactivate health_form
  condition:
  - active_loop: health_form
  steps:
  - action: health_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  - action: utter_slots_value
  - intent: thankyou
  - action: utter_no_worries
  - action: utter_goodbye

stories.yml

version: "2.0"

stories:

- story: Greet user back
  steps:
  - intent: greet
  - action: utter_greet

I did it! I had 1 typo in form

    exercise:
    - type: from_entity
      entity: email <- this should be exercise, silly me :P

and I rewrote Stories & rules, also included out_of_scope handling

rules.yml

version: "2.0"

rules:
- rule: Activate health_form
  steps:
  - intent: affirm
  - action: health_form
  - active_loop: health_form

- rule: Submit health_form
  condition:
  - active_loop: health_form
  steps:
  - action: health_form
  - active_loop: null
  - action: utter_slots_value
  - action: action_restart

stories.yml

version: "2.0"

stories:

- story: Greet user back
  steps:
  - intent: greet
  - action: utter_greet

- story: Thank you, end and reset
  steps:
  - intent: thankyou
  - action: utter_no_worries
  - action: utter_goodbye
  - action: action_restart

- story: No Form
  steps:
  - intent: greet
  - action: utter_greet
  - intent: deny
  - action: utter_no_worries
  - action: utter_goodbye
  - action: action_restart

- story: Sad Path 1 - Retry
  steps:
  - intent: affirm
  - action: health_form
  - active_loop: health_form
  - intent: out_of_scope
  - action: utter_ask_continue
  - intent: affirm
  - action: health_form
  - active_loop: null
  - action: utter_slots_value
  - action: action_restart

- story: Sad Path 2 - Stop
  steps:
  - intent: affirm
  - action: health_form
  - active_loop: health_form
  - intent: out_of_scope
  - action: utter_ask_continue
  - intent: deny
  - action: action_deactivate_loop
  - active_loop: null
  - action: utter_no_worries
  - action: utter_goodbye
  - action: action_restart

Just 1 thing is left, I need to skip exercise slot if confirm_exercise is false… searching for examples and old posts in this forum. If someone bump into this thread, please feel free to add anything you know :slight_smile:

I was able to finally complete this, I added below stuff in actions.py after reading docs, referring this example & thanks to @marcos.allysson for this answer

from typing import Text, List

from rasa_sdk import Tracker, FormValidationAction
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict

class ValidateHealthForm(FormValidationAction):

  def name(self) -> Text:
      return "validate_health_form"

  async def required_slots(
    self,
    slots_mapped_in_domain: List[Text],
    dispatcher: "CollectingDispatcher",
    tracker: "Tracker",
    domain: "DomainDict"
  ) -> List[Text]:
    if tracker.get_slot("confirm_exercise") == True:
      return ["confirm_exercise", "exercise", "sleep", "diet", "stress", "goal"]
    else:
      return ["confirm_exercise", "sleep", "diet", "stress", "goal"]

after this I uncommented 2 lines in endpoints.yml most likely this is for telling rasa where to send requests for checking custom actions. (correct me if i am wrong)

action_endpoint:
 url: "http://localhost:5055/webhook"

finally in domain.yml file I added below stuff just before form definition.

actions:
- validate_health_form

Note : The purpose of this thread to help a beginner fumbling across internet to understand & implement things in latest rasa sdk :rainbow:

1 Like