What i am trying to accomplish is create a dynamic form. A user can create a request for a schedule with a teacher.
Form has 2 required slots. Teachers email and date.
When the user inputs the email i use the technique shown in the rasa documentation to update the required_slots by overriding it. This works:
before user inputs email and slot is empty:
[‘scheduled_meeting_teacher_email’, ‘scheduled_meeting_date’]
after user inputs the email and the slot(scheduled_meeting_teacher_email) is filled:
[‘scheduled_meeting_correct_teacher_email’, ‘scheduled_meeting_teacher_email’, ‘scheduled_meeting_date’]
So the next required slot becomes scheduled_meeting_correct_teacher_email
Based on the documentation is now expect utter_ask_scheduled_meeting_correct_teacher_email to be triggered. But that never happens. I can see that the next step becomes extract_scheduled_meeting_correct_teacher_email which i build around the showcase shown here: (18) Customise a Form to Properly Ask for Names | Rasa Tutorials - YouTube which seemed like a pretty good trick.
But since utter_ask_ never got triggered this just
At this point i imagine that i am either missing something or the version difference means that this no longer works or i have to change something more that i cant figure out. I believe that the mappings is the source of this but maybe i am wrong.
So yeah. How do i make this work? Any help will be super appreciated.
Here is the code:
class ValidateScheduledMeetingWithTeacherForm(FormValidationAction):
def name(self) -> Text:
return "validate_scheduled_meeting_with_teacher_form"
async def required_slots(self, domain_slots, dispatcher, tracker, domain):
updated_slots = domain_slots.copy()
if tracker.get_slot("scheduled_meeting_teacher_email") and tracker.get_slot("scheduled_meeting_correct_teacher_email")==None:
updated_slots = ["scheduled_meeting_correct_teacher_email"] + updated_slots
if tracker.get_slot("scheduled_meeting_date") and tracker.get_slot("scheduled_meeting_correct_date")==None:
updated_slots = ["scheduled_meeting_correct_date"] + updated_slots
print(updated_slots)
return updated_slots
async def extract_scheduled_meeting_correct_teacher_email(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict
) -> Dict[Text, Any]:
intent = tracker.get_intent_of_latest_message()
return {"scheduled_meeting_correct_teacher_email": intent == "user_affirm"}
def validate_scheduled_meeting_correct_teacher_email(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
if tracker.get_slot("scheduled_meeting_correct_teacher_email"):
return {"scheduled_meeting_teacher_email": tracker.get_slot("scheduled_meeting_teacher_email"), "scheduled_meeting_correct_teacher_email": True}
return {"scheduled_meeting_teacher_email": None, "scheduled_meeting_correct_teacher_email": None}
async def extract_scheduled_meeting_correct_date(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
intent = tracker.get_intent_of_latest_message()
return {"scheduled_meeting_correct_date": intent == "user_affirm"}
def validate_scheduled_meeting_correct_date(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
if tracker.get_slot("scheduled_meeting_correct_date"):
return {"scheduled_meeting_date": tracker.get_slot("scheduled_meeting_teacher_email"), "scheduled_meeting_correct_date": True}
return {"scheduled_meeting_date": None, "scheduled_meeting_correct_date": None}
def validate_scheduled_meeting_teacher_email(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
try:
if slot_value=="test@uni.com":
return {"scheduled_meeting_teacher_email": slot_value}
else:
return {"scheduled_meeting_teacher_email": None}
except ValueError:
return {"scheduled_meeting_teacher_email": None}
def validate_scheduled_meeting_date(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
try:
# Parse the date with the expected format
date_obj = datetime.strptime(slot_value, "%d/%m/%Y")
today = datetime.today()
min_date = today + 1
max_date = today + timedelta(days=30)
# Check if the date is within the range
if date_obj <= min_date <= max_date:
return {"scheduled_meeting_date": slot_value}
else:
return {"scheduled_meeting_date": None }
except ValueError:
return {"scheduled_meeting_date": None }
My slots:
scheduled_meeting_teacher_email:
type: text
influence_conversation: true
mappings:
- type: from_entity
entity: university_email
conditions:
- active_loop: scheduled_meeting_with_teacher_form
requested_slot: scheduled_meeting_teacher_email
scheduled_meeting_date:
type: text
influence_conversation: true
mappings:
- type: from_entity
entity: date
conditions:
- active_loop: scheduled_meeting_with_teacher_form
requested_slot: scheduled_meeting_date
scheduled_meeting_correct_teacher_email:
type: bool
initial_value: null
influence_conversation: true
mappings:
- type: custom
scheduled_meeting_correct_date:
type: bool
initial_value: null
influence_conversation: true
mappings:
- type: custom
And my responses:
utter_ask_scheduled_meeting_teacher_email:
- text: "Ποιο είναι το email του/της καθηγητή/καθηγήτριας που θέλεις να συναντήσεις;"
utter_ask_scheduled_meeting_date:
- text: "Ποια ημερομηνία θα σε ενδιέφερε;"
utter_ask_scheduled_meeting_correct_teacher_email:
- text: "To email που δήλωσες είναι: . Συμφωνείς;"
buttons:
- title: "Ναι"
payload: '/user_affirm'
- title: "Οχι"
payload: '/user_deny'
utter_ask_scheduled_meeting_correct_date:
- text: "Η ημερομηνίας που δήλωσες είναι: . Συμφωνείς;"
buttons:
- title: "Ναι"
payload: '/user_affirm'
- title: "Οχι"
payload: '/user_deny'