ana-35's picture
New try
5c082e6
import ast
import operator as op
from langchain.tools import Tool
operators = {
ast.Add: op.add,
ast.Sub: op.sub,
ast.Mult: op.mul,
ast.Div: op.truediv,
ast.Pow: op.pow,
ast.Mod: op.mod,
ast.USub: op.neg,
}
def safe_eval(expr: str) -> float:
"""
Safely evaluate a mathematical expression string.
Supports +, -, *, /, **, %, and negative numbers.
"""
def eval_node(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return operators[type(node.op)](eval_node(node.left), eval_node(node.right))
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](eval_node(node.operand))
else:
raise TypeError(f"Unsupported type: {node}")
try:
node = ast.parse(expr, mode='eval').body
return eval_node(node)
except Exception as e:
return f"[Calculator error: {e}]"
def calculator(query: str) -> str:
try:
result = safe_eval(query)
return str(result)
except Exception as e:
return f"[Calculator error: {e}]"
calculator_tool = Tool.from_function(
name="calculator",
description="Performs safe mathematical calculations from a text query. Supports +, -, *, /, %, and powers.",
func=calculator
)