jjvelezo commited on
Commit
0d37642
·
verified ·
1 Parent(s): 10af3d7

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +175 -42
agent.py CHANGED
@@ -1,90 +1,112 @@
1
- from smolagents import Tool, DuckDuckGoSearchTool, GoogleSearchTool, VisitWebpageTool, WikipediaSearchTool, PythonInterpreterTool, FinalAnswerTool
 
 
 
2
  from tavily import TavilyClient
3
  from dotenv import load_dotenv
4
- import os
5
 
6
- load_dotenv() # Cargar variables de entorno desde .env
 
 
 
 
 
 
 
7
 
8
- # Inicializar herramientas directamente en agent.py
9
- duck_search = DuckDuckGoSearchTool()
10
- google_search = GoogleSearchTool()
11
- visit_page = VisitWebpageTool()
12
- wiki_search = WikipediaSearchTool()
13
- do_python = PythonInterpreterTool()
14
  final_answer = FinalAnswerTool()
 
 
15
  tavily_search = TavilyClient()
16
 
17
- # Herramienta de transcripción de audio a texto
18
  speech_to_text_tool = Tool.from_space("hf-audio/whisper-large-v3-turbo",
19
  name="speech_to_text_tool",
20
- description="""Convierte un archivo de audio a texto. Usa este comando:
21
- 'speech_to_text_tool(filename)'""",
22
  api_name="/predict")
23
 
24
- # Herramienta de QA visual
25
  visual_qa_tool = Tool.from_space("sitammeur/PicQ",
26
- name="visual_qa_tool",
27
- description="""Responde preguntas sobre una imagen proporcionada.
28
- Usa el comando: visual_qa_tool(question=<pregunta>, image=<nombre_de_imagen>)""",
29
  api_name="/predict")
30
 
31
- # Inicializar el modelo de Azure OpenAI
32
- from smolagents import AzureOpenAIServerModel
33
- import app_tokens
34
-
35
- model = AzureOpenAIServerModel(
36
- model_id=app_tokens.AZURE_OPENAI_MODEL,
37
- azure_endpoint=app_tokens.AZURE_OPENAI_ENDPOINT,
38
- api_key=app_tokens.AZURE_OPENAI_API_KEY,
39
- api_version=app_tokens.OPENAI_API_VERSION
40
- )
41
-
42
  class BasicAgent:
43
  def __init__(self):
44
- # Agente de búsqueda en la web
45
  self.web_agent = CodeAgent(
46
- model=model,
47
- tools=[visit_page, wiki_search, google_search, final_answer],
 
 
 
 
 
48
  max_steps=8,
49
  name="web_agent",
50
- description="Este agente realiza búsquedas en la web.",
51
  add_base_tools=True
52
  )
53
 
54
- # Agente de conversión de audio a texto
55
  self.audio_agent = CodeAgent(
56
- model=model,
 
 
 
 
 
57
  tools=[speech_to_text_tool, final_answer],
58
  max_steps=4,
59
  name="audio_agent",
60
- description="Este agente convierte audio a texto.",
61
  add_base_tools=True
62
  )
63
 
64
- # Agente para ejecución de código Python
65
  self.py_agent = CodeAgent(
66
- model=model,
 
 
 
 
 
67
  tools=[do_python, final_answer],
68
  additional_authorized_imports=["json", "pandas", "numpy", "regex"],
69
  max_steps=8,
70
  name="python_code_agent",
71
- description="Este agente ejecuta y valida código Python.",
72
  add_base_tools=True
73
  )
74
 
75
- # Agente para análisis de imágenes
76
  self.visual_agent = CodeAgent(
77
- model=model,
 
 
 
 
 
78
  tools=[visual_qa_tool, final_answer],
79
  max_steps=4,
80
  name="visual_qa_agent",
81
- description="Este agente responde preguntas sobre imágenes.",
82
  add_base_tools=True
83
  )
84
 
85
- # Agente principal que coordina otros agentes
86
  self.manager_agent = CodeAgent(
87
- model=model,
 
 
 
 
 
88
  tools=[],
89
  managed_agents=[self.web_agent, self.audio_agent, self.py_agent, self.visual_agent],
90
  planning_interval=8,
@@ -99,3 +121,114 @@ class BasicAgent:
99
  else:
100
  result = self.manager_agent.run(question)
101
  return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import requests
4
+ from smolagents import Tool, CodeAgent, FinalAnswerTool, AzureOpenAIServerModel
5
  from tavily import TavilyClient
6
  from dotenv import load_dotenv
 
7
 
8
+ load_dotenv() # Cargar variables de entorno
9
+
10
+ # Variables de entorno
11
+ AZURE_OPENAI_MODEL = os.getenv("AZURE_OPENAI_MODEL")
12
+ AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
13
+ AZURE_OPENAI_API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
14
+ OPENAI_API_VERSION = os.getenv("OPENAI_API_VERSION")
15
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
16
 
17
+ # Herramientas definidas
18
+ duck_search = Tool.from_space("duckduckgo-search-v1", name="duck_search", description="Búsqueda en DuckDuckGo", api_name="/predict")
19
+ google_search = Tool.from_space("google-search-v1", name="google_search", description="Búsqueda en Google", api_name="/predict")
20
+ visit_page = Tool.from_space("visit-webpage-v1", name="visit_page", description="Visita páginas web", api_name="/predict")
21
+ wiki_search = Tool.from_space("wikipedia-search-v1", name="wiki_search", description="Búsqueda en Wikipedia", api_name="/predict")
22
+ do_python = Tool.from_space("python-interpreter-v1", name="do_python", description="Ejecuta código Python", api_name="/predict")
23
  final_answer = FinalAnswerTool()
24
+
25
+ # Inicializar el cliente de Tavily
26
  tavily_search = TavilyClient()
27
 
 
28
  speech_to_text_tool = Tool.from_space("hf-audio/whisper-large-v3-turbo",
29
  name="speech_to_text_tool",
30
+ description="Convierte audio en texto proporcionando un archivo o URL.",
 
31
  api_name="/predict")
32
 
 
33
  visual_qa_tool = Tool.from_space("sitammeur/PicQ",
34
+ name="visual_qa_tool",
35
+ description="Responde preguntas sobre una imagen proporcionada.",
 
36
  api_name="/predict")
37
 
38
+ # Agente básico
 
 
 
 
 
 
 
 
 
 
39
  class BasicAgent:
40
  def __init__(self):
41
+ # Agente para búsqueda web
42
  self.web_agent = CodeAgent(
43
+ model=AzureOpenAIServerModel(
44
+ model_id=AZURE_OPENAI_MODEL,
45
+ azure_endpoint=AZURE_OPENAI_ENDPOINT,
46
+ api_key=AZURE_OPENAI_API_KEY,
47
+ api_version=OPENAI_API_VERSION
48
+ ),
49
+ tools=[duck_search, google_search, wiki_search, visit_page, final_answer],
50
  max_steps=8,
51
  name="web_agent",
52
+ description="Realiza búsquedas web usando Google, DuckDuckGo y Wikipedia.",
53
  add_base_tools=True
54
  )
55
 
56
+ # Agente para convertir audio a texto
57
  self.audio_agent = CodeAgent(
58
+ model=AzureOpenAIServerModel(
59
+ model_id=AZURE_OPENAI_MODEL,
60
+ azure_endpoint=AZURE_OPENAI_ENDPOINT,
61
+ api_key=AZURE_OPENAI_API_KEY,
62
+ api_version=OPENAI_API_VERSION
63
+ ),
64
  tools=[speech_to_text_tool, final_answer],
65
  max_steps=4,
66
  name="audio_agent",
67
+ description="Convierte audio en texto.",
68
  add_base_tools=True
69
  )
70
 
71
+ # Agente para ejecutar código Python
72
  self.py_agent = CodeAgent(
73
+ model=AzureOpenAIServerModel(
74
+ model_id=AZURE_OPENAI_MODEL,
75
+ azure_endpoint=AZURE_OPENAI_ENDPOINT,
76
+ api_key=AZURE_OPENAI_API_KEY,
77
+ api_version=OPENAI_API_VERSION
78
+ ),
79
  tools=[do_python, final_answer],
80
  additional_authorized_imports=["json", "pandas", "numpy", "regex"],
81
  max_steps=8,
82
  name="python_code_agent",
83
+ description="Ejecuta y valida código Python.",
84
  add_base_tools=True
85
  )
86
 
87
+ # Agente para responder preguntas sobre imágenes
88
  self.visual_agent = CodeAgent(
89
+ model=AzureOpenAIServerModel(
90
+ model_id=AZURE_OPENAI_MODEL,
91
+ azure_endpoint=AZURE_OPENAI_ENDPOINT,
92
+ api_key=AZURE_OPENAI_API_KEY,
93
+ api_version=OPENAI_API_VERSION
94
+ ),
95
  tools=[visual_qa_tool, final_answer],
96
  max_steps=4,
97
  name="visual_qa_agent",
98
+ description="Responde preguntas sobre imágenes.",
99
  add_base_tools=True
100
  )
101
 
102
+ # Agente principal que maneja los subagentes
103
  self.manager_agent = CodeAgent(
104
+ model=AzureOpenAIServerModel(
105
+ model_id=AZURE_OPENAI_MODEL,
106
+ azure_endpoint=AZURE_OPENAI_ENDPOINT,
107
+ api_key=AZURE_OPENAI_API_KEY,
108
+ api_version=OPENAI_API_VERSION
109
+ ),
110
  tools=[],
111
  managed_agents=[self.web_agent, self.audio_agent, self.py_agent, self.visual_agent],
112
  planning_interval=8,
 
121
  else:
122
  result = self.manager_agent.run(question)
123
  return result
124
+
125
+
126
+ # Función para ejecutar el flujo de trabajo completo
127
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
128
+ """
129
+ Obtiene todas las preguntas, ejecuta el BasicAgent sobre ellas, envía las respuestas y muestra los resultados.
130
+ """
131
+ space_id = os.getenv("SPACE_ID") # Obtener el ID del espacio para enviar el enlace al código
132
+
133
+ if profile:
134
+ username = f"{profile.username}"
135
+ print(f"Usuario logueado: {username}")
136
+ else:
137
+ print("Usuario no logueado.")
138
+ return "Por favor, inicie sesión en Hugging Face.", None
139
+
140
+ api_url = DEFAULT_API_URL
141
+ questions_url = f"{api_url}/questions"
142
+ attachments_url = f"{api_url}/files/"
143
+ submit_url = f"{api_url}/submit"
144
+
145
+ try:
146
+ print("Iniciando agente...")
147
+ agent = BasicAgent() # Aquí inicializamos el agente
148
+ except Exception as e:
149
+ print(f"Error al inicializar el agente: {e}")
150
+ return f"Error al inicializar el agente: {e}", None
151
+
152
+ # 2. Obtener preguntas
153
+ print(f"Obteniendo preguntas de: {questions_url}")
154
+ try:
155
+ response = requests.get(questions_url, timeout=15)
156
+ response.raise_for_status()
157
+ questions_data = response.json()
158
+ if not questions_data:
159
+ print("La lista de preguntas está vacía.")
160
+ return "La lista de preguntas está vacía o en formato incorrecto.", None
161
+ print(f"Obtenidas {len(questions_data)} preguntas.")
162
+ for q in questions_data:
163
+ file_name = q.get("file_name", "")
164
+ task_id = q.get("task_id")
165
+ if file_name and task_id:
166
+ try:
167
+ att_response = requests.get(f"{attachments_url}{task_id}", timeout=15)
168
+ att_response.raise_for_status()
169
+ q["attachment_b64"] = att_response.text
170
+ except Exception as e:
171
+ print(f"Error al obtener archivo adjunto para tarea {task_id}: {e}")
172
+ q["attachment_b64"] = None
173
+ except requests.exceptions.RequestException as e:
174
+ print(f"Error al obtener preguntas: {e}")
175
+ return f"Error al obtener preguntas: {e}", None
176
+
177
+ # 3. Ejecutar agente sobre preguntas
178
+ results_log = []
179
+ answers_payload = []
180
+ print(f"Ejecutando agente sobre {len(questions_data)} preguntas...")
181
+ for item in questions_data:
182
+ task_id = item.get("task_id")
183
+ question_text = item.get("question", "")
184
+ attachment_b64 = item.get("attachment_b64", "")
185
+ if attachment_b64:
186
+ question_text = f"{question_text}\n\n[ATTACHMENT:]\n{attachment_b64}"
187
+ if not task_id or question_text is None:
188
+ print(f"Saltando elemento con task_id o pregunta faltante: {item}")
189
+ continue
190
+ try:
191
+ submitted_answer = agent.forward(question_text) # Aquí ejecutamos el agente para obtener la respuesta
192
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
193
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
194
+ except Exception as e:
195
+ print(f"Error ejecutando agente sobre tarea {task_id}: {e}")
196
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"ERROR AGENTE: {e}"})
197
+
198
+ if not answers_payload:
199
+ print("El agente no generó respuestas.")
200
+ return "El agente no generó respuestas.", None
201
+
202
+ # 4. Preparar la sumisión
203
+ submission_data = {"username": username.strip(), "answers": answers_payload}
204
+ print(f"Enviando respuestas para el usuario '{username}'...")
205
+
206
+ # 5. Enviar respuestas
207
+ try:
208
+ response = requests.post(submit_url, json=submission_data, timeout=60)
209
+ response.raise_for_status()
210
+ result_data = response.json()
211
+ final_status = (
212
+ f"¡Envío exitoso!\n"
213
+ f"Usuario: {result_data.get('username')}\n"
214
+ f"Puntuación total: {result_data.get('score', 'N/A')}% "
215
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correctas)"
216
+ )
217
+ print("Envío exitoso.")
218
+ return final_status, results_log
219
+ except requests.exceptions.RequestException as e:
220
+ status_message = f"Error al enviar respuestas: {e}"
221
+ print(status_message)
222
+ return status_message, results_log
223
+
224
+ # Interfaz de Gradio
225
+ with gr.Blocks() as demo:
226
+ gr.Markdown("# Evaluador de Agente Básico")
227
+ gr.LoginButton()
228
+ run_button = gr.Button("Ejecutar Evaluación y Enviar Todas las Respuestas")
229
+ status_output = gr.Textbox(label="Resultado de Ejecución / Envío", lines=5, interactive=False)
230
+ results_table = gr.DataFrame(label="Preguntas y Respuestas del Agente", wrap=True)
231
+ run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
232
+
233
+ if __name__ == "__main__":
234
+ demo.launch(debug=True, share=False)