Spaces:
Sleeping
Sleeping
Jatin Mehra
commited on
Commit
·
bcaf7fa
1
Parent(s):
9492bcd
Enhance session management in load_session function to ensure LLM consistency and improve error handling. Update chunk processing to accommodate larger text sizes and integrate conversation memory for chat history management.
Browse files
app.py
CHANGED
|
@@ -2,6 +2,8 @@ import os
|
|
| 2 |
import dotenv
|
| 3 |
import pickle
|
| 4 |
import uuid
|
|
|
|
|
|
|
| 5 |
from fastapi import FastAPI, UploadFile, File, Form, HTTPException
|
| 6 |
from fastapi.responses import JSONResponse
|
| 7 |
from fastapi.middleware.cors import CORSMiddleware
|
|
@@ -19,8 +21,6 @@ from preprocessing import (
|
|
| 19 |
tools
|
| 20 |
)
|
| 21 |
from sentence_transformers import SentenceTransformer
|
| 22 |
-
import shutil
|
| 23 |
-
import traceback
|
| 24 |
|
| 25 |
# Load environment variables
|
| 26 |
dotenv.load_dotenv()
|
|
@@ -76,36 +76,57 @@ def load_session(session_id, model_name="meta-llama/llama-4-scout-17b-16e-instru
|
|
| 76 |
try:
|
| 77 |
# Check if session is already in memory
|
| 78 |
if session_id in sessions:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
return sessions[session_id], True
|
| 80 |
|
| 81 |
# Try to load from disk
|
| 82 |
-
|
| 83 |
-
if os.path.exists(
|
| 84 |
-
with open(
|
| 85 |
-
data = pickle.load(f)
|
| 86 |
|
| 87 |
# Recreate non-pickled objects
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
-
return None, False
|
| 107 |
except Exception as e:
|
| 108 |
-
print(f"Error loading session: {str(e)}")
|
|
|
|
| 109 |
return None, False
|
| 110 |
|
| 111 |
# Function to remove PDF file
|
|
@@ -165,7 +186,7 @@ async def upload_pdf(
|
|
| 165 |
|
| 166 |
# Process the PDF
|
| 167 |
documents = process_pdf_file(file_path) # Returns list of Document objects
|
| 168 |
-
chunks = chunk_text(documents, max_length=
|
| 169 |
|
| 170 |
# Create embeddings
|
| 171 |
model = SentenceTransformer('BAAI/bge-large-en-v1.5') # Updated embedding model
|
|
@@ -219,6 +240,14 @@ async def chat(request: ChatRequest):
|
|
| 219 |
raise HTTPException(status_code=404, detail="Session not found. Please upload a document first.")
|
| 220 |
|
| 221 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
# Retrieve similar chunks
|
| 223 |
similar_chunks = retrieve_similar_chunks(
|
| 224 |
request.query,
|
|
@@ -234,7 +263,8 @@ async def chat(request: ChatRequest):
|
|
| 234 |
tools,
|
| 235 |
query=request.query,
|
| 236 |
context_chunks=similar_chunks, # Pass the list of tuples
|
| 237 |
-
Use_Tavily=request.use_search
|
|
|
|
| 238 |
)
|
| 239 |
|
| 240 |
# Update chat history
|
|
|
|
| 2 |
import dotenv
|
| 3 |
import pickle
|
| 4 |
import uuid
|
| 5 |
+
import shutil
|
| 6 |
+
import traceback
|
| 7 |
from fastapi import FastAPI, UploadFile, File, Form, HTTPException
|
| 8 |
from fastapi.responses import JSONResponse
|
| 9 |
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
| 21 |
tools
|
| 22 |
)
|
| 23 |
from sentence_transformers import SentenceTransformer
|
|
|
|
|
|
|
| 24 |
|
| 25 |
# Load environment variables
|
| 26 |
dotenv.load_dotenv()
|
|
|
|
| 76 |
try:
|
| 77 |
# Check if session is already in memory
|
| 78 |
if session_id in sessions:
|
| 79 |
+
# Ensure the LLM in the cached session matches the requested model_name
|
| 80 |
+
# If not, update it. This handles cases where model_name might change for an existing session.
|
| 81 |
+
if sessions[session_id].get("llm") is None or sessions[session_id]["llm"].model_name != model_name:
|
| 82 |
+
try:
|
| 83 |
+
sessions[session_id]["llm"] = model_selection(model_name)
|
| 84 |
+
except Exception as e:
|
| 85 |
+
print(f"Error updating LLM for in-memory session {session_id} to {model_name}: {str(e)}")
|
| 86 |
+
# Decide if this is a critical error; for now, we'll proceed with the old LLM or handle as error
|
| 87 |
+
# For simplicity, if LLM update fails, we might want to indicate session load failure or use existing.
|
| 88 |
+
# Here, we'll let it proceed, but this could be a point of further refinement.
|
| 89 |
return sessions[session_id], True
|
| 90 |
|
| 91 |
# Try to load from disk
|
| 92 |
+
file_path_pkl = f"{UPLOAD_DIR}/{session_id}_session.pkl"
|
| 93 |
+
if os.path.exists(file_path_pkl):
|
| 94 |
+
with open(file_path_pkl, "rb") as f:
|
| 95 |
+
data = pickle.load(f) # This is pickle_safe_data
|
| 96 |
|
| 97 |
# Recreate non-pickled objects
|
| 98 |
+
# Ensure 'chunks' and 'file_path' (for the original PDF) are present in the loaded data
|
| 99 |
+
# and the original PDF file still exists.
|
| 100 |
+
original_pdf_path = data.get("file_path")
|
| 101 |
+
if data.get("chunks") and original_pdf_path and os.path.exists(original_pdf_path):
|
| 102 |
+
embedding_model_instance = SentenceTransformer('BAAI/bge-large-en-v1.5')
|
| 103 |
+
# data["chunks"] is already the list of dicts: {text: ..., metadata: ...}
|
| 104 |
+
recreated_embeddings, _ = create_embeddings(data["chunks"], embedding_model_instance)
|
| 105 |
+
recreated_index = build_faiss_index(recreated_embeddings)
|
| 106 |
+
recreated_llm = model_selection(model_name)
|
| 107 |
+
|
| 108 |
+
full_session_data = {
|
| 109 |
+
"file_path": original_pdf_path,
|
| 110 |
+
"file_name": data.get("file_name"),
|
| 111 |
+
"chunks": data.get("chunks"), # These are chunks_with_metadata
|
| 112 |
+
"chat_history": data.get("chat_history", []),
|
| 113 |
+
"model": embedding_model_instance, # SentenceTransformer model
|
| 114 |
+
"index": recreated_index, # FAISS index
|
| 115 |
+
"llm": recreated_llm # LLM
|
| 116 |
+
}
|
| 117 |
+
sessions[session_id] = full_session_data # Store in memory cache
|
| 118 |
+
return full_session_data, True
|
| 119 |
+
else:
|
| 120 |
+
# If essential data for reconstruction is missing from pickle or the original PDF is gone
|
| 121 |
+
print(f"Warning: Session data for {session_id} is incomplete or its PDF file '{original_pdf_path}' is missing. Cannot reconstruct session.")
|
| 122 |
+
# Optionally, remove the stale .pkl file
|
| 123 |
+
# os.remove(file_path_pkl)
|
| 124 |
+
return None, False
|
| 125 |
|
| 126 |
+
return None, False # Session not in memory and not found on disk, or reconstruction failed
|
| 127 |
except Exception as e:
|
| 128 |
+
print(f"Error loading session {session_id}: {str(e)}")
|
| 129 |
+
print(traceback.format_exc()) # Print full traceback for debugging
|
| 130 |
return None, False
|
| 131 |
|
| 132 |
# Function to remove PDF file
|
|
|
|
| 186 |
|
| 187 |
# Process the PDF
|
| 188 |
documents = process_pdf_file(file_path) # Returns list of Document objects
|
| 189 |
+
chunks = chunk_text(documents, max_length=1500) # Updated to handle documents
|
| 190 |
|
| 191 |
# Create embeddings
|
| 192 |
model = SentenceTransformer('BAAI/bge-large-en-v1.5') # Updated embedding model
|
|
|
|
| 240 |
raise HTTPException(status_code=404, detail="Session not found. Please upload a document first.")
|
| 241 |
|
| 242 |
try:
|
| 243 |
+
from langchain.memory import ConversationBufferMemory
|
| 244 |
+
agent_memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
|
| 245 |
+
|
| 246 |
+
for entry in session.get("chat_history", []):
|
| 247 |
+
agent_memory.chat_memory.add_user_message(entry["user"])
|
| 248 |
+
agent_memory.chat_memory.add_ai_message(entry["assistant"])
|
| 249 |
+
|
| 250 |
+
|
| 251 |
# Retrieve similar chunks
|
| 252 |
similar_chunks = retrieve_similar_chunks(
|
| 253 |
request.query,
|
|
|
|
| 263 |
tools,
|
| 264 |
query=request.query,
|
| 265 |
context_chunks=similar_chunks, # Pass the list of tuples
|
| 266 |
+
Use_Tavily=request.use_search,
|
| 267 |
+
memory=agent_memory
|
| 268 |
)
|
| 269 |
|
| 270 |
# Update chat history
|