Different responses depending on boolean slots

Hello, I’m a student trying to do a project for the university and I don´t have much experience with this application and with programming in general. I am trying to do a (experimental) chatbot that changes behaviour depending on the time that it is been asked. So, I did some actions to know what time is it and to change some boolean slots to influence the conversation. I am not getting good results and I would like to know if it is because Rasa is not prepared for this or maybe I am the one not doing things correctly. This is how two similar stories would look:

story: greet
steps:
  - intent: greet
  - action: action_check_tiredness
  - slot_was_set:
    - available: True
  - slot_was_set:
    - not_tired: True
  - action: utter_greet

- story: greet early
  steps:
  - intent: greet
  - action: action_check_tiredness
  - slot_was_set:
    - available: False
  - slot_was_set:
    - early: True
  - action: utter_greet_early

and slots:

> available:
>     type: bool
>     influence_conversation: true
>   
>   early:
>     type: bool
>     influence_conversation: true
> 
>   not_tired:
>     type: bool
>     influence_conversation: true

Hi @losunitis, is it behaving as expected when you test the training stories above? Also, would you be able to share what your training story data looks like?

Hi @b-quachtran, sorry for the late answer. My idea was to fill some slots with an action that gets the current time at the start of the session and then influence the answers depending on those slots. When I had only one slot = tired: false/true it was working ok, the problem arrives when I have different slots such as: early, not_tired, after_lunch, late, asleep. Maybe this are too many slots to fill and that is what is confusing the program. For now, sometimes it works and sometimes it does’t answer. Here is all my code until now:

stories:

- story: run change slots
  steps:
  - intent: run_change
  - action: action_change_true_false

- story: run tired action
  steps:
  - intent: run_tired
  - action: action_check_working_hours

- story: tired
  steps:
  - intent: ask_tiredness
  - slot_was_set:
    - tired: True
  - action: utter_tired_state

- story: not tired
  steps:
  - intent: ask_tiredness
  - slot_was_set:
    - tired: False
  - action: utter_nottired_state

- story: run weekend action
  steps:
  - intent: run_weekend
  - action: action_check_weekend

- story: weekend
  steps:
  - intent: ask_weekend
  - slot_was_set:
    - week: True
  - action: utter_in_not_weekend

- story: weekday
  steps:
  - intent: ask_weekend
  - slot_was_set:
    - week: False
  - action: utter_is_weekend

- story: run reset slots
  steps:
  - intent: run_resetSlot
  - action: action_slot_reset

- story: say slot value
  steps:
  - intent: ask_slot_value
  - action: utter_slot_value

## diferent greet

- story: run reset slots
  steps:
  - intent: run_day_state
  - action: action_check_day_state

- story: run startSession
  steps:
  - intent: run_reset_sesion
  - action: action_session_start

- story: greet early
  steps:
  - intent: greet
  - slot_was_set:
    - early: True
  - action: utter_greet_early

- story: greet not tired
  steps:
  - intent: greet
  - slot_was_set:
    - not_tired: True
  - action: utter_greet_not_tired

- story: greet after lunch
  steps:
  - intent: greet
  - slot_was_set:
    - after_lunch: True
  - action: utter_greet_after_lunch

- story: greet late
  steps:
  - intent: greet
  - slot_was_set:
    - late: True
  - action: utter_greet_late

- story: greet asleep
  steps:
  - intent: greet
  - slot_was_set:
    - asleep: True
  - action: utter_greet_asleep

NLU: nlu: - intent: greet examples: | - hey - hello - hi - hello there - good morning - good evening - moin - hey there - let’s go - hey dude - goodmorning - goodevening - good afternoon

- intent: ask_weekend
  examples: |
    - what day is it?
    - tell me the day 
    - day?

- intent: run_tired
  examples: |
    - run tiredness
    - run tired action

- intent: run_weekend
  examples: |
    - run weekend
    - run week
    - weekend

- intent: run_resetSlot
  examples: |
    - reset
    - reset slots
    - run reset slots

