@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,220 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UnsupportedFunctionalityError,
|
|
3
|
+
type LanguageModelV4FilePart,
|
|
4
|
+
type LanguageModelV4Prompt,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import {
|
|
7
|
+
convertToBase64,
|
|
8
|
+
getTopLevelMediaType,
|
|
9
|
+
resolveFullMediaType,
|
|
10
|
+
} from '@ai-sdk/provider-utils';
|
|
11
|
+
import type { AlibabaChatPrompt } from './alibaba-chat-prompt';
|
|
12
|
+
import type { CacheControlValidator } from './get-cache-control';
|
|
13
|
+
|
|
14
|
+
function formatImageUrl({ part }: { part: LanguageModelV4FilePart }): string {
|
|
15
|
+
if (part.data.type === 'url') {
|
|
16
|
+
return part.data.url.toString();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (part.data.type === 'data') {
|
|
20
|
+
return `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw new UnsupportedFunctionalityError({
|
|
24
|
+
functionality: `file part data type ${part.data.type}`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function convertToAlibabaChatMessages({
|
|
29
|
+
prompt,
|
|
30
|
+
cacheControlValidator,
|
|
31
|
+
}: {
|
|
32
|
+
prompt: LanguageModelV4Prompt;
|
|
33
|
+
cacheControlValidator?: CacheControlValidator;
|
|
34
|
+
}): AlibabaChatPrompt {
|
|
35
|
+
const messages: AlibabaChatPrompt = [];
|
|
36
|
+
|
|
37
|
+
for (const { role, content, ...message } of prompt) {
|
|
38
|
+
const messageCacheControl = cacheControlValidator?.getCacheControl(
|
|
39
|
+
message.providerOptions,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
switch (role) {
|
|
43
|
+
case 'system': {
|
|
44
|
+
if (messageCacheControl) {
|
|
45
|
+
messages.push({
|
|
46
|
+
role: 'system',
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: 'text',
|
|
50
|
+
text: content,
|
|
51
|
+
cache_control: messageCacheControl,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
messages.push({ role: 'system', content });
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
case 'user': {
|
|
62
|
+
messages.push({
|
|
63
|
+
role: 'user',
|
|
64
|
+
content: content.map((part, index) => {
|
|
65
|
+
const isLastPart = index === content.length - 1;
|
|
66
|
+
const partCacheControl =
|
|
67
|
+
cacheControlValidator?.getCacheControl(part.providerOptions) ??
|
|
68
|
+
(isLastPart ? messageCacheControl : undefined);
|
|
69
|
+
|
|
70
|
+
switch (part.type) {
|
|
71
|
+
case 'text': {
|
|
72
|
+
return {
|
|
73
|
+
type: 'text',
|
|
74
|
+
text: part.text,
|
|
75
|
+
...(partCacheControl
|
|
76
|
+
? { cache_control: partCacheControl }
|
|
77
|
+
: {}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
case 'file': {
|
|
82
|
+
switch (part.data.type) {
|
|
83
|
+
case 'reference': {
|
|
84
|
+
throw new UnsupportedFunctionalityError({
|
|
85
|
+
functionality: 'file parts with provider references',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
case 'text': {
|
|
89
|
+
throw new UnsupportedFunctionalityError({
|
|
90
|
+
functionality: 'text file parts',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
case 'url':
|
|
94
|
+
case 'data': {
|
|
95
|
+
if (getTopLevelMediaType(part.mediaType) === 'image') {
|
|
96
|
+
return {
|
|
97
|
+
type: 'image_url',
|
|
98
|
+
image_url: {
|
|
99
|
+
url: formatImageUrl({ part }),
|
|
100
|
+
},
|
|
101
|
+
...(partCacheControl
|
|
102
|
+
? { cache_control: partCacheControl }
|
|
103
|
+
: {}),
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
throw new UnsupportedFunctionalityError({
|
|
107
|
+
functionality: 'Only image file parts are supported',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}),
|
|
115
|
+
});
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
case 'assistant': {
|
|
120
|
+
let text = '';
|
|
121
|
+
const toolCalls: Array<{
|
|
122
|
+
id: string;
|
|
123
|
+
type: 'function';
|
|
124
|
+
function: { name: string; arguments: string };
|
|
125
|
+
}> = [];
|
|
126
|
+
|
|
127
|
+
for (const part of content) {
|
|
128
|
+
switch (part.type) {
|
|
129
|
+
case 'text': {
|
|
130
|
+
text += part.text;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'tool-call': {
|
|
134
|
+
toolCalls.push({
|
|
135
|
+
id: part.toolCallId,
|
|
136
|
+
type: 'function',
|
|
137
|
+
function: {
|
|
138
|
+
name: part.toolName,
|
|
139
|
+
arguments: JSON.stringify(part.input),
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case 'reasoning': {
|
|
145
|
+
// Reasoning content is handled separately in the response
|
|
146
|
+
// but may appear in assistant messages during multi-turn conversations
|
|
147
|
+
text += part.text;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
messages.push({
|
|
154
|
+
role: 'assistant',
|
|
155
|
+
content: messageCacheControl
|
|
156
|
+
? [{ type: 'text', text, cache_control: messageCacheControl }]
|
|
157
|
+
: text || null,
|
|
158
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
case 'tool': {
|
|
165
|
+
const toolResponses = content.filter(
|
|
166
|
+
r => r.type !== 'tool-approval-response',
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
for (let i = 0; i < toolResponses.length; i++) {
|
|
170
|
+
const toolResponse = toolResponses[i];
|
|
171
|
+
const output = toolResponse.output;
|
|
172
|
+
const isLastPart = i === toolResponses.length - 1;
|
|
173
|
+
|
|
174
|
+
const partCacheControl =
|
|
175
|
+
cacheControlValidator?.getCacheControl(
|
|
176
|
+
toolResponse.providerOptions,
|
|
177
|
+
) ?? (isLastPart ? messageCacheControl : undefined);
|
|
178
|
+
|
|
179
|
+
let contentValue: string;
|
|
180
|
+
switch (output.type) {
|
|
181
|
+
case 'text':
|
|
182
|
+
case 'error-text':
|
|
183
|
+
contentValue = output.value;
|
|
184
|
+
break;
|
|
185
|
+
case 'execution-denied':
|
|
186
|
+
contentValue = output.reason ?? 'Tool call execution denied.';
|
|
187
|
+
break;
|
|
188
|
+
case 'content':
|
|
189
|
+
case 'json':
|
|
190
|
+
case 'error-json':
|
|
191
|
+
contentValue = JSON.stringify(output.value);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
messages.push({
|
|
196
|
+
role: 'tool',
|
|
197
|
+
tool_call_id: toolResponse.toolCallId,
|
|
198
|
+
content: partCacheControl
|
|
199
|
+
? [
|
|
200
|
+
{
|
|
201
|
+
type: 'text',
|
|
202
|
+
text: contentValue,
|
|
203
|
+
cache_control: partCacheControl,
|
|
204
|
+
},
|
|
205
|
+
]
|
|
206
|
+
: contentValue,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
default: {
|
|
213
|
+
const _exhaustiveCheck: never = role;
|
|
214
|
+
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return messages;
|
|
220
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SharedV4ProviderMetadata,
|
|
3
|
+
SharedV4Warning,
|
|
4
|
+
} from '@ai-sdk/provider';
|
|
5
|
+
import type { AlibabaCacheControl } from './alibaba-chat-prompt';
|
|
6
|
+
|
|
7
|
+
// Alibaba allows a maximum of 4 cache breakpoints per request
|
|
8
|
+
const MAX_CACHE_BREAKPOINTS = 4;
|
|
9
|
+
|
|
10
|
+
function getCacheControl(
|
|
11
|
+
providerMetadata: SharedV4ProviderMetadata | undefined,
|
|
12
|
+
): AlibabaCacheControl | undefined {
|
|
13
|
+
const alibaba = providerMetadata?.alibaba;
|
|
14
|
+
|
|
15
|
+
const cacheControlValue = alibaba?.cacheControl ?? alibaba?.cache_control;
|
|
16
|
+
|
|
17
|
+
// Pass through value assuming it is of the correct type.
|
|
18
|
+
// The Alibaba API will validate the value.
|
|
19
|
+
return cacheControlValue as AlibabaCacheControl | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class CacheControlValidator {
|
|
23
|
+
private breakpointCount = 0;
|
|
24
|
+
private warnings: SharedV4Warning[] = [];
|
|
25
|
+
|
|
26
|
+
getCacheControl(
|
|
27
|
+
providerMetadata: SharedV4ProviderMetadata | undefined,
|
|
28
|
+
): AlibabaCacheControl | undefined {
|
|
29
|
+
const cacheControlValue = getCacheControl(providerMetadata);
|
|
30
|
+
|
|
31
|
+
if (!cacheControlValue) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
this.breakpointCount++;
|
|
36
|
+
if (this.breakpointCount > MAX_CACHE_BREAKPOINTS) {
|
|
37
|
+
this.warnings.push({
|
|
38
|
+
type: 'other',
|
|
39
|
+
message: `Max breakpoint limit exceeded. Only the last ${MAX_CACHE_BREAKPOINTS} cache markers will take effect.`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return cacheControlValue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getWarnings(): SharedV4Warning[] {
|
|
47
|
+
return this.warnings;
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AlibabaChatModelId,
|
|
3
|
+
AlibabaLanguageModelChatOptions,
|
|
4
|
+
/** @deprecated Use `AlibabaLanguageModelChatOptions` instead. */
|
|
5
|
+
AlibabaLanguageModelChatOptions as AlibabaLanguageModelOptions,
|
|
6
|
+
/** @deprecated Use `AlibabaLanguageModelChatOptions` instead. */
|
|
7
|
+
AlibabaLanguageModelChatOptions as AlibabaProviderOptions,
|
|
8
|
+
} from './alibaba-chat-language-model-options';
|
|
9
|
+
export type { AlibabaCacheControl } from './alibaba-chat-prompt';
|
|
10
|
+
export type {
|
|
11
|
+
AlibabaEmbeddingModelId,
|
|
12
|
+
AlibabaEmbeddingModelOptions,
|
|
13
|
+
} from './alibaba-embedding-model-options';
|
|
14
|
+
export {
|
|
15
|
+
type AlibabaProvider,
|
|
16
|
+
type AlibabaProviderSettings,
|
|
17
|
+
alibaba,
|
|
18
|
+
createAlibaba,
|
|
19
|
+
} from './alibaba-provider';
|
|
20
|
+
export type {
|
|
21
|
+
AlibabaVideoModelOptions,
|
|
22
|
+
/** @deprecated Use `AlibabaVideoModelOptions` instead. */
|
|
23
|
+
AlibabaVideoModelOptions as AlibabaVideoProviderOptions,
|
|
24
|
+
} from './alibaba-video-model-options';
|
|
25
|
+
export type { AlibabaVideoModelId } from './alibaba-video-settings';
|
|
26
|
+
export type { AlibabaUsage } from './convert-alibaba-usage';
|
|
27
|
+
export { VERSION } from './version';
|