Use AST-Grep Tools to search, analyze, and rewrite code using structural patterns instead of regex.
Unlike regex, AST patterns understand code structure — they won’t match patterns inside comments or strings. $VAR captures a single node, $$$ captures multiple nodes.
from praisonaiagents import Agentfrom praisonaiagents.tools import ast_grep_searchagent = Agent( name="CodeSearcher", instructions="Search code for structural patterns.", tools=[ast_grep_search],)result = agent.start("Find all function definitions in ./src")
# Find all Python function definitionsresult = ast_grep_search("def $FN($$$)", lang="python", path="./src")# Find all console.log calls in JavaScriptresult = ast_grep_search("console.log($$$)", lang="javascript")# Find all async functionsresult = ast_grep_search("async def $FN($$$)", lang="python")# Find all class definitions with inheritanceresult = ast_grep_search("class $NAME($BASE):", lang="python")
AST-grep tools are automatically included when using autonomy mode:
Copy
from praisonaiagents import Agent# Tools auto-included via get_autonomy_default_tools()agent = Agent(autonomy=True)agent.start("Refactor the codebase to use consistent naming")
In autonomy mode, ast-grep tools are available without explicit tools= — the agent can use them whenever it decides to search or rewrite code.
AST-grep tools work safely even when ast-grep is not installed:
Copy
from praisonaiagents.tools import is_ast_grep_available, ast_grep_search# Check availabilityif is_ast_grep_available(): result = ast_grep_search("def $FN($$$)", lang="python")else: print("ast-grep not installed")# Or just call it — returns helpful install instructionsresult = ast_grep_search("def $FN($$$)", lang="python")# If not installed, returns:# "ast-grep is not installed or not available in PATH.# To install: pip install ast-grep-cli"
Agents with ast-grep tools will never crash if ast-grep is missing. The tools return install instructions instead.
# All function definitions"def $FN($$$)"# All class definitions"class $NAME($$$):"# All if statements"if $COND: $$$"# All async functions"async def $FN($$$)"# All list comprehensions"[$EXPR for $VAR in $ITER]"
JavaScript / TypeScript
Copy
// All arrow functions"($$$) => $BODY"// All console.log calls"console.log($$$)"// All async functions"async function $FN($$$) { $$$ }"// All React useState hooks"const [$STATE, $SETTER] = useState($$$)"// All fetch calls"fetch($URL, $$$)"
Rust
Copy
// All function definitions"fn $FN($$$) -> $RET { $$$ }"// All impl blocks"impl $TYPE { $$$ }"// All match expressions"match $EXPR { $$$ }"// All unsafe blocks"unsafe { $$$ }"
from praisonaiagents import Agent, Task, AgentTeamfrom praisonaiagents.tools import ast_grep_search, ast_grep_scansecurity_agent = Agent( name="SecurityAuditor", instructions="""Audit code for security vulnerabilities: - Find eval() and exec() calls - Find SQL string concatenation - Find hardcoded credentials""", tools=[ast_grep_search, ast_grep_scan],)audit_task = Task( description="Audit ./src for security issues: eval/exec usage, SQL injection, hardcoded secrets.", expected_output="Security report with findings and recommendations.", agent=security_agent, name="security_audit")team = AgentTeam(agents=[security_agent], tasks=[audit_task], process="sequential")team.start()
Code Migration Agent
Copy
from praisonaiagents import Agentfrom praisonaiagents.tools import ast_grep_search, ast_grep_rewritemigrator = Agent( name="Migrator", instructions="""Migrate code patterns: - Replace deprecated APIs with new ones - Always preview first (dry_run=True) - Only apply changes after confirming the preview""", tools=[ast_grep_search, ast_grep_rewrite],)result = migrator.start( "Replace all console.log calls with logger.info in JavaScript files under ./app")
Multi-Agent Code Review
Copy
from praisonaiagents import Agent, Task, AgentTeamfrom praisonaiagents.tools import ast_grep_search, ast_grep_scan# Searcher finds patternssearcher = Agent( name="PatternFinder", instructions="Find code patterns and anti-patterns using AST search.", tools=[ast_grep_search],)# Reviewer analyzes findingsreviewer = Agent( name="CodeReviewer", instructions="Review code quality findings and provide recommendations.",)search_task = Task( description="Find all functions longer than 50 lines and deeply nested conditionals.", agent=searcher, name="pattern_search")review_task = Task( description="Review the search findings and provide refactoring recommendations.", agent=reviewer, name="code_review")team = AgentTeam( agents=[searcher, reviewer], tasks=[search_task, review_task], process="sequential")team.start()