pub struct LoopDetector { /* private fields */ }Expand description
Detects repeated action patterns in agent loops.
Three independent signals, each tracking consecutive repetitions:
| Signal | Tracks | Catches |
|---|---|---|
| Exact | Identical signatures | Trivial loops (same tool, same args) |
| Category | Normalized signatures | Semantic loops (same intent, diff syntax) |
| Output | Identical tool output (by hash) | Stagnation (different tools, same result) |
Usage:
let mut detector = LoopDetector::new(6);
// Per step: check action signatures
let sig = "bash:rg -n 'TODO' src/";
let cat = normalize_signature(sig);
match detector.check_with_category(sig, &cat) {
LoopStatus::Abort(n) => { /* stop */ }
LoopStatus::Warning(n) => { /* inject system message */ }
LoopStatus::Ok => { /* proceed */ }
}
// Per action execution: check tool output
match detector.record_output("No matches found") {
LoopStatus::Warning(n) => { /* nudge model */ }
_ => {}
}Implementations§
Source§impl LoopDetector
impl LoopDetector
Sourcepub fn new(abort_threshold: usize) -> Self
pub fn new(abort_threshold: usize) -> Self
Create detector. Warns at ⌈abort_threshold/2⌉, aborts at abort_threshold.
Sourcepub fn with_thresholds(warn_threshold: usize, abort_threshold: usize) -> Self
pub fn with_thresholds(warn_threshold: usize, abort_threshold: usize) -> Self
Create detector with explicit warn threshold.
Sourcepub fn check(&mut self, signature: &str) -> LoopStatus
pub fn check(&mut self, signature: &str) -> LoopStatus
Check action signature only (backward-compatible).
Uses signature as both exact match and category.
For semantic loop detection, use [check_with_category] instead.
Sourcepub fn check_with_category(
&mut self,
signature: &str,
category: &str,
) -> LoopStatus
pub fn check_with_category( &mut self, signature: &str, category: &str, ) -> LoopStatus
Check action with separate exact signature and normalized category.
Returns the worst status across exact and category signals.
Sourcepub fn record_output(&mut self, output: &str) -> LoopStatus
pub fn record_output(&mut self, output: &str) -> LoopStatus
Record a tool output and check for output stagnation.
Call after each action execution. Returns LoopStatus::Warning or
LoopStatus::Abort if the same output has been seen too many
consecutive times — the model is retrying a command that keeps
giving the same result.
Sourcepub fn repeat_count(&self) -> usize
pub fn repeat_count(&self) -> usize
Current repeat count (max across all signals).
Sourcepub fn exact_count(&self) -> usize
pub fn exact_count(&self) -> usize
Exact signature repeat count.
Sourcepub fn category_count(&self) -> usize
pub fn category_count(&self) -> usize
Normalized category repeat count.
Sourcepub fn output_count(&self) -> usize
pub fn output_count(&self) -> usize
Output stagnation repeat count.