pub struct ModelSpec {Show 14 fields
pub provider: String,
pub model: String,
pub api_identifier: String,
pub max_output_tokens: usize,
pub input_context: usize,
pub generation: f32,
pub tier: String,
pub legacy: bool,
pub retires: Option<String>,
pub supports_structured_output: bool,
pub input_token_price: Option<f64>,
pub output_token_price: Option<f64>,
pub beta_headers: Vec<BetaHeader>,
pub source: ModelSource,
}Expand description
Specification for a single model: its identity, limits, tier, and any beta-header unlocks.
A ModelSpec is the central row of the registry. provider and
tier cross-reference into a ProviderConfig (via
ModelConfiguration::providers and ProviderConfig::tiers).
max_output_tokens and input_context are the base limits; entries
in beta_headers raise them when the corresponding HTTP header is sent.
source is loader-populated and records which layer contributed the
entry — never read from YAML.
§Identifier normalization
The same underlying model is addressable through several identifier formats depending on how the API is reached:
- Canonical (Anthropic direct):
claude-3-7-sonnet-20250219 - Bedrock with region prefix:
us.anthropic.claude-3-7-sonnet-20250219-v1:0 - AWS-direct without region:
anthropic.claude-3-haiku-20240307-v1:0 - Regional gateways:
eu.anthropic.claude-3-opus-20240229-v2:1
All four resolve to the same ModelSpec:
ModelRegistry::get_model_spec tries an exact match first, and on
miss strips region/provider prefixes and version suffixes before
retrying. See ADR-0011 for the design
rationale.
Fields§
§provider: StringAI provider name (e.g., “claude”).
model: StringHuman-readable model name (e.g., “Claude Opus 4”).
api_identifier: StringAPI identifier used for requests (e.g., “claude-3-opus-20240229”).
max_output_tokens: usizeMaximum number of tokens that can be generated in a single response.
input_context: usizeMaximum number of tokens that can be included in the input context.
generation: f32Model generation number (e.g., 3.0, 3.5, 4.0).
tier: StringPerformance tier (e.g., “fast”, “balanced”, “flagship”).
legacy: boolWhether this is a legacy model that may be deprecated.
retires: Option<String>Announced retirement date (YYYY-MM-DD), if the provider has published
one.
Complements Self::legacy, which cannot distinguish “older but fine”
from “stops working on a known date” (#1334). None covers both models
with no announced retirement and deprecated models whose date is still
TBD — absence means “no published date”, never “not retiring”.
A past date means the model is already retired and its identifier now
404s; such entries are retained only so Bedrock/AWS identifier
normalization keeps resolving them (see ADR-0011).
Held as a plain String: nothing parses or compares it today, it is
carried verbatim into omni-dev config models show.
supports_structured_output: boolWhether this model supports structured JSON-schema output via the
Anthropic Messages API output_config.format (and the equivalent on
Bedrock).
Gates the direct-API / Bedrock schema path (#1119): only models
flagged here advertise
AiClientCapabilities::supports_response_schema,
so a caller on an older model — which would 400 on
output_config — transparently keeps the YAML fallback. Defaults to
false, so unmarked and unknown models are never sent the field.
input_token_price: Option<f64>Price per million input tokens in USD, if known.
Used to compute per-invocation cost for backends that report token
usage (currently the direct Anthropic API — see
[crate::claude::ai::compute_cost_usd]). None for unpriced models
(e.g. the OpenAI/Gemini entries), which surface cost as unknown.
output_token_price: Option<f64>Price per million output tokens in USD, if known. See
Self::input_token_price.
beta_headers: Vec<BetaHeader>Beta headers that unlock enhanced limits for this model.
source: ModelSourceLayer that contributed this entry. Populated by the loader; never read from YAML.