I have a rule which should perform the action action_hotel_change when the intent hotel_negative is triggered during active_loop of hotel_booking_form . In the form hotel_booking_form, first two slots (hotelname, person) are mapped by custom slot mapping.
RASA doesn’t perform action_hotel_change even if it classify the phrase into the intent `hotel_negative’ until it starts asking prompt for slots in the domain file (predefined mapping). I feel the form is not active during custom slot mapping correct me if I am wrong.
class ValidateHotelBookingForm(FormValidationAction):
def name(self) -> Text:
return "validate_hotel_booking_form"
async def required_slots(
self,
slots_mapped_in_domain: List[Text],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: "DomainDict",
) -> Optional[List[Text]]:
custom_slot_list = ["hotelname","person"]
for i in custom_slot_list:
if not tracker.get_slot(i):
return [i] + slots_mapped_in_domain
return slots_mapped_in_domain
def extract_hotelname(self, dispatcher, tracker, domain):
name = next(tracker.get_latest_entity_values("hotel_name"),None)
return {"hotelname": name}
I also wrote a rule to handle chitchat and faq, this doesn’t work during custom slot mapping (after asking prompt for slots mapped by custom mapping)
I’m not sure if this is the solution, but why do you have a rule only for when the hotel name is wrong? All this should be handled dynamically inside the form. The only rule I’d have are to activate and deactivate the form:
is there a better way to do it?
I will try the solution you mentioned, but still I would need rules to for each unhappy path, right? to triigger an intent and perform an action to reset that particular slot
I’ve recently written this post as an answer to a very similar question (I even thought you were the same person!), hope it can help
It would be better (I think) to detect the intents name_negative and phone_negative inside the FormValidationAction and change the required slots depending on that.
one other doubt, if a user inputs an out of scope phrase during slot filling, and after uttering default_fallback sentence , will it return back to the form filling. This is how i wrote for fallback during form filling not sure if this is right
I checked the post you mentioned above, In that user can request to change a slot only at the end of the form filling. And the fucntion validate_slot_to_correct() works only when the slot value slot_to_correct is updated. Is there any way we can make a function to work at every every iteration of form filling .
When I use forms without defining my own custom slots all works well.
As soon as I add custom slots, an extract method for the slot and a validate method - The rules for handling chitchat, explain intents etc stop working.
I solved the problem in updating the slot value using the following code, this worked for custom slot filling too
async def validate(self, dispatcher, tracker, domain):
intent = tracker.get_intent_of_latest_message()
slots: Dict[Text, Any] = tracker.slots_to_validate()
if intent == "name_negative":
person_name = name_change(dispatcher, tracker) #fucntion to extract name
return [SlotSet('person', person_name)]
if intent == "hotel_negative" and slots['hotelname']:
hotelname = hotel_change(dispatcher,tracker) #function to extract hotel name
return [SlotSet('hotelname', hotelname)]
return [SlotSet(slot, value) for slot, value in slots.items()]
In the extract method I returned an empty dictionary when the value doesn’t match what I am looking for.
In the validate method, I return a dictionary of the slot value if the validation is a success and if it fails then i return:
return {"slot_name": None}
This along with the rules and stories seems to work as expected now.
Another issue I discovered was that when some of my slots had “influence_conversation: true” with a null initial value, rules stopped working as expected.
There seemed to be a bug with this working with the rules so after either setting an initial value, or setting influence conversation to false, the rules started working as expected.