fix(coderd): send assigned chat model IDs verbatim - #28144
Conversation
Provider hints are now authoritative in model resolution, so no layer strips vendor prefixes from slash-namespaced model IDs. The save-time and request-time rejection of such models on OpenRouter-like openai-type providers guarded against the old stripping behavior and would now block working configurations.
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Fixes #27361 (CODAGT-832).
Problem
When an Agents model was configured under a non-gateway provider type (e.g. Anthropic or OpenAI) with a model ID whose first
/- or:-segment matched a built-in provider name (anthropic,azure,bedrock,google,openai,openai-compat,openrouter,vercel),chatprovider.ResolveModelWithProviderHintparsed it as a canonicalprovider/modelreference: the prefix was stripped and the request rerouted to the embedded provider type, overriding the provider the admin explicitly assigned. LLM gateways (e.g. LiteLLM) that namespace their catalogs asbedrock/...oranthropic/...behind an Anthropic- or OpenAI-type provider failed with an opaque upstream "Model not found", and escaping was impossible (bedrock/bedrock/...still rerouted).Fix
A valid provider hint is now authoritative:
ResolveModelWithProviderHintreturns the assigned provider and the verbatim model ID whenever a hint is present. Canonicalprovider/modelandprovider:modelparsing applies only to hint-less resolution paths. Every production call site derives the hint from the model config's explicitly assigned AI provider, so the assignment always wins.The save-time guard rejecting slash-namespaced models on OpenRouter-like providers typed as
openai(provider namedopenrouteror hosted atopenrouter.ai) is kept: that combination remains a misconfiguration whose correct fix is theopenrouterprovider type, and rejecting it early beats a confusing upstream error. Its wording no longer claims prefix stripping happens.Back-compat note
A pre-existing config that relied on stripping (e.g. model
anthropic/claude-xassigned to an Anthropic-type provider pointing at the real Anthropic API) now sends the prefixed ID verbatim and will get a clear upstream model-not-found error; the admin fixes it by editing the model ID. Nothing in the product ever suggested the canonical form for assigned models.Validation
TestResolveModelWithProviderHintupdated (hints preservebedrock/...,anthropic/...,provider:...verbatim; hint-less canonical parsing unchanged), red-green verified against the old ordering. Gateway and openai-type provider routing tests assert verbatim pass-through end to end../coderd/x/chatd/...suites plusTestCreateChatModelConfig,TestUpdateChatModelConfig, andTestValidateChatModelConfigProviderModelpass.anthropic/claude-haiku-4.5, with trace logs confirmingprovider=openai model=anthropic/claude-haiku-4.5(verbatim, not rerouted); gateway-type (openai-compat) routing withdeepseek/deepseek-v4-pro-0813and the model catalog/picker regressions pass.