jarguello76 commited on
Commit
ca526ca
·
verified ·
1 Parent(s): b0c1042

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -145
app.py CHANGED
@@ -1,126 +1,47 @@
 
1
  import os
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
- from smolagents import GradioUI, CodeAgent, HfApiModel
6
- from smolagents import TransformersModel
7
- import torch
8
- from transformers import AutoTokenizer
9
- from smolagents import DuckDuckGoSearchTool
10
- # Import your custom tools from their modules
11
- from tools import (
12
- WeatherInfoTool, HubStatsTool,
13
- CalculatorTool, CalendarTool, EmailTool, FileManagementTool,
14
- DatabaseQueryTool, TranslationTool, TextToSpeechTool,
15
- SpeechToTextTool, ImageRecognitionTool, NLPTool, APIIntegrationTool
16
- )
17
- from retriever import load_guest_dataset
18
 
19
- # --- Constants ---
20
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
21
- HUGGINGFACE_TOKEN = os.getenv("agents_token")
22
-
23
- # # Initialize the Hugging Face model with better generation parameters
24
- # model = TransformersModel(
25
- # model_id="allenai/OLMo-2-0425-1B-Instruct",
26
- # device="auto",
27
- # # Add generation parameters to prevent loops
28
- # generation_kwargs={
29
- # "max_new_tokens": 512,
30
- # "temperature": 0.7,
31
- # "do_sample": True,
32
- # "pad_token_id": None, # Will be set automatically
33
- # "eos_token_id": None, # Will be set automatically
34
- # "repetition_penalty": 1.1,
35
- # "no_repeat_ngram_size": 3,
36
- # }
37
- # )
38
- model = HfApiModel(
39
- model_id="microsoft/DialoGPT-medium",
40
- token=HUGGINGFACE_TOKEN
41
- )
42
- # Initialize the web search tool
43
- search_tool = DuckDuckGoSearchTool()
44
 
45
- # Initialize the weather tool
46
- weather_info_tool = WeatherInfoTool()
47
 
48
- # Initialize the Hub stats tool
49
- hub_stats_tool = HubStatsTool()
50
-
51
- # Initialize additional tools (only the most essential ones to avoid confusion)
52
- calculator_tool = CalculatorTool()
53
- calendar_tool = CalendarTool()
54
 
55
- # Load the guest dataset and initialize the guest info tool
56
- guest_info_tool = load_guest_dataset()
57
 
58
- # Create AgentChen with essential tools only
59
- AgentChen = CodeAgent(
60
- tools=[
61
- search_tool,
62
- guest_info_tool,
63
- calculator_tool,
64
- weather_info_tool,
65
- hub_stats_tool,
66
- ],
67
- model=model,
68
- add_base_tools=True, # Add any additional base tools
69
- planning_interval=None, # Disable planning to reduce complexity
70
- max_iterations=3, # Limit iterations to prevent loops
71
- )
72
 
73
- class AgentChenWrapper:
 
74
  def __init__(self):
75
- self.agent = AgentChen
76
- print("AgentChenWrapper initialized.")
77
-
78
  def __call__(self, question: str) -> str:
79
  print(f"Agent received question (first 50 chars): {question[:50]}...")
80
-
81
- # Ensure the question is a string
82
- if not isinstance(question, str):
83
- print(f"Error: Expected a string, got {type(question)}")
84
- return "Error: Input must be a string."
85
-
86
- # Clean and prepare the question
87
- question = question.strip()
88
- if not question:
89
- return "Error: Empty question received."
90
-
91
- try:
92
- # Use the CodeAgent to run the question with a timeout-like approach
93
- print("Running agent...")
94
- answer = self.agent.run(question)
95
-
96
- # Ensure we get a string response
97
- if answer is None:
98
- answer = "No response generated."
99
- else:
100
- answer = str(answer).strip()
101
-
102
- # Limit response length to prevent issues
103
- if len(answer) > 1000:
104
- answer = answer[:1000] + "... [truncated]"
105
-
106
- print(f"Agent returning answer (first 100 chars): {answer[:100]}...")
107
- return answer
108
-
109
- except Exception as e:
110
- error_msg = f"Error in agent execution: {str(e)}"
111
- print(error_msg)
112
- return error_msg
113
 
114
- def run_and_submit_all(profile: gr.OAuthProfile | None):
 
115
  """
116
- Fetches all questions, runs the AgentChen on them, submits all answers,
117
  and displays the results.
118
  """
119
  # --- Determine HF Space Runtime URL and Repo URL ---
120
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
121
-
122
  if profile:
123
- username = f"{profile.username}"
124
  print(f"User logged in: {username}")
125
  else:
126
  print("User not logged in.")
@@ -130,13 +51,13 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
130
  questions_url = f"{api_url}/questions"
131
  submit_url = f"{api_url}/submit"
132
 
133
- # 1. Instantiate Agent
134
  try:
135
- agent = AgentChenWrapper()
136
  except Exception as e:
137
  print(f"Error instantiating agent: {e}")
138
  return f"Error initializing agent: {e}", None
139
-
140
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
141
  print(agent_code)
142
 
@@ -146,57 +67,44 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
146
  response = requests.get(questions_url, timeout=15)
147
  response.raise_for_status()
148
  questions_data = response.json()
149
-
150
  if not questions_data:
151
- print("Fetched questions list is empty.")
152
- return "Fetched questions list is empty or invalid format.", None
153
-
154
  print(f"Fetched {len(questions_data)} questions.")
155
  except requests.exceptions.RequestException as e:
156
  print(f"Error fetching questions: {e}")
157
  return f"Error fetching questions: {e}", None
158
  except requests.exceptions.JSONDecodeError as e:
159
- print(f"Error decoding JSON response from questions endpoint: {e}")
160
- print(f"Response text: {response.text[:500]}")
161
- return f"Error decoding server response for questions: {e}", None
162
  except Exception as e:
163
  print(f"An unexpected error occurred fetching questions: {e}")
164
  return f"An unexpected error occurred fetching questions: {e}", None
165
 
166
- # 3. Run your Agent (limit to first 5 questions for testing)
167
  results_log = []
168
  answers_payload = []
169
-
170
- # Limit questions for initial testing
171
- test_questions = questions_data[:5] # Only process first 5 questions
172
- print(f"Running agent on {len(test_questions)} questions (limited for testing)...")
173
-
174
- for i, item in enumerate(test_questions):
175
  task_id = item.get("task_id")
176
  question_text = item.get("question")
177
-
178
  if not task_id or question_text is None:
179
  print(f"Skipping item with missing task_id or question: {item}")
180
  continue
181
-
182
- print(f"Processing question {i+1}/{len(test_questions)}: {task_id}")
183
-
184
  try:
185
  submitted_answer = agent(question_text)
186
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
187
- results_log.append({"Task ID": task_id, "Question": question_text[:100] + "...", "Submitted Answer": submitted_answer[:200] + "..."})
188
- print(f"Successfully processed question {i+1}")
189
  except Exception as e:
190
- print(f"Error running agent on task {task_id}: {e}")
191
- error_answer = f"AGENT ERROR: {str(e)}"
192
- answers_payload.append({"task_id": task_id, "submitted_answer": error_answer})
193
- results_log.append({"Task ID": task_id, "Question": question_text[:100] + "...", "Submitted Answer": error_answer})
194
 
195
  if not answers_payload:
196
  print("Agent did not produce any answers to submit.")
197
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
198
 
199
- # 4. Prepare Submission
200
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
201
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
202
  print(status_update)
@@ -207,7 +115,6 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
207
  response = requests.post(submit_url, json=submission_data, timeout=60)
208
  response.raise_for_status()
209
  result_data = response.json()
