File size: 5,480 Bytes
04c94f2
 
 
 
c8c0c7c
 
 
 
 
 
 
 
 
 
 
d288445
c8c0c7c
 
 
 
3f0ba1f
 
d288445
 
3f0ba1f
d288445
c8c0c7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d288445
 
c8c0c7c
 
 
 
 
d288445
c8c0c7c
 
 
 
d288445
c8c0c7c
 
 
 
 
 
d288445
046f158
c8c0c7c
 
d288445
abcb242
 
c8c0c7c
 
d288445
c8c0c7c
 
 
 
 
 
d288445
c8c0c7c
 
 
 
 
 
 
 
d288445
c8c0c7c
d288445
c8c0c7c
 
d288445
 
e45a837
d288445
c8c0c7c
d288445
c8c0c7c
 
 
 
 
 
 
 
6e3243e
c8c0c7c
 
 
 
 
 
 
 
 
 
507bbac
c8c0c7c
 
 
6e3243e
 
c8c0c7c
 
 
 
6e3243e
c8c0c7c
 
 
6e3243e
c8c0c7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""
This files contains your custom actions which can be used 
to run custom Python code.
"""
from typing import Any, Text, Dict, List
import json
import requests
import sqlite3
import textwrap


from rasa_sdk import Action, Tracker
from rasa_sdk.events import UserUtteranceReverted
from rasa_sdk.executor import CollectingDispatcher


class ActionDefaultFallback(Action):
    """Executes the fallback action and goes back to the previous state
    of the dialogue"""

    customer_id = "1526022105"
    corpus_id = 64
    header = {
        "customer-id": customer_id,
        "x-api-key": "zqt_WvU_2ZweWSRlgL9671UWkbvrVWxOjhJpT07dPw"
    }
    con = None

    def name(self) -> Text:
        con = sqlite3.connect("./reviews.db")
        self.cur = con.cursor()
        return "zir_action_fallback"

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

        number_results = 3
        data_dict = {
            "query": [
                {
                    "query": tracker.latest_message["text"],
                    "num_results": number_results,
                    "corpus_key": [
                        {
                            "customer_id": self.customer_id,
                            "corpus_id": self.corpus_id
                        }
                    ]
                }
            ]
        }

        payload = json.dumps(data_dict)
        response = requests.post(f"https://h.serving.zir-ai.io:443/v1/query",
                                 data=payload,
                                 verify=True,
                                 headers=self.header,
                                 timeout=10)
        parsed = json.loads(response.text)
        first_resp = parsed["responseSet"][0]["response"][0]
        last_resp = parsed["responseSet"][0]["response"][-1]
        textQuery = []
        if last_resp["score"] < 0.3 or first_resp["score"] < 0.3:
            textQuery.append(
                "I'm sorry, I don't have any information about that.")
        else:
            textQuery = print_responses(parsed["responseSet"][0], self.cur)
            textQuery.insert(0, "\n")
            textQuery.insert(
                0, "Here's what other customers had to say about that:")
        textQuery = "\n".join(textQuery)
        dispatcher.utter_message(text=textQuery)

        # Revert user message which led to fallback.
        return [UserUtteranceReverted()]


def print_responses(response_set, sqlite_cursor):
    """Print responses to the console."""
    text_list = []
    for result in response_set["response"]:
        doc = response_set["document"][result["documentIndex"]]
        query = f"""
            SELECT title, date, hotel, review FROM reviews
                WHERE doc_id="{doc["id"]}"
        """
        for row in sqlite_cursor.execute(query):
            title, date, hotel, fulltext = row
            text_list.append("**" + title + "**")
            if is_title(result):
                text_list.append(f"{head(fulltext)}")
            else:
                t = result["text"]
                text_list.append(f"{highlight(fulltext, t)}")
            text_list.append(
                "*" + f" > \"Atlantis, Dubai\" reviewed on {date}" + " *")
            text_list.append("\n")
            break
    return text_list


def highlight(fulltext, snippet):
    """Return a result snippet with context, suitable for terminal display."""
    if snippet in fulltext:
        start = fulltext.index(snippet)
        end = start + len(snippet)

        lines = textwrap.wrap(fulltext, drop_whitespace=False)
        start_line = 0
        end_line = len(lines)
        pos = 0

        # Figure out which lines to display, and insert ANSI
        # code to highlight the actual snippet.
        for x, line in enumerate(lines):
            next_pos = pos + len(line)

            color_start = pos <= start < next_pos
            color_end = pos <= end <= next_pos

            if color_start and color_end:
                start_line = end_line = x
                ips = start - pos   # insertion point
                ipe = end - pos     # insertion point
                lines[x] = line[:ips] + "**" + line[ips:ipe] + \
                    "**" + line[ipe:]
            elif color_start:
                start_line = x
                ip = start - pos    # insertion point
                lines[x] = line[:ip] + "**" + line[ip:]
            elif color_end:
                end_line = x
                ip = end - pos    # insertion point
                lines[x] = line[:ip] + "**" + line[ip:]

            pos = next_pos

        # Widen the line selection to include a bit of context.
        if start_line > 0:
            start_line -= 1
        end_line += 2
        return prettify('\n'.join(lines[start_line:end_line]))
    return prettify(snippet)

def head(fulltext):
    """Returns the first three lines of the review."""
    lines = textwrap.wrap(fulltext)
    return prettify('\n'.join(lines[0:3]) + '...')


def is_title(result):
    """Returns true if the result is a title match."""
    for metadatum in result["metadata"]:
        if metadatum["name"] == "is_title":
            return metadatum["value"] == "true"
    return False


def prettify(text):
    """Clean up the text to make it more suitable for display."""
    return text.replace("&amp;", "&").replace("&quot;", "\"")