Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -236,7 +236,7 @@ def chat_box_card():
|
|
236 |
dbc.CardBody([
|
237 |
html.Div(id="chat-window", style={
|
238 |
"height": "60vh",
|
239 |
-
"overflowY": "
|
240 |
"overflowX": "auto",
|
241 |
"display": "flex",
|
242 |
"flexDirection": "column",
|
@@ -247,7 +247,11 @@ def chat_box_card():
|
|
247 |
})
|
248 |
]),
|
249 |
className="mt-3",
|
250 |
-
style={
|
|
|
|
|
|
|
|
|
251 |
)
|
252 |
|
253 |
def user_input_card():
|
@@ -429,6 +433,7 @@ def main_callback(session_id, send_clicks, file_contents, new_chat_clicks, strea
|
|
429 |
|
430 |
file_was_uploaded_and_sent = False
|
431 |
file_upload_message = None
|
|
|
432 |
if trigger == "file-upload" and file_contents and file_names:
|
433 |
uploads = []
|
434 |
file_upload_messages = []
|
@@ -450,12 +455,12 @@ def main_callback(session_id, send_clicks, file_contents, new_chat_clicks, strea
|
|
450 |
if text.strip():
|
451 |
embed_user_doc(session_id, fname, text)
|
452 |
logger.info(f"Session {session_id}: Uploaded doc '{n}' embedded for user vector store")
|
453 |
-
# Add extracted text to chat
|
454 |
preview = text[:1000]
|
455 |
file_upload_messages.append({
|
456 |
"role": "user",
|
457 |
"content": f"[Document uploaded: {n}]\n{preview if preview.strip() else '[No text extracted]'}"
|
458 |
})
|
|
|
459 |
else:
|
460 |
file_upload_messages.append({
|
461 |
"role": "user",
|
@@ -472,11 +477,88 @@ def main_callback(session_id, send_clicks, file_contents, new_chat_clicks, strea
|
|
472 |
"content": f"[File uploaded: {n}]"
|
473 |
})
|
474 |
state["uploads"].extend(uploads)
|
475 |
-
#
|
476 |
for msg in file_upload_messages:
|
477 |
state["messages"].append(msg)
|
478 |
save_session_state(session_id)
|
479 |
logger.info(f"Session {session_id}: Uploaded files {[u['name'] for u in uploads]}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
480 |
|
481 |
send_triggered = False
|
482 |
if trigger == "send-btn" or trigger == "hidden-send":
|
|
|
236 |
dbc.CardBody([
|
237 |
html.Div(id="chat-window", style={
|
238 |
"height": "60vh",
|
239 |
+
"overflowY": "scroll",
|
240 |
"overflowX": "auto",
|
241 |
"display": "flex",
|
242 |
"flexDirection": "column",
|
|
|
247 |
})
|
248 |
]),
|
249 |
className="mt-3",
|
250 |
+
style={
|
251 |
+
"height": "62vh",
|
252 |
+
"overflowY": "scroll",
|
253 |
+
"overflowX": "auto"
|
254 |
+
}
|
255 |
)
|
256 |
|
257 |
def user_input_card():
|
|
|
433 |
|
434 |
file_was_uploaded_and_sent = False
|
435 |
file_upload_message = None
|
436 |
+
doc_texts_to_send = []
|
437 |
if trigger == "file-upload" and file_contents and file_names:
|
438 |
uploads = []
|
439 |
file_upload_messages = []
|
|
|
455 |
if text.strip():
|
456 |
embed_user_doc(session_id, fname, text)
|
457 |
logger.info(f"Session {session_id}: Uploaded doc '{n}' embedded for user vector store")
|
|
|
458 |
preview = text[:1000]
|
459 |
file_upload_messages.append({
|
460 |
"role": "user",
|
461 |
"content": f"[Document uploaded: {n}]\n{preview if preview.strip() else '[No text extracted]'}"
|
462 |
})
|
463 |
+
doc_texts_to_send.append(text.strip())
|
464 |
else:
|
465 |
file_upload_messages.append({
|
466 |
"role": "user",
|
|
|
477 |
"content": f"[File uploaded: {n}]"
|
478 |
})
|
479 |
state["uploads"].extend(uploads)
|
480 |
+
# Add all file upload messages to chat
|
481 |
for msg in file_upload_messages:
|
482 |
state["messages"].append(msg)
|
483 |
save_session_state(session_id)
|
484 |
logger.info(f"Session {session_id}: Uploaded files {[u['name'] for u in uploads]}")
|
485 |
+
# If text was extracted, send it to OpenAI as a question for assistant reply
|
486 |
+
if doc_texts_to_send:
|
487 |
+
doc_question = "\n\n".join(doc_texts_to_send)
|
488 |
+
state["messages"].append({"role": "user", "content": doc_question})
|
489 |
+
state["streaming"] = True
|
490 |
+
state["stream_buffer"] = ""
|
491 |
+
save_session_state(session_id)
|
492 |
+
def run_stream_for_doc(session_id, messages, doc_question):
|
493 |
+
try:
|
494 |
+
system_prompt = load_system_prompt()
|
495 |
+
rag_chunks = []
|
496 |
+
try:
|
497 |
+
global_embeds = []
|
498 |
+
global_texts = []
|
499 |
+
global_fnames = []
|
500 |
+
for fname, emb in EMBEDDING_INDEX.items():
|
501 |
+
global_embeds.append(emb)
|
502 |
+
global_texts.append(EMBEDDING_TEXTS[fname])
|
503 |
+
global_fnames.append(fname)
|
504 |
+
global_rag = semantic_search(doc_question, global_embeds, global_texts, global_fnames, top_k=2)
|
505 |
+
if global_rag:
|
506 |
+
for r in global_rag:
|
507 |
+
rag_chunks.append(f"Global doc [{r['filename']}]:\n{r['text'][:1000]}")
|
508 |
+
user_embeds, user_texts, user_fnames = get_user_embeddings(session_id)
|
509 |
+
user_rag = semantic_search(doc_question, user_embeds, user_texts, user_fnames, top_k=2)
|
510 |
+
if user_rag:
|
511 |
+
for r in user_rag:
|
512 |
+
rag_chunks.append(f"User upload [{r['filename']}]:\n{r['text'][:1000]}")
|
513 |
+
except Exception as e:
|
514 |
+
logger.error(f"Session {session_id}: RAG error (doc upload): {e}")
|
515 |
+
context_block = ""
|
516 |
+
if rag_chunks:
|
517 |
+
context_block = "The following sources may help answer the question:\n\n" + "\n\n".join(rag_chunks) + "\n\n"
|
518 |
+
msg_list = [{"role": "system", "content": system_prompt}]
|
519 |
+
if context_block:
|
520 |
+
msg_list.append({"role": "system", "content": context_block})
|
521 |
+
for m in messages:
|
522 |
+
msg_list.append({"role": m["role"], "content": m["content"]})
|
523 |
+
response = openai.ChatCompletion.create(
|
524 |
+
model="gpt-3.5-turbo",
|
525 |
+
messages=msg_list,
|
526 |
+
max_tokens=700,
|
527 |
+
temperature=0.2,
|
528 |
+
stream=True,
|
529 |
+
)
|
530 |
+
reply = ""
|
531 |
+
for chunk in response:
|
532 |
+
delta = chunk["choices"][0]["delta"]
|
533 |
+
content = delta.get("content", "")
|
534 |
+
if content:
|
535 |
+
reply += content
|
536 |
+
session_lock = get_session_lock(session_id)
|
537 |
+
with session_lock:
|
538 |
+
load_session_state(session_id)
|
539 |
+
state = get_session_state(session_id)
|
540 |
+
state["stream_buffer"] = reply
|
541 |
+
save_session_state(session_id)
|
542 |
+
session_lock = get_session_lock(session_id)
|
543 |
+
with session_lock:
|
544 |
+
load_session_state(session_id)
|
545 |
+
state = get_session_state(session_id)
|
546 |
+
state["messages"].append({"role": "assistant", "content": reply})
|
547 |
+
state["stream_buffer"] = ""
|
548 |
+
state["streaming"] = False
|
549 |
+
save_session_state(session_id)
|
550 |
+
logger.info(f"Session {session_id}: Assistant responded to doc upload")
|
551 |
+
except Exception as e:
|
552 |
+
session_lock = get_session_lock(session_id)
|
553 |
+
with session_lock:
|
554 |
+
load_session_state(session_id)
|
555 |
+
state = get_session_state(session_id)
|
556 |
+
state["streaming"] = False
|
557 |
+
state["stream_buffer"] = ""
|
558 |
+
save_session_state(session_id)
|
559 |
+
logger.error(f"Session {session_id}: Streaming error for doc upload: {e}")
|
560 |
+
threading.Thread(target=run_stream_for_doc, args=(session_id, list(state["messages"]), doc_question), daemon=True).start()
|
561 |
+
start_streaming = True
|
562 |
|
563 |
send_triggered = False
|
564 |
if trigger == "send-btn" or trigger == "hidden-send":
|