@ai-sdk/alibaba 0.0.0-6b196531-20260710185421
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 +775 -0
- package/LICENSE +13 -0
- package/README.md +151 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +1380 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
- package/src/alibaba-chat-language-model-options.ts +56 -0
- package/src/alibaba-chat-language-model.ts +568 -0
- package/src/alibaba-chat-prompt.ts +67 -0
- package/src/alibaba-config.ts +9 -0
- package/src/alibaba-embedding-model-options.ts +33 -0
- package/src/alibaba-embedding-model.ts +178 -0
- package/src/alibaba-error.ts +17 -0
- package/src/alibaba-provider.ts +187 -0
- package/src/alibaba-video-model-options.ts +77 -0
- package/src/alibaba-video-model.ts +587 -0
- package/src/alibaba-video-settings.ts +16 -0
- package/src/convert-alibaba-usage.ts +37 -0
- package/src/convert-to-alibaba-chat-messages.ts +220 -0
- package/src/get-cache-control.ts +49 -0
- package/src/index.ts +27 -0
- package/src/version.ts +6 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getResponseMetadata,
|
|
3
|
+
mapOpenAICompatibleFinishReason,
|
|
4
|
+
prepareTools,
|
|
5
|
+
} from '@ai-sdk/openai-compatible/internal';
|
|
6
|
+
import type {
|
|
7
|
+
LanguageModelV4,
|
|
8
|
+
LanguageModelV4CallOptions,
|
|
9
|
+
LanguageModelV4Content,
|
|
10
|
+
LanguageModelV4FinishReason,
|
|
11
|
+
LanguageModelV4GenerateResult,
|
|
12
|
+
LanguageModelV4StreamPart,
|
|
13
|
+
LanguageModelV4StreamResult,
|
|
14
|
+
SharedV4Warning,
|
|
15
|
+
} from '@ai-sdk/provider';
|
|
16
|
+
import {
|
|
17
|
+
combineHeaders,
|
|
18
|
+
createEventSourceResponseHandler,
|
|
19
|
+
createJsonResponseHandler,
|
|
20
|
+
generateId,
|
|
21
|
+
isCustomReasoning,
|
|
22
|
+
mapReasoningToProviderBudget,
|
|
23
|
+
parseProviderOptions,
|
|
24
|
+
postJsonToApi,
|
|
25
|
+
serializeModelOptions,
|
|
26
|
+
StreamingToolCallTracker,
|
|
27
|
+
WORKFLOW_SERIALIZE,
|
|
28
|
+
WORKFLOW_DESERIALIZE,
|
|
29
|
+
type InferSchema,
|
|
30
|
+
type ParseResult,
|
|
31
|
+
} from '@ai-sdk/provider-utils';
|
|
32
|
+
import { z } from 'zod/v4';
|
|
33
|
+
import {
|
|
34
|
+
alibabaLanguageModelChatOptions,
|
|
35
|
+
type AlibabaChatModelId,
|
|
36
|
+
} from './alibaba-chat-language-model-options';
|
|
37
|
+
import type { AlibabaConfig } from './alibaba-config';
|
|
38
|
+
import { alibabaFailedResponseHandler } from './alibaba-error';
|
|
39
|
+
import { convertAlibabaUsage } from './convert-alibaba-usage';
|
|
40
|
+
import { convertToAlibabaChatMessages } from './convert-to-alibaba-chat-messages';
|
|
41
|
+
import { CacheControlValidator } from './get-cache-control';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Alibaba language model implementation.
|
|
45
|
+
*
|
|
46
|
+
* Implements LanguageModelV4 interface for Alibaba Cloud's Qwen models.
|
|
47
|
+
* Supports OpenAI-compatible chat completions API with Alibaba-specific features:
|
|
48
|
+
* - Reasoning/thinking mode (enable_thinking, reasoning_content)
|
|
49
|
+
* - Thinking budget control (thinking_budget)
|
|
50
|
+
* - Prompt caching (cached_tokens tracking)
|
|
51
|
+
*/
|
|
52
|
+
export class AlibabaChatLanguageModel implements LanguageModelV4 {
|
|
53
|
+
readonly specificationVersion = 'v4';
|
|
54
|
+
readonly modelId: AlibabaChatModelId;
|
|
55
|
+
|
|
56
|
+
private readonly config: AlibabaConfig;
|
|
57
|
+
|
|
58
|
+
static [WORKFLOW_SERIALIZE](model: AlibabaChatLanguageModel) {
|
|
59
|
+
return serializeModelOptions({
|
|
60
|
+
modelId: model.modelId,
|
|
61
|
+
config: model.config,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
66
|
+
modelId: AlibabaChatModelId;
|
|
67
|
+
config: AlibabaConfig;
|
|
68
|
+
}) {
|
|
69
|
+
return new AlibabaChatLanguageModel(options.modelId, options.config);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
constructor(modelId: AlibabaChatModelId, config: AlibabaConfig) {
|
|
73
|
+
this.modelId = modelId;
|
|
74
|
+
this.config = config;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get provider(): string {
|
|
78
|
+
return this.config.provider;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
readonly supportedUrls: Record<string, RegExp[]> = {
|
|
82
|
+
'image/*': [/^https?:\/\/.*$/],
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Builds request arguments for Alibaba API call.
|
|
87
|
+
* Converts AI SDK options to Alibaba API format.
|
|
88
|
+
*/
|
|
89
|
+
private async getArgs({
|
|
90
|
+
prompt,
|
|
91
|
+
maxOutputTokens,
|
|
92
|
+
temperature,
|
|
93
|
+
topP,
|
|
94
|
+
topK,
|
|
95
|
+
frequencyPenalty,
|
|
96
|
+
presencePenalty,
|
|
97
|
+
stopSequences,
|
|
98
|
+
responseFormat,
|
|
99
|
+
seed,
|
|
100
|
+
reasoning,
|
|
101
|
+
providerOptions,
|
|
102
|
+
tools,
|
|
103
|
+
toolChoice,
|
|
104
|
+
}: LanguageModelV4CallOptions) {
|
|
105
|
+
const warnings: SharedV4Warning[] = [];
|
|
106
|
+
|
|
107
|
+
const cacheControlValidator = new CacheControlValidator();
|
|
108
|
+
|
|
109
|
+
const alibabaOptions = await parseProviderOptions({
|
|
110
|
+
provider: 'alibaba',
|
|
111
|
+
providerOptions,
|
|
112
|
+
schema: alibabaLanguageModelChatOptions,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Warn about unsupported features
|
|
116
|
+
if (frequencyPenalty != null) {
|
|
117
|
+
warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Build base request arguments
|
|
121
|
+
const baseArgs = {
|
|
122
|
+
model: this.modelId,
|
|
123
|
+
max_tokens: maxOutputTokens,
|
|
124
|
+
temperature,
|
|
125
|
+
top_p: topP,
|
|
126
|
+
top_k: topK,
|
|
127
|
+
presence_penalty: presencePenalty,
|
|
128
|
+
stop: stopSequences,
|
|
129
|
+
seed,
|
|
130
|
+
response_format:
|
|
131
|
+
responseFormat?.type === 'json'
|
|
132
|
+
? responseFormat.schema != null
|
|
133
|
+
? {
|
|
134
|
+
type: 'json_schema',
|
|
135
|
+
json_schema: {
|
|
136
|
+
schema: responseFormat.schema,
|
|
137
|
+
name: responseFormat.name ?? 'response',
|
|
138
|
+
description: responseFormat.description,
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
: { type: 'json_object' }
|
|
142
|
+
: undefined,
|
|
143
|
+
|
|
144
|
+
...resolveAlibabaThinking({
|
|
145
|
+
reasoning,
|
|
146
|
+
alibabaOptions,
|
|
147
|
+
warnings,
|
|
148
|
+
}),
|
|
149
|
+
|
|
150
|
+
// Convert messages with cache control support
|
|
151
|
+
messages: convertToAlibabaChatMessages({
|
|
152
|
+
prompt,
|
|
153
|
+
cacheControlValidator,
|
|
154
|
+
}),
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Prepare tools
|
|
158
|
+
const {
|
|
159
|
+
tools: alibabaTools,
|
|
160
|
+
toolChoice: alibabaToolChoice,
|
|
161
|
+
toolWarnings,
|
|
162
|
+
} = prepareTools({ tools, toolChoice });
|
|
163
|
+
|
|
164
|
+
warnings.push(...cacheControlValidator.getWarnings());
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
args: {
|
|
168
|
+
...baseArgs,
|
|
169
|
+
tools: alibabaTools,
|
|
170
|
+
tool_choice: alibabaToolChoice,
|
|
171
|
+
...(alibabaTools != null &&
|
|
172
|
+
alibabaOptions?.parallelToolCalls !== undefined
|
|
173
|
+
? { parallel_tool_calls: alibabaOptions.parallelToolCalls }
|
|
174
|
+
: {}),
|
|
175
|
+
},
|
|
176
|
+
warnings: [...warnings, ...toolWarnings],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async doGenerate(
|
|
181
|
+
options: LanguageModelV4CallOptions,
|
|
182
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
183
|
+
const { args, warnings } = await this.getArgs(options);
|
|
184
|
+
|
|
185
|
+
const {
|
|
186
|
+
responseHeaders,
|
|
187
|
+
value: response,
|
|
188
|
+
rawValue: rawResponse,
|
|
189
|
+
} = await postJsonToApi({
|
|
190
|
+
url: `${this.config.baseURL}/chat/completions`,
|
|
191
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
192
|
+
body: args,
|
|
193
|
+
failedResponseHandler: alibabaFailedResponseHandler,
|
|
194
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
195
|
+
alibabaChatResponseSchema,
|
|
196
|
+
),
|
|
197
|
+
abortSignal: options.abortSignal,
|
|
198
|
+
fetch: this.config.fetch,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const choice = response.choices[0];
|
|
202
|
+
const content: Array<LanguageModelV4Content> = [];
|
|
203
|
+
|
|
204
|
+
// text content:
|
|
205
|
+
const text = choice.message.content;
|
|
206
|
+
if (text != null && text.length > 0) {
|
|
207
|
+
content.push({ type: 'text', text });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// reasoning content (Alibaba uses 'reasoning_content' field):
|
|
211
|
+
const reasoning = choice.message.reasoning_content;
|
|
212
|
+
if (reasoning != null && reasoning.length > 0) {
|
|
213
|
+
content.push({
|
|
214
|
+
type: 'reasoning',
|
|
215
|
+
text: reasoning,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// tool calls:
|
|
220
|
+
if (choice.message.tool_calls != null) {
|
|
221
|
+
for (const toolCall of choice.message.tool_calls) {
|
|
222
|
+
content.push({
|
|
223
|
+
type: 'tool-call',
|
|
224
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
225
|
+
toolName: toolCall.function.name,
|
|
226
|
+
input: toolCall.function.arguments!,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
content,
|
|
233
|
+
finishReason: {
|
|
234
|
+
unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
|
|
235
|
+
raw: choice.finish_reason ?? undefined,
|
|
236
|
+
},
|
|
237
|
+
usage: convertAlibabaUsage(response.usage),
|
|
238
|
+
request: { body: JSON.stringify(args) },
|
|
239
|
+
response: {
|
|
240
|
+
...getResponseMetadata(response),
|
|
241
|
+
headers: responseHeaders,
|
|
242
|
+
body: rawResponse,
|
|
243
|
+
},
|
|
244
|
+
warnings,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async doStream(
|
|
249
|
+
options: LanguageModelV4CallOptions,
|
|
250
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
251
|
+
const { args, warnings } = await this.getArgs(options);
|
|
252
|
+
const body = {
|
|
253
|
+
...args,
|
|
254
|
+
stream: true,
|
|
255
|
+
stream_options: this.config.includeUsage
|
|
256
|
+
? { include_usage: true }
|
|
257
|
+
: undefined,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const { responseHeaders, value: response } = await postJsonToApi({
|
|
261
|
+
url: `${this.config.baseURL}/chat/completions`,
|
|
262
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
263
|
+
body,
|
|
264
|
+
failedResponseHandler: alibabaFailedResponseHandler,
|
|
265
|
+
successfulResponseHandler: createEventSourceResponseHandler(
|
|
266
|
+
alibabaChatChunkSchema,
|
|
267
|
+
),
|
|
268
|
+
abortSignal: options.abortSignal,
|
|
269
|
+
fetch: this.config.fetch,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// Track state across chunks
|
|
273
|
+
let finishReason: LanguageModelV4FinishReason = {
|
|
274
|
+
unified: 'other',
|
|
275
|
+
raw: undefined,
|
|
276
|
+
};
|
|
277
|
+
let usage: z.infer<typeof alibabaUsageSchema> | undefined = undefined;
|
|
278
|
+
|
|
279
|
+
let isFirstChunk = true;
|
|
280
|
+
let activeText = false;
|
|
281
|
+
let activeReasoningId: string | null = null;
|
|
282
|
+
|
|
283
|
+
let toolCallTracker: StreamingToolCallTracker;
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
stream: response.pipeThrough(
|
|
287
|
+
new TransformStream<
|
|
288
|
+
ParseResult<z.infer<typeof alibabaChatChunkSchema>>,
|
|
289
|
+
LanguageModelV4StreamPart
|
|
290
|
+
>({
|
|
291
|
+
start(controller) {
|
|
292
|
+
toolCallTracker = new StreamingToolCallTracker(controller, {
|
|
293
|
+
generateId,
|
|
294
|
+
});
|
|
295
|
+
controller.enqueue({ type: 'stream-start', warnings });
|
|
296
|
+
},
|
|
297
|
+
|
|
298
|
+
transform(chunk, controller) {
|
|
299
|
+
// Emit raw chunk if requested (before anything else)
|
|
300
|
+
if (options.includeRawChunks) {
|
|
301
|
+
controller.enqueue({ type: 'raw', rawValue: chunk.rawValue });
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Handle parse errors
|
|
305
|
+
if (!chunk.success) {
|
|
306
|
+
controller.enqueue({ type: 'error', error: chunk.error });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const value = chunk.value;
|
|
311
|
+
|
|
312
|
+
// Emit response metadata on first chunk
|
|
313
|
+
if (isFirstChunk) {
|
|
314
|
+
isFirstChunk = false;
|
|
315
|
+
controller.enqueue({
|
|
316
|
+
type: 'response-metadata',
|
|
317
|
+
...getResponseMetadata(value),
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Track usage (appears in final chunk)
|
|
322
|
+
if (value.usage != null) {
|
|
323
|
+
usage = value.usage;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Skip processing if no choices (usage-only chunk)
|
|
327
|
+
if (value.choices.length === 0) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const choice = value.choices[0];
|
|
332
|
+
const delta = choice.delta;
|
|
333
|
+
|
|
334
|
+
// Handle reasoning content streaming (Alibaba thinking mode)
|
|
335
|
+
if (
|
|
336
|
+
delta.reasoning_content != null &&
|
|
337
|
+
delta.reasoning_content.length > 0
|
|
338
|
+
) {
|
|
339
|
+
if (activeReasoningId == null) {
|
|
340
|
+
// End any active text before starting reasoning
|
|
341
|
+
if (activeText) {
|
|
342
|
+
controller.enqueue({ type: 'text-end', id: '0' });
|
|
343
|
+
activeText = false;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
activeReasoningId = generateId();
|
|
347
|
+
controller.enqueue({
|
|
348
|
+
type: 'reasoning-start',
|
|
349
|
+
id: activeReasoningId,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
controller.enqueue({
|
|
354
|
+
type: 'reasoning-delta',
|
|
355
|
+
id: activeReasoningId,
|
|
356
|
+
delta: delta.reasoning_content,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Handle text content streaming
|
|
361
|
+
if (delta.content != null && delta.content.length > 0) {
|
|
362
|
+
// End any active reasoning before starting text
|
|
363
|
+
if (activeReasoningId != null) {
|
|
364
|
+
controller.enqueue({
|
|
365
|
+
type: 'reasoning-end',
|
|
366
|
+
id: activeReasoningId,
|
|
367
|
+
});
|
|
368
|
+
activeReasoningId = null;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (!activeText) {
|
|
372
|
+
controller.enqueue({ type: 'text-start', id: '0' });
|
|
373
|
+
activeText = true;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
controller.enqueue({
|
|
377
|
+
type: 'text-delta',
|
|
378
|
+
id: '0',
|
|
379
|
+
delta: delta.content,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Handle tool call streaming
|
|
384
|
+
if (delta.tool_calls != null) {
|
|
385
|
+
// End any active reasoning or text before tool calls
|
|
386
|
+
if (activeReasoningId != null) {
|
|
387
|
+
controller.enqueue({
|
|
388
|
+
type: 'reasoning-end',
|
|
389
|
+
id: activeReasoningId,
|
|
390
|
+
});
|
|
391
|
+
activeReasoningId = null;
|
|
392
|
+
}
|
|
393
|
+
if (activeText) {
|
|
394
|
+
controller.enqueue({ type: 'text-end', id: '0' });
|
|
395
|
+
activeText = false;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
399
|
+
toolCallTracker.processDelta(toolCallDelta);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Track finish reason
|
|
404
|
+
if (choice.finish_reason != null) {
|
|
405
|
+
finishReason = {
|
|
406
|
+
unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
|
|
407
|
+
raw: choice.finish_reason,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
flush(controller) {
|
|
413
|
+
if (activeReasoningId != null) {
|
|
414
|
+
controller.enqueue({
|
|
415
|
+
type: 'reasoning-end',
|
|
416
|
+
id: activeReasoningId,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (activeText) {
|
|
421
|
+
controller.enqueue({ type: 'text-end', id: '0' });
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
toolCallTracker.flush();
|
|
425
|
+
|
|
426
|
+
controller.enqueue({
|
|
427
|
+
type: 'finish',
|
|
428
|
+
finishReason,
|
|
429
|
+
usage: convertAlibabaUsage(usage),
|
|
430
|
+
});
|
|
431
|
+
},
|
|
432
|
+
}),
|
|
433
|
+
),
|
|
434
|
+
request: { body: JSON.stringify(body) },
|
|
435
|
+
response: { headers: responseHeaders },
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function resolveAlibabaThinking({
|
|
441
|
+
reasoning,
|
|
442
|
+
alibabaOptions,
|
|
443
|
+
warnings,
|
|
444
|
+
}: {
|
|
445
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
446
|
+
alibabaOptions:
|
|
447
|
+
| InferSchema<typeof alibabaLanguageModelChatOptions>
|
|
448
|
+
| undefined;
|
|
449
|
+
warnings: SharedV4Warning[];
|
|
450
|
+
}): { enable_thinking?: boolean; thinking_budget?: number } {
|
|
451
|
+
if (
|
|
452
|
+
alibabaOptions?.enableThinking != null ||
|
|
453
|
+
alibabaOptions?.thinkingBudget != null
|
|
454
|
+
) {
|
|
455
|
+
return {
|
|
456
|
+
...(alibabaOptions.enableThinking != null
|
|
457
|
+
? { enable_thinking: alibabaOptions.enableThinking }
|
|
458
|
+
: {}),
|
|
459
|
+
...(alibabaOptions.thinkingBudget != null
|
|
460
|
+
? { thinking_budget: alibabaOptions.thinkingBudget }
|
|
461
|
+
: {}),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (!isCustomReasoning(reasoning)) {
|
|
466
|
+
return {};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (reasoning === 'none') {
|
|
470
|
+
return { enable_thinking: false };
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const thinkingBudget = mapReasoningToProviderBudget({
|
|
474
|
+
reasoning,
|
|
475
|
+
maxOutputTokens: 16384,
|
|
476
|
+
maxReasoningBudget: 16384,
|
|
477
|
+
warnings,
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
enable_thinking: true,
|
|
482
|
+
...(thinkingBudget != null ? { thinking_budget: thinkingBudget } : {}),
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Reference for schemas below:
|
|
488
|
+
* https://www.alibabacloud.com/help/en/model-studio/qwen-api-via-openai-chat-completions
|
|
489
|
+
*/
|
|
490
|
+
const alibabaUsageSchema = z.object({
|
|
491
|
+
prompt_tokens: z.number(),
|
|
492
|
+
completion_tokens: z.number(),
|
|
493
|
+
total_tokens: z.number(),
|
|
494
|
+
prompt_tokens_details: z
|
|
495
|
+
.object({
|
|
496
|
+
cached_tokens: z.number().nullish(),
|
|
497
|
+
cache_creation_input_tokens: z.number().nullish(),
|
|
498
|
+
})
|
|
499
|
+
.nullish(),
|
|
500
|
+
completion_tokens_details: z
|
|
501
|
+
.object({
|
|
502
|
+
reasoning_tokens: z.number().nullish(),
|
|
503
|
+
})
|
|
504
|
+
.nullish(),
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
const alibabaChatResponseSchema = z.object({
|
|
508
|
+
id: z.string().nullish(),
|
|
509
|
+
created: z.number().nullish(),
|
|
510
|
+
model: z.string().nullish(),
|
|
511
|
+
choices: z.array(
|
|
512
|
+
z.object({
|
|
513
|
+
message: z.object({
|
|
514
|
+
role: z.literal('assistant').nullish(),
|
|
515
|
+
content: z.string().nullish(),
|
|
516
|
+
reasoning_content: z.string().nullish(), // Alibaba thinking mode
|
|
517
|
+
tool_calls: z
|
|
518
|
+
.array(
|
|
519
|
+
z.object({
|
|
520
|
+
id: z.string(),
|
|
521
|
+
type: z.literal('function'),
|
|
522
|
+
function: z.object({
|
|
523
|
+
name: z.string(),
|
|
524
|
+
arguments: z.string(),
|
|
525
|
+
}),
|
|
526
|
+
}),
|
|
527
|
+
)
|
|
528
|
+
.nullish(),
|
|
529
|
+
}),
|
|
530
|
+
finish_reason: z.string().nullish(),
|
|
531
|
+
index: z.number(),
|
|
532
|
+
}),
|
|
533
|
+
),
|
|
534
|
+
usage: alibabaUsageSchema.nullish(),
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
const alibabaChatChunkSchema = z.object({
|
|
538
|
+
id: z.string().nullish(),
|
|
539
|
+
created: z.number().nullish(),
|
|
540
|
+
model: z.string().nullish(),
|
|
541
|
+
choices: z.array(
|
|
542
|
+
z.object({
|
|
543
|
+
delta: z.object({
|
|
544
|
+
role: z.enum(['assistant']).nullish(),
|
|
545
|
+
content: z.string().nullish(),
|
|
546
|
+
reasoning_content: z.string().nullish(), // Alibaba thinking mode delta
|
|
547
|
+
tool_calls: z
|
|
548
|
+
.array(
|
|
549
|
+
z.object({
|
|
550
|
+
index: z.number().nullish(), // Index for accumulating tool calls
|
|
551
|
+
id: z.string().nullish(),
|
|
552
|
+
type: z.literal('function').nullish(),
|
|
553
|
+
function: z
|
|
554
|
+
.object({
|
|
555
|
+
name: z.string().nullish(),
|
|
556
|
+
arguments: z.string().nullish(),
|
|
557
|
+
})
|
|
558
|
+
.nullish(),
|
|
559
|
+
}),
|
|
560
|
+
)
|
|
561
|
+
.nullish(),
|
|
562
|
+
}),
|
|
563
|
+
finish_reason: z.string().nullish(),
|
|
564
|
+
index: z.number(),
|
|
565
|
+
}),
|
|
566
|
+
),
|
|
567
|
+
usage: alibabaUsageSchema.nullish(), // Usage only appears in final chunk
|
|
568
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type AlibabaCacheControl = { type: string };
|
|
2
|
+
|
|
3
|
+
export type AlibabaChatPrompt = Array<AlibabaChatMessage>;
|
|
4
|
+
|
|
5
|
+
export type AlibabaChatMessage =
|
|
6
|
+
| AlibabaChatSystemMessage
|
|
7
|
+
| AlibabaChatUserMessage
|
|
8
|
+
| AlibabaChatAssistantMessage
|
|
9
|
+
| AlibabaChatToolMessage;
|
|
10
|
+
|
|
11
|
+
export interface AlibabaChatSystemMessage {
|
|
12
|
+
role: 'system';
|
|
13
|
+
content: string | Array<AlibabaChatSystemMessageContent>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type AlibabaChatSystemMessageContent = {
|
|
17
|
+
type: 'text';
|
|
18
|
+
text: string;
|
|
19
|
+
cache_control?: AlibabaCacheControl;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface AlibabaChatUserMessage {
|
|
23
|
+
role: 'user';
|
|
24
|
+
content: string | Array<AlibabaChatUserMessageContent>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type AlibabaChatUserMessageContent =
|
|
28
|
+
| { type: 'text'; text: string; cache_control?: AlibabaCacheControl }
|
|
29
|
+
| {
|
|
30
|
+
type: 'image_url';
|
|
31
|
+
image_url: { url: string };
|
|
32
|
+
cache_control?: AlibabaCacheControl;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export interface AlibabaChatAssistantMessage {
|
|
36
|
+
role: 'assistant';
|
|
37
|
+
content: string | null | Array<AlibabaChatAssistantMessageContent>;
|
|
38
|
+
tool_calls?: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
type: 'function';
|
|
41
|
+
function: { name: string; arguments: string };
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type AlibabaChatAssistantMessageContent = {
|
|
46
|
+
type: 'text';
|
|
47
|
+
text: string;
|
|
48
|
+
cache_control?: AlibabaCacheControl;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export interface AlibabaChatToolMessage {
|
|
52
|
+
role: 'tool';
|
|
53
|
+
tool_call_id: string;
|
|
54
|
+
content: string | Array<AlibabaChatToolMessageContent>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type AlibabaChatToolMessageContent = {
|
|
58
|
+
type: 'text';
|
|
59
|
+
text: string;
|
|
60
|
+
cache_control?: AlibabaCacheControl;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type AlibabaChatToolChoice =
|
|
64
|
+
| { type: 'function'; function: { name: string } }
|
|
65
|
+
| 'auto'
|
|
66
|
+
| 'none'
|
|
67
|
+
| 'required';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
export type AlibabaEmbeddingModelId =
|
|
4
|
+
| 'text-embedding-v4'
|
|
5
|
+
| 'text-embedding-v3'
|
|
6
|
+
| (string & {});
|
|
7
|
+
|
|
8
|
+
export const alibabaEmbeddingModelOptions = z.object({
|
|
9
|
+
/**
|
|
10
|
+
* Differentiates query text from document text for asymmetric retrieval tasks.
|
|
11
|
+
* Defaults to `document`.
|
|
12
|
+
*/
|
|
13
|
+
textType: z.enum(['query', 'document']).optional(),
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The dimension of the output embedding vectors. Defaults to 1024.
|
|
17
|
+
*
|
|
18
|
+
* `text-embedding-v4` also supports 1536 and 2048 dimensions.
|
|
19
|
+
*/
|
|
20
|
+
dimension: z.number().optional(),
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The output vector type. Defaults to `dense`.
|
|
24
|
+
*
|
|
25
|
+
* Sparse-only output is not supported by the AI SDK embedding interface,
|
|
26
|
+
* which requires dense number arrays.
|
|
27
|
+
*/
|
|
28
|
+
outputType: z.enum(['dense', 'sparse', 'dense&sparse']).optional(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export type AlibabaEmbeddingModelOptions = z.infer<
|
|
32
|
+
typeof alibabaEmbeddingModelOptions
|
|
33
|
+
>;
|