emanuelediluzio commited on
Commit
3f9356e
·
verified ·
1 Parent(s): 37c727d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -125
app.py CHANGED
@@ -3,141 +3,135 @@ import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
6
- # ECCO LA MODIFICA QUI SOTTO:
7
- from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel
8
 
9
  # --- Constants ---
10
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  # --- Basic Agent Definition ---
13
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
14
  class BasicAgent:
15
  def __init__(self):
16
- print("Inizializzazione del VERO Agente AI...")
17
 
18
- # 1. Definisci il modello (usiamo Qwen su HF) - ECCO LA MODIFICA QUI SOTTO:
19
  self.model = InferenceClientModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct")
20
 
21
- # 2. Fornisci all'agente gli strumenti per cercare su internet
22
- self.tools = [DuckDuckGoSearchTool()]
23
 
24
- # 3. Crea l'agente
25
  self.agent = CodeAgent(
26
  tools=self.tools,
27
  model=self.model,
28
- max_steps=10,
29
- additional_authorized_imports=["requests", "bs4", "json", "time"]
30
  )
31
 
32
- # 4. IL TRUCCO PER L'EXACT MATCH: Istruzioni severissime
33
  self.prompt_template = """
34
- You must answer the following question.
35
 
36
- CRITICAL RULE (EXACT MATCH):
37
- You must output ONLY the exact requested answer.
38
- Absolutely NO introductory phrases, no "The answer is...", no "FINAL ANSWER:".
39
- Just return the raw data, word, or number.
 
40
 
41
  Question to solve: {question}
42
  """
43
 
44
  def __call__(self, question: str) -> str:
45
- print(f"Agent received question (first 50 chars): {question[:50]}...")
46
  try:
47
- # Combina la domanda con le nostre istruzioni severe
48
  formatted_prompt = self.prompt_template.format(question=question)
49
-
50
- # Fai ragionare e agire il tuo agente!
51
  answer = self.agent.run(formatted_prompt)
52
-
53
- # Pulisce la stringa da eventuali spazi extra
54
  final_answer = str(answer).strip()
 
 
 
 
 
55
  print(f"L'agente ha trovato la risposta: {final_answer}")
56
  return final_answer
57
  except Exception as e:
58
- print(f"Errore durante l'esecuzione dell'agente: {e}")
59
  return "Error"
60
 
61
 
62
  def run_and_submit_all( profile: gr.OAuthProfile | None):
63
- """
64
- Fetches all questions, runs the BasicAgent on them, submits all answers,
65
- and displays the results.
66
- """
67
- # --- Determine HF Space Runtime URL and Repo URL ---
68
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
69
 
70
  if profile:
71
  username= f"{profile.username}"
72
  print(f"User logged in: {username}")
73
  else:
74
- print("User not logged in.")
75
  return "Please Login to Hugging Face with the button.", None
76
 
77
  api_url = DEFAULT_API_URL
78
  questions_url = f"{api_url}/questions"
79
  submit_url = f"{api_url}/submit"
80
 
81
- # 1. Instantiate Agent ( modify this part to create your agent)
82
  try:
83
  agent = BasicAgent()
84
  except Exception as e:
85
- print(f"Error instantiating agent: {e}")
86
  return f"Error initializing agent: {e}", None
87
- # 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)
88
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
89
- print(agent_code)
90
 
91
- # 2. Fetch Questions
92
- print(f"Fetching questions from: {questions_url}")
93
  try:
94
  response = requests.get(questions_url, timeout=15)
95
  response.raise_for_status()
96
  questions_data = response.json()
97
  if not questions_data:
98
- print("Fetched questions list is empty.")
99
  return "Fetched questions list is empty or invalid format.", None
100
- print(f"Fetched {len(questions_data)} questions.")
101
- except requests.exceptions.RequestException as e:
102
- print(f"Error fetching questions: {e}")
103
- return f"Error fetching questions: {e}", None
104
- except requests.exceptions.JSONDecodeError as e:
105
- print(f"Error decoding JSON response from questions endpoint: {e}")
106
- print(f"Response text: {response.text[:500]}")
107
- return f"Error decoding server response for questions: {e}", None
108
  except Exception as e:
109
- print(f"An unexpected error occurred fetching questions: {e}")
110
- return f"An unexpected error occurred fetching questions: {e}", None
111
 
112
- # 3. Run your Agent
113
  results_log = []
114
  answers_payload = []
115
- print(f"Running agent on {len(questions_data)} questions...")
116
  for item in questions_data:
117
  task_id = item.get("task_id")
118
  question_text = item.get("question")
119
  if not task_id or question_text is None:
120
- print(f"Skipping item with missing task_id or question: {item}")
121
  continue
122
  try:
123
  submitted_answer = agent(question_text)
124
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
125
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
126
  except Exception as e:
127
- print(f"Error running agent on task {task_id}: {e}")
128
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
129
 
130
  if not answers_payload:
131
- print("Agent did not produce any answers to submit.")
132
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
133
 
134
- # 4. Prepare Submission
135
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
136
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
137
- print(status_update)
138
-
139
- # 5. Submit
140
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
141
  try:
142
  response = requests.post(submit_url, json=submission_data, timeout=60)
143
  response.raise_for_status()
@@ -149,61 +143,17 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
149
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
150
  f"Message: {result_data.get('message', 'No message received.')}"
151
  )
152
- print("Submission successful.")
153
- results_df = pd.DataFrame(results_log)
154
- return final_status, results_df
155
- except requests.exceptions.HTTPError as e:
156
- error_detail = f"Server responded with status {e.response.status_code}."
157
- try:
158
- error_json = e.response.json()
159
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
160
- except requests.exceptions.JSONDecodeError:
161
- error_detail += f" Response: {e.response.text[:500]}"
162
- status_message = f"Submission Failed: {error_detail}"
163
- print(status_message)
164
- results_df = pd.DataFrame(results_log)
165
- return status_message, results_df
166
- except requests.exceptions.Timeout:
167
- status_message = "Submission Failed: The request timed out."
168
- print(status_message)
169
- results_df = pd.DataFrame(results_log)
170
- return status_message, results_df
171
- except requests.exceptions.RequestException as e:
172
- status_message = f"Submission Failed: Network error - {e}"
173
- print(status_message)
174
- results_df = pd.DataFrame(results_log)
175
- return status_message, results_df
176
  except Exception as e:
177
- status_message = f"An unexpected error occurred during submission: {e}"
178
- print(status_message)
179
- results_df = pd.DataFrame(results_log)
180
- return status_message, results_df
181
-
182
 
183
  # --- Build Gradio Interface using Blocks ---
184
  with gr.Blocks() as demo:
185
  gr.Markdown("# Basic Agent Evaluation Runner")
186
- gr.Markdown(
187
- """
188
- **Instructions:**
189
-
190
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
191
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
192
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
193
-
194
- ---
195
- **Disclaimers:**
196
- 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).
197
- 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.
198
- """
199
- )
200
-
201
  gr.LoginButton()
202
-
203
  run_button = gr.Button("Run Evaluation & Submit All Answers")
204
-
205
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
206
-
207
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
208
 
209
  run_button.click(
@@ -212,25 +162,6 @@ with gr.Blocks() as demo:
212
  )
213
 
214
  if __name__ == "__main__":
215
- print("\n" + "-"*30 + " App Starting " + "-"*30)
216
- # Check for SPACE_HOST and SPACE_ID at startup for information
217
  space_host_startup = os.getenv("SPACE_HOST")
218
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
219
-
220
- if space_host_startup:
221
- print(f"✅ SPACE_HOST found: {space_host_startup}")
222
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
223
- else:
224
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
225
-
226
- if space_id_startup: # Print repo URLs if SPACE_ID is found
227
- print(f"✅ SPACE_ID found: {space_id_startup}")
228
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
229
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
230
- else:
231
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
232
-
233
- print("-"*(60 + len(" App Starting ")) + "\n")
234
-
235
- print("Launching Gradio Interface for Basic Agent Evaluation...")
236
  demo.launch(debug=True, share=False)
 
3
  import requests
4
  import inspect
5
  import pandas as pd
6
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, tool
 
7
 
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
+ # ==========================================
12
+ # 🚀 NUOVO TOOL: LETTORE DI PAGINE WEB
13
+ # ==========================================
14
+ @tool
15
+ def visit_webpage(url: str) -> str:
16
+ """Visits a webpage and returns its text content. Use this to read articles or Wikipedia pages.
17
+ Args:
18
+ url: The URL of the webpage to visit.
19
+ """
20
+ try:
21
+ import requests
22
+ from bs4 import BeautifulSoup
23
+ headers = {'User-Agent': 'Mozilla/5.0'}
24
+ response = requests.get(url, headers=headers, timeout=10)
25
+ response.raise_for_status()
26
+ soup = BeautifulSoup(response.text, 'html.parser')
27
+ # Rimuove script e stili per pulire il testo
28
+ for script in soup(["script", "style"]):
29
+ script.extract()
30
+ text = soup.get_text(separator='\n', strip=True)
31
+ # Restituisce i primi 10000 caratteri per non intasare la memoria dell'agente
32
+ return text[:10000]
33
+ except Exception as e:
34
+ return f"Error reading the webpage: {str(e)}"
35
+
36
  # --- Basic Agent Definition ---
 
37
  class BasicAgent:
38
  def __init__(self):
