@ai-sdk/anthropic 3.0.133 → 3.0.134

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": "3.0.133",
3
+ "version": "3.0.134",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -48,6 +48,7 @@ export interface AnthropicUserMessage {
48
48
  content: Array<
49
49
  | AnthropicTextContent
50
50
  | AnthropicImageContent
51
+ | AnthropicVideoContent
51
52
  | AnthropicDocumentContent
52
53
  | AnthropicToolResultContent
53
54
  >;
@@ -126,6 +127,13 @@ export interface AnthropicImageContent {
126
127
  cache_control: AnthropicCacheControl | undefined;
127
128
  }
128
129
 
130
+ /** Video blocks supplied by compatible providers through custom media conversion. */
131
+ export interface AnthropicVideoContent {
132
+ type: 'video';
133
+ source: AnthropicContentSource;
134
+ cache_control: AnthropicCacheControl | undefined;
135
+ }
136
+
129
137
  export interface AnthropicDocumentContent {
130
138
  type: 'document';
131
139
  source: AnthropicContentSource;
@@ -56,7 +56,10 @@ import {
56
56
  convertAnthropicMessagesUsage,
57
57
  type AnthropicMessagesUsage,
58
58
  } from './convert-anthropic-messages-usage';
59
- import { convertToAnthropicMessagesPrompt } from './convert-to-anthropic-messages-prompt';
59
+ import {
60
+ convertToAnthropicMessagesPrompt,
61
+ type AnthropicMediaPartConverter,
62
+ } from './convert-to-anthropic-messages-prompt';
60
63
  import { CacheControlValidator } from './get-cache-control';
61
64
  import { mapAnthropicStopReason } from './map-anthropic-stop-reason';
62
65
  import { sanitizeJsonSchema } from './sanitize-json-schema';
@@ -186,6 +189,14 @@ type AnthropicMessagesConfig = {
186
189
  headers: Resolvable<Record<string, string | undefined>>;
187
190
  fetch?: FetchFunction;
188
191
  buildRequestUrl?: (baseURL: string, isStreaming: boolean) => string;
192
+ /** Custom media conversion for compatible providers. */
193
+ convertMediaPart?: AnthropicMediaPartConverter;
194
+ /** Maximum temperature for compatible providers. Defaults to 1. */
195
+ maxTemperature?: number;
196
+ /** Preserve temperature and topP with thinking for compatible providers. */
197
+ supportsTemperatureAndTopPWithThinking?: boolean;
198
+ /** Cache option namespace for compatible providers. Defaults to anthropic. */
199
+ cacheControlProviderOptionsName?: string;
189
200
  transformRequestBody?: (
190
201
  args: Record<string, any>,
191
202
  betas: Set<string>,
@@ -278,18 +289,24 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
278
289
  warnings.push({ type: 'unsupported', feature: 'seed' });
279
290
  }
280
291
 
281
- if (temperature != null && temperature > 1) {
292
+ const maxTemperature = this.config.maxTemperature ?? 1;
293
+ const temperatureProvider =
294
+ this.config.maxTemperature == null
295
+ ? 'anthropic'
296
+ : this.providerOptionsName;
297
+
298
+ if (temperature != null && temperature > maxTemperature) {
282
299
  warnings.push({
283
300
  type: 'unsupported',
284
301
  feature: 'temperature',
285
- details: `${temperature} exceeds anthropic maximum of 1.0. clamped to 1.0`,
302
+ details: `${temperature} exceeds ${temperatureProvider} maximum of ${maxTemperature.toFixed(1)}. clamped to ${maxTemperature.toFixed(1)}`,
286
303
  });
287
- temperature = 1;
304
+ temperature = maxTemperature;
288
305
  } else if (temperature != null && temperature < 0) {
289
306
  warnings.push({
290
307
  type: 'unsupported',
291
308
  feature: 'temperature',
292
- details: `${temperature} is below anthropic minimum of 0. clamped to 0`,
309
+ details: `${temperature} is below ${temperatureProvider} minimum of 0. clamped to 0`,
293
310
  });
294
311
  temperature = 0;
295
312
  }
@@ -448,7 +465,9 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
448
465
  const contextManagement = anthropicOptions?.contextManagement;
449
466
 
450
467
  // Create a shared cache control validator to track breakpoints across tools and messages
451
- const cacheControlValidator = new CacheControlValidator();
468
+ const cacheControlValidator = new CacheControlValidator(
469
+ this.config.cacheControlProviderOptionsName,
470
+ );
452
471
 
453
472
  const toolNameMapping = createToolNameMapping({
454
473
  tools,
@@ -487,6 +506,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
487
506
  cacheControlValidator,
488
507
  toolNameMapping,
489
508
  toolsetNames,
509
+ convertMediaPart: this.config.convertMediaPart,
490
510
  });
491
511
 
492
512
  // Some models always run adaptive thinking and reject `disabled` thinking
@@ -799,7 +819,10 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
799
819
  thinkingBudget = 1024;
800
820
  }
801
821
 
802
- if (baseArgs.temperature != null) {
822
+ if (
823
+ baseArgs.temperature != null &&
824
+ !this.config.supportsTemperatureAndTopPWithThinking
825
+ ) {
803
826
  baseArgs.temperature = undefined;
804
827
  warnings.push({
805
828
  type: 'unsupported',
@@ -817,7 +840,7 @@ export class AnthropicMessagesLanguageModel implements LanguageModelV3 {
817
840
  });
818
841
  }
819
842
 
820
- if (topP != null) {
843
+ if (topP != null && !this.config.supportsTemperatureAndTopPWithThinking) {
821
844
  baseArgs.top_p = undefined;
822
845
  warnings.push({
823
846
  type: 'unsupported',
@@ -2,6 +2,7 @@ import {
2
2
  UnsupportedFunctionalityError,
3
3
  type SharedV3Warning,
4
4
  type LanguageModelV3DataContent,
5
+ type LanguageModelV3FilePart,
5
6
  type LanguageModelV3Message,
6
7
  type LanguageModelV3Prompt,
7
8
  type SharedV3ProviderMetadata,
@@ -19,6 +20,7 @@ import {
19
20
  import {
20
21
  anthropicReasoningMetadataSchema,
21
22
  type AnthropicAssistantMessage,
23
+ type AnthropicImageContent,
22
24
  type AnthropicMessagesPrompt,
23
25
  type AnthropicSystemMessage,
24
26
  type AnthropicTextContent,
@@ -26,6 +28,7 @@ import {
26
28
  type AnthropicToolCallCaller,
27
29
  type AnthropicToolResultContent,
28
30
  type AnthropicUserMessage,
31
+ type AnthropicVideoContent,
29
32
  type AnthropicWebFetchToolResultContent,
30
33
  type Citation,
31
34
  } from './anthropic-messages-api';
@@ -109,6 +112,14 @@ async function extractErrorValue(
109
112
  return {};
110
113
  }
111
114
 
115
+ /** Return undefined to use the default file conversion. */
116
+ export type AnthropicMediaPartConverter = (
117
+ part: LanguageModelV3FilePart,
118
+ ) => PromiseLike<
119
+ | Omit<AnthropicImageContent | AnthropicVideoContent, 'cache_control'>
120
+ | undefined
121
+ >;
122
+
112
123
  export async function convertToAnthropicMessagesPrompt({
113
124
  prompt,
114
125
  sendReasoning,
@@ -116,12 +127,14 @@ export async function convertToAnthropicMessagesPrompt({
116
127
  cacheControlValidator,
117
128
  toolNameMapping,
118
129
  toolsetNames = {},
130
+ convertMediaPart,
119
131
  }: {
120
132
  prompt: LanguageModelV3Prompt;
121
133
  sendReasoning: boolean;
122
134
  warnings: SharedV3Warning[];
123
135
  cacheControlValidator?: CacheControlValidator;
124
136
  toolNameMapping: ToolNameMapping;
137
+ convertMediaPart?: AnthropicMediaPartConverter;
125
138
 
126
139
  /**
127
140
  * Maps custom tool names of toolset tools (e.g. the computer toolset) to
@@ -336,6 +349,15 @@ export async function convertToAnthropicMessagesPrompt({
336
349
  }
337
350
 
338
351
  case 'file': {
352
+ const customContent = await convertMediaPart?.(part);
353
+ if (customContent != null) {
354
+ anthropicContent.push({
355
+ ...customContent,
356
+ cache_control: cacheControl,
357
+ });
358
+ break;
359
+ }
360
+
339
361
  if (part.mediaType.startsWith('image/')) {
340
362
  anthropicContent.push({
341
363
  type: 'image',
@@ -11,11 +11,18 @@ const MAX_CACHE_BREAKPOINTS = 4;
11
11
  // Allows both cacheControl and cache_control for flexibility
12
12
  function getCacheControl(
13
13
  providerMetadata: SharedV3ProviderMetadata | undefined,
14
+ providerOptionsName: string,
14
15
  ): AnthropicCacheControl | undefined {
16
+ const custom = providerMetadata?.[providerOptionsName];
15
17
  const anthropic = providerMetadata?.anthropic;
16
18
 
17
- // allow both cacheControl and cache_control:
18
- const cacheControlValue = anthropic?.cacheControl ?? anthropic?.cache_control;
19
+ // Prefer the configured namespace, retaining the canonical namespace as a fallback.
20
+ // Allow both cacheControl and cache_control.
21
+ const cacheControlValue =
22
+ custom?.cacheControl ??
23
+ custom?.cache_control ??
24
+ anthropic?.cacheControl ??
25
+ anthropic?.cache_control;
19
26
 
20
27
  // Pass through value assuming it is of the correct type.
21
28
  // The Anthropic API will validate the value.
@@ -26,11 +33,16 @@ export class CacheControlValidator {
26
33
  private breakpointCount = 0;
27
34
  private warnings: SharedV3Warning[] = [];
28
35
 
36
+ constructor(private readonly providerOptionsName = 'anthropic') {}
37
+
29
38
  getCacheControl(
30
39
  providerMetadata: SharedV3ProviderMetadata | undefined,
31
40
  context: { type: string; canCache: boolean },
32
41
  ): AnthropicCacheControl | undefined {
33
- const cacheControlValue = getCacheControl(providerMetadata);
42
+ const cacheControlValue = getCacheControl(
43
+ providerMetadata,
44
+ this.providerOptionsName,
45
+ );
34
46
 
35
47
  if (!cacheControlValue) {
36
48
  return undefined;