File size: 3,078 Bytes
459d768
 
33f5c90
bbd6414
 
 
0cf4e94
bbd6414
1ebb5b2
 
8fef849
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0cf4e94
8fef849
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bbd6414
 
8fef849
33f5c90
a343396
8fef849
bbd6414
 
 
 
33f5c90
8fef849
a343396
 
 
 
70b95a1
33f5c90
8fef849
 
 
 
 
 
a343396
1ebb5b2
bbd6414
70b95a1
bbd6414
b60534d
bbd6414
a343396
8fef849
 
 
 
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
import os
import chainlit as cl
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_groq import ChatGroq  # βœ… Correct import
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA

# PDF to QA chain processor
def process_file(file_path):
    loader = PyPDFLoader(file_path)
    documents = loader.load()
    cl.run_sync(cl.Message("πŸ“„ PDF loaded successfully. Splitting text...").send())

    text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
    texts = text_splitter.split_documents(documents)

    cl.run_sync(cl.Message("πŸ” Creating embeddings and FAISS vector store...").send())
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    vectorstore = FAISS.from_documents(texts, embeddings)

    cl.run_sync(cl.Message("βš™οΈ Building RetrievalQA chain...").send())

    prompt_template = """
    Use the following pieces of context to answer the question at the end.
    If you don't know the answer, just say you don't know β€” don't try to make up an answer.
    
    {context}
    
    Question: {question}
    Helpful Answer:
    """

    prompt = PromptTemplate(
        template=prompt_template,
        input_variables=["context", "question"]
    )

    # βœ… Use Groq Chat Model
    llm = ChatGroq(
        api_key=os.environ.get("GROQ_API_KEY"),
        model_name="llama3-8b-8192"
    )

    qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
        chain_type_kwargs={"prompt": prompt},
        return_source_documents=True
    )

    return qa_chain

# On Chat Start
@cl.on_chat_start
async def start():
    await cl.Message("πŸ‘‹ Welcome! Upload a PDF to begin.").send()

    await cl.AskFileMessage(
        content="πŸ“„ Upload a PDF file below (Max 20 MB):",
        accept=["application/pdf"],
        max_size_mb=20,
        timeout=180
    ).send()

# On User Message
@cl.on_message
async def handle_message(message: cl.Message):
    if files := await cl.user_session.get("files"):
        file = files[0]
        file_path = file.path

        qa_chain = await cl.make_async(process_file)(file_path)
        cl.user_session.set("qa_chain", qa_chain)
        cl.user_session.set("ready", True)

        await cl.Message(f"βœ… File `{file.name}` processed. QA chain is ready. You can now ask your question!").send()
        cl.user_session.set("files", None)
        return

    if not cl.user_session.get("ready"):
        await cl.Message("⚠️ Please upload a PDF file first.").send()
        return

    qa_chain = cl.user_session.get("qa_chain")
    await cl.Message("πŸ’¬ Thinking...").send()

    response = qa_chain(message.content)
    answer = response["result"]
    await cl.Message(content=f"🧠 Answer: {answer}").send()