Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise first aid kit #72

Merged
merged 7 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
172 changes: 155 additions & 17 deletions Rasa_Bot/actions/actions_first_aid_kit.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import logging

from . import validator
from .definitions import DATABASE_URL, NUM_TOP_ACTIVITIES, REDIS_URL
from .helper import (get_latest_bot_utterance,
get_user_intervention_activity_inputs,)

from celery import Celery
from datetime import datetime, timedelta
from rasa_sdk import Action
from rasa_sdk.events import FollowupAction
from virtual_coach_db.dbschema.models import FirstAidKit
from rasa_sdk import Action, Tracker
from rasa_sdk.events import FollowupAction, SlotSet
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormValidationAction
from typing import Any, Dict, Text
from virtual_coach_db.dbschema.models import (FirstAidKit,
InterventionActivity)
from virtual_coach_db.helper.helper_functions import get_db_session

from .definitions import DATABASE_URL, NUM_TOP_ACTIVITIES, REDIS_URL


celery = Celery(broker=REDIS_URL)

Expand Down Expand Up @@ -40,7 +49,7 @@ async def run(self, dispatcher, tracker, domain):

current_intervention = tracker.get_slot('current_intervention_component')

if current_intervention is None:
if current_intervention == 'NONE':
return[FollowupAction('action_end_dialog')]

new_intent = 'EXTERNAL_' + current_intervention
Expand Down Expand Up @@ -74,29 +83,158 @@ async def run(self, dispatcher, tracker, domain):
)

kit_text = ""
filled = False # Whether the first aid kit has content
activity_ids_list = [] # List of activity IDs

# the kit exists
if selected is not None:

# get up to the highest rated activities
# get the highest rated activities
sorted_activities = sorted(
selected,
key=lambda x: x.activity_rating
)[:NUM_TOP_ACTIVITIES]

for activity_idx, activity in enumerate(sorted_activities):
kit_text += str(activity_idx + 1) + ") "
if activity.intervention_activity_id is None:
kit_text += activity.user_activity_title
else:
kit_text += activity.intervention_activity.intervention_activity_title
if not activity_idx == len(selected) - 1:
kit_text += activity.intervention_activity.intervention_activity_title
kit_text += ": " + activity.intervention_activity.intervention_activity_description
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intervention_activity_description is always empty currently. Do we have the content for this?

if not activity_idx == len(sorted_activities) - 1:
kit_text += "\n"

activity_ids_list.append(activity.intervention_activity.intervention_activity_id)

filled = True

dispatcher.utter_message(template="utter_first_aid_kit",
first_aid_kit_text=kit_text)
# the kit doesn't exist
else:
dispatcher.utter_message(template="utter_first_aid_kit_empty")
return [SlotSet('first_aid_kit_text', kit_text),
SlotSet('first_aid_kit_filled', filled),
SlotSet('first_aid_kit_activities_ids', activity_ids_list)]

return []

class ValidateFirstAidKitChosenActivityForm(FormValidationAction):
def name(self) -> Text:
return 'validate_first_aid_kit_chosen_activity_form'

def validate_first_aid_kit_chosen_activity_slot(
self, value: Text, dispatcher: CollectingDispatcher,
tracker: Tracker, domain: Dict[Text, Any]) -> Dict[Text, Any]:
# pylint: disable=unused-argument
"""Validate first_aid_kit_chosen_activity_slot"""

last_utterance = get_latest_bot_utterance(tracker.events)
if last_utterance != 'utter_ask_first_aid_kit_chosen_activity_slot':
return {"first_aid_kit_chosen_activity_slot": None}

if not validator.validate_number_in_range_response(n_min=1, n_max=5,
response=value):
return {"first_aid_kit_chosen_activity_slot": None}

activity_ids_list = tracker.get_slot('first_aid_kit_activities_ids')

return {"first_aid_kit_chosen_activity_slot": activity_ids_list[int(value) - 1]}


class ActionFirstAidKitCheckUserInputRequired(Action):
"""Check whether chosen activity requires user input."""

def name(self):
return "action_first_aid_kit_check_user_input_required"

async def run(self, dispatcher, tracker, domain):

# Get ID of chosen activity
activity_id = tracker.get_slot('first_aid_kit_chosen_activity_slot')

