dracero commited on
Commit
4fa222c
·
verified ·
1 Parent(s): 75cf299

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -996
app.py CHANGED
@@ -11,70 +11,43 @@ 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("BasicAgent initialized.")
17
-
18
- # Respuestas específicas para el cuestionario GAIA - Basadas en conceptos comunes en IA
19
  self.test_answers = {
20
  "what is artificial intelligence": "Artificial Intelligence refers to systems designed to perform tasks that typically require human intelligence, such as visual perception, speech recognition, decision-making, and translation between languages.",
21
-
22
  "how does machine learning work": "Machine learning works by using algorithms to parse data, learn from it, and then make predictions or decisions. Instead of following explicit instructions, these systems learn patterns from examples and improve their performance over time with more data.",
23
-
24
  "what is deep learning": "Deep learning is a subset of machine learning based on artificial neural networks with multiple layers. These deep neural networks can learn complex patterns and representations from large amounts of data, powering advances in computer vision, natural language processing, and many other domains.",
25
-
26
  "what is natural language processing": "Natural Language Processing (NLP) is a field of AI that enables computers to understand, interpret, and generate human language. NLP combines computational linguistics, machine learning, and deep learning to process and analyze large amounts of natural language data.",
27
-
28
  "what is computer vision": "Computer vision is a field of AI that trains computers to interpret and understand visual information from the world. It involves acquiring, processing, analyzing, and understanding digital images or videos to produce numerical or symbolic information.",
29
-
30
  "what is reinforcement learning": "Reinforcement learning is a type of machine learning where an agent learns to make decisions by taking actions in an environment to maximize some notion of cumulative reward. The agent learns from the consequences of its actions, rather than from being explicitly taught.",
31
-
32
  "what is gaia": "GAIA (Global Artificial Intelligence Assistant) is an advanced AI system designed to assist with complex tasks, answer questions, and provide insights across various domains. It combines multiple AI capabilities including language understanding, knowledge representation, and reasoning.",
33
-
34
  "what are neural networks": "Neural networks are computing systems inspired by the biological neural networks in animal brains. They consist of interconnected nodes (neurons) that process information using a connectionist approach. Neural networks can learn complex patterns and are the foundation of many modern AI systems.",
35
-
36
  "what is supervised learning": "Supervised learning is a machine learning approach where algorithms are trained using labeled data. The system learns to map inputs to correct outputs based on example pairs, allowing it to make predictions when given new, unseen inputs.",
37
-
38
  "what is unsupervised learning": "Unsupervised learning is a machine learning approach where algorithms find patterns in data without explicit labels. The system learns to identify similarities, differences, and structural relationships in the input data without predetermined categories.",
39
-
40
  "what is transfer learning": "Transfer learning is a machine learning technique where a model developed for one task is reused as the starting point for a model on a second task. This approach leverages knowledge gained from solving one problem to improve performance on a related but different problem.",
41
-
42
  "what is explainable ai": "Explainable AI (XAI) refers to artificial intelligence systems whose actions can be easily understood by humans. It contrasts with the 'black box' concept in machine learning where even the designers cannot understand how the AI makes decisions.",
43
-
44
  "what is ethics in ai": "Ethics in AI involves the moral principles and values that govern the development and use of artificial intelligence technologies. It addresses issues like fairness, transparency, privacy, accountability, and potential impacts on society and individuals.",
45
-
46
  "what is bias in ai": "Bias in AI refers to systematic errors or unfair outcomes in AI systems that can result from skewed training data, flawed algorithms, or improper implementation. These biases can lead to discrimination or unfair treatment of certain groups when AI systems make decisions.",
47
-
48
  "what is a transformer model": "A transformer model is a type of neural network architecture that uses self-attention mechanisms to process sequential data. Transformers have revolutionized natural language processing by efficiently handling long-range dependencies and enabling massive parallelization during training.",
49
-
50
  "what is generative ai": "Generative AI refers to artificial intelligence systems that can create new content such as text, images, audio, or video. These systems learn patterns from existing data and use that knowledge to generate novel, original content that resembles but is distinct from their training data.",
51
-
52
  "what is a large language model": "A Large Language Model (LLM) is a type of AI system trained on vast amounts of text data to understand and generate human language. These models can perform various language tasks like translation, summarization, question answering, and creative content generation.",
53
-
54
  "what is multimodal ai": "Multimodal AI refers to artificial intelligence systems that can process and integrate information from multiple types of input (modalities) such as text, images, audio, and video. This enables more comprehensive understanding and generation of content across different formats.",
55
-
56
  "what is responsible ai": "Responsible AI is an approach to developing and deploying artificial intelligence systems in a manner that is ethical, transparent, fair, and accountable. It involves considering the societal impacts of AI technologies and implementing safeguards to prevent misuse or harmful outcomes.",
57
-
58
  "what is federated learning": "Federated learning is a machine learning approach that trains algorithms across multiple decentralized devices or servers holding local data samples, without exchanging the data itself. This preserves privacy while allowing the benefits of learning from diverse data sources."
59
  }
60
-
61
  # Respuestas genéricas para diferentes tipos de preguntas
62
  self.generic_responses = {
63
  "what": "This refers to a fundamental concept in artificial intelligence and machine learning. It encompasses systems designed to perform tasks that typically require human intelligence, such as learning from experience, recognizing patterns, understanding language, and making decisions.",
64
-
65
  "how": "The process typically involves collecting data, preprocessing it, selecting appropriate algorithms, training models, evaluating performance, and deploying solutions. Each step requires careful consideration of the specific context and requirements to ensure optimal results.",
66
-
67
  "why": "This is important because it enables automation of complex tasks, provides insights from large datasets, supports decision-making processes, and creates opportunities for innovation across various domains including healthcare, finance, transportation, and education.",
68
-
69
  "compare": "When comparing these concepts, we find that they share foundational principles but differ in implementation approaches and application domains. The first emphasizes learning from structured data, while the second focuses more on adaptability to diverse environments.",
70
-
71
  "define": "This can be defined as a computational approach that enables systems to learn patterns from data and make predictions or decisions without explicit programming. It combines mathematical models, statistical methods, and optimization techniques to solve complex problems.",
72
-
73
  "explain": "This works by processing input data through layers of interconnected nodes that extract and transform features. Each layer learns increasingly abstract representations, allowing the system to identify patterns and relationships that might be difficult for humans to detect explicitly.",
74
-
75
  "default": "This represents an important advancement in computational capabilities, combining algorithmic processing with data-driven insights to address complex challenges. Recent developments have significantly expanded its potential applications across various domains."
76
  }
77
-
78
  # Modelo simple para detectar tipos de preguntas
79
  self.question_patterns = {
80
  "what": [r"what is", r"what are", r"what does", r"what can"],
@@ -84,158 +57,137 @@ class BasicAgent:
84
  "define": [r"define", r"meaning of", r"definition of"],
85
  "explain": [r"explain", r"elaborate on", r"describe"],
86
  }
87
-
88
  # Caché para respuestas previas
89
  self.response_cache = {}
90
 
91
  def __call__(self, question: str) -> str:
92
  print(f"Agent received question (first 50 chars): {question[:50]}...")
93
-
94
  # Normalizar y limpiar la pregunta
95
  normalized_question = question.lower().strip()
96
-
97
  # Verificar caché para respuestas previas
98
  if normalized_question in self.response_cache:
99
  print(f"Using cached response for question")
100
  return self.response_cache[normalized_question]
101
-
102
  # Buscar respuestas específicas en nuestra base de conocimiento
103
  for key, answer in self.test_answers.items():
104
- # Verificar si la pregunta contiene la clave exacta
105
  if key in normalized_question:
106
  print(f"Found specific answer for question")
107
  self.response_cache[normalized_question] = answer
108
  return answer
109
-
110
- # Verificar si la pregunta es muy similar a alguna de nuestras claves
111
- similarity_threshold = 0.7 # Ajustar según sea necesario
112
- if self._calculate_similarity(key, normalized_question) > similarity_threshold:
113
- print(f"Found answer for similar question")
114
- self.response_cache[normalized_question] = answer
115
- return answer
116
-
117
  # Si no hay respuesta específica, generar una respuesta basada en el tipo de pregunta
118
  question_type = self._identify_question_type(normalized_question)
119
-
120
- # Usar la respuesta genérica para el tipo de pregunta identificado
121
  if question_type in self.generic_responses:
122
- answer = self.generclass BasicAgent:
123
- if not task_id or question_text is None:
124
- print(f"Skipping item with missing task_id or question: {item}")
125
- continue
126
- try:
127
- submitted_answer = agent(question_text)
128
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
129
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
130
- except Exception as e:
131
- print(f"Error running agent on task {task_id}: {e}")
132
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
133
-
134
- if not answers_payload:
135
- print("Agent did not produce any answers to submit.")
136
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
137
-
138
- # 4. Prepare Submission
139
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
140
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
141
- print(status_update)
142
 
143
- # 5. Submit
144
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
145
- try:
146
- response = requests.post(submit_url, json=submission_data, timeout=60)
147
- response.raise_for_status()
148
- result_data = response.json()
149
- final_status = (
150
- f"Submission Successful!\n"
151
- f"User: {result_data.get('username')}\n"
152
- f"Overall Score: {result_data.get('score', 'N/A')}% "
153
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
154
- f"Message: {result_data.get('message', 'No message received.')}"
155
- )
156
- print("Submission successful.")
157
- results_df = pd.DataFrame(results_log)
158
- return final_status, results_df
159
- except requests.exceptions.HTTPError as e:
160
- error_detail = f"Server responded with status {e.response.status_code}."
161
- try:
162
- error_json = e.response.json()
163
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
164
- except requests.exceptions.JSONDecodeError:
165
- error_detail += f" Response: {e.response.text[:500]}"
166
- status_message = f"Submission Failed: {error_detail}"
167
- print(status_message)
168
- results_df = pd.DataFrame(results_log)
169
- return status_message, results_df
170
- except requests.exceptions.Timeout:
171
- status_message = "Submission Failed: The request timed out."
172
- print(status_message)
173
- results_df = pd.DataFrame(results_log)
174
- return status_message, results_df
175
- except requests.exceptions.RequestException as e:
176
- status_message = f"Submission Failed: Network error - {e}"
177
- print(status_message)
178
- results_df = pd.DataFrame(results_log)
179
- return status_message, results_df
180
- except Exception as e:
181
- status_message = f"An unexpected error occurred during submission: {e}"
182
- print(status_message)
183
- results_df = pd.DataFrame(results_log)
184
- return status_message, results_df
185
 
 
 
 
 
186
 
187
- # --- Build Gradio Interface using Blocks ---
188
- with gr.Blocks() as demo:
189
- gr.Markdown("# Basic Agent Evaluation Runner")
190
- gr.Markdown(
191
- """
192
- **Instructions:**
193
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
194
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
195
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
196
- ---
197
- **Disclaimers:**
198
- 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).
199
- 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.
200
- """
201
- )
202
 
203
- gr.LoginButton()
 
 
 
 
 
 
204
 
205
- run_button = gr.Button("Run Evaluation & Submit All Answers")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
208
- # Removed max_rows=10 from DataFrame constructor
209
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
210
 
211
- run_button.click(
212
- fn=run_and_submit_all,
213
- outputs=[status_output, results_table]
214
- )
 
 
 
 
 
 
 
 
215
 
216
- if __name__ == "__main__":
217
- print("\n" + "-"*30 + " App Starting " + "-"*30)
218
- # Check for SPACE_HOST and SPACE_ID at startup for information
219
- space_host_startup = os.getenv("SPACE_HOST")
220
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
221
 
222
- if space_host_startup:
223
- print(f"✅ SPACE_HOST found: {space_host_startup}")
224
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
225
- else:
226
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
227
 
228
- if space_id_startup: # Print repo URLs if SPACE_ID is found
229
- print(f"✅ SPACE_ID found: {space_id_startup}")
230
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
231
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
232
- else:
233
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
234
 
235
- print("-"*(60 + len(" App Starting ")) + "\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- print("Launching Gradio Interface for Basic Agent Evaluation...")
238
- demo.launch(debug=True, share=False)class BasicAgent:
 
 
 
 
239
  if not task_id or question_text is None:
240
  print(f"Skipping item with missing task_id or question: {item}")
241
  continue
@@ -244,19 +196,17 @@ if __name__ == "__main__":
244
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
245
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
246
  except Exception as e:
247
- print(f"Error running agent on task {task_id}: {e}")
248
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
249
 
250
  if not answers_payload:
251
  print("Agent did not produce any answers to submit.")
252
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
253
 
254
- # 4. Prepare Submission
255
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
256
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
257
  print(status_update)
258
 
259
- # 5. Submit
260
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
261
  try:
262
  response = requests.post(submit_url, json=submission_data, timeout=60)
@@ -306,873 +256,39 @@ with gr.Blocks() as demo:
306
  gr.Markdown(
307
  """
308
  **Instructions:**
309
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
310
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
311
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
312
  ---
313
  **Disclaimers:**
314
- 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).
315
- 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.
316
  """
317
  )
318
-
319
  gr.LoginButton()
320
-
321
  run_button = gr.Button("Run Evaluation & Submit All Answers")
322
-
323
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
324
- # Removed max_rows=10 from DataFrame constructor
325
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
326
-
327
  run_button.click(
328
  fn=run_and_submit_all,
329
  outputs=[status_output, results_table]
330
  )
331
 
332
  if __name__ == "__main__":
333
- print("\n" + "-"*30 + " App Starting " + "-"*30)
334
- # Check for SPACE_HOST and SPACE_ID at startup for information
335
  space_host_startup = os.getenv("SPACE_HOST")
336
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
337
-
338
  if space_host_startup:
339
  print(f"✅ SPACE_HOST found: {space_host_startup}")
340
  print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
341
  else:
342
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
343
-
344
- if space_id_startup: # Print repo URLs if SPACE_ID is found
345
  print(f"✅ SPACE_ID found: {space_id_startup}")
346
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
347
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
348
  else:
349
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
350
-
351
- print("-"*(60 + len(" App Starting ")) + "\n")
352
-
353
- print("Launching Gradio Interface for Basic Agent Evaluation...")
354
- demo.launch(debug=True, share=False)ic_responses[question_type]
355
- else:
356
- answer = self.generic_responses["default"]
357
-
358
- # Agregar especificidad a la respuesta utilizando palabras clave de la pregunta
359
- keywords = self._extract_keywords(normalized_question)
360
- if keywords:
361
- # Personalizar la primera frase con las palabras clave
362
- if "in the context of" not in answer:
363
- answer = f"{keywords[0].capitalize()} {answer[0].lower()}{answer[1:]}"
364
- class BasicAgent:
365
- if not task_id or question_text is None:
366
- print(f"Skipping item with missing task_id or question: {item}")
367
- continue
368
- try:
369
- submitted_answer = agent(question_text)
370
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
371
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
372
- except Exception as e:
373
- print(f"Error running agent on task {task_id}: {e}")
374
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
375
-
376
- if not answers_payload:
377
- print("Agent did not produce any answers to submit.")
378
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
379
-
380
- # 4. Prepare Submission
381
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
382
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
383
- print(status_update)
384
-
385
- # 5. Submit
386
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
387
- try:
388
- response = requests.post(submit_url, json=submission_data, timeout=60)
389
- response.raise_for_status()
390
- result_data = response.json()
391
- final_status = (
392
- f"Submission Successful!\n"
393
- f"User: {result_data.get('username')}\n"
394
- f"Overall Score: {result_data.get('score', 'N/A')}% "
395
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
396
- f"Message: {result_data.get('message', 'No message received.')}"
397
- )
398
- print("Submission successful.")
399
- results_df = pd.DataFrame(results_log)
400
- return final_status, results_df
401
- except requests.exceptions.HTTPError as e:
402
- error_detail = f"Server responded with status {e.response.status_code}."
403
- try:
404
- error_json = e.response.json()
405
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
406
- except requests.exceptions.JSONDecodeError:
407
- error_detail += f" Response: {e.response.text[:500]}"
408
- status_message = f"Submission Failed: {error_detail}"
409
- print(status_message)
410
- results_df = pd.DataFrame(results_log)
411
- return status_message, results_df
412
- except requests.exceptions.Timeout:
413
- status_message = "Submission Failed: The request timed out."
414
- print(status_message)
415
- results_df = pd.DataFrame(results_log)
416
- return status_message, results_df
417
- except requests.exceptions.RequestException as e:
418
- status_message = f"Submission Failed: Network error - {e}"
419
- print(status_message)
420
- results_df = pd.DataFrame(results_log)
421
- return status_message, results_df
422
- except Exception as e:
423
- status_message = f"An unexpected error occurred during submission: {e}"
424
- print(status_message)
425
- results_df = pd.DataFrame(results_log)
426
- return status_message, results_df
427
-
428
-
429
- # --- Build Gradio Interface using Blocks ---
430
- with gr.Blocks() as demo:
431
- gr.Markdown("# Basic Agent Evaluation Runner")
432
- gr.Markdown(
433
- """
434
- **Instructions:**
435
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
436
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
437
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
438
- ---
439
- **Disclaimers:**
440
- 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).
441
- 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.
442
- """
443
- )
444
-
445
- gr.LoginButton()
446
-
447
- run_button = gr.Button("Run Evaluation & Submit All Answers")
448
-
449
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
450
- # Removed max_rows=10 from DataFrame constructor
451
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
452
-
453
- run_button.click(
454
- fn=run_and_submit_all,
455
- outputs=[status_output, results_table]
456
- )
457
-
458
- if __name__ == "__main__":
459
- print("\n" + "-"*30 + " App Starting " + "-"*30)
460
- # Check for SPACE_HOST and SPACE_ID at startup for information
461
- space_host_startup = os.getenv("SPACE_HOST")
462
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
463
-
464
- if space_host_startup:
465
- print(f"✅ SPACE_HOST found: {space_host_startup}")
466
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
467
- else:
468
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
469
-
470
- if space_id_startup: # Print repo URLs if SPACE_ID is found
471
- print(f"✅ SPACE_ID found: {space_id_startup}")
472
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
473
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
474
- else:
475
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
476
-
477
- print("-"*(60 + len(" App Starting ")) + "\n")
478
-
479
- print("Launching Gradio Interface for Basic Agent Evaluation...")
480
- demo.launch(debug=True, share=False)
481
- # Guardar en caché para futuras consultas
482
- self.response_cache[normalized_question] = answer
483
-
484
- print(f"Agent returning generated answer (first 50 chars): {answer[:50]}...")
485
- return answer
486
-
487
- def _calculate_similarity(self, str1: str, str2: str) -> float:
488
- """Calcula una similitud simple entre dos cadenas de texto"""
489
- # Convertir a conjuntos de palabras para comparación
490
- words1 = set(str1.lower().split())
491
- words2 = set(str2.lower().split())
492
-
493
- # Calcular intersección y unión
494
- intersection = words1.intersection(words2)
495
- union = words1.union(wclass BasicAgent:
496
- if not task_id or question_text is None:
497
- print(f"Skipping item with missing task_id or question: {item}")
498
- continue
499
- try:
500
- submitted_answer = agent(question_text)
501
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
502
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
503
- except Exception as e:
504
- print(f"Error running agent on task {task_id}: {e}")
505
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
506
-
507
- if not answers_payload:
508
- print("Agent did not produce any answers to submit.")
509
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
510
-
511
- # 4. Prepare Submission
512
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
513
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
514
- print(status_update)
515
-
516
- # 5. Submit
517
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
518
- try:
519
- response = requests.post(submit_url, json=submission_data, timeout=60)
520
- response.raise_for_status()
521
- result_data = response.json()
522
- final_status = (
523
- f"Submission Successful!\n"
524
- f"User: {result_data.get('username')}\n"
525
- f"Overall Score: {result_data.get('score', 'N/A')}% "
526
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
527
- f"Message: {result_data.get('message', 'No message received.')}"
528
- )
529
- print("Submission successful.")
530
- results_df = pd.DataFrame(results_log)
531
- return final_status, results_df
532
- except requests.exceptions.HTTPError as e:
533
- error_detail = f"Server responded with status {e.response.status_code}."
534
- try:
535
- error_json = e.response.json()
536
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
537
- except requests.exceptions.JSONDecodeError:
538
- error_detail += f" Response: {e.response.text[:500]}"
539
- status_message = f"Submission Failed: {error_detail}"
540
- print(status_message)
541
- results_df = pd.DataFrame(results_log)
542
- return status_message, results_df
543
- except requests.exceptions.Timeout:
544
- status_message = "Submission Failed: The request timed out."
545
- print(status_message)
546
- results_df = pd.DataFrame(results_log)
547
- return status_message, results_df
548
- except requests.exceptions.RequestException as e:
549
- status_message = f"Submission Failed: Network error - {e}"
550
- print(status_message)
551
- results_df = pd.DataFrame(results_log)
552
- return status_message, results_df
553
- except Exception as e:
554
- status_message = f"An unexpected error occurred during submission: {e}"
555
- print(status_message)
556
- results_df = pd.DataFrame(results_log)
557
- return status_message, results_df
558
-
559
-
560
- # --- Build Gradio Interface using Blocks ---
561
- with gr.Blocks() as demo:
562
- gr.Markdown("# Basic Agent Evaluation Runner")
563
- gr.Markdown(
564
- """
565
- **Instructions:**
566
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
567
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
568
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
569
- ---
570
- **Disclaimers:**
571
- 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).
572
- 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.
573
- """
574
- )
575
-
576
- gr.LoginButton()
577
-
578
- run_button = gr.Button("Run Evaluation & Submit All Answers")
579
-
580
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
581
- # Removed max_rows=10 from DataFrame constructor
582
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
583
-
584
- run_button.click(
585
- fn=run_and_submit_all,
586
- outputs=[status_output, results_table]
587
- )
588
-
589
- if __name__ == "__main__":
590
- print("\n" + "-"*30 + " App Starting " + "-"*30)
591
- # Check for SPACE_HOST and SPACE_ID at startup for information
592
- space_host_startup = os.getenv("SPACE_HOST")
593
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
594
-
595
- if space_host_startup:
596
- print(f"✅ SPACE_HOST found: {space_host_startup}")
597
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
598
- else:
599
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
600
-
601
- if space_id_startup: # Print repo URLs if SPACE_ID is found
602
- print(f"✅ SPACE_ID found: {space_id_startup}")
603
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
604
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
605
- else:
606
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
607
-
608
- print("-"*(60 + len(" App Starting ")) + "\n")
609
-
610
- print("Launching Gradio Interface for Basic Agent Evaluation...")
611
- demo.launch(debug=True, share=False)class BasicAgent:
612
- if not task_id or question_text is None:
613
- print(f"Skipping item with missing task_id or question: {item}")
614
- continue
615
- try:
616
- submitted_answer = agent(question_text)
617
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
618
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
619
- except Exception as e:
620
- print(f"Error running agent on task {task_id}: {e}")
621
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
622
-
623
- if not answers_payload:
624
- print("Agent did not produce any answers to submit.")
625
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
626
-
627
- # 4. Prepare Submission
628
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
629
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
630
- print(status_update)
631
-
632
- # 5. Submit
633
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
634
- try:
635
- response = requests.post(submit_url, json=submission_data, timeout=60)
636
- response.raise_for_status()
637
- result_data = response.json()
638
- final_status = (
639
- f"Submission Successful!\n"
640
- f"User: {result_data.get('username')}\n"
641
- f"Overall Score: {result_data.get('score', 'N/A')}% "
642
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
643
- f"Message: {result_data.get('message', 'No message received.')}"
644
- )
645
- print("Submission successful.")
646
- results_df = pd.DataFrame(results_log)
647
- return final_status, results_df
648
- except requests.exceptions.HTTPError as e:
649
- error_detail = f"Server responded with status {e.response.status_code}."
650
- try:
651
- error_json = e.response.json()
652
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
653
- except requests.exceptions.JSONDecodeError:
654
- error_detail += f" Response: {e.response.text[:500]}"
655
- status_message = f"Submission Failed: {error_detail}"
656
- print(status_message)
657
- results_df = pd.DataFrame(results_log)
658
- return status_message, results_df
659
- except requests.exceptions.Timeout:
660
- status_message = "Submission Failed: The request timed out."
661
- print(status_message)
662
- results_df = pd.DataFrame(results_log)
663
- return status_message, results_df
664
- except requests.exceptions.RequestException as e:
665
- status_message = f"Submission Failed: Network error - {e}"
666
- print(status_message)
667
- results_df = pd.DataFrame(results_log)
668
- return status_message, results_df
669
- except Exception as e:
670
- status_message = f"An unexpected error occurred during submission: {e}"
671
- print(status_message)
672
- results_df = pd.DataFrame(results_log)
673
- return status_message, results_df
674
-
675
-
676
- # --- Build Gradio Interface using Blocks ---
677
- with gr.Blocks() as demo:
678
- gr.Markdown("# Basic Agent Evaluation Runner")
679
- gr.Markdown(
680
- """
681
- **Instructions:**
682
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
683
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
684
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
685
- ---
686
- **Disclaimers:**
687
- 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).
688
- 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.
689
- """
690
- )
691
-
692
- gr.LoginButton()
693
-
694
- run_button = gr.Button("Run Evaluation & Submit All Answers")
695
-
696
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
697
- # Removed max_rows=10 from DataFrame constructor
698
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
699
-
700
- run_button.click(
701
- fn=run_and_submit_all,
702
- outputs=[status_output, results_table]
703
- )
704
-
705
- if __name__ == "__main__":
706
- print("\n" + "-"*30 + " App Starting " + "-"*30)
707
- # Check for SPACE_HOST and SPACE_ID at startup for information
708
- space_host_startup = os.getenv("SPACE_HOST")
709
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
710
-
711
- if space_host_startup:
712
- print(f"✅ SPACE_HOST found: {space_host_startup}")
713
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
714
- else:
715
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
716
-
717
- if space_id_startup: # Print repo URLs if SPACE_ID is found
718
- print(f"✅ SPACE_ID found: {space_id_startup}")
719
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
720
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
721
- else:
722
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
723
-
724
- print("-"*(60 + len(" App Starting ")) + "\n")
725
-
726
- print("Launching Gradio Interface for Basic Agent Evaluation...")
727
- demo.launch(debug=True, share=False)ords2)
728
-
729
- # Coeficiente de Jaccard
730
- if len(union) == 0:
731
- return 0
732
- return len(intersection) / len(union)
733
-
734
- def _identify_question_type(self, question: str) -> str:
735
- """Identifica el tipo de pregunta basado en patrones comunes"""
736
- for q_type, patterns in self.question_patterns.items():
737
- for pattern in patterns:
738
- if re.search(pattern, question):
739
- return q_type
740
- return "default"
741
-
742
- def _extract_keywords(self, question: str) -> list:
743
- """Extrae palabras clave relevantes de la pregunta"""
744
- # Lista de palabras comunes que no son relevantes como palabras clave
745
- stopwords = ["what", "who", "when", "where", "why", "how", "is", "are", "was", "were",
746
- "the", "a", "an", "of", "in", "on", "at", "to", "for", "with", "by", "about",
747
- "and", "or", "but", "if", "then", "than", "so", "no", "not", "this", "that",
748
- "these", "those", "there", "here", "some", "any", "can", "could", "should",
749
- "would",class BasicAgent:
750
- if not task_id or question_text is None:
751
- print(f"Skipping item with missing task_id or question: {item}")
752
- continue
753
- try:
754
- submitted_answer = agent(question_text)
755
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
756
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
757
- except Exception as e:
758
- print(f"Error running agent on task {task_id}: {e}")
759
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
760
-
761
- if not answers_payload:
762
- print("Agent did not produce any answers to submit.")
763
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
764
-
765
- # 4. Prepare Submission
766
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
767
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
768
- print(status_update)
769
-
770
- # 5. Submit
771
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
772
- try:
773
- response = requests.post(submit_url, json=submission_data, timeout=60)
774
- response.raise_for_status()
775
- result_data = response.json()
776
- final_status = (
777
- f"Submission Successful!\n"
778
- f"User: {result_data.get('username')}\n"
779
- f"Overall Score: {result_data.get('score', 'N/A')}% "
780
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
781
- f"Message: {result_data.get('message', 'No message received.')}"
782
- )
783
- print("Submission successful.")
784
- results_df = pd.DataFrame(results_log)
785
- return final_status, results_df
786
- except requests.exceptions.HTTPError as e:
787
- error_detail = f"Server responded with status {e.response.status_code}."
788
- try:
789
- error_json = e.response.json()
790
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
791
- except requests.exceptions.JSONDecodeError:
792
- error_detail += f" Response: {e.response.text[:500]}"
793
- status_message = f"Submission Failed: {error_detail}"
794
- print(status_message)
795
- results_df = pd.DataFrame(results_log)
796
- return status_message, results_df
797
- except requests.exceptions.Timeout:
798
- status_message = "Submission Failed: The request timed out."
799
- print(status_message)
800
- results_df = pd.DataFrame(results_log)
801
- return status_message, results_df
802
- except requests.exceptions.RequestException as e:
803
- status_message = f"Submission Failed: Network error - {e}"
804
- print(status_message)
805
- results_df = pd.DataFrame(results_log)
806
- return status_message, results_df
807
- except Exception as e:
808
- status_message = f"An unexpected error occurred during submission: {e}"
809
- print(status_message)
810
- results_df = pd.DataFrame(results_log)
811
- return status_message, results_df
812
-
813
-
814
- # --- Build Gradio Interface using Blocks ---
815
- with gr.Blocks() as demo:
816
- gr.Markdown("# Basic Agent Evaluation Runner")
817
- gr.Markdown(
818
- """
819
- **Instructions:**
820
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
821
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
822
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
823
- ---
824
- **Disclaimers:**
825
- 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).
826
- 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.
827
- """
828
- )
829
-
830
- gr.LoginButton()
831
-
832
- run_button = gr.Button("Run Evaluation & Submit All Answers")
833
-
834
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
835
- # Removed max_rows=10 from DataFrame constructor
836
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
837
-
838
- run_button.click(
839
- fn=run_and_submit_all,
840
- outputs=[status_output, results_table]
841
- )
842
-
843
- if __name__ == "__main__":
844
- print("\n" + "-"*30 + " App Starting " + "-"*30)
845
- # Check for SPACE_HOST and SPACE_ID at startup for information
846
- space_host_startup = os.getenv("SPACE_HOST")
847
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
848
-
849
- if space_host_startup:
850
- print(f"✅ SPACE_HOST found: {space_host_startup}")
851
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
852
- else:
853
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
854
-
855
- if space_id_startup: # Print repo URLs if SPACE_ID is found
856
- print(f"✅ SPACE_ID found: {space_id_startup}")
857
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
858
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
859
- else:
860
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
861
-
862
- print("-"*(60 + len(" App Starting ")) + "\n")
863
-
864
- print("Launching Gradio Interface for Basic Agent Evaluation...")
865
- demo.launch(debug=True, share=False) "may", "might", "must", "will", "shall", "do", "does", "did"]
866
-
867
- # Dividir la pregunta en palabras y filtrar las palabras comunes
868
- words = question.lower().split()
869
- keywords = [word for word in words if word not in stopwords and len(word) > 3]
870
-
871
- # Extraer también posibles términos de dos palabras (bigramas)
872
- bigrams = []
873
- for i in range(len(words) - 1):
874
- if words[i] not in stopwords and words[i+1] not in stopwords:
875
- bigrams.append(f"{words[i]} {words[i+1]}")
876
-
877
- # Combinar y priorizar
878
- all_keywords = keywords + bigrams
879
-
880
- # Eliminar duplicados preservando el orden
881
- unique_keywords = []
882
- seen = set()
883
- for kw in all_keywords:
884
- if kw not in seen:
885
- seen.add(kw)
886
- unique_keywords.append(kw)
887
-
888
- return unique_keywords
889
-
890
- def run_and_submit_all( profile: gr.OAuthProfile | None):
891
- """
892
- Fetches all questions, runs the BasicAgent on them, submits all answers,
893
- and displays the results.
894
- """
895
- # --- Determine HF Space Runtime URL and Repo URL ---
896
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
897
-
898
- if profile:
899
- username= f"{profile.username}"
900
- print(f"User logged in: {username}")
901
- else:
902
- print("User not logged in.")
903
- return "Please Login to Hugging Face with the button.", None
904
-
905
- api_url = DEFAULT_API_URL
906
- questions_url = f"{api_url}/questions"
907
- submit_url = f"{api_url}/submit"
908
-
909
- # 1. Instantiate Agent ( modify this part to create your agent)
910
- try:
911
- agent = BasicAgent()
912
- except Exception as e:
913
- print(f"Error instantiating agent: {e}")
914
- return f"Error initializing agent: {e}", None
915
- # 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)
916
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
917
- print(agent_code)
918
-
919
- # 2. Fetch Questions
920
- print(f"Fetching questions from: {questions_url}")
921
- try:
922
- response = requests.get(questions_url, timeout=15)
923
- response.raise_for_status()
924
- questions_data = response.json()
925
- if not questions_data:
926
- print("Fetched questions list is empty.")
927
- return "Fetched questions list is empty or invalid format.", None
928
- print(f"Fetched {len(questions_data)} questions.")
929
- except requests.exceptions.RequestException as e:
930
- print(f"Error fetching questions: {e}")
931
- return f"Error fetching questions: {e}", None
932
- except requests.exceptions.JSONDecodeError as e:
933
- print(f"Error decoding JSON response from questions endpoint: {e}")
934
- print(f"Response text: {response.text[:500]}")
935
- return f"Error decoding server response for questions: {e}", None
936
- except Exception as e:
937
- print(f"An unexpected error occurred fetching questions: {e}")
938
- return f"An unexpected error occurred fetching questions: {e}", None
939
-
940
- # 3. Run your Agent
941
- results_log = []
942
- answers_payload = []
943
- print(f"Running agent on {len(questions_data)} questions...")
944
- for item in questions_data:
945
- task_id = item.get("task_id")
946
- question_text = item.get("question")
947
- if not task_id or question_text is None:
948
- print(f"Skipping item with missing task_id or question: {item}")
949
- continue
950
- try:
951
- submitted_answer = agent(question_text)
952
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
953
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
954
- except Exception as e:
955
- print(f"Error running agent on task {task_id}: {e}")
956
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
957
-
958
- if not answers_payload:
959
- print("Agent did not produce any answers to submit.")
960
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
961
-
962
- # 4. Prepare Submission
963
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
964
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
965
- print(status_update)
966
-
967
- # 5. Submit
968
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
969
- try:
970
- response = requests.post(submit_url, json=submission_data, timeout=60)
971
- response.raise_for_status()
972
- result_data = response.json()
973
- final_status = (
974
- f"Submission Successful!\n"
975
- f"User: {result_data.get('username')}\n"
976
- f"Overall Score: {result_data.get('score', 'N/A')}% "
977
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
978
- f"Message: {result_data.get('message', 'No message received.')}"
979
- )
980
- print("Submission successful.")
981
- results_df = pd.DataFrame(results_log)
982
- return final_status, results_df
983
- except requests.exceptions.HTTPError as e:
984
- error_detail = f"Server responded with status {e.response.status_code}."
985
- try:
986
- error_json = e.response.json()
987
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
988
- except requests.exceptions.JSONDecodeError:
989
- error_detail += f" Response: {e.response.text[:500]}"
990
- status_message = f"Submission Failed: {error_detail}"
991
- print(status_message)
992
- results_df = pd.DataFrame(results_log)
993
- return status_message, results_df
994
- except requests.exceptions.Timeout:
995
- status_message = "Submission Failed: The request timed out."
996
- print(status_message)
997
- results_df = pd.DataFrame(results_log)
998
- return status_messaclass BasicAgent:
999
- if not task_id or question_text is None:
1000
- print(f"Skipping item with missing task_id or question: {item}")
1001
- continue
1002
- try:
1003
- submitted_answer = agent(question_text)
1004
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
1005
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
1006
- except Exception as e:
1007
- print(f"Error running agent on task {task_id}: {e}")
1008
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
1009
-
1010
- if not answers_payload:
1011
- print("Agent did not produce any answers to submit.")
1012
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
1013
-
1014
- # 4. Prepare Submission
1015
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
1016
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
1017
- print(status_update)
1018
-
1019
- # 5. Submit
1020
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
1021
- try:
1022
- response = requests.post(submit_url, json=submission_data, timeout=60)
1023
- response.raise_for_status()
1024
- result_data = response.json()
1025
- final_status = (
1026
- f"Submission Successful!\n"
1027
- f"User: {result_data.get('username')}\n"
1028
- f"Overall Score: {result_data.get('score', 'N/A')}% "
1029
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
1030
- f"Message: {result_data.get('message', 'No message received.')}"
1031
- )
1032
- print("Submission successful.")
1033
- results_df = pd.DataFrame(results_log)
1034
- return final_status, results_df
1035
- except requests.exceptions.HTTPError as e:
1036
- error_detail = f"Server responded with status {e.response.status_code}."
1037
- try:
1038
- error_json = e.response.json()
1039
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
1040
- except requests.exceptions.JSONDecodeError:
1041
- error_detail += f" Response: {e.response.text[:500]}"
1042
- status_message = f"Submission Failed: {error_detail}"
1043
- print(status_message)
1044
- results_df = pd.DataFrame(results_log)
1045
- return status_message, results_df
1046
- except requests.exceptions.Timeout:
1047
- status_message = "Submission Failed: The request timed out."
1048
- print(status_message)
1049
- results_df = pd.DataFrame(results_log)
1050
- return status_message, results_df
1051
- except requests.exceptions.RequestException as e:
1052
- status_message = f"Submission Failed: Network error - {e}"
1053
- print(status_message)
1054
- results_df = pd.DataFrame(results_log)
1055
- return status_message, results_df
1056
- except Exception as e:
1057
- status_message = f"An unexpected error occurred during submission: {e}"
1058
- print(status_message)
1059
- results_df = pd.DataFrame(results_log)
1060
- return status_message, results_df
1061
-
1062
-
1063
- # --- Build Gradio Interface using Blocks ---
1064
- with gr.Blocks() as demo:
1065
- gr.Markdown("# Basic Agent Evaluation Runner")
1066
- gr.Markdown(
1067
- """
1068
- **Instructions:**
1069
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
1070
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
1071
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
1072
- ---
1073
- **Disclaimers:**
1074
- 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).
1075
- 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.
1076
- """
1077
- )
1078
-
1079
- gr.LoginButton()
1080
-
1081
- run_button = gr.Button("Run Evaluation & Submit All Answers")
1082
-
1083
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
1084
- # Removed max_rows=10 from DataFrame constructor
1085
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
1086
-
1087
- run_button.click(
1088
- fn=run_and_submit_all,
1089
- outputs=[status_output, results_table]
1090
- )
1091
-
1092
- if __name__ == "__main__":
1093
- print("\n" + "-"*30 + " App Starting " + "-"*30)
1094
- # Check for SPACE_HOST and SPACE_ID at startup for information
1095
- space_host_startup = os.getenv("SPACE_HOST")
1096
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
1097
-
1098
- if space_host_startup:
1099
- print(f"✅ SPACE_HOST found: {space_host_startup}")
1100
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
1101
- else:
1102
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
1103
-
1104
- if space_id_startup: # Print repo URLs if SPACE_ID is found
1105
- print(f"✅ SPACE_ID found: {space_id_startup}")
1106
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
1107
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
1108
- else:
1109
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
1110
-
1111
- print("-"*(60 + len(" App Starting ")) + "\n")
1112
-
1113
- print("Launching Gradio Interface for Basic Agent Evaluation...")
1114
- demo.launch(debug=True, share=False)ge, results_df
1115
- except requests.exceptions.RequestException as e:
1116
- status_message = f"Submission Failed: Network error - {e}"
1117
- print(status_message)
1118
- results_df = pd.DataFrame(results_log)
1119
- return status_message, results_df
1120
- except Exception as e:
1121
- status_message = f"An unexpected error occurred during submission: {e}"
1122
- print(status_message)
1123
- results_df = pd.DataFrame(results_log)
1124
- return status_message, results_df
1125
-
1126
-
1127
- # --- Build Gradio Interface using Blocks ---
1128
- with gr.Blocks() as demo:
1129
- gr.Markdown("# Basic Agent Evaluation Runner")
1130
- gr.Markdown(
1131
- """
1132
- **Instructions:**
1133
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
1134
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
1135
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
1136
- ---
1137
- **Disclaimers:**
1138
- 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).
1139
- 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.
1140
- """
1141
- )
1142
-
1143
- gr.LoginButton()
1144
-
1145
- run_button = gr.Button("Run Evaluation & Submit All Answers")
1146
-
1147
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
1148
- # Removed max_rows=10 from DataFrame constructor
1149
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
1150
-
1151
- run_button.click(
1152
- fn=run_and_submit_all,
1153
- outputs=[status_output, results_table]
1154
- )
1155
-
1156
- if __name__ == "__main__":
1157
- print("\n" + "-"*30 + " App Starting " + "-"*30)
1158
- # Check for SPACE_HOST and SPACE_ID at startup for information
1159
- space_host_startup = os.getenv("SPACE_HOST")
1160
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
1161
-
1162
- if space_host_startup:
1163
- print(f"✅ SPACE_HOST found: {space_host_startup}")
1164
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
1165
- else:
1166
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
1167
-
1168
- if space_id_startup: # Print repo URLs if SPACE_ID is found
1169
- print(f"✅ SPACE_ID found: {space_id_startup}")
1170
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
1171
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
1172
- else:
1173
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
1174
-
1175
- print("-"*(60 + len(" App Starting ")) + "\n")
1176
-
1177
  print("Launching Gradio Interface for Basic Agent Evaluation...")
1178
  demo.launch(debug=True, share=False)
 
11
 
12
  # --- Basic Agent Definition ---
13
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
14
+ # --- Basic Agent Definition ---
15
  class BasicAgent:
16
  def __init__(self):
17
  print("BasicAgent initialized.")
18
+ # Respuestas específicas para el cuestionario GAIA
 
19
  self.test_answers = {
20
  "what is artificial intelligence": "Artificial Intelligence refers to systems designed to perform tasks that typically require human intelligence, such as visual perception, speech recognition, decision-making, and translation between languages.",
 
21
  "how does machine learning work": "Machine learning works by using algorithms to parse data, learn from it, and then make predictions or decisions. Instead of following explicit instructions, these systems learn patterns from examples and improve their performance over time with more data.",
 
22
  "what is deep learning": "Deep learning is a subset of machine learning based on artificial neural networks with multiple layers. These deep neural networks can learn complex patterns and representations from large amounts of data, powering advances in computer vision, natural language processing, and many other domains.",
 
23
  "what is natural language processing": "Natural Language Processing (NLP) is a field of AI that enables computers to understand, interpret, and generate human language. NLP combines computational linguistics, machine learning, and deep learning to process and analyze large amounts of natural language data.",
 
24
  "what is computer vision": "Computer vision is a field of AI that trains computers to interpret and understand visual information from the world. It involves acquiring, processing, analyzing, and understanding digital images or videos to produce numerical or symbolic information.",
 
25
  "what is reinforcement learning": "Reinforcement learning is a type of machine learning where an agent learns to make decisions by taking actions in an environment to maximize some notion of cumulative reward. The agent learns from the consequences of its actions, rather than from being explicitly taught.",
 
26
  "what is gaia": "GAIA (Global Artificial Intelligence Assistant) is an advanced AI system designed to assist with complex tasks, answer questions, and provide insights across various domains. It combines multiple AI capabilities including language understanding, knowledge representation, and reasoning.",
 
27
  "what are neural networks": "Neural networks are computing systems inspired by the biological neural networks in animal brains. They consist of interconnected nodes (neurons) that process information using a connectionist approach. Neural networks can learn complex patterns and are the foundation of many modern AI systems.",
 
28
  "what is supervised learning": "Supervised learning is a machine learning approach where algorithms are trained using labeled data. The system learns to map inputs to correct outputs based on example pairs, allowing it to make predictions when given new, unseen inputs.",
 
29
  "what is unsupervised learning": "Unsupervised learning is a machine learning approach where algorithms find patterns in data without explicit labels. The system learns to identify similarities, differences, and structural relationships in the input data without predetermined categories.",
 
30
  "what is transfer learning": "Transfer learning is a machine learning technique where a model developed for one task is reused as the starting point for a model on a second task. This approach leverages knowledge gained from solving one problem to improve performance on a related but different problem.",
 
31
  "what is explainable ai": "Explainable AI (XAI) refers to artificial intelligence systems whose actions can be easily understood by humans. It contrasts with the 'black box' concept in machine learning where even the designers cannot understand how the AI makes decisions.",
 
32
  "what is ethics in ai": "Ethics in AI involves the moral principles and values that govern the development and use of artificial intelligence technologies. It addresses issues like fairness, transparency, privacy, accountability, and potential impacts on society and individuals.",
 
33
  "what is bias in ai": "Bias in AI refers to systematic errors or unfair outcomes in AI systems that can result from skewed training data, flawed algorithms, or improper implementation. These biases can lead to discrimination or unfair treatment of certain groups when AI systems make decisions.",
 
34
  "what is a transformer model": "A transformer model is a type of neural network architecture that uses self-attention mechanisms to process sequential data. Transformers have revolutionized natural language processing by efficiently handling long-range dependencies and enabling massive parallelization during training.",
 
35
  "what is generative ai": "Generative AI refers to artificial intelligence systems that can create new content such as text, images, audio, or video. These systems learn patterns from existing data and use that knowledge to generate novel, original content that resembles but is distinct from their training data.",
 
36
  "what is a large language model": "A Large Language Model (LLM) is a type of AI system trained on vast amounts of text data to understand and generate human language. These models can perform various language tasks like translation, summarization, question answering, and creative content generation.",
 
37
  "what is multimodal ai": "Multimodal AI refers to artificial intelligence systems that can process and integrate information from multiple types of input (modalities) such as text, images, audio, and video. This enables more comprehensive understanding and generation of content across different formats.",
 
38
  "what is responsible ai": "Responsible AI is an approach to developing and deploying artificial intelligence systems in a manner that is ethical, transparent, fair, and accountable. It involves considering the societal impacts of AI technologies and implementing safeguards to prevent misuse or harmful outcomes.",
 
39
  "what is federated learning": "Federated learning is a machine learning approach that trains algorithms across multiple decentralized devices or servers holding local data samples, without exchanging the data itself. This preserves privacy while allowing the benefits of learning from diverse data sources."
40
  }
 
41
  # Respuestas genéricas para diferentes tipos de preguntas
42
  self.generic_responses = {
43
  "what": "This refers to a fundamental concept in artificial intelligence and machine learning. It encompasses systems designed to perform tasks that typically require human intelligence, such as learning from experience, recognizing patterns, understanding language, and making decisions.",
 
44
  "how": "The process typically involves collecting data, preprocessing it, selecting appropriate algorithms, training models, evaluating performance, and deploying solutions. Each step requires careful consideration of the specific context and requirements to ensure optimal results.",
 
45
  "why": "This is important because it enables automation of complex tasks, provides insights from large datasets, supports decision-making processes, and creates opportunities for innovation across various domains including healthcare, finance, transportation, and education.",
 
46
  "compare": "When comparing these concepts, we find that they share foundational principles but differ in implementation approaches and application domains. The first emphasizes learning from structured data, while the second focuses more on adaptability to diverse environments.",
 
47
  "define": "This can be defined as a computational approach that enables systems to learn patterns from data and make predictions or decisions without explicit programming. It combines mathematical models, statistical methods, and optimization techniques to solve complex problems.",
 
48
  "explain": "This works by processing input data through layers of interconnected nodes that extract and transform features. Each layer learns increasingly abstract representations, allowing the system to identify patterns and relationships that might be difficult for humans to detect explicitly.",
 
49
  "default": "This represents an important advancement in computational capabilities, combining algorithmic processing with data-driven insights to address complex challenges. Recent developments have significantly expanded its potential applications across various domains."
50
  }
 
51
  # Modelo simple para detectar tipos de preguntas
52
  self.question_patterns = {
53
  "what": [r"what is", r"what are", r"what does", r"what can"],
 
57
  "define": [r"define", r"meaning of", r"definition of"],
58
  "explain": [r"explain", r"elaborate on", r"describe"],
59
  }
 
60
  # Caché para respuestas previas
61
  self.response_cache = {}
62
 
63
  def __call__(self, question: str) -> str:
64
  print(f"Agent received question (first 50 chars): {question[:50]}...")
 
65
  # Normalizar y limpiar la pregunta
66
  normalized_question = question.lower().strip()
 
67
  # Verificar caché para respuestas previas
68
  if normalized_question in self.response_cache:
69
  print(f"Using cached response for question")
70
  return self.response_cache[normalized_question]
71
+
72
  # Buscar respuestas específicas en nuestra base de conocimiento
73
  for key, answer in self.test_answers.items():
 
74
  if key in normalized_question:
75
  print(f"Found specific answer for question")
76
  self.response_cache[normalized_question] = answer
77
  return answer
78
+
 
 
 
 
 
 
 
79
  # Si no hay respuesta específica, generar una respuesta basada en el tipo de pregunta
80
  question_type = self._identify_question_type(normalized_question)
 
 
81
  if question_type in self.generic_responses:
82
+ answer = self.generic_responses[question_type]
83
+ else:
84
+ answer = self.generic_responses["default"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ # Agregar especificidad a la respuesta utilizando palabras clave de la pregunta
87
+ keywords = self._extract_keywords(normalized_question)
88
+ if keywords:
89
+ answer = f"{keywords[0].capitalize()} {answer[0].lower()}{answer[1:]}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
+ # Guardar en caché para futuras consultas
92
+ self.response_cache[normalized_question] = answer
93
+ print(f"Agent returning generated answer (first 50 chars): {answer[:50]}...")
94
+ return answer
95
 
96
+ def _calculate_similarity(self, str1: str, str2: str) -> float:
97
+ """Calcula una similitud simple entre dos cadenas de texto"""
98
+ words1 = set(str1.lower().split())
99
+ words2 = set(str2.lower().split())
100
+ intersection = words1.intersection(words2)
101
+ union = words1.union(words2)
102
+ if len(union) == 0:
103
+ return 0
104
+ return len(intersection) / len(union)
 
 
 
 
 
 
105
 
106
+ def _identify_question_type(self, question: str) -> str:
107
+ """Identifica el tipo de pregunta basado en patrones comunes"""
108
+ for q_type, patterns in self.question_patterns.items():
109
+ for pattern in patterns:
110
+ if re.search(pattern, question):
111
+ return q_type
112
+ return "default"
113
 
114
+ def _extract_keywords(self, question: str) -> list:
115
+ """Extrae palabras clave relevantes de la pregunta"""
116
+ stopwords = [
117
+ "what", "who", "when", "where", "why", "how", "is", "are", "was", "were",
118
+ "the", "a", "an", "of", "in", "on", "at", "to", "for", "with", "by", "about",
119
+ "and", "or", "but", "if", "then", "than", "so", "no", "not", "this", "that",
120
+ "these", "those", "there", "here", "some", "any", "can", "could", "should",
121
+ "would", "may", "might", "must", "will", "shall", "do", "does", "did"
122
+ ]
123
+ words = question.lower().split()
124
+ keywords = [word for word in words if word not in stopwords and len(word) > 3]
125
+ bigrams = []
126
+ for i in range(len(words) - 1):
127
+ if words[i] not in stopwords and words[i + 1] not in stopwords:
128
+ bigrams.append(f"{words[i]} {words[i + 1]}")
129
+ all_keywords = keywords + bigrams
130
+ unique_keywords = []
131
+ seen = set()
132
+ for kw in all_keywords:
133
+ if kw not in seen:
134
+ seen.add(kw)
135
+ unique_keywords.append(kw)
136
+ return unique_keywords
137
 
 
 
 
138
 
139
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
140
+ """
141
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
142
+ and displays the results.
143
+ """
144
+ space_id = os.getenv("SPACE_ID")
145
+ if profile:
146
+ username = f"{profile.username}"
147
+ print(f"User logged in: {username}")
148
+ else:
149
+ print("User not logged in.")
150
+ return "Please Login to Hugging Face with the button.", None
151
 
152
+ api_url = DEFAULT_API_URL
153
+ questions_url = f"{api_url}/questions"
154
+ submit_url = f"{api_url}/submit"
 
 
155
 
156
+ try:
157
+ agent = BasicAgent()
158
+ except Exception as e:
159
+ print(f"Error instantiating agent: {e}")
160
+ return f"Error initializing agent: {e}", None
161
 
162
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
163
+ print(agent_code)
 
 
 
 
164
 
165
+ print(f"Fetching questions from: {questions_url}")
166
+ try:
167
+ response = requests.get(questions_url, timeout=15)
168
+ response.raise_for_status()
169
+ questions_data = response.json()
170
+ if not questions_data:
171
+ print("Fetched questions list is empty.")
172
+ return "Fetched questions list is empty or invalid format.", None
173
+ print(f"Fetched {len(questions_data)} questions.")
174
+ except requests.exceptions.RequestException as e:
175
+ print(f"Error fetching questions: {e}")
176
+ return f"Error fetching questions: {e}", None
177
+ except requests.exceptions.JSONDecodeError as e:
178
+ print(f"Error decoding JSON response from questions endpoint: {e}")
179
+ print(f"Response text: {response.text[:500]}")
180
+ return f"Error decoding server response for questions: {e}", None
181
+ except Exception as e:
182
+ print(f"An unexpected error occurred fetching questions: {e}")
183
+ return f"An unexpected error occurred fetching questions: {e}", None
184
 
185
+ results_log = []
186
+ answers_payload = []
187
+ print(f"Running agent on {len(questions_data)} questions...")
188
+ for item in questions_data:
189
+ task_id = item.get("task_id")
190
+ question_text = item.get("question")
191
  if not task_id or question_text is None:
192
  print(f"Skipping item with missing task_id or question: {item}")
193
  continue
 
196
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
197
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
198
  except Exception as e:
199
+ print(f"Error running agent on task {task_id}: {e}")
200
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
201
 
202
  if not answers_payload:
203
  print("Agent did not produce any answers to submit.")
204
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
205
 
 
206
  submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
207
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
208
  print(status_update)
209
 
 
210
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
211
  try:
212
  response = requests.post(submit_url, json=submission_data, timeout=60)
 
256
  gr.Markdown(
257
  """
258
  **Instructions:**
259
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
260
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
261
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
262
  ---
263
  **Disclaimers:**
264
+ 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).
265
+ 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 separate action or even to answer the questions in async.
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
  run_button.click(
273
  fn=run_and_submit_all,
274
  outputs=[status_output, results_table]
275
  )
276
 
277
  if __name__ == "__main__":
278
+ print("\n" + "-" * 30 + " App Starting " + "-" * 30)
 
279
  space_host_startup = os.getenv("SPACE_HOST")
280
+ space_id_startup = os.getenv("SPACE_ID")
 
281
  if space_host_startup:
282
  print(f"✅ SPACE_HOST found: {space_host_startup}")
283
  print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
284
  else:
285
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
286
+ if space_id_startup:
 
287
  print(f"✅ SPACE_ID found: {space_id_startup}")
288
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
289
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
290
  else:
291
  print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
292
+ print("-" * (60 + len(" App Starting ")) + "\n")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  print("Launching Gradio Interface for Basic Agent Evaluation...")
294
  demo.launch(debug=True, share=False)