Repository navigation
Conversation
…colua#3901) Every single-provider entry in the catalog declares a `capabilities` object. A combo declared none at all -- just { id, object, owned_by }. Codex CLI reads that field to decide what tool schema to send. Seeing no declared tool support it downgraded the schema on the actual /v1/responses call, and the model was handed two stub tools with empty parameters.properties: nothing it could call, and no error anywhere. A request routed to a combo may land on any member -- reordering by capability fit sorts but never drops -- so the pool can only promise what every member honours. Declaring tools:true because one member has them is a promise fallback breaks silently, on the turn it matters. Only the flags a client reads to decide what to send are reported. Thinking wire format, budget ranges and token limits describe how to talk to one specific model and would be wrong rather than merely incomplete if merged across a pool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3901.
Every single-provider entry in
GET /v1/modelsdeclares acapabilitiesobject. A combo declared none at all:{"id":"gpt-5.6-sol","object":"model","owned_by":"combo"}Codex CLI reads that field to decide what tool schema to send on the actual call. Seeing no declared tool support it downgrades, and the reporter's
requestDetailsshows what reaches the provider: two stub tools with emptyparameters.properties— nothing the model can call, and no error anywhere in the chain. A combo looks like a model that cannot use tools, and the failure reads as the model being bad at its job.What it declares
Only what every member honours.
reorderModelsByCapabilitysorts a combo's members by fit but never drops one — the comment on it says so, "never drops a model (fallback intact)" — so a request can still land on any member. Declaringtools: truebecause the first member supports them is a promise fallback breaks silently, on the turn a tool is actually needed. The conservative AND is the only answer the pool can keep.That is safe to compute because
getCapabilitiesForModelalways answers: it merges withDEFAULT_CAPABILITIES, so an unknown model reports the default (tools: true) rather than nothing. There is no "unknown" here to mistake for false.Only the flags a client reads to decide what to send —
tools,vision,reasoning,search, and the input/output modality flags.thinkingFormat,thinkingRange,contextWindowandmaxOutputdescribe how to talk to one specific model; merged across a pool they would be wrong rather than merely incomplete, so they are deliberately left off.Verification
npx next build— 0 errors.Checked by breaking it: changing the AND to an OR (one member is enough) fails 3 of the 6 — the withheld-feature case, the missing-record case, and the per-flag independence case. That is the mutation that matters here, because OR is the reading that makes the reporter's symptom go away while reintroducing the silent-failure version of it.
One test exists only to pin that an absent
capabilitiesis still possible for a combo with genuinely no members, and never as a quiet fallback for one that has them — an absent field is what the bug looked like, so it must not become the error path.Note on overlap
This touches the same
elsebranch as my #3880, which addscontext_length/max_completion_tokensto combo entries by the same "smallest member" reasoning. They are independent and I have kept this one standalone againstmasterso it can be taken on its own; if #3880 goes first this rebases to one hunk, and I am happy to do that.