pradeepsengarr commited on
Commit
79d5bf3
Β·
verified Β·
1 Parent(s): 74f0494

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +240 -24
app.py CHANGED
@@ -9,7 +9,6 @@ from sklearn.metrics.pairwise import cosine_similarity
9
 
10
  TOGETHER_API_KEY = os.environ.get("TOGETHER_API_KEY")
11
  SERPER_API_KEY = os.environ.get("SERPER_API_KEY")
12
-
13
  model = SentenceTransformer("all-MiniLM-L6-v2")
14
  doc_chunks = []
15
  doc_embeddings = []
@@ -27,9 +26,17 @@ def split_into_chunks(text, chunk_size=300):
27
  # --- Embed all chunks and cache ---
28
  def process_uploaded_file(file):
29
  global doc_chunks, doc_embeddings
30
- text = extract_pdf_text(file)
31
- doc_chunks = split_into_chunks(text)
32
- doc_embeddings = model.encode(doc_chunks)
 
 
 
 
 
 
 
 
33
 
34
  # --- RAG from file ---
35
  def retrieve_relevant_chunks(query):
@@ -46,7 +53,7 @@ def call_together_llm(context, question):
46
  "Content-Type": "application/json"
47
  }
48
  messages = [
49
- {"role": "system", "content": "You are a helpful assistant answering from the given context."},
50
  {"role": "user", "content": f"Context: {context}\n\nQuestion: {question}"}
51
  ]
52
  data = {
@@ -69,35 +76,244 @@ def web_search(query):
69
  return "\n".join([f"{r['title']} - {r['link']}\n{r['snippet']}" for r in results[:3]])
70
 
71
  # --- Main Chat Logic ---
72
- def answer_question(question, source):
 
 
 
73
  try:
74
- if source == "Web Search":
 
 
 
75
  context = web_search(question)
76
- elif source == "Uploaded File":
 
77
  if not doc_chunks:
78
- return "❌ Please upload a document first."
 
 
79
  context = retrieve_relevant_chunks(question)
 
80
  else:
81
- return "❌ Unknown source selected."
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- return call_together_llm(context, question)
84
  except Exception as e:
85
- return f"❌ Error: {e}"
 
 
86
 
87
- # --- Gradio UI ---
88
- with gr.Blocks() as demo:
89
- gr.Markdown("# πŸ” RAG Chatbot (Web + File Powered)")
90
 
91
- with gr.Row():
92
- source_choice = gr.Radio(["Web Search", "Uploaded File"], label="Select Knowledge Source", value="Web Search")
 
 
 
 
93
 
94
- file_input = gr.File(label="πŸ“ Upload PDF File", visible=True, file_types=[".pdf"])
 
 
 
 
 
 
 
 
95
 
96
- with gr.Row():
97
- question_input = gr.Textbox(label="Ask a question", placeholder="Ask anything...")
98
- answer_output = gr.Textbox(label="Answer", lines=8)
 
 
 
99
 
100
- file_input.change(fn=process_uploaded_file, inputs=file_input, outputs=[])
101
- question_input.submit(fn=answer_question, inputs=[question_input, source_choice], outputs=answer_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- demo.launch()
 
 
 
 
 
 
 
 
9
 
10
  TOGETHER_API_KEY = os.environ.get("TOGETHER_API_KEY")
11
  SERPER_API_KEY = os.environ.get("SERPER_API_KEY")
 
12
  model = SentenceTransformer("all-MiniLM-L6-v2")
13
  doc_chunks = []
14
  doc_embeddings = []
 
26
  # --- Embed all chunks and cache ---
27
  def process_uploaded_file(file):
28
  global doc_chunks, doc_embeddings
29
+ if file is None:
30
+ return "⚠️ No file selected", gr.update(visible=False)
31
+
32
+ try:
33
+ text = extract_pdf_text(file)
34
+ doc_chunks = split_into_chunks(text)
35
+ doc_embeddings = model.encode(doc_chunks)
36
+ status = f"βœ… Successfully processed {len(doc_chunks)} chunks from your document!"
37
+ return status, gr.update(visible=True, value=f"πŸ“„ Document loaded: {len(doc_chunks)} chunks ready")
38
+ except Exception as e:
39
+ return f"❌ Error processing file: {str(e)}", gr.update(visible=False)
40
 
41
  # --- RAG from file ---
42
  def retrieve_relevant_chunks(query):
 
53
  "Content-Type": "application/json"
54
  }
55
  messages = [
56
+ {"role": "system", "content": "You are a helpful assistant answering from the given context. Provide detailed, accurate responses based on the context provided."},
57
  {"role": "user", "content": f"Context: {context}\n\nQuestion: {question}"}
58
  ]
59
  data = {
 
76
  return "\n".join([f"{r['title']} - {r['link']}\n{r['snippet']}" for r in results[:3]])
77
 
78
  # --- Main Chat Logic ---
79
+ def answer_question(question, source, history):
80
+ if not question.strip():
81
+ return history, ""
82
+
83
  try:
84
+ # Add user question to history
85
+ history = history + [[question, None]]
86
+
87
+ if source == "🌐 Web Search":
88
  context = web_search(question)
89
+ source_info = "🌐 **Source:** Web Search"
90
+ elif source == "πŸ“„ Uploaded File":
91
  if not doc_chunks:
92
+ answer = "❌ Please upload a PDF document first to use this feature."
93
+ history[-1][1] = answer
94
+ return history, ""
95
  context = retrieve_relevant_chunks(question)
96
+ source_info = "πŸ“„ **Source:** Uploaded Document"
97
  else:
98
+ answer = "❌ Please select a valid knowledge source."
99
+ history[-1][1] = answer
100
+ return history, ""
101
+
102
+ # Get answer from LLM
103
+ answer = call_together_llm(context, question)
104
+ formatted_answer = f"{source_info}\n\n{answer}"
105
+
106
+ # Update history with answer
107
+ history[-1][1] = formatted_answer
108
+
109
+ return history, ""
110
 
 
111
  except Exception as e:
112
+ error_msg = f"❌ **Error:** {str(e)}\n\nPlease check your API keys and try again."
113
+ history[-1][1] = error_msg
114
+ return history, ""
115
 
116
+ # --- Clear chat history ---
117
+ def clear_chat():
118
+ return []
119
 
120
+ # --- Custom CSS ---
121
+ custom_css = """
122
+ .gradio-container {
123
+ max-width: 1200px !important;
124
+ margin: auto !important;
125
+ }
126
 
127
+ .header-text {
128
+ text-align: center;
129
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
130
+ -webkit-background-clip: text;
131
+ -webkit-text-fill-color: transparent;
132
+ font-size: 2.5em;
133
+ font-weight: bold;
134
+ margin-bottom: 10px;
135
+ }
136
 
137
+ .subtitle-text {
138
+ text-align: center;
139
+ color: #666;
140
+ font-size: 1.2em;
141
+ margin-bottom: 30px;
142
+ }
143
 
144
+ .source-radio .wrap {
145
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
146
+ border-radius: 15px;
147
+ padding: 15px;
148
+ margin: 10px 0;
149
+ }
150
+
151
+ .source-radio label {
152
+ color: white !important;
153
+ font-weight: 600;
154
+ }
155
+
156
+ .upload-area {
157
+ border: 2px dashed #667eea;
158
+ border-radius: 15px;
159
+ padding: 20px;
160
+ text-align: center;
161
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
162
+ transition: all 0.3s ease;
163
+ }
164
+
165
+ .upload-area:hover {
166
+ border-color: #764ba2;
167
+ transform: translateY(-2px);
168
+ }
169
+
170
+ .chat-container {
171
+ border-radius: 15px;
172
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
173
+ background: white;
174
+ padding: 20px;
175
+ margin: 20px 0;
176
+ }
177
+
178
+ .status-box {
179
+ background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);
180
+ border-radius: 10px;
181
+ padding: 15px;
182
+ margin: 10px 0;
183
+ border: none;
184
+ color: #2d3748;
185
+ font-weight: 500;
186
+ }
187
+
188
+ .footer-text {
189
+ text-align: center;
190
+ color: #888;
191
+ font-size: 0.9em;
192
+ margin-top: 30px;
193
+ padding: 20px;
194
+ border-top: 1px solid #eee;
195
+ }
196
+ """
197
+
198
+ # --- Enhanced Gradio UI ---
199
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="πŸ€– RAG Chatbot") as demo:
200
+
201
+ # Header
202
+ gr.HTML("""
203
+ <div class="header-text">πŸ€– Intelligent RAG Chatbot</div>
204
+ <div class="subtitle-text">Ask questions from web or upload your documents for AI-powered answers</div>
205
+ """)
206
+
207
+ with gr.Row():
208
+ with gr.Column(scale=1):
209
+ # Knowledge Source Selection
210
+ gr.Markdown("### 🎯 **Choose Your Knowledge Source**")
211
+ source_choice = gr.Radio(
212
+ ["🌐 Web Search", "πŸ“„ Uploaded File"],
213
+ label="Select Knowledge Source",
214
+ value="🌐 Web Search",
215
+ elem_classes=["source-radio"]
216
+ )
217
+
218
+ # File Upload Section
219
+ gr.Markdown("### πŸ“ **Document Upload**")
220
+ file_input = gr.File(
221
+ label="Upload PDF Document",
222
+ file_types=[".pdf"],
223
+ elem_classes=["upload-area"]
224
+ )
225
+
226
+ file_status = gr.Textbox(
227
+ label="πŸ“Š Processing Status",
228
+ interactive=False,
229
+ elem_classes=["status-box"]
230
+ )
231
+
232
+ document_info = gr.Textbox(
233
+ label="πŸ“„ Document Info",
234
+ visible=False,
235
+ interactive=False,
236
+ elem_classes=["status-box"]
237
+ )
238
+
239
+ with gr.Column(scale=2):
240
+ # Chat Interface
241
+ gr.Markdown("### πŸ’¬ **Chat Interface**")
242
+
243
+ chatbot = gr.Chatbot(
244
+ label="Conversation",
245
+ height=500,
246
+ elem_classes=["chat-container"],
247
+ bubble_full_width=False,
248
+ show_label=False
249
+ )
250
+
251
+ with gr.Row():
252
+ question_input = gr.Textbox(
253
+ label="Ask your question",
254
+ placeholder="Type your question here... (Press Enter to send)",
255
+ lines=2,
256
+ scale=4
257
+ )
258
+
259
+ with gr.Column(scale=1, min_width=100):
260
+ send_btn = gr.Button("πŸš€ Send", variant="primary", size="lg")
261
+ clear_btn = gr.Button("πŸ—‘οΈ Clear", variant="secondary", size="lg")
262
+
263
+ # Advanced Settings (Collapsible)
264
+ with gr.Accordion("βš™οΈ Advanced Settings", open=False):
265
+ gr.Markdown("""
266
+ **API Configuration:**
267
+ - Ensure your `TOGETHER_API_KEY` environment variable is set
268
+ - Ensure your `SERPER_API_KEY` environment variable is set for web search
269
+
270
+ **Features:**
271
+ - 🌐 **Web Search**: Get real-time information from the internet
272
+ - πŸ“„ **Document Upload**: Upload PDF files and ask questions about their content
273
+ - πŸ€– **AI-Powered**: Uses Mixtral-8x7B model for intelligent responses
274
+ - πŸ” **Semantic Search**: Advanced embedding-based document retrieval
275
+ """)
276
+
277
+ # Footer
278
+ gr.HTML("""
279
+ <div class="footer-text">
280
+ πŸš€ Powered by Together AI & Serper API |
281
+ πŸ“š Built with Sentence Transformers & Gradio |
282
+ πŸ’‘ Enhanced RAG System
283
+ </div>
284
+ """)
285
+
286
+ # Event Handlers
287
+ file_input.change(
288
+ fn=process_uploaded_file,
289
+ inputs=file_input,
290
+ outputs=[file_status, document_info]
291
+ )
292
+
293
+ # Send message on button click or Enter key
294
+ question_input.submit(
295
+ fn=answer_question,
296
+ inputs=[question_input, source_choice, chatbot],
297
+ outputs=[chatbot, question_input]
298
+ )
299
+
300
+ send_btn.click(
301
+ fn=answer_question,
302
+ inputs=[question_input, source_choice, chatbot],
303
+ outputs=[chatbot, question_input]
304
+ )
305
+
306
+ clear_btn.click(
307
+ fn=clear_chat,
308
+ inputs=[],
309
+ outputs=[chatbot]
310
+ )
311
 
312
+ # Launch the app
313
+ if __name__ == "__main__":
314
+ demo.launch(
315
+ share=True,
316
+ server_name="0.0.0.0",
317
+ server_port=7860,
318
+ show_error=True
319
+ )