@ai-sdk/amazon-bedrock 5.0.0-beta.4 → 5.0.0-beta.41

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.
@@ -514,6 +514,37 @@ console.log(amazonResult.text); // text response
514
514
  See [AI SDK UI: Chatbot](/docs/ai-sdk-ui/chatbot#reasoning) for more details
515
515
  on how to integrate reasoning into your chatbot.
516
516
 
517
+ ## Service Tiers
518
+
519
+ Amazon Bedrock supports selecting an inference service tier per request via the `serviceTier` provider option.
520
+
521
+ ```ts
522
+ import {
523
+ bedrock,
524
+ type AmazonBedrockLanguageModelOptions,
525
+ } from '@ai-sdk/amazon-bedrock';
526
+ import { generateText } from 'ai';
527
+
528
+ const result = await generateText({
529
+ model: bedrock('us.anthropic.claude-sonnet-4-20250514-v1:0'),
530
+ prompt: 'Summarize this support ticket backlog.',
531
+ providerOptions: {
532
+ bedrock: {
533
+ serviceTier: 'priority',
534
+ } satisfies AmazonBedrockLanguageModelOptions,
535
+ },
536
+ });
537
+ ```
538
+
539
+ Supported values are:
540
+
541
+ - `reserved`
542
+ - `priority`
543
+ - `default`
544
+ - `flex`
545
+
546
+ See the [Amazon Bedrock service tiers documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html) for model availability and behavior.
547
+
517
548
  ## Extended Context Window
518
549
 
519
550
  Claude Sonnet 4 models on Amazon Bedrock support an extended context window of up to 1 million tokens when using the `context-1m-2025-08-07` beta feature.
@@ -1380,6 +1411,16 @@ const { text } = await generateText({
1380
1411
  });
1381
1412
  ```
1382
1413
 
1414
+ ### Provider Options
1415
+
1416
+ The following optional provider options are available for Bedrock Anthropic models:
1417
+
1418
+ - `metadata` _object_
1419
+
1420
+ Optional. Metadata to include with the request. See the [Anthropic API documentation](https://platform.claude.com/docs/en/api/messages/create) for details.
1421
+
1422
+ - `userId` _string_ - An external identifier for the end-user.
1423
+
1383
1424
  ### Cache Control
1384
1425
 
1385
1426
  In the messages and message parts, you can use the `providerOptions` property to set cache control breakpoints.
@@ -1433,7 +1474,7 @@ They are available via the `tools` property of the provider instance.
1433
1474
 
1434
1475
  ```ts
1435
1476
  import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
1436
- import { generateText, stepCountIs } from 'ai';
1477
+ import { generateText, isStepCount } from 'ai';
1437
1478
 
1438
1479
  const result = await generateText({
1439
1480
  model: bedrockAnthropic('us.anthropic.claude-sonnet-4-5-20250929-v1:0'),
@@ -1446,7 +1487,7 @@ const result = await generateText({
1446
1487
  }),
1447
1488
  },
1448
1489
  prompt: 'List the files in my directory.',
1449
- stopWhen: stepCountIs(2),
1490
+ stopWhen: isStepCount(2),
1450
1491
  });
1451
1492
  ```
1452
1493
 
@@ -1454,7 +1495,7 @@ const result = await generateText({
1454
1495
 
1455
1496
  ```ts
1456
1497
  import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
1457
- import { generateText, stepCountIs } from 'ai';
1498
+ import { generateText, isStepCount } from 'ai';
1458
1499
 
1459
1500
  const result = await generateText({
1460
1501
  model: bedrockAnthropic('us.anthropic.claude-sonnet-4-5-20250929-v1:0'),
@@ -1467,7 +1508,7 @@ const result = await generateText({
1467
1508
  }),
1468
1509
  },
1469
1510
  prompt: 'Update my README file.',
1470
- stopWhen: stepCountIs(5),
1511
+ stopWhen: isStepCount(5),
1471
1512
  });
1472
1513
  ```
1473
1514
 
@@ -1475,7 +1516,7 @@ const result = await generateText({
1475
1516
 
1476
1517
  ```ts
1477
1518
  import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
1478
- import { generateText, stepCountIs } from 'ai';
1519
+ import { generateText, isStepCount } from 'ai';
1479
1520
  import fs from 'fs';
1480
1521
 
1481
1522
  const result = await generateText({
@@ -1510,7 +1551,7 @@ const result = await generateText({
1510
1551
  }),
1511
1552
  },
1512
1553
  prompt: 'Take a screenshot.',
1513
- stopWhen: stepCountIs(3),
1554
+ stopWhen: isStepCount(3),
1514
1555
  });
1515
1556
  ```
1516
1557
 
@@ -1518,6 +1559,7 @@ const result = await generateText({
1518
1559
 
1519
1560
  Anthropic has reasoning support for Claude 3.7 and Claude 4 models on Bedrock, including:
1520
1561
 
1562
+ - `us.anthropic.claude-opus-4-7`
1521
1563
  - `us.anthropic.claude-opus-4-6-v1`
1522
1564
  - `us.anthropic.claude-opus-4-5-20251101-v1:0`
1523
1565
  - `us.anthropic.claude-sonnet-4-5-20250929-v1:0`
@@ -1554,6 +1596,7 @@ on how to integrate reasoning into your chatbot.
1554
1596
 
1555
1597
  | Model | Image Input | Object Generation | Tool Usage | Computer Use | Reasoning |
1556
1598
  | ---------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
1599
+ | `us.anthropic.claude-opus-4-7` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
1557
1600
  | `us.anthropic.claude-opus-4-6-v1` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
1558
1601
  | `us.anthropic.claude-opus-4-5-20251101-v1:0` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
1559
1602
  | `us.anthropic.claude-sonnet-4-5-20250929-v1:0` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@ai-sdk/amazon-bedrock",
3
- "version": "5.0.0-beta.4",
3
+ "version": "5.0.0-beta.41",
4
+ "type": "module",
4
5
  "license": "Apache-2.0",
5
6
  "sideEffects": false,
6
7
  "main": "./dist/index.js",
7
- "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist/**/*",
@@ -25,29 +25,29 @@
25
25
  "./package.json": "./package.json",
26
26
  ".": {
27
27
  "types": "./dist/index.d.ts",
28
- "import": "./dist/index.mjs",
29
- "require": "./dist/index.js"
28
+ "import": "./dist/index.js",
29
+ "default": "./dist/index.js"
30
30
  },
31
31
  "./anthropic": {
32
32
  "types": "./dist/anthropic/index.d.ts",
33
- "import": "./dist/anthropic/index.mjs",
34
- "require": "./dist/anthropic/index.js"
33
+ "import": "./dist/anthropic/index.js",
34
+ "default": "./dist/anthropic/index.js"
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
38
  "@smithy/eventstream-codec": "^4.0.1",
39
39
  "@smithy/util-utf8": "^4.0.0",
40
40
  "aws4fetch": "^1.0.20",
41
- "@ai-sdk/anthropic": "4.0.0-beta.4",
42
- "@ai-sdk/provider-utils": "5.0.0-beta.1",
43
- "@ai-sdk/provider": "4.0.0-beta.0"
41
+ "@ai-sdk/anthropic": "4.0.0-beta.37",
42
+ "@ai-sdk/provider": "4.0.0-beta.12",
43
+ "@ai-sdk/provider-utils": "5.0.0-beta.26"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "20.17.24",
47
47
  "tsup": "^8.3.0",
48
48
  "typescript": "5.8.3",
49
49
  "zod": "3.25.76",
50
- "@ai-sdk/test-server": "2.0.0-beta.0",
50
+ "@ai-sdk/test-server": "2.0.0-beta.1",
51
51
  "@vercel/ai-tsconfig": "0.0.0"
52
52
  },
53
53
  "peerDependencies": {
@@ -74,9 +74,7 @@
74
74
  "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
75
75
  "build:watch": "pnpm clean && tsup --watch",
76
76
  "clean": "del-cli dist docs *.tsbuildinfo",
77
- "lint": "eslint \"./**/*.ts*\"",
78
77
  "type-check": "tsc --build",
79
- "prettier-check": "prettier --check \"./**/*.ts*\"",
80
78
  "test": "pnpm test:node && pnpm test:edge",
81
79
  "test:update": "pnpm test:node -u",
82
80
  "test:watch": "vitest --config vitest.node.config.js",
@@ -3,14 +3,40 @@ import {
3
3
  FetchFunction,
4
4
  safeParseJSON,
5
5
  } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
6
7
  import { createBedrockEventStreamDecoder } from '../bedrock-event-stream-decoder';
7
8
 
9
+ const bedrockErrorSchema = z.looseObject({
10
+ message: z.string().optional(),
11
+ });
12
+
8
13
  export function createBedrockAnthropicFetch(
9
14
  baseFetch: FetchFunction,
10
15
  ): FetchFunction {
11
16
  return async (url, options) => {
12
17
  const response = await baseFetch(url, options);
13
18
 
19
+ // Transform Bedrock error responses into Anthropic error format
20
+ // so that anthropicFailedResponseHandler can extract the message.
21
+ if (!response.ok) {
22
+ const text = await response.text();
23
+ const parsed = await safeParseJSON({ text, schema: bedrockErrorSchema });
24
+
25
+ const message =
26
+ parsed.success && parsed.value.message ? parsed.value.message : text;
27
+
28
+ const anthropicError = JSON.stringify({
29
+ type: 'error',
30
+ error: { type: 'error', message },
31
+ });
32
+
33
+ return new Response(anthropicError, {
34
+ status: response.status,
35
+ statusText: response.statusText,
36
+ headers: response.headers,
37
+ });
38
+ }
39
+
14
40
  const contentType = response.headers.get('content-type');
15
41
  if (
16
42
  contentType?.includes('application/vnd.amazon.eventstream') &&
@@ -1,4 +1,5 @@
1
1
  export type BedrockAnthropicModelId =
2
+ | 'anthropic.claude-opus-4-7'
2
3
  | 'anthropic.claude-opus-4-6-v1'
3
4
  | 'anthropic.claude-sonnet-4-6-v1'
4
5
  | 'anthropic.claude-opus-4-5-20251101-v1:0'
@@ -14,6 +15,7 @@ export type BedrockAnthropicModelId =
14
15
  | 'anthropic.claude-3-opus-20240229-v1:0'
15
16
  | 'anthropic.claude-3-sonnet-20240229-v1:0'
16
17
  | 'anthropic.claude-3-haiku-20240307-v1:0'
18
+ | 'us.anthropic.claude-opus-4-7'
17
19
  | 'us.anthropic.claude-opus-4-6-v1'
18
20
  | 'us.anthropic.claude-sonnet-4-6-v1'
19
21
  | 'us.anthropic.claude-opus-4-5-20251101-v1:0'
@@ -47,6 +47,10 @@ const BEDROCK_TOOL_BETA_MAP: Record<string, string> = {
47
47
  text_editor_20250728: 'computer-use-2025-01-24',
48
48
  computer_20250124: 'computer-use-2025-01-24',
49
49
  computer_20241022: 'computer-use-2024-10-22',
50
+ tool_search_tool_regex_20251119: 'tool-search-tool-2025-10-19',
51
+ // BM25 is not currently supported on Bedrock, but including the beta flag
52
+ // so that Bedrock returns a more useful error message if it's used.
53
+ tool_search_tool_bm25_20251119: 'tool-search-tool-2025-10-19',
50
54
  };
51
55
 
52
56
  export interface BedrockAnthropicProvider extends ProviderV4 {
@@ -257,7 +261,13 @@ export function createBedrockAnthropic(
257
261
  }`,
258
262
 
259
263
  transformRequestBody: (args, betas) => {
260
- const { model, stream, tool_choice, tools, ...rest } = args;
264
+ const {
265
+ model: _model,
266
+ stream: _stream,
267
+ tool_choice,
268
+ tools,
269
+ ...rest
270
+ } = args;
261
271
 
262
272
  const transformedToolChoice =
263
273
  tool_choice != null
@@ -13,6 +13,9 @@ export interface BedrockConverseInput {
13
13
  };
14
14
  additionalModelRequestFields?: Record<string, unknown>;
15
15
  additionalModelResponseFieldPaths?: string[];
16
+ serviceTier?: {
17
+ type: string;
18
+ };
16
19
  guardrailConfig?:
17
20
  | BedrockGuardrailConfiguration
18
21
  | BedrockGuardrailStreamConfiguration
@@ -19,10 +19,17 @@ import {
19
19
  combineHeaders,
20
20
  createJsonErrorResponseHandler,
21
21
  createJsonResponseHandler,
22
+ isCustomReasoning,
23
+ mapReasoningToProviderBudget,
24
+ mapReasoningToProviderEffort,
22
25
  parseProviderOptions,
23
26
  postJsonToApi,
24
27
  resolve,
28
+ serializeModelOptions,
29
+ WORKFLOW_SERIALIZE,
30
+ WORKFLOW_DESERIALIZE,
25
31
  } from '@ai-sdk/provider-utils';
32
+ import { getModelCapabilities } from '@ai-sdk/anthropic/internal';
26
33
  import { z } from 'zod/v4';
27
34
  import {
28
35
  BEDROCK_STOP_REASONS,
@@ -30,6 +37,7 @@ import {
30
37
  BedrockStopReason,
31
38
  } from './bedrock-api-types';
32
39
  import {
40
+ AmazonBedrockLanguageModelOptions,
33
41
  BedrockChatModelId,
34
42
  amazonBedrockLanguageModelOptions,
35
43
  } from './bedrock-chat-options';
@@ -43,7 +51,7 @@ import { isMistralModel, normalizeToolCallId } from './normalize-tool-call-id';
43
51
 
44
52
  type BedrockChatConfig = {
45
53
  baseUrl: () => string;
46
- headers: Resolvable<Record<string, string | undefined>>;
54
+ headers?: Resolvable<Record<string, string | undefined>>;
47
55
  fetch?: FetchFunction;
48
56
  generateId: () => string;
49
57
  };
@@ -52,6 +60,20 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
52
60
  readonly specificationVersion = 'v4';
53
61
  readonly provider = 'amazon-bedrock';
54
62
 
63
+ static [WORKFLOW_SERIALIZE](model: BedrockChatLanguageModel) {
64
+ return serializeModelOptions({
65
+ modelId: model.modelId,
66
+ config: model.config,
67
+ });
68
+ }
69
+
70
+ static [WORKFLOW_DESERIALIZE](options: {
71
+ modelId: string;
72
+ config: BedrockChatConfig;
73
+ }) {
74
+ return new BedrockChatLanguageModel(options.modelId, options.config);
75
+ }
76
+
55
77
  constructor(
56
78
  readonly modelId: BedrockChatModelId,
57
79
  private readonly config: BedrockChatConfig,
@@ -70,6 +92,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
70
92
  seed,
71
93
  tools,
72
94
  toolChoice,
95
+ reasoning,
73
96
  providerOptions,
74
97
  }: LanguageModelV4CallOptions): Promise<{
75
98
  command: BedrockConverseInput;
@@ -78,7 +101,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
78
101
  betas: Set<string>;
79
102
  }> {
80
103
  // Parse provider options
81
- const bedrockOptions =
104
+ let bedrockOptions =
82
105
  (await parseProviderOptions({
83
106
  provider: 'bedrock',
84
107
  providerOptions,
@@ -137,13 +160,26 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
137
160
  }
138
161
 
139
162
  const isAnthropicModel = this.modelId.includes('anthropic');
163
+ const isOpenAIModel = this.modelId.startsWith('openai.');
164
+
165
+ bedrockOptions = resolveBedrockReasoningConfig({
166
+ reasoning,
167
+ bedrockOptions,
168
+ warnings,
169
+ isAnthropicModel,
170
+ modelId: this.modelId,
171
+ });
172
+
140
173
  const isThinkingEnabled =
141
174
  bedrockOptions.reasoningConfig?.type === 'enabled' ||
142
175
  bedrockOptions.reasoningConfig?.type === 'adaptive';
143
176
 
177
+ const { supportsStructuredOutput: modelSupportsStructuredOutput } =
178
+ getModelCapabilities(this.modelId);
179
+
144
180
  const useNativeStructuredOutput =
145
181
  isAnthropicModel &&
146
- isThinkingEnabled &&
182
+ (modelSupportsStructuredOutput || isThinkingEnabled) &&
147
183
  responseFormat?.type === 'json' &&
148
184
  responseFormat.schema != null;
149
185
 
@@ -194,6 +230,10 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
194
230
  thinkingType === 'enabled'
195
231
  ? bedrockOptions.reasoningConfig?.budgetTokens
196
232
  : undefined;
233
+ const thinkingDisplay =
234
+ thinkingType === 'adaptive'
235
+ ? bedrockOptions.reasoningConfig?.display
236
+ : undefined;
197
237
  const isAnthropicThinkingEnabled = isAnthropicModel && isThinkingEnabled;
198
238
 
199
239
  const inferenceConfig = {
@@ -223,6 +263,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
223
263
  ...bedrockOptions.additionalModelRequestFields,
224
264
  thinking: {
225
265
  type: 'adaptive',
266
+ ...(thinkingDisplay != null && { display: thinkingDisplay }),
226
267
  },
227
268
  };
228
269
  }
@@ -247,7 +288,6 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
247
288
 
248
289
  const maxReasoningEffort =
249
290
  bedrockOptions.reasoningConfig?.maxReasoningEffort;
250
- const isOpenAIModel = this.modelId.startsWith('openai.');
251
291
 
252
292
  if (maxReasoningEffort != null) {
253
293
  if (isAnthropicModel) {
@@ -368,6 +408,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
368
408
  const {
369
409
  reasoningConfig: _,
370
410
  additionalModelRequestFields: __,
411
+ serviceTier: ___,
371
412
  ...filteredBedrockOptions
372
413
  } = providerOptions?.bedrock || {};
373
414
 
@@ -387,6 +428,11 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
387
428
  ...(Object.keys(inferenceConfig).length > 0 && {
388
429
  inferenceConfig,
389
430
  }),
431
+ ...(bedrockOptions.serviceTier != null && {
432
+ serviceTier: {
433
+ type: bedrockOptions.serviceTier,
434
+ },
435
+ }),
390
436
  ...filteredBedrockOptions,
391
437
  ...(toolConfig.tools !== undefined && toolConfig.tools.length > 0
392
438
  ? { toolConfig }
@@ -407,7 +453,10 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
407
453
  }: {
408
454
  headers: Record<string, string | undefined> | undefined;
409
455
  }) {
410
- return combineHeaders(await resolve(this.config.headers), headers);
456
+ return combineHeaders(
457
+ this.config.headers ? await resolve(this.config.headers) : undefined,
458
+ headers,
459
+ );
411
460
  }
412
461
 
413
462
  async doGenerate(
@@ -441,7 +490,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
441
490
  // map response content to content array
442
491
  for (const part of response.output.message.content) {
443
492
  // text
444
- if (part.text) {
493
+ if (part.text != null) {
445
494
  content.push({ type: 'text', text: part.text });
446
495
  }
447
496
 
@@ -845,6 +894,13 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
845
894
  'signature' in reasoningContent &&
846
895
  reasoningContent.signature
847
896
  ) {
897
+ if (contentBlocks[blockIndex] == null) {
898
+ contentBlocks[blockIndex] = { type: 'reasoning' };
899
+ controller.enqueue({
900
+ type: 'reasoning-start',
901
+ id: String(blockIndex),
902
+ });
903
+ }
848
904
  controller.enqueue({
849
905
  type: 'reasoning-delta',
850
906
  id: String(blockIndex),
@@ -856,6 +912,13 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
856
912
  },
857
913
  });
858
914
  } else if ('data' in reasoningContent && reasoningContent.data) {
915
+ if (contentBlocks[blockIndex] == null) {
916
+ contentBlocks[blockIndex] = { type: 'reasoning' };
917
+ controller.enqueue({
918
+ type: 'reasoning-start',
919
+ id: String(blockIndex),
920
+ });
921
+ }
859
922
  controller.enqueue({
860
923
  type: 'reasoning-delta',
861
924
  id: String(blockIndex),
@@ -1122,3 +1185,73 @@ export const bedrockReasoningMetadataSchema = z.object({
1122
1185
  export type BedrockReasoningMetadata = z.infer<
1123
1186
  typeof bedrockReasoningMetadataSchema
1124
1187
  >;
1188
+
1189
+ const bedrockReasoningEffortMap: Partial<
1190
+ Record<string, 'low' | 'medium' | 'high' | 'max'>
1191
+ > = {
1192
+ minimal: 'low',
1193
+ low: 'low',
1194
+ medium: 'medium',
1195
+ high: 'high',
1196
+ xhigh: 'max',
1197
+ };
1198
+
1199
+ function resolveBedrockReasoningConfig({
1200
+ reasoning,
1201
+ bedrockOptions,
1202
+ warnings,
1203
+ isAnthropicModel,
1204
+ modelId,
1205
+ }: {
1206
+ reasoning: LanguageModelV4CallOptions['reasoning'];
1207
+ bedrockOptions: AmazonBedrockLanguageModelOptions;
1208
+ warnings: SharedV4Warning[];
1209
+ isAnthropicModel: boolean;
1210
+ modelId: string;
1211
+ }): AmazonBedrockLanguageModelOptions {
1212
+ if (!isCustomReasoning(reasoning) || bedrockOptions.reasoningConfig != null) {
1213
+ return bedrockOptions;
1214
+ }
1215
+
1216
+ const result = { ...bedrockOptions };
1217
+
1218
+ if (isAnthropicModel) {
1219
+ const capabilities = getModelCapabilities(modelId);
1220
+
1221
+ if (reasoning === 'none') {
1222
+ result.reasoningConfig = { type: 'disabled' };
1223
+ } else if (capabilities.supportsAdaptiveThinking) {
1224
+ const effort = mapReasoningToProviderEffort({
1225
+ reasoning,
1226
+ effortMap: bedrockReasoningEffortMap,
1227
+ warnings,
1228
+ });
1229
+ result.reasoningConfig = {
1230
+ type: 'adaptive',
1231
+ maxReasoningEffort: effort,
1232
+ };
1233
+ } else {
1234
+ const budgetTokens = mapReasoningToProviderBudget({
1235
+ reasoning,
1236
+ maxOutputTokens: capabilities.maxOutputTokens,
1237
+ maxReasoningBudget: capabilities.maxOutputTokens,
1238
+ warnings,
1239
+ });
1240
+ if (budgetTokens != null) {
1241
+ result.reasoningConfig = {
1242
+ type: 'enabled',
1243
+ budgetTokens,
1244
+ };
1245
+ }
1246
+ }
1247
+ } else if (reasoning !== 'none') {
1248
+ const effort = mapReasoningToProviderEffort({
1249
+ reasoning,
1250
+ effortMap: bedrockReasoningEffortMap,
1251
+ warnings,
1252
+ });
1253
+ result.reasoningConfig = { maxReasoningEffort: effort };
1254
+ }
1255
+
1256
+ return result;
1257
+ }
@@ -7,6 +7,7 @@ export type BedrockChatModelId =
7
7
  | 'anthropic.claude-v2'
8
8
  | 'anthropic.claude-v2:1'
9
9
  | 'anthropic.claude-instant-v1'
10
+ | 'anthropic.claude-opus-4-7'
10
11
  | 'anthropic.claude-opus-4-6-v1'
11
12
  | 'anthropic.claude-sonnet-4-6-v1'
12
13
  | 'anthropic.claude-opus-4-5-20251101-v1:0'
@@ -54,6 +55,7 @@ export type BedrockChatModelId =
54
55
  | 'us.anthropic.claude-3-5-haiku-20241022-v1:0'
55
56
  | 'us.anthropic.claude-3-5-sonnet-20241022-v2:0'
56
57
  | 'us.anthropic.claude-3-7-sonnet-20250219-v1:0'
58
+ | 'us.anthropic.claude-opus-4-7'
57
59
  | 'us.anthropic.claude-opus-4-6-v1'
58
60
  | 'us.anthropic.claude-sonnet-4-6-v1'
59
61
  | 'us.anthropic.claude-opus-4-5-20251101-v1:0'
@@ -115,13 +117,26 @@ export const amazonBedrockLanguageModelOptions = z.object({
115
117
  ])
116
118
  .optional(),
117
119
  budgetTokens: z.number().optional(),
118
- maxReasoningEffort: z.enum(['low', 'medium', 'high', 'max']).optional(),
120
+ maxReasoningEffort: z
121
+ .enum(['low', 'medium', 'high', 'xhigh', 'max'])
122
+ .optional(),
123
+ display: z.enum(['omitted', 'summarized']).optional(),
119
124
  })
120
125
  .optional(),
121
126
  /**
122
127
  * Anthropic beta features to enable
123
128
  */
124
129
  anthropicBeta: z.array(z.string()).optional(),
130
+ /**
131
+ * Service tier for the request.
132
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html
133
+ *
134
+ * - 'reserved': Uses provisioned throughput capacity
135
+ * - 'priority': Prioritizes low-latency inference when capacity is available
136
+ * - 'default': Standard on-demand tier
137
+ * - 'flex': Lower-cost tier for flexible latency workloads
138
+ */
139
+ serviceTier: z.enum(['reserved', 'priority', 'default', 'flex']).optional(),
125
140
  });
126
141
 
127
142
  export type AmazonBedrockLanguageModelOptions = z.infer<
@@ -11,6 +11,9 @@ import {
11
11
  parseProviderOptions,
12
12
  postJsonToApi,
13
13
  resolve,
14
+ serializeModelOptions,
15
+ WORKFLOW_SERIALIZE,
16
+ WORKFLOW_DESERIALIZE,
14
17
  } from '@ai-sdk/provider-utils';
15
18
  import {
16
19
  BedrockEmbeddingModelId,
@@ -21,7 +24,7 @@ import { z } from 'zod/v4';
21
24
 
22
25
  type BedrockEmbeddingConfig = {
23
26
  baseUrl: () => string;
24
- headers: Resolvable<Record<string, string | undefined>>;
27
+ headers?: Resolvable<Record<string, string | undefined>>;
25
28
  fetch?: FetchFunction;
26
29
  };
27
30
 
@@ -33,6 +36,20 @@ export class BedrockEmbeddingModel implements EmbeddingModelV4 {
33
36
  readonly maxEmbeddingsPerCall = 1;
34
37
  readonly supportsParallelCalls = true;
35
38
 
39
+ static [WORKFLOW_SERIALIZE](model: BedrockEmbeddingModel) {
40
+ return serializeModelOptions({
41
+ modelId: model.modelId,
42
+ config: model.config,
43
+ });
44
+ }
45
+
46
+ static [WORKFLOW_DESERIALIZE](options: {
47
+ modelId: string;
48
+ config: BedrockEmbeddingConfig;
49
+ }) {
50
+ return new BedrockEmbeddingModel(options.modelId, options.config);
51
+ }
52
+
36
53
  constructor(
37
54
  readonly modelId: BedrockEmbeddingModelId,
38
55
  private readonly config: BedrockEmbeddingConfig,
@@ -107,7 +124,10 @@ export class BedrockEmbeddingModel implements EmbeddingModelV4 {
107
124
  const { value: response } = await postJsonToApi({
108
125
  url,
109
126
  headers: await resolve(
110
- combineHeaders(await resolve(this.config.headers), headers),
127
+ combineHeaders(
128
+ this.config.headers ? await resolve(this.config.headers) : undefined,
129
+ headers,
130
+ ),
111
131
  ),
112
132
  body: args,
113
133
  failedResponseHandler: createJsonErrorResponseHandler({
@@ -12,6 +12,9 @@ import {
12
12
  createJsonResponseHandler,
13
13
  postJsonToApi,
14
14
  resolve,
15
+ serializeModelOptions,
16
+ WORKFLOW_SERIALIZE,
17
+ WORKFLOW_DESERIALIZE,
15
18
  } from '@ai-sdk/provider-utils';
16
19
  import {
17
20
  BedrockImageModelId,
@@ -22,7 +25,7 @@ import { z } from 'zod/v4';
22
25
 
23
26
  type BedrockImageModelConfig = {
24
27
  baseUrl: () => string;
25
- headers: Resolvable<Record<string, string | undefined>>;
28
+ headers?: Resolvable<Record<string, string | undefined>>;
26
29
  fetch?: FetchFunction;
27
30
  _internal?: {
28
31
  currentDate?: () => Date;
@@ -33,6 +36,20 @@ export class BedrockImageModel implements ImageModelV4 {
33
36
  readonly specificationVersion = 'v4';
34
37
  readonly provider = 'amazon-bedrock';
35
38
 
39
+ static [WORKFLOW_SERIALIZE](model: BedrockImageModel) {
40
+ return serializeModelOptions({
41
+ modelId: model.modelId,
42
+ config: model.config,
43
+ });
44
+ }
45
+
46
+ static [WORKFLOW_DESERIALIZE](options: {
47
+ modelId: string;
48
+ config: BedrockImageModelConfig;
49
+ }) {
50
+ return new BedrockImageModel(options.modelId, options.config);
51
+ }
52
+
36
53
  get maxImagesPerCall(): number {
37
54
  return modelMaxImagesPerCall[this.modelId] ?? 1;
38
55
  }
@@ -220,7 +237,10 @@ export class BedrockImageModel implements ImageModelV4 {
220
237
  const { value: response, responseHeaders } = await postJsonToApi({
221
238
  url: this.getUrl(this.modelId),
222
239
  headers: await resolve(
223
- combineHeaders(await resolve(this.config.headers), headers),
240
+ combineHeaders(
241
+ this.config.headers ? await resolve(this.config.headers) : undefined,
242
+ headers,
243
+ ),
224
244
  ),
225
245
  body: args,
226
246
  failedResponseHandler: createJsonErrorResponseHandler({