I’m trying to use the Rasa form example on github and I have a problem with the dynamic slots: the first_name slot is being set over and over, througout the form. Everytime another slot is asked.
This is the log of the interactive shell:
Chat History
──────────────────────────────────────────────────────────────────────────────────
6 can I sign up ?
intent: signup 0.98
──────────────────────────────────────────────────────────────────────────────────
7 signup_form 1.00
active_loop{"name": "signup_form"}
slot{"requested_slot": "first_name"}
What is your first name? <-- asks for first_name (the source of the problem)
slot{"first_name": "Syker"}
Thank you It's Syker <-- already failed interactive labeling !!!
slot{"name_spelled_correctly": null}
slot{"first_name": "It's Syker"}
slot{"requested_slot": "name_spelled_correctly"}
Are you sure it's spelled correctly? <-- said no, you got it wrong
slot{"name_spelled_correctly": null}
slot{"first_name": null}
slot{"requested_slot": "first_name"}
Can I have you first name, please? <-- try with first_name only
slot{"first_name": "Syker"}
Thank you Syker <-- verify first_name
slot{"name_spelled_correctly": null}
slot{"first_name": "Syker"}
slot{"requested_slot": "name_spelled_correctly"}
Are you sure it's spelled correctly? <-- unknown name: ok
slot{"name_spelled_correctly": true}
slot{"first_name": "Syker"}
slot{"requested_slot": "last_name"}
Can I have you last name, please? <-- switch to last_name
slot{"name_spelled_correctly": null}
slot{"last_name": "Wazabi"}
slot{"first_name": null}
slot{"requested_slot": "first_name"}
What is your first name? <--- failed: first_name is not set !!!
slot{"first_name": "Syker"}
... <-- verify first_name + unknown: ok
I need your email address. <-- switch to email
slot{"email": "whatever@gmail.com"}
slot{"name_spelled_correctly": null}
slot{"email": "whatever@gmail.com"}
slot{"first_name": null}
slot{"requested_slot": "first_name"}
Can I have you first name, please? <--- failed: first_name is not set !!!
slot{"first_name": "Syker"}
... <-- verify first_name + unknown: ok
slot{"first_name": "Syker"}
slot{"requested_slot": null}
slot{"requested_slot": null}
active_loop{"name": null}
This is my form validation in action.py
:
from typing import Text, List, Any, Dict, Optional
import pathlib
from rasa_sdk import Tracker, FormValidationAction
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict
NAMES = pathlib.Path("data/names.txt").read_text().split("\n")
class ValidateNameForm(FormValidationAction):
def name(self) -> Text:
return "validate_signup_form"
async def required_slots(self, slots_mapped_in_domain, dispatcher, tracker, domain,):
first_name = tracker.slots.get('first_name')
print(first_name)
if first_name is not None:
if first_name not in NAMES:
print('Unknown first name. Checking for correctness.')
return ['name_spelled_correctly'] + slots_mapped_in_domain
last_name = tracker.slots.get('last_name')
email = tracker.slots.get("email")
return slots_mapped_in_domain
def validate_email(self, slot_value, dispatcher, tracker, domain):
# for now
if not '@' in slot_value or len(slot_value) <= 3:
dispatcher.utter_message(text=f"Your email doesn't seem correct. I'm assuming you mis-spelled.")
return {"email": None}
else:
return {"email": slot_value}
def validate_first_name(self, slot_value, dispatcher, tracker, domain):
"""Validate `first_name` value."""
# If the name is super short, it might be wrong.
intent = tracker.get_intent_of_latest_message()
if intent == 'deny':
return {'first_name': None}
print(f"First name given = {slot_value} length = {len(slot_value)}")
if len(slot_value) < 2:
dispatcher.utter_message(text=f"That's a very short name. I'm assuming you mis-spelled.")
return {"first_name": None}
else:
dispatcher.utter_message(text=f'Thank you {slot_value}')
return {"first_name": slot_value}
def validate_last_name(self, slot_value, dispatcher, tracker, domain):
"""Validate `last_name` value."""
# If the name is super short, it might be wrong.
if len(slot_value) < 2:
dispatcher.utter_message(text=f"That's a very short name. I'm assuming you mis-spelled.")
return {"last_name": None}
else:
return {"last_name": slot_value}
async def extract_name_spelled_correctly(self, dispatcher, tracker, domain):
intent = tracker.get_intent_of_latest_message()
return {"name_spelled_correctly": intent == "affirm"}
def validate_name_spelled_correctly(self, slot_value, dispatcher, tracker, domain):
"""Validate name spelled correctly"""
if tracker.get_slot("name_spelled_correctly"):
return {"first_name": tracker.get_slot("first_name"), "name_spelled_correctly": True}
return {"first_name": None, "name_spelled_correctly": None}
``