While debugging, I found that when I enter a wrong answer to the slot, the validation works and set slot to null but it moves to the next slot question. And at the end, it goes to the null slots and asks for them again.
So, I need it to stuck in the slot until the user enter the right answer (like the behavior in Rasa version 1)
Here is my code:
Actions.py
class ValidateDebitGraceForm(FormValidationAction):
def name(self) -> Text:
return “validate_debit_date_and_grace_form”
def getRequiredSlots(self, tracker):
if tracker.get_slot("instruction_options") == "signup":
required_slots = ["instruction_options", "debit_date", "grace_period"]
else:
required_slots = ["instruction_options"]
print(required_slots)
return required_slots
async def run(self, dispatcher, tracker, domain):
events = await self.validate(dispatcher, tracker, domain)
required_slots = self.getRequiredSlots(tracker)
for slot_name in required_slots:
if tracker.slots.get(slot_name) is None:
# The slot is not filled yet. Request the user to fill this slot next.
events.append(SlotSet("requested_slot", slot_name))
return events
# All slots are filled.
events.append(SlotSet("requested_slot", None))
return events
def validate_instruction_options(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
if ("signup" in slot_value or "sign me up" in slot_value or "Sign Me Up" in slot_value) or (slot_value == "1"):
slot_value = "signup"
elif ("Send me a copy of the quote, I’m not sure yet" in slot_value) or (slot_value == "2"):
slot_value = "Send me a copy of the quote"
elif ("No, Thanks" in slot_value or "no thanks" in slot_value or "No thanks" in slot_value) or (slot_value == "3"):
slot_value = "No thanks"
else:
dispatcher.utter_message(template="utter_enter_valid_number")
return{"instruction_options": None}
return{"instruction_options": slot_value}
def validate_debit_date(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
try:
amount = int(slot_value)
if amount > 0 and amount < 32:
break
else:
dispatcher.utter_message(template="utter_enter_valid_number")
return {"debit_date": None}
except ValueError:
dispatcher.utter_message(template="utter_enter_valid_number")
return {"debit_date": None}
return {"debit_date": slot_value}
def validate_grace_period(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
try:
amount = int(slot_value)
if amount == 1 or amount == 2:
break
else:
dispatcher.utter_message(template="utter_enter_valid_number")
return {"grace_period": None}
except ValueError:
dispatcher.utter_message(template="utter_enter_valid_number")
return {"grace_period": None}
dispatcher.utter_message(template="utter_sent_doc_and_ask_anything_else")
dispatcher.utter_message(template="utter_ask_help")
return {"grace_period": slot_value}
domain.yml
forms:
debit_date_and_grace_form:
instruction_options:
- type: from_text
intent: inform
debit_date:
- type: from_text
intent: inform
grace_period:
- type: from_text
intent: inform