pub struct RouterModelProvider { /* private fields */ }Expand description
Multi-model router — routes requests to different model_provider+model combos based on a task hint encoded in the model parameter.
The model parameter can be:
- A regular model name (e.g. “anthropic/claude-sonnet-4”) → uses default model_provider
- A hint-prefixed string (e.g. “hint:reasoning”) → resolves via route table
This wraps multiple pre-created model_providers and selects the right one per request.
Implementations§
Source§impl RouterModelProvider
impl RouterModelProvider
Sourcepub fn new(
alias: &str,
model_providers: Vec<(String, Box<dyn ModelProvider>)>,
routes: Vec<(String, Route)>,
default_model: String,
) -> Self
pub fn new( alias: &str, model_providers: Vec<(String, Box<dyn ModelProvider>)>, routes: Vec<(String, Route)>, default_model: String, ) -> Self
Create a new router with a default model_provider and optional routes.
model_providers is a list of (name, model_provider) pairs. The first one is the default.
routes maps hint names to Route structs containing provider_name and model.
Sourcepub fn resolve_cost_optimized(
&self,
model: &str,
model_provider_pricing: &HashMap<String, HashMap<String, f64>>,
required_vision: bool,
required_tools: bool,
) -> (usize, String)
pub fn resolve_cost_optimized( &self, model: &str, model_provider_pricing: &HashMap<String, HashMap<String, f64>>, required_vision: bool, required_tools: bool, ) -> (usize, String)
Resolve a model parameter to the cheapest qualifying route based on pricing.
If the model starts with "hint:cost-optimized" or "hint:cheapest", this
method scores each route by input_price + output_price (a simple proxy for
total cost), optionally filtering by capability requirements, and returns the
cheapest qualifying route.
Falls back to the default route when no pricing data matches.
Trait Implementations§
Source§impl Attributable for RouterModelProvider
impl Attributable for RouterModelProvider
Source§impl ModelProvider for RouterModelProvider
impl ModelProvider for RouterModelProvider
Source§fn chat_with_system<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
system_prompt: Option<&'life1 str>,
message: &'life2 str,
model: &'life3 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn chat_with_system<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
system_prompt: Option<&'life1 str>,
message: &'life2 str,
model: &'life3 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
simple_chat for
the temperature contract.Source§fn chat_with_history<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
messages: &'life1 [ChatMessage],
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn chat_with_history<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
messages: &'life1 [ChatMessage],
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
simple_chat for the temperature
contract.Source§fn chat<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
request: ChatRequest<'life1>,
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<ChatResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn chat<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
request: ChatRequest<'life1>,
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<ChatResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
simple_chat for
the temperature contract.Source§fn chat_with_tools<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
messages: &'life1 [ChatMessage],
tools: &'life2 [Value],
model: &'life3 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<ChatResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn chat_with_tools<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
messages: &'life1 [ChatMessage],
tools: &'life2 [Value],
model: &'life3 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<ChatResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
simple_chat for the temperature contract.Source§fn supports_native_tools(&self) -> bool
fn supports_native_tools(&self) -> bool
Source§fn supports_streaming(&self) -> bool
fn supports_streaming(&self) -> bool
Source§fn supports_streaming_tool_events(&self) -> bool
fn supports_streaming_tool_events(&self) -> bool
Source§fn stream_chat_with_system(
&self,
system_prompt: Option<&str>,
message: &str,
model: &str,
temperature: Option<f64>,
options: StreamOptions,
) -> BoxStream<'static, StreamResult<StreamChunk>>
fn stream_chat_with_system( &self, system_prompt: Option<&str>, message: &str, model: &str, temperature: Option<f64>, options: StreamOptions, ) -> BoxStream<'static, StreamResult<StreamChunk>>
simple_chat for
the temperature contract.Source§fn stream_chat_with_history(
&self,
messages: &[ChatMessage],
model: &str,
temperature: Option<f64>,
options: StreamOptions,
) -> BoxStream<'static, StreamResult<StreamChunk>>
fn stream_chat_with_history( &self, messages: &[ChatMessage], model: &str, temperature: Option<f64>, options: StreamOptions, ) -> BoxStream<'static, StreamResult<StreamChunk>>
simple_chat for the temperature
contract.Source§fn stream_chat(
&self,
request: ChatRequest<'_>,
model: &str,
temperature: Option<f64>,
options: StreamOptions,
) -> BoxStream<'static, StreamResult<StreamEvent>>
fn stream_chat( &self, request: ChatRequest<'_>, model: &str, temperature: Option<f64>, options: StreamOptions, ) -> BoxStream<'static, StreamResult<StreamEvent>>
simple_chat for the
temperature contract.Source§fn supports_vision(&self) -> bool
fn supports_vision(&self) -> bool
Source§fn warmup<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn warmup<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn capabilities(&self) -> ProviderCapabilities
fn capabilities(&self) -> ProviderCapabilities
Source§fn default_temperature(&self) -> f64
fn default_temperature(&self) -> f64
None. Override per family.Source§fn default_max_tokens(&self) -> u32
fn default_max_tokens(&self) -> u32
Source§fn default_timeout_secs(&self) -> u64
fn default_timeout_secs(&self) -> u64
Source§fn default_base_url(&self) -> Option<&str>
fn default_base_url(&self) -> Option<&str>
const &'static strs
without allocations. None = model_provider has no universal endpoint
(local model_providers, auth-less CLIs, user-BYO endpoints).Source§fn default_wire_api(&self) -> &str
fn default_wire_api(&self) -> &str
"responses" (OpenAI Codex-style) or
"chat_completions" (everything else). Providers override to their
native format.Source§fn convert_tools(&self, tools: &[ToolSpec]) -> ToolsPayload
fn convert_tools(&self, tools: &[ToolSpec]) -> ToolsPayload
Source§fn simple_chat<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
message: &'life1 str,
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn simple_chat<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
message: &'life1 str,
model: &'life2 str,
temperature: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Auto Trait Implementations§
impl Freeze for RouterModelProvider
impl !RefUnwindSafe for RouterModelProvider
impl Send for RouterModelProvider
impl Sync for RouterModelProvider
impl Unpin for RouterModelProvider
impl UnsafeUnpin for RouterModelProvider
impl !UnwindSafe for RouterModelProvider
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<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more