Documentation Index Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
Use this file to discover all available pages before exploring further.
Use an AST allow-list instead of eval() when a custom tool evaluates user-supplied math.
Quick Start
Unsafe (don't do this)
This pattern is dangerous and vulnerable to remote code execution attacks: # DON'T USE - Unsafe pattern
def unsafe_calculator ( expr ):
try :
result = eval ( expr , { " __builtins__ " : {}})
return str ( result )
except Exception :
return " error "
Safe pattern
Use the AST-based allow-list for secure math evaluation: import ast
from praisonaiagents import Agent
def _safe_calc ( expr : str ) -> str :
""" Safely evaluate basic arithmetic expressions using AST. """
try :
# Parse the expression into an AST
tree = ast . parse ( expr , mode = ' eval ' )
# Check if all nodes are safe
for node in ast . walk ( tree ):
if not isinstance ( node , (
ast . Expression , ast . BinOp , ast . UnaryOp ,
ast . Constant , ast . Num , # ast.Num for older Python versions
ast . Add , ast . Sub , ast . Mult , ast . Div ,
ast . USub , ast . UAdd
)):
return " error " # Reject unsafe operations
# Compile and evaluate the safe expression
code = compile ( tree , ' <string> ' , ' eval ' )
result = eval ( code )
return str ( result )
except Exception :
return " error "
# Create agent with safe calculator tool
agent = Agent (
name = " MathAgent " ,
instructions = " You are a helpful math assistant. Use the calculator for arithmetic. " ,
tools =[
{
" type " : " function " ,
" function " : {
" name " : " calculator " ,
" description " : " Safely evaluate basic arithmetic expressions " ,
" parameters " : {
" type " : " object " ,
" properties " : {
" expression " : {
" type " : " string " ,
" description " : " Math expression like '2 + 3 * 4' "
}
},
" required " : [ " expression " ]
}
}
}
]
)
@ agent . tool
def calculator ( expression : str ) -> str :
""" Safely calculate arithmetic expressions. """
return _safe_calc ( expression )
# Test the safe calculator
result = agent . start ( " Calculate 15 + 27 * 3 " )
How It Works
Allow-list Reference
The AST allow-list permits only these node types for safe arithmetic evaluation:
Node Type Purpose Example ast.ExpressionRoot expression node Required wrapper ast.BinOpBinary operations 2 + 3, 4 * 5ast.UnaryOpUnary operations -5, +3ast.ConstantLiteral values 42, 3.14ast.AddAddition operator +ast.SubSubtraction operator -ast.MultMultiplication operator *ast.DivDivision operator /ast.USubUnary minus -xast.UAddUnary plus +x
Explicitly rejected constructs:
Function calls (pow(), exec(), __import__())
Attribute access (.attr, obj.method)
Names/variables (x, globals)
List/dict comprehensions
Power operator (**)
Modulo operator (%)
Common Patterns
Integrate with MCP server
from praisonaiagents . mcp import MCP
import ast
def _safe_calc ( expr : str ) -> str :
""" Safe math evaluation for MCP tools. """
try :
tree = ast . parse ( expr , mode = ' eval ' )
for node in ast . walk ( tree ):
if not isinstance ( node , (
ast . Expression , ast . BinOp , ast . UnaryOp ,
ast . Constant , ast . Num ,
ast . Add , ast . Sub , ast . Mult , ast . Div ,
ast . USub , ast . UAdd
)):
return " error "
code = compile ( tree , ' <string> ' , ' eval ' )
return str ( eval ( code ))
except Exception :
return " error "
# Use in MCP server context
mcp_server = MCP (
name = " safe-calculator " ,
tools =[{
" name " : " calculate " ,
" description " : " Safely evaluate arithmetic expressions " ,
" handler " : lambda expr : _safe_calc ( expr [ " expression " ])
}]
)
from praisonai import Agent , ManagedAgent , LocalManagedConfig
def _safe_calc ( expr : str ) -> str :
""" AST-based safe calculator. """
try :
tree = ast . parse ( expr , mode = ' eval ' )
for node in ast . walk ( tree ):
if not isinstance ( node , (
ast . Expression , ast . BinOp , ast . UnaryOp ,
ast . Constant , ast . Num ,
ast . Add , ast . Sub , ast . Mult , ast . Div ,
ast . USub , ast . UAdd
)):
return " error "
code = compile ( tree , ' <string> ' , ' eval ' )
return str ( eval ( code ))
except Exception :
return " error "
def handle_calculator ( tool_name , tool_input ):
""" Safe calculator handler for managed agents. """
expr = tool_input . get ( " expression " , " 0 " )
result = _safe_calc ( expr )
print ( f " [Calculator: { expr } = { result } ]" )
return result
# Configure managed agent with safe calculator
managed = ManagedAgent (
provider = " local " ,
config = LocalManagedConfig (
model = " gpt-4o-mini " ,
system = " You are an assistant with a calculator tool. Use it for math. " ,
name = " SafeCalcAgent " ,
tools =[{
" type " : " custom " ,
" name " : " calculator " ,
" description " : " Evaluate a math expression safely " ,
" input_schema " : {
" type " : " object " ,
" properties " : {
" expression " : { " type " : " string " , " description " : " Math expression " },
},
" required " : [ " expression " ],
},
}],
),
on_custom_tool = handle_calculator ,
)
agent = Agent ( name = " calc " , backend = managed )
result = agent . start ( " Use the calculator to compute 99 * 77 " )
Best Practices
Never call eval() on user input
Always parse user expressions through AST validation before evaluation. The eval() function can execute arbitrary Python code and should never receive untrusted input, even with restricted __builtins__.
Reject before parsing using a character allow-list
Add an initial character filter to catch obviously malicious input: def _safe_calc ( expr : str ) -> str :
# Pre-filter: only allow safe characters
allowed_chars = set ( " 0123456789+-*/(). " )
if not all ( c in allowed_chars for c in expr ):
return " error "
# Continue with AST parsing...
try :
tree = ast . parse ( expr , mode = ' eval ' )
# ... rest of validation
except Exception :
return " error "
Return a sentinel string rather than raising
Return "error" instead of raising exceptions to provide graceful degradation in agent workflows. This prevents the entire agent conversation from failing due to a malformed math expression.
Prevent resource exhaustion by limiting expression length: def _safe_calc ( expr : str ) -> str :
if len ( expr ) > 100 : # Reasonable limit
return " error "
# Continue with validation...
Security Guide Complete security practices and hardening measures
Custom Tools Build custom tools for agents with proper patterns