Aakash010 commited on
Commit
a07ad75
·
verified ·
1 Parent(s): be81334

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -94
app.py CHANGED
@@ -1,48 +1,120 @@
1
-
2
  import os
 
3
  import gradio as gr
4
  import requests
5
- import inspect
6
  import pandas as pd
7
- from smolagents import CodeAgent, DuckDuckGoSearchTool,PythonInterpreterTool,OpenAIServerModel , LiteLLMModel
8
- from langchain_openai import ChatOpenAI
9
- from dotenv import load_dotenv
10
- load_dotenv()
11
- import litellm
12
- litellm._turn_on_debug()
13
- # (Keep Constants as is)
14
  # --- Constants ---
15
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
16
 
17
- # --- Basic Agent Definition ---
18
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  class BasicAgent:
20
  def __init__(self):
21
- model =OpenAIServerModel(
22
  model_id="llama-3.3-70b-versatile",
23
  api_base="https://api.groq.com/openai/v1",
24
  api_key=os.getenv("GROQ_API_KEY")
25
  )
26
- self.agent = CodeAgent(
27
  model=model,
28
- tools=[DuckDuckGoSearchTool(), PythonInterpreterTool()],
29
- verbosity_level=1
 
 
 
 
 
 
30
  )
31
 
32
- def __call__(self, question: str) -> str:
33
- return self.agent.run(question)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
 
35
 
36
- def run_and_submit_all( profile: gr.OAuthProfile | None):
37
- """
38
- Fetches all questions, runs the BasicAgent on them, submits all answers,
39
- and displays the results.
40
- """
41
- # --- Determine HF Space Runtime URL and Repo URL ---
42
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
43
 
44
  if profile:
45
- username= f"{profile.username}"
46
  print(f"User logged in: {username}")
47
  else:
48
  print("User not logged in.")
@@ -52,13 +124,13 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
52
  questions_url = f"{api_url}/questions"
53
  submit_url = f"{api_url}/submit"
54
 
55
- # 1. Instantiate Agent ( modify this part to create your agent)
56
  try:
57
  agent = BasicAgent()
58
  except Exception as e:
59
  print(f"Error instantiating agent: {e}")
60
  return f"Error initializing agent: {e}", None
61
- # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
62
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
63
  print(agent_code)
64
 
@@ -69,49 +141,48 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
69
  response.raise_for_status()
70
  questions_data = response.json()
71
  if not questions_data:
72
- print("Fetched questions list is empty.")
73
- return "Fetched questions list is empty or invalid format.", None
74
  print(f"Fetched {len(questions_data)} questions.")
75
- except requests.exceptions.RequestException as e:
76
- print(f"Error fetching questions: {e}")
77
- return f"Error fetching questions: {e}", None
78
- except requests.exceptions.JSONDecodeError as e:
79
- print(f"Error decoding JSON response from questions endpoint: {e}")
80
- print(f"Response text: {response.text[:500]}")
81
- return f"Error decoding server response for questions: {e}", None
82
  except Exception as e:
83
- print(f"An unexpected error occurred fetching questions: {e}")
84
- return f"An unexpected error occurred fetching questions: {e}", None
85
 
86
- # 3. Run your Agent
87
  results_log = []
88
  answers_payload = []
89
  print(f"Running agent on {len(questions_data)} questions...")
90
- for item in questions_data:
 
91
  task_id = item.get("task_id")
92
  question_text = item.get("question")
 
93
  if not task_id or question_text is None:
94
  print(f"Skipping item with missing task_id or question: {item}")
95
  continue
 
 
 
 
96
  try:
97
- submitted_answer = agent(question_text)
 
98
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
99
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
100
  except Exception as e:
101
- print(f"Error running agent on task {task_id}: {e}")
102
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
103
 
104
  if not answers_payload:
105
- print("Agent did not produce any answers to submit.")
106
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
107
 
108
- # 4. Prepare Submission
109
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
110
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
111
- print(status_update)
112
 
113
- # 5. Submit
114
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
115
  try:
116
  response = requests.post(submit_url, json=submission_data, timeout=60)
