shukdevdatta123 commited on
Commit
9697189
·
verified ·
1 Parent(s): 6eb068d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +283 -166
app.py CHANGED
@@ -14,9 +14,9 @@ class RealTimeFactChecker:
14
  """Initialize Groq client with API key"""
15
  try:
16
  self.client = Groq(api_key=api_key)
17
- return True, "<div class='status-success'>✅ API Key validated successfully!</div>"
18
  except Exception as e:
19
- return False, f"<div class='status-error'>❌ Error initializing client: {str(e)}</div>"
20
 
21
  def get_system_prompt(self):
22
  """Get the system prompt for consistent behavior"""
@@ -51,7 +51,7 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
51
  def query_compound_model(self, query, model, temperature=0.7, custom_system_prompt=None):
52
  """Query the compound model and return response with tool execution info"""
53
  if not self.client:
54
- return "<div class='status-error'>❌ Please set a valid API key first.</div>", None, None
55
 
56
  try:
57
  start_time = time.time()
@@ -60,8 +60,14 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
60
 
61
  chat_completion = self.client.chat.completions.create(
62
  messages=[
63
- {"role": "system", "content": system_prompt},
64
- {"role": "user", "content": query}
 
 
 
 
 
 
65
  ],
66
  model=model,
67
  temperature=temperature,
@@ -72,20 +78,22 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
72
  response_time = round(end_time - start_time, 2)
73
 
74
  response_content = chat_completion.choices[0].message.content
 
75
  executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
 
76
  tool_info = self.format_tool_info(executed_tools)
77
 
78
  return response_content, tool_info, response_time
79
 
80
  except Exception as e:
81
- return f"<div class='status-error'>❌ Error querying model: {str(e)}</div>", None, None
82
 
83
  def format_tool_info(self, executed_tools):
84
- """Format executed tools information as HTML"""
85
  if not executed_tools:
86
- return "<div class='tool-info'>🔍 <strong>Tools Used:</strong> None (Used existing knowledge)</div>"
87
 
88
- tool_html = "<div class='tool-info'>🔍 <strong>Tools Used:</strong><ul>"
89
  for i, tool in enumerate(executed_tools, 1):
90
  try:
91
  if hasattr(tool, 'name'):
@@ -97,22 +105,24 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
97
  else:
98
  tool_name = str(tool)
99
 
100
- tool_html += f"<li>{i}. <strong>{tool_name}</strong>"
101
 
102
  if hasattr(tool, 'parameters'):
103
  params = tool.parameters
104
  if isinstance(params, dict):
105
- tool_html += "<ul>"
106
  for key, value in params.items():
107
- tool_html += f"<li>{key}: {value}</li>"
108
- tool_html += "</ul>"
109
  elif hasattr(tool, 'input'):
110
- tool_html += f"<ul><li>Input: {tool.input}</li></ul>"
111
- tool_html += "</li>"
 
112
  except Exception:
113
- tool_html += f"<li>{i}. <strong>Tool {i}</strong> (Error parsing details)</li>"
114
- tool_html += "</ul></div>"
115
- return tool_html
 
116
 
117
  def get_example_queries(self):
118
  """Return categorized example queries"""
@@ -164,12 +174,12 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
164
  def get_custom_prompt_examples(self):
165
  """Return custom system prompt examples"""
166
  return {
167
- "🎯 Fact-Checker": "You are a fact-checker. Always verify claims with multiple sources and clearly indicate confidence levels in your assessments.",
168
- "📊 News Analyst": "You are a news analyst. Focus on providing balanced, unbiased reporting with multiple perspectives on current events.",
169
- "💼 Financial Advisor": "You are a financial advisor. Provide accurate market data with context about trends and implications for investors.",
170
- "🔬 Research Assistant": "You are a research assistant specializing in scientific and technical information. Provide detailed, evidence-based responses.",
171
- "🌍 Global News Correspondent": "You are a global news correspondent. Focus on international events and their interconnections.",
172
- "📈 Market Analyst": "You are a market analyst. Provide detailed financial analysis including technical indicators and market sentiment."
173
  }
174
 
175
  def create_interface():
@@ -178,152 +188,206 @@ def create_interface():
178
  custom_css = """
179
  <style>
180
  .gradio-container {
181
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
182
- padding: 20px;
 
183
  min-height: 100vh;
184
- font-family: 'Segoe UI', sans-serif;
185
- color: #333;
186
  }
187
-
188
- h1, h2, h3, h4 {
189
- color: white;
190
- text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
 
 
 
 
191
  }
192
-
193
- .feature-card {
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  background: white;
195
- border-radius: 10px;
196
- padding: 20px;
197
- margin-bottom: 20px;
198
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
199
- transition: transform 0.3s ease;
200
  }
201
-
202
- .feature-card:hover {
203
- transform: translateY(-5px);
204
  }
205
-
206
  .example-grid {
207
  display: grid;
208
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
209
- gap: 10px;
 
210
  }
211
-
212
- .status-success {
213
- background: #48bb78;
214
- color: white;
215
- padding: 10px;
216
- border-radius: 5px;
 
 
217
  }
218
-
219
- .status-warning {
220
- background: #ed8936;
221
- color: white;
222
- padding: 10px;
223
- border-radius: 5px;
224
  }
225
-
 
 
 
 
 
 
 
 
226
  .status-error {
227
- background: #f56565;
228
- color: white;
229
- padding: 10px;
230
- border-radius: 5px;
 
231
  }
232
-
233
  .results-section {
234
  background: white;
235
- border-radius: 10px;
236
- padding: 20px;
237
- margin-top: 20px;
238
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
239
- }
240
-
241
- .response-content {
242
- background: #f8f9fa;
243
- padding: 15px;
244
- border-radius: 8px;
245
- margin-bottom: 15px;
246
- }
247
-
248
- .response-content h3 {
249
- color: #2d3748;
250
- margin-bottom: 10px;
251
- }
252
-
253
- .response-content p {
254
- line-height: 1.6;
255
- color: #4a5568;
256
  }
257
-
258
- .timestamp {
259
- font-size: 0.9rem;
260
- color: #718096;
261
- margin-top: 10px;
262
- }
263
-
264
  .tool-info {
265
- background: #edf2f7;
266
- padding: 15px;
267
  border-radius: 8px;
268
- color: #2d3748;
269
- }
270
-
271
- .tool-info ul {
272
- list-style-type: none;
273
- padding-left: 0;
274
- }
275
-
276
- .tool-info li {
277
- margin-bottom: 8px;
278
  }
279
-
280
  .performance-badge {
281
- background: #48bb78;
282
- color: white;
283
- padding: 5px 10px;
284
- border-radius: 15px;
285
- font-weight: bold;
286
  display: inline-block;
 
 
287
  }
288
-
289
  .footer-section {
290
- background: #2d3748;
291
  color: white;
292
- padding: 20px;
293
- border-radius: 10px;
294
- margin-top: 20px;
295
  text-align: center;
296
  }
297
-
298
  .footer-section a {
299
- color: #63b3ed;
300
  text-decoration: none;
 
301
  }
302
-
303
  .footer-section a:hover {
304
  text-decoration: underline;
305
  }
306
-
307
- @media (max-width: 768px) {
308
- .gradio-row {
309
- flex-direction: column;
310
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  }
312
  </style>
313
  """
314
 
315
  def validate_api_key(api_key):
316
  if not api_key or api_key.strip() == "":
317
- return "<div class='status-error'>❌ Please enter a valid API key</div>", False
 
318
  success, message = fact_checker.initialize_client(api_key.strip())
319
  return message, success
320
 
321
  def process_query(query, model, temperature, api_key, system_prompt):
322
  if not api_key or api_key.strip() == "":
323
- return "<div class='status-error'>❌ Please set your API key first</div>", "", ""
324
 
325
  if not query or query.strip() == "":
326
- return "<div class='status-error'>❌ Please enter a query</div>", "", ""
327
 
328
  if not fact_checker.client:
329
  success, message = fact_checker.initialize_client(api_key.strip())
@@ -336,16 +400,17 @@ def create_interface():
336
 
337
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
338
  formatted_response = f"""
339
- <div class='response-content'>
340
- <h3>Query: {query}</h3>
341
- <p>{response}</p>
342
- <p class='timestamp'>Generated at {timestamp} in {response_time}s</p>
 
 
 
343
  </div>
344
  """
345
 
346
- performance_html = f"<span class='performance-badge'>⚡ Response time: {response_time}s</span>"
347
-
348
- return formatted_response, tool_info or "", performance_html
349
 
350
  def reset_system_prompt():
351
  return fact_checker.get_system_prompt()
@@ -358,37 +423,72 @@ def create_interface():
358
 
359
  with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) as demo:
