@ai-sdk/amazon-bedrock 5.0.20 → 5.0.22

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.
@@ -35,7 +35,7 @@ var import_provider_utils = require("@ai-sdk/provider-utils");
35
35
  var import_aws4fetch = require("aws4fetch");
36
36
 
37
37
  // src/version.ts
38
- var VERSION = true ? "5.0.20" : "0.0.0-test";
38
+ var VERSION = true ? "5.0.22" : "0.0.0-test";
39
39
 
40
40
  // src/amazon-bedrock-sigv4-fetch.ts
41
41
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
@@ -23,7 +23,7 @@ import {
23
23
  import { AwsV4Signer } from "aws4fetch";
24
24
 
25
25
  // src/version.ts
26
- var VERSION = true ? "5.0.20" : "0.0.0-test";
26
+ var VERSION = true ? "5.0.22" : "0.0.0-test";
27
27
 
28
28
  // src/amazon-bedrock-sigv4-fetch.ts
29
29
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/amazon-bedrock",
3
- "version": "5.0.20",
3
+ "version": "5.0.22",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -44,10 +44,10 @@
44
44
  "@smithy/eventstream-codec": "^4.3.3",
45
45
  "@smithy/util-utf8": "^4.3.3",
46
46
  "aws4fetch": "^1.0.20",
47
- "@ai-sdk/anthropic": "4.0.14",
48
- "@ai-sdk/openai": "4.0.13",
47
+ "@ai-sdk/anthropic": "4.0.15",
48
+ "@ai-sdk/openai": "4.0.14",
49
49
  "@ai-sdk/provider": "4.0.3",
50
- "@ai-sdk/provider-utils": "5.0.9"
50
+ "@ai-sdk/provider-utils": "5.0.10"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "22.19.19",
@@ -16,6 +16,7 @@ import {
16
16
  combineHeaders,
17
17
  createJsonErrorResponseHandler,
18
18
  createJsonResponseHandler,
19
+ injectJsonInstructionIntoMessages,
19
20
  isCustomReasoning,
20
21
  mapReasoningToProviderBudget,
21
22
  mapReasoningToProviderEffort,
@@ -101,6 +102,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
101
102
  }: LanguageModelV4CallOptions): Promise<{
102
103
  command: AmazonBedrockConverseInput;
103
104
  warnings: SharedV4Warning[];
105
+ usesJsonInstruction: boolean;
104
106
  usesJsonResponseTool: boolean;
105
107
  betas: Set<string>;
106
108
  }> {
@@ -188,16 +190,33 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
188
190
  const { supportsStructuredOutput: modelSupportsStructuredOutput } =
189
191
  getModelCapabilities(this.modelId);
190
192
 
193
+ const modelRejectsNativeStructuredOutput =
194
+ this.modelId.includes('claude-opus-4-7') ||
195
+ this.modelId.includes('claude-opus-4-8') ||
196
+ this.modelId.includes('claude-fable-5') ||
197
+ this.modelId.includes('claude-sonnet-5');
198
+
191
199
  const useNativeStructuredOutput =
192
200
  isAnthropicModel &&
201
+ !modelRejectsNativeStructuredOutput &&
193
202
  (modelSupportsStructuredOutput || isThinkingEnabled) &&
194
203
  responseFormat?.type === 'json' &&
195
204
  responseFormat.schema != null;
196
205
 
206
+ const useJsonInstructionForStructuredOutput =
207
+ isAnthropicModel &&
208
+ (this.modelId.includes('claude-opus-4-7') ||
209
+ this.modelId.includes('claude-opus-4-8')) &&
210
+ responseFormat?.type === 'json' &&
211
+ responseFormat.schema != null &&
212
+ tools != null &&
213
+ tools.length > 0;
214
+
197
215
  const jsonResponseTool: LanguageModelV4FunctionTool | undefined =
198
216
  responseFormat?.type === 'json' &&
199
217
  responseFormat.schema != null &&
200
- !useNativeStructuredOutput
218
+ !useNativeStructuredOutput &&
219
+ !useJsonInstructionForStructuredOutput
201
220
  ? {
202
221
  type: 'function',
203
222
  name: 'json',
@@ -409,6 +428,15 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
409
428
  }
410
429
  }
411
430
 
431
+ if (useJsonInstructionForStructuredOutput) {
432
+ filteredPrompt = injectJsonInstructionIntoMessages({
433
+ messages: filteredPrompt,
434
+ schema: responseFormat!.schema,
435
+ schemaSuffix:
436
+ 'You MUST answer with only a JSON object that matches the JSON schema above. Do not wrap it in markdown fences or include any other text.',
437
+ });
438
+ }
439
+
412
440
  const isMistral = isMistralModel(this.modelId);
413
441
  const { system, messages } = await convertToAmazonBedrockChatMessages(
414
442
  filteredPrompt,
@@ -450,6 +478,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
450
478
  : {}),
451
479
  },
452
480
  warnings,
