Update veryfinal.py
Browse files- veryfinal.py +40 -33
veryfinal.py
CHANGED
@@ -9,11 +9,12 @@ load_dotenv()
|
|
9 |
from agno.agent import Agent
|
10 |
from agno.models.groq import Groq
|
11 |
from agno.models.google import Gemini
|
12 |
-
from agno.tools.duckduckgo import DuckDuckGoTools
|
13 |
from agno.tools.yfinance import YFinanceTools
|
14 |
|
|
|
|
|
|
|
15 |
# Additional imports for custom tools
|
16 |
-
from langchain_community.tools.tavily_search import TavilySearchResults
|
17 |
from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
|
18 |
|
19 |
# Advanced Rate Limiter with exponential backoff (SILENT)
|
@@ -37,18 +38,6 @@ class AdvancedRateLimiter:
|
|
37 |
wait_time = 60 - (current_time - self.request_times[0]) + random.uniform(2, 8)
|
38 |
await asyncio.sleep(wait_time)
|
39 |
|
40 |
-
# Calculate wait time for tokens (SILENT)
|
41 |
-
if self.tokens_per_minute:
|
42 |
-
total_tokens = sum(tokens for _, tokens in self.token_usage)
|
43 |
-
if total_tokens + estimated_tokens > self.tokens_per_minute:
|
44 |
-
wait_time = 60 - (current_time - self.token_usage[0][0]) + random.uniform(3, 10)
|
45 |
-
await asyncio.sleep(wait_time)
|
46 |
-
|
47 |
-
# Add exponential backoff for consecutive failures (SILENT)
|
48 |
-
if self.consecutive_failures > 0:
|
49 |
-
backoff_time = min(2 ** self.consecutive_failures, 120) + random.uniform(2, 6)
|
50 |
-
await asyncio.sleep(backoff_time)
|
51 |
-
|
52 |
# Record this request
|
53 |
self.request_times.append(current_time)
|
54 |
if self.tokens_per_minute:
|
@@ -63,6 +52,10 @@ class AdvancedRateLimiter:
|
|
63 |
# Initialize rate limiters for free tiers
|
64 |
groq_limiter = AdvancedRateLimiter(requests_per_minute=30, tokens_per_minute=6000)
|
65 |
gemini_limiter = AdvancedRateLimiter(requests_per_minute=2, tokens_per_minute=32000)
|
|
|
|
|
|
|
|
|
66 |
|
67 |
# Custom tool functions with rate limiting (SILENT)
|
68 |
def multiply_tool(a: float, b: float) -> float:
|
@@ -83,14 +76,26 @@ def divide_tool(a: float, b: float) -> float:
|
|
83 |
raise ValueError("Cannot divide by zero.")
|
84 |
return a / b
|
85 |
|
86 |
-
async def
|
87 |
-
"""Search
|
88 |
try:
|
89 |
-
await
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
except Exception as e:
|
93 |
-
return f"
|
94 |
|
95 |
async def wiki_search_tool(query: str) -> str:
|
96 |
"""Search Wikipedia with rate limiting."""
|
@@ -102,6 +107,15 @@ async def wiki_search_tool(query: str) -> str:
|
|
102 |
except Exception as e:
|
103 |
return f"Wikipedia search failed: {str(e)}"
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
# Create specialized Agno agents (SILENT)
|
106 |
def create_agno_agents():
|
107 |
"""Create specialized Agno agents with the best free models"""
|
@@ -134,10 +148,10 @@ def create_agno_agents():
|
|
134 |
api_key=os.getenv("GOOGLE_API_KEY"),
|
135 |
temperature=0
|
136 |
),
|
137 |
-
tools=[
|
138 |
instructions=[
|
139 |
"You are a research specialist with access to multiple search tools.",
|
140 |
-
"Use
|
141 |
"Always cite sources and provide well-researched answers.",
|
142 |
"Synthesize information from multiple sources when possible.",
|
143 |
"Finish with: FINAL ANSWER: [your researched answer]"
|
@@ -154,12 +168,11 @@ def create_agno_agents():
|
|
154 |
api_key=os.getenv("GROQ_API_KEY"),
|
155 |
temperature=0
|
156 |
),
|
157 |
-
tools=[
|
158 |
instructions=[
|
159 |
"You are the main coordinator agent.",
|
160 |
"Analyze queries and provide comprehensive responses.",
|
161 |
-
"Use search
|
162 |
-
"Route complex math to calculation tools.",
|
163 |
"Always finish with: FINAL ANSWER: [your final answer]"
|
164 |
],
|
165 |
show_tool_calls=False, # SILENT
|
@@ -218,11 +231,6 @@ class AgnoMultiAgentSystem:
|
|
218 |
await asyncio.sleep(wait_time)
|
219 |
continue
|
220 |
|
221 |
-
elif any(keyword in error_msg for keyword in ['api', 'connection', 'timeout', 'service unavailable']):
|
222 |
-
wait_time = (2 ** attempt) + random.uniform(5, 15)
|
223 |
-
await asyncio.sleep(wait_time)
|
224 |
-
continue
|
225 |
-
|
226 |
elif attempt == max_retries - 1:
|
227 |
try:
|
228 |
return self.agents["coordinator"].run(f"Answer this as best you can: {query}", stream=False)
|
@@ -246,7 +254,6 @@ def main(query: str) -> str:
|
|
246 |
try:
|
247 |
loop = asyncio.get_event_loop()
|
248 |
if loop.is_running():
|
249 |
-
# For Jupyter notebooks
|
250 |
import nest_asyncio
|
251 |
nest_asyncio.apply()
|
252 |
return asyncio.run(main_async(query))
|
@@ -265,12 +272,12 @@ def get_final_answer(query: str) -> str:
|
|
265 |
else:
|
266 |
return full_response.strip()
|
267 |
|
268 |
-
# For Jupyter notebooks
|
269 |
async def run_query(query: str) -> str:
|
270 |
"""Direct async function for Jupyter notebooks (SILENT)"""
|
271 |
return await main_async(query)
|
272 |
|
273 |
if __name__ == "__main__":
|
274 |
-
# Test the Agno system - CLEAN OUTPUT ONLY
|
275 |
result = get_final_answer("What are the names of the US presidents who were assassinated?")
|
276 |
print(result)
|
|
|
9 |
from agno.agent import Agent
|
10 |
from agno.models.groq import Groq
|
11 |
from agno.models.google import Gemini
|
|
|
12 |
from agno.tools.yfinance import YFinanceTools
|
13 |
|
14 |
+
# Tavily import (replacing DuckDuckGo)
|
15 |
+
from tavily import TavilyClient
|
16 |
+
|
17 |
# Additional imports for custom tools
|
|
|
18 |
from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
|
19 |
|
20 |
# Advanced Rate Limiter with exponential backoff (SILENT)
|
|
|
38 |
wait_time = 60 - (current_time - self.request_times[0]) + random.uniform(2, 8)
|
39 |
await asyncio.sleep(wait_time)
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
# Record this request
|
42 |
self.request_times.append(current_time)
|
43 |
if self.tokens_per_minute:
|
|
|
52 |
# Initialize rate limiters for free tiers
|
53 |
groq_limiter = AdvancedRateLimiter(requests_per_minute=30, tokens_per_minute=6000)
|
54 |
gemini_limiter = AdvancedRateLimiter(requests_per_minute=2, tokens_per_minute=32000)
|
55 |
+
tavily_limiter = AdvancedRateLimiter(requests_per_minute=50) # Tavily rate limit
|
56 |
+
|
57 |
+
# Initialize Tavily client
|
58 |
+
tavily_client = TavilyClient(os.getenv("TAVILY_API_KEY"))
|
59 |
|
60 |
# Custom tool functions with rate limiting (SILENT)
|
61 |
def multiply_tool(a: float, b: float) -> float:
|
|
|
76 |
raise ValueError("Cannot divide by zero.")
|
77 |
return a / b
|
78 |
|
79 |
+
async def tavily_search_tool(query: str) -> str:
|
80 |
+
"""Search using Tavily with rate limiting."""
|
81 |
try:
|
82 |
+
await tavily_limiter.wait_if_needed()
|
83 |
+
response = tavily_client.search(
|
84 |
+
query=query,
|
85 |
+
max_results=3,
|
86 |
+
search_depth="basic",
|
87 |
+
include_answer=False
|
88 |
+
)
|
89 |
+
|
90 |
+
# Format results
|
91 |
+
results = []
|
92 |
+
for result in response.get('results', []):
|
93 |
+
results.append(f"Title: {result.get('title', '')}\nContent: {result.get('content', '')}")
|
94 |
+
|
95 |
+
return "\n\n---\n\n".join(results)
|
96 |
+
|
97 |
except Exception as e:
|
98 |
+
return f"Tavily search failed: {str(e)}"
|
99 |
|
100 |
async def wiki_search_tool(query: str) -> str:
|
101 |
"""Search Wikipedia with rate limiting."""
|
|
|
107 |
except Exception as e:
|
108 |
return f"Wikipedia search failed: {str(e)}"
|
109 |
|
110 |
+
async def arxiv_search_tool(query: str) -> str:
|
111 |
+
"""Search ArXiv with rate limiting."""
|
112 |
+
try:
|
113 |
+
await asyncio.sleep(random.uniform(1, 4))
|
114 |
+
search_docs = ArxivLoader(query=query, load_max_docs=2).load()
|
115 |
+
return "\n\n---\n\n".join([doc.page_content[:800] for doc in search_docs])
|
116 |
+
except Exception as e:
|
117 |
+
return f"ArXiv search failed: {str(e)}"
|
118 |
+
|
119 |
# Create specialized Agno agents (SILENT)
|
120 |
def create_agno_agents():
|
121 |
"""Create specialized Agno agents with the best free models"""
|
|
|
148 |
api_key=os.getenv("GOOGLE_API_KEY"),
|
149 |
temperature=0
|
150 |
),
|
151 |
+
tools=[tavily_search_tool, wiki_search_tool, arxiv_search_tool], # Using Tavily instead of DuckDuckGo
|
152 |
instructions=[
|
153 |
"You are a research specialist with access to multiple search tools.",
|
154 |
+
"Use Tavily search for current web information, Wikipedia for encyclopedic content, and ArXiv for academic papers.",
|
155 |
"Always cite sources and provide well-researched answers.",
|
156 |
"Synthesize information from multiple sources when possible.",
|
157 |
"Finish with: FINAL ANSWER: [your researched answer]"
|
|
|
168 |
api_key=os.getenv("GROQ_API_KEY"),
|
169 |
temperature=0
|
170 |
),
|
171 |
+
tools=[tavily_search_tool, wiki_search_tool], # Using Tavily instead of DuckDuckGo
|
172 |
instructions=[
|
173 |
"You are the main coordinator agent.",
|
174 |
"Analyze queries and provide comprehensive responses.",
|
175 |
+
"Use Tavily search for current information and Wikipedia for background context.",
|
|
|
176 |
"Always finish with: FINAL ANSWER: [your final answer]"
|
177 |
],
|
178 |
show_tool_calls=False, # SILENT
|
|
|
231 |
await asyncio.sleep(wait_time)
|
232 |
continue
|
233 |
|
|
|
|
|
|
|
|
|
|
|
234 |
elif attempt == max_retries - 1:
|
235 |
try:
|
236 |
return self.agents["coordinator"].run(f"Answer this as best you can: {query}", stream=False)
|
|
|
254 |
try:
|
255 |
loop = asyncio.get_event_loop()
|
256 |
if loop.is_running():
|
|
|
257 |
import nest_asyncio
|
258 |
nest_asyncio.apply()
|
259 |
return asyncio.run(main_async(query))
|
|
|
272 |
else:
|
273 |
return full_response.strip()
|
274 |
|
275 |
+
# For Jupyter notebooks
|
276 |
async def run_query(query: str) -> str:
|
277 |
"""Direct async function for Jupyter notebooks (SILENT)"""
|
278 |
return await main_async(query)
|
279 |
|
280 |
if __name__ == "__main__":
|
281 |
+
# Test the Agno system with Tavily - CLEAN OUTPUT ONLY
|
282 |
result = get_final_answer("What are the names of the US presidents who were assassinated?")
|
283 |
print(result)
|