File size: 4,003 Bytes
7167edb
 
 
 
 
ca51654
7167edb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca51654
 
7167edb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca51654
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7167edb
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import streamlit as st
import os
import tempfile
import langchain
from langchain_community.document_loaders import PyPDFLoader
from groq_client import GroqClient
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
# CHANGE IS HERE: Updated import for text splitter
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate

# 1. Page Setup
st.title("🧠 GenAI RAG Project")
st.caption("Upload a PDF and ask questions from it! (Powered by Gemma2:2b)")

# 2. Sidebar for Upload
with st.sidebar:
    st.header("📂 Upload Document")
    uploaded_file = st.file_uploader("Choose a PDF", type="pdf")

# 3. Main Logic
if uploaded_file is not None:
    # --- STEP A: Load the PDF ---
    with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_file:
        temp_file.write(uploaded_file.read())
        temp_file_path = temp_file.name

    st.success("File Uploaded! Processing...")
    
    # --- STEP B: Split Text (Chunking) ---
    loader = PyPDFLoader(temp_file_path)
    docs = loader.load()
    
    # Text ko chhote tukdon mein todna
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    splits = text_splitter.split_documents(docs)

    # --- STEP C: Create Embeddings (The Brain) ---
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    
    # --- STEP D: Store in Vector DB (Chroma) ---
    vectorstore = Chroma.from_documents(documents=splits, embedding=embeddings)
    retriever = vectorstore.as_retriever()

    st.success("Analysis Complete! You can now chat below.")

    # --- STEP E: Setup Chat Interface ---
    
    # RAG Prompt (AI ko instruction)
    system_prompt = (
        "You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. "
        "If you don't know the answer, say that you don't know. Use three sentences maximum and keep the answer concise."
    )

    # Chat UI Logic
    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 user_input := st.chat_input("Ask something about your PDF..."):
        # User ka question dikhao
        st.chat_message("user").markdown(user_input)
        st.session_state.messages.append({"role": "user", "content": user_input})

        # AI se answer maango
        with st.chat_message("assistant"):
            with st.spinner("Analyzing document..."):
                try:
                    # Retrieve relevant docs
                    try:
                        docs = retriever.get_relevant_documents(user_input)
                    except Exception:
                        try:
                            docs = vectorstore.similarity_search(user_input, k=4)
                        except Exception:
                            docs = []

                    contexts = []
                    for d in docs:
                        content = getattr(d, 'page_content', None) or getattr(d, 'content', None) or str(d)
                        contexts.append(content)

                    llm = GroqClient(model="gemma2:2b")
                    answer = llm.generate_from_context(contexts, user_input, system_instructions=system_prompt)
                    st.markdown(answer)
                    st.session_state.messages.append({"role": "assistant", "content": answer})
                except Exception as e:
                    st.error(f"Error generating answer: {e}")

    # Cleanup (Optional)
    try:
        os.remove(temp_file_path)
    except:
        pass

else:
    st.info("👈 Please upload a PDF from the sidebar to start!")