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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -56
app.py CHANGED
@@ -1,105 +1,127 @@
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, 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
 
@@ -108,13 +130,14 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
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")
@@ -128,7 +151,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
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
 
@@ -137,24 +160,24 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
137
  response.raise_for_status()
138
  result_data = response.json()
139
  final_status = (
140
- f"Submission Successful!\n"
141
- f"User: {result_data.get('username')}\n"
142
- f"Overall Score: {result_data.get('score', 'N/A')}% "
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(
160
  fn=run_and_submit_all,
 
1
  import os
2
+ import re
3
  import gradio as gr
4
  import requests
 
5
  import pandas as pd
6
+ from bs4 import BeautifulSoup
7
  from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, tool
8
 
9
  # --- Constants ---
10
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
11
 
12
  # ==========================================
13
+ # 🚀 TOOL 1: RICERCA E LETTURA WEB AVANZATA
14
  # ==========================================
15
  @tool
16
  def visit_webpage(url: str) -> str:
17
+ """Visits a webpage and extracts its main clean text. Use this to read Wikipedia, news, or articles.
18
  Args:
19
  url: The URL of the webpage to visit.
20
  """
21
  try:
22
+ headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
23
+ response = requests.get(url, headers=headers, timeout=15)
 
 
24
  response.raise_for_status()
25
+
26
  soup = BeautifulSoup(response.text, 'html.parser')
27
+ # Rimuove tutto ciò che non è testo utile
28
+ for element in soup(["script", "style", "nav", "footer", "header", "aside"]):
29
+ element.extract()
30
+
31
  text = soup.get_text(separator='\n', strip=True)
32
+ # Prende i primi 15000 caratteri di puro testo informativo
33
+ return text[:15000]
34
  except Exception as e:
35
  return f"Error reading the webpage: {str(e)}"
36
 
37
+ # ==========================================
38
+ # 🧠 IL SUPER AGENTE
39
+ # ==========================================
40
+ class SuperAgent:
41
  def __init__(self):
42
+ print("Inizializzazione del SUPER Agente AI in corso...")
43
 
44
+ # 1. Modello
45
  self.model = InferenceClientModel(model_id="Qwen/Qwen2.5-Coder-32B-Instruct")
46
 
47
+ # 2. Tools
48
  self.tools = [DuckDuckGoSearchTool(), visit_webpage]
49
 
50
+ # 3. Agente (Potenza massima, importazioni analitiche sbloccate)
51
  self.agent = CodeAgent(
52
  tools=self.tools,
53
  model=self.model,
54
+ max_steps=20, # Aumentati i tentativi a 20!
55
+ additional_authorized_imports=[
56
+ "requests", "bs4", "json", "time", "math", "datetime",
57
+ "pandas", "numpy", "re", "csv", "urllib"
58
+ ]
59
  )
60
 
61
+ # 4. Prompt Estremo per GAIA
62
  self.prompt_template = """
63
+ You are an elite AI data analyst solving the GAIA benchmark.
64
+ You are provided with a question. You MUST use your tools to find the answer.
65
 
66
+ CRITICAL RULES FOR YOUR FINAL OUTPUT:
67
+ 1. EXACT MATCH ONLY: Output ONLY the final answer. Nothing else.
68
+ 2. If the answer is a number, return JUST the number (e.g., '14' or '1998').
69
+ 3. If the answer is a name/word, return JUST the word.
70
+ 4. NEVER use phrases like "The answer is", "Based on my search", or "FINAL ANSWER:".
71
+ 5. If the question requires math, date calculation, or text processing, write the Python code to solve it internally.
72
 
73
+ Question: {question}
74
  """
75
 
76
  def __call__(self, question: str) -> str:
77
+ print(f"\n[DOMANDA RICEVUTA]: {question[:80]}...")
78
  try:
79
  formatted_prompt = self.prompt_template.format(question=question)
80
+ raw_answer = self.agent.run(formatted_prompt)
81
+ final_answer = str(raw_answer).strip()
82
 
83
+ # --- FILTRO ANTI-BLABLA ---
84
+ # Se l'LLM si ostina a inserire testo, lo forziamo a tacere tagliando le frasi comuni.
85
+ prefixes_to_cut = ["The answer is", "FINAL ANSWER:", "Answer:", "final answer is", "The requested word is", "The highest number is"]
86
+ for prefix in prefixes_to_cut:
87
+ if prefix.lower() in final_answer.lower():
88
+ idx = final_answer.lower().rfind(prefix.lower()) + len(prefix)
89
+ final_answer = final_answer[idx:].strip()
90
+
91
+ # Toglie il punto finale se l'ha messo per sbaglio (es. "1994." -> "1994")
92
+ if final_answer.endswith('.'):
93
+ final_answer = final_answer[:-1]
94
 
95
+ # Toglie virgolette extra o asterischi di formattazione Markdown
96
+ final_answer = final_answer.replace("**", "").replace('"', "").replace("'", "")
97
+
98
+ print(f"[RISPOSTA PULITA TROVATA]: {final_answer}")
99
  return final_answer
100
  except Exception as e:
101
+ print(f"Errore durante l'elaborazione: {e}")
102
  return "Error"
103
 
104
 
105
+ # ==========================================
106
+ # ⚙️ INTERFACCIA E RUNNER
107
+ # ==========================================
108
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
109
  space_id = os.getenv("SPACE_ID")
110
 
111
  if profile:
112
+ username = f"{profile.username}"
113
+ print(f"Utente autenticato: {username}")
114
  else:
115
+ return "Per favore, fai il Login con Hugging Face usando l'apposito tasto.", None
116
 
117
  api_url = DEFAULT_API_URL
118
  questions_url = f"{api_url}/questions"
119
  submit_url = f"{api_url}/submit"
120
 
121
  try:
122
+ agent = SuperAgent()
123
  except Exception as e:
124
+ return f"Errore nell'inizializzazione dell'agente: {e}", None
125
 
126
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
127
 
 
130
  response.raise_for_status()
131
  questions_data = response.json()
132
  if not questions_data:
133
+ return "La lista delle domande scaricata è vuota.", None
134
  except Exception as e:
135
+ return f"Errore nel download delle domande: {e}", None
136
 
137
  results_log = []
138
  answers_payload = []
139
 
140
+ print(f"Avvio elaborazione su {len(questions_data)} domande...")
141
  for item in questions_data:
142
  task_id = item.get("task_id")
143
  question_text = item.get("question")
 
151
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
152
 
153
  if not answers_payload:
154
+ return "L'agente non ha prodotto risposte da inviare.", pd.DataFrame(results_log)
155
 
156
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
157
 
 
160
  response.raise_for_status()
161
  result_data = response.json()
162
  final_status = (
163
+ f" Invio Completato con Successo!\n"
164
+ f"👤 Utente: {result_data.get('username')}\n"
165
+ f"🏆 Punteggio: {result_data.get('score', 'N/A')}% "
166
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} corrette)\n"
167
+ f"📝 Messaggio: {result_data.get('message', 'Nessun messaggio ricevuto.')}"
168
  )
169
  return final_status, pd.DataFrame(results_log)
170
  except Exception as e:
171
+ status_message = f" Invio Fallito: {e}"
172
  return status_message, pd.DataFrame(results_log)
173
 
174
+ # --- Build Gradio Interface ---
175
  with gr.Blocks() as demo:
176
+ gr.Markdown("# 🚀 Super Agente - Final Assignment Runner")
177
  gr.LoginButton()
178
+ run_button = gr.Button("Avvia Valutazione & Invia Risposte", variant="primary")
179
+ status_output = gr.Textbox(label="Stato Esecuzione / Risultato", lines=5, interactive=False)
180
+ results_table = gr.DataFrame(label="Domande e Risposte dell'Agente", wrap=True)
181
 
182
  run_button.click(
183
  fn=run_and_submit_all,