@ai-sdk/zai 0.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # @ai-sdk/zai
2
+
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 5604dde: feat(zai): add the Z.AI provider with GLM chat completions, streaming, reasoning, tools, and multimodal inputs
8
+
9
+ ### Patch Changes
10
+
11
+ - ad28ecb: Backport: Add GLM-5.3-Flash model support to the Z.AI provider and AI Gateway.
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2023 Vercel, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md CHANGED
@@ -1,5 +1,47 @@
1
- # @ai-sdk/zai
1
+ # AI SDK - Z.AI Provider
2
2
 
3
- AI SDK provider for Z.ai.
3
+ The **Z.AI provider** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for [Z.AI](https://z.ai/) GLM models.
4
4
 
5
- The implementation is maintained in the `vercel/ai` repository.
5
+ > **Deploying to Vercel?** With Vercel's AI Gateway you can access Z.AI (and hundreds of models from other providers) without installing an additional provider package. [Get started with AI Gateway](https://vercel.com/ai-gateway).
6
+
7
+ ## Setup
8
+
9
+ Install the Z.AI provider with:
10
+
11
+ ```bash
12
+ npm i @ai-sdk/zai
13
+ ```
14
+
15
+ ## Provider Instance
16
+
17
+ Import the default provider instance from `@ai-sdk/zai`:
18
+
19
+ ```ts
20
+ import { zai } from '@ai-sdk/zai';
21
+ ```
22
+
23
+ The provider reads the API key from `ZAI_API_KEY` by default. To configure it explicitly, use `createZai`:
24
+
25
+ ```ts
26
+ import { createZai } from '@ai-sdk/zai';
27
+
28
+ const zai = createZai({
29
+ apiKey: process.env.ZAI_API_KEY,
30
+ });
31
+ ```
32
+
33
+ ## Language Models
34
+
35
+ ```ts
36
+ import { zai } from '@ai-sdk/zai';
37
+ import { generateText } from 'ai';
38
+
39
+ const { text } = await generateText({
40
+ model: zai('glm-5.3'),
41
+ prompt: 'Explain why the sky is blue.',
42
+ });
43
+
44
+ console.log(text);
45
+ ```
46
+
47
+ The provider supports streaming, reasoning, function tools, JSON object output, and URL-based image and video input on compatible GLM models.
@@ -0,0 +1,92 @@
1
+ import { z } from 'zod/v4';
2
+ import { ProviderV3, LanguageModelV3 } from '@ai-sdk/provider';
3
+ import { FetchFunction } from '@ai-sdk/provider-utils';
4
+
5
+ declare const zaiLanguageModelChatOptions: z.ZodObject<{
6
+ doSample: z.ZodOptional<z.ZodBoolean>;
7
+ thinking: z.ZodOptional<z.ZodObject<{
8
+ type: z.ZodOptional<z.ZodEnum<{
9
+ enabled: "enabled";
10
+ disabled: "disabled";
11
+ }>>;
12
+ clearThinking: z.ZodOptional<z.ZodBoolean>;
13
+ }, z.core.$strip>>;
14
+ reasoningEffort: z.ZodOptional<z.ZodEnum<{
15
+ none: "none";
16
+ minimal: "minimal";
17
+ low: "low";
18
+ medium: "medium";
19
+ high: "high";
20
+ xhigh: "xhigh";
21
+ max: "max";
22
+ }>>;
23
+ toolStream: z.ZodOptional<z.ZodBoolean>;
24
+ requestId: z.ZodOptional<z.ZodString>;
25
+ userId: z.ZodOptional<z.ZodString>;
26
+ }, z.core.$strip>;
27
+ type ZaiLanguageModelChatOptions = z.infer<typeof zaiLanguageModelChatOptions>;
28
+
29
+ /**
30
+ * Z.AI chat model ids from the official OpenAPI 1.0.0 specification,
31
+ * retrieved from https://docs.z.ai/openapi.json on 2026-08-26.
32
+ */
33
+ type ZaiChatModelId = 'glm-5.3' | 'glm-5.2' | 'glm-5.1' | 'glm-5-turbo' | 'glm-5' | 'glm-4.7' | 'glm-4.7-flash' | 'glm-4.7-flashx' | 'glm-4.6' | 'glm-4.5' | 'glm-4.5-air' | 'glm-4.5-x' | 'glm-4.5-airx' | 'glm-4.5-flash' | 'glm-4-32b-0414-128k' | 'glm-5.3-flash' | 'glm-5v-turbo' | 'glm-4.6v' | 'glm-4.6v-flash' | 'glm-4.6v-flashx' | 'glm-4.5v' | 'autoglm-phone-multilingual' | (string & {});
34
+
35
+ declare const zaiErrorSchema: z.ZodUnion<readonly [z.ZodObject<{
36
+ code: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
37
+ message: z.ZodString;
38
+ }, z.core.$strip>, z.ZodObject<{
39
+ error: z.ZodObject<{
40
+ code: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
41
+ message: z.ZodString;
42
+ }, z.core.$strip>;
43
+ }, z.core.$strip>]>;
44
+ type ZaiErrorData = z.infer<typeof zaiErrorSchema>;
45
+
46
+ interface ZaiProviderSettings {
47
+ /**
48
+ * Z.AI API key. Defaults to the `ZAI_API_KEY` environment variable.
49
+ */
50
+ apiKey?: string;
51
+ /**
52
+ * Base URL for API calls. Defaults to
53
+ * `https://api.z.ai/api/paas/v4`.
54
+ */
55
+ baseURL?: string;
56
+ /**
57
+ * Custom headers to include in requests.
58
+ */
59
+ headers?: Record<string, string>;
60
+ /**
61
+ * Custom fetch implementation.
62
+ */
63
+ fetch?: FetchFunction;
64
+ }
65
+ interface ZaiProvider extends ProviderV3 {
66
+ /**
67
+ * Creates a Z.AI chat model for text generation.
68
+ */
69
+ (modelId: ZaiChatModelId): LanguageModelV3;
70
+ /**
71
+ * Creates a Z.AI language model.
72
+ */
73
+ languageModel(modelId: ZaiChatModelId): LanguageModelV3;
74
+ /**
75
+ * Creates a Z.AI chat model.
76
+ */
77
+ chatModel(modelId: ZaiChatModelId): LanguageModelV3;
78
+ /**
79
+ * Creates a Z.AI chat model.
80
+ */
81
+ chat(modelId: ZaiChatModelId): LanguageModelV3;
82
+ /**
83
+ * @deprecated Use `embeddingModel` instead.
84
+ */
85
+ textEmbeddingModel(modelId: string): never;
86
+ }
87
+ declare function createZai(options?: ZaiProviderSettings): ZaiProvider;
88
+ declare const zai: ZaiProvider;
89
+
90
+ declare const VERSION: string;
91
+
92
+ export { VERSION, type ZaiChatModelId, type ZaiErrorData, type ZaiLanguageModelChatOptions, type ZaiProvider, type ZaiProviderSettings, createZai, zai };
package/dist/index.js ADDED
@@ -0,0 +1,250 @@
1
+ // src/zai-provider.ts
2
+ import {
3
+ NoSuchModelError
4
+ } from "@ai-sdk/provider";
5
+ import {
6
+ loadApiKey,
7
+ withoutTrailingSlash,
8
+ withUserAgentSuffix
9
+ } from "@ai-sdk/provider-utils";
10
+
11
+ // src/version.ts
12
+ var VERSION = true ? "2.0.0" : "0.0.0-test";
13
+
14
+ // src/zai-chat-language-model.ts
15
+ import { OpenAICompatibleChatLanguageModel } from "@ai-sdk/openai-compatible";
16
+ import {
17
+ parseProviderOptions
18
+ } from "@ai-sdk/provider-utils";
19
+
20
+ // src/zai-chat-language-model-options.ts
21
+ import { z } from "zod/v4";
22
+ var zaiLanguageModelChatOptions = z.object({
23
+ /**
24
+ * Enables or disables sampling. When disabled, temperature and topP do not
25
+ * take effect.
26
+ */
27
+ doSample: z.boolean().optional(),
28
+ /**
29
+ * Controls model thinking and whether reasoning from earlier turns is kept.
30
+ */
31
+ thinking: z.object({
32
+ type: z.enum(["enabled", "disabled"]).optional(),
33
+ clearThinking: z.boolean().optional()
34
+ }).optional(),
35
+ /**
36
+ * Controls reasoning effort for GLM-5.2 and later models.
37
+ */
38
+ reasoningEffort: z.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional(),
39
+ /**
40
+ * Enables incremental function-call argument streaming on supported models.
41
+ */
42
+ toolStream: z.boolean().optional(),
43
+ /**
44
+ * A caller-provided request identifier between 6 and 64 characters.
45
+ */
46
+ requestId: z.string().min(6).max(64).optional(),
47
+ /**
48
+ * A non-sensitive end-user identifier between 6 and 128 characters.
49
+ */
50
+ userId: z.string().min(6).max(128).optional()
51
+ });
52
+
53
+ // src/zai-error.ts
54
+ import { z as z2 } from "zod/v4";
55
+ var zaiErrorDetailsSchema = z2.object({
56
+ code: z2.union([z2.number(), z2.string()]).nullish(),
57
+ message: z2.string()
58
+ });
59
+ var zaiErrorSchema = z2.union([
60
+ zaiErrorDetailsSchema,
61
+ z2.object({ error: zaiErrorDetailsSchema })
62
+ ]);
63
+ var zaiErrorStructure = {
64
+ errorSchema: zaiErrorSchema,
65
+ errorToMessage: (data) => "error" in data ? data.error.message : data.message
66
+ };
67
+
68
+ // src/zai-chat-language-model.ts
69
+ function transformZaiRequestBody(args) {
70
+ const {
71
+ doSample,
72
+ frequency_penalty: _frequencyPenalty,
73
+ presence_penalty: _presencePenalty,
74
+ requestId,
75
+ seed: _seed,
76
+ thinking,
77
+ toolStream,
78
+ user: _user,
79
+ userId,
80
+ verbosity: _verbosity,
81
+ ...restArgs
82
+ } = args;
83
+ return {
84
+ ...restArgs,
85
+ ...doSample !== void 0 && { do_sample: doSample },
86
+ ...thinking !== void 0 && {
87
+ thinking: {
88
+ ...thinking.type !== void 0 && { type: thinking.type },
89
+ ...thinking.clearThinking !== void 0 && {
90
+ clear_thinking: thinking.clearThinking
91
+ }
92
+ }
93
+ },
94
+ ...toolStream !== void 0 && { tool_stream: toolStream },
95
+ ...requestId !== void 0 && { request_id: requestId },
96
+ ...userId !== void 0 && { user_id: userId }
97
+ };
98
+ }
99
+ function mapZaiFinishReason(finishReason) {
100
+ switch (finishReason.raw) {
101
+ case "sensitive":
102
+ return { unified: "content-filter", raw: finishReason.raw };
103
+ case "model_context_window_exceeded":
104
+ return { unified: "length", raw: finishReason.raw };
105
+ case "network_error":
106
+ return { unified: "error", raw: finishReason.raw };
107
+ default:
108
+ return finishReason;
109
+ }
110
+ }
111
+ var ZaiChatLanguageModel = class extends OpenAICompatibleChatLanguageModel {
112
+ constructor(modelId, config) {
113
+ const headers = config.headers;
114
+ super(modelId, {
115
+ provider: config.provider,
116
+ url: ({ path }) => `${config.baseURL}${path}`,
117
+ headers: () => headers == null ? {} : typeof headers === "function" ? headers() : headers,
118
+ fetch: config.fetch,
119
+ errorStructure: zaiErrorStructure,
120
+ transformRequestBody: transformZaiRequestBody,
121
+ supportedUrls: () => ({
122
+ "image/*": [/^https?:\/\//],
123
+ "video/*": [/^https?:\/\//]
124
+ })
125
+ });
126
+ }
127
+ async prepareCallOptions(options) {
128
+ const warnings = [];
129
+ const zaiOptions = await parseProviderOptions({
130
+ provider: "zai",
131
+ providerOptions: options.providerOptions,
132
+ schema: zaiLanguageModelChatOptions
133
+ });
134
+ if (options.frequencyPenalty != null) {
135
+ warnings.push({ type: "unsupported", feature: "frequencyPenalty" });
136
+ }
137
+ if (options.presencePenalty != null) {
138
+ warnings.push({ type: "unsupported", feature: "presencePenalty" });
139
+ }
140
+ if (options.seed != null) {
141
+ warnings.push({ type: "unsupported", feature: "seed" });
142
+ }
143
+ let tools = options.tools;
144
+ let toolChoice = options.toolChoice;
145
+ if ((toolChoice == null ? void 0 : toolChoice.type) === "none") {
146
+ tools = void 0;
147
+ toolChoice = void 0;
148
+ } else if (toolChoice != null && toolChoice.type !== "auto") {
149
+ warnings.push({
150
+ type: "unsupported",
151
+ feature: `toolChoice ${toolChoice.type}`,
152
+ details: "Z.AI currently supports only automatic tool selection."
153
+ });
154
+ toolChoice = void 0;
155
+ }
156
+ const normalizedOptions = {
157
+ ...options,
158
+ frequencyPenalty: void 0,
159
+ presencePenalty: void 0,
160
+ seed: void 0,
161
+ tools,
162
+ toolChoice,
163
+ providerOptions: zaiOptions == null ? options.providerOptions : {
164
+ ...options.providerOptions,
165
+ zai: zaiOptions
166
+ }
167
+ };
168
+ return { normalizedOptions, warnings };
169
+ }
170
+ async doGenerate(options) {
171
+ const { normalizedOptions, warnings } = await this.prepareCallOptions(options);
172
+ const result = await super.doGenerate(normalizedOptions);
173
+ return {
174
+ ...result,
175
+ finishReason: mapZaiFinishReason(result.finishReason),
176
+ warnings: [...result.warnings, ...warnings]
177
+ };
178
+ }
179
+ async doStream(options) {
180
+ const { normalizedOptions, warnings } = await this.prepareCallOptions(options);
181
+ const result = await super.doStream(normalizedOptions);
182
+ return {
183
+ ...result,
184
+ stream: result.stream.pipeThrough(
185
+ new TransformStream({
186
+ transform(part, controller) {
187
+ if (part.type === "stream-start") {
188
+ controller.enqueue({
189
+ ...part,
190
+ warnings: [...part.warnings, ...warnings]
191
+ });
192
+ return;
193
+ }
194
+ if (part.type === "finish") {
195
+ controller.enqueue({
196
+ ...part,
197
+ finishReason: mapZaiFinishReason(part.finishReason)
198
+ });
199
+ return;
200
+ }
201
+ controller.enqueue(part);
202
+ }
203
+ })
204
+ )
205
+ };
206
+ }
207
+ };
208
+
209
+ // src/zai-provider.ts
210
+ function createZai(options = {}) {
211
+ var _a;
212
+ const baseURL = (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : "https://api.z.ai/api/paas/v4";
213
+ const getHeaders = () => withUserAgentSuffix(
214
+ {
215
+ Authorization: `Bearer ${loadApiKey({
216
+ apiKey: options.apiKey,
217
+ environmentVariableName: "ZAI_API_KEY",
218
+ description: "Z.AI API key"
219
+ })}`,
220
+ ...options.headers
221
+ },
222
+ `ai-sdk/zai/${VERSION}`
223
+ );
224
+ const createLanguageModel = (modelId) => new ZaiChatLanguageModel(modelId, {
225
+ provider: "zai.chat",
226
+ baseURL,
227
+ headers: getHeaders,
228
+ fetch: options.fetch
229
+ });
230
+ const provider = (modelId) => createLanguageModel(modelId);
231
+ provider.specificationVersion = "v3";
232
+ provider.languageModel = createLanguageModel;
233
+ provider.chatModel = createLanguageModel;
234
+ provider.chat = createLanguageModel;
235
+ provider.embeddingModel = (modelId) => {
236
+ throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
237
+ };
238
+ provider.textEmbeddingModel = provider.embeddingModel;
239
+ provider.imageModel = (modelId) => {
240
+ throw new NoSuchModelError({ modelId, modelType: "imageModel" });
241
+ };
242
+ return provider;
243
+ }
244
+ var zai = createZai();
245
+ export {
246
+ VERSION,
247
+ createZai,
248
+ zai
249
+ };
250
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/zai-provider.ts","../src/version.ts","../src/zai-chat-language-model.ts","../src/zai-chat-language-model-options.ts","../src/zai-error.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type LanguageModelV3,\n type ProviderV3,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { VERSION } from './version';\nimport { ZaiChatLanguageModel } from './zai-chat-language-model';\nimport type { ZaiChatModelId } from './zai-chat-options';\n\nexport interface ZaiProviderSettings {\n /**\n * Z.AI API key. Defaults to the `ZAI_API_KEY` environment variable.\n */\n apiKey?: string;\n\n /**\n * Base URL for API calls. Defaults to\n * `https://api.z.ai/api/paas/v4`.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation.\n */\n fetch?: FetchFunction;\n}\n\nexport interface ZaiProvider extends ProviderV3 {\n /**\n * Creates a Z.AI chat model for text generation.\n */\n (modelId: ZaiChatModelId): LanguageModelV3;\n\n /**\n * Creates a Z.AI language model.\n */\n languageModel(modelId: ZaiChatModelId): LanguageModelV3;\n\n /**\n * Creates a Z.AI chat model.\n */\n chatModel(modelId: ZaiChatModelId): LanguageModelV3;\n\n /**\n * Creates a Z.AI chat model.\n */\n chat(modelId: ZaiChatModelId): LanguageModelV3;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n}\n\nexport function createZai(options: ZaiProviderSettings = {}): ZaiProvider {\n const baseURL =\n withoutTrailingSlash(options.baseURL) ?? 'https://api.z.ai/api/paas/v4';\n\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'ZAI_API_KEY',\n description: 'Z.AI API key',\n })}`,\n ...options.headers,\n },\n `ai-sdk/zai/${VERSION}`,\n );\n\n const createLanguageModel = (modelId: ZaiChatModelId) =>\n new ZaiChatLanguageModel(modelId, {\n provider: 'zai.chat',\n baseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const provider = (modelId: ZaiChatModelId) => createLanguageModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.languageModel = createLanguageModel;\n provider.chatModel = createLanguageModel;\n provider.chat = createLanguageModel;\n\n provider.embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });\n };\n provider.textEmbeddingModel = provider.embeddingModel;\n provider.imageModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n };\n\n return provider;\n}\n\nexport const zai = createZai();\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';\nimport type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3FinishReason,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamPart,\n LanguageModelV3StreamResult,\n SharedV3Warning,\n} from '@ai-sdk/provider';\nimport {\n parseProviderOptions,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport type { ZaiChatModelId } from './zai-chat-options';\nimport { zaiLanguageModelChatOptions } from './zai-chat-language-model-options';\nimport { zaiErrorStructure } from './zai-error';\n\nexport type ZaiChatConfig = {\n provider: string;\n baseURL: string;\n headers?:\n | Record<string, string | undefined>\n | (() => Record<string, string | undefined>);\n fetch?: FetchFunction;\n};\n\nfunction transformZaiRequestBody(\n args: Record<string, any>,\n): Record<string, any> {\n const {\n doSample,\n frequency_penalty: _frequencyPenalty,\n presence_penalty: _presencePenalty,\n requestId,\n seed: _seed,\n thinking,\n toolStream,\n user: _user,\n userId,\n verbosity: _verbosity,\n ...restArgs\n } = args;\n\n return {\n ...restArgs,\n ...(doSample !== undefined && { do_sample: doSample }),\n ...(thinking !== undefined && {\n thinking: {\n ...(thinking.type !== undefined && { type: thinking.type }),\n ...(thinking.clearThinking !== undefined && {\n clear_thinking: thinking.clearThinking,\n }),\n },\n }),\n ...(toolStream !== undefined && { tool_stream: toolStream }),\n ...(requestId !== undefined && { request_id: requestId }),\n ...(userId !== undefined && { user_id: userId }),\n };\n}\n\nfunction mapZaiFinishReason(\n finishReason: LanguageModelV3FinishReason,\n): LanguageModelV3FinishReason {\n switch (finishReason.raw) {\n case 'sensitive':\n return { unified: 'content-filter', raw: finishReason.raw };\n case 'model_context_window_exceeded':\n return { unified: 'length', raw: finishReason.raw };\n case 'network_error':\n return { unified: 'error', raw: finishReason.raw };\n default:\n return finishReason;\n }\n}\n\nexport class ZaiChatLanguageModel\n extends OpenAICompatibleChatLanguageModel\n implements LanguageModelV3\n{\n constructor(modelId: ZaiChatModelId, config: ZaiChatConfig) {\n const headers = config.headers;\n\n super(modelId, {\n provider: config.provider,\n url: ({ path }) => `${config.baseURL}${path}`,\n headers: () =>\n headers == null\n ? {}\n : typeof headers === 'function'\n ? headers()\n : headers,\n fetch: config.fetch,\n errorStructure: zaiErrorStructure,\n transformRequestBody: transformZaiRequestBody,\n supportedUrls: () => ({\n 'image/*': [/^https?:\\/\\//],\n 'video/*': [/^https?:\\/\\//],\n }),\n });\n }\n\n private async prepareCallOptions(options: LanguageModelV3CallOptions) {\n const warnings: SharedV3Warning[] = [];\n\n const zaiOptions = await parseProviderOptions({\n provider: 'zai',\n providerOptions: options.providerOptions,\n schema: zaiLanguageModelChatOptions,\n });\n\n if (options.frequencyPenalty != null) {\n warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });\n }\n if (options.presencePenalty != null) {\n warnings.push({ type: 'unsupported', feature: 'presencePenalty' });\n }\n if (options.seed != null) {\n warnings.push({ type: 'unsupported', feature: 'seed' });\n }\n\n let tools = options.tools;\n let toolChoice = options.toolChoice;\n\n if (toolChoice?.type === 'none') {\n tools = undefined;\n toolChoice = undefined;\n } else if (toolChoice != null && toolChoice.type !== 'auto') {\n warnings.push({\n type: 'unsupported',\n feature: `toolChoice ${toolChoice.type}`,\n details: 'Z.AI currently supports only automatic tool selection.',\n });\n toolChoice = undefined;\n }\n\n const normalizedOptions: LanguageModelV3CallOptions = {\n ...options,\n frequencyPenalty: undefined,\n presencePenalty: undefined,\n seed: undefined,\n tools,\n toolChoice,\n providerOptions:\n zaiOptions == null\n ? options.providerOptions\n : {\n ...options.providerOptions,\n zai: zaiOptions,\n },\n };\n\n return { normalizedOptions, warnings };\n }\n\n async doGenerate(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3GenerateResult> {\n const { normalizedOptions, warnings } =\n await this.prepareCallOptions(options);\n const result = await super.doGenerate(normalizedOptions);\n\n return {\n ...result,\n finishReason: mapZaiFinishReason(result.finishReason),\n warnings: [...result.warnings, ...warnings],\n };\n }\n\n async doStream(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3StreamResult> {\n const { normalizedOptions, warnings } =\n await this.prepareCallOptions(options);\n const result = await super.doStream(normalizedOptions);\n\n return {\n ...result,\n stream: result.stream.pipeThrough(\n new TransformStream<\n LanguageModelV3StreamPart,\n LanguageModelV3StreamPart\n >({\n transform(part, controller) {\n if (part.type === 'stream-start') {\n controller.enqueue({\n ...part,\n warnings: [...part.warnings, ...warnings],\n });\n return;\n }\n\n if (part.type === 'finish') {\n controller.enqueue({\n ...part,\n finishReason: mapZaiFinishReason(part.finishReason),\n });\n return;\n }\n\n controller.enqueue(part);\n },\n }),\n ),\n };\n }\n}\n","import { z } from 'zod/v4';\n\nexport const zaiLanguageModelChatOptions = z.object({\n /**\n * Enables or disables sampling. When disabled, temperature and topP do not\n * take effect.\n */\n doSample: z.boolean().optional(),\n\n /**\n * Controls model thinking and whether reasoning from earlier turns is kept.\n */\n thinking: z\n .object({\n type: z.enum(['enabled', 'disabled']).optional(),\n clearThinking: z.boolean().optional(),\n })\n .optional(),\n\n /**\n * Controls reasoning effort for GLM-5.2 and later models.\n */\n reasoningEffort: z\n .enum(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'])\n .optional(),\n\n /**\n * Enables incremental function-call argument streaming on supported models.\n */\n toolStream: z.boolean().optional(),\n\n /**\n * A caller-provided request identifier between 6 and 64 characters.\n */\n requestId: z.string().min(6).max(64).optional(),\n\n /**\n * A non-sensitive end-user identifier between 6 and 128 characters.\n */\n userId: z.string().min(6).max(128).optional(),\n});\n\nexport type ZaiLanguageModelChatOptions = z.infer<\n typeof zaiLanguageModelChatOptions\n>;\n","import type { ProviderErrorStructure } from '@ai-sdk/openai-compatible';\nimport { z } from 'zod/v4';\n\nconst zaiErrorDetailsSchema = z.object({\n code: z.union([z.number(), z.string()]).nullish(),\n message: z.string(),\n});\n\nconst zaiErrorSchema = z.union([\n zaiErrorDetailsSchema,\n z.object({ error: zaiErrorDetailsSchema }),\n]);\n\nexport type ZaiErrorData = z.infer<typeof zaiErrorSchema>;\n\nexport const zaiErrorStructure: ProviderErrorStructure<ZaiErrorData> = {\n errorSchema: zaiErrorSchema,\n errorToMessage: data => ('error' in data ? data.error.message : data.message),\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;;;ACRA,IAAM,UACX,OACI,UACA;;;ACLN,SAAS,yCAAyC;AAUlD;AAAA,EACE;AAAA,OAEK;;;ACbP,SAAS,SAAS;AAEX,IAAM,8BAA8B,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKlD,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAK/B,UAAU,EACP,OAAO;AAAA,IACN,MAAM,EAAE,KAAK,CAAC,WAAW,UAAU,CAAC,EAAE,SAAS;AAAA,IAC/C,eAAe,EAAE,QAAQ,EAAE,SAAS;AAAA,EACtC,CAAC,EACA,SAAS;AAAA;AAAA;AAAA;AAAA,EAKZ,iBAAiB,EACd,KAAK,CAAC,QAAQ,WAAW,OAAO,UAAU,QAAQ,SAAS,KAAK,CAAC,EACjE,SAAS;AAAA;AAAA;AAAA;AAAA,EAKZ,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAKjC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA;AAAA;AAAA;AAAA,EAK9C,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAC9C,CAAC;;;ACvCD,SAAS,KAAAA,UAAS;AAElB,IAAM,wBAAwBA,GAAE,OAAO;AAAA,EACrC,MAAMA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,CAAC,EAAE,QAAQ;AAAA,EAChD,SAASA,GAAE,OAAO;AACpB,CAAC;AAED,IAAM,iBAAiBA,GAAE,MAAM;AAAA,EAC7B;AAAA,EACAA,GAAE,OAAO,EAAE,OAAO,sBAAsB,CAAC;AAC3C,CAAC;AAIM,IAAM,oBAA0D;AAAA,EACrE,aAAa;AAAA,EACb,gBAAgB,UAAS,WAAW,OAAO,KAAK,MAAM,UAAU,KAAK;AACvE;;;AFSA,SAAS,wBACP,MACqB;AACrB,QAAM;AAAA,IACJ;AAAA,IACA,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,WAAW;AAAA,IACX,GAAG;AAAA,EACL,IAAI;AAEJ,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,aAAa,UAAa,EAAE,WAAW,SAAS;AAAA,IACpD,GAAI,aAAa,UAAa;AAAA,MAC5B,UAAU;AAAA,QACR,GAAI,SAAS,SAAS,UAAa,EAAE,MAAM,SAAS,KAAK;AAAA,QACzD,GAAI,SAAS,kBAAkB,UAAa;AAAA,UAC1C,gBAAgB,SAAS;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAAA,IACA,GAAI,eAAe,UAAa,EAAE,aAAa,WAAW;AAAA,IAC1D,GAAI,cAAc,UAAa,EAAE,YAAY,UAAU;AAAA,IACvD,GAAI,WAAW,UAAa,EAAE,SAAS,OAAO;AAAA,EAChD;AACF;AAEA,SAAS,mBACP,cAC6B;AAC7B,UAAQ,aAAa,KAAK;AAAA,IACxB,KAAK;AACH,aAAO,EAAE,SAAS,kBAAkB,KAAK,aAAa,IAAI;AAAA,IAC5D,KAAK;AACH,aAAO,EAAE,SAAS,UAAU,KAAK,aAAa,IAAI;AAAA,IACpD,KAAK;AACH,aAAO,EAAE,SAAS,SAAS,KAAK,aAAa,IAAI;AAAA,IACnD;AACE,aAAO;AAAA,EACX;AACF;AAEO,IAAM,uBAAN,cACG,kCAEV;AAAA,EACE,YAAY,SAAyB,QAAuB;AAC1D,UAAM,UAAU,OAAO;AAEvB,UAAM,SAAS;AAAA,MACb,UAAU,OAAO;AAAA,MACjB,KAAK,CAAC,EAAE,KAAK,MAAM,GAAG,OAAO,OAAO,GAAG,IAAI;AAAA,MAC3C,SAAS,MACP,WAAW,OACP,CAAC,IACD,OAAO,YAAY,aACjB,QAAQ,IACR;AAAA,MACR,OAAO,OAAO;AAAA,MACd,gBAAgB;AAAA,MAChB,sBAAsB;AAAA,MACtB,eAAe,OAAO;AAAA,QACpB,WAAW,CAAC,cAAc;AAAA,QAC1B,WAAW,CAAC,cAAc;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,mBAAmB,SAAqC;AACpE,UAAM,WAA8B,CAAC;AAErC,UAAM,aAAa,MAAM,qBAAqB;AAAA,MAC5C,UAAU;AAAA,MACV,iBAAiB,QAAQ;AAAA,MACzB,QAAQ;AAAA,IACV,CAAC;AAED,QAAI,QAAQ,oBAAoB,MAAM;AACpC,eAAS,KAAK,EAAE,MAAM,eAAe,SAAS,mBAAmB,CAAC;AAAA,IACpE;AACA,QAAI,QAAQ,mBAAmB,MAAM;AACnC,eAAS,KAAK,EAAE,MAAM,eAAe,SAAS,kBAAkB,CAAC;AAAA,IACnE;AACA,QAAI,QAAQ,QAAQ,MAAM;AACxB,eAAS,KAAK,EAAE,MAAM,eAAe,SAAS,OAAO,CAAC;AAAA,IACxD;AAEA,QAAI,QAAQ,QAAQ;AACpB,QAAI,aAAa,QAAQ;AAEzB,SAAI,yCAAY,UAAS,QAAQ;AAC/B,cAAQ;AACR,mBAAa;AAAA,IACf,WAAW,cAAc,QAAQ,WAAW,SAAS,QAAQ;AAC3D,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,SAAS,cAAc,WAAW,IAAI;AAAA,QACtC,SAAS;AAAA,MACX,CAAC;AACD,mBAAa;AAAA,IACf;AAEA,UAAM,oBAAgD;AAAA,MACpD,GAAG;AAAA,MACH,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,iBACE,cAAc,OACV,QAAQ,kBACR;AAAA,QACE,GAAG,QAAQ;AAAA,QACX,KAAK;AAAA,MACP;AAAA,IACR;AAEA,WAAO,EAAE,mBAAmB,SAAS;AAAA,EACvC;AAAA,EAEA,MAAM,WACJ,SACwC;AACxC,UAAM,EAAE,mBAAmB,SAAS,IAClC,MAAM,KAAK,mBAAmB,OAAO;AACvC,UAAM,SAAS,MAAM,MAAM,WAAW,iBAAiB;AAEvD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,cAAc,mBAAmB,OAAO,YAAY;AAAA,MACpD,UAAU,CAAC,GAAG,OAAO,UAAU,GAAG,QAAQ;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,SACsC;AACtC,UAAM,EAAE,mBAAmB,SAAS,IAClC,MAAM,KAAK,mBAAmB,OAAO;AACvC,UAAM,SAAS,MAAM,MAAM,SAAS,iBAAiB;AAErD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,OAAO,OAAO;AAAA,QACpB,IAAI,gBAGF;AAAA,UACA,UAAU,MAAM,YAAY;AAC1B,gBAAI,KAAK,SAAS,gBAAgB;AAChC,yBAAW,QAAQ;AAAA,gBACjB,GAAG;AAAA,gBACH,UAAU,CAAC,GAAG,KAAK,UAAU,GAAG,QAAQ;AAAA,cAC1C,CAAC;AACD;AAAA,YACF;AAEA,gBAAI,KAAK,SAAS,UAAU;AAC1B,yBAAW,QAAQ;AAAA,gBACjB,GAAG;AAAA,gBACH,cAAc,mBAAmB,KAAK,YAAY;AAAA,cACpD,CAAC;AACD;AAAA,YACF;AAEA,uBAAW,QAAQ,IAAI;AAAA,UACzB;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AF7IO,SAAS,UAAU,UAA+B,CAAC,GAAgB;AAjE1E;AAkEE,QAAM,WACJ,0BAAqB,QAAQ,OAAO,MAApC,YAAyC;AAE3C,QAAM,aAAa,MACjB;AAAA,IACE;AAAA,MACE,eAAe,UAAU,WAAW;AAAA,QAClC,QAAQ,QAAQ;AAAA,QAChB,yBAAyB;AAAA,QACzB,aAAa;AAAA,MACf,CAAC,CAAC;AAAA,MACF,GAAG,QAAQ;AAAA,IACb;AAAA,IACA,cAAc,OAAO;AAAA,EACvB;AAEF,QAAM,sBAAsB,CAAC,YAC3B,IAAI,qBAAqB,SAAS;AAAA,IAChC,UAAU;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT,OAAO,QAAQ;AAAA,EACjB,CAAC;AAEH,QAAM,WAAW,CAAC,YAA4B,oBAAoB,OAAO;AAEzE,WAAS,uBAAuB;AAChC,WAAS,gBAAgB;AACzB,WAAS,YAAY;AACrB,WAAS,OAAO;AAEhB,WAAS,iBAAiB,CAAC,YAAoB;AAC7C,UAAM,IAAI,iBAAiB,EAAE,SAAS,WAAW,iBAAiB,CAAC;AAAA,EACrE;AACA,WAAS,qBAAqB,SAAS;AACvC,WAAS,aAAa,CAAC,YAAoB;AACzC,UAAM,IAAI,iBAAiB,EAAE,SAAS,WAAW,aAAa,CAAC;AAAA,EACjE;AAEA,SAAO;AACT;AAEO,IAAM,MAAM,UAAU;","names":["z"]}
@@ -0,0 +1,159 @@
1
+ ---
2
+ title: Z.AI
3
+ description: Learn how to use Z.AI's GLM models with the AI SDK.
4
+ ---
5
+
6
+ # Z.AI Provider
7
+
8
+ The [Z.AI](https://z.ai/) provider gives you access to GLM language and vision models through the Z.AI API.
9
+
10
+ API keys can be created in the [Z.AI API key console](https://z.ai/manage-apikey/apikey-list).
11
+
12
+ ## Setup
13
+
14
+ The Z.AI provider is available through the `@ai-sdk/zai` package. Install it with:
15
+
16
+ <InstallPackages packages="@ai-sdk/zai" />
17
+
18
+ Set the `ZAI_API_KEY` environment variable:
19
+
20
+ ```bash
21
+ ZAI_API_KEY=your-api-key
22
+ ```
23
+
24
+ ## Provider Instance
25
+
26
+ Import the default provider instance `zai` from `@ai-sdk/zai`:
27
+
28
+ ```ts
29
+ import { zai } from '@ai-sdk/zai';
30
+ ```
31
+
32
+ For custom configuration, use `createZai`:
33
+
34
+ ```ts
35
+ import { createZai } from '@ai-sdk/zai';
36
+
37
+ const zai = createZai({
38
+ apiKey: process.env.ZAI_API_KEY,
39
+ baseURL: 'https://api.z.ai/api/paas/v4',
40
+ });
41
+ ```
42
+
43
+ The provider accepts these optional settings:
44
+
45
+ - **apiKey** _string_
46
+
47
+ API key sent in the `Authorization` header. It defaults to the `ZAI_API_KEY` environment variable.
48
+
49
+ - **baseURL** _string_
50
+
51
+ URL prefix for API requests. It defaults to `https://api.z.ai/api/paas/v4`.
52
+
53
+ - **headers** _Record&lt;string, string&gt;_
54
+
55
+ Additional request headers.
56
+
57
+ - **fetch** _FetchFunction_
58
+
59
+ Custom fetch implementation, for example to intercept requests in middleware.
60
+
61
+ ## Language Models
62
+
63
+ Create a language model by passing its model id to the provider:
64
+
65
+ ```ts
66
+ import { zai } from '@ai-sdk/zai';
67
+ import { generateText } from 'ai';
68
+
69
+ const { text } = await generateText({
70
+ model: zai('glm-5.3'),
71
+ prompt: 'Explain quantum entanglement in simple terms.',
72
+ });
73
+ ```
74
+
75
+ Current model families include GLM 5, GLM 4.7, GLM 4.6, GLM 4.5, and the GLM vision models. Model availability changes over time; see the [Z.AI model documentation](https://docs.z.ai/guides/llm) for the current catalog.
76
+
77
+ The provider supports:
78
+
79
+ - text generation and streaming
80
+ - reasoning output and reasoning history
81
+ - function calling, including incremental tool-call streaming
82
+ - JSON object output
83
+ - URL-based image and video inputs on compatible vision models
84
+
85
+ ## Provider Options
86
+
87
+ Z.AI-specific options can be passed through `providerOptions.zai`:
88
+
89
+ ```ts
90
+ import { zai } from '@ai-sdk/zai';
91
+ import { generateText } from 'ai';
92
+
93
+ const result = await generateText({
94
+ model: zai('glm-5.3'),
95
+ prompt: 'Compare two approaches to implementing a rate limiter.',
96
+ providerOptions: {
97
+ zai: {
98
+ thinking: { type: 'enabled', clearThinking: true },
99
+ reasoningEffort: 'high',
100
+ requestId: 'request-123456',
101
+ userId: 'user-123456',
102
+ },
103
+ },
104
+ });
105
+ ```
106
+
107
+ The following options are available:
108
+
109
+ - **doSample** _boolean_
110
+
111
+ Enables sampling. When disabled, `temperature` and `topP` do not take effect.
112
+
113
+ - **thinking** _object_
114
+
115
+ Controls thinking with `type: 'enabled' | 'disabled'`. Set `clearThinking` to `false` to retain reasoning from previous assistant messages.
116
+
117
+ - **reasoningEffort** _'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'_
118
+
119
+ Controls reasoning effort on supported models.
120
+
121
+ - **toolStream** _boolean_
122
+
123
+ Enables incremental function-call argument streaming on supported models.
124
+
125
+ - **requestId** _string_
126
+
127
+ A caller-provided request id between 6 and 64 characters.
128
+
129
+ - **userId** _string_
130
+
131
+ A non-sensitive end-user id between 6 and 128 characters.
132
+
133
+ ## Streaming Tool Calls
134
+
135
+ Enable `toolStream` when you want supported GLM models to stream function-call arguments incrementally:
136
+
137
+ ```ts
138
+ import { zai } from '@ai-sdk/zai';
139
+ import { streamText, tool } from 'ai';
140
+ import { z } from 'zod';
141
+
142
+ const result = streamText({
143
+ model: zai('glm-5.3'),
144
+ prompt: 'What is the weather in San Francisco?',
145
+ tools: {
146
+ weather: tool({
147
+ description: 'Get the weather for a city',
148
+ inputSchema: z.object({ city: z.string() }),
149
+ }),
150
+ },
151
+ providerOptions: {
152
+ zai: { toolStream: true },
153
+ },
154
+ });
155
+
156
+ for await (const part of result.fullStream) {
157
+ console.log(part);
158
+ }
159
+ ```
package/package.json CHANGED
@@ -1,23 +1,77 @@
1
1
  {
2
2
  "name": "@ai-sdk/zai",
3
- "version": "0.0.0",
4
- "description": "AI SDK provider for Z.ai",
5
- "license": "Apache-2.0",
3
+ "version": "2.0.0",
6
4
  "type": "module",
7
- "main": "./index.js",
8
- "exports": {
9
- ".": "./index.js"
10
- },
5
+ "license": "Apache-2.0",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
11
9
  "files": [
12
- "index.js",
10
+ "dist/**/*",
11
+ "docs/**/*",
12
+ "src",
13
+ "!src/**/*.test.ts",
14
+ "!src/**/*.test-d.ts",
15
+ "!src/**/__snapshots__",
16
+ "!src/**/__fixtures__",
17
+ "CHANGELOG.md",
13
18
  "README.md"
14
19
  ],
20
+ "directories": {
21
+ "doc": "./docs"
22
+ },
23
+ "exports": {
24
+ "./package.json": "./package.json",
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "dependencies": {
32
+ "@ai-sdk/openai-compatible": "2.0.72",
33
+ "@ai-sdk/provider": "3.0.15",
34
+ "@ai-sdk/provider-utils": "4.0.48"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "20.17.24",
38
+ "tsup": "^8",
39
+ "typescript": "5.8.3",
40
+ "zod": "3.25.76",
41
+ "@vercel/ai-tsconfig": "0.0.0"
42
+ },
43
+ "peerDependencies": {
44
+ "zod": "^3.25.76 || ^4.1.8"
45
+ },
46
+ "engines": {
47
+ "node": ">=18"
48
+ },
15
49
  "publishConfig": {
16
- "access": "public"
50
+ "access": "public",
51
+ "provenance": true
17
52
  },
53
+ "homepage": "https://ai-sdk.dev/docs",
18
54
  "repository": {
19
55
  "type": "git",
20
- "url": "git+https://github.com/vercel/ai.git",
56
+ "url": "https://github.com/vercel/ai",
21
57
  "directory": "packages/zai"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/vercel/ai/issues"
61
+ },
62
+ "keywords": [
63
+ "ai"
64
+ ],
65
+ "description": "The Z.AI provider for the AI SDK contains language model support for Z.AI's GLM models.",
66
+ "scripts": {
67
+ "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
68
+ "build:watch": "pnpm clean && tsup --watch",
69
+ "clean": "del-cli dist docs *.tsbuildinfo",
70
+ "type-check": "tsc --build",
71
+ "test": "pnpm test:node && pnpm test:edge",
72
+ "test:update": "pnpm test:node -u",
73
+ "test:watch": "vitest --config vitest.node.config.js",
74
+ "test:edge": "vitest --config vitest.edge.config.js --run",
75
+ "test:node": "vitest --config vitest.node.config.js --run"
22
76
  }
23
- }
77
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export type { ZaiLanguageModelChatOptions } from './zai-chat-language-model-options';
2
+ export type { ZaiChatModelId } from './zai-chat-options';
3
+ export type { ZaiErrorData } from './zai-error';
4
+ export { createZai, zai } from './zai-provider';
5
+ export type { ZaiProvider, ZaiProviderSettings } from './zai-provider';
6
+ export { VERSION } from './version';
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod/v4';
2
+
3
+ export const zaiLanguageModelChatOptions = z.object({
4
+ /**
5
+ * Enables or disables sampling. When disabled, temperature and topP do not
6
+ * take effect.
7
+ */
8
+ doSample: z.boolean().optional(),
9
+
10
+ /**
11
+ * Controls model thinking and whether reasoning from earlier turns is kept.
12
+ */
13
+ thinking: z
14
+ .object({
15
+ type: z.enum(['enabled', 'disabled']).optional(),
16
+ clearThinking: z.boolean().optional(),
17
+ })
18
+ .optional(),
19
+
20
+ /**
21
+ * Controls reasoning effort for GLM-5.2 and later models.
22
+ */
23
+ reasoningEffort: z
24
+ .enum(['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'])
25
+ .optional(),
26
+
27
+ /**
28
+ * Enables incremental function-call argument streaming on supported models.
29
+ */
30
+ toolStream: z.boolean().optional(),
31
+
32
+ /**
33
+ * A caller-provided request identifier between 6 and 64 characters.
34
+ */
35
+ requestId: z.string().min(6).max(64).optional(),
36
+
37
+ /**
38
+ * A non-sensitive end-user identifier between 6 and 128 characters.
39
+ */
40
+ userId: z.string().min(6).max(128).optional(),
41
+ });
42
+
43
+ export type ZaiLanguageModelChatOptions = z.infer<
44
+ typeof zaiLanguageModelChatOptions
45
+ >;
@@ -0,0 +1,207 @@
1
+ import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';
2
+ import type {
3
+ LanguageModelV3,
4
+ LanguageModelV3CallOptions,
5
+ LanguageModelV3FinishReason,
6
+ LanguageModelV3GenerateResult,
7
+ LanguageModelV3StreamPart,
8
+ LanguageModelV3StreamResult,
9
+ SharedV3Warning,
10
+ } from '@ai-sdk/provider';
11
+ import {
12
+ parseProviderOptions,
13
+ type FetchFunction,
14
+ } from '@ai-sdk/provider-utils';
15
+ import type { ZaiChatModelId } from './zai-chat-options';
16
+ import { zaiLanguageModelChatOptions } from './zai-chat-language-model-options';
17
+ import { zaiErrorStructure } from './zai-error';
18
+
19
+ export type ZaiChatConfig = {
20
+ provider: string;
21
+ baseURL: string;
22
+ headers?:
23
+ | Record<string, string | undefined>
24
+ | (() => Record<string, string | undefined>);
25
+ fetch?: FetchFunction;
26
+ };
27
+
28
+ function transformZaiRequestBody(
29
+ args: Record<string, any>,
30
+ ): Record<string, any> {
31
+ const {
32
+ doSample,
33
+ frequency_penalty: _frequencyPenalty,
34
+ presence_penalty: _presencePenalty,
35
+ requestId,
36
+ seed: _seed,
37
+ thinking,
38
+ toolStream,
39
+ user: _user,
40
+ userId,
41
+ verbosity: _verbosity,
42
+ ...restArgs
43
+ } = args;
44
+
45
+ return {
46
+ ...restArgs,
47
+ ...(doSample !== undefined && { do_sample: doSample }),
48
+ ...(thinking !== undefined && {
49
+ thinking: {
50
+ ...(thinking.type !== undefined && { type: thinking.type }),
51
+ ...(thinking.clearThinking !== undefined && {
52
+ clear_thinking: thinking.clearThinking,
53
+ }),
54
+ },
55
+ }),
56
+ ...(toolStream !== undefined && { tool_stream: toolStream }),
57
+ ...(requestId !== undefined && { request_id: requestId }),
58
+ ...(userId !== undefined && { user_id: userId }),
59
+ };
60
+ }
61
+
62
+ function mapZaiFinishReason(
63
+ finishReason: LanguageModelV3FinishReason,
64
+ ): LanguageModelV3FinishReason {
65
+ switch (finishReason.raw) {
66
+ case 'sensitive':
67
+ return { unified: 'content-filter', raw: finishReason.raw };
68
+ case 'model_context_window_exceeded':
69
+ return { unified: 'length', raw: finishReason.raw };
70
+ case 'network_error':
71
+ return { unified: 'error', raw: finishReason.raw };
72
+ default:
73
+ return finishReason;
74
+ }
75
+ }
76
+
77
+ export class ZaiChatLanguageModel
78
+ extends OpenAICompatibleChatLanguageModel
79
+ implements LanguageModelV3
80
+ {
81
+ constructor(modelId: ZaiChatModelId, config: ZaiChatConfig) {
82
+ const headers = config.headers;
83
+
84
+ super(modelId, {
85
+ provider: config.provider,
86
+ url: ({ path }) => `${config.baseURL}${path}`,
87
+ headers: () =>
88
+ headers == null
89
+ ? {}
90
+ : typeof headers === 'function'
91
+ ? headers()
92
+ : headers,
93
+ fetch: config.fetch,
94
+ errorStructure: zaiErrorStructure,
95
+ transformRequestBody: transformZaiRequestBody,
96
+ supportedUrls: () => ({
97
+ 'image/*': [/^https?:\/\//],
98
+ 'video/*': [/^https?:\/\//],
99
+ }),
100
+ });
101
+ }
102
+
103
+ private async prepareCallOptions(options: LanguageModelV3CallOptions) {
104
+ const warnings: SharedV3Warning[] = [];
105
+
106
+ const zaiOptions = await parseProviderOptions({
107
+ provider: 'zai',
108
+ providerOptions: options.providerOptions,
109
+ schema: zaiLanguageModelChatOptions,
110
+ });
111
+
112
+ if (options.frequencyPenalty != null) {
113
+ warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
114
+ }
115
+ if (options.presencePenalty != null) {
116
+ warnings.push({ type: 'unsupported', feature: 'presencePenalty' });
117
+ }
118
+ if (options.seed != null) {
119
+ warnings.push({ type: 'unsupported', feature: 'seed' });
120
+ }
121
+
122
+ let tools = options.tools;
123
+ let toolChoice = options.toolChoice;
124
+
125
+ if (toolChoice?.type === 'none') {
126
+ tools = undefined;
127
+ toolChoice = undefined;
128
+ } else if (toolChoice != null && toolChoice.type !== 'auto') {
129
+ warnings.push({
130
+ type: 'unsupported',
131
+ feature: `toolChoice ${toolChoice.type}`,
132
+ details: 'Z.AI currently supports only automatic tool selection.',
133
+ });
134
+ toolChoice = undefined;
135
+ }
136
+
137
+ const normalizedOptions: LanguageModelV3CallOptions = {
138
+ ...options,
139
+ frequencyPenalty: undefined,
140
+ presencePenalty: undefined,
141
+ seed: undefined,
142
+ tools,
143
+ toolChoice,
144
+ providerOptions:
145
+ zaiOptions == null
146
+ ? options.providerOptions
147
+ : {
148
+ ...options.providerOptions,
149
+ zai: zaiOptions,
150
+ },
151
+ };
152
+
153
+ return { normalizedOptions, warnings };
154
+ }
155
+
156
+ async doGenerate(
157
+ options: LanguageModelV3CallOptions,
158
+ ): Promise<LanguageModelV3GenerateResult> {
159
+ const { normalizedOptions, warnings } =
160
+ await this.prepareCallOptions(options);
161
+ const result = await super.doGenerate(normalizedOptions);
162
+
163
+ return {
164
+ ...result,
165
+ finishReason: mapZaiFinishReason(result.finishReason),
166
+ warnings: [...result.warnings, ...warnings],
167
+ };
168
+ }
169
+
170
+ async doStream(
171
+ options: LanguageModelV3CallOptions,
172
+ ): Promise<LanguageModelV3StreamResult> {
173
+ const { normalizedOptions, warnings } =
174
+ await this.prepareCallOptions(options);
175
+ const result = await super.doStream(normalizedOptions);
176
+
177
+ return {
178
+ ...result,
179
+ stream: result.stream.pipeThrough(
180
+ new TransformStream<
181
+ LanguageModelV3StreamPart,
182
+ LanguageModelV3StreamPart
183
+ >({
184
+ transform(part, controller) {
185
+ if (part.type === 'stream-start') {
186
+ controller.enqueue({
187
+ ...part,
188
+ warnings: [...part.warnings, ...warnings],
189
+ });
190
+ return;
191
+ }
192
+
193
+ if (part.type === 'finish') {
194
+ controller.enqueue({
195
+ ...part,
196
+ finishReason: mapZaiFinishReason(part.finishReason),
197
+ });
198
+ return;
199
+ }
200
+
201
+ controller.enqueue(part);
202
+ },
203
+ }),
204
+ ),
205
+ };
206
+ }
207
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Z.AI chat model ids from the official OpenAPI 1.0.0 specification,
3
+ * retrieved from https://docs.z.ai/openapi.json on 2026-08-26.
4
+ */
5
+ export type ZaiChatModelId =
6
+ | 'glm-5.3'
7
+ | 'glm-5.2'
8
+ | 'glm-5.1'
9
+ | 'glm-5-turbo'
10
+ | 'glm-5'
11
+ | 'glm-4.7'
12
+ | 'glm-4.7-flash'
13
+ | 'glm-4.7-flashx'
14
+ | 'glm-4.6'
15
+ | 'glm-4.5'
16
+ | 'glm-4.5-air'
17
+ | 'glm-4.5-x'
18
+ | 'glm-4.5-airx'
19
+ | 'glm-4.5-flash'
20
+ | 'glm-4-32b-0414-128k'
21
+ | 'glm-5.3-flash'
22
+ | 'glm-5v-turbo'
23
+ | 'glm-4.6v'
24
+ | 'glm-4.6v-flash'
25
+ | 'glm-4.6v-flashx'
26
+ | 'glm-4.5v'
27
+ | 'autoglm-phone-multilingual'
28
+ | (string & {});
@@ -0,0 +1,19 @@
1
+ import type { ProviderErrorStructure } from '@ai-sdk/openai-compatible';
2
+ import { z } from 'zod/v4';
3
+
4
+ const zaiErrorDetailsSchema = z.object({
5
+ code: z.union([z.number(), z.string()]).nullish(),
6
+ message: z.string(),
7
+ });
8
+
9
+ const zaiErrorSchema = z.union([
10
+ zaiErrorDetailsSchema,
11
+ z.object({ error: zaiErrorDetailsSchema }),
12
+ ]);
13
+
14
+ export type ZaiErrorData = z.infer<typeof zaiErrorSchema>;
15
+
16
+ export const zaiErrorStructure: ProviderErrorStructure<ZaiErrorData> = {
17
+ errorSchema: zaiErrorSchema,
18
+ errorToMessage: data => ('error' in data ? data.error.message : data.message),
19
+ };
@@ -0,0 +1,109 @@
1
+ import {
2
+ NoSuchModelError,
3
+ type LanguageModelV3,
4
+ type ProviderV3,
5
+ } from '@ai-sdk/provider';
6
+ import {
7
+ loadApiKey,
8
+ withoutTrailingSlash,
9
+ withUserAgentSuffix,
10
+ type FetchFunction,
11
+ } from '@ai-sdk/provider-utils';
12
+ import { VERSION } from './version';
13
+ import { ZaiChatLanguageModel } from './zai-chat-language-model';
14
+ import type { ZaiChatModelId } from './zai-chat-options';
15
+
16
+ export interface ZaiProviderSettings {
17
+ /**
18
+ * Z.AI API key. Defaults to the `ZAI_API_KEY` environment variable.
19
+ */
20
+ apiKey?: string;
21
+
22
+ /**
23
+ * Base URL for API calls. Defaults to
24
+ * `https://api.z.ai/api/paas/v4`.
25
+ */
26
+ baseURL?: string;
27
+
28
+ /**
29
+ * Custom headers to include in requests.
30
+ */
31
+ headers?: Record<string, string>;
32
+
33
+ /**
34
+ * Custom fetch implementation.
35
+ */
36
+ fetch?: FetchFunction;
37
+ }
38
+
39
+ export interface ZaiProvider extends ProviderV3 {
40
+ /**
41
+ * Creates a Z.AI chat model for text generation.
42
+ */
43
+ (modelId: ZaiChatModelId): LanguageModelV3;
44
+
45
+ /**
46
+ * Creates a Z.AI language model.
47
+ */
48
+ languageModel(modelId: ZaiChatModelId): LanguageModelV3;
49
+
50
+ /**
51
+ * Creates a Z.AI chat model.
52
+ */
53
+ chatModel(modelId: ZaiChatModelId): LanguageModelV3;
54
+
55
+ /**
56
+ * Creates a Z.AI chat model.
57
+ */
58
+ chat(modelId: ZaiChatModelId): LanguageModelV3;
59
+
60
+ /**
61
+ * @deprecated Use `embeddingModel` instead.
62
+ */
63
+ textEmbeddingModel(modelId: string): never;
64
+ }
65
+
66
+ export function createZai(options: ZaiProviderSettings = {}): ZaiProvider {
67
+ const baseURL =
68
+ withoutTrailingSlash(options.baseURL) ?? 'https://api.z.ai/api/paas/v4';
69
+
70
+ const getHeaders = () =>
71
+ withUserAgentSuffix(
72
+ {
73
+ Authorization: `Bearer ${loadApiKey({
74
+ apiKey: options.apiKey,
75
+ environmentVariableName: 'ZAI_API_KEY',
76
+ description: 'Z.AI API key',
77
+ })}`,
78
+ ...options.headers,
79
+ },
80
+ `ai-sdk/zai/${VERSION}`,
81
+ );
82
+
83
+ const createLanguageModel = (modelId: ZaiChatModelId) =>
84
+ new ZaiChatLanguageModel(modelId, {
85
+ provider: 'zai.chat',
86
+ baseURL,
87
+ headers: getHeaders,
88
+ fetch: options.fetch,
89
+ });
90
+
91
+ const provider = (modelId: ZaiChatModelId) => createLanguageModel(modelId);
92
+
93
+ provider.specificationVersion = 'v3' as const;
94
+ provider.languageModel = createLanguageModel;
95
+ provider.chatModel = createLanguageModel;
96
+ provider.chat = createLanguageModel;
97
+
98
+ provider.embeddingModel = (modelId: string) => {
99
+ throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
100
+ };
101
+ provider.textEmbeddingModel = provider.embeddingModel;
102
+ provider.imageModel = (modelId: string) => {
103
+ throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
104
+ };
105
+
106
+ return provider;
107
+ }
108
+
109
+ export const zai = createZai();
package/index.js DELETED
@@ -1 +0,0 @@
1
- export {};