mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-05 23:42:03 +00:00
fix(cli): update Coding Plan Global/Intl labels and fix description logic
- Fix AuthDialog to show correct description for coding-plan-intl mode - Update i18n keys from 'Coding Plan (Bailian, Global/Intl)' to 'Bailian Coding Plan (Global/Intl)' - Sync translations across all locales (en, zh, de, ja, pt, ru) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
39360dc058
commit
c1789a0458
11 changed files with 361 additions and 309 deletions
|
|
@ -80,7 +80,7 @@ export function AuthDialog(): React.JSX.Element {
|
|||
},
|
||||
{
|
||||
key: 'coding-plan-intl',
|
||||
label: t('Coding Plan (Bailian, Global/Intl)'),
|
||||
label: t('Bailian Coding Plan (Global/Intl)'),
|
||||
value: 'coding-plan-intl' as ApiKeySubMode,
|
||||
},
|
||||
{
|
||||
|
|
@ -259,10 +259,12 @@ export function AuthDialog(): React.JSX.Element {
|
|||
</Box>
|
||||
<Box marginTop={1} paddingLeft={2}>
|
||||
<Text color={theme.text.secondary}>
|
||||
{apiKeySubItems[apiKeySubModeIndex]?.value === 'coding-plan'
|
||||
? t("Paste your api key of Bailian Coding Plan and you're all set!")
|
||||
: t(
|
||||
{apiKeySubItems[apiKeySubModeIndex]?.value === 'custom'
|
||||
? t(
|
||||
'More instructions about configuring `modelProviders` manually.',
|
||||
)
|
||||
: t(
|
||||
"Paste your api key of Bailian Coding Plan and you're all set!",
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import {
|
|||
getCodingPlanConfig,
|
||||
isCodingPlanConfig,
|
||||
CodingPlanRegion,
|
||||
CODING_PLAN_ENV_KEY,
|
||||
} from '../../constants/codingPlan.js';
|
||||
|
||||
export type { QwenAuthState } from '../hooks/useQwenAuth.js';
|
||||
|
|
@ -298,23 +299,22 @@ export const useAuthCommand = (
|
|||
setAuthError(null);
|
||||
|
||||
// Get configuration based on region
|
||||
const codingPlanConfig = getCodingPlanConfig(region);
|
||||
const { template, envKey, version } = codingPlanConfig;
|
||||
const { template, version, regionName } = getCodingPlanConfig(region);
|
||||
|
||||
// Get persist scope
|
||||
const persistScope = getPersistScopeForModelSelection(settings);
|
||||
|
||||
// Store api-key in settings.env
|
||||
settings.setValue(persistScope, `env.${envKey}`, apiKey);
|
||||
// Store api-key in settings.env (unified env key)
|
||||
settings.setValue(persistScope, `env.${CODING_PLAN_ENV_KEY}`, apiKey);
|
||||
|
||||
// Sync to process.env immediately so refreshAuth can read the apiKey
|
||||
process.env[envKey] = apiKey;
|
||||
process.env[CODING_PLAN_ENV_KEY] = apiKey;
|
||||
|
||||
// Generate model configs from template
|
||||
const newConfigs: ProviderModelConfig[] = template.map(
|
||||
(templateConfig) => ({
|
||||
...templateConfig,
|
||||
envKey,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -324,14 +324,9 @@ export const useAuthCommand = (
|
|||
settings.merged.modelProviders as ModelProvidersConfig | undefined
|
||||
)?.[AuthType.USE_OPENAI] || [];
|
||||
|
||||
// Identify Coding Plan configs by baseUrl + envKey for the given region
|
||||
// Remove existing Coding Plan configs to ensure template changes are applied
|
||||
const checkIsCodingPlanConfig = (config: ProviderModelConfig) =>
|
||||
isCodingPlanConfig(config.baseUrl, config.envKey, region);
|
||||
|
||||
// Filter out existing Coding Plan configs for this region, keep user custom configs
|
||||
// Filter out all existing Coding Plan configs (mutually exclusive)
|
||||
const nonCodingPlanConfigs = existingConfigs.filter(
|
||||
(existing) => !checkIsCodingPlanConfig(existing),
|
||||
(existing) => !isCodingPlanConfig(existing.baseUrl, existing.envKey),
|
||||
);
|
||||
|
||||
// Add new Coding Plan configs at the beginning
|
||||
|
|
@ -351,13 +346,11 @@ export const useAuthCommand = (
|
|||
AuthType.USE_OPENAI,
|
||||
);
|
||||
|
||||
// Persist coding plan version for future update detection
|
||||
// Store version with region suffix to distinguish between China and Intl versions
|
||||
const versionKey =
|
||||
region === CodingPlanRegion.GLOBAL
|
||||
? 'codingPlan.versionIntl'
|
||||
: 'codingPlan.version';
|
||||
settings.setValue(persistScope, versionKey, version);
|
||||
// Persist coding plan region
|
||||
settings.setValue(persistScope, 'codingPlan.region', region);
|
||||
|
||||
// Persist coding plan version (single field for backward compatibility)
|
||||
settings.setValue(persistScope, 'codingPlan.version', version);
|
||||
|
||||
// If there are configs, use the first one as the model
|
||||
if (updatedConfigs.length > 0 && updatedConfigs[0]?.id) {
|
||||
|
|
@ -387,16 +380,12 @@ export const useAuthCommand = (
|
|||
onAuthChange?.();
|
||||
|
||||
// Add success message
|
||||
const regionLabel =
|
||||
region === CodingPlanRegion.GLOBAL
|
||||
? 'Coding Plan (Global/Intl)'
|
||||
: 'Coding Plan';
|
||||
addItem(
|
||||
{
|
||||
type: MessageType.INFO,
|
||||
text: t(
|
||||
'Authenticated successfully with {{region}}. API key is stored in settings.env.',
|
||||
{ region: regionLabel },
|
||||
{ region: regionName },
|
||||
),
|
||||
},
|
||||
Date.now(),
|
||||
|
|
|
|||
|
|
@ -9,14 +9,15 @@ import { renderHook, waitFor } from '@testing-library/react';
|
|||
import { useCodingPlanUpdates } from './useCodingPlanUpdates.js';
|
||||
import {
|
||||
CODING_PLAN_ENV_KEY,
|
||||
CODING_PLAN_INTL_ENV_KEY,
|
||||
CODING_PLAN_BASE_URL,
|
||||
CODING_PLAN_INTL_BASE_URL,
|
||||
CODING_PLAN_VERSION,
|
||||
CODING_PLAN_INTL_VERSION,
|
||||
getCodingPlanConfig,
|
||||
CodingPlanRegion,
|
||||
} from '../../constants/codingPlan.js';
|
||||
import { AuthType } from '@qwen-code/qwen-code-core';
|
||||
|
||||
// Get region configs for testing
|
||||
const chinaConfig = getCodingPlanConfig(CodingPlanRegion.CHINA);
|
||||
const globalConfig = getCodingPlanConfig(CodingPlanRegion.GLOBAL);
|
||||
|
||||
describe('useCodingPlanUpdates', () => {
|
||||
const mockSettings = {
|
||||
merged: {
|
||||
|
|
@ -39,7 +40,6 @@ describe('useCodingPlanUpdates', () => {
|
|||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
delete process.env[CODING_PLAN_ENV_KEY];
|
||||
delete process.env[CODING_PLAN_INTL_ENV_KEY];
|
||||
});
|
||||
|
||||
describe('version comparison', () => {
|
||||
|
|
@ -57,23 +57,10 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(result.current.codingPlanUpdateRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not show update prompt when China versions match', () => {
|
||||
mockSettings.merged.codingPlan = { version: CODING_PLAN_VERSION };
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
mockSettings as never,
|
||||
mockConfig as never,
|
||||
mockAddItem,
|
||||
),
|
||||
);
|
||||
|
||||
expect(result.current.codingPlanUpdateRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not show update prompt when Global versions match', () => {
|
||||
it('should not show update prompt when China region versions match', () => {
|
||||
mockSettings.merged.codingPlan = {
|
||||
versionIntl: CODING_PLAN_INTL_VERSION,
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: chinaConfig.version,
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
|
|
@ -87,8 +74,28 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(result.current.codingPlanUpdateRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should show update prompt when China versions differ', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
it('should not show update prompt when Global region versions match', () => {
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.GLOBAL,
|
||||
version: globalConfig.version,
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
mockSettings as never,
|
||||
mockConfig as never,
|
||||
mockAddItem,
|
||||
),
|
||||
);
|
||||
|
||||
expect(result.current.codingPlanUpdateRequest).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should default to China region when region is not specified', async () => {
|
||||
// No region specified, should default to China
|
||||
mockSettings.merged.codingPlan = {
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
|
|
@ -102,11 +109,17 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(result.current.codingPlanUpdateRequest).toBeDefined();
|
||||
});
|
||||
|
||||
expect(result.current.codingPlanUpdateRequest?.prompt).toContain('China');
|
||||
// Should prompt for China region since it defaults to China
|
||||
expect(result.current.codingPlanUpdateRequest?.prompt).toContain(
|
||||
chinaConfig.regionName,
|
||||
);
|
||||
});
|
||||
|
||||
it('should show update prompt when Global versions differ', async () => {
|
||||
mockSettings.merged.codingPlan = { versionIntl: 'old-version-hash' };
|
||||
it('should show update prompt when China region versions differ', async () => {
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
|
|
@ -121,19 +134,45 @@ describe('useCodingPlanUpdates', () => {
|
|||
});
|
||||
|
||||
expect(result.current.codingPlanUpdateRequest?.prompt).toContain(
|
||||
'Global',
|
||||
chinaConfig.regionName,
|
||||
);
|
||||
});
|
||||
|
||||
it('should show update prompt when Global region versions differ', async () => {
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.GLOBAL,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
mockSettings as never,
|
||||
mockConfig as never,
|
||||
mockAddItem,
|
||||
),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.codingPlanUpdateRequest).toBeDefined();
|
||||
});
|
||||
|
||||
expect(result.current.codingPlanUpdateRequest?.prompt).toContain(
|
||||
globalConfig.regionName,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update execution', () => {
|
||||
it('should execute China region update when user confirms', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
mockSettings.merged.modelProviders = {
|
||||
[AuthType.USE_OPENAI]: [
|
||||
{
|
||||
id: 'test-model-china-1',
|
||||
baseUrl: CODING_PLAN_BASE_URL,
|
||||
baseUrl: chinaConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
},
|
||||
{
|
||||
|
|
@ -162,7 +201,7 @@ describe('useCodingPlanUpdates', () => {
|
|||
|
||||
// Wait for async update to complete
|
||||
await waitFor(() => {
|
||||
// Should update model providers (at least 2 calls: modelProviders + version)
|
||||
// Should update model providers (at least 2 calls: modelProviders + version + region)
|
||||
expect(mockSettings.setValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
@ -170,7 +209,14 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(mockSettings.setValue).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
'codingPlan.version',
|
||||
CODING_PLAN_VERSION,
|
||||
chinaConfig.version,
|
||||
);
|
||||
|
||||
// Should update region
|
||||
expect(mockSettings.setValue).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
'codingPlan.region',
|
||||
CodingPlanRegion.CHINA,
|
||||
);
|
||||
|
||||
// Should reload and refresh auth
|
||||
|
|
@ -181,20 +227,23 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'info',
|
||||
text: expect.stringContaining('Coding Plan'),
|
||||
text: expect.stringContaining(chinaConfig.regionName),
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
|
||||
it('should execute Global region update when user confirms', async () => {
|
||||
mockSettings.merged.codingPlan = { versionIntl: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.GLOBAL,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
mockSettings.merged.modelProviders = {
|
||||
[AuthType.USE_OPENAI]: [
|
||||
{
|
||||
id: 'test-model-global-1',
|
||||
baseUrl: CODING_PLAN_INTL_BASE_URL,
|
||||
envKey: CODING_PLAN_INTL_ENV_KEY,
|
||||
baseUrl: globalConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
},
|
||||
{
|
||||
id: 'custom-model',
|
||||
|
|
@ -225,11 +274,18 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(mockSettings.setValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Should update versionIntl with correct hash
|
||||
// Should update version with correct hash (single version field)
|
||||
expect(mockSettings.setValue).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
'codingPlan.versionIntl',
|
||||
CODING_PLAN_INTL_VERSION,
|
||||
'codingPlan.version',
|
||||
globalConfig.version,
|
||||
);
|
||||
|
||||
// Should update region
|
||||
expect(mockSettings.setValue).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
'codingPlan.region',
|
||||
CodingPlanRegion.GLOBAL,
|
||||
);
|
||||
|
||||
// Should reload and refresh auth
|
||||
|
|
@ -240,14 +296,17 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'info',
|
||||
text: expect.stringContaining('Global'),
|
||||
text: expect.stringContaining(globalConfig.regionName),
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not execute update when user declines', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
|
|
@ -269,17 +328,22 @@ describe('useCodingPlanUpdates', () => {
|
|||
expect(mockConfig.reloadModelProvidersConfig).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should only update configs for the specific region', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
const chinaConfig = {
|
||||
it('should replace all Coding Plan configs during update (mutually exclusive)', async () => {
|
||||
// Since regions are mutually exclusive, when updating one region,
|
||||
// all Coding Plan configs should be replaced (not preserving other region configs)
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
const chinaModelConfig = {
|
||||
id: 'test-model-china-1',
|
||||
baseUrl: CODING_PLAN_BASE_URL,
|
||||
baseUrl: chinaConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
};
|
||||
const globalConfig = {
|
||||
const globalModelConfig = {
|
||||
id: 'test-model-global-1',
|
||||
baseUrl: CODING_PLAN_INTL_BASE_URL,
|
||||
envKey: CODING_PLAN_INTL_ENV_KEY,
|
||||
baseUrl: globalConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
};
|
||||
const customConfig = {
|
||||
id: 'custom-model',
|
||||
|
|
@ -287,7 +351,11 @@ describe('useCodingPlanUpdates', () => {
|
|||
envKey: 'CUSTOM_API_KEY',
|
||||
};
|
||||
mockSettings.merged.modelProviders = {
|
||||
[AuthType.USE_OPENAI]: [chinaConfig, globalConfig, customConfig],
|
||||
[AuthType.USE_OPENAI]: [
|
||||
chinaModelConfig,
|
||||
globalModelConfig,
|
||||
customConfig,
|
||||
],
|
||||
};
|
||||
mockConfig.refreshAuth.mockResolvedValue(undefined);
|
||||
|
||||
|
|
@ -316,21 +384,21 @@ describe('useCodingPlanUpdates', () => {
|
|||
(call[1] as string).includes('modelProviders'),
|
||||
);
|
||||
|
||||
// Should preserve Global config and custom config, only update China configs
|
||||
expect(modelProvidersCall).toBeDefined();
|
||||
const updatedConfigs = modelProvidersCall![2] as Array<
|
||||
Record<string, unknown>
|
||||
>;
|
||||
|
||||
// Should have new China configs + preserved Global config + custom config
|
||||
expect(updatedConfigs.length).toBeGreaterThanOrEqual(3);
|
||||
// Should have new China configs + custom config only (global config removed since regions are mutually exclusive)
|
||||
// The template has 2 models, so we expect 2 (from template) + 1 (custom) = 3
|
||||
expect(updatedConfigs.length).toBe(3);
|
||||
|
||||
// Should contain the Global config (not modified)
|
||||
// Should NOT contain the Global config (mutually exclusive)
|
||||
expect(
|
||||
updatedConfigs.some(
|
||||
(c: Record<string, unknown>) => c['id'] === 'test-model-global-1',
|
||||
(c: Record<string, unknown>) => c['baseUrl'] === globalConfig.baseUrl,
|
||||
),
|
||||
).toBe(true);
|
||||
).toBe(false);
|
||||
|
||||
// Should contain the custom config
|
||||
expect(
|
||||
|
|
@ -339,13 +407,23 @@ describe('useCodingPlanUpdates', () => {
|
|||
),
|
||||
).toBe(true);
|
||||
|
||||
// All configs should use the unified env key
|
||||
updatedConfigs.forEach((config) => {
|
||||
if (config['envKey'] === CODING_PLAN_ENV_KEY) {
|
||||
expect(config['baseUrl']).toBe(chinaConfig.baseUrl);
|
||||
}
|
||||
});
|
||||
|
||||
// Should reload and refresh auth
|
||||
expect(mockConfig.reloadModelProvidersConfig).toHaveBeenCalled();
|
||||
expect(mockConfig.refreshAuth).toHaveBeenCalledWith(AuthType.USE_OPENAI);
|
||||
});
|
||||
|
||||
it('should preserve non-Coding Plan configs during update', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
const customConfig = {
|
||||
id: 'custom-model',
|
||||
baseUrl: 'https://custom.example.com',
|
||||
|
|
@ -355,7 +433,7 @@ describe('useCodingPlanUpdates', () => {
|
|||
[AuthType.USE_OPENAI]: [
|
||||
{
|
||||
id: 'test-model-china-1',
|
||||
baseUrl: CODING_PLAN_BASE_URL,
|
||||
baseUrl: chinaConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
},
|
||||
customConfig,
|
||||
|
|
@ -402,12 +480,15 @@ describe('useCodingPlanUpdates', () => {
|
|||
});
|
||||
|
||||
it('should handle update errors gracefully', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
mockSettings.merged.modelProviders = {
|
||||
[AuthType.USE_OPENAI]: [
|
||||
{
|
||||
id: 'test-model-china-1',
|
||||
baseUrl: CODING_PLAN_BASE_URL,
|
||||
baseUrl: chinaConfig.baseUrl,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
},
|
||||
],
|
||||
|
|
@ -443,7 +524,10 @@ describe('useCodingPlanUpdates', () => {
|
|||
|
||||
describe('dismissUpdate', () => {
|
||||
it('should clear update request when dismissed', async () => {
|
||||
mockSettings.merged.codingPlan = { version: 'old-version-hash' };
|
||||
mockSettings.merged.codingPlan = {
|
||||
region: CodingPlanRegion.CHINA,
|
||||
version: 'old-version-hash',
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useCodingPlanUpdates(
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@ import type { LoadedSettings } from '../../config/settings.js';
|
|||
import { getPersistScopeForModelSelection } from '../../config/modelProvidersScope.js';
|
||||
import {
|
||||
isCodingPlanConfig,
|
||||
CODING_PLAN_VERSION,
|
||||
CODING_PLAN_INTL_VERSION,
|
||||
getCodingPlanConfig,
|
||||
CodingPlanRegion,
|
||||
CODING_PLAN_ENV_KEY,
|
||||
} from '../../constants/codingPlan.js';
|
||||
import { t } from '../../i18n/index.js';
|
||||
|
||||
|
|
@ -43,7 +42,7 @@ export function useCodingPlanUpdates(
|
|||
/**
|
||||
* Execute the Coding Plan configuration update.
|
||||
* Removes old Coding Plan configs and replaces them with new ones from the template.
|
||||
* Automatically detects whether the user is using China or Intl version.
|
||||
* Uses the region from settings.codingPlan.region (defaults to CHINA).
|
||||
*/
|
||||
const executeUpdate = useCallback(
|
||||
async (region: CodingPlanRegion = CodingPlanRegion.CHINA) => {
|
||||
|
|
@ -58,24 +57,23 @@ export function useCodingPlanUpdates(
|
|||
| undefined
|
||||
)?.[AuthType.USE_OPENAI] || [];
|
||||
|
||||
// Filter out Coding Plan configs for the given region (keep user custom configs)
|
||||
// Filter out all Coding Plan configs (since they are mutually exclusive)
|
||||
// Keep only non-Coding-Plan user custom configs
|
||||
const nonCodingPlanConfigs = currentConfigs.filter(
|
||||
(cfg) =>
|
||||
!isCodingPlanConfig(
|
||||
cfg['baseUrl'] as string | undefined,
|
||||
cfg['envKey'] as string | undefined,
|
||||
region,
|
||||
),
|
||||
);
|
||||
|
||||
// Get the correct configuration based on region
|
||||
const codingPlanConfig = getCodingPlanConfig(region);
|
||||
const { template, envKey, version } = codingPlanConfig;
|
||||
// Get the configuration for the current region
|
||||
const { template, version, regionName } = getCodingPlanConfig(region);
|
||||
|
||||
// Generate new configs from template
|
||||
const newConfigs = template.map((templateConfig) => ({
|
||||
...templateConfig,
|
||||
envKey,
|
||||
envKey: CODING_PLAN_ENV_KEY,
|
||||
}));
|
||||
|
||||
// Combine: new Coding Plan configs at the front, user configs preserved
|
||||
|
|
@ -91,12 +89,11 @@ export function useCodingPlanUpdates(
|
|||
updatedConfigs,
|
||||
);
|
||||
|
||||
// Update the version with region-specific key
|
||||
const versionKey =
|
||||
region === CodingPlanRegion.GLOBAL
|
||||
? 'codingPlan.versionIntl'
|
||||
: 'codingPlan.version';
|
||||
settings.setValue(persistScope, versionKey, version);
|
||||
// Update the version (single version field for backward compatibility)
|
||||
settings.setValue(persistScope, 'codingPlan.version', version);
|
||||
|
||||
// Update the region
|
||||
settings.setValue(persistScope, 'codingPlan.region', region);
|
||||
|
||||
// Hot-reload model providers configuration
|
||||
const updatedModelProviders = {
|
||||
|
|
@ -112,16 +109,12 @@ export function useCodingPlanUpdates(
|
|||
// Refresh auth with the new configuration
|
||||
await config.refreshAuth(AuthType.USE_OPENAI);
|
||||
|
||||
const regionLabel =
|
||||
region === CodingPlanRegion.GLOBAL
|
||||
? 'Coding Plan (Global/Intl)'
|
||||
: 'Coding Plan';
|
||||
addItem(
|
||||
{
|
||||
type: 'info',
|
||||
text: t(
|
||||
'{{region}} configuration updated successfully. New models are now available.',
|
||||
{ region: regionLabel },
|
||||
{ region: regionName },
|
||||
),
|
||||
},
|
||||
Date.now(),
|
||||
|
|
@ -148,56 +141,46 @@ export function useCodingPlanUpdates(
|
|||
|
||||
/**
|
||||
* Check for version mismatch and prompt user for update if needed.
|
||||
* Uses the region from settings.codingPlan.region (defaults to CHINA if not set).
|
||||
*/
|
||||
const checkForUpdates = useCallback(() => {
|
||||
const mergedSettings = settings.merged as {
|
||||
codingPlan?: { version?: string; versionIntl?: string };
|
||||
codingPlan?: {
|
||||
version?: string;
|
||||
region?: CodingPlanRegion;
|
||||
};
|
||||
};
|
||||
|
||||
const savedChinaVersion = mergedSettings.codingPlan?.version;
|
||||
const savedIntlVersion = mergedSettings.codingPlan?.versionIntl;
|
||||
// Get the region (default to CHINA if not set)
|
||||
const region = mergedSettings.codingPlan?.region ?? CodingPlanRegion.CHINA;
|
||||
|
||||
// Determine which version the user is using based on saved version
|
||||
// Check China version first
|
||||
if (savedChinaVersion) {
|
||||
if (savedChinaVersion !== CODING_PLAN_VERSION) {
|
||||
// China version mismatch - prompt for update
|
||||
setUpdateRequest({
|
||||
prompt: t(
|
||||
'New model configurations are available for Bailian Coding Plan (China). Update now?',
|
||||
),
|
||||
onConfirm: async (confirmed: boolean) => {
|
||||
setUpdateRequest(undefined);
|
||||
if (confirmed) {
|
||||
await executeUpdate(CodingPlanRegion.CHINA);
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Intl version
|
||||
if (savedIntlVersion) {
|
||||
if (savedIntlVersion !== CODING_PLAN_INTL_VERSION) {
|
||||
// Intl version mismatch - prompt for update
|
||||
setUpdateRequest({
|
||||
prompt: t(
|
||||
'New model configurations are available for Coding Plan (Global/Intl). Update now?',
|
||||
),
|
||||
onConfirm: async (confirmed: boolean) => {
|
||||
setUpdateRequest(undefined);
|
||||
if (confirmed) {
|
||||
await executeUpdate(CodingPlanRegion.GLOBAL);
|
||||
}
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Get the saved version for the current region
|
||||
const savedVersion = mergedSettings.codingPlan?.version;
|
||||
|
||||
// If no version is stored, user hasn't used Coding Plan yet - skip check
|
||||
return;
|
||||
if (!savedVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current version for the region
|
||||
const currentVersion = getCodingPlanConfig(region).version;
|
||||
|
||||
// Check if version matches
|
||||
if (savedVersion !== currentVersion) {
|
||||
const { regionName } = getCodingPlanConfig(region);
|
||||
setUpdateRequest({
|
||||
prompt: t(
|
||||
'New model configurations are available for {{region}}. Update now?',
|
||||
{ region: regionName },
|
||||
),
|
||||
onConfirm: async (confirmed: boolean) => {
|
||||
setUpdateRequest(undefined);
|
||||
if (confirmed) {
|
||||
await executeUpdate(region);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [settings, executeUpdate]);
|
||||
|
||||
// Check for updates on mount
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue