Files changed (6) hide show
  1. .gradio/certificate.pem +0 -31
  2. agent.py +0 -117
  3. app.py +5 -7
  4. gaia_agent.py +33 -0
  5. logic.py +6 -50
  6. requirements.txt +1 -6
.gradio/certificate.pem DELETED
@@ -1,31 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- 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
- 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
- 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
- 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
- ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
7
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
15
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
25
- 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
- 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
- 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
- 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
- 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
- emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
31
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
agent.py DELETED
@@ -1,117 +0,0 @@
1
- import os
2
- from pathlib import Path
3
- from typing import Optional, Union
4
-
5
- import pandas as pd
6
- from dotenv import load_dotenv
7
- from smolagents import (CodeAgent, DuckDuckGoSearchTool, FinalAnswerTool,
8
- LiteLLMModel, PythonInterpreterTool,
9
- WikipediaSearchTool)
10
- from smolagents.tools import Tool
11
- from tabulate import tabulate
12
-
13
- # Load environment variables
14
- load_dotenv()
15
-
16
- # Initialize the model
17
- model = LiteLLMModel(
18
- model_id=os.getenv("GEMINI_MODEL"), api_key=os.getenv("GEMINI_API_KEY")
19
- )
20
-
21
-
22
- class ExcelToTextTool(Tool):
23
- """Render an Excel worksheet as a Markdown table."""
24
-
25
- name = "excel_to_text"
26
- description = (
27
- "Read an Excel file and return a Markdown table of the requested sheet. "
28
- "Accepts either the sheet name or a zero-based index (as a string)."
29
- )
30
-
31
- inputs = {
32
- "excel_path": {
33
- "type": "string",
34
- "description": "Path to the Excel file (.xlsx or .xls).",
35
- },
36
- "sheet_name": {
37
- "type": "string",
38
- "description": (
39
- "Worksheet name or zero-based index (as a string). "
40
- "Optional; defaults to the first sheet."
41
- ),
42
- "nullable": True,
43
- },
44
- }
45
-
46
- output_type = "string"
47
-
48
- def forward(self, excel_path: str, sheet_name: Optional[str] = None) -> str:
49
- """Load the Excel file and return the sheet as a Markdown table.
50
-
51
- Args:
52
- excel_path: Path to the Excel file.
53
- sheet_name: Optional name or index of the sheet to read. If None, reads the first sheet.
54
-
55
- Returns:
56
- A Markdown table representing the Excel sheet, or an error message if the file is not found or cannot be read.
57
- """
58
-
59
- file_path = Path(excel_path).expanduser().resolve()
60
- if not file_path.is_file():
61
- return f"Error: Excel file not found at {file_path}"
62
-
63
- try:
64
- sheet: Union[str, int] = (
65
- int(sheet_name)
66
- if sheet_name and sheet_name.isdigit()
67
- else sheet_name or 0
68
- )
69
-
70
- df = pd.read_excel(file_path, sheet_name=sheet)
71
-
72
- if hasattr(df, "to_markdown"):
73
- return df.to_markdown(index=False)
74
-
75
- return tabulate(df, headers="keys", tablefmt="github", showindex=False)
76
-
77
- except Exception as e:
78
- return f"Error reading Excel file: {e}"
79
-
80
-
81
- class GaiaAgent:
82
- """An agent capable of using tools to answer general questions."""
83
-
84
- def __init__(self):
85
- """Initializes the GaiaAgent with a set of tools."""
86
-
87
- print("GaiaAgent initialized with tools.")
88
-
89
- tools = [
90
- DuckDuckGoSearchTool(),
91
- WikipediaSearchTool(),
92
- ExcelToTextTool(),
93
- PythonInterpreterTool(),
94
- FinalAnswerTool(),
95
- ]
96
-
97
- self.agent = CodeAgent(
98
- model=model,
99
- tools=tools,
100
- add_base_tools=True,
101
- additional_authorized_imports=["pandas", "numpy", "csv", "subprocess"],
102
- )
103
-
104
- def __call__(self, task_id: str, question: str) -> str:
105
- """Processes a question using the agent and its tools.
106
-
107
- Args:
108
- task_id: A unique identifier for the task.
109
- question: The question to be answered.
110
-
111
- Returns:
112
- The answer generated by the agent.
113
- """
114
- print(f"Agent received task_id='{task_id}' | question='{question[:50]}...'")
115
- answer = self.agent.run(question)
116
- print(f"Agent returning answer: {answer}")
117
- return answer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -1,6 +1,6 @@
1
  import os
2
 
3
- import agent
4
  import gradio as gr
5
  import logic
6
  import pandas as pd
@@ -9,9 +9,7 @@ from dotenv import load_dotenv
9
  load_dotenv()
10
 
11
 
12
- def run_and_submit_all(
13
- profile: gr.OAuthProfile | None,
14
- ) -> tuple[str, pd.DataFrame | None]:
15
  """Fetches all questions, runs the BasicAgent on them, submits all answers,
16
  and displays the results.
17
 
@@ -41,7 +39,7 @@ def run_and_submit_all(
41
 
42
  # 1. Instantiate Agent
43
  try:
44
- gaia_agent = agent.GaiaAgent()
45
  except Exception as e:
46
  print(f"Error instantiating agent: {e}")
47
  return f"Error initializing agent: {e}", None
@@ -53,7 +51,7 @@ def run_and_submit_all(
53
  return str(e), None
54
 
55
  # 3. Run the Agent
56
- results_log, answers_payload = logic.run_agent(gaia_agent, questions_data)
57
  if not answers_payload:
58
  print("Agent did not produce any answers to submit.")
59
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
@@ -138,4 +136,4 @@ if __name__ == "__main__":
138
  print("-" * (60 + len(" App Starting ")) + "\n")
139
 
140
  print("Launching Gradio Interface for Basic Agent Evaluation...")
141
- gaia_ui.launch(debug=True, share=True)
 
1
  import os
2
 
3
+ import gaia_agent
4
  import gradio as gr
5
  import logic
6
  import pandas as pd
 
9
  load_dotenv()
10
 
11
 
12
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
 
 
13
  """Fetches all questions, runs the BasicAgent on them, submits all answers,
14
  and displays the results.
15
 
 
39
 
40
  # 1. Instantiate Agent
41
  try:
42
+ agent = gaia_agent.GaiaAgent()
43
  except Exception as e:
44
  print(f"Error instantiating agent: {e}")
45
  return f"Error initializing agent: {e}", None
 
51
  return str(e), None
52
 
53
  # 3. Run the Agent
54
+ results_log, answers_payload = logic.run_agent(agent, questions_data)
55
  if not answers_payload:
56
  print("Agent did not produce any answers to submit.")
57
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
 
136
  print("-" * (60 + len(" App Starting ")) + "\n")
137
 
138
  print("Launching Gradio Interface for Basic Agent Evaluation...")
139
+ gaia_ui.launch(debug=True, share=False)
gaia_agent.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class GaiaAgent:
2
+ """
3
+ A basic agent that receives a question and returns a fixed answer.
4
+
5
+ This class serves as a placeholder or a simple baseline agent for testing
6
+ and demonstration purposes. It does not perform any sophisticated
7
+ reasoning or information retrieval.
8
+ """
9
+
10
+ def __init__(self):
11
+ """
12
+ Initializes the GaiaAgent.
13
+
14
+ Currently, this constructor simply prints a message to the console.
15
+ In a more complex implementation, this method might load a model,
16
+ connect to a database, or perform other setup tasks.
17
+ """
18
+ print("BasicAgent initialized.")
19
+
20
+ def __call__(self, question: str) -> str:
21
+ """
22
+ Processes a question and returns a fixed answer.
23
+
24
+ Args:
25
+ question: The question to be processed.
26
+
27
+ Returns:
28
+ A fixed string representing the agent's answer.
29
+ """
30
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
31
+ fixed_answer = "This is a default answer."
32
+ print(f"Agent returning fixed answer: {fixed_answer}")
33
+ return fixed_answer
logic.py CHANGED
@@ -1,17 +1,14 @@
1
  from typing import Dict, List, Tuple
2
- import re
3
- import tempfile
4
- from pathlib import Path
5
  import pandas as pd
6
  import requests
7
- from agent import GaiaAgent
8
  from pandas import DataFrame
9
 
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
  QUESTIONS_URL = f"{DEFAULT_API_URL}/questions"
13
  SUBMIT_URL = f"{DEFAULT_API_URL}/submit"
14
- FILE_PATH = f"{DEFAULT_API_URL}/files/"
15
 
16
 
17
  # --- Helper Methods ---
