Upload 4 files
Browse files- app.py +169 -0
- decoder_output.py +35 -0
- neural_searcher.py +50 -0
- traversaal.py +28 -0
app.py
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import decoder_output
|
3 |
+
import cut_text
|
4 |
+
import hotel_chatbot
|
5 |
+
import traversaal
|
6 |
+
import streamlit as st
|
7 |
+
from qdrant_client import QdrantClient
|
8 |
+
from neural_searcher import NeuralSearcher
|
9 |
+
|
10 |
+
|
11 |
+
def home_page():
|
12 |
+
# st.title("TraverGo")
|
13 |
+
|
14 |
+
st.markdown("<h1 style='text-align: center; color: white;'>TraverGo</h1>", unsafe_allow_html=True)
|
15 |
+
st.markdown("<h2 style='text-align: center; color: white;'>Find any type of Hotel you want !</h2>", unsafe_allow_html=True)
|
16 |
+
st.session_state["value"] = None
|
17 |
+
|
18 |
+
def search_hotels():
|
19 |
+
query = st.text_input("Enter your hotel preferences:", placeholder ="clean and cheap hotel with good food and gym")
|
20 |
+
|
21 |
+
if "load_state" not in st.session_state:
|
22 |
+
st.session_state.load_state = False;
|
23 |
+
|
24 |
+
# Perform semantic search when user submits query
|
25 |
+
if query or st.session_state.load_state:
|
26 |
+
st.session_state.load_state=True;
|
27 |
+
neural_searcher = NeuralSearcher(collection_name="hotel_descriptions")
|
28 |
+
results = sorted(neural_searcher.search(query), key=lambda d: d['sentiment_rate_average'])
|
29 |
+
st.subheader("Hotels")
|
30 |
+
for hotel in results:
|
31 |
+
explore_hotel(hotel, query) # Call a separate function for each hotel
|
32 |
+
|
33 |
+
def explore_hotel(hotel, query):
|
34 |
+
if "decoder" not in st.session_state:
|
35 |
+
st.session_state['decoder'] = [0];
|
36 |
+
|
37 |
+
button = st.checkbox(hotel['hotel_name'])
|
38 |
+
|
39 |
+
|
40 |
+
if not button:
|
41 |
+
if st.session_state.decoder == [0]:
|
42 |
+
x = (decoder_output.decode(hotel['hotel_description'][:1000], query))
|
43 |
+
st.session_state['value_1'] = x
|
44 |
+
st.session_state.decoder = [st.session_state.decoder[0] + 1]
|
45 |
+
st.write(x)
|
46 |
+
|
47 |
+
elif (st.session_state.decoder == [1]):
|
48 |
+
x = (decoder_output.decode(hotel['hotel_description'][:1000], query))
|
49 |
+
st.session_state['value_2'] = x
|
50 |
+
|
51 |
+
st.session_state.decoder = [st.session_state.decoder[0] + 1];
|
52 |
+
st.write(x);
|
53 |
+
|
54 |
+
elif st.session_state.decoder == [2]:
|
55 |
+
x = (decoder_output.decode(hotel['hotel_description'][:1000], query))
|
56 |
+
st.session_state['value_3'] = x;
|
57 |
+
st.session_state.decoder = [st.session_state.decoder[0] + 1];
|
58 |
+
st.write(x);
|
59 |
+
|
60 |
+
|
61 |
+
if (st.session_state.decoder[0] >= 3):
|
62 |
+
i = st.session_state.decoder[0] % 3
|
63 |
+
l = ['value_1', 'value_2', 'value_3']
|
64 |
+
st.session_state[l[i - 1]];
|
65 |
+
st.session_state.decoder = [st.session_state.decoder[0] + 1];
|
66 |
+
|
67 |
+
if button:
|
68 |
+
st.session_state["value"] = hotel
|
69 |
+
|
70 |
+
|
71 |
+
# if (st.session_state.decoder[0] < 3):
|
72 |
+
# st.write(decoder_output.decode(hotel['hotel_description'][:1000], query))
|
73 |
+
# st.session_state.decoder = [st.session_state[0] + 1];
|
74 |
+
#
|
75 |
+
|
76 |
+
question = st.text_input(f"Enter a question about {hotel['hotel_name']}:");
|
77 |
+
|
78 |
+
if question:
|
79 |
+
st.write(ares_api(question + "for" + hotel['hotel_name'] + "located in" + hotel['country']))
|
80 |
+
# if "load_state" not in st.session_state:
|
81 |
+
# st.session_state.load_state = False;
|
82 |
+
# Perform semantic search when user submits query
|
83 |
+
# if question:
|
84 |
+
|
85 |
+
|
86 |
+
|
87 |
+
|
88 |
+
|
89 |
+
|
90 |
+
search_hotels()
|
91 |
+
chat_page()
|
92 |
+
|
93 |
+
|
94 |
+
def ares_api(query):
|
95 |
+
response_json = traversaal.getResponse(query);
|
96 |
+
# if response_json is not json:
|
97 |
+
# return "Could not find information"
|
98 |
+
return (response_json['data']['response_text'])
|
99 |
+
def chat_page():
|
100 |
+
hotel = st.session_state["value"]
|
101 |
+
st.session_state.value = None
|
102 |
+
if (hotel == None):
|
103 |
+
return;
|
104 |
+
|
105 |
+
st.write(hotel['hotel_name']);
|
106 |
+
st.title("Conversation")
|
107 |
+
|
108 |
+
# Set OpenAI API key from Streamlit secrets
|
109 |
+
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
110 |
+
|
111 |
+
# st.session_state.pop("messages")
|
112 |
+
# Set a default model
|
113 |
+
if "openai_model" not in st.session_state:
|
114 |
+
st.session_state["openai_model"] = "gpt-3.5-turbo"
|
115 |
+
|
116 |
+
prompt = f"{hotel['hotel_description'][:2000]}\n\n you are a hotel advisor now, you should give the best response based on the above text. i will now ask you some questions get ready"
|
117 |
+
# Initialize chat history
|
118 |
+
if "messages" not in st.session_state:
|
119 |
+
st.session_state.messages = [{"role": "user", "content": prompt}]
|
120 |
+
|
121 |
+
# Display chat messages from history on app rerun
|
122 |
+
# keys_subset = list(st.session_state.messages.keys())[1:]
|
123 |
+
# subset_dict = {key: original_dict[key] for key in keys_subset}
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
for message in st.session_state.messages[1:]:
|
128 |
+
with st.chat_message(message["role"]):
|
129 |
+
st.markdown(message["content"])
|
130 |
+
|
131 |
+
# Accept user input
|
132 |
+
if prompt := st.chat_input("What is up?"):
|
133 |
+
x = ares_api(prompt)
|
134 |
+
# Add user message to chat history
|
135 |
+
st.session_state.messages[0]['content'] += "\n" + x;
|
136 |
+
st.session_state.messages.append({"role": "assistant", "content": prompt})
|
137 |
+
# Display user message in chat message container
|
138 |
+
with st.chat_message("user"):
|
139 |
+
st.markdown(prompt)
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
#Display assistant response in chat message container
|
144 |
+
with st.chat_message("assistant"):
|
145 |
+
stream = client.chat.completions.create(
|
146 |
+
model=st.session_state["openai_model"],
|
147 |
+
messages=[
|
148 |
+
{"role": m["role"], "content": m["content"]}
|
149 |
+
for m in st.session_state.messages
|
150 |
+
],
|
151 |
+
stream=True,
|
152 |
+
)
|
153 |
+
response = st.write_stream(stream)
|
154 |
+
st.session_state.messages.append({"role": "assistant", "content": response})
|
155 |
+
|
156 |
+
|
157 |
+
# hotel_chatbot.start_page();
|
158 |
+
|
159 |
+
home_page()
|
160 |
+
#
|
161 |
+
#
|
162 |
+
# page = st.sidebar.selectbox("Select a page", ["Home", "Chatbot"])
|
163 |
+
#
|
164 |
+
#
|
165 |
+
# if page == "Home":
|
166 |
+
# home_page()
|
167 |
+
# elif page == "Chatbot":
|
168 |
+
# chat_page(None)
|
169 |
+
#
|
decoder_output.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
import os
|
3 |
+
# Load the Falcon 7B model
|
4 |
+
from openai import OpenAI
|
5 |
+
import streamlit as st
|
6 |
+
|
7 |
+
def decode(hotel_description, query):
|
8 |
+
client = OpenAI(api_key=st.secrets["OPENAI_API_KEY"])
|
9 |
+
|
10 |
+
prompt = f"""
|
11 |
+
this is the hotel descriptoin:
|
12 |
+
|
13 |
+
\"{hotel_description}\"
|
14 |
+
|
15 |
+
and these are my requirements
|
16 |
+
|
17 |
+
\"{query}\"
|
18 |
+
|
19 |
+
now tell me why the hotel might be a good fit for me given the requirements, make it consise.
|
20 |
+
"""
|
21 |
+
|
22 |
+
stream = client.chat.completions.create(
|
23 |
+
model="gpt-3.5-turbo",
|
24 |
+
messages=[{"role": "user", "content": prompt}],
|
25 |
+
stream=True,
|
26 |
+
)
|
27 |
+
str = ""
|
28 |
+
for chunk in stream:
|
29 |
+
if chunk.choices[0].delta.content is not None:
|
30 |
+
str += (chunk.choices[0].delta.content)
|
31 |
+
return str
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
|
neural_searcher.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from qdrant_client import QdrantClient
|
2 |
+
import streamlit as st
|
3 |
+
|
4 |
+
from qdrant_client.models import Filter
|
5 |
+
from sentence_transformers import SentenceTransformer
|
6 |
+
|
7 |
+
#
|
8 |
+
class NeuralSearcher:
|
9 |
+
def __init__(self, collection_name):
|
10 |
+
self.collection_name = collection_name
|
11 |
+
# Initialize encoder model
|
12 |
+
self.model = SentenceTransformer("all-MiniLM-L6-v2", device="cpu")
|
13 |
+
# initialize Qdrant client
|
14 |
+
# self.qdrant_client = QdrantClient("http://localhost:6333")
|
15 |
+
self.qdrant_client = QdrantClient(
|
16 |
+
url="https://ed55d75f-bb54-4c09-8907-8d112e6278a1.us-east4-0.gcp.cloud.qdrant.io",
|
17 |
+
api_key=st.secrets["QDRANT_API_KEY"],
|
18 |
+
)
|
19 |
+
|
20 |
+
def search(self, text: str):
|
21 |
+
# Convert text query into vector
|
22 |
+
vector = self.model.encode(text).tolist()
|
23 |
+
|
24 |
+
#
|
25 |
+
# city_of_interest = "Berlin"
|
26 |
+
# # Define a filter for cities
|
27 |
+
# city_filter = Filter(**{
|
28 |
+
# "must": [{
|
29 |
+
# "key": "country", # Store city information in a field of the same name
|
30 |
+
# "match": { # This condition checks if payload field has the requested value
|
31 |
+
# "value": "London"
|
32 |
+
# }
|
33 |
+
# }]
|
34 |
+
# })
|
35 |
+
#
|
36 |
+
# Use `vector` for search for closest vectors in the collection
|
37 |
+
search_result = self.qdrant_client.search(
|
38 |
+
collection_name=self.collection_name,
|
39 |
+
query_vector=vector,
|
40 |
+
query_filter=None, # If you don't want any filters for now
|
41 |
+
limit=3, # 5 the most closest results is enough
|
42 |
+
)
|
43 |
+
# `search_result` contains found vector ids with similarity scores along with the stored payload
|
44 |
+
# In this function you are interested in payload only
|
45 |
+
payloads = [hit.payload for hit in search_result]
|
46 |
+
return payloads
|
47 |
+
|
48 |
+
|
49 |
+
|
50 |
+
|
traversaal.py
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import streamlit as st
|
3 |
+
import json
|
4 |
+
import os
|
5 |
+
|
6 |
+
def getResponse(query):
|
7 |
+
|
8 |
+
url = "https://api-ares.traversaal.ai/live/predict"
|
9 |
+
|
10 |
+
|
11 |
+
payload = { "query": [query] }
|
12 |
+
headers = {
|
13 |
+
"x-api-key": st.secrets["TRAVERSAAL"],
|
14 |
+
"content-type": "application/json"
|
15 |
+
}
|
16 |
+
|
17 |
+
response = requests.post(url, json=payload, headers=headers)
|
18 |
+
if response.status_code == 200:
|
19 |
+
# Get the JSON content from the response
|
20 |
+
json_content = response.json()
|
21 |
+
|
22 |
+
# Specify the file path where you want to save the JSON content
|
23 |
+
return json_content
|
24 |
+
else:
|
25 |
+
print(response.status_code)
|
26 |
+
return " "
|
27 |
+
|
28 |
+
|