Spaces:
Sleeping
Sleeping
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)
|