Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -4,6 +4,7 @@ from groq import Groq
|
|
4 |
import json
|
5 |
from datetime import datetime
|
6 |
import time
|
|
|
7 |
|
8 |
class RealTimeFactChecker:
|
9 |
def __init__(self):
|
@@ -14,9 +15,9 @@ class RealTimeFactChecker:
|
|
14 |
"""Initialize Groq client with API key"""
|
15 |
try:
|
16 |
self.client = Groq(api_key=api_key)
|
17 |
-
return True, "
|
18 |
except Exception as e:
|
19 |
-
return False, f"
|
20 |
|
21 |
def get_system_prompt(self):
|
22 |
"""Get the system prompt for consistent behavior"""
|
@@ -38,7 +39,7 @@ WHEN TO SEARCH:
|
|
38 |
- Weather conditions or forecasts
|
39 |
- Recent scientific discoveries or research
|
40 |
- Current political developments
|
41 |
-
- Real-time
|
42 |
- Verification of recent claims or rumors
|
43 |
RESPONSE FORMAT:
|
44 |
- Lead with key facts
|
@@ -51,11 +52,12 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
|
|
51 |
def query_compound_model(self, query, model, temperature=0.7, custom_system_prompt=None):
|
52 |
"""Query the compound model and return response with tool execution info"""
|
53 |
if not self.client:
|
54 |
-
return "
|
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(
|
@@ -77,25 +79,47 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
|
|
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 |
|
|
|
82 |
executed_tools = getattr(chat_completion.choices[0].message, 'executed_tools', None)
|
83 |
|
|
|
84 |
tool_info = self.format_tool_info(executed_tools)
|
85 |
|
86 |
return response_content, tool_info, response_time
|
87 |
|
88 |
except Exception as e:
|
89 |
-
return f"
|
90 |
|
91 |
def format_tool_info(self, executed_tools):
|
92 |
"""Format executed tools information for display"""
|
93 |
if not executed_tools:
|
94 |
-
return "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
-
tool_info = "<div class='tool-info'><strong>Tools Used:</strong><ul>"
|
97 |
for i, tool in enumerate(executed_tools, 1):
|
98 |
try:
|
|
|
99 |
if hasattr(tool, 'name'):
|
100 |
tool_name = tool.name
|
101 |
elif hasattr(tool, 'tool_name'):
|
@@ -105,64 +129,113 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
|
|
105 |
else:
|
106 |
tool_name = str(tool)
|
107 |
|
108 |
-
|
|
|
|
|
|
|
109 |
|
|
|
110 |
if hasattr(tool, 'parameters'):
|
111 |
params = tool.parameters
|
112 |
if isinstance(params, dict):
|
113 |
-
tool_info += "<ul>"
|
114 |
for key, value in params.items():
|
115 |
-
|
116 |
-
tool_info += "</ul>"
|
117 |
elif hasattr(tool, 'input'):
|
118 |
-
|
119 |
-
|
|
|
120 |
|
121 |
except Exception as e:
|
122 |
-
|
123 |
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
def get_example_queries(self):
|
128 |
"""Return categorized example queries"""
|
129 |
return {
|
130 |
-
"Latest News": [
|
131 |
"What are the top 3 news stories today?",
|
132 |
"Latest developments in AI technology this week",
|
133 |
"Recent political events in the United States",
|
134 |
"Breaking news about climate change",
|
135 |
"What happened in the stock market today?"
|
136 |
],
|
137 |
-
"Financial Data": [
|
138 |
"Current price of Bitcoin",
|
139 |
"Tesla stock price today",
|
140 |
"How is the S&P 500 performing today?",
|
141 |
"Latest cryptocurrency market trends",
|
142 |
"What's the current inflation rate?"
|
143 |
],
|
144 |
-
"Weather Updates": [
|
145 |
"Current weather in New York City",
|
146 |
"Weather forecast for London this week",
|
147 |
"Is it going to rain in San Francisco today?",
|
148 |
"Temperature in Tokyo right now",
|
149 |
"Weather conditions in Sydney"
|
150 |
],
|
151 |
-
"Science & Technology": [
|
152 |
"Latest breakthroughs in fusion energy",
|
153 |
"Recent discoveries in space exploration",
|
154 |
"New developments in quantum computing",
|
155 |
"Latest medical research findings",
|
156 |
"Recent advances in renewable energy"
|
157 |
],
|
158 |
-
"Sports & Entertainment": [
|
159 |
"Latest football match results",
|
160 |
"Who won the recent tennis tournament?",
|
161 |
"Box office numbers for this weekend",
|
162 |
"Latest movie releases this month",
|
163 |
"Recent celebrity news"
|
164 |
],
|
165 |
-
"Fact Checking": [
|
166 |
"Is it true that the Earth's population reached 8 billion?",
|
167 |
"Verify: Did company X announce layoffs recently?",
|
168 |
"Check if the recent earthquake in Turkey was magnitude 7+",
|
@@ -174,215 +247,429 @@ Remember: Your goal is to be the most reliable, up-to-date source of information
|
|
174 |
def get_custom_prompt_examples(self):
|
175 |
"""Return custom system prompt examples"""
|
176 |
return {
|
177 |
-
"Fact-Checker": "You are a fact-checker. Always verify claims with multiple sources and clearly indicate confidence levels in your assessments. Use phrases like 'highly confident', 'moderately confident', or 'requires verification' when presenting information.",
|
178 |
-
|
179 |
-
"
|
180 |
-
|
181 |
-
"
|
182 |
-
|
|
|
|
|
|
|
|
|
|
|
183 |
}
|
184 |
|
185 |
def create_interface():
|
186 |
fact_checker = RealTimeFactChecker()
|
187 |
|
|
|
188 |
custom_css = """
|
189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
.gradio-container {
|
191 |
-
max-width: 1200px;
|
192 |
margin: 0 auto;
|
193 |
-
background: #f5f7fa;
|
194 |
-
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
195 |
padding: 20px;
|
|
|
196 |
}
|
197 |
|
198 |
-
|
199 |
-
|
|
|
|
|
200 |
padding: 2rem;
|
201 |
-
border-radius:
|
202 |
-
text-align: center;
|
203 |
-
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
204 |
margin-bottom: 2rem;
|
|
|
|
|
205 |
}
|
206 |
|
207 |
-
.header h1 {
|
208 |
-
font-size:
|
209 |
-
|
210 |
-
margin: 0;
|
211 |
}
|
212 |
|
213 |
-
.header p {
|
214 |
-
font-size: 1rem;
|
215 |
-
|
216 |
-
|
217 |
}
|
218 |
|
|
|
219 |
.card {
|
220 |
-
background:
|
221 |
border-radius: 12px;
|
222 |
padding: 1.5rem;
|
223 |
margin-bottom: 1.5rem;
|
224 |
-
box-shadow: 0
|
225 |
border: 1px solid #e2e8f0;
|
226 |
}
|
227 |
|
228 |
.card h3 {
|
|
|
229 |
font-size: 1.25rem;
|
230 |
-
|
231 |
-
margin:
|
|
|
|
|
|
|
232 |
}
|
233 |
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
|
|
238 |
border-radius: 8px;
|
239 |
-
|
240 |
}
|
241 |
|
242 |
-
.status
|
243 |
-
background: #
|
244 |
-
color:
|
245 |
-
padding: 0.75rem;
|
246 |
border-radius: 8px;
|
247 |
-
|
248 |
}
|
249 |
|
250 |
-
.
|
251 |
-
background: #
|
252 |
-
|
|
|
253 |
border-radius: 8px;
|
254 |
-
|
255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
}
|
257 |
|
258 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
margin: 0.5rem 0;
|
260 |
-
|
|
|
261 |
}
|
262 |
|
263 |
-
.
|
264 |
-
background: #
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
border-radius: 12px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
padding: 1.5rem;
|
267 |
-
|
268 |
-
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
269 |
}
|
270 |
|
271 |
-
.
|
272 |
-
|
273 |
-
|
274 |
-
|
|
|
275 |
}
|
276 |
|
277 |
-
.
|
278 |
-
|
279 |
-
|
|
|
|
|
|
|
280 |
}
|
281 |
|
282 |
-
.
|
283 |
-
|
284 |
-
|
|
|
285 |
margin-top: 1rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
font-style: italic;
|
287 |
}
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
}
|
295 |
|
296 |
-
.
|
297 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
padding: 1rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
border-radius: 8px;
|
|
|
300 |
cursor: pointer;
|
301 |
-
transition:
|
|
|
302 |
}
|
303 |
|
304 |
-
.
|
305 |
background: #e2e8f0;
|
306 |
}
|
307 |
|
308 |
-
.
|
309 |
-
background: #e6fffa;
|
310 |
padding: 1rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
border-radius: 8px;
|
312 |
-
|
313 |
cursor: pointer;
|
314 |
-
transition:
|
315 |
}
|
316 |
|
317 |
-
.
|
318 |
-
background: #
|
319 |
}
|
320 |
|
321 |
-
.
|
322 |
-
|
323 |
-
color: #
|
324 |
-
|
|
|
|
|
|
|
|
|
|
|
325 |
}
|
326 |
|
327 |
-
.
|
328 |
-
|
329 |
-
color: #
|
330 |
}
|
331 |
|
|
|
332 |
.footer {
|
333 |
-
background: #
|
334 |
-
color:
|
335 |
padding: 2rem;
|
336 |
border-radius: 12px;
|
337 |
-
text-align: center;
|
338 |
margin-top: 2rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
}
|
340 |
|
341 |
.footer a {
|
342 |
-
color: #
|
343 |
text-decoration: none;
|
344 |
font-weight: 500;
|
345 |
}
|
346 |
|
347 |
.footer a:hover {
|
348 |
-
color: #
|
349 |
text-decoration: underline;
|
350 |
}
|
351 |
|
352 |
-
.
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
padding: 0.75rem 1.5rem;
|
357 |
-
border-radius: 8px;
|
358 |
-
font-weight: 500;
|
359 |
}
|
360 |
|
361 |
-
.
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
}
|
369 |
-
</style>
|
370 |
"""
|
371 |
|
372 |
def validate_api_key(api_key):
|
373 |
if not api_key or api_key.strip() == "":
|
374 |
-
return "
|
375 |
|
376 |
success, message = fact_checker.initialize_client(api_key.strip())
|
377 |
return message, success
|
378 |
|
379 |
def process_query(query, model, temperature, api_key, system_prompt):
|
380 |
if not api_key or api_key.strip() == "":
|
381 |
-
return "
|
382 |
|
383 |
if not query or query.strip() == "":
|
384 |
-
return "
|
385 |
|
|
|
386 |
if not fact_checker.client:
|
387 |
success, message = fact_checker.initialize_client(api_key.strip())
|
388 |
if not success:
|
@@ -392,18 +679,10 @@ def create_interface():
|
|
392 |
query.strip(), model, temperature, system_prompt.strip() if system_prompt else None
|
393 |
)
|
394 |
|
395 |
-
|
396 |
-
formatted_response =
|
397 |
-
<div class='result-content'>
|
398 |
-
<h4>Query:</h4>
|
399 |
-
<p>{query}</p>
|
400 |
-
<h4>Response:</h4>
|
401 |
-
<p>{response}</p>
|
402 |
-
<p class='performance'>Generated at {timestamp} in {response_time}s</p>
|
403 |
-
</div>
|
404 |
-
"""
|
405 |
|
406 |
-
return formatted_response, tool_info or "", f"
|
407 |
|
408 |
def reset_system_prompt():
|
409 |
return fact_checker.get_system_prompt()
|
@@ -414,125 +693,183 @@ def create_interface():
|
|
414 |
def load_custom_prompt(prompt_text):
|
415 |
return prompt_text
|
416 |
|
417 |
-
|
|
|
418 |
|
|
|
419 |
gr.HTML("""
|
420 |
-
<div class="header">
|
421 |
-
<h1>🔍 Real-time Fact Checker</h1>
|
422 |
-
<p>
|
423 |
</div>
|
424 |
""")
|
425 |
|
426 |
with gr.Row():
|
427 |
-
with gr.Column(scale=
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
436 |
)
|
437 |
-
|
438 |
-
|
|
|
|
|
|
|
|
|
|
|
439 |
)
|
440 |
-
validate_btn = gr.Button("Validate API Key", variant="secondary")
|
441 |
-
gr.HTML('</div>')
|
442 |
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
)
|
453 |
-
reset_prompt_btn = gr.Button("Reset to Default", variant="secondary")
|
454 |
-
|
455 |
-
gr.Markdown("#### Prompt Examples")
|
456 |
-
custom_prompts = fact_checker.get_custom_prompt_examples()
|
457 |
-
for title, prompt in custom_prompts.items():
|
458 |
-
gr.HTML(f"""
|
459 |
-
<div class="prompt-example" onclick="document.getElementById('system_prompt_input').value = '{prompt}'">
|
460 |
-
<div class="prompt-title">{title}</div>
|
461 |
-
<div class="prompt-text">{prompt[:80]}...</div>
|
462 |
-
</div>
|
463 |
-
""")
|
464 |
-
gr.HTML('</div>')
|
465 |
|
466 |
-
with gr.
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
lines=3
|
473 |
-
)
|
474 |
-
with gr.Row():
|
475 |
-
model_choice = gr.Dropdown(
|
476 |
-
choices=fact_checker.model_options,
|
477 |
-
value="compound-beta",
|
478 |
-
label="Model"
|
479 |
)
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
|
|
486 |
)
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
|
503 |
-
gr.HTML('<div class="result-card">')
|
504 |
-
gr.Markdown("### Results")
|
505 |
with gr.Row():
|
506 |
-
with gr.Column(scale=
|
507 |
response_output = gr.HTML(
|
508 |
-
value="<div
|
509 |
)
|
510 |
-
|
|
|
511 |
tool_info_output = gr.HTML(
|
512 |
-
value="<div
|
513 |
)
|
514 |
-
|
515 |
-
|
|
|
|
|
|
|
516 |
)
|
517 |
-
gr.HTML('</div>')
|
518 |
-
|
519 |
-
gr.HTML("""
|
520 |
-
<div class="footer">
|
521 |
-
<h3>Links</h3>
|
522 |
-
<p>
|
523 |
-
<a href="https://console.groq.com/" target="_blank">Groq Console</a> |
|
524 |
-
<a href="https://console.groq.com/docs/quickstart" target="_blank">Documentation</a> |
|
525 |
-
<a href="https://console.groq.com/docs/models" target="_blank">Models Info</a>
|
526 |
-
</p>
|
527 |
-
<h3>Tips</h3>
|
528 |
-
<ul style="text-align: left; display: inline-block;">
|
529 |
-
<li>Use compound-beta for detailed responses</li>
|
530 |
-
<li>Adjust temperature for creative or factual responses</li>
|
531 |
-
<li>Check tool execution info for source transparency</li>
|
532 |
-
</ul>
|
533 |
-
</div>
|
534 |
-
""")
|
535 |
|
|
|
536 |
validate_btn.click(
|
537 |
fn=validate_api_key,
|
538 |
inputs=[api_key_input],
|
@@ -551,12 +888,34 @@ def create_interface():
|
|
551 |
)
|
552 |
|
553 |
clear_btn.click(
|
554 |
-
fn=lambda: ("", "<div
|
555 |
outputs=[query_input, response_output, tool_info_output, performance_output]
|
556 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
557 |
|
558 |
return demo
|
559 |
|
|
|
560 |
if __name__ == "__main__":
|
561 |
demo = create_interface()
|
562 |
demo.launch(
|
|
|
4 |
import json
|
5 |
from datetime import datetime
|
6 |
import time
|
7 |
+
import re
|
8 |
|
9 |
class RealTimeFactChecker:
|
10 |
def __init__(self):
|
|
|
15 |
"""Initialize Groq client with API key"""
|
16 |
try:
|
17 |
self.client = Groq(api_key=api_key)
|
18 |
+
return True, "✅ API Key validated successfully!"
|
19 |
except Exception as e:
|
20 |
+
return False, f"❌ Error initializing client: {str(e)}"
|
21 |
|
22 |
def get_system_prompt(self):
|
23 |
"""Get the system prompt for consistent behavior"""
|
|
|
39 |
- Weather conditions or forecasts
|
40 |
- Recent scientific discoveries or research
|
41 |
- Current political developments
|
42 |
+
- Real-time statistics or data
|
43 |
- Verification of recent claims or rumors
|
44 |
RESPONSE FORMAT:
|
45 |
- Lead with key facts
|
|
|
52 |
def query_compound_model(self, query, model, temperature=0.7, custom_system_prompt=None):
|
53 |
"""Query the compound model and return response with tool execution info"""
|
54 |
if not self.client:
|
55 |
+
return "❌ Please set a valid API key first.", None, None
|
56 |
|
57 |
try:
|
58 |
start_time = time.time()
|
59 |
|
60 |
+
# Use custom system prompt if provided
|
61 |
system_prompt = custom_system_prompt if custom_system_prompt else self.get_system_prompt()
|
62 |
|
63 |
chat_completion = self.client.chat.completions.create(
|
|
|
79 |
end_time = time.time()
|
80 |
response_time = round(end_time - start_time, 2)
|
81 |
|
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
|
89 |
tool_info = self.format_tool_info(executed_tools)
|
90 |
|
91 |
return response_content, tool_info, response_time
|
92 |
|
93 |
except Exception as e:
|
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
|
123 |
if hasattr(tool, 'name'):
|
124 |
tool_name = tool.name
|
125 |
elif hasattr(tool, 'tool_name'):
|
|
|
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"""
|
202 |
return {
|
203 |
+
"📰 Latest News": [
|
204 |
"What are the top 3 news stories today?",
|
205 |
"Latest developments in AI technology this week",
|
206 |
"Recent political events in the United States",
|
207 |
"Breaking news about climate change",
|
208 |
"What happened in the stock market today?"
|
209 |
],
|
210 |
+
"💰 Financial Data": [
|
211 |
"Current price of Bitcoin",
|
212 |
"Tesla stock price today",
|
213 |
"How is the S&P 500 performing today?",
|
214 |
"Latest cryptocurrency market trends",
|
215 |
"What's the current inflation rate?"
|
216 |
],
|
217 |
+
"🌤️ Weather Updates": [
|
218 |
"Current weather in New York City",
|
219 |
"Weather forecast for London this week",
|
220 |
"Is it going to rain in San Francisco today?",
|
221 |
"Temperature in Tokyo right now",
|
222 |
"Weather conditions in Sydney"
|
223 |
],
|
224 |
+
"🔬 Science & Technology": [
|
225 |
"Latest breakthroughs in fusion energy",
|
226 |
"Recent discoveries in space exploration",
|
227 |
"New developments in quantum computing",
|
228 |
"Latest medical research findings",
|
229 |
"Recent advances in renewable energy"
|
230 |
],
|
231 |
+
"🏆 Sports & Entertainment": [
|
232 |
"Latest football match results",
|
233 |
"Who won the recent tennis tournament?",
|
234 |
"Box office numbers for this weekend",
|
235 |
"Latest movie releases this month",
|
236 |
"Recent celebrity news"
|
237 |
],
|
238 |
+
"🔍 Fact Checking": [
|
239 |
"Is it true that the Earth's population reached 8 billion?",
|
240 |
"Verify: Did company X announce layoffs recently?",
|
241 |
"Check if the recent earthquake in Turkey was magnitude 7+",
|
|
|
247 |
def get_custom_prompt_examples(self):
|
248 |
"""Return custom system prompt examples"""
|
249 |
return {
|
250 |
+
"🎯 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.",
|
251 |
+
|
252 |
+
"📊 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.",
|
253 |
+
|
254 |
+
"💼 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.",
|
255 |
+
|
256 |
+
"🔬 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.",
|
257 |
+
|
258 |
+
"🌍 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.",
|
259 |
+
|
260 |
+
"📈 Market Analyst": "You are a market analyst. Provide detailed financial analysis including technical indicators, market sentiment, and economic factors affecting price movements."
|
261 |
}
|
262 |
|
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):
|
659 |
if not api_key or api_key.strip() == "":
|
660 |
+
return "❌ Please enter a valid API key", False
|
661 |
|
662 |
success, message = fact_checker.initialize_client(api_key.strip())
|
663 |
return message, success
|
664 |
|
665 |
def process_query(query, model, temperature, api_key, system_prompt):
|
666 |
if not api_key or api_key.strip() == "":
|
667 |
+
return "❌ Please set your API key first", "", ""
|
668 |
|
669 |
if not query or query.strip() == "":
|
670 |
+
return "❌ Please enter a query", "", ""
|
671 |
|
672 |
+
# Initialize client if not already done
|
673 |
if not fact_checker.client:
|
674 |
success, message = fact_checker.initialize_client(api_key.strip())
|
675 |
if not success:
|
|
|
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 |
|
687 |
def reset_system_prompt():
|
688 |
return fact_checker.get_system_prompt()
|
|
|
693 |
def load_custom_prompt(prompt_text):
|
694 |
return prompt_text
|
695 |
|
696 |
+
# Create the Gradio interface
|
697 |
+
with gr.Blocks(title="Real-time Fact Checker & News Agent", css=custom_css) 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>
|
705 |
""")
|
706 |
|
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(
|
867 |
+
label="Performance",
|
868 |
+
value="",
|
869 |
+
interactive=False
|
870 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
871 |
|
872 |
+
# Event handlers
|
873 |
validate_btn.click(
|
874 |
fn=validate_api_key,
|
875 |
inputs=[api_key_input],
|
|
|
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>
|
901 |
+
<a href="https://console.groq.com/docs/quickstart" target="_blank">Groq Documentation</a> - Learn more about Groq models<br>
|
902 |
+
<a href="https://console.groq.com/docs/models" target="_blank">Compound Models Info</a> - Details about compound models
|
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>
|
910 |
+
<li>Use custom system prompts to specialize the AI for different types of queries</li>
|
911 |
+
<li>Check the Tool Execution Info to see when web search was used</li>
|
912 |
+
</ul>
|
913 |
+
</div>
|
914 |
+
""")
|
915 |
|
916 |
return demo
|
917 |
|
918 |
+
# Launch the application
|
919 |
if __name__ == "__main__":
|
920 |
demo = create_interface()
|
921 |
demo.launch(
|