Mikkel Skovdal commited on
Commit
f0eb1da
·
1 Parent(s): 7d72891

audio and image support

Browse files
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
.gitignore CHANGED
@@ -1,5 +1,5 @@
1
  secret
2
  test.ipynb
3
  .env
4
- error.txt
5
  log.txt
 
 
1
  secret
2
  test.ipynb
3
  .env
 
4
  log.txt
5
+ src/temp/files/
app.py CHANGED
@@ -12,25 +12,6 @@ from src.api_client import ApiClient
12
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
13
 
14
 
15
- def save_file(file_content, task_id):
16
- """
17
- Save a task file to a temporary location
18
- """
19
- if not file_content:
20
- return None
21
-
22
- # Create a temporary file
23
- temp_dir = tempfile.gettempdir()
24
- file_path = os.path.join(temp_dir, f"task_{task_id}.txt")
25
-
26
- # Write content to the file
27
- with open(file_path, "wb") as f:
28
- f.write(file_content)
29
-
30
- print(f"File saved to {file_path}")
31
- return file_path
32
-
33
-
34
  def run_and_submit_all(profile: gr.OAuthProfile | None):
35
  """
36
  Fetches all questions, runs the CustomAgent on them, submits all answers,
@@ -49,7 +30,6 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
49
  # 1. Instantiate Agent ( modify this part to create your agent)
50
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
51
  print(agent_code)
52
- # Initialize Agent with configuration
53
  try:
54
  agent_config = get_config()
55
  print(f"Using agent configuration: {agent_config}")
@@ -83,6 +63,9 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
83
  for item in questions_data:
84
  task_id = item.get("task_id")
85
  question_text = item.get("question")
 
 
 
86
  if not task_id or question_text is None:
87
  print(f"Skipping item with missing task_id or question: {item}")
88
  continue
@@ -95,13 +78,11 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
95
  )
96
 
97
  # Check if the question has an associated file
98
- file_path = None
99
- try:
100
- file_content = api_client.get_file(task_id)
101
- print(f"Downloaded file for task {task_id}")
102
- file_path = save_file(file_content, task_id)
103
- except Exception as file_e:
104
- print(f"No file for task {task_id}")
105
 
106
  # Run the agent to get the answer
107
  submitted_answer = agent.forward(question_text, file_path)
@@ -134,7 +115,8 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
134
  }
135
  )
136
  finally:
137
- time.sleep(agent_config.get("sleep", 60)) # Delay between requests
 
138
 
139
  # Print summary
140
  print(f"\nProcessing complete: {completed} questions processed, {failed} failures")
@@ -143,12 +125,15 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
143
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
144
 
145
  # Store results in a log file
146
- log_file_path = "logging/log.txt"
147
  os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
148
  timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
149
  with open(log_file_path, "a") as log_file:
150
  for entry in results_log:
151
  log_file.write(f"{timestamp} - {entry}\n")
 
 
 
152
 
153
  # 4. Prepare Submission
154
  print(f"Submitting {len(answers_payload)} answers for username '{username}'...")
 
12
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
13
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  def run_and_submit_all(profile: gr.OAuthProfile | None):
16
  """
17
  Fetches all questions, runs the CustomAgent on them, submits all answers,
 
30
  # 1. Instantiate Agent ( modify this part to create your agent)
31
  agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
32
  print(agent_code)
 
33
  try:
34
  agent_config = get_config()
35
  print(f"Using agent configuration: {agent_config}")
 
63
  for item in questions_data:
64
  task_id = item.get("task_id")
65
  question_text = item.get("question")
66
+ file_name = item.get("file_name")
67
+ file_path = None
68
+
69
  if not task_id or question_text is None:
70
  print(f"Skipping item with missing task_id or question: {item}")
71
  continue
 
78
  )
79
 
80
  # Check if the question has an associated file
81
+ if file_name:
82
+ try:
83
+ file_path = api_client.get_file(task_id=task_id, file_name=file_name)
84
+ except Exception as file_e:
85
+ print(f"Failed to download the file for task {task_id} - {file_e}")
 
 
86
 
87
  # Run the agent to get the answer
88
  submitted_answer = agent.forward(question_text, file_path)
 
115
  }
116
  )
117
  finally:
118
+ if completed+failed < total_questions:
119
+ time.sleep(55)
120
 
121
  # Print summary
122
  print(f"\nProcessing complete: {completed} questions processed, {failed} failures")
 
125
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
126
 
127
  # Store results in a log file
128
+ log_file_path = "src/temp/log.txt"
129
  os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
130
  timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
131
  with open(log_file_path, "a") as log_file:
132
  for entry in results_log:
133
  log_file.write(f"{timestamp} - {entry}\n")
134
+ log_file.write(
135
+ f"{timestamp} - Summary: {completed} questions processed, {failed} failures\n\n"
136
+ )
137
 
138
  # 4. Prepare Submission
139
  print(f"Submitting {len(answers_payload)} answers for username '{username}'...")
requirements.txt CHANGED
@@ -2,4 +2,7 @@ gradio
2
  requests
3
  smolagents
4
  smolagents[litellm]
5
- ratelimiter
 
 
 
 
2
  requests
3
  smolagents
4
  smolagents[litellm]
5
+ ratelimiter
6
+ youtube-transcript-api
7
+ SpeechRecognition
8
+ pydub
src/.DS_Store CHANGED
Binary files a/src/.DS_Store and b/src/.DS_Store differ
 
src/__pycache__/agent.cpython-310.pyc CHANGED
Binary files a/src/__pycache__/agent.cpython-310.pyc and b/src/__pycache__/agent.cpython-310.pyc differ
 
src/__pycache__/api_client.cpython-310.pyc CHANGED
Binary files a/src/__pycache__/api_client.cpython-310.pyc and b/src/__pycache__/api_client.cpython-310.pyc differ
 
src/__pycache__/tools.cpython-310.pyc ADDED
Binary file (1.1 kB). View file
 
src/agent.py CHANGED
@@ -1,15 +1,23 @@
1
- from smolagents import CodeAgent, LiteLLMModel, DuckDuckGoSearchTool, PythonInterpreterTool
2
- import datetime
 
 
 
 
 
 
 
3
  import os
4
- import time
5
- from typing import List, Optional
6
  from dotenv import load_dotenv
7
 
8
- load_dotenv()
9
-
10
 
 
11
  SYSTEM_PROMPT = """
12
- You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.\n
 
 
 
13
  """
14
 
15
 
@@ -30,28 +38,41 @@ class CustomAgent:
30
  """
31
  self.logging = logging
32
  self.verbose = verbose
33
- self.imports = ["pandas", "numpy", "datetime", "json", "re", "math", "os", "requests", "csv", "urllib"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  if additional_imports:
35
  self.imports.extend(additional_imports)
36
 
37
- # Initialize tools
38
  self.tools = [
39
  DuckDuckGoSearchTool(),
40
  PythonInterpreterTool(),
41
- # save_and_read_file,
42
- # download_file_from_url,
43
- # analyze_csv_file,
44
- # analyze_excel_file
45
  ]
46
 
47
  # Initialize the model
48
  model = LiteLLMModel(
49
- model_id=model_id,
50
  api_key=os.getenv("GEMINI_API_KEY"),
51
  timeout=timeout,
52
  )
53
 
54
- # Initialize the CodeAgent
55
  self.agent = CodeAgent(
56
  model=model,
57
  tools=self.tools,
@@ -64,14 +85,10 @@ class CustomAgent:
64
  print("CustomAgent initialized.")
65
 
66
  def __call__(self, question: str) -> str:
67
- if self.verbose:
68
- print(f"Agent received question (first 50 chars): {question[:50]}...")
69
  try:
70
  full_prompt = f"""{question}
71
- When answering, provide ONLY the precise answer requested.
72
- Do not include explanations, steps, reasoning, or additional text.
73
- Be direct and specific. GAIA benchmark requires exact matching answers.
74
- For example, if asked "What is the capital of France?", respond simply with "Paris".
75
  """
76
  answer = self.agent.run(full_prompt)
77
  answer = self._clean_answer(answer)
@@ -82,39 +99,34 @@ class CustomAgent:
82
  if self.verbose:
83
  print(error_msg)
84
  return error_msg
85
-
86
  def forward(self, question: str, file_path) -> str:
87
- if self.verbose:
88
- print(f"Agent received question (first 50 chars): {question[:50]}...")
89
  try:
90
- context = f"Question: {question}"
91
- # If there's a file, read it and include its content in the context
 
92
  if file_path:
93
- try:
94
- with open(file_path, 'r') as f:
95
- file_content = f.read()
96
-
97
- # Determine file type from extension
98
- import os
99
- file_ext = os.path.splitext(file_path)[1].lower()
100
-
101
- context = f"""
102
- Question: {question}
103
- This question has an associated file. Here is the file content:
104
- ```{file_ext}
105
- {file_content}
106
- ```
107
- Analyze the file content above to answer the question.
108
- """
109
- except Exception as _:
110
- print(f"Error reading file {file_path}. Proceeding without file content.")
111
- full_prompt = f"""{context}
112
- When answering, provide ONLY the precise answer requested.
113
- Do not include explanations, steps, reasoning, or additional text.
114
- Be direct and specific. GAIA benchmark requires exact matching answers.
115
- For example, if asked "What is the capital of France?", respond simply with "Paris".
116
- """
117
- answer = self.agent.run(full_prompt)
118
  answer = self._clean_answer(answer)
119
  return answer
120
 
@@ -123,27 +135,24 @@ class CustomAgent:
123
  if self.verbose:
124
  print(error_msg)
125
  return error_msg
126
-
127
  def _clean_answer(self, answer: any) -> str:
128
  """
129
  Clean up the answer to remove common prefixes and formatting
130
  that models often add but that can cause exact match failures.
131
-
132
  Args:
133
  answer: The raw answer from the model
134
-
135
  Returns:
136
  The cleaned answer as a string
137
  """
138
  # Convert non-string types to strings
139
  if not isinstance(answer, str):
140
- # Handle numeric types (float, int)
141
  if isinstance(answer, float):
142
- # Format floating point numbers properly
143
  if answer.is_integer():
144
  formatted_answer = str(int(answer))
145
  else:
146
- # For currency values that might need formatting
147
  if abs(answer) >= 1000:
148
  formatted_answer = f"${answer:,.2f}"
149
  else:
@@ -153,13 +162,13 @@ class CustomAgent:
153
  return str(answer)
154
  else:
155
  return str(answer)
156
-
157
  # Normalize whitespace
158
  answer = answer.strip()
159
-
160
  # Remove common prefixes and formatting that models add
161
  prefixes_to_remove = [
162
- "The answer is ",
163
  "Answer: ",
164
  "Final answer: ",
165
  "The result is ",
@@ -169,12 +178,14 @@ class CustomAgent:
169
  ]
170
  for prefix in prefixes_to_remove:
171
  if answer.startswith(prefix):
172
- answer = answer[len(prefix):].strip()
173
-
174
  # Remove quotes if they wrap the entire answer
175
- if (answer.startswith('"') and answer.endswith('"')) or (answer.startswith("'") and answer.endswith("'")):
 
 
176
  answer = answer[1:-1].strip()
177
-
178
  return answer
179
 
180
 
@@ -184,13 +195,12 @@ def get_config():
184
  """
185
  # Default configuration
186
  config = {
187
- "model_id": "models/gemini-2.5-flash-preview-04-17",
188
  "logging": False,
189
  "max_steps": 5,
190
  "verbose": False,
191
  "executor_type": "local",
192
- "timeout": 120 ,
193
- "sleep" : 60,
194
  }
195
-
196
  return config
 
1
+ from smolagents import (
2
+ CodeAgent,
3
+ LiteLLMModel,
4
+ DuckDuckGoSearchTool,
5
+ PythonInterpreterTool,
6
+ VisitWebpageTool,
7
+ )
8
+ from src.tools import extract_text_from_youtube
9
+ from PIL import Image
10
  import os
11
+ from typing import List
 
12
  from dotenv import load_dotenv
13
 
 
 
14
 
15
+ load_dotenv()
16
  SYSTEM_PROMPT = """
17
+ When answering, provide ONLY the precise answer requested.
18
+ Do not include explanations, steps, reasoning, or additional text.
19
+ Be direct and specific. GAIA benchmark requires exact matching answers.
20
+ For example, if asked "What is the capital of France?", respond simply with "Paris".
21
  """
22
 
23
 
 
38
  """
39
  self.logging = logging
40
  self.verbose = verbose
41
+ self.imports = [
42
+ "pandas",
43
+ "numpy",
44
+ "io",
45
+ "datetime",
46
+ "json",
47
+ "re",
48
+ "math",
49
+ "os",
50
+ "requests",
51
+ "csv",
52
+ "urllib",
53
+ "youtube-transcript-api",
54
+ "SpeechRecognition",
55
+ "pydub",
56
+ ]
57
  if additional_imports:
58
  self.imports.extend(additional_imports)
59
 
60
+ # Initialize tools
61
  self.tools = [
62
  DuckDuckGoSearchTool(),
63
  PythonInterpreterTool(),
64
+ VisitWebpageTool(),
65
+ extract_text_from_youtube,
 
 
66
  ]
67
 
68
  # Initialize the model
69
  model = LiteLLMModel(
70
+ model_id=model_id,
71
  api_key=os.getenv("GEMINI_API_KEY"),
72
  timeout=timeout,
73
  )
74
 
75
+ # Initialize the CodeAgent
76
  self.agent = CodeAgent(
77
  model=model,
78
  tools=self.tools,
 
85
  print("CustomAgent initialized.")
86
 
87
  def __call__(self, question: str) -> str:
88
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
 
89
  try:
90
  full_prompt = f"""{question}
91
+ {SYSTEM_PROMPT}
 
 
 
92
  """
93
  answer = self.agent.run(full_prompt)
94
  answer = self._clean_answer(answer)
 
99
  if self.verbose:
100
  print(error_msg)
101
  return error_msg
102
+
103
  def forward(self, question: str, file_path) -> str:
104
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
 
105
  try:
106
+ full_prompt = f"""Question: {question}
107
+
108
+ {SYSTEM_PROMPT}"""
109
  if file_path:
110
+ file_path_ext = os.path.splitext(file_path)[1]
111
+ if file_path_ext.lower() in [".jpg", ".jpeg", ".png"]:
112
+ image = Image.open(file_path).convert("RGB")
113
+ answer = self.agent.run(full_prompt, images=[image])
114
+ elif file_path_ext.lower() in [".txt", ".py"]:
115
+ with open(file_path, "r") as f:
116
+ content = f.read()
117
+ full_prompt = f"""Question: {question}
118
+ File content: ```{content}```
119
+
120
+ {SYSTEM_PROMPT}"""
121
+ answer = self.agent.run(full_prompt)
122
+ else:
123
+ full_prompt = f"""Question: {question}
124
+ File path: {file_path}
125
+
126
+ {SYSTEM_PROMPT}"""
127
+ answer = self.agent.run(full_prompt)
128
+ else:
129
+ answer = self.agent.run(full_prompt)
 
 
 
 
 
130
  answer = self._clean_answer(answer)
131
  return answer
132
 
 
135
  if self.verbose:
136
  print(error_msg)
137
  return error_msg
138
+
139
  def _clean_answer(self, answer: any) -> str:
140
  """
141
  Clean up the answer to remove common prefixes and formatting
142
  that models often add but that can cause exact match failures.
143
+
144
  Args:
145
  answer: The raw answer from the model
146
+
147
  Returns:
148
  The cleaned answer as a string
149
  """
150
  # Convert non-string types to strings
151
  if not isinstance(answer, str):
 
152
  if isinstance(answer, float):
 
153
  if answer.is_integer():
154
  formatted_answer = str(int(answer))
155
  else:
 
156
  if abs(answer) >= 1000:
157
  formatted_answer = f"${answer:,.2f}"
158
  else:
 
162
  return str(answer)
163
  else:
164
  return str(answer)
165
+
166
  # Normalize whitespace
167
  answer = answer.strip()
168
+
169
  # Remove common prefixes and formatting that models add
170
  prefixes_to_remove = [
171
+ "The answer is ",
172
  "Answer: ",
173
  "Final answer: ",
174
  "The result is ",
 
178
  ]
179
  for prefix in prefixes_to_remove:
180
  if answer.startswith(prefix):
181
+ answer = answer[len(prefix) :].strip()
182
+
183
  # Remove quotes if they wrap the entire answer
184
+ if (answer.startswith('"') and answer.endswith('"')) or (
185
+ answer.startswith("'") and answer.endswith("'")
186
+ ):
187
  answer = answer[1:-1].strip()
188
+
189
  return answer
190
 
191
 
 
195
  """
196
  # Default configuration
197
  config = {
198
+ "model_id": "gemini/gemini-2.5-flash-preview-04-17",
199
  "logging": False,
200
  "max_steps": 5,
201
  "verbose": False,
202
  "executor_type": "local",
203
+ "timeout": 120,
 
204
  }
205
+
206
  return config
src/api_client.py CHANGED
@@ -3,35 +3,56 @@ import os
3
  import datetime
4
  from typing import List, Dict, Any
5
 
 
6
  class ApiClient:
7
  def __init__(self, api_url="https://agents-course-unit4-scoring.hf.space"):
8
  self.api_url = api_url
9
  self.questions_url = f"{api_url}/questions"
10
  self.submit_url = f"{api_url}/submit"
11
  self.files_url = f"{api_url}/files"
12
-
13
  def get_questions(self, limit=20) -> List[Dict[str, Any]]:
14
  limit = min(limit, 20)
15
  limit = max(limit, 1)
16
  response = requests.get(self.questions_url)
17
  response.raise_for_status()
18
  return response.json()[:limit]
19
-
20
  def get_random_question(self) -> Dict[str, Any]:
21
  response = requests.get(f"{self.api_url}/random-question")
22
  response.raise_for_status()
23
  return response.json()
24
-
25
- def get_file(self, task_id: str) -> bytes:
26
- response = requests.get(f"{self.files_url}/{task_id}")
 
 
 
 
 
 
 
27
  response.raise_for_status()
28
- return response.content
29
-
30
- def submit_answers(self, username: str, agent_code: str, answers_payload: List[Dict[str, Any]], logging: bool) -> Dict[str, Any]:
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  data = {
32
  "username": username,
33
  "agent_code": agent_code,
34
- "answers": answers_payload
35
  }
36
  response = requests.post(self.submit_url, json=data)
37
  response.raise_for_status()
 
3
  import datetime
4
  from typing import List, Dict, Any
5
 
6
+
7
  class ApiClient:
8
  def __init__(self, api_url="https://agents-course-unit4-scoring.hf.space"):
9
  self.api_url = api_url
10
  self.questions_url = f"{api_url}/questions"
11
  self.submit_url = f"{api_url}/submit"
12
  self.files_url = f"{api_url}/files"
13
+
14
  def get_questions(self, limit=20) -> List[Dict[str, Any]]:
15
  limit = min(limit, 20)
16
  limit = max(limit, 1)
17
  response = requests.get(self.questions_url)
18
  response.raise_for_status()
19
  return response.json()[:limit]
20
+
21
  def get_random_question(self) -> Dict[str, Any]:
22
  response = requests.get(f"{self.api_url}/random-question")
23
  response.raise_for_status()
24
  return response.json()
25
+
26
+ def get_file(self, task_id, file_name: str) -> bytes:
27
+ # check if file already exists
28
+ file_path = os.path.join("src/temp/files", file_name)
29
+ if os.path.exists(file_path):
30
+ return file_path
31
+
32
+ # Download the file
33
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
34
+ response = requests.get(f"{self.files_url}/{task_id}", stream=True)
35
  response.raise_for_status()
36
+
37
+ # Save the file
38
+ with open(file_path, "wb") as f:
39
+ for chunk in response.iter_content(chunk_size=8192):
40
+ f.write(chunk)
41
+ print(f"File saved to {file_path}")
42
+
43
+ return file_path
44
+
45
+ def submit_answers(
46
+ self,
47
+ username: str,
48
+ agent_code: str,
49
+ answers_payload: List[Dict[str, Any]],
50
+ logging: bool,
51
+ ) -> Dict[str, Any]:
52
  data = {
53
  "username": username,
54
  "agent_code": agent_code,
55
+ "answers": answers_payload,
56
  }
57
  response = requests.post(self.submit_url, json=data)
58
  response.raise_for_status()
src/temp/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/tools.py CHANGED
@@ -2,8 +2,48 @@ from smolagents import tool
2
 
3
 
4
  @tool
5
- def test():
6
  """
7
- Test function that returns a string.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  """
9
- return "This is a test function."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
 
4
  @tool
5
+ def extract_text_from_mp3(mp3_file_path: str) -> str:
6
  """
7
+ Extract text from an mp3 audio file.
8
+
9
+ Args:
10
+ mp3_file_path (str): Path to the mp3 file.
11
+ Returns:
12
+ str: The text extracted from the mp3 file.
13
+ """
14
+ try:
15
+ import speech_recognition as sr
16
+ from pydub import AudioSegment
17
+
18
+ audio = AudioSegment.from_mp3(mp3_file_path)
19
+ wav_file = f"{mp3_file_path}.wav"
20
+ audio.export(wav_file, format="wav")
21
+ recognizer = sr.Recognizer()
22
+
23
+ with sr.AudioFile(wav_file) as source:
24
+ audio_data = recognizer.record(source)
25
+ text = recognizer.recognize_google(audio_data)
26
+ return text
27
+ except Exception as e:
28
+ return f"Could not extract text from mp3 file: {e}"
29
+
30
+
31
+ @tool
32
+ def extract_text_from_youtube(youtube_id: str) -> str:
33
  """
34
+ Extract text from a youtube video.
35
+
36
+ Args:
37
+ youtube_id (str): ID of the youtube video. Not the full URL. Example: "dQw4w9WgXcQ"
38
+ Returns:
39
+ str: The text extracted from the youtube video.
40
+ """
41
+ try:
42
+ from youtube_transcript_api import YouTubeTranscriptApi
43
+
44
+ ytt_api = YouTubeTranscriptApi()
45
+ fetched_transcript = ytt_api.fetch(youtube_id)
46
+ plaintext = " ".join(snippet.text for snippet in fetched_transcript)
47
+ return plaintext
48
+ except:
49
+ return "Could not fetch transcript from YouTube video."
test.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ [
2
+ {'task_id': '8e867cd7-cff9-4e6c-867a-ff5ddc2550be', 'question': 'How many studio albums were published by Mercedes Sosa between 2000 and 2009 (included)? You can use the latest 2022 version of english wikipedia.', 'Level': '1', 'file_name': ''},
3
+ {'task_id': 'a1e91b78-d3d8-4675-bb8d-62741b4b68a6', 'question': 'In the video https://www.youtube.com/watch?v=L1vXCYZAYYM, what is the highest number of bird species to be on camera simultaneously?', 'Level': '1', 'file_name': ''},
4
+ {'task_id': '2d83110e-a098-4ebb-9987-066c06fa42d0', 'question': '.rewsna eht sa "tfel" drow eht fo etisoppo eht etirw ,ecnetnes siht dnatsrednu uoy fI', 'Level': '1', 'file_name': ''},
5
+ {'task_id': 'cca530fc-4052-43b2-b130-b30968d8aa44', 'question': "Review the chess position provided in the image. It is black's turn. Provide the correct next move for black which guarantees a win. Please provide your response in algebraic notation.", 'Level': '1', 'file_name': 'cca530fc-4052-43b2-b130-b30968d8aa44.png'},
6
+ {'task_id': '4fc2f1ae-8625-45b5-ab34-ad4433bc21f8', 'question': 'Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?', 'Level': '1', 'file_name': ''}]