360
  gr.HTML("""
361
- <div style='text-align: center; padding: 20px;'>
362
- <h1>🔍 Real-time Fact Checker & News Agent</h1>
363
- <p style='color: white;'>Powered by Groq's Compound Models with Built-in Web Search</p>
364
  </div>
365
  """)
366
 
367
- with gr.Row(elem_classes="gradio-row"):
368
  with gr.Column(scale=2):
369
  with gr.Group():
370
- gr.HTML('<div class="feature-card">')
371
  gr.Markdown("### 🔑 API Configuration")
372
  api_key_input = gr.Textbox(
373
  label="Groq API Key",
374
  placeholder="Enter your Groq API key here...",
375
- type="password"
 
376
  )
377
  api_status = gr.HTML(
378
- label="Status",
379
- value="<div class='status-warning'>⚠️ Please enter your API key</div>"
380
  )
381
  validate_btn = gr.Button("Validate API Key", variant="secondary")
382
  gr.HTML('</div>')
383
 
384
  with gr.Group():
385
- gr.HTML('<div class="feature-card">')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  gr.Markdown("### 💭 Your Query")
387
  query_input = gr.Textbox(
388
  label="Ask anything that requires real-time information",
389
  placeholder="e.g., What are the latest AI developments today?",
390
  lines=4
391
  )
 
