@ai-sdk/alibaba 2.0.58 → 2.0.59
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 +9 -0
- package/dist/index.d.ts +171 -163
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1214 -1531
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,1592 +1,1275 @@
|
|
|
1
|
-
|
|
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/alibaba-chat-language-model.ts
|
|
12
|
-
import {
|
|
13
|
-
combineHeaders,
|
|
14
|
-
createEventSourceResponseHandler,
|
|
15
|
-
createJsonResponseHandler,
|
|
16
|
-
createLanguageModelResponseMetadata as getResponseMetadata,
|
|
17
|
-
generateId,
|
|
18
|
-
injectJsonInstructionIntoMessages,
|
|
19
|
-
isCustomReasoning,
|
|
20
|
-
mapReasoningToProviderBudget,
|
|
21
|
-
parseProviderOptions,
|
|
22
|
-
postJsonToApi,
|
|
23
|
-
serializeModelOptions,
|
|
24
|
-
StreamingToolCallTracker,
|
|
25
|
-
WORKFLOW_SERIALIZE,
|
|
26
|
-
WORKFLOW_DESERIALIZE
|
|
27
|
-
} from "@ai-sdk/provider-utils";
|
|
28
|
-
import { z as z3 } from "zod/v4";
|
|
29
|
-
|
|
30
|
-
// src/alibaba-chat-language-model-options.ts
|
|
1
|
+
import { AISDKError, NoSuchModelError, TooManyEmbeddingValuesForCallError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
|
|
2
|
+
import { StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, convertImageModelFileToDataUri, convertToBase64, convertUint8ArrayToBase64, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata, createNullLanguageModelUsage, generateId, getFromApi, getTopLevelMediaType, injectJsonInstructionIntoMessages, isCustomReasoning, lazySchema, loadApiKey, mapReasoningToProviderBudget, parseProviderOptions, postJsonToApi, resolve, resolveFullMediaType, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
|
|
31
3
|
import { z } from "zod/v4";
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// src/alibaba-error.ts
|
|
62
|
-
import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
|
|
63
|
-
import { z as z2 } from "zod/v4";
|
|
64
|
-
var alibabaErrorDataSchema = z2.object({
|
|
65
|
-
error: z2.object({
|
|
66
|
-
message: z2.string(),
|
|
67
|
-
code: z2.string().nullish(),
|
|
68
|
-
type: z2.string().nullish()
|
|
69
|
-
})
|
|
4
|
+
//#region src/alibaba-chat-language-model-options.ts
|
|
5
|
+
const alibabaLanguageModelChatOptions = z.object({
|
|
6
|
+
/**
|
|
7
|
+
* Enable thinking/reasoning mode for supported models.
|
|
8
|
+
* When enabled, the model generates reasoning content before the response.
|
|
9
|
+
*
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
enableThinking: z.boolean().optional(),
|
|
13
|
+
/**
|
|
14
|
+
* Maximum number of reasoning tokens to generate.
|
|
15
|
+
*/
|
|
16
|
+
thinkingBudget: z.number().positive().optional(),
|
|
17
|
+
/**
|
|
18
|
+
* Whether to preserve reasoning from previous assistant messages.
|
|
19
|
+
*
|
|
20
|
+
* When enabled, historical reasoning is sent separately as
|
|
21
|
+
* `reasoning_content` and Alibaba receives `preserve_thinking: true`.
|
|
22
|
+
* Defaults to `true` for models that support preserved thinking; set to
|
|
23
|
+
* `false` to opt out.
|
|
24
|
+
*/
|
|
25
|
+
preserveThinking: z.boolean().optional(),
|
|
26
|
+
/**
|
|
27
|
+
* Whether to enable parallel function calling during tool use.
|
|
28
|
+
*
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
parallelToolCalls: z.boolean().optional()
|
|
70
32
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/alibaba-error.ts
|
|
35
|
+
const alibabaErrorDataSchema = z.object({ error: z.object({
|
|
36
|
+
message: z.string(),
|
|
37
|
+
code: z.string().nullish(),
|
|
38
|
+
type: z.string().nullish()
|
|
39
|
+
}) });
|
|
40
|
+
const alibabaFailedResponseHandler = createJsonErrorResponseHandler({
|
|
41
|
+
errorSchema: alibabaErrorDataSchema,
|
|
42
|
+
errorToMessage: (data) => data.error.message
|
|
74
43
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
},
|
|
124
|
-
toolWarnings
|
|
125
|
-
};
|
|
126
|
-
default: {
|
|
127
|
-
const _exhaustiveCheck = type;
|
|
128
|
-
throw new UnsupportedFunctionalityError({
|
|
129
|
-
functionality: `tool choice type: ${_exhaustiveCheck}`
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/alibaba-prepare-tools.ts
|
|
46
|
+
function prepareTools({ tools, toolChoice }) {
|
|
47
|
+
tools = tools?.length ? tools : void 0;
|
|
48
|
+
const toolWarnings = [];
|
|
49
|
+
if (tools == null) return {
|
|
50
|
+
tools: void 0,
|
|
51
|
+
toolChoice: void 0,
|
|
52
|
+
toolWarnings
|
|
53
|
+
};
|
|
54
|
+
const alibabaTools = [];
|
|
55
|
+
for (const tool of tools) if (tool.type === "provider") toolWarnings.push({
|
|
56
|
+
type: "unsupported",
|
|
57
|
+
feature: `provider-defined tool ${tool.id}`
|
|
58
|
+
});
|
|
59
|
+
else alibabaTools.push({
|
|
60
|
+
type: "function",
|
|
61
|
+
function: {
|
|
62
|
+
name: tool.name,
|
|
63
|
+
description: tool.description,
|
|
64
|
+
parameters: tool.inputSchema,
|
|
65
|
+
...tool.strict != null ? { strict: tool.strict } : {}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
if (toolChoice == null) return {
|
|
69
|
+
tools: alibabaTools,
|
|
70
|
+
toolChoice: void 0,
|
|
71
|
+
toolWarnings
|
|
72
|
+
};
|
|
73
|
+
const type = toolChoice.type;
|
|
74
|
+
switch (type) {
|
|
75
|
+
case "auto":
|
|
76
|
+
case "none":
|
|
77
|
+
case "required": return {
|
|
78
|
+
tools: alibabaTools,
|
|
79
|
+
toolChoice: type,
|
|
80
|
+
toolWarnings
|
|
81
|
+
};
|
|
82
|
+
case "tool": return {
|
|
83
|
+
tools: alibabaTools,
|
|
84
|
+
toolChoice: {
|
|
85
|
+
type: "function",
|
|
86
|
+
function: { name: toolChoice.toolName }
|
|
87
|
+
},
|
|
88
|
+
toolWarnings
|
|
89
|
+
};
|
|
90
|
+
default: throw new UnsupportedFunctionalityError({ functionality: `tool choice type: ${type}` });
|
|
91
|
+
}
|
|
133
92
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
import { createNullLanguageModelUsage } from "@ai-sdk/provider-utils";
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/convert-alibaba-usage.ts
|
|
137
95
|
function convertAlibabaUsage(usage) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
},
|
|
159
|
-
raw: usage
|
|
160
|
-
};
|
|
96
|
+
if (usage == null) return createNullLanguageModelUsage();
|
|
97
|
+
const promptTokens = usage.prompt_tokens ?? 0;
|
|
98
|
+
const completionTokens = usage.completion_tokens ?? 0;
|
|
99
|
+
const cacheReadTokens = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
100
|
+
const cacheWriteTokens = usage.prompt_tokens_details?.cache_creation_input_tokens ?? 0;
|
|
101
|
+
const reasoningTokens = usage.completion_tokens_details?.reasoning_tokens ?? 0;
|
|
102
|
+
return {
|
|
103
|
+
inputTokens: {
|
|
104
|
+
total: promptTokens,
|
|
105
|
+
noCache: promptTokens - cacheReadTokens - cacheWriteTokens,
|
|
106
|
+
cacheRead: cacheReadTokens,
|
|
107
|
+
cacheWrite: cacheWriteTokens
|
|
108
|
+
},
|
|
109
|
+
outputTokens: {
|
|
110
|
+
total: completionTokens,
|
|
111
|
+
text: Math.max(0, completionTokens - reasoningTokens),
|
|
112
|
+
reasoning: reasoningTokens
|
|
113
|
+
},
|
|
114
|
+
raw: usage
|
|
115
|
+
};
|
|
161
116
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
import {
|
|
165
|
-
UnsupportedFunctionalityError as UnsupportedFunctionalityError2
|
|
166
|
-
} from "@ai-sdk/provider";
|
|
167
|
-
import {
|
|
168
|
-
convertToBase64,
|
|
169
|
-
getTopLevelMediaType,
|
|
170
|
-
resolveFullMediaType
|
|
171
|
-
} from "@ai-sdk/provider-utils";
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/convert-to-alibaba-chat-messages.ts
|
|
172
119
|
function formatImageUrl({ part }) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if (part.data.type === "data") {
|
|
177
|
-
return `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`;
|
|
178
|
-
}
|
|
179
|
-
throw new UnsupportedFunctionalityError2({
|
|
180
|
-
functionality: `file part data type ${part.data.type}`
|
|
181
|
-
});
|
|
120
|
+
if (part.data.type === "url") return part.data.url.toString();
|
|
121
|
+
if (part.data.type === "data") return `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`;
|
|
122
|
+
throw new UnsupportedFunctionalityError({ functionality: `file part data type ${part.data.type}` });
|
|
182
123
|
}
|
|
183
|
-
function convertToAlibabaChatMessages({
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
306
|
-
});
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
case "tool": {
|
|
310
|
-
const toolResponses = content.filter(
|
|
311
|
-
(r) => r.type !== "tool-approval-response"
|
|
312
|
-
);
|
|
313
|
-
for (let i = 0; i < toolResponses.length; i++) {
|
|
314
|
-
const toolResponse = toolResponses[i];
|
|
315
|
-
const output = toolResponse.output;
|
|
316
|
-
const isLastPart = i === toolResponses.length - 1;
|
|
317
|
-
const partCacheControl = cacheControlValidator?.getCacheControl(
|
|
318
|
-
toolResponse.providerOptions
|
|
319
|
-
) ?? (isLastPart ? messageCacheControl : void 0);
|
|
320
|
-
let contentValue;
|
|
321
|
-
switch (output.type) {
|
|
322
|
-
case "text":
|
|
323
|
-
case "error-text":
|
|
324
|
-
contentValue = output.value;
|
|
325
|
-
break;
|
|
326
|
-
case "execution-denied":
|
|
327
|
-
contentValue = output.reason ?? "Tool call execution denied.";
|
|
328
|
-
break;
|
|
329
|
-
case "content":
|
|
330
|
-
case "json":
|
|
331
|
-
case "error-json":
|
|
332
|
-
contentValue = JSON.stringify(output.value);
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
messages.push({
|
|
336
|
-
role: "tool",
|
|
337
|
-
tool_call_id: toolResponse.toolCallId,
|
|
338
|
-
content: partCacheControl ? [
|
|
339
|
-
{
|
|
340
|
-
type: "text",
|
|
341
|
-
text: contentValue,
|
|
342
|
-
cache_control: partCacheControl
|
|
343
|
-
}
|
|
344
|
-
] : contentValue
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
default: {
|
|
350
|
-
const _exhaustiveCheck = role;
|
|
351
|
-
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return messages;
|
|
124
|
+
function convertToAlibabaChatMessages({ prompt, cacheControlValidator, preserveThinking = false }) {
|
|
125
|
+
const messages = [];
|
|
126
|
+
let lastUserMessageIndex = -1;
|
|
127
|
+
for (let i = prompt.length - 1; i >= 0; i--) if (prompt[i].role === "user") {
|
|
128
|
+
lastUserMessageIndex = i;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
let index = -1;
|
|
132
|
+
for (const { role, content, ...message } of prompt) {
|
|
133
|
+
index++;
|
|
134
|
+
const messageCacheControl = cacheControlValidator?.getCacheControl(message.providerOptions);
|
|
135
|
+
switch (role) {
|
|
136
|
+
case "system":
|
|
137
|
+
if (messageCacheControl) messages.push({
|
|
138
|
+
role: "system",
|
|
139
|
+
content: [{
|
|
140
|
+
type: "text",
|
|
141
|
+
text: content,
|
|
142
|
+
cache_control: messageCacheControl
|
|
143
|
+
}]
|
|
144
|
+
});
|
|
145
|
+
else messages.push({
|
|
146
|
+
role: "system",
|
|
147
|
+
content
|
|
148
|
+
});
|
|
149
|
+
break;
|
|
150
|
+
case "user":
|
|
151
|
+
messages.push({
|
|
152
|
+
role: "user",
|
|
153
|
+
content: content.map((part, index) => {
|
|
154
|
+
const isLastPart = index === content.length - 1;
|
|
155
|
+
const partCacheControl = cacheControlValidator?.getCacheControl(part.providerOptions) ?? (isLastPart ? messageCacheControl : void 0);
|
|
156
|
+
switch (part.type) {
|
|
157
|
+
case "text": return {
|
|
158
|
+
type: "text",
|
|
159
|
+
text: part.text,
|
|
160
|
+
...partCacheControl ? { cache_control: partCacheControl } : {}
|
|
161
|
+
};
|
|
162
|
+
case "file": switch (part.data.type) {
|
|
163
|
+
case "reference": throw new UnsupportedFunctionalityError({ functionality: "file parts with provider references" });
|
|
164
|
+
case "text": throw new UnsupportedFunctionalityError({ functionality: "text file parts" });
|
|
165
|
+
case "url":
|
|
166
|
+
case "data": if (getTopLevelMediaType(part.mediaType) === "image") return {
|
|
167
|
+
type: "image_url",
|
|
168
|
+
image_url: { url: formatImageUrl({ part }) },
|
|
169
|
+
...partCacheControl ? { cache_control: partCacheControl } : {}
|
|
170
|
+
};
|
|
171
|
+
else throw new UnsupportedFunctionalityError({ functionality: "Only image file parts are supported" });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
177
|
+
case "assistant": {
|
|
178
|
+
let text = "";
|
|
179
|
+
let reasoningContent = "";
|
|
180
|
+
const toolCalls = [];
|
|
181
|
+
for (const part of content) switch (part.type) {
|
|
182
|
+
case "text":
|
|
183
|
+
text += part.text;
|
|
184
|
+
break;
|
|
185
|
+
case "tool-call":
|
|
186
|
+
toolCalls.push({
|
|
187
|
+
id: part.toolCallId,
|
|
188
|
+
type: "function",
|
|
189
|
+
function: {
|
|
190
|
+
name: part.toolName,
|
|
191
|
+
arguments: JSON.stringify(part.input)
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
break;
|
|
195
|
+
case "reasoning": if (preserveThinking || index > lastUserMessageIndex) reasoningContent += part.text;
|
|
196
|
+
}
|
|
197
|
+
if (text.length === 0 && toolCalls.length === 0 && reasoningContent.length === 0) break;
|
|
198
|
+
messages.push({
|
|
199
|
+
role: "assistant",
|
|
200
|
+
content: text.length === 0 && toolCalls.length === 0 && reasoningContent.length > 0 ? null : messageCacheControl ? [{
|
|
201
|
+
type: "text",
|
|
202
|
+
text,
|
|
203
|
+
cache_control: messageCacheControl
|
|
204
|
+
}] : text || null,
|
|
205
|
+
...reasoningContent.length > 0 ? { reasoning_content: reasoningContent } : {},
|
|
206
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
207
|
+
});
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case "tool": {
|
|
211
|
+
const toolResponses = content.filter((r) => r.type !== "tool-approval-response");
|
|
212
|
+
for (let i = 0; i < toolResponses.length; i++) {
|
|
213
|
+
const toolResponse = toolResponses[i];
|
|
214
|
+
const output = toolResponse.output;
|
|
215
|
+
const isLastPart = i === toolResponses.length - 1;
|
|
216
|
+
const partCacheControl = cacheControlValidator?.getCacheControl(toolResponse.providerOptions) ?? (isLastPart ? messageCacheControl : void 0);
|
|
217
|
+
let contentValue;
|
|
218
|
+
switch (output.type) {
|
|
219
|
+
case "text":
|
|
220
|
+
case "error-text":
|
|
221
|
+
contentValue = output.value;
|
|
222
|
+
break;
|
|
223
|
+
case "execution-denied":
|
|
224
|
+
contentValue = output.reason ?? "Tool call execution denied.";
|
|
225
|
+
break;
|
|
226
|
+
case "content":
|
|
227
|
+
case "json":
|
|
228
|
+
case "error-json": contentValue = JSON.stringify(output.value);
|
|
229
|
+
}
|
|
230
|
+
messages.push({
|
|
231
|
+
role: "tool",
|
|
232
|
+
tool_call_id: toolResponse.toolCallId,
|
|
233
|
+
content: partCacheControl ? [{
|
|
234
|
+
type: "text",
|
|
235
|
+
text: contentValue,
|
|
236
|
+
cache_control: partCacheControl
|
|
237
|
+
}] : contentValue
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
default: throw new Error(`Unsupported role: ${role}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return messages;
|
|
356
246
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/get-cache-control.ts
|
|
249
|
+
const MAX_CACHE_BREAKPOINTS = 4;
|
|
360
250
|
function getCacheControl(providerMetadata) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return cacheControlValue;
|
|
251
|
+
const alibaba = providerMetadata?.alibaba;
|
|
252
|
+
return alibaba?.cacheControl ?? alibaba?.cache_control;
|
|
364
253
|
}
|
|
365
254
|
var CacheControlValidator = class {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
getWarnings() {
|
|
385
|
-
return this.warnings;
|
|
386
|
-
}
|
|
255
|
+
constructor() {
|
|
256
|
+
this.breakpointCount = 0;
|
|
257
|
+
this.warnings = [];
|
|
258
|
+
}
|
|
259
|
+
getCacheControl(providerMetadata) {
|
|
260
|
+
const cacheControlValue = getCacheControl(providerMetadata);
|
|
261
|
+
if (!cacheControlValue) return;
|
|
262
|
+
this.breakpointCount++;
|
|
263
|
+
if (this.breakpointCount > MAX_CACHE_BREAKPOINTS) this.warnings.push({
|
|
264
|
+
type: "other",
|
|
265
|
+
message: `Max breakpoint limit exceeded. Only the last ${MAX_CACHE_BREAKPOINTS} cache markers will take effect.`
|
|
266
|
+
});
|
|
267
|
+
return cacheControlValue;
|
|
268
|
+
}
|
|
269
|
+
getWarnings() {
|
|
270
|
+
return this.warnings;
|
|
271
|
+
}
|
|
387
272
|
};
|
|
388
|
-
|
|
389
|
-
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/map-alibaba-finish-reason.ts
|
|
390
275
|
function mapAlibabaFinishReason(finishReason) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
case "tool_calls":
|
|
400
|
-
return "tool-calls";
|
|
401
|
-
default:
|
|
402
|
-
return "other";
|
|
403
|
-
}
|
|
276
|
+
switch (finishReason) {
|
|
277
|
+
case "stop": return "stop";
|
|
278
|
+
case "length": return "length";
|
|
279
|
+
case "content_filter": return "content-filter";
|
|
280
|
+
case "function_call":
|
|
281
|
+
case "tool_calls": return "tool-calls";
|
|
282
|
+
default: return "other";
|
|
283
|
+
}
|
|
404
284
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
285
|
+
//#endregion
|
|
286
|
+
//#region src/supports-json-schema-output.ts
|
|
287
|
+
const JSON_SCHEMA_MODEL_PREFIXES = [
|
|
288
|
+
"qwen3.7-plus",
|
|
289
|
+
"qwen3.7-flash",
|
|
290
|
+
"qwen3.7-max",
|
|
291
|
+
"qwen3.8-max",
|
|
292
|
+
"qwen3.8-flash"
|
|
413
293
|
];
|
|
414
294
|
function supportsJsonSchemaOutput(modelId) {
|
|
415
|
-
|
|
416
|
-
(prefix) => modelId === prefix || modelId.startsWith(`${prefix}-`)
|
|
417
|
-
);
|
|
295
|
+
return JSON_SCHEMA_MODEL_PREFIXES.some((prefix) => modelId === prefix || modelId.startsWith(`${prefix}-`));
|
|
418
296
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/supports-preserved-thinking.ts
|
|
299
|
+
/**
|
|
300
|
+
* Whether a model id supports Alibaba's preserved-thinking mode
|
|
301
|
+
* (`preserve_thinking`), which replays assistant `reasoning_content` from
|
|
302
|
+
* previous turns.
|
|
303
|
+
*
|
|
304
|
+
* Supported models per Alibaba's documentation:
|
|
305
|
+
* https://docs.qwencloud.com/developer-guides/text-generation/thinking#preserve-thinking-in-multi-turn
|
|
306
|
+
*/
|
|
307
|
+
const preservedThinkingModelIds = /* @__PURE__ */ new Set([
|
|
308
|
+
"kimi-k2.7-code",
|
|
309
|
+
"qwen3.6-max-preview",
|
|
310
|
+
"qwen3.6-plus",
|
|
311
|
+
"qwen3.6-plus-2026-04-02",
|
|
312
|
+
"qwen3.7-flash",
|
|
313
|
+
"qwen3.7-flash-2026-07-15",
|
|
314
|
+
"qwen3.7-max",
|
|
315
|
+
"qwen3.7-max-2026-05-17",
|
|
316
|
+
"qwen3.7-max-2026-05-20",
|
|
317
|
+
"qwen3.7-max-2026-06-08",
|
|
318
|
+
"qwen3.7-max-preview",
|
|
319
|
+
"qwen3.7-plus",
|
|
320
|
+
"qwen3.7-plus-2026-05-26",
|
|
321
|
+
"qwen3.8-flash",
|
|
322
|
+
"qwen3.8-max",
|
|
323
|
+
"qwen3.8-max-0902"
|
|
438
324
|
]);
|
|
439
325
|
function supportsPreservedThinking(modelId) {
|
|
440
|
-
|
|
326
|
+
return preservedThinkingModelIds.has(modelId);
|
|
441
327
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
controller.enqueue({
|
|
733
|
-
type: "reasoning-end",
|
|
734
|
-
id: activeReasoningId
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
if (activeText) {
|
|
738
|
-
controller.enqueue({ type: "text-end", id: "0" });
|
|
739
|
-
}
|
|
740
|
-
toolCallTracker.flush();
|
|
741
|
-
controller.enqueue({
|
|
742
|
-
type: "finish",
|
|
743
|
-
finishReason,
|
|
744
|
-
usage: convertAlibabaUsage(usage)
|
|
745
|
-
});
|
|
746
|
-
}
|
|
747
|
-
})
|
|
748
|
-
),
|
|
749
|
-
request: { body: JSON.stringify(body) },
|
|
750
|
-
response: { headers: responseHeaders }
|
|
751
|
-
};
|
|
752
|
-
}
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region src/alibaba-chat-language-model.ts
|
|
330
|
+
/**
|
|
331
|
+
* Alibaba language model implementation.
|
|
332
|
+
*
|
|
333
|
+
* Implements LanguageModelV4 interface for Alibaba Cloud's Qwen models.
|
|
334
|
+
* Supports OpenAI-compatible chat completions API with Alibaba-specific features:
|
|
335
|
+
* - Reasoning/thinking mode (enable_thinking, reasoning_content)
|
|
336
|
+
* - Thinking budget control (thinking_budget)
|
|
337
|
+
* - Prompt caching (cached_tokens tracking)
|
|
338
|
+
*/
|
|
339
|
+
var AlibabaChatLanguageModel = class AlibabaChatLanguageModel {
|
|
340
|
+
static [WORKFLOW_SERIALIZE](model) {
|
|
341
|
+
return serializeModelOptions({
|
|
342
|
+
modelId: model.modelId,
|
|
343
|
+
config: model.config
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
static [WORKFLOW_DESERIALIZE](options) {
|
|
347
|
+
return new AlibabaChatLanguageModel(options.modelId, options.config);
|
|
348
|
+
}
|
|
349
|
+
constructor(modelId, config) {
|
|
350
|
+
this.specificationVersion = "v4";
|
|
351
|
+
this.supportedUrls = { "image/*": [/^https?:\/\/.*$/] };
|
|
352
|
+
this.modelId = modelId;
|
|
353
|
+
this.config = config;
|
|
354
|
+
}
|
|
355
|
+
get provider() {
|
|
356
|
+
return this.config.provider;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Builds request arguments for Alibaba API call.
|
|
360
|
+
* Converts AI SDK options to Alibaba API format.
|
|
361
|
+
*/
|
|
362
|
+
async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, stopSequences, responseFormat, seed, reasoning, providerOptions, tools, toolChoice }) {
|
|
363
|
+
const warnings = [];
|
|
364
|
+
const cacheControlValidator = new CacheControlValidator();
|
|
365
|
+
const alibabaOptions = await parseProviderOptions({
|
|
366
|
+
provider: "alibaba",
|
|
367
|
+
providerOptions,
|
|
368
|
+
schema: alibabaLanguageModelChatOptions
|
|
369
|
+
});
|
|
370
|
+
if (frequencyPenalty != null) warnings.push({
|
|
371
|
+
type: "unsupported",
|
|
372
|
+
feature: "frequencyPenalty"
|
|
373
|
+
});
|
|
374
|
+
const preserveThinking = alibabaOptions?.preserveThinking ?? (supportsPreservedThinking(this.modelId) ? true : void 0);
|
|
375
|
+
const useJsonSchema = responseFormat?.type === "json" && responseFormat.schema != null && supportsJsonSchemaOutput(this.modelId);
|
|
376
|
+
const useJsonObject = responseFormat?.type === "json" && !useJsonSchema;
|
|
377
|
+
if (useJsonObject && responseFormat.schema != null) warnings.push({
|
|
378
|
+
type: "compatibility",
|
|
379
|
+
feature: "responseFormat JSON schema",
|
|
380
|
+
details: `Alibaba does not support JSON Schema output for model ${this.modelId}. JSON Object mode is used instead. The schema was injected into the system message and will only be validated locally.`
|
|
381
|
+
});
|
|
382
|
+
const resolvedPrompt = useJsonObject ? injectJsonInstructionIntoMessages({
|
|
383
|
+
messages: prompt,
|
|
384
|
+
schema: responseFormat.schema
|
|
385
|
+
}) : prompt;
|
|
386
|
+
const baseArgs = {
|
|
387
|
+
model: this.modelId,
|
|
388
|
+
max_tokens: maxOutputTokens,
|
|
389
|
+
temperature,
|
|
390
|
+
top_p: topP,
|
|
391
|
+
top_k: topK,
|
|
392
|
+
presence_penalty: presencePenalty,
|
|
393
|
+
stop: stopSequences,
|
|
394
|
+
seed,
|
|
395
|
+
response_format: responseFormat?.type === "json" ? useJsonSchema ? {
|
|
396
|
+
type: "json_schema",
|
|
397
|
+
json_schema: {
|
|
398
|
+
schema: responseFormat.schema,
|
|
399
|
+
name: responseFormat.name ?? "response",
|
|
400
|
+
description: responseFormat.description
|
|
401
|
+
}
|
|
402
|
+
} : { type: "json_object" } : void 0,
|
|
403
|
+
...resolveAlibabaThinking({
|
|
404
|
+
reasoning,
|
|
405
|
+
alibabaOptions,
|
|
406
|
+
warnings
|
|
407
|
+
}),
|
|
408
|
+
...preserveThinking != null ? { preserve_thinking: preserveThinking } : {},
|
|
409
|
+
messages: convertToAlibabaChatMessages({
|
|
410
|
+
prompt: resolvedPrompt,
|
|
411
|
+
cacheControlValidator,
|
|
412
|
+
preserveThinking: preserveThinking ?? false
|
|
413
|
+
})
|
|
414
|
+
};
|
|
415
|
+
const { tools: alibabaTools, toolChoice: alibabaToolChoice, toolWarnings } = prepareTools({
|
|
416
|
+
tools,
|
|
417
|
+
toolChoice
|
|
418
|
+
});
|
|
419
|
+
warnings.push(...cacheControlValidator.getWarnings());
|
|
420
|
+
return {
|
|
421
|
+
args: {
|
|
422
|
+
...baseArgs,
|
|
423
|
+
tools: alibabaTools,
|
|
424
|
+
tool_choice: alibabaToolChoice,
|
|
425
|
+
...alibabaTools != null && alibabaOptions?.parallelToolCalls !== void 0 ? { parallel_tool_calls: alibabaOptions.parallelToolCalls } : {}
|
|
426
|
+
},
|
|
427
|
+
warnings: [...warnings, ...toolWarnings]
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
async doGenerate(options) {
|
|
431
|
+
const { args, warnings } = await this.getArgs(options);
|
|
432
|
+
const { responseHeaders, value: response, rawValue: rawResponse } = await postJsonToApi({
|
|
433
|
+
url: `${this.config.baseURL}/chat/completions`,
|
|
434
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
435
|
+
body: args,
|
|
436
|
+
failedResponseHandler: alibabaFailedResponseHandler,
|
|
437
|
+
successfulResponseHandler: createJsonResponseHandler(alibabaChatResponseSchema),
|
|
438
|
+
abortSignal: options.abortSignal,
|
|
439
|
+
fetch: this.config.fetch
|
|
440
|
+
});
|
|
441
|
+
const choice = response.choices[0];
|
|
442
|
+
const content = [];
|
|
443
|
+
const text = choice.message.content;
|
|
444
|
+
if (text != null && text.length > 0) content.push({
|
|
445
|
+
type: "text",
|
|
446
|
+
text
|
|
447
|
+
});
|
|
448
|
+
const reasoning = choice.message.reasoning_content;
|
|
449
|
+
if (reasoning != null && reasoning.length > 0) content.push({
|
|
450
|
+
type: "reasoning",
|
|
451
|
+
text: reasoning
|
|
452
|
+
});
|
|
453
|
+
if (choice.message.tool_calls != null) for (const toolCall of choice.message.tool_calls) content.push({
|
|
454
|
+
type: "tool-call",
|
|
455
|
+
toolCallId: toolCall.id || generateId(),
|
|
456
|
+
toolName: toolCall.function.name,
|
|
457
|
+
input: toolCall.function.arguments
|
|
458
|
+
});
|
|
459
|
+
return {
|
|
460
|
+
content,
|
|
461
|
+
finishReason: {
|
|
462
|
+
unified: mapAlibabaFinishReason(choice.finish_reason),
|
|
463
|
+
raw: choice.finish_reason ?? void 0
|
|
464
|
+
},
|
|
465
|
+
usage: convertAlibabaUsage(response.usage),
|
|
466
|
+
request: { body: JSON.stringify(args) },
|
|
467
|
+
response: {
|
|
468
|
+
...createLanguageModelResponseMetadata(response),
|
|
469
|
+
headers: responseHeaders,
|
|
470
|
+
body: rawResponse
|
|
471
|
+
},
|
|
472
|
+
warnings
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
async doStream(options) {
|
|
476
|
+
const { args, warnings } = await this.getArgs(options);
|
|
477
|
+
const body = {
|
|
478
|
+
...args,
|
|
479
|
+
stream: true,
|
|
480
|
+
stream_options: this.config.includeUsage ? { include_usage: true } : void 0
|
|
481
|
+
};
|
|
482
|
+
const { responseHeaders, value: response } = await postJsonToApi({
|
|
483
|
+
url: `${this.config.baseURL}/chat/completions`,
|
|
484
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
485
|
+
body,
|
|
486
|
+
failedResponseHandler: alibabaFailedResponseHandler,
|
|
487
|
+
successfulResponseHandler: createEventSourceResponseHandler(alibabaChatChunkSchema),
|
|
488
|
+
abortSignal: options.abortSignal,
|
|
489
|
+
fetch: this.config.fetch
|
|
490
|
+
});
|
|
491
|
+
let finishReason = {
|
|
492
|
+
unified: "other",
|
|
493
|
+
raw: void 0
|
|
494
|
+
};
|
|
495
|
+
let usage = void 0;
|
|
496
|
+
let isFirstChunk = true;
|
|
497
|
+
let activeText = false;
|
|
498
|
+
let activeReasoningId = null;
|
|
499
|
+
let toolCallTracker;
|
|
500
|
+
return {
|
|
501
|
+
stream: response.pipeThrough(new TransformStream({
|
|
502
|
+
start(controller) {
|
|
503
|
+
toolCallTracker = new StreamingToolCallTracker(controller, { generateId });
|
|
504
|
+
controller.enqueue({
|
|
505
|
+
type: "stream-start",
|
|
506
|
+
warnings
|
|
507
|
+
});
|
|
508
|
+
},
|
|
509
|
+
transform(chunk, controller) {
|
|
510
|
+
if (options.includeRawChunks) controller.enqueue({
|
|
511
|
+
type: "raw",
|
|
512
|
+
rawValue: chunk.rawValue
|
|
513
|
+
});
|
|
514
|
+
if (!chunk.success) {
|
|
515
|
+
controller.enqueue({
|
|
516
|
+
type: "error",
|
|
517
|
+
error: chunk.error
|
|
518
|
+
});
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
const value = chunk.value;
|
|
522
|
+
if (isFirstChunk) {
|
|
523
|
+
isFirstChunk = false;
|
|
524
|
+
controller.enqueue({
|
|
525
|
+
type: "response-metadata",
|
|
526
|
+
...createLanguageModelResponseMetadata(value)
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
if (value.usage != null) usage = value.usage;
|
|
530
|
+
if (value.choices.length === 0) return;
|
|
531
|
+
const choice = value.choices[0];
|
|
532
|
+
const delta = choice.delta;
|
|
533
|
+
if (delta.reasoning_content != null && delta.reasoning_content.length > 0) {
|
|
534
|
+
if (activeReasoningId == null) {
|
|
535
|
+
if (activeText) {
|
|
536
|
+
controller.enqueue({
|
|
537
|
+
type: "text-end",
|
|
538
|
+
id: "0"
|
|
539
|
+
});
|
|
540
|
+
activeText = false;
|
|
541
|
+
}
|
|
542
|
+
activeReasoningId = generateId();
|
|
543
|
+
controller.enqueue({
|
|
544
|
+
type: "reasoning-start",
|
|
545
|
+
id: activeReasoningId
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
controller.enqueue({
|
|
549
|
+
type: "reasoning-delta",
|
|
550
|
+
id: activeReasoningId,
|
|
551
|
+
delta: delta.reasoning_content
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
if (delta.content != null && delta.content.length > 0) {
|
|
555
|
+
if (activeReasoningId != null) {
|
|
556
|
+
controller.enqueue({
|
|
557
|
+
type: "reasoning-end",
|
|
558
|
+
id: activeReasoningId
|
|
559
|
+
});
|
|
560
|
+
activeReasoningId = null;
|
|
561
|
+
}
|
|
562
|
+
if (!activeText) {
|
|
563
|
+
controller.enqueue({
|
|
564
|
+
type: "text-start",
|
|
565
|
+
id: "0"
|
|
566
|
+
});
|
|
567
|
+
activeText = true;
|
|
568
|
+
}
|
|
569
|
+
controller.enqueue({
|
|
570
|
+
type: "text-delta",
|
|
571
|
+
id: "0",
|
|
572
|
+
delta: delta.content
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
if (delta.tool_calls != null && delta.tool_calls.length > 0) {
|
|
576
|
+
if (activeReasoningId != null) {
|
|
577
|
+
controller.enqueue({
|
|
578
|
+
type: "reasoning-end",
|
|
579
|
+
id: activeReasoningId
|
|
580
|
+
});
|
|
581
|
+
activeReasoningId = null;
|
|
582
|
+
}
|
|
583
|
+
if (activeText) {
|
|
584
|
+
controller.enqueue({
|
|
585
|
+
type: "text-end",
|
|
586
|
+
id: "0"
|
|
587
|
+
});
|
|
588
|
+
activeText = false;
|
|
589
|
+
}
|
|
590
|
+
for (const toolCallDelta of delta.tool_calls) toolCallTracker.processDelta(toolCallDelta);
|
|
591
|
+
}
|
|
592
|
+
if (choice.finish_reason != null) finishReason = {
|
|
593
|
+
unified: mapAlibabaFinishReason(choice.finish_reason),
|
|
594
|
+
raw: choice.finish_reason
|
|
595
|
+
};
|
|
596
|
+
},
|
|
597
|
+
flush(controller) {
|
|
598
|
+
if (activeReasoningId != null) controller.enqueue({
|
|
599
|
+
type: "reasoning-end",
|
|
600
|
+
id: activeReasoningId
|
|
601
|
+
});
|
|
602
|
+
if (activeText) controller.enqueue({
|
|
603
|
+
type: "text-end",
|
|
604
|
+
id: "0"
|
|
605
|
+
});
|
|
606
|
+
toolCallTracker.flush();
|
|
607
|
+
controller.enqueue({
|
|
608
|
+
type: "finish",
|
|
609
|
+
finishReason,
|
|
610
|
+
usage: convertAlibabaUsage(usage)
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
})),
|
|
614
|
+
request: { body: JSON.stringify(body) },
|
|
615
|
+
response: { headers: responseHeaders }
|
|
616
|
+
};
|
|
617
|
+
}
|
|
753
618
|
};
|
|
754
|
-
function resolveAlibabaThinking({
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const thinkingBudget = mapReasoningToProviderBudget({
|
|
772
|
-
reasoning,
|
|
773
|
-
maxOutputTokens: 16384,
|
|
774
|
-
maxReasoningBudget: 16384,
|
|
775
|
-
warnings
|
|
776
|
-
});
|
|
777
|
-
return {
|
|
778
|
-
enable_thinking: true,
|
|
779
|
-
...thinkingBudget != null ? { thinking_budget: thinkingBudget } : {}
|
|
780
|
-
};
|
|
619
|
+
function resolveAlibabaThinking({ reasoning, alibabaOptions, warnings }) {
|
|
620
|
+
if (alibabaOptions?.enableThinking != null || alibabaOptions?.thinkingBudget != null) return {
|
|
621
|
+
...alibabaOptions.enableThinking != null ? { enable_thinking: alibabaOptions.enableThinking } : {},
|
|
622
|
+
...alibabaOptions.thinkingBudget != null ? { thinking_budget: alibabaOptions.thinkingBudget } : {}
|
|
623
|
+
};
|
|
624
|
+
if (!isCustomReasoning(reasoning)) return {};
|
|
625
|
+
if (reasoning === "none") return { enable_thinking: false };
|
|
626
|
+
const thinkingBudget = mapReasoningToProviderBudget({
|
|
627
|
+
reasoning,
|
|
628
|
+
maxOutputTokens: 16384,
|
|
629
|
+
maxReasoningBudget: 16384,
|
|
630
|
+
warnings
|
|
631
|
+
});
|
|
632
|
+
return {
|
|
633
|
+
enable_thinking: true,
|
|
634
|
+
...thinkingBudget != null ? { thinking_budget: thinkingBudget } : {}
|
|
635
|
+
};
|
|
781
636
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
637
|
+
/**
|
|
638
|
+
* Reference for schemas below:
|
|
639
|
+
* https://www.alibabacloud.com/help/en/model-studio/qwen-api-via-openai-chat-completions
|
|
640
|
+
*/
|
|
641
|
+
const alibabaUsageSchema = z.looseObject({
|
|
642
|
+
prompt_tokens: z.number(),
|
|
643
|
+
completion_tokens: z.number(),
|
|
644
|
+
total_tokens: z.number(),
|
|
645
|
+
prompt_tokens_details: z.looseObject({
|
|
646
|
+
cached_tokens: z.number().nullish(),
|
|
647
|
+
cache_creation_input_tokens: z.number().nullish(),
|
|
648
|
+
cache_type: z.string().nullish()
|
|
649
|
+
}).nullish(),
|
|
650
|
+
completion_tokens_details: z.looseObject({ reasoning_tokens: z.number().nullish() }).nullish()
|
|
794
651
|
});
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
finish_reason: z3.string().nullish(),
|
|
818
|
-
index: z3.number()
|
|
819
|
-
})
|
|
820
|
-
),
|
|
821
|
-
usage: alibabaUsageSchema.nullish()
|
|
652
|
+
const alibabaChatResponseSchema = z.object({
|
|
653
|
+
id: z.string().nullish(),
|
|
654
|
+
created: z.number().nullish(),
|
|
655
|
+
model: z.string().nullish(),
|
|
656
|
+
choices: z.array(z.object({
|
|
657
|
+
message: z.object({
|
|
658
|
+
role: z.literal("assistant").nullish(),
|
|
659
|
+
content: z.string().nullish(),
|
|
660
|
+
reasoning_content: z.string().nullish(),
|
|
661
|
+
tool_calls: z.array(z.object({
|
|
662
|
+
id: z.string(),
|
|
663
|
+
type: z.literal("function"),
|
|
664
|
+
function: z.object({
|
|
665
|
+
name: z.string(),
|
|
666
|
+
arguments: z.string()
|
|
667
|
+
})
|
|
668
|
+
})).nullish()
|
|
669
|
+
}),
|
|
670
|
+
finish_reason: z.string().nullish(),
|
|
671
|
+
index: z.number()
|
|
672
|
+
})),
|
|
673
|
+
usage: alibabaUsageSchema.nullish()
|
|
822
674
|
});
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}),
|
|
847
|
-
finish_reason: z3.string().nullish(),
|
|
848
|
-
index: z3.number()
|
|
849
|
-
})
|
|
850
|
-
),
|
|
851
|
-
usage: alibabaUsageSchema.nullish()
|
|
852
|
-
// Usage only appears in final chunk
|
|
675
|
+
const alibabaChatChunkSchema = z.object({
|
|
676
|
+
id: z.string().nullish(),
|
|
677
|
+
created: z.number().nullish(),
|
|
678
|
+
model: z.string().nullish(),
|
|
679
|
+
choices: z.array(z.object({
|
|
680
|
+
delta: z.object({
|
|
681
|
+
role: z.enum(["assistant"]).nullish(),
|
|
682
|
+
content: z.string().nullish(),
|
|
683
|
+
reasoning_content: z.string().nullish(),
|
|
684
|
+
tool_calls: z.array(z.object({
|
|
685
|
+
index: z.number().nullish(),
|
|
686
|
+
id: z.string().nullish(),
|
|
687
|
+
type: z.literal("function").nullish(),
|
|
688
|
+
function: z.object({
|
|
689
|
+
name: z.string().nullish(),
|
|
690
|
+
arguments: z.string().nullish()
|
|
691
|
+
}).nullish()
|
|
692
|
+
})).nullish()
|
|
693
|
+
}),
|
|
694
|
+
finish_reason: z.string().nullish(),
|
|
695
|
+
index: z.number()
|
|
696
|
+
})),
|
|
697
|
+
usage: alibabaUsageSchema.nullish()
|
|
853
698
|
});
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
textType: z4.enum(["query", "document"]).optional(),
|
|
880
|
-
/**
|
|
881
|
-
* The dimension of the output embedding vectors. Defaults to 1024.
|
|
882
|
-
*
|
|
883
|
-
* `text-embedding-v4` also supports 1536 and 2048 dimensions.
|
|
884
|
-
*/
|
|
885
|
-
dimension: z4.number().optional(),
|
|
886
|
-
/**
|
|
887
|
-
* The output vector type. Defaults to `dense`.
|
|
888
|
-
*
|
|
889
|
-
* Sparse-only output is not supported by the AI SDK embedding interface,
|
|
890
|
-
* which requires dense number arrays.
|
|
891
|
-
*/
|
|
892
|
-
outputType: z4.enum(["dense", "sparse", "dense&sparse"]).optional()
|
|
699
|
+
//#endregion
|
|
700
|
+
//#region src/alibaba-embedding-model-options.ts
|
|
701
|
+
const alibabaEmbeddingModelOptions = z.object({
|
|
702
|
+
/**
|
|
703
|
+
* Differentiates query text from document text for asymmetric retrieval tasks.
|
|
704
|
+
* Defaults to `document`.
|
|
705
|
+
*/
|
|
706
|
+
textType: z.enum(["query", "document"]).optional(),
|
|
707
|
+
/**
|
|
708
|
+
* The dimension of the output embedding vectors. Defaults to 1024.
|
|
709
|
+
*
|
|
710
|
+
* `text-embedding-v4` also supports 1536 and 2048 dimensions.
|
|
711
|
+
*/
|
|
712
|
+
dimension: z.number().optional(),
|
|
713
|
+
/**
|
|
714
|
+
* The output vector type. Defaults to `dense`.
|
|
715
|
+
*
|
|
716
|
+
* Sparse-only output is not supported by the AI SDK embedding interface,
|
|
717
|
+
* which requires dense number arrays.
|
|
718
|
+
*/
|
|
719
|
+
outputType: z.enum([
|
|
720
|
+
"dense",
|
|
721
|
+
"sparse",
|
|
722
|
+
"dense&sparse"
|
|
723
|
+
]).optional()
|
|
893
724
|
});
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
725
|
+
//#endregion
|
|
726
|
+
//#region src/alibaba-embedding-model.ts
|
|
727
|
+
const alibabaEmbeddingFailedResponseHandler = createJsonErrorResponseHandler({
|
|
728
|
+
errorSchema: z.object({
|
|
729
|
+
code: z.string().nullish(),
|
|
730
|
+
message: z.string(),
|
|
731
|
+
request_id: z.string().nullish()
|
|
732
|
+
}),
|
|
733
|
+
errorToMessage: (data) => data.message
|
|
903
734
|
});
|
|
904
|
-
var AlibabaEmbeddingModel = class
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
});
|
|
974
|
-
const sortedEmbeddings = response.output.embeddings.sort(
|
|
975
|
-
(a, b) => a.text_index - b.text_index
|
|
976
|
-
);
|
|
977
|
-
const sparseEmbeddings = sortedEmbeddings.map(
|
|
978
|
-
(item) => item.sparse_embedding == null ? void 0 : {
|
|
979
|
-
textIndex: item.text_index,
|
|
980
|
-
sparseEmbedding: item.sparse_embedding
|
|
981
|
-
}
|
|
982
|
-
).filter((item) => item != null);
|
|
983
|
-
return {
|
|
984
|
-
warnings: [],
|
|
985
|
-
embeddings: sortedEmbeddings.map((item) => item.embedding),
|
|
986
|
-
usage: response.usage ? { tokens: response.usage.total_tokens } : void 0,
|
|
987
|
-
providerMetadata: sparseEmbeddings.length > 0 ? {
|
|
988
|
-
alibaba: {
|
|
989
|
-
sparseEmbeddings
|
|
990
|
-
}
|
|
991
|
-
} : void 0,
|
|
992
|
-
response: { headers: responseHeaders, body: rawValue }
|
|
993
|
-
};
|
|
994
|
-
}
|
|
735
|
+
var AlibabaEmbeddingModel = class AlibabaEmbeddingModel {
|
|
736
|
+
static [WORKFLOW_SERIALIZE](model) {
|
|
737
|
+
return serializeModelOptions({
|
|
738
|
+
modelId: model.modelId,
|
|
739
|
+
config: model.config
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
static [WORKFLOW_DESERIALIZE](options) {
|
|
743
|
+
return new AlibabaEmbeddingModel(options.modelId, options.config);
|
|
744
|
+
}
|
|
745
|
+
constructor(modelId, config) {
|
|
746
|
+
this.specificationVersion = "v4";
|
|
747
|
+
this.maxEmbeddingsPerCall = 10;
|
|
748
|
+
this.supportsParallelCalls = false;
|
|
749
|
+
this.modelId = modelId;
|
|
750
|
+
this.config = config;
|
|
751
|
+
}
|
|
752
|
+
get provider() {
|
|
753
|
+
return this.config.provider;
|
|
754
|
+
}
|
|
755
|
+
async doEmbed({ values, headers, abortSignal, providerOptions }) {
|
|
756
|
+
if (values.length > this.maxEmbeddingsPerCall) throw new TooManyEmbeddingValuesForCallError({
|
|
757
|
+
provider: this.provider,
|
|
758
|
+
modelId: this.modelId,
|
|
759
|
+
maxEmbeddingsPerCall: this.maxEmbeddingsPerCall,
|
|
760
|
+
values
|
|
761
|
+
});
|
|
762
|
+
const alibabaOptions = await parseProviderOptions({
|
|
763
|
+
provider: "alibaba",
|
|
764
|
+
providerOptions,
|
|
765
|
+
schema: alibabaEmbeddingModelOptions
|
|
766
|
+
});
|
|
767
|
+
if (alibabaOptions?.outputType === "sparse") throw new UnsupportedFunctionalityError({
|
|
768
|
+
functionality: "Alibaba embedding outputType 'sparse'",
|
|
769
|
+
message: "Alibaba embedding outputType 'sparse' is not supported because AI SDK embeddings require dense number arrays. Use 'dense' or 'dense&sparse' instead."
|
|
770
|
+
});
|
|
771
|
+
const { responseHeaders, value: response, rawValue } = await postJsonToApi({
|
|
772
|
+
url: `${this.config.baseURL}/services/embeddings/text-embedding/text-embedding`,
|
|
773
|
+
headers: combineHeaders(this.config.headers?.(), headers),
|
|
774
|
+
body: {
|
|
775
|
+
model: this.modelId,
|
|
776
|
+
input: { texts: values },
|
|
777
|
+
parameters: {
|
|
778
|
+
text_type: alibabaOptions?.textType,
|
|
779
|
+
dimension: alibabaOptions?.dimension,
|
|
780
|
+
output_type: alibabaOptions?.outputType
|
|
781
|
+
}
|
|
782
|
+
},
|
|
783
|
+
failedResponseHandler: alibabaEmbeddingFailedResponseHandler,
|
|
784
|
+
successfulResponseHandler: createJsonResponseHandler(alibabaTextEmbeddingResponseSchema),
|
|
785
|
+
abortSignal,
|
|
786
|
+
fetch: this.config.fetch
|
|
787
|
+
});
|
|
788
|
+
const sortedEmbeddings = response.output.embeddings.sort((a, b) => a.text_index - b.text_index);
|
|
789
|
+
const sparseEmbeddings = sortedEmbeddings.map((item) => item.sparse_embedding == null ? void 0 : {
|
|
790
|
+
textIndex: item.text_index,
|
|
791
|
+
sparseEmbedding: item.sparse_embedding
|
|
792
|
+
}).filter((item) => item != null);
|
|
793
|
+
return {
|
|
794
|
+
warnings: [],
|
|
795
|
+
embeddings: sortedEmbeddings.map((item) => item.embedding),
|
|
796
|
+
usage: response.usage ? { tokens: response.usage.total_tokens } : void 0,
|
|
797
|
+
providerMetadata: sparseEmbeddings.length > 0 ? { alibaba: { sparseEmbeddings } } : void 0,
|
|
798
|
+
response: {
|
|
799
|
+
headers: responseHeaders,
|
|
800
|
+
body: rawValue
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
}
|
|
995
804
|
};
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
805
|
+
const alibabaTextEmbeddingSparseEmbeddingSchema = z.object({
|
|
806
|
+
index: z.number(),
|
|
807
|
+
value: z.number(),
|
|
808
|
+
token: z.string().nullish()
|
|
1000
809
|
});
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
})
|
|
1009
|
-
)
|
|
1010
|
-
}),
|
|
1011
|
-
usage: z5.object({
|
|
1012
|
-
total_tokens: z5.number()
|
|
1013
|
-
}).nullish()
|
|
810
|
+
const alibabaTextEmbeddingResponseSchema = z.object({
|
|
811
|
+
output: z.object({ embeddings: z.array(z.object({
|
|
812
|
+
embedding: z.array(z.number()),
|
|
813
|
+
text_index: z.number(),
|
|
814
|
+
sparse_embedding: z.array(alibabaTextEmbeddingSparseEmbeddingSchema).nullish()
|
|
815
|
+
})) }),
|
|
816
|
+
usage: z.object({ total_tokens: z.number() }).nullish()
|
|
1014
817
|
});
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
"link"
|
|
1056
|
-
]),
|
|
1057
|
-
url: z6.string(),
|
|
1058
|
-
referenceVoice: z6.string().nullish()
|
|
1059
|
-
})
|
|
1060
|
-
).nullish(),
|
|
1061
|
-
ratio: z6.enum(["adaptive", "16:9", "9:16", "1:1", "4:3", "3:4"]).nullish(),
|
|
1062
|
-
pollIntervalMs: z6.number().positive().nullish(),
|
|
1063
|
-
pollTimeoutMs: z6.number().positive().nullish()
|
|
1064
|
-
})
|
|
1065
|
-
)
|
|
1066
|
-
);
|
|
1067
|
-
|
|
1068
|
-
// src/alibaba-video-model.ts
|
|
1069
|
-
var alibabaVideoErrorSchema = z7.object({
|
|
1070
|
-
code: z7.string().nullish(),
|
|
1071
|
-
message: z7.string(),
|
|
1072
|
-
request_id: z7.string().nullish()
|
|
818
|
+
//#endregion
|
|
819
|
+
//#region src/alibaba-video-model-options.ts
|
|
820
|
+
const alibabaVideoModelOptionsSchema = lazySchema(() => zodSchema(z.looseObject({
|
|
821
|
+
negativePrompt: z.string().nullish(),
|
|
822
|
+
audioUrl: z.string().nullish(),
|
|
823
|
+
promptExtend: z.boolean().nullish(),
|
|
824
|
+
shotType: z.enum(["single", "multi"]).nullish(),
|
|
825
|
+
watermark: z.boolean().nullish(),
|
|
826
|
+
audio: z.boolean().nullish(),
|
|
827
|
+
referenceUrls: z.array(z.string()).nullish(),
|
|
828
|
+
media: z.array(z.object({
|
|
829
|
+
type: z.enum([
|
|
830
|
+
"reference_image",
|
|
831
|
+
"reference_video",
|
|
832
|
+
"reference_audio",
|
|
833
|
+
"first_frame",
|
|
834
|
+
"last_frame",
|
|
835
|
+
"file",
|
|
836
|
+
"link"
|
|
837
|
+
]),
|
|
838
|
+
url: z.string(),
|
|
839
|
+
referenceVoice: z.string().nullish()
|
|
840
|
+
})).nullish(),
|
|
841
|
+
ratio: z.enum([
|
|
842
|
+
"adaptive",
|
|
843
|
+
"16:9",
|
|
844
|
+
"9:16",
|
|
845
|
+
"1:1",
|
|
846
|
+
"4:3",
|
|
847
|
+
"3:4"
|
|
848
|
+
]).nullish(),
|
|
849
|
+
pollIntervalMs: z.number().positive().nullish(),
|
|
850
|
+
pollTimeoutMs: z.number().positive().nullish()
|
|
851
|
+
})));
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region src/alibaba-video-model.ts
|
|
854
|
+
const alibabaVideoErrorSchema = z.object({
|
|
855
|
+
code: z.string().nullish(),
|
|
856
|
+
message: z.string(),
|
|
857
|
+
request_id: z.string().nullish()
|
|
1073
858
|
});
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
859
|
+
const alibabaVideoFailedResponseHandler = createJsonErrorResponseHandler({
|
|
860
|
+
errorSchema: alibabaVideoErrorSchema,
|
|
861
|
+
errorToMessage: (data) => data.message
|
|
1077
862
|
});
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
863
|
+
const alibabaVideoCreateTaskSchema = z.object({
|
|
864
|
+
output: z.object({
|
|
865
|
+
task_status: z.string(),
|
|
866
|
+
task_id: z.string()
|
|
867
|
+
}).nullish(),
|
|
868
|
+
request_id: z.string().nullish()
|
|
1084
869
|
});
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
request_id: z7.string().nullish()
|
|
870
|
+
const alibabaVideoTaskStatusSchema = z.object({
|
|
871
|
+
output: z.object({
|
|
872
|
+
task_id: z.string(),
|
|
873
|
+
task_status: z.string(),
|
|
874
|
+
video_url: z.string().nullish(),
|
|
875
|
+
submit_time: z.string().nullish(),
|
|
876
|
+
scheduled_time: z.string().nullish(),
|
|
877
|
+
end_time: z.string().nullish(),
|
|
878
|
+
orig_prompt: z.string().nullish(),
|
|
879
|
+
actual_prompt: z.string().nullish(),
|
|
880
|
+
code: z.string().nullish(),
|
|
881
|
+
message: z.string().nullish()
|
|
882
|
+
}).nullish(),
|
|
883
|
+
usage: z.object({
|
|
884
|
+
duration: z.number().nullish(),
|
|
885
|
+
output_video_duration: z.number().nullish(),
|
|
886
|
+
input_video_duration: z.number().nullish(),
|
|
887
|
+
fps: z.number().nullish(),
|
|
888
|
+
SR: z.number().nullish(),
|
|
889
|
+
size: z.string().nullish(),
|
|
890
|
+
ratio: z.string().nullish()
|
|
891
|
+
}).nullish(),
|
|
892
|
+
request_id: z.string().nullish()
|
|
1109
893
|
});
|
|
1110
894
|
function detectMode(modelId) {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
895
|
+
if (modelId.includes("-i2v")) return "i2v";
|
|
896
|
+
if (modelId.includes("-r2v")) return "r2v";
|
|
897
|
+
return "t2v";
|
|
1114
898
|
}
|
|
1115
899
|
function detectProtocol(modelId) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
900
|
+
if (modelId.startsWith("wan3")) return "wan3";
|
|
901
|
+
if (modelId.startsWith("wan2.7")) return "wan27";
|
|
902
|
+
return "legacy";
|
|
1119
903
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
904
|
+
const resolutionTierMap = {
|
|
905
|
+
"1280x720": "720P",
|
|
906
|
+
"720x1280": "720P",
|
|
907
|
+
"960x960": "720P",
|
|
908
|
+
"1088x832": "720P",
|
|
909
|
+
"832x1088": "720P",
|
|
910
|
+
"1920x1080": "1080P",
|
|
911
|
+
"1080x1920": "1080P",
|
|
912
|
+
"1440x1440": "1080P",
|
|
913
|
+
"1632x1248": "1080P",
|
|
914
|
+
"1248x1632": "1080P",
|
|
915
|
+
"832x480": "480P",
|
|
916
|
+
"480x832": "480P",
|
|
917
|
+
"624x624": "480P"
|
|
1134
918
|
};
|
|
1135
|
-
|
|
919
|
+
const supportedRatios = /* @__PURE__ */ new Set([
|
|
920
|
+
"16:9",
|
|
921
|
+
"9:16",
|
|
922
|
+
"1:1",
|
|
923
|
+
"4:3",
|
|
924
|
+
"3:4"
|
|
925
|
+
]);
|
|
1136
926
|
function deriveRatioFromResolution(resolution) {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
[a, b] = [b, a % b];
|
|
1145
|
-
}
|
|
1146
|
-
const ratio = `${width / a}:${height / a}`;
|
|
1147
|
-
return supportedRatios.has(ratio) ? ratio : void 0;
|
|
927
|
+
const [width, height] = resolution.split("x").map(Number);
|
|
928
|
+
if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) return;
|
|
929
|
+
let a = width;
|
|
930
|
+
let b = height;
|
|
931
|
+
while (b !== 0) [a, b] = [b, a % b];
|
|
932
|
+
const ratio = `${width / a}:${height / a}`;
|
|
933
|
+
return supportedRatios.has(ratio) ? ratio : void 0;
|
|
1148
934
|
}
|
|
1149
935
|
function fileToImageString(file) {
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
}
|
|
1153
|
-
return typeof file.data === "string" ? file.data : convertUint8ArrayToBase64(file.data);
|
|
936
|
+
if (file.type === "url") return file.url;
|
|
937
|
+
return typeof file.data === "string" ? file.data : convertUint8ArrayToBase64(file.data);
|
|
1154
938
|
}
|
|
1155
939
|
function getFirstFrameImage(options) {
|
|
1156
|
-
|
|
940
|
+
return options.frameImages?.find((frame) => frame.frameType === "first_frame")?.image;
|
|
1157
941
|
}
|
|
1158
942
|
function getLastFrameImage(options) {
|
|
1159
|
-
|
|
943
|
+
return options.frameImages?.find((frame) => frame.frameType === "last_frame")?.image;
|
|
1160
944
|
}
|
|
1161
945
|
function resolveStartImage(options) {
|
|
1162
|
-
|
|
946
|
+
return getFirstFrameImage(options) ?? options.image;
|
|
1163
947
|
}
|
|
1164
948
|
function isVideoUrl(url) {
|
|
1165
|
-
|
|
949
|
+
return /\.(mp4|mov)([?#]|$)/i.test(url);
|
|
1166
950
|
}
|
|
1167
951
|
function resolveMedia(options, alibabaOptions, warnings, frames) {
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
media.push({
|
|
1197
|
-
type: "first_frame",
|
|
1198
|
-
url: convertImageModelFileToDataUri(frames.first)
|
|
1199
|
-
});
|
|
1200
|
-
}
|
|
1201
|
-
if (frames.last != null) {
|
|
1202
|
-
media.push({
|
|
1203
|
-
type: "last_frame",
|
|
1204
|
-
url: convertImageModelFileToDataUri(frames.last)
|
|
1205
|
-
});
|
|
1206
|
-
}
|
|
1207
|
-
return media.length > 0 ? media : void 0;
|
|
952
|
+
if (alibabaOptions?.media != null && alibabaOptions.media.length > 0) return alibabaOptions.media.map((item) => ({
|
|
953
|
+
type: item.type,
|
|
954
|
+
url: item.url,
|
|
955
|
+
...item.referenceVoice != null ? { reference_voice: item.referenceVoice } : {}
|
|
956
|
+
}));
|
|
957
|
+
const media = [];
|
|
958
|
+
for (const reference of options.inputReferences ?? []) if (reference.type === "url") media.push({
|
|
959
|
+
type: isVideoUrl(reference.url) ? "reference_video" : "reference_image",
|
|
960
|
+
url: reference.url
|
|
961
|
+
});
|
|
962
|
+
else if (reference.mediaType.startsWith("image/")) media.push({
|
|
963
|
+
type: "reference_image",
|
|
964
|
+
url: convertImageModelFileToDataUri(reference)
|
|
965
|
+
});
|
|
966
|
+
else warnings.push({
|
|
967
|
+
type: "unsupported",
|
|
968
|
+
feature: "inputReferences",
|
|
969
|
+
details: "Alibaba reference-to-video requires URL references for videos. Non-URL video reference was skipped."
|
|
970
|
+
});
|
|
971
|
+
if (frames.first != null) media.push({
|
|
972
|
+
type: "first_frame",
|
|
973
|
+
url: convertImageModelFileToDataUri(frames.first)
|
|
974
|
+
});
|
|
975
|
+
if (frames.last != null) media.push({
|
|
976
|
+
type: "last_frame",
|
|
977
|
+
url: convertImageModelFileToDataUri(frames.last)
|
|
978
|
+
});
|
|
979
|
+
return media.length > 0 ? media : void 0;
|
|
1208
980
|
}
|
|
1209
981
|
function resolveReferenceUrls(options, alibabaOptions, warnings) {
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
details: "Alibaba reference-to-video requires URL references. Non-URL reference was skipped."
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
return urls.length > 0 ? urls : void 0;
|
|
1227
|
-
}
|
|
1228
|
-
return alibabaOptions?.referenceUrls ?? void 0;
|
|
982
|
+
if (options.frameImages != null && options.frameImages.length > 0) return;
|
|
983
|
+
if (options.inputReferences != null && options.inputReferences.length > 0) {
|
|
984
|
+
const urls = [];
|
|
985
|
+
for (const reference of options.inputReferences) if (reference.type === "url") urls.push(reference.url);
|
|
986
|
+
else warnings.push({
|
|
987
|
+
type: "unsupported",
|
|
988
|
+
feature: "inputReferences",
|
|
989
|
+
details: "Alibaba reference-to-video requires URL references. Non-URL reference was skipped."
|
|
990
|
+
});
|
|
991
|
+
return urls.length > 0 ? urls : void 0;
|
|
992
|
+
}
|
|
993
|
+
return alibabaOptions?.referenceUrls ?? void 0;
|
|
1229
994
|
}
|
|
1230
995
|
var AlibabaVideoModel = class {
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
{
|
|
1448
|
-
"X-DashScope-Async": "enable"
|
|
1449
|
-
}
|
|
1450
|
-
),
|
|
1451
|
-
body: {
|
|
1452
|
-
model: this.modelId,
|
|
1453
|
-
input,
|
|
1454
|
-
parameters
|
|
1455
|
-
},
|
|
1456
|
-
successfulResponseHandler: createJsonResponseHandler3(
|
|
1457
|
-
alibabaVideoCreateTaskSchema
|
|
1458
|
-
),
|
|
1459
|
-
failedResponseHandler: alibabaVideoFailedResponseHandler,
|
|
1460
|
-
abortSignal: options.abortSignal,
|
|
1461
|
-
fetch: this.config.fetch
|
|
1462
|
-
});
|
|
1463
|
-
const taskId = createResponse.output?.task_id;
|
|
1464
|
-
if (!taskId) {
|
|
1465
|
-
throw new AISDKError({
|
|
1466
|
-
name: "ALIBABA_VIDEO_GENERATION_ERROR",
|
|
1467
|
-
message: `No task_id returned from Alibaba API. Response: ${JSON.stringify(createResponse)}`
|
|
1468
|
-
});
|
|
1469
|
-
}
|
|
1470
|
-
return {
|
|
1471
|
-
operation: { taskId },
|
|
1472
|
-
warnings,
|
|
1473
|
-
response: {
|
|
1474
|
-
timestamp: currentDate,
|
|
1475
|
-
modelId: this.modelId,
|
|
1476
|
-
headers: responseHeaders
|
|
1477
|
-
}
|
|
1478
|
-
};
|
|
1479
|
-
}
|
|
1480
|
-
async doStatus(options) {
|
|
1481
|
-
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
1482
|
-
const { taskId } = options.operation;
|
|
1483
|
-
const { value: statusResponse, responseHeaders } = await getFromApi({
|
|
1484
|
-
url: `${this.config.baseURL}/api/v1/tasks/${taskId}`,
|
|
1485
|
-
validateUrl: false,
|
|
1486
|
-
headers: combineHeaders3(
|
|
1487
|
-
await resolve(this.config.headers),
|
|
1488
|
-
options.headers
|
|
1489
|
-
),
|
|
1490
|
-
successfulResponseHandler: createJsonResponseHandler3(
|
|
1491
|
-
alibabaVideoTaskStatusSchema
|
|
1492
|
-
),
|
|
1493
|
-
failedResponseHandler: alibabaVideoFailedResponseHandler,
|
|
1494
|
-
abortSignal: options.abortSignal,
|
|
1495
|
-
fetch: this.config.fetch
|
|
1496
|
-
});
|
|
1497
|
-
const taskStatus = statusResponse.output?.task_status;
|
|
1498
|
-
if (taskStatus === "SUCCEEDED") {
|
|
1499
|
-
return this.buildCompletedResult(
|
|
1500
|
-
statusResponse,
|
|
1501
|
-
responseHeaders,
|
|
1502
|
-
[],
|
|
1503
|
-
currentDate
|
|
1504
|
-
);
|
|
1505
|
-
}
|
|
1506
|
-
if (taskStatus === "FAILED" || taskStatus === "CANCELED") {
|
|
1507
|
-
return {
|
|
1508
|
-
status: "error",
|
|
1509
|
-
error: `Video generation ${taskStatus.toLowerCase()}. Task ID: ${taskId}. ${statusResponse.output?.message ?? ""}`.trim(),
|
|
1510
|
-
response: {
|
|
1511
|
-
timestamp: currentDate,
|
|
1512
|
-
modelId: this.modelId,
|
|
1513
|
-
headers: responseHeaders
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
}
|
|
1517
|
-
return {
|
|
1518
|
-
status: "pending",
|
|
1519
|
-
response: {
|
|
1520
|
-
timestamp: currentDate,
|
|
1521
|
-
modelId: this.modelId,
|
|
1522
|
-
headers: responseHeaders
|
|
1523
|
-
}
|
|
1524
|
-
};
|
|
1525
|
-
}
|
|
996
|
+
get provider() {
|
|
997
|
+
return this.config.provider;
|
|
998
|
+
}
|
|
999
|
+
constructor(modelId, config) {
|
|
1000
|
+
this.modelId = modelId;
|
|
1001
|
+
this.config = config;
|
|
1002
|
+
this.specificationVersion = "v4";
|
|
1003
|
+
this.maxVideosPerCall = 1;
|
|
1004
|
+
}
|
|
1005
|
+
async buildRequest(options) {
|
|
1006
|
+
const warnings = [];
|
|
1007
|
+
const mode = detectMode(this.modelId);
|
|
1008
|
+
const alibabaOptions = await parseProviderOptions({
|
|
1009
|
+
provider: "alibaba",
|
|
1010
|
+
providerOptions: options.providerOptions,
|
|
1011
|
+
schema: alibabaVideoModelOptionsSchema
|
|
1012
|
+
});
|
|
1013
|
+
const input = {};
|
|
1014
|
+
if (options.prompt != null) input.prompt = options.prompt;
|
|
1015
|
+
if (alibabaOptions?.negativePrompt != null) input.negative_prompt = alibabaOptions.negativePrompt;
|
|
1016
|
+
if (alibabaOptions?.audioUrl != null) input.audio_url = alibabaOptions.audioUrl;
|
|
1017
|
+
const startImage = resolveStartImage(options);
|
|
1018
|
+
const protocol = detectProtocol(this.modelId);
|
|
1019
|
+
const wan27 = protocol === "wan27";
|
|
1020
|
+
const wan3 = protocol === "wan3";
|
|
1021
|
+
const tieredProtocol = wan27 || wan3;
|
|
1022
|
+
const supportsRatio = wan3 || wan27 && mode !== "i2v";
|
|
1023
|
+
if (!wan3 && mode === "i2v" && startImage != null) input.img_url = fileToImageString(startImage);
|
|
1024
|
+
if (wan3) {
|
|
1025
|
+
const media = resolveMedia(options, alibabaOptions, warnings, {
|
|
1026
|
+
first: startImage,
|
|
1027
|
+
last: getLastFrameImage(options)
|
|
1028
|
+
});
|
|
1029
|
+
if (media != null) input.media = media;
|
|
1030
|
+
} else if (mode === "r2v") {
|
|
1031
|
+
if (wan27) {
|
|
1032
|
+
const media = resolveMedia(options, alibabaOptions, warnings, { first: getFirstFrameImage(options) });
|
|
1033
|
+
if (media != null) input.media = media;
|
|
1034
|
+
} else {
|
|
1035
|
+
const referenceUrls = resolveReferenceUrls(options, alibabaOptions, warnings);
|
|
1036
|
+
if (referenceUrls != null && referenceUrls.length > 0) input.reference_urls = referenceUrls;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
if (getLastFrameImage(options) != null && !wan3) warnings.push({
|
|
1040
|
+
type: "unsupported",
|
|
1041
|
+
feature: "frameImages",
|
|
1042
|
+
details: "This model does not support last_frame. The last frame image was ignored."
|
|
1043
|
+
});
|
|
1044
|
+
if (options.inputReferences != null && options.inputReferences.length > 0 && mode !== "r2v" && !wan3) warnings.push({
|
|
1045
|
+
type: "unsupported",
|
|
1046
|
+
feature: "inputReferences",
|
|
1047
|
+
details: "Alibaba only supports inputReferences (reference-to-video) on reference-to-video models. The reference images were ignored."
|
|
1048
|
+
});
|
|
1049
|
+
const parameters = {};
|
|
1050
|
+
if (options.duration != null) parameters.duration = options.duration;
|
|
1051
|
+
if (options.seed != null) parameters.seed = options.seed;
|
|
1052
|
+
if (options.resolution != null) {
|
|
1053
|
+
if (mode === "i2v" || tieredProtocol) {
|
|
1054
|
+
const resolutionTier = resolutionTierMap[options.resolution] || options.resolution;
|
|
1055
|
+
const supportedTiers = wan3 ? [
|
|
1056
|
+
"480P",
|
|
1057
|
+
"720P",
|
|
1058
|
+
"1080P"
|
|
1059
|
+
] : ["720P", "1080P"];
|
|
1060
|
+
if (tieredProtocol && !supportedTiers.includes(resolutionTier)) warnings.push({
|
|
1061
|
+
type: "unsupported",
|
|
1062
|
+
feature: "resolution",
|
|
1063
|
+
details: `${wan3 ? "wan3" : "wan2.7"} models only support the ${supportedTiers.join(", ")} resolution tiers. The resolution "${options.resolution}" was ignored.`
|
|
1064
|
+
});
|
|
1065
|
+
else parameters.resolution = resolutionTier;
|
|
1066
|
+
} else parameters.size = options.resolution.replace("x", "*");
|
|
1067
|
+
}
|
|
1068
|
+
if (supportsRatio) {
|
|
1069
|
+
const ratio = alibabaOptions?.ratio ?? options.aspectRatio ?? (options.resolution != null ? deriveRatioFromResolution(options.resolution) : void 0);
|
|
1070
|
+
if (ratio != null) parameters.ratio = ratio;
|
|
1071
|
+
}
|
|
1072
|
+
if (alibabaOptions?.promptExtend != null) parameters.prompt_extend = alibabaOptions.promptExtend;
|
|
1073
|
+
if (alibabaOptions?.shotType != null) {
|
|
1074
|
+
if (tieredProtocol) warnings.push({
|
|
1075
|
+
type: "unsupported",
|
|
1076
|
+
feature: "shotType",
|
|
1077
|
+
details: `${wan3 ? "wan3" : "wan2.7"} models do not support the shotType option. Describe the shot structure in the prompt instead.`
|
|
1078
|
+
});
|
|
1079
|
+
else parameters.shot_type = alibabaOptions.shotType;
|
|
1080
|
+
}
|
|
1081
|
+
if (alibabaOptions?.watermark != null) parameters.watermark = alibabaOptions.watermark;
|
|
1082
|
+
const audio = options.generateAudio ?? alibabaOptions?.audio;
|
|
1083
|
+
if (audio != null) {
|
|
1084
|
+
if (wan27) warnings.push({
|
|
1085
|
+
type: "unsupported",
|
|
1086
|
+
feature: "generateAudio",
|
|
1087
|
+
details: "wan2.7 models always generate audio. The audio option was ignored."
|
|
1088
|
+
});
|
|
1089
|
+
else parameters.audio = audio;
|
|
1090
|
+
}
|
|
1091
|
+
if (options.aspectRatio && !supportsRatio) warnings.push({
|
|
1092
|
+
type: "unsupported",
|
|
1093
|
+
feature: "aspectRatio",
|
|
1094
|
+
details: "Alibaba video models use explicit size/resolution dimensions. Use the resolution option or providerOptions.alibaba for size control."
|
|
1095
|
+
});
|
|
1096
|
+
if (options.fps) warnings.push({
|
|
1097
|
+
type: "unsupported",
|
|
1098
|
+
feature: "fps",
|
|
1099
|
+
details: "Alibaba video models do not support custom FPS."
|
|
1100
|
+
});
|
|
1101
|
+
if (options.n != null && options.n > 1) warnings.push({
|
|
1102
|
+
type: "unsupported",
|
|
1103
|
+
feature: "n",
|
|
1104
|
+
details: "Alibaba video models only support generating 1 video per call."
|
|
1105
|
+
});
|
|
1106
|
+
return {
|
|
1107
|
+
input,
|
|
1108
|
+
parameters,
|
|
1109
|
+
warnings,
|
|
1110
|
+
alibabaOptions
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
buildCompletedResult(statusResponse, responseHeaders, warnings, currentDate) {
|
|
1114
|
+
const taskId = statusResponse.output?.task_id;
|
|
1115
|
+
const videoUrl = statusResponse.output?.video_url;
|
|
1116
|
+
if (!videoUrl) throw new AISDKError({
|
|
1117
|
+
name: "ALIBABA_VIDEO_GENERATION_ERROR",
|
|
1118
|
+
message: `No video URL in response. Task ID: ${taskId}`
|
|
1119
|
+
});
|
|
1120
|
+
return {
|
|
1121
|
+
status: "completed",
|
|
1122
|
+
videos: [{
|
|
1123
|
+
type: "url",
|
|
1124
|
+
url: videoUrl,
|
|
1125
|
+
mediaType: "video/mp4"
|
|
1126
|
+
}],
|
|
1127
|
+
warnings,
|
|
1128
|
+
response: {
|
|
1129
|
+
timestamp: currentDate,
|
|
1130
|
+
modelId: this.modelId,
|
|
1131
|
+
headers: responseHeaders
|
|
1132
|
+
},
|
|
1133
|
+
providerMetadata: { alibaba: {
|
|
1134
|
+
taskId,
|
|
1135
|
+
videoUrl,
|
|
1136
|
+
...statusResponse.output?.actual_prompt ? { actualPrompt: statusResponse.output.actual_prompt } : {},
|
|
1137
|
+
...statusResponse.usage ? { usage: {
|
|
1138
|
+
duration: statusResponse.usage.duration,
|
|
1139
|
+
outputVideoDuration: statusResponse.usage.output_video_duration,
|
|
1140
|
+
resolution: statusResponse.usage.SR,
|
|
1141
|
+
size: statusResponse.usage.size,
|
|
1142
|
+
...statusResponse.usage.input_video_duration != null ? { inputVideoDuration: statusResponse.usage.input_video_duration } : {},
|
|
1143
|
+
...statusResponse.usage.fps != null ? { fps: statusResponse.usage.fps } : {},
|
|
1144
|
+
...statusResponse.usage.ratio != null ? { ratio: statusResponse.usage.ratio } : {}
|
|
1145
|
+
} } : {}
|
|
1146
|
+
} }
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
async doStart(options) {
|
|
1150
|
+
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
1151
|
+
const { input, parameters, warnings } = await this.buildRequest(options);
|
|
1152
|
+
const { value: createResponse, responseHeaders } = await postJsonToApi({
|
|
1153
|
+
url: `${this.config.baseURL}/api/v1/services/aigc/video-generation/video-synthesis`,
|
|
1154
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers, { "X-DashScope-Async": "enable" }),
|
|
1155
|
+
body: {
|
|
1156
|
+
model: this.modelId,
|
|
1157
|
+
input,
|
|
1158
|
+
parameters
|
|
1159
|
+
},
|
|
1160
|
+
successfulResponseHandler: createJsonResponseHandler(alibabaVideoCreateTaskSchema),
|
|
1161
|
+
failedResponseHandler: alibabaVideoFailedResponseHandler,
|
|
1162
|
+
abortSignal: options.abortSignal,
|
|
1163
|
+
fetch: this.config.fetch
|
|
1164
|
+
});
|
|
1165
|
+
const taskId = createResponse.output?.task_id;
|
|
1166
|
+
if (!taskId) throw new AISDKError({
|
|
1167
|
+
name: "ALIBABA_VIDEO_GENERATION_ERROR",
|
|
1168
|
+
message: `No task_id returned from Alibaba API. Response: ${JSON.stringify(createResponse)}`
|
|
1169
|
+
});
|
|
1170
|
+
return {
|
|
1171
|
+
operation: { taskId },
|
|
1172
|
+
warnings,
|
|
1173
|
+
response: {
|
|
1174
|
+
timestamp: currentDate,
|
|
1175
|
+
modelId: this.modelId,
|
|
1176
|
+
headers: responseHeaders
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
async doStatus(options) {
|
|
1181
|
+
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
1182
|
+
const { taskId } = options.operation;
|
|
1183
|
+
const { value: statusResponse, responseHeaders } = await getFromApi({
|
|
1184
|
+
url: `${this.config.baseURL}/api/v1/tasks/${taskId}`,
|
|
1185
|
+
validateUrl: false,
|
|
1186
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
1187
|
+
successfulResponseHandler: createJsonResponseHandler(alibabaVideoTaskStatusSchema),
|
|
1188
|
+
failedResponseHandler: alibabaVideoFailedResponseHandler,
|
|
1189
|
+
abortSignal: options.abortSignal,
|
|
1190
|
+
fetch: this.config.fetch
|
|
1191
|
+
});
|
|
1192
|
+
const taskStatus = statusResponse.output?.task_status;
|
|
1193
|
+
if (taskStatus === "SUCCEEDED") return this.buildCompletedResult(statusResponse, responseHeaders, [], currentDate);
|
|
1194
|
+
if (taskStatus === "FAILED" || taskStatus === "CANCELED") return {
|
|
1195
|
+
status: "error",
|
|
1196
|
+
error: `Video generation ${taskStatus.toLowerCase()}. Task ID: ${taskId}. ${statusResponse.output?.message ?? ""}`.trim(),
|
|
1197
|
+
response: {
|
|
1198
|
+
timestamp: currentDate,
|
|
1199
|
+
modelId: this.modelId,
|
|
1200
|
+
headers: responseHeaders
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
return {
|
|
1204
|
+
status: "pending",
|
|
1205
|
+
response: {
|
|
1206
|
+
timestamp: currentDate,
|
|
1207
|
+
modelId: this.modelId,
|
|
1208
|
+
headers: responseHeaders
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1526
1212
|
};
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1213
|
+
//#endregion
|
|
1214
|
+
//#region src/version.ts
|
|
1215
|
+
const VERSION = "2.0.59";
|
|
1216
|
+
//#endregion
|
|
1217
|
+
//#region src/alibaba-provider.ts
|
|
1218
|
+
/**
|
|
1219
|
+
* Create an Alibaba Cloud (Qwen) provider instance.
|
|
1220
|
+
*/
|
|
1532
1221
|
function createAlibaba(options = {}) {
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
provider.imageModel = (modelId) => {
|
|
1582
|
-
throw new NoSuchModelError({ modelId, modelType: "imageModel" });
|
|
1583
|
-
};
|
|
1584
|
-
return provider;
|
|
1222
|
+
const baseURL = withoutTrailingSlash(options.baseURL) ?? "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
|
|
1223
|
+
const videoBaseURL = withoutTrailingSlash(options.videoBaseURL) ?? "https://dashscope-intl.aliyuncs.com";
|
|
1224
|
+
const embeddingBaseURL = withoutTrailingSlash(options.embeddingBaseURL) ?? "https://dashscope-intl.aliyuncs.com/api/v1";
|
|
1225
|
+
const getHeaders = () => withUserAgentSuffix({
|
|
1226
|
+
Authorization: `Bearer ${loadApiKey({
|
|
1227
|
+
apiKey: options.apiKey,
|
|
1228
|
+
environmentVariableName: "ALIBABA_API_KEY",
|
|
1229
|
+
description: "Alibaba Cloud (DashScope)"
|
|
1230
|
+
})}`,
|
|
1231
|
+
...options.headers
|
|
1232
|
+
}, `ai-sdk-alibaba/${VERSION}`);
|
|
1233
|
+
const createLanguageModel = (modelId) => new AlibabaChatLanguageModel(modelId, {
|
|
1234
|
+
provider: "alibaba.chat",
|
|
1235
|
+
baseURL,
|
|
1236
|
+
headers: getHeaders,
|
|
1237
|
+
fetch: options.fetch,
|
|
1238
|
+
includeUsage: options.includeUsage ?? true
|
|
1239
|
+
});
|
|
1240
|
+
const createEmbeddingModel = (modelId) => new AlibabaEmbeddingModel(modelId, {
|
|
1241
|
+
provider: "alibaba.embedding",
|
|
1242
|
+
baseURL: embeddingBaseURL,
|
|
1243
|
+
headers: getHeaders,
|
|
1244
|
+
fetch: options.fetch
|
|
1245
|
+
});
|
|
1246
|
+
const createVideoModel = (modelId) => new AlibabaVideoModel(modelId, {
|
|
1247
|
+
provider: "alibaba.video",
|
|
1248
|
+
baseURL: videoBaseURL,
|
|
1249
|
+
headers: getHeaders,
|
|
1250
|
+
fetch: options.fetch
|
|
1251
|
+
});
|
|
1252
|
+
const provider = function(modelId) {
|
|
1253
|
+
if (new.target) throw new Error("The Alibaba model function cannot be called with the new keyword.");
|
|
1254
|
+
return createLanguageModel(modelId);
|
|
1255
|
+
};
|
|
1256
|
+
provider.specificationVersion = "v4";
|
|
1257
|
+
provider.languageModel = createLanguageModel;
|
|
1258
|
+
provider.chatModel = createLanguageModel;
|
|
1259
|
+
provider.embedding = createEmbeddingModel;
|
|
1260
|
+
provider.embeddingModel = createEmbeddingModel;
|
|
1261
|
+
provider.video = createVideoModel;
|
|
1262
|
+
provider.videoModel = createVideoModel;
|
|
1263
|
+
provider.imageModel = (modelId) => {
|
|
1264
|
+
throw new NoSuchModelError({
|
|
1265
|
+
modelId,
|
|
1266
|
+
modelType: "imageModel"
|
|
1267
|
+
});
|
|
1268
|
+
};
|
|
1269
|
+
return provider;
|
|
1585
1270
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
createAlibaba
|
|
1591
|
-
};
|
|
1271
|
+
const alibaba = createAlibaba();
|
|
1272
|
+
//#endregion
|
|
1273
|
+
export { VERSION, alibaba, createAlibaba };
|
|
1274
|
+
|
|
1592
1275
|
//# sourceMappingURL=index.js.map
|