@arnilo/prism-provider-zai 0.0.16 → 0.0.18
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 +10 -0
- package/dist/models.js +1 -1
- package/dist/provider.js +26 -90
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
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",
|
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
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-provider-zai",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
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.0.18"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@arnilo/prism": "file:../.."
|