shukdevdatta123 commited on
Commit
bb11b45
·
verified ·
1 Parent(s): dee28b4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +679 -30
app.py CHANGED
@@ -1,42 +1,691 @@
1
- from Crypto.Cipher import AES
2
- from Crypto.Protocol.KDF import PBKDF2
3
  import os
4
- import tempfile
5
- from dotenv import load_dotenv
 
 
 
6
 
7
- load_dotenv() # Load all environment variables
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- def unpad(data):
10
- return data[:-data[-1]]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- def decrypt_and_run():
13
- # Get password from Hugging Face Secrets environment variable
14
- password = os.getenv("PASSWORD")
15
- if not password:
16
- raise ValueError("PASSWORD secret not found in environment variables")
17
 
18
- password = password.encode()
 
 
 
 
 
19
 
20
- with open("code.enc", "rb") as f:
21
- encrypted = f.read()
 
22
 
23
- salt = encrypted[:16]
24
- iv = encrypted[16:32]
25
- ciphertext = encrypted[32:]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- key = PBKDF2(password, salt, dkLen=32, count=1000000)
28
- cipher = AES.new(key, AES.MODE_CBC, iv)
 
 
 
29
 
30
- plaintext = unpad(cipher.decrypt(ciphertext))
 
 
 
 
 
 
 
31
 
32
- with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode='wb') as tmp:
33
- tmp.write(plaintext)
34
- tmp.flush()
35
- print(f"[INFO] Running decrypted code from {tmp.name}")
36
- os.system(f"python {tmp.name}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
- if __name__ == "__main__":
39
- decrypt_and_run()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- # This script decrypts the encrypted code and runs it.
42
- # Ensure you have the PASSWORD secret set in your Hugging Face Secrets
 
 
 
 
 
 
1
  import os
2
+ import gradio as gr
3
+ from groq import Groq
4
+ import json
5
+ from datetime import datetime
6
+ import time
7
 
8
+ class RealTimeFactChecker:
9
+ def __init__(self):
10
+ self.client = None
11
+ self.model_options = ["compound-beta", "compound-beta-mini"]
12
+
13
+ def initialize_client(self, api_key):
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
+ 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
38
+ - Weather conditions or forecasts
39
+ - Recent scientific discoveries or research
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 "❌ Please set a valid API key first.", 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
+ {
64
+ "role": "system",
65
+ "content": system_prompt
66
+ },
67
+ {
68
+ "role": "user",
69
+ "content": query,
70
+ }
71
+ ],
72
+ model=model,
73
+ temperature=temperature,
74
+ max_tokens=1500
75
+ )
76
+
77
+ end_time = time.time()
78
+ response_time = round(end_time - start_time, 2)
79
+
80
+ response_content = chat_completion.choices[0].message.content
81
+ executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
82
+ tool_info = self.format_tool_info(executed_tools)
83
+
84
+ return response_content, tool_info, response_time
85
+
86
+ except Exception as e:
87
+ return f"❌ Error querying model: {str(e)}", None, None
88
+
89
+ def format_tool_info(self, executed_tools):
90
+ """Format executed tools information for display"""
91
+ if not executed_tools:
92
+ return "🔍 **Tools Used:** None (Used existing knowledge)"
93
+
94
+ tool_info = "🔍 **Tools Used:**\n"
95
+ for i, tool in enumerate(executed_tools, 1):
96
+ try:
97
+ if hasattr(tool, 'name'):
98
+ tool_name = tool.name
99
+ elif hasattr(tool, 'tool_name'):
100
+ tool_name = tool.tool_name
101
+ elif isinstance(tool, dict):
102
+ tool_name = tool.get('name', 'Unknown')
103
+ else:
104
+ tool_name = str(tool)
105
+
106
+ tool_info += f"{i}. **{tool_name}**\n"
107
+
108
+ if hasattr(tool, 'parameters'):
109
+ params = tool.parameters
110
+ if isinstance(params, dict):
111
+ for key, value in params.items():
112
+ tool_info += f" - {key}: {value}\n"
113
+ elif hasattr(tool, 'input'):
114
+ tool_info += f" - Input: {tool.input}\n"
115
+
116
+ except Exception as e:
117
+ tool_info += f"{i}. **Tool {i}** (Error parsing details)\n"
118
+
119
+ return tool_info
120
+
121
+ def get_example_queries(self):
122
+ """Return categorized example queries"""
123
+ return {
124
+ "📰 Latest News": [
125
+ "What are the top 3 news stories today?",
126
+ "Latest developments in AI technology this week",
127
+ "Recent political events in the United States",
128
+ "Breaking news about climate change",
129
+ "What happened in the stock market today?"
130
+ ],
131
+ "💰 Financial Data": [
132
+ "Current price of Bitcoin",
133
+ "Tesla stock price today",
134
+ "How is the S&P 500 performing today?",
135
+ "Latest cryptocurrency market trends",
136
+ "What's the current inflation rate?"
137
+ ],
138
+ "🌤️ Weather Updates": [
139
+ "Current weather in New York City",
140
+ "Weather forecast for London this week",
141
+ "Is it going to rain in San Francisco today?",
142
+ "Temperature in Tokyo right now",
143
+ "Weather conditions in Sydney"
144
+ ],
145
+ "🔬 Science & Technology": [
146
+ "Latest breakthroughs in fusion energy",
147
+ "Recent discoveries in space exploration",
148
+ "New developments in quantum computing",
149
+ "Latest medical research findings",
150
+ "Recent advances in renewable energy"
151
+ ],
152
+ "🏆 Sports & Entertainment": [
153
+ "Latest football match results",
154
+ "Who won the recent tennis tournament?",
155
+ "Box office numbers for this weekend",
156
+ "Latest movie releases this month",
157
+ "Recent celebrity news"
158
+ ],
159
+ "🔍 Fact Checking": [
160
+ "Is it true that the Earth's population reached 8 billion?",
161
+ "Verify: Did company X announce layoffs recently?",
162
+ "Check if the recent earthquake in Turkey was magnitude 7+",
163
+ "Confirm the latest unemployment rate statistics",
164
+ "Verify recent claims about electric vehicle sales"
165
+ ]
166
+ }
167
+
168
+ def get_custom_prompt_examples(self):
169
+ """Return custom system prompt examples"""
170
+ return {
171
+ "🎯 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.",
172
+ "📊 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.",
173
+ "💼 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.",
174
+ "🔬 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.",
175
+ "🌍 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.",
176
+ "📈 Market Analyst": "You are a market analyst. Provide detailed financial analysis including technical indicators, market sentiment, and economic factors affecting price movements."
177
+ }
178
 
179
+ def show_prompt(title, prompt):
180
+ """Display the selected prompt in the display area"""
181
+ return f"**{title}**\n\n{prompt}"
 
 
182
 
183
+ def apply_prompt(displayed_prompt, system_prompt_input):
184
+ """Apply the displayed prompt to the system prompt input"""
185
+ # Extract the prompt text (skip the title line)
186
+ prompt_lines = displayed_prompt.split("\n")
187
+ prompt_text = "\n".join(line for line in prompt_lines[2:] if line.strip()) if len(prompt_lines) > 2 else displayed_prompt
188
+ return prompt_text
189
 
190
+ def clear_display():
191
+ """Clear the displayed prompt area"""
192
+ return ""
193
 
194
+ def create_interface():
195
+ fact_checker = RealTimeFactChecker()
196
+
197
+ custom_css = """
198
+ .gradio-container {
199
+ max-width: 1400px !important;
200
+ margin: 0 auto;
201
+ background: white;
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
+ color: wheat;
224
+ font-size: 1.2rem;
225
+ margin: 10px 0 0 0;
226
+ opacity: 0.9;
227
+ }
228
+
229
+ .feature-card {
230
+ background: white;
231
+ border-radius: 15px;
232
+ padding: 25px;
233
+ margin: 20px 0;
234
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
235
+ border: 1px solid #e1e8ed;
236
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
237
+ }
238
+
239
+ .feature-card:hover {
240
+ transform: translateY(-5px);
241
+ box-shadow: 0 15px 40px rgba(0,0,0,0.2);
242
+ }
243
+
244
+ .example-grid {
245
+ display: grid;
246
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
247
+ gap: 15px;
248
+ margin-top: 20px;
249
+ }
250
+
251
+ .example-category {
252
+ background: #f8f9fa;
253
+ border-radius: 10px;
254
+ padding: 15px;
255
+ border-left: 4px solid #667eea;
256
+ }
257
+
258
+ .example-category h4 {
259
+ margin: 0 0 10px 0;
260
+ color: #2d3748;
261
+ font-weight: 600;
262
+ }
263
+
264
+ .status-success {
265
+ background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
266
+ color: white;
267
+ padding: 10px 15px;
268
+ border-radius: 8px;
269
+ font-weight: 500;
270
+ }
271
+
272
+ .status-warning {
273
+ background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%);
274
+ color: white;
275
+ padding: 10px 15px;
276
+ border-radius: 8px;
277
+ font-weight: 500;
278
+ }
279
+
280
+ .status-error {
281
+ background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
282
+ color: white;
283
+ padding: 10px 15px;
284
+ border-radius: 8px;
285
+ font-weight: 500;
286
+ }
287
+
288
+ .results-section {
289
+ background: white;
290
+ border-radius: 15px;
291
+ padding: 30px;
292
+ margin: 30px 0;
293
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
294
+ }
295
+
296
+ .tool-info {
297
+ background: #f7fafc;
298
+ border-left: 4px solid #4299e1;
299
+ padding: 15px;
300
+ border-radius: 8px;
301
+ margin: 15px 0;
302
+ }
303
+
304
+ .performance-badge {
305
+ background: linear-gradient(135deg, #38b2ac 0%, #319795 100%);
306
+ color: white;
307
+ padding: 8px 15px;
308
+ border-radius: 20px;
309
+ font-weight: 500;
310
+ display: inline-block;
311
+ }
312
 
313
+ .performance-badge label {
314
+ color: white;
315
+ font-weight: 600;
316
+ font-size: 0.9rem;
317
+ }
318
 
319
+ .footer-section {
320
+ background: #2d3748;
321
+ color: white;
322
+ padding: 30px;
323
+ border-radius: 15px;
324
+ margin-top: 30px;
325
+ text-align: center;
326
+ }
327
 
328
+ .footer-section h3 {
329
+ color: wheat;
330
+ }
331
+
332
+ .footer-section a {
333
+ color: #63b3ed;
334
+ text-decoration: none;
335
+ font-weight: 500;
336
+ }
337
+
338
+ .footer-section a:hover {
339
+ color: #90cdf4;
340
+ text-decoration: underline;
341
+ }
342
+
343
+ .prompt-display {
344
+ background: white;
345
+ border-radius: 10px;
346
+ padding: 15px;
347
+ border: 1px solid #bee3f8;
348
+ margin: 10px 0;
349
+ }
350
+
351
+ .custom-button {
352
+ margin-top: 20px;
353
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
354
+ color: white;
355
+ margin-left: 8px;
356
+ margin-right: 8px;
357
+ border-radius: 8px;
358
+ border: none;
359
+ font-weight: 600;
360
+ transition: all 0.3s ease;
361
+ cursor: pointer;
362
+ }
363
+
364
+ .custom-button:hover {
365
+ transform: translateY(-2px);
366
+ box-shadow: 0 5px 15px rgba(0,0,0,0.2);
367
+ background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
368
+ }
369
+
370
+ .custom-button:active {
371
+ transform: translateY(0);
372
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
373
+ }
374
+
375
+ .custom-button-secondary {
376
+ margin-top: 20px;
377
+ margin-left: 8px;
378
+ margin-right: 8px;
379
+ background: linear-gradient(135deg, #a0aec0 0%, #718096 100%);
380
+ color: white;
381
+ border-radius: 8px;
382
+ border: none;
383
+ font-weight: 600;
384
+ transition: all 0.3s ease;
385
+ cursor: pointer;
386
+ }
387
+
388
+ .custom-button-secondary:hover {
389
+ transform: translateY(-2px);
390
+ box-shadow: 0 5px 15px rgba(0,0,0,0.2);
391
+ background: linear-gradient(135deg, #718096 0%, #a0aec0 100%);
392
+ }
393
+
394
+ .custom-button-small {
395
+ padding: 8px 16px;
396
+ font-size: 0.9rem;
397
+ }
398
+ #neuroscope-accordion {
399
+ background: linear-gradient(to right, #00ff94, #00b4db);
400
+ border-radius: 8px;
401
+ margin-top: 10px;
402
+ margin-bottom: 10px;
403
+ }
404
+ """
405
+
406
+ def validate_api_key(api_key):
407
+ if not api_key or api_key.strip() == "":
408
+ return "❌ Please enter a valid API key", False
409
+
410
+ success, message = fact_checker.initialize_client(api_key.strip())
411
+ return message, success
412
+
413
+ def process_query(query, model, temperature, api_key, system_prompt):
414
+ if not api_key or api_key.strip() == "":
415
+ return "❌ Please set your API key first", "", ""
416
+
417
+ if not query or query.strip() == "":
418
+ return "❌ Please enter a query", "", ""
419
+
420
+ if not fact_checker.client:
421
+ success, message = fact_checker.initialize_client(api_key.strip())
422
+ if not success:
423
+ return message, "", ""
424
+
425
+ response, tool_info, response_time = fact_checker.query_compound_model(
426
+ query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
427
+ )
428
+
429
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
430
+ formatted_response = f"**Query:** {query}\n\n**Response:**\n{response}\n\n---\n*Generated at {timestamp} in {response_time}s*"
431
+
432
+ return formatted_response, tool_info or "", f"⚡ Response time: {response_time}s"
433
+
434
+ def reset_system_prompt():
435
+ return fact_checker.get_system_prompt()
436
+
437
+ def load_example(example_text):
438
+ return example_text
439
+
440
+ with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) as demo:
441
+ gr.HTML("""
442
+ <div class="main-header">
443
+ <h1>🔍 Real-time Fact Checker & News Agent</h1>
444
+ <p>Powered by Groq's Compound Models with Built-in Web Search</p>
445
+ </div>
446
+ """)
447
+
448
+ with gr.Row():
449
+ with gr.Column(scale=2):
450
+ with gr.Group():
451
+ gr.HTML('<div class="feature-card">🔑 API Configuration</div>')
452
+ api_key_input = gr.Textbox(
453
+ label="Groq API Key",
454
+ placeholder="Enter your Groq API key here...",
455
+ type="password",
456
+ info="Get your free API key from https://console.groq.com/"
457
+ )
458
+ api_status = gr.Textbox(
459
+ label="Status",
460
+ value="⚠️ Please enter your API key",
461
+ interactive=False,
462
+ elem_classes=["status-warning"]
463
+ )
464
+ validate_btn = gr.Button("Validate API Key", elem_classes=["custom-button"])
465
+ gr.HTML('</div>')
466
+
467
+ with gr.Group():
468
+ gr.HTML('<div class="feature-card">⚙️ Advanced Options</div>')
469
+
470
+ # Define prompt_display before using it in button events
471
+ prompt_display = gr.Markdown(
472
+ label="Selected Prompt",
473
+ value="",
474
+ elem_classes=["prompt-display"]
475
+ )
476
+ with gr.Accordion("📝 System Prompt Examples (Click to view)", open=False, elem_id="neuroscope-accordion"):
477
+ gr.Markdown("**Click any example to display its full prompt below:**")
478
+
479
+ custom_prompts = fact_checker.get_custom_prompt_examples()
480
+ for title, prompt in custom_prompts.items():
481
+ with gr.Row():
482
+ prompt_btn = gr.Button(
483
+ f"{title}: {prompt[:100]}...",
484
+ elem_classes=["custom-button-secondary", "custom-button-small"]
485
+ )
486
+ prompt_btn.click(
487
+ fn=show_prompt,
488
+ inputs=[gr.State(value=title), gr.State(value=prompt)],
489
+ outputs=[prompt_display]
490
+ )
491
 
492
+ with gr.Row():
493
+ apply_prompt_btn = gr.Button("Apply Prompt", elem_classes=["custom-button-secondary", "custom-button-small"])
494
+ clear_prompt_btn = gr.Button("Clear Display", elem_classes=["custom-button-secondary", "custom-button-small"])
495
+
496
+ with gr.Accordion("🔧 System Prompt (Click to customize)", open=False, elem_id="neuroscope-accordion"):
497
+ system_prompt_input = gr.Textbox(
498
+ label="System Prompt",
499
+ value=fact_checker.get_system_prompt(),
500
+ lines=8,
501
+ info="Customize how the AI behaves and responds"
502
+ )
503
+ reset_prompt_btn = gr.Button("Reset to Default", elem_classes=["custom-button-secondary", "custom-button-small"])
504
+
505
+ gr.Markdown("**Quick Load Custom Prompts:**")
506
+ with gr.Row():
507
+ for title, prompt in custom_prompts.items():
508
+ quick_prompt_btn = gr.Button(title, elem_classes=["custom-button-secondary", "custom-button-small"])
509
+ quick_prompt_btn.click(
510
+ fn=lambda p=prompt: p,
511
+ outputs=[system_prompt_input]
512
+ )
513
+
514
+ apply_prompt_btn.click(
515
+ fn=apply_prompt,
516
+ inputs=[prompt_display, system_prompt_input],
517
+ outputs=[system_prompt_input]
518
+ )
519
+
520
+ clear_prompt_btn.click(
521
+ fn=clear_display,
522
+ outputs=[prompt_display]
523
+ )
524
+
525
+ gr.HTML('</div>')
526
+
527
+ with gr.Group():
528
+ gr.HTML('<div class="feature-card">💭 Your Query</div>')
529
+ query_input = gr.Textbox(
530
+ label="Ask anything that requires real-time information",
531
+ placeholder="e.g., What are the latest AI developments today?",
532
+ lines=4
533
+ )
534
+
535
+ with gr.Row():
536
+ model_choice = gr.Dropdown(
537
+ choices=fact_checker.model_options,
538
+ value="compound-beta",
539
+ label="Model",
540
+ info="compound-beta: More capable | compound-beta-mini: Faster"
541
+ )
542
+ temperature = gr.Slider(
543
+ minimum=0.0,
544
+ maximum=1.0,
545
+ value=0.7,
546
+ step=0.1,
547
+ label="Temperature",
548
+ info="Higher = more creative, Lower = more focused"
549
+ )
550
+
551
+ with gr.Row():
552
+ submit_btn = gr.Button("🔍 Get Real-time Information", elem_classes=["custom-button"])
553
+ clear_btn = gr.Button("Clear", elem_classes=["custom-button-secondary"])
554
+ gr.HTML('</div>')
555
+
556
+ with gr.Column(scale=1):
557
+ with gr.Group():
558
+ gr.HTML('<div class="feature-card">📝 Example Queries</div>')
559
+
560
+ examples = fact_checker.get_example_queries()
561
+
562
+ with gr.Accordion("📰 Latest News", open=False, elem_id="neuroscope-accordion"):
563
+ with gr.Row():
564
+ for query in examples["📰 Latest News"]:
565
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
566
+ example_btn.click(
567
+ fn=lambda q=query: q,
568
+ outputs=[query_input]
569
+ )
570
+
571
+ with gr.Accordion("💰 Financial Data", open=False, elem_id="neuroscope-accordion"):
572
+ with gr.Row():
573
+ for query in examples["💰 Financial Data"]:
574
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
575
+ example_btn.click(
576
+ fn=lambda q=query: q,
577
+ outputs=[query_input]
578
+ )
579
+
580
+ with gr.Accordion("🌤️ Weather Updates", open=False, elem_id="neuroscope-accordion"):
581
+ with gr.Row():
582
+ for query in examples["🌤️ Weather Updates"]:
583
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
584
+ example_btn.click(
585
+ fn=lambda q=query: q,
586
+ outputs=[query_input]
587
+ )
588
+
589
+ with gr.Accordion("🔬 Science & Technology", open=False, elem_id="neuroscope-accordion"):
590
+ with gr.Row():
591
+ for query in examples["🔬 Science & Technology"]:
592
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
593
+ example_btn.click(
594
+ fn=lambda q=query: q,
595
+ outputs=[query_input]
596
+ )
597
+
598
+ with gr.Accordion("🏆 Sports & Entertainment", open=False, elem_id="neuroscope-accordion"):
599
+ with gr.Row():
600
+ for query in examples["🏆 Sports & Entertainment"]:
601
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
602
+ example_btn.click(
603
+ fn=lambda q=query: q,
604
+ outputs=[query_input]
605
+ )
606
+
607
+ with gr.Accordion("🔍 Fact Checking", open=False, elem_id="neuroscope-accordion"):
608
+ with gr.Row():
609
+ for query in examples["🔍 Fact Checking"]:
610
+ example_btn = gr.Button(query, elem_classes=["custom-button-secondary", "custom-button-small"])
611
+ example_btn.click(
612
+ fn=lambda q=query: q,
613
+ outputs=[query_input]
614
+ )
615
+
616
+ gr.HTML('</div>')
617
+
618
+ gr.HTML('<div class="results-section">📊 Results</div>')
619
+
620
+ with gr.Row():
621
+ with gr.Column(scale=2):
622
+ response_output = gr.Markdown(
623
+ label="Response",
624
+ value="*Your response will appear here...*",
625
+ elem_classes=["feature-card"]
626
+ )
627
+
628
+ with gr.Column(scale=1):
629
+ tool_info_output = gr.Markdown(
630
+ label="Tool Execution Info",
631
+ value="*Tool execution details will appear here...*",
632
+ elem_classes=["tool-info"]
633
+ )
634
+
635
+ performance_output = gr.Textbox(
636
+ label="Performance",
637
+ value="",
638
+ interactive=False,
639
+ elem_classes=["performance-badge"]
640
+ )
641
+ gr.HTML('</div>')
642
+
643
+ validate_btn.click(
644
+ fn=validate_api_key,
645
+ inputs=[api_key_input],
646
+ outputs=[api_status, gr.State()]
647
+ )
648
+
649
+ reset_prompt_btn.click(
650
+ fn=reset_system_prompt,
651
+ outputs=[system_prompt_input]
652
+ )
653
+
654
+ submit_btn.click(
655
+ fn=process_query,
656
+ inputs=[query_input, model_choice, temperature, api_key_input, system_prompt_input],
657
+ outputs=[response_output, tool_info_output, performance_output]
658
+ )
659
+
660
+ clear_btn.click(
661
+ fn=lambda: ("", "*Your response will appear here...*", "*Tool execution details will appear here...*", ""),
662
+ outputs=[query_input, response_output, tool_info_output, performance_output]
663
+ )
664
+
665
+ gr.HTML("""
666
+ <div class="footer-section">
667
+ <h3>🔗 Useful Links</h3>
668
+ <p>
669
+ <a href="https://console.groq.com/" target="_blank">Groq Console</a> - <span style="color: wheat;">Get your free API key</span><br>
670
+ <a href="https://console.groq.com/docs/quickstart" target="_blank">Groq Documentation</a> - <span style="color: wheat;">Learn more about Groq models</span><br>
671
+ <a href="https://console.groq.com/docs/models" target="_blank">Compound Models Info</a> - <span style="color: wheat;">Details about compound models</span><br>
672
+ </p>
673
+
674
+ <h3>💡 Tips</h3>
675
+ <ul style="text-align: left; display: inline-block;">
676
+ <li style="color: wheat;">The compound models automatically use web search when real-time information is needed</li>
677
+ <li style="color: wheat;">Try different temperature settings: 0.1 for factual queries, 0.7-0.9 for creative questions</li>
678
+ <li style="color: wheat;">compound-beta is more capable but slower, compound-beta-mini is faster but less capable</li>
679
+ <li style="color: wheat;">Use custom system prompts to specialize the AI for different types of queries</li>
680
+ <li style="color: wheat;">Check the Tool Execution Info to see when web search was used</li>
681
+ </ul>
682
+ </div>
683
+ """)
684
+
685
+ return demo
686
 
687
+ if __name__ == "__main__":
688
+ demo = create_interface()
689
+ demo.launch(
690
+ share=True
691
+ )