-
Notifications
You must be signed in to change notification settings - Fork 3k
fix(core,vscode): keep provider update versions in sync #8889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1df9c1d
71bd8f1
244451c
ffa5c8d
d798388
bbd4889
2469ebc
a447db5
4099542
3646f92
92ca1f4
bec8736
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,8 +205,9 @@ function findAllPendingUpdates( | |
| if (!metadata.version) continue; | ||
|
|
||
| const baseUrl = metadata.baseUrl || resolveBaseUrl(provider); | ||
| const currentTemplate = buildProviderTemplate(provider, baseUrl); | ||
| const currentVersion = computeModelListVersion(currentTemplate); | ||
| const currentVersion = computeModelListVersion( | ||
| buildProviderTemplate(provider, baseUrl), | ||
| ); | ||
|
|
||
| if (metadata.version === currentVersion) continue; | ||
| if (metadata.ignoredVersion === currentVersion) continue; | ||
|
|
@@ -255,9 +256,10 @@ export function useProviderUpdates( | |
| const migrated = useRef(false); | ||
|
|
||
| const executeUpdate = useCallback( | ||
| async (providerCfg: ProviderConfig, baseUrl?: string) => { | ||
| async (pending: PendingUpdate) => { | ||
| try { | ||
| const resolved = resolveBaseUrl(providerCfg, baseUrl); | ||
| const providerCfg = pending.provider; | ||
| const resolved = resolveBaseUrl(providerCfg, pending.baseUrl); | ||
|
yiliang114 marked this conversation as resolved.
|
||
| // An update only refreshes built-in models — user-added custom IDs | ||
| // must be carried through so they are not deleted by the | ||
| // prepend-and-remove-owned merge. | ||
|
|
@@ -270,7 +272,12 @@ export function useProviderUpdates( | |
| apiKey: '', | ||
| modelIds: [...defaultIds, ...customIds], | ||
| }); | ||
| installPlan.providerState![ | ||
| `${PROVIDER_METADATA_NS}.${pending.metadataKey}` | ||
| ]!['version'] = pending.currentVersion; | ||
|
yiliang114 marked this conversation as resolved.
|
||
| delete installPlan.env; | ||
| // Template updates never change the selected model. | ||
| delete installPlan.modelSelection; | ||
|
Comment on lines
+279
to
+280
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] The 中文说明[建议] — qwen3.8-max via Qwen Code /review (v0.21.9)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] The prompt still promises a model switch this line prevents Deleting However
using
Either soften the prompt text (e.g. "Your selected model is being removed; use Note: the This review was generated by QoderWork AI |
||
| const previousModel = config.getModel(); | ||
| const activeConfig = config.getContentGeneratorConfig(); | ||
| const updatesActiveProvider = | ||
|
|
@@ -280,14 +287,6 @@ export function useProviderUpdates( | |
| activeConfig.baseUrl, | ||
| activeConfig.apiKeyEnvKey, | ||
| ); | ||
| const newConfigs = installPlan.modelProviders?.[0]?.models ?? []; | ||
| const previousModelStillAvailable = newConfigs.some( | ||
| (cfg) => cfg.id === previousModel, | ||
| ); | ||
| // Only the active provider may migrate model selection. | ||
| if (!updatesActiveProvider || previousModelStillAvailable) { | ||
| delete installPlan.modelSelection; | ||
| } | ||
| const settingsAdapter = createLoadedSettingsAdapter(settings); | ||
|
|
||
| await applyProviderInstallPlan(installPlan, { | ||
|
|
@@ -386,7 +385,7 @@ export function useProviderUpdates( | |
| setUpdateRequest(undefined); | ||
| if (choice === 'update') { | ||
| for (const p of pendingList) { | ||
| await executeUpdate(p.provider, p.baseUrl); | ||
| await executeUpdate(p); | ||
| } | ||
| } else if (choice === 'skip') { | ||
| const persistScope = getPersistScopeForModelSelection(settings); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,8 +62,14 @@ describe('buildInstallPlan', () => { | |
| }); | ||
|
|
||
| it('builds a plan with editable models and unknown IDs', () => { | ||
| const config = makeConfig({ modelsEditable: true }); | ||
| const plan = buildInstallPlan(config, { | ||
| const config = makeConfig({ | ||
| modelsEditable: true, | ||
| models: [ | ||
| { id: 'model-a', contextWindowSize: 8192, enableThinking: true }, | ||
| { id: 'model-b' }, | ||
| ], | ||
| }); | ||
| const plan = buildInstallPlanSrc(config, { | ||
| baseUrl: 'https://api.test.com/v1', | ||
| apiKey: 'sk-test', | ||
| modelIds: ['model-a', 'unknown-model'], | ||
|
|
@@ -77,6 +83,9 @@ describe('buildInstallPlan', () => { | |
| name: '[Test] unknown-model', | ||
| }); | ||
| expect(models?.[1]?.generationConfig).toBeUndefined(); | ||
| expect(plan.providerState?.['providerMetadata.test']?.['version']).toBe( | ||
| computeModelListVersion(models ?? []), | ||
| ); | ||
|
yiliang114 marked this conversation as resolved.
|
||
| }); | ||
|
|
||
| it('applies advancedConfig to editable unknown model IDs only', () => { | ||
|
|
@@ -674,7 +683,9 @@ import { | |
| getAllProviderBaseUrls as getAllProviderBaseUrlsSrc, | ||
| } from '../all-providers.js'; | ||
| import { | ||
| buildInstallPlan as buildInstallPlanSrc, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] Still unresolved from the previous review: source import placed after first use
Please move this source-relative import block (and the This review was generated by QoderWork AI |
||
| resolveBaseUrl as resolveBaseUrlSrc, | ||
| resolveMetadataKey as resolveMetadataKeySrc, | ||
| providerMatchesCredentials as providerMatchesCredentialsSrc, | ||
|
yiliang114 marked this conversation as resolved.
|
||
| } from '../provider-config.js'; | ||
|
|
||
|
|
@@ -795,8 +806,6 @@ describe('providerMatchesCredentials with function envKey (custom provider)', () | |
| }); | ||
| }); | ||
|
|
||
| import { resolveMetadataKey as resolveMetadataKeySrc } from '../provider-config.js'; | ||
|
|
||
| describe('customHeaders in ProviderConfig', () => { | ||
| it('merges customHeaders into generationConfig for fixed models', () => { | ||
| const config = makeConfig({ | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,7 +25,11 @@ vi.mock('@qwen-code/qwen-code-core', async (importOriginal) => { | |||||||||||||||||||
| }; | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import { AuthType, type ProviderInstallPlan } from '@qwen-code/qwen-code-core'; | ||||||||||||||||||||
| import { | ||||||||||||||||||||
| AuthType, | ||||||||||||||||||||
| CODING_PLAN_GLOBAL_BASE_URL, | ||||||||||||||||||||
| type ProviderInstallPlan, | ||||||||||||||||||||
| } from '@qwen-code/qwen-code-core'; | ||||||||||||||||||||
| import { CODING_PLAN_ENV_KEY } from './subscriptionPlanDefinitions.js'; | ||||||||||||||||||||
| import { | ||||||||||||||||||||
| applyProviderInstallPlanToFile, | ||||||||||||||||||||
|
|
@@ -52,6 +56,19 @@ describe('settingsWriter', () => { | |||||||||||||||||||
| fs.rmSync(tempDir, { recursive: true, force: true }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| it('persists the selected Coding Plan region metadata', () => { | ||||||||||||||||||||
| writeCodingPlanConfig('global', 'coding-plan-key'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const settings = JSON.parse( | ||||||||||||||||||||
| fs.readFileSync(settingsPath, 'utf-8'), | ||||||||||||||||||||
| ) as Record<string, Record<string, Record<string, unknown>>>; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| expect(settings.providerMetadata?.['coding-plan']).toMatchObject({ | ||||||||||||||||||||
| region: 'global', | ||||||||||||||||||||
| baseUrl: CODING_PLAN_GLOBAL_BASE_URL, | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
Comment on lines
+66
to
+69
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] No test asserts the
Suggested change
中文说明[建议] 没有测试断言 — qwen3.8-max via Qwen Code /review (v0.21.9) |
||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| it('clears stale coding plan metadata when writing api-key providers', () => { | ||||||||||||||||||||
| writeCodingPlanConfig('china', 'coding-plan-key'); | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.