Spaces:
Sleeping
Sleeping
| 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 | |
| ) |