39
+ print("Inizializzazione dell'Agente AI POTENZIATO...")
40
 
41
+ # 1. Definisci il modello
42
  self.model = InferenceClientModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct")
43
 
44
+ # 2. Strumenti: Ricerca + Lettura Web
45
+ self.tools = [DuckDuckGoSearchTool(), visit_webpage]
46
 
47
+ # 3. Crea l'agente (aumentati i max_steps a 15 per farlo pensare di più)
48
  self.agent = CodeAgent(
49
  tools=self.tools,
50
  model=self.model,
51
+ max_steps=15,
52
+ additional_authorized_imports=["requests", "bs4", "json", "time", "math", "datetime"]
53
  )
54
 
55
+ # 4. PROMPT CORAZZATO PER EXACT MATCH
56
  self.prompt_template = """
57
+ You are an expert AI solving the GAIA benchmark. You must answer the following question.
58
 
59
+ CRITICAL RULES:
60
+ 1. If you need information, use DuckDuckGoSearchTool to find URLs, then use the visit_webpage tool to read the content of those URLs.
61
+ 2. EXACT MATCH ONLY: You must output ONLY the exact requested answer.
62
+ 3. Absolutely NO introductory phrases, no "The answer is...", no "FINAL ANSWER:".
63
+ 4. If the question asks for a number, return JUST the number. If it asks for a name, return JUST the name.
64
 
65
  Question to solve: {question}
66
  """
67
 
68
  def __call__(self, question: str) -> str:
69
+ print(f"Agent received question: {question[:50]}...")
70
  try:
 
71
  formatted_prompt = self.prompt_template.format(question=question)
 
 
72
  answer = self.agent.run(formatted_prompt)
 
 
73
  final_answer = str(answer).strip()
74
+
75
+ # Un'ultima pulizia di sicurezza se l'LLM fa di testa sua
76
+ if "FINAL ANSWER:" in final_answer:
77
+ final_answer = final_answer.split("FINAL ANSWER:")[-1].strip()
78
+
79
  print(f"L'agente ha trovato la risposta: {final_answer}")
80
  return final_answer
81
  except Exception as e:
82
+ print(f"Errore: {e}")
83
  return "Error"
84
 
85
 
86
  def run_and_submit_all( profile: gr.OAuthProfile | None):
87
+ space_id = os.getenv("SPACE_ID")
 
 
 
 
 
88
 
89
  if profile:
90
  username= f"{profile.username}"
91
  print(f"User logged in: {username}")
92
  else:
 
93
  return "Please Login to Hugging Face with the button.", None
94
 
95
  api_url = DEFAULT_API_URL
96
  questions_url = f"{api_url}/questions"
97
  submit_url = f"{api_url}/submit"
98
 
 
99
  try:
100
  agent = BasicAgent()
101
  except Exception as e:
 
102
  return f"Error initializing agent: {e}", None
103
+
104
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
 
105
 
 
 
106
  try:
107
  response = requests.get(questions_url, timeout=15)
108
  response.raise_for_status()
109
  questions_data = response.json()
110
  if not questions_data:
 
111
  return "Fetched questions list is empty or invalid format.", None
 
 
 
 
 
 
 
 
112
  except Exception as e:
113
+ return f"Error fetching questions: {e}", None
 
114
 
 
115
  results_log = []
116
  answers_payload = []
117
+
118
  for item in questions_data:
119
  task_id = item.get("task_id")
120
  question_text = item.get("question")
121
  if not task_id or question_text is None:
 
122
  continue
123
  try:
124
  submitted_answer = agent(question_text)
125
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
126
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
127
  except Exception as e:
 
128
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
129
 
130
  if not answers_payload:
 
131
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
132
 
 
133
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
134
+
 
 
 
 
135
  try:
136
  response = requests.post(submit_url, json=submission_data, timeout=60)
137
  response.raise_for_status()
 
143
  f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
144
  f"Message: {result_data.get('message', 'No message received.')}"
145
  )
146
+ return final_status, pd.DataFrame(results_log)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  except Exception as e:
148
+ status_message = f"Submission Failed: {e}"
149
+ return status_message, pd.DataFrame(results_log)
 
 
 
150
 
151
  # --- Build Gradio Interface using Blocks ---
152
  with gr.Blocks() as demo:
153
  gr.Markdown("# Basic Agent Evaluation Runner")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  gr.LoginButton()
 
155
  run_button = gr.Button("Run Evaluation & Submit All Answers")
 
156
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
157
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
158
 
159
  run_button.click(
 
162
  )
163
 
164
  if __name__ == "__main__":
 
 
165
  space_host_startup = os.getenv("SPACE_HOST")
166
+ space_id_startup = os.getenv("SPACE_ID")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  demo.launch(debug=True, share=False)