Files changed (1) hide show
  1. agent.py +113 -0
agent.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Agent for the Agents Course GAIA final assignment.
3
+ This file must be named agent.py and placed in the root of your Space,
4
+ next to app.py.
5
+ """
6
+
7
+ import os
8
+ import re
9
+ import requests
10
+ from smolagents import (
11
+ CodeAgent,
12
+ DuckDuckGoSearchTool,
13
+ VisitWebpageTool,
14
+ InferenceClientModel,
15
+ tool,
16
+ )
17
+
18
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
+
20
+
21
+ @tool
22
+ def download_task_file(task_id: str) -> str:
23
+ """
24
+ Downloads the file attached to a GAIA task (if any) and saves it locally.
25
+ Use this when a question references an attached file (image, spreadsheet,
26
+ audio, etc). Returns the local file path, or an error message if there is
27
+ no file for this task.
28
+
29
+ Args:
30
+ task_id: The task_id string for the current question.
31
+ """
32
+ url = f"{DEFAULT_API_URL}/files/{task_id}"
33
+ try:
34
+ resp = requests.get(url, timeout=30)
35
+ if resp.status_code != 200:
36
+ return f"No file available for task_id {task_id} (status {resp.status_code})"
37
+ cd = resp.headers.get("content-disposition", "")
38
+ match = re.search(r'filename="?([^"]+)"?', cd)
39
+ filename = match.group(1) if match else f"{task_id}.bin"
40
+ local_path = os.path.join("/tmp", filename)
41
+ with open(local_path, "wb") as f:
42
+ f.write(resp.content)
43
+ return local_path
44
+ except Exception as e:
45
+ return f"Error downloading file: {e}"
46
+
47
+
48
+ @tool
49
+ def read_text_file(path: str) -> str:
50
+ """
51
+ Reads and returns the text content of a local file (e.g. .txt, .csv, .py).
52
+ Use this after download_task_file when the file is plain text or CSV.
53
+
54
+ Args:
55
+ path: Local filesystem path to the file.
56
+ """
57
+ try:
58
+ with open(path, "r", errors="ignore") as f:
59
+ return f.read()[:20000]
60
+ except Exception as e:
61
+ return f"Error reading file: {e}"
62
+
63
+
64
+ class BasicAgent:
65
+ def __init__(self):
66
+ print("BasicAgent initialized.")
67
+
68
+ model = InferenceClientModel(
69
+ model_id="Qwen/Qwen2.5-Coder-32B-Instruct"
70
+ )
71
+
72
+ self.agent = CodeAgent(
73
+ tools=[
74
+ DuckDuckGoSearchTool(),
75
+ VisitWebpageTool(),
76
+ download_task_file,
77
+ read_text_file,
78
+ ],
79
+ model=model,
80
+ max_steps=12,
81
+ additional_authorized_imports=["re", "itertools", "math", "statistics"],
82
+ )
83
+
84
+ def __call__(self, question: str, task_id: str = None) -> str:
85
+ print(f"Agent received question (first 80 chars): {question[:80]}...")
86
+
87
+ instructions = (
88
+ "You are answering a benchmark question that will be graded by EXACT "
89
+ "STRING MATCH. Follow these rules strictly:\n"
90
+ "1. Reply with ONLY the final answer — no explanation, no restating "
91
+ "the question, no leading phrases like 'The answer is'.\n"
92
+ "2. Do not include the words 'FINAL ANSWER' in your reply.\n"
93
+ "3. Match the exact format requested (e.g. a number with no commas "
94
+ "unless asked, a comma-separated list with no extra spaces unless "
95
+ "shown otherwise, exact capitalization/pluralization as requested).\n"
96
+ "4. If the question references an attached file, call "
97
+ f"download_task_file(task_id='{task_id}') first to fetch it, then "
98
+ "read/inspect it before answering.\n"
99
+ "5. If you are not fully sure, still give your best single-guess "
100
+ "answer in the correct format — never leave it blank or explain "
101
+ "why you're unsure.\n\n"
102
+ f"Question:\n{question}"
103
+ )
104
+
105
+ try:
106
+ answer = self.agent.run(instructions)
107
+ except Exception as e:
108
+ print(f"Agent error: {e}")
109
+ answer = ""
110
+
111
+ answer = str(answer).strip()
112
+ print(f"Agent returning answer: {answer}")
113
+ return answer