| |
| |
| |
| |
| |
| |
| |
| |
| FINAL ANSWER: |
| |
| |
| |
| |
| |
| |
| hflitellm |
| Qwen/Qwen2.5-Coder-32B-Instruct |
| gpt-4oanthropic/claude-sonnet-4-5 |
| |
| |
| |
|
|
| import os |
| import io |
| import re |
| import json |
| import tempfile |
|
|
| import requests |
| import pandas as pd |
| import gradio as gr |
|
|
| from smolagents import ( |
| CodeAgent, |
| InferenceClientModel, |
| LiteLLMModel, |
| DuckDuckGoSearchTool, |
| WikipediaSearchTool, |
| VisitWebpageTool, |
| ) |
|
|
| DEFAULT_API_URL = |
| JSONL_PATH = |
|
|
| # Official GAIA system prompt (from the paper / leaderboard). |
| GAIA_SYSTEM_PROMPT = ( |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ) |
|
|
|
|
| # --------------------------------------------------------------------------- # |
| # Model selection |
| # --------------------------------------------------------------------------- # |
| def build_model(): |
| provider = os.getenv(, ).lower() |
| model_id = os.getenv(, ) |
|
|
| if provider == : |
| return LiteLLMModel( |
| model_id=model_id, |
| api_key=os.getenv() or os.getenv(), |
| temperature=0.0, |
| ) |
|
|
| kwargs = {: model_id, : 0.0} |
| hf_provider = os.getenv() # e.g. , |
| if hf_provider: |
| kwargs[] = hf_provider |
| token = os.getenv() |
| if token: |
| kwargs[] = token |
| return InferenceClientModel(**kwargs) |
|
|
|
|
| # --------------------------------------------------------------------------- # |
| # File handling: download a task's attachment and extract usable text |
| # --------------------------------------------------------------------------- # |
| def fetch_file_text(api_url: str, task_id: str, file_name: str) -> str: |
| url = f"{api_url}/files/{task_id}" |
| try: |
| r = requests.get(url, timeout=60) |
| r.raise_for_status() |
| except Exception as e: |
| return f"[Could not download attached file '{file_name}': {e}]" |
| |
| data = r.content |
| ext = file_name.lower().rsplit(".", 1)[-1] if "." in file_name else "" |
| |
| try: |
| if ext in ("txt", "py", "md", "json", "xml", "csv", "tsv"): |
| text = data.decode("utf-8", errors="replace") |
| if ext == "csv": |
| df = pd.read_csv(io.StringIO(text)) |
| return f"CSV file '{file_name}' content:\n{df.to_string()}" |
| if ext == "tsv": |
| df = pd.read_csv(io.StringIO(text), sep="\t") |
| return f"TSV file '{file_name}' content:\n{df.to_string()}" |
| return f"File '{file_name}' content:\n{text}" |
| |
| if ext in ("xlsx", "xls"): |
| sheets = pd.read_excel(io.BytesIO(data), sheet_name=None) |
| parts = [f"Excel file '{file_name}':"] |
| for name, df in sheets.items(): |
| parts.append(f"--- sheet: {name} ---\n{df.to_string()}") |
| return "\n".join(parts) |
| |
| if ext == "pdf": |
| import pdfplumber |
| with pdfplumber.open(io.BytesIO(data)) as pdf: |
| pages = [p.extract_text() or "" for p in pdf.pages] |
| return f"PDF file '{file_name}' text:\n" + "\n".join(pages) |
| |
| if ext == "docx": |
| import docx |
| tmp = os.path.join(tempfile.gettempdir(), file_name) |
| with open(tmp, "wb") as f: |
| f.write(data) |
| doc = docx.Document(tmp) |
| return f"Word file '{file_name}':\n" + "\n".join( |
| p.text for p in doc.paragraphs |
| ) |
| |
| tmp = os.path.join(tempfile.gettempdir(), file_name) |
| with open(tmp, "wb") as f: |
| f.write(data) |
| return ( |
| f"[A file named '{file_name}' is attached and saved locally at '{tmp}'. " |
| f"Use your tools / Python to inspect it if the question needs it.]" |
| ) |
| except Exception as e: |
| return f"[Attached file '{file_name}' could not be parsed: {e}]" |
| |
| |
| # --------------------------------------------------------------------------- # |
| # Answer extraction / normalization |
| # --------------------------------------------------------------------------- # |
| def extract_answer(raw: str) -> str: |
| """Take the text after the last 'FINAL ANSWER:' if present, then normalize.""" |
| text = str(raw).strip() |
| matches = list(re.finditer(r"final answer\s*:", text, flags=re.IGNORECASE)) |
| if matches: |
| text = text[matches[-1].end():].strip() |
| # collapse to first line (the answer should be a single line) |
| text = text.splitlines()[0].strip() if text else text |
| # strip wrapping quotes / brackets |
| if len(text) >= 2 and text[0] == text[-1] and text[0] in ("''): |
| text = text[1:-1].strip() |
| # drop a trailing period unless it is part of a number |
| if text.endswith(".") and not re.fullmatch(r"[\d.]+", text): |
| text = text[:-1].strip() |
| return text |
| |
| |
| # --------------------------------------------------------------------------- # |
| # The agent |
| # --------------------------------------------------------------------------- # |
| class GaiaAgent: |
| def __init__(self, api_url: str = DEFAULT_API_URL): |
| self.api_url = api_url |
| model = build_model() |
| tools = [ |
| DuckDuckGoSearchTool(), |
| VisitWebpageTool(), |
| WikipediaSearchTool(user_agent="GAIA-course-agent (student@example.com)"), |
| ] |
| self.agent = CodeAgent( |
| tools=tools, |
| model=model, |
| add_base_tools=True, # python interpreter + transcriber |
| additional_authorized_imports=[ |
| "pandas", "numpy", "math", "statistics", |
| "json", "re", "datetime", "itertools", |
| ], |
| max_steps=10, |
| verbosity_level=1, |
| ) |
| print("GaiaAgent ready.") |
| |
| def _reasoning_trace(self) -> str: |
| """Reconstruct a compact trace from the agent's memory of the last run. |
| |
| |
| steps |
| model_output |
| |
| |
| observations |
| |
| Observation: |
| \n |
| |
| |
| |
| |
| Returns (answer, reasoning_trace). |
| |
| |
| \n\nWhen you call final_answer, pass ONLY the value that should |
| follow 'FINAL ANSWER:', formatted by the rules above.\n\nQUESTION:\n |
| |
| |
| |
| \n\n |
| |
| |
| |
| |
| Agent error on task {task_id}: {e} |
| unknownerror: {e} |
| |
| |
| |
| |
| |
| |
| SPACE_ID |
| |
| |
| |
| User logged in: {username} |
| |
| Please Login to Hugging Face with the button. |
| |
| |
| {api_url}/questions |
| {api_url}/submit |
| |
| |
| |
| |
| Error initializing agent: {e} |
| |
| |
| https://huggingface.co/spaces/{space_id}/tree/mainlocal |
| |
| |
| |
| |
| |
| |
| |
| Fetched questions list is empty. |
| |
| Error fetching questions: {e} |
| |
| |
| |
| |
| |
| |
| task_id |
| question |
| file_name |
| |
| |
| Running task {task_id} ... |
| |
| |
| |
| task_idsubmitted_answer |
| |
| |
| task_idmodel_answerreasoning_trace |
| |
| |
| Task IDQuestionSubmitted Answer |
| |
| |
| |
| |
| wutf-8 |
| |
| \n |
| |
| |
| Could not write jsonl: {e} |
| |
| |
| |
| Agent produced no answers. |
| |
| |
| username |
| agent_code |
| answers |
| |
| |
| |
| |
| |
| |
| |
| Submission Successful!\n |
| User: {data.get('username')}\n |
| Score: {data.get('score', 'N/A')}% |
| ({data.get('correct_count', '?')}/ |
| {data.get('total_attempted', '?')} correct)\n |
| Message: {data.get('message', '')} |
| |
| |
| |
| Submission Failed: {e} |
| |
| |
| |
| |
| |
| |
| # GAIA Agent — Final Assignment |
| |
| 1. Log in with Hugging Face below.\n |
| 2. Click **Run Evaluation & Submit All Answers**.\n\n |
| This submits to the course leaderboard AND produces a |
| `gaia_submission.jsonl` file in the official GAIA format for download. |
| Running all questions can take several minutes. |
| |
| |
| Run Evaluation & Submit All Answers |
| |
| Run Status / Submission Result |
| |
| Questions and Agent Answers |
| Official GAIA submission (.jsonl) |
| |
| |
| |
| |
| |
| |
| __main__ |
| |