varuneshv's picture
Fix session state cleanup for removed PDFs
2997920
Raw
History Blame Contribute Delete
4.09 kB
import streamlit as st
import tempfile
import uuid
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from graph.workflow import app
@st.cache_resource
def load_embedding_model():
return HuggingFaceEmbeddings(
model_name="BAAI/bge-base-en-v1.5"
)
embedding_model = load_embedding_model()
st.set_page_config(
page_title="Agentic Corrective RAG",
page_icon="🤖",
layout="wide"
)
st.title("🤖 Agentic Corrective RAG")
uploaded_files = st.sidebar.file_uploader(
"Upload PDF files",
type=["pdf"],
accept_multiple_files=True
)
# ---------------- PDF Processing ----------------
uploaded_names = sorted(
[file.name for file in uploaded_files]
) if uploaded_files else []
if (
uploaded_files and
st.session_state.get("uploaded_files") != uploaded_names
):
with st.spinner("Processing PDFs..."):
documents = []
for uploaded_file in uploaded_files:
with tempfile.NamedTemporaryFile(
delete=False,
suffix=".pdf"
) as tmp_file:
uploaded_file.seek(0)
tmp_file.write(
uploaded_file.getvalue()
)
tmp_path = tmp_file.name
loader = PyMuPDFLoader(tmp_path)
docs = loader.load()
documents.extend(docs)
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunked_docs = splitter.split_documents(
documents
)
if "uploaded_vector_db" in st.session_state:
try:
st.session_state[
"uploaded_vector_db"
].delete_collection()
except Exception:
pass
del st.session_state[
"uploaded_vector_db"
]
collection_name = (
f"session_{uuid.uuid4().hex[:8]}"
)
uploaded_db = Chroma.from_documents(
documents=chunked_docs,
embedding=embedding_model,
collection_name=collection_name,
)
st.session_state.uploaded_vector_db = uploaded_db
st.session_state.uploaded_files = uploaded_names
st.sidebar.success(
f"Indexed {len(chunked_docs)} chunks."
)
# ------------------------------------------------
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if prompt := st.chat_input("Ask anything..."):
if "uploaded_vector_db" not in st.session_state:
st.warning("Please upload at least one PDF first.")
st.stop()
st.session_state.messages.append(
{
"role": "user",
"content": prompt
}
)
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
with st.spinner("Thinking..."):
result = app.invoke(
{
"question": prompt,
# use uploaded DB if available
"vector_db": st.session_state.get(
"uploaded_vector_db",
None
)
}
)
response = result["answer"]
st.markdown(response)
if result.get("route") == "local":
st.caption(
f"Source: Uploaded Document | Retrieval Score: {result['retrieval_score']:.3f}"
)
elif result.get("route") == "web":
st.caption(
f"Source: Web Search | Retrieval Score: {result['retrieval_score']:.3f}"
)
st.session_state.messages.append(
{
"role": "assistant",
"content": response
}
)