Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/grumpy-teeth-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

The Z.ai provider now supports their coding plan (subscription)
6 changes: 5 additions & 1 deletion packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof zaiApiLineSchema>
// 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({
Expand Down
14 changes: 14 additions & 0 deletions packages/types/src/providers/zai.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -125,3 +126,16 @@ export const mainlandZAiModels = {
} as const satisfies Record<string, ModelInfo>

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<ZaiApiLine, { name: string; baseUrl: string; isChina: boolean }>
// kilocode_change end
12 changes: 10 additions & 2 deletions src/api/providers/__tests__/zai.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/paas/v4",
}),
)
})

it("should use the provided API key for international", () => {
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions src/api/providers/zai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -14,14 +15,14 @@ import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"

export class ZAiHandler extends BaseOpenAiCompatibleProvider<InternationalZAiModelId | MainlandZAiModelId> {
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/paas/v4",
baseURL: zaiApiLineConfigs[options.zaiApiLine ?? "international_coding"].baseUrl, // kilocode_change
apiKey: options.zaiApiKey ?? "not-provided",
defaultProviderModelId: defaultModelId,
providerModels: models,
Expand Down
32 changes: 23 additions & 9 deletions webview-ui/src/components/settings/providers/ZAi.tsx
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -33,15 +39,23 @@ export const ZAi = ({ apiConfiguration, setApiConfigurationField }: ZAiProps) =>
<div>
<label className="block font-medium mb-1">{t("settings:providers.zaiEntrypoint")}</label>
<VSCodeDropdown
value={apiConfiguration.zaiApiLine || "international"}
value={
apiConfiguration.zaiApiLine || zaiApiLineSchema.enum.international_coding /*kilocode_chance*/
}
onChange={handleInputChange("zaiApiLine")}
className={cn("w-full")}>
<VSCodeOption value="international" className="p-2">
api.z.ai
</VSCodeOption>
<VSCodeOption value="china" className="p-2">
open.bigmodel.cn
</VSCodeOption>
{
// kilocode_change start
zaiApiLineSchema.options.map((zaiApiLine) => {
const config = zaiApiLineConfigs[zaiApiLine]
return (
<VSCodeOption key={zaiApiLine} value={zaiApiLine} className="p-2">
{config.name} ({config.baseUrl})
</VSCodeOption>
)
})
// kilocode_change end
}
</VSCodeDropdown>
<div className="text-xs text-vscode-descriptionForeground mt-1">
{t("settings:providers.zaiEntrypointDescription")}
Expand All @@ -62,7 +76,7 @@ export const ZAi = ({ apiConfiguration, setApiConfigurationField }: ZAiProps) =>
{!apiConfiguration?.zaiApiKey && (
<VSCodeButtonLink
href={
apiConfiguration.zaiApiLine === "china"
zaiApiLineConfigs[apiConfiguration.zaiApiLine ?? "international_coding"].isChina // kilocode_change
? "https://open.bigmodel.cn/console/overview"
: "https://z.ai/manage-apikey/apikey-list"
}
Expand Down
Loading