@ai-sdk/amazon-bedrock 5.0.0-beta.7 → 5.0.0-beta.85

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 (56) hide show
  1. package/CHANGELOG.md +677 -4
  2. package/README.md +2 -0
  3. package/dist/anthropic/index.d.ts +10 -10
  4. package/dist/anthropic/index.js +151 -117
  5. package/dist/anthropic/index.js.map +1 -1
  6. package/dist/index.d.ts +36 -23
  7. package/dist/index.js +881 -604
  8. package/dist/index.js.map +1 -1
  9. package/dist/mantle/index.cjs +253 -0
  10. package/dist/mantle/index.cjs.map +1 -0
  11. package/dist/mantle/index.d.cts +99 -0
  12. package/dist/mantle/index.d.ts +99 -0
  13. package/dist/mantle/index.js +240 -0
  14. package/dist/mantle/index.js.map +1 -0
  15. package/docs/08-amazon-bedrock.mdx +310 -84
  16. package/mantle/index.d.ts +1 -0
  17. package/package.json +27 -20
  18. package/src/amazon-bedrock-api-types.ts +228 -0
  19. package/src/{bedrock-chat-options.ts → amazon-bedrock-chat-language-model-options.ts} +27 -8
  20. package/src/{bedrock-chat-language-model.ts → amazon-bedrock-chat-language-model.ts} +350 -180
  21. package/src/{bedrock-embedding-options.ts → amazon-bedrock-embedding-model-options.ts} +1 -1
  22. package/src/{bedrock-embedding-model.ts → amazon-bedrock-embedding-model.ts} +61 -29
  23. package/src/{bedrock-error.ts → amazon-bedrock-error.ts} +1 -1
  24. package/src/{bedrock-event-stream-decoder.ts → amazon-bedrock-event-stream-decoder.ts} +1 -1
  25. package/src/{bedrock-event-stream-response-handler.ts → amazon-bedrock-event-stream-response-handler.ts} +6 -6
  26. package/src/{bedrock-image-model.ts → amazon-bedrock-image-model.ts} +62 -38
  27. package/src/amazon-bedrock-image-settings.ts +9 -0
  28. package/src/{bedrock-prepare-tools.ts → amazon-bedrock-prepare-tools.ts} +22 -18
  29. package/src/{bedrock-provider.ts → amazon-bedrock-provider.ts} +53 -46
  30. package/src/amazon-bedrock-reasoning-metadata.ts +10 -0
  31. package/src/{bedrock-sigv4-fetch.ts → amazon-bedrock-sigv4-fetch.ts} +17 -9
  32. package/src/anthropic/amazon-bedrock-anthropic-fetch.ts +104 -0
  33. package/src/anthropic/{bedrock-anthropic-options.ts → amazon-bedrock-anthropic-options.ts} +7 -1
  34. package/src/anthropic/{bedrock-anthropic-provider.ts → amazon-bedrock-anthropic-provider.ts} +40 -24
  35. package/src/anthropic/index.ts +19 -7
  36. package/src/{convert-bedrock-usage.ts → convert-amazon-bedrock-usage.ts} +4 -4
  37. package/src/convert-to-amazon-bedrock-chat-messages.ts +556 -0
  38. package/src/index.ts +15 -8
  39. package/src/inject-fetch-headers.ts +1 -1
  40. package/src/mantle/bedrock-mantle-options.ts +15 -0
  41. package/src/mantle/bedrock-mantle-provider.ts +283 -0
  42. package/src/mantle/index.ts +6 -0
  43. package/src/{map-bedrock-finish-reason.ts → map-amazon-bedrock-finish-reason.ts} +4 -4
  44. package/src/reranking/{bedrock-reranking-api.ts → amazon-bedrock-reranking-api.ts} +3 -3
  45. package/src/reranking/{bedrock-reranking-options.ts → amazon-bedrock-reranking-model-options.ts} +1 -1
  46. package/src/reranking/{bedrock-reranking-model.ts → amazon-bedrock-reranking-model.ts} +32 -25
  47. package/dist/anthropic/index.d.mts +0 -91
  48. package/dist/anthropic/index.mjs +0 -397
  49. package/dist/anthropic/index.mjs.map +0 -1
  50. package/dist/index.d.mts +0 -194
  51. package/dist/index.mjs +0 -2329
  52. package/dist/index.mjs.map +0 -1
  53. package/src/anthropic/bedrock-anthropic-fetch.ts +0 -68
  54. package/src/bedrock-api-types.ts +0 -216
  55. package/src/bedrock-image-settings.ts +0 -6
  56. package/src/convert-to-bedrock-chat-messages.ts +0 -468
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  JSONObject,
3
3
  LanguageModelV4,
4
4
  LanguageModelV4CallOptions,
@@ -13,48 +13,74 @@ import {
13
13
  SharedV4Warning,
14
14
  } from '@ai-sdk/provider';
