buildCatalogModel function
Builds a Model for provider/modelId with catalog defaults, overrid-
able per reference (see ModelRef).
maxTokens resolution order: the capability override layer
(modelCapabilityOverrides, gh-1426), the explicit override, then the
Claude ceiling table (resolveModelMaxOutputTokens), then the provider
spec default — per-model reality beats the blanket 16384. The same
layered precedence governs contextWindow and thinkingLevel, and an
override's omitMaxOutputTokens lands on the model compat (AC7).
Throws ConfigException for unknown providers.
Implementation
Model buildCatalogModel(
String provider,
String modelId, {
String? baseUrl,
int? contextWindow,
int? maxTokens,
List<String>? input,
String? thinkingLevel,
String? authHeader,
Duration? connectTimeout,
Duration? streamIdleTimeout,
String? timeoutScopeLabel,
}) {
final spec = catalogProvider(provider);
if (spec == null) {
throw ConfigException(
'unknown provider "$provider" — supported providers: '
'${providerCatalog.keys.join(', ')}',
);
}
validateAuthHeaderDialect(authHeader, spec, 'provider "$provider"');
final caps = resolveModelCapabilities(
provider: spec.name,
modelId: modelId,
override: modelCapabilityOverrides?.lookup(spec.name, modelId),
roleContextWindow: contextWindow,
roleMaxTokens: maxTokens,
roleThinkingLevel: thinkingLevel,
spec: spec,
api: spec.api,
reasoning: spec.reasoning,
);
return Model(
id: modelId,
name: modelId,
api: spec.api,
provider: spec.name,
baseUrl: baseUrl ?? spec.defaultBaseUrl,
reasoning: spec.reasoning,
input: input ?? spec.input,
thinkingLevel: caps.thinkingLevel,
contextWindow: caps.contextWindow,
maxTokens: caps.maxTokens,
authHeader: authHeader,
// The omit-compat flag rides the model compat (AC7); every other
// compat field stays null so the adapter's auto-detection applies.
compat: caps.omitMaxOutputTokens
? const OpenAICompletionsCompat(omitMaxOutputTokens: true)
: null,
// The resolver's loud notes (E1 divergence, E3 gate, E4 catalog miss)
// ride the model so the status surfaces can render them — never
// dropped at the build boundary (gh-1426 rework).
capabilityNotes: caps.notes,
// Request-scoped watchdog windows from a roles chain entry (issue
// #1554): the top precedence layer, riding the model like every other
// per-entry config field (thinkingLevel/authHeader precedent).
connectTimeout: connectTimeout,
streamIdleTimeout: streamIdleTimeout,
timeoutScopeLabel: timeoutScopeLabel,
);
}