shukdevdatta123 commited on
Commit
dce043e
·
verified ·
1 Parent(s): f0ba435

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +256 -542
app.py CHANGED
@@ -4,7 +4,6 @@ from groq import Groq
4
  import json
5
  from datetime import datetime
6
  import time
7
- import re
8
 
9
  class RealTimeFactChecker:
10
  def __init__(self):
@@ -82,7 +81,7 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
82
  # Extract response
83
  response_content = chat_completion.choices[0].message.content
84
 
85
- # Check for executed tools
86
  executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
87
 
88
  # Format tool execution info
@@ -94,29 +93,11 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
94
  return f"❌ Error querying model: {str(e)}", None, None
95
 
96
  def format_tool_info(self, executed_tools):
97
- """Format executed tools information for display"""
98
  if not executed_tools:
99
- return """
100
- <div class="tool-info-card">
101
- <div class="tool-info-header">
102
- <i class="icon">🧠</i>
103
- <h3>Knowledge Source</h3>
104
- </div>
105
- <div class="tool-info-content">
106
- <p>Response generated from existing knowledge base</p>
107
- </div>
108
- </div>
109
- """
110
-
111
- tool_html = """
112
- <div class="tool-info-card">
113
- <div class="tool-info-header">
114
- <i class="icon">🔍</i>
115
- <h3>Tools Executed</h3>
116
- </div>
117
- <div class="tool-info-content">
118
- """
119
 
 
120
  for i, tool in enumerate(executed_tools, 1):
121
  try:
122
  # Handle different tool object types
@@ -129,73 +110,21 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
129
  else:
130
  tool_name = str(tool)
131
 
132
- tool_html += f"""
133
- <div class="tool-item">
134
- <div class="tool-name">{i}. {tool_name}</div>
135
- """
136
 
137
  # Add tool parameters if available
138
  if hasattr(tool, 'parameters'):
139
  params = tool.parameters
140
  if isinstance(params, dict):
141
  for key, value in params.items():
142
- tool_html += f'<div class="tool-param">{key}: {value}</div>'
143
  elif hasattr(tool, 'input'):
144
- tool_html += f'<div class="tool-param">Input: {tool.input}</div>'
145
-
146
- tool_html += "</div>"
147
 
148
  except Exception as e:
149
- tool_html += f'<div class="tool-item"><div class="tool-name">{i}. Tool {i}</div><div class="tool-param">Error parsing details</div></div>'
150
-
151
- tool_html += """
152
- </div>
153
- </div>
154
- """
155
-
156
- return tool_html
157
-
158
- def format_response(self, response_content, query, response_time):
159
- """Format the response with proper HTML structure"""
160
- # Convert markdown-like formatting to HTML
161
- formatted_content = response_content
162
-
163
- # Convert **bold** to <strong>
164
- formatted_content = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', formatted_content)
165
-
166
- # Convert *italic* to <em>
167
- formatted_content = re.sub(r'\*(.*?)\*', r'<em>\1</em>', formatted_content)
168
-
169
- # Convert newlines to <br> for better formatting
170
- formatted_content = formatted_content.replace('\n', '<br>')
171
-
172
- # Convert numbered lists
173
- formatted_content = re.sub(r'^(\d+\.\s)', r'<br><strong>\1</strong>', formatted_content, flags=re.MULTILINE)
174
-
175
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
176
 
177
- html_response = f"""
178
- <div class="response-card">
179
- <div class="response-header">
180
- <div class="query-section">
181
- <h3>📝 Query</h3>
182
- <p class="query-text">{query}</p>
183
- </div>
184
- <div class="meta-info">
185
- <span class="timestamp">🕐 {timestamp}</span>
186
- <span class="response-time">⚡ {response_time}s</span>
187
- </div>
188
- </div>
189
- <div class="response-content">
190
- <h3>💬 Response</h3>
191
- <div class="response-text">
192
- {formatted_content}
193
- </div>
194
- </div>
195
- </div>
196
- """
197
-
198
- return html_response
199
 
200
  def get_example_queries(self):
201
  """Return categorized example queries"""
@@ -263,396 +192,171 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
263
  def create_interface():
264
  fact_checker = RealTimeFactChecker()
265
 
