Skip to main content

LoopGuard

Struct LoopGuard 

Source
pub struct LoopGuard { /* private fields */ }
Expand description

Sliding-window detector for repeated tool calls.

The guard keeps the last window (tool_name, args) records in a FIFO ring. On every LoopGuard::record, if the new key already appears threshold times (including the call being recorded) in the buffer, LoopDetectedError is returned. The new call is still recorded so repeated calls to record after a detection stay deterministic.

Use LoopGuard::would_raise to peek at the next decision without mutating the buffer.

Implementations§

Source§

impl LoopGuard

Source

pub fn with_capacity(window: usize, threshold: usize) -> Self

Construct a guard.

§Panics

Panics on invalid construction (matches the spirit of Python’s ValueError, but in Rust idiom we treat invalid construction as a programming bug rather than a recoverable error):

  • window < 2
  • threshold < 2
  • threshold > window

If you want a non-panicking constructor, see LoopGuard::try_new.

Source

pub fn try_new(window: usize, threshold: usize) -> Result<Self, ConfigError>

Fallible constructor. Returns Err(ConfigError) instead of panicking.

Source

pub fn with_key_fn<F>(window: usize, threshold: usize, key_fn: F) -> Self
where F: Fn(&str, &Value) -> Key + Send + Sync + 'static,

Construct a guard with a custom key function.

The key function decides which calls should be considered “the same”. Two calls that produce equal Keys count toward the threshold. Use this to ignore noisy fields like request_id or timestamp that change every call but don’t represent real intent.

Source

pub fn window(&self) -> usize

Configured window size.

Source

pub fn threshold(&self) -> usize

Configured threshold.

Source

pub fn len(&self) -> usize

Number of calls currently in the buffer.

Source

pub fn is_empty(&self) -> bool

True if no calls have been recorded since construction or last reset.

Source

pub fn recent_keys(&self) -> Vec<&Key>

Recent keys, oldest first.

Returned as borrowed references so callers do not pay an allocation cost just to inspect the ring. Clone individual entries with key.clone() if you need to keep them past the next record call.

Source

pub fn record( &mut self, tool_name: &str, args: &Value, ) -> Result<(), LoopDetectedError>

Record a call. Returns Err(LoopDetectedError) if the threshold is met.

The call is recorded into the ring before the count is checked, so subsequent calls observe the same offending entry until evicted.

Source

pub fn would_raise(&self, tool_name: &str, args: &Value) -> bool

Return true if the next record for this key would raise.

Lets callers preview the outcome without mutating the buffer. The simulation accounts for buffer eviction: if the buffer is already full and the oldest entry has the same key, the projected count loses one before gaining one.

Source

pub fn reset(&mut self)

Forget all recorded calls.

Trait Implementations§

Source§

impl Debug for LoopGuard

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.