210
-
211
  final_status = (
212
  f"Submission Successful!\n"
213
  f"User: {result_data.get('username')}\n"
@@ -218,7 +125,6 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
218
  print("Submission successful.")
219
  results_df = pd.DataFrame(results_log)
220
  return final_status, results_df
221
-
222
  except requests.exceptions.HTTPError as e:
223
  error_detail = f"Server responded with status {e.response.status_code}."
224
  try:
@@ -226,30 +132,27 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
226
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
227
  except requests.exceptions.JSONDecodeError:
228
  error_detail += f" Response: {e.response.text[:500]}"
229
-
230
  status_message = f"Submission Failed: {error_detail}"
231
  print(status_message)
232
  results_df = pd.DataFrame(results_log)
233
  return status_message, results_df
234
-
235
  except requests.exceptions.Timeout:
236
  status_message = "Submission Failed: The request timed out."
237
  print(status_message)
238
  results_df = pd.DataFrame(results_log)
239
  return status_message, results_df
240
-
241
  except requests.exceptions.RequestException as e:
242
  status_message = f"Submission Failed: Network error - {e}"
243
  print(status_message)
244
  results_df = pd.DataFrame(results_log)
245
  return status_message, results_df
246
-
247
  except Exception as e:
248
  status_message = f"An unexpected error occurred during submission: {e}"
249
  print(status_message)
250
  results_df = pd.DataFrame(results_log)
251
  return status_message, results_df
252
 
 
253
  # --- Build Gradio Interface using Blocks ---
254
  with gr.Blocks() as demo:
255
  gr.Markdown("# Basic Agent Evaluation Runner")
@@ -261,15 +164,19 @@ with gr.Blocks() as demo:
261
  3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
262
  ---
263
  **Disclaimers:**
264
- This version processes only the first 5 questions for testing purposes. Once working properly, you can remove the limit.
 
265
  """
266
  )
267
-
268
  gr.LoginButton()
 
269
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
270
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
271
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
272
-
273
  run_button.click(
274
  fn=run_and_submit_all,
275
  outputs=[status_output, results_table]
@@ -277,24 +184,24 @@ with gr.Blocks() as demo:
277
 
278
  if __name__ == "__main__":
279
  print("\n" + "-"*30 + " App Starting " + "-"*30)
280
-
281
  # Check for SPACE_HOST and SPACE_ID at startup for information
282
  space_host_startup = os.getenv("SPACE_HOST")
283
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
284
-
285
  if space_host_startup:
286
  print(f"✅ SPACE_HOST found: {space_host_startup}")
287
  print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
288
  else:
289
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
290
-
291
  if space_id_startup: # Print repo URLs if SPACE_ID is found
292
  print(f"✅ SPACE_ID found: {space_id_startup}")
293
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
294
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
295
  else:
296
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
297
-
298
  print("-"*(60 + len(" App Starting ")) + "\n")
 
299
  print("Launching Gradio Interface for Basic Agent Evaluation...")
300
- demo.launch(debug=True, share=True)
 
1
+ """ Basic Agent Evaluation Runner"""
2
  import os
3
+ import inspect
4
  import gradio as gr
5
  import requests
6
  import pandas as pd
7
+ from langchain_core.messages import HumanMessage
8
+ from agent import build_graph
 
 
 
 
 
 
 
 
 
 
 
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
 
 
11
 
12
+ # (Keep Constants as is)
13
+ # --- Constants ---
14
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
 
 
15
 
16
+ # --- Basic Agent Definition ---
17
+ # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ class BasicAgent:
21
+ """A langgraph agent."""
22
  def __init__(self):
23
+ print("BasicAgent initialized.")
24
+ self.graph = build_graph()
25
+
26
  def __call__(self, question: str) -> str:
27
  print(f"Agent received question (first 50 chars): {question[:50]}...")
28
+ # Wrap the question in a HumanMessage from langchain_core
29
+ messages = [HumanMessage(content=question)]
30
+ messages = self.graph.invoke({"messages": messages})
31
+ answer = messages['messages'][-1].content
32
+ return answer[14:]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+
35
+ def run_and_submit_all( profile: gr.OAuthProfile | None):
36
  """
37
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
38
  and displays the results.
39
  """
40
  # --- Determine HF Space Runtime URL and Repo URL ---
41
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
42
+
43
  if profile:
44
+ username= f"{profile.username}"
45
  print(f"User logged in: {username}")
46
  else:
47
  print("User not logged in.")
 
51
  questions_url = f"{api_url}/questions"
52
  submit_url = f"{api_url}/submit"
53
 
54
+ # 1. Instantiate Agent ( modify this part to create your agent)
55
  try:
56
+ agent = BasicAgent()
57
  except Exception as e:
58
  print(f"Error instantiating agent: {e}")
59
  return f"Error initializing agent: {e}", None
60
+ # 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)
61
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
62
  print(agent_code)
63
 
 
67
  response = requests.get(questions_url, timeout=15)
68
  response.raise_for_status()
69
  questions_data = response.json()
 
70
  if not questions_data:
71
+ print("Fetched questions list is empty.")
72
+ return "Fetched questions list is empty or invalid format.", None
 
73
  print(f"Fetched {len(questions_data)} questions.")
74
  except requests.exceptions.RequestException as e:
75
  print(f"Error fetching questions: {e}")
76
  return f"Error fetching questions: {e}", None
77
  except requests.exceptions.JSONDecodeError as e:
78
+ print(f"Error decoding JSON response from questions endpoint: {e}")
79
+ print(f"Response text: {response.text[:500]}")
80
+ return f"Error decoding server response for questions: {e}", None
81
  except Exception as e:
82
  print(f"An unexpected error occurred fetching questions: {e}")
83
  return f"An unexpected error occurred fetching questions: {e}", None
84
 
85
+ # 3. Run your Agent
86
  results_log = []
87
  answers_payload = []
88
+ print(f"Running agent on {len(questions_data)} questions...")
89
+ for item in questions_data:
 
 
 
 
90
  task_id = item.get("task_id")
91
  question_text = item.get("question")
 
92
  if not task_id or question_text is None:
93
  print(f"Skipping item with missing task_id or question: {item}")
94
  continue
 
 
 
95
  try:
96
  submitted_answer = agent(question_text)
97
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
98
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
99
  except Exception as e:
100
+ print(f"Error running agent on task {task_id}: {e}")
101
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
102
 
103
  if not answers_payload:
104
  print("Agent did not produce any answers to submit.")
105
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
106
 
107
+ # 4. Prepare Submission
108
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
109
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
110
  print(status_update)
 
115
  response = requests.post(submit_url, json=submission_data, timeout=60)
116
  response.raise_for_status()
117
  result_data = response.json()
 
118
  final_status = (
119
  f"Submission Successful!\n"
120
  f"User: {result_data.get('username')}\n"
 
125
  print("Submission successful.")
126
  results_df = pd.DataFrame(results_log)
127
  return final_status, results_df
 
128
  except requests.exceptions.HTTPError as e:
129
  error_detail = f"Server responded with status {e.response.status_code}."
130
  try:
 
132
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
133
  except requests.exceptions.JSONDecodeError:
134
  error_detail += f" Response: {e.response.text[:500]}"
 
135
  status_message = f"Submission Failed: {error_detail}"
136
  print(status_message)
137
  results_df = pd.DataFrame(results_log)
138
  return status_message, results_df
 
139
  except requests.exceptions.Timeout:
140
  status_message = "Submission Failed: The request timed out."
141
  print(status_message)
142
  results_df = pd.DataFrame(results_log)
143
  return status_message, results_df
 
144
  except requests.exceptions.RequestException as e:
145
  status_message = f"Submission Failed: Network error - {e}"
146
  print(status_message)
147
  results_df = pd.DataFrame(results_log)
148
  return status_message, results_df
 
149
  except Exception as e:
150
  status_message = f"An unexpected error occurred during submission: {e}"
151
  print(status_message)
152
  results_df = pd.DataFrame(results_log)
153
  return status_message, results_df
154
 
155
+
156
  # --- Build Gradio Interface using Blocks ---
157
  with gr.Blocks() as demo:
158
  gr.Markdown("# Basic Agent Evaluation Runner")
 
164
  3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
165
  ---
166
  **Disclaimers:**
167
+ 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).
168
+ 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.
169
  """
170
  )
171
+
172
  gr.LoginButton()
173
+
174
  run_button = gr.Button("Run Evaluation & Submit All Answers")
175
+
176
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
177
+ # Removed max_rows=10 from DataFrame constructor
178
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
179
+
180
  run_button.click(
181
  fn=run_and_submit_all,
182
  outputs=[status_output, results_table]
 
184
 
185
  if __name__ == "__main__":
186
  print("\n" + "-"*30 + " App Starting " + "-"*30)
 
187
  # Check for SPACE_HOST and SPACE_ID at startup for information
188
  space_host_startup = os.getenv("SPACE_HOST")
189
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
190
+
191
  if space_host_startup:
192
  print(f"✅ SPACE_HOST found: {space_host_startup}")
193
  print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
194
  else:
195
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
196
+
197
  if space_id_startup: # Print repo URLs if SPACE_ID is found
198
  print(f"✅ SPACE_ID found: {space_id_startup}")
199
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
200
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
201
  else:
202
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
203
+
204
  print("-"*(60 + len(" App Starting ")) + "\n")
205
+
206
  print("Launching Gradio Interface for Basic Agent Evaluation...")
207
+ demo.launch(debug=True, share=False)