I am using the latest version of rasa
rasa==3.6.20
rasa-sdk==3.6.2
I have a form during the validation of a slot in the form i want to move to an action to trigger an new form . how to achieve the same .
I tried to overriding next_requested_slot method to trigger to an Action but i does not triggering the Action , how to achieve it ?
This piece of code is written in next_requested_slot method.
if go_to_form in ["affirm"]:
print("Enterted Here in go to form")
return [
FollowupAction(name="action_name"),
]```
If this is wrong , please suggest me a way to either trigger to a new form from a form or trigger an action from a form , from a validation of a form
from rasa_sdk import Action, FormValidationAction
from rasa_sdk.events import FollowupAction, SlotSet
class ValidateMyForm(FormValidationAction):
def name(self) → Text:
return “validate_my_form”
def validate_my_slot(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate slot_value."""
if slot_value == "some_value":
# Trigger a new form
dispatcher.utter_message(text="Switching to new form")
return {
"my_slot": slot_value,
"next_form": "my_new_form_name"
}
else:
# Handle invalid slot value
dispatcher.utter_message(text="Invalid slot value.")
return {"my_slot": None}
class MyNewForm(Form):
def name(self) → Text:
return “my_new_form_name”
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
"""A list of required slots that the form has to fill."""
return ["slot1", "slot2"]
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
"""A dictionary to map required slots to
- an extracted entity
- intent: intent name
- custom slot validation
"""
return {
"slot1": self.from_entity(entity="slot1_entity"),
"slot2": self.from_entity(entity="slot2_entity"),
}
Explanation:
ValidateMyForm:
validate_my_slot: This method validates the value of the my_slot.
If slot_value meets the condition (e.g., slot_value == “some_value”), it:
Sets the my_slot with the valid value.
Sets the next_form to the name of the new form (“my_new_form_name”). This signals to Rasa that the current form should be exited and the new form should be activated.
If the slot_value is invalid:
Sets my_slot to None (indicating an invalid value).
Sends an error message to the user.
MyNewForm:
This is the new form that will be triggered when the condition in validate_my_slot is met.
required_slots: Defines the list of slots that the new form needs to fill.
slot_mappings: Specifies how to extract the values for each required slot.
Key Points:
next_form Event: The key to triggering a new form within a form validation is to set the next_form event in the validate_slot method.
Form Switching: Rasa will automatically switch to the specified next_form when this event is triggered.
Clean and Organized Code: This approach provides a structured and maintainable way to handle form switching within your Rasa forms.
Note:
Replace “my_slot”, “my_new_form_name”, “slot1”, “slot2”, and “some_value” with the actual names of your slots and forms.
Adjust the validation logic and slot mappings according to your specific requirements.
This refined approach demonstrates how to effectively trigger a new form from within an existing form’s validation in Rasa, ensuring a smooth and intuitive user experience.
To trigger a new form or an action from within the validation method of a form in Rasa, you should use the FollowupAction event correctly within your validation method. Overriding the next_requested_slot method might not always work as intended. Instead, you can handle this within the validation method itself.
Here’s an example of how you can achieve this:
Validation Method:
In your custom action for the form, override the validate method to include your logic.
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.events import SlotSet, FollowupAction
class ValidateFormAction(Action):
def name(self):
return "validate_form_action"
def validate_slot_name(
self,
value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict[Text, Any]]:
if value.lower() == "affirm":
dispatcher.utter_message(text="Starting new form...")
return [FollowupAction(name="new_form_action")]
return [SlotSet("slot_name", value)]
Form Action:
Define the action that you want to trigger as the new form.
class NewFormAction(Action):
def name(self):
return "new_form_action"
def run(self, dispatcher, tracker, domain):
# Your logic for the new form
return []
Domain File:
Ensure that both actions are properly listed in your domain file under actions.
actions:
- validate_form_action
- new_form_action
Stories or Rules:
Define the flow in your stories or rules to handle transitions.
Story Example:
stories:
- story: Form to New Form Transition
steps:
- intent: your_intent
- action: form_action
- active_loop: form_action
- slot_was_set:
- slot_name: "affirm"
- action: new_form_action
- active_loop: new_form_action
By using the FollowupAction event within the validation method, you can trigger another action or form based on the slot value. This should help you achieve the desired behavior.