@ai-sdk/amazon-bedrock 4.0.134 → 4.0.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @ai-sdk/amazon-bedrock
2
2
 
3
+ ## 4.0.135
4
+
5
+ ### Patch Changes
6
+
7
+ - 7c05582: Avoid unreliable synthetic response tools when structured output is combined with tools on Bedrock Claude Opus 4.7 and 4.8.
8
+ - Updated dependencies [06fb54c]
9
+ - @ai-sdk/provider-utils@4.0.39
10
+ - @ai-sdk/anthropic@3.0.97
11
+ - @ai-sdk/openai@3.0.85
12
+
3
13
  ## 4.0.134
4
14
 
5
15
  ### Patch Changes
@@ -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 ? "4.0.134" : "0.0.0-test";
38
+ var VERSION = true ? "4.0.135" : "0.0.0-test";
39
39
 
40
40
  // src/bedrock-sigv4-fetch.ts
41
41
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
@@ -24,7 +24,7 @@ import {
24
24
  import { AwsV4Signer } from "aws4fetch";
25
25
 
26
26
  // src/version.ts
27
- var VERSION = true ? "4.0.134" : "0.0.0-test";
27
+ var VERSION = true ? "4.0.135" : "0.0.0-test";
28
28
 
29
29
  // src/bedrock-sigv4-fetch.ts
30
30
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
package/dist/index.js CHANGED
@@ -865,8 +865,11 @@ var BedrockChatLanguageModel = class {
865
865
  }
866
866
  const isAnthropicModel = this.modelId.includes("anthropic");
867
867
  const isThinkingEnabled = ((_b = bedrockOptions.reasoningConfig) == null ? void 0 : _b.type) === "enabled" || ((_c = bedrockOptions.reasoningConfig) == null ? void 0 : _c.type) === "adaptive";
868
- const useNativeStructuredOutput = isAnthropicModel && isThinkingEnabled && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null;
869
- const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useNativeStructuredOutput ? {
868
+ const modelRejectsNativeStructuredOutput = this.modelId.includes("claude-opus-4-7") || this.modelId.includes("claude-opus-4-8") || this.modelId.includes("claude-fable-5") || this.modelId.includes("claude-sonnet-5");
869
+ const modelSupportsStructuredOutput = bedrockChatModelSupportsStructuredOutput(this.modelId);
870
+ const useNativeStructuredOutput = isAnthropicModel && !modelRejectsNativeStructuredOutput && (modelSupportsStructuredOutput || isThinkingEnabled) && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null;
871
+ const useJsonInstructionForStructuredOutput = isAnthropicModel && (this.modelId.includes("claude-opus-4-7") || this.modelId.includes("claude-opus-4-8")) && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && tools != null && tools.length > 0;
872
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useNativeStructuredOutput && !useJsonInstructionForStructuredOutput ? {
870
873
  type: "function",
871
874
  name: "json",
872
875
  description: "Respond with a JSON object.",
@@ -1031,6 +1034,13 @@ var BedrockChatLanguageModel = class {
1031
1034
  });
1032
1035
  }
1033
1036
  }
1037
+ if (useJsonInstructionForStructuredOutput) {
1038
+ filteredPrompt = (0, import_provider_utils4.injectJsonInstructionIntoMessages)({
1039
+ messages: filteredPrompt,
1040
+ schema: responseFormat.schema,
1041
+ schemaSuffix: "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."
1042
+ });
1043
+ }
1034
1044
  const isMistral = isMistralModel(this.modelId);
1035
1045
  const { system, messages } = await convertToBedrockChatMessages(
1036
1046
  filteredPrompt,
@@ -1063,6 +1073,7 @@ var BedrockChatLanguageModel = class {
1063
1073
  ...toolConfig.tools !== void 0 && toolConfig.tools.length > 0 ? { toolConfig } : {}
1064
1074
  },
1065
1075
  warnings,
1076
+ usesJsonInstruction: useJsonInstructionForStructuredOutput,
1066
1077
  usesJsonResponseTool: jsonResponseTool != null,
1067
1078
  betas
1068
1079
  };
@@ -1073,10 +1084,11 @@ var BedrockChatLanguageModel = class {
1073
1084
  return (0, import_provider_utils4.combineHeaders)(await (0, import_provider_utils4.resolve)(this.config.headers), headers);
1074
1085
  }
