pub struct FallbackModel { /* private fields */ }Expand description
Tries each model in order. Moves on when a request fails with a retryable error or when the answer is unusable:
- cut off by the token limit (unless
accept_truncated), - empty — no text and no tool calls (unless
accept_empty), - a final answer that is not JSON with the required fields
(
require_json_fields), - rejected by a custom check (
require).
Rejected answers are recorded in ModelResponse::rejected and their
cost still counts toward budgets. With usability checks enabled,
streaming is buffered per attempt so a rejected answer never reaches
the caller.
Implementations§
Source§impl FallbackModel
impl FallbackModel
pub fn new(models: Vec<Arc<dyn Model>>) -> Self
Sourcepub fn keep_last_answer(self) -> Self
pub fn keep_last_answer(self) -> Self
When every model’s answer is unusable, return the last one anyway instead of failing the call.
For agents with a finish_schema:
a final answer that is not quite valid JSON then reaches the agent’s
corrective retry, which usually fixes it on the same cheap model,
rather than ending the run. Transport and API errors still fail.
Sourcepub fn accept_truncated(self) -> Self
pub fn accept_truncated(self) -> Self
Keep answers that hit the token limit.
Sourcepub fn accept_empty(self) -> Self
pub fn accept_empty(self) -> Self
Keep answers with no text and no tool calls.
Sourcepub fn require_json_fields(self, fields: &[&str]) -> Self
pub fn require_json_fields(self, fields: &[&str]) -> Self
Final answers (no tool calls) must contain a JSON object with these
top-level fields, e.g. ["summary", "work", "risks", "confidence"].
Trait Implementations§
Source§impl Model for FallbackModel
impl Model for FallbackModel
Source§fn stream<'life0, 'life1, 'async_trait>(
&'life0 self,
request: &'life1 ModelRequest,
) -> Pin<Box<dyn Future<Output = Result<ModelStream, ModelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn stream<'life0, 'life1, 'async_trait>(
&'life0 self,
request: &'life1 ModelRequest,
) -> Pin<Box<dyn Future<Output = Result<ModelStream, ModelError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fails over only while opening the stream; once tokens flow, errors are surfaced to the caller.
Source§fn pricing(&self) -> Option<Pricing>
fn pricing(&self) -> Option<Pricing>
Conservative (field-wise maximum) pricing across all models, or
None if any model is unpriced.
Source§fn cost_usd(&self, response: &ModelResponse) -> Option<f64>
fn cost_usd(&self, response: &ModelResponse) -> Option<f64>
Prices the response with the model that actually served it; falls back to the conservative maximum rather than ever under-counting. Cost of the answer (priced on the model that served it, else the conservative maximum) plus every rejected attempt.
Source§fn max_call_cost(&self, input_tokens: u64, output_tokens: u64) -> Option<f64>
fn max_call_cost(&self, input_tokens: u64, output_tokens: u64) -> Option<f64>
Every model may be tried (and paid for) in one call.