How to set a slot value in custom form?

Hi

How do I set slot values hard? I get warnings (see below). I am trying to solve this problem for a VERY long time. I think the way i set the slot is not correct! But I am not sure if this is the origin of my warning. The bot behaves correct, it is just the warning that worries me a lot!

I want to ask for specific user informations:

  • What is your first name?
  • What is you last name?
  • What is your street name?
  • What is your house number?

Therefore I use a custom form which asks the user to get all these data.

I am not sure, how the value which is given by the user is stored in the slot.

This is what I do:

domain.yml:

intents:
- name
- name_last
- street_name
- house_number

entities:
- name
- name_last
- street_name
- house_number

slots:
  name:
    type: unfeaturized
  name_last:
    type: unfeaturized
  street_name:
    type: unfeaturized
  house_number:
    type: unfeaturized

actions:
   - utter_ask_name
   - utter_ask_name_last
   - utter_ask_street_name
   - utter_ask_house_number

forms:
- authenticate_form

templates:

  utter_ask_name:
    - text: What is your first name?
      buttons:
        - title: "FirstName"
          payload: "name"

  utter_ask_name_last:
    - text: What is your last name?
      buttons:
        - title: "LastName"
          payload: "name_last"

actions.py:


class AuthenticateForm(FormAction):

    def name(self):
        # type: () -> Text
        return "authenticate_form"

    @staticmethod
    def required_slots(tracker):
        # type: () -> List[Text]

        return ["name", "name_last", "street_name", "house_number"]

    def submit(self, dispatcher, tracker, domain):
        # type: (CollectingDispatcher, Tracker, Dict[Text, Any]) -> List[Dict]
        """
        Define what the form has to do after all required slots are filled
        """
        return []

    def slot_mappings(self):
        # type: () -> Dict[Text: Union[Dict, List[Dict]]]

        return {
            "name": [self.from_entity(entity="name", not_intent=["chitchat"])],
            "name_last": [self.from_entity(entity="name_last", not_intent=["chitchat"])],
            "street_name": [self.from_entity(entity="street_name", not_intent=["chitchat"])],
            "house_number": [self.from_entity(entity="house_number", not_intent=["chitchat"])]
        }

    def validate(self,
                 dispatcher: CollectingDispatcher,
                 tracker: Tracker,
                 domain: Dict[Text, Any]) -> List[Dict]:

     .....
         for slot, value in slot_values.items():

            if slot == 'name':

                if ...:
                    slot_values[slot] = value
                else:
                    slot_values[slot] = None

            if slot == 'street_name':

                if ...:
                    slot_values[slot] = value
                else:
                    slot_values[slot] = None

            ....

        return [SlotSet(slot, value) for slot, value in slot_values.items()]

stories.md:

## story_form_happy_path
- authenticate_form
- form{"name": "authenticate_form"} 
- slot{"name": "Sam"}    
- slot{"name_last": "Johns"} 
- slot{"street_name": "Gartenstrasse"}
- form{"name": null} 

This approach works, but I get the following warnings:

UserWarning: Interpreter parsed an intent 'name:' that is not defined in the domain.

UserWarning: Interpreter parsed an intent 'name_last:' that is not defined in the domain.

UserWarning: Interpreter parsed an intent 'street_name:' that is not defined in the domain.

UserWarning: Interpreter parsed an intent 'house_number:' that is not defined in the domain.

This is strange, since these intents are clearly defined in my domain-file. So, how do I set the slot value correctly?

Hello @Chatbot_Ra,

I think you need to put ‘/’ in front of the intent in the button’s payload, like this: /name and /name_last.

Can you try this and see how it goes ?

This is what you suggests:

templates:

  utter_ask_name:
    - text: What is your first name?
      buttons:
        - title: "FirstName"
          payload: "/name"

  utter_ask_name_last:
    - text: What is your last name?
      buttons:
        - title: "LastName"
          payload: "/name_last"

This doesn’t help. THis way I can not set the slot, because now in the dialog there will be a button “FirstName” and “LastName”. I do not want an button, I want to set the slot.

The way I suggest it is working. However, I get these strange warnings (see my first post)

Instead of implementing all the slots in validate, you might also want to consider using the following method syntax:

def validate_<your_slot>

This way you won’t have to handle that logic yourself. Also, is there any reason why you are defining all those slots in your story? This would be enough unless you are setting those other slots along with them in your custom action server:

 # Example form
 - auth_form
 - form{"name" : "auth_form"}
 - form{"name": null}

The form policy has the highest priority unless you define your own custom policies. Like in your previous post, you most likely don’t need those intents and should opt for something else. For more information regarding forms, please consult the wiki Forms

@Mappi: Sure, thanks for your answer. I will consider this in the future! I am still a beginer and there is a lot to learn.

I thought this is the way to to it. Can I remove these values in the stories.md file?

What about the warning I get all the time (please see my first post)? You have any idea where this comes from?

I think I’ve mentioned it in a different post, but it seems to be picking up “name:” instead of “name”. I would need to see other parts (Maybe the rest of stories or the NLU data).

If we look at the source code of that warning this is what it does:

    ...
    f"Interpreter parsed an intent '{intent}' "
                "that is not defined in the domain."

Thanks, I remember you said this. I checked the complete project, but could not find anything. But I totaly agree with you: it seems strange that is says name: and not name.

However, since I recently upgraded to the latest Rasa version and the problem was never there before, I think the solution to the problem is more fundamental.