- intent: ask_slot_value
  examples: |
    - slot values
    - values?
    - slots

- intent: ask_tiredness
  examples: |
    - are you tired?
    - tired?

- intent: run_day_state
  examples: |
    - run state action
    - run state

- intent: run_change
  examples: |
    - run change action
    - run change

- intent: run_reset_sesion
  examples: |
    - run start sesion 
    - run start

domain: version: “2.0”

intents:
  - greet
  - run_tired
  - run_weekend
  - ask_weekend
  - run_resetSlot
  - ask_slot_value
  - ask_tiredness
  - run_day_state
  - run_change
  - run_reset_sesion
slots:

  tired:
    type: bool
    influence_conversation: true  

  week:
    type: bool
    influence_conversation: true  

  early:
    type: bool
    influence_conversation: true 

  not_tired:
    type: bool
    influence_conversation: true 

  after_lunch:
    type: bool
    influence_conversation: true

  late:
    type: bool
    influence_conversation: true

  asleep:
    type: bool
    influence_conversation: true

responses:
  
  utter_tired_state:
  - text: "I am tired"
  
  utter_nottired_state:
  - text: "I am not tired"

  utter_is_weekend:
  - text: "It is the weekend!"
  
  utter_in_not_weekend:
  - text: "It is a week day :("
  
  utter_slot_value:
  - text: "Tired: {tired} | Week: {week} | Early: {early} | Not tired: {not_tired} | After lunch: {after_lunch} | Late: {late} | Asleep: {asleep}"

  utter_greet_early:
  - text: "Coffee please..."

  utter_greet_not_tired:
  - text: "Hey! Nice day!"

  utter_greet_after_lunch:
  - text: "Hello"

  utter_greet_late:
  - text: "Too late!"

  utter_greet_asleep:
  - text: "Zzzz..."
actions:
  - action_session_start
  - action_change_true_false
  - action_check_day_state
  - action_check_working_hours
  - action_check_weekend
  - action_slot_reset

session_config:
  session_expiration_time: 60
  carry_over_slots_to_new_session: true

actions:

# This files contains your custom actions which can be used to run
# custom Python code.
#
# See this guide on how to implement these action:
# https://rasa.com/docs/rasa/custom-actions


# This is a simple example for a custom action which utters "Hello World!"

from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.events import AllSlotsReset
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.events import SlotSet, SessionStarted, ActionExecuted, EventType
from datetime import datetime, date
import datetime as dt

class ActionSessionStart(Action):
    def name(self) -> Text:
        return "action_session_start"

    def run(self, dispatcher, tracker, domain):
        # type: (CollectingDispatcher, Tracker, Dict[Text, Any]) -> List[Dict[Text, Any]]
        
        now = dt.datetime.now()
        tdy8am = now.replace(hour=8, minute=0, second=0, microsecond=0)
        tdy16pm = now.replace(hour=16, minute=0, second=0, microsecond=0)
       
        #available= tracker.get_slot("available")
        tired = tracker.get_slot("tired") 

        if now > tdy8am and now < tdy16pm:
            #available=True
            tired=False  
        else: 
            #available=False
            tired=True

        x = datetime.today()
        weekno = x.weekday()

        week= tracker.get_slot("week")

        if weekno < 5:
            week= True
        else:
            week= False

        today6am = now.replace(hour=6, minute=0, second=0, microsecond=0)
        today8am = now.replace(hour=8, minute=0, second=0, microsecond=0)
        today14pm = now.replace(hour=14, minute=0, second=0, microsecond=0)
        today16pm = now.replace(hour=16, minute=0, second=0, microsecond=0)
        today23pm = now.replace(hour=23, minute=0, second=0, microsecond=0)
        today1am = now.replace(hour=1, minute=0, second=0, microsecond=0) 
       
        early = tracker.get_slot("early") 
        after_lunch = tracker.get_slot("after_lunch") 
        late = tracker.get_slot("late") 
        asleep = tracker.get_slot("asleep") 
        not_tired = tracker.get_slot("not_tired")

        if now > today6am and now < today8am:
            early= True 
        elif now > today14pm and now < today16pm:
            after_lunch = True    
        elif now > today16pm and now < today23pm:
            late= True
        elif now > today23pm and now < today6am:
            asleep= True 
        elif now > today8am and now < today14pm:
            not_tired = True 

        return[SlotSet("week", week),SlotSet("tired", tired),SlotSet("early", early),SlotSet("after_lunch", after_lunch),SlotSet("late", late), SlotSet("asleep", asleep), SlotSet("not_tired", not_tired)]
        

class ChangeTrueFalse(Action):
    def name(self): # type: () -> Text 
        return "action_change_true_false"

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

        tired= None
        week= None
            
        early= True
        after_lunch= None
        not_tired=None
        late= None
        asleep= None

        return[SlotSet("week", week),SlotSet("tired", tired),SlotSet("early", early),SlotSet("after_lunch", after_lunch),SlotSet("late", late), SlotSet("asleep", asleep), SlotSet("not_tired", not_tired)]
        
class CheckDayState(Action):
    def name(self): # type: () -> Text 
        return "action_check_day_state"

    def run(self, dispatcher, tracker, domain):
        # type: (CollectingDispatcher, Tracker, Dict[Text, Any]) -> List[Dict[Text, Any]]
        
        now = dt.datetime.now()
        today6am = now.replace(hour=6, minute=0, second=0, microsecond=0)
        today8am = now.replace(hour=8, minute=0, second=0, microsecond=0)
        today14pm = now.replace(hour=14, minute=0, second=0, microsecond=0)
        today16pm = now.replace(hour=16, minute=0, second=0, microsecond=0)
        today23pm = now.replace(hour=23, minute=0, second=0, microsecond=0)
        today1am = now.replace(hour=1, minute=0, second=0, microsecond=0) 
       
        early = tracker.get_slot("early") 
        after_lunch = tracker.get_slot("after_lunch") 
        late = tracker.get_slot("late") 
        asleep = tracker.get_slot("asleep") 
        not_tired = tracker.get_slot("not_tired")

        if now > today6am and now < today8am:
            early= True 
        elif now > today14pm and now < today16pm:
            after_lunch = True    
        elif now > today16pm and now < today23pm:
            late= True 
        elif now > today23pm and now < today6am:
            asleep= True 
        elif now > today8am and now < today14pm:
            not_tired = True 
        return [SlotSet("early", early),SlotSet("after_lunch", after_lunch),SlotSet("late", late), SlotSet("asleep", asleep), SlotSet("not_tired", not_tired)]
        
class CheckWorkingHours(Action):
    def name(self): # type: () -> Text 
        return "action_check_working_hours"

    def run(self, dispatcher, tracker, domain):
        # type: (CollectingDispatcher, Tracker, Dict[Text, Any]) -> List[Dict[Text, Any]]
        
        now = dt.datetime.now()
        today8am = now.replace(hour=8, minute=0, second=0, microsecond=0)
        today16pm = now.replace(hour=16, minute=0, second=0, microsecond=0)
       
        #available= tracker.get_slot("available")
        tired = tracker.get_slot("tired") 

        if now > today8am and now < today16pm:
            #available=True
            tired=False  
        else: 
            #available=False
            tired=True
        return [SlotSet("tired", tired)]

class CheckWeekend(Action):
    def name(self): # type: () -> Text 
        return "action_check_weekend"

    def run(self, dispatcher, tracker, domain):
        # type: (CollectingDispatcher, Tracker, Dict[Text, Any]) -> List[Dict[Text, Any]]
        x = datetime.today()
        weekno = x.weekday()

        week= tracker.get_slot("week")

        if weekno < 5:
            week= True
        else:
            week= False
        print(weekno)
        return [SlotSet("week", week)]

class AllSlotsReset(Action):
    def name(self):
        return 'action_slot_reset'
    def run(self, dispatcher, tracker, domain):
            return[AllSlotsReset()]