117
  response.raise_for_status()
@@ -124,60 +195,35 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
124
  f"Message: {result_data.get('message', 'No message received.')}"
125
  )
126
  print("Submission successful.")
127
- results_df = pd.DataFrame(results_log)
128
- return final_status, results_df
129
  except requests.exceptions.HTTPError as e:
130
  error_detail = f"Server responded with status {e.response.status_code}."
131
  try:
132
  error_json = e.response.json()
133
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
134
- except requests.exceptions.JSONDecodeError:
135
  error_detail += f" Response: {e.response.text[:500]}"
136
- status_message = f"Submission Failed: {error_detail}"
137
- print(status_message)
138
- results_df = pd.DataFrame(results_log)
139
- return status_message, results_df
140
- except requests.exceptions.Timeout:
141
- status_message = "Submission Failed: The request timed out."
142
- print(status_message)
143
- results_df = pd.DataFrame(results_log)
144
- return status_message, results_df
145
- except requests.exceptions.RequestException as e:
146
- status_message = f"Submission Failed: Network error - {e}"
147
- print(status_message)
148
- results_df = pd.DataFrame(results_log)
149
- return status_message, results_df
150
  except Exception as e:
151
- status_message = f"An unexpected error occurred during submission: {e}"
152
- print(status_message)
153
- results_df = pd.DataFrame(results_log)
154
- return status_message, results_df
155
 
 
156
 
157
- # --- Build Gradio Interface using Blocks ---
158
  with gr.Blocks() as demo:
159
- gr.Markdown("# Basic Agent Evaluation Runner")
160
  gr.Markdown(
161
  """
162
  **Instructions:**
163
-
164
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
165
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
166
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
167
-
168
- ---
169
- **Disclaimers:**
170
- Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
171
- This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a seperate action or even to answer the questions in async.
172
  """
173
  )
174
 
175
  gr.LoginButton()
176
-
177
  run_button = gr.Button("Run Evaluation & Submit All Answers")
178
-
179
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
180
- # Removed max_rows=10 from DataFrame constructor
181
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
182
 
183
  run_button.click(
@@ -187,24 +233,20 @@ with gr.Blocks() as demo:
187
 
188
  if __name__ == "__main__":
189
  print("\n" + "-"*30 + " App Starting " + "-"*30)
190
- # Check for SPACE_HOST and SPACE_ID at startup for information
191
  space_host_startup = os.getenv("SPACE_HOST")
192
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
193
 
194
  if space_host_startup:
195
  print(f"✅ SPACE_HOST found: {space_host_startup}")
196
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
197
  else:
198
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
199
 
200
- if space_id_startup: # Print repo URLs if SPACE_ID is found
201
  print(f"✅ SPACE_ID found: {space_id_startup}")
202
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
203
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
204
  else:
205
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
206
 
207
  print("-"*(60 + len(" App Starting ")) + "\n")
208
-
209
- print("Launching Gradio Interface for Basic Agent Evaluation...")
210
  demo.launch(debug=True, share=False)
 
 
1
  import os
2
+ import time
3
  import gradio as gr
4
  import requests
 
5
  import pandas as pd
6
+ from smolagents import ToolCallingAgent, OpenAIServerModel, DuckDuckGoSearchTool, PythonInterpreterTool, Tool
7
+
 
 
 
 
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
+ # --- Custom Tools ---
12
+
13
+ class WikipediaTool(Tool):
14
+ name = "wikipedia_search"
15
+ description = "Search Wikipedia and get article text. Use this when the question mentions Wikipedia or needs encyclopedic facts."
16
+ inputs = {"query": {"type": "string", "description": "The topic to search on Wikipedia"}}
17
+ output_type = "string"
18
+
19
+ def forward(self, query: str) -> str:
20
+ try:
21
+ search_url = (
22
+ f"https://en.wikipedia.org/w/api.php"
23
+ f"?action=query&titles={query.replace(' ', '_')}"
24
+ f"&prop=extracts&explaintext=true&format=json"
25
+ )
26
+ r = requests.get(search_url, timeout=10)
27
+ pages = r.json()["query"]["pages"]
28
+ page = next(iter(pages.values()))
29
+ text = page.get("extract", "No content found")
30
+ return text[:4000]
31
+ except Exception as e:
32
+ return f"Wikipedia error: {e}"
33
+
34
+
35
+ class YouTubeTranscriptTool(Tool):
36
+ name = "youtube_transcript"
37
+ description = "Gets the transcript of a YouTube video. Use when the question contains a YouTube URL or asks about video content."
38
+ inputs = {"url": {"type": "string", "description": "YouTube video URL or video ID"}}
39
+ output_type = "string"
40
+
41
+ def forward(self, url: str) -> str:
42
+ try:
43
+ from youtube_transcript_api import YouTubeTranscriptApi
44
+ if "v=" in url:
45
+ video_id = url.split("v=")[1].split("&")[0]
46
+ elif "youtu.be/" in url:
47
+ video_id = url.split("youtu.be/")[1].split("?")[0]
48
+ else:
49
+ video_id = url.strip()
50
+ transcript = YouTubeTranscriptApi.get_transcript(video_id)
51
+ return " ".join([t["text"] for t in transcript])[:4000]
52
+ except Exception as e:
53
+ return f"Transcript error: {e}"
54
+
55
+
56
+ class FileDownloadTool(Tool):
57
+ name = "download_file"
58
+ description = "Downloads a file attached to a GAIA question using its task_id. Use when the question references an attached file, image, CSV, or PDF."
59
+ inputs = {"task_id": {"type": "string", "description": "The task_id of the current question"}}
60
+ output_type = "string"
61
+
62
+ def forward(self, task_id: str) -> str:
63
+ try:
64
+ url = f"https://agents-course-unit4-scoring.hf.space/files/{task_id}"
65
+ r = requests.get(url, timeout=15)
66
+ if r.status_code == 200:
67
+ return r.text[:4000]
68
+ return f"No file found for task_id {task_id}"
69
+ except Exception as e:
70
+ return f"File download error: {e}"
71
+
72
+
73
+ # --- Agent ---
74
+
75
  class BasicAgent:
76
  def __init__(self):
77
+ model = OpenAIServerModel(
78
  model_id="llama-3.3-70b-versatile",
79
  api_base="https://api.groq.com/openai/v1",
80
  api_key=os.getenv("GROQ_API_KEY")
81
  )
82
+ self.agent = ToolCallingAgent(
83
  model=model,
84
+ tools=[
85
+ DuckDuckGoSearchTool(),
86
+ PythonInterpreterTool(),
87
+ WikipediaTool(),
88
+ YouTubeTranscriptTool(),
89
+ FileDownloadTool(),
90
+ ],
91
+ max_steps=4,
92
  )
93
 
94
+ def __call__(self, question: str, task_id: str = "") -> str:
95
+ try:
96
+ prompt = f"""Answer the following question accurately.
97
+ Return ONLY the final answer — no explanation, no punctuation, no extra words.
98
+ If the answer is a number, return just the number.
99
+ If the answer is a name, return just the name.
100
+ If the answer is a list, return comma separated values.
101
+ Task ID (use this with download_file tool if the question references a file): {task_id}
102
+
103
+ Question: {question}"""
104
+ result = self.agent.run(prompt)
105
+ return str(result)
106
+ except Exception as e:
107
+ print(f"Agent error: {e}")
108
+ return "I don't know"
109
+
110
 
111
+ # --- Main Evaluation Function ---
112
 
113
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
114
+ space_id = os.getenv("SPACE_ID")
 
 
 
 
 
115
 
116
  if profile:
117
+ username = f"{profile.username}"
118
  print(f"User logged in: {username}")
119
  else:
120
  print("User not logged in.")
 
124
  questions_url = f"{api_url}/questions"
125
  submit_url = f"{api_url}/submit"
126
 
127
+ # 1. Instantiate Agent
128
  try:
129
  agent = BasicAgent()
130
  except Exception as e:
131
  print(f"Error instantiating agent: {e}")
132
  return f"Error initializing agent: {e}", None
133
+
134
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
135
  print(agent_code)
136
 
 
141
  response.raise_for_status()
142
  questions_data = response.json()
143
  if not questions_data:
144
+ return "Fetched questions list is empty or invalid format.", None
 
145
  print(f"Fetched {len(questions_data)} questions.")
 
 
 
 
 
 
 
146
  except Exception as e:
147
+ return f"Error fetching questions: {e}", None
 
148
 
149
+ # 3. Run Agent on each question
150
  results_log = []
151
  answers_payload = []
152
  print(f"Running agent on {len(questions_data)} questions...")
153
+
154
+ for i, item in enumerate(questions_data):
155
  task_id = item.get("task_id")
156
  question_text = item.get("question")
157
+
158
  if not task_id or question_text is None:
159
  print(f"Skipping item with missing task_id or question: {item}")
160
  continue
161
+
162
+ print(f"\n[{i+1}/{len(questions_data)}] Task: {task_id}")
163
+ print(f"Question: {question_text[:100]}...")
164
+
165
  try:
166
+ submitted_answer = agent(question_text, task_id)
167
+ print(f"Answer: {submitted_answer}")
168
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
169
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
170
  except Exception as e:
171
+ print(f"Error on task {task_id}: {e}")
172
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
173
+
174
+ # Rate limit protection — Groq free tier is 6000 tokens/min
175
+ if i < len(questions_data) - 1:
176
+ print("Waiting 12s to respect rate limits...")
177
+ time.sleep(12)
178
 
179
  if not answers_payload:
 
180
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
181
 
182
+ # 4. Submit
183
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
184
+ print(f"\nSubmitting {len(answers_payload)} answers...")
 
185
 
 
 
186
  try:
187
  response = requests.post(submit_url, json=submission_data, timeout=60)
188
  response.raise_for_status()
 
195
  f"Message: {result_data.get('message', 'No message received.')}"
196
  )
