diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index a66aae08a243..5262e7602d68 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -377,7 +377,7 @@ const sambaNovaSchema = apiModelIdProviderModelSchema.extend({ sambaNovaApiKey: z.string().optional(), }) -export const zaiApiLineSchema = z.enum(["international_coding", "international", "china_coding", "china"]) +export const zaiApiLineSchema = z.enum(["international_coding", "china_coding"]) export type ZaiApiLine = z.infer diff --git a/packages/types/src/providers/zai.ts b/packages/types/src/providers/zai.ts index de8c6cd4e493..f65ab63f456c 100644 --- a/packages/types/src/providers/zai.ts +++ b/packages/types/src/providers/zai.ts @@ -161,7 +161,5 @@ export const zaiApiLineConfigs = { baseUrl: "https://api.z.ai/api/coding/paas/v4", isChina: false, }, - international: { name: "International Standard", baseUrl: "https://api.z.ai/api/paas/v4", isChina: false }, china_coding: { name: "China Coding Plan", baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4", isChina: true }, - china: { name: "China Standard", baseUrl: "https://open.bigmodel.cn/api/paas/v4", isChina: true }, } satisfies Record diff --git a/src/api/providers/__tests__/zai.spec.ts b/src/api/providers/__tests__/zai.spec.ts index 383394b703c0..bb892960889f 100644 --- a/src/api/providers/__tests__/zai.spec.ts +++ b/src/api/providers/__tests__/zai.spec.ts @@ -36,21 +36,21 @@ describe("ZAiHandler", () => { describe("International Z AI", () => { beforeEach(() => { - handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international" }) + handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international_coding" }) }) it("should use the correct international Z AI base URL", () => { - new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international" }) + new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international_coding" }) expect(OpenAI).toHaveBeenCalledWith( expect.objectContaining({ - baseURL: "https://api.z.ai/api/paas/v4", + baseURL: "https://api.z.ai/api/coding/paas/v4", }), ) }) it("should use the provided API key for international", () => { const zaiApiKey = "test-zai-api-key" - new ZAiHandler({ zaiApiKey, zaiApiLine: "international" }) + new ZAiHandler({ zaiApiKey, zaiApiLine: "international_coding" }) expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ apiKey: zaiApiKey })) }) @@ -65,7 +65,7 @@ describe("ZAiHandler", () => { const handlerWithModel = new ZAiHandler({ apiModelId: testModelId, zaiApiKey: "test-zai-api-key", - zaiApiLine: "international", + zaiApiLine: "international_coding", }) const model = handlerWithModel.getModel() expect(model.id).toBe(testModelId) @@ -77,7 +77,7 @@ describe("ZAiHandler", () => { const handlerWithModel = new ZAiHandler({ apiModelId: testModelId, zaiApiKey: "test-zai-api-key", - zaiApiLine: "international", + zaiApiLine: "international_coding", }) const model = handlerWithModel.getModel() expect(model.id).toBe(testModelId) @@ -88,19 +88,19 @@ describe("ZAiHandler", () => { describe("China Z AI", () => { beforeEach(() => { - handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "china" }) + handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "china_coding" }) }) it("should use the correct China Z AI base URL", () => { - new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "china" }) + new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "china_coding" }) expect(OpenAI).toHaveBeenCalledWith( - expect.objectContaining({ baseURL: "https://open.bigmodel.cn/api/paas/v4" }), + expect.objectContaining({ baseURL: "https://open.bigmodel.cn/api/coding/paas/v4" }), ) }) it("should use the provided API key for China", () => { const zaiApiKey = "test-zai-api-key" - new ZAiHandler({ zaiApiKey, zaiApiLine: "china" }) + new ZAiHandler({ zaiApiKey, zaiApiLine: "china_coding" }) expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ apiKey: zaiApiKey })) }) @@ -115,7 +115,7 @@ describe("ZAiHandler", () => { const handlerWithModel = new ZAiHandler({ apiModelId: testModelId, zaiApiKey: "test-zai-api-key", - zaiApiLine: "china", + zaiApiLine: "china_coding", }) const model = handlerWithModel.getModel() expect(model.id).toBe(testModelId) @@ -127,7 +127,7 @@ describe("ZAiHandler", () => { const handlerWithModel = new ZAiHandler({ apiModelId: testModelId, zaiApiKey: "test-zai-api-key", - zaiApiLine: "china", + zaiApiLine: "china_coding", }) const model = handlerWithModel.getModel() expect(model.id).toBe(testModelId) @@ -151,14 +151,14 @@ describe("ZAiHandler", () => { }) it("should use 'not-provided' as default API key when none is specified", () => { - new ZAiHandler({ zaiApiLine: "international" }) + new ZAiHandler({ zaiApiLine: "international_coding" }) expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ apiKey: "not-provided" })) }) }) describe("API Methods", () => { beforeEach(() => { - handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international" }) + handler = new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international_coding" }) }) it("completePrompt method should return text from Z AI API", async () => { @@ -231,7 +231,7 @@ describe("ZAiHandler", () => { const handlerWithModel = new ZAiHandler({ apiModelId: modelId, zaiApiKey: "test-zai-api-key", - zaiApiLine: "international", + zaiApiLine: "international_coding", }) mockCreate.mockImplementationOnce(() => { diff --git a/src/core/config/ProviderSettingsManager.ts b/src/core/config/ProviderSettingsManager.ts index 357a04b33a41..1e57ef834198 100644 --- a/src/core/config/ProviderSettingsManager.ts +++ b/src/core/config/ProviderSettingsManager.ts @@ -46,6 +46,7 @@ export const providerProfilesSchema = z.object({ openAiHeadersMigrated: z.boolean().optional(), consecutiveMistakeLimitMigrated: z.boolean().optional(), todoListEnabledMigrated: z.boolean().optional(), + zaiApiLineMigrated: z.boolean().optional(), }) .optional(), }) @@ -70,6 +71,7 @@ export class ProviderSettingsManager { openAiHeadersMigrated: true, // Mark as migrated on fresh installs consecutiveMistakeLimitMigrated: true, // Mark as migrated on fresh installs todoListEnabledMigrated: true, // Mark as migrated on fresh installs + zaiApiLineMigrated: true, // Mark as migrated on fresh installs }, } @@ -142,6 +144,7 @@ export class ProviderSettingsManager { openAiHeadersMigrated: false, consecutiveMistakeLimitMigrated: false, todoListEnabledMigrated: false, + zaiApiLineMigrated: false, } // Initialize with default values isDirty = true } @@ -176,6 +179,12 @@ export class ProviderSettingsManager { isDirty = true } + if (!providerProfiles.migrations.zaiApiLineMigrated) { + await this.migrateZaiApiLine(providerProfiles) + providerProfiles.migrations.zaiApiLineMigrated = true + isDirty = true + } + if (isDirty) { await this.store(providerProfiles) } @@ -293,6 +302,24 @@ export class ProviderSettingsManager { } } + private async migrateZaiApiLine(providerProfiles: ProviderProfiles) { + try { + for (const [_name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) { + // Cast to any to access the zaiApiLine property which might exist + const configAny = apiConfig as any + + // Migrate old "international" and "china" values to new "international_coding" and "china_coding" + if (configAny.zaiApiLine === "international") { + configAny.zaiApiLine = "international_coding" + } else if (configAny.zaiApiLine === "china") { + configAny.zaiApiLine = "china_coding" + } + } + } catch (error) { + console.error(`[MigrateZaiApiLine] Failed to migrate Z AI API line settings:`, error) + } + } + /** * Apply model migrations for all providers * Returns true if any migrations were applied diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 4142796b668a..37c1c286b983 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -345,7 +345,7 @@ const ApiOptions = ({ zai: { field: "apiModelId", default: - apiConfiguration.zaiApiLine === "china" + apiConfiguration.zaiApiLine === "china_coding" ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId, }, diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 0d0514b4d667..a3ce1e63e4e1 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -238,7 +238,7 @@ function getSelectedModel({ return { id, info } } case "zai": { - const isChina = apiConfiguration.zaiApiLine === "china" + const isChina = apiConfiguration.zaiApiLine === "china_coding" const models = isChina ? mainlandZAiModels : internationalZAiModels const defaultModelId = isChina ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId const id = apiConfiguration.apiModelId ?? defaultModelId