@@ -116,9 +113,8 @@ def submit_answers(submission_data: dict, results_log: list) -> Tuple[str, DataF
116
  return status_message, results_df
117
 
118
 
119
- def run_agent(
120
- gaia_agent: GaiaAgent, questions_data: List[Dict]
121
- ) -> Tuple[List[Dict], List[Dict]]:
122
  """Runs the agent on a list of questions and returns the results and answers.
123
 
124
  This function iterates through a list of questions, runs the provided agent on each
@@ -126,7 +122,7 @@ def run_agent(
126
  agent execution and returns the results log and the answers payload.
127
 
128
  Args:
129
- gaia_agent (GaiaAgent): An instance of the GaiaAgent class, which is responsible for
130
  generating answers to the questions.
131
  questions_data (List[Dict]): A list of dictionaries, where each dictionary
132
  represents a question and contains at least the 'task_id' and 'question' keys.
@@ -145,12 +141,11 @@ def run_agent(
145
  for item in questions_data:
146
  task_id = item.get("task_id")
147
  question_text = item.get("question")
148
- question_text = process_file(task_id, question_text)
149
  if not task_id or question_text is None:
150
  print(f"⚠️ Skipping invalid item (missing task_id or question): {item}")
151
  continue
152
  try:
153
- submitted_answer = gaia_agent(task_id, question_text)
154
  answers_payload.append(
155
  {"task_id": task_id, "submitted_answer": submitted_answer}
156
  )
@@ -166,42 +161,3 @@ def run_agent(
166
  }
167
  )
168
  return results_log, answers_payload
169
-
170
-
171
- def process_file(task_id: str, question_text: str) -> str:
172
- """
173
- Attempt to download a file associated with a task from the API.
174
-
175
- - If the file exists (HTTP 200), it is saved to a temp directory and the local file path is returned.
176
- - If no file is found (HTTP 404), returns None.
177
- - For all other HTTP errors, the exception is propagated to the caller.
178
- """
179
- file_url = f"{FILE_PATH}{task_id}"
180
-
181
- try:
182
- response = requests.get(file_url, timeout=30)
183
- response.raise_for_status()
184
- except requests.exceptions.RequestException as exc:
185
- print(f"Exception in download_file>> {str(exc)}")
186
- return question_text # Unable to get the file
187
-
188
- # Determine filename from 'Content-Disposition' header, fallback to task_id
189
- content_disposition = response.headers.get("content-disposition", "")
190
- filename = task_id
191
- match = re.search(r'filename="([^"]+)"', content_disposition)
192
- if match:
193
- filename = match.group(1)
194
-
195
- # Save file in a temp directory
196
- temp_storage_dir = Path(tempfile.gettempdir()) / "gaia_cached_files"
197
- temp_storage_dir.mkdir(parents=True, exist_ok=True)
198
-
199
- file_path = temp_storage_dir / filename
200
- file_path.write_bytes(response.content)
201
- return (
202
- f"{question_text}\n\n"
203
- f"---\n"
204
- f"A file was downloaded for this task and saved locally at:\n"
205
- f"{str(file_path)}\n"
206
- f"---\n\n"
207
- )
 
1
  from typing import Dict, List, Tuple
2
+
 
 
3
  import pandas as pd
4
  import requests
5
+ from gaia_agent import GaiaAgent
6
  from pandas import DataFrame
7
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
  QUESTIONS_URL = f"{DEFAULT_API_URL}/questions"
11
  SUBMIT_URL = f"{DEFAULT_API_URL}/submit"
 
12
 
13
 
14
  # --- Helper Methods ---
 
113
  return status_message, results_df
114
 
115
 
116
+ def run_agent(agent: GaiaAgent,
117
+ questions_data: List[Dict]) -> Tuple[List[Dict], List[Dict]]:
 
118
  """Runs the agent on a list of questions and returns the results and answers.
119
 
120
  This function iterates through a list of questions, runs the provided agent on each
 
122
  agent execution and returns the results log and the answers payload.
123
 
124
  Args:
125
+ agent (GaiaAgent): An instance of the GaiaAgent class, which is responsible for
126
  generating answers to the questions.
127
  questions_data (List[Dict]): A list of dictionaries, where each dictionary
128
  represents a question and contains at least the 'task_id' and 'question' keys.
 
141
  for item in questions_data:
142
  task_id = item.get("task_id")
143
  question_text = item.get("question")
 
144
  if not task_id or question_text is None:
145
  print(f"⚠️ Skipping invalid item (missing task_id or question): {item}")
146
  continue
147
  try:
148
+ submitted_answer = agent(question_text)
149
  answers_payload.append(
150
  {"task_id": task_id, "submitted_answer": submitted_answer}
151
  )
 
161
  }
162
  )
163
  return results_log, answers_payload
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -2,9 +2,4 @@ gradio
2
  gradio[oauth]
3
  requests
4
  python-dotenv
5
- pandas
6
- smolagents
7
- wikipedia-api
8
- google-generativeai
9
- smolagents[litellm]
10
- tabulate
 
2
  gradio[oauth]
3
  requests
4
  python-dotenv
5
+ pandas