-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
actions.py
113 lines (89 loc) · 3.45 KB
/
actions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from typing import Dict, Text, Any, List, Union
from rasa_sdk import Tracker, Action
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
from rasa_sdk.events import EventType, SlotSet
import json
# Test comment
# Open drink json and convert to dict
with open("drinks.json", "r") as f:
drink_recipes_dict = json.load(f)
class ActionDrinkList(Action):
"""Returns the list of drinks we know recipes for"""
def name(self) -> Text:
return "action_drink_list"
def run(self, dispatcher, tracker, domain) -> List[EventType]:
drink_list = []
for drink_recipe in drink_recipes_dict:
drink_list.append(drink_recipe["name"])
recipe_response = "\n".join(str(drink) for drink in drink_list)
dispatcher.utter_message(
f"I know about the following drink recipes: {recipe_response}"
)
return []
class DrinkForm(FormAction):
"""Custom form action for drink search"""
def name(self) -> Text:
"""Unique identifier of the form"""
return "drink_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
"""A list of required slots that the form has to fill"""
return ["drink"]
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
"""A dictionary to map required slots to
- an extracted entity
- intent: value pairs
- a whole message
or a list of them, where a first match will be picked"""
return {"drink": self.from_entity(entity="drink")}
@staticmethod
def drink_db() -> List[Text]:
"""Database of supported drinks"""
return [
"rum punch",
"joco mule",
"hemingway",
"painkiller",
]
def validate_drink(
self,
value: Text,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> Dict[Text, Any]:
"""Validate drink value."""
if value.lower() in self.drink_db():
# validation succeeded, set the value of the "drink" slot to value
return {"drink": value}
else:
dispatcher.utter_message(template="utter_wrong_drink")
# validation failed, set this slot to None, meaning the
# user will be asked for the slot again
return {"drink": None}
def submit(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict]:
"""Define what the form has to do
after all required slots are filled"""
drink = tracker.get_slot("drink")
drink_recipe = {}
# Ensure drink recipe is in our drink dict and
# grab its data for the response.
for drink_recipe in drink_recipes_dict:
if drink_recipe["name"] == drink:
drink_ingredients = " \n".join(
[str(elem) for elem in drink_recipe["ingredients"]]
)
drink_garnish = drink_recipe["garnish"]
# Utter recipe to user if found in dictionary from json file.
dispatcher.utter_message(
f"To make a {drink}, you will combine the following "
f"ingredients: \n {drink_ingredients} \n"
f"and garnish with an {drink_garnish}"
)
return [SlotSet("drink", None)]