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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +161 -326
app.py CHANGED
@@ -14,27 +14,24 @@ class RealTimeFactChecker:
14
  """Initialize Groq client with API key"""
15
  try:
16
  self.client = Groq(api_key=api_key)
17
- return True, " API Key validated successfully!"
18
  except Exception as e:
19
- return False, f" Error initializing client: {str(e)}"
20
 
21
  def get_system_prompt(self):
22
  """Get the system prompt for consistent behavior"""
23
  return """You are a Real-time Fact Checker and News Agent. Your primary role is to provide accurate, up-to-date information by leveraging web search when needed.
24
-
25
  CORE RESPONSIBILITIES:
26
  1. **Fact Verification**: Always verify claims with current, reliable sources
27
  2. **Real-time Information**: Use web search for any information that changes frequently (news, stocks, weather, current events)
28
  3. **Source Transparency**: When using web search, mention the sources or indicate that you've searched for current information
29
  4. **Accuracy First**: If information is uncertain or conflicting, acknowledge this clearly
30
-
31
  RESPONSE GUIDELINES:
32
  - **Structure**: Start with a clear, direct answer, then provide supporting details
33
  - **Recency**: Always prioritize the most recent, reliable information
34
  - **Clarity**: Use clear, professional language while remaining accessible
35
  - **Completeness**: Provide comprehensive answers but stay focused on the query
36
  - **Source Awareness**: When you've searched for information, briefly indicate this (e.g., "Based on current reports..." or "Recent data shows...")
37
-
38
  WHEN TO SEARCH:
39
  - Breaking news or current events
40
  - Stock prices, market data, or financial information
@@ -43,37 +40,28 @@ WHEN TO SEARCH:
43
  - Current political developments
44
  - Real-time statistics or data
45
  - Verification of recent claims or rumors
46
-
47
  RESPONSE FORMAT:
48
  - Lead with key facts
49
  - Include relevant context
50
  - Mention timeframe when relevant (e.g., "as of today", "this week")
51
  - If multiple sources conflict, acknowledge this
52
  - End with a clear summary for complex topics
53
-
54
  Remember: Your goal is to be the most reliable, up-to-date source of information possible."""
55
 
56
  def query_compound_model(self, query, model, temperature=0.7, custom_system_prompt=None):
57
  """Query the compound model and return response with tool execution info"""
58
  if not self.client:
59
- return " Please set a valid API key first.", None, None
60
 
61
  try:
62
  start_time = time.time()
63
 
64
- # Use custom system prompt if provided
65
  system_prompt = custom_system_prompt if custom_system_prompt else self.get_system_prompt()
66
 
