|
import re |
|
from duckduckgo_search import DDGS |
|
from typing import List, Dict, Any |
|
|
|
class BaseTool: |
|
def __init__(self, name: str, description: str): |
|
self.name = name |
|
self.description = description |
|
|
|
def run(self, *args, **kwargs) -> str: |
|
raise NotImplementedError |
|
|
|
class Calculator(BaseTool): |
|
def __init__(self): |
|
super().__init__( |
|
name="Calculator", |
|
description="Performs basic arithmetic. Input: math expression as string" |
|
) |
|
|
|
def run(self, expression: str) -> str: |
|
try: |
|
expression = expression.replace(' ', '') |
|
if not re.match(r'^[\d+\-*/.()]+$', expression): |
|
return "Error: Invalid characters in expression" |
|
result = eval(expression) |
|
return str(result) |
|
except Exception as e: |
|
return f"Calculation error: {str(e)}" |
|
|
|
class DocRetriever(BaseTool): |
|
def __init__(self): |
|
super().__init__( |
|
name="DocRetriever", |
|
description="Searches provided text. Input: 'query: <search_term>'" |
|
) |
|
self.document = "" |
|
|
|
def load_document(self, text: str): |
|
self.document = text |
|
|
|
def run(self, query: str) -> str: |
|
if not self.document: |
|
return "No document loaded" |
|
|
|
sentences = [s.strip() for s in self.document.split('.') if s] |
|
results = [s for s in sentences if query.lower() in s.lower()] |
|
return '. '.join(results[:3]) + '...' if results else "No matches found" |
|
|
|
class WebSearcher(BaseTool): |
|
def __init__(self): |
|
super().__init__( |
|
name="WebSearcher", |
|
description="Searches the web. Input: search query" |
|
) |
|
|
|
def run(self, query: str) -> str: |
|
try: |
|
with DDGS() as ddgs: |
|
results = [r for r in ddgs.text(query, max_results=3)] |
|
return '\n'.join([f"[{r['title']}]({r['href']}): {r['body']}" for r in results]) |
|
except Exception as e: |
|
return f"Search error: {str(e)}" |