From cb44445574a43179968656ade28bfce666973f9d Mon Sep 17 00:00:00 2001 From: Christiaan Arnoldus Date: Fri, 12 Sep 2025 11:00:01 +0200 Subject: [PATCH 1/3] Add coding plan support to Z.ai provider --- .changeset/grumpy-teeth-care.md | 5 +++++ src/api/providers/__tests__/zai.spec.ts | 12 ++++++++++-- src/api/providers/zai.ts | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 .changeset/grumpy-teeth-care.md diff --git a/.changeset/grumpy-teeth-care.md b/.changeset/grumpy-teeth-care.md new file mode 100644 index 00000000000..5398278ff24 --- /dev/null +++ b/.changeset/grumpy-teeth-care.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +The Z.ai provider now supports their coding plan (subscription) diff --git a/src/api/providers/__tests__/zai.spec.ts b/src/api/providers/__tests__/zai.spec.ts index 6882cfe448b..0465e49ba58 100644 --- a/src/api/providers/__tests__/zai.spec.ts +++ b/src/api/providers/__tests__/zai.spec.ts @@ -41,7 +41,11 @@ describe("ZAiHandler", () => { it("should use the correct international Z AI base URL", () => { new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international" }) - expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ baseURL: "https://api.z.ai/api/paas/v4" })) + expect(OpenAI).toHaveBeenCalledWith( + expect.objectContaining({ + baseURL: "https://api.z.ai/api/coding/paas/v4", // kilocode_change, upstream pr pending + }), + ) }) it("should use the provided API key for international", () => { @@ -109,7 +113,11 @@ describe("ZAiHandler", () => { describe("Default behavior", () => { it("should default to international when no zaiApiLine is specified", () => { const handlerDefault = new ZAiHandler({ zaiApiKey: "test-zai-api-key" }) - expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ baseURL: "https://api.z.ai/api/paas/v4" })) + expect(OpenAI).toHaveBeenCalledWith( + expect.objectContaining({ + baseURL: "https://api.z.ai/api/coding/paas/v4", // kilocode_change, upstream pr pending + }), + ) const model = handlerDefault.getModel() expect(model.id).toBe(internationalZAiDefaultModelId) diff --git a/src/api/providers/zai.ts b/src/api/providers/zai.ts index e37e37f01b4..dceec620b87 100644 --- a/src/api/providers/zai.ts +++ b/src/api/providers/zai.ts @@ -21,7 +21,7 @@ export class ZAiHandler extends BaseOpenAiCompatibleProvider Date: Mon, 15 Sep 2025 11:25:07 +0200 Subject: [PATCH 2/3] Allow users to change between the old and new base urls --- packages/types/src/provider-settings.ts | 6 +++- packages/types/src/providers/zai.ts | 14 ++++++++ src/api/providers/zai.ts | 5 +-- .../src/components/settings/providers/ZAi.tsx | 32 +++++++++++++------ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index c9d5c592eab..d819361c7a4 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -351,11 +351,15 @@ export const virtualQuotaFallbackProfileDataSchema = z.object({ const virtualQuotaFallbackSchema = baseProviderSettingsSchema.extend({ profiles: z.array(virtualQuotaFallbackProfileDataSchema).optional(), }) + +export const zaiApiLineSchema = z.enum(["international_coding", "international", "china_coding", "china"]) + +export type ZaiApiLine = z.infer // kilocode_change end const zaiSchema = apiModelIdProviderModelSchema.extend({ zaiApiKey: z.string().optional(), - zaiApiLine: z.union([z.literal("china"), z.literal("international")]).optional(), + zaiApiLine: zaiApiLineSchema.optional(), // kilocode_change }) const fireworksSchema = apiModelIdProviderModelSchema.extend({ diff --git a/packages/types/src/providers/zai.ts b/packages/types/src/providers/zai.ts index a65c5865770..c47ae36f270 100644 --- a/packages/types/src/providers/zai.ts +++ b/packages/types/src/providers/zai.ts @@ -1,4 +1,5 @@ import type { ModelInfo } from "../model.js" +import { ZaiApiLine } from "../provider-settings.js" // kilocode_change // Z AI // https://docs.z.ai/guides/llm/glm-4.5 @@ -125,3 +126,16 @@ export const mainlandZAiModels = { } as const satisfies Record export const ZAI_DEFAULT_TEMPERATURE = 0 + +// kilocode_change start +export const zaiApiLineConfigs = { + international_coding: { + name: "International Coding Plan", + 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 +// kilocode_change end diff --git a/src/api/providers/zai.ts b/src/api/providers/zai.ts index dceec620b87..5478db8c1a0 100644 --- a/src/api/providers/zai.ts +++ b/src/api/providers/zai.ts @@ -6,6 +6,7 @@ import { type InternationalZAiModelId, type MainlandZAiModelId, ZAI_DEFAULT_TEMPERATURE, + zaiApiLineConfigs, // kilocode_change } from "@roo-code/types" import type { ApiHandlerOptions } from "../../shared/api" @@ -14,14 +15,14 @@ import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider" export class ZAiHandler extends BaseOpenAiCompatibleProvider { constructor(options: ApiHandlerOptions) { - const isChina = options.zaiApiLine === "china" + const isChina = zaiApiLineConfigs[options.zaiApiLine ?? "international_coding"].isChina // kilocode_change const models = isChina ? mainlandZAiModels : internationalZAiModels const defaultModelId = isChina ? mainlandZAiDefaultModelId : internationalZAiDefaultModelId super({ ...options, providerName: "Z AI", - baseURL: isChina ? "https://open.bigmodel.cn/api/paas/v4" : "https://api.z.ai/api/coding/paas/v4", // kilocode_change, upstream pr pending + baseURL: zaiApiLineConfigs[options.zaiApiLine ?? "international_coding"].baseUrl, // kilocode_change apiKey: options.zaiApiKey ?? "not-provided", defaultProviderModelId: defaultModelId, providerModels: models, diff --git a/webview-ui/src/components/settings/providers/ZAi.tsx b/webview-ui/src/components/settings/providers/ZAi.tsx index bc23f28346a..06c72b6ac80 100644 --- a/webview-ui/src/components/settings/providers/ZAi.tsx +++ b/webview-ui/src/components/settings/providers/ZAi.tsx @@ -1,7 +1,13 @@ import { useCallback } from "react" import { VSCodeTextField, VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react" -import type { ProviderSettings } from "@roo-code/types" +import { + // kilocode_change start + zaiApiLineConfigs, + zaiApiLineSchema, + // kilocode_change end + type ProviderSettings, +} from "@roo-code/types" import { useAppTranslation } from "@src/i18n/TranslationContext" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" @@ -33,15 +39,23 @@ export const ZAi = ({ apiConfiguration, setApiConfigurationField }: ZAiProps) =>
- - api.z.ai - - - open.bigmodel.cn - + { + // kilocode_change start + zaiApiLineSchema.options.map((zaiApiLine) => { + const config = zaiApiLineConfigs[zaiApiLine] + return ( + + {config.name} ({config.baseUrl}) + + ) + }) + // kilocode_change end + }
{t("settings:providers.zaiEntrypointDescription")} @@ -62,7 +76,7 @@ export const ZAi = ({ apiConfiguration, setApiConfigurationField }: ZAiProps) => {!apiConfiguration?.zaiApiKey && ( Date: Mon, 15 Sep 2025 11:34:07 +0200 Subject: [PATCH 3/3] Fix test --- src/api/providers/__tests__/zai.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/providers/__tests__/zai.spec.ts b/src/api/providers/__tests__/zai.spec.ts index 0465e49ba58..a90cd5c436f 100644 --- a/src/api/providers/__tests__/zai.spec.ts +++ b/src/api/providers/__tests__/zai.spec.ts @@ -43,7 +43,7 @@ describe("ZAiHandler", () => { new ZAiHandler({ zaiApiKey: "test-zai-api-key", zaiApiLine: "international" }) expect(OpenAI).toHaveBeenCalledWith( expect.objectContaining({ - baseURL: "https://api.z.ai/api/coding/paas/v4", // kilocode_change, upstream pr pending + baseURL: "https://api.z.ai/api/paas/v4", }), ) })