Merge pull request #2 from basitanwer/first_commit
Browse files- .gitignore +4 -0
- .gitignore/.gitignore +0 -1
- README.md +161 -0
- actions/__init__.py +0 -0
- actions/actions.py +168 -0
- config.yml +27 -0
- credentials.yml +6 -0
- data/nlu.yml +101 -0
- data/rules.yml +16 -0
- data/stories.yml +41 -0
- domain.yml +54 -0
- endpoints.yml +4 -0
- requirements.txt +3 -0
- reviews.db +0 -0
- tests/test_stories.yml +26 -0
- web/index.html +21 -0
- web/rasa_zir.gif +0 -0
.gitignore
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*.tar.gz
|
2 |
+
*.pyc
|
3 |
+
results/
|
4 |
+
models/
|
.gitignore/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
foo.bar
|
|
|
|
README.md
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!--lint disable no-literal-urls-->
|
2 |
+
<p align="center">
|
3 |
+
<a href="https://zir-ai.com/">
|
4 |
+
<img
|
5 |
+
alt="Zir AI"
|
6 |
+
src="https://zir-ai.com/static/media/logo-light.637c616a.svg"
|
7 |
+
width="400"
|
8 |
+
/>
|
9 |
+
</a>
|
10 |
+
</p>
|
11 |
+
|
12 |
+
The source code in this repository shows a simple Rasa chatbot fallback
|
13 |
+
mechanism, which gets relevant information from ZIR Semantic Search.
|
14 |
+
|
15 |
+
# Table of contents
|
16 |
+
|
17 |
+
- [Rasa Bot & Zir](#rasa-bot--zir)
|
18 |
+
- [Setup & Play](#setup--play)
|
19 |
+
- [Set-up Rasa](#set-up-rasa)
|
20 |
+
- [Set-up repo](#set-up-repo)
|
21 |
+
- [Running the demo](#running-the-demo)
|
22 |
+
- [Customizing the bot](#customizing-the-bot)
|
23 |
+
- [Data](#data)
|
24 |
+
- [Rasa Custom Action](#rasa-custom-action)
|
25 |
+
|
26 |
+
## Rasa Bot & Zir
|
27 |
+
|
28 |
+
[Rasa](https://rasa.com/) is the leading conversational AI platform, for
|
29 |
+
personalized conversations at scale. Developers provide the questions they
|
30 |
+
expect the end customer to ask and the Rasa bot, using AI, predicts and matches
|
31 |
+
what the customer intended to ask. With this information at hand, developers can
|
32 |
+
easily match what the bot should respond to.
|
33 |
+
|
34 |
+
This is all well unless when the customer asks a valid question the developer
|
35 |
+
did not expect, for such a scenario Rasa provides a
|
36 |
+
[fallback mechanism](https://rasa.com/docs/rasa/fallback-handoff#fallbacks).
|
37 |
+
|
38 |
+
> Although Rasa will generalize to unseen messages, some messages might receive
|
39 |
+
> a low classification confidence. Using Fallbacks will help ensure that these
|
40 |
+
> low confidence messages are handled gracefully, giving your assistant the
|
41 |
+
> option to either respond with a default message or attempt to disambiguate the
|
42 |
+
> user input.
|
43 |
+
|
44 |
+
Using the mechanism the bot can ask a fallback action and search through the
|
45 |
+
reviews uploaded in [Zir-AI](https://zir-ai.com) with the help of
|
46 |
+
[custom actions](https://rasa.com/docs/rasa/custom-actions). The relevant
|
47 |
+
information is shown if available otherwise if the confidence of the question to
|
48 |
+
reviews available is low, we fallback to a generic statement.
|
49 |
+
|
50 |
+
The results sum up to be this:
|
51 |
+
|
52 |
+
![zir-serach](./web/rasa_zir.gif)
|
53 |
+
|
54 |
+
## Setup & Play
|
55 |
+
|
56 |
+
You'll need to have Rasa installed and this repository. You might want to create
|
57 |
+
a [virtual environment](https://docs.python.org/3/library/venv.html) to isolate
|
58 |
+
the dependencies rasa requires.
|
59 |
+
|
60 |
+
### Set-up Rasa
|
61 |
+
|
62 |
+
Follow the
|
63 |
+
[rasa installation instructions](https://rasa.com/docs/rasa/installation) or
|
64 |
+
copy-paste the following commands in terminal
|
65 |
+
|
66 |
+
```bash
|
67 |
+
pip3 install -U pip
|
68 |
+
pip3 install rasa
|
69 |
+
rasa --version
|
70 |
+
```
|
71 |
+
|
72 |
+
This should print the rasa version similar to follow
|
73 |
+
|
74 |
+
```bash
|
75 |
+
Rasa Version : 2.7.0
|
76 |
+
Minimum Compatible Version: 2.6.0
|
77 |
+
Rasa SDK Version : 2.7.0
|
78 |
+
Rasa X Version : None
|
79 |
+
Python Version : 3.8.5
|
80 |
+
Operating System : Linux
|
81 |
+
Python Path : /bin/python3
|
82 |
+
```
|
83 |
+
|
84 |
+
> Windows & WSL works too
|
85 |
+
|
86 |
+
### Set-up repo
|
87 |
+
|
88 |
+
To install dependencies for this repository to work install python dependencies
|
89 |
+
from requirements.txt
|
90 |
+
|
91 |
+
```bash
|
92 |
+
pip install -r requirements.txt
|
93 |
+
python3 -m spacy download en_core_web_md
|
94 |
+
```
|
95 |
+
|
96 |
+
This will install the spacy model `en_core_web_md` this bot is configured with.
|
97 |
+
Now you'll need to train the rasa bot
|
98 |
+
|
99 |
+
```bash
|
100 |
+
rasa train
|
101 |
+
```
|
102 |
+
|
103 |
+
### Running the demo
|
104 |
+
|
105 |
+
While running the model, you are required to run the rasa action server along
|
106 |
+
with the rasa bot. So in one terminal run
|
107 |
+
|
108 |
+
```bash
|
109 |
+
rasa run actions
|
110 |
+
```
|
111 |
+
|
112 |
+
In another terminal, you can either play with the bot in your `shell` or on the
|
113 |
+
browser.
|
114 |
+
|
115 |
+
To talk to the bot in shell run
|
116 |
+
|
117 |
+
```bash
|
118 |
+
rasa shell
|
119 |
+
```
|
120 |
+
|
121 |
+
Or to talk to the bot in the browser run
|
122 |
+
|
123 |
+
```bash
|
124 |
+
rasa run --credentials ./credentials.yml --enable-api --auth-token XYZ123 --model ./models --endpoints ./endpoints.yml --cors "*"
|
125 |
+
```
|
126 |
+
|
127 |
+
Now, open the `index.html` in your browser to talk to the bot.
|
128 |
+
|
129 |
+
## Customizing the bot
|
130 |
+
|
131 |
+
Use the following information to customize the bot and the source of data.
|
132 |
+
|
133 |
+
### Data
|
134 |
+
|
135 |
+
Data for the bot is sourced from [OpinRank](https://github.com/kavgan/OpinRank/)
|
136 |
+
and reviews for Hotel Jumeirah are specifically used for this bot. Reviews are
|
137 |
+
parsed from https://github.com/amin3141/zir-souffle. Use `hotels.py` to generate
|
138 |
+
the output `json` and the `reviews.db`. Copy the generated `reviews.db` file to
|
139 |
+
this repository.
|
140 |
+
|
141 |
+
Create a corpus on [Zir AI](https://zir-ai.com/console/corpora) and upload all
|
142 |
+
the JSON files. Create an API key for access and note down the following
|
143 |
+
information
|
144 |
+
|
145 |
+
- API key
|
146 |
+
- corpus id
|
147 |
+
- customer id
|
148 |
+
|
149 |
+
### Rasa Custom Action
|
150 |
+
|
151 |
+
Use the above-collected information and replace the information in
|
152 |
+
`actions/actions.py` and you're good to go.
|
153 |
+
|
154 |
+
```python
|
155 |
+
customer_id = "1835841754"
|
156 |
+
corpus_id = 1
|
157 |
+
header = {
|
158 |
+
"customer-id": customer_id,
|
159 |
+
"x-api-key": "zqt_WvU_2atFHgqYxxT2sQswwIUgogI8K3QeWs0oqA"
|
160 |
+
}
|
161 |
+
```
|
actions/__init__.py
ADDED
File without changes
|
actions/actions.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
This files contains your custom actions which can be used
|
3 |
+
to run custom Python code.
|
4 |
+
"""
|
5 |
+
from typing import Any, Text, Dict, List
|
6 |
+
import json
|
7 |
+
import requests
|
8 |
+
import sqlite3
|
9 |
+
import textwrap
|
10 |
+
|
11 |
+
|
12 |
+
from rasa_sdk import Action, Tracker
|
13 |
+
from rasa_sdk.events import UserUtteranceReverted
|
14 |
+
from rasa_sdk.executor import CollectingDispatcher
|
15 |
+
|
16 |
+
|
17 |
+
class ActionDefaultFallback(Action):
|
18 |
+
"""Executes the fallback action and goes back to the previous state
|
19 |
+
of the dialogue"""
|
20 |
+
|
21 |
+
customer_id = "1526022105"
|
22 |
+
corpus_id = 40
|
23 |
+
header = {
|
24 |
+
"customer-id": customer_id,
|
25 |
+
"x-api-key": "zqt_WvU_2atFHgqYxxT2sQswwIUgogI8K3QeWs0oqA"
|
26 |
+
}
|
27 |
+
con = None
|
28 |
+
|
29 |
+
def name(self) -> Text:
|
30 |
+
con = sqlite3.connect("./reviews.db")
|
31 |
+
self.cur = con.cursor()
|
32 |
+
return "zir_action_fallback"
|
33 |
+
|
34 |
+
async def run(
|
35 |
+
self,
|
36 |
+
dispatcher: CollectingDispatcher,
|
37 |
+
tracker: Tracker,
|
38 |
+
domain: Dict[Text, Any],
|
39 |
+
) -> List[Dict[Text, Any]]:
|
40 |
+
|
41 |
+
number_results = 3
|
42 |
+
data_dict = {
|
43 |
+
"query": [
|
44 |
+
{
|
45 |
+
"query": tracker.latest_message["text"],
|
46 |
+
"num_results": number_results,
|
47 |
+
"corpus_key": [
|
48 |
+
{
|
49 |
+
"customer_id": self.customer_id,
|
50 |
+
"corpus_id": self.corpus_id
|
51 |
+
}
|
52 |
+
]
|
53 |
+
}
|
54 |
+
]
|
55 |
+
}
|
56 |
+
|
57 |
+
payload = json.dumps(data_dict)
|
58 |
+
response = requests.post(f"https://h.serving.zir-ai.io:443/v1/query",
|
59 |
+
data=payload,
|
60 |
+
verify=True,
|
61 |
+
headers=self.header,
|
62 |
+
timeout=10)
|
63 |
+
parsed = json.loads(response.text)
|
64 |
+
first_resp = parsed["responseSet"][0]["response"][0]
|
65 |
+
last_resp = parsed["responseSet"][0]["response"][-1]
|
66 |
+
textQuery = []
|
67 |
+
print(last_resp["score"])
|
68 |
+
print(first_resp["score"])
|
69 |
+
if last_resp["score"] < 0.3 or first_resp["score"] < 0.3:
|
70 |
+
textQuery.append(
|
71 |
+
"I'm sorry, I don't have any information about that.")
|
72 |
+
else:
|
73 |
+
textQuery = print_responses(parsed["responseSet"][0], self.cur)
|
74 |
+
textQuery.insert(0, "\n")
|
75 |
+
textQuery.insert(
|
76 |
+
0, "Here's what other customers had to say about that:")
|
77 |
+
textQuery = "\n".join(textQuery)
|
78 |
+
dispatcher.utter_message(text=textQuery)
|
79 |
+
|
80 |
+
# Revert user message which led to fallback.
|
81 |
+
return [UserUtteranceReverted()]
|
82 |
+
|
83 |
+
|
84 |
+
def print_responses(response_set, sqlite_cursor):
|
85 |
+
"""Print responses to the console."""
|
86 |
+
text_list = []
|
87 |
+
for result in response_set["response"]:
|
88 |
+
doc = response_set["document"][result["documentIndex"]]
|
89 |
+
query = f"""
|
90 |
+
SELECT title, date, hotel, review FROM reviews
|
91 |
+
WHERE doc_id="{doc["id"]}"
|
92 |
+
"""
|
93 |
+
for row in sqlite_cursor.execute(query):
|
94 |
+
title, date, hotel, fulltext = row
|
95 |
+
text_list.append("**" + title + "**")
|
96 |
+
if is_title(result):
|
97 |
+
text_list.append(f"{head(fulltext)}")
|
98 |
+
else:
|
99 |
+
t = result["text"]
|
100 |
+
text_list.append(f"{highlight(fulltext, t)}")
|
101 |
+
text_list.append(
|
102 |
+
"*" + f"{" > \"Jumeirah Hotels & Resorts\" reviewed on {date}" + " *")
|
103 |
+
text_list.append("\n")
|
104 |
+
break
|
105 |
+
return text_list
|
106 |
+
|
107 |
+
|
108 |
+
def highlight(fulltext, snippet):
|
109 |
+
"""Return a result snippet with context, suitable for terminal display."""
|
110 |
+
if snippet in fulltext:
|
111 |
+
start = fulltext.index(snippet)
|
112 |
+
end = start + len(snippet)
|
113 |
+
|
114 |
+
lines = textwrap.wrap(fulltext)
|
115 |
+
start_line = 0
|
116 |
+
end_line = len(lines)
|
117 |
+
pos = 0
|
118 |
+
|
119 |
+
# Figure out which lines to display, and insert ANSI
|
120 |
+
# code to highlight the actual snippet.
|
121 |
+
for x, line in enumerate(lines):
|
122 |
+
next_pos = pos + len(line)
|
123 |
+
|
124 |
+
color_start = pos <= start < next_pos
|
125 |
+
color_end = pos <= end < next_pos
|
126 |
+
|
127 |
+
if color_start and color_end:
|
128 |
+
start_line = end_line = x
|
129 |
+
ips = start - pos - x # insertion point
|
130 |
+
ipe = end - pos - x # insertion point
|
131 |
+
lines[x] = line[:ips] + "**" + line[ips:ipe] + \
|
132 |
+
"**" + line[ipe:]
|
133 |
+
elif color_start:
|
134 |
+
start_line = x
|
135 |
+
ip = start - pos - x # insertion point
|
136 |
+
lines[x] = line[:ip] + "**" + line[ip:]
|
137 |
+
elif color_end:
|
138 |
+
end_line = x
|
139 |
+
ip = end - pos - x # insertion point
|
140 |
+
lines[x] = line[:ip] + "**" + line[ip:]
|
141 |
+
|
142 |
+
pos = next_pos
|
143 |
+
|
144 |
+
# Widen the line selection to include a bit of context.
|
145 |
+
if start_line > 0:
|
146 |
+
start_line -= 1
|
147 |
+
end_line += 2
|
148 |
+
return prettify('\n'.join(lines[start_line:end_line]))
|
149 |
+
return prettify(snippet)
|
150 |
+
|
151 |
+
|
152 |
+
def head(fulltext):
|
153 |
+
"""Returns the first three lines of the review."""
|
154 |
+
lines = textwrap.wrap(fulltext)
|
155 |
+
return prettify('\n'.join(lines[0:3]) + '...')
|
156 |
+
|
157 |
+
|
158 |
+
def is_title(result):
|
159 |
+
"""Returns true if the result is a title match."""
|
160 |
+
for metadatum in result["metadata"]:
|
161 |
+
if metadatum["name"] == "is_title":
|
162 |
+
return metadatum["value"] == "true"
|
163 |
+
return False
|
164 |
+
|
165 |
+
|
166 |
+
def prettify(text):
|
167 |
+
"""Clean up the text to make it more suitable for display."""
|
168 |
+
return text.replace("&", "&").replace(""", "\"")
|
config.yml
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Configuration for Rasa NLU.
|
2 |
+
# https://rasa.com/docs/rasa/nlu/components/
|
3 |
+
language: en
|
4 |
+
|
5 |
+
pipeline:
|
6 |
+
- name: SpacyNLP
|
7 |
+
- name: SpacyTokenizer
|
8 |
+
- name: SpacyFeaturizer
|
9 |
+
- name: RegexFeaturizer
|
10 |
+
- name: LexicalSyntacticFeaturizer
|
11 |
+
- name: CountVectorsFeaturizer
|
12 |
+
- name: CountVectorsFeaturizer
|
13 |
+
analyzer: "char_wb"
|
14 |
+
min_ngram: 1
|
15 |
+
max_ngram: 4
|
16 |
+
- name: DIETClassifier
|
17 |
+
epochs: 100
|
18 |
+
- name: EntitySynonymMapper
|
19 |
+
- name: ResponseSelector
|
20 |
+
epochs: 100
|
21 |
+
- name: FallbackClassifier
|
22 |
+
threshold: 0.6
|
23 |
+
ambiguity_threshold: 0.1
|
24 |
+
|
25 |
+
# Configuration for Rasa Core.
|
26 |
+
# https://rasa.com/docs/rasa/core/policies/
|
27 |
+
policies:
|
credentials.yml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file contains the credentials for the voice & chat platforms
|
2 |
+
# which your bot is using.
|
3 |
+
# https://rasa.com/docs/rasa/messaging-and-voice-channels
|
4 |
+
|
5 |
+
rasa:
|
6 |
+
url: "http://localhost:5002/api"
|
data/nlu.yml
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# NLU training data for the bot.
|
2 |
+
# This file stores the expected queries from the user.
|
3 |
+
# Whenever a user utters a message, it is always matched to an intent.
|
4 |
+
# This match comes with a confidence number that can be used to identify
|
5 |
+
# how much related the intent is to the uttered message.
|
6 |
+
# Minumum number of examples are 2 for each intent.
|
7 |
+
# When writing a new intent, update domain.yml as well.
|
8 |
+
version: "2.0"
|
9 |
+
|
10 |
+
nlu:
|
11 |
+
- intent: greet
|
12 |
+
examples: |
|
13 |
+
- hey
|
14 |
+
- hello
|
15 |
+
- hi
|
16 |
+
- hello there
|
17 |
+
- good morning
|
18 |
+
- good evening
|
19 |
+
- moin
|
20 |
+
- hey there
|
21 |
+
- let's go
|
22 |
+
- hey dude
|
23 |
+
- goodmorning
|
24 |
+
- goodevening
|
25 |
+
- good afternoon
|
26 |
+
|
27 |
+
- intent: goodbye
|
28 |
+
examples: |
|
29 |
+
- good afternoon
|
30 |
+
- cu
|
31 |
+
- good by
|
32 |
+
- cee you later
|
33 |
+
- good night
|
34 |
+
- bye
|
35 |
+
- goodbye
|
36 |
+
- have a nice day
|
37 |
+
- see you around
|
38 |
+
- bye bye
|
39 |
+
- see you later
|
40 |
+
|
41 |
+
- intent: affirm
|
42 |
+
examples: |
|
43 |
+
- yes
|
44 |
+
- y
|
45 |
+
- indeed
|
46 |
+
- of course
|
47 |
+
- that sounds good
|
48 |
+
- correct
|
49 |
+
|
50 |
+
- intent: deny
|
51 |
+
examples: |
|
52 |
+
- no
|
53 |
+
- n
|
54 |
+
- never
|
55 |
+
- I don't think so
|
56 |
+
- don't like that
|
57 |
+
- no way
|
58 |
+
- not really
|
59 |
+
|
60 |
+
- intent: ask_location
|
61 |
+
examples: |
|
62 |
+
- Where is the hotel?
|
63 |
+
- The hotel is where?
|
64 |
+
- In which city is the hotel?
|
65 |
+
|
66 |
+
- intent: jumeirah_living
|
67 |
+
examples: |
|
68 |
+
- What is Jumeirah Living?
|
69 |
+
- Is Jumeirah Living a package?
|
70 |
+
- What can yo tell of Jumeirah Living?
|
71 |
+
- Jumeirah Living?
|
72 |
+
- Jumeirah?
|
73 |
+
|
74 |
+
- intent: jumeirah_one
|
75 |
+
examples: |
|
76 |
+
- What is Jumeirah One?
|
77 |
+
- Is Jumeirah One a package?
|
78 |
+
- What can yo tell of Jumeirah One?
|
79 |
+
- Jumeirah One?
|
80 |
+
- Jumeirah?
|
81 |
+
|
82 |
+
- intent: lost_and_found
|
83 |
+
examples: |
|
84 |
+
- What is your policy on list and found items?
|
85 |
+
- I lost something, can it be returned?
|
86 |
+
- Luggage lost
|
87 |
+
- Lost my phone.
|
88 |
+
- Return a lost items?
|
89 |
+
|
90 |
+
- intent: jumeirah
|
91 |
+
examples: |
|
92 |
+
- What is Jumeirah?
|
93 |
+
- Is Jumeirah a hotel or a brand?
|
94 |
+
|
95 |
+
- intent: reservations
|
96 |
+
examples: |
|
97 |
+
- How many rooms do you have?
|
98 |
+
- i want to reserve rooms
|
99 |
+
- Rooms available
|
100 |
+
- Book a room
|
101 |
+
- Need a place to stay for the night
|
data/rules.yml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Rules, along with stories are used as training data for the bot and define
|
2 |
+
# how a conversation should always happen provided an intent.
|
3 |
+
# If in doubt, use stories and do not over-use rules.
|
4 |
+
version: "2.0"
|
5 |
+
|
6 |
+
rules:
|
7 |
+
|
8 |
+
- rule: Say goodbye anytime the user says goodbye
|
9 |
+
steps:
|
10 |
+
- intent: goodbye
|
11 |
+
- action: utter_goodbye
|
12 |
+
|
13 |
+
- rule: Ask the user to rephrase whenever they send a message with low NLU confidence
|
14 |
+
steps:
|
15 |
+
- intent: nlu_fallback
|
16 |
+
- action: zir_action_fallback
|
data/stories.yml
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file presents stories or the conversations likely to happen
|
2 |
+
# with the user. Stories are also training data for the bot to stitch intents
|
3 |
+
# with actions & to behave more like a human.
|
4 |
+
version: "2.0"
|
5 |
+
|
6 |
+
stories:
|
7 |
+
|
8 |
+
- story: faq question
|
9 |
+
steps:
|
10 |
+
- intent: greet
|
11 |
+
- action: utter_greet
|
12 |
+
- intent: reservations
|
13 |
+
- action: utter_reservation
|
14 |
+
|
15 |
+
- story: faq jum liv
|
16 |
+
steps:
|
17 |
+
- intent: greet
|
18 |
+
- action: utter_greet
|
19 |
+
- intent: jumeirah_living
|
20 |
+
- action: utter_jum_liv
|
21 |
+
|
22 |
+
- story: faq jum one
|
23 |
+
steps:
|
24 |
+
- intent: greet
|
25 |
+
- action: utter_greet
|
26 |
+
- intent: jumeirah_one
|
27 |
+
- action: utter_jum_one
|
28 |
+
|
29 |
+
- story: faq jum
|
30 |
+
steps:
|
31 |
+
- intent: greet
|
32 |
+
- action: utter_greet
|
33 |
+
- intent: jumeirah
|
34 |
+
- action: utter_jum
|
35 |
+
|
36 |
+
- story: faq lost
|
37 |
+
steps:
|
38 |
+
- intent: greet
|
39 |
+
- action: utter_greet
|
40 |
+
- intent: lost_and_found
|
41 |
+
- action: utter_lost_found
|
domain.yml
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file binds the different aspects of your bot together.
|
2 |
+
# Stories, intents, actions etc. are all declared here to be used.
|
3 |
+
# To learn more https://rasa.com/docs/rasa/domain/
|
4 |
+
version: "2.0"
|
5 |
+
|
6 |
+
intents:
|
7 |
+
- greet
|
8 |
+
- goodbye
|
9 |
+
- affirm
|
10 |
+
- deny
|
11 |
+
- jumeirah_living
|
12 |
+
- jumeirah_one
|
13 |
+
- lost_and_found
|
14 |
+
- jumeirah
|
15 |
+
- reservations
|
16 |
+
- ask_location
|
17 |
+
|
18 |
+
responses:
|
19 |
+
utter_please_rephrase:
|
20 |
+
- text: Sorry I didn't get that. Can you rephrase?
|
21 |
+
|
22 |
+
utter_greet:
|
23 |
+
- text: "Hey! How are you?"
|
24 |
+
|
25 |
+
utter_did_that_help:
|
26 |
+
- text: "Did that help you?"
|
27 |
+
|
28 |
+
utter_happy:
|
29 |
+
- text: "Great, carry on!"
|
30 |
+
|
31 |
+
utter_goodbye:
|
32 |
+
- text: "Bye"
|
33 |
+
|
34 |
+
utter_reservation:
|
35 |
+
- text: "Please go to 'Check Rates & Book Now' section of the hotel you have a reservation for. You will find and an area called 'Cancellations and Amendments'. For all other amendments and cancellations, email or call our Reservations Office."
|
36 |
+
|
37 |
+
utter_jum_liv:
|
38 |
+
- text: "Jumeirah Living is our luxury brand of residences and serviced apartments. Whether for short, mid-term or extended stays, Jumeirah Living will offer innovative yet personal lifestyle experiences unique to each guest, resident and owner, with a strong emphasis on effortless living."
|
39 |
+
|
40 |
+
utter_jum_one:
|
41 |
+
- text: "Jumeirah One is Jumeirah’s loyalty programme designed to recognise and reward loyal guests of Jumeirah. Guests can enjoy more of life’s pleasures with privileged access to an exclusive global lifestyle."
|
42 |
+
|
43 |
+
utter_lost_found:
|
44 |
+
- text: "Should any guests lose personal belongings whilst staying at a Jumeirah Hotel or Resort in Dubai, if recovered, the item will be recorded as 'found' by that particular property. Each property keeps detailed records of all 'found' items and will store these for a maximum of three months. After this period, in line with the directives of the General Department of Criminal Investigation in Dubai, all unclaimed items will be handed over to the nearest Police Station. These 'found' items will then be kept at the police warehouse for a further three months after which they will be auctioned, and any funds raised given to charity.Should hotel guests need to locate any item after the initial three month period expires, they are requested to contact the hotel who will assist in coordinating with the police station where the found items are handed over. The police will then advise the necessary procedures to locate any item."
|
45 |
+
|
46 |
+
utter_jum:
|
47 |
+
- text: "Jumeirah is a world-class international hotel and hospitality company which currently manages hotels in Abu Dhabi, Bahrain, Dubai, Frankfurt, Kuwait, London, Maldives, Mallorca and Shanghai. Please view our Portfolio for more information."
|
48 |
+
|
49 |
+
session_config:
|
50 |
+
session_expiration_time: 60
|
51 |
+
carry_over_slots_to_new_session: true
|
52 |
+
|
53 |
+
actions:
|
54 |
+
- zir_action_fallback
|
endpoints.yml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file contains the different endpoints your bot can use.
|
2 |
+
|
3 |
+
action_endpoint:
|
4 |
+
url: "http://0.0.0.0:5055/webhook"
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
sqlite3
|
2 |
+
textwrap
|
3 |
+
spacy
|
reviews.db
ADDED
Binary file (926 kB). View file
|
|
tests/test_stories.yml
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#### This file contains tests to evaluate that your bot behaves as expected.
|
2 |
+
#### If you want to learn more, please see the docs: https://rasa.com/docs/rasa/testing-your-assistant
|
3 |
+
stories:
|
4 |
+
|
5 |
+
- story: A basic story test
|
6 |
+
steps:
|
7 |
+
- user: |
|
8 |
+
hello
|
9 |
+
intent: greet
|
10 |
+
- action: utter_greet
|
11 |
+
- user: |
|
12 |
+
Book a room for two please.
|
13 |
+
intent: reservations
|
14 |
+
- action: utter_reservation
|
15 |
+
|
16 |
+
|
17 |
+
- story: Fallback test
|
18 |
+
steps:
|
19 |
+
- user: |
|
20 |
+
hello
|
21 |
+
intent: greet
|
22 |
+
- action: utter_greet
|
23 |
+
- user: |
|
24 |
+
Can we play golf?
|
25 |
+
intent: nlu_fallback
|
26 |
+
- action: zir_action_fallback
|
web/index.html
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<head>
|
2 |
+
<link rel="stylesheet"
|
3 |
+
href="https://npm-scalableminds.s3.eu-central-1.amazonaws.com/@scalableminds/chatroom@master/dist/Chatroom.css" />
|
4 |
+
</head>
|
5 |
+
|
6 |
+
<body>
|
7 |
+
<div class="chat-container"></div>
|
8 |
+
|
9 |
+
<script
|
10 |
+
src="https://npm-scalableminds.s3.eu-central-1.amazonaws.com/@scalableminds/chatroom@master/dist/Chatroom.js" />
|
11 |
+
</script>
|
12 |
+
<script type="text/javascript">
|
13 |
+
var chatroom = new window.Chatroom({
|
14 |
+
host: "http://localhost:5005",
|
15 |
+
title: "Kendra, powered by Rasa and ZIR AI",
|
16 |
+
container: document.querySelector(".chat-container"),
|
17 |
+
welcomeMessage: "Hello, my name is Kendra, and I'll be happy to assist with your questions about Burj Al Arab Jumeirah. How may I help you"
|
18 |
+
});
|
19 |
+
chatroom.openChat();
|
20 |
+
</script>
|
21 |
+
</body>
|
web/rasa_zir.gif
ADDED