67
  chat_completion = self.client.chat.completions.create(
68
  messages=[
69
- {
70
- "role": "system",
71
- "content": system_prompt
72
- },
73
- {
74
- "role": "user",
75
- "content": query,
76
- }
77
  ],
78
  model=model,
79
  temperature=temperature,
@@ -83,29 +71,23 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
83
  end_time = time.time()
84
  response_time = round(end_time - start_time, 2)
85
 
86
- # Extract response
87
  response_content = chat_completion.choices[0].message.content
88
-
89
- # Check for executed tools - Fixed the error here
90
  executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
91
-
92
- # Format tool execution info
93
  tool_info = self.format_tool_info(executed_tools)
94
 
95
  return response_content, tool_info, response_time
96
 
97
  except Exception as e:
98
- return f" Error querying model: {str(e)}", None, None
99
 
100
  def format_tool_info(self, executed_tools):
101
- """Format executed tools information for display - FIXED"""
102
  if not executed_tools:
103
- return "🔍 **Tools Used:** None (Used existing knowledge)"
104
 
105
- tool_info = "🔍 **Tools Used:**\n"
106
  for i, tool in enumerate(executed_tools, 1):
107
  try:
108
- # Handle different tool object types
109
  if hasattr(tool, 'name'):
110
  tool_name = tool.name
111
  elif hasattr(tool, 'tool_name'):
@@ -115,21 +97,22 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
115
  else:
116
  tool_name = str(tool)
117
 
118
- tool_info += f"{i}. **{tool_name}**\n"
119
 
120
- # Add tool parameters if available
121
  if hasattr(tool, 'parameters'):
122
  params = tool.parameters
123
  if isinstance(params, dict):
 
124
  for key, value in params.items():
125
- tool_info += f" - {key}: {value}\n"
 
126
  elif hasattr(tool, 'input'):
127
- tool_info += f" - Input: {tool.input}\n"
128
-
129
- except Exception as e:
130
- tool_info += f"{i}. **Tool {i}** (Error parsing details)\n"
131
-
132
- return tool_info
133
 
134
  def get_example_queries(self):
135
  """Return categorized example queries"""
@@ -181,204 +164,167 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
181
  def get_custom_prompt_examples(self):
182
  """Return custom system prompt examples"""
183
  return {
184
- "🎯 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.",
185
-
186
- "📊 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.",
187
-
188
- "💼 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.",
189
-
190
- "🔬 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.",
191
-
192
- "🌍 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.",
193
-
194
- "📈 Market Analyst": "You are a market analyst. Provide detailed financial analysis including technical indicators, market sentiment, and economic factors affecting price movements."
195
  }
196
 
197
  def create_interface():
198
  fact_checker = RealTimeFactChecker()
199
 
200
- # Custom CSS for beautiful styling
201
  custom_css = """
202
  <style>
203
  .gradio-container {
204
- max-width: 1400px !important;
205
- margin: 0 auto;
206
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 
207
  min-height: 100vh;
208
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 
209
  }
210
-
211
- .main-header {
212
- background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
213
  color: white;
214
- padding: 30px;
215
- border-radius: 20px;
216
- margin-bottom: 30px;
217
- text-align: center;
218
- box-shadow: 0 10px 30px rgba(0,0,0,0.3);
219
  }
220
-
221
- .main-header h1 {
222
- font-size: 2.5rem;
223
- margin: 0;
224
- text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
225
- }
226
-
227
- .main-header p {
228
- font-size: 1.2rem;
229
- margin: 10px 0 0 0;
230
- opacity: 0.9;
231
- }
232
-
233
  .feature-card {
234
  background: white;
235
- border-radius: 15px;
236
- padding: 25px;
237
- margin: 20px 0;
238
- box-shadow: 0 8px 25px rgba(0,0,0,0.1);
239
- border: 1px solid #e1e8ed;
240
- transition: transform 0.3s ease, box-shadow 0.3s ease;
241
  }
242
-
243
  .feature-card:hover {
244
  transform: translateY(-5px);
245
- box-shadow: 0 15px 40px rgba(0,0,0,0.2);
246
  }
247
-
248
  .example-grid {
249
  display: grid;
250
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
251
- gap: 15px;
252
- margin-top: 20px;
253
  }
254
-
255
- .example-category {
256
- background: #f8f9fa;
257
- border-radius: 10px;
258
- padding: 15px;
259
- border-left: 4px solid #667eea;
260
- }
261
-
262
- .example-category h4 {
263
- margin: 0 0 10px 0;
264
- color: #2d3748;
265
- font-weight: 600;
266
- }
267
-
268
  .status-success {
269
- background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
270
  color: white;
271
- padding: 10px 15px;
272
- border-radius: 8px;
273
- font-weight: 500;
274
  }
275
-
276
  .status-warning {
277
- background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%);
278
  color: white;
279
- padding: 10px 15px;
280
- border-radius: 8px;
281
- font-weight: 500;
282
  }
283
-
284
  .status-error {
285
- background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
286
  color: white;
287
- padding: 10px 15px;
288
- border-radius: 8px;
289
- font-weight: 500;
290
  }
291
-
292
  .results-section {
293
  background: white;
294
- border-radius: 15px;
295
- padding: 30px;
296
- margin: 30px 0;
297
- box-shadow: 0 8px 25px rgba(0,0,0,0.1);
298
  }
299
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  .tool-info {
301
- background: #f7fafc;
302
- border-left: 4px solid #4299e1;
303
  padding: 15px;
304
  border-radius: 8px;
305
- margin: 15px 0;
306
  }
307
-
 
 
 
 
 
 
 
 
 
308
  .performance-badge {
309
- background: linear-gradient(135deg, #38b2ac 0%, #319795 100%);
310
  color: white;
311
- padding: 8px 15px;
312
- border-radius: 20px;
313
- font-weight: 500;
314
  display: inline-block;
315
- margin: 10px 0;
316
  }
317
-
318
  .footer-section {
319
  background: #2d3748;
320
  color: white;
321
- padding: 30px;
322
- border-radius: 15px;
323
- margin-top: 30px;
324
  text-align: center;
325
  }
326
-
327
  .footer-section a {
328
  color: #63b3ed;
329
  text-decoration: none;
330
- font-weight: 500;
331
  }
332
-
333
  .footer-section a:hover {
334
- color: #90cdf4;
335
  text-decoration: underline;
336
  }
337
-
338
- .prompt-example {
339
- background: #ebf8ff;
340
- border: 1px solid #bee3f8;
341
- border-radius: 8px;
342
- padding: 12px;
343
- margin: 8px 0;
344
- cursor: pointer;
345
- transition: all 0.3s ease;
346
- }
347
-
348
- .prompt-example:hover {
349
- background: #bee3f8;
350
- transform: translateX(5px);
351
- }
352
-
353
- .prompt-example-title {
354
- font-weight: 600;
355
- color: #2b6cb0;
356
- margin-bottom: 5px;
357
- }
358
-
359
- .prompt-example-text {
360
- font-size: 0.9rem;
361
- color: #4a5568;
362
- line-height: 1.4;
363
  }
364
  </style>
365
  """
366
 
367
  def validate_api_key(api_key):
368
  if not api_key or api_key.strip() == "":
369
- return " Please enter a valid API key", False
370
-
371
  success, message = fact_checker.initialize_client(api_key.strip())
372
  return message, success
373
 
374
  def process_query(query, model, temperature, api_key, system_prompt):
375
  if not api_key or api_key.strip() == "":
376
- return " Please set your API key first", "", ""
377
 
378
  if not query or query.strip() == "":
379
- return " Please enter a query", "", ""
380
 
381
- # Initialize client if not already done
382
  if not fact_checker.client:
383
  success, message = fact_checker.initialize_client(api_key.strip())
384
  if not success:
@@ -388,11 +334,18 @@ def create_interface():
388
  query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
389
  )
390
 
391
- # Format response with timestamp
392
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
393
- formatted_response = f"**Query:** {query}\n\n**Response:**\n{response}\n\n---\n*Generated at {timestamp} in {response_time}s*"
 
 
 
 
 
 
394
 
395
- return formatted_response, tool_info or "", f" Response time: {response_time}s"
 
 
396
 
397
  def reset_system_prompt():
398
  return fact_checker.get_system_prompt()
@@ -403,79 +356,31 @@ def create_interface():
403
  def load_custom_prompt(prompt_text):
404
  return prompt_text
405
 
406
- # Create the Gradio interface
407
  with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) as demo:
408
-
409
- # Header
410
  gr.HTML("""
411
- <div class="main-header">
412
  <h1>🔍 Real-time Fact Checker & News Agent</h1>
413
- <p>Powered by Groq's Compound Models with Built-in Web Search</p>
414
  </div>
415
  """)
416
 
417
- with gr.Row():
418
  with gr.Column(scale=2):
419
- # API Key section
420
  with gr.Group():
421
  gr.HTML('<div class="feature-card">')
422
  gr.Markdown("### 🔑 API Configuration")
423
  api_key_input = gr.Textbox(
424
  label="Groq API Key",
425
  placeholder="Enter your Groq API key here...",
426
- type="password",
427
- info="Get your free API key from https://console.groq.com/"
428
  )
429
- api_status = gr.Textbox(
430
  label="Status",
431
- value="⚠️ Please enter your API key",
432
- interactive=False
433
  )
434
  validate_btn = gr.Button("Validate API Key", variant="secondary")
435
  gr.HTML('</div>')
436
 
437
- # Advanced options
438
- with gr.Group():
439
- gr.HTML('<div class="feature-card">')
440
- gr.Markdown("### ⚙️ Advanced Options")
441
-
442
- # Custom System Prompt Examples
443
- with gr.Accordion("📝 System Prompt Examples (Click to view)", open=False):
444
- gr.Markdown("**Click any example to load it as your system prompt:**")
445
-
446
- custom_prompts = fact_checker.get_custom_prompt_examples()
447
- for title, prompt in custom_prompts.items():
448
- with gr.Row():
449
- gr.HTML(f"""
450
- <div class="prompt-example" onclick="document.getElementById('system_prompt_input').value = '{prompt}'">
451
- <div class="prompt-example-title">{title}</div>
452
- <div class="prompt-example-text">{prompt[:100]}...</div>
453
- </div>
454
- """)
455
-
456
- with gr.Accordion("🔧 System Prompt (Click to customize)", open=False):
457
- system_prompt_input = gr.Textbox(
458
- label="System Prompt",
459
- value=fact_checker.get_system_prompt(),
460
- lines=8,
461
- info="Customize how the AI behaves and responds",
462
- elem_id="system_prompt_input"
463
- )
464
- reset_prompt_btn = gr.Button("Reset to Default", variant="secondary", size="sm")
465
-
466
- # Add buttons for each custom prompt
467
- gr.Markdown("**Quick Load Custom Prompts:**")
468
- custom_prompts = fact_checker.get_custom_prompt_examples()
469
- for title, prompt in custom_prompts.items():
470
- prompt_btn = gr.Button(title, variant="secondary", size="sm")
471
- prompt_btn.click(
472
- fn=lambda p=prompt: p,
473
- outputs=[system_prompt_input]
474
- )
475
-
476
- gr.HTML('</div>')
477
-
478
- # Query section
479
  with gr.Group():
480
  gr.HTML('<div class="feature-card">')
481
  gr.Markdown("### 💭 Your Query")
@@ -484,159 +389,89 @@ def create_interface():
484
  placeholder="e.g., What are the latest AI developments today?",
485
  lines=4
486
  )
487
-
488
  with gr.Row():
489
  model_choice = gr.Dropdown(
490
  choices=fact_checker.model_options,
491
  value="compound-beta",
492
- label="Model",
493
- info="compound-beta: More capable | compound-beta-mini: Faster"
494
  )
495
  temperature = gr.Slider(
496
  minimum=0.0,
497
  maximum=1.0,
498
  value=0.7,
499
  step=0.1,
500
- label="Temperature",
501
- info="Higher = more creative, Lower = more focused"
502
  )
503
-
504
- submit_btn = gr.Button("🔍 Get Real-time Information", variant="primary", size="lg")
505
  clear_btn = gr.Button("Clear", variant="secondary")
506
  gr.HTML('</div>')
507
 
508
  with gr.Column(scale=1):
509
- # Example queries with tabs
510
  with gr.Group():
511
  gr.HTML('<div class="feature-card">')
512
  gr.Markdown("### 📝 Example Queries")
513
- gr.Markdown("Click any example to load it:")
514
-
515
  examples = fact_checker.get_example_queries()
516
-
517
- with gr.Accordion("📰 Latest News", open=True):
518
- for query in examples["📰 Latest News"]:
519
- example_btn = gr.Button(query, variant="secondary", size="sm")
520
- example_btn.click(
521
- fn=lambda q=query: q,
522
- outputs=[query_input]
523
- )
524
-
525
- with gr.Accordion("💰 Financial Data", open=False):
526
- for query in examples["💰 Financial Data"]:
527
- example_btn = gr.Button(query, variant="secondary", size="sm")
528
- example_btn.click(
529
- fn=lambda q=query: q,
530
- outputs=[query_input]
531
- )
532
-
533
- with gr.Accordion("🌤️ Weather Updates", open=False):
534
- for query in examples["🌤️ Weather Updates"]:
535
- example_btn = gr.Button(query, variant="secondary", size="sm")
536
- example_btn.click(
537
- fn=lambda q=query: q,
538
- outputs=[query_input]
539
- )
540
-
541
- with gr.Accordion("🔬 Science & Technology", open=False):
542
- for query in examples["🔬 Science & Technology"]:
543
- example_btn = gr.Button(query, variant="secondary", size="sm")
544
- example_btn.click(
545
- fn=lambda q=query: q,
546
- outputs=[query_input]
547
- )
548
-
549
- with gr.Accordion("🏆 Sports & Entertainment", open=False):
550
- for query in examples["🏆 Sports & Entertainment"]:
551
- example_btn = gr.Button(query, variant="secondary", size="sm")
552
- example_btn.click(
553
- fn=lambda q=query: q,
554
- outputs=[query_input]
555
- )
556
-
557
- with gr.Accordion("🔍 Fact Checking", open=False):
558
- for query in examples["🔍 Fact Checking"]:
559
- example_btn = gr.Button(query, variant="secondary", size="sm")
560
- example_btn.click(
561
- fn=lambda q=query: q,
562
- outputs=[query_input]
563
- )
564
-
565
  gr.HTML('</div>')
566
 
567
- # Results section
568
  gr.HTML('<div class="results-section">')
569
  gr.Markdown("### 📊 Results")
570
-
571
  with gr.Row():
572
  with gr.Column(scale=2):
573
- response_output = gr.Markdown(
574
  label="Response",
575
- value="*Your response will appear here...*"
576
  )
577
-
578
  with gr.Column(scale=1):
579
- tool_info_output = gr.Markdown(
580
  label="Tool Execution Info",
581
- value="*Tool execution details will appear here...*"
582
  )
583
-
584
- performance_output = gr.Textbox(
585
  label="Performance",
586
- value="",
587
- interactive=False
588
  )
589
  gr.HTML('</div>')
590
 
