@ai-sdk/anthropic 4.0.0-beta.3 → 4.0.0-beta.31

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.
@@ -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)
@@ -309,26 +331,16 @@ export async function convertToAnthropicMessagesPrompt({
309
331
  type: 'text' as const,
310
332
  text: contentPart.text,
311
333
  };
312
- case 'image-data': {
313
- return {
314
- type: 'image' as const,
315
- source: {
316
- type: 'base64' as const,
317
- media_type: contentPart.mediaType,
318
- data: contentPart.data,
319
- },
320
- };
321
- }
322
- case 'image-url': {
323
- return {
324
- type: 'image' as const,
325
- source: {
326
- type: 'url' as const,
327
- url: contentPart.url,
328
- },
329
- };
330
- }
331
334
  case 'file-url': {
335
+ if (contentPart.mediaType.startsWith('image/')) {
336
+ return {
337
+ type: 'image' as const,
338
+ source: {
339
+ type: 'url' as const,
340
+ url: contentPart.url,
341
+ },
342
+ };
343
+ }
332
344
  return {
333
345
  type: 'document' as const,
334
346
  source: {
@@ -338,6 +350,16 @@ export async function convertToAnthropicMessagesPrompt({
338
350
  };
339
351
  }
340
352
  case 'file-data': {
353
+ if (contentPart.mediaType.startsWith('image/')) {
354
+ return {
355
+ type: 'image' as const,
356
+ source: {
357
+ type: 'base64' as const,
358
+ media_type: contentPart.mediaType,
359
+ data: contentPart.data,
360
+ },
361
+ };
362
+ }
341
363
  if (contentPart.mediaType === 'application/pdf') {
342
364
  betas.add('pdfs-2024-09-25');
343
365
  return {
@@ -1,4 +1,7 @@
1
- export { AnthropicMessagesLanguageModel } from '../anthropic-messages-language-model';
1
+ export {
2
+ AnthropicMessagesLanguageModel,
3
+ getModelCapabilities,
4
+ } from '../anthropic-messages-language-model';
2
5
  export { anthropicTools } from '../anthropic-tools';
3
6
  export type { AnthropicMessagesModelId } from '../anthropic-messages-options';
4
7
  export { prepareTools } from '../anthropic-prepare-tools';
@@ -0,0 +1,44 @@
1
+ import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
2
+ import { z } from 'zod/v4';
3
+
4
+ export const anthropicSkillResponseSchema = lazySchema(() =>
5
+ zodSchema(
6
+ z.object({
7
+ id: z.string(),
8
+ display_title: z.string().nullish(),
9
+ name: z.string().nullish(),
10
+ description: z.string().nullish(),
11
+ latest_version: z.string().nullish(),
12
+ source: z.string(),
13
+ created_at: z.string(),
14
+ updated_at: z.string(),
15
+ }),
16
+ ),
17
+ );
18
+
19
+ export type AnthropicSkillResponse = ReturnType<
20
+ typeof anthropicSkillResponseSchema
21
+ >['_type'];
22
+
23
+ export const anthropicSkillVersionListResponseSchema = lazySchema(() =>
24
+ zodSchema(
25
+ z.object({
26
+ data: z.array(
27
+ z.object({
28
+ version: z.string(),
29
+ }),
30
+ ),
31
+ }),
32
+ ),
33
+ );
34
+
35
+ export const anthropicSkillVersionResponseSchema = lazySchema(() =>
36
+ zodSchema(
37
+ z.object({
38
+ type: z.string(),
39
+ skill_id: z.string(),
40
+ name: z.string().nullish(),
41
+ description: z.string().nullish(),
42
+ }),
43
+ ),
44
+ );
@@ -0,0 +1,136 @@
1
+ import { SkillsV4, SharedV4Warning } from '@ai-sdk/provider';
2
+ import {
3
+ combineHeaders,
4
+ convertBase64ToUint8Array,
5
+ createJsonResponseHandler,
6
+ FetchFunction,
7
+ getFromApi,
8
+ postFormDataToApi,
9
+ Resolvable,
10
+ resolve,
11
+ } from '@ai-sdk/provider-utils';
12
+ import { anthropicFailedResponseHandler } from '../anthropic-error';
13
+ import {
14
+ anthropicSkillResponseSchema,
15
+ anthropicSkillVersionResponseSchema,
16
+ } from './anthropic-skills-api';
17
+
18
+ interface AnthropicSkillsConfig {
19
+ provider: string;
20
+ baseURL: string;
21
+ headers: Resolvable<Record<string, string | undefined>>;
22
+ fetch?: FetchFunction;
23
+ }
24
+
25
+ export class AnthropicSkills implements SkillsV4 {
26
+ readonly specificationVersion = 'v4';
27
+
28
+ get provider(): string {
29
+ return this.config.provider;
30
+ }
31
+
32
+ constructor(private readonly config: AnthropicSkillsConfig) {}
33
+
34
+ private async getHeaders(): Promise<Record<string, string | undefined>> {
35
+ return combineHeaders(await resolve(this.config.headers), {
36
+ 'anthropic-beta': 'skills-2025-10-02',
37
+ });
38
+ }
39
+
40
+ private async fetchVersionMetadata({
41
+ skillId,
42
+ version,
43
+ headers,
44
+ }: {
45
+ skillId: string;
46
+ version: string;
47
+ headers: Record<string, string | undefined>;
48
+ }): Promise<{ name?: string; description?: string }> {
49
+ const { value: versionResponse } = await getFromApi({
50
+ url: `${this.config.baseURL}/skills/${skillId}/versions/${version}`,
51
+ headers,
52
+ failedResponseHandler: anthropicFailedResponseHandler,
53
+ successfulResponseHandler: createJsonResponseHandler(
54
+ anthropicSkillVersionResponseSchema,
55
+ ),
56
+ fetch: this.config.fetch,
57
+ });
58
+
59
+ return {
60
+ ...(versionResponse.name != null ? { name: versionResponse.name } : {}),
61
+ ...(versionResponse.description != null
62
+ ? { description: versionResponse.description }
63
+ : {}),
64
+ };
65
+ }
66
+
67
+ async uploadSkill(
68
+ params: Parameters<SkillsV4['uploadSkill']>[0],
69
+ ): Promise<Awaited<ReturnType<SkillsV4['uploadSkill']>>> {
70
+ const warnings: SharedV4Warning[] = [];
71
+
72
+ const formData = new FormData();
73
+
74
+ if (params.displayTitle != null) {
75
+ formData.append('display_title', params.displayTitle);
76
+ }
77
+
78
+ for (const file of params.files) {
79
+ const content =
80
+ typeof file.content === 'string'
81
+ ? convertBase64ToUint8Array(file.content)
82
+ : file.content;
83
+
84
+ formData.append('files[]', new Blob([content]), file.path);
85
+ }
86
+
87
+ const headers = await this.getHeaders();
88
+
89
+ const { value: response } = await postFormDataToApi({
90
+ url: `${this.config.baseURL}/skills`,
91
+ headers,
92
+ formData,
93
+ failedResponseHandler: anthropicFailedResponseHandler,
94
+ successfulResponseHandler: createJsonResponseHandler(
95
+ anthropicSkillResponseSchema,
96
+ ),
97
+ fetch: this.config.fetch,
98
+ });
99
+
100
+ const versionMetadata =
101
+ response.latest_version != null
102
+ ? await this.fetchVersionMetadata({
103
+ skillId: response.id,
104
+ version: response.latest_version,
105
+ headers,
106
+ })
107
+ : {};
108
+
109
+ const name = versionMetadata.name ?? response.name;
110
+ const description = versionMetadata.description ?? response.description;
111
+
112
+ return {
113
+ providerReference: { anthropic: response.id },
114
+ ...(response.display_title != null
115
+ ? { displayTitle: response.display_title }
116
+ : {}),
117
+ ...(name != null ? { name } : {}),
118
+ ...(description != null ? { description } : {}),
119
+ ...(response.latest_version != null
120
+ ? { latestVersion: response.latest_version }
121
+ : {}),
122
+ providerMetadata: {
123
+ anthropic: {
124
+ ...(response.source != null ? { source: response.source } : {}),
125
+ ...(response.created_at != null
126
+ ? { createdAt: response.created_at }
127
+ : {}),
128
+ ...(response.updated_at != null
129
+ ? { updatedAt: response.updated_at }
130
+ : {}),
131
+ },
132
+ },
133
+ warnings,
134
+ };
135
+ }
136
+ }