pub enum RecoveryAction {
Retry {
delay: Duration,
},
Skip(String),
AskUser(String),
Fail(String),
}Expand description
What the framework should do after a failure.
Produced by RecoveryStrategy::decide() after the
Reflector::analyze() step. Each variant maps to a different action
in the agent loop — the strategy decides which one; the engine
executes it.
§Variants in rough order of severity
Retry is the most permissive (try again, optionally with a
correction); Skip continues past the failed step; AskUser
yields control for human input; Fail terminates the operation and
propagates the error. A typical strategy progresses through these as
the attempt budget drains: early attempts → Retry, late attempts →
Fail or AskUser.
§Equality and ordering
Derives Eq so two actions compare equal when their payloads
match (same delay, same string). Useful in tests that assert a
strategy picked a specific action; not meaningful for runtime
prioritization — there is no Ord impl, by design.
§Example
use loopctl::reflection::RecoveryAction;
use std::time::Duration;
let action = RecoveryAction::Retry {
delay: Duration::from_millis(500),
};
assert!(action.is_retry());
assert_eq!(action.delay(), Some(Duration::from_millis(500)));
let fail = RecoveryAction::Fail("unrecoverable".to_string());
assert!(fail.is_fail());Variants§
Retry
Retry the failed operation.
Wait for delay before retrying. If the
FailureAnalysis::correction that produced this action was
Some, the engine applies it (substituting
Correction::modified_input or swapping to
Correction::alternative_tool) before re-dispatching the tool
call. The strategy is responsible for choosing a sensible delay
— typically backoff that grows with the attempt number.
Fields
Skip(String)
Skip the failed operation and continue with the rest of the turn.
The framework logs the reason and moves on rather than retrying. Use when the step is optional or the failure is non-fatal — e.g., a metric-emitting tool that the agent can safely proceed without. The carried string is the human-readable reason to log.
AskUser(String)
Ask the user for input before continuing.
Yields control to the caller with a prompt string. The framework
surfaces this in whatever interaction model it runs under
(headless: prints the prompt and waits on stdin; TUI: renders a
prompt and waits for input). Use when the strategy cannot decide
autonomously — e.g., a permission-style failure that a human
should adjudicate, or a ToolChange correction that requires a
choice between plausible alternatives.
Fail(String)
Fail the operation and propagate the error.
No further retries — the framework should report this failure and
stop the recovery loop. The carried string is the error message
to surface. Use when the failure is unrecoverable, when the
attempt budget is exhausted, or when a Reflector returned
ReflectionError::Internal (the engine conservatively maps
reflector failure to Fail).
Implementations§
Source§impl RecoveryAction
impl RecoveryAction
Sourcepub fn delay(&self) -> Option<Duration>
pub fn delay(&self) -> Option<Duration>
Returns the retry delay, if this is a Retry action.
Lets callers branch on the wait without a full match. Returns
None for the other three variants, so a strategy can write
action.delay().unwrap_or(Duration::ZERO) to default a non-retry
action to immediate handling.
Sourcepub fn is_retry(&self) -> bool
pub fn is_retry(&self) -> bool
Returns true if this is a Retry action.
Convenience predicate; equivalent to
matches!(action, RecoveryAction::Retry { .. }). Useful in
engine code that gates on retry vs. non-retry without caring
about the delay.
Sourcepub fn is_fail(&self) -> bool
pub fn is_fail(&self) -> bool
Returns true if this is a Fail action.
Convenience predicate. Engine code commonly checks this to decide whether to terminate the recovery loop and propagate the error.
Sourcepub fn is_skip(&self) -> bool
pub fn is_skip(&self) -> bool
Returns true if this is a Skip action.
Convenience predicate. Use to distinguish “move on silently” from the harder-failure variants when logging.
Sourcepub fn is_ask_user(&self) -> bool
pub fn is_ask_user(&self) -> bool
Returns true if this is an AskUser action.
Convenience predicate. Engine code checks this to know it must yield control to the caller (headless: stdin; TUI: prompt) rather than continue autonomously.
Trait Implementations§
Source§impl Clone for RecoveryAction
impl Clone for RecoveryAction
Source§fn clone(&self) -> RecoveryAction
fn clone(&self) -> RecoveryAction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RecoveryAction
impl Debug for RecoveryAction
Source§impl Display for RecoveryAction
impl Display for RecoveryAction
impl Eq for RecoveryAction
Source§impl PartialEq for RecoveryAction
impl PartialEq for RecoveryAction
impl StructuralPartialEq for RecoveryAction
Auto Trait Implementations§
impl Freeze for RecoveryAction
impl RefUnwindSafe for RecoveryAction
impl Send for RecoveryAction
impl Sync for RecoveryAction
impl Unpin for RecoveryAction
impl UnsafeUnpin for RecoveryAction
impl UnwindSafe for RecoveryAction
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.