481
+ usesJsonInstruction: useJsonInstructionForStructuredOutput,
453
482
  usesJsonResponseTool: jsonResponseTool != null,
454
483
  betas,
455
484
  };
@@ -476,6 +505,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
476
505
  const {
477
506
  command: args,
478
507
  warnings,
508
+ usesJsonInstruction,
479
509
  usesJsonResponseTool,
480
510
  } = await this.getArgs(options);
481
511
 
@@ -497,12 +527,18 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
497
527
 
498
528
  const content: Array<LanguageModelV4Content> = [];
499
529
  let isJsonResponseFromTool = false;
530
+ const jsonObjectTextExtractor = usesJsonInstruction
531
+ ? new JsonObjectTextExtractor()
532
+ : undefined;
500
533
 
501
534
  // map response content to content array
502
535
  for (const part of response.output.message.content) {
503
536
  // text
504
537
  if (part.text != null) {
505
- content.push({ type: 'text', text: part.text });
538
+ content.push({
539
+ type: 'text',
540
+ text: jsonObjectTextExtractor?.process(part.text) ?? part.text,
541
+ });
506
542
  }
507
543
 
508
544
  // reasoning
@@ -629,6 +665,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
629
665
  headers: responseHeaders,
630
666
  },
631
667
  warnings,
668
+ request: { body: args },
632
669
  ...(providerMetadata && { providerMetadata }),
633
670
  };
634
671
  }
@@ -639,6 +676,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
639
676
  const {
640
677
  command: args,
641
678
  warnings,
679
+ usesJsonInstruction,
642
680
  usesJsonResponseTool,
643
681
  } = await this.getArgs(options);
644
682
  const modelId = this.modelId;
@@ -668,6 +706,9 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
668
706
  let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
669
707
  let isJsonResponseFromTool = false;
670
708
  let stopSequence: string | null = null;
709
+ const jsonObjectTextExtractor = usesJsonInstruction
710
+ ? new JsonObjectTextExtractor()
711
+ : undefined;
671
712
 
672
713
  const contentBlocks: Record<
673
714
  number,
@@ -829,11 +870,18 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
829
870
  });
830
871
  }
831
872
 
832
- controller.enqueue({
833
- type: 'text-delta',
834
- id: String(blockIndex),
835
- delta: value.contentBlockDelta.delta.text,
836
- });
873
+ const textDelta =
874
+ jsonObjectTextExtractor?.process(
875
+ value.contentBlockDelta.delta.text,
876
+ ) ?? value.contentBlockDelta.delta.text;
877
+
878
+ if (textDelta.length > 0) {
879
+ controller.enqueue({
880
+ type: 'text-delta',
881
+ id: String(blockIndex),
882
+ delta: textDelta,
883
+ });
884
+ }
837
885
  }
838
886
 
839
887
  if (value.contentBlockStop?.contentBlockIndex != null) {
@@ -1043,7 +1091,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
1043
1091
  },
1044
1092
  }),
1045
1093
  ),
1046
- // TODO request?
1094
+ request: { body: args },
1047
1095
  response: { headers: responseHeaders },
1048
1096
  };
1049
1097
  }
@@ -1054,6 +1102,68 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
1054
1102
  }
1055
1103
  }
1056
1104
 
1105
+ class JsonObjectTextExtractor {
1106
+ private started = false;
1107
+ private completed = false;
1108
+ private depth = 0;
1109
+ private inString = false;
1110
+ private escaped = false;
1111
+
1112
+ process(text: string): string {
1113
+ let result = '';
1114
+
1115
+ for (const character of text) {
1116
+ if (this.completed) {
1117
+ break;
1118
+ }
1119
+
1120
+ if (!this.started) {
1121
+ if (character !== '{') {
1122
+ continue;
1123
+ }
1124
+
1125
+ this.started = true;
1126
+ this.depth = 1;
1127
+ result += character;
1128
+ continue;
1129
+ }
1130
+
1131
+ result += character;
1132
+
1133
+ if (this.escaped) {
1134
+ this.escaped = false;
1135
+ continue;
1136
+ }
1137
+
1138
+ if (character === '\\' && this.inString) {
1139
+ this.escaped = true;
1140
+ continue;
1141
+ }
1142
+
1143
+ if (character === '"') {
1144
+ this.inString = !this.inString;
1145
+ continue;
1146
+ }
1147
+
1148
+ if (this.inString) {
1149
+ continue;
1150
+ }
1151
+
1152
+ if (character === '{') {
1153
+ this.depth++;
1154
+ } else if (character === '}') {
1155
+ this.depth--;
1156
+
1157
+ if (this.depth === 0) {
1158
+ this.completed = true;
1159
+ }
1160
+ }
1161
+ }
1162
+
1163
+ return result;
1164
+ }
1165
+ }
1166
+
1057
1167
  const AmazonBedrockStopReasonSchema = z.union([
1058
1168
  z.enum(BEDROCK_STOP_REASONS),
1059
1169
  z.string(),