feat(providers): add Z.AI/Zhipu GLM multi-configuration support
Add four distinct provider variants for GLM models: - zai: International pay-as-you-go (api.z.ai) - zai-coding: International Coding Plan (api.z.ai/coding) - zhipu: China pay-as-you-go (bigmodel.cn) - zhipu-coding: China Coding Plan (bigmodel.cn/coding) Includes: - Provider config functions with proper base URLs - GLM model definition (glm-4.7, 205K context) - Env var resolution with fallback chains - Provider ID normalization for aliases - Usage provider IDs and labels Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
parent
718bc3f9c8
commit
719ab3b4c5
@ -255,6 +255,20 @@ export function resolveEnvApiKey(provider: string): EnvApiKeyResult | null {
|
||||
return pick("ZAI_API_KEY") ?? pick("Z_AI_API_KEY");
|
||||
}
|
||||
|
||||
if (normalized === "zai-coding") {
|
||||
// Coding plan can use same key as general, just different endpoint
|
||||
return pick("ZAI_CODING_API_KEY") ?? pick("ZAI_API_KEY") ?? pick("Z_AI_API_KEY");
|
||||
}
|
||||
|
||||
if (normalized === "zhipu") {
|
||||
return pick("ZHIPU_API_KEY");
|
||||
}
|
||||
|
||||
if (normalized === "zhipu-coding") {
|
||||
// Coding plan can use same key as general, just different endpoint
|
||||
return pick("ZHIPU_CODING_API_KEY") ?? pick("ZHIPU_API_KEY");
|
||||
}
|
||||
|
||||
if (normalized === "google-vertex") {
|
||||
const envKey = getEnvApiKey(normalized);
|
||||
if (!envKey) return null;
|
||||
|
||||
@ -6,8 +6,15 @@ function isOpenAiCompletionsModel(model: Model<Api>): model is Model<"openai-com
|
||||
|
||||
export function normalizeModelCompat(model: Model<Api>): Model<Api> {
|
||||
const baseUrl = model.baseUrl ?? "";
|
||||
const isZai = model.provider === "zai" || baseUrl.includes("api.z.ai");
|
||||
if (!isZai || !isOpenAiCompletionsModel(model)) return model;
|
||||
// All GLM providers (Z.AI international and Zhipu AI China) share the same compatibility
|
||||
const isGlm =
|
||||
model.provider === "zai" ||
|
||||
model.provider === "zai-coding" ||
|
||||
model.provider === "zhipu" ||
|
||||
model.provider === "zhipu-coding" ||
|
||||
baseUrl.includes("api.z.ai") ||
|
||||
baseUrl.includes("bigmodel.cn");
|
||||
if (!isGlm || !isOpenAiCompletionsModel(model)) return model;
|
||||
|
||||
const openaiModel = model as Model<"openai-completions">;
|
||||
const compat = openaiModel.compat ?? undefined;
|
||||
|
||||
@ -26,7 +26,12 @@ export function modelKey(provider: string, model: string) {
|
||||
|
||||
export function normalizeProviderId(provider: string): string {
|
||||
const normalized = provider.trim().toLowerCase();
|
||||
// Z.AI international variants
|
||||
if (normalized === "z.ai" || normalized === "z-ai") return "zai";
|
||||
if (normalized === "z.ai-coding" || normalized === "z-ai-coding") return "zai-coding";
|
||||
// Zhipu AI (China) variants
|
||||
if (normalized === "zhipuai" || normalized === "zhipu-ai") return "zhipu";
|
||||
if (normalized === "zhipuai-coding" || normalized === "zhipu-ai-coding") return "zhipu-coding";
|
||||
if (normalized === "opencode-zen") return "opencode";
|
||||
if (normalized === "qwen") return "qwen-portal";
|
||||
return normalized;
|
||||
|
||||
@ -14,11 +14,22 @@ import type { MoltbotConfig } from "../config/config.js";
|
||||
import {
|
||||
OPENROUTER_DEFAULT_MODEL_REF,
|
||||
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
|
||||
ZAI_CODING_DEFAULT_MODEL_REF,
|
||||
ZAI_DEFAULT_MODEL_REF,
|
||||
ZHIPU_CODING_DEFAULT_MODEL_REF,
|
||||
ZHIPU_DEFAULT_MODEL_REF,
|
||||
} from "./onboard-auth.credentials.js";
|
||||
|
||||
// Z.AI / Zhipu AI base URLs
|
||||
export const ZAI_BASE_URL = "https://api.z.ai/api/paas/v4";
|
||||
export const ZAI_CODING_BASE_URL = "https://api.z.ai/api/coding/paas/v4";
|
||||
export const ZHIPU_BASE_URL = "https://open.bigmodel.cn/api/paas/v4";
|
||||
export const ZHIPU_CODING_BASE_URL = "https://open.bigmodel.cn/api/coding/paas/v4";
|
||||
import {
|
||||
buildGlmModelDefinition,
|
||||
buildKimiCodeModelDefinition,
|
||||
buildMoonshotModelDefinition,
|
||||
GLM_DEFAULT_MODEL_ID,
|
||||
KIMI_CODE_BASE_URL,
|
||||
KIMI_CODE_MODEL_ID,
|
||||
KIMI_CODE_MODEL_REF,
|
||||
@ -27,14 +38,33 @@ import {
|
||||
MOONSHOT_DEFAULT_MODEL_REF,
|
||||
} from "./onboard-auth.models.js";
|
||||
|
||||
export function applyZaiConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
export function applyZaiProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[ZAI_DEFAULT_MODEL_REF] = {
|
||||
...models[ZAI_DEFAULT_MODEL_REF],
|
||||
alias: models[ZAI_DEFAULT_MODEL_REF]?.alias ?? "GLM",
|
||||
};
|
||||
|
||||
const existingModel = cfg.agents?.defaults?.model;
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers.zai;
|
||||
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
|
||||
const defaultModel = buildGlmModelDefinition();
|
||||
const hasDefaultModel = existingModels.some((model) => model.id === GLM_DEFAULT_MODEL_ID);
|
||||
const mergedModels = hasDefaultModel ? existingModels : [...existingModels, defaultModel];
|
||||
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
|
||||
const normalizedApiKey = resolvedApiKey?.trim();
|
||||
providers.zai = {
|
||||
...existingProviderRest,
|
||||
baseUrl: ZAI_BASE_URL,
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : [defaultModel],
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
agents: {
|
||||
@ -42,6 +72,24 @@ export function applyZaiConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
defaults: {
|
||||
...cfg.agents?.defaults,
|
||||
models,
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: cfg.models?.mode ?? "merge",
|
||||
providers,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZaiConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const next = applyZaiProviderConfig(cfg);
|
||||
const existingModel = next.agents?.defaults?.model;
|
||||
return {
|
||||
...next,
|
||||
agents: {
|
||||
...next.agents,
|
||||
defaults: {
|
||||
...next.agents?.defaults,
|
||||
model: {
|
||||
...(existingModel && "fallbacks" in (existingModel as Record<string, unknown>)
|
||||
? {
|
||||
@ -55,6 +103,201 @@ export function applyZaiConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZaiCodingProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[ZAI_CODING_DEFAULT_MODEL_REF] = {
|
||||
...models[ZAI_CODING_DEFAULT_MODEL_REF],
|
||||
alias: models[ZAI_CODING_DEFAULT_MODEL_REF]?.alias ?? "GLM Coding",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers["zai-coding"];
|
||||
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
|
||||
const defaultModel = buildGlmModelDefinition();
|
||||
const hasDefaultModel = existingModels.some((model) => model.id === GLM_DEFAULT_MODEL_ID);
|
||||
const mergedModels = hasDefaultModel ? existingModels : [...existingModels, defaultModel];
|
||||
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
|
||||
const normalizedApiKey = resolvedApiKey?.trim();
|
||||
providers["zai-coding"] = {
|
||||
...existingProviderRest,
|
||||
baseUrl: ZAI_CODING_BASE_URL,
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : [defaultModel],
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
agents: {
|
||||
...cfg.agents,
|
||||
defaults: {
|
||||
...cfg.agents?.defaults,
|
||||
models,
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: cfg.models?.mode ?? "merge",
|
||||
providers,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZaiCodingConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const next = applyZaiCodingProviderConfig(cfg);
|
||||
const existingModel = next.agents?.defaults?.model;
|
||||
return {
|
||||
...next,
|
||||
agents: {
|
||||
...next.agents,
|
||||
defaults: {
|
||||
...next.agents?.defaults,
|
||||
model: {
|
||||
...(existingModel && "fallbacks" in (existingModel as Record<string, unknown>)
|
||||
? {
|
||||
fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks,
|
||||
}
|
||||
: undefined),
|
||||
primary: ZAI_CODING_DEFAULT_MODEL_REF,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZhipuProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[ZHIPU_DEFAULT_MODEL_REF] = {
|
||||
...models[ZHIPU_DEFAULT_MODEL_REF],
|
||||
alias: models[ZHIPU_DEFAULT_MODEL_REF]?.alias ?? "GLM",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers.zhipu;
|
||||
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
|
||||
const defaultModel = buildGlmModelDefinition();
|
||||
const hasDefaultModel = existingModels.some((model) => model.id === GLM_DEFAULT_MODEL_ID);
|
||||
const mergedModels = hasDefaultModel ? existingModels : [...existingModels, defaultModel];
|
||||
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
|
||||
const normalizedApiKey = resolvedApiKey?.trim();
|
||||
providers.zhipu = {
|
||||
...existingProviderRest,
|
||||
baseUrl: ZHIPU_BASE_URL,
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : [defaultModel],
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
agents: {
|
||||
...cfg.agents,
|
||||
defaults: {
|
||||
...cfg.agents?.defaults,
|
||||
models,
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: cfg.models?.mode ?? "merge",
|
||||
providers,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZhipuConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const next = applyZhipuProviderConfig(cfg);
|
||||
const existingModel = next.agents?.defaults?.model;
|
||||
return {
|
||||
...next,
|
||||
agents: {
|
||||
...next.agents,
|
||||
defaults: {
|
||||
...next.agents?.defaults,
|
||||
model: {
|
||||
...(existingModel && "fallbacks" in (existingModel as Record<string, unknown>)
|
||||
? {
|
||||
fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks,
|
||||
}
|
||||
: undefined),
|
||||
primary: ZHIPU_DEFAULT_MODEL_REF,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZhipuCodingProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[ZHIPU_CODING_DEFAULT_MODEL_REF] = {
|
||||
...models[ZHIPU_CODING_DEFAULT_MODEL_REF],
|
||||
alias: models[ZHIPU_CODING_DEFAULT_MODEL_REF]?.alias ?? "GLM Coding",
|
||||
};
|
||||
|
||||
const providers = { ...cfg.models?.providers };
|
||||
const existingProvider = providers["zhipu-coding"];
|
||||
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
|
||||
const defaultModel = buildGlmModelDefinition();
|
||||
const hasDefaultModel = existingModels.some((model) => model.id === GLM_DEFAULT_MODEL_ID);
|
||||
const mergedModels = hasDefaultModel ? existingModels : [...existingModels, defaultModel];
|
||||
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
> as { apiKey?: string };
|
||||
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
|
||||
const normalizedApiKey = resolvedApiKey?.trim();
|
||||
providers["zhipu-coding"] = {
|
||||
...existingProviderRest,
|
||||
baseUrl: ZHIPU_CODING_BASE_URL,
|
||||
api: "openai-completions",
|
||||
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
|
||||
models: mergedModels.length > 0 ? mergedModels : [defaultModel],
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg,
|
||||
agents: {
|
||||
...cfg.agents,
|
||||
defaults: {
|
||||
...cfg.agents?.defaults,
|
||||
models,
|
||||
},
|
||||
},
|
||||
models: {
|
||||
mode: cfg.models?.mode ?? "merge",
|
||||
providers,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyZhipuCodingConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const next = applyZhipuCodingProviderConfig(cfg);
|
||||
const existingModel = next.agents?.defaults?.model;
|
||||
return {
|
||||
...next,
|
||||
agents: {
|
||||
...next.agents,
|
||||
defaults: {
|
||||
...next.agents?.defaults,
|
||||
model: {
|
||||
...(existingModel && "fallbacks" in (existingModel as Record<string, unknown>)
|
||||
? {
|
||||
fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks,
|
||||
}
|
||||
: undefined),
|
||||
primary: ZHIPU_CODING_DEFAULT_MODEL_REF,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyOpenrouterProviderConfig(cfg: MoltbotConfig): MoltbotConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[OPENROUTER_DEFAULT_MODEL_REF] = {
|
||||
|
||||
@ -113,6 +113,9 @@ export async function setVeniceApiKey(key: string, agentDir?: string) {
|
||||
}
|
||||
|
||||
export const ZAI_DEFAULT_MODEL_REF = "zai/glm-4.7";
|
||||
export const ZAI_CODING_DEFAULT_MODEL_REF = "zai-coding/glm-4.7";
|
||||
export const ZHIPU_DEFAULT_MODEL_REF = "zhipu/glm-4.7";
|
||||
export const ZHIPU_CODING_DEFAULT_MODEL_REF = "zhipu-coding/glm-4.7";
|
||||
export const OPENROUTER_DEFAULT_MODEL_REF = "openrouter/auto";
|
||||
export const VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF = "vercel-ai-gateway/anthropic/claude-opus-4.5";
|
||||
|
||||
@ -129,6 +132,45 @@ export async function setZaiApiKey(key: string, agentDir?: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function setZaiCodingApiKey(key: string, agentDir?: string) {
|
||||
// Write to resolved agent dir so gateway finds credentials on startup.
|
||||
upsertAuthProfile({
|
||||
profileId: "zai-coding:default",
|
||||
credential: {
|
||||
type: "api_key",
|
||||
provider: "zai-coding",
|
||||
key,
|
||||
},
|
||||
agentDir: resolveAuthAgentDir(agentDir),
|
||||
});
|
||||
}
|
||||
|
||||
export async function setZhipuApiKey(key: string, agentDir?: string) {
|
||||
// Write to resolved agent dir so gateway finds credentials on startup.
|
||||
upsertAuthProfile({
|
||||
profileId: "zhipu:default",
|
||||
credential: {
|
||||
type: "api_key",
|
||||
provider: "zhipu",
|
||||
key,
|
||||
},
|
||||
agentDir: resolveAuthAgentDir(agentDir),
|
||||
});
|
||||
}
|
||||
|
||||
export async function setZhipuCodingApiKey(key: string, agentDir?: string) {
|
||||
// Write to resolved agent dir so gateway finds credentials on startup.
|
||||
upsertAuthProfile({
|
||||
profileId: "zhipu-coding:default",
|
||||
credential: {
|
||||
type: "api_key",
|
||||
provider: "zhipu-coding",
|
||||
key,
|
||||
},
|
||||
agentDir: resolveAuthAgentDir(agentDir),
|
||||
});
|
||||
}
|
||||
|
||||
export async function setOpenrouterApiKey(key: string, agentDir?: string) {
|
||||
upsertAuthProfile({
|
||||
profileId: "openrouter:default",
|
||||
|
||||
@ -20,6 +20,11 @@ export const KIMI_CODE_MAX_TOKENS = 32768;
|
||||
export const KIMI_CODE_HEADERS = { "User-Agent": "KimiCLI/0.77" } as const;
|
||||
export const KIMI_CODE_COMPAT = { supportsDeveloperRole: false } as const;
|
||||
|
||||
// GLM (Z.AI / Zhipu AI) models
|
||||
export const GLM_DEFAULT_MODEL_ID = "glm-4.7";
|
||||
export const GLM_DEFAULT_CONTEXT_WINDOW = 205000;
|
||||
export const GLM_DEFAULT_MAX_TOKENS = 8192;
|
||||
|
||||
// Pricing: MiniMax doesn't publish public rates. Override in models.json for accurate costs.
|
||||
export const MINIMAX_API_COST = {
|
||||
input: 15,
|
||||
@ -51,6 +56,12 @@ export const KIMI_CODE_DEFAULT_COST = {
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
};
|
||||
export const GLM_DEFAULT_COST = {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
};
|
||||
|
||||
const MINIMAX_MODEL_CATALOG = {
|
||||
"MiniMax-M2.1": { name: "MiniMax M2.1", reasoning: false },
|
||||
@ -116,3 +127,15 @@ export function buildKimiCodeModelDefinition(): ModelDefinitionConfig {
|
||||
compat: KIMI_CODE_COMPAT,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildGlmModelDefinition(): ModelDefinitionConfig {
|
||||
return {
|
||||
id: GLM_DEFAULT_MODEL_ID,
|
||||
name: "GLM 4.7",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: GLM_DEFAULT_COST,
|
||||
contextWindow: GLM_DEFAULT_CONTEXT_WINDOW,
|
||||
maxTokens: GLM_DEFAULT_MAX_TOKENS,
|
||||
};
|
||||
}
|
||||
|
||||
@ -17,7 +17,14 @@ export {
|
||||
applyVeniceProviderConfig,
|
||||
applyVercelAiGatewayConfig,
|
||||
applyVercelAiGatewayProviderConfig,
|
||||
applyZaiCodingConfig,
|
||||
applyZaiCodingProviderConfig,
|
||||
applyZaiConfig,
|
||||
applyZaiProviderConfig,
|
||||
applyZhipuCodingConfig,
|
||||
applyZhipuCodingProviderConfig,
|
||||
applyZhipuConfig,
|
||||
applyZhipuProviderConfig,
|
||||
} from "./onboard-auth.config-core.js";
|
||||
export {
|
||||
applyMinimaxApiConfig,
|
||||
@ -45,9 +52,15 @@ export {
|
||||
setVeniceApiKey,
|
||||
setVercelAiGatewayApiKey,
|
||||
setZaiApiKey,
|
||||
setZaiCodingApiKey,
|
||||
setZhipuApiKey,
|
||||
setZhipuCodingApiKey,
|
||||
writeOAuthCredentials,
|
||||
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
|
||||
ZAI_CODING_DEFAULT_MODEL_REF,
|
||||
ZAI_DEFAULT_MODEL_REF,
|
||||
ZHIPU_CODING_DEFAULT_MODEL_REF,
|
||||
ZHIPU_DEFAULT_MODEL_REF,
|
||||
} from "./onboard-auth.credentials.js";
|
||||
export {
|
||||
buildKimiCodeModelDefinition,
|
||||
|
||||
@ -10,7 +10,10 @@ export const PROVIDER_LABELS: Record<UsageProviderId, string> = {
|
||||
"google-antigravity": "Antigravity",
|
||||
minimax: "MiniMax",
|
||||
"openai-codex": "Codex",
|
||||
zai: "z.ai",
|
||||
zai: "Z.AI",
|
||||
"zai-coding": "Z.AI Coding",
|
||||
zhipu: "Zhipu AI",
|
||||
"zhipu-coding": "Zhipu AI Coding",
|
||||
};
|
||||
|
||||
export const usageProviders: UsageProviderId[] = [
|
||||
@ -21,6 +24,9 @@ export const usageProviders: UsageProviderId[] = [
|
||||
"minimax",
|
||||
"openai-codex",
|
||||
"zai",
|
||||
"zai-coding",
|
||||
"zhipu",
|
||||
"zhipu-coding",
|
||||
];
|
||||
|
||||
export function resolveUsageProviderId(provider?: string | null): UsageProviderId | undefined {
|
||||
|
||||
@ -24,4 +24,7 @@ export type UsageProviderId =
|
||||
| "google-antigravity"
|
||||
| "minimax"
|
||||
| "openai-codex"
|
||||
| "zai";
|
||||
| "zai"
|
||||
| "zai-coding"
|
||||
| "zhipu"
|
||||
| "zhipu-coding";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user