benjipeng commited on
Commit
fb79f9d
·
verified ·
1 Parent(s): 808bca2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -108
app.py CHANGED
@@ -2,166 +2,149 @@ import os
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
 
5
 
6
  # Import your upgraded agent
7
  from agent import GeminiAgent
8
 
9
  # --- Constants ---
10
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
11
- # This is the security gate. Only this user can run submissions.
12
  MY_HF_USERNAME = "benjipeng"
 
13
 
14
- def run_and_submit_all(profile: gr.OAuthProfile | None):
 
15
  """
16
- Fetches all questions, runs the GeminiAgent on them, submits all answers,
17
- and displays the results. This function is restricted to a specific user and
18
- provides file context to the agent.
19
  """
20
- # --- Determine HF Space Runtime URL and Repo URL ---
21
- space_id = os.getenv("SPACE_ID")
22
-
23
- # --- User Authentication and Authorization ---
24
- if not profile:
25
- return "Please Login to Hugging Face with the button to run the evaluation.", None
26
-
27
- username = profile.username
28
- print(f"User logged in: {username}")
29
 
30
- if username != MY_HF_USERNAME:
31
- print(f"Access denied for user: {username}. Allowed user is {MY_HF_USERNAME}.")
32
- return f"Error: This Space is configured for a specific user. Access denied for '{username}'.", None
33
-
34
- api_url = DEFAULT_API_URL
35
- questions_url = f"{api_url}/questions"
36
- submit_url = f"{api_url}/submit"
37
 
38
- # 1. Instantiate Agent
39
- print("Instantiating agent...")
40
  try:
41
- agent = GeminiAgent()
42
- except Exception as e:
43
- error_msg = f"Error initializing agent: {e}"
44
- print(error_msg)
45
- return error_msg, None
46
-
47
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
48
- print(f"Code link for submission: {agent_code}")
49
-
50
- # 2. Fetch Questions
51
- print(f"Fetching questions from: {questions_url}")
52
- try:
53
- response = requests.get(questions_url, timeout=20)
54
  response.raise_for_status()
55
  questions_data = response.json()
56
- if not questions_data:
57
- print("Fetched questions list is empty.")
58
- return "Fetched questions list is empty or invalid format.", None
59
- print(f"Fetched {len(questions_data)} questions.")
60
- except requests.exceptions.RequestException as e:
61
- error_msg = f"Error fetching questions: {e}"
62
- print(error_msg)
63
- return error_msg, None
64
- except requests.exceptions.JSONDecodeError as e:
65
- error_msg = f"Error decoding server response for questions: {e}"
66
- print(error_msg)
67
- print(f"Response text: {response.text[:500]}")
68
- return error_msg, None
69
-
70
- # 3. Run your Agent (with context injection)
71
  results_log = []
72
- answers_payload = []
73
- print(f"Running agent on {len(questions_data)} questions...")
74
- for item in questions_data:
75
  task_id = item.get("task_id")
76
  question_text = item.get("question")
77
-
78
- # This is the key improvement: check if a file is associated with the question
79
  has_file = item.get("file", None) is not None
80
 
81
- if not task_id or question_text is None:
82
- print(f"Skipping item with missing task_id or question: {item}")
83
- continue
84
-
85
- # Modify the question to give the agent context about the file's existence
86
- if has_file:
87
- modified_question = f"{question_text}\n\n[Agent Note: A file is attached to this question. Use the 'read_file_from_api' tool to access it if needed.]"
88
- else:
89
- modified_question = question_text
90
-
91
  try:
92
- # Pass BOTH the modified question and the task_id to the agent
93
  submitted_answer = agent(modified_question, task_id)
94
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
95
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
96
  except Exception as e:
97
- print(f"Error running agent on task {task_id}: {e}")
98
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
99
 
100
- if not answers_payload:
101
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
 
102
 
103
- # 4. Prepare Submission
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
105
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
106
- print(status_update)
 
107
 
108
- # 5. Submit
109
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
110
  try:
111
- response = requests.post(submit_url, json=submission_data, timeout=120) # Increased timeout
112
  response.raise_for_status()
113
  result_data = response.json()
