@ai-sdk/anthropic 4.0.0-beta.4 → 4.0.0-beta.40

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +293 -4
  2. package/README.md +2 -0
  3. package/dist/index.d.ts +83 -58
  4. package/dist/index.js +1918 -1259
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +85 -58
  7. package/dist/internal/index.js +1679 -1245
  8. package/dist/internal/index.js.map +1 -1
  9. package/docs/05-anthropic.mdx +115 -12
  10. package/package.json +14 -15
  11. package/src/{anthropic-messages-api.ts → anthropic-api.ts} +8 -4
  12. package/src/anthropic-files.ts +96 -0
  13. package/src/{anthropic-messages-language-model.ts → anthropic-language-model.ts} +239 -54
  14. package/src/anthropic-message-metadata.ts +0 -3
  15. package/src/{anthropic-messages-options.ts → anthropic-options.ts} +68 -11
  16. package/src/anthropic-prepare-tools.ts +12 -5
  17. package/src/anthropic-provider.ts +39 -10
  18. package/src/{convert-anthropic-messages-usage.ts → convert-anthropic-usage.ts} +3 -3
  19. package/src/{convert-to-anthropic-messages-prompt.ts → convert-to-anthropic-prompt.ts} +51 -28
  20. package/src/get-cache-control.ts +1 -1
  21. package/src/index.ts +1 -1
  22. package/src/internal/index.ts +11 -2
  23. package/src/sanitize-json-schema.ts +203 -0
  24. package/src/skills/anthropic-skills-api.ts +44 -0
  25. package/src/skills/anthropic-skills.ts +136 -0
  26. package/src/tool/bash_20241022.ts +2 -2
  27. package/src/tool/bash_20250124.ts +2 -2
  28. package/src/tool/code-execution_20250522.ts +2 -2
  29. package/src/tool/code-execution_20250825.ts +2 -2
  30. package/src/tool/code-execution_20260120.ts +2 -2
  31. package/src/tool/computer_20241022.ts +2 -2
  32. package/src/tool/computer_20250124.ts +2 -2
  33. package/src/tool/computer_20251124.ts +2 -2
  34. package/src/tool/memory_20250818.ts +2 -2
  35. package/src/tool/text-editor_20241022.ts +2 -2
  36. package/src/tool/text-editor_20250124.ts +2 -2
  37. package/src/tool/text-editor_20250429.ts +2 -2
  38. package/src/tool/text-editor_20250728.ts +2 -2
  39. package/src/tool/tool-search-bm25_20251119.ts +2 -2
  40. package/src/tool/tool-search-regex_20251119.ts +2 -2
  41. package/src/tool/web-fetch-20250910.ts +2 -2
  42. package/src/tool/web-fetch-20260209.ts +2 -2
  43. package/src/tool/web-search_20250305.ts +2 -2
  44. package/src/tool/web-search_20260209.ts +2 -2
  45. package/dist/index.d.mts +0 -1090
  46. package/dist/index.mjs +0 -5244
  47. package/dist/index.mjs.map +0 -1
  48. package/dist/internal/index.d.mts +0 -969
  49. package/dist/internal/index.mjs +0 -5136
  50. package/dist/internal/index.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod/v4';
2
2
 
3
3
  // https://docs.claude.com/en/docs/about-claude/models/overview
4
- export type AnthropicMessagesModelId =
4
+ export type AnthropicModelId =
5
5
  | 'claude-3-haiku-20240307'
6
6
  | 'claude-haiku-4-5-20251001'
7
7
  | 'claude-haiku-4-5'
@@ -17,6 +17,7 @@ export type AnthropicMessagesModelId =
17
17
  | 'claude-sonnet-4-5'
18
18
  | 'claude-sonnet-4-6'
19
19
  | 'claude-opus-4-6'
20
+ | 'claude-opus-4-7'
20
21
  | (string & {});
21
22
 
22
23
  /**
@@ -83,6 +84,12 @@ export const anthropicLanguageModelOptions = z.object({
83
84
  z.object({
84
85
  /** for Sonnet 4.6, Opus 4.6, and newer models */
85
86
  type: z.literal('adaptive'),
87
+ /**
88
+ * Controls whether thinking content is included in the response.
89
+ * - `"omitted"`: Thinking blocks are present but text is empty (default for Opus 4.7+).
90
+ * - `"summarized"`: Thinking content is returned. Required to see reasoning output.
91
+ */
92
+ display: z.enum(['omitted', 'summarized']).optional(),
86
93
  }),
87
94
  z.object({
88
95
  /** for models before Opus 4.6, except Sonnet 4.6 still supports it */
@@ -112,6 +119,23 @@ export const anthropicLanguageModelOptions = z.object({
112
119
  })
113
120
  .optional(),
114
121
 
122
+ /**
123
+ * Metadata to include with the request.
124
+ *
125
+ * See https://platform.claude.com/docs/en/api/messages/create for details.
126
+ */
127
+ metadata: z
128
+ .object({
129
+ /**
130
+ * An external identifier for the user associated with the request.
131
+ *
132
+ * Should be a UUID, hash value, or other opaque identifier.
133
+ * Must not contain PII (name, email, phone number, etc.).
134
+ */
135
+ userId: z.string().optional(),
136
+ })
137
+ .optional(),
138
+
115
139
  /**
116
140
  * MCP servers to be utilized in this request.
117
141
  */
@@ -142,21 +166,29 @@ export const anthropicLanguageModelOptions = z.object({
142
166
  id: z.string().optional(),
143
167
  skills: z
144
168
  .array(
145
- z.object({
146
- type: z.union([z.literal('anthropic'), z.literal('custom')]),
147
- skillId: z.string(),
148
- version: z.string().optional(),
149
- }),
169
+ z.discriminatedUnion('type', [
170
+ z.object({
171
+ type: z.literal('anthropic'),
172
+ skillId: z.string(),
173
+ version: z.string().optional(),
174
+ }),
175
+ z.object({
176
+ type: z.literal('custom'),
177
+ providerReference: z.record(z.string(), z.string()),
178
+ version: z.string().optional(),
179
+ }),
180
+ ]),
150
181
  )
151
182
  .optional(),
152
183
  })
153
184
  .optional(),
154
185
 
155
186
  /**
156
- * Whether to enable tool streaming (and structured output streaming).
157
- *
158
- * When set to false, the model will return all tool calls and results
159
- * at once after a delay.
187
+ * Whether to enable fine-grained (eager) streaming of tool call inputs
188
+ * and structured outputs for every function tool in the request. When
189
+ * true (the default), each function tool receives a default of
190
+ * `eager_input_streaming: true` unless it explicitly sets
191
+ * `providerOptions.anthropic.eagerInputStreaming`.
160
192
  *
161
193
  * @default true
162
194
  */
@@ -165,7 +197,22 @@ export const anthropicLanguageModelOptions = z.object({
165
197
  /**
166
198
  * @default 'high'
167
199
  */
168
- effort: z.enum(['low', 'medium', 'high', 'max']).optional(),
200
+ effort: z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
201
+
202
+ /**
203
+ * Task budget for agentic turns. Informs the model of the total token budget
204
+ * available for the current task, allowing it to prioritize work and wind down
205
+ * gracefully as the budget is consumed.
206
+ *
207
+ * Advisory only — does not enforce a hard token limit.
208
+ */
209
+ taskBudget: z
210
+ .object({
211
+ type: z.literal('tokens'),
212
+ total: z.number().int().min(20000),
213
+ remaining: z.number().int().min(0).optional(),
214
+ })
215
+ .optional(),
169
216
 
170
217
  /**
171
218
  * Enable fast mode for faster inference (2.5x faster output token speeds).
@@ -173,6 +220,16 @@ export const anthropicLanguageModelOptions = z.object({
173
220
  */
174
221
  speed: z.enum(['fast', 'standard']).optional(),
175
222
 
223
+ /**
224
+ * Controls where model inference runs for this request.
225
+ *
226
+ * - `"global"`: Inference may run in any available geography (default).
227
+ * - `"us"`: Inference runs only in US-based infrastructure.
228
+ *
229
+ * See https://platform.claude.com/docs/en/build-with-claude/data-residency
230
+ */
231
+ inferenceGeo: z.enum(['us', 'global']).optional(),
232
+
176
233
  /**
177
234
  * A set of beta features to enable.
178
235
  * Allow a provider to receive the full `betas` set if it needs it.
@@ -3,7 +3,7 @@ import {
3
3
  SharedV4Warning,
4
4
  UnsupportedFunctionalityError,
5
5
  } from '@ai-sdk/provider';
6
- import { AnthropicTool, AnthropicToolChoice } from './anthropic-messages-api';
6
+ import { AnthropicTool, AnthropicToolChoice } from './anthropic-api';
7
7
  import { CacheControlValidator } from './get-cache-control';
8
8
  import { textEditor_20250728ArgsSchema } from './tool/text-editor_20250728';
9
9
  import { webSearch_20260209ArgsSchema } from './tool/web-search_20260209';
@@ -27,6 +27,7 @@ export async function prepareTools({
27
27
  cacheControlValidator,
28
28
  supportsStructuredOutput,
29
29
  supportsStrictTools,
30
+ defaultEagerInputStreaming = false,
30
31
  }: {
31
32
  tools: LanguageModelV4CallOptions['tools'];
32
33
  toolChoice: LanguageModelV4CallOptions['toolChoice'] | undefined;
@@ -42,6 +43,12 @@ export async function prepareTools({
42
43
  * Whether the model supports strict mode on tool definitions.
43
44
  */
44
45
  supportsStrictTools: boolean;
46
+
47
+ /**
48
+ * Default for `eager_input_streaming` on function tools that do not set
49
+ * it explicitly. Driven by the model-level `toolStreaming` option.
50
+ */
51
+ defaultEagerInputStreaming?: boolean;
45
52
  }): Promise<{
46
53
  tools: Array<AnthropicTool> | undefined;
47
54
  toolChoice: AnthropicToolChoice | undefined;
@@ -73,8 +80,10 @@ export async function prepareTools({
73
80
  const anthropicOptions = tool.providerOptions?.anthropic as
74
81
  | AnthropicToolOptions
75
82
  | undefined;
76
- // eager_input_streaming is only supported on custom (function) tools
77
- const eagerInputStreaming = anthropicOptions?.eagerInputStreaming;
83
+ // eager_input_streaming is only supported on custom (function) tools.
84
+ // Fall back to the model-level default when the tool doesn't set it.
85
+ const eagerInputStreaming =
86
+ anthropicOptions?.eagerInputStreaming ?? defaultEagerInputStreaming;
78
87
  const deferLoading = anthropicOptions?.deferLoading;
79
88
  const allowedCallers = anthropicOptions?.allowedCallers;
80
89
 
@@ -322,7 +331,6 @@ export async function prepareTools({
322
331
  }
323
332
 
324
333
  case 'anthropic.tool_search_regex_20251119': {
325
- betas.add('advanced-tool-use-2025-11-20');
326
334
  anthropicTools.push({
327
335
  type: 'tool_search_tool_regex_20251119',
328
336
  name: 'tool_search_tool_regex',
@@ -331,7 +339,6 @@ export async function prepareTools({
331
339
  }
332
340
 
333
341
  case 'anthropic.tool_search_bm25_20251119': {
334
- betas.add('advanced-tool-use-2025-11-20');
335
342
  anthropicTools.push({
336
343
  type: 'tool_search_tool_bm25_20251119',
337
344
  name: 'tool_search_tool_bm25',
@@ -1,8 +1,10 @@
1
1
  import {
2
+ FilesV4,
2
3
  InvalidArgumentError,
3
4
  LanguageModelV4,
4
5
  NoSuchModelError,
5
6
  ProviderV4,
7
+ SkillsV4,
6
8
  } from '@ai-sdk/provider';
7
9
  import {
8
10
  FetchFunction,
@@ -12,31 +14,40 @@ import {
12
14
  withoutTrailingSlash,
13
15
  withUserAgentSuffix,
14
16
  } from '@ai-sdk/provider-utils';
15
- import { VERSION } from './version';
16
- import { AnthropicMessagesLanguageModel } from './anthropic-messages-language-model';
17
- import { AnthropicMessagesModelId } from './anthropic-messages-options';
17
+ import { AnthropicFiles } from './anthropic-files';
18
+ import { AnthropicLanguageModel } from './anthropic-language-model';
19
+ import { AnthropicModelId } from './anthropic-options';
18
20
  import { anthropicTools } from './anthropic-tools';
21
+ import { AnthropicSkills } from './skills/anthropic-skills';
22
+ import { VERSION } from './version';
19
23
 
20
24
  export interface AnthropicProvider extends ProviderV4 {
21
25
  /**
22
26
  * Creates a model for text generation.
23
27
  */
24
- (modelId: AnthropicMessagesModelId): LanguageModelV4;
28
+ (modelId: AnthropicModelId): LanguageModelV4;
25
29
 
26
30
  /**
27
31
  * Creates a model for text generation.
28
32
  */
29
- languageModel(modelId: AnthropicMessagesModelId): LanguageModelV4;
33
+ languageModel(modelId: AnthropicModelId): LanguageModelV4;
30
34
 
31
- chat(modelId: AnthropicMessagesModelId): LanguageModelV4;
35
+ chat(modelId: AnthropicModelId): LanguageModelV4;
32
36
 
33
- messages(modelId: AnthropicMessagesModelId): LanguageModelV4;
37
+ messages(modelId: AnthropicModelId): LanguageModelV4;
34
38
 
35
39
  /**
36
40
  * @deprecated Use `embeddingModel` instead.
37
41
  */
38
42
  textEmbeddingModel(modelId: string): never;
39
43
 
44
+ files(): FilesV4;
45
+
46
+ /**
47
+ * Returns a SkillsV4 interface for uploading skills to Anthropic.
48
+ */
49
+ skills(): SkillsV4;
50
+
40
51
  /**
41
52
  * Anthropic-specific computer use tool.
42
53
  */
@@ -130,8 +141,8 @@ export function createAnthropic(
130
141
  );
131
142
  };
132
143
 
133
- const createChatModel = (modelId: AnthropicMessagesModelId) =>
134
- new AnthropicMessagesLanguageModel(modelId, {
144
+ const createChatModel = (modelId: AnthropicModelId) =>
145
+ new AnthropicLanguageModel(modelId, {
135
146
  provider: providerName,
136
147
  baseURL,
137
148
  headers: getHeaders,
@@ -143,7 +154,15 @@ export function createAnthropic(
143
154
  }),
144
155
  });
145
156
 
146
- const provider = function (modelId: AnthropicMessagesModelId) {
157
+ const createSkills = () =>
158
+ new AnthropicSkills({
159
+ provider: `${providerName.replace('.messages', '')}.skills`,
160
+ baseURL,
161
+ headers: getHeaders,
162
+ fetch: options.fetch,
163
+ });
164
+
165
+ const provider = function (modelId: AnthropicModelId) {
147
166
  if (new.target) {
148
167
  throw new Error(
149
168
  'The Anthropic model function cannot be called with the new keyword.',
@@ -166,6 +185,16 @@ export function createAnthropic(
166
185
  throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
167
186
  };
168
187
 
188
+ provider.files = () =>
189
+ new AnthropicFiles({
190
+ provider: providerName,
191
+ baseURL,
192
+ headers: getHeaders,
193
+ fetch: options.fetch,
194
+ });
195
+
196
+ provider.skills = createSkills;
197
+
169
198
  provider.tools = anthropicTools;
170
199
 
171
200
  return provider;
@@ -11,7 +11,7 @@ export type AnthropicUsageIteration = {
11
11
  output_tokens: number;
12
12
  };
13
13
 
14
- export type AnthropicMessagesUsage = {
14
+ export type AnthropicUsage = {
15
15
  input_tokens: number;
16
16
  output_tokens: number;
17
17
  cache_creation_input_tokens?: number | null;
@@ -25,11 +25,11 @@ export type AnthropicMessagesUsage = {
25
25
  iterations?: AnthropicUsageIteration[] | null;
26
26
  };
27
27
 
28
- export function convertAnthropicMessagesUsage({
28
+ export function convertAnthropicUsage({
29
29
  usage,
30
30
  rawUsage,
31
31
  }: {
32
- usage: AnthropicMessagesUsage;
32
+ usage: AnthropicUsage;
33
33
  rawUsage?: JSONObject;
34
34
  }): LanguageModelV4Usage {
35
35
  const cacheCreationTokens = usage.cache_creation_input_tokens ?? 0;
@@ -9,20 +9,22 @@ 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,
16
18
  } from '@ai-sdk/provider-utils';
17
19
  import {
18
20
  AnthropicAssistantMessage,
19
- AnthropicMessagesPrompt,
21
+ AnthropicPrompt,
20
22
  anthropicReasoningMetadataSchema,
21
23
  AnthropicToolResultContent,
22
24
  AnthropicUserMessage,
23
25
  AnthropicWebFetchToolResultContent,
24
- } from './anthropic-messages-api';
25
- import { anthropicFilePartProviderOptions } from './anthropic-messages-options';
26
+ } from './anthropic-api';
27
+ import { anthropicFilePartProviderOptions } from './anthropic-options';
26
28
  import { CacheControlValidator } from './get-cache-control';
27
29
  import { codeExecution_20250522OutputSchema } from './tool/code-execution_20250522';
28
30
  import { codeExecution_20250825OutputSchema } from './tool/code-execution_20250825';
@@ -68,7 +70,7 @@ function getUrlString(data: LanguageModelV4DataContent): string {
68
70
  return data instanceof URL ? data.toString() : (data as string);
69
71
  }
70
72
 
71
- export async function convertToAnthropicMessagesPrompt({
73
+ export async function convertToAnthropicPrompt({
72
74
  prompt,
73
75
  sendReasoning,
74
76
  warnings,
@@ -81,15 +83,15 @@ export async function convertToAnthropicMessagesPrompt({
81
83
  cacheControlValidator?: CacheControlValidator;
82
84
  toolNameMapping: ToolNameMapping;
83
85
  }): Promise<{
84
- prompt: AnthropicMessagesPrompt;
86
+ prompt: AnthropicPrompt;
85
87
  betas: Set<string>;
86
88
  }> {
87
89
  const betas = new Set<string>();
88
90
  const blocks = groupIntoBlocks(prompt);
89
91
  const validator = cacheControlValidator || new CacheControlValidator();
90
92
 
91
- let system: AnthropicMessagesPrompt['system'] = undefined;
92
- const messages: AnthropicMessagesPrompt['messages'] = [];
93
+ let system: AnthropicPrompt['system'] = undefined;
94
+ const messages: AnthropicPrompt['messages'] = [];
93
95
 
94
96
  async function shouldEnableCitations(
95
97
  providerMetadata: SharedV4ProviderMetadata | undefined,
@@ -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 {
@@ -391,7 +413,8 @@ export async function convertToAnthropicMessagesPrompt({
391
413
  contentValue = output.value;
392
414
  break;
393
415
  case 'execution-denied':
394
- contentValue = output.reason ?? 'Tool execution denied.';
416
+ contentValue =
417
+ output.reason ?? 'Tool call execution denied.';
395
418
  break;
396
419
  case 'json':
397
420
  case 'error-json':
@@ -1,5 +1,5 @@
1
1
  import { SharedV4Warning, SharedV4ProviderMetadata } from '@ai-sdk/provider';
2
- import { AnthropicCacheControl } from './anthropic-messages-api';
2
+ import { AnthropicCacheControl } from './anthropic-api';
3
3
 
4
4
  // Anthropic allows a maximum of 4 cache breakpoints per request
5
5
  const MAX_CACHE_BREAKPOINTS = 4;
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@ export type {
6
6
  AnthropicLanguageModelOptions,
7
7
  /** @deprecated Use `AnthropicLanguageModelOptions` instead. */
8
8
  AnthropicLanguageModelOptions as AnthropicProviderOptions,
9
- } from './anthropic-messages-options';
9
+ } from './anthropic-options';
10
10
  export type { AnthropicToolOptions } from './anthropic-prepare-tools';
11
11
  export { anthropic, createAnthropic } from './anthropic-provider';
12
12
  export type {
@@ -1,4 +1,13 @@
1
- export { AnthropicMessagesLanguageModel } from '../anthropic-messages-language-model';
1
+ export {
2
+ AnthropicLanguageModel,
3
+ /** @deprecated Use `AnthropicLanguageModel` instead. */
4
+ AnthropicLanguageModel as AnthropicMessagesLanguageModel,
5
+ getModelCapabilities,
6
+ } from '../anthropic-language-model';
2
7
  export { anthropicTools } from '../anthropic-tools';
3
- export type { AnthropicMessagesModelId } from '../anthropic-messages-options';
8
+ export type {
9
+ AnthropicModelId,
10
+ /** @deprecated Use `AnthropicModelId` instead. */
11
+ AnthropicModelId as AnthropicMessagesModelId,
12
+ } from '../anthropic-options';
4
13
  export { prepareTools } from '../anthropic-prepare-tools';