266
- # Modern CSS design
267
  custom_css = """
268
- /* Reset and base styles */
269
- * {
270
- margin: 0;
271
- padding: 0;
272
- box-sizing: border-box;
273
- }
274
-
275
- body {
276
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
277
- background: #f8fafc;
278
- color: #334155;
279
- line-height: 1.6;
280
- }
281
-
282
  .gradio-container {
283
- max-width: 1200px !important;
284
  margin: 0 auto;
285
- padding: 20px;
286
- background: #f8fafc;
 
287
  }
288
 
289
- /* Header */
290
- .app-header {
291
- background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
292
  color: white;
293
- padding: 2rem;
294
- border-radius: 16px;
295
- margin-bottom: 2rem;
296
  text-align: center;
297
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
298
  }
299
 
300
- .app-header h1 {
301
  font-size: 2.5rem;
302
- font-weight: 700;
303
- margin-bottom: 0.5rem;
304
  }
305
 
306
- .app-header p {
307
- font-size: 1.1rem;
 
308
  opacity: 0.9;
309
- font-weight: 400;
310
  }
311
 
312
- /* Cards */
313
- .card {
314
  background: white;
315
- border-radius: 12px;
316
- padding: 1.5rem;
317
- margin-bottom: 1.5rem;
318
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
319
- border: 1px solid #e2e8f0;
 
320
  }
321
 
322
- .card h3 {
323
- color: #1e293b;
324
- font-size: 1.25rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  font-weight: 600;
326
- margin-bottom: 1rem;
327
- display: flex;
328
- align-items: center;
329
- gap: 0.5rem;
330
  }
331
 
332
- /* Status indicators */
333
  .status-success {
334
- background: #10b981;
335
  color: white;
336
- padding: 0.75rem 1rem;
337
  border-radius: 8px;
338
  font-weight: 500;
339
  }
340
 
341
  .status-warning {
342
- background: #f59e0b;
343
  color: white;
344
- padding: 0.75rem 1rem;
345
  border-radius: 8px;
346
  font-weight: 500;
347
  }
348
 
349
  .status-error {
350
- background: #ef4444;
351
  color: white;
352
- padding: 0.75rem 1rem;
353
- border-radius: 8px;
354
- font-weight: 500;
355
- }
356
-
357
- /* Example buttons */
358
- .example-btn {
359
- background: #f1f5f9;
360
- border: 1px solid #e2e8f0;
361
- color: #475569;
362
- padding: 0.75rem 1rem;
363
- border-radius: 8px;
364
- cursor: pointer;
365
- transition: all 0.2s ease;
366
- margin: 0.25rem;
367
- font-size: 0.875rem;
368
- text-align: left;
369
- }
370
-
371
- .example-btn:hover {
372
- background: #e2e8f0;
373
- border-color: #3b82f6;
374
- color: #1e40af;
375
- }
376
-
377
- /* Custom prompt examples */
378
- .prompt-example {
379
- background: #f8fafc;
380
- border: 1px solid #e2e8f0;
381
- border-radius: 8px;
382
- padding: 1rem;
383
- margin: 0.5rem 0;
384
- cursor: pointer;
385
- transition: all 0.2s ease;
386
- }
387
-
388
- .prompt-example:hover {
389
- background: #e2e8f0;
390
- border-color: #3b82f6;
391
- }
392
-
393
- .prompt-example-title {
394
- font-weight: 600;
395
- color: #1e40af;
396
- margin-bottom: 0.5rem;
397
- }
398
-
399
- .prompt-example-text {
400
- font-size: 0.875rem;
401
- color: #64748b;
402
- line-height: 1.4;
403
- }
404
-
405
- /* Response card */
406
- .response-card {
407
- background: white;
408
- border-radius: 12px;
409
- border: 1px solid #e2e8f0;
410
- overflow: hidden;
411
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
412
- }
413
-
414
- .response-header {
415
- background: #f8fafc;
416
- padding: 1.5rem;
417
- border-bottom: 1px solid #e2e8f0;
418
- }
419
-
420
- .query-section h3 {
421
- color: #1e293b;
422
- font-size: 1.1rem;
423
- font-weight: 600;
424
- margin-bottom: 0.5rem;
425
- }
426
-
427
- .query-text {
428
- background: #e2e8f0;
429
- padding: 1rem;
430
  border-radius: 8px;
431
- font-style: italic;
432
- color: #475569;
433
- }
434
-
435
- .meta-info {
436
- display: flex;
437
- justify-content: space-between;
438
- align-items: center;
439
- margin-top: 1rem;
440
- font-size: 0.875rem;
441
- color: #64748b;
442
- }
443
-
444
- .timestamp, .response-time {
445
- background: #f1f5f9;
446
- padding: 0.5rem 0.75rem;
447
- border-radius: 6px;
448
  font-weight: 500;
449
  }
450
 
451
- .response-content {
452
- padding: 1.5rem;
453
- }
454
-
455
- .response-content h3 {
456
- color: #1e293b;
457
- font-size: 1.1rem;
458
- font-weight: 600;
459
- margin-bottom: 1rem;
460
- }
461
-
462
- .response-text {
463
- color: #374151;
464
- line-height: 1.7;
465
- font-size: 0.95rem;
466
- }
467
-
468
- .response-text strong {
469
- color: #1e293b;
470
- font-weight: 600;
471
- }
472
-
473
- .response-text em {
474
- color: #6366f1;
475
- font-style: italic;
476
- }
477
-
478
- /* Tool info card */
479
- .tool-info-card {
480
  background: white;
481
- border-radius: 12px;
482
- border: 1px solid #e2e8f0;
483
- overflow: hidden;
484
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
485
  }
486
 
487
- .tool-info-header {
488
- background: #f0f9ff;
489
- padding: 1rem 1.5rem;
490
- border-bottom: 1px solid #e2e8f0;
491
- display: flex;
492
- align-items: center;
493
- gap: 0.75rem;
494
- }
495
-
496
- .tool-info-header .icon {
497
- font-size: 1.5rem;
498
- }
499
-
500
- .tool-info-header h3 {
501
- color: #1e40af;
502
- font-size: 1.1rem;
503
- font-weight: 600;
504
- margin: 0;
505
- }
506
-
507
- .tool-info-content {
508
- padding: 1.5rem;
509
- }
510
-
511
- .tool-item {
512
- background: #f8fafc;
513
  border-radius: 8px;
514
- padding: 1rem;
515
- margin-bottom: 0.75rem;
516
- border: 1px solid #e2e8f0;
517
- }
518
-
519
- .tool-item:last-child {
520
- margin-bottom: 0;
521
- }
522
-
523
- .tool-name {
524
- font-weight: 600;
525
- color: #1e293b;
526
- margin-bottom: 0.5rem;
527
- }
528
-
529
- .tool-param {
530
- font-size: 0.875rem;
531
- color: #64748b;
532
- margin-left: 1rem;
533
  }
534
 
535
- /* Accordion styles */
536
- .accordion-header {
537
- background: #f8fafc;
538
- border: 1px solid #e2e8f0;
539
- border-radius: 8px;
540
- padding: 1rem;
541
- cursor: pointer;
542
- transition: all 0.2s ease;
543
- margin-bottom: 0.5rem;
544
- }
545
-
546
- .accordion-header:hover {
547
- background: #e2e8f0;
548
- }
549
-
550
- .accordion-content {
551
- padding: 1rem;
552
- border: 1px solid #e2e8f0;
553
- border-top: none;
554
- border-radius: 0 0 8px 8px;
555
- background: white;
556
- }
557
-
558
- /* Performance badge */
559
  .performance-badge {
560
- background: #10b981;
561
  color: white;
562
- padding: 0.5rem 1rem;
563
  border-radius: 20px;
564
- font-size: 0.875rem;
565
  font-weight: 500;
566
  display: inline-block;
 
567
  }
568
 
569
- /* Buttons */
570
- .btn-primary {
571
- background: #3b82f6;
572
- color: white;
573
- border: none;
574
- padding: 0.75rem 1.5rem;
575
- border-radius: 8px;
576
- font-weight: 500;
577
- cursor: pointer;
578
- transition: all 0.2s ease;
579
- }
580
-
581
- .btn-primary:hover {
582
- background: #2563eb;
583
- }
584
-
585
- .btn-secondary {
586
- background: #f1f5f9;
587
- color: #475569;
588
- border: 1px solid #e2e8f0;
589
- padding: 0.75rem 1.5rem;
590
- border-radius: 8px;
591
- font-weight: 500;
592
- cursor: pointer;
593
- transition: all 0.2s ease;
594
- }
595
-
596
- .btn-secondary:hover {
597
- background: #e2e8f0;
598
- border-color: #3b82f6;
599
- }
600
-
601
- /* Footer */
602
- .footer {
603
- background: #1e293b;
604
  color: white;
605
- padding: 2rem;
606
- border-radius: 12px;
607
- margin-top: 2rem;
608
  text-align: center;
609
  }
610
 
611
- .footer h3 {
612
- color: white;
613
- margin-bottom: 1rem;
614
- }
615
-
616
- .footer a {
617
- color: #60a5fa;
618
  text-decoration: none;
619
  font-weight: 500;
620
  }
621
 
622
- .footer a:hover {
623
- color: #93c5fd;
624
  text-decoration: underline;
625
  }
626
 
627
- .footer ul {
628
- list-style: none;
629
- padding: 0;
630
- margin: 1rem 0;
 
 
 
 
631
  }
632
 
633
- .footer ul li {
634
- margin: 0.5rem 0;
 
635
  }
636
 
637
- /* Responsive design */
638
- @media (max-width: 768px) {
639
- .gradio-container {
640
- padding: 1rem;
641
- }
642
-
643
- .app-header h1 {
644
- font-size: 2rem;
645
- }
646
-
647
- .card {
648
- padding: 1rem;
649
- }
650
-
651
- .meta-info {
652
- flex-direction: column;
653
- gap: 0.5rem;
654
- }
655
  }
 
 
 
 
 
 
 
656
  """
657
 
658
  def validate_api_key(api_key):
@@ -679,8 +383,9 @@ def create_interface():
679
  query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
680
  )
681
 
682
- # Format response with HTML
683
- formatted_response = fact_checker.format_response(response, query, response_time)
 
684
 
685
  return formatted_response, tool_info or "", f"⚡ Response time: {response_time}s"
686
 
@@ -694,11 +399,11 @@ def create_interface():
694
  return prompt_text
695
 
696
  # Create the Gradio interface
697
- with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css, theme=gr.themes.Ocean()) as demo:
698
 
699
  # Header
700
  gr.HTML("""
701
- <div class="app-header">
702
  <h1>🔍 Real-time Fact Checker & News Agent</h1>
703
  <p>Powered by Groq's Compound Models with Built-in Web Search</p>
704
  </div>
@@ -707,160 +412,168 @@ def create_interface():
707
  with gr.Row():
708
  with gr.Column(scale=2):
709
  # API Key section
710
- gr.HTML('<div class="card">')
711
- gr.HTML('<h3>🔑 API Configuration</h3>')
712
- api_key_input = gr.Textbox(
713
- label="Groq API Key",
714
- placeholder="Enter your Groq API key here...",
715
- type="password",
716
- info="Get your free API key from https://console.groq.com/"
717
- )
718
- api_status = gr.Textbox(
719
- label="Status",
720
- value="⚠️ Please enter your API key",
721
- interactive=False
722
- )
723
- validate_btn = gr.Button("Validate API Key", variant="secondary")
724
- gr.HTML('</div>')
 
725
 
726
  # Advanced options
727
- gr.HTML('<div class="card">')
728
- gr.HTML('<h3>⚙️ Advanced Options</h3>')
729
-
730
- # Custom System Prompt Examples
731
- with gr.Accordion("📝 System Prompt Examples", open=False):
732
- gr.Markdown("**Click any example to load it as your system prompt:**")
 
 
 
 
 
 
 
 
 
 
 
733
 
734
- custom_prompts = fact_checker.get_custom_prompt_examples()
735
- for title, prompt in custom_prompts.items():
736
- with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
737
  prompt_btn = gr.Button(title, variant="secondary", size="sm")
738
  prompt_btn.click(
739
  fn=lambda p=prompt: p,
740
- outputs=[gr.Textbox(elem_id="system_prompt_input")]
741
  )
742
-
743
- with gr.Accordion("🔧 System Prompt Customization", open=False):
744
- system_prompt_input = gr.Textbox(
745
- label="System Prompt",
746
- value=fact_checker.get_system_prompt(),
747
- lines=8,
748
- info="Customize how the AI behaves and responds",
749
- elem_id="system_prompt_input"
750
- )
751
- reset_prompt_btn = gr.Button("Reset to Default", variant="secondary", size="sm")
752
 
753
- # Add buttons for each custom prompt
754
- gr.Markdown("**Quick Load Custom Prompts:**")
755
- custom_prompts = fact_checker.get_custom_prompt_examples()
756
- for title, prompt in custom_prompts.items():
757
- prompt_btn = gr.Button(title, variant="secondary", size="sm")
758
- prompt_btn.click(
759
- fn=lambda p=prompt: p,
760
- outputs=[system_prompt_input]
761
- )
762
-
763
- gr.HTML('</div>')
764
 
765
  # Query section
766
- gr.HTML('<div class="card">')
767
- gr.HTML('<h3>💭 Your Query</h3>')
768
- query_input = gr.Textbox(
769
- label="Ask anything that requires real-time information",
770
- placeholder="e.g., What are the latest AI developments today?",
771
- lines=4
772
- )
773
-
774
- with gr.Row():
775
- model_choice = gr.Dropdown(
776
- choices=fact_checker.model_options,
777
- value="compound-beta",
778
- label="Model",
779
- info="compound-beta: More capable | compound-beta-mini: Faster"
780
  )
781
- temperature = gr.Slider(
782
- minimum=0.0,
783
- maximum=1.0,
784
- value=0.7,
785
- step=0.1,
786
- label="Temperature",
787
- info="Higher = more creative, Lower = more focused"
788
- )
789
-
790
- submit_btn = gr.Button("🔍 Get Real-time Information", variant="primary", size="lg")
791
- clear_btn = gr.Button("Clear", variant="secondary")
792
- gr.HTML('</div>')
793
-
794
- with gr.Column(scale=1):
795
- # Example queries
796
- gr.HTML('<div class="card">')
797
- gr.HTML('<h3>📝 Example Queries</h3>')
798
- gr.Markdown("Click any example to load it:")
799
-
800
- examples = fact_checker.get_example_queries()
801
-
802
- with gr.Accordion("📰 Latest News", open=True):
803
- for query in examples["📰 Latest News"]:
804
- example_btn = gr.Button(query, variant="secondary", size="sm")
805
- example_btn.click(
806
- fn=lambda q=query: q,
807
- outputs=[query_input]
808
- )
809
-
810
- with gr.Accordion("💰 Financial Data", open=False):
811
- for query in examples["💰 Financial Data"]:
812
- example_btn = gr.Button(query, variant="secondary", size="sm")
813
- example_btn.click(
814
- fn=lambda q=query: q,
815
- outputs=[query_input]
816
- )
817
-
818
- with gr.Accordion("🌤️ Weather Updates", open=False):
819
- for query in examples["🌤️ Weather Updates"]:
820
- example_btn = gr.Button(query, variant="secondary", size="sm")
821
- example_btn.click(
822
- fn=lambda q=query: q,
823
- outputs=[query_input]
824
- )
825
-
826
- with gr.Accordion("🔬 Science & Technology", open=False):
827
- for query in examples["🔬 Science & Technology"]:
828
- example_btn = gr.Button(query, variant="secondary", size="sm")
829
- example_btn.click(
830
- fn=lambda q=query: q,
831
- outputs=[query_input]
832
- )
833
-
834
- with gr.Accordion("🏆 Sports & Entertainment", open=False):
835
- for query in examples["🏆 Sports & Entertainment"]:
836
- example_btn = gr.Button(query, variant="secondary", size="sm")
837
- example_btn.click(
838
- fn=lambda q=query: q,
839
- outputs=[query_input]
840
  )
841
-
842
- with gr.Accordion("🔍 Fact Checking", open=False):
843
- for query in examples["🔍 Fact Checking"]:
844
- example_btn = gr.Button(query, variant="secondary", size="sm")
845
- example_btn.click(
846
- fn=lambda q=query: q,
847
- outputs=[query_input]
848
  )
849
-
850
- gr.HTML('</div>')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
851
 
852
  # Results section
853
- gr.HTML('<h3 style="margin: 2rem 0 1rem 0; color: #1e293b; font-size: 1.5rem;">📊 Results</h3>')
 
854
 
855
  with gr.Row():
856
  with gr.Column(scale=2):
857
- response_output = gr.HTML(
858
- value="<div style='padding: 2rem; text-align: center; color: #64748b; font-style: italic;'>Your response will appear here...</div>"
 
859
  )
860
 
861
  with gr.Column(scale=1):
862
- tool_info_output = gr.HTML(
863
- value="<div style='padding: 2rem; text-align: center; color: #64748b; font-style: italic;'>Tool execution details will appear here...</div>"
 
864
  )
865
 
866
  performance_output = gr.Textbox(
@@ -868,6 +581,7 @@ def create_interface():
868
  value="",
869
  interactive=False
870
  )
 
871
 
872
  # Event handlers
873
  validate_btn.click(
@@ -888,13 +602,13 @@ def create_interface():
888
  )
889
 
890
  clear_btn.click(
891
- fn=lambda: ("", "<div style='padding: 2rem; text-align: center; color: #64748b; font-style: italic;'>Your response will appear here...</div>", "<div style='padding: 2rem; text-align: center; color: #64748b; font-style: italic;'>Tool execution details will appear here...</div>", ""),
892
  outputs=[query_input, response_output, tool_info_output, performance_output]
893
  )
894
 
895
  # Footer
896
  gr.HTML("""
897
- <div class="footer">
898
  <h3>🔗 Useful Links</h3>
899
  <p>
900
  <a href="https://console.groq.com/" target="_blank">Groq Console</a> - Get your free API key<br>
@@ -903,7 +617,7 @@ def create_interface():
903
  </p>
904
 
905
  <h3>💡 Tips</h3>
906
- <ul>
907
  <li>The compound models automatically use web search when real-time information is needed</li>
908
  <li>Try different temperature settings: 0.1 for factual queries, 0.7-0.9 for creative questions</li>
909
  <li>compound-beta is more capable but slower, compound-beta-mini is faster but less capable</li>
 
4
  import json
5
  from datetime import datetime
6
  import time
 
7
 
8
  class RealTimeFactChecker:
9
  def __init__(self):
 
81
  # Extract response
82
  response_content = chat_completion.choices[0].message.content
83
 
84
+ # Check for executed tools - Fixed the error here
85
  executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
86
 
87
  # Format tool execution info
 
93
  return f"❌ Error querying model: {str(e)}", None, None
94
 
95
  def format_tool_info(self, executed_tools):
96
+ """Format executed tools information for display - FIXED"""
97
  if not executed_tools:
98
+ return "🔍 **Tools Used:** None (Used existing knowledge)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ tool_info = "🔍 **Tools Used:**\n"
101
  for i, tool in enumerate(executed_tools, 1):
102
  try:
103
  # Handle different tool object types
 
110
  else:
111
  tool_name = str(tool)
112
 
113
+ tool_info += f"{i}. **{tool_name}**\n"
 
 
 
114
 
115
  # Add tool parameters if available
116
  if hasattr(tool, 'parameters'):
117
  params = tool.parameters
118
  if isinstance(params, dict):
119
  for key, value in params.items():
120
+ tool_info += f" - {key}: {value}\n"
121
  elif hasattr(tool, 'input'):
122
+ tool_info += f" - Input: {tool.input}\n"
 
 
123
 
124
  except Exception as e:
125
+ tool_info += f"{i}. **Tool {i}** (Error parsing details)\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ return tool_info
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
  def get_example_queries(self):
130
  """Return categorized example queries"""
 
192
  def create_interface():
193
  fact_checker = RealTimeFactChecker()
194
 
195
+ # Custom CSS for beautiful styling
196
  custom_css = """
197
+ <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  .gradio-container {
199
+ max-width: 1400px !important;
200
  margin: 0 auto;
201
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
202
+ min-height: 100vh;
203
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
204
  }
205
 
206
+ .main-header {
207
+ background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
 
208
  color: white;
209
+ padding: 30px;
210
+ border-radius: 20px;
211
+ margin-bottom: 30px;
212
  text-align: center;
213
+ box-shadow: 0 10px 30px rgba(0,0,0,0.3);
214
  }
215
 
216
+ .main-header h1 {
217
  font-size: 2.5rem;
218
+ margin: 0;
219
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
220
  }
221
 
222
+ .main-header p {
223
+ font-size: 1.2rem;
224
+ margin: 10px 0 0 0;
225
  opacity: 0.9;
 
226
  }
227
 
228
+ .feature-card {
 
229
  background: white;
230
+ border-radius: 15px;
231
+ padding: 25px;
232
+ margin: 20px 0;
233
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
234
+ border: 1px solid #e1e8ed;
235
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
236
  }
237
 
238
+ .feature-card:hover {
239
+ transform: translateY(-5px);
240
+ box-shadow: 0 15px 40px rgba(0,0,0,0.2);
241
+ }
242
+
243
+ .example-grid {
244
+ display: grid;
245
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
246
+ gap: 15px;
247
+ margin-top: 20px;
248
+ }
249
+
250
+ .example-category {
251
+ background: #f8f9fa;
252
+ border-radius: 10px;
253
+ padding: 15px;
254
+ border-left: 4px solid #667eea;
255
+ }
256
+
257
+ .example-category h4 {
258
+ margin: 0 0 10px 0;
259
+ color: #2d3748;
260
  font-weight: 600;
 
 
 
 
261
  }
262
 
 
263
  .status-success {
264
+ background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
265
  color: white;
266
+ padding: 10px 15px;
267
  border-radius: 8px;
268
  font-weight: 500;
269
  }
270
 
271
  .status-warning {
272
+ background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%);
273
  color: white;
274
+ padding: 10px 15px;
275
  border-radius: 8px;
276
  font-weight: 500;
277
  }
278
 
279
  .status-error {
280
+ background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
281
  color: white;
282
+ padding: 10px 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  border-radius: 8px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  font-weight: 500;
285
  }
286
 
287
+ .results-section {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  background: white;
289
+ border-radius: 15px;
290
+ padding: 30px;
291
+ margin: 30px 0;
292
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
293
  }
294
 
295
+ .tool-info {
296
+ background: #f7fafc;
297
+ border-left: 4px solid #4299e1;
298
+ padding: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  border-radius: 8px;
300
+ margin: 15px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  }
302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  .performance-badge {
304
+ background: linear-gradient(135deg, #38b2ac 0%, #319795 100%);
305
  color: white;
306
+ padding: 8px 15px;
307
  border-radius: 20px;
 
308
  font-weight: 500;
309
  display: inline-block;
310
+ margin: 10px 0;
311
  }
312
 
313
+ .footer-section {
314
+ background: #2d3748;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  color: white;
316
+ padding: 30px;
317
+ border-radius: 15px;
318
+ margin-top: 30px;
319
  text-align: center;
320
  }
321
 
322
+ .footer-section a {
323
+ color: #63b3ed;
 
 
 
 
 
324
  text-decoration: none;
325
  font-weight: 500;
326
  }
327
 
328
+ .footer-section a:hover {
329
+ color: #90cdf4;
330
  text-decoration: underline;
331
  }
332
 
333
+ .prompt-example {
334
+ background: #ebf8ff;
335
+ border: 1px solid #bee3f8;
336
+ border-radius: 8px;
337
+ padding: 12px;
338
+ margin: 8px 0;
339
+ cursor: pointer;
340
+ transition: all 0.3s ease;
341
  }
342
 
343
+ .prompt-example:hover {
344
+ background: #bee3f8;
345
+ transform: translateX(5px);
346
  }
347
 
348
+ .prompt-example-title {
349
+ font-weight: 600;
350
+ color: #2b6cb0;
351
+ margin-bottom: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  }
353
+
354
+ .prompt-example-text {
355
+ font-size: 0.9rem;
356
+ color: #4a5568;
357
+ line-height: 1.4;
358
+ }
359
+ </style>
360
  """
361
 
362
  def validate_api_key(api_key):
 
383
  query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
384
  )
385
 
386
+ # Format response with timestamp
387
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
388
+ formatted_response = f"**Query:** {query}\n\n**Response:**\n{response}\n\n---\n*Generated at {timestamp} in {response_time}s*"
389
 
390
  return formatted_response, tool_info or "", f"⚡ Response time: {response_time}s"
391
 
 
399
  return prompt_text
400
 
401
  # Create the Gradio interface
402
+ with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) as demo:
403
 
404
  # Header
405
  gr.HTML("""
406
+ <div class="main-header">
407
  <h1>🔍 Real-time Fact Checker & News Agent</h1>
408
  <p>Powered by Groq's Compound Models with Built-in Web Search</p>
409
  </div>
 
412
  with gr.Row():
413
  with gr.Column(scale=2):
414
  # API Key section
415
+ with gr.Group():
416
+ gr.HTML('<div class="feature-card">')
417
+ gr.Markdown("### 🔑 API Configuration")
418
+ api_key_input = gr.Textbox(
419
+ label="Groq API Key",
420
+ placeholder="Enter your Groq API key here...",
421
+ type="password",
422
+ info="Get your free API key from https://console.groq.com/"
423
+ )
424
+ api_status = gr.Textbox(
425
+ label="Status",
426
+ value="⚠️ Please enter your API key",
427
+ interactive=False
428
+ )
429
+ validate_btn = gr.Button("Validate API Key", variant="secondary")
430
+ gr.HTML('</div>')
431
 
432
  # Advanced options
433
+ with gr.Group():
434
+ gr.HTML('<div class="feature-card">')
435
+ gr.Markdown("### ⚙️ Advanced Options")
436
+
437
+ # Custom System Prompt Examples
438
+ with gr.Accordion("📝 System Prompt Examples (Click to view)", open=False):
439
+ gr.Markdown("**Click any example to load it as your system prompt:**")
440
+
441
+ custom_prompts = fact_checker.get_custom_prompt_examples()
442
+ for title, prompt in custom_prompts.items():
443
+ with gr.Row():
444
+ gr.HTML(f"""
445
+ <div class="prompt-example" onclick="document.getElementById('system_prompt_input').value = '{prompt}'">
446
+ <div class="prompt-example-title">{title}</div>
447
+ <div class="prompt-example-text">{prompt[:100]}...</div>
448
+ </div>
449
+ """)
450
 
451
+ with gr.Accordion("🔧 System Prompt (Click to customize)", open=False):
452
+ system_prompt_input = gr.Textbox(
453
+ label="System Prompt",
454
+ value=fact_checker.get_system_prompt(),
455
+ lines=8,
456
+ info="Customize how the AI behaves and responds",
457
+ elem_id="system_prompt_input"
458
+ )
459
+ reset_prompt_btn = gr.Button("Reset to Default", variant="secondary", size="sm")
460
+
461
+ # Add buttons for each custom prompt
462
+ gr.Markdown("**Quick Load Custom Prompts:**")
463
+ custom_prompts = fact_checker.get_custom_prompt_examples()
464
+ for title, prompt in custom_prompts.items():
465
  prompt_btn = gr.Button(title, variant="secondary", size="sm")
466
  prompt_btn.click(
467
  fn=lambda p=prompt: p,
468
+ outputs=[system_prompt_input]
469
  )
 
 
 
 
 
 
 
 
 
 
470
 
471
+ gr.HTML('</div>')
 
 
 
 
 
 
 
 
 
 
472
 
473
  # Query section
474
+ with gr.Group():
475
+ gr.HTML('<div class="feature-card">')
476
+ gr.Markdown("### 💭 Your Query")
477
+ query_input = gr.Textbox(
478
+ label="Ask anything that requires real-time information",
479
+ placeholder="e.g., What are the latest AI developments today?",
480
+ lines=4
 
 
 
 
 
 
 
481
  )
482
+
483
+ with gr.Row():
484
+ model_choice = gr.Dropdown(
485
+ choices=fact_checker.model_options,
486
+ value="compound-beta",
487
+ label="Model",
488
+ info="compound-beta: More capable | compound-beta-mini: Faster"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  )
490
+ temperature = gr.Slider(
491
+ minimum=0.0,
492
+ maximum=1.0,
493
+ value=0.7,
494
+ step=0.1,
495
+ label="Temperature",
496
+ info="Higher = more creative, Lower = more focused"
497
  )
498
+
499
+ submit_btn = gr.Button("🔍 Get Real-time Information", variant="primary", size="lg")
500
+ clear_btn = gr.Button("Clear", variant="secondary")
501
+ gr.HTML('</div>')
502
+
503
+ with gr.Column(scale=1):
504
+ # Example queries with tabs
505
+ with gr.Group():
506
+ gr.HTML('<div class="feature-card">')
507
+ gr.Markdown("### 📝 Example Queries")
508
+ gr.Markdown("Click any example to load it:")
509
+
510
+ examples = fact_checker.get_example_queries()
511
+
512
+ with gr.Accordion("📰 Latest News", open=True):
513
+ for query in examples["📰 Latest News"]:
514
+ example_btn = gr.Button(query, variant="secondary", size="sm")
515
+ example_btn.click(
516
+ fn=lambda q=query: q,
517
+ outputs=[query_input]
518
+ )
519
+
520
+ with gr.Accordion("💰 Financial Data", open=False):
521
+ for query in examples["💰 Financial Data"]:
522
+ example_btn = gr.Button(query, variant="secondary", size="sm")
523
+ example_btn.click(
524
+ fn=lambda q=query: q,
525
+ outputs=[query_input]
526
+ )
527
+
528
+ with gr.Accordion("🌤️ Weather Updates", open=False):
529
+ for query in examples["🌤️ Weather Updates"]:
530
+ example_btn = gr.Button(query, variant="secondary", size="sm")
531
+ example_btn.click(
532
+ fn=lambda q=query: q,
533
+ outputs=[query_input]
534
+ )
535
+
536
+ with gr.Accordion("🔬 Science & Technology", open=False):
537
+ for query in examples["🔬 Science & Technology"]:
538
+ example_btn = gr.Button(query, variant="secondary", size="sm")
539
+ example_btn.click(
540
+ fn=lambda q=query: q,
541
+ outputs=[query_input]
542
+ )
543
+
544
+ with gr.Accordion("🏆 Sports & Entertainment", open=False):
545
+ for query in examples["🏆 Sports & Entertainment"]:
546
+ example_btn = gr.Button(query, variant="secondary", size="sm")
547
+ example_btn.click(
548
+ fn=lambda q=query: q,
549
+ outputs=[query_input]
550
+ )
551
+
552
+ with gr.Accordion("🔍 Fact Checking", open=False):
553
+ for query in examples["🔍 Fact Checking"]:
554
+ example_btn = gr.Button(query, variant="secondary", size="sm")
555
+ example_btn.click(
556
+ fn=lambda q=query: q,
557
+ outputs=[query_input]
558
+ )
559
+
560
+ gr.HTML('</div>')
561
 
562
  # Results section
563
+ gr.HTML('<div class="results-section">')
564
+ gr.Markdown("### 📊 Results")
565
 
566
  with gr.Row():
567
  with gr.Column(scale=2):
568
+ response_output = gr.Markdown(
569
+ label="Response",
570
+ value="*Your response will appear here...*"
571
  )
572
 
573
  with gr.Column(scale=1):
574
+ tool_info_output = gr.Markdown(
575
+ label="Tool Execution Info",
576
+ value="*Tool execution details will appear here...*"
577
  )
578
 
579
  performance_output = gr.Textbox(
 
581
  value="",
582
  interactive=False
583
  )
584
+ gr.HTML('</div>')
585
 
586
  # Event handlers
587
  validate_btn.click(
 
602
  )
603
 
604
  clear_btn.click(
605
+ fn=lambda: ("", "*Your response will appear here...*", "*Tool execution details will appear here...*", ""),
606
  outputs=[query_input, response_output, tool_info_output, performance_output]
607
  )
608
 
609
  # Footer
610
  gr.HTML("""
611
+ <div class="footer-section">
612
  <h3>🔗 Useful Links</h3>
613
  <p>
614
  <a href="https://console.groq.com/" target="_blank">Groq Console</a> - Get your free API key<br>
 
617
  </p>
618
 
619
  <h3>💡 Tips</h3>
620
+ <ul style="text-align: left; display: inline-block;">
621
  <li>The compound models automatically use web search when real-time information is needed</li>
622
  <li>Try different temperature settings: 0.1 for factual queries, 0.7-0.9 for creative questions</li>
623
  <li>compound-beta is more capable but slower, compound-beta-mini is faster but less capable</li>