OlexandrPaz commited on
Commit
ab49b6f
·
verified ·
1 Parent(s): aea4aa2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +434 -115
app.py CHANGED
@@ -1,196 +1,515 @@
1
  import os
 
2
  import gradio as gr
3
- import requests
4
- import inspect
5
  import pandas as pd
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- # (Keep Constants as is)
8
- # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
- # --- Basic Agent Definition ---
12
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
 
 
 
13
  class BasicAgent:
14
  def __init__(self):
15
- print("BasicAgent initialized.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
21
-
22
- def run_and_submit_all( profile: gr.OAuthProfile | None):
23
- """
24
- Fetches all questions, runs the BasicAgent on them, submits all answers,
25
- and displays the results.
26
- """
27
- # --- Determine HF Space Runtime URL and Repo URL ---
28
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  if profile:
31
- username= f"{profile.username}"
32
  print(f"User logged in: {username}")
33
  else:
34
  print("User not logged in.")
35
  return "Please Login to Hugging Face with the button.", None
36
 
37
  api_url = DEFAULT_API_URL
 
38
  questions_url = f"{api_url}/questions"
39
  submit_url = f"{api_url}/submit"
40
 
41
- # 1. Instantiate Agent ( modify this part to create your agent)
 
 
 
42
  try:
43
  agent = BasicAgent()
 
44
  except Exception as e:
45
  print(f"Error instantiating agent: {e}")
46
- return f"Error initializing agent: {e}", None
47
- # 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)
48
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
49
- print(agent_code)
50
 
51
- # 2. Fetch Questions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  print(f"Fetching questions from: {questions_url}")
 
53
  try:
54
- response = requests.get(questions_url, timeout=15)
 
 
 
 
55
  response.raise_for_status()
 
56
  questions_data = response.json()
 
57
  if not questions_data:
58
- print("Fetched questions list is empty.")
59
- return "Fetched questions list is empty or invalid format.", None
60
- print(f"Fetched {len(questions_data)} questions.")
 
 
 
 
 
 
61
  except requests.exceptions.RequestException as e:
 
62
  print(f"Error fetching questions: {e}")
63
- return f"Error fetching questions: {e}", None
64
- except requests.exceptions.JSONDecodeError as e:
65
- print(f"Error decoding JSON response from questions endpoint: {e}")
66
- print(f"Response text: {response.text[:500]}")
67
- return f"Error decoding server response for questions: {e}", None
 
68
  except Exception as e:
69
- print(f"An unexpected error occurred fetching questions: {e}")
70
- return f"An unexpected error occurred fetching questions: {e}", None
71
 
72
- # 3. Run your Agent
 
 
 
 
 
 
 
 
 
 
 
 
73
  results_log = []
74
  answers_payload = []
75
- print(f"Running agent on {len(questions_data)} questions...")
76
- for item in questions_data:
 
 
 
 
 
 
 
 
 
77
  task_id = item.get("task_id")
78
  question_text = item.get("question")
 
79
  if not task_id or question_text is None:
80
- print(f"Skipping item with missing task_id or question: {item}")
 
 
81
  continue
 
 
 
 
 
 
 
 
 
 
82
  try:
83
- submitted_answer = agent(question_text)
84
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
85
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
86
  except Exception as e:
87
- print(f"Error running agent on task {task_id}: {e}")
88
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  if not answers_payload:
91
- print("Agent did not produce any answers to submit.")
92
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
93
 
94
- # 4. Prepare Submission
95
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
96
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
97
- print(status_update)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
- # 5. Submit
100
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
101
  try:
102
- response = requests.post(submit_url, json=submission_data, timeout=60)
 
 
 
 
 
103
  response.raise_for_status()
 
104
  result_data = response.json()
 
105
  final_status = (
106
- f"Submission Successful!\n"
107
- f"User: {result_data.get('username')}\n"
108
- f"Overall Score: {result_data.get('score', 'N/A')}% "
109
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
110
- f"Message: {result_data.get('message', 'No message received.')}"
111
- )
112
- print("Submission successful.")
113
- results_df = pd.DataFrame(results_log)
114
- return final_status, results_df
 
 
 
 
 
 
 
 
 
 
 
115
  except requests.exceptions.HTTPError as e:
116
- error_detail = f"Server responded with status {e.response.status_code}."
 
 
 
 
 
117
  try:
118
  error_json = e.response.json()
119
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
120
- except requests.exceptions.JSONDecodeError:
121
- error_detail += f" Response: {e.response.text[:500]}"
122
- status_message = f"Submission Failed: {error_detail}"
 
 
 
 
 
 
 
 
 
 
 
 
123
  print(status_message)
124
- results_df = pd.DataFrame(results_log)
125
- return status_message, results_df
 
 
 
 
126
  except requests.exceptions.Timeout:
127
- status_message = "Submission Failed: The request timed out."
 
 
 
 
 
128
  print(status_message)
129
- results_df = pd.DataFrame(results_log)
130
- return status_message, results_df
 
 
 
 
131
  except requests.exceptions.RequestException as e:
132
- status_message = f"Submission Failed: Network error - {e}"
 
 
 
 
 
133
  print(status_message)
134
- results_df = pd.DataFrame(results_log)
135
- return status_message, results_df
 
 
 
 
136
  except Exception as e:
137
- status_message = f"An unexpected error occurred during submission: {e}"
 
 
 
 
138
  print(status_message)
139
- results_df = pd.DataFrame(results_log)
140
- return status_message, results_df
 
 
 
141
 
142
 
143
- # --- Build Gradio Interface using Blocks ---
 
 
 
144
  with gr.Blocks() as demo:
145
- gr.Markdown("# Basic Agent Evaluation Runner")
 
 
 
 
146
  gr.Markdown(
147
  """
148
- **Instructions:**
149
 
150
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
151
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
152
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
 
 
 
153
 
154
- ---
155
- **Disclaimers:**
156
- 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).
157
- 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.
158
- """
159
  )
160
 
161
  gr.LoginButton()
162
 
163
- run_button = gr.Button("Run Evaluation & Submit All Answers")
 
 
164
 
165
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
166
- # Removed max_rows=10 from DataFrame constructor
167
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
 
 
 
 
 
 
168
 
169
  run_button.click(
170
  fn=run_and_submit_all,
171
- outputs=[status_output, results_table]
 
 
 
172
  )
173
 
 
 
 
 
 
174
  if __name__ == "__main__":
175
- print("\n" + "-"*30 + " App Starting " + "-"*30)
176
- # Check for SPACE_HOST and SPACE_ID at startup for information
177
- space_host_startup = os.getenv("SPACE_HOST")
178
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
179
-
180
- if space_host_startup:
181
- print(f"✅ SPACE_HOST found: {space_host_startup}")
182
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
183
- else:
184
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
185
 
186
- if space_id_startup: # Print repo URLs if SPACE_ID is found
187
- print(f"✅ SPACE_ID found: {space_id_startup}")
188
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
189
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
190
- else:
191
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
 
 
 
 
 
 
 
192
 
193
- print("-"*(60 + len(" App Starting ")) + "\n")
194
 
195
- print("Launching Gradio Interface for Basic Agent Evaluation...")
196
- demo.launch(debug=True, share=False)
 
 
 
1
  import os
2
+
3
  import gradio as gr
 
 
4
  import pandas as pd
5
+ import requests
6
+
7
+ from smolagents import (
8
+ CodeAgent,
9
+ DuckDuckGoSearchTool,
10
+ InferenceClientModel,
11
+ )
12
+
13
+
14
+ # ---------------------------------------------------------
15
+ # Configuration
16
+ # ---------------------------------------------------------
17
 
 
 
18
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
19
 
20
+
21
+ # ---------------------------------------------------------
22
+ # Agent
23
+ # ---------------------------------------------------------
24
+
25
  class BasicAgent:
26
  def __init__(self):
27
+ print("Initializing GAIA agent...")
28
+
29
+ hf_token = os.getenv("HF_TOKEN")
30
+
31
+ if not hf_token:
32
+ raise RuntimeError(
33
+ "HF_TOKEN is missing. "
34
+ "Add it in Space -> Settings -> Variables and secrets."
35
+ )
36
+
37
+ self.model = InferenceClientModel(
38
+ token=hf_token
39
+ )
40
+
41
+ self.agent = CodeAgent(
42
+ tools=[
43
+ DuckDuckGoSearchTool(),
44
+ ],
45
+ model=self.model,
46
+ additional_authorized_imports=[
47
+ "requests",
48
+ "re",
49
+ "json",
50
+ "math",
51
+ "datetime",
52
+ "statistics",
53
+ "collections",
54
+ "itertools",
55
+ ],
56
+ max_steps=12,
57
+ )
58
+
59
+ print("GAIA agent initialized successfully.")
60
+
61
  def __call__(self, question: str) -> str:
62
+ print("\n" + "=" * 80)
63
+ print("QUESTION:")
64
+ print(question)
65
+ print("=" * 80)
66
+
67
+ prompt = f"""
68
+ You are an autonomous agent solving a GAIA benchmark question.
69
+
70
+ Your objective is to determine the exact final answer.
71
+
72
+ You may use:
73
+ - web search
74
+ - Python/code
75
+ - HTTP requests
76
+ - calculations
77
+ - text processing
78
+
79
+ Instructions:
80
+
81
+ 1. Read the question extremely carefully.
82
+
83
+ 2. Determine whether the answer can be derived directly or whether
84
+ external research is necessary.
85
+
86
+ 3. When current or factual information is required, use web search.
87
+
88
+ 4. When calculations, transformations, counting, decoding, reversing
89
+ text, parsing, or similar operations are required, use Python.
90
+
91
+ 5. Verify important facts whenever possible.
92
+
93
+ 6. Pay very close attention to requested formatting.
94
+
95
+ 7. The final response MUST contain ONLY the answer.
96
+
97
+ Do NOT include:
98
+ - explanations
99
+ - reasoning
100
+ - citations
101
+ - "FINAL ANSWER:"
102
+ - introductory text
103
+
104
+ Examples of valid final responses:
105
+
106
+ 7
107
+
108
+ Mercedes Sosa
109
+
110
+ Paris
111
+
112
+ 12, 15, 18
113
+
114
+ The answer should be as short and exact as possible.
115
+
116
+ QUESTION:
117
+
118
+ {question}
119
+ """
120
+
121
+ try:
122
+ result = self.agent.run(prompt)
123
+
124
+ answer = str(result).strip()
125
+
126
+ # Some models may still prepend FINAL ANSWER.
127
+ prefixes = [
128
+ "FINAL ANSWER:",
129
+ "Final Answer:",
130
+ "Final answer:",
131
+ ]
132
+
133
+ for prefix in prefixes:
134
+ if answer.startswith(prefix):
135
+ answer = answer[len(prefix):].strip()
136
+
137
+ print("\nAGENT FINAL ANSWER:")
138
+ print(answer)
139
+
140
+ return answer
141
+
142
+ except Exception as e:
143
+ print(f"Agent error: {e}")
144
+ return ""
145
+
146
+
147
+ # ---------------------------------------------------------
148
+ # Evaluation
149
+ # ---------------------------------------------------------
150
+
151
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
152
+
153
+ space_id = os.getenv("SPACE_ID")
154
 
155
  if profile:
156
+ username = f"{profile.username}"
157
  print(f"User logged in: {username}")
158
  else:
159
  print("User not logged in.")
160
  return "Please Login to Hugging Face with the button.", None
161
 
162
  api_url = DEFAULT_API_URL
163
+
164
  questions_url = f"{api_url}/questions"
165
  submit_url = f"{api_url}/submit"
166
 
167
+ # -----------------------------------------------------
168
+ # Initialize agent
169
+ # -----------------------------------------------------
170
+
171
  try:
172
  agent = BasicAgent()
173
+
174
  except Exception as e:
175
  print(f"Error instantiating agent: {e}")
 
 
 
 
176
 
177
+ return (
178
+ f"Error initializing agent: {e}",
179
+ None,
180
+ )
181
+
182
+ # Public link to your agent source code
183
+ agent_code = (
184
+ f"https://huggingface.co/spaces/"
185
+ f"{space_id}/tree/main"
186
+ )
187
+
188
+ print(f"Agent code: {agent_code}")
189
+
190
+ # -----------------------------------------------------
191
+ # Fetch questions
192
+ # -----------------------------------------------------
193
+
194
  print(f"Fetching questions from: {questions_url}")
195
+
196
  try:
197
+ response = requests.get(
198
+ questions_url,
199
+ timeout=30,
200
+ )
201
+
202
  response.raise_for_status()
203
+
204
  questions_data = response.json()
205
+
206
  if not questions_data:
207
+ return (
208
+ "Fetched questions list is empty or invalid.",
209
+ None,
210
+ )
211
+
212
+ print(
213
+ f"Fetched {len(questions_data)} questions."
214
+ )
215
+
216
  except requests.exceptions.RequestException as e:
217
+
218
  print(f"Error fetching questions: {e}")
219
+
220
+ return (
221
+ f"Error fetching questions: {e}",
222
+ None,
223
+ )
224
+
225
  except Exception as e:
 
 
226
 
227
+ print(
228
+ f"Unexpected error fetching questions: {e}"
229
+ )
230
+
231
+ return (
232
+ f"Unexpected error fetching questions: {e}",
233
+ None,
234
+ )
235
+
236
+ # -----------------------------------------------------
237
+ # Run agent
238
+ # -----------------------------------------------------
239
+
240
  results_log = []
241
  answers_payload = []
242
+
243
+ print(
244
+ f"Running agent on "
245
+ f"{len(questions_data)} questions..."
246
+ )
247
+
248
+ for index, item in enumerate(
249
+ questions_data,
250
+ start=1,
251
+ ):
252
+
253
  task_id = item.get("task_id")
254
  question_text = item.get("question")
255
+
256
  if not task_id or question_text is None:
257
+ print(
258
+ f"Skipping invalid question: {item}"
259
+ )
260
  continue
261
+
262
+ print("\n" + "#" * 80)
263
+
264
+ print(
265
+ f"QUESTION "
266
+ f"{index}/{len(questions_data)}"
267
+ )
268
+
269
+ print(f"Task ID: {task_id}")
270
+
271
  try:
272
+ submitted_answer = agent(
273
+ question_text
274
+ )
275
+
276
  except Exception as e:
277
+
278
+ print(
279
+ f"Error running agent on "
280
+ f"{task_id}: {e}"
281
+ )
282
+
283
+ submitted_answer = ""
284
+
285
+ answers_payload.append(
286
+ {
287
+ "task_id": task_id,
288
+ "submitted_answer":
289
+ submitted_answer,
290
+ }
291
+ )
292
+
293
+ results_log.append(
294
+ {
295
+ "Task ID": task_id,
296
+ "Question": question_text,
297
+ "Submitted Answer":
298
+ submitted_answer,
299
+ }
300
+ )
301
+
302
+ # -----------------------------------------------------
303
+ # Ensure answers exist
304
+ # -----------------------------------------------------
305
 
306
  if not answers_payload:
 
 
307
 
308
+ return (
309
+ "Agent did not produce any answers.",
310
+ pd.DataFrame(results_log),
311
+ )
312
+
313
+ # -----------------------------------------------------
314
+ # Submission payload
315
+ # -----------------------------------------------------
316
+
317
+ submission_data = {
318
+ "username": username.strip(),
319
+ "agent_code": agent_code,
320
+ "answers": answers_payload,
321
+ }
322
+
323
+ print(
324
+ f"Agent finished. Submitting "
325
+ f"{len(answers_payload)} answers "
326
+ f"for user '{username}'..."
327
+ )
328
+
329
+ # -----------------------------------------------------
330
+ # Submit
331
+ # -----------------------------------------------------
332
 
 
 
333
  try:
334
+ response = requests.post(
335
+ submit_url,
336
+ json=submission_data,
337
+ timeout=120,
338
+ )
339
+
340
  response.raise_for_status()
341
+
342
  result_data = response.json()
343
+
344
  final_status = (
345
+ "Submission Successful!\n"
346
+ f"User: "
347
+ f"{result_data.get('username')}\n"
348
+ f"Overall Score: "
349
+ f"{result_data.get('score', 'N/A')}% "
350
+ f"("
351
+ f"{result_data.get('correct_count', '?')}/"
352
+ f"{result_data.get('total_attempted', '?')}"
353
+ f" correct)\n"
354
+ f"Message: "
355
+ f"{result_data.get('message', 'No message received.')}"
356
+ )
357
+
358
+ print(final_status)
359
+
360
+ return (
361
+ final_status,
362
+ pd.DataFrame(results_log),
363
+ )
364
+
365
  except requests.exceptions.HTTPError as e:
366
+
367
+ error_detail = (
368
+ f"Server responded with status "
369
+ f"{e.response.status_code}."
370
+ )
371
+
372
  try:
373
  error_json = e.response.json()
374
+
375
+ error_detail += (
376
+ f" Detail: "
377
+ f"{error_json.get('detail', e.response.text)}"
378
+ )
379
+
380
+ except Exception:
381
+ error_detail += (
382
+ f" Response: "
383
+ f"{e.response.text[:500]}"
384
+ )
385
+
386
+ status_message = (
387
+ f"Submission Failed: {error_detail}"
388
+ )
389
+
390
  print(status_message)
391
+
392
+ return (
393
+ status_message,
394
+ pd.DataFrame(results_log),
395
+ )
396
+
397
  except requests.exceptions.Timeout:
398
+
399
+ status_message = (
400
+ "Submission Failed: "
401
+ "The request timed out."
402
+ )
403
+
404
  print(status_message)
405
+
406
+ return (
407
+ status_message,
408
+ pd.DataFrame(results_log),
409
+ )
410
+
411
  except requests.exceptions.RequestException as e:
412
+
413
+ status_message = (
414
+ f"Submission Failed: "
415
+ f"Network error - {e}"
416
+ )
417
+
418
  print(status_message)
419
+
420
+ return (
421
+ status_message,
422
+ pd.DataFrame(results_log),
423
+ )
424
+
425
  except Exception as e:
426
+
427
+ status_message = (
428
+ f"Unexpected submission error: {e}"
429
+ )
430
+
431
  print(status_message)
432
+
433
+ return (
434
+ status_message,
435
+ pd.DataFrame(results_log),
436
+ )
437
 
438
 
439
+ # ---------------------------------------------------------
440
+ # Gradio UI
441
+ # ---------------------------------------------------------
442
+
443
  with gr.Blocks() as demo:
444
+
445
+ gr.Markdown(
446
+ "# GAIA Agent Evaluation Runner"
447
+ )
448
+
449
  gr.Markdown(
450
  """
451
+ ### Instructions
452
 
453
+ 1. Log in with your Hugging Face account.
454
+ 2. Click **Run Evaluation & Submit All Answers**.
455
+ 3. The agent will fetch the GAIA questions.
456
+ 4. It will solve each question.
457
+ 5. Answers will automatically be submitted.
458
+ 6. Your score will appear below.
459
 
460
+ The evaluation can take several minutes.
461
+ """
 
 
 
462
  )
463
 
464
  gr.LoginButton()
465
 
466
+ run_button = gr.Button(
467
+ "Run Evaluation & Submit All Answers"
468
+ )
469
 
470
+ status_output = gr.Textbox(
471
+ label="Run Status / Submission Result",
472
+ lines=6,
473
+ interactive=False,
474
+ )
475
+
476
+ results_table = gr.DataFrame(
477
+ label="Questions and Agent Answers",
478
+ wrap=True,
479
+ )
480
 
481
  run_button.click(
482
  fn=run_and_submit_all,
483
+ outputs=[
484
+ status_output,
485
+ results_table,
486
+ ],
487
  )
488
 
489
+
490
+ # ---------------------------------------------------------
491
+ # Start
492
+ # ---------------------------------------------------------
493
+
494
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
495
 
496
+ print("\n" + "=" * 80)
497
+
498
+ print("Starting GAIA Agent Space")
499
+
500
+ print(
501
+ f"SPACE_ID: "
502
+ f"{os.getenv('SPACE_ID', 'not found')}"
503
+ )
504
+
505
+ print(
506
+ f"SPACE_HOST: "
507
+ f"{os.getenv('SPACE_HOST', 'not found')}"
508
+ )
509
 
510
+ print("=" * 80 + "\n")
511
 
512
+ demo.launch(
513
+ debug=True,
514
+ share=False,
515
+ )