Mehedi2 commited on
Commit
26e0177
·
verified ·
1 Parent(s): 6e3c530

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +163 -22
agent.py CHANGED
@@ -2,6 +2,7 @@ import os
2
  import time
3
  from pathlib import Path
4
  from typing import Optional, Union
 
5
 
6
  import pandas as pd
7
  from dotenv import load_dotenv
@@ -20,11 +21,59 @@ from smolagents.tools import Tool
20
  # Load environment variables
21
  load_dotenv()
22
 
23
- # Initialize the model
24
- model = LiteLLMModel(
25
- model_id="gemini/gemini-2.5-flash-preview-09-2025",
26
- api_key=os.getenv("GEMINI_API_KEY"),
27
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
 
30
  class ExcelToTextTool(Tool):
@@ -74,12 +123,25 @@ class ExcelToTextTool(Tool):
74
 
75
 
76
  class GaiaAgent:
77
- """An agent capable of using tools to answer general questions with rate limiting."""
78
 
79
- def __init__(self):
80
- print("✅ GaiaAgent initialized with tools.")
 
81
 
82
- tools = [
 
 
 
 
 
 
 
 
 
 
 
 
83
  DuckDuckGoSearchTool(),
84
  WikipediaSearchTool(),
85
  ExcelToTextTool(),
@@ -87,16 +149,61 @@ class GaiaAgent:
87
  FinalAnswerTool(),
88
  ]
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  self.agent = CodeAgent(
91
  model=model,
92
- tools=tools,
93
  add_base_tools=True,
94
  additional_authorized_imports=["pandas", "numpy", "csv", "subprocess"],
 
95
  )
 
 
 
 
96
 
97
- # Rate limiting configuration
98
- self.last_call_time = 0
99
- self.min_delay = 60 # 60 seconds between calls (10 per minute = 6s spacing)
 
 
 
 
 
 
 
 
 
100
 
101
  def __call__(self, task_id: str, question: str) -> str:
102
  # Apply rate limiting
@@ -106,17 +213,51 @@ class GaiaAgent:
106
  print(f"⏳ Rate limiting: waiting {wait_time:.1f}s...")
107
  time.sleep(wait_time)
108
 
109
- print(f"🔹 Agent received task_id='{task_id}' | question='{question[:50]}...'")
 
110
 
111
- try:
112
- answer = self.agent.run(question)
113
- if not answer:
114
- answer = "⚠️ Sorry, I could not generate a valid response."
115
- except Exception as e:
116
- answer = f"⚠️ Agent failed with error: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  # Update last call time
119
  self.last_call_time = time.time()
120
 
121
- print(f"🔹 Agent returning answer: {answer}")
122
- return answer
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import time
3
  from pathlib import Path
4
  from typing import Optional, Union
5
+ from itertools import cycle
6
 
7
  import pandas as pd
8
  from dotenv import load_dotenv
 
21
  # Load environment variables
22
  load_dotenv()
23
 
24
+
25
+ class MultiModelManager:
26
+ """Manages multiple Groq models with rotation and fallback."""
27
+
28
+ def __init__(self):
29
+ # Your selected Groq models with function calling / tool use support
30
+ self.models = [
31
+ "openai/gpt-oss-120b", # GPT OSS 120B - Most powerful, 500 tok/s
32
+ "openai/gpt-oss-20b", # GPT OSS 20B - Fast, 1000 tok/s
33
+ "meta-llama/llama-4-scout-17b-16e-instruct", # Llama 4 Scout - Multimodal
34
+ "qwen/qwen3-32b", # Qwen 3 32B - Advanced reasoning
35
+ "moonshotai/kimi-k2-instruct", # Kimi K2 - 1T params, agentic
36
+ ]
37
+
38
+ self.api_key = os.getenv("GROQ_API_KEY")
39
+ self.model_cycle = cycle(self.models)
40
+ self.current_model_name = self.models[0]
41
+
42
+ def get_next_model(self):
43
+ """Get the next model in rotation."""
44
+ self.current_model_name = next(self.model_cycle)
45
+ return LiteLLMModel(
46
+ model_id=self.current_model_name,
47
+ api_key=self.api_key,
48
+ )
49
+
50
+ def get_model_by_complexity(self, complexity: str = "high"):
51
+ """
52
+ Get a model based on task complexity.
53
+
54
+ Args:
55
+ complexity: "high", "medium", or "low"
56
+ """
57
+ if complexity == "high":
58
+ model_id = self.models[0] # llama-3.3-70b
59
+ elif complexity == "medium":
60
+ model_id = self.models[2] # mixtral-8x7b
61
+ else: # low
62
+ model_id = self.models[3] # llama-3.1-8b
63
+
64
+ self.current_model_name = model_id
65
+ return LiteLLMModel(
66
+ model_id=model_id,
67
+ api_key=self.api_key,
68
+ )
69
+
70
+ def get_primary_model(self):
71
+ """Get the primary (best) model."""
72
+ self.current_model_name = self.models[0]
73
+ return LiteLLMModel(
74
+ model_id=self.models[0],
75
+ api_key=self.api_key,
76
+ )
77
 
78
 
79
  class ExcelToTextTool(Tool):
 
123
 
124
 
125
  class GaiaAgent:
126
+ """An agent with multiple Groq models for better performance."""
127
 
128
+ def __init__(self, strategy: str = "primary"):
129
+ """
130
+ Initialize agent with model strategy.
131
 
132
+ Args:
133
+ strategy: "primary" (use best model), "rotate" (cycle through models),
134
+ or "adaptive" (choose based on task complexity)
135
+ """
136
+ print(f"✅ GaiaAgent initialized with '{strategy}' strategy.")
137
+
138
+ self.strategy = strategy
139
+ self.model_manager = MultiModelManager()
140
+ self.retry_count = 0
141
+ self.max_retries = 2
142
+
143
+ # Initialize tools
144
+ self.tools = [
145
  DuckDuckGoSearchTool(),
146
  WikipediaSearchTool(),
147
  ExcelToTextTool(),
 
149
  FinalAnswerTool(),
150
  ]
151
 
152
+ # System prompt for better performance
153
+ self.system_prompt = (
154
+ "You are a helpful assistant that answers questions accurately. "
155
+ "When given a question:\n"
156
+ "1. Analyze it carefully and break it down step by step\n"
157
+ "2. Use tools when needed (web search, Python code, etc.)\n"
158
+ "3. For math/logic problems, write Python code to verify your answer\n"
159
+ "4. For factual questions, search the web if needed\n"
160
+ "5. Double-check your work before providing the final answer\n"
161
+ "6. Provide concise, direct answers without unnecessary explanation\n"
162
+ "7. If dealing with tables or data, use Python/pandas to analyze them accurately"
163
+ )
164
+
165
+ # Rate limiting
166
+ self.last_call_time = 0
167
+ self.min_delay = 1 # Groq is very fast, minimal delay needed
168
+
169
+ # Initialize agent with primary model
170
+ self._reinitialize_agent()
171
+
172
+ def _reinitialize_agent(self):
173
+ """Reinitialize the agent with a new model."""
174
+ if self.strategy == "primary":
175
+ model = self.model_manager.get_primary_model()
176
+ elif self.strategy == "rotate":
177
+ model = self.model_manager.get_next_model()
178
+ else: # adaptive
179
+ model = self.model_manager.get_model_by_complexity("high")
180
+
181
+ print(f"🤖 Using model: {self.model_manager.current_model_name}")
182
+
183
  self.agent = CodeAgent(
184
  model=model,
185
+ tools=self.tools,
186
  add_base_tools=True,
187
  additional_authorized_imports=["pandas", "numpy", "csv", "subprocess"],
188
+ system_prompt=self.system_prompt,
189
  )
190
+
191
+ def _detect_complexity(self, question: str) -> str:
192
+ """Detect question complexity based on keywords."""
193
+ question_lower = question.lower()
194
 
195
+ # High complexity indicators
196
+ high_keywords = ["analyze", "complex", "multiple", "calculate", "prove",
197
+ "demonstrate", "derive", "algorithm"]
198
+ if any(keyword in question_lower for keyword in high_keywords):
199
+ return "high"
200
+
201
+ # Low complexity indicators
202
+ low_keywords = ["what is", "who is", "when", "define", "list"]
203
+ if any(keyword in question_lower for keyword in low_keywords):
204
+ return "low"
205
+
206
+ return "medium"
207
 
208
  def __call__(self, task_id: str, question: str) -> str:
209
  # Apply rate limiting
 
213
  print(f"⏳ Rate limiting: waiting {wait_time:.1f}s...")
214
  time.sleep(wait_time)
215
 
216
+ print(f"🔹 Task ID: {task_id}")
217
+ print(f"🔹 Question: {question[:100]}...")
218
 
219
+ # Adaptive strategy: choose model based on complexity
220
+ if self.strategy == "adaptive":
221
+ complexity = self._detect_complexity(question)
222
+ model = self.model_manager.get_model_by_complexity(complexity)
223
+ print(f"🎯 Detected complexity: {complexity}")
224
+ self._reinitialize_agent()
225
+ elif self.strategy == "rotate":
226
+ self._reinitialize_agent()
227
+
228
+ # Try to get answer with retry logic
229
+ answer = None
230
+ for attempt in range(self.max_retries + 1):
231
+ try:
232
+ answer = self.agent.run(question)
233
+ if answer:
234
+ break
235
+ except Exception as e:
236
+ print(f"⚠️ Attempt {attempt + 1} failed: {str(e)[:100]}")
237
+ if attempt < self.max_retries:
238
+ print(f"🔄 Retrying with next model...")
239
+ self._reinitialize_agent()
240
+ time.sleep(2)
241
+ else:
242
+ answer = f"⚠️ Agent failed after {self.max_retries + 1} attempts: {e}"
243
+
244
+ if not answer:
245
+ answer = "⚠️ Sorry, I could not generate a valid response."
246
 
247
  # Update last call time
248
  self.last_call_time = time.time()
249
 
250
+ print(f" Answer: {str(answer)[:100]}...")
251
+ return answer
252
+
253
+
254
+ # Example usage configurations:
255
+
256
+ # Strategy 1: Use primary (best) model for all tasks
257
+ # agent = GaiaAgent(strategy="primary")
258
+
259
+ # Strategy 2: Rotate between models to distribute load
260
+ # agent = GaiaAgent(strategy="rotate")
261
+
262
+ # Strategy 3: Adaptive - choose model based on question complexity
263
+ # agent = GaiaAgent(strategy="adaptive")