Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -9,6 +9,20 @@ import Arcana
|
|
9 |
from nylon import *
|
10 |
import pandas as pd
|
11 |
import json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
# SSL configuration to avoid verification issues
|
14 |
try:
|
@@ -19,23 +33,58 @@ else:
|
|
19 |
ssl._create_default_https_context = _create_unverified_https_context
|
20 |
|
21 |
def query_database2(query):
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
for message in relevant_messages:
|
33 |
-
print(f"Sender: {message[0]}, Time: {message[1]}, Tag: {message[3]}")
|
34 |
-
print(f"Message: {message[2][:100]}...")
|
35 |
-
print()
|
36 |
|
37 |
-
df_data = [str(message) for message in relevant_messages]
|
38 |
-
return ';'.join(df_data)
|
39 |
|
40 |
# OpenAI client setup
|
41 |
client = OpenAI(
|
@@ -46,7 +95,7 @@ client = OpenAI(
|
|
46 |
# Function list for OpenAI API
|
47 |
function_list = [
|
48 |
{
|
49 |
-
"name": "
|
50 |
"description": "Query the database and return a list of results as strings",
|
51 |
"parameters": {
|
52 |
"type": "object",
|
@@ -58,12 +107,27 @@ function_list = [
|
|
58 |
},
|
59 |
"required": ["query"]
|
60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
]
|
63 |
|
64 |
# Mapping of function names to actual function objects
|
65 |
function_map = {
|
66 |
-
"
|
|
|
67 |
}
|
68 |
|
69 |
def execute_function(function_name, function_args):
|
@@ -72,12 +136,19 @@ def execute_function(function_name, function_args):
|
|
72 |
else:
|
73 |
return f"Error: Function {function_name} not found"
|
74 |
|
75 |
-
|
|
|
76 |
def openai_api_call(messages, retries=3, delay=5):
|
|
|
|
|
77 |
for attempt in range(retries):
|
78 |
try:
|
|
|
|
|
|
|
|
|
79 |
completion = client.chat.completions.create(
|
80 |
-
model="gpt-3.5-turbo",
|
81 |
messages=messages,
|
82 |
functions=function_list,
|
83 |
function_call='auto',
|
@@ -109,10 +180,43 @@ def openai_api_call(messages, retries=3, delay=5):
|
|
109 |
else:
|
110 |
return "Sorry, I am having trouble connecting to the server. Please try again later."
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
# Chatbot response function
|
113 |
def chatbot_response(message, history):
|
114 |
messages = [{"role": "system", "content": '''You are Arcana, a dynamic study resource database designed to help students excel in their exams. Your responses should be accurate, informative, and evidence-based whenever possible. Follow these guidelines:
|
115 |
-
Your primary goal is to provide students with the most helpful and accurate study information, utilizing both your internal knowledge and the PDF resources at your disposal.'''}]
|
116 |
|
117 |
for human, assistant in history:
|
118 |
messages.append({"role": "user", "content": human})
|
@@ -130,7 +234,7 @@ from concurrent.futures import ThreadPoolExecutor
|
|
130 |
# Function to handle the file upload
|
131 |
def handle_file_upload(file):
|
132 |
# Ensure the cache2 directory exists
|
133 |
-
cache_dir =
|
134 |
os.makedirs(cache_dir, exist_ok=True)
|
135 |
|
136 |
# Get the uploaded file path
|
@@ -154,7 +258,7 @@ def handle_file_upload_threaded(file):
|
|
154 |
return future.result()
|
155 |
|
156 |
def list_uploaded_files():
|
157 |
-
foldername
|
158 |
if not os.path.exists(foldername):
|
159 |
return []
|
160 |
files = os.listdir(foldername)
|
@@ -167,7 +271,7 @@ def on_select(evt: gr.SelectData):
|
|
167 |
selected = selected_value
|
168 |
print(f"Selected value: {selected_value} at index: {selected_index}")
|
169 |
|
170 |
-
file_path = os.path.join(
|
171 |
status_message = f"Selected: {selected_value}" if selected_value else "No file selected"
|
172 |
|
173 |
file_size = get_file_size(file_path) if file_path else ""
|
@@ -193,9 +297,8 @@ def get_file_creation_time(file_path):
|
|
193 |
return ""
|
194 |
|
195 |
def delete_file():
|
196 |
-
global selected
|
197 |
if selected:
|
198 |
-
foldername = 'cache'
|
199 |
file_path = os.path.join(foldername, selected)
|
200 |
if os.path.exists(file_path):
|
201 |
os.remove(file_path)
|
@@ -209,12 +312,12 @@ def refresh_files():
|
|
209 |
return list_uploaded_files()
|
210 |
|
211 |
def display_file(evt: gr.SelectData, df):
|
212 |
-
file_path = os.path.join(
|
213 |
return file_path, file_path if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')) else None, f"Displaying: {evt.value}"
|
214 |
|
215 |
def render_to_database():
|
216 |
# This function is undefined as per your request
|
217 |
-
Arcana.main()
|
218 |
|
219 |
def change_theme(theme):
|
220 |
gr.Interface.theme = theme
|
@@ -222,8 +325,8 @@ def change_theme(theme):
|
|
222 |
def rename_file(new_name):
|
223 |
global selected
|
224 |
if selected and new_name:
|
225 |
-
old_path = os.path.join(
|
226 |
-
new_path = os.path.join(
|
227 |
if os.path.exists(old_path):
|
228 |
os.rename(old_path, new_path)
|
229 |
selected = new_name
|
@@ -234,7 +337,7 @@ def rename_file(new_name):
|
|
234 |
|
235 |
def query_database(query):
|
236 |
# Usage example
|
237 |
-
db = ChatDatabase('
|
238 |
|
239 |
# Example 1: Get relevant messages
|
240 |
sender = 'Arcana'
|
@@ -257,6 +360,27 @@ def query_database(query):
|
|
257 |
|
258 |
return df
|
259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
|
261 |
example_database = [
|
262 |
"What is Hydrogen Bonding?",
|
@@ -284,17 +408,20 @@ def get_random_examples(num_examples=5):
|
|
284 |
chatbot_interface = gr.ChatInterface(
|
285 |
chatbot_response,
|
286 |
chatbot=gr.Chatbot(height=400),
|
287 |
-
textbox=gr.Textbox(placeholder="Type your message here...", container=
|
288 |
title="Review With Arcana",
|
289 |
description="ArcanaUI v0.8 - Chatbot",
|
290 |
-
theme="
|
291 |
examples=get_random_examples(),
|
292 |
cache_examples=False,
|
293 |
-
retry_btn=
|
294 |
undo_btn="Delete Previous",
|
295 |
-
clear_btn="Clear"
|
296 |
)
|
297 |
|
|
|
|
|
|
|
298 |
|
299 |
def relaunch():
|
300 |
global demo
|
@@ -324,7 +451,7 @@ async () => {
|
|
324 |
|
325 |
with gr.TabItem("Chatbot"):
|
326 |
chatbot_interface.render()
|
327 |
-
|
328 |
# File uploading interface
|
329 |
with gr.TabItem('Upload'):
|
330 |
gr.Markdown('# Upload and View Files')
|
@@ -380,10 +507,22 @@ async () => {
|
|
380 |
|
381 |
test_nylon = gr.Textbox(label='Test Nylon', placeholder='Query')
|
382 |
uploaded_files_list2 = gr.DataFrame(headers=["Nylon Returned Query"], datatype="str", interactive=False)
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
with gr.TabItem('Theme'):
|
388 |
gr.Markdown('Change Theme')
|
389 |
|
@@ -393,7 +532,13 @@ async () => {
|
|
393 |
theme_button.click(fn=change_theme, inputs=theme_dropdown)
|
394 |
relaunch_button = gr.Button('Relaunch')
|
395 |
relaunch_button.click(fn=relaunch)
|
|
|
|
|
396 |
|
|
|
|
|
|
|
|
|
397 |
|
398 |
# Launch the interface
|
399 |
demo.launch(share=True)
|
|
|
9 |
from nylon import *
|
10 |
import pandas as pd
|
11 |
import json
|
12 |
+
import fiber
|
13 |
+
|
14 |
+
|
15 |
+
foldername = 'Celsiaaa'
|
16 |
+
dbmsmode = 'Fiber'
|
17 |
+
|
18 |
+
try:
|
19 |
+
with open('settings.arcana',mode='r') as file:
|
20 |
+
foldername,dbmsmode = file.read().split('\n')
|
21 |
+
except Exception as e:
|
22 |
+
print(e)
|
23 |
+
with open('settings.arcana',mode='w') as file:
|
24 |
+
newsettings = foldername+'\n'+dbmsmode
|
25 |
+
file.write(newsettings)
|
26 |
|
27 |
# SSL configuration to avoid verification issues
|
28 |
try:
|
|
|
33 |
ssl._create_default_https_context = _create_unverified_https_context
|
34 |
|
35 |
def query_database2(query):
|
36 |
+
print(dbmsmode)
|
37 |
+
if dbmsmode == 'Nylon':
|
38 |
+
db = ChatDatabase(foldername+'.txt')
|
39 |
+
|
40 |
+
sender = 'Arcana'
|
41 |
+
N = 10
|
42 |
+
cache = {}
|
43 |
+
query_tag = None
|
44 |
+
|
45 |
+
relevant_messages = db.get_relevant_messages(sender, query, N, cache, query_tag)
|
46 |
+
|
47 |
+
print("Relevant messages:")
|
48 |
+
for message in relevant_messages:
|
49 |
+
print(f"Sender: {message[0]}, Time: {message[1]}, Tag: {message[3]}")
|
50 |
+
print(f"Message: {message[2][:100]}...")
|
51 |
+
print()
|
52 |
+
|
53 |
+
df_data = [str(message) for message in relevant_messages]
|
54 |
+
return ';'.join(df_data)
|
55 |
+
elif dbmsmode == 'Fiber':
|
56 |
+
dbms = fiber.FiberDBMS()
|
57 |
+
# Load or create the database
|
58 |
+
dbms.load_or_create(foldername+'.txt')
|
59 |
+
results = dbms.query(query, 3)
|
60 |
+
|
61 |
+
# Convert each result dictionary to a string
|
62 |
+
result_strings = []
|
63 |
+
for result in results:
|
64 |
+
result_str = f"Name: {result['name']}\nContent: {result['content']}\nTags: {result['tags']}\nIndex: {result['index']}"
|
65 |
+
result_strings.append(result_str)
|
66 |
+
|
67 |
+
# Join all result strings with a separator
|
68 |
+
return ';'.join(result_strings)
|
69 |
+
|
70 |
+
def list_files_indb(directory=foldername):
|
71 |
+
"""
|
72 |
+
List all files in the given directory, separated by semicolons.
|
73 |
+
|
74 |
+
:param directory: The directory to list files from. Defaults to the current directory.
|
75 |
+
:return: A string of filenames separated by semicolons.
|
76 |
+
"""
|
77 |
+
try:
|
78 |
+
# Get all files in the directory
|
79 |
+
files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
|
80 |
+
|
81 |
+
# Join the filenames with semicolons
|
82 |
+
return ';'.join(files)
|
83 |
+
except Exception as e:
|
84 |
+
return f"An error occurred: {str(e)}"
|
85 |
|
86 |
+
search_mode = 0#Always Search
|
|
|
|
|
|
|
|
|
87 |
|
|
|
|
|
88 |
|
89 |
# OpenAI client setup
|
90 |
client = OpenAI(
|
|
|
95 |
# Function list for OpenAI API
|
96 |
function_list = [
|
97 |
{
|
98 |
+
"name": "search_database",
|
99 |
"description": "Query the database and return a list of results as strings",
|
100 |
"parameters": {
|
101 |
"type": "object",
|
|
|
107 |
},
|
108 |
"required": ["query"]
|
109 |
}
|
110 |
+
},
|
111 |
+
|
112 |
+
{
|
113 |
+
"name": "list_database_files",
|
114 |
+
"description": "Check what files are present in the database",
|
115 |
+
"parameters":{
|
116 |
+
"type":"object",
|
117 |
+
"properties":{
|
118 |
+
"query":{
|
119 |
+
"type":"string",
|
120 |
+
"description":"Gives a list of semicolon seperated file names in the database"
|
121 |
+
},
|
122 |
+
},
|
123 |
+
}
|
124 |
}
|
125 |
]
|
126 |
|
127 |
# Mapping of function names to actual function objects
|
128 |
function_map = {
|
129 |
+
"search_database": query_database2,
|
130 |
+
"list_database_files":list_files_indb
|
131 |
}
|
132 |
|
133 |
def execute_function(function_name, function_args):
|
|
|
136 |
else:
|
137 |
return f"Error: Function {function_name} not found"
|
138 |
|
139 |
+
mapsearchmode = ['always', 'auto', 'none']
|
140 |
+
|
141 |
def openai_api_call(messages, retries=3, delay=5):
|
142 |
+
global search_mode # Declare search_mode as a global variable
|
143 |
+
|
144 |
for attempt in range(retries):
|
145 |
try:
|
146 |
+
# Modify the user's message if search_mode is 0
|
147 |
+
if search_mode == 0:
|
148 |
+
messages[-1]['content'] = "[System: SEARCH when the user ASKED A QUESTION & remember to CITE(the source is the first tag). Otherwise do not search];" + messages[-1]['content']
|
149 |
+
|
150 |
completion = client.chat.completions.create(
|
151 |
+
model="gpt-3.5-turbo",
|
152 |
messages=messages,
|
153 |
functions=function_list,
|
154 |
function_call='auto',
|
|
|
180 |
else:
|
181 |
return "Sorry, I am having trouble connecting to the server. Please try again later."
|
182 |
|
183 |
+
return "Failed to get a response after multiple attempts."
|
184 |
+
|
185 |
+
|
186 |
+
def handle_search_mode(mode):
|
187 |
+
print(mode)
|
188 |
+
global search_mode
|
189 |
+
if mode == "Always":
|
190 |
+
search_mode = 0
|
191 |
+
return "You are in Mode 1"
|
192 |
+
elif mode == "Automatic":
|
193 |
+
search_mode = 1
|
194 |
+
return "You are in Mode 2"
|
195 |
+
else:
|
196 |
+
search_mode = 0
|
197 |
+
return "Select a mode"
|
198 |
+
|
199 |
+
def handle_dbms_mode(mode):
|
200 |
+
print(mode)
|
201 |
+
global dbmsmode
|
202 |
+
with open('settings.arcana',mode='w') as file:
|
203 |
+
newsettings = foldername+'\n'+mode
|
204 |
+
file.write(newsettings)
|
205 |
+
|
206 |
+
if mode == "Nylon":
|
207 |
+
dbmsmode = "Nylon"
|
208 |
+
return "You are in Mode 1"
|
209 |
+
elif mode == "Fiber":
|
210 |
+
dbmsmode = "Fiber"
|
211 |
+
return "You are in Mode 2"
|
212 |
+
else:
|
213 |
+
search_mode = 0
|
214 |
+
return "Select a mode"
|
215 |
+
|
216 |
# Chatbot response function
|
217 |
def chatbot_response(message, history):
|
218 |
messages = [{"role": "system", "content": '''You are Arcana, a dynamic study resource database designed to help students excel in their exams. Your responses should be accurate, informative, and evidence-based whenever possible. Follow these guidelines:
|
219 |
+
Your primary goal is to provide students with the most helpful and accurate study information, utilizing both your internal knowledge and the PDF resources at your disposal. You will search your database for answers and properly intext cite them, unless there is no such data, then you will intextcite[Arcana].'''}]
|
220 |
|
221 |
for human, assistant in history:
|
222 |
messages.append({"role": "user", "content": human})
|
|
|
234 |
# Function to handle the file upload
|
235 |
def handle_file_upload(file):
|
236 |
# Ensure the cache2 directory exists
|
237 |
+
cache_dir = foldername
|
238 |
os.makedirs(cache_dir, exist_ok=True)
|
239 |
|
240 |
# Get the uploaded file path
|
|
|
258 |
return future.result()
|
259 |
|
260 |
def list_uploaded_files():
|
261 |
+
global foldername
|
262 |
if not os.path.exists(foldername):
|
263 |
return []
|
264 |
files = os.listdir(foldername)
|
|
|
271 |
selected = selected_value
|
272 |
print(f"Selected value: {selected_value} at index: {selected_index}")
|
273 |
|
274 |
+
file_path = os.path.join(foldername,selected_value) if selected_value else None
|
275 |
status_message = f"Selected: {selected_value}" if selected_value else "No file selected"
|
276 |
|
277 |
file_size = get_file_size(file_path) if file_path else ""
|
|
|
297 |
return ""
|
298 |
|
299 |
def delete_file():
|
300 |
+
global selected,foldername
|
301 |
if selected:
|
|
|
302 |
file_path = os.path.join(foldername, selected)
|
303 |
if os.path.exists(file_path):
|
304 |
os.remove(file_path)
|
|
|
312 |
return list_uploaded_files()
|
313 |
|
314 |
def display_file(evt: gr.SelectData, df):
|
315 |
+
file_path = os.path.join(foldername, evt.value)
|
316 |
return file_path, file_path if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')) else None, f"Displaying: {evt.value}"
|
317 |
|
318 |
def render_to_database():
|
319 |
# This function is undefined as per your request
|
320 |
+
Arcana.main(foldername)
|
321 |
|
322 |
def change_theme(theme):
|
323 |
gr.Interface.theme = theme
|
|
|
325 |
def rename_file(new_name):
|
326 |
global selected
|
327 |
if selected and new_name:
|
328 |
+
old_path = os.path.join(foldername, selected)
|
329 |
+
new_path = os.path.join(foldername, new_name+'.'+selected.split('.')[-1])
|
330 |
if os.path.exists(old_path):
|
331 |
os.rename(old_path, new_path)
|
332 |
selected = new_name
|
|
|
337 |
|
338 |
def query_database(query):
|
339 |
# Usage example
|
340 |
+
db = ChatDatabase(foldername+'.txt')
|
341 |
|
342 |
# Example 1: Get relevant messages
|
343 |
sender = 'Arcana'
|
|
|
360 |
|
361 |
return df
|
362 |
|
363 |
+
def query_database_fiber(query):
|
364 |
+
dbms = fiber.FiberDBMS()
|
365 |
+
# Load or create the database
|
366 |
+
dbms.load_or_create(foldername+'.txt')
|
367 |
+
results = dbms.query(query, 10)
|
368 |
+
|
369 |
+
# Convert the results to a pandas DataFrame
|
370 |
+
df = pd.DataFrame(results)
|
371 |
+
|
372 |
+
# Reorder columns if needed
|
373 |
+
columns_order = ['name', 'content', 'tags', 'index']
|
374 |
+
df = df[columns_order]
|
375 |
+
|
376 |
+
return df
|
377 |
+
|
378 |
+
def setdbname(name):
|
379 |
+
global foldername
|
380 |
+
foldername = name
|
381 |
+
with open('settings.arcana',mode='w') as file:
|
382 |
+
newsettings = foldername+'\n'+dbmsmode
|
383 |
+
file.write(newsettings)
|
384 |
|
385 |
example_database = [
|
386 |
"What is Hydrogen Bonding?",
|
|
|
408 |
chatbot_interface = gr.ChatInterface(
|
409 |
chatbot_response,
|
410 |
chatbot=gr.Chatbot(height=400),
|
411 |
+
textbox=gr.Textbox(placeholder="Type your message here...", container=False, scale=100),
|
412 |
title="Review With Arcana",
|
413 |
description="ArcanaUI v0.8 - Chatbot",
|
414 |
+
theme="default",
|
415 |
examples=get_random_examples(),
|
416 |
cache_examples=False,
|
417 |
+
retry_btn=gr.Button('Retry'),
|
418 |
undo_btn="Delete Previous",
|
419 |
+
clear_btn="Clear",
|
420 |
)
|
421 |
|
422 |
+
def chatbot_response(message):
|
423 |
+
# Your chatbot response logic here
|
424 |
+
return f"Response to: {message}"
|
425 |
|
426 |
def relaunch():
|
427 |
global demo
|
|
|
451 |
|
452 |
with gr.TabItem("Chatbot"):
|
453 |
chatbot_interface.render()
|
454 |
+
|
455 |
# File uploading interface
|
456 |
with gr.TabItem('Upload'):
|
457 |
gr.Markdown('# Upload and View Files')
|
|
|
507 |
|
508 |
test_nylon = gr.Textbox(label='Test Nylon', placeholder='Query')
|
509 |
uploaded_files_list2 = gr.DataFrame(headers=["Nylon Returned Query"], datatype="str", interactive=False)
|
510 |
+
query_button2 = gr.Button('Query')
|
511 |
+
query_button2.click(fn=query_database, inputs=test_nylon, outputs=uploaded_files_list2)
|
512 |
+
|
513 |
+
test_fiber = gr.Textbox(label='Test Fiber', placeholder='Query')
|
514 |
+
uploaded_files_list3 = gr.DataFrame(headers=["Fiber Returned Query"], datatype="str", interactive=False)
|
515 |
+
query_button3 = gr.Button('Query')
|
516 |
+
query_button3.click(fn=query_database_fiber, inputs=test_fiber, outputs=uploaded_files_list3)
|
517 |
+
|
518 |
+
gr.Markdown('Nylon 2.1 will be deprecated in text-text selections, as it is built for image-text selections.\nDefault model is Fiber.')
|
519 |
+
dbmsmode_selector = gr.Radio(["Nylon", "Fiber"], label="Select Model")
|
520 |
+
dbmsmode_selector.change(handle_dbms_mode, dbmsmode_selector)
|
521 |
+
|
522 |
+
database_name = gr.Textbox(label='Database Name', placeholder='cache')
|
523 |
+
set_dbname = gr.Button('Set Database Name')
|
524 |
+
set_dbname.click(fn=setdbname, inputs=database_name)
|
525 |
+
|
526 |
with gr.TabItem('Theme'):
|
527 |
gr.Markdown('Change Theme')
|
528 |
|
|
|
532 |
theme_button.click(fn=change_theme, inputs=theme_dropdown)
|
533 |
relaunch_button = gr.Button('Relaunch')
|
534 |
relaunch_button.click(fn=relaunch)
|
535 |
+
with gr.TabItem('Search'):
|
536 |
+
gr.Markdown('Set Search Modes')
|
537 |
|
538 |
+
searchmode_selector = gr.Radio(["Always", "Automatic"], label="Select Mode")
|
539 |
+
output = gr.Textbox(label="Output")
|
540 |
+
searchmode_selector.change(handle_search_mode, searchmode_selector, output)
|
541 |
+
|
542 |
|
543 |
# Launch the interface
|
544 |
demo.launch(share=True)
|