#[non_exhaustive]pub struct ModelSpec {Show 14 fields
pub id: String,
pub provider: ProviderId,
pub display_name: String,
pub context_window: Option<u32>,
pub max_output_tokens: Option<u32>,
pub input: Modalities,
pub reasoning: ReasoningSupport,
pub caching: CacheSupport,
pub tools: bool,
pub structured_output: bool,
pub pricing: Option<Pricing>,
pub deprecated: bool,
pub sampling: Option<Sampling>,
pub compat: Compat,
}Expand description
One model’s facts: limits, input modalities, the reasoning and caching it
takes, and its prices. Catalog builds one per row of
its data; ModelSpec::new and the with_* setters build one in code,
for a model the catalog does not list, and
Catalog::insert adds it.
It serializes field by field and reads back the same. For the override
file’s row shape, use Self::to_row_json.
use rig_core::catalog::{Catalog, ModelSpec, Pricing};
use rig_core::providers::registry::ProviderId;
let ollama = ProviderId::catalog("ollama").ok_or("a known vendor")?;
let mut catalog = Catalog::builtin().clone();
catalog.insert(
ModelSpec::new(ollama, "qwen3:4b")
.with_context_window(32_768)
.with_tools(true)
.with_pricing(Pricing::new(0.0, 0.0)),
);
let qwen = catalog.get(ollama, "qwen3:4b").ok_or("inserted")?.spec;
assert_eq!(qwen.context_window, Some(32_768));Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.id: StringThe provider’s own model id.
provider: ProviderIdThe provider serving the model under Self::id, in the protocol
family the model is reached by: its vendor’s own
(ProviderId::catalog) unless the catalog row names another
under rig.format. Self::format reads it.
display_name: StringA human-readable name.
context_window: Option<u32>The most tokens the model reads and writes in one request, if known.
max_output_tokens: Option<u32>The most tokens the model writes in one reply, if known.
input: ModalitiesWhat the model reads.
reasoning: ReasoningSupportThe reasoning the model takes.
caching: CacheSupportThe cache retentions the model honours.
tools: boolWhether the model calls tools.
structured_output: boolWhether the model constrains its output to a JSON schema.
pricing: Option<Pricing>Prices in USD per million tokens, if known.
deprecated: boolWhether the provider has deprecated the model.
sampling: Option<Sampling>When the model takes sampling parameters (temperature, top_p,
top_logprobs, logprobs), or None when unknown.
compat: CompatWire facts the encoders read that no portable field holds.
Implementations§
Source§impl ModelSpec
impl ModelSpec
Sourcepub fn new(provider: ProviderId, id: impl Into<String>) -> Self
pub fn new(provider: ProviderId, id: impl Into<String>) -> Self
A spec for provider’s model id with nothing else known: its id as
its name, no limits, text input only, no reasoning, unknown caching,
no tools or structured output, no prices (None, never zero), not
deprecated, unknown sampling and default Compat.
Sourcepub fn format(&self) -> Option<Format>
pub fn format(&self) -> Option<Format>
The protocol family a connection to this model speaks unless told
otherwise, or None for a provider the registry cannot configure.
To reach the model in another family its vendor is registered for,
build the spec with that ProviderId or pass the family to
ConnectOptions::format.
Sourcepub fn reference(&self) -> String
pub fn reference(&self) -> String
The vendor/model reference Catalog::resolve
reads back to this model.
Sourcepub fn default_options(&self, reasoning: Option<Reasoning>) -> GenerationOptions
pub fn default_options(&self, reasoning: Option<Reasoning>) -> GenerationOptions
The options of a request to this model with reasoning (None
for the provider’s default): that reasoning, and the short prompt
cache when Self::caching lists it. A model whose caching the
catalog does not know gets no cache option, which it could refuse.
Sourcepub fn with_display_name(self, name: impl Into<String>) -> Self
pub fn with_display_name(self, name: impl Into<String>) -> Self
This spec named name.
Sourcepub fn with_context_window(self, tokens: u32) -> Self
pub fn with_context_window(self, tokens: u32) -> Self
This spec with a context window of tokens.
Sourcepub fn with_max_output_tokens(self, tokens: u32) -> Self
pub fn with_max_output_tokens(self, tokens: u32) -> Self
This spec writing at most tokens in one reply.
Sourcepub fn with_reasoning(self, reasoning: ReasoningSupport) -> Self
pub fn with_reasoning(self, reasoning: ReasoningSupport) -> Self
This spec taking reasoning.
Sourcepub fn with_caching(self, caching: CacheSupport) -> Self
pub fn with_caching(self, caching: CacheSupport) -> Self
This spec honouring caching.
Sourcepub fn with_tools(self, tools: bool) -> Self
pub fn with_tools(self, tools: bool) -> Self
This spec with tool calling set to tools.
Sourcepub fn with_pricing(self, pricing: Pricing) -> Self
pub fn with_pricing(self, pricing: Pricing) -> Self
This spec priced at pricing.
Sourcepub fn with_sampling(self, sampling: Sampling) -> Self
pub fn with_sampling(self, sampling: Sampling) -> Self
This spec taking sampling parameters as sampling says.
Sourcepub fn with_compat(self, compat: Compat) -> Self
pub fn with_compat(self, compat: Compat) -> Self
This spec with the wire facts compat.
Sourcepub fn to_row_json(&self) -> Value
pub fn to_row_json(&self) -> Value
This spec as one models.dev-shaped row of an override file, with
rig’s facts under rig. Read back under its vendor key, the row
builds this spec again. A fact the spec does not know (a None
limit, price, sampling rule or reasoning default, or empty caching)
is left out, so laid over another row it keeps that row’s value.
Sourcepub fn validate(
&self,
options: &GenerationOptions,
) -> Result<(), UnsupportedOption>
pub fn validate( &self, options: &GenerationOptions, ) -> Result<(), UnsupportedOption>
Checks options against the rules Self::refusals applies,
and returns the first refusal. It checks only what options holds,
so it never refuses temperature, which a request carries outside
its options; Self::refusals checks the whole request.
§Errors
The first option the model cannot take. The error names the option, the provider’s vendor and this model.
Sourcepub fn refusals(&self, request: &CompletionRequest) -> Vec<UnsupportedOption>
pub fn refusals(&self, request: &CompletionRequest) -> Vec<UnsupportedOption>
Every option of request the model cannot take, by the rules every
completion wire also applies before it encodes, so a request this
refuses is refused by the model’s wire too:
reasoningagainstSelf::reasoning(ReasoningSupport::refusal);cacheagainstSelf::caching(CacheSupport::refusal);top_pandtemperatureagainstSelf::sampling:Sampling::Neverrefuses both, andSampling::ReasoningOffrefuses both while the model reasons. A model that cannot turn reasoning off always reasons; one that can reasons unlessreasoningisOff, and with noreasoningset, when it names a default effort.
A request whose GenerationOptions are default is not checked, as
GenerationOptions::is_default says, so this is empty for it. A
wire refuses more than this: what its route or API cannot carry
(DynModel::check reports both).
Sourcepub fn fit(&self, request: &mut CompletionRequest) -> Vec<UnsupportedOption>
pub fn fit(&self, request: &mut CompletionRequest) -> Vec<UnsupportedOption>
Fits request to this model: takes out each option it would refuse
(Self::refusals) and leaves everything else as it is, so a request
built or edited for another model keeps what this one takes. A refused
reasoning setting becomes the provider default (None) first, since
whether the model reasons decides whether it takes temperature and
top_p. Returns what was taken out, in that order; afterwards
Self::refusals of the request is empty.
use rig_core::catalog::{ModelSpec, ReasoningSupport};
use rig_core::completion::{CompletionRequest, Effort, GenerationOptions, Reasoning};
use rig_core::providers::registry::ProviderId;
let vendor = ProviderId::catalog("ollama").ok_or("a known vendor")?;
let plain = ModelSpec::new(vendor, "plain").with_reasoning(ReasoningSupport::None);
let options = GenerationOptions::default().reasoning(Reasoning::Effort(Effort::High));
let mut request = CompletionRequest::new("hi").options(options.seed(7));
let dropped = plain.fit(&mut request);
assert_eq!(dropped.len(), 1);
assert_eq!((request.options.reasoning, request.options.seed), (None, Some(7)));Trait Implementations§
Source§impl<'de> Deserialize<'de> for ModelSpec
impl<'de> Deserialize<'de> for ModelSpec
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<'a> From<&'a ModelSpec> for ModelSelector<'a>
impl<'a> From<&'a ModelSpec> for ModelSelector<'a>
impl StructuralPartialEq for ModelSpec
Auto Trait Implementations§
impl Freeze for ModelSpec
impl RefUnwindSafe for ModelSpec
impl Send for ModelSpec
impl Sync for ModelSpec
impl Unpin for ModelSpec
impl UnsafeUnpin for ModelSpec
impl UnwindSafe for ModelSpec
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§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