feat(ai): Add zAI provider support

- Add 'zai' as a KnownProvider type
- Add ZAI_API_KEY environment variable mapping
- Generate 4 zAI models (glm-4.5-air, glm-4.5v, etc.) using anthropic-messages API
- Add comprehensive test coverage for zAI provider in generate.test.ts and empty.test.ts
- Models support reasoning/thinking capabilities and tool calling
This commit is contained in:
Mario Zechner 2025-09-07 00:09:15 +02:00
parent 9230b83d94
commit d073953ef7
6 changed files with 299 additions and 26 deletions

View file

@ -106,6 +106,7 @@ export function getApiKey(provider: any): string | undefined {
cerebras: "CEREBRAS_API_KEY",
xai: "XAI_API_KEY",
openrouter: "OPENROUTER_API_KEY",
zai: "ZAI_API_KEY",
};
const envVar = envMap[provider];

View file

@ -946,6 +946,23 @@ export const MODELS = {
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"moonshotai/kimi-k2-instruct-0905": {
id: "moonshotai/kimi-k2-instruct-0905",
name: "Kimi K2 Instruct 0905",
api: "openai-completions",
provider: "groq",
baseUrl: "https://api.groq.com/openai/v1",
reasoning: false,
input: ["text"],
cost: {
input: 1,
output: 3,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"moonshotai/kimi-k2-instruct": {
id: "moonshotai/kimi-k2-instruct",
name: "Kimi K2 Instruct",
@ -1325,7 +1342,145 @@ export const MODELS = {
maxTokens: 8192,
} satisfies Model<"openai-completions">,
},
zai: {
"glm-4.5-air": {
id: "glm-4.5-air",
name: "GLM-4.5-Air",
api: "anthropic-messages",
provider: "zai",
baseUrl: "https://api.z.ai/api/anthropic",
reasoning: true,
input: ["text"],
cost: {
input: 0.2,
output: 1.1,
cacheRead: 0.03,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 98304,
} satisfies Model<"anthropic-messages">,
"glm-4.5v": {
id: "glm-4.5v",
name: "GLM 4.5V",
api: "anthropic-messages",
provider: "zai",
baseUrl: "https://api.z.ai/api/anthropic",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.6,
output: 1.8,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 64000,
maxTokens: 16384,
} satisfies Model<"anthropic-messages">,
"glm-4.5-flash": {
id: "glm-4.5-flash",
name: "GLM-4.5-Flash",
api: "anthropic-messages",
provider: "zai",
baseUrl: "https://api.z.ai/api/anthropic",
reasoning: true,
input: ["text"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 98304,
} satisfies Model<"anthropic-messages">,
"glm-4.5": {
id: "glm-4.5",
name: "GLM-4.5",
api: "anthropic-messages",
provider: "zai",
baseUrl: "https://api.z.ai/api/anthropic",
reasoning: true,
input: ["text"],
cost: {
input: 0.6,
output: 2.2,
cacheRead: 0.11,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 98304,
} satisfies Model<"anthropic-messages">,
},
openrouter: {
"openrouter/sonoma-dusk-alpha": {
id: "openrouter/sonoma-dusk-alpha",
name: "Sonoma Dusk Alpha",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text", "image"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 2000000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"openrouter/sonoma-sky-alpha": {
id: "openrouter/sonoma-sky-alpha",
name: "Sonoma Sky Alpha",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 2000000,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"qwen/qwen3-max": {
id: "qwen/qwen3-max",
name: "Qwen: Qwen3 Max",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 1.2,
output: 6,
cacheRead: 0.24,
cacheWrite: 0,
},
contextWindow: 256000,
maxTokens: 32768,
} satisfies Model<"openai-completions">,
"moonshotai/kimi-k2-0905": {
id: "moonshotai/kimi-k2-0905",
name: "MoonshotAI: Kimi K2 0905",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.2962,
output: 1.1852999999999998,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 262144,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"deepcogito/cogito-v2-preview-llama-109b-moe": {
id: "deepcogito/cogito-v2-preview-llama-109b-moe",
name: "Cogito V2 Preview Llama 109B",
@ -1343,6 +1498,23 @@ export const MODELS = {
contextWindow: 32767,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"stepfun-ai/step3": {
id: "stepfun-ai/step3",
name: "StepFun: Step3",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: true,
input: ["text", "image"],
cost: {
input: 0.5700000000000001,
output: 1.42,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 65536,
maxTokens: 65536,
} satisfies Model<"openai-completions">,
"qwen/qwen3-30b-a3b-thinking-2507": {
id: "qwen/qwen3-30b-a3b-thinking-2507",
name: "Qwen: Qwen3 30B A3B Thinking 2507",
@ -1685,7 +1857,7 @@ export const MODELS = {
} satisfies Model<"openai-completions">,
"moonshotai/kimi-k2:free": {
id: "moonshotai/kimi-k2:free",
name: "MoonshotAI: Kimi K2 (free)",
name: "MoonshotAI: Kimi K2 0711 (free)",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
@ -1702,7 +1874,7 @@ export const MODELS = {
} satisfies Model<"openai-completions">,
"moonshotai/kimi-k2": {
id: "moonshotai/kimi-k2",
name: "MoonshotAI: Kimi K2",
name: "MoonshotAI: Kimi K2 0711",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
@ -2236,12 +2408,12 @@ export const MODELS = {
reasoning: true,
input: ["text"],
cost: {
input: 0.075,
output: 0.15,
input: 0.15,
output: 0.39999999999999997,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
contextWindow: 32768,
maxTokens: 4096,
} satisfies Model<"openai-completions">,
"mistralai/mistral-saba": {
@ -2737,23 +2909,6 @@ export const MODELS = {
contextWindow: 32768,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-8b-instruct": {
id: "meta-llama/llama-3.1-8b-instruct",
name: "Meta: Llama 3.1 8B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.015,
output: 0.02,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-70b-instruct": {
id: "meta-llama/llama-3.1-70b-instruct",
name: "Meta: Llama 3.1 70B Instruct",
@ -2771,6 +2926,23 @@ export const MODELS = {
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"meta-llama/llama-3.1-8b-instruct": {
id: "meta-llama/llama-3.1-8b-instruct",
name: "Meta: Llama 3.1 8B Instruct",
api: "openai-completions",
provider: "openrouter",
baseUrl: "https://openrouter.ai/api/v1",
reasoning: false,
input: ["text"],
cost: {
input: 0.015,
output: 0.02,
cacheRead: 0,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 16384,
} satisfies Model<"openai-completions">,
"mistralai/mistral-nemo": {
id: "mistralai/mistral-nemo",
name: "Mistral: Mistral Nemo",

View file

@ -23,7 +23,7 @@ const _exhaustive: _CheckExhaustive = true;
// Helper type to get options for a specific API
export type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];
export type KnownProvider = "anthropic" | "google" | "openai" | "xai" | "groq" | "cerebras" | "openrouter";
export type KnownProvider = "anthropic" | "google" | "openai" | "xai" | "groq" | "cerebras" | "openrouter" | "zai";
export type Provider = KnownProvider | string;
export type ReasoningEffort = "minimal" | "low" | "medium" | "high";