sodigital's picture
Create tools.py
29a4c69 verified
import os
import sys
import re
import json
import logging
import ast
import operator as op
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
from smolagents import CodeAgent, DuckDuckGoSearchTool, InferenceClientModel, tool
@tool
def get_current_time() -> str:
"""Get the current date and time in a readable format."""
now = datetime.now()
return now.strftime("%Y-%m-%d %H:%M:%S")
@tool
def calculate_basic_math(expression: str) -> str:
"""
Safely evaluate basic mathematical expressions using AST.
Args:
expression: A string containing a mathematical expression like "2+2" or "10*5"
Returns:
The result of the calculation as a string
"""
# Safe operations mapping
SAFE_OPS = {
ast.Add: op.add,
ast.Sub: op.sub,
ast.Mult: op.mul,
ast.Div: op.truediv,
ast.Pow: op.pow,
ast.USub: op.neg
}
def _safe_eval(node):
"""Recursively evaluate AST nodes safely."""
if isinstance(node, ast.Num): # Numbers
return node.n
elif isinstance(node, ast.Constant): # Python 3.8+ constant nodes
return node.value
elif isinstance(node, ast.BinOp): # Binary operations
return SAFE_OPS[type(node.op)](_safe_eval(node.left), _safe_eval(node.right))
elif isinstance(node, ast.UnaryOp): # Unary operations
return SAFE_OPS[type(node.op)](_safe_eval(node.operand))
else:
raise ValueError(f"Unsupported operation: {type(node)}")
try:
# Parse expression into AST and evaluate safely
node = ast.parse(expression, mode='eval')
result = _safe_eval(node.body)
return f"Result: {result}"
except Exception as e:
return f"Error calculating '{expression}': {str(e)}"
@tool
def save_note(content: str, filename: Optional[str] = None) -> str:
"""
Save a note to a text file.
Args:
content: The content to save in the note
filename: Optional filename. If not provided, uses timestamp
Returns:
Success message with filename
"""
try:
if filename is None:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"note_{timestamp}.txt"
# Try to create notes directory, fall back to /tmp if permission denied
try:
os.makedirs("notes", exist_ok=True)
notes_dir = "notes"
except PermissionError:
notes_dir = "/tmp/notes"
os.makedirs(notes_dir, exist_ok=True)
filepath = os.path.join(notes_dir, filename)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
return f"βœ… Note saved successfully to: {filepath}"
except Exception as e:
return f"❌ Error saving note: {str(e)}"
@tool
def list_saved_notes() -> str:
"""List all saved notes in the notes directory."""
try:
# Check both possible notes directories
all_files = []
for notes_dir in ["notes", "/tmp/notes"]:
if os.path.exists(notes_dir):
files = os.listdir(notes_dir)
txt_files = [f for f in files if f.endswith('.txt')]
all_files.extend([(f, notes_dir) for f in txt_files])
if not all_files:
return "πŸ“‚ No notes found. Save a note first!"
file_list = "\n".join([f"- {file} ({location})" for file, location in sorted(all_files)])
return f"πŸ“‚ Saved notes:\n{file_list}"
except Exception as e:
return f"❌ Error listing notes: {str(e)}"