|
|
import os |
|
|
import gradio as gr |
|
|
import requests |
|
|
import pandas as pd |
|
|
import math |
|
|
|
|
|
from smolagents import ToolCallingAgent, tool |
|
|
from smolagents.models import OpenAIServerModel |
|
|
from duckduckgo_search import DDGS |
|
|
|
|
|
|
|
|
@tool |
|
|
def web_search(query: str) -> str: |
|
|
""" |
|
|
Perform a web search using DuckDuckGo. |
|
|
|
|
|
Args: |
|
|
query (str): The search query string. |
|
|
|
|
|
Returns: |
|
|
str: A formatted string with search results. |
|
|
""" |
|
|
try: |
|
|
with DDGS() as ddgs: |
|
|
results = ddgs.text(query, max_results=3) |
|
|
return "\n\n".join( |
|
|
f"Title: {r['title']}\nContent: {r['body']}\nURL: {r['href']}" |
|
|
for r in results |
|
|
) if results else "No results found." |
|
|
except Exception as e: |
|
|
return f"Search error: {str(e)}" |
|
|
|
|
|
|
|
|
@tool |
|
|
def calculate(expression: str) -> str: |
|
|
""" |
|
|
Evaluate a mathematical expression safely. |
|
|
|
|
|
Args: |
|
|
expression (str): The math expression to evaluate. |
|
|
|
|
|
Returns: |
|
|
str: The result as a string, or an error message. |
|
|
""" |
|
|
try: |
|
|
safe_dict = {k: v for k, v in math.__dict__.items() if not k.startswith("__")} |
|
|
safe_dict.update({'abs': abs, 'round': round}) |
|
|
result = eval(expression, {"__builtins__": None}, safe_dict) |
|
|
return str(result) |
|
|
except Exception as e: |
|
|
return f"Calculation error: {str(e)}" |
|
|
|
|
|
|
|
|
class GAIAAgent: |
|
|
def __init__(self): |
|
|
model = OpenAIServerModel(model_id="gpt-3.5-turbo", api_key=os.getenv("OPENAI_API_KEY")) |
|
|
self.agent = ToolCallingAgent( |
|
|
name="GAIA_Agent", |
|
|
description="AI assistant using web_search and calculate tools.", |
|
|
tools=[web_search, calculate], |
|
|
model=model, |
|
|
) |
|
|
|
|
|
def __call__(self, question: str) -> str: |
|
|
try: |
|
|
return self.agent.run( |
|
|
question, |
|
|
planning_interval=3, |
|
|
system_prompt=( |
|
|
"You are an AI assistant. Use web_search for factual queries " |
|
|
"and calculate for math problems. Be concise and accurate." |
|
|
) |
|
|
) |
|
|
except Exception as e: |
|
|
return f"Error: {e}" |
|
|
|
|
|
|
|
|
def submit_answers(profile: gr.OAuthProfile | None): |
|
|
if not profile: |
|
|
return "Please login to Hugging Face", None |
|
|
|
|
|
agent = GAIAAgent() |
|
|
resp = requests.get("https://agents-course-unit4-scoring.hf.space/questions", timeout=20) |
|
|
questions = resp.json() or [] |
|
|
|
|
|
answers, rows = [], [] |
|
|
for item in questions[:15]: |
|
|
tid, q = item.get("task_id"), item.get("question") |
|
|
ans = agent(q) |
|
|
answers.append({"task_id": tid, "submitted_answer": ans[:1000]}) |
|
|
rows.append({"Task ID": tid, "Question": q[:100], "Answer": ans[:200]}) |
|
|
|
|
|
post = requests.post("https://agents-course-unit4-scoring.hf.space/submit", json={ |
|
|
"username": profile.username, |
|
|
"agent_code": f"https://huggingface.co/spaces/{os.getenv('SPACE_ID')}", |
|
|
"answers": answers |
|
|
}, timeout=60) |
|
|
data = post.json() |
|
|
|
|
|
out = f"Submitted {len(answers)} answers\nScore: {data.get('score', 'N/A')}%\nCorrect: {data.get('correct_count',0)}/{len(answers)}" |
|
|
return out, pd.DataFrame(rows) |
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
gr.Markdown("# GAIA Agent") |
|
|
gr.LoginButton() |
|
|
btn = gr.Button("Run Evaluation", variant="primary") |
|
|
status = gr.Textbox(label="Results") |
|
|
df = gr.DataFrame(label="Details") |
|
|
btn.click(submit_answers, outputs=[status, df]) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|