Skip to main content

ModelRegistry

Struct ModelRegistry 

Source
pub struct ModelRegistry { /* private fields */ }
Available on crate feature model-discovery only.
Expand description

A layered model resolver: user override → feed cache → static table.

Construct one with new, optionally seed user overrides, then refresh it from a ModelCatalogSource to populate the feed cache. resolve walks the layers in priority order and always returns a ResolvedModel (empty + ResolvedSource::Unknown when nothing matched).

Implementations§

Source§

impl ModelRegistry

Source

pub fn new() -> ModelRegistry

Create an empty registry (no overrides, no feed loaded).

Source

pub fn with_override( self, provider: impl AsRef<str>, model: impl AsRef<str>, entry: CatalogEntry, ) -> ModelRegistry

Builder-style: add a user override that wins over feed and static data.

Source

pub fn register( &mut self, provider: impl AsRef<str>, model: impl AsRef<str>, entry: CatalogEntry, )

Register (or replace) a user override in place.

Source

pub async fn refresh( &self, source: &dyn ModelCatalogSource, ) -> Result<usize, Error>

Fetch from source and replace the feed cache. Returns the entry count.

§Errors

Returns an error if the source fails to fetch or parse, or if the cache lock is poisoned.

Source

pub fn resolve(&self, provider: &str, model: &str) -> ResolvedModel

Resolve a provider/model through the layers: override → feed → static.

Source

pub fn resolve_dynamic( &self, provider: &str, model: &str, ) -> Option<ResolvedModel>

Resolve through the dynamic layers only — user override → feed cache — reporting None when neither carries the pair.

Unlike resolve this never falls back to the static table, which lets a caller that owns its own static lookup keep the two sources apart. That distinction matters when the key a model is filed under differs per source: a caller can then ask this catalog about every key the feeds might use before letting the static table answer under the (narrower) set of keys it is built from, instead of having the first key that happens to hit the static layer short-circuit the search.

Source

pub fn resolve_override( &self, provider: &str, model: &str, ) -> Option<ResolvedModel>

Resolve through the override layer only — a user-registered override — reporting None when the pair has none.

An override is authoritative: the caller uses it in preference to any feed row, so it is probed on its own. See estimate_override_cost_usd.

Source

pub fn estimate_override_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate cost from the override layer only (never feed or static), with tier selection. None when the pair has no override.

Source

pub fn estimate_override_base_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate cost from the override layer only, at the base band (a summed usage). None when the pair has no override.

Source

pub fn resolve_feed(&self, provider: &str, model: &str) -> Option<ResolvedModel>

Resolve through the feed layer only — the refreshable cache — skipping both the override and the static table. None when the feed has none.

A caller that scopes override authority by candidate specificity needs the feed price at a key independently of any override on the same key, which the layered lookups (which let an override shadow the feed) cannot give it.

Source

pub fn estimate_feed_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate cost from the feed layer only (never override or static), with tier selection. None when the feed has no row for the pair.

Source

pub fn estimate_feed_base_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate cost from the feed layer only, at the base band (a summed usage). None when the feed has no row for the pair.

Source

pub fn estimate_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate request cost in USD using the layered pricing (override → feed → static), if any.

Reports None — “this catalog cannot price the call” — rather than a partial figure when the resolved pricing is missing a rate for a usage component with a nonzero token count (e.g. a feed row that lists an input rate but no output rate). A caller can then fall back to another pricing source instead of billing those tokens at zero.

A call whose context exceeds a published tier threshold is billed at that tier’s rates, not the base rates.

Source

pub fn estimate_dynamic_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate request cost in USD from the dynamic layers only (override → feed), never the static table. See resolve_dynamic.

Declines partial pricing, and selects the tier the call falls in, exactly as estimate_cost_usd does.

usage must describe a SINGLE provider call: tier selection reads its input-token count as the call’s context size. To price a summed usage, use estimate_dynamic_base_cost_usd.

Source

pub fn estimate_dynamic_base_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate cost from the dynamic layers at the BASE band, ignoring any long-context tiers.

For a summed usage — a thread’s cumulative tokens, not one call — the input-token count is not a context size: ten 50K-token calls sum to 500K without any single call ever reaching a 272K threshold. Selecting a tier from that sum would reprice the whole history at long-context rates a call never paid, so aggregate repricing stays on the base band.

Trait Implementations§

Source§

impl Clone for ModelRegistry

Source§

fn clone(&self) -> ModelRegistry

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl CostEstimator for ModelRegistry

Source§

fn estimate_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate the USD cost of usage for provider/model. Read more
Source§

fn estimate_aggregate_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate the USD cost of a summed usage — a thread’s cumulative tokens rather than one call. Read more
Source§

fn estimate_override_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate the USD cost only if provider/model resolves through a source layer the caller must treat as authoritative over the others — a user-registered override. Read more
Source§

fn estimate_override_aggregate_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

The summed-usage counterpart of estimate_override_cost_usd.
Source§

fn estimate_feed_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

Estimate the USD cost from a source layer that has NO absolute authority — a refreshable feed row, as opposed to a user override. Read more
Source§

fn estimate_feed_aggregate_cost_usd( &self, provider: &str, model: &str, usage: &Usage, ) -> Option<f64>

The summed-usage counterpart of estimate_feed_cost_usd.
Source§

impl Default for ModelRegistry

Source§

fn default() -> ModelRegistry

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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