feat(agent): add pre-execution step_callback for loop detection#4422
Conversation
Fire step_callback BEFORE tool execution with an AgentAction where result=None, enabling external listeners to detect infinite retry loops by inspecting tool name and arguments before the tool runs. Covers all three execution paths: ReAct sync, ReAct async, and native function calling. Zero breaking changes to existing callbacks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| print("\n" + "=" * 60) | ||
| print("SUCCESS: Pre-execution hook fires with tool name + args") | ||
| print(" before the tool is actually executed.") | ||
| print("=" * 60) |
There was a problem hiding this comment.
Development reproduction script committed to repository root
Low Severity
reproduce_hook.py is a development/debugging reproduction script placed at the repository root. It's not a proper test (not in the test directory, not referenced by any test runner), and its name and docstring ("Reproduction script demonstrating…") indicate it was used during development to verify the feature and was unintentionally included in the commit.


Fire step_callback BEFORE tool execution with an AgentAction where result=None, enabling external listeners to detect infinite retry loops by inspecting tool name and arguments before the tool runs.
Covers all three execution paths: ReAct sync, ReAct async, and native function calling. Zero breaking changes to existing callbacks.
Note
Medium Risk
Touches the core agent execution loop and changes callback timing/volume, which may affect downstream observers that assume callbacks only occur after tool execution.
Overview
step_callbackis expanded to fire before tool execution across all execution paths (ReAct sync/async and native function-calling), emitting a pre-executionAgentActionwithresult=Nonethat includes the tool name and serialized arguments.Adds a dedicated
_invoke_pre_tool_step_callback()helper to construct this pre-step event, updatesAgent.step_callbackdocs to reflect the new semantics, and includes a smallreproduce_hook.pyscript demonstrating the new pre/post callback behavior.Written by Cursor Bugbot for commit 9f452ba. This will update automatically on new commits. Configure here.