15
15
  import {
16
- FetchFunction,
17
- ParseResult,
18
- Resolvable,
19
16
  combineHeaders,
20
17
  createJsonErrorResponseHandler,
21
18
  createJsonResponseHandler,
19
+ isCustomReasoning,
20
+ mapReasoningToProviderBudget,
21
+ mapReasoningToProviderEffort,
22
22
  parseProviderOptions,
23
23
  postJsonToApi,
24
24
  resolve,
25
+ serializeModelOptions,
26
+ WORKFLOW_SERIALIZE,
27
+ WORKFLOW_DESERIALIZE,
28
+ type FetchFunction,
29
+ type ParseResult,
30
+ type Resolvable,
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,
29
- BedrockConverseInput,
30
- BedrockStopReason,
31
- } from './bedrock-api-types';
36
+ type AmazonBedrockConverseInput,
37
+ type AmazonBedrockStopReason,
38
+ } from './amazon-bedrock-api-types';
39
+ import {
40
+ amazonBedrockLanguageModelChatOptions,
41
+ type AmazonBedrockLanguageModelChatOptions,
42
+ type AmazonBedrockChatModelId,
43
+ } from './amazon-bedrock-chat-language-model-options';
44
+ import { AmazonBedrockErrorSchema } from './amazon-bedrock-error';
45
+ import { createAmazonBedrockEventStreamResponseHandler } from './amazon-bedrock-event-stream-response-handler';
46
+ import { prepareTools } from './amazon-bedrock-prepare-tools';
32
47
  import {
33
- BedrockChatModelId,
34
- amazonBedrockLanguageModelOptions,
35
- } from './bedrock-chat-options';
36
- import { BedrockErrorSchema } from './bedrock-error';
37
- import { createBedrockEventStreamResponseHandler } from './bedrock-event-stream-response-handler';
38
- import { prepareTools } from './bedrock-prepare-tools';
39
- import { BedrockUsage, convertBedrockUsage } from './convert-bedrock-usage';
40
- import { convertToBedrockChatMessages } from './convert-to-bedrock-chat-messages';
41
- import { mapBedrockFinishReason } from './map-bedrock-finish-reason';
48
+ convertAmazonBedrockUsage,
49
+ type AmazonBedrockUsage,
50
+ } from './convert-amazon-bedrock-usage';
51
+ import { convertToAmazonBedrockChatMessages } from './convert-to-amazon-bedrock-chat-messages';
52
+ import { mapAmazonBedrockFinishReason } from './map-amazon-bedrock-finish-reason';
42
53
  import { isMistralModel, normalizeToolCallId } from './normalize-tool-call-id';
54
+ import type { AmazonBedrockReasoningMetadata } from './amazon-bedrock-reasoning-metadata';
43
55
 
44
- type BedrockChatConfig = {
56
+ type AmazonBedrockChatConfig = {
45
57
  baseUrl: () => string;
46
- headers: Resolvable<Record<string, string | undefined>>;
58
+ headers?: Resolvable<Record<string, string | undefined>>;
47
59
  fetch?: FetchFunction;
48
60
  generateId: () => string;
49
61
  };
50
62
 
51
- export class BedrockChatLanguageModel implements LanguageModelV4 {
63
+ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
52
64
  readonly specificationVersion = 'v4';
53
65
  readonly provider = 'amazon-bedrock';
54
66
 
67
+ static [WORKFLOW_SERIALIZE](model: AmazonBedrockChatLanguageModel) {
68
+ return serializeModelOptions({
69
+ modelId: model.modelId,
70
+ config: model.config,
71
+ });
72
+ }
73
+
74
+ static [WORKFLOW_DESERIALIZE](options: {
75
+ modelId: string;
76
+ config: AmazonBedrockChatConfig;
77
+ }) {
78
+ return new AmazonBedrockChatLanguageModel(options.modelId, options.config);
79
+ }
80
+
55
81
  constructor(
56
- readonly modelId: BedrockChatModelId,
57
- private readonly config: BedrockChatConfig,
82
+ readonly modelId: AmazonBedrockChatModelId,
83
+ private readonly config: AmazonBedrockChatConfig,
58
84
  ) {}
59
85
 
60
86
  private async getArgs({
@@ -70,20 +96,28 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
70
96
  seed,
71
97
  tools,
72
98
  toolChoice,
99
+ reasoning,
73
100
  providerOptions,
74
101
  }: LanguageModelV4CallOptions): Promise<{
75
- command: BedrockConverseInput;
102
+ command: AmazonBedrockConverseInput;
76
103
  warnings: SharedV4Warning[];
77
104
  usesJsonResponseTool: boolean;
78
105
  betas: Set<string>;
79
106
  }> {
80
- // Parse provider options
81
- const bedrockOptions =
107
+ // Parse provider options. Prefer `amazonBedrock`; fall back to legacy
108
+ // `bedrock` key for backward compatibility.
109
+ let amazonBedrockOptions =
110
+ (await parseProviderOptions({
111
+ provider: 'amazonBedrock',
112
+ providerOptions,
113
+ schema: amazonBedrockLanguageModelChatOptions,
114
+ })) ??
82
115
  (await parseProviderOptions({
83
116
  provider: 'bedrock',
84
117
  providerOptions,
85
- schema: amazonBedrockLanguageModelOptions,
86
- })) ?? {};
118
+ schema: amazonBedrockLanguageModelChatOptions,
119
+ })) ??
120
+ {};
87
121
 
88
122
  const warnings: SharedV4Warning[] = [];
89
123
 
@@ -137,13 +171,26 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
137
171
  }
138
172
 
139
173
  const isAnthropicModel = this.modelId.includes('anthropic');
174
+ const isOpenAIModel = this.modelId.startsWith('openai.');
175
+
176
+ amazonBedrockOptions = resolveAmazonBedrockReasoningConfig({
177
+ reasoning,
178
+ amazonBedrockOptions,
179
+ warnings,
180
+ isAnthropicModel,
181
+ modelId: this.modelId,
182
+ });
183
+
140
184
  const isThinkingEnabled =
141
- bedrockOptions.reasoningConfig?.type === 'enabled' ||
142
- bedrockOptions.reasoningConfig?.type === 'adaptive';
185
+ amazonBedrockOptions.reasoningConfig?.type === 'enabled' ||
186
+ amazonBedrockOptions.reasoningConfig?.type === 'adaptive';
187
+
188
+ const { supportsStructuredOutput: modelSupportsStructuredOutput } =
189
+ getModelCapabilities(this.modelId);
143
190
 
144
191
  const useNativeStructuredOutput =
145
192
  isAnthropicModel &&
146
- isThinkingEnabled &&
193
+ (modelSupportsStructuredOutput || isThinkingEnabled) &&
147
194
  responseFormat?.type === 'json' &&
148
195
  responseFormat.schema != null;
149
196
 
@@ -170,29 +217,33 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
170
217
  warnings.push(...toolWarnings);
171
218
 
172
219
  if (additionalTools) {
173
- bedrockOptions.additionalModelRequestFields = {
174
- ...bedrockOptions.additionalModelRequestFields,
220
+ amazonBedrockOptions.additionalModelRequestFields = {
221
+ ...amazonBedrockOptions.additionalModelRequestFields,
175
222
  ...additionalTools,
176
223
  };
177
224
  }
178
225
 
179
- if (betas.size > 0 || bedrockOptions.anthropicBeta) {
180
- const existingBetas = bedrockOptions.anthropicBeta ?? [];
226
+ if (betas.size > 0 || amazonBedrockOptions.anthropicBeta) {
227
+ const existingBetas = amazonBedrockOptions.anthropicBeta ?? [];
181
228
  const mergedBetas =
182
229
  betas.size > 0
183
230
  ? [...existingBetas, ...Array.from(betas)]
184
231
  : existingBetas;
185
232
 
186
- bedrockOptions.additionalModelRequestFields = {
187
- ...bedrockOptions.additionalModelRequestFields,
233
+ amazonBedrockOptions.additionalModelRequestFields = {
234
+ ...amazonBedrockOptions.additionalModelRequestFields,
188
235
  anthropic_beta: mergedBetas,
189
236
  };
190
237
  }
191
238
 
192
- const thinkingType = bedrockOptions.reasoningConfig?.type;
239
+ const thinkingType = amazonBedrockOptions.reasoningConfig?.type;
193
240
  const thinkingBudget =
194
241
  thinkingType === 'enabled'
195
- ? bedrockOptions.reasoningConfig?.budgetTokens
242
+ ? amazonBedrockOptions.reasoningConfig?.budgetTokens
243
+ : undefined;
244
+ const thinkingDisplay =
245
+ thinkingType === 'adaptive'
246
+ ? amazonBedrockOptions.reasoningConfig?.display
196
247
  : undefined;
197
248
  const isAnthropicThinkingEnabled = isAnthropicModel && isThinkingEnabled;
198
249
 
@@ -211,23 +262,24 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
211
262
  } else {
212
263
  inferenceConfig.maxTokens = thinkingBudget + 4096; // Default + thinking budget maxTokens = 4096, TODO update default in v5
213
264
  }
214
- bedrockOptions.additionalModelRequestFields = {
215
- ...bedrockOptions.additionalModelRequestFields,
265
+ amazonBedrockOptions.additionalModelRequestFields = {
266
+ ...amazonBedrockOptions.additionalModelRequestFields,
216
267
  thinking: {
217
268
  type: 'enabled',
218
269
  budget_tokens: thinkingBudget,
219
270
  },
220
271
  };
221
272
  } else if (thinkingType === 'adaptive') {
222
- bedrockOptions.additionalModelRequestFields = {
223
- ...bedrockOptions.additionalModelRequestFields,
273
+ amazonBedrockOptions.additionalModelRequestFields = {
274
+ ...amazonBedrockOptions.additionalModelRequestFields,
224
275
  thinking: {
225
276
  type: 'adaptive',
277
+ ...(thinkingDisplay != null && { display: thinkingDisplay }),
226
278
  },
227
279
  };
228
280
  }
229
281
  } else if (!isAnthropicModel) {
230
- if (bedrockOptions.reasoningConfig?.budgetTokens != null) {
282
+ if (amazonBedrockOptions.reasoningConfig?.budgetTokens != null) {
231
283
  warnings.push({
232
284
  type: 'unsupported',
233
285
  feature: 'budgetTokens',
@@ -246,28 +298,27 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
246
298
  }
247
299
 
248
300
  const maxReasoningEffort =
249
- bedrockOptions.reasoningConfig?.maxReasoningEffort;
250
- const isOpenAIModel = this.modelId.startsWith('openai.');
301
+ amazonBedrockOptions.reasoningConfig?.maxReasoningEffort;
251
302
 
252
303
  if (maxReasoningEffort != null) {
253
304
  if (isAnthropicModel) {
254
- bedrockOptions.additionalModelRequestFields = {
255
- ...bedrockOptions.additionalModelRequestFields,
305
+ amazonBedrockOptions.additionalModelRequestFields = {
306
+ ...amazonBedrockOptions.additionalModelRequestFields,
256
307
  output_config: {
257
- ...bedrockOptions.additionalModelRequestFields?.output_config,
308
+ ...amazonBedrockOptions.additionalModelRequestFields?.output_config,
258
309
  effort: maxReasoningEffort,
259
310
  },
260
311
  };
261
312
  } else if (isOpenAIModel) {
262
313
  // OpenAI models on Bedrock expect `reasoning_effort` as a flat value
263
- bedrockOptions.additionalModelRequestFields = {
264
- ...bedrockOptions.additionalModelRequestFields,
314
+ amazonBedrockOptions.additionalModelRequestFields = {
315
+ ...amazonBedrockOptions.additionalModelRequestFields,
265
316
  reasoning_effort: maxReasoningEffort,
266
317
  };
267
318
  } else {
268
319
  // other models (such as Nova 2) use reasoningConfig format
269
- bedrockOptions.additionalModelRequestFields = {
270
- ...bedrockOptions.additionalModelRequestFields,
320
+ amazonBedrockOptions.additionalModelRequestFields = {
321
+ ...amazonBedrockOptions.additionalModelRequestFields,
271
322
  reasoningConfig: {
272
323
  ...(thinkingType != null &&
273
324
  thinkingType !== 'adaptive' && { type: thinkingType }),
@@ -279,10 +330,10 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
279
330
  }
280
331
 
281
332
  if (useNativeStructuredOutput) {
282
- bedrockOptions.additionalModelRequestFields = {
283
- ...bedrockOptions.additionalModelRequestFields,
333
+ amazonBedrockOptions.additionalModelRequestFields = {
334
+ ...amazonBedrockOptions.additionalModelRequestFields,
284
335
  output_config: {
285
- ...bedrockOptions.additionalModelRequestFields?.output_config,
336
+ ...amazonBedrockOptions.additionalModelRequestFields?.output_config,
286
337
  format: {
287
338
  type: 'json_schema',
288
339
  schema: responseFormat!.schema,
@@ -359,17 +410,18 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
359
410
  }
360
411
 
361
412
  const isMistral = isMistralModel(this.modelId);
362
- const { system, messages } = await convertToBedrockChatMessages(
413
+ const { system, messages } = await convertToAmazonBedrockChatMessages(
363
414
  filteredPrompt,
364
415
  isMistral,
365
416
  );
366
417
 
367
- // Filter out reasoningConfig from providerOptions.bedrock to prevent sending it to Bedrock API
418
+ // Filter out reasoningConfig from amazonBedrock provider options to prevent sending it to Bedrock API
368
419
  const {
369
420
  reasoningConfig: _,
370
421
  additionalModelRequestFields: __,
371
- ...filteredBedrockOptions
372
- } = providerOptions?.bedrock || {};
422
+ serviceTier: ___,
423
+ ...filteredAmazonBedrockOptions
424
+ } = providerOptions?.amazonBedrock ?? providerOptions?.bedrock ?? {};
373
425
 
374
426
  const additionalModelResponseFieldPaths = isAnthropicModel
375
427
  ? ['/delta/stop_sequence']
@@ -380,14 +432,19 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
380
432
  system,
381
433
  messages,
382
434
  additionalModelRequestFields:
383
- bedrockOptions.additionalModelRequestFields,
435
+ amazonBedrockOptions.additionalModelRequestFields,
384
436
  ...(additionalModelResponseFieldPaths && {
385
437
  additionalModelResponseFieldPaths,
386
438
  }),
387
439
  ...(Object.keys(inferenceConfig).length > 0 && {
388
440
  inferenceConfig,
389
441
  }),
390
- ...filteredBedrockOptions,
442
+ ...(amazonBedrockOptions.serviceTier != null && {
443
+ serviceTier: {
444
+ type: amazonBedrockOptions.serviceTier,
445
+ },
446
+ }),
447
+ ...filteredAmazonBedrockOptions,
391
448
  ...(toolConfig.tools !== undefined && toolConfig.tools.length > 0
392
449
  ? { toolConfig }
393
450
  : {}),
@@ -407,7 +464,10 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
407
464
  }: {
408
465
  headers: Record<string, string | undefined> | undefined;
409
466
  }) {
410
- return combineHeaders(await resolve(this.config.headers), headers);
467
+ return combineHeaders(
468
+ this.config.headers ? await resolve(this.config.headers) : undefined,
469
+ headers,
470
+ );
411
471
  }
412
472
 
413
473
  async doGenerate(
@@ -425,11 +485,11 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
425
485
  headers: await this.getHeaders({ headers: options.headers }),
426
486
  body: args,
427
487
  failedResponseHandler: createJsonErrorResponseHandler({
428
- errorSchema: BedrockErrorSchema,
488
+ errorSchema: AmazonBedrockErrorSchema,
429
489
  errorToMessage: error => `${error.message ?? 'Unknown error'}`,
430
490
  }),
431
491
  successfulResponseHandler: createJsonResponseHandler(
432
- BedrockResponseSchema,
492
+ AmazonBedrockResponseSchema,
433
493
  ),
434
494
  abortSignal: options.abortSignal,
435
495
  fetch: this.config.fetch,
@@ -441,7 +501,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
441
501
  // map response content to content array
442
502
  for (const part of response.output.message.content) {
443
503
  // text
444
- if (part.text) {
504
+ if (part.text != null) {
445
505
  content.push({ type: 'text', text: part.text });
446
506
  }
447
507
 
@@ -454,23 +514,26 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
454
514
  };
455
515
 
456
516
  if (part.reasoningContent.reasoningText.signature) {
517
+ const reasoningPayload: AmazonBedrockReasoningMetadata = {
518
+ signature: part.reasoningContent.reasoningText.signature,
519
+ };
457
520
  reasoning.providerMetadata = {
458
- bedrock: {
459
- signature: part.reasoningContent.reasoningText.signature,
460
- } satisfies BedrockReasoningMetadata,
521
+ amazonBedrock: reasoningPayload,
522
+ bedrock: reasoningPayload,
461
523
  };
462
524
  }
463
525
 
464
526
  content.push(reasoning);
465
527
  } else if ('redactedReasoning' in part.reasoningContent) {
528
+ const redactedPayload: AmazonBedrockReasoningMetadata = {
529
+ redactedData: part.reasoningContent.redactedReasoning.data ?? '',
530
+ };
466
531
  content.push({
467
532
  type: 'reasoning',
468
533
  text: '',
469
534
  providerMetadata: {
470
- bedrock: {
471
- redactedData:
472
- part.reasoningContent.redactedReasoning.data ?? '',
473
- } satisfies BedrockReasoningMetadata,
535
+ amazonBedrock: redactedPayload,
536
+ bedrock: redactedPayload,
474
537
  },
475
538
  });
476
539
  }
@@ -506,7 +569,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
506
569
  const stopSequence =
507
570
  response.additionalModelResponseFields?.delta?.stop_sequence ?? null;
508
571
 
509
- const providerMetadata =
572
+ const providerMetadataPayload =
510
573
  response.trace ||
511
574
  response.usage ||
512
575
  response.performanceConfig ||
@@ -514,43 +577,48 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
514
577
  isJsonResponseFromTool ||
515
578
  stopSequence
516
579
  ? {
517
- bedrock: {
518
- ...(response.trace && typeof response.trace === 'object'
519
- ? { trace: response.trace as JSONObject }
520
- : {}),
521
- ...(response.performanceConfig && {
522
- performanceConfig: response.performanceConfig,
523
- }),
524
- ...(response.serviceTier && {
525
- serviceTier: response.serviceTier,
526
- }),
527
- ...((response.usage?.cacheWriteInputTokens != null ||
528
- response.usage?.cacheDetails != null) && {
529
- usage: {
530
- ...(response.usage.cacheWriteInputTokens != null && {
531
- cacheWriteInputTokens: response.usage.cacheWriteInputTokens,
532
- }),
533
- ...(response.usage.cacheDetails != null && {
534
- cacheDetails: response.usage.cacheDetails,
535
- }),
536
- },
537
- }),
538
- ...(isJsonResponseFromTool && { isJsonResponseFromTool: true }),
539
- stopSequence,
540
- },
580
+ ...(response.trace && typeof response.trace === 'object'
581
+ ? { trace: response.trace as JSONObject }
582
+ : {}),
583
+ ...(response.performanceConfig && {
584
+ performanceConfig: response.performanceConfig,
585
+ }),
586
+ ...(response.serviceTier && {
587
+ serviceTier: response.serviceTier,
588
+ }),
589
+ ...((response.usage?.cacheWriteInputTokens != null ||
590
+ response.usage?.cacheDetails != null) && {
591
+ usage: {
592
+ ...(response.usage.cacheWriteInputTokens != null && {
593
+ cacheWriteInputTokens: response.usage.cacheWriteInputTokens,
594
+ }),
595
+ ...(response.usage.cacheDetails != null && {
596
+ cacheDetails: response.usage.cacheDetails,
597
+ }),
598
+ },
599
+ }),
600
+ ...(isJsonResponseFromTool && { isJsonResponseFromTool: true }),
601
+ stopSequence,
541
602
  }
542
603
  : undefined;
543
604
 
605
+ const providerMetadata = providerMetadataPayload
606
+ ? {
607
+ amazonBedrock: providerMetadataPayload,
608
+ bedrock: providerMetadataPayload,
609
+ }
610
+ : undefined;
611
+
544
612
  return {
545
613
  content,
546
614
  finishReason: {
547
- unified: mapBedrockFinishReason(
548
- response.stopReason as BedrockStopReason,
615
+ unified: mapAmazonBedrockFinishReason(
616
+ response.stopReason as AmazonBedrockStopReason,
549
617
  isJsonResponseFromTool,
550
618
  ),
551
619
  raw: response.stopReason ?? undefined,
552
620
  },
553
- usage: convertBedrockUsage(response.usage),
621
+ usage: convertAmazonBedrockUsage(response.usage),
554
622
  response: {
555
623
  id: responseHeaders?.['x-amzn-requestid'] ?? undefined,
556
624
  timestamp:
@@ -582,11 +650,12 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
582
650
  headers: await this.getHeaders({ headers: options.headers }),
583
651
  body: args,
584
652
  failedResponseHandler: createJsonErrorResponseHandler({
585
- errorSchema: BedrockErrorSchema,
653
+ errorSchema: AmazonBedrockErrorSchema,
586
654
  errorToMessage: error => `${error.type}: ${error.message}`,
587
655
  }),
588
- successfulResponseHandler:
589
- createBedrockEventStreamResponseHandler(BedrockStreamSchema),
656
+ successfulResponseHandler: createAmazonBedrockEventStreamResponseHandler(
657
+ AmazonBedrockStreamSchema,
658
+ ),
590
659
  abortSignal: options.abortSignal,
591
660
  fetch: this.config.fetch,
592
661
  });
@@ -595,7 +664,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
595
664
  unified: 'other',
596
665
  raw: undefined,
597
666
  };
598
- let usage: BedrockUsage | undefined = undefined;
667
+ let usage: AmazonBedrockUsage | undefined = undefined;
599
668
  let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
600
669
  let isJsonResponseFromTool = false;
601
670
  let stopSequence: string | null = null;
@@ -615,7 +684,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
615
684
  return {
616
685
  stream: response.pipeThrough(
617
686
  new TransformStream<
618
- ParseResult<z.infer<typeof BedrockStreamSchema>>,
687
+ ParseResult<z.infer<typeof AmazonBedrockStreamSchema>>,
619
688
  LanguageModelV4StreamPart
620
689
  >({
621
690
  start(controller) {
@@ -632,9 +701,9 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
632
701
  },
633
702
 
634
703
  transform(chunk, controller) {
635
- function enqueueError(bedrockError: Record<string, any>) {
704
+ function enqueueError(amazonBedrockError: Record<string, any>) {
636
705
  finishReason = { unified: 'error', raw: undefined };
637
- controller.enqueue({ type: 'error', error: bedrockError });
706
+ controller.enqueue({ type: 'error', error: amazonBedrockError });
638
707
  }
639
708
 
640
709
  // Emit raw chunk if requested (before anything else)
@@ -670,8 +739,8 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
670
739
 
671
740
  if (value.messageStop) {
672
741
  finishReason = {
673
- unified: mapBedrockFinishReason(
674
- value.messageStop.stopReason as BedrockStopReason,
742
+ unified: mapAmazonBedrockFinishReason(
743
+ value.messageStop.stopReason as AmazonBedrockStopReason,
675
744
  isJsonResponseFromTool,
676
745
  ),
677
746
  raw: value.messageStop.stopReason ?? undefined,
@@ -715,17 +784,19 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
715
784
  value.metadata.performanceConfig ||
716
785
  value.metadata.serviceTier
717
786
  ) {
787
+ const metadataPayload = {
788
+ ...cacheUsage,
789
+ ...trace,
790
+ ...(value.metadata.performanceConfig && {
791
+ performanceConfig: value.metadata.performanceConfig,
792
+ }),
793
+ ...(value.metadata.serviceTier && {
794
+ serviceTier: value.metadata.serviceTier,
795
+ }),
796
+ };
718
797
  providerMetadata = {
719
- bedrock: {
720
- ...cacheUsage,
721
- ...trace,
722
- ...(value.metadata.performanceConfig && {
723
- performanceConfig: value.metadata.performanceConfig,
724
- }),
725
- ...(value.metadata.serviceTier && {
726
- serviceTier: value.metadata.serviceTier,
727
- }),
728
- },
798
+ amazonBedrock: metadataPayload,
799
+ bedrock: metadataPayload,
729
800
  };
730
801
  }
731
802
  }
@@ -845,27 +916,49 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
845
916
  'signature' in reasoningContent &&
846
917
  reasoningContent.signature
847
918
  ) {
848
- controller.enqueue({
849
- type: 'reasoning-delta',
850
- id: String(blockIndex),
851
- delta: '',
852
- providerMetadata: {
853
- bedrock: {
854
- signature: reasoningContent.signature,
855
- } satisfies BedrockReasoningMetadata,
856
- },
857
- });
919
+ if (contentBlocks[blockIndex] == null) {
920
+ contentBlocks[blockIndex] = { type: 'reasoning' };
921
+ controller.enqueue({
922
+ type: 'reasoning-start',
923
+ id: String(blockIndex),
924
+ });
925
+ }
926
+ {
927
+ const signaturePayload: AmazonBedrockReasoningMetadata = {
928
+ signature: reasoningContent.signature,
929
+ };
930
+ controller.enqueue({
931
+ type: 'reasoning-delta',
932
+ id: String(blockIndex),
933
+ delta: '',
934
+ providerMetadata: {
935
+ amazonBedrock: signaturePayload,
936
+ bedrock: signaturePayload,
937
+ },
938
+ });
939
+ }
858
940
  } else if ('data' in reasoningContent && reasoningContent.data) {
859
- controller.enqueue({
860
- type: 'reasoning-delta',
861
- id: String(blockIndex),
862
- delta: '',
863
- providerMetadata: {
864
- bedrock: {
865
- redactedData: reasoningContent.data,
866
- } satisfies BedrockReasoningMetadata,
867
- },
868
- });
941
+ if (contentBlocks[blockIndex] == null) {
942
+ contentBlocks[blockIndex] = { type: 'reasoning' };
943
+ controller.enqueue({
944
+ type: 'reasoning-start',
945
+ id: String(blockIndex),
946
+ });
947
+ }
948
+ {
949
+ const redactedPayload: AmazonBedrockReasoningMetadata = {
950
+ redactedData: reasoningContent.data,
951
+ };
952
+ controller.enqueue({
953
+ type: 'reasoning-delta',
954
+ id: String(blockIndex),
955
+ delta: '',
956
+ providerMetadata: {
957
+ amazonBedrock: redactedPayload,
958
+ bedrock: redactedPayload,
959
+ },
960
+ });
961
+ }
869
962
  }
870
963
  }
871
964
 
@@ -926,30 +1019,25 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
926
1019
  flush(controller) {
927
1020
  // Update provider metadata with isJsonResponseFromTool and stopSequence if needed
928
1021
  if (isJsonResponseFromTool || stopSequence != null) {
929
- if (providerMetadata) {
930
- providerMetadata.bedrock = {
931
- ...providerMetadata.bedrock,
932
- ...(isJsonResponseFromTool && {
933
- isJsonResponseFromTool: true,
934
- }),
935
- stopSequence,
936
- };
937
- } else {
938
- providerMetadata = {
939
- bedrock: {
940
- ...(isJsonResponseFromTool && {
941
- isJsonResponseFromTool: true,
942
- }),
943
- stopSequence,
944
- },
945
- };
946
- }
1022
+ const updatePayload = {
1023
+ ...(providerMetadata?.amazonBedrock ??
1024
+ providerMetadata?.bedrock),
1025
+ ...(isJsonResponseFromTool && {
1026
+ isJsonResponseFromTool: true,
1027
+ }),
1028
+ stopSequence,
1029
+ };
1030
+ providerMetadata = {
1031
+ ...providerMetadata,
1032
+ amazonBedrock: updatePayload,
1033
+ bedrock: updatePayload,
1034
+ };
947
1035
  }
948
1036
 
949
1037
  controller.enqueue({
950
1038
  type: 'finish',
951
1039
  finishReason,
952
- usage: convertBedrockUsage(usage),
1040
+ usage: convertAmazonBedrockUsage(usage),
953
1041
  ...(providerMetadata && { providerMetadata }),
954
1042
  });
955
1043
  },
@@ -966,12 +1054,12 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
966
1054
  }
967
1055
  }
968
1056
 
969
- const BedrockStopReasonSchema = z.union([
1057
+ const AmazonBedrockStopReasonSchema = z.union([
970
1058
  z.enum(BEDROCK_STOP_REASONS),
971
1059
  z.string(),
972
1060
  ]);
973
1061
 
974
- const BedrockAdditionalModelResponseFieldsSchema = z
1062
+ const AmazonBedrockAdditionalModelResponseFieldsSchema = z
975
1063
  .object({
976
1064
  delta: z
977
1065
  .object({
@@ -981,24 +1069,24 @@ const BedrockAdditionalModelResponseFieldsSchema = z
981
1069
  })
982
1070
  .catchall(z.unknown());
983
1071
 
984
- const BedrockToolUseSchema = z.object({
1072
+ const AmazonBedrockToolUseSchema = z.object({
985
1073
  toolUseId: z.string(),
986
1074
  name: z.string(),
987
- input: z.unknown(),
1075
+ input: z.unknown().optional(),
988
1076
  });
989
1077
 
990
- const BedrockReasoningTextSchema = z.object({
1078
+ const AmazonBedrockReasoningTextSchema = z.object({
991
1079
  signature: z.string().nullish(),
992
1080
  text: z.string(),
993
1081
  });
994
1082
 
995
- const BedrockRedactedReasoningSchema = z.object({
1083
+ const AmazonBedrockRedactedReasoningSchema = z.object({
996
1084
  data: z.string(),
997
1085
  });
998
1086
 
999
1087
  // limited version of the schema, focused on what is needed for the implementation
1000
1088
  // this approach limits breakages when the API changes and increases efficiency
1001
- const BedrockResponseSchema = z.object({
1089
+ const AmazonBedrockResponseSchema = z.object({
1002
1090
  metrics: z
1003
1091
  .object({
1004
1092
  latencyMs: z.number(),
@@ -1009,14 +1097,14 @@ const BedrockResponseSchema = z.object({
1009
1097
  content: z.array(
1010
1098
  z.object({
1011
1099
  text: z.string().nullish(),
1012
- toolUse: BedrockToolUseSchema.nullish(),
1100
+ toolUse: AmazonBedrockToolUseSchema.nullish(),
1013
1101
  reasoningContent: z
1014
1102
  .union([
1015
1103
  z.object({
1016
- reasoningText: BedrockReasoningTextSchema,
1104
+ reasoningText: AmazonBedrockReasoningTextSchema,
1017
1105
  }),
1018
1106
  z.object({
1019
- redactedReasoning: BedrockRedactedReasoningSchema,
1107
+ redactedReasoning: AmazonBedrockRedactedReasoningSchema,
1020
1108
  }),
1021
1109
  ])
1022
1110
  .nullish(),
@@ -1025,9 +1113,9 @@ const BedrockResponseSchema = z.object({
1025
1113
  role: z.string(),
1026
1114
  }),
1027
1115
  }),
1028
- stopReason: BedrockStopReasonSchema,
1116
+ stopReason: AmazonBedrockStopReasonSchema,
1029
1117
  additionalModelResponseFields:
1030
- BedrockAdditionalModelResponseFieldsSchema.nullish(),
1118
+ AmazonBedrockAdditionalModelResponseFieldsSchema.nullish(),
1031
1119
  trace: z.unknown().nullish(),
1032
1120
  performanceConfig: z.object({ latency: z.string() }).nullish(),
1033
1121
  serviceTier: z.object({ type: z.string() }).nullish(),
@@ -1045,7 +1133,7 @@ const BedrockResponseSchema = z.object({
1045
1133
 
1046
1134
  // limited version of the schema, focussed on what is needed for the implementation
1047
1135
  // this approach limits breakages when the API changes and increases efficiency
1048
- const BedrockStreamSchema = z.object({
1136
+ const AmazonBedrockStreamSchema = z.object({
1049
1137
  contentBlockDelta: z
1050
1138
  .object({
1051
1139
  contentBlockIndex: z.number(),
@@ -1073,7 +1161,7 @@ const BedrockStreamSchema = z.object({
1073
1161
  contentBlockIndex: z.number(),
1074
1162
  start: z
1075
1163
  .object({
1076
- toolUse: BedrockToolUseSchema.nullish(),
1164
+ toolUse: AmazonBedrockToolUseSchema.nullish(),
1077
1165
  })
1078
1166
  .nullish(),
1079
1167
  })
@@ -1087,8 +1175,8 @@ const BedrockStreamSchema = z.object({
1087
1175
  messageStop: z
1088
1176
  .object({
1089
1177
  additionalModelResponseFields:
1090
- BedrockAdditionalModelResponseFieldsSchema.nullish(),
1091
- stopReason: BedrockStopReasonSchema,
1178
+ AmazonBedrockAdditionalModelResponseFieldsSchema.nullish(),
1179
+ stopReason: AmazonBedrockStopReasonSchema,
1092
1180
  })
1093
1181
  .nullish(),
1094
1182
  metadata: z
@@ -1114,11 +1202,93 @@ const BedrockStreamSchema = z.object({
1114
1202
  validationException: z.record(z.string(), z.unknown()).nullish(),
1115
1203
  });
1116
1204
 
1117
- export const bedrockReasoningMetadataSchema = z.object({
1118
- signature: z.string().optional(),
1119
- redactedData: z.string().optional(),
1120
- });
1205
+ export {
1206
+ amazonBedrockReasoningMetadataSchema,
1207
+ type AmazonBedrockReasoningMetadata,
1208
+ } from './amazon-bedrock-reasoning-metadata';
1209
+
1210
+ const amazonBedrockReasoningEffortMap: Partial<
1211
+ Record<string, 'low' | 'medium' | 'high' | 'max'>
1212
+ > = {
1213
+ minimal: 'low',
1214
+ low: 'low',
1215
+ medium: 'medium',
1216
+ high: 'high',
1217
+ xhigh: 'max',
1218
+ };
1219
+
1220
+ function resolveAmazonBedrockReasoningConfig({
1221
+ reasoning,
1222
+ amazonBedrockOptions,
1223
+ warnings,
1224
+ isAnthropicModel,
1225
+ modelId,
1226
+ }: {
1227
+ reasoning: LanguageModelV4CallOptions['reasoning'];
1228
+ amazonBedrockOptions: AmazonBedrockLanguageModelChatOptions;
1229
+ warnings: SharedV4Warning[];
1230
+ isAnthropicModel: boolean;
1231
+ modelId: string;
1232
+ }): AmazonBedrockLanguageModelChatOptions {
1233
+ if (!isCustomReasoning(reasoning)) {
1234
+ return amazonBedrockOptions;
1235
+ }
1236
+
1237
+ const result = { ...amazonBedrockOptions };
1238
+
1239
+ if (isAnthropicModel) {
1240
+ const capabilities = getModelCapabilities(modelId);
1241
+
1242
+ if (reasoning === 'none') {
1243
+ result.reasoningConfig = { type: 'disabled' };
1244
+ } else if (capabilities.supportsAdaptiveThinking) {
1245
+ const effort = mapReasoningToProviderEffort({
1246
+ reasoning,
1247
+ effortMap: amazonBedrockReasoningEffortMap,
1248
+ warnings,
1249
+ });
1250
+ result.reasoningConfig = {
1251
+ type: 'adaptive',
1252
+ maxReasoningEffort: effort,
1253
+ ...amazonBedrockOptions.reasoningConfig,
1254
+ };
1255
+ } else {
1256
+ const budgetTokens = mapReasoningToProviderBudget({
1257
+ reasoning,
1258
+ maxOutputTokens: capabilities.maxOutputTokens,
1259
+ maxReasoningBudget: capabilities.maxOutputTokens,
1260
+ warnings,
1261
+ });
1262
+ if (budgetTokens != null) {
1263
+ result.reasoningConfig = {
1264
+ type: 'enabled',
1265
+ budgetTokens,
1266
+ ...amazonBedrockOptions.reasoningConfig,
1267
+ };
1268
+ }
1269
+ }
1270
+ } else if (reasoning !== 'none') {
1271
+ const effort = mapReasoningToProviderEffort({
1272
+ reasoning,
1273
+ effortMap: amazonBedrockReasoningEffortMap,
1274
+ warnings,
1275
+ });
1276
+ result.reasoningConfig = {
1277
+ maxReasoningEffort: effort,
1278
+ ...amazonBedrockOptions.reasoningConfig,
1279
+ };
1280
+ }
1121
1281
 
1122
- export type BedrockReasoningMetadata = z.infer<
1123
- typeof bedrockReasoningMetadataSchema
1124
- >;
1282
+ /*
1283
+ * Mirror anthropic-messages-language-model.ts: when the merged type ends up
1284
+ * 'disabled' (user override combined with a non-none reasoning), strip
1285
+ * derived effort/budget so downstream does not emit output_config.effort
1286
+ * alongside disabled thinking.
1287
+ */
1288
+ if (result.reasoningConfig?.type === 'disabled') {
1289
+ delete result.reasoningConfig.maxReasoningEffort;
1290
+ delete result.reasoningConfig.budgetTokens;
1291
+ }
1292
+
1293
+ return result;
1294
+ }