Form exits when extracting slot fails

Hi,

I have a form that extracts a 3 entities, 2 cities and date. The date entity is extracted using duckling. I also have a form validation action to pre-process and validate the 3 entities. My issue is that the form exits when no date is recognised during the date exctraction. The form exits before the date validation function is excuted and the bot simply utters a random utterance or a response based on the intent that it classified.

I am running rasa version 2.4.3

My form is as follows:

  flight_form:
    departure_city:
      - type: from_entity
        entity: city
        role: from
      - type: from_entity
        entity: city
    arrival_city:
      - type: from_entity
        entity: city
        role: to
      - type: from_entity
        entity: city
    departure_date:
      - type: from_entity
        entity: time

My date validation function is as follows:

    def validate_departure_date( 
        self,
        slot_value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> List[EventType]:

        print('validate_departure_date')

        grain = None
        try:
            entity = tracker.latest_message['entities']
            grain = entity[0]['additional_info']['grain']
        except:
            dispatcher.utter_message(text = "I didn't quite get that. Please rephrase the date!")
            return {"departure_date": None}

        if grain == 'week':
            dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
            return {"departure_date": None}

        elif grain == 'month':
            dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
            return {"departure_date": None}

        elif grain == 'year':
            dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
            return {"departure_date": None}

        else:
            return {"departure_date": slot_value[:10]}

And my rule is as follows:

- rule: activate book flight form
  steps:
  - intent: book_flight
  - action: flight_form
  - active_loop: flight_form

- rule: submit book flight form
  condition:
  - active_loop: flight_form
  steps:
  - action: flight_form
  - active_loop: null
  - slot_was_set:
    - requested_slot: null
  - action: action_confirm_flight

Can you provide the debug log? Does the action server report any errors?

This :point_up: is a screenshot of the debug log when I’m testing the validation.

When I enter an invalid date, and the classifier always classifies the first word of the text I enter to be the entity ‘city’ even though I have a lookup table for my cities (This is issue number 1). Issue number 2 is that on the debug log, ‘validate_flight_form’ is called but there is no ‘departure_date’ slot to validate so on the action server, my ‘validate_departure_date’ function is never called.

@SangeMax97 I have a similar problem. I have also configured the out of scope and fallback policies. So when I give answers like this in the form, it’s recognized as out of scope intent and giving that response. After this I need an empty message from the user side to get back to the form. Idk why this is happening

After spending some time coming up with different solutions I found a simple one that works. Instead of extracting the date entity, I capture the whole user utterance using the from_text mapping and extract the date inside the validation function. Here’s how my files now look…

My form:

  flight_form:
    departure_city:
      - type: from_entity
        entity: city
        role: from
      - type: from_entity
        entity: city
    arrival_city:
      - type: from_entity
        entity: city
        role: to
      - type: from_entity
        entity: city
    departure_date:
      - type: from_text

New validation function:

    def validate_departure_date( 
        self,
        slot_value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> List[EventType]:

        print('validate_departure_date')
        print(slot_value)

        grain = None
        try:
            payload = {
                'locale':'en_US',
                'text': slot_value
            }
            #  Duckling server running on http://app.botlhale.io:8000
            request = requests.post('http://app.botlhale.io:8000/parse', data=payload)
            response = request.json()[0]

            grain = response['value']['grain']
            date = response['value']['value']

            if grain == 'week':
                dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
                return {"departure_date": None}

            elif grain == 'month':
                dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
                return {"departure_date": None}

            elif grain == 'year':
                dispatcher.utter_message(text = "That's too vague. Please specify an exact date or day!")
                return {"departure_date": None}

            else:
                return {"departure_date": date[:10]}
            
        except:
            dispatcher.utter_message(text = "I didn't quite get that. Please rephrase the date!")
            return {"departure_date": None}

And my rule remains unchanged

Thanks for the log. You should consider an out of scope intent for gibberish like this example in the rasa-demo.

For the city entity extraction, have you tried Spacy as recommended here.

@stephens I did put all these examples in out of scope intent. But the form closes once this out of scope intent is identified. Shouldn’t the form continue from where ever it was left with before uttering this intent?

I don’t see that you have an example rule/story directing the form to continue after an out of scope intent.

You can find a discussion of this in the Forms docs with the chitchat intent.

1 Like