591
- # Event handlers
 
 
 
 
 
 
 
 
 
 
 
 
592
  validate_btn.click(
593
  fn=validate_api_key,
594
  inputs=[api_key_input],
595
  outputs=[api_status, gr.State()]
596
  )
597
 
598
- reset_prompt_btn.click(
599
- fn=reset_system_prompt,
600
- outputs=[system_prompt_input]
601
- )
602
-
603
  submit_btn.click(
604
  fn=process_query,
605
- inputs=[query_input, model_choice, temperature, api_key_input, system_prompt_input],
606
  outputs=[response_output, tool_info_output, performance_output]
607
  )
608
 
609
  clear_btn.click(
610
- fn=lambda: ("", "*Your response will appear here...*", "*Tool execution details will appear here...*", ""),
 
611
  outputs=[query_input, response_output, tool_info_output, performance_output]
612
  )
613
-
614
- # Footer
615
- gr.HTML("""
616
- <div class="footer-section">
617
- <h3>🔗 Useful Links</h3>
618
- <p>
619
- <a href="https://console.groq.com/" target="_blank">Groq Console</a> - Get your free API key<br>
620
- <a href="https://console.groq.com/docs/quickstart" target="_blank">Groq Documentation</a> - Learn more about Groq models<br>
621
- <a href="https://console.groq.com/docs/models" target="_blank">Compound Models Info</a> - Details about compound models
622
- </p>
623
-
624
- <h3>💡 Tips</h3>
625
- <ul style="text-align: left; display: inline-block;">
626
- <li>The compound models automatically use web search when real-time information is needed</li>
627
- <li>Try different temperature settings: 0.1 for factual queries, 0.7-0.9 for creative questions</li>
628
- <li>compound-beta is more capable but slower, compound-beta-mini is faster but less capable</li>
629
- <li>Use custom system prompts to specialize the AI for different types of queries</li>
630
- <li>Check the Tool Execution Info to see when web search was used</li>
631
- </ul>
632
- </div>
633
- """)
634
 
635
  return demo
636
 
637
- # Launch the application
638
  if __name__ == "__main__":
639
  demo = create_interface()
640
- demo.launch(
641
- share=True
642
- )
 
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"""
23
  return """You are a Real-time Fact Checker and News Agent. Your primary role is to provide accurate, up-to-date information by leveraging web search when needed.
 
24
  CORE RESPONSIBILITIES:
25
  1. **Fact Verification**: Always verify claims with current, reliable sources
26
  2. **Real-time Information**: Use web search for any information that changes frequently (news, stocks, weather, current events)
27
  3. **Source Transparency**: When using web search, mention the sources or indicate that you've searched for current information
28
  4. **Accuracy First**: If information is uncertain or conflicting, acknowledge this clearly
 
29
  RESPONSE GUIDELINES:
30
  - **Structure**: Start with a clear, direct answer, then provide supporting details
31
  - **Recency**: Always prioritize the most recent, reliable information
32
  - **Clarity**: Use clear, professional language while remaining accessible
33
  - **Completeness**: Provide comprehensive answers but stay focused on the query
34
  - **Source Awareness**: When you've searched for information, briefly indicate this (e.g., "Based on current reports..." or "Recent data shows...")
 
35
  WHEN TO SEARCH:
36
  - Breaking news or current events
37
  - Stock prices, market data, or financial information
 
40
  - Current political developments
41
  - Real-time statistics or data
42
  - Verification of recent claims or rumors
 
43
  RESPONSE FORMAT:
44
  - Lead with key facts
45
  - Include relevant context
46
  - Mention timeframe when relevant (e.g., "as of today", "this week")
47
  - If multiple sources conflict, acknowledge this
48
  - End with a clear summary for complex topics
 
49
  Remember: Your goal is to be the most reliable, up-to-date source of information possible."""
50
 
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()
58
 
 
59
  system_prompt = custom_system_prompt if custom_system_prompt else self.get_system_prompt()
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,
 
71
  end_time = time.time()
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'):
92
  tool_name = tool.name
93
  elif hasattr(tool, 'tool_name'):
 
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
  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():
176
  fact_checker = RealTimeFactChecker()
177
 
 
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())
330
  if not success:
 
334
  query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
335
  )
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()
 
356
  def load_custom_prompt(prompt_text):
357
  return prompt_text
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")
 
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,
395
  value="compound-beta",
396
+ label="Model"
 
397
  )
398
  temperature = gr.Slider(
399
  minimum=0.0,
400
  maximum=1.0,
401
  value=0.7,
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
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  gr.HTML('</div>')
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)