yooke commited on
Commit
28b77fd
·
verified ·
1 Parent(s): d267ada

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -131
app.py CHANGED
@@ -1,182 +1,155 @@
1
  import os
2
- import traceback
3
  import gradio as gr
4
  import requests
 
5
  import pandas as pd
6
- from smolagents import CodeAgent, DuckDuckGoSearchTool, PythonInterpreterTool, HfApiModel, LiteLLMModel, WikipediaSearchTool
7
- from huggingface_hub import login
8
- import time
9
-
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
- HF_TOKEN = os.getenv("HF_TOKEN")
13
- # login(HF_TOKEN) # Recommended via Space secrets
14
 
15
- model = LiteLLMModel(model_id="deepseek/deepseek-chat",
16
- api_key=os.getenv("DEEPSEEK_API_KEY"),
17
- base_url="https://api.deepseek.com")
18
 
19
  # --- Basic Agent Definition ---
 
 
20
  class BasicAgent:
21
  def __init__(self):
22
- # print("BasicAgent initialized.") # Removed
23
- self.model = model
24
- self.tools = [
25
- PythonInterpreterTool(),
26
- DuckDuckGoSearchTool(),
27
- WikipediaSearchTool(),
28
- ]
29
  self.agent = CodeAgent(
30
- model=self.model,
31
- tools=self.tools,
32
- add_base_tools=True
33
  )
34
-
35
- def answer_question(self, question: str) -> str:
36
- # print(f"Processing question (first 50 chars): {question[:50]}...") # Removed
37
- try:
38
- result = self.agent.run(question)
39
- if not isinstance(result, str):
40
- result = str(result)
41
- if "Final answer:" in result:
42
- final_answer_part = result.split("Final answer:", 1)[1].strip()
43
- return final_answer_part
44
- return result
45
- except Exception as e: # Capture exception object
46
- print(f"Error in agent.run for question '{question[:50]}...':\n{traceback.format_exc()}")
47
- return f"I encountered an issue processing your question: {str(e)}"
48
-
49
-
50
- # Global variables
51
- processed_questions_cache = {}
52
- submission_has_been_completed = False
53
-
54
- def run_and_submit_all(profile: gr.OAuthProfile | None):
55
- global processed_questions_cache, submission_has_been_completed
56
-
57
- # print(f"--- run_and_submit_all triggered. Submission completed: {submission_has_been_completed} ---") # Removed
58
-
59
- if submission_has_been_completed and processed_questions_cache:
60
- # print("--- Submission previously completed. Displaying cached results. ---") # Removed
61
- results_log_display = []
62
- for task_id, data in processed_questions_cache.items():
63
- results_log_display.append({"Task ID": task_id, "Question": data["question"], "Submitted Answer": data["answer"]})
64
- return "评估已完成并提交。如果需要重新运行,请刷新页面。", pd.DataFrame(results_log_display if results_log_display else [{}])
65
-
66
- if not profile:
67
- # print("--- User not logged in. ---") # Removed
68
- return "请先使用 Hugging Face 账号登录。", None
69
-
70
- username = profile.username
71
- print(f"--- User: {username}. Starting new submission process. ---") # Kept for context
72
 
73
  api_url = DEFAULT_API_URL
74
  questions_url = f"{api_url}/questions"
75
  submit_url = f"{api_url}/submit"
76
- space_id = os.getenv("SPACE_ID")
77
- agent_code_url = f"https://huggingface.co/spaces/{space_id}/tree/main" if space_id else "N/A (SPACE_ID not set)"
78
 
 
79
  try:
80
  agent = BasicAgent()
81
  except Exception as e:
82
- print(f"Fatal: Error instantiating agent: {e}\n{traceback.format_exc()}")
83
- return f"初始化 Agent 失败: {e}", None
84
-
85
- # 1. Fetch Questions
86
- # print(f"Fetching questions from: {questions_url}") # Removed
 
 
 
87
  try:
88
- response = requests.get(questions_url, timeout=20)
89
  response.raise_for_status()
90
  questions_data = response.json()
91
  if not questions_data:
92
- print("Warning: Fetched questions list is empty.")
93
- return "获取到的问题列表为空。", None
94
- # print(f"Fetched {len(questions_data)} questions.") # Removed
95
  except requests.exceptions.RequestException as e:
96
- print(f"Fatal: Error fetching questions: {e}\n{traceback.format_exc()}")
97
- return f"获取问题失败: {e}", None
98
  except requests.exceptions.JSONDecodeError as e:
99
- print(f"Fatal: Error decoding JSON from questions: {e}\nResponse text: {response.text[:500]}")
100
- return f"解析问题数据失败: {e}", None
 
 
 
 
101
 
 
102
  results_log = []
103
  answers_payload = []
104
-
105
- # 2. Run Agent on Questions
106
- print(f"--- Running agent on {len(questions_data)} questions... ---")
107
- for i, item in enumerate(questions_data):
108
  task_id = item.get("task_id")
109
  question_text = item.get("question")
110
-
111
  if not task_id or question_text is None:
112
- print(f"Warning: Skipping item with missing task_id or question: {item}")
113
  continue
114
-
115
- print(f"--- Processing question {i+1}/{len(questions_data)} (ID: {task_id}): \"{question_text[:70]}...\" ---")
116
- submitted_answer = "AGENT_ERROR: Did not run or failed" # Default in case of early exit
117
  try:
118
- submitted_answer = agent.answer_question(question_text)
119
- print(f"--- Answer for Q{i+1} (ID: {task_id}): \"{submitted_answer[:70]}...\" ---") # Print the answer
120
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
121
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
122
  except Exception as e:
123
- # This specific exception handling might be redundant if agent.answer_question handles its own exceptions and returns a string
124
- # However, keeping it as a fallback.
125
- print(f"Error running agent on task {task_id} (Question: \"{question_text[:50]}...\"):\n{traceback.format_exc()}")
126
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT_ERROR: {e}"})
127
-
128
- # CRITICAL: This sleep is likely causing timeouts.
129
- # print(f"--- Waiting before next question... ---") # Removed
130
- time.sleep(1) # MINIMAL SLEEP - ADJUST OR REMOVE FOR TESTING / BASED ON API LIMITS
131
 
132
  if not answers_payload:
133
- print("Warning: Agent did not produce any answers to submit.")
134
- return "Agent 未能生成任何答案用于提交。", pd.DataFrame(results_log)
135
 
136
- # 3. Prepare and Submit
137
- submission_data = {"username": username, "agent_code": agent_code_url, "answers": answers_payload}
138
- # status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..." # Removed
139
- # print(status_update) # Removed
140
 
141
- print(f"--- Submitting {len(answers_payload)} answers for user '{username}'... ---")
 
142
  try:
143
  response = requests.post(submit_url, json=submission_data, timeout=60)
144
  response.raise_for_status()
145
  result_data = response.json()
146
  final_status = (
147
- f"提交成功!\n"
148
- f"用户: {result_data.get('username')}\n"
149
- f"总分: {result_data.get('score', 'N/A')}% "
150
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} 正确)\n"
151
- f"消息: {result_data.get('message', '无消息.')}"
152
  )
153
- print(f"--- Submission successful for {username}! Score: {result_data.get('score', 'N/A')}% ---")
154
- submission_has_been_completed = True
155
- for item_log in results_log:
156
- processed_questions_cache[item_log["Task ID"]] = {
157
- "question": item_log["Question"],
158
- "answer": item_log["Submitted Answer"]
159
- }
160
  results_df = pd.DataFrame(results_log)
161
  return final_status, results_df
162
  except requests.exceptions.HTTPError as e:
163
- error_detail = f"服务器响应状态 {e.response.status_code}."
164
  try:
165
  error_json = e.response.json()
166
- error_detail += f" 详情: {error_json.get('detail', e.response.text)}"
167
  except requests.exceptions.JSONDecodeError:
168
- error_detail += f" 响应内容: {e.response.text[:500]}"
169
- status_message = f"提交失败: {error_detail}"
 
 
 
170
  except requests.exceptions.Timeout:
171
- status_message = "提交失败: 请求超时."
 
 
 
172
  except requests.exceptions.RequestException as e:
173
- status_message = f"提交失败: 网络错误 - {e}"
 
 
 
174
  except Exception as e:
175
- status_message = f"提交过程中发生未知错误: {e}\n{traceback.format_exc()}"
176
-
177
- print(f"--- Submission failed or an error occurred for {username}: {status_message} ---")
178
- results_df = pd.DataFrame(results_log)
179
- return status_message, results_df
180
 
181
 
182
  # --- Build Gradio Interface using Blocks ---
@@ -185,29 +158,52 @@ with gr.Blocks() as demo:
185
  gr.Markdown(
186
  """
187
  **Instructions:**
188
- 1. Modify the code (if needed) to define your agent's logic.
189
- 2. Log in to your Hugging Face account using the button below.
190
- 3. Click 'Run Evaluation & Submit All Answers'.
 
 
191
  ---
192
  **Disclaimers:**
193
- This process can take a significant amount of time.
194
- If the process seems to restart, it might be due to platform timeouts.
195
- Check the application logs on Hugging Face Spaces for more details.
196
  """
197
  )
198
 
199
  gr.LoginButton()
 
200
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
201
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
202
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
203
 
204
  run_button.click(
205
  fn=run_and_submit_all,
206
- outputs=[status_output, results_table],
207
  )
208
 
209
  if __name__ == "__main__":
210
  print("\n" + "-"*30 + " App Starting " + "-"*30)
211
- # Minimal startup logs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  print("Launching Gradio Interface for Basic Agent Evaluation...")
213
- demo.launch(debug=False, share=True) # debug=False for cleaner logs in production, True for local dev
 
1
  import os
 
2
  import gradio as gr
3
  import requests
4
+ import inspect
5
  import pandas as pd
6
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, OpenAIServerModel
7
+ # (Keep Constants as is)
 
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
 
10
 
 
 
 
11
 
12
  # --- Basic Agent Definition ---
13
+ # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
14
+ DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
15
  class BasicAgent:
16
  def __init__(self):
17
+ print("BasicAgent initialized.")
18
+ # Initialize the model
19
+ #model = HfApiModel()
20
+ model = OpenAIServerModel(model_id="deepseek-chat")
21
+ # Initialize the search tool
22
+ search_tool = DuckDuckGoSearchTool()
23
+ # Initialize Agent
24
  self.agent = CodeAgent(
25
+ model = model,
26
+ tools=[search_tool]
 
27
  )
28
+ def __call__(self, question: str) -> str:
29
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
30
+ fixed_answer =self.agent.run(question)
31
+ print(f"Agent returning fixed answer: {fixed_answer}")
32
+ return fixed_answer
33
+
34
+ def run_and_submit_all( profile: gr.OAuthProfile | None):
35
+ """
36
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
37
+ and displays the results.
38
+ """
39
+ # --- Determine HF Space Runtime URL and Repo URL ---
40
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
41
+
42
+ if profile:
43
+ username= f"{profile.username}"
44
+ print(f"User logged in: {username}")
45
+ else:
46
+ print("User not logged in.")
47
+ return "Please Login to Hugging Face with the button.", None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  api_url = DEFAULT_API_URL
50
  questions_url = f"{api_url}/questions"
51
  submit_url = f"{api_url}/submit"
 
 
52
 
53
+ # 1. Instantiate Agent ( modify this part to create your agent)
54
  try:
55
  agent = BasicAgent()
56
  except Exception as e:
57
+ print(f"Error instantiating agent: {e}")
58
+ return f"Error initializing agent: {e}", None
59
+ # 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)
60
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
61
+ print(agent_code)
62
+
63
+ # 2. Fetch Questions
64
+ print(f"Fetching questions from: {questions_url}")
65
  try:
66
+ response = requests.get(questions_url, timeout=15)
67
  response.raise_for_status()
68
  questions_data = response.json()
69
  if not questions_data:
70
+ print("Fetched questions list is empty.")
71
+ return "Fetched questions list is empty or invalid format.", None
72
+ print(f"Fetched {len(questions_data)} questions.")
73
  except requests.exceptions.RequestException as e:
74
+ print(f"Error fetching questions: {e}")
75
+ return f"Error fetching questions: {e}", None
76
  except requests.exceptions.JSONDecodeError as e:
77
+ print(f"Error decoding JSON response from questions endpoint: {e}")
78
+ print(f"Response text: {response.text[:500]}")
79
+ return f"Error decoding server response for questions: {e}", None
80
+ except Exception as e:
81
+ print(f"An unexpected error occurred fetching questions: {e}")
82
+ return f"An unexpected error occurred fetching questions: {e}", None
83
 
84
+ # 3. Run your Agent
85
  results_log = []
86
  answers_payload = []
87
+ print(f"Running agent on {len(questions_data)} questions...")
88
+ for item in questions_data:
 
 
89
  task_id = item.get("task_id")
90
  question_text = item.get("question")
 
91
  if not task_id or question_text is None:
92
+ print(f"Skipping item with missing task_id or question: {item}")
93
  continue
 
 
 
94
  try:
95
+ submitted_answer = agent(question_text)
 
96
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
97
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
98
  except Exception as e:
99
+ print(f"Error running agent on task {task_id}: {e}")
100
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
 
101
 
102
  if not answers_payload:
103
+ print("Agent did not produce any answers to submit.")
104
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
105
 
106
+ # 4. Prepare Submission
107
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
108
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
109
+ print(status_update)
110
 
111
+ # 5. Submit
112
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
113
  try:
114
  response = requests.post(submit_url, json=submission_data, timeout=60)
115
  response.raise_for_status()
116
  result_data = response.json()
117
  final_status = (
118
+ f"Submission Successful!\n"
119
+ f"User: {result_data.get('username')}\n"
120
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
121
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
122
+ f"Message: {result_data.get('message', 'No message received.')}"
123
  )
124
+ print("Submission successful.")
 
 
 
 
 
 
125
  results_df = pd.DataFrame(results_log)
126
  return final_status, results_df
127
  except requests.exceptions.HTTPError as e:
128
+ error_detail = f"Server responded with status {e.response.status_code}."
129
  try:
130
  error_json = e.response.json()
131
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
132
  except requests.exceptions.JSONDecodeError:
133
+ error_detail += f" Response: {e.response.text[:500]}"
134
+ status_message = f"Submission Failed: {error_detail}"
135
+ print(status_message)
136
+ results_df = pd.DataFrame(results_log)
137
+ return status_message, results_df
138
  except requests.exceptions.Timeout:
139
+ status_message = "Submission Failed: The request timed out."
140
+ print(status_message)
141
+ results_df = pd.DataFrame(results_log)
142
+ return status_message, results_df
143
  except requests.exceptions.RequestException as e:
144
+ status_message = f"Submission Failed: Network error - {e}"
145
+ print(status_message)
146
+ results_df = pd.DataFrame(results_log)
147
+ return status_message, results_df
148
  except Exception as e:
149
+ status_message = f"An unexpected error occurred during submission: {e}"
150
+ print(status_message)
151
+ results_df = pd.DataFrame(results_log)
152
+ return status_message, results_df
 
153
 
154
 
155
  # --- Build Gradio Interface using Blocks ---
 
158
  gr.Markdown(
159
  """
160
  **Instructions:**
161
+
162
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
163
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
164
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
165
+
166
  ---
167
  **Disclaimers:**
168
+ 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).
169
+ 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.
170
+ Please note that this version requires an OpenAI Key to run.
171
  """
172
  )
173
 
174
  gr.LoginButton()
175
+
176
  run_button = gr.Button("Run Evaluation & Submit All Answers")
177
+
178
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
179
+ # Removed max_rows=10 from DataFrame constructor
180
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
181
 
182
  run_button.click(
183
  fn=run_and_submit_all,
184
+ outputs=[status_output, results_table]
185
  )
186
 
187
  if __name__ == "__main__":
188
  print("\n" + "-"*30 + " App Starting " + "-"*30)
189
+ # Check for SPACE_HOST and SPACE_ID at startup for information
190
+ space_host_startup = os.getenv("SPACE_HOST")
191
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
192
+
193
+ if space_host_startup:
194
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
195
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
196
+ else:
197
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
198
+
199
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
200
+ print(f"✅ SPACE_ID found: {space_id_startup}")
201
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
202
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
203
+ else:
204
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
205
+
206
+ print("-"*(60 + len(" App Starting ")) + "\n")
207
+
208
  print("Launching Gradio Interface for Basic Agent Evaluation...")
209
+ demo.launch(debug=True, share=False)