@ai-sdk/anthropic 4.0.0-beta.16 → 4.0.0-beta.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/anthropic",
3
- "version": "4.0.0-beta.16",
3
+ "version": "4.0.0-beta.17",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -36,8 +36,8 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "@ai-sdk/provider": "4.0.0-beta.5",
40
- "@ai-sdk/provider-utils": "5.0.0-beta.9"
39
+ "@ai-sdk/provider": "4.0.0-beta.6",
40
+ "@ai-sdk/provider-utils": "5.0.0-beta.10"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -0,0 +1,106 @@
1
+ import {
2
+ FilesV4,
3
+ FilesV4UploadFileCallOptions,
4
+ FilesV4UploadFileResult,
5
+ } from '@ai-sdk/provider';
6
+ import {
7
+ combineHeaders,
8
+ convertBase64ToUint8Array,
9
+ createJsonResponseHandler,
10
+ FetchFunction,
11
+ lazySchema,
12
+ parseProviderOptions,
13
+ postFormDataToApi,
14
+ zodSchema,
15
+ } from '@ai-sdk/provider-utils';
16
+ import { z } from 'zod/v4';
17
+ import { anthropicFailedResponseHandler } from './anthropic-error';
18
+
19
+ const anthropicUploadFileProviderOptions = z.object({});
20
+
21
+ const anthropicUploadFileResponseSchema = lazySchema(() =>
22
+ zodSchema(
23
+ z.object({
24
+ id: z.string(),
25
+ type: z.literal('file'),
26
+ filename: z.string(),
27
+ mime_type: z.string(),
28
+ size_bytes: z.number(),
29
+ created_at: z.string(),
30
+ downloadable: z.boolean().nullish(),
31
+ }),
32
+ ),
33
+ );
34
+
35
+ interface AnthropicFilesConfig {
36
+ provider: string;
37
+ baseURL: string;
38
+ headers: () => Record<string, string | undefined>;
39
+ fetch?: FetchFunction;
40
+ }
41
+
42
+ export class AnthropicFiles implements FilesV4 {
43
+ readonly specificationVersion = 'v4';
44
+
45
+ get provider(): string {
46
+ return this.config.provider;
47
+ }
48
+
49
+ constructor(private readonly config: AnthropicFilesConfig) {}
50
+
51
+ async uploadFile({
52
+ data,
53
+ mediaType,
54
+ filename,
55
+ providerOptions,
56
+ }: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult> {
57
+ const anthropicOptions = await parseProviderOptions({
58
+ provider: 'anthropic',
59
+ providerOptions,
60
+ schema: zodSchema(anthropicUploadFileProviderOptions),
61
+ });
62
+
63
+ const fileBytes =
64
+ data instanceof Uint8Array ? data : convertBase64ToUint8Array(data);
65
+
66
+ const blob = new Blob([fileBytes], { type: mediaType });
67
+
68
+ const formData = new FormData();
69
+ if (filename != null) {
70
+ formData.append('file', blob, filename);
71
+ } else {
72
+ formData.append('file', blob);
73
+ }
74
+
75
+ const { value: response } = await postFormDataToApi({
76
+ url: `${this.config.baseURL}/files`,
77
+ headers: combineHeaders(this.config.headers(), {
78
+ 'anthropic-beta': 'files-api-2025-04-14',
79
+ }),
80
+ formData,
81
+ failedResponseHandler: anthropicFailedResponseHandler,
82
+ successfulResponseHandler: createJsonResponseHandler(
83
+ anthropicUploadFileResponseSchema,
84
+ ),
85
+ fetch: this.config.fetch,
86
+ });
87
+
88
+ return {
89
+ warnings: [],
90
+ providerReference: { anthropic: response.id },
91
+ mediaType: response.mime_type ?? mediaType,
92
+ filename: response.filename ?? filename,
93
+ providerMetadata: {
94
+ anthropic: {
95
+ filename: response.filename,
96
+ mimeType: response.mime_type,
97
+ sizeBytes: response.size_bytes,
98
+ createdAt: response.created_at,
99
+ ...(response.downloadable != null
100
+ ? { downloadable: response.downloadable }
101
+ : {}),
102
+ },
103
+ },
104
+ };
105
+ }
106
+ }
@@ -87,6 +87,10 @@ type AnthropicContentSource =
87
87
  type: 'text';
88
88
  media_type: 'text/plain';
89
89
  data: string;
90
+ }
91
+ | {
92
+ type: 'file';
93
+ file_id: string;
90
94
  };
91
95
 
92
96
  export interface AnthropicImageContent {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ FilesV4,
2
3
  InvalidArgumentError,
3
4
  LanguageModelV4,
4
5
  NoSuchModelError,
@@ -12,10 +13,11 @@ import {
12
13
  withoutTrailingSlash,
13
14
  withUserAgentSuffix,
14
15
  } from '@ai-sdk/provider-utils';
15
- import { VERSION } from './version';
16
+ import { AnthropicFiles } from './anthropic-files';
16
17
  import { AnthropicMessagesLanguageModel } from './anthropic-messages-language-model';
17
18
  import { AnthropicMessagesModelId } from './anthropic-messages-options';
18
19
  import { anthropicTools } from './anthropic-tools';
20
+ import { VERSION } from './version';
19
21
 
20
22
  export interface AnthropicProvider extends ProviderV4 {
21
23
  /**
@@ -37,6 +39,8 @@ export interface AnthropicProvider extends ProviderV4 {
37
39
  */
38
40
  textEmbeddingModel(modelId: string): never;
39
41
 
42
+ files(): FilesV4;
43
+
40
44
  /**
41
45
  * Anthropic-specific computer use tool.
42
46
  */
@@ -166,6 +170,14 @@ export function createAnthropic(
166
170
  throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
167
171
  };
168
172
 
173
+ provider.files = () =>
174
+ new AnthropicFiles({
175
+ provider: providerName,
176
+ baseURL,
177
+ headers: getHeaders,
178
+ fetch: options.fetch,
179
+ });
180
+
169
181
  provider.tools = anthropicTools;
170
182
 
171
183
  return provider;
@@ -9,7 +9,9 @@ import {
9
9
  import {
10
10
  convertBase64ToUint8Array,
11
11
  convertToBase64,
12
+ isProviderReference,
12
13
  parseProviderOptions,
14
+ resolveProviderReference,
13
15
  validateTypes,
14
16
  isNonNullable,
15
17
  ToolNameMapping,
@@ -183,7 +185,27 @@ export async function convertToAnthropicMessagesPrompt({
183
185
  }
184
186
 
185
187
  case 'file': {
186
- if (part.mediaType.startsWith('image/')) {
188
+ if (isProviderReference(part.data)) {
189
+ const fileId = resolveProviderReference({
190
+ reference: part.data,
191
+ provider: 'anthropic',
192
+ });
193
+ betas.add('files-api-2025-04-14');
194
+
195
+ if (part.mediaType.startsWith('image/')) {
196
+ anthropicContent.push({
197
+ type: 'image',
198
+ source: { type: 'file', file_id: fileId },
199
+ cache_control: cacheControl,
200
+ });
201
+ } else {
202
+ anthropicContent.push({
203
+ type: 'document',
204
+ source: { type: 'file', file_id: fileId },
205
+ cache_control: cacheControl,
206
+ });
207
+ }
208
+ } else if (part.mediaType.startsWith('image/')) {
187
209
  anthropicContent.push({
188
210
  type: 'image',
189
211
  source: isUrlData(part.data)