# Check in database if activity requires user input
session = get_db_session(db_url=DATABASE_URL)
selected = (
session.query(
InterventionActivity
)
.filter_by(
intervention_activity_id=activity_id
).one()
)

input_required = int(selected.user_input_required)

return [SlotSet('first_aid_kit_chosen_activity_input_required',
input_required)]


class ActionFirstAidKitGetUserInput(Action):
"""Get most recent user input for chosen activity from database."""

def name(self):
return "action_first_aid_kit_get_user_input"

async def run(self, dispatcher, tracker, domain):

# Get ID of chosen activity
activity_id = tracker.get_slot('first_aid_kit_chosen_activity_slot')

user_id = tracker.current_state()['sender_id']

user_inputs = get_user_intervention_activity_inputs(user_id,
activity_id)
last_input = user_inputs[-1].user_input

return [SlotSet("first_aid_kit_user_input_slot", last_input)]


class ActionFirstAidKitGetInstructions(Action):
"""Get instructions for chosen activity from database."""

def name(self):
return "action_first_aid_kit_get_instructions"

async def run(self, dispatcher, tracker, domain):

# Get ID of chosen activity
activity_id = tracker.get_slot('first_aid_kit_chosen_activity_slot')

session = get_db_session(db_url=DATABASE_URL)
selected = (
session.query(
InterventionActivity
)
.filter_by(
intervention_activity_id=activity_id
).one()
)

instructions = selected.intervention_activity_full_instructions

return [SlotSet("first_aid_kit_instructions_slot", instructions)]


class ValidateFirstAidKitEndForm(FormValidationAction):
def name(self) -> Text:
return 'validate_first_aid_kit_end_form'

def validate_first_aid_kit_end_slot(
self, value: Text, dispatcher: CollectingDispatcher,
tracker: Tracker, domain: Dict[Text, Any]) -> Dict[Text, Any]:
# pylint: disable=unused-argument
"""Validate first_aid_kit_end_slot"""

last_utterance = get_latest_bot_utterance(tracker.events)
if last_utterance != 'utter_ask_first_aid_kit_end_slot':
return {"first_aid_kit_end_slot": None}

if not validator.validate_number_in_range_response(n_min=1, n_max=2,
response=value):
return {"first_aid_kit_end_slot": None}

return {"first_aid_kit_end_slot": int(value)}


class ActionFirstAidKitRepeat(Action):
"""Repeat first aid kit dialog."""

def name(self):
return "action_first_aid_kit_repeat"

async def run(self, dispatcher, tracker, domain):

return [FollowupAction('utter_first_aid_kit_show_activity_titles_1')]
17 changes: 1 addition & 16 deletions Rasa_Bot/actions/actions_general_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
REFLECTIVE_QUESTION_CONSENSUS)
from .helper import (get_latest_bot_utterance,
get_random_activities,
get_user_intervention_activity_inputs,
store_dialog_closed_answer_to_db)
from rasa_sdk import Action, FormValidationAction, Tracker
from rasa_sdk.events import SlotSet
Expand Down Expand Up @@ -450,22 +451,6 @@ def save_activity_to_fak(user_id: int, activity_id: int, rating_value: int):
activity_rating=rating_value)
)
session.commit()


def get_user_intervention_activity_inputs(user_id: int, activity_id: int):
session = get_db_session(db_url=DATABASE_URL)

user_inputs = (
session.query(
InterventionActivitiesPerformed
)
.filter(
InterventionActivitiesPerformed.users_nicedayuid == user_id,
InterventionActivitiesPerformed.intervention_activity_id == activity_id
).all()
)

return user_inputs


