Spaces:
Sleeping
Sleeping
more tools and added allowed
Browse files
app.py
CHANGED
|
@@ -9,6 +9,12 @@ import time
|
|
| 9 |
import random
|
| 10 |
import json
|
| 11 |
import google.generativeai as genai
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
from smolagents import FinalAnswerTool, Tool, tool, OpenAIServerModel, DuckDuckGoSearchTool, CodeAgent, VisitWebpageTool
|
| 13 |
|
| 14 |
|
|
@@ -127,6 +133,184 @@ class WikipediaSearchTool(Tool):
|
|
| 127 |
|
| 128 |
return f"Wikipedia search unavailable for '{query}'. Use your knowledge to answer."
|
| 129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
# --- Gemini Model Wrapper ---
|
| 131 |
class GeminiModel:
|
| 132 |
def __init__(self, model_name="gemini-2.0-flash", temperature=0.0, max_tokens=500):
|
|
@@ -187,25 +371,25 @@ class SlpMultiAgent:
|
|
| 187 |
)
|
| 188 |
print("Using OpenAI model (Gemini not available)")
|
| 189 |
|
| 190 |
-
# Create
|
| 191 |
research_agent = CodeAgent(
|
| 192 |
-
tools=[GoogleSearchTool(), KnowledgeBaseTool()],
|
| 193 |
model=model if not isinstance(model, GeminiModel) else OpenAIServerModel(model_id="gpt-3.5-turbo", temperature=0.0, max_tokens=400),
|
| 194 |
-
additional_authorized_imports=["re", "datetime"],
|
| 195 |
-
max_steps=
|
| 196 |
name="ResearchAgent",
|
| 197 |
verbosity_level=0,
|
| 198 |
-
description="Research agent with Google Search and knowledge lookup."
|
| 199 |
)
|
| 200 |
|
| 201 |
solver_agent = CodeAgent(
|
| 202 |
-
tools=[
|
| 203 |
model=model if not isinstance(model, GeminiModel) else OpenAIServerModel(model_id="gpt-3.5-turbo", temperature=0.0, max_tokens=400),
|
| 204 |
-
additional_authorized_imports=["math", "re", "collections", "itertools"],
|
| 205 |
-
max_steps=
|
| 206 |
name="SolverAgent",
|
| 207 |
verbosity_level=0,
|
| 208 |
-
description="Problem solving with
|
| 209 |
)
|
| 210 |
|
| 211 |
manager_agent = CodeAgent(
|
|
@@ -214,14 +398,14 @@ class SlpMultiAgent:
|
|
| 214 |
temperature=0.0,
|
| 215 |
max_tokens=500
|
| 216 |
),
|
| 217 |
-
tools=[GoogleSearchTool(), KnowledgeBaseTool()],
|
| 218 |
managed_agents=[research_agent, solver_agent],
|
| 219 |
name="ManagerAgent",
|
| 220 |
-
description="Manager with
|
| 221 |
-
additional_authorized_imports=["re", "math"],
|
| 222 |
planning_interval=1,
|
| 223 |
verbosity_level=0,
|
| 224 |
-
max_steps=
|
| 225 |
final_answer_checks=[check_reasoning]
|
| 226 |
)
|
| 227 |
|
|
@@ -237,11 +421,24 @@ class SlpMultiAgent:
|
|
| 237 |
lambda: manager_agent.run(f"""
|
| 238 |
Question: {short_question}
|
| 239 |
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
-
|
| 245 |
|
| 246 |
IMPORTANT: Always end with exactly this format:
|
| 247 |
<code>
|
|
|
|
| 9 |
import random
|
| 10 |
import json
|
| 11 |
import google.generativeai as genai
|
| 12 |
+
import tempfile
|
| 13 |
+
import uuid
|
| 14 |
+
import math
|
| 15 |
+
import cmath
|
| 16 |
+
import numpy as np
|
| 17 |
+
from urllib.parse import urlparse
|
| 18 |
from smolagents import FinalAnswerTool, Tool, tool, OpenAIServerModel, DuckDuckGoSearchTool, CodeAgent, VisitWebpageTool
|
| 19 |
|
| 20 |
|
|
|
|
| 133 |
|
| 134 |
return f"Wikipedia search unavailable for '{query}'. Use your knowledge to answer."
|
| 135 |
|
| 136 |
+
# --- Mathematical Tools ---
|
| 137 |
+
class MathTool(Tool):
|
| 138 |
+
name = "math_calculator"
|
| 139 |
+
description = "Perform mathematical calculations including basic operations, powers, roots"
|
| 140 |
+
inputs = {"expression": {"type": "string", "description": "Mathematical expression to evaluate"}}
|
| 141 |
+
output_type = "string"
|
| 142 |
+
|
| 143 |
+
def __init__(self):
|
| 144 |
+
super().__init__()
|
| 145 |
+
self.is_initialized = True
|
| 146 |
+
|
| 147 |
+
def forward(self, expression: str) -> str:
|
| 148 |
+
try:
|
| 149 |
+
# Safe evaluation of mathematical expressions
|
| 150 |
+
allowed_names = {
|
| 151 |
+
k: v for k, v in math.__dict__.items() if not k.startswith("__")
|
| 152 |
+
}
|
| 153 |
+
allowed_names.update({"abs": abs, "round": round, "pow": pow})
|
| 154 |
+
|
| 155 |
+
result = eval(expression, {"__builtins__": {}}, allowed_names)
|
| 156 |
+
return f"Result: {result}"
|
| 157 |
+
except Exception as e:
|
| 158 |
+
return f"Math calculation error: {str(e)}"
|
| 159 |
+
|
| 160 |
+
# --- File Processing Tools ---
|
| 161 |
+
class FileProcessorTool(Tool):
|
| 162 |
+
name = "file_processor"
|
| 163 |
+
description = "Download files from URLs, save content to files, and analyze CSV/Excel files"
|
| 164 |
+
inputs = {
|
| 165 |
+
"action": {"type": "string", "description": "Action: 'download', 'save', 'analyze_csv', 'analyze_excel'"},
|
| 166 |
+
"data": {"type": "string", "description": "URL, content, or file path depending on action"}
|
| 167 |
+
}
|
| 168 |
+
output_type = "string"
|
| 169 |
+
|
| 170 |
+
def __init__(self):
|
| 171 |
+
super().__init__()
|
| 172 |
+
self.is_initialized = True
|
| 173 |
+
|
| 174 |
+
def forward(self, action: str, data: str) -> str:
|
| 175 |
+
try:
|
| 176 |
+
if action == "download":
|
| 177 |
+
return self._download_file(data)
|
| 178 |
+
elif action == "save":
|
| 179 |
+
return self._save_content(data)
|
| 180 |
+
elif action == "analyze_csv":
|
| 181 |
+
return self._analyze_csv(data)
|
| 182 |
+
elif action == "analyze_excel":
|
| 183 |
+
return self._analyze_excel(data)
|
| 184 |
+
else:
|
| 185 |
+
return f"Unknown action: {action}"
|
| 186 |
+
except Exception as e:
|
| 187 |
+
return f"File processing error: {str(e)}"
|
| 188 |
+
|
| 189 |
+
def _download_file(self, url: str) -> str:
|
| 190 |
+
try:
|
| 191 |
+
response = requests.get(url, timeout=10)
|
| 192 |
+
response.raise_for_status()
|
| 193 |
+
|
| 194 |
+
filename = os.path.basename(urlparse(url).path) or f"download_{uuid.uuid4().hex[:8]}"
|
| 195 |
+
filepath = os.path.join(tempfile.gettempdir(), filename)
|
| 196 |
+
|
| 197 |
+
with open(filepath, 'wb') as f:
|
| 198 |
+
f.write(response.content)
|
| 199 |
+
|
| 200 |
+
return f"File downloaded to: {filepath}"
|
| 201 |
+
except Exception as e:
|
| 202 |
+
return f"Download failed: {str(e)}"
|
| 203 |
+
|
| 204 |
+
def _save_content(self, content: str) -> str:
|
| 205 |
+
try:
|
| 206 |
+
filepath = os.path.join(tempfile.gettempdir(), f"content_{uuid.uuid4().hex[:8]}.txt")
|
| 207 |
+
with open(filepath, 'w') as f:
|
| 208 |
+
f.write(content)
|
| 209 |
+
return f"Content saved to: {filepath}"
|
| 210 |
+
except Exception as e:
|
| 211 |
+
return f"Save failed: {str(e)}"
|
| 212 |
+
|
| 213 |
+
def _analyze_csv(self, filepath: str) -> str:
|
| 214 |
+
try:
|
| 215 |
+
df = pd.read_csv(filepath)
|
| 216 |
+
result = f"CSV Analysis:\n- Rows: {len(df)}\n- Columns: {len(df.columns)}\n"
|
| 217 |
+
result += f"- Column names: {', '.join(df.columns)}\n"
|
| 218 |
+
result += f"- Summary:\n{df.describe().to_string()}"
|
| 219 |
+
return result[:1000]
|
| 220 |
+
except Exception as e:
|
| 221 |
+
return f"CSV analysis failed: {str(e)}"
|
| 222 |
+
|
| 223 |
+
def _analyze_excel(self, filepath: str) -> str:
|
| 224 |
+
try:
|
| 225 |
+
df = pd.read_excel(filepath)
|
| 226 |
+
result = f"Excel Analysis:\n- Rows: {len(df)}\n- Columns: {len(df.columns)}\n"
|
| 227 |
+
result += f"- Column names: {', '.join(df.columns)}\n"
|
| 228 |
+
result += f"- Summary:\n{df.describe().to_string()}"
|
| 229 |
+
return result[:1000]
|
| 230 |
+
except Exception as e:
|
| 231 |
+
return f"Excel analysis failed: {str(e)}"
|
| 232 |
+
|
| 233 |
+
# --- Code Execution Tool ---
|
| 234 |
+
class CodeExecutorTool(Tool):
|
| 235 |
+
name = "code_executor"
|
| 236 |
+
description = "Execute Python code safely and return results"
|
| 237 |
+
inputs = {"code": {"type": "string", "description": "Python code to execute"}}
|
| 238 |
+
output_type = "string"
|
| 239 |
+
|
| 240 |
+
def __init__(self):
|
| 241 |
+
super().__init__()
|
| 242 |
+
self.is_initialized = True
|
| 243 |
+
|
| 244 |
+
def forward(self, code: str) -> str:
|
| 245 |
+
try:
|
| 246 |
+
# Create a restricted execution environment
|
| 247 |
+
allowed_modules = {
|
| 248 |
+
'math': math, 'cmath': cmath, 'random': random,
|
| 249 |
+
'json': json, 'time': time, 'os': os,
|
| 250 |
+
'pandas': pd, 'numpy': np
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
# Capture output
|
| 254 |
+
import io
|
| 255 |
+
import sys
|
| 256 |
+
from contextlib import redirect_stdout, redirect_stderr
|
| 257 |
+
|
| 258 |
+
stdout_capture = io.StringIO()
|
| 259 |
+
stderr_capture = io.StringIO()
|
| 260 |
+
|
| 261 |
+
with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture):
|
| 262 |
+
exec(code, {"__builtins__": {}, **allowed_modules})
|
| 263 |
+
|
| 264 |
+
stdout_result = stdout_capture.getvalue()
|
| 265 |
+
stderr_result = stderr_capture.getvalue()
|
| 266 |
+
|
| 267 |
+
result = "Code executed successfully\n"
|
| 268 |
+
if stdout_result:
|
| 269 |
+
result += f"Output: {stdout_result}\n"
|
| 270 |
+
if stderr_result:
|
| 271 |
+
result += f"Errors: {stderr_result}\n"
|
| 272 |
+
|
| 273 |
+
return result[:1000]
|
| 274 |
+
|
| 275 |
+
except Exception as e:
|
| 276 |
+
return f"Code execution error: {str(e)}"
|
| 277 |
+
|
| 278 |
+
# --- Web Scraping Tool ---
|
| 279 |
+
class WebScrapeTool(Tool):
|
| 280 |
+
name = "web_scraper"
|
| 281 |
+
description = "Scrape content from web pages"
|
| 282 |
+
inputs = {"url": {"type": "string", "description": "URL to scrape"}}
|
| 283 |
+
output_type = "string"
|
| 284 |
+
|
| 285 |
+
def __init__(self):
|
| 286 |
+
super().__init__()
|
| 287 |
+
self.is_initialized = True
|
| 288 |
+
|
| 289 |
+
def forward(self, url: str) -> str:
|
| 290 |
+
try:
|
| 291 |
+
response = requests.get(url, timeout=10, headers={'User-Agent': 'Mozilla/5.0'})
|
| 292 |
+
response.raise_for_status()
|
| 293 |
+
|
| 294 |
+
# Simple text extraction (you could add BeautifulSoup for better parsing)
|
| 295 |
+
content = response.text
|
| 296 |
+
|
| 297 |
+
# Extract title if possible
|
| 298 |
+
title_start = content.find('<title>')
|
| 299 |
+
title_end = content.find('</title>')
|
| 300 |
+
title = "Unknown"
|
| 301 |
+
if title_start != -1 and title_end != -1:
|
| 302 |
+
title = content[title_start+7:title_end]
|
| 303 |
+
|
| 304 |
+
# Return basic info
|
| 305 |
+
result = f"Page Title: {title}\n"
|
| 306 |
+
result += f"Content Length: {len(content)} characters\n"
|
| 307 |
+
result += f"First 500 chars: {content[:500]}..."
|
| 308 |
+
|
| 309 |
+
return result
|
| 310 |
+
|
| 311 |
+
except Exception as e:
|
| 312 |
+
return f"Web scraping error: {str(e)}"
|
| 313 |
+
|
| 314 |
# --- Gemini Model Wrapper ---
|
| 315 |
class GeminiModel:
|
| 316 |
def __init__(self, model_name="gemini-2.0-flash", temperature=0.0, max_tokens=500):
|
|
|
|
| 371 |
)
|
| 372 |
print("Using OpenAI model (Gemini not available)")
|
| 373 |
|
| 374 |
+
# Create comprehensive agents with multiple tools
|
| 375 |
research_agent = CodeAgent(
|
| 376 |
+
tools=[GoogleSearchTool(), WikipediaSearchTool(), WebScrapeTool(), KnowledgeBaseTool()],
|
| 377 |
model=model if not isinstance(model, GeminiModel) else OpenAIServerModel(model_id="gpt-3.5-turbo", temperature=0.0, max_tokens=400),
|
| 378 |
+
additional_authorized_imports=["re", "datetime", "math", "json", "requests", "pandas", "numpy", "time", "os", "tempfile", "uuid"],
|
| 379 |
+
max_steps=3,
|
| 380 |
name="ResearchAgent",
|
| 381 |
verbosity_level=0,
|
| 382 |
+
description="Research agent with Google Search, Wikipedia, web scraping, and knowledge lookup."
|
| 383 |
)
|
| 384 |
|
| 385 |
solver_agent = CodeAgent(
|
| 386 |
+
tools=[MathTool(), CodeExecutorTool(), FileProcessorTool(), GoogleSearchTool()],
|
| 387 |
model=model if not isinstance(model, GeminiModel) else OpenAIServerModel(model_id="gpt-3.5-turbo", temperature=0.0, max_tokens=400),
|
| 388 |
+
additional_authorized_imports=["math", "re", "collections", "itertools", "pandas", "numpy", "json", "time", "os", "tempfile", "uuid", "requests"],
|
| 389 |
+
max_steps=3,
|
| 390 |
name="SolverAgent",
|
| 391 |
verbosity_level=0,
|
| 392 |
+
description="Problem solving with math, code execution, file processing, and search capabilities."
|
| 393 |
)
|
| 394 |
|
| 395 |
manager_agent = CodeAgent(
|
|
|
|
| 398 |
temperature=0.0,
|
| 399 |
max_tokens=500
|
| 400 |
),
|
| 401 |
+
tools=[GoogleSearchTool(), MathTool(), FileProcessorTool(), KnowledgeBaseTool()],
|
| 402 |
managed_agents=[research_agent, solver_agent],
|
| 403 |
name="ManagerAgent",
|
| 404 |
+
description="Manager with comprehensive tool access and agent coordination.",
|
| 405 |
+
additional_authorized_imports=["re", "math", "json", "pandas", "numpy", "requests", "time", "os", "tempfile", "uuid"],
|
| 406 |
planning_interval=1,
|
| 407 |
verbosity_level=0,
|
| 408 |
+
max_steps=4,
|
| 409 |
final_answer_checks=[check_reasoning]
|
| 410 |
)
|
| 411 |
|
|
|
|
| 421 |
lambda: manager_agent.run(f"""
|
| 422 |
Question: {short_question}
|
| 423 |
|
| 424 |
+
IMPORTANT: Use ONLY the available tool functions, do NOT try to call functions directly in code.
|
| 425 |
+
|
| 426 |
+
Available tools (call these as functions):
|
| 427 |
+
- google_search(query="your search"): Web search (PRIMARY for factual questions)
|
| 428 |
+
- math_calculator(expression="your math"): Mathematical calculations
|
| 429 |
+
- file_processor(action="download/save/analyze_csv/analyze_excel", data="url/content/path"): File operations
|
| 430 |
+
- knowledge_base(topic="your topic"): Structured knowledge lookup
|
| 431 |
+
|
| 432 |
+
Managed agents (delegate to these):
|
| 433 |
+
- ResearchAgent: For complex research tasks
|
| 434 |
+
- SolverAgent: For complex problem solving
|
| 435 |
+
|
| 436 |
+
Strategy:
|
| 437 |
+
1. For factual questions: Call google_search() directly
|
| 438 |
+
2. For calculations: Call math_calculator() directly
|
| 439 |
+
3. For complex tasks: Delegate to appropriate agent
|
| 440 |
|
| 441 |
+
DO NOT write code that calls undefined functions like wikipedia_search().
|
| 442 |
|
| 443 |
IMPORTANT: Always end with exactly this format:
|
| 444 |
<code>
|