plugins/hooks/tool_guardrails/tool_guardrails
Tool loop guardrails — circuit breaker for stuck tool loops. Detects repeated same-tool failures, identical-argument retries, no-progress idempotent loops, and total failure counts. Escalates: warn → block tool → halt loop.
Types
pub type Escalation {
None
Warn(reason: String)
BlockTool(name: String, reason: String)
HaltLoop(reason: String)
}
Constructors
-
None -
Warn(reason: String) -
BlockTool(name: String, reason: String) -
HaltLoop(reason: String)
pub type LoopState {
LoopState(
same_tool_failures: Int,
same_args_streak: Int,
total_failures: Int,
last_tool_name: String,
last_tool_args: String,
blocked_tools: List(String),
halted: Bool,
recent_results: List(#(String, String, String)),
)
}
Constructors
-
LoopState( same_tool_failures: Int, same_args_streak: Int, total_failures: Int, last_tool_name: String, last_tool_args: String, blocked_tools: List(String), halted: Bool, recent_results: List(#(String, String, String)), )
Values
pub fn block_tool(
state: LoopState,
tool_name: String,
) -> LoopState
Block a tool for the remainder of this turn.
pub fn escalation(
state: LoopState,
same_tool_warn: Int,
same_tool_block: Int,
same_args_block: Int,
total_halt: Int,
no_progress_warn: Int,
no_progress_block: Int,
) -> Escalation
Determine what escalation action to take based on current state.
pub fn is_blocked(state: LoopState, tool_name: String) -> Bool
Check if a tool is currently blocked.
pub fn no_progress_count(state: LoopState) -> Int
Count consecutive occurrences of the same (tool, args, result) tuple at the end of the recent results ring buffer.
pub fn record_failure(
state: LoopState,
tool_name: String,
args: String,
) -> LoopState
Record a tool failure. Increments counters for escalation detection.