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 fresh() -> LoopState

Create a fresh guardrail state.

pub fn halt(state: LoopState) -> LoopState

Halt the loop entirely.

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.

pub fn record_success(
  state: LoopState,
  tool_name: String,
  args: String,
  result: String,
) -> LoopState

Record a successful tool execution. Resets all failure counters. Tracks results for idempotent tools to detect no-progress loops.

Search Document