Skip to main content

ModelRouter

Struct ModelRouter 

Source
pub struct ModelRouter<C, S, A> { /* private fields */ }
Expand description

Routes each request to a model tier chosen by an LLM classifier.

A ModelRouter wraps a classifier provider plus three tier providers and, for every request, makes one extra classifier call to decide whether the work is Simple, Moderate, or Complex, then dispatches to the fast, capable, or advanced provider respectively. If the classifier call fails (error or rate limit) the router conservatively treats the request as Complex rather than risk under-serving it (see classify).

ModelRouter itself implements LlmProvider, so it can be passed anywhere a &dyn LlmProvider is expected (run_structured, RefreshingProvider, etc.). chat classifies then routes; the streaming chat_stream classifies first, then streams the chosen tier.

Note: the fast and capable tiers currently share one provider type S (only advanced has its own type A), so mixing e.g. a Gemini fast tier with an OpenAI capable tier requires both behind the same concrete type. Use Arc<dyn LlmProvider> for all three tiers to mix providers freely.

Implementations§

Source§

impl<C, S, A> ModelRouter<C, S, A>

Source

pub const fn new( classifier: C, fast: S, capable: S, advanced: A, ) -> ModelRouter<C, S, A>

Source

pub async fn classify( &self, request: &ChatRequest, ) -> Result<TaskComplexity, Error>

§Errors

Returns an error if the LLM provider fails.

Source

pub async fn route(&self, request: ChatRequest) -> Result<ChatOutcome, Error>

§Errors

Returns an error if the LLM provider fails.

Source

pub async fn route_with_tier( &self, request: ChatRequest, tier: ModelTier, ) -> Result<ChatOutcome, Error>

§Errors

Returns an error if the LLM provider fails.

Source

pub const fn fast_provider(&self) -> &S

Source

pub const fn capable_provider(&self) -> &S

Source

pub const fn advanced_provider(&self) -> &A

Trait Implementations§

Source§

impl<C, S, A> LlmProvider for ModelRouter<C, S, A>

Source§

fn model(&self) -> &str

Reports the capable (mid) tier’s model as the router’s representative model identifier.

Source§

fn provider(&self) -> &'static str

Reports the capable (mid) tier’s provider as the router’s representative provider identifier.

Source§

fn chat<'life0, 'async_trait>( &'life0 self, request: ChatRequest, ) -> Pin<Box<dyn Future<Output = Result<ChatOutcome, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, ModelRouter<C, S, A>: 'async_trait,

Non-streaming chat completion.
Source§

fn chat_stream( &self, request: ChatRequest, ) -> Pin<Box<dyn Stream<Item = Result<StreamDelta, Error>> + Send + '_>>

Streaming chat completion. Read more
Source§

fn configured_thinking(&self) -> Option<&ThinkingConfig>

Provider-owned thinking configuration, if any.
Source§

fn capabilities(&self) -> Option<&'static ModelCapabilities>

Canonical capability metadata for this provider/model, if known.
Source§

fn validate_thinking_config( &self, thinking: Option<&ThinkingConfig>, ) -> Result<(), Error>

Validate a thinking configuration against the provider/model capabilities. Read more
Source§

fn resolve_thinking_config( &self, request_thinking: Option<&ThinkingConfig>, ) -> Result<Option<ThinkingConfig>, Error>

Resolve the effective thinking configuration for a request. Read more
Source§

fn default_max_tokens(&self) -> u32

Default maximum output tokens for this provider/model when the caller does not explicitly override AgentConfig.max_tokens.
Source§

fn structured_output_support(&self) -> StructuredOutputSupport

How this provider satisfies a structured-output (ResponseFormat) request. Read more

Auto Trait Implementations§

§

impl<C, S, A> Freeze for ModelRouter<C, S, A>
where C: Freeze, S: Freeze, A: Freeze,

§

impl<C, S, A> RefUnwindSafe for ModelRouter<C, S, A>

§

impl<C, S, A> Send for ModelRouter<C, S, A>
where C: Send, S: Send, A: Send,

§

impl<C, S, A> Sync for ModelRouter<C, S, A>
where C: Sync, S: Sync, A: Sync,

§

impl<C, S, A> Unpin for ModelRouter<C, S, A>
where C: Unpin, S: Unpin, A: Unpin,

§

impl<C, S, A> UnsafeUnpin for ModelRouter<C, S, A>

§

impl<C, S, A> UnwindSafe for ModelRouter<C, S, A>
where C: UnwindSafe, S: UnwindSafe, A: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more