|
import os |
|
import time |
|
import gradio as gr |
|
import requests |
|
import pandas as pd |
|
|
|
from smolagents import CodeAgent, OpenAIServerModel |
|
from smolagents.tools import WebSearchTool, BaseTools |
|
|
|
|
|
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" |
|
MAX_QUESTION_LENGTH = 4000 |
|
|
|
|
|
class ReliableWebSearch(WebSearchTool): |
|
def run(self, query: str) -> str: |
|
for attempt in range(3): |
|
try: |
|
return super().run(query) |
|
except Exception as e: |
|
if "rate" in str(e).lower(): |
|
print(f"[WebSearch] Rate limit, retry {attempt+1}/3") |
|
time.sleep(2 * (attempt + 1)) |
|
else: |
|
raise |
|
raise RuntimeError("WebSearchTool failed after retries") |
|
|
|
|
|
class SmartGAIAAgent: |
|
def __init__(self): |
|
key = os.getenv("OPENAI_API_KEY") |
|
if not key: |
|
raise ValueError("Missing OPENAI_API_KEY") |
|
model = OpenAIServerModel(model_id="gpt-4", api_key=key) |
|
self.agent = CodeAgent( |
|
tools=[ReliableWebSearch()], |
|
model=model, |
|
add_base_tools=True |
|
) |
|
|
|
def __call__(self, question: str) -> str: |
|
q = question[:MAX_QUESTION_LENGTH] |
|
try: |
|
return self.agent.run(q).strip() |
|
except Exception as e: |
|
print("Agent error:", e) |
|
return "error" |
|
|
|
|
|
def run_and_submit_all(profile: gr.OAuthProfile | None): |
|
username = profile.username if profile else None |
|
if not username: |
|
return "Please Login to Hugging Face", None |
|
|
|
try: |
|
agent = SmartGAIAAgent() |
|
except Exception as e: |
|
return f"Error initializing agent: {e}", None |
|
|
|
resp = requests.get(f"{DEFAULT_API_URL}/questions", timeout=15) |
|
resp.raise_for_status() |
|
questions = resp.json() |
|
|
|
payload, logs = [], [] |
|
skip_kw = ['.mp3','.wav','.png','.jpg','youtube','video','watch','listen'] |
|
for item in questions: |
|
tid = item.get("task_id") |
|
q = item.get("question","") |
|
if not tid or not q or len(q)>MAX_QUESTION_LENGTH or any(k in q.lower() for k in skip_kw): |
|
continue |
|
ans = agent(q) |
|
payload.append({"task_id": tid, "submitted_answer": ans}) |
|
logs.append({"Task ID": tid, "Question": q, "Submitted Answer": ans}) |
|
|
|
if not payload: |
|
return "No valid questions to submit.", pd.DataFrame(logs) |
|
|
|
sub = { |
|
"username": username, |
|
"agent_code": f"https://huggingface.co/spaces/{os.getenv('SPACE_ID')}/tree/main", |
|
"answers": payload |
|
} |
|
resp = requests.post(f"{DEFAULT_API_URL}/submit", json=sub, timeout=60) |
|
resp.raise_for_status() |
|
result = resp.json() |
|
status = f"Score: {result.get('score')}% ({result.get('correct_count')}/{result.get('total_attempted')})" |
|
return status, pd.DataFrame(logs) |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# GAIA Agent") |
|
gr.LoginButton() |
|
run_btn = gr.Button("Run & Submit") |
|
status = gr.Textbox(lines=5) |
|
table = gr.DataFrame() |
|
run_btn.click(run_and_submit_all, outputs=[status, table]) |
|
|
|
if __name__ == "__main__": |
|
demo.launch(debug=True, share=False) |