1075
1086
  async doGenerate(options) {
1076
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1087
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1077
1088
  const {
1078
1089
  command: args,
1079
1090
  warnings,
1091
+ usesJsonInstruction,
1080
1092
  usesJsonResponseTool
1081
1093
  } = await this.getArgs(options);
1082
1094
  const url = `${this.getUrl(this.modelId)}/converse`;
@@ -1099,9 +1111,13 @@ var BedrockChatLanguageModel = class {
1099
1111
  });
1100
1112
  const content = [];
1101
1113
  let isJsonResponseFromTool = false;
1114
+ const jsonObjectTextExtractor = usesJsonInstruction ? new JsonObjectTextExtractor() : void 0;
1102
1115
  for (const part of response.output.message.content) {
1103
1116
  if (part.text != null) {
1104
- content.push({ type: "text", text: part.text });
1117
+ content.push({
1118
+ type: "text",
1119
+ text: (_a = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(part.text)) != null ? _a : part.text
1120
+ });
1105
1121
  }
1106
1122
  if (part.reasoningContent) {
1107
1123
  if ("reasoningText" in part.reasoningContent) {
@@ -1123,7 +1139,7 @@ var BedrockChatLanguageModel = class {
1123
1139
  text: "",
1124
1140
  providerMetadata: {
1125
1141
  bedrock: {
1126
- redactedData: (_a = part.reasoningContent.redactedReasoning.data) != null ? _a : ""
1142
+ redactedData: (_b = part.reasoningContent.redactedReasoning.data) != null ? _b : ""
1127
1143
  }
1128
1144
  }
1129
1145
  });
@@ -1139,17 +1155,17 @@ var BedrockChatLanguageModel = class {
1139
1155
  });
1140
1156
  } else {
1141
1157
  const isMistral = isMistralModel(this.modelId);
1142
- const rawToolCallId = (_c = (_b = part.toolUse) == null ? void 0 : _b.toolUseId) != null ? _c : this.config.generateId();
1158
+ const rawToolCallId = (_d = (_c = part.toolUse) == null ? void 0 : _c.toolUseId) != null ? _d : this.config.generateId();
1143
1159
  content.push({
1144
1160
  type: "tool-call",
1145
1161
  toolCallId: normalizeToolCallId(rawToolCallId, isMistral),
1146
- toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
1147
- input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : {})
1162
+ toolName: (_f = (_e = part.toolUse) == null ? void 0 : _e.name) != null ? _f : `tool-${this.config.generateId()}`,
1163
+ input: JSON.stringify((_h = (_g = part.toolUse) == null ? void 0 : _g.input) != null ? _h : {})
1148
1164
  });
1149
1165
  }
1150
1166
  }
1151
1167
  }