114
- final_status = (
115
  f"Submission Successful!\n"
116
  f"User: {result_data.get('username')}\n"
117
  f"Overall Score: {result_data.get('score', 'N/A')}% "
118
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
119
  f"Message: {result_data.get('message', 'No message received.')}"
120
  )
121
- print("Submission successful.")
122
- results_df = pd.DataFrame(results_log)
123
- return final_status, results_df
124
  except requests.exceptions.HTTPError as e:
125
- error_detail = f"Server responded with status {e.response.status_code}."
126
- try:
127
- error_json = e.response.json()
128
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
129
- except requests.exceptions.JSONDecodeError:
130
- error_detail += f" Response: {e.response.text[:500]}"
131
- status_message = f"Submission Failed: {error_detail}"
132
- print(status_message)
133
- results_df = pd.DataFrame(results_log)
134
- return status_message, results_df
135
- except requests.exceptions.RequestException as e:
136
- status_message = f"Submission Failed: Network error - {e}"
137
- print(status_message)
138
- results_df = pd.DataFrame(results_log)
139
- return status_message, results_df
140
 
141
  # --- Build Gradio Interface using Blocks ---
142
  with gr.Blocks() as demo:
143
- gr.Markdown("# Gemini ReAct Agent for GAIA")
144
  gr.Markdown(
145
  """
146
- **Instructions:**
147
- 1. Log in using the Hugging Face login button below.
148
- 2. Click 'Run Evaluation & Submit' to start the process.
149
- 3. The agent will fetch all 20 questions, reason about them step-by-step, use tools (like web search and a file reader), and submit the final answers for scoring.
150
-
151
- **Note:** This process can take several minutes. Please be patient.
 
 
152
  """
153
  )
 
154
  gr.LoginButton()
155
 
156
- run_button = gr.Button("Run Evaluation & Submit All Answers")
 
 
157
 
158
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
159
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
160
 
161
  run_button.click(
162
- fn=run_and_submit_all,
 
163
  outputs=[status_output, results_table]
164
  )
 
 
 
 
 
 
165
 
166
  if __name__ == "__main__":
167
  print("\n" + "-"*30 + " App Starting " + "-"*30)
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
+ import json
6
 
7
  # Import your upgraded agent
8
  from agent import GeminiAgent
9
 
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
12
  MY_HF_USERNAME = "benjipeng"
13
+ ANSWERS_FILE = "answers.json"
14
 
15
+ # --- Logic for Running the Agent ---
16
+ def run_agent_only(profile: gr.OAuthProfile | None):
17
  """
18
+ Fetches questions, runs the agent on them, and saves the answers to a file.
19
+ This is the long-running part of the process.
 
20
  """
21
+ if not profile or profile.username != MY_HF_USERNAME:
22
+ yield "Error: Please log in as the correct user (`benjipeng`) to run the agent.", pd.DataFrame()
23
+ return
 
 
 
 
 
 
24
 
25
+ print("Starting agent run...")
26
+ yield "Fetching questions...", pd.DataFrame()
 
 
 
 
 
27
 
 
 
28
  try:
29
+ response = requests.get(f"{DEFAULT_API_URL}/questions", timeout=20)
 
 
 
 
 
 
 
 
 
 
 
 
30
  response.raise_for_status()
31
  questions_data = response.json()
32
+ except Exception as e:
33
+ yield f"Error fetching questions: {e}", pd.DataFrame()
34
+ return
35
+
36
+ yield f"Fetched {len(questions_data)} questions. Initializing agent...", pd.DataFrame()
37
+ agent = GeminiAgent()
38
+
39
+ all_answers = []
 
 
 
 
 
 
 
40
  results_log = []
41
+
42
+ for i, item in enumerate(questions_data):
 
43
  task_id = item.get("task_id")
44
  question_text = item.get("question")
 
 
45
  has_file = item.get("file", None) is not None
46
 
47
+ status_message = f"Processing question {i+1}/{len(questions_data)} (Task ID: {task_id})..."
48
+ yield status_message, pd.DataFrame(results_log)
49
+
50
+ modified_question = f"{question_text}\n\n[Agent Note: A file is attached.]" if has_file else question_text
51
+
 
 
 
 
 
52
  try:
 
53
  submitted_answer = agent(modified_question, task_id)
 
 
54
  except Exception as e:
55
+ submitted_answer = f"AGENT ERROR: {e}"
56
+
57
+ all_answers.append({"task_id": task_id, "submitted_answer": submitted_answer})
58
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
59
 
60
+ # Save progress incrementally
61
+ with open(ANSWERS_FILE, 'w') as f:
62
+ json.dump(all_answers, f, indent=2)
63
 
64
+ yield f"Agent run complete. All {len(all_answers)} answers saved to {ANSWERS_FILE}. Ready to submit.", pd.DataFrame(results_log)
65
+
66
+
67
+ # --- Logic for Submitting Answers ---
68
+ def submit_saved_answers(profile: gr.OAuthProfile | None):
69
+ """
70
+ Reads the answers from the saved file and submits them to the scoring server.
71
+ This is the fast part of the process.
72
+ """
73
+ if not profile or profile.username != MY_HF_USERNAME:
74
+ return "Error: Please log in as the correct user (`benjipeng`) to submit."
75
+
76
+ space_id = os.getenv("SPACE_ID")
77
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
78
+ username = profile.username
79
+
80
+ try:
81
+ with open(ANSWERS_FILE, 'r') as f:
82
+ answers_payload = json.load(f)
83
+ except FileNotFoundError:
84
+ return f"Error: Answers file '{ANSWERS_FILE}' not found. Please run the agent first."
85
+ except json.JSONDecodeError:
86
+ return f"Error: Could not read the answers file. It might be corrupted."
87
+
88
+ if not answers_payload:
89
+ return "Error: Answers file is empty."
90
+
91
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
92
+
93
+ submit_url = f"{DEFAULT_API_URL}/submit"
94
+ print(f"Submitting {len(answers_payload)} answers for user '{username}'...")
95
 
 
 
96
  try:
97
+ response = requests.post(submit_url, json=submission_data, timeout=60)
98
  response.raise_for_status()
99
  result_data = response.json()
100
+ return (
101
  f"Submission Successful!\n"
102
  f"User: {result_data.get('username')}\n"
103
  f"Overall Score: {result_data.get('score', 'N/A')}% "
104
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
105
  f"Message: {result_data.get('message', 'No message received.')}"
106
  )
 
 
 
107
  except requests.exceptions.HTTPError as e:
108
+ return f"Submission Failed: Server responded with status {e.response.status_code}. Detail: {e.response.text}"
109
+ except Exception as e:
110
+ return f"An unexpected error occurred during submission: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  # --- Build Gradio Interface using Blocks ---
113
  with gr.Blocks() as demo:
114
+ gr.Markdown("# Gemini ReAct Agent for GAIA (Two-Step Submission)")
115
  gr.Markdown(
116
  """
117
+ **Step 1: Run Agent & Save Answers**
118
+ - This is the long process that can take 10-20 minutes.
119
+ - The agent will answer all 20 questions and save the results to a file.
120
+ - You will see the progress in the status box and the table below.
121
+
122
+ **Step 2: Submit Saved Answers**
123
+ - Once Step 1 is complete, click this button.
124
+ - This will be very fast and will send your saved answers to be scored.
125
  """
126
  )
127
+
128
  gr.LoginButton()
129
 
130
+ with gr.Row():
131
+ run_button = gr.Button("Step 1: Run Agent & Save Answers")
132
+ submit_button = gr.Button("Step 2: Submit Saved Answers")
133
 
134
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
135
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True, interactive=False)
136
 
137
  run_button.click(
138
+ fn=run_agent_only,
139
+ inputs=None, # LoginButton profile is passed implicitly
140
  outputs=[status_output, results_table]
141
  )
142
+
143
+ submit_button.click(
144
+ fn=submit_saved_answers,
145
+ inputs=None, # LoginButton profile is passed implicitly
146
+ outputs=[status_output]
147
+ )
148
 
149
  if __name__ == "__main__":
150
  print("\n" + "-"*30 + " App Starting " + "-"*30)