@ai-sdk/alibaba 1.0.54 → 1.0.55
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 +6 -0
- package/README.md +54 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +61 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/alibaba-chat-language-model.ts +13 -0
- package/src/alibaba-chat-options.ts +10 -0
- package/src/alibaba-chat-prompt.ts +1 -0
- package/src/convert-to-alibaba-chat-messages.ts +39 -6
- package/src/supports-preserved-thinking.ts +30 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -63,6 +63,60 @@ console.log('Reasoning:', reasoningText);
|
|
|
63
63
|
console.log('Answer:', text);
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## Preserved Thinking Example (Multi-Turn Reasoning)
|
|
67
|
+
|
|
68
|
+
For models that support preserved thinking, the AI SDK sends reasoning from
|
|
69
|
+
previous assistant messages back as Alibaba `reasoning_content` by default
|
|
70
|
+
(`preserve_thinking`), so the model can build on its earlier thought process:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { alibaba } from '@ai-sdk/alibaba';
|
|
74
|
+
import { generateText } from 'ai';
|
|
75
|
+
|
|
76
|
+
const providerOptions = {
|
|
77
|
+
alibaba: {
|
|
78
|
+
enableThinking: true,
|
|
79
|
+
thinkingBudget: 2048,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const opening = {
|
|
84
|
+
role: 'user' as const,
|
|
85
|
+
content: 'Is Kafka or RocketMQ a better fit for transactional messages?',
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const first = await generateText({
|
|
89
|
+
model: alibaba('qwen3.7-max'),
|
|
90
|
+
messages: [opening],
|
|
91
|
+
providerOptions,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const second = await generateText({
|
|
95
|
+
model: alibaba('qwen3.7-max'),
|
|
96
|
+
messages: [
|
|
97
|
+
opening,
|
|
98
|
+
...first.responseMessages, // append unchanged to keep the reasoning parts
|
|
99
|
+
{ role: 'user', content: 'Which tradeoff mattered most?' },
|
|
100
|
+
],
|
|
101
|
+
providerOptions,
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
When continuing the conversation, append `responseMessages` unchanged so the
|
|
106
|
+
reasoning parts survive to be serialized as `reasoning_content`. Set the
|
|
107
|
+
`preserveThinking` provider option to `false` to opt out. Keep in mind:
|
|
108
|
+
|
|
109
|
+
- `preserveThinking` does not enable thinking by itself.
|
|
110
|
+
- It is enabled by default only for models that Alibaba documents as supporting
|
|
111
|
+
preserved thinking; for other models the option is not sent unless you set it
|
|
112
|
+
explicitly. See Alibaba's
|
|
113
|
+
[preserved-thinking documentation](https://docs.qwencloud.com/developer-guides/text-generation/thinking#preserve-thinking-in-multi-turn).
|
|
114
|
+
- Reasoning from the current tool-call round is always sent back with tool
|
|
115
|
+
results, as Alibaba recommends.
|
|
116
|
+
- Preserved reasoning increases input token usage and billing.
|
|
117
|
+
- Historical reasoning remains separate from visible assistant text; it is never
|
|
118
|
+
merged into `content`.
|
|
119
|
+
|
|
66
120
|
## Embedding Model Example
|
|
67
121
|
|
|
68
122
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -6,6 +6,7 @@ type AlibabaChatModelId = 'qwen3.7-max' | 'qwen3-max' | 'qwen3-max-preview' | 'q
|
|
|
6
6
|
declare const alibabaLanguageModelOptions: z.ZodObject<{
|
|
7
7
|
enableThinking: z.ZodOptional<z.ZodBoolean>;
|
|
8
8
|
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
preserveThinking: z.ZodOptional<z.ZodBoolean>;
|
|
9
10
|
parallelToolCalls: z.ZodOptional<z.ZodBoolean>;
|
|
10
11
|
}, z.core.$strip>;
|
|
11
12
|
type AlibabaLanguageModelOptions = z.infer<typeof alibabaLanguageModelOptions>;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ type AlibabaChatModelId = 'qwen3.7-max' | 'qwen3-max' | 'qwen3-max-preview' | 'q
|
|
|
6
6
|
declare const alibabaLanguageModelOptions: z.ZodObject<{
|
|
7
7
|
enableThinking: z.ZodOptional<z.ZodBoolean>;
|
|
8
8
|
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
9
|
+
preserveThinking: z.ZodOptional<z.ZodBoolean>;
|
|
9
10
|
parallelToolCalls: z.ZodOptional<z.ZodBoolean>;
|
|
10
11
|
}, z.core.$strip>;
|
|
11
12
|
type AlibabaLanguageModelOptions = z.infer<typeof alibabaLanguageModelOptions>;
|
package/dist/index.js
CHANGED
|
@@ -50,6 +50,15 @@ var alibabaLanguageModelOptions = import_v4.z.object({
|
|
|
50
50
|
* Maximum number of reasoning tokens to generate.
|
|
51
51
|
*/
|
|
52
52
|
thinkingBudget: import_v4.z.number().positive().optional(),
|
|
53
|
+
/**
|
|
54
|
+
* Whether to preserve reasoning from previous assistant messages.
|
|
55
|
+
*
|
|
56
|
+
* When enabled, historical reasoning is sent separately as
|
|
57
|
+
* `reasoning_content` and Alibaba receives `preserve_thinking: true`.
|
|
58
|
+
* Defaults to `true` for models that support preserved thinking; set to
|
|
59
|
+
* `false` to opt out.
|
|
60
|
+
*/
|
|
61
|
+
preserveThinking: import_v4.z.boolean().optional(),
|
|
53
62
|
/**
|
|
54
63
|
* Whether to enable parallel function calling during tool use.
|
|
55
64
|
*
|
|
@@ -101,11 +110,21 @@ function formatImageUrl({
|
|
|
101
110
|
}
|
|
102
111
|
function convertToAlibabaChatMessages({
|
|
103
112
|
prompt,
|
|
104
|
-
cacheControlValidator
|
|
113
|
+
cacheControlValidator,
|
|
114
|
+
preserveThinking = false
|
|
105
115
|
}) {
|
|
106
116
|
var _a, _b;
|
|
107
117
|
const messages = [];
|
|
118
|
+
let lastUserMessageIndex = -1;
|
|
119
|
+
for (let i = prompt.length - 1; i >= 0; i--) {
|
|
120
|
+
if (prompt[i].role === "user") {
|
|
121
|
+
lastUserMessageIndex = i;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let index = -1;
|
|
108
126
|
for (const { role, content, ...message } of prompt) {
|
|
127
|
+
index++;
|
|
109
128
|
const messageCacheControl = cacheControlValidator == null ? void 0 : cacheControlValidator.getCacheControl(
|
|
110
129
|
message.providerOptions
|
|
111
130
|
);
|
|
@@ -130,9 +149,9 @@ function convertToAlibabaChatMessages({
|
|
|
130
149
|
case "user": {
|
|
131
150
|
messages.push({
|
|
132
151
|
role: "user",
|
|
133
|
-
content: content.map((part,
|
|
152
|
+
content: content.map((part, index2) => {
|
|
134
153
|
var _a2;
|
|
135
|
-
const isLastPart =
|
|
154
|
+
const isLastPart = index2 === content.length - 1;
|
|
136
155
|
const partCacheControl = (_a2 = cacheControlValidator == null ? void 0 : cacheControlValidator.getCacheControl(part.providerOptions)) != null ? _a2 : isLastPart ? messageCacheControl : void 0;
|
|
137
156
|
switch (part.type) {
|
|
138
157
|
case "text": {
|
|
@@ -165,6 +184,7 @@ function convertToAlibabaChatMessages({
|
|
|
165
184
|
}
|
|
166
185
|
case "assistant": {
|
|
167
186
|
let text = "";
|
|
187
|
+
let reasoningContent = "";
|
|
168
188
|
const toolCalls = [];
|
|
169
189
|
for (const part of content) {
|
|
170
190
|
switch (part.type) {
|
|
@@ -184,14 +204,20 @@ function convertToAlibabaChatMessages({
|
|
|
184
204
|
break;
|
|
185
205
|
}
|
|
186
206
|
case "reasoning": {
|
|
187
|
-
|
|
207
|
+
if (preserveThinking || index > lastUserMessageIndex) {
|
|
208
|
+
reasoningContent += part.text;
|
|
209
|
+
}
|
|
188
210
|
break;
|
|
189
211
|
}
|
|
190
212
|
}
|
|
191
213
|
}
|
|
214
|
+
if (text.length === 0 && toolCalls.length === 0 && reasoningContent.length === 0) {
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
192
217
|
messages.push({
|
|
193
218
|
role: "assistant",
|
|
194
|
-
content: messageCacheControl ? [{ type: "text", text, cache_control: messageCacheControl }] : text || null,
|
|
219
|
+
content: text.length === 0 && toolCalls.length === 0 && reasoningContent.length > 0 ? null : messageCacheControl ? [{ type: "text", text, cache_control: messageCacheControl }] : text || null,
|
|
220
|
+
...reasoningContent.length > 0 ? { reasoning_content: reasoningContent } : {},
|
|
195
221
|
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
196
222
|
});
|
|
197
223
|
break;
|
|
@@ -277,6 +303,29 @@ var CacheControlValidator = class {
|
|
|
277
303
|
}
|
|
278
304
|
};
|
|
279
305
|
|
|
306
|
+
// src/supports-preserved-thinking.ts
|
|
307
|
+
var 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"
|
|
324
|
+
]);
|
|
325
|
+
function supportsPreservedThinking(modelId) {
|
|
326
|
+
return preservedThinkingModelIds.has(modelId);
|
|
327
|
+
}
|
|
328
|
+
|
|
280
329
|
// src/alibaba-chat-language-model.ts
|
|
281
330
|
var AlibabaLanguageModel = class {
|
|
282
331
|
constructor(modelId, config) {
|
|
@@ -309,7 +358,7 @@ var AlibabaLanguageModel = class {
|
|
|
309
358
|
tools,
|
|
310
359
|
toolChoice
|
|
311
360
|
}) {
|
|
312
|
-
var _a;
|
|
361
|
+
var _a, _b;
|
|
313
362
|
const warnings = [];
|
|
314
363
|
const cacheControlValidator = new CacheControlValidator();
|
|
315
364
|
const alibabaOptions = await (0, import_provider_utils3.parseProviderOptions)({
|
|
@@ -320,6 +369,7 @@ var AlibabaLanguageModel = class {
|
|
|
320
369
|
if (frequencyPenalty != null) {
|
|
321
370
|
warnings.push({ type: "unsupported", feature: "frequencyPenalty" });
|
|
322
371
|
}
|
|
372
|
+
const preserveThinking = (_a = alibabaOptions == null ? void 0 : alibabaOptions.preserveThinking) != null ? _a : supportsPreservedThinking(this.modelId) ? true : void 0;
|
|
323
373
|
const baseArgs = {
|
|
324
374
|
model: this.modelId,
|
|
325
375
|
max_tokens: maxOutputTokens,
|
|
@@ -333,17 +383,19 @@ var AlibabaLanguageModel = class {
|
|
|
333
383
|
type: "json_schema",
|
|
334
384
|
json_schema: {
|
|
335
385
|
schema: responseFormat.schema,
|
|
336
|
-
name: (
|
|
386
|
+
name: (_b = responseFormat.name) != null ? _b : "response",
|
|
337
387
|
description: responseFormat.description
|
|
338
388
|
}
|
|
339
389
|
} : { type: "json_object" } : void 0,
|
|
340
390
|
// Alibaba-specific options
|
|
341
391
|
...(alibabaOptions == null ? void 0 : alibabaOptions.enableThinking) != null ? { enable_thinking: alibabaOptions.enableThinking } : {},
|
|
342
392
|
...(alibabaOptions == null ? void 0 : alibabaOptions.thinkingBudget) != null ? { thinking_budget: alibabaOptions.thinkingBudget } : {},
|
|
393
|
+
...preserveThinking != null ? { preserve_thinking: preserveThinking } : {},
|
|
343
394
|
// Convert messages with cache control support
|
|
344
395
|
messages: convertToAlibabaChatMessages({
|
|
345
396
|
prompt,
|
|
346
|
-
cacheControlValidator
|
|
397
|
+
cacheControlValidator,
|
|
398
|
+
preserveThinking: preserveThinking != null ? preserveThinking : false
|
|
347
399
|
})
|
|
348
400
|
};
|
|
349
401
|
const {
|
|
@@ -1312,7 +1364,7 @@ var AlibabaVideoModel = class {
|
|
|
1312
1364
|
};
|
|
1313
1365
|
|
|
1314
1366
|
// src/version.ts
|
|
1315
|
-
var VERSION = true ? "1.0.
|
|
1367
|
+
var VERSION = true ? "1.0.55" : "0.0.0-test";
|
|
1316
1368
|
|
|
1317
1369
|
// src/alibaba-provider.ts
|
|
1318
1370
|
function createAlibaba(options = {}) {
|