Spaces:
Sleeping
Sleeping
| import json | |
| import re | |
| from datetime import datetime | |
| from typing import Any | |
| try: | |
| import numexpr as _numexpr | |
| _HAS_NUMEXPR = True | |
| except ImportError: | |
| _numexpr = None # type: ignore[assignment] | |
| _HAS_NUMEXPR = False | |
| try: | |
| from duckduckgo_search import DDGS as _DDGS | |
| _HAS_DDGS = True | |
| except ImportError: | |
| _DDGS = None # type: ignore[assignment,misc] | |
| _HAS_DDGS = False | |
| # Tool definitions in OpenAI function-calling format | |
| TOOL_DEFINITIONS = [ | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "calculate", | |
| "description": "Evaluate a mathematical expression and return the result.", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "expression": { | |
| "type": "string", | |
| "description": "A safe math expression, e.g. '2 ** 10 + sqrt(144)'", | |
| } | |
| }, | |
| "required": ["expression"], | |
| }, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_datetime", | |
| "description": "Return the current date and time.", | |
| "parameters": {"type": "object", "properties": {}, "required": []}, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "web_search", | |
| "description": "Search the web using DuckDuckGo and return top results.", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "query": {"type": "string", "description": "Search query"}, | |
| "max_results": { | |
| "type": "integer", | |
| "description": "Number of results (1-5)", | |
| "default": 3, | |
| }, | |
| }, | |
| "required": ["query"], | |
| }, | |
| }, | |
| }, | |
| ] | |
| def calculate(expression: str) -> str: | |
| if not _HAS_NUMEXPR: | |
| # Fallback: restrict to safe subset via regex then eval | |
| if re.search(r"[^0-9\s\+\-\*\/\(\)\.\%\^]", expression): | |
| return "Error: unsafe expression" | |
| try: | |
| return str(eval(expression, {"__builtins__": {}}, {})) # noqa: S307 | |
| except Exception as e: | |
| return f"Error: {e}" | |
| try: | |
| result = _numexpr.evaluate(expression) # type: ignore[union-attr] | |
| return str(float(result)) | |
| except Exception as e: | |
| return f"Error: {e}" | |
| def get_datetime() -> str: | |
| return datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| def web_search(query: str, max_results: int = 3) -> str: | |
| if not _HAS_DDGS: | |
| return "Web search unavailable (duckduckgo_search not installed)." | |
| try: | |
| results = [] | |
| with _DDGS() as ddgs: # type: ignore[operator] | |
| for r in ddgs.text(query, max_results=max_results): | |
| results.append(f"**{r['title']}**\n{r['body']}\n{r['href']}") | |
| return "\n\n".join(results) if results else "No results found." | |
| except Exception as e: | |
| return f"Search error: {e}" | |
| def dispatch_tool(name: str, arguments: Any) -> str: | |
| if isinstance(arguments, str): | |
| try: | |
| arguments = json.loads(arguments) | |
| except json.JSONDecodeError: | |
| arguments = {} | |
| if name == "calculate": | |
| return calculate(arguments.get("expression", "")) | |
| if name == "get_datetime": | |
| return get_datetime() | |
| if name == "web_search": | |
| return web_search(arguments.get("query", ""), arguments.get("max_results", 3)) | |
| return f"Unknown tool: {name}" | |