Spaces:
Running
Running
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
|