@ai-sdk/amazon-bedrock 5.0.0-beta.4 → 5.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.
@@ -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.40",
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.36",
42
+ "@ai-sdk/provider": "4.0.0-beta.12",
43
+ "@ai-sdk/provider-utils": "5.0.0-beta.25"
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
 
@@ -247,7 +283,6 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
247
283
 
248
284
  const maxReasoningEffort =
249
285
  bedrockOptions.reasoningConfig?.maxReasoningEffort;
250
- const isOpenAIModel = this.modelId.startsWith('openai.');
251
286
 
252
287
  if (maxReasoningEffort != null) {
253
288
  if (isAnthropicModel) {
@@ -368,6 +403,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
368
403
  const {
369
404
  reasoningConfig: _,
370
405
  additionalModelRequestFields: __,
406
+ serviceTier: ___,
371
407
  ...filteredBedrockOptions
372
408
  } = providerOptions?.bedrock || {};
373
409
 
@@ -387,6 +423,11 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
387
423
  ...(Object.keys(inferenceConfig).length > 0 && {
388
424
  inferenceConfig,
389
425
  }),
426
+ ...(bedrockOptions.serviceTier != null && {
427
+ serviceTier: {
428
+ type: bedrockOptions.serviceTier,
429
+ },
430
+ }),
390
431
  ...filteredBedrockOptions,
391
432
  ...(toolConfig.tools !== undefined && toolConfig.tools.length > 0
392
433
  ? { toolConfig }
@@ -407,7 +448,10 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
407
448
  }: {
408
449
  headers: Record<string, string | undefined> | undefined;
409
450
  }) {
410
- return combineHeaders(await resolve(this.config.headers), headers);
451
+ return combineHeaders(
452
+ this.config.headers ? await resolve(this.config.headers) : undefined,
453
+ headers,
454
+ );
411
455
  }
412
456
 
413
457
  async doGenerate(
@@ -441,7 +485,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
441
485
  // map response content to content array
442
486
  for (const part of response.output.message.content) {
443
487
  // text
444
- if (part.text) {
488
+ if (part.text != null) {
445
489
  content.push({ type: 'text', text: part.text });
446
490
  }
447
491
 
@@ -1122,3 +1166,73 @@ export const bedrockReasoningMetadataSchema = z.object({
1122
1166
  export type BedrockReasoningMetadata = z.infer<
1123
1167
  typeof bedrockReasoningMetadataSchema
1124
1168
  >;
1169
+
1170
+ const bedrockReasoningEffortMap: Partial<
1171
+ Record<string, 'low' | 'medium' | 'high' | 'max'>
1172
+ > = {
1173
+ minimal: 'low',
1174
+ low: 'low',
1175
+ medium: 'medium',
1176
+ high: 'high',
1177
+ xhigh: 'max',
1178
+ };
1179
+
1180
+ function resolveBedrockReasoningConfig({
1181
+ reasoning,
1182
+ bedrockOptions,
1183
+ warnings,
1184
+ isAnthropicModel,
1185
+ modelId,
1186
+ }: {
1187
+ reasoning: LanguageModelV4CallOptions['reasoning'];
1188
+ bedrockOptions: AmazonBedrockLanguageModelOptions;
1189
+ warnings: SharedV4Warning[];
1190
+ isAnthropicModel: boolean;
1191
+ modelId: string;
1192
+ }): AmazonBedrockLanguageModelOptions {
1193
+ if (!isCustomReasoning(reasoning) || bedrockOptions.reasoningConfig != null) {
1194
+ return bedrockOptions;
1195
+ }
1196
+
1197
+ const result = { ...bedrockOptions };
1198
+
1199
+ if (isAnthropicModel) {
1200
+ const capabilities = getModelCapabilities(modelId);
1201
+
1202
+ if (reasoning === 'none') {
1203
+ result.reasoningConfig = { type: 'disabled' };
1204
+ } else if (capabilities.supportsAdaptiveThinking) {
1205
+ const effort = mapReasoningToProviderEffort({
1206
+ reasoning,
1207
+ effortMap: bedrockReasoningEffortMap,
1208
+ warnings,
1209
+ });
1210
+ result.reasoningConfig = {
1211
+ type: 'adaptive',
1212
+ maxReasoningEffort: effort,
1213
+ };
1214
+ } else {
1215
+ const budgetTokens = mapReasoningToProviderBudget({
1216
+ reasoning,
1217
+ maxOutputTokens: capabilities.maxOutputTokens,
1218
+ maxReasoningBudget: capabilities.maxOutputTokens,
1219
+ warnings,
1220
+ });
1221
+ if (budgetTokens != null) {
1222
+ result.reasoningConfig = {
1223
+ type: 'enabled',
1224
+ budgetTokens,
1225
+ };
1226
+ }
1227
+ }
1228
+ } else if (reasoning !== 'none') {
1229
+ const effort = mapReasoningToProviderEffort({
1230
+ reasoning,
1231
+ effortMap: bedrockReasoningEffortMap,
1232
+ warnings,
1233
+ });
1234
+ result.reasoningConfig = { maxReasoningEffort: effort };
1235
+ }
1236
+
1237
+ return result;
1238
+ }
@@ -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'
@@ -122,6 +124,16 @@ export const amazonBedrockLanguageModelOptions = z.object({
122
124
  * Anthropic beta features to enable
123
125
  */
124
126
  anthropicBeta: z.array(z.string()).optional(),
127
+ /**
128
+ * Service tier for the request.
129
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html
130
+ *
131
+ * - 'reserved': Uses provisioned throughput capacity
132
+ * - 'priority': Prioritizes low-latency inference when capacity is available
133
+ * - 'default': Standard on-demand tier
134
+ * - 'flex': Lower-cost tier for flexible latency workloads
135
+ */
136
+ serviceTier: z.enum(['reserved', 'priority', 'default', 'flex']).optional(),
125
137
  });
126
138
 
127
139
  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({