392
  with gr.Row():
393
  model_choice = gr.Dropdown(
394
  choices=fact_checker.model_options,
@@ -402,19 +502,23 @@ def create_interface():
402
  step=0.1,
403
  label="Temperature"
404
  )
 
405
  submit_btn = gr.Button("🔍 Get Real-time Information", variant="primary")
406
  clear_btn = gr.Button("Clear", variant="secondary")
407
  gr.HTML('</div>')
408
 
409
  with gr.Column(scale=1):
410
  with gr.Group():
411
- gr.HTML('<div class="feature-card">')
412
  gr.Markdown("### 📝 Example Queries")
 
 
413
  examples = fact_checker.get_example_queries()
414
  for category, queries in examples.items():
415
- with gr.Accordion(category, open=False):
416
  for query in queries:
417
- gr.Button(query, variant="secondary").click(
 
418
  fn=lambda q=query: q,
419
  outputs=[query_input]
420
  )
@@ -422,56 +526,69 @@ def create_interface():
422
 
423
  gr.HTML('<div class="results-section">')
424
  gr.Markdown("### 📊 Results")
 
425
  with gr.Row():
426
  with gr.Column(scale=2):
427
  response_output = gr.HTML(
428
- label="Response",
429
- value="<div class='response-content'><p>Your response will appear here...</p></div>"
430
  )
 
431
  with gr.Column(scale=1):
432
  tool_info_output = gr.HTML(
433
- label="Tool Execution Info",
434
- value="<div class='tool-info'>Tool execution details will appear here...</div>"
435
  )
 
436
  performance_output = gr.HTML(
437
- label="Performance",
438
  value=""
439
  )
440
  gr.HTML('</div>')
441
 
442
- gr.HTML("""
443
- <div class="footer-section">
444
- <h3>🔗 Useful Links</h3>
445
- <p>
446
- <a href="https://console.groq.com/" target="_blank">Groq Console</a> |
447
- <a href="https://console.groq.com/docs/quickstart" target="_blank">Docs</a> |
448
- <a href="https://console.groq.com/docs/models" target="_blank">Models</a>
449
- </p>
450
- <h3>💡 Tips</h3>
451
- <p>Use custom prompts to specialize the AI. Check tool info for web search usage.</p>
452
- </div>
453
- """)
454
-
455
  validate_btn.click(
456
  fn=validate_api_key,
457
  inputs=[api_key_input],
458
  outputs=[api_status, gr.State()]
459
  )
460
 
 
 
 
 
 
461
  submit_btn.click(
462
  fn=process_query,
463
- inputs=[query_input, model_choice, temperature, api_key_input, gr.State()],
464
  outputs=[response_output, tool_info_output, performance_output]
465
  )
466
 
467
  clear_btn.click(
468
- fn=lambda: ("", "<div class='response-content'><p>Your response will appear here...</p></div>",
469
- "<div class='tool-info'>Tool execution details will appear here...</div>", ""),
470
  outputs=[query_input, response_output, tool_info_output, performance_output]
471
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
472
 
473
  return demo
474
 
475
  if __name__ == "__main__":
476
  demo = create_interface()
477
- demo.launch(share=True)
 
 
 
14
  """Initialize Groq client with API key"""
15
  try:
16
  self.client = Groq(api_key=api_key)
17
+ return True, '<div class="status-success">✅ API Key validated successfully!</div>'
18
  except Exception as e:
19
+ return False, f'<div class="status-error">❌ Error initializing client: {str(e)}</div>'
20
 
21
  def get_system_prompt(self):
22
  """Get the system prompt for consistent behavior"""
 
51
  def query_compound_model(self, query, model, temperature=0.7, custom_system_prompt=None):
52
  """Query the compound model and return response with tool execution info"""
53
  if not self.client:
54
+ return '<div class="status-error">❌ Please set a valid API key first.</div>', None, None
55
 
56
  try:
57
  start_time = time.time()
 
60
 
61
  chat_completion = self.client.chat.completions.create(
62
  messages=[
63
+ {
64
+ "role": "system",
65
+ "content": system_prompt
66
+ },
67
+ {
68
+ "role": "user",
69
+ "content": query,
70
+ }
71
  ],
72
  model=model,
73
  temperature=temperature,
 
78
  response_time = round(end_time - start_time, 2)
79
 
80
  response_content = chat_completion.choices[0].message.content
81
+
82
  executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
83
+
84
  tool_info = self.format_tool_info(executed_tools)
85
 
86
  return response_content, tool_info, response_time
87
 
88
  except Exception as e:
89
+ return f'<div class="status-error">❌ Error querying model: {str(e)}</div>', None, None
90
 
91
  def format_tool_info(self, executed_tools):
92
+ """Format executed tools information for display"""
93
  if not executed_tools:
94
+ return '<div class="tool-info"><strong>🔍 Tools Used:</strong> None (Used existing knowledge)</div>'
95
 
96
+ tool_info = '<div class="tool-info"><strong>🔍 Tools Used:</strong><ul>'
97
  for i, tool in enumerate(executed_tools, 1):
98
  try:
99
  if hasattr(tool, 'name'):
 
105
  else:
106
  tool_name = str(tool)
107
 
108
+ tool_info += f'<li>{i}. <strong>{tool_name}</strong>'
109
 
110
  if hasattr(tool, 'parameters'):
111
  params = tool.parameters
112
  if isinstance(params, dict):
113
+ tool_info += '<ul>'
114
  for key, value in params.items():
115
+ tool_info += f'<li>{key}: {value}</li>'
116
+ tool_info += '</ul>'
117
  elif hasattr(tool, 'input'):
118
+ tool_info += f'<ul><li>Input: {tool.input}</li></ul>'
119
+ tool_info += '</li>'
120
+
121
  except Exception:
122
+ tool_info += f'<li>{i}. <strong>Tool {i}</strong> (Error parsing details)</li>'
123
+
124
+ tool_info += '</ul></div>'
125
+ return tool_info
126
 
127
  def get_example_queries(self):
128
  """Return categorized example queries"""
 
174
  def get_custom_prompt_examples(self):
175
  """Return custom system prompt examples"""
176
  return {
177
+ "🎯 Fact-Checker": "You are a fact-checker. Always verify claims with multiple sources and clearly indicate confidence levels in your assessments. Use phrases like 'highly confident', 'moderately confident', or 'requires verification' when presenting information.",
178
+ "📊 News Analyst": "You are a news analyst. Focus on providing balanced, unbiased reporting with multiple perspectives on current events. Always present different viewpoints and avoid partisan language.",
179
+ "💼 Financial Advisor": "You are a financial advisor. Provide accurate market data with context about trends and implications for investors. Always include disclaimers about market risks and the importance of professional financial advice.",
180
+ "🔬 Research Assistant": "You are a research assistant specializing in scientific and technical information. Provide detailed, evidence-based responses with proper context about methodology and limitations of studies.",
181
+ "🌍 Global News Correspondent": "You are a global news correspondent. Focus on international events and their interconnections. Provide cultural context and explain how events in one region might affect others.",
182
+ "📈 Market Analyst": "You are a market analyst. Provide detailed financial analysis including technical indicators, market sentiment, and economic factors affecting price movements."
183
  }
184
 
185
  def create_interface():
 
188
  custom_css = """
189
  <style>
190
  .gradio-container {
191
+ max-width: 1400px;
192
+ margin: 0 auto;
193
+ background: #f5f7fa;
194
  min-height: 100vh;
195
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
196
+ color: #1f2937;
197
  }
198
+
199
+ .main-header {
200
+ background: white;
201
+ padding: 2rem;
202
+ border-radius: 12px;
203
+ margin: 2rem 1rem;
204
+ text-align: center;
205
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
206
  }
207
+
208
+ .main-header h1 {
209
+ font-size: 2rem;
210
+ font-weight: 700;
211
+ margin: 0;
212
+ color: #111827;
213
+ }
214
+
215
+ .main-header p {
216
+ font-size: 1rem;
217
+ color: #4b5563;
218
+ margin: 0.5rem 0 0;
219
+ }
220
+
221
+ .section-card {
222
  background: white;
223
+ border-radius: 12px;
224
+ padding: 1.5rem;
225
+ margin: 1rem;
226
+ box-shadow: 0 2px 8px rgba(0,0,0,0.05);
227
+ transition: box-shadow 0.2s ease;
228
  }
229
+
230
+ .section-card:hover {
231
+ box-shadow: 0 4px 16px rgba(0,0,0,0.1);
232
  }
233
+
234
  .example-grid {
235
  display: grid;
236
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
237
+ gap: 1rem;
238
+ margin-top: 1rem;
239
  }
240
+
241
+ .example-item {
242
+ background: #f8fafc;
243
+ border-radius: 8px;
244
+ padding: 1rem;
245
+ cursor: pointer;
246
+ transition: all 0.2s ease;
247
+ border: 1px solid #e5e7eb;
248
  }
249
+
250
+ .example-item:hover {
251
+ background: #e5e7eb;
252
+ transform: translateY(-2px);
 
 
253
  }
254
+
255
+ .status-success {
256
+ background: #ecfdf5;
257
+ color: #065f46;
258
+ padding: 0.75rem;
259
+ border-radius: 8px;
260
+ border: 1px solid #d1fae5;
261
+ }
262
+
263
  .status-error {
264
+ background: #fef2f2;
265
+ color: #991b1b;
266
+ padding: 0.75rem;
267
+ border-radius: 8px;
268
+ border: 1px solid #fee2e2;
269
  }
270
+
271
  .results-section {
272
  background: white;
273
+ border-radius: 12px;
274
+ padding: 1.5rem;
275
+ margin: 1rem;
276
+ box-shadow: 0 2px 8px rgba(0,0,0,0.05);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  }
278
+
 
 
 
 
 
 
279
  .tool-info {
280
+ background: #f8fafc;
 
281
  border-radius: 8px;
282
+ padding: 1rem;
283
+ margin: 1rem 0;
284
+ border: 1px solid #e5e7eb;
 
 
 
 
 
 
 
285
  }
286
+
287
  .performance-badge {
288
+ background: #e5e7eb;
289
+ color: #374151;
290
+ padding: 0.5rem 1rem;
291
+ border-radius: 9999px;
 
292
  display: inline-block;
293
+ margin: 0.5rem 0;
294
+ font-size: 0.875rem;
295
  }
296
+
297
  .footer-section {
298
+ background: #111827;
299
  color: white;
300
+ padding: 2rem;
301
+ border-radius: 12px;
302
+ margin: 2rem 1rem;
303
  text-align: center;
304
  }
305
+
306
  .footer-section a {
307
+ color: #60a5fa;
308
  text-decoration: none;
309
+ font-weight: 500;
310
  }
311
+
312
  .footer-section a:hover {
313
  text-decoration: underline;
314
  }
315
+
316
+ .prompt-example {
317
+ background: #f8fafc;
318
+ border-radius: 8px;
319
+ padding: 1rem;
320
+ margin: 0.5rem 0;
321
+ cursor: pointer;
322
+ transition: all 0.2s ease;
323
+ border: 1px solid #e5e7eb;
324
+ }
325
+
326
+ .prompt-example:hover {
327
+ background: #e5e7eb;
328
+ }
329
+
330
+ .prompt-example-title {
331
+ font-weight: 600;
332
+ color: #1f2937;
333
+ margin-bottom: 0.25rem;
334
+ }
335
+
336
+ .prompt-example-text {
337
+ font-size: 0.875rem;
338
+ color: #4b5563;
339
+ line-height: 1.5;
340
+ }
341
+
342
+ .gr-button {
343
+ border-radius: 8px !important;
344
+ padding: 0.75rem 1.5rem !important;
345
+ font-weight: 500 !important;
346
+ }
347
+
348
+ .gr-button-primary {
349
+ background: #2563eb !important;
350
+ color: white !important;
351
+ }
352
+
353
+ .gr-button-primary:hover {
354
+ background: #1d4ed8 !important;
355
+ }
356
+
357
+ .gr-button-secondary {
358
+ background: #e5e7eb !important;
359
+ color: #374151 !important;
360
+ }
361
+
362
+ .gr-button-secondary:hover {
363
+ background: #d1d5db !important;
364
+ }
365
+
366
+ .gr-textbox, .gr-dropdown, .gr-slider {
367
+ border-radius: 8px !important;
368
+ border: 1px solid #e5e7eb !important;
369
+ }
370
+
371
+ .gr-accordion {
372
+ border-radius: 8px !important;
373
+ border: 1px solid #e5e7eb !important;
374
  }
375
  </style>
376
  """
377
 
378
  def validate_api_key(api_key):
379
  if not api_key or api_key.strip() == "":
380
+ return '<div class="status-error">❌ Please enter a valid API key</div>', False
381
+
382
  success, message = fact_checker.initialize_client(api_key.strip())
383
  return message, success
384
 
385
  def process_query(query, model, temperature, api_key, system_prompt):
386
  if not api_key or api_key.strip() == "":
387
+ return '<div class="status-error">❌ Please set your API key first</div>', "", ""
388
 
389
  if not query or query.strip() == "":
390
+ return '<div class="status-error">❌ Please enter a query</div>', "", ""
391
 
392
  if not fact_checker.client:
393
  success, message = fact_checker.initialize_client(api_key.strip())
 
400
 
401
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
402
  formatted_response = f"""
403
+ <div class="results-section">
404
+ <h3>Query</h3>
405
+ <p>{query}</p>
406
+ <h3>Response</h3>
407
+ <div>{response}</div>
408
+ <hr>
409
+ <p><em>Generated at {timestamp} in {response_time}s</em></p>
410
  </div>
411
  """
412
 
413
+ return formatted_response, tool_info or "", f'<div class="performance-badge">⚡ Response time: {response_time}s</div>'
 
 
414
 
415
  def reset_system_prompt():
416
  return fact_checker.get_system_prompt()
 
423
 
424
  with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) as demo:
425
  gr.HTML("""
426
+ <div class="main-header">
427
+ <h1>🔍 Real-time Fact Checker</h1>
428
+ <p>Powered by Groq's Compound Models with Real-time Web Search</p>
429
  </div>
430
  """)
431
 
432
+ with gr.Row():
433
  with gr.Column(scale=2):
434
  with gr.Group():
435
+ gr.HTML('<div class="section-card">')
436
  gr.Markdown("### 🔑 API Configuration")
437
  api_key_input = gr.Textbox(
438
  label="Groq API Key",
439
  placeholder="Enter your Groq API key here...",
440
+ type="password",
441
+ info="Get your free API key from https://console.groq.com/"
442
  )
443
  api_status = gr.HTML(
444
+ value='<div class="status-error">⚠️ Please enter your API key</div>'
 
445
  )
446
  validate_btn = gr.Button("Validate API Key", variant="secondary")
447
  gr.HTML('</div>')
448
 
449
  with gr.Group():
450
+ gr.HTML('<div class="section-card">')
451
+ gr.Markdown("### ⚙️ Advanced Options")
452
+
453
+ with gr.Accordion("📝 System Prompt Examples", open=False):
454
+ gr.Markdown("**Click any example to load it as your system prompt:**")
455
+ custom_prompts = fact_checker.get_custom_prompt_examples()
456
+ for title, prompt in custom_prompts.items():
457
+ gr.HTML(f"""
458
+ <div class="prompt-example" onclick="document.getElementById('system_prompt_input').value = '{prompt}'">
459
+ <div class="prompt-example-title">{title}</div>
460
+ <div class="prompt-example-text">{prompt[:100]}...</div>
461
+ </div>
462
+ """)
463
+
464
+ with gr.Accordion("🔧 System Prompt", open=False):
465
+ system_prompt_input = gr.Textbox(
466
+ label="System Prompt",
467
+ value=fact_checker.get_system_prompt(),
468
+ lines=8,
469
+ info="Customize how the AI behaves and responds",
470
+ elem_id="system_prompt_input"
471
+ )
472
+ reset_prompt_btn = gr.Button("Reset to Default", variant="secondary")
473
+
474
+ gr.Markdown("**Quick Load Custom Prompts:**")
475
+ for title, prompt in custom_prompts.items():
476
+ prompt_btn = gr.Button(title, variant="secondary")
477
+ prompt_btn.click(
478
+ fn=lambda p=prompt: p,
479
+ outputs=[system_prompt_input]
480
+ )
481
+ gr.HTML('</div>')
482
+
483
+ with gr.Group():
484
+ gr.HTML('<div class="section-card">')
485
  gr.Markdown("### 💭 Your Query")
486
  query_input = gr.Textbox(
487
  label="Ask anything that requires real-time information",
488
  placeholder="e.g., What are the latest AI developments today?",
489
  lines=4
490
  )
491
+
492
  with gr.Row():
493
  model_choice = gr.Dropdown(
494
  choices=fact_checker.model_options,
 
502
  step=0.1,
503
  label="Temperature"
504
  )
505
+
506
  submit_btn = gr.Button("🔍 Get Real-time Information", variant="primary")
507
  clear_btn = gr.Button("Clear", variant="secondary")
508
  gr.HTML('</div>')
509
 
510
  with gr.Column(scale=1):
511
  with gr.Group():
512
+ gr.HTML('<div class="section-card">')
513
  gr.Markdown("### 📝 Example Queries")
514
+ gr.Markdown("Click any example to load it:")
515
+
516
  examples = fact_checker.get_example_queries()
517
  for category, queries in examples.items():
518
+ with gr.Accordion(category, open=category == "📰 Latest News"):
519
  for query in queries:
520
+ example_btn = gr.Button(query, variant="secondary")
521
+ example_btn.click(
522
  fn=lambda q=query: q,
523
  outputs=[query_input]
524
  )
 
526
 
527
  gr.HTML('<div class="results-section">')
528
  gr.Markdown("### 📊 Results")
529
+
530
  with gr.Row():
531
  with gr.Column(scale=2):
532
  response_output = gr.HTML(
533
+ value='<div class="results-section"><em>Your response will appear here...</em></div>'
 
534
  )
535
+
536
  with gr.Column(scale=1):
537
  tool_info_output = gr.HTML(
538
+ value='<div class="tool-info"><em>Tool execution details will appear here...</em></div>'
 
539
  )
540
+
541
  performance_output = gr.HTML(
 
542
  value=""
543
  )
544
  gr.HTML('</div>')
545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  validate_btn.click(
547
  fn=validate_api_key,
548
  inputs=[api_key_input],
549
  outputs=[api_status, gr.State()]
550
  )
551
 
552
+ reset_prompt_btn.click(
553
+ fn=reset_system_prompt,
554
+ outputs=[system_prompt_input]
555
+ )
556
+
557
  submit_btn.click(
558
  fn=process_query,
559
+ inputs=[query_input, model_choice, temperature, api_key_input, system_prompt_input],
560
  outputs=[response_output, tool_info_output, performance_output]
561
  )
562
 
563
  clear_btn.click(
564
+ fn=lambda: ("", '<div class="results-section"><em>Your response will appear here...</em></div>',
565
+ '<div class="tool-info"><em>Tool execution details will appear here...</em></div>', ""),
566
  outputs=[query_input, response_output, tool_info_output, performance_output]
567
  )
568
+
569
+ gr.HTML("""
570
+ <div class="footer-section">
571
+ <h3>🔗 Useful Links</h3>
572
+ <p>
573
+ <a href="https://console.groq.com/" target="_blank">Groq Console</a> - Get your free API key<br>
574
+ <a href="https://console.groq.com/docs/quickstart" target="_blank">Groq Documentation</a> - Learn more about Groq models<br>
575
+ <a href="https://console.groq.com/docs/models" target="_blank">Compound Models Info</a> - Details about compound models
576
+ </p>
577
+ <h3>💡 Tips</h3>
578
+ <ul style="text-align: left; display: inline-block;">
579
+ <li>Compound models use web search for real-time information</li>
580
+ <li>Use temperature 0.1 for factual queries, 0.7-0.9 for creative ones</li>
581
+ <li>compound-beta: more capable | compound-beta-mini: faster</li>
582
+ <li>Customize system prompts for specialized responses</li>
583
+ <li>Check Tool Execution Info for web search usage</li>
584
+ </ul>
585
+ </div>
586
+ """)
587
 
588
  return demo
589
 
590
  if __name__ == "__main__":
591
  demo = create_interface()
592
+ demo.launch(
593
+ share=True
594
+ )