Different responses based on a slot is given or not

Hello everyone,

I would like to ask, how to make the assistant give a different response based on if a slot is filled or not?

Here is a part of my configuration:

slots:
    user:
        type: text
        influence_conversation: true

responses:
  utter_greet:
  - text: "Hey {user}! How can I help you?"
  - text: "Hi, what can I do for you?"

I supposed that "influence_conversation" == true would define the behaviour of the assistant by choosing one over the other response depending on the existence of the slot. But, Sometimes I am getting a response like “Hey None! How can I help you?” which is not the desired behaviour.

Do I have to create a custom action to have the desired behaviour?

So my thought is something like the above:

-user input: "Hello, I am Vangelis"
-assistant's response:
    if user_slot is filled then response:
        "Hey Vangelis, how can I help you?"
    elif user_slot is not filled then response:
        "Hey, how can I help you?"

@EvanMath Hi, please cross-check this code and I have only given you the basic idea about how you can get the user name.

In domain.yml

intents:
- inform

slots:
  user: 
    type: text
    influence_conversation: true

entities:
  - user

responses:
  uttter_ask_name:
 - text: " Please tell me you name"

  utter_greet:
  - text: "Hey {user}! How can I help you?"
  - text: "Hi {user}, what can I do for you?"

actions:
- action_greet

In nlu.yml


- intent:inform
examples: |
- [Tom](user)
- [Lisa](user)
- It is [Tom](user)
- My name is [Bob](user)

In stories.yml


## Ask name
stories:
  - story: welcome path1
    steps:
      - intent: utter_ask_name
      - action: utter_greet
    

In action.py

class ActionGreet(Action):

     def name(self) -> Text:
         return "action_greet"

     def run(self, dispatcher: CollectingDispatcher,
             tracker: Tracker,
             domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
            
         user=tracker.get_slot("user") 
         dispatcher.utter_message(template="utter_greet")
         
         return []

You can customise this code as per your user case. Good Luck!

I hope this will solve your issue.

1 Like

I hoped for a simpler approach :sweat_smile:. Thank you @nik202 .

I just want to add; you can do this as well:

Completely discard utter_greet and use action_greet instead. Keep your stories and everything the same as originally except for renaming the action.

Then, in the action, you check if the user has given his name and utter the according message.

class ActionGreet(Action):
    def name(self):
        return "action_greet"

    def run(self, dispatcher, tracker, domain):
        if (user := tracker.get_slot("user")):
            dispatcher.utter_message(f"Hey {user}! How can I help you?")
        else:
            dispatcher.utter_message("Hi, what can I do for you?")

        return []
1 Like

Thank you @ChrisRahme . I have a question in this block:

what this part := means?

1 Like

Ah, this is the Walrus Operator, introduced in Python 3.8 :slight_smile:

x := y will set x to y and return its value. So this

if (user := tracker.get_slot("user")):
    ...

is equivalent to this

user = tracker.get_slot("user")
if (user):
    ...

The if block will be executed if user is neither False, None (which is the main check here), nor 0.

1 Like