mangubee commited on
Commit
e7b4937
·
1 Parent(s): f1b095a

fix: correct author name formatting in multiple files

Browse files
.env.example CHANGED
@@ -1,5 +1,5 @@
1
  # GAIA Benchmark Agent - Environment Configuration Template
2
- # Author: @mangobee
3
  # Date: 2026-01-01
4
  #
5
  # Copy this file to .env and fill in your API keys
 
1
  # GAIA Benchmark Agent - Environment Configuration Template
2
+ # Author: @mangubee
3
  # Date: 2026-01-01
4
  #
5
  # Copy this file to .env and fill in your API keys
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
  # GAIA Benchmark Agent - Dependencies
2
- # Author: @mangobee
3
  # Date: 2026-01-01
4
 
5
  # ============================================================================
 
1
  # GAIA Benchmark Agent - Dependencies
2
+ # Author: @mangubee
3
  # Date: 2026-01-01
4
 
5
  # ============================================================================
src/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  GAIA Benchmark Agent - Source Package
3
- Author: @mangobee
4
  Date: 2026-01-01
5
  """
6
 
 
1
  """
2
  GAIA Benchmark Agent - Source Package
3
+ Author: @mangubee
4
  Date: 2026-01-01
5
  """
6
 
src/agent/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  LangGraph agent core package
3
- Author: @mangobee
4
  """
5
 
6
  from .graph import GAIAAgent
 
1
  """
2
  LangGraph agent core package
3
+ Author: @mangubee
4
  """
5
 
6
  from .graph import GAIAAgent
src/agent/graph.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  LangGraph Agent Core - StateGraph Definition
3
- Author: @mangobee
4
  Date: 2026-01-01
5
 
6
  Stage 1: Skeleton with placeholder nodes
@@ -19,7 +19,15 @@ from pathlib import Path
19
  from typing import TypedDict, List, Optional
20
  from langgraph.graph import StateGraph, END
21
  from src.config import Settings
