# app.py
import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import HuggingFacePipeline
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
import tempfile
# --- Streamlit page config ---
st.set_page_config(page_title="📚 Multi PDF Chatbot", layout="wide", page_icon="🤖")
# --- Header ---
st.markdown(
"
📚 Multi-PDF Chat Agent 🤖
",
unsafe_allow_html=True
)
# --- Sidebar Styling ---
st.markdown(
"""
""",
unsafe_allow_html=True
)
# --- Sidebar Layout ---
with st.sidebar:
# Profile image
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
st.image("assets/img/main.png", width=100)
# Upload PDFs
st.markdown('', unsafe_allow_html=True)
st.markdown("#### 📁 Upload PDF Files")
pdf_docs = st.file_uploader("Drag and drop your PDFs here", accept_multiple_files=True, label_visibility="collapsed")
st.markdown('
', unsafe_allow_html=True)
# Footer
st.markdown(
"""
""",
unsafe_allow_html=True
)
# --- Main Logic ---
# Store FAISS vector store in session state
if "vectorstore" not in st.session_state:
st.session_state.vectorstore = None
if pdf_docs:
if st.button("📤 Submit & Process"):
with st.spinner("Processing PDFs..."):
all_text = ""
for pdf_file in pdf_docs:
pdf_reader = PdfReader(pdf_file)
for page in pdf_reader.pages:
all_text += page.extract_text() + "\n"
# Split text into chunks
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
chunks = splitter.split_text(all_text)
# Create embeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
st.session_state.vectorstore = FAISS.from_texts(chunks, embeddings)
st.success("✅ PDF content indexed successfully!")
# --- Load local LLM ---
@st.cache_resource(show_spinner=False)
def load_local_llm():
tokenizer = AutoTokenizer.from_pretrained("TheBloke/guanaco-7B-GGML")
model = AutoModelForCausalLM.from_pretrained("TheBloke/guanaco-7B-GGML")
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_length=512)
return HuggingFacePipeline(pipeline=pipe)
llm = load_local_llm()
# --- Question input ---
user_question = st.text_input("🔍 Ask something from your uploaded PDFs:")
if user_question:
if st.session_state.vectorstore is None:
st.warning("⚠️ Please upload and process PDFs first.")
else:
with st.spinner("Thinking... 💭"):
relevant_docs = st.session_state.vectorstore.similarity_search(user_question)
chain = load_qa_chain(llm, chain_type="stuff")
answer = chain.run(input_documents=relevant_docs, question=user_question)
st.success("Answer:")
st.write(answer)
# --- Fixed footer ---
st.markdown(
"""
📄 Multi-PDF Chatbot | Powered by LangChain, FAISS & Local AI
""",
unsafe_allow_html=True
)