|
|
|
|
|
""" |
|
|
Tool definitions for the agent |
|
|
""" |
|
|
|
|
|
import requests |
|
|
from typing import List, Dict, Any |
|
|
import re |
|
|
|
|
|
class Tool: |
|
|
"""Base tool class""" |
|
|
def __init__(self, name: str, description: str, parameters: Dict[str, Any]): |
|
|
self.name = name |
|
|
self.description = description |
|
|
self.parameters = parameters |
|
|
|
|
|
def __call__(self, **kwargs): |
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
class WebSearchTool(Tool): |
|
|
"""Web search using DuckDuckGo or similar""" |
|
|
|
|
|
def __init__(self): |
|
|
super().__init__( |
|
|
name="web_search", |
|
|
description="Search the web for current information. Use this when you need to find facts, statistics, recent events, or any information not in your training data.", |
|
|
parameters={ |
|
|
"type": "object", |
|
|
"properties": { |
|
|
"query": { |
|
|
"type": "string", |
|
|
"description": "The search query" |
|
|
} |
|
|
}, |
|
|
"required": ["query"] |
|
|
} |
|
|
) |
|
|
|
|
|
def __call__(self, query: str) -> str: |
|
|
"""Perform web search using DuckDuckGo API""" |
|
|
try: |
|
|
|
|
|
url = "https://api.duckduckgo.com/" |
|
|
params = { |
|
|
"q": query, |
|
|
"format": "json", |
|
|
"no_html": 1, |
|
|
"skip_disambig": 1 |
|
|
} |
|
|
|
|
|
response = requests.get(url, params=params, timeout=10) |
|
|
data = response.json() |
|
|
|
|
|
|
|
|
results = [] |
|
|
|
|
|
if data.get("Abstract"): |
|
|
results.append(data["Abstract"]) |
|
|
|
|
|
if data.get("RelatedTopics"): |
|
|
for topic in data["RelatedTopics"][:3]: |
|
|
if isinstance(topic, dict) and topic.get("Text"): |
|
|
results.append(topic["Text"]) |
|
|
|
|
|
if results: |
|
|
return " ".join(results) |
|
|
|
|
|
return f"No detailed results found for: {query}" |
|
|
|
|
|
except Exception as e: |
|
|
return f"Search error: {str(e)}" |
|
|
|
|
|
|
|
|
class WikipediaSearchTool(Tool): |
|
|
"""Wikipedia search""" |
|
|
|
|
|
def __init__(self): |
|
|
super().__init__( |
|
|
name="wikipedia_search", |
|
|
description="Search Wikipedia for encyclopedic knowledge about people, places, events, concepts, etc.", |
|
|
parameters={ |
|
|
"type": "object", |
|
|
"properties": { |
|
|
"query": { |
|
|
"type": "string", |
|
|
"description": "The Wikipedia search query" |
|
|
} |
|
|
}, |
|
|
"required": ["query"] |
|
|
} |
|
|
) |
|
|
|
|
|
def __call__(self, query: str) -> str: |
|
|
"""Search Wikipedia""" |
|
|
try: |
|
|
|
|
|
url = "https://en.wikipedia.org/w/api.php" |
|
|
params = { |
|
|
"action": "query", |
|
|
"list": "search", |
|
|
"srsearch": query, |
|
|
"format": "json", |
|
|
"utf8": 1, |
|
|
"srlimit": 1 |
|
|
} |
|
|
|
|
|
response = requests.get(url, params=params, timeout=10) |
|
|
data = response.json() |
|
|
|
|
|
if data.get("query", {}).get("search"): |
|
|
|
|
|
page_title = data["query"]["search"][0]["title"] |
|
|
|
|
|
|
|
|
extract_params = { |
|
|
"action": "query", |
|
|
"titles": page_title, |
|
|
"prop": "extracts", |
|
|
"exintro": True, |
|
|
"explaintext": True, |
|
|
"format": "json" |
|
|
} |
|
|
|
|
|
extract_response = requests.get(url, params=extract_params, timeout=10) |
|
|
extract_data = extract_response.json() |
|
|
|
|
|
pages = extract_data.get("query", {}).get("pages", {}) |
|
|
for page_id, page_data in pages.items(): |
|
|
extract = page_data.get("extract", "") |
|
|
if extract: |
|
|
|
|
|
return extract[:500] + ("..." if len(extract) > 500 else "") |
|
|
|
|
|
return f"No Wikipedia results found for: {query}" |
|
|
|
|
|
except Exception as e: |
|
|
return f"Wikipedia search error: {str(e)}" |
|
|
|
|
|
|
|
|
class CalculateTool(Tool): |
|
|
"""Calculator for mathematical operations""" |
|
|
|
|
|
def __init__(self): |
|
|
super().__init__( |
|
|
name="calculate", |
|
|
description="Perform mathematical calculations. Supports basic arithmetic, percentages, and simple expressions.", |
|
|
parameters={ |
|
|
"type": "object", |
|
|
"properties": { |
|
|
"expression": { |
|
|
"type": "string", |
|
|
"description": "The mathematical expression to evaluate (e.g., '2 + 2', '10 * 5', '100 / 4')" |
|
|
} |
|
|
}, |
|
|
"required": ["expression"] |
|
|
} |
|
|
) |
|
|
|
|
|
def __call__(self, expression: str) -> str: |
|
|
"""Safely evaluate mathematical expression""" |
|
|
try: |
|
|
|
|
|
safe_expr = re.sub(r'[^0-9+\-*/().\s]', '', expression) |
|
|
result = eval(safe_expr) |
|
|
return str(result) |
|
|
except Exception as e: |
|
|
return f"Calculation error: {str(e)}" |
|
|
|
|
|
|
|
|
def get_tools() -> List[Tool]: |
|
|
"""Return list of available tools""" |
|
|
return [ |
|
|
WebSearchTool(), |
|
|
WikipediaSearchTool(), |
|
|
CalculateTool() |
|
|
] |
|
|
|