@ai-sdk/zai 0.0.0 → 3.0.1
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 +19 -0
- package/LICENSE +13 -0
- package/README.md +45 -3
- package/dist/index.d.ts +88 -0
- package/dist/index.js +265 -0
- package/dist/index.js.map +1 -0
- package/docs/200-zai.mdx +159 -0
- package/package.json +65 -11
- package/src/index.ts +6 -0
- package/src/version.ts +6 -0
- package/src/zai-chat-language-model-options.ts +45 -0
- package/src/zai-chat-language-model.ts +233 -0
- package/src/zai-chat-options.ts +28 -0
- package/src/zai-error.ts +19 -0
- package/src/zai-provider.ts +103 -0
- package/index.js +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# @ai-sdk/zai
|
|
2
|
+
|
|
3
|
+
## 3.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [3e125ba]
|
|
8
|
+
- @ai-sdk/provider-utils@5.0.32
|
|
9
|
+
- @ai-sdk/openai-compatible@3.0.39
|
|
10
|
+
|
|
11
|
+
## 3.0.0
|
|
12
|
+
|
|
13
|
+
### Major Changes
|
|
14
|
+
|
|
15
|
+
- b580642: feat(zai): add the Z.AI provider with GLM chat completions, streaming, reasoning, tools, and multimodal inputs
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 81bebaf: 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
|
-
#
|
|
1
|
+
# AI SDK - Z.AI Provider
|
|
2
2
|
|
|
3
|
-
AI SDK
|
|
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
|
-
|
|
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.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { ProviderV4, LanguageModelV4 } 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 ProviderV4 {
|
|
66
|
+
/**
|
|
67
|
+
* Creates a Z.AI chat model for text generation.
|
|
68
|
+
*/
|
|
69
|
+
(modelId: ZaiChatModelId): LanguageModelV4;
|
|
70
|
+
/**
|
|
71
|
+
* Creates a Z.AI language model.
|
|
72
|
+
*/
|
|
73
|
+
languageModel(modelId: ZaiChatModelId): LanguageModelV4;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a Z.AI chat model.
|
|
76
|
+
*/
|
|
77
|
+
chat(modelId: ZaiChatModelId): LanguageModelV4;
|
|
78
|
+
/**
|
|
79
|
+
* @deprecated Use `embeddingModel` instead.
|
|
80
|
+
*/
|
|
81
|
+
textEmbeddingModel(modelId: string): never;
|
|
82
|
+
}
|
|
83
|
+
declare function createZai(options?: ZaiProviderSettings): ZaiProvider;
|
|
84
|
+
declare const zai: ZaiProvider;
|
|
85
|
+
|
|
86
|
+
declare const VERSION: string;
|
|
87
|
+
|
|
88
|
+
export { VERSION, type ZaiChatModelId, type ZaiErrorData, type ZaiLanguageModelChatOptions, type ZaiProvider, type ZaiProviderSettings, createZai, zai };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
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 ? "3.0.1" : "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
|
+
serializeModelOptions,
|
|
19
|
+
WORKFLOW_DESERIALIZE,
|
|
20
|
+
WORKFLOW_SERIALIZE
|
|
21
|
+
} from "@ai-sdk/provider-utils";
|
|
22
|
+
|
|
23
|
+
// src/zai-chat-language-model-options.ts
|
|
24
|
+
import { z } from "zod/v4";
|
|
25
|
+
var zaiLanguageModelChatOptions = z.object({
|
|
26
|
+
/**
|
|
27
|
+
* Enables or disables sampling. When disabled, temperature and topP do not
|
|
28
|
+
* take effect.
|
|
29
|
+
*/
|
|
30
|
+
doSample: z.boolean().optional(),
|
|
31
|
+
/**
|
|
32
|
+
* Controls model thinking and whether reasoning from earlier turns is kept.
|
|
33
|
+
*/
|
|
34
|
+
thinking: z.object({
|
|
35
|
+
type: z.enum(["enabled", "disabled"]).optional(),
|
|
36
|
+
clearThinking: z.boolean().optional()
|
|
37
|
+
}).optional(),
|
|
38
|
+
/**
|
|
39
|
+
* Controls reasoning effort for GLM-5.2 and later models.
|
|
40
|
+
*/
|
|
41
|
+
reasoningEffort: z.enum(["none", "minimal", "low", "medium", "high", "xhigh", "max"]).optional(),
|
|
42
|
+
/**
|
|
43
|
+
* Enables incremental function-call argument streaming on supported models.
|
|
44
|
+
*/
|
|
45
|
+
toolStream: z.boolean().optional(),
|
|
46
|
+
/**
|
|
47
|
+
* A caller-provided request identifier between 6 and 64 characters.
|
|
48
|
+
*/
|
|
49
|
+
requestId: z.string().min(6).max(64).optional(),
|
|
50
|
+
/**
|
|
51
|
+
* A non-sensitive end-user identifier between 6 and 128 characters.
|
|
52
|
+
*/
|
|
53
|
+
userId: z.string().min(6).max(128).optional()
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// src/zai-error.ts
|
|
57
|
+
import { z as z2 } from "zod/v4";
|
|
58
|
+
var zaiErrorDetailsSchema = z2.object({
|
|
59
|
+
code: z2.union([z2.number(), z2.string()]).nullish(),
|
|
60
|
+
message: z2.string()
|
|
61
|
+
});
|
|
62
|
+
var zaiErrorSchema = z2.union([
|
|
63
|
+
zaiErrorDetailsSchema,
|
|
64
|
+
z2.object({ error: zaiErrorDetailsSchema })
|
|
65
|
+
]);
|
|
66
|
+
var zaiErrorStructure = {
|
|
67
|
+
errorSchema: zaiErrorSchema,
|
|
68
|
+
errorToMessage: (data) => "error" in data ? data.error.message : data.message
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/zai-chat-language-model.ts
|
|
72
|
+
function transformZaiRequestBody(args) {
|
|
73
|
+
const {
|
|
74
|
+
doSample,
|
|
75
|
+
frequency_penalty: _frequencyPenalty,
|
|
76
|
+
presence_penalty: _presencePenalty,
|
|
77
|
+
requestId,
|
|
78
|
+
seed: _seed,
|
|
79
|
+
thinking,
|
|
80
|
+
toolStream,
|
|
81
|
+
user: _user,
|
|
82
|
+
userId,
|
|
83
|
+
verbosity: _verbosity,
|
|
84
|
+
...restArgs
|
|
85
|
+
} = args;
|
|
86
|
+
return {
|
|
87
|
+
...restArgs,
|
|
88
|
+
...doSample !== void 0 && { do_sample: doSample },
|
|
89
|
+
...thinking !== void 0 && {
|
|
90
|
+
thinking: {
|
|
91
|
+
...thinking.type !== void 0 && { type: thinking.type },
|
|
92
|
+
...thinking.clearThinking !== void 0 && {
|
|
93
|
+
clear_thinking: thinking.clearThinking
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
...toolStream !== void 0 && { tool_stream: toolStream },
|
|
98
|
+
...requestId !== void 0 && { request_id: requestId },
|
|
99
|
+
...userId !== void 0 && { user_id: userId }
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function mapZaiFinishReason(finishReason) {
|
|
103
|
+
switch (finishReason.raw) {
|
|
104
|
+
case "sensitive":
|
|
105
|
+
return { unified: "content-filter", raw: finishReason.raw };
|
|
106
|
+
case "model_context_window_exceeded":
|
|
107
|
+
return { unified: "length", raw: finishReason.raw };
|
|
108
|
+
case "network_error":
|
|
109
|
+
return { unified: "error", raw: finishReason.raw };
|
|
110
|
+
default:
|
|
111
|
+
return finishReason;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
var ZaiChatLanguageModel = class _ZaiChatLanguageModel extends OpenAICompatibleChatLanguageModel {
|
|
115
|
+
static [WORKFLOW_SERIALIZE](model) {
|
|
116
|
+
return serializeModelOptions({
|
|
117
|
+
modelId: model.modelId,
|
|
118
|
+
config: model.zaiConfig
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
static [WORKFLOW_DESERIALIZE](options) {
|
|
122
|
+
return new _ZaiChatLanguageModel(
|
|
123
|
+
options.modelId,
|
|
124
|
+
options.config
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
constructor(modelId, config) {
|
|
128
|
+
const headers = config.headers;
|
|
129
|
+
super(modelId, {
|
|
130
|
+
provider: config.provider,
|
|
131
|
+
url: ({ path }) => `${config.baseURL}${path}`,
|
|
132
|
+
headers: headers == null ? void 0 : () => typeof headers === "function" ? headers() : headers,
|
|
133
|
+
fetch: config.fetch,
|
|
134
|
+
errorStructure: zaiErrorStructure,
|
|
135
|
+
transformRequestBody: transformZaiRequestBody,
|
|
136
|
+
supportedUrls: () => ({
|
|
137
|
+
"image/*": [/^https?:\/\//],
|
|
138
|
+
"video/*": [/^https?:\/\//]
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
this.zaiConfig = config;
|
|
142
|
+
}
|
|
143
|
+
async prepareCallOptions(options) {
|
|
144
|
+
const warnings = [];
|
|
145
|
+
const zaiOptions = await parseProviderOptions({
|
|
146
|
+
provider: "zai",
|
|
147
|
+
providerOptions: options.providerOptions,
|
|
148
|
+
schema: zaiLanguageModelChatOptions
|
|
149
|
+
});
|
|
150
|
+
if (options.frequencyPenalty != null) {
|
|
151
|
+
warnings.push({ type: "unsupported", feature: "frequencyPenalty" });
|
|
152
|
+
}
|
|
153
|
+
if (options.presencePenalty != null) {
|
|
154
|
+
warnings.push({ type: "unsupported", feature: "presencePenalty" });
|
|
155
|
+
}
|
|
156
|
+
if (options.seed != null) {
|
|
157
|
+
warnings.push({ type: "unsupported", feature: "seed" });
|
|
158
|
+
}
|
|
159
|
+
let tools = options.tools;
|
|
160
|
+
let toolChoice = options.toolChoice;
|
|
161
|
+
if ((toolChoice == null ? void 0 : toolChoice.type) === "none") {
|
|
162
|
+
tools = void 0;
|
|
163
|
+
toolChoice = void 0;
|
|
164
|
+
} else if (toolChoice != null && toolChoice.type !== "auto") {
|
|
165
|
+
warnings.push({
|
|
166
|
+
type: "unsupported",
|
|
167
|
+
feature: `toolChoice ${toolChoice.type}`,
|
|
168
|
+
details: "Z.AI currently supports only automatic tool selection."
|
|
169
|
+
});
|
|
170
|
+
toolChoice = void 0;
|
|
171
|
+
}
|
|
172
|
+
const normalizedOptions = {
|
|
173
|
+
...options,
|
|
174
|
+
frequencyPenalty: void 0,
|
|
175
|
+
presencePenalty: void 0,
|
|
176
|
+
seed: void 0,
|
|
177
|
+
tools,
|
|
178
|
+
toolChoice,
|
|
179
|
+
providerOptions: zaiOptions == null ? options.providerOptions : {
|
|
180
|
+
...options.providerOptions,
|
|
181
|
+
zai: zaiOptions
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return { normalizedOptions, warnings };
|
|
185
|
+
}
|
|
186
|
+
async doGenerate(options) {
|
|
187
|
+
const { normalizedOptions, warnings } = await this.prepareCallOptions(options);
|
|
188
|
+
const result = await super.doGenerate(normalizedOptions);
|
|
189
|
+
return {
|
|
190
|
+
...result,
|
|
191
|
+
finishReason: mapZaiFinishReason(result.finishReason),
|
|
192
|
+
warnings: [...result.warnings, ...warnings]
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
async doStream(options) {
|
|
196
|
+
const { normalizedOptions, warnings } = await this.prepareCallOptions(options);
|
|
197
|
+
const result = await super.doStream(normalizedOptions);
|
|
198
|
+
return {
|
|
199
|
+
...result,
|
|
200
|
+
stream: result.stream.pipeThrough(
|
|
201
|
+
new TransformStream({
|
|
202
|
+
transform(part, controller) {
|
|
203
|
+
if (part.type === "stream-start") {
|
|
204
|
+
controller.enqueue({
|
|
205
|
+
...part,
|
|
206
|
+
warnings: [...part.warnings, ...warnings]
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (part.type === "finish") {
|
|
211
|
+
controller.enqueue({
|
|
212
|
+
...part,
|
|
213
|
+
finishReason: mapZaiFinishReason(part.finishReason)
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
controller.enqueue(part);
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// src/zai-provider.ts
|
|
226
|
+
function createZai(options = {}) {
|
|
227
|
+
var _a;
|
|
228
|
+
const baseURL = (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : "https://api.z.ai/api/paas/v4";
|
|
229
|
+
const getHeaders = () => withUserAgentSuffix(
|
|
230
|
+
{
|
|
231
|
+
Authorization: `Bearer ${loadApiKey({
|
|
232
|
+
apiKey: options.apiKey,
|
|
233
|
+
environmentVariableName: "ZAI_API_KEY",
|
|
234
|
+
description: "Z.AI API key"
|
|
235
|
+
})}`,
|
|
236
|
+
...options.headers
|
|
237
|
+
},
|
|
238
|
+
`ai-sdk/zai/${VERSION}`
|
|
239
|
+
);
|
|
240
|
+
const createLanguageModel = (modelId) => new ZaiChatLanguageModel(modelId, {
|
|
241
|
+
provider: "zai.chat",
|
|
242
|
+
baseURL,
|
|
243
|
+
headers: getHeaders,
|
|
244
|
+
fetch: options.fetch
|
|
245
|
+
});
|
|
246
|
+
const provider = (modelId) => createLanguageModel(modelId);
|
|
247
|
+
provider.specificationVersion = "v4";
|
|
248
|
+
provider.languageModel = createLanguageModel;
|
|
249
|
+
provider.chat = createLanguageModel;
|
|
250
|
+
provider.embeddingModel = (modelId) => {
|
|
251
|
+
throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
|
|
252
|
+
};
|
|
253
|
+
provider.textEmbeddingModel = provider.embeddingModel;
|
|
254
|
+
provider.imageModel = (modelId) => {
|
|
255
|
+
throw new NoSuchModelError({ modelId, modelType: "imageModel" });
|
|
256
|
+
};
|
|
257
|
+
return provider;
|
|
258
|
+
}
|
|
259
|
+
var zai = createZai();
|
|
260
|
+
export {
|
|
261
|
+
VERSION,
|
|
262
|
+
createZai,
|
|
263
|
+
zai
|
|
264
|
+
};
|
|
265
|
+
//# 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 LanguageModelV4,\n type ProviderV4,\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 ProviderV4 {\n /**\n * Creates a Z.AI chat model for text generation.\n */\n (modelId: ZaiChatModelId): LanguageModelV4;\n\n /**\n * Creates a Z.AI language model.\n */\n languageModel(modelId: ZaiChatModelId): LanguageModelV4;\n\n /**\n * Creates a Z.AI chat model.\n */\n chat(modelId: ZaiChatModelId): LanguageModelV4;\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 = 'v4' as const;\n provider.languageModel = 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 LanguageModelV4,\n LanguageModelV4CallOptions,\n LanguageModelV4FinishReason,\n LanguageModelV4GenerateResult,\n LanguageModelV4StreamPart,\n LanguageModelV4StreamResult,\n SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n parseProviderOptions,\n serializeModelOptions,\n WORKFLOW_DESERIALIZE,\n WORKFLOW_SERIALIZE,\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\ntype OpenAICompatibleChatConfig = ConstructorParameters<\n typeof OpenAICompatibleChatLanguageModel\n>[1];\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: LanguageModelV4FinishReason,\n): LanguageModelV4FinishReason {\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 LanguageModelV4\n{\n private readonly zaiConfig: ZaiChatConfig;\n\n static [WORKFLOW_SERIALIZE](model: ZaiChatLanguageModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.zaiConfig,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: string;\n config: OpenAICompatibleChatConfig;\n }) {\n return new ZaiChatLanguageModel(\n options.modelId,\n options.config as unknown as ZaiChatConfig,\n );\n }\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 ? undefined\n : () => (typeof headers === 'function' ? headers() : headers),\n fetch: config.fetch,\n errorStructure: zaiErrorStructure,\n transformRequestBody: transformZaiRequestBody,\n supportedUrls: () => ({\n 'image/*': [/^https?:\\/\\//],\n 'video/*': [/^https?:\\/\\//],\n }),\n });\n\n this.zaiConfig = config;\n }\n\n private async prepareCallOptions(options: LanguageModelV4CallOptions) {\n const warnings: SharedV4Warning[] = [];\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: LanguageModelV4CallOptions = {\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: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4GenerateResult> {\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: LanguageModelV4CallOptions,\n ): Promise<LanguageModelV4StreamResult> {\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 LanguageModelV4StreamPart,\n LanguageModelV4StreamPart\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":"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","names":["z"]}
|
package/docs/200-zai.mdx
ADDED
|
@@ -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<string, string>_
|
|
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": "
|
|
4
|
-
"description": "AI SDK provider for Z.ai",
|
|
5
|
-
"license": "Apache-2.0",
|
|
3
|
+
"version": "3.0.1",
|
|
6
4
|
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
11
9
|
"files": [
|
|
12
|
-
"
|
|
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": "3.0.39",
|
|
33
|
+
"@ai-sdk/provider": "4.0.8",
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.32"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "22.19.19",
|
|
38
|
+
"@vercel/ai-tsconfig": "0.0.0",
|
|
39
|
+
"tsup": "^8.5.1",
|
|
40
|
+
"typescript": "5.8.3",
|
|
41
|
+
"zod": "3.25.76"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"zod": "^3.25.76 || ^4.1.8"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22"
|
|
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": "
|
|
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,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,233 @@
|
|
|
1
|
+
import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';
|
|
2
|
+
import type {
|
|
3
|
+
LanguageModelV4,
|
|
4
|
+
LanguageModelV4CallOptions,
|
|
5
|
+
LanguageModelV4FinishReason,
|
|
6
|
+
LanguageModelV4GenerateResult,
|
|
7
|
+
LanguageModelV4StreamPart,
|
|
8
|
+
LanguageModelV4StreamResult,
|
|
9
|
+
SharedV4Warning,
|
|
10
|
+
} from '@ai-sdk/provider';
|
|
11
|
+
import {
|
|
12
|
+
parseProviderOptions,
|
|
13
|
+
serializeModelOptions,
|
|
14
|
+
WORKFLOW_DESERIALIZE,
|
|
15
|
+
WORKFLOW_SERIALIZE,
|
|
16
|
+
type FetchFunction,
|
|
17
|
+
} from '@ai-sdk/provider-utils';
|
|
18
|
+
import type { ZaiChatModelId } from './zai-chat-options';
|
|
19
|
+
import { zaiLanguageModelChatOptions } from './zai-chat-language-model-options';
|
|
20
|
+
import { zaiErrorStructure } from './zai-error';
|
|
21
|
+
|
|
22
|
+
type OpenAICompatibleChatConfig = ConstructorParameters<
|
|
23
|
+
typeof OpenAICompatibleChatLanguageModel
|
|
24
|
+
>[1];
|
|
25
|
+
|
|
26
|
+
export type ZaiChatConfig = {
|
|
27
|
+
provider: string;
|
|
28
|
+
baseURL: string;
|
|
29
|
+
headers?:
|
|
30
|
+
| Record<string, string | undefined>
|
|
31
|
+
| (() => Record<string, string | undefined>);
|
|
32
|
+
fetch?: FetchFunction;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function transformZaiRequestBody(
|
|
36
|
+
args: Record<string, any>,
|
|
37
|
+
): Record<string, any> {
|
|
38
|
+
const {
|
|
39
|
+
doSample,
|
|
40
|
+
frequency_penalty: _frequencyPenalty,
|
|
41
|
+
presence_penalty: _presencePenalty,
|
|
42
|
+
requestId,
|
|
43
|
+
seed: _seed,
|
|
44
|
+
thinking,
|
|
45
|
+
toolStream,
|
|
46
|
+
user: _user,
|
|
47
|
+
userId,
|
|
48
|
+
verbosity: _verbosity,
|
|
49
|
+
...restArgs
|
|
50
|
+
} = args;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
...restArgs,
|
|
54
|
+
...(doSample !== undefined && { do_sample: doSample }),
|
|
55
|
+
...(thinking !== undefined && {
|
|
56
|
+
thinking: {
|
|
57
|
+
...(thinking.type !== undefined && { type: thinking.type }),
|
|
58
|
+
...(thinking.clearThinking !== undefined && {
|
|
59
|
+
clear_thinking: thinking.clearThinking,
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
...(toolStream !== undefined && { tool_stream: toolStream }),
|
|
64
|
+
...(requestId !== undefined && { request_id: requestId }),
|
|
65
|
+
...(userId !== undefined && { user_id: userId }),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function mapZaiFinishReason(
|
|
70
|
+
finishReason: LanguageModelV4FinishReason,
|
|
71
|
+
): LanguageModelV4FinishReason {
|
|
72
|
+
switch (finishReason.raw) {
|
|
73
|
+
case 'sensitive':
|
|
74
|
+
return { unified: 'content-filter', raw: finishReason.raw };
|
|
75
|
+
case 'model_context_window_exceeded':
|
|
76
|
+
return { unified: 'length', raw: finishReason.raw };
|
|
77
|
+
case 'network_error':
|
|
78
|
+
return { unified: 'error', raw: finishReason.raw };
|
|
79
|
+
default:
|
|
80
|
+
return finishReason;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class ZaiChatLanguageModel
|
|
85
|
+
extends OpenAICompatibleChatLanguageModel
|
|
86
|
+
implements LanguageModelV4
|
|
87
|
+
{
|
|
88
|
+
private readonly zaiConfig: ZaiChatConfig;
|
|
89
|
+
|
|
90
|
+
static [WORKFLOW_SERIALIZE](model: ZaiChatLanguageModel) {
|
|
91
|
+
return serializeModelOptions({
|
|
92
|
+
modelId: model.modelId,
|
|
93
|
+
config: model.zaiConfig,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
98
|
+
modelId: string;
|
|
99
|
+
config: OpenAICompatibleChatConfig;
|
|
100
|
+
}) {
|
|
101
|
+
return new ZaiChatLanguageModel(
|
|
102
|
+
options.modelId,
|
|
103
|
+
options.config as unknown as ZaiChatConfig,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
constructor(modelId: ZaiChatModelId, config: ZaiChatConfig) {
|
|
108
|
+
const headers = config.headers;
|
|
109
|
+
|
|
110
|
+
super(modelId, {
|
|
111
|
+
provider: config.provider,
|
|
112
|
+
url: ({ path }) => `${config.baseURL}${path}`,
|
|
113
|
+
headers:
|
|
114
|
+
headers == null
|
|
115
|
+
? undefined
|
|
116
|
+
: () => (typeof headers === 'function' ? headers() : headers),
|
|
117
|
+
fetch: config.fetch,
|
|
118
|
+
errorStructure: zaiErrorStructure,
|
|
119
|
+
transformRequestBody: transformZaiRequestBody,
|
|
120
|
+
supportedUrls: () => ({
|
|
121
|
+
'image/*': [/^https?:\/\//],
|
|
122
|
+
'video/*': [/^https?:\/\//],
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
this.zaiConfig = config;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private async prepareCallOptions(options: LanguageModelV4CallOptions) {
|
|
130
|
+
const warnings: SharedV4Warning[] = [];
|
|
131
|
+
|
|
132
|
+
const zaiOptions = await parseProviderOptions({
|
|
133
|
+
provider: 'zai',
|
|
134
|
+
providerOptions: options.providerOptions,
|
|
135
|
+
schema: zaiLanguageModelChatOptions,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
if (options.frequencyPenalty != null) {
|
|
139
|
+
warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
|
|
140
|
+
}
|
|
141
|
+
if (options.presencePenalty != null) {
|
|
142
|
+
warnings.push({ type: 'unsupported', feature: 'presencePenalty' });
|
|
143
|
+
}
|
|
144
|
+
if (options.seed != null) {
|
|
145
|
+
warnings.push({ type: 'unsupported', feature: 'seed' });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let tools = options.tools;
|
|
149
|
+
let toolChoice = options.toolChoice;
|
|
150
|
+
|
|
151
|
+
if (toolChoice?.type === 'none') {
|
|
152
|
+
tools = undefined;
|
|
153
|
+
toolChoice = undefined;
|
|
154
|
+
} else if (toolChoice != null && toolChoice.type !== 'auto') {
|
|
155
|
+
warnings.push({
|
|
156
|
+
type: 'unsupported',
|
|
157
|
+
feature: `toolChoice ${toolChoice.type}`,
|
|
158
|
+
details: 'Z.AI currently supports only automatic tool selection.',
|
|
159
|
+
});
|
|
160
|
+
toolChoice = undefined;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const normalizedOptions: LanguageModelV4CallOptions = {
|
|
164
|
+
...options,
|
|
165
|
+
frequencyPenalty: undefined,
|
|
166
|
+
presencePenalty: undefined,
|
|
167
|
+
seed: undefined,
|
|
168
|
+
tools,
|
|
169
|
+
toolChoice,
|
|
170
|
+
providerOptions:
|
|
171
|
+
zaiOptions == null
|
|
172
|
+
? options.providerOptions
|
|
173
|
+
: {
|
|
174
|
+
...options.providerOptions,
|
|
175
|
+
zai: zaiOptions,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return { normalizedOptions, warnings };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async doGenerate(
|
|
183
|
+
options: LanguageModelV4CallOptions,
|
|
184
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
185
|
+
const { normalizedOptions, warnings } =
|
|
186
|
+
await this.prepareCallOptions(options);
|
|
187
|
+
const result = await super.doGenerate(normalizedOptions);
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
...result,
|
|
191
|
+
finishReason: mapZaiFinishReason(result.finishReason),
|
|
192
|
+
warnings: [...result.warnings, ...warnings],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async doStream(
|
|
197
|
+
options: LanguageModelV4CallOptions,
|
|
198
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
199
|
+
const { normalizedOptions, warnings } =
|
|
200
|
+
await this.prepareCallOptions(options);
|
|
201
|
+
const result = await super.doStream(normalizedOptions);
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
...result,
|
|
205
|
+
stream: result.stream.pipeThrough(
|
|
206
|
+
new TransformStream<
|
|
207
|
+
LanguageModelV4StreamPart,
|
|
208
|
+
LanguageModelV4StreamPart
|
|
209
|
+
>({
|
|
210
|
+
transform(part, controller) {
|
|
211
|
+
if (part.type === 'stream-start') {
|
|
212
|
+
controller.enqueue({
|
|
213
|
+
...part,
|
|
214
|
+
warnings: [...part.warnings, ...warnings],
|
|
215
|
+
});
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (part.type === 'finish') {
|
|
220
|
+
controller.enqueue({
|
|
221
|
+
...part,
|
|
222
|
+
finishReason: mapZaiFinishReason(part.finishReason),
|
|
223
|
+
});
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
controller.enqueue(part);
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
230
|
+
),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
@@ -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 & {});
|
package/src/zai-error.ts
ADDED
|
@@ -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,103 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NoSuchModelError,
|
|
3
|
+
type LanguageModelV4,
|
|
4
|
+
type ProviderV4,
|
|
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 ProviderV4 {
|
|
40
|
+
/**
|
|
41
|
+
* Creates a Z.AI chat model for text generation.
|
|
42
|
+
*/
|
|
43
|
+
(modelId: ZaiChatModelId): LanguageModelV4;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a Z.AI language model.
|
|
47
|
+
*/
|
|
48
|
+
languageModel(modelId: ZaiChatModelId): LanguageModelV4;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Creates a Z.AI chat model.
|
|
52
|
+
*/
|
|
53
|
+
chat(modelId: ZaiChatModelId): LanguageModelV4;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @deprecated Use `embeddingModel` instead.
|
|
57
|
+
*/
|
|
58
|
+
textEmbeddingModel(modelId: string): never;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createZai(options: ZaiProviderSettings = {}): ZaiProvider {
|
|
62
|
+
const baseURL =
|
|
63
|
+
withoutTrailingSlash(options.baseURL) ?? 'https://api.z.ai/api/paas/v4';
|
|
64
|
+
|
|
65
|
+
const getHeaders = () =>
|
|
66
|
+
withUserAgentSuffix(
|
|
67
|
+
{
|
|
68
|
+
Authorization: `Bearer ${loadApiKey({
|
|
69
|
+
apiKey: options.apiKey,
|
|
70
|
+
environmentVariableName: 'ZAI_API_KEY',
|
|
71
|
+
description: 'Z.AI API key',
|
|
72
|
+
})}`,
|
|
73
|
+
...options.headers,
|
|
74
|
+
},
|
|
75
|
+
`ai-sdk/zai/${VERSION}`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const createLanguageModel = (modelId: ZaiChatModelId) =>
|
|
79
|
+
new ZaiChatLanguageModel(modelId, {
|
|
80
|
+
provider: 'zai.chat',
|
|
81
|
+
baseURL,
|
|
82
|
+
headers: getHeaders,
|
|
83
|
+
fetch: options.fetch,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const provider = (modelId: ZaiChatModelId) => createLanguageModel(modelId);
|
|
87
|
+
|
|
88
|
+
provider.specificationVersion = 'v4' as const;
|
|
89
|
+
provider.languageModel = createLanguageModel;
|
|
90
|
+
provider.chat = createLanguageModel;
|
|
91
|
+
|
|
92
|
+
provider.embeddingModel = (modelId: string) => {
|
|
93
|
+
throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
|
|
94
|
+
};
|
|
95
|
+
provider.textEmbeddingModel = provider.embeddingModel;
|
|
96
|
+
provider.imageModel = (modelId: string) => {
|
|
97
|
+
throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return provider;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const zai = createZai();
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|