Viske commited on
Commit
817c39e
·
verified ·
1 Parent(s): 81917a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +613 -167
app.py CHANGED
@@ -1,196 +1,642 @@
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
+ import json
3
+ import re
4
+
5
  import gradio as gr
 
 
6
  import pandas as pd
7
 
8
+ from huggingface_hub import InferenceClient
9
+
10
+ from prompt import SYSTEM_PROMPT
11
+
12
+ from tools import (
13
+ execute_tool,
14
+ download_file
15
+ )
16
+
17
+ import requests
18
+
19
+
20
+ # ============================================================
21
+ # CONFIG
22
+ # ============================================================
23
+
24
+ SCORING_API = (
25
+ "https://agents-course-unit4-scoring.hf.space"
26
+ )
27
+
28
+ MODEL_ID = os.getenv(
29
+ "TEXT_MODEL",
30
+ "Qwen/Qwen2.5-72B-Instruct"
31
+ )
32
+
33
+ HF_TOKEN = os.getenv("HF_TOKEN")
34
+
35
+ MAX_STEPS = 10
36
+
37
+
38
+ client = InferenceClient(
39
+ token=HF_TOKEN
40
+ )
41
+
42
+
43
+ # ============================================================
44
+ # ANSWER CLEANING
45
+ # ============================================================
46
+
47
+ def clean_answer(answer):
48
+
49
+ answer = str(answer).strip()
50
+
51
+ # Remove markdown code fences.
52
+ answer = re.sub(
53
+ r"^```(?:text)?\s*",
54
+ "",
55
+ answer,
56
+ flags=re.IGNORECASE
57
+ )
58
+
59
+ answer = re.sub(
60
+ r"\s*```$",
61
+ "",
62
+ answer
63
+ )
64
+
65
+ # Remove accidental prefixes.
66
+ answer = re.sub(
67
+ r"^\s*FINAL ANSWER\s*:?\s*",
68
+ "",
69
+ answer,
70
+ flags=re.IGNORECASE
71
+ )
72
+
73
+ answer = re.sub(
74
+ r"^\s*THE ANSWER IS\s*:?\s*",
75
+ "",
76
+ answer,
77
+ flags=re.IGNORECASE
78
+ )
79
+
80
+ return answer.strip()
81
+
82
+
83
+ # ============================================================
84
+ # MODEL CALL
85
+ # ============================================================
86
+
87
+ def call_model(messages):
88
+
89
+ response = client.chat.completions.create(
90
+ model=MODEL_ID,
91
+ messages=messages,
92
+ max_tokens=1200,
93
+ temperature=0
94
+ )
95
+
96
+ return response.choices[0].message.content
97
+
98
+
99
+ # ============================================================
100
+ # AGENT
101
+ # ============================================================
102
+
103
+ def solve_question(
104
+ task_id,
105
+ question
106
+ ):
107
+
108
+ messages = [
109
+ {
110
+ "role": "system",
111
+ "content": SYSTEM_PROMPT
112
+ },
113
+ {
114
+ "role": "user",
115
+ "content": (
116
+ f"GAIA TASK ID: {task_id}\n\n"
117
+ f"QUESTION:\n{question}\n\n"
118
+ "Solve this question."
119
+ )
120
+ }
121
+ ]
122
+
123
+ # Cache downloaded attachment path if needed.
124
+ attachment_path = None
125
+
126
+ for step in range(MAX_STEPS):
127
+
128
+ print(
129
+ f" Agent step {step + 1}/{MAX_STEPS}"
130
+ )
131
+
132
+ raw = call_model(messages)
133
+
134
+ print(
135
+ f" Model: {raw[:500]}"
136
+ )
137
+
138
+ # ----------------------------------------------------
139
+ # Parse JSON
140
+ # ----------------------------------------------------
141
+
142
+ try:
143
+
144
+ decision = json.loads(
145
+ raw.strip()
146
+ )
147
+
148
+ except json.JSONDecodeError:
149
+
150
+ # Sometimes models put JSON inside markdown.
151
+ match = re.search(
152
+ r"\{.*\}",
153
+ raw,
154
+ re.DOTALL
155
+ )
156
+
157
+ if match:
158
+
159
+ try:
160
+ decision = json.loads(
161
+ match.group(0)
162
+ )
163
+
164
+ except json.JSONDecodeError:
165
+ decision = None
166
+
167
+ else:
168
+ decision = None
169
+
170
+ # ----------------------------------------------------
171
+ # Invalid model response
172
+ # ----------------------------------------------------
173
+
174
+ if not decision:
175
+
176
+ messages.append({
177
+ "role": "assistant",
178
+ "content": raw
179
+ })
180
+
181
+ messages.append({
182
+ "role": "user",
183
+ "content": (
184
+ "Your response was not valid JSON.\n"
185
+ "Return ONLY one of these formats:\n\n"
186
+ '{"action":"tool","tool":"TOOL_NAME","input":"..."}\n'
187
+ '{"action":"final","answer":"..."}'
188
+ )
189
+ })
190
+
191
+ continue
192
+
193
+ # ----------------------------------------------------
194
+ # FINAL ANSWER
195
+ # ----------------------------------------------------
196
+
197
+ if decision.get("action") == "final":
198
+
199
+ answer = decision.get(
200
+ "answer",
201
+ ""
202
+ )
203
+
204
+ return clean_answer(
205
+ answer
206
+ )
207
+
208
+ # ----------------------------------------------------
209
+ # TOOL CALL
210
+ # ----------------------------------------------------
211
+
212
+ if decision.get("action") == "tool":
213
+
214
+ tool_name = decision.get(
215
+ "tool"
216
+ )
217
+
218
+ tool_input = decision.get(
219
+ "input",
220
+ ""
221
+ )
222
+
223
+ # -----------------------------------------------
224
+ # Automatically download attachment
225
+ # -----------------------------------------------
226
+
227
+ if (
228
+ tool_name == "download_file"
229
+ and not attachment_path
230
+ ):
231
+
232
+ attachment_path = (
233
+ download_file(task_id)
234
+ )
235
+
236
+ tool_result = (
237
+ f"FILE_PATH:\n"
238
+ f"{attachment_path}\n\n"
239
+ f"The file has been downloaded."
240
+ )
241
+
242
+ # -----------------------------------------------
243
+ # Inspect downloaded file
244
+ # -----------------------------------------------
245
+
246
+ elif (
247
+ tool_name == "inspect_file"
248
+ and tool_input == "CURRENT_FILE"
249
+ ):
250
+
251
+ if not attachment_path:
252
+
253
+ attachment_path = (
254
+ download_file(task_id)
255
+ )
256
+
257
+ tool_result = execute_tool(
258
+ "inspect_file",
259
+ attachment_path,
260
+ task_id,
261
+ question
262
+ )
263
+
264
+ # -----------------------------------------------
265
+ # Audio
266
+ # -----------------------------------------------
267
+
268
+ elif (
269
+ tool_name == "transcribe_audio"
270
+ and tool_input == "CURRENT_FILE"
271
+ ):
272
+
273
+ if not attachment_path:
274
+
275
+ attachment_path = (
276
+ download_file(task_id)
277
+ )
278
+
279
+ tool_result = execute_tool(
280
+ "transcribe_audio",
281
+ attachment_path,
282
+ task_id,
283
+ question
284
+ )
285
+
286
+ # -----------------------------------------------
287
+ # Image
288
+ # -----------------------------------------------
289
+
290
+ elif (
291
+ tool_name == "analyze_image"
292
+ and tool_input == "CURRENT_FILE"
293
+ ):
294
+
295
+ if not attachment_path:
296
+
297
+ attachment_path = (
298
+ download_file(task_id)
299
+ )
300
+
301
+ tool_result = execute_tool(
302
+ "analyze_image",
303
+ attachment_path,
304
+ task_id,
305
+ question
306
+ )
307
+
308
+ # -----------------------------------------------
309
+ # Normal tool
310
+ # -----------------------------------------------
311
+
312
+ else:
313
+
314
+ tool_result = execute_tool(
315
+ tool_name,
316
+ tool_input,
317
+ task_id,
318
+ question
319
+ )
320
+
321
+ # Don't let huge tool outputs destroy context.
322
+ tool_result = str(
323
+ tool_result
324
+ )[:40000]
325
+
326
+ messages.append({
327
+ "role": "assistant",
328
+ "content": raw
329
+ })
330
+
331
+ messages.append({
332
+ "role": "user",
333
+ "content": (
334
+ f"TOOL RESULT ({tool_name}):\n"
335
+ f"{tool_result}\n\n"
336
+ "Continue solving the original question. "
337
+ "Use another tool if necessary, otherwise "
338
+ "return the final JSON answer."
339
+ )
340
+ })
341
+
342
+ continue
343
+
344
+ return "Unable to determine the answer."
345
+
346
+
347
+ # ============================================================
348
+ # FETCH QUESTIONS
349
+ # ============================================================
350
+
351
+ def get_questions():
352
+
353
+ response = requests.get(
354
+ f"{SCORING_API}/questions",
355
+ timeout=30
356
+ )
357
+
358
+ response.raise_for_status()
359
+
360
+ return response.json()
361
+
362
+
363
+ # ============================================================
364
+ # SUBMIT
365
+ # ============================================================
366
+
367
+ def submit(
368
+ username,
369
+ agent_code,
370
+ answers
371
+ ):
372
+
373
+ payload = {
374
+ "username": username,
375
+ "agent_code": agent_code,
376
+ "answers": answers
377
+ }
378
+
379
+ response = requests.post(
380
+ f"{SCORING_API}/submit",
381
+ json=payload,
382
+ timeout=180
383
+ )
384
+
385
+ response.raise_for_status()
386
+
387
+ return response.json()
388
+
389
+
390
+ # ============================================================
391
+ # MAIN EVALUATION
392
+ # ============================================================
393
+
394
+ def run_and_submit_all(
395
+ profile: gr.OAuthProfile | None
396
+ ):
397
+
398
+ if profile is None:
399
+
400
+ return (
401
+ "Please login to Hugging Face.",
402
+ None
403
+ )
404
+
405
+ username = profile.username
406
+
407
+ space_id = os.getenv(
408
+ "SPACE_ID"
409
+ )
410
+
411
+ if not space_id:
412
+
413
+ return (
414
+ "SPACE_ID was not found.",
415
+ None
416
+ )
417
+
418
+ agent_code = (
419
+ "https://huggingface.co/spaces/"
420
+ f"{space_id}/tree/main"
421
+ )
422
+
423
+ print("=" * 70)
424
+ print("GAIA UNIT 4 AGENT")
425
+ print("=" * 70)
426
+
427
+ print(
428
+ f"Username: {username}"
429
+ )
430
+
431
+ print(
432
+ f"Agent code: {agent_code}"
433
+ )
434
+
435
+ # --------------------------------------------------------
436
+ # Fetch questions
437
+ # --------------------------------------------------------
438
+
439
  try:
440
+
441
+ questions = get_questions()
442
+
 
 
 
 
 
 
 
 
 
 
 
443
  except Exception as e:
444
+
445
+ return (
446
+ f"Could not fetch questions: {e}",
447
+ None
448
+ )
449
+
450
+ print(
451
+ f"Fetched {len(questions)} questions."
452
+ )
453
+
454
+ answers = []
455
+ results = []
456
+
457
+ # --------------------------------------------------------
458
+ # Solve questions
459
+ # --------------------------------------------------------
460
+
461
+ for index, item in enumerate(
462
+ questions,
463
+ start=1
464
+ ):
465
+
466
+ task_id = item.get(
467
+ "task_id"
468
+ )
469
+
470
+ question = item.get(
471
+ "question"
472
+ )
473
+
474
+ print("\n" + "=" * 70)
475
+
476
+ print(
477
+ f"QUESTION {index}/{len(questions)}"
478
+ )
479
+
480
+ print(
481
+ f"TASK ID: {task_id}"
482
+ )
483
+
484
+ print(
485
+ question[:500]
486
+ )
487
+
488
+ print("=" * 70)
489
+
490
  try:
491
+
492
+ answer = solve_question(
493
+ task_id,
494
+ question
495
+ )
496
+
497
+ answer = clean_answer(
498
+ answer
499
+ )
500
+
501
+ print(
502
+ f"FINAL ANSWER: {answer}"
503
+ )
504
+
505
+ answers.append({
506
+ "task_id": task_id,
507
+ "submitted_answer": answer
508
+ })
509
+
510
+ results.append({
511
+ "Task ID": task_id,
512
+ "Submitted Answer": answer
513
+ })
514
+
515
  except Exception as e:
 
 
516
 
517
+ print(
518
+ f"ERROR: {e}"
519
+ )
520
+
521
+ results.append({
522
+ "Task ID": task_id,
523
+ "Submitted Answer":
524
+ f"ERROR: {e}"
525
+ })
526
 
527
+ # --------------------------------------------------------
528
+ # Submit
529
+ # --------------------------------------------------------
530
+
531
+ if not answers:
532
+
533
+ return (
534
+ "No answers were generated.",
535
+ pd.DataFrame(results)
536
+ )
537
+
538
+ print("\n" + "=" * 70)
539
+ print("SUBMITTING")
540
+ print("=" * 70)
541
 
 
 
542
  try:
543
+
544
+ result = submit(
545
+ username,
546
+ agent_code,
547
+ answers
548
+ )
549
+
550
+ score = result.get(
551
+ "score",
552
+ "N/A"
553
+ )
554
+
555
+ correct = result.get(
556
+ "correct_count",
557
+ "?"
558
+ )
559
+
560
+ total = result.get(
561
+ "total_attempted",
562
+ "?"
563
+ )
564
+
565
+ message = result.get(
566
+ "message",
567
+ ""
568
+ )
569
+
570
+ status = (
571
+ "Submission Successful!\n\n"
572
+ f"User: {username}\n"
573
+ f"Score: {score}%\n"
574
+ f"Correct: {correct}/{total}\n"
575
+ f"Message: {message}"
576
+ )
577
+
578
+ print(status)
579
+
580
+ return (
581
+ status,
582
+ pd.DataFrame(results)
583
+ )
584
+
585
  except Exception as e:
 
 
 
 
586
 
587
+ status = (
588
+ f"Submission failed: {e}"
589
+ )
590
+
591
+ print(status)
592
+
593
+ return (
594
+ status,
595
+ pd.DataFrame(results)
596
+ )
597
+
598
+
599
+ # ============================================================
600
+ # MINIMAL UI
601
+ # ============================================================
602
 
 
603
  with gr.Blocks() as demo:
 
 
 
 
604
 
605
+ gr.Markdown(
606
+ "# GAIA Unit 4 Agent"
607
+ )
608
 
609
+ gr.Markdown(
610
+ "Login and click the button to run all GAIA questions."
 
 
 
611
  )
612
 
613
  gr.LoginButton()
614
 
615
+ run_button = gr.Button(
616
+ "Run Evaluation & Submit"
617
+ )
618
+
619
+ status = gr.Textbox(
620
+ label="Result",
621
+ lines=6
622
+ )
623
 
624
+ results = gr.DataFrame(
625
+ label="Answers"
626
+ )
627
 
628
  run_button.click(
629
  fn=run_and_submit_all,
630
+ outputs=[
631
+ status,
632
+ results
633
+ ]
634
  )
635
 
636
+
637
  if __name__ == "__main__":
638
+
639
+ demo.launch(
640
+ debug=True,
641
+ share=False
642
+ )