resolveModelCapabilities function

EffectiveCaps resolveModelCapabilities({
  1. required String provider,
  2. required String modelId,
  3. ModelCapabilityOverride? override,
  4. String? roleThinkingLevel,
  5. int? roleContextWindow,
  6. int? roleMaxTokens,
  7. int? endpointContextWindow,
  8. int? endpointMaxTokens,
  9. ProviderSpec? spec,
  10. int? remoteCatalogContextWindow,
  11. String? api,
  12. bool reasoning = true,
  13. int? contextWindowCap,
})

The layered resolution (gh-1426 AC1). Pure: every layer is an explicit argument, no IO. See the library docs for the precedence contract.

Implementation

EffectiveCaps resolveModelCapabilities({
  required String provider,
  required String modelId,
  ModelCapabilityOverride? override,
  String? roleThinkingLevel,
  int? roleContextWindow,
  int? roleMaxTokens,
  int? endpointContextWindow,
  int? endpointMaxTokens,
  ProviderSpec? spec,
  int? remoteCatalogContextWindow,
  String? api,
  bool reasoning = true,
  int? contextWindowCap,
}) {
  // ── context window: override > role slot > endpoint > remote catalog >
  //    spec > documented unknown default, then the global cap LAST.
  final (window, windowNotes) = _resolveCapabilityWindowLayer(
    provider: provider,
    modelId: modelId,
    override: override,
    roleContextWindow: roleContextWindow,
    endpointContextWindow: endpointContextWindow,
    remoteCatalogContextWindow: remoteCatalogContextWindow,
    spec: spec,
    contextWindowCap: contextWindowCap,
  );

  // ── max output tokens: override > role slot > endpoint > Claude
  //    ceiling table > spec > documented unknown default. ONE effective
  //    api for both consumers (the ceiling table and the documented wire
  //    field): a caller that passes spec but no api must not document
  //    max_tokens for a claude id while resolving WITHOUT the ceiling
  //    table (gh-1426 rework).
  final effectiveApi = api ?? spec?.api;
  final (maxTokens, maxTokensNotes) = _resolveCapabilityMaxTokensLayer(
    provider: provider,
    modelId: modelId,
    override: override,
    roleMaxTokens: roleMaxTokens,
    endpointMaxTokens: endpointMaxTokens,
    api: effectiveApi ?? '',
    spec: spec,
  );
  final notes = [...windowNotes, ...maxTokensNotes];

  // ── thinking: model pin (override) > role slot, then the gate.
  final (thinkingLevel, gateNote) = gateThinkingLevel(
    override?.thinkingLevel ?? roleThinkingLevel,
    reasoning: reasoning,
  );
  if (gateNote != null) {
    notes.add('$provider/$modelId: $gateNote');
  }

  // ── E4: an override addressing a model no catalog knows is kept (it
  //    addresses the future), with a surfaced warning.
  if (override != null &&
      spec == null &&
      remoteCatalogContextWindow == null &&
      endpointContextWindow == null) {
    notes.add(
      'capability override for $provider/$modelId has no catalog entry — '
      'documented defaults + the override apply',
    );
  }

  return EffectiveCaps(
    contextWindow: window,
    maxTokens: maxTokens,
    thinkingLevel: thinkingLevel,
    maxTokensField: maxTokensFieldFor(effectiveApi),
    omitMaxOutputTokens: override?.omitMaxOutputTokens ?? false,
    notes: notes,
  );
}