1152
- const stopSequence = (_j = (_i = (_h = response.additionalModelResponseFields) == null ? void 0 : _h.delta) == null ? void 0 : _i.stop_sequence) != null ? _j : null;
1168
+ const stopSequence = (_k = (_j = (_i = response.additionalModelResponseFields) == null ? void 0 : _i.delta) == null ? void 0 : _j.stop_sequence) != null ? _k : null;
1153
1169
  const providerMetadata = response.trace || response.usage || response.performanceConfig || response.serviceTier || isJsonResponseFromTool || stopSequence ? {
1154
1170
  bedrock: {
1155
1171
  ...response.trace && typeof response.trace === "object" ? { trace: response.trace } : {},
@@ -1159,7 +1175,7 @@ var BedrockChatLanguageModel = class {
1159
1175
  ...response.serviceTier && {
1160
1176
  serviceTier: response.serviceTier
1161
1177
  },
1162
- ...(((_k = response.usage) == null ? void 0 : _k.cacheWriteInputTokens) != null || ((_l = response.usage) == null ? void 0 : _l.cacheDetails) != null) && {
1178
+ ...(((_l = response.usage) == null ? void 0 : _l.cacheWriteInputTokens) != null || ((_m = response.usage) == null ? void 0 : _m.cacheDetails) != null) && {
1163
1179
  usage: {
1164
1180
  ...response.usage.cacheWriteInputTokens != null && {
1165
1181
  cacheWriteInputTokens: response.usage.cacheWriteInputTokens
@@ -1180,11 +1196,11 @@ var BedrockChatLanguageModel = class {
1180
1196
  response.stopReason,
1181
1197
  isJsonResponseFromTool
1182
1198
  ),
1183
- raw: (_m = response.stopReason) != null ? _m : void 0
1199
+ raw: (_n = response.stopReason) != null ? _n : void 0
1184
1200
  },
1185
1201
  usage: convertBedrockUsage(response.usage),
1186
1202
  response: {
1187
- id: (_n = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _n : void 0,
1203
+ id: (_o = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _o : void 0,
1188
1204
  timestamp: (responseHeaders == null ? void 0 : responseHeaders["date"]) != null ? new Date(responseHeaders["date"]) : void 0,
1189
1205
  modelId: this.modelId,
1190
1206
  headers: responseHeaders
@@ -1197,6 +1213,7 @@ var BedrockChatLanguageModel = class {
1197
1213
  const {
1198
1214
  command: args,
1199
1215
  warnings,
1216
+ usesJsonInstruction,
1200
1217
  usesJsonResponseTool
1201
1218
  } = await this.getArgs(options);
1202
1219
  const modelId = this.modelId;
@@ -1222,6 +1239,7 @@ var BedrockChatLanguageModel = class {
1222
1239
  let providerMetadata = void 0;
1223
1240
  let isJsonResponseFromTool = false;
1224
1241
  let stopSequence = null;
1242
+ const jsonObjectTextExtractor = usesJsonInstruction ? new JsonObjectTextExtractor() : void 0;
1225
1243
  const contentBlocks = {};
1226
1244
  return {
1227
1245
  stream: response.pipeThrough(
@@ -1237,7 +1255,7 @@ var BedrockChatLanguageModel = class {
1237
1255
  });
1238
1256
  },
1239
1257
  transform(chunk, controller) {
1240
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
1258
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
1241
1259
  function enqueueError(bedrockError) {
1242
1260
  finishReason = { unified: "error", raw: void 0 };
1243
1261
  controller.enqueue({ type: "error", error: bedrockError });
@@ -1325,13 +1343,18 @@ var BedrockChatLanguageModel = class {
1325
1343
  id: String(blockIndex)
1326
1344
  });
1327
1345
  }
1328
- controller.enqueue({
1329
- type: "text-delta",
1330
- id: String(blockIndex),
1331
- delta: value.contentBlockDelta.delta.text
1332
- });
1346
+ const textDelta = (_m = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(
1347
+ value.contentBlockDelta.delta.text
1348
+ )) != null ? _m : value.contentBlockDelta.delta.text;
1349
+ if (textDelta.length > 0) {
1350
+ controller.enqueue({
1351
+ type: "text-delta",
1352
+ id: String(blockIndex),
1353
+ delta: textDelta
1354
+ });
1355
+ }
1333
1356
  }
1334
- if (((_m = value.contentBlockStop) == null ? void 0 : _m.contentBlockIndex) != null) {
1357
+ if (((_n = value.contentBlockStop) == null ? void 0 : _n.contentBlockIndex) != null) {
1335
1358
  const blockIndex = value.contentBlockStop.contentBlockIndex;
1336
1359
  const contentBlock = contentBlocks[blockIndex];
1337
1360
  if (contentBlock != null) {
@@ -1377,7 +1400,7 @@ var BedrockChatLanguageModel = class {
1377
1400
  delete contentBlocks[blockIndex];
1378
1401
  }
1379
1402
  }
1380
- if (((_n = value.contentBlockDelta) == null ? void 0 : _n.delta) && "reasoningContent" in value.contentBlockDelta.delta && value.contentBlockDelta.delta.reasoningContent) {
1403
+ if (((_o = value.contentBlockDelta) == null ? void 0 : _o.delta) && "reasoningContent" in value.contentBlockDelta.delta && value.contentBlockDelta.delta.reasoningContent) {
1381
1404
  const blockIndex = value.contentBlockDelta.contentBlockIndex || 0;
1382
1405
  const reasoningContent = value.contentBlockDelta.delta.reasoningContent;
1383
1406
  if ("text" in reasoningContent && reasoningContent.text) {
@@ -1432,7 +1455,7 @@ var BedrockChatLanguageModel = class {
1432
1455
  }
1433
1456
  }
1434
1457
  const contentBlockStart = value.contentBlockStart;
1435
- if (((_o = contentBlockStart == null ? void 0 : contentBlockStart.start) == null ? void 0 : _o.toolUse) != null) {
1458
+ if (((_p = contentBlockStart == null ? void 0 : contentBlockStart.start) == null ? void 0 : _p.toolUse) != null) {
1436
1459
  const toolUse = contentBlockStart.start.toolUse;
1437
1460
  const blockIndex = contentBlockStart.contentBlockIndex;
1438
1461
  const isJsonResponseTool = usesJsonResponseTool && toolUse.name === "json";
@@ -1460,7 +1483,7 @@ var BedrockChatLanguageModel = class {
1460
1483
  const blockIndex = contentBlockDelta.contentBlockIndex;
1461
1484
  const contentBlock = contentBlocks[blockIndex];
1462
1485
  if ((contentBlock == null ? void 0 : contentBlock.type) === "tool-call") {
1463
- const delta = (_p = contentBlockDelta.delta.toolUse.input) != null ? _p : "";
1486
+ const delta = (_q = contentBlockDelta.delta.toolUse.input) != null ? _q : "";
1464
1487
  if (!contentBlock.isJsonResponseTool) {
1465
1488
  controller.enqueue({
1466
1489
  type: "tool-input-delta",
@@ -1511,6 +1534,60 @@ var BedrockChatLanguageModel = class {
1511
1534
  return `${this.config.baseUrl()}/model/${encodedModelId}`;
1512
1535
  }
1513
1536
  };
1537
+ function bedrockChatModelSupportsStructuredOutput(modelId) {
1538
+ return modelId.includes("claude-opus-4-8") || modelId.includes("claude-opus-4-7") || modelId.includes("claude-fable-5") || modelId.includes("claude-sonnet-5") || modelId.includes("claude-sonnet-4-6") || modelId.includes("claude-opus-4-6") || modelId.includes("claude-sonnet-4-5") || modelId.includes("claude-opus-4-5") || modelId.includes("claude-haiku-4-5") || modelId.includes("claude-opus-4-1");
1539
+ }
1540
+ var JsonObjectTextExtractor = class {
1541
+ constructor() {
1542
+ this.started = false;
1543
+ this.completed = false;
1544
+ this.depth = 0;
1545
+ this.inString = false;
1546
+ this.escaped = false;
1547
+ }
1548
+ process(text) {
1549
+ let result = "";
1550
+ for (const character of text) {
1551
+ if (this.completed) {
1552
+ break;
1553
+ }
1554
+ if (!this.started) {
1555
+ if (character !== "{") {
1556
+ continue;
1557
+ }
1558
+ this.started = true;
1559
+ this.depth = 1;
1560
+ result += character;
1561
+ continue;
1562
+ }
1563
+ result += character;
1564
+ if (this.escaped) {
1565
+ this.escaped = false;
1566
+ continue;
1567
+ }
1568
+ if (character === "\\" && this.inString) {
1569
+ this.escaped = true;
1570
+ continue;
1571
+ }
1572
+ if (character === '"') {
1573
+ this.inString = !this.inString;
1574
+ continue;
1575
+ }
1576
+ if (this.inString) {
1577
+ continue;
1578
+ }
1579
+ if (character === "{") {
1580
+ this.depth++;
1581
+ } else if (character === "}") {
1582
+ this.depth--;
1583
+ if (this.depth === 0) {
1584
+ this.completed = true;
1585
+ }
1586
+ }
1587
+ }
1588
+ return result;
1589
+ }
1590
+ };
1514
1591
  var BedrockStopReasonSchema = import_v44.z.union([
1515
1592
  import_v44.z.enum(BEDROCK_STOP_REASONS),
1516
1593
  import_v44.z.string()
@@ -2023,7 +2100,7 @@ var import_provider_utils7 = require("@ai-sdk/provider-utils");
2023
2100
  var import_aws4fetch = require("aws4fetch");
2024
2101
 
2025
2102
  // src/version.ts
2026
- var VERSION = true ? "4.0.134" : "0.0.0-test";
2103
+ var VERSION = true ? "4.0.135" : "0.0.0-test";
2027
2104
 
2028
2105
  // src/bedrock-sigv4-fetch.ts
2029
2106
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {