@ai-sdk/amazon-bedrock 5.0.20 → 5.0.21

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
+ ## 5.0.21
4
+
5
+ ### Patch Changes
6
+
7
+ - b0e9d24: Avoid unreliable synthetic response tools when structured output is combined with tools on Bedrock Claude Opus 4.7 and 4.8.
8
+ - Updated dependencies [31c7be8]
9
+ - @ai-sdk/provider-utils@5.0.10
10
+ - @ai-sdk/anthropic@4.0.15
11
+ - @ai-sdk/openai@4.0.14
12
+
3
13
  ## 5.0.20
4
14
 
5
15
  ### Patch Changes
@@ -24,7 +24,7 @@ import {
24
24
  import { AwsV4Signer } from "aws4fetch";
25
25
 
26
26
  // src/version.ts
27
- var VERSION = true ? "5.0.20" : "0.0.0-test";
27
+ var VERSION = true ? "5.0.21" : "0.0.0-test";
28
28
 
29
29
  // src/amazon-bedrock-sigv4-fetch.ts
30
30
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  combineHeaders,
14
14
  createJsonErrorResponseHandler,
15
15
  createJsonResponseHandler,
16
+ injectJsonInstructionIntoMessages,
16
17
  isCustomReasoning,
17
18
  mapReasoningToProviderBudget,
18
19
  mapReasoningToProviderEffort,
@@ -929,8 +930,10 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
929
930
  });
930
931
  const isThinkingEnabled = ((_c = amazonBedrockOptions.reasoningConfig) == null ? void 0 : _c.type) === "enabled" || ((_d = amazonBedrockOptions.reasoningConfig) == null ? void 0 : _d.type) === "adaptive";
931
932
  const { supportsStructuredOutput: modelSupportsStructuredOutput } = getModelCapabilities(this.modelId);
932
- const useNativeStructuredOutput = isAnthropicModel && (modelSupportsStructuredOutput || isThinkingEnabled) && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null;
933
- const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useNativeStructuredOutput ? {
933
+ 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");
934
+ const useNativeStructuredOutput = isAnthropicModel && !modelRejectsNativeStructuredOutput && (modelSupportsStructuredOutput || isThinkingEnabled) && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null;
935
+ 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;
936
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useNativeStructuredOutput && !useJsonInstructionForStructuredOutput ? {
934
937
  type: "function",
935
938
  name: "json",
936
939
  description: "Respond with a JSON object.",
@@ -1094,6 +1097,13 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1094
1097
  });
1095
1098
  }
1096
1099
  }
1100
+ if (useJsonInstructionForStructuredOutput) {
1101
+ filteredPrompt = injectJsonInstructionIntoMessages({
1102
+ messages: filteredPrompt,
1103
+ schema: responseFormat.schema,
1104
+ 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."
1105
+ });
1106
+ }
1097
1107
  const isMistral = isMistralModel(this.modelId);
1098
1108
  const { system, messages } = await convertToAmazonBedrockChatMessages(
1099
1109
  filteredPrompt,
@@ -1126,6 +1136,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1126
1136
  ...toolConfig.tools !== void 0 && toolConfig.tools.length > 0 ? { toolConfig } : {}
1127
1137
  },
1128
1138
  warnings,
1139
+ usesJsonInstruction: useJsonInstructionForStructuredOutput,
1129
1140
  usesJsonResponseTool: jsonResponseTool != null,
1130
1141
  betas
1131
1142
  };
@@ -1139,10 +1150,11 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1139
1150
  );
1140
1151
  }
1141
1152
  async doGenerate(options) {
1142
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1153
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1143
1154
  const {
1144
1155
  command: args,
1145
1156
  warnings,
1157
+ usesJsonInstruction,
1146
1158
  usesJsonResponseTool
1147
1159
  } = await this.getArgs(options);
1148
1160
  const url = `${this.getUrl(this.modelId)}/converse`;
@@ -1165,9 +1177,13 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1165
1177
  });
1166
1178
  const content = [];
1167
1179
  let isJsonResponseFromTool = false;
1180
+ const jsonObjectTextExtractor = usesJsonInstruction ? new JsonObjectTextExtractor() : void 0;
1168
1181
  for (const part of response.output.message.content) {
1169
1182
  if (part.text != null) {
1170
- content.push({ type: "text", text: part.text });
1183
+ content.push({
1184
+ type: "text",
1185
+ text: (_a = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(part.text)) != null ? _a : part.text
1186
+ });
1171
1187
  }
1172
1188
  if (part.reasoningContent) {
1173
1189
  if ("reasoningText" in part.reasoningContent) {
@@ -1187,7 +1203,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1187
1203
  content.push(reasoning);
1188
1204
  } else if ("redactedReasoning" in part.reasoningContent) {
1189
1205
  const redactedPayload = {
1190
- redactedData: (_a = part.reasoningContent.redactedReasoning.data) != null ? _a : ""
1206
+ redactedData: (_b = part.reasoningContent.redactedReasoning.data) != null ? _b : ""
1191
1207
  };
1192
1208
  content.push({
1193
1209
  type: "reasoning",
@@ -1209,17 +1225,17 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1209
1225
  });
1210
1226
  } else {
1211
1227
  const isMistral = isMistralModel(this.modelId);
1212
- const rawToolCallId = (_c = (_b = part.toolUse) == null ? void 0 : _b.toolUseId) != null ? _c : this.config.generateId();
1228
+ const rawToolCallId = (_d = (_c = part.toolUse) == null ? void 0 : _c.toolUseId) != null ? _d : this.config.generateId();
1213
1229
  content.push({
1214
1230
  type: "tool-call",
1215
1231
  toolCallId: normalizeToolCallId(rawToolCallId, isMistral),
1216
- toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
1217
- input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : {})
1232
+ toolName: (_f = (_e = part.toolUse) == null ? void 0 : _e.name) != null ? _f : `tool-${this.config.generateId()}`,
1233
+ input: JSON.stringify((_h = (_g = part.toolUse) == null ? void 0 : _g.input) != null ? _h : {})
1218
1234
  });
1219
1235
  }
1220
1236
  }
1221
1237
  }
