HuzaifaTech commited on
Commit
8a1b6fa
·
verified ·
1 Parent(s): 751d399

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -0
app.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # =========================
2
+ # IMPORTS
3
+ # =========================
4
+ from langchain_community.document_loaders import PyPDFLoader
5
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
6
+ from langchain.embeddings import HuggingFaceEmbeddings
7
+ from langchain.vectorstores import Chroma
8
+ from groq import Groq
9
+ from duckduckgo_search import DDGS
10
+ import gradio as gr
11
+
12
+
13
+ # =========================
14
+ # CONFIG
15
+ # =========================
16
+ GROQ_API_KEY = "Ai_tutor" # 🔥 set in HF secrets instead
17
+
18
+ client = Groq(api_key=GROQ_API_KEY)
19
+
20
+ vectorstore = None
21
+ retriever = None
22
+
23
+
24
+ # =========================
25
+ # PROMPT
26
+ # =========================
27
+ def build_prompt(context, question):
28
+ return f"""
29
+ You are an expert AI assistant.
30
+
31
+ Use ONLY the context below.
32
+ If answer is not present, say "Not found in document".
33
+
34
+ CONTEXT:
35
+ {context}
36
+
37
+ QUESTION:
38
+ {question}
39
+
40
+ ANSWER:
41
+ """
42
+
43
+
44
+ # =========================
45
+ # WEB SEARCH
46
+ # =========================
47
+ def web_search(query):
48
+ results = []
49
+ with DDGS() as ddgs:
50
+ for r in ddgs.text(query, max_results=3):
51
+ results.append(r["body"])
52
+ return "\n\n".join(results)
53
+
54
+
55
+ # =========================
56
+ # PROCESS PDF
57
+ # =========================
58
+ def process_pdf(file):
59
+
60
+ global vectorstore, retriever
61
+
62
+ loader = PyPDFLoader(file.name)
63
+ documents = loader.load()
64
+
65
+ text_splitter = RecursiveCharacterTextSplitter(
66
+ chunk_size=600,
67
+ chunk_overlap=100
68
+ )
69
+
70
+ chunks = text_splitter.split_documents(documents)
71
+
72
+ embedding_model = HuggingFaceEmbeddings(
73
+ model_name="sentence-transformers/all-MiniLM-L6-v2"
74
+ )
75
+
76
+ vectorstore = Chroma.from_documents(
77
+ documents=chunks,
78
+ embedding=embedding_model
79
+ )
80
+
81
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
82
+
83
+ return "✅ PDF processed. Ask questions."
84
+
85
+
86
+ # =========================
87
+ # RAG FUNCTION (HYBRID)
88
+ # =========================
89
+ def ask_rag(query):
90
+
91
+ global retriever
92
+
93
+ if retriever is None:
94
+ return "⚠️ Upload a PDF first."
95
+
96
+ docs = retriever.invoke(query)
97
+ pdf_context = "\n\n".join([d.page_content for d in docs])
98
+
99
+ # Hybrid fallback
100
+ if len(pdf_context.strip()) < 50:
101
+ web_context = web_search(query)
102
+ context = pdf_context + "\n\nWEB:\n" + web_context
103
+ else:
104
+ context = pdf_context
105
+
106
+ prompt = build_prompt(context, query)
107
+
108
+ response = client.chat.completions.create(
109
+ messages=[{"role": "user", "content": prompt}],
110
+ model="llama3-8b-8192"
111
+ )
112
+
113
+ return response.choices[0].message.content
114
+
115
+
116
+ # =========================
117
+ # CHAT
118
+ # =========================
119
+ def chat(user_message, history):
120
+
121
+ response = ask_rag(user_message)
122
+
123
+ history.append({"role": "user", "content": user_message})
124
+ history.append({"role": "assistant", "content": response})
125
+
126
+ return history, history
127
+
128
+
129
+ # =========================
130
+ # UI
131
+ # =========================
132
+ with gr.Blocks() as app:
133
+
134
+ gr.Markdown("# 🧠 Hybrid RAG Chatbot (PDF + Web)")
135
+
136
+ file = gr.File(label="Upload PDF")
137
+ status = gr.Textbox(label="Status")
138
+
139
+ chatbot = gr.Chatbot(type="messages", allow_tags=False)
140
+ msg = gr.Textbox(placeholder="Ask your question...")
141
+ state = gr.State([])
142
+
143
+ file.change(process_pdf, file, status)
144
+ msg.submit(chat, [msg, state], [chatbot, state])
145
+
146
+ app.launch()