Distinguish unmet required options from unsupported capabilities in model selection errors - #254
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## trunk #254 +/- ##
============================================
+ Coverage 88.16% 88.31% +0.15%
- Complexity 1217 1228 +11
============================================
Files 61 61
Lines 3945 3989 +44
============================================
+ Hits 3478 3523 +45
+ Misses 467 466 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I will be on leave for some time. Will be officially back at 20th of July. |
|
I've requested @felixarntz to share his thoughts, but this makes sense to me and would help with debugging. There was recently a pretty significant refactor of the |
Returns the required options a given model's metadata does not support, either because the option is not listed at all or because the required value is not among the supported values. areMetBy() is refactored to reuse it, with no behavior change. This makes it possible for callers to report *why* a model was excluded during model selection instead of only knowing that it was.
…ction error When no model satisfied the prompt requirements, the exception always read "No models found that support <capability> for this prompt", even when models supporting the capability exist and only a required option (e.g. the temperature sampling parameter) excluded them. A consumer setting an option no available model supports was told the capability itself is unsupported, which is misleading. The message now re-checks the candidates against the required capabilities alone and, when that yields matches, names the unmet options instead: - "... Models supporting text_generation are available, but none of them support the following required options: temperature." - "... but no single model supports all of the following required options together: topP, temperature." (when each option is only individually supported) The existing messages are unchanged when the capability itself is the problem, including the provider-restricted variant.
The getConfiguredModel() and ModelResolver::resolve() docblocks still claimed an explicitly set model is validated against the requirements before use. That validation was removed; an explicit model is used as-is, and unsupported parameters surface as errors from the provider's API. Update the docblocks to describe the actual behavior.
a7f87c9 to
6d582f1
Compare
|
@JasonTheAdams Thanks for the heads-up. I've rebased the PR onto the current trunk and adapted it to the new model resolver architecture. Since the model selection logic (including the "No models found…" exception) moved from the PromptBuilder::getConfiguredModel() into ModelResolver::resolve(), the changes from this PR now live in ModelResolver:
|
Summary
When no model satisfies the prompt requirements,
PromptBuilderalways threw:even when models supporting the capability exist and only a required option excluded them. Because every configured option becomes a hard requirement in
ModelRequirements::fromPromptData(), a consumer doing something as ordinary as:against a provider whose models don't support
temperaturewas told that text generation is unsupported, which is misleading and hard to debug. The capability is fine; the sampling parameter is the problem.This is becoming more visible now that real models reject options they previously accepted: beginning with Claude Opus 4.7, the Anthropic API returns a 400 for any non-default
temperature/top_p/top_k, so the Anthropic provider needs to stop advertising those options in its model metadata (see WordPress/ai-provider-for-anthropic#25). Accurate metadata is only half the story, the SDK should then also report option-based selection failures accurately.How it works
When the candidate set is empty,
PromptBuildernow re-checks the registry against the required capabilities alone:No model supports the capability → the existing messages are unchanged (byte-identical), including the provider-restricted variant.
Models support the capability, but required options excluded them → the message names the options:
Each option is only individually supported (e.g. one model supports
temperature, anothertopP, none both) → the message reflects that:Supporting changes:
ModelRequirements::getUnmetRequiredOptions( ModelMetadata $metadata ): arrayreturns the required options a model does not support (missing, or value not supported).areMetBy()is refactored to reuse it with no behavior change.getConfiguredModel()docblock still claimed an explicitly set model is validated against the requirements; that validation was removed in ba25084, so the docblock now describes the actual behavior (explicit model is used as-is; unsupported parameters surface as errors from the provider's API).Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Fable 5
Used for: Investigating the model selection flow, drafting the implementation and tests. The final implementation was reviewed and edited by me.
Issue
Motivated by the discussion in WordPress/ai-provider-for-anthropic#25.