lellm_agent/runtime/
fallback.rs1use std::sync::Arc;
7
8use async_trait::async_trait;
9use lellm_core::{LlmError, Message};
10
11pub struct FallbackContext<'a> {
18 pub error: &'a LlmError,
20 pub attempt: usize,
22 pub iterations: usize,
24 pub conversation: Arc<[Message]>,
26}
27
28#[derive(Debug, Clone)]
32pub enum FallbackAction {
33 Retry,
35 Abort,
37 }
44
45#[async_trait]
47pub trait FallbackStrategy: Send + Sync {
48 async fn handle(&self, ctx: &FallbackContext) -> FallbackAction;
50}
51
52pub struct DefaultFallback {
54 max_retries: usize,
55}
56
57impl DefaultFallback {
58 pub fn new(max_retries: usize) -> Self {
59 Self { max_retries }
60 }
61
62 fn is_retriable(error: &LlmError) -> bool {
64 match error {
65 LlmError::Timeout { .. } | LlmError::Network { .. } => true,
66 LlmError::Provider {
67 status: Some(s), ..
68 } => *s >= 500,
69 _ => false,
70 }
71 }
72}
73
74impl Default for DefaultFallback {
75 fn default() -> Self {
76 Self::new(3)
77 }
78}
79
80#[async_trait]
81impl FallbackStrategy for DefaultFallback {
82 async fn handle(&self, ctx: &FallbackContext) -> FallbackAction {
83 if Self::is_retriable(ctx.error) && ctx.attempt < self.max_retries {
84 FallbackAction::Retry
85 } else {
86 FallbackAction::Abort
87 }
88 }
89}