Spaces:
Runtime error
Runtime error
Fix
Browse files
app.py
CHANGED
@@ -21,15 +21,7 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
|
21 |
|
22 |
@tool
|
23 |
def advanced_web_search(query: str, num_results: int = 10) -> str:
|
24 |
-
"""Advanced web search using multiple search engines with fallback
|
25 |
-
|
26 |
-
Args:
|
27 |
-
query: The search query
|
28 |
-
num_results: Number of results to return (default 10)
|
29 |
-
|
30 |
-
Returns:
|
31 |
-
Comprehensive search results as formatted string
|
32 |
-
"""
|
33 |
try:
|
34 |
# First try Serper API if available
|
35 |
api_key = os.getenv("SERPER_API_KEY")
|
@@ -77,14 +69,7 @@ def advanced_web_search(query: str, num_results: int = 10) -> str:
|
|
77 |
|
78 |
@tool
|
79 |
def wikipedia_lookup(topic: str) -> str:
|
80 |
-
"""Enhanced Wikipedia search and content extraction
|
81 |
-
|
82 |
-
Args:
|
83 |
-
topic: Wikipedia topic to look up
|
84 |
-
|
85 |
-
Returns:
|
86 |
-
Wikipedia content with structured information
|
87 |
-
"""
|
88 |
try:
|
89 |
# Clean the topic
|
90 |
topic_clean = topic.replace(" ", "_").strip()
|
@@ -131,14 +116,7 @@ def wikipedia_lookup(topic: str) -> str:
|
|
131 |
|
132 |
@tool
|
133 |
def youtube_video_analyzer(url: str) -> str:
|
134 |
-
"""Advanced YouTube video analysis with multiple extraction methods
|
135 |
-
|
136 |
-
Args:
|
137 |
-
url: YouTube video URL
|
138 |
-
|
139 |
-
Returns:
|
140 |
-
Comprehensive video information
|
141 |
-
"""
|
142 |
try:
|
143 |
# Extract video ID using multiple patterns
|
144 |
video_id = None
|
@@ -223,15 +201,7 @@ def youtube_video_analyzer(url: str) -> str:
|
|
223 |
|
224 |
@tool
|
225 |
def text_manipulator(text: str, operation: str = "reverse") -> str:
|
226 |
-
"""Advanced text manipulation and analysis tool
|
227 |
-
|
228 |
-
Args:
|
229 |
-
text: Text to manipulate
|
230 |
-
operation: Operation type (reverse, analyze, extract_numbers, etc.)
|
231 |
-
|
232 |
-
Returns:
|
233 |
-
Manipulated or analyzed text
|
234 |
-
"""
|
235 |
try:
|
236 |
if operation == "reverse":
|
237 |
return text[::-1]
|
@@ -255,14 +225,7 @@ def text_manipulator(text: str, operation: str = "reverse") -> str:
|
|
255 |
|
256 |
@tool
|
257 |
def mathematical_solver(problem: str) -> str:
|
258 |
-
"""Advanced mathematical problem solver with specific GAIA patterns
|
259 |
-
|
260 |
-
Args:
|
261 |
-
problem: Mathematical problem description
|
262 |
-
|
263 |
-
Returns:
|
264 |
-
Mathematical solution or analysis
|
265 |
-
"""
|
266 |
try:
|
267 |
problem_lower = problem.lower()
|
268 |
|
@@ -303,71 +266,9 @@ STRATEGY: Systematically check each pair in the table"""
|
|
303 |
except Exception as e:
|
304 |
return f"Math solver error: {str(e)}"
|
305 |
|
306 |
-
@tool
|
307 |
-
def data_classifier(data_string: str, classification_type: str = "botanical") -> str:
|
308 |
-
"""Advanced data classification tool for various categorization tasks
|
309 |
-
|
310 |
-
Args:
|
311 |
-
data_string: String containing data to classify
|
312 |
-
classification_type: Type of classification (botanical, numerical, etc.)
|
313 |
-
|
314 |
-
Returns:
|
315 |
-
Classified and sorted data
|
316 |
-
"""
|
317 |
-
try:
|
318 |
-
if classification_type == "botanical" or "vegetable" in classification_type:
|
319 |
-
# Extract items from the string
|
320 |
-
items = []
|
321 |
-
|
322 |
-
# Split by common delimiters
|
323 |
-
for delimiter in [',', ';', 'and', '&']:
|
324 |
-
if delimiter in data_string:
|
325 |
-
items = [item.strip() for item in data_string.split(delimiter)]
|
326 |
-
break
|
327 |
-
|
328 |
-
if not items and ' ' in data_string:
|
329 |
-
items = data_string.split()
|
330 |
-
|
331 |
-
# Classify as true botanical vegetables (not fruits used as vegetables)
|
332 |
-
true_vegetables = []
|
333 |
-
|
334 |
-
# Botanical vegetable keywords (parts of plants that are not fruits/seeds)
|
335 |
-
vegetable_keywords = [
|
336 |
-
'basil', 'lettuce', 'celery', 'broccoli', 'cabbage', 'spinach',
|
337 |
-
'kale', 'chard', 'arugula', 'parsley', 'cilantro', 'dill',
|
338 |
-
'sweet potato', 'potato', 'carrot', 'beet', 'radish', 'turnip',
|
339 |
-
'onion', 'garlic', 'leek', 'scallion', 'asparagus', 'artichoke'
|
340 |
-
]
|
341 |
-
|
342 |
-
for item in items:
|
343 |
-
item_clean = item.lower().strip()
|
344 |
-
if any(veg in item_clean for veg in vegetable_keywords):
|
345 |
-
true_vegetables.append(item.strip())
|
346 |
-
|
347 |
-
# Sort alphabetically
|
348 |
-
true_vegetables.sort()
|
349 |
-
return ', '.join(true_vegetables)
|
350 |
-
|
351 |
-
elif classification_type == "numerical":
|
352 |
-
numbers = re.findall(r'-?\d+\.?\d*', data_string)
|
353 |
-
return f"NUMBERS: {', '.join(numbers)}"
|
354 |
-
|
355 |
-
return f"CLASSIFIED_DATA: {data_string[:100]}..."
|
356 |
-
|
357 |
-
except Exception as e:
|
358 |
-
return f"Classification error: {str(e)}"
|
359 |
-
|
360 |
@tool
|
361 |
def specialized_lookup(query: str, domain: str = "general") -> str:
|
362 |
-
"""Specialized lookup tool for domain-specific information
|
363 |
-
|
364 |
-
Args:
|
365 |
-
query: Search query
|
366 |
-
domain: Domain to search in (olympics, music, sports, etc.)
|
367 |
-
|
368 |
-
Returns:
|
369 |
-
Domain-specific information
|
370 |
-
"""
|
371 |
try:
|
372 |
if domain == "olympics" or "olympics" in query.lower():
|
373 |
# Enhanced Olympics search
|
@@ -419,7 +320,6 @@ class EnhancedGAIAAgent:
|
|
419 |
youtube_video_analyzer,
|
420 |
text_manipulator,
|
421 |
mathematical_solver,
|
422 |
-
data_classifier,
|
423 |
specialized_lookup
|
424 |
]
|
425 |
|
@@ -456,8 +356,6 @@ class EnhancedGAIAAgent:
|
|
456 |
return "youtube"
|
457 |
elif "ecnetnes siht dnatsrednu uoy fi" in question_lower or any(reversed_word in question_lower for reversed_word in ["fi", "dnif", "eht"]):
|
458 |
return "reversed_text"
|
459 |
-
elif "botanical" in question_lower and "vegetable" in question_lower:
|
460 |
-
return "botanical_classification"
|
461 |
elif any(math_term in question_lower for math_term in ["commutative", "operation", "chess", "checkmate"]):
|
462 |
return "mathematical"
|
463 |
elif any(olympics_term in question_lower for olympics_term in ["olympics", "olympic", "1928", "amsterdam"]):
|
@@ -513,13 +411,6 @@ class EnhancedGAIAAgent:
|
|
513 |
|
514 |
return result
|
515 |
|
516 |
-
elif question_type == "botanical_classification":
|
517 |
-
# Extract the grocery list
|
518 |
-
food_items = re.search(r'milk.*?peanuts', question, re.IGNORECASE)
|
519 |
-
if food_items:
|
520 |
-
item_list = food_items.group(0)
|
521 |
-
return data_classifier(item_list, "botanical")
|
522 |
-
|
523 |
elif question_type == "mathematical":
|
524 |
return mathematical_solver(question)
|
525 |
|
@@ -715,103 +606,27 @@ Processing Summary:
|
|
715 |
print(error_status)
|
716 |
return error_status, pd.DataFrame(results_log)
|
717 |
|
718 |
-
# ---
|
719 |
with gr.Blocks(title="Enhanced GAIA Agent") as demo:
|
720 |
-
gr.Markdown("#
|
721 |
-
gr.Markdown(""
|
722 |
-
**Advanced Multi-Tool Agent for GAIA Benchmark**
|
723 |
-
|
724 |
-
**🛠️ Enhanced Capabilities:**
|
725 |
-
- **Advanced Web Search**: Multi-engine search with Serper API + DuckDuckGo fallback
|
726 |
-
- **Wikipedia Integration**: Comprehensive Wikipedia lookup and content extraction
|
727 |
-
- **YouTube Analysis**: Deep video content analysis and metadata extraction
|
728 |
-
- **Text Processing**: Reverse text decoding, pattern recognition, number extraction
|
729 |
-
- **Mathematical Solver**: Group theory, chess analysis, number theory problems
|
730 |
-
- **Data Classification**: Botanical classification, categorical data sorting
|
731 |
-
- **Domain Specialists**: Olympics, music, sports, scientific information lookup
|
732 |
-
|
733 |
-
**🎯 Target: 35%+ Accuracy**
|
734 |
-
|
735 |
-
**📋 Instructions:**
|
736 |
-
1. Login to your Hugging Face account using the button below
|
737 |
-
2. Click 'Run Enhanced Evaluation' to start the benchmark
|
738 |
-
3. The agent will automatically process all questions using optimal strategies
|
739 |
-
4. Results will be submitted and displayed with detailed analytics
|
740 |
-
|
741 |
-
**⏱️ Processing Time:** ~5-10 minutes depending on question complexity
|
742 |
-
""")
|
743 |
|
744 |
gr.LoginButton()
|
745 |
-
|
746 |
-
with gr.Row():
|
747 |
-
run_button = gr.Button(
|
748 |
-
"🚀 Run Enhanced Evaluation & Submit All Answers",
|
749 |
-
variant="primary",
|
750 |
-
size="lg"
|
751 |
-
)
|
752 |
-
|
753 |
-
status_output = gr.Textbox(
|
754 |
-
label="📊 Evaluation Status & Results",
|
755 |
-
lines=15,
|
756 |
-
interactive=False,
|
757 |
-
placeholder="Results will appear here after evaluation..."
|
758 |
-
)
|
759 |
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
)
|
765 |
|
766 |
-
run_button.click(
|
767 |
-
fn=run_and_submit_all,
|
768 |
-
outputs=[status_output, results_table]
|
769 |
-
)
|
770 |
|
771 |
if __name__ == "__main__":
|
772 |
-
print("
|
773 |
-
print("🚀 ENHANCED GAIA AGENT STARTING")
|
774 |
-
print("="*60)
|
775 |
|
776 |
# Environment check
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
("
|
781 |
-
("SERPER_API_KEY", "Advanced web search"),
|
782 |
-
("HUGGINGFACE_INFERENCE_TOKEN", "Model access")
|
783 |
-
]
|
784 |
-
|
785 |
-
for var_name, description in required_vars:
|
786 |
-
if os.getenv(var_name):
|
787 |
-
env_status.append(f"✅ {var_name}: Ready")
|
788 |
-
else:
|
789 |
-
env_status.append(f"❌ {var_name}: Missing ({description})")
|
790 |
|
791 |
-
|
792 |
-
for status in env_status:
|
793 |
-
print(f" {status}")
|
794 |
-
|
795 |
-
print(f"\n🎯 Target Accuracy: 35%")
|
796 |
-
print(f"🔧 Enhanced Tools: 7 specialized tools loaded")
|
797 |
-
print(f"🌐 Web Search: Serper API + DuckDuckGo fallback")
|
798 |
-
print(f"📚 Knowledge: Wikipedia + Domain specialists")
|
799 |
-
print("\n" + "="*60)
|
800 |
-
|
801 |
-
# Launch the interface
|
802 |
-
try:
|
803 |
-
demo.launch(
|
804 |
-
server_name="0.0.0.0",
|
805 |
-
server_port=7860,
|
806 |
-
share=False,
|
807 |
-
show_error=True,
|
808 |
-
quiet=False
|
809 |
-
)
|
810 |
-
except Exception as e:
|
811 |
-
print(f"❌ Error launching Gradio interface: {e}")
|
812 |
-
print("Attempting fallback launch...")
|
813 |
-
try:
|
814 |
-
demo.launch()
|
815 |
-
except Exception as fallback_error:
|
816 |
-
print(f"❌ Fallback launch failed: {fallback_error}")
|
817 |
-
exit(1)
|
|
|
21 |
|
22 |
@tool
|
23 |
def advanced_web_search(query: str, num_results: int = 10) -> str:
|
24 |
+
"""Advanced web search using multiple search engines with fallback"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
try:
|
26 |
# First try Serper API if available
|
27 |
api_key = os.getenv("SERPER_API_KEY")
|
|
|
69 |
|
70 |
@tool
|
71 |
def wikipedia_lookup(topic: str) -> str:
|
72 |
+
"""Enhanced Wikipedia search and content extraction"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
try:
|
74 |
# Clean the topic
|
75 |
topic_clean = topic.replace(" ", "_").strip()
|
|
|
116 |
|
117 |
@tool
|
118 |
def youtube_video_analyzer(url: str) -> str:
|
119 |
+
"""Advanced YouTube video analysis with multiple extraction methods"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
try:
|
121 |
# Extract video ID using multiple patterns
|
122 |
video_id = None
|
|
|
201 |
|
202 |
@tool
|
203 |
def text_manipulator(text: str, operation: str = "reverse") -> str:
|
204 |
+
"""Advanced text manipulation and analysis tool"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
try:
|
206 |
if operation == "reverse":
|
207 |
return text[::-1]
|
|
|
225 |
|
226 |
@tool
|
227 |
def mathematical_solver(problem: str) -> str:
|
228 |
+
"""Advanced mathematical problem solver with specific GAIA patterns"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
try:
|
230 |
problem_lower = problem.lower()
|
231 |
|
|
|
266 |
except Exception as e:
|
267 |
return f"Math solver error: {str(e)}"
|
268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
@tool
|
270 |
def specialized_lookup(query: str, domain: str = "general") -> str:
|
271 |
+
"""Specialized lookup tool for domain-specific information"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
try:
|
273 |
if domain == "olympics" or "olympics" in query.lower():
|
274 |
# Enhanced Olympics search
|
|
|
320 |
youtube_video_analyzer,
|
321 |
text_manipulator,
|
322 |
mathematical_solver,
|
|
|
323 |
specialized_lookup
|
324 |
]
|
325 |
|
|
|
356 |
return "youtube"
|
357 |
elif "ecnetnes siht dnatsrednu uoy fi" in question_lower or any(reversed_word in question_lower for reversed_word in ["fi", "dnif", "eht"]):
|
358 |
return "reversed_text"
|
|
|
|
|
359 |
elif any(math_term in question_lower for math_term in ["commutative", "operation", "chess", "checkmate"]):
|
360 |
return "mathematical"
|
361 |
elif any(olympics_term in question_lower for olympics_term in ["olympics", "olympic", "1928", "amsterdam"]):
|
|
|
411 |
|
412 |
return result
|
413 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
414 |
elif question_type == "mathematical":
|
415 |
return mathematical_solver(question)
|
416 |
|
|
|
606 |
print(error_status)
|
607 |
return error_status, pd.DataFrame(results_log)
|
608 |
|
609 |
+
# --- Simplified Gradio Interface ---
|
610 |
with gr.Blocks(title="Enhanced GAIA Agent") as demo:
|
611 |
+
gr.Markdown("# Enhanced GAIA Benchmark Agent")
|
612 |
+
gr.Markdown("Advanced Multi-Tool Agent with Web Search, Wikipedia, YouTube Analysis, and Domain Specialists")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
613 |
|
614 |
gr.LoginButton()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
|
616 |
+
run_button = gr.Button("Run Enhanced Evaluation & Submit All Answers", variant="primary")
|
617 |
+
|
618 |
+
status_output = gr.Textbox(label="Status & Results", lines=10, interactive=False)
|
619 |
+
results_table = gr.DataFrame(label="Question Analysis", wrap=True, interactive=False)
|
|
|
620 |
|
621 |
+
run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
|
|
|
|
|
|
|
622 |
|
623 |
if __name__ == "__main__":
|
624 |
+
print("Enhanced GAIA Agent Starting...")
|
|
|
|
|
625 |
|
626 |
# Environment check
|
627 |
+
env_vars = ["SPACE_HOST", "SPACE_ID", "SERPER_API_KEY", "HUGGINGFACE_INFERENCE_TOKEN"]
|
628 |
+
for var in env_vars:
|
629 |
+
status = "✅" if os.getenv(var) else "❌"
|
630 |
+
print(f"{status} {var}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
631 |
|
632 |
+
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|