@arnilo/prism-provider-zai 0.0.96 → 0.1.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 +113 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/models.js +2 -5
- package/dist/provider.js +31 -99
- package/dist/thinking.js +6 -10
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,116 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.0] - 2026-08-09
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Released with exact 0.1.0 graph.
|
|
7
|
+
|
|
8
|
+
## [0.0.28] - 2026-08-08
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Released with exact 0.0.28 graph.
|
|
12
|
+
|
|
13
|
+
## [0.0.27] - 2026-08-07
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Released with exact 0.0.27 graph.
|
|
17
|
+
|
|
18
|
+
## [0.0.26] - 2026-08-06
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Released with exact 0.0.26 graph.
|
|
22
|
+
|
|
23
|
+
## [0.0.25] - 2026-08-06
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- Released with exact 0.0.25 graph.
|
|
27
|
+
|
|
28
|
+
## [0.0.24] - 2026-08-04
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Durable `AgentEventSource` (memory + PostgreSQL LISTEN/NOTIFY), recoverable `ToolEffectStore`, and AG-UI MCP/MCP Apps/A2A fronting for Phase 7.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- Publishable graph remains **47** manifests at **0.0.24**; peers and lockfile move together.
|
|
35
|
+
|
|
36
|
+
See [migration guide](../../docs/migration.md) for the 0.0.23 → 0.0.24 notes.
|
|
37
|
+
|
|
38
|
+
## [0.0.23] - 2026-08-03
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
- Released with exact 0.0.23 graph.
|
|
42
|
+
|
|
43
|
+
## [0.0.22] - 2026-07-31
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
- Released with exact 0.0.22 graph.
|
|
47
|
+
|
|
48
|
+
## [0.0.21] - 2026-07-31
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- Released with exact 0.0.21 graph.
|
|
52
|
+
|
|
53
|
+
## [0.0.20] - 2026-07-31
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- Released with exact 0.0.20 graph.
|
|
57
|
+
|
|
58
|
+
## [0.0.19] - 2026-07-30
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- Released with exact 0.0.19 graph.
|
|
62
|
+
|
|
63
|
+
## [0.0.18] - 2026-07-30
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
- Released with exact 0.0.18 graph.
|
|
67
|
+
|
|
68
|
+
## [0.0.17] - 2026-07-29
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
- Released with exact 0.0.17 graph.
|
|
72
|
+
|
|
73
|
+
## [0.0.16] - 2026-07-26
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
- Released with exact 0.0.16 graph.
|
|
77
|
+
|
|
78
|
+
## [0.0.15] - 2026-07-26
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- Released with exact 0.0.15 graph.
|
|
83
|
+
|
|
84
|
+
## [0.0.14] - 2026-07-26
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- Released with exact 0.0.14 graph.
|
|
89
|
+
|
|
90
|
+
## [0.0.13] - 2026-07-24
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
|
|
94
|
+
- Released with exact 0.0.13 graph.
|
|
95
|
+
|
|
96
|
+
## [0.0.12] - 2026-07-22
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- Released with exact 0.0.12 graph.
|
|
101
|
+
|
|
102
|
+
## [0.0.11] - 2026-07-22
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
- Released with exact 0.0.11 graph.
|
|
107
|
+
|
|
108
|
+
## [0.0.10] - 2026-07-21
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
|
|
112
|
+
- Released with exact 0.0.10 graph.
|
|
113
|
+
|
|
1
114
|
## [0.0.96] - 2026-07-21
|
|
2
115
|
|
|
3
116
|
### Changed
|
|
@@ -12,7 +125,6 @@
|
|
|
12
125
|
|
|
13
126
|
- Malformed streamed tool-call arguments yield recoverable tool calls via `toolCallFromArgumentsText` instead of throwing `ProviderTransportError` / terminal stream errors.
|
|
14
127
|
|
|
15
|
-
|
|
16
128
|
## [0.0.8] - 2026-07-20
|
|
17
129
|
|
|
18
130
|
- Released with the exact 0.0.8 first-party package graph.
|
|
@@ -44,7 +156,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
44
156
|
|
|
45
157
|
- Pinned the required `@arnilo/prism` peer and package metadata to 0.0.5; runtime behavior is unchanged.
|
|
46
158
|
|
|
47
|
-
|
|
48
159
|
## [0.0.4] - 2026-07-14
|
|
49
160
|
|
|
50
161
|
### Changed
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ export interface ZaiProviderPackageOptions {
|
|
|
7
7
|
readonly models?: readonly ModelConfig[];
|
|
8
8
|
}
|
|
9
9
|
export declare function createZaiProviderPackage(options?: ZaiProviderPackageOptions): ProviderPackage;
|
|
10
|
-
export { defineZaiModel,
|
|
11
|
-
export { createZaiProvider, toZaiMessage,
|
|
10
|
+
export { defineZaiModel, type ListZaiModelsOptions, listZaiModels, mapZaiModel, type ZaiModelConfig, type ZaiModelEntry, zaiModels, } from "./models.js";
|
|
11
|
+
export { createZaiProvider, toZaiMessage, ZAI_DEFAULT_BASE_URL, type ZaiProviderOptions, zaiBody, zaiEvents, } from "./provider.js";
|
|
12
12
|
export { zaiClearThinking, zaiPreserveThinking, zaiReasoningEffort, zaiThinking, zaiToolStream, } from "./thinking.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineProviderPackage } from "@arnilo/prism";
|
|
2
|
-
import { createZaiProvider } from "./provider.js";
|
|
3
2
|
import { zaiModels } from "./models.js";
|
|
3
|
+
import { createZaiProvider } from "./provider.js";
|
|
4
4
|
export function createZaiProviderPackage(options = {}) {
|
|
5
5
|
const providerId = options.id ?? "zai";
|
|
6
6
|
return defineProviderPackage({
|
|
@@ -16,6 +16,6 @@ export function createZaiProviderPackage(options = {}) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
export { defineZaiModel, listZaiModels, mapZaiModel, zaiModels, } from "./models.js";
|
|
19
|
-
export { createZaiProvider, toZaiMessage, zaiBody, zaiEvents,
|
|
19
|
+
export { createZaiProvider, toZaiMessage, ZAI_DEFAULT_BASE_URL, zaiBody, zaiEvents, } from "./provider.js";
|
|
20
20
|
export { zaiClearThinking, zaiPreserveThinking, zaiReasoningEffort, zaiThinking, zaiToolStream, } from "./thinking.js";
|
|
21
21
|
//# sourceMappingURL=index.js.map
|
package/dist/models.js
CHANGED
|
@@ -24,7 +24,7 @@ export function defineZaiModel(config) {
|
|
|
24
24
|
*/
|
|
25
25
|
export async function listZaiModels(options = {}) {
|
|
26
26
|
const provider = options.provider ?? "zai";
|
|
27
|
-
const baseUrl = (options.baseUrl ?? "https://api.z.ai/api/paas/v4").replace(
|
|
27
|
+
const baseUrl = (options.baseUrl ?? "https://api.z.ai/api/paas/v4").replace(/\/+$/, "");
|
|
28
28
|
const token = await resolveCredentialValue(options.apiKey, { provider, name: "apiKey" });
|
|
29
29
|
const response = await (options.fetch ?? fetch)(`${baseUrl}/models`, {
|
|
30
30
|
method: "GET",
|
|
@@ -165,10 +165,7 @@ function limitsForZaiModel(modelId) {
|
|
|
165
165
|
}
|
|
166
166
|
function looksLikeReasoningModel(modelId) {
|
|
167
167
|
const id = modelId.toLowerCase();
|
|
168
|
-
return (id.includes("glm-5")
|
|
169
|
-
|| id.includes("glm-4.7")
|
|
170
|
-
|| id.includes("glm-4.6")
|
|
171
|
-
|| id.includes("glm-4.5"));
|
|
168
|
+
return id.includes("glm-5") || id.includes("glm-4.7") || id.includes("glm-4.6") || id.includes("glm-4.5");
|
|
172
169
|
}
|
|
173
170
|
function looksLikeVisionModel(modelId) {
|
|
174
171
|
const id = modelId.toLowerCase();
|
package/dist/provider.js
CHANGED
|
@@ -1,107 +1,43 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { readBoundedResponseText, readSseData } from "@arnilo/prism/providers/transport";
|
|
1
|
+
import { applyOpenAIChatStructuredOutput } from "@arnilo/prism/providers/openai";
|
|
2
|
+
import { buildOpenAIChatBody, createOpenAICompatibleProvider, openAIChatEvents } from "@arnilo/prism/providers/openai-compatible";
|
|
4
3
|
import { zaiPreserveThinking, zaiReasoningEffort, zaiThinking, zaiToolStream } from "./thinking.js";
|
|
5
4
|
/** Official international Chat Completions base (China `open.bigmodel.cn` remains overridable). */
|
|
6
5
|
export const ZAI_DEFAULT_BASE_URL = "https://api.z.ai/api/paas/v4";
|
|
7
6
|
export function createZaiProvider(options = {}) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const response = await (options.fetch ?? fetch)(`${baseUrl}/chat/completions`, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: {
|
|
21
|
-
...request.options?.headers,
|
|
22
|
-
"content-type": "application/json",
|
|
23
|
-
...(token ? { authorization: `Bearer ${token}` } : {})
|
|
24
|
-
},
|
|
25
|
-
body: JSON.stringify(zaiBody(request)),
|
|
26
|
-
signal: request.signal
|
|
27
|
-
});
|
|
28
|
-
if (!response.ok) {
|
|
29
|
-
return yield providerError(new Error(`Z.AI request failed: ${response.status} ${await readBoundedResponseText(response, { secrets })}`), secrets);
|
|
30
|
-
}
|
|
31
|
-
if (!response.body)
|
|
32
|
-
return yield providerError(new Error("Z.AI response had no body"), secrets);
|
|
33
|
-
yield* zaiEvents(response.body, request.signal);
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
yield providerError(error, secrets);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
};
|
|
7
|
+
return createOpenAICompatibleProvider({
|
|
8
|
+
id: options.id ?? "zai",
|
|
9
|
+
baseUrl: (options.baseUrl ?? ZAI_DEFAULT_BASE_URL).replace(/\/+$/, ""),
|
|
10
|
+
apiKey: options.apiKey,
|
|
11
|
+
fetch: options.fetch,
|
|
12
|
+
doneUsage: true,
|
|
13
|
+
requestFailedPrefix: "Z.AI request failed",
|
|
14
|
+
serializeMessage: (message, request) => toZaiMessage(message, request.model, zaiPreserveThinking(request)),
|
|
15
|
+
transformBody: (body, request) => zaiTransform(body, request),
|
|
16
|
+
});
|
|
40
17
|
}
|
|
41
18
|
export function zaiBody(request) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
...parameters,
|
|
19
|
+
return buildOpenAIChatBody(request, {
|
|
20
|
+
serializeMessage: (message, req) => toZaiMessage(message, req.model, zaiPreserveThinking(req)),
|
|
21
|
+
transformBody: (body, req) => zaiTransform(body, req),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function zaiTransform(body, request) {
|
|
25
|
+
const { maxTokens, stream_options: _streamOptions, ...rest } = body;
|
|
26
|
+
const transformed = {
|
|
27
|
+
...rest,
|
|
52
28
|
max_tokens: maxTokens ?? request.model.limits?.maxOutputTokens,
|
|
53
|
-
...
|
|
29
|
+
...stripZaiManagedCompat(request.options?.compat),
|
|
54
30
|
...request.options?.extra,
|
|
55
31
|
// Resolved official fields win over raw compat/extra escape hatches.
|
|
56
32
|
thinking: zaiThinking(request),
|
|
57
33
|
reasoning_effort: zaiReasoningEffort(request),
|
|
58
|
-
tool_stream: zaiToolStream(request)
|
|
34
|
+
tool_stream: zaiToolStream(request),
|
|
59
35
|
};
|
|
60
|
-
applyOpenAIChatStructuredOutput(
|
|
61
|
-
return clean(
|
|
36
|
+
applyOpenAIChatStructuredOutput(transformed, request.options?.structuredOutput);
|
|
37
|
+
return clean(transformed);
|
|
62
38
|
}
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
let usage;
|
|
66
|
-
for await (const data of readSseData(body, { signal })) {
|
|
67
|
-
if (data === "[DONE]")
|
|
68
|
-
break;
|
|
69
|
-
const chunk = JSON.parse(data);
|
|
70
|
-
if (chunk.usage) {
|
|
71
|
-
const mapped = mapOpenAIChatUsage(chunk.usage);
|
|
72
|
-
if (mapped) {
|
|
73
|
-
usage = mapped;
|
|
74
|
-
yield providerUsage(mapped);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
for (const choice of chunk.choices ?? []) {
|
|
78
|
-
const delta = choice.delta ?? {};
|
|
79
|
-
if (delta.content)
|
|
80
|
-
yield providerTextDelta(delta.content);
|
|
81
|
-
if (delta.reasoning_content)
|
|
82
|
-
yield providerThinkingDelta(delta.reasoning_content);
|
|
83
|
-
for (const tool of delta.tool_calls ?? []) {
|
|
84
|
-
const index = tool.index ?? 0;
|
|
85
|
-
const current = tools.get(index) ?? { argumentsText: "" };
|
|
86
|
-
current.id = tool.id ?? current.id;
|
|
87
|
-
current.name = tool.function?.name ?? current.name;
|
|
88
|
-
current.argumentsText += tool.function?.arguments ?? "";
|
|
89
|
-
tools.set(index, current);
|
|
90
|
-
yield providerToolCallDelta({
|
|
91
|
-
index,
|
|
92
|
-
id: tool.id,
|
|
93
|
-
name: tool.function?.name,
|
|
94
|
-
argumentsText: tool.function?.arguments
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
for (const call of tools.values()) {
|
|
100
|
-
if (call.id && call.name) {
|
|
101
|
-
yield providerToolCall(toolCallFromArgumentsText(call.id, call.name, call.argumentsText));
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
yield providerDone(usage);
|
|
39
|
+
export function zaiEvents(body, signal) {
|
|
40
|
+
return openAIChatEvents(body, { signal, doneUsage: true });
|
|
105
41
|
}
|
|
106
42
|
/**
|
|
107
43
|
* Serialize Prism messages for Z.AI Chat Completions.
|
|
@@ -112,15 +48,13 @@ export async function* zaiEvents(body, signal) {
|
|
|
112
48
|
export function toZaiMessage(message, model, preserveThinking = false) {
|
|
113
49
|
const capabilities = model.capabilities ?? {};
|
|
114
50
|
const thinkingParts = message.content.filter((part) => part.type === "thinking");
|
|
115
|
-
const reasoningContent = preserveThinking && thinkingParts.length > 0
|
|
116
|
-
? thinkingParts.map((part) => part.text).join("\n")
|
|
117
|
-
: undefined;
|
|
51
|
+
const reasoningContent = preserveThinking && thinkingParts.length > 0 ? thinkingParts.map((part) => part.text).join("\n") : undefined;
|
|
118
52
|
if (message.role === "tool") {
|
|
119
53
|
const result = message.content.find((part) => part.type === "tool_result");
|
|
120
54
|
return {
|
|
121
55
|
role: "tool",
|
|
122
56
|
tool_call_id: result?.toolCallId ?? "",
|
|
123
|
-
content: result ? JSON.stringify(result.result ?? result.error ?? null) : ""
|
|
57
|
+
content: result ? JSON.stringify(result.result ?? result.error ?? null) : "",
|
|
124
58
|
};
|
|
125
59
|
}
|
|
126
60
|
if (message.role === "assistant") {
|
|
@@ -133,9 +67,9 @@ export function toZaiMessage(message, model, preserveThinking = false) {
|
|
|
133
67
|
tool_calls: toolCalls.map((call) => ({
|
|
134
68
|
id: call.id,
|
|
135
69
|
type: "function",
|
|
136
|
-
function: { name: call.name, arguments: JSON.stringify(call.arguments) }
|
|
70
|
+
function: { name: call.name, arguments: JSON.stringify(call.arguments) },
|
|
137
71
|
})),
|
|
138
|
-
reasoning_content: reasoningContent
|
|
72
|
+
reasoning_content: reasoningContent,
|
|
139
73
|
});
|
|
140
74
|
}
|
|
141
75
|
}
|
|
@@ -145,8 +79,6 @@ export function toZaiMessage(message, model, preserveThinking = false) {
|
|
|
145
79
|
content.push({ type: "text", text: part.text });
|
|
146
80
|
}
|
|
147
81
|
else if (part.type === "thinking") {
|
|
148
|
-
// Handled via reasoning_content when preserving; otherwise dropped.
|
|
149
|
-
continue;
|
|
150
82
|
}
|
|
151
83
|
else if (part.type === "image") {
|
|
152
84
|
if (!capabilities.input?.includes("image")) {
|
package/dist/thinking.js
CHANGED
|
@@ -30,9 +30,7 @@ export function zaiThinking(request) {
|
|
|
30
30
|
* @see https://docs.z.ai/guides/capabilities/thinking
|
|
31
31
|
*/
|
|
32
32
|
export function zaiReasoningEffort(request) {
|
|
33
|
-
const effort = request.options?.compat?.reasoning_effort
|
|
34
|
-
?? request.options?.compat?.reasoningEffort
|
|
35
|
-
?? request.model.compat?.reasoning_effort;
|
|
33
|
+
const effort = request.options?.compat?.reasoning_effort ?? request.options?.compat?.reasoningEffort ?? request.model.compat?.reasoning_effort;
|
|
36
34
|
return typeof effort === "string" ? effort : undefined;
|
|
37
35
|
}
|
|
38
36
|
/**
|
|
@@ -52,9 +50,7 @@ export function zaiClearThinking(request) {
|
|
|
52
50
|
const fromThinkingObject = readClearThinkingFromObject(request.options?.compat?.thinking ?? request.model.compat?.thinking);
|
|
53
51
|
if (fromThinkingObject !== undefined)
|
|
54
52
|
return fromThinkingObject;
|
|
55
|
-
const value = request.options?.compat?.clear_thinking
|
|
56
|
-
?? request.options?.compat?.clearThinking
|
|
57
|
-
?? request.model.compat?.clear_thinking;
|
|
53
|
+
const value = request.options?.compat?.clear_thinking ?? request.options?.compat?.clearThinking ?? request.model.compat?.clear_thinking;
|
|
58
54
|
return typeof value === "boolean" ? value : undefined;
|
|
59
55
|
}
|
|
60
56
|
/**
|
|
@@ -66,10 +62,10 @@ export function zaiPreserveThinking(request) {
|
|
|
66
62
|
const clear = zaiClearThinking(request);
|
|
67
63
|
if (clear === true)
|
|
68
64
|
return false;
|
|
69
|
-
const value = request.options?.compat?.preserveThinking
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const value = request.options?.compat?.preserveThinking ??
|
|
66
|
+
request.options?.compat?.preserve_thinking ??
|
|
67
|
+
request.model.compat?.preserveThinking ??
|
|
68
|
+
request.model.compat?.preserve_thinking;
|
|
73
69
|
if (typeof value === "boolean")
|
|
74
70
|
return value;
|
|
75
71
|
// clear_thinking:false implies preserved thinking even without an explicit preserve flag.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-provider-zai",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Z.AI provider package for Prism.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"pack:dry-run": "npm pack --dry-run"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@arnilo/prism": "0.0
|
|
28
|
+
"@arnilo/prism": "0.1.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@arnilo/prism": "file:../.."
|