1222
- const stopSequence = (_j = (_i = (_h = response.additionalModelResponseFields) == null ? void 0 : _h.delta) == null ? void 0 : _i.stop_sequence) != null ? _j : null;
1238
+ const stopSequence = (_k = (_j = (_i = response.additionalModelResponseFields) == null ? void 0 : _i.delta) == null ? void 0 : _j.stop_sequence) != null ? _k : null;
1223
1239
  const providerMetadataPayload = response.trace || response.usage || response.performanceConfig || response.serviceTier || isJsonResponseFromTool || stopSequence ? {
1224
1240
  ...response.trace && typeof response.trace === "object" ? { trace: response.trace } : {},
1225
1241
  ...response.performanceConfig && {
@@ -1228,7 +1244,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1228
1244
  ...response.serviceTier && {
1229
1245
  serviceTier: response.serviceTier
1230
1246
  },
1231
- ...(((_k = response.usage) == null ? void 0 : _k.cacheWriteInputTokens) != null || ((_l = response.usage) == null ? void 0 : _l.cacheDetails) != null) && {
1247
+ ...(((_l = response.usage) == null ? void 0 : _l.cacheWriteInputTokens) != null || ((_m = response.usage) == null ? void 0 : _m.cacheDetails) != null) && {
1232
1248
  usage: {
1233
1249
  ...response.usage.cacheWriteInputTokens != null && {
1234
1250
  cacheWriteInputTokens: response.usage.cacheWriteInputTokens
@@ -1252,11 +1268,11 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1252
1268
  response.stopReason,
1253
1269
  isJsonResponseFromTool
1254
1270
  ),
1255
- raw: (_m = response.stopReason) != null ? _m : void 0
1271
+ raw: (_n = response.stopReason) != null ? _n : void 0
1256
1272
  },
1257
1273
  usage: convertAmazonBedrockUsage(response.usage),
1258
1274
  response: {
1259
- id: (_n = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _n : void 0,
1275
+ id: (_o = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _o : void 0,
1260
1276
  timestamp: (responseHeaders == null ? void 0 : responseHeaders["date"]) != null ? new Date(responseHeaders["date"]) : void 0,
1261
1277
  modelId: this.modelId,
1262
1278
  headers: responseHeaders
@@ -1269,6 +1285,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1269
1285
  const {
1270
1286
  command: args,
1271
1287
  warnings,
1288
+ usesJsonInstruction,
1272
1289
  usesJsonResponseTool
1273
1290
  } = await this.getArgs(options);
1274
1291
  const modelId = this.modelId;
@@ -1296,6 +1313,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1296
1313
  let providerMetadata = void 0;
1297
1314
  let isJsonResponseFromTool = false;
1298
1315
  let stopSequence = null;
1316
+ const jsonObjectTextExtractor = usesJsonInstruction ? new JsonObjectTextExtractor() : void 0;
1299
1317
  const contentBlocks = {};
1300
1318
  return {
1301
1319
  stream: response.pipeThrough(
@@ -1311,7 +1329,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1311
1329
  });
1312
1330
  },
1313
1331
  transform(chunk, controller) {
1314
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
1332
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
1315
1333
  function enqueueError(amazonBedrockError) {
1316
1334
  finishReason = { unified: "error", raw: void 0 };
1317
1335
  controller.enqueue({ type: "error", error: amazonBedrockError });
@@ -1401,13 +1419,18 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1401
1419
  id: String(blockIndex)
1402
1420
  });
1403
1421
  }
1404
- controller.enqueue({
1405
- type: "text-delta",
1406
- id: String(blockIndex),
1407
- delta: value.contentBlockDelta.delta.text
1408
- });
1422
+ const textDelta = (_m = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(
1423
+ value.contentBlockDelta.delta.text
1424
+ )) != null ? _m : value.contentBlockDelta.delta.text;
1425
+ if (textDelta.length > 0) {
1426
+ controller.enqueue({
1427
+ type: "text-delta",
1428
+ id: String(blockIndex),
1429
+ delta: textDelta
1430
+ });
1431
+ }
1409
1432
  }
1410
- if (((_m = value.contentBlockStop) == null ? void 0 : _m.contentBlockIndex) != null) {
1433
+ if (((_n = value.contentBlockStop) == null ? void 0 : _n.contentBlockIndex) != null) {
1411
1434
  const blockIndex = value.contentBlockStop.contentBlockIndex;
1412
1435
  const contentBlock = contentBlocks[blockIndex];
1413
1436
  if (contentBlock != null) {
@@ -1453,7 +1476,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1453
1476
  delete contentBlocks[blockIndex];
1454
1477
  }
1455
1478
  }
1456
- if (((_n = value.contentBlockDelta) == null ? void 0 : _n.delta) && "reasoningContent" in value.contentBlockDelta.delta && value.contentBlockDelta.delta.reasoningContent) {
1479
+ if (((_o = value.contentBlockDelta) == null ? void 0 : _o.delta) && "reasoningContent" in value.contentBlockDelta.delta && value.contentBlockDelta.delta.reasoningContent) {
1457
1480
  const blockIndex = value.contentBlockDelta.contentBlockIndex || 0;
1458
1481
  const reasoningContent = value.contentBlockDelta.delta.reasoningContent;
1459
1482
  if ("text" in reasoningContent && reasoningContent.text) {
@@ -1516,7 +1539,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1516
1539
  }
1517
1540
  }
1518
1541
  const contentBlockStart = value.contentBlockStart;
1519
- if (((_o = contentBlockStart == null ? void 0 : contentBlockStart.start) == null ? void 0 : _o.toolUse) != null) {
1542
+ if (((_p = contentBlockStart == null ? void 0 : contentBlockStart.start) == null ? void 0 : _p.toolUse) != null) {
1520
1543
  const toolUse = contentBlockStart.start.toolUse;
1521
1544
  const blockIndex = contentBlockStart.contentBlockIndex;
1522
1545
  const isJsonResponseTool = usesJsonResponseTool && toolUse.name === "json";
@@ -1544,7 +1567,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1544
1567
  const blockIndex = contentBlockDelta.contentBlockIndex;
1545
1568
  const contentBlock = contentBlocks[blockIndex];
1546
1569
  if ((contentBlock == null ? void 0 : contentBlock.type) === "tool-call") {
1547
- const delta = (_p = contentBlockDelta.delta.toolUse.input) != null ? _p : "";
1570
+ const delta = (_q = contentBlockDelta.delta.toolUse.input) != null ? _q : "";
1548
1571
  if (!contentBlock.isJsonResponseTool) {
1549
1572
  controller.enqueue({
1550
1573
  type: "tool-input-delta",
@@ -1590,6 +1613,57 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1590
1613
  return `${this.config.baseUrl()}/model/${encodedModelId}`;
1591
1614
  }
1592
1615
  };
1616
+ var JsonObjectTextExtractor = class {
1617
+ constructor() {
1618
+ this.started = false;
1619
+ this.completed = false;
1620
+ this.depth = 0;
1621
+ this.inString = false;
1622
+ this.escaped = false;
1623
+ }
1624
+ process(text) {
1625
+ let result = "";
1626
+ for (const character of text) {
1627
+ if (this.completed) {
1628
+ break;
1629
+ }
1630
+ if (!this.started) {
1631
+ if (character !== "{") {
1632
+ continue;
1633
+ }
1634
+ this.started = true;
1635
+ this.depth = 1;
1636
+ result += character;
1637
+ continue;
1638
+ }
1639
+ result += character;
1640
+ if (this.escaped) {
1641
+ this.escaped = false;
1642
+ continue;
1643
+ }
1644
+ if (character === "\\" && this.inString) {
1645
+ this.escaped = true;
1646
+ continue;
1647
+ }
1648
+ if (character === '"') {
1649
+ this.inString = !this.inString;
1650
+ continue;
1651
+ }
1652
+ if (this.inString) {
1653
+ continue;
1654
+ }
1655
+ if (character === "{") {
1656
+ this.depth++;
1657
+ } else if (character === "}") {
1658
+ this.depth--;
1659
+ if (this.depth === 0) {
1660
+ this.completed = true;
1661
+ }
1662
+ }
1663
+ }
1664
+ return result;
1665
+ }
1666
+ };
1593
1667
  var AmazonBedrockStopReasonSchema = z4.union([
1594
1668
  z4.enum(BEDROCK_STOP_REASONS),
1595
1669
  z4.string()
@@ -2269,7 +2343,7 @@ import {
2269
2343
  import { AwsV4Signer } from "aws4fetch";
2270
2344
 
2271
2345
  // src/version.ts
2272
- var VERSION = true ? "5.0.20" : "0.0.0-test";
2346
+ var VERSION = true ? "5.0.21" : "0.0.0-test";
2273
2347
 
2274
2348
  // src/amazon-bedrock-sigv4-fetch.ts
2275
2349
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {