diff --git a/Rasa_Bot/actions/actions_idle_commands.py b/Rasa_Bot/actions/actions_idle_commands.py index 59bc31d5..f9c33cb8 100644 --- a/Rasa_Bot/actions/actions_idle_commands.py +++ b/Rasa_Bot/actions/actions_idle_commands.py @@ -1,8 +1,10 @@ from celery import Celery from rasa_sdk import Action -from .helper import dialog_to_be_completed, get_dialog_completion_state +from rasa_sdk.events import FollowupAction + +from .helper import dialog_to_be_completed,get_current_user_phase, get_dialog_completion_state from virtual_coach_db.helper.definitions import Components -from .definitions import REDIS_URL +from .definitions import REDIS_URL, FsmStates celery = Celery(broker=REDIS_URL) @@ -16,7 +18,14 @@ def name(self): async def run(self, dispatcher, tracker, domain): user_id = tracker.current_state()['sender_id'] - celery.send_task('celery_tasks.user_trigger_dialog', (user_id, Components.RELAPSE_DIALOG)) + phase = get_current_user_phase(user_id) + + # check if the dialog can be executed (the use is in the execution phase) + if phase != FsmStates.EXECUTION_RUN: + return [FollowupAction('utter_help_not_available')] + + celery.send_task('celery_tasks.user_trigger_dialog', + (user_id, Components.RELAPSE_DIALOG)) class ActionTriggerFirstAidDialog(Action): @@ -28,7 +37,14 @@ def name(self): async def run(self, dispatcher, tracker, domain): user_id = tracker.current_state()['sender_id'] - celery.send_task('celery_tasks.user_trigger_dialog', (user_id, Components.FIRST_AID_KIT)) + ehbo_enabled = get_dialog_completion_state(user_id, Components.FIRST_AID_KIT_VIDEO) + # if the first aid kit is available, trigger it + if ehbo_enabled: + celery.send_task('celery_tasks.user_trigger_dialog', + (user_id, Components.FIRST_AID_KIT)) + # if the first aid kit is not yet available, show the menu + else: + return[FollowupAction('utter_ehbo_not_available')] class ActionTriggerExplainFirstAidVideoDialog(Action): @@ -40,8 +56,14 @@ def name(self): async def run(self, dispatcher, tracker, domain): user_id = tracker.current_state()['sender_id'] - celery.send_task('celery_tasks.user_trigger_dialog', (user_id, - Components.FIRST_AID_KIT_VIDEO)) + ehbo_enabled = get_dialog_completion_state(user_id, Components.FIRST_AID_KIT_VIDEO) + # if the first aid kit is available, trigger it + if ehbo_enabled: + celery.send_task('celery_tasks.user_trigger_dialog', + (user_id, Components.FIRST_AID_KIT_VIDEO)) + # if the first aid kit is not yet available, show the menu + else: + return [FollowupAction('utter_ehbo_not_available')] class ActionTriggerGeneralActivityDialog(Action): @@ -83,14 +105,32 @@ async def run(self, dispatcher, tracker, domain): # is the ehbo option to be shown (the explanatory video has been shown) show_ehbo = get_dialog_completion_state(user_id, Components.FIRST_AID_KIT_VIDEO) - if complete_dialog and show_ehbo: - dispatcher.utter_message(response="utter_central_mode_options") - elif not complete_dialog and show_ehbo: - dispatcher.utter_message(response="utter_central_mode_options_without_verder") - elif complete_dialog and not show_ehbo: - dispatcher.utter_message(response="utter_central_mode_options_no_ehbo") + # the help command is shown just in the execution + phase = get_current_user_phase(user_id) + + if phase != FsmStates.EXECUTION_RUN: + show_help = False else: - dispatcher.utter_message(response="utter_central_mode_options_without_verder_no_ehbo") + show_help = True + + # select the utterances + + # show the verder command + if complete_dialog: + dispatcher.utter_message(response="utter_central_mode_options_verder") + # show the help command + if show_help: + dispatcher.utter_message(response="utter_central_mode_options_help") + # show the ehbo command + if show_ehbo: + dispatcher.utter_message(response="utter_central_mode_options_ehbo") + + # show the exercise command + dispatcher.utter_message(response="utter_central_mode_options_oefening") + # show the medication video command + dispatcher.utter_message(response="utter_central_mode_options_medicatie") + # show the last general statement + dispatcher.utter_message(response="utter_central_mode_options_outro") class ActionTriggerUncompletedDialog(Action): @@ -107,5 +147,4 @@ async def run(self, dispatcher, tracker, domain): celery.send_task('celery_tasks.user_trigger_dialog', (user_id, Components.CONTINUE_UNCOMPLETED_DIALOG)) else: - dispatcher.utter_message(response="utter_no_valid_uncompleted_dialog") - dispatcher.utter_message(response="utter_central_mode_options_without_verder") + return [FollowupAction('utter_no_valid_uncompleted_dialog')] diff --git a/Rasa_Bot/data/rules/rules.yml b/Rasa_Bot/data/rules/rules.yml deleted file mode 100644 index fd1cda3d..00000000 --- a/Rasa_Bot/data/rules/rules.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: "3.1" - -rules: -# Only applies at start of conversation -- rule: Process when people talk about urgent things that we cannot handle - conversation_start: true - steps: - - intent: urgent - - action: utter_refer - - action: utter_central_mode_options - - action: action_end_dialog - -- rule: Ask for foreseen smoking HRS whenever this is externally triggered (by scheduler) - steps: - - intent: EXTERNAL_trigger_ask_foreseen_hrs - - action: utter_ask_foreseen_hrs - -- rule: Return the number of smoked cigarettes when the user asks for it - steps: - - intent: request_tracked_cigarettes - - action: action_save_number_cigarettes - - action: action_get_number_cigarettes - - action: action_end_dialog - -- rule: Set a tracker reminder when asked - steps: - - intent: request_tracker_reminder - - action: action_set_cigarettes_tracker_reminder - - action: utter_reminder_is_set - - action: action_end_dialog - -- rule: Test metadata - steps: - - intent: request_metadata - - action: action_set_file_path - - action: action_upload_file - - action: utter_file_sent - - action: action_send_metadata - - action: action_end_dialog diff --git a/Rasa_Bot/data/rules/rules_idle_commands.yml b/Rasa_Bot/data/rules/rules_idle_commands.yml index bf76ddcd..6dd7a2b2 100644 --- a/Rasa_Bot/data/rules/rules_idle_commands.yml +++ b/Rasa_Bot/data/rules/rules_idle_commands.yml @@ -8,6 +8,30 @@ rules: - action: action_select_menu - action: action_end_dialog +- rule: trigger the menu options externally + steps: + - intent: EXTERNAL_central_options + - action: action_select_menu + - action: action_end_dialog + +- rule: trigger the menu options if ehbo is not available + steps: + - action: utter_ehbo_not_available + - action: action_select_menu + - action: action_end_dialog + +- rule: trigger the menu options if verder not available + steps: + - action: utter_no_valid_uncompleted_dialog + - action: action_select_menu + - action: action_end_dialog + +- rule: trigger the menu options if hrs not available + steps: + - action: utter_help_not_available + - action: action_select_menu + - action: action_end_dialog + - rule: help command steps: - intent: help_intent @@ -39,29 +63,3 @@ rules: steps: - intent: continue_dialog_intent - action: action_trigger_uncompleted_dialog - -- rule: central mode with all options - steps: - - intent: EXTERNAL_central_options - - action: utter_central_mode_options - - action: action_end_dialog - -- rule: central mode without ehbo - steps: - - intent: EXTERNAL_central_options_no_ehbo - - action: utter_central_mode_options_no_ehbo - - action: action_end_dialog - -- rule: no valid uncompleted dialog with ehbo - steps: - - intent: EXTERNAL_no_valid_uncompleted_dialog - - action: utter_no_valid_uncompleted_dialog - - action: utter_central_mode_options_without_verder - - action: action_end_dialog - -- rule: no valid uncompleted dialog without ehbo - steps: - - intent: EXTERNAL_no_valid_uncompleted_dialog_no_ehbo - - action: utter_no_valid_uncompleted_dialog - - action: utter_central_mode_options_without_verder_no_ehbo - - action: action_end_dialog diff --git a/Rasa_Bot/domain/domain_common.yml b/Rasa_Bot/domain/domain_common.yml index ec4791d4..44989b56 100644 --- a/Rasa_Bot/domain/domain_common.yml +++ b/Rasa_Bot/domain/domain_common.yml @@ -39,61 +39,30 @@ responses: utter_file_sent: - text: "Here is your file" - # We present the user with the options from the central mode - utter_central_mode_options: - - text: "Typ 'help' als je zin hebt om te roken, hebt gerookt of het lastig vindt om in beweging te komen. βœ‹πŸ½ - \n\n - Typ 'ehbo' als je je EHBO-doos wilt openen om een bewaarde oefening te bekijken of opnieuw te doen. 🧰 - Wil je opnieuw uitleg over hoe de EHBO-doos werkt? Typ dan 'uitleg'. ℹ️ - \n\n - Typ 'oefening' als je een oefening wilt doen. πŸ“± - \n\n - Typ 'medicatie' om de video over nicotinevervangende middelen en medicatie opnieuw te bekijken. πŸ’Š - \n\n - Typ 'verder' om een onafgemaakte dialoog af te ronden. βœ” - \n\n - Heb je behoefte om iemand te spreken? Je kunt altijd een afspraak maken met je huisarts. 🩺 - Je kunt ook altijd bellen met de gratis Stoppen met roken telefoonlijn (0800-1995).πŸ“ž - De Stoplijn is van maandag t/m vrijdag bereikbaar van 9 tot 17 uur." + utter_central_mode_options_help: + - text: "Typ 'help' als je zin hebt om te roken, hebt gerookt of het lastig vindt om in beweging te komen. βœ‹πŸ½" - # We present the user with the options from the central mode when the ehbo is not available - utter_central_mode_options_no_ehbo: - - text: "Typ 'help' als je zin hebt om te roken, hebt gerookt of het lastig vindt om in beweging te komen. βœ‹πŸ½ - \n\n - Typ 'oefening' als je een oefening wilt doen. πŸ“± - \n\n - Typ 'medicatie' om de video over nicotinevervangende middelen en medicatie opnieuw te bekijken. πŸ’Š - \n\n - Typ 'verder' om een onafgemaakte dialoog af te ronden. βœ” - \n\n - Heb je behoefte om iemand te spreken? Je kunt altijd een afspraak maken met je huisarts. 🩺 - Je kunt ook altijd bellen met de gratis Stoppen met roken telefoonlijn (0800-1995).πŸ“ž - De Stoplijn is van maandag t/m vrijdag bereikbaar van 9 tot 17 uur." - - # Print this when there is no uncompleted dialog to finish after informing the user - # that there is none (i.e., do not mention the "verder"-option again then) - utter_central_mode_options_without_verder: - - text: "Typ 'help' als je zin hebt om te roken, hebt gerookt of het lastig vindt om in beweging te komen. βœ‹πŸ½ - \n\n - Typ 'ehbo' als je je EHBO-doos wilt openen om een bewaarde oefening te bekijken of opnieuw te doen. 🧰 - Wil je opnieuw uitleg over hoe de EHBO-doos werkt? Typ dan 'uitleg'. ℹ️ - \n\n - Typ 'oefening' als je een oefening wilt doen. πŸ“± - \n\n - Typ 'medicatie' om de video over nicotinevervangende middelen en medicatie opnieuw te bekijken. πŸ’Š - \n\n - Heb je behoefte om iemand te spreken? Je kunt altijd een afspraak maken met je huisarts. 🩺 - Je kunt ook altijd bellen met de gratis Stoppen met roken telefoonlijn (0800-1995).πŸ“ž - De Stoplijn is van maandag t/m vrijdag bereikbaar van 9 tot 17 uur." + utter_central_mode_options_ehbo: + - text: "Typ 'ehbo' als je je EHBO-doos wilt openen om een bewaarde oefening te bekijken of opnieuw te doen. 🧰 + Wil je opnieuw uitleg over hoe de EHBO-doos werkt? Typ dan 'uitleg'. β„Ή" - # Print this when there is no uncompleted dialog to finish and the ehbo is not yet active - utter_central_mode_options_without_verder_no_ehbo: - - text: "Typ 'help' als je zin hebt om te roken, hebt gerookt of het lastig vindt om in beweging te komen. βœ‹πŸ½ - \n\n - Typ 'oefening' als je een oefening wilt doen. πŸ“± - \n\n - Typ 'medicatie' om de video over nicotinevervangende middelen en medicatie opnieuw te bekijken. πŸ’Š - \n\n - Heb je behoefte om iemand te spreken? Je kunt altijd een afspraak maken met je huisarts. 🩺 + utter_central_mode_options_oefening: + - text: "Typ 'oefening' als je een oefening wilt doen. πŸ“±" + + utter_central_mode_options_medicatie: + - text: "Typ 'medicatie' om de video over nicotinevervangende middelen en medicatie opnieuw te bekijken. πŸ’Š" + + utter_central_mode_options_verder: + - text: "Typ 'verder' om een onafgemaakte dialoog af te ronden. βœ”" + + utter_central_mode_options_outro: + - text: "Heb je behoefte om iemand te spreken? Je kunt altijd een afspraak maken met je huisarts. 🩺 Je kunt ook altijd bellen met de gratis Stoppen met roken telefoonlijn (0800-1995).πŸ“ž De Stoplijn is van maandag t/m vrijdag bereikbaar van 9 tot 17 uur." + + utter_help_not_available: + - text: "Je bent nu in de voorbereidingsfase. Je kunt β€˜help’ gebruiken tijdens de uitvoeringsfase." + + + utter_ehbo_not_available: + - text: "Je bent nu in de voorbereidingsfase. Je kunt 'ehbo' gebruiken tijdens de uitvoeringsfase." diff --git a/Rasa_Bot/domain/domain_idle_commands.yml b/Rasa_Bot/domain/domain_idle_commands.yml index 4be9c1ab..8980a0e2 100644 --- a/Rasa_Bot/domain/domain_idle_commands.yml +++ b/Rasa_Bot/domain/domain_idle_commands.yml @@ -15,7 +15,7 @@ responses: # For low next action confidence, "utter_default" is automatically called. # For low NLU confidence, we have defined a rule. utter_default: - - text: "Sorry, ik begrijp (nog) niet wat je bedoelt, kun je me het op een andere manier duidelijk maken?" + - text: "Goed om van je te horen! Er zijn verschillende dingen die je kunt doen:" # There is no valid uncompleted dialog utter_no_valid_uncompleted_dialog: diff --git a/Rasa_Bot/models/20230719-090950-mature-use.tar.gz b/Rasa_Bot/models/20230727-172231-inverted-defense.tar.gz similarity index 67% rename from Rasa_Bot/models/20230719-090950-mature-use.tar.gz rename to Rasa_Bot/models/20230727-172231-inverted-defense.tar.gz index 568ae700..b57473f9 100644 Binary files a/Rasa_Bot/models/20230719-090950-mature-use.tar.gz and b/Rasa_Bot/models/20230727-172231-inverted-defense.tar.gz differ diff --git a/scheduler/state_machine/controller.py b/scheduler/state_machine/controller.py index 7f784240..f5ec86d7 100644 --- a/scheduler/state_machine/controller.py +++ b/scheduler/state_machine/controller.py @@ -1,8 +1,7 @@ import logging from celery import Celery from datetime import date, datetime, timedelta -from state_machine.state_machine_utils import (create_new_date, dialog_to_be_completed, - get_dialog_completion_state, +from state_machine.state_machine_utils import (create_new_date, get_dialog_completion_state, get_execution_week, get_intervention_component, get_next_planned_date, get_next_scheduled_occurrence, get_quit_date, get_pa_group, get_start_date, @@ -91,15 +90,13 @@ def on_dialog_rescheduled(self, dialog, new_date): phase=1) def on_user_trigger(self, dialog): - if dialog in (Components.FIRST_AID_KIT, dialog == Components.FIRST_AID_KIT_VIDEO): + if dialog in (Components.FIRST_AID_KIT, + Components.FIRST_AID_KIT_VIDEO, + Components.RELAPSE_DIALOG): # dialog not available in this phase - if dialog_to_be_completed(self.user_id) is None: - complete = False - else: - complete = True - run_option_menu(user_id=self.user_id, ehbo=False, complete_dialog=complete) + run_option_menu(user_id=self.user_id) elif dialog == Components.CONTINUE_UNCOMPLETED_DIALOG: - run_uncompleted_dialog(self.user_id, show_ehbo=False) + run_uncompleted_dialog(self.user_id) else: plan_and_store(user_id=self.user_id, dialog=dialog, @@ -178,13 +175,12 @@ def on_user_trigger(self, dialog): and not get_dialog_completion_state(self.user_id, Components.FIRST_AID_KIT_VIDEO): # if the introductory video of the first aid kit has not been executed, # the first aid kit cannot be executed - if dialog_to_be_completed(self.user_id) is None: - complete = False - else: - complete = True - run_option_menu(self.user_id, ehbo=False, complete_dialog=complete) + run_option_menu(self.user_id) + elif dialog == Components.RELAPSE_DIALOG: + # the relapse dialog is not available in this phase + run_option_menu(self.user_id) elif dialog == Components.CONTINUE_UNCOMPLETED_DIALOG: - run_uncompleted_dialog(self.user_id, show_ehbo=False) + run_uncompleted_dialog(self.user_id) else: plan_and_store(user_id=self.user_id, dialog=dialog, @@ -254,9 +250,12 @@ def on_dialog_rescheduled(self, dialog, new_date): phase=1) def on_user_trigger(self, dialog): - # in this phase a dialog can be continued + # the relapse dialog is not available in this phase if dialog == Components.CONTINUE_UNCOMPLETED_DIALOG: run_uncompleted_dialog(self.user_id) + # in this phase a dialog can be continued + elif dialog == Components.RELAPSE_DIALOG: + run_option_menu(self.user_id) else: plan_and_store(user_id=self.user_id, dialog=dialog, @@ -365,6 +364,9 @@ def on_new_day(self, current_date: date): def on_user_trigger(self, dialog: str): if dialog == Components.CONTINUE_UNCOMPLETED_DIALOG: run_uncompleted_dialog(self.user_id) + # the relapse dialog is not available in this phase + elif dialog == Components.RELAPSE_DIALOG: + run_option_menu(self.user_id) else: plan_and_store(user_id=self.user_id, dialog=dialog, diff --git a/scheduler/state_machine/state_machine_utils.py b/scheduler/state_machine/state_machine_utils.py index f2294308..b2239750 100644 --- a/scheduler/state_machine/state_machine_utils.py +++ b/scheduler/state_machine/state_machine_utils.py @@ -561,13 +561,12 @@ def dialog_to_be_completed(user_id: int) -> Optional[UserInterventionState]: return None -def run_uncompleted_dialog(user_id: int, show_ehbo: bool = True): +def run_uncompleted_dialog(user_id: int): """ Checks if a dialog has to be completed and, in this case runs it from the latest completed part. Args: user_id: ID of the user - show_ehbo: show the menu with ehbo command if true """ @@ -588,30 +587,19 @@ def run_uncompleted_dialog(user_id: int, show_ehbo: bool = True): (user_id, component.intervention_component.intervention_component_trigger) ) else: - run_option_menu(user_id, ehbo=show_ehbo, complete_dialog=False) + run_option_menu(user_id) -def run_option_menu(user_id: int, ehbo: bool = True, complete_dialog: bool = False): +def run_option_menu(user_id: int): """ - Runs a celery task for showing the options menu without the 'verder' option + Runs a celery task for showing the options' menu. Args: user_id: ID of the user - ehbo: show ehbo command if true - complete_dialog: show verder command if true - - """ - if ehbo and complete_dialog: - celery.send_task(TRIGGER_INTENT, (user_id, ComponentsTriggers.CENTRAL_OPTIONS, False)) - elif ehbo and not complete_dialog: - celery.send_task(TRIGGER_INTENT, - (user_id, ComponentsTriggers.CENTRAL_OPTIONS_NO_COMPLETE, False)) - elif not ehbo and complete_dialog: - celery.send_task(TRIGGER_INTENT, - (user_id, ComponentsTriggers.CENTRAL_OPTIONS_NO_EHBO, False)) - elif not ehbo and not complete_dialog: - celery.send_task(TRIGGER_INTENT, - (user_id, ComponentsTriggers.CENTRAL_OPTIONS_NO_EHBO_NO_COMPLETE, False)) + + """ + + celery.send_task(TRIGGER_INTENT, (user_id, ComponentsTriggers.CENTRAL_OPTIONS, False)) def retrieve_intervention_day(user_id: int, current_date: date) -> int: