revert(cli): undo OPENAI_MODEL precedence change in modelProviders lookup (#3567)#3633
Merged
Merged
Conversation
…tion (#3567)" This reverts commit 007a109. The change made `OPENAI_MODEL` outrank `settings.model.name` when looking up the active entry in `settings.modelProviders`. Combined with the core resolver's `modelProvider > cli > env > settings` priority, this caused a regression: a `/model` selection (which writes `settings.model.name`) was silently overridden whenever `OPENAI_MODEL` was set in the user's shell, with no warning surfaced. Restoring the previous behavior — looking up the provider entry by `argv.model || settings.model?.name` — preserves the implicit contract that an explicit `modelProviders` config takes precedence over stale shell defaults. Users without a `modelProviders` config are unaffected: env vars still drive model selection through the core resolver. See discussion on #3567.
wenshao
approved these changes
Apr 26, 2026
wenshao
left a comment
Collaborator
There was a problem hiding this comment.
LGTM! ✅ — gpt-5.5 via Qwen Code
Contributor
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
B-A-M-N
added a commit
to B-A-M-N/qwen-code
that referenced
this pull request
Apr 27, 2026
…ection Fixes model precedence regression from QwenLM#3567 (reverted in QwenLM#3633): - argv.model > settings.model.name > OPENAI_MODEL > QWEN_MODEL - settings.model.name wins over OPENAI_MODEL when it matches a provider - OPENAI_MODEL only used as fallback when no explicit model is configured - Added tests proving both paths: settings wins, and OPENAI_MODEL fallback works Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
wenshao
pushed a commit
that referenced
this pull request
Apr 30, 2026
…3645) * fix(cli): correct OPENAI_MODEL precedence without breaking /model selection Fixes model precedence regression from #3567 (reverted in #3633): - argv.model > settings.model.name > OPENAI_MODEL > QWEN_MODEL - settings.model.name wins over OPENAI_MODEL when it matches a provider - OPENAI_MODEL only used as fallback when no explicit model is configured - Added tests proving both paths: settings wins, and OPENAI_MODEL fallback works Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): separate model selection from provider lookup to prevent env override The previous implementation iterated through candidates [argv.model, settings.model.name, OPENAI_MODEL, QWEN_MODEL] and picked the first matching provider. This caused settings.model.name to be overridden by OPENAI_MODEL when the former didn't match any provider. Fix by: 1. First resolve target model using strict precedence 2. Only look up provider for that specific model 3. Filter OPENAI_MODEL/QWEN_MODEL from env when model was resolved from settings or argv, preventing the core resolver from picking up these env vars Also fixes Edge Case 5 test (was testing buggy behavior) and adds integration test verifying settings.model.name wins over OPENAI_MODEL. * fix(types): remove unused type annotation from mock The mockImplementation used ModelConfigSourcesInput type which wasn't properly resolved. Remove the type annotation to fix TypeScript and ESLint errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * trigger CI * chore: trigger clean CI build * fix(test): make mock compatible with CI type checking The mockImplementation was causing TS2345 in CI because the return type didn't match ModelConfigResolutionResult. Fixed by using optional chaining and removing type annotations that caused CI build failures. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): make mock compatible with CI type checking The mock of resolveModelConfig returned sources as { model: string } instead of { model: ConfigSource }, causing a type error in CI only (where strictBuild is enabled). Use proper ConfigSource objects. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): update mock to match reviewer suggestion Use proper ConfigSource objects with path/envKey details as suggested in the review, matching what resolveModelConfig actually returns. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(cli): add regression tests for model precedence Adds [Regression] tests that guard against the original bug where OPENAI_MODEL incorrectly overrode settings.model.name. Tests cover: - settings.model.name precedence over OPENAI_MODEL - OPENAI_MODEL used when settings.model.name not set - argv.model overriding both settings and env - QWEN_MODEL as fallback when OPENAI_MODEL not set - Non-OpenAI auth ignoring OPENAI_MODEL Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): address reviewer feedback on model precedence PR - Add missing assertion in Non-OpenAI auth test to verify OPENAI_MODEL is filtered from env passed to resolveModelConfig - Clean up modelProvider lookup comment to clarify the old bug is fixed Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): address review feedback on model precedence PR - Sanitize OPENAI_MODEL/QWEN_MODEL in beforeEach to prevent flaky tests - Remove stray "// trigger rebuild" comment - Add AUTH_ENV_MODEL_VARS mapping for all auth types (not just OpenAI) - Fix filteredEnv logic to strip ALL model env vars when model not from env - Use sourceEnvVar tracking to only keep the env var that was actually used Fixes the blocking test failure when OPENAI_MODEL is set in shell env. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): fix test assertion for filtered env, add source-based filtering comments --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
xaelistic
pushed a commit
to xaelistic/qwen-code
that referenced
this pull request
Jun 7, 2026
…tion (QwenLM#3567)" (QwenLM#3633) This reverts commit 4420229. The change made `OPENAI_MODEL` outrank `settings.model.name` when looking up the active entry in `settings.modelProviders`. Combined with the core resolver's `modelProvider > cli > env > settings` priority, this caused a regression: a `/model` selection (which writes `settings.model.name`) was silently overridden whenever `OPENAI_MODEL` was set in the user's shell, with no warning surfaced. Restoring the previous behavior — looking up the provider entry by `argv.model || settings.model?.name` — preserves the implicit contract that an explicit `modelProviders` config takes precedence over stale shell defaults. Users without a `modelProviders` config are unaffected: env vars still drive model selection through the core resolver. See discussion on QwenLM#3567.
xaelistic
pushed a commit
to xaelistic/qwen-code
that referenced
this pull request
Jun 7, 2026
…wenLM#3645) * fix(cli): correct OPENAI_MODEL precedence without breaking /model selection Fixes model precedence regression from QwenLM#3567 (reverted in QwenLM#3633): - argv.model > settings.model.name > OPENAI_MODEL > QWEN_MODEL - settings.model.name wins over OPENAI_MODEL when it matches a provider - OPENAI_MODEL only used as fallback when no explicit model is configured - Added tests proving both paths: settings wins, and OPENAI_MODEL fallback works Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): separate model selection from provider lookup to prevent env override The previous implementation iterated through candidates [argv.model, settings.model.name, OPENAI_MODEL, QWEN_MODEL] and picked the first matching provider. This caused settings.model.name to be overridden by OPENAI_MODEL when the former didn't match any provider. Fix by: 1. First resolve target model using strict precedence 2. Only look up provider for that specific model 3. Filter OPENAI_MODEL/QWEN_MODEL from env when model was resolved from settings or argv, preventing the core resolver from picking up these env vars Also fixes Edge Case 5 test (was testing buggy behavior) and adds integration test verifying settings.model.name wins over OPENAI_MODEL. * fix(types): remove unused type annotation from mock The mockImplementation used ModelConfigSourcesInput type which wasn't properly resolved. Remove the type annotation to fix TypeScript and ESLint errors. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * trigger CI * chore: trigger clean CI build * fix(test): make mock compatible with CI type checking The mockImplementation was causing TS2345 in CI because the return type didn't match ModelConfigResolutionResult. Fixed by using optional chaining and removing type annotations that caused CI build failures. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): make mock compatible with CI type checking The mock of resolveModelConfig returned sources as { model: string } instead of { model: ConfigSource }, causing a type error in CI only (where strictBuild is enabled). Use proper ConfigSource objects. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(test): update mock to match reviewer suggestion Use proper ConfigSource objects with path/envKey details as suggested in the review, matching what resolveModelConfig actually returns. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(cli): add regression tests for model precedence Adds [Regression] tests that guard against the original bug where OPENAI_MODEL incorrectly overrode settings.model.name. Tests cover: - settings.model.name precedence over OPENAI_MODEL - OPENAI_MODEL used when settings.model.name not set - argv.model overriding both settings and env - QWEN_MODEL as fallback when OPENAI_MODEL not set - Non-OpenAI auth ignoring OPENAI_MODEL Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): address reviewer feedback on model precedence PR - Add missing assertion in Non-OpenAI auth test to verify OPENAI_MODEL is filtered from env passed to resolveModelConfig - Clean up modelProvider lookup comment to clarify the old bug is fixed Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): address review feedback on model precedence PR - Sanitize OPENAI_MODEL/QWEN_MODEL in beforeEach to prevent flaky tests - Remove stray "// trigger rebuild" comment - Add AUTH_ENV_MODEL_VARS mapping for all auth types (not just OpenAI) - Fix filteredEnv logic to strip ALL model env vars when model not from env - Use sourceEnvVar tracking to only keep the env var that was actually used Fixes the blocking test failure when OPENAI_MODEL is set in shell env. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(cli): fix test assertion for filtered env, add source-based filtering comments --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
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.
Summary
packages/cli/src/utils/modelConfigUtils.tsto useargv.model || settings.model?.name(its prior behavior)./modelselection in the CLI is silently overridden wheneverOPENAI_MODELis set in the user's shell, with no warning surfaced. Detailed reasoning posted in a comment on #3567.settings.modelProvidersconfig should not be overridden by stale shell env vars; users without amodelProvidersconfig are unaffected since env vars still drive model selection through the core resolver.The regression in plain terms
OPENAI_MODEL=qwen3-coder-plusexported in their shell rc./model qwen-coder-turboin the CLI to switch — this writessettings.model.name, and the user has a corresponding entry insettings.modelProviders.Pre-#3567, the CLI looked up the provider entry by
settings.model.name, found it, and the matchedmodelProvider.idwon via the core resolver'smodelProvider > cli > env > settingspriority. The/modelchoice was respected.Post-#3567, the lookup uses
OPENAI_MODELfirst, doesn't match any entry inmodelProviders, returnsundefined, and env wins via fallback. The/modelchoice is silently overridden.Validation
cd packages/cli OPENAI_MODEL=ci-leak-model OPENAI_API_KEY=fake OPENAI_BASE_URL=http://x \ npx vitest run src/utils/modelConfigUtils.test.tsmodelConfigUtilstests pass even withOPENAI_MODELset in env (matching CI conditions).Test Files 1 passed (1) | Tests 28 passed (28). Before this revert, the same command failed onshould find modelProvider from settings.model.name when argv.model is not provided— the exact failure surfaced in run 24949085749.mainto reproduce the failure, then check out this branch and run it again to confirm it passes.Scope / Risk
OPENAI_MODELoverriding theirsettings.modelProvidersconfig will see the env var ignored when a matching provider entry exists forsettings.model.name. Pre-fix(cli): respect OPENAI_MODEL precedence in CLI model resolution #3567 behavior is restored, so this matches the long-standing semantics shipped before that PR./modelflow. Asked the original author to share the scenario in the comment thread.Testing Matrix
Testing matrix notes: tests verified on macOS only. Change is platform-agnostic (pure TypeScript logic in the model resolver), so no platform-specific risk.