Rules for unhappy path or any other rulles doesn't work during custom slot mapping

Rules are not working properly when slots are filled by custom slot mapping

  • rule: wrong hotel name
    - active_loop : hotel_booking_form
    - intent: hotel_negative
    - action: action_hotel_change
    - action: hotel_booking_form
    - active_loop: hotel_booking_form

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(
            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)

@ChrisRahme is this a common issue or am i doing something wrong ? I followed your suggestions to do custom mapping

Hey Athul,

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:

- rule: Activate form
  - intent: log_in
  - action: form_log_in
  - active_loop: form_log_in

- rule: Submit form
  - active_loop: form_log_in
  - action: form_log_in
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  - action: action_submit_form_log_in

I wrote separate rules to handle each unhappy path (for slots person_name, hotel_name, check_in,)

This is the story:

  • story: test steps:
    • intent: room_booking
    • action: hotel_booking_form
    • active_loop : hotel_booking_form

and these are some among the rules, when a user wants to edit the slot value:

- rule: wrong name
  - active_loop: hotel_booking_form
  - intent: name_negative
  - action: action_name_change
  - action: hotel_booking_form
  - active_loop: hotel_booking_form

- rule: wrong phone
  - active_loop: hotel_booking_form
  - intent: phone_negative
  - action: action_phone_change
  - action: hotel_booking_form
  - active_loop: hotel_booking_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 :slight_smile:

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

  • rule: fallback during hotel booking condition:
    • active_loop: hotel_booking_form steps:
    • intent: nlu_fallback
    • action: utter_default
    • action: hotel_booking_form
    • active_loop: hotel_booking_form

Again, no need for rules other than starting and ending a form. Try to use stories instead.

Anyway, I don’t think you may need to do that as a rule or story, the form should continue after fallback (I could be wrong).

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 .

I’m having the same issue.

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.

1 Like

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()]
1 Like

Sorry for the late reply, I’m glad you got it working :slight_smile: Please mark your post as solution

i still have the problem of handling chitchat and faq during custom custom slot mapping, chitchat works fine during predefined slot mapping.

check this comment, tell me if this works


I did end up getting it working.

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.