Retry and Fallback

Synwire provides built-in retry and fallback mechanisms for handling transient errors.

Retry configuration

Wrap any RunnableCore with retry logic:

use synwire_core::runnables::{RunnableRetry, RetryConfig};
use synwire_core::error::SynwireErrorKind;

let config = RetryConfig::new()
    .max_retries(3)
    .retry_on(vec![SynwireErrorKind::Model]);  // Only retry model errors

let retryable = RunnableRetry::new(my_runnable, config);

Fallbacks

Chain multiple runnables as fallbacks. If the primary fails, the next is tried:

use synwire_core::runnables::with_fallbacks;
use synwire_core::language_models::{FakeChatModel, BaseChatModel};

let primary = FakeChatModel::new(vec!["Primary response".into()]);
let fallback = FakeChatModel::new(vec!["Fallback response".into()]);

// with_fallbacks tries each in order
let resilient = with_fallbacks(vec![
    Box::new(primary),
    Box::new(fallback),
]);

Error kinds for matching

SynwireErrorKind categorises errors for retry/fallback decisions:

KindWhen to retry
ModelRate limits, timeouts, transient failures
ToolTool invocation failures
ParseOutput parsing failures (consider with caution)
EmbeddingEmbedding API failures
CredentialTypically not retryable
SerializationNot retryable

Combining retry and fallback

use synwire_core::runnables::{RunnableRetry, RetryConfig, with_fallbacks};
use synwire_core::error::SynwireErrorKind;

// Primary with retry
let primary_with_retry = RunnableRetry::new(
    primary_model,
    RetryConfig::new()
        .max_retries(2)
        .retry_on(vec![SynwireErrorKind::Model]),
);

// Fallback without retry
let resilient = with_fallbacks(vec![
    Box::new(primary_with_retry),
    Box::new(fallback_model),
]);

Callback on retry

Monitor retries via the CallbackHandler:

impl CallbackHandler for MyCallback {
    fn on_retry<'a>(
        &'a self,
        attempt: u32,
        error: &'a str,
    ) -> BoxFuture<'a, ()> {
        Box::pin(async move {
            eprintln!("Retry attempt {attempt}: {error}");
        })
    }
}