Adding additional slot in between a form using custom action

I’m building a survey chatbot in that If a user may give an unhappy response I need to ask what is the reasons? for that, I need to add one more slot in the form in between the survey.

please help in this regard Thank you

Hello, sekhar!

Could you provide an dialog example?

You can do same:

intents:
- intent_iam_unhappy

slots:
  user_unhappy:
    type: bool
    initial_value: false
    mappings:
    - type: from_intent
      intent: intent_iam_unhappy
      value: true
      conditions:
        - active_loop: my_form

  ask_reason:
    type: text
    mappings:
      - type: from_text
        conditions:
          - active_loop: my_form
          - requested_slot: ask_reason

rule is usual

rules:
- rule: open form
  steps:
  - intent: open_form
  - action: my_form
  - active_loop: my_form

you should add this action

from typing import Text, List, Optional

from rasa_sdk.forms import FormValidationAction

class ValidateMyForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_my_form"

    async def required_slots(
        self,
        domain_slots: List[Text],
        dispatcher: "CollectingDispatcher",
        tracker: "Tracker",
        domain: "DomainDict",
    ) -> List[Text]:
        additional_slots = []
        if tracker.slots.get("user_unhappy") is True:
            # If the user said he was unhappy add
            # new slot to ask the reason
            additional_slots.append("ask_reason")

        return additional_slots + domain_slots

actually, I have four options like 1 Absolutely 2 Yes 3 Not really 4 Not at tall

for options 3 and 4 I need to ask the reason

Like that?

intents:
- intent_absolutely
- intent_yes
- intent_not_really
- intent_not_at_all

slots:
  user_unhappy:
    type: bool
    initial_value: false
    mappings:
    - type: from_intent
      intent: intent_not_really
      value: true
      conditions:
        - active_loop: my_form
    - type: from_intent
      intent: intent_not_at_all
      value: true
      conditions:
        - active_loop: my_form

  ask_reason:
    type: text
    mappings:
      - type: from_text
        conditions:
          - active_loop: my_form
          - requested_slot: ask_reason

okay, but i have 11 questions for my survey and I make each question a slot and given options in that slot only

version: "3.0"

intents:
  - greet
  - goodbye
  - affirm
  - deny
  - selection
  - bot_challenge


slots:
  ask_reason:
    type: text
    mappings:
      - type: from_text
        conditions:
          - active_loop: survey_form
          - requested_slot: ask_reason
  1st_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  2nd_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  3rd_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  4th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  5th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  6th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  7th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  8th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  9th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  10th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection
  11th_qn:
    type: any
    mappings:
    - type: from_entity
      entity: select
      #intent: selection

entities:
- select

forms:
  survey_form:
    required_slots:
      - 1st_qn
      - 2nd_qn
      - 3rd_qn
      - 4th_qn
      - 5th_qn
      - 6th_qn
      - 7th_qn
      - 8th_qn
      - 9th_qn
      - 10th_qn
      - 11th_qn

responses:
  utter_greet:
  - text: |
      Hello, welcome to diva
  utter_start_survey:
  - text: |
      Hi, I'm Diva! I have been entrusted with the responsibility of knowing about your experience in our organization. Please do speak your mind as your feedback will remain completely confidential. 
      
      Shall we start the first set of questions for the survey? (Y/N)
  utter_start_questioning:
  - text: |
      For questions with multiple-choice, preceded by the symbol 👉, please select the answer that fits best of the options that I will provide.

      Let's start then.
      
  utter_ask_1st_qn:
  - text: |
      👉 *I believe that my organization is on a growth path*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_2nd_qn:
  - text: |
      👉 *I can honestly express my opinion as I know my views are valued*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_3rd_qn:
  - text: |
      👉 *I believe our senior leaders can lead the organization to future success*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_4th_qn:
  - text: |
      👉 *I feel I can count on my co-workers for help*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_5th_qn:
  - text: |
      👉 *The communication between my co-workers and me are honest and transparent*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_6th_qn:
  - text: |
      👉 *I have co-workers with whom I can share my personal feelings*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_7th_qn:
  - text: |
      👉 *I believe that my Manager follows through promises with action*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_8th_qn:
  - text: |
      👉 *I feel that my supervisor trusts the team to work without excessive supervision*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_9th_qn:
  - text: |
      👉 *I believe that my manager is open to ideas and suggestions other than his/her own*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_10th_qn:
  - text: |
      👉 *I trust that I can grow within the organization*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall

  utter_ask_11th_qn:
  - text: |
      👉 *I believe my actions contribute positively in the growth of the organization*
      1 Absolutely 
      2	 Yes 
      3	 Not really
      4	 Not at tall
  utter_ask_reason:
  - text: "📝 Okay. What makes you say so?"
  - text: "📝 Can you help me understand this better?"

  utter_goodbye:
  - text: |
      Thanks for your time in taking this survey 
      Have a great day

  utter_iamabot:
  - text: "I am Diva, powered by bot"

actions: 
- validate_survey_form
session_config:
  session_expiration_time: 60
  carry_over_slots_to_new_session: true

and nlu is

- intent: selection
  examples: |
    - [1]{"entity": "select"}
    - [2]{"entity": "select"}
    - [3]{"entity": "select"}
    - [4]{"entity": "select"}
    - [yes]{"entity": "select"}
    - [absolutely]{"entity": "select"}
    - [not really]{"entity": "select"}
    - [not at all]{"entity": "select"}

and custom action is

from cgitb import text
from email import message
from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk import Tracker, ValidationAction, Action
from rasa_sdk.types import DomainDict


class ValidateDateForm(ValidationAction):

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

    def validate_1st_qn(
        self,
        #slot_value: Any,
        domain_slots: List[Text],
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:  
        message = tracker.get_slot("1st_qn")
        l1 = ["1", "absolutely"]
        l2 = ["2", "yes", "yes i do"]
        l3 = ["3", "no", "not really"]
        l4 = ["4", "not at all"]
        if message in l1:
            dispatcher.utter_message(text="Brilliant!")
            return{"1st_qn": message}
        if message in l2:
            dispatcher.utter_message(text="Glad to know that.")
            return{"1st_qn": message}

    async def required_slots(
        self,
        domain_slots: List[Text],
        dispatcher: "CollectingDispatcher",
        tracker: "Tracker",
        domain: "DomainDict",
    ) -> List[Text]:
        
        additional_slots = []
        if tracker.slots.get("user_unhappy") is True:
            # If the user said he was unhappy add
            # new slot to ask the reason
            additional_slots.append("ask_reason")

        return additional_slots + domain_slots