class ValidatePersuasionReflectionForm(FormValidationAction):
Expand Down
17 changes: 17 additions & 0 deletions Rasa_Bot/actions/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from virtual_coach_db.dbschema.models import (Users, DialogClosedAnswers,
DialogOpenAnswers,
InterventionActivity,
InterventionActivitiesPerformed,
InterventionComponents,
InterventionPhases,
UserInterventionState,
Expand Down Expand Up @@ -43,6 +44,22 @@ def store_dialog_closed_answer_to_db(user_id: int, question_id: int, answer_valu
session.commit() # Update database


def get_user_intervention_activity_inputs(user_id: int, activity_id: int):
session = get_db_session(db_url=DATABASE_URL)

user_inputs = (
session.query(
InterventionActivitiesPerformed
)
.filter(
InterventionActivitiesPerformed.users_nicedayuid == user_id,
InterventionActivitiesPerformed.intervention_activity_id == activity_id
).all()
)

return user_inputs


def store_dialog_closed_answer_list_to_db(user_id: int, question_id: int, answers_values: str):
"""
saves to the db all the closed answers provided as a string, where each answer value
Expand Down
2 changes: 1 addition & 1 deletion Rasa_Bot/actions/requirements-actions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ python-dateutil==2.8.1
python-dotenv
redis
sqlalchemy
git+https://github.com/PerfectFit-project/virtual-coach-db@v0.1.8
git+https://github.com/PerfectFit-project/virtual-coach-db@v0.1.10
git+https://github.com/PerfectFit-project/pa-algorithms
git+https://github.com/PerfectFit-project/niceday_client@v0.1.3
88 changes: 83 additions & 5 deletions Rasa_Bot/data/rules/rules_first_aid_kit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,87 @@
version: "3.1"

rules:
## Get first aid kit
- rule: Get first aid kit
## Get first aid kit empty
- rule: Get first aid kit empty
steps:
- intent: CENTRAL_get_first_aid_kit
- action: action_get_first_aid_kit
- action: action_resume_after_fak
- intent: CENTRAL_get_first_aid_kit
- action: action_get_first_aid_kit
- slot_was_set:
- first_aid_kit_filled: false
- action: utter_first_aid_kit_empty
- action: action_resume_after_fak

## 1: Get first aid kit is filled
- rule: Get first aid kit filled
steps:
- intent: CENTRAL_get_first_aid_kit
- action: action_get_first_aid_kit
- slot_was_set:
- first_aid_kit_filled: true
- action: utter_first_aid_kit_intro
- action: action_first_aid_kit_repeat
wait_for_user_input: false

## 2 + 3a: user input required
- rule: First aid kit user input required
steps:
- action: utter_first_aid_kit_show_activity_titles_1
- action: utter_first_aid_kit_show_activity_titles_2
- action: first_aid_kit_chosen_activity_form
- active_loop: first_aid_kit_chosen_activity_form
- active_loop: null
- action: action_first_aid_kit_check_user_input_required
- slot_was_set:
- first_aid_kit_chosen_activity_input_required: true
- action: action_first_aid_kit_get_user_input
- action: utter_first_aid_kit_show_full_text_input_1
- action: utter_first_aid_kit_show_full_text_input_2
- action: utter_first_aid_kit_end_or_repeat_1
- action: first_aid_kit_end_form
- active_loop: first_aid_kit_end_form
wait_for_user_input: false

## 2 + 3b: no user input required
- rule: First aid kit no user input required
steps:
- action: utter_first_aid_kit_show_activity_titles_1
- action: utter_first_aid_kit_show_activity_titles_2
- action: first_aid_kit_chosen_activity_form
- active_loop: first_aid_kit_chosen_activity_form
- active_loop: null
- action: action_first_aid_kit_check_user_input_required
- slot_was_set:
- first_aid_kit_chosen_activity_input_required: false
- action: action_first_aid_kit_get_instructions
- action: utter_first_aid_kit_show_full_text_noinput_1
- action: utter_first_aid_kit_show_full_text_noinput_2
- action: utter_first_aid_kit_end_or_repeat_1
- action: first_aid_kit_end_form
- active_loop: first_aid_kit_end_form
wait_for_user_input: false

## 4a: User wants to end dialog
- rule: End first aid kit dialog
condition:
- active_loop: first_aid_kit_end_form
steps:
- action: first_aid_kit_end_form
- active_loop: null
- slot_was_set:
- first_aid_kit_end_slot: 1
- action: utter_first_aid_kit_end_1
- action: utter_first_aid_kit_end_2
- action: action_resume_after_fak
wait_for_user_input: false

## 4b: User wants to repeat dialog
- rule: Repeat first aid kit dialog
condition:
- active_loop: first_aid_kit_end_form
steps:
- action: first_aid_kit_end_form
- active_loop: null
- slot_was_set:
- first_aid_kit_end_slot: 2
- action: utter_first_aid_kit_repeat_1
- action: action_first_aid_kit_repeat
Loading