197
  print("Submission successful.")
198
+ return final_status, pd.DataFrame(results_log)
 
199
  except requests.exceptions.HTTPError as e:
200
  error_detail = f"Server responded with status {e.response.status_code}."
201
  try:
202
  error_json = e.response.json()
203
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
204
+ except Exception:
205
  error_detail += f" Response: {e.response.text[:500]}"
206
+ return f"Submission Failed: {error_detail}", pd.DataFrame(results_log)
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  except Exception as e:
208
+ return f"Submission error: {e}", pd.DataFrame(results_log)
209
+
 
 
210
 
211
+ # --- Gradio UI ---
212
 
 
213
  with gr.Blocks() as demo:
214
+ gr.Markdown("# GAIA Agent Evaluation Runner")
215
  gr.Markdown(
216
  """
217
  **Instructions:**
218
+ 1. Log in to your Hugging Face account using the button below.
219
+ 2. Click 'Run Evaluation & Submit All Answers' to start.
220
+ 3. The agent will answer all 20 questions and submit. Takes ~5 minutes due to rate limits.
 
 
 
 
 
 
221
  """
222
  )
223
 
224
  gr.LoginButton()
 
225
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
226
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
227
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
228
 
229
  run_button.click(
 
233
 
234
  if __name__ == "__main__":
235
  print("\n" + "-"*30 + " App Starting " + "-"*30)
236
+
237
  space_host_startup = os.getenv("SPACE_HOST")
238
+ space_id_startup = os.getenv("SPACE_ID")
239
 
240
  if space_host_startup:
241
  print(f"✅ SPACE_HOST found: {space_host_startup}")
 
242
  else:
243
+ print("ℹ️ SPACE_HOST not found (running locally).")
244
 
245
+ if space_id_startup:
246
  print(f"✅ SPACE_ID found: {space_id_startup}")
 
 
247
  else:
248
+ print("ℹ️ SPACE_ID not found (running locally).")
249
 
250
  print("-"*(60 + len(" App Starting ")) + "\n")
251
+ print("Launching Gradio Interface...")
 
252
  demo.launch(debug=True, share=False)