22
- from src.tools import TOOLS, search, parse_file, safe_eval, analyze_image, youtube_transcript, transcribe_audio
 
 
 
 
 
 
 
 
23
  from src.agent.llm_client import (
24
  plan_question,
25
  select_tools_with_function_calling,
@@ -35,6 +43,7 @@ logger = logging.getLogger(__name__)
35
  # Helper Functions
36
  # ============================================================================
37
 
 
38
  def is_vision_question(question: str) -> bool:
39
  """
40
  Detect if question requires vision analysis tool.
@@ -47,9 +56,19 @@ def is_vision_question(question: str) -> bool:
47
  Returns:
48
  True if question likely requires vision tool, False otherwise
49
  """
50
- vision_keywords = ["image", "video", "youtube", "photo", "picture", "watch", "screenshot", "visual"]
 
 
 
 
 
 
 
 
 
51
  return any(keyword in question.lower() for keyword in vision_keywords)
52
 
 
53
  # ============================================================================
54
  # Agent State Definition
55
  # ============================================================================
@@ -119,7 +138,9 @@ def fallback_tool_selection(
119
  Returns:
120
  List of tool calls with basic parameters
121
  """
122
- logger.info("[fallback_tool_selection] Using keyword-based fallback for tool selection")
 
 
123
 
124
  tool_calls = []
125
  question_lower = question.lower()
@@ -127,53 +148,88 @@ def fallback_tool_selection(
127
  combined = f"{question_lower} {plan_lower}"
128
 
129
  # Search tool: keywords like "search", "find", "look up", "who", "what", "when", "where"
130
- search_keywords = ["search", "find", "look up", "who is", "what is", "when", "where", "google"]
 
 
 
 
 
 
 
 
 
131
  if any(keyword in combined for keyword in search_keywords):
132
  # Extract search query - use first sentence or full question
133
- query = question.split('.')[0] if '.' in question else question
134
- tool_calls.append({
135
- "tool": "web_search",
136
- "params": {"query": query}
137
- })
138
- logger.info(f"[fallback_tool_selection] Added web_search tool with query: {query}")
139
 
140
  # Math tool: keywords like "calculate", "compute", "+", "-", "*", "/", "="
141
- math_keywords = ["calculate", "compute", "math", "sum", "multiply", "divide", "+", "-", "*", "/", "="]
 
 
 
 
 
 
 
 
 
 
 
 
142
  if any(keyword in combined for keyword in math_keywords):
143
  # Try to extract expression - look for patterns with numbers and operators
144
  import re
 
145
  # Look for mathematical expressions
146
- expr_match = re.search(r'[\d\s\+\-\*/\(\)\.]+', question)
147
  if expr_match:
148
  expression = expr_match.group().strip()
149
- tool_calls.append({
150
- "tool": "calculator",
151
- "params": {"expression": expression}
152
- })
153
- logger.info(f"[fallback_tool_selection] Added calculator tool with expression: {expression}")
 
154
 
155
  # File tool: if file_paths available, use them
156
  if file_paths:
157
  for file_path in file_paths:
158
  # Determine file type and appropriate tool
159
  file_ext = Path(file_path).suffix.lower()
160
- if file_ext in ['.png', '.jpg', '.jpeg']:
161
- tool_calls.append({
162
- "tool": "vision",
163
- "params": {"image_path": file_path}
164
- })
165
- logger.info(f"[fallback_tool_selection] Added vision tool for image: {file_path}")
166
- elif file_ext in ['.pdf', '.xlsx', '.xls', '.csv', '.json', '.txt', '.docx', '.doc']:
167
- tool_calls.append({
168
- "tool": "parse_file",
169
- "params": {"file_path": file_path}
170
- })
171
- logger.info(f"[fallback_tool_selection] Added parse_file tool for: {file_path}")
 
 
 
 
 
 
 
 
 
 
 
172
  else:
173
  # Keyword-based file detection (legacy)
174
  file_keywords = ["file", "parse", "read", "csv", "json", "txt", "document"]
175
  if any(keyword in combined for keyword in file_keywords):
176
- logger.warning("[fallback_tool_selection] File operation detected but no file_paths available")
 
 
177
 
178
  # Image tool: keywords like "image", "picture", "photo", "analyze", "vision"
179
  image_keywords = ["image", "picture", "photo", "analyze image", "vision"]
@@ -182,17 +238,20 @@ def fallback_tool_selection(
182
  # Already handled above in file_paths check
183
  pass
184
  else:
185
- logger.warning("[fallback_tool_selection] Image operation detected but no file_paths available")
 
 
186
 
187
  if not tool_calls:
188
- logger.warning("[fallback_tool_selection] No tools selected by fallback - adding default search")
 
 
189
  # Default: just search the question
190
- tool_calls.append({
191
- "tool": "web_search",
192
- "params": {"query": question}
193
- })
194
 
195
- logger.info(f"[fallback_tool_selection] Fallback selected {len(tool_calls)} tool(s)")
 
 
196
  return tool_calls
197
 
198
 
@@ -264,7 +323,9 @@ def execute_node(state: AgentState) -> AgentState:
264
  )
265
  elif not isinstance(tool_calls, list):
266
  logger.error(f"[execute] Invalid type: {type(tool_calls)}, using fallback")
267
- state["errors"].append(f"Tool selection returned invalid type: {type(tool_calls)}")
 
 
268
  tool_calls = fallback_tool_selection(
269
  state["question"], state["plan"], state.get("file_paths")
270
  )
@@ -284,12 +345,14 @@ def execute_node(state: AgentState) -> AgentState:
284
  result = tool_func(**params)
285
  logger.info(f"[{idx}/{len(tool_calls)}] {tool_name} ✓")
286
 
287
- tool_results.append({
288
- "tool": tool_name,
289
- "params": params,
290
- "result": result,
291
- "status": "success",
292
- })
 
 
293
 
294
  # Extract evidence - handle different result formats
295
  if isinstance(result, dict):
@@ -307,7 +370,9 @@ def execute_node(state: AgentState) -> AgentState:
307
  title = r.get("title", "")[:100]
308
  url = r.get("url", "")[:100]
309
  snippet = r.get("snippet", "")[:200]
310
- formatted.append(f"Title: {title}\nURL: {url}\nSnippet: {snippet}")
 
 
311
  evidence.append("\n\n".join(formatted))
312
  else:
313
  evidence.append(str(result))
@@ -320,13 +385,17 @@ def execute_node(state: AgentState) -> AgentState:
320
 
321
  except Exception as tool_error:
322
  logger.error(f"[execute] ✗ {tool_name}: {tool_error}")
323
- tool_results.append({
324
- "tool": tool_name,
325
- "params": params,
326
- "error": str(tool_error),
327
- "status": "failed",
328
- })
329
- if tool_name == "vision" and ("quota" in str(tool_error).lower() or "429" in str(tool_error)):
 
 
 
 
330
  state["errors"].append(f"Vision failed: LLM quota exhausted")
331
  else:
332
  state["errors"].append(f"{tool_name}: {type(tool_error).__name__}")
@@ -336,7 +405,9 @@ def execute_node(state: AgentState) -> AgentState:
336
  except Exception as e:
337
  logger.error(f"[execute] ✗ {type(e).__name__}: {str(e)}")
338
 
339
- if is_vision_question(state["question"]) and ("quota" in str(e).lower() or "429" in str(e)):
 
 
340
  state["errors"].append("Vision unavailable (quota exhausted)")
341
  else:
342
  state["errors"].append(f"Execution error: {type(e).__name__}")
@@ -364,12 +435,14 @@ def execute_node(state: AgentState) -> AgentState:
364
  tool_func = TOOL_FUNCTIONS.get(tool_name)
365
  if tool_func:
366
  result = tool_func(**params)
367
- tool_results.append({
368
- "tool": tool_name,
369
- "params": params,
370
- "result": result,
371
- "status": "success"
372
- })
 
 
373
  if isinstance(result, dict):
374
  if "answer" in result:
375
  evidence.append(result["answer"])
@@ -381,7 +454,9 @@ def execute_node(state: AgentState) -> AgentState:
381
  title = r.get("title", "")[:100]
382
  url = r.get("url", "")[:100]
383
  snippet = r.get("snippet", "")[:200]
384
- formatted.append(f"Title: {title}\nURL: {url}\nSnippet: {snippet}")
 
 
385
  evidence.append("\n\n".join(formatted))
386
  else:
387
  evidence.append(str(result))
@@ -411,7 +486,9 @@ def answer_node(state: AgentState) -> AgentState:
411
 
412
  try:
413
  if not state["evidence"]:
414
- error_summary = "; ".join(state["errors"]) if state["errors"] else "No errors logged"
 
 
415
  state["answer"] = f"ERROR: No evidence. {error_summary}"
416
  logger.error(f"[answer] ✗ No evidence - {error_summary}")
417
  return state
@@ -425,7 +502,9 @@ def answer_node(state: AgentState) -> AgentState:
425
  except Exception as e:
426
  logger.error(f"[answer] ✗ {type(e).__name__}: {str(e)}")
427
  state["errors"].append(f"Answer synthesis error: {type(e).__name__}: {str(e)}")
428
- state["answer"] = f"ERROR: Answer synthesis failed - {type(e).__name__}: {str(e)}"
 
 
429
 
430
  return state
431
 
@@ -491,7 +570,9 @@ class GAIAAgent:
491
  warning_msg = f"⚠️ WARNING: Missing API keys: {', '.join(missing_keys)}"
492
  print(warning_msg)
493
  logger.warning(warning_msg)
494
- print(" Agent may fail to answer questions. Set keys in environment variables.")
 
 
495
  else:
496
  print("✓ All API keys present")
497
 
 
1
  """
2
  LangGraph Agent Core - StateGraph Definition
3
+ Author: @mangubee
4
  Date: 2026-01-01
5
 
6
  Stage 1: Skeleton with placeholder nodes
 
19
  from typing import TypedDict, List, Optional
20
  from langgraph.graph import StateGraph, END
21
  from src.config import Settings
22
+ from src.tools import (
23
+ TOOLS,
24
+ search,
25
+ parse_file,
26
+ safe_eval,
27
+ analyze_image,
28
+ youtube_transcript,
29
+ transcribe_audio,
30
+ )
31
  from src.agent.llm_client import (
32
  plan_question,
33
  select_tools_with_function_calling,
 
43
  # Helper Functions
44
  # ============================================================================
45
 
46
+
47
  def is_vision_question(question: str) -> bool:
48
  """
49
  Detect if question requires vision analysis tool.
 
56
  Returns:
57
  True if question likely requires vision tool, False otherwise
58
  """
59
+ vision_keywords = [
60
+ "image",
61
+ "video",
62
+ "youtube",
63
+ "photo",
64
+ "picture",
65
+ "watch",
66
+ "screenshot",
67
+ "visual",
68
+ ]
69
  return any(keyword in question.lower() for keyword in vision_keywords)
70
 
71
+
72
  # ============================================================================
73
  # Agent State Definition
74
  # ============================================================================
 
138
  Returns:
139
  List of tool calls with basic parameters
140
  """
141
+ logger.info(
142
+ "[fallback_tool_selection] Using keyword-based fallback for tool selection"
143
+ )
144
 
145
  tool_calls = []
146
  question_lower = question.lower()
 
148
  combined = f"{question_lower} {plan_lower}"
149
 
150
  # Search tool: keywords like "search", "find", "look up", "who", "what", "when", "where"
151
+ search_keywords = [
152
+ "search",
153
+ "find",
154
+ "look up",
155
+ "who is",
156
+ "what is",
157
+ "when",
158
+ "where",
159
+ "google",
160
+ ]
161
  if any(keyword in combined for keyword in search_keywords):
162
  # Extract search query - use first sentence or full question
163
+ query = question.split(".")[0] if "." in question else question
164
+ tool_calls.append({"tool": "web_search", "params": {"query": query}})
165
+ logger.info(
166
+ f"[fallback_tool_selection] Added web_search tool with query: {query}"
167
+ )
 
168
 
169
  # Math tool: keywords like "calculate", "compute", "+", "-", "*", "/", "="
170
+ math_keywords = [
171
+ "calculate",
172
+ "compute",
173
+ "math",
174
+ "sum",
175
+ "multiply",
176
+ "divide",
177
+ "+",
178
+ "-",
179
+ "*",
180
+ "/",
181
+ "=",
182
+ ]
183
  if any(keyword in combined for keyword in math_keywords):
184
  # Try to extract expression - look for patterns with numbers and operators
185
  import re
186
+
187
  # Look for mathematical expressions
188
+ expr_match = re.search(r"[\d\s\+\-\*/\(\)\.]+", question)
189
  if expr_match:
190
  expression = expr_match.group().strip()
191
+ tool_calls.append(
192
+ {"tool": "calculator", "params": {"expression": expression}}
193
+ )
194
+ logger.info(
195
+ f"[fallback_tool_selection] Added calculator tool with expression: {expression}"
196
+ )
197
 
198
  # File tool: if file_paths available, use them
199
  if file_paths:
200
  for file_path in file_paths:
201
  # Determine file type and appropriate tool
202
  file_ext = Path(file_path).suffix.lower()
203
+ if file_ext in [".png", ".jpg", ".jpeg"]:
204
+ tool_calls.append(
205
+ {"tool": "vision", "params": {"image_path": file_path}}
206
+ )
207
+ logger.info(
208
+ f"[fallback_tool_selection] Added vision tool for image: {file_path}"
209
+ )
210
+ elif file_ext in [
211
+ ".pdf",
212
+ ".xlsx",
213
+ ".xls",
214
+ ".csv",
215
+ ".json",
216
+ ".txt",
217
+ ".docx",
218
+ ".doc",
219
+ ]:
220
+ tool_calls.append(
221
+ {"tool": "parse_file", "params": {"file_path": file_path}}
222
+ )
223
+ logger.info(
224
+ f"[fallback_tool_selection] Added parse_file tool for: {file_path}"
225
+ )
226
  else:
227
  # Keyword-based file detection (legacy)
228
  file_keywords = ["file", "parse", "read", "csv", "json", "txt", "document"]
229
  if any(keyword in combined for keyword in file_keywords):
230
+ logger.warning(
231
+ "[fallback_tool_selection] File operation detected but no file_paths available"
232
+ )
233
 
234
  # Image tool: keywords like "image", "picture", "photo", "analyze", "vision"
235
  image_keywords = ["image", "picture", "photo", "analyze image", "vision"]
 
238
  # Already handled above in file_paths check
239
  pass
240
  else:
241
+ logger.warning(
242
+ "[fallback_tool_selection] Image operation detected but no file_paths available"
243
+ )
244
 
245
  if not tool_calls:
246
+ logger.warning(
247
+ "[fallback_tool_selection] No tools selected by fallback - adding default search"
248
+ )
249
  # Default: just search the question
250
+ tool_calls.append({"tool": "web_search", "params": {"query": question}})
 
 
 
251
 
252
+ logger.info(
253
+ f"[fallback_tool_selection] Fallback selected {len(tool_calls)} tool(s)"
254
+ )
255
  return tool_calls
256
 
257
 
 
323
  )
324
  elif not isinstance(tool_calls, list):
325
  logger.error(f"[execute] Invalid type: {type(tool_calls)}, using fallback")
326
+ state["errors"].append(
327
+ f"Tool selection returned invalid type: {type(tool_calls)}"
328
+ )
329
  tool_calls = fallback_tool_selection(
330
  state["question"], state["plan"], state.get("file_paths")
331
  )
 
345
  result = tool_func(**params)
346
  logger.info(f"[{idx}/{len(tool_calls)}] {tool_name} ✓")
347
 
348
+ tool_results.append(
349
+ {
350
+ "tool": tool_name,
351
+ "params": params,
352
+ "result": result,
353
+ "status": "success",
354
+ }
355
+ )
356
 
357
  # Extract evidence - handle different result formats
358
  if isinstance(result, dict):
 
370
  title = r.get("title", "")[:100]
371
  url = r.get("url", "")[:100]
372
  snippet = r.get("snippet", "")[:200]
373
+ formatted.append(
374
+ f"Title: {title}\nURL: {url}\nSnippet: {snippet}"
375
+ )
376
  evidence.append("\n\n".join(formatted))
377
  else:
378
  evidence.append(str(result))
 
385
 
386
  except Exception as tool_error:
387
  logger.error(f"[execute] ✗ {tool_name}: {tool_error}")
388
+ tool_results.append(
389
+ {
390
+ "tool": tool_name,
391
+ "params": params,
392
+ "error": str(tool_error),
393
+ "status": "failed",
394
+ }
395
+ )
396
+ if tool_name == "vision" and (
397
+ "quota" in str(tool_error).lower() or "429" in str(tool_error)
398
+ ):
399
  state["errors"].append(f"Vision failed: LLM quota exhausted")
400
  else:
401
  state["errors"].append(f"{tool_name}: {type(tool_error).__name__}")
 
405
  except Exception as e:
406
  logger.error(f"[execute] ✗ {type(e).__name__}: {str(e)}")
407
 
408
+ if is_vision_question(state["question"]) and (
409
+ "quota" in str(e).lower() or "429" in str(e)
410
+ ):
411
  state["errors"].append("Vision unavailable (quota exhausted)")
412
  else:
413
  state["errors"].append(f"Execution error: {type(e).__name__}")
 
435
  tool_func = TOOL_FUNCTIONS.get(tool_name)
436
  if tool_func:
437
  result = tool_func(**params)
438
+ tool_results.append(
439
+ {
440
+ "tool": tool_name,
441
+ "params": params,
442
+ "result": result,
443
+ "status": "success",
444
+ }
445
+ )
446
  if isinstance(result, dict):
447
  if "answer" in result:
448
  evidence.append(result["answer"])
 
454
  title = r.get("title", "")[:100]
455
  url = r.get("url", "")[:100]
456
  snippet = r.get("snippet", "")[:200]
457
+ formatted.append(
458
+ f"Title: {title}\nURL: {url}\nSnippet: {snippet}"
459
+ )
460
  evidence.append("\n\n".join(formatted))
461
  else:
462
  evidence.append(str(result))
 
486
 
487
  try:
488
  if not state["evidence"]:
489
+ error_summary = (
490
+ "; ".join(state["errors"]) if state["errors"] else "No errors logged"
491
+ )
492
  state["answer"] = f"ERROR: No evidence. {error_summary}"
493
  logger.error(f"[answer] ✗ No evidence - {error_summary}")
494
  return state
 
502
  except Exception as e:
503
  logger.error(f"[answer] ✗ {type(e).__name__}: {str(e)}")
504
  state["errors"].append(f"Answer synthesis error: {type(e).__name__}: {str(e)}")
505
+ state["answer"] = (
506
+ f"ERROR: Answer synthesis failed - {type(e).__name__}: {str(e)}"
507
+ )
508
 
509
  return state
510
 
 
570
  warning_msg = f"⚠️ WARNING: Missing API keys: {', '.join(missing_keys)}"
571
  print(warning_msg)
572
  logger.warning(warning_msg)
573
+ print(
574
+ " Agent may fail to answer questions. Set keys in environment variables."
575
+ )
576
  else:
577
  print("✓ All API keys present")
578
 
src/agent/llm_client.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  LLM Client Module - Multi-Provider LLM Integration
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Handles all LLM calls for:
 
1
  """
2
  LLM Client Module - Multi-Provider LLM Integration
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Handles all LLM calls for:
src/config/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Configuration management package
3
- Author: @mangobee
4
  """
5
 
6
  from .settings import Settings
 
1
  """
2
  Configuration management package
3
+ Author: @mangubee
4
  """
5
 
6
  from .settings import Settings
src/config/settings.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Configuration Management
3
- Author: @mangobee
4
  Date: 2026-01-01
5
 
6
  Loads environment variables and defines configuration constants for GAIA agent.
 
1
  """
2
  Configuration Management
3
+ Author: @mangubee
4
  Date: 2026-01-01
5
 
6
  Loads environment variables and defines configuration constants for GAIA agent.
src/tools/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tool implementations package
3
- Author: @mangobee
4
 
5
  This package contains all agent tools:
6
  - web_search: Web search using Tavily/Exa
 
1
  """
2
  Tool implementations package
3
+ Author: @mangubee
4
 
5
  This package contains all agent tools:
6
  - web_search: Web search using Tavily/Exa
src/tools/audio.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Audio Transcription Tool - Whisper speech-to-text
3
- Author: @mangobee
4
  Date: 2026-01-13
5
 
6
  Provides audio transcription using OpenAI Whisper:
 
1
  """
2
  Audio Transcription Tool - Whisper speech-to-text
3
+ Author: @mangubee
4
  Date: 2026-01-13
5
 
6
  Provides audio transcription using OpenAI Whisper:
src/tools/calculator.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Calculator Tool - Safe mathematical expression evaluation
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Provides safe evaluation of mathematical expressions with:
 
1
  """
2
  Calculator Tool - Safe mathematical expression evaluation
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Provides safe evaluation of mathematical expressions with:
src/tools/file_parser.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  File Parser Tool - Multi-format file reading
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Provides file parsing for:
 
1
  """
2
  File Parser Tool - Multi-format file reading
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Provides file parsing for:
src/tools/vision.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Vision Tool - Image analysis using multimodal LLMs
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Provides image analysis functionality using:
 
1
  """
2
  Vision Tool - Image analysis using multimodal LLMs
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Provides image analysis functionality using:
src/tools/web_search.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Web Search Tool - Tavily and Exa implementations
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Provides web search functionality with:
 
1
  """
2
  Web Search Tool - Tavily and Exa implementations
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Provides web search functionality with:
src/tools/youtube.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  YouTube Video Analysis Tool - Extract transcripts or analyze frames from YouTube videos
3
- Author: @mangobee
4
  Date: 2026-01-13
5
 
6
  Provides two modes for YouTube video analysis:
 
1
  """
2
  YouTube Video Analysis Tool - Extract transcripts or analyze frames from YouTube videos
3
+ Author: @mangubee
4
  Date: 2026-01-13
5
 
6
  Provides two modes for YouTube video analysis:
src/utils/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """Utility modules for GAIA agent.
2
 
3
- Author: @mangobee
4
  """
5
 
6
  from .ground_truth import get_ground_truth, GAIAGroundTruth
 
1
  """Utility modules for GAIA agent.
2
 
3
+ Author: @mangubee
4
  """
5
 
6
  from .ground_truth import get_ground_truth, GAIAGroundTruth
src/utils/ground_truth.py CHANGED
@@ -1,6 +1,6 @@
1
  """Ground truth comparison using GAIA validation dataset.
2
 
3
- Author: @mangobee
4
 
5
  Since the GAIA API only returns summary stats (X/Y correct) without per-question
6
  correctness, we load the public validation dataset to compare our answers locally.
 
1
  """Ground truth comparison using GAIA validation dataset.
2
 
3
+ Author: @mangubee
4
 
5
  Since the GAIA API only returns summary stats (X/Y correct) without per-question
6
  correctness, we load the public validation dataset to compare our answers locally.
test/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tests Package for GAIA Agent
3
- Author: @mangobee
4
  Date: 2026-01-01
5
 
6
  Test organization:
 
1
  """
2
  Tests Package for GAIA Agent
3
+ Author: @mangubee
4
  Date: 2026-01-01
5
 
6
  Test organization:
test/fixtures/generate_fixtures.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Generate test fixtures for file parser tests
3
- Author: @mangobee
4
  """
5
 
6
  from pathlib import Path
 
1
  """
2
  Generate test fixtures for file parser tests
3
+ Author: @mangubee
4
  """
5
 
6
  from pathlib import Path
test/test_agent_basic.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Basic Tests for GAIA Agent - Stage 1 Validation
3
- Author: @mangobee
4
  Date: 2026-01-01
5
 
6
  Tests for Stage 1: Foundation Setup
 
1
  """
2
  Basic Tests for GAIA Agent - Stage 1 Validation
3
+ Author: @mangubee
4
  Date: 2026-01-01
5
 
6
  Tests for Stage 1: Foundation Setup
test/test_calculator.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tests for calculator tool (safe mathematical evaluation)
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
 
1
  """
2
  Tests for calculator tool (safe mathematical evaluation)
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
test/test_file_parser.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tests for file parser tool
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
 
1
  """
2
  Tests for file parser tool
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
test/test_llm_integration.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  LLM Integration Tests - Stage 3 Validation
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Tests for Stage 3 LLM integration:
 
1
  """
2
  LLM Integration Tests - Stage 3 Validation
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Tests for Stage 3 LLM integration:
test/test_phase0_hf_vision_api.py CHANGED
@@ -1,7 +1,7 @@
1
  #!/usr/bin/env python3
2
  """
3
  Phase 0: HuggingFace Inference API Vision Validation
4
- Author: @mangobee
5
  Date: 2026-01-07
6
 
7
  Tests HF Inference API with vision models to validate multimodal support BEFORE
 
1
  #!/usr/bin/env python3
2
  """
3
  Phase 0: HuggingFace Inference API Vision Validation
4
+ Author: @mangubee
5
  Date: 2026-01-07
6
 
7
  Tests HF Inference API with vision models to validate multimodal support BEFORE
test/test_smoke_hf_vision.py CHANGED
@@ -1,7 +1,7 @@
1
  #!/usr/bin/env python3
2
  """
3
  Phase 2: Smoke Tests for HF Vision Integration
4
- Author: @mangobee
5
  Date: 2026-01-11
6
 
7
  Quick validation that HF vision works before GAIA evaluation.
 
1
  #!/usr/bin/env python3
2
  """
3
  Phase 2: Smoke Tests for HF Vision Integration
4
+ Author: @mangubee
5
  Date: 2026-01-11
6
 
7
  Quick validation that HF vision works before GAIA evaluation.
test/test_stage1.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Stage 1 Quick Verification Test
3
- Author: @mangobee
4
 
5
  Test that agent initialization and basic execution works.
6
  """
 
1
  """
2
  Stage 1 Quick Verification Test
3
+ Author: @mangubee
4
 
5
  Test that agent initialization and basic execution works.
6
  """
test/test_stage3_e2e.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Stage 3 End-to-End Test with Real LLM API
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Manual test for Stage 3 workflow with actual Claude API.
 
1
  """
2
  Stage 3 End-to-End Test with Real LLM API
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Manual test for Stage 3 workflow with actual Claude API.
test/test_vision.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tests for vision tool (multimodal image analysis)
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
 
1
  """
2
  Tests for vision tool (multimodal image analysis)
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
test/test_web_search.py CHANGED
@@ -1,6 +1,6 @@
1
  """
2
  Tests for web search tool (Tavily and Exa)
3
- Author: @mangobee
4
  Date: 2026-01-02
5
 
6
  Tests cover:
 
1
  """
2
  Tests for web search tool (Tavily and Exa)
3
+ Author: @mangubee
4
  Date: 2026-01-02
5
 
6
  Tests cover: