hassenhamdi commited on
Commit
6573e0d
·
verified ·
1 Parent(s): c38cd66

Create agent.py

Browse files
Files changed (1) hide show
  1. agent.py +157 -0
agent.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # agent.py
2
+ import contextlib
3
+ import io
4
+ import logging
5
+ import os
6
+ logger = logging.getLogger(__name__)
7
+
8
+ from models import GoogleModelID # Import GoogleModelID
9
+ from settings import Settings
10
+ from smolagents import OpenAIServerModel, CodeAgent, FinalAnswerTool # Changed from LiteLLMModel
11
+ from smolagents import DuckDuckGoSearchTool, VisitWebpageTool # Changed from GoogleSearchTool
12
+ from smolagents.local_python_executor import BASE_PYTHON_TOOLS
13
+ from tools import GetTaskFileTool, VideoUnderstandingTool, AudioUnderstandingTool
14
+ from tools import ChessBoardFENTool, BestChessMoveTool, ConvertChessMoveTool, ExcelParsingTool
15
+ import json # Added for BASE_PYTHON_TOOLS
16
+ import pandas as pd # Added for BASE_PYTHON_TOOLS
17
+
18
+
19
+ # Extend BASE_PYTHON_TOOLS for the PythonInterpreterTool to have access to these
20
+ BASE_PYTHON_TOOLS["open"] = open
21
+ BASE_PYTHON_TOOLS["os"] = os
22
+ BASE_PYTHON_TOOLS["io"] = io
23
+ BASE_PYTHON_TOOLS["contextlib"] = contextlib
24
+ BASE_PYTHON_TOOLS["exec"] = exec # Note: exec is powerful, use with caution in production
25
+ BASE_PYTHON_TOOLS["json"] = json # For parsing JSON if needed by agent
26
+ BASE_PYTHON_TOOLS["pd"] = pd # For pandas operations if needed by agent
27
+
28
+ class ResearchAgent:
29
+ def __init__(self, settings: Settings):
30
+ self.agent = CodeAgent(
31
+ name="researcher",
32
+ description="A specialized agent for web research, video analysis, and audio understanding. Give it your query as an argument. Use 'duckduckgo_search_tool' for web searches, 'visit_webpage_tool' to read web page content, 'video_understanding_tool' for YouTube videos, and 'audio_understanding_tool' for local audio files.",
33
+ add_base_tools=False,
34
+ tools=[
35
+ DuckDuckGoSearchTool(), # Changed from GoogleSearchTool
36
+ VisitWebpageTool(max_output_length=100000),
37
+ VideoUnderstandingTool(settings, GoogleModelID.GEMINI_2_0_FLASH), # Still uses 2.0 Flash for specific multimodal tasks
38
+ AudioUnderstandingTool(settings, GoogleModelID.GEMINI_2_0_FLASH) # Still uses 2.0 Flash for specific multimodal tasks
39
+ ],
40
+ additional_authorized_imports=[
41
+ "unicodedata", "stat", "datetime", "random", "pandas", "itertools",
42
+ "math", "statistics", "queue", "time", "collections", "re", "os",
43
+ "json", "io", "urllib.parse"
44
+ ],
45
+ max_steps=15,
46
+ verbosity_level=2,
47
+ model=OpenAIServerModel( # Changed to OpenAIServerModel
48
+ model_id=GoogleModelID.GEMINI_2_5_FLASH_PREVIEW, # Set to GEMINI_2_5_FLASH_PREVIEW
49
+ api_base="https://generativelanguage.googleapis.com/v1beta/openai/", # Gemini API base
50
+ api_key = settings.gemini_api_key.get_secret_value(), # Use Gemini API key
51
+ temperature=0.1,
52
+ timeout=180
53
+ )
54
+ )
55
+ logger.info("ResearchAgent initialized.")
56
+
57
+ class ChessAgent:
58
+ def __init__(self, settings: Settings):
59
+ self.agent = CodeAgent(
60
+ name="chess_player",
61
+ description="Makes a chess move. Give it a query including board image filepath and player turn (black or white).",
62
+ add_base_tools=False,
63
+ tools=[
64
+ ChessBoardFENTool(),
65
+ BestChessMoveTool(settings),
66
+ ConvertChessMoveTool(settings, GoogleModelID.GEMINI_2_5_FLASH_PREVIEW), # Changed to Gemini Flash Preview
67
+ ],
68
+ additional_authorized_imports=[
69
+ "unicodedata", "stat", "datetime", "random", "pandas", "itertools",
70
+ "math", "statistics", "queue", "time", "collections", "re", "os",
71
+ "json", "urllib.parse"
72
+ ],
73
+ max_steps=10,
74
+ verbosity_level=2,
75
+ model=OpenAIServerModel( # Changed to OpenAIServerModel
76
+ model_id=GoogleModelID.GEMINI_2_5_FLASH_PREVIEW, # Set to GEMINI_2_5_FLASH_PREVIEW
77
+ api_base="https://generativelanguage.googleapis.com/v1beta/openai/", # Gemini API base
78
+ api_key = settings.gemini_api_key.get_secret_value(), # Use Gemini API key
79
+ temperature=0.0,
80
+ timeout=180
81
+ )
82
+ )
83
+ logger.info("ChessAgent initialized.")
84
+
85
+ class ManagerAgent:
86
+ """
87
+ The main orchestrating agent that routes questions to specialized sub-agents
88
+ or handles them directly with its own tools.
89
+ """
90
+ def __init__(self, settings: Settings):
91
+ self.settings = settings
92
+ self.researcher = ResearchAgent(settings).agent
93
+ self.chess_player = ChessAgent(settings).agent
94
+
95
+ # Main manager agent
96
+ self.agent = CodeAgent(
97
+ name="manager",
98
+ description=(
99
+ "You are a highly capable AI assistant designed to solve complex GAIA benchmark questions. "
100
+ "Your primary role is to route tasks to the most appropriate specialized agent: "
101
+ "'researcher' for general knowledge, web browsing, video, and audio understanding tasks, "
102
+ "or 'chess_player' for chess-related tasks. "
103
+ "If a task involves downloading a file, use 'get_task_file_tool' first. "
104
+ "If you have the final answer, use 'final_answer_tool'.\n\n"
105
+ "**Available Tools:**\n"
106
+ "- `get_task_file_tool(task_id: str, file_name: str)`: Downloads a file associated with a task.\n"
107
+ "- `final_answer_tool(answer: str)`: Use this when you have the exact final answer.\n\n"
108
+ "**Managed Agents:**\n"
109
+ "- `researcher(query: str)`: Use for questions requiring web search, video analysis, or audio analysis.\n"
110
+ "- `chess_player(query: str)`: Use for questions related to chess positions or moves.\n\n"
111
+ "Think step-by-step. If a task involves a file, use `get_task_file_tool` first to download it, then pass the file path to the appropriate sub-agent or tool."
112
+ ),
113
+ tools=[
114
+ GetTaskFileTool(settings),
115
+ FinalAnswerTool(),
116
+ ExcelParsingTool(settings) # Added ExcelParsingTool to ManagerAgent as it handles file paths
117
+ ],
118
+ model=OpenAIServerModel( # Changed to OpenAIServerModel
119
+ model_id=GoogleModelID.GEMINI_2_5_FLASH_PREVIEW, # Set to GEMINI_2_5_FLASH_PREVIEW
120
+ api_base="https://generativelanguage.googleapis.com/v1beta/openai/", # Gemini API base
121
+ api_key = settings.gemini_api_key.get_secret_value(), # Use Gemini API key
122
+ temperature=0.0,
123
+ timeout=180
124
+ ),
125
+ managed_agents=[self.researcher, self.chess_player],
126
+ verbosity_level=2,
127
+ max_steps=20
128
+ )
129
+ logger.info("ManagerAgent initialized.")
130
+
131
+ def __call__(self, question_data: dict) -> str:
132
+ task_id = question_data.get("task_id", "N/A")
133
+ question_text = question_data.get("question", "")
134
+ file_name = question_data.get("file_name", "")
135
+
136
+ enriched_question = (
137
+ f"{question_text} "
138
+ f"task_id: {task_id}. "
139
+ f"Your final answer should be a number or as few words as possible. "
140
+ f"Only use abbreviations when the question calls for abbreviations. "
141
+ f"If needed, use a comma separated list of values; the comma is always followed by a space. "
142
+ f"Critically review your answer before making it the final answer. "
143
+ f"Double check the answer to make sure it meets all format requirements stated in the question. "
144
+ )
145
+ if file_name:
146
+ enriched_question = f"{enriched_question} file_name: {file_name} (use get_task_file_tool to fetch this file and then pass its path to the relevant tool/agent, or excel_parsing_tool if it's an Excel file)." # Updated prompt for Excel
147
+
148
+ logger.info(f"ManagerAgent received question (first 100 chars): {enriched_question[:100]}...")
149
+
150
+ try:
151
+ final_answer = self.agent.run(enriched_question)
152
+ logger.info(f"ManagerAgent returning final answer: {final_answer}")
153
+ return final_answer
154
+ except Exception as e:
155
+ logger.error(f"Error running ManagerAgent on task {task_id}: {e}")
156
+ return f"AGENT ERROR: {e}"
157
+