@ai-sdk/amazon-bedrock 3.0.56 → 3.0.57
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 +25 -0
- package/dist/index.js +57 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +57 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @ai-sdk/amazon-bedrock
|
|
2
2
|
|
|
3
|
+
## 3.0.57
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 708df55: feat(provider/amazon-bedrock,provider/google-vertex-anthropic): add support for tool calling with structured output
|
|
8
|
+
|
|
9
|
+
Added support for combining tool calling with structured outputs in both Amazon Bedrock and Google Vertex Anthropic providers. This allows developers to use tools (like weather lookups, web search, etc.) alongside structured JSON output schemas, enabling multi-step agentic workflows with structured final outputs.
|
|
10
|
+
|
|
11
|
+
**Amazon Bedrock Changes:**
|
|
12
|
+
|
|
13
|
+
- Removed incorrect warning that prevented using tools with JSON response format
|
|
14
|
+
- Updated tool choice to use `{ type: 'required' }` instead of specific tool selection when using structured outputs
|
|
15
|
+
- Added `isJsonResponseFromTool` parameter to finish reason mapping
|
|
16
|
+
- JSON tool responses are correctly converted to text content and finish reason is mapped from `tool_use` to `stop`
|
|
17
|
+
- Added comprehensive test coverage for combining tools with structured outputs
|
|
18
|
+
- Added example files demonstrating the feature
|
|
19
|
+
|
|
20
|
+
**Google Vertex Anthropic Changes:**
|
|
21
|
+
|
|
22
|
+
- Inherits support from underlying Anthropic provider implementation
|
|
23
|
+
- Added test coverage to verify the feature works correctly
|
|
24
|
+
- Added example files demonstrating the feature
|
|
25
|
+
|
|
26
|
+
This brings Anthropic provider's structured output capabilities to the Amazon Bedrock and Google Vertex Anthropic providers.
|
|
27
|
+
|
|
3
28
|
## 3.0.56
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
30
30
|
var import_provider_utils8 = require("@ai-sdk/provider-utils");
|
|
31
31
|
|
|
32
32
|
// src/version.ts
|
|
33
|
-
var VERSION = true ? "3.0.
|
|
33
|
+
var VERSION = true ? "3.0.57" : "0.0.0-test";
|
|
34
34
|
|
|
35
35
|
// src/bedrock-provider.ts
|
|
36
36
|
var import_internal2 = require("@ai-sdk/anthropic/internal");
|
|
@@ -649,7 +649,7 @@ function groupIntoBlocks(prompt) {
|
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
// src/map-bedrock-finish-reason.ts
|
|
652
|
-
function mapBedrockFinishReason(finishReason) {
|
|
652
|
+
function mapBedrockFinishReason(finishReason, isJsonResponseFromTool) {
|
|
653
653
|
switch (finishReason) {
|
|
654
654
|
case "stop_sequence":
|
|
655
655
|
case "end_turn":
|
|
@@ -660,7 +660,7 @@ function mapBedrockFinishReason(finishReason) {
|
|
|
660
660
|
case "guardrail_intervened":
|
|
661
661
|
return "content-filter";
|
|
662
662
|
case "tool_use":
|
|
663
|
-
return "tool-calls";
|
|
663
|
+
return isJsonResponseFromTool ? "stop" : "tool-calls";
|
|
664
664
|
default:
|
|
665
665
|
return "unknown";
|
|
666
666
|
}
|
|
@@ -739,14 +739,6 @@ var BedrockChatLanguageModel = class {
|
|
|
739
739
|
details: "Only text and json response formats are supported."
|
|
740
740
|
});
|
|
741
741
|
}
|
|
742
|
-
if (tools != null && (responseFormat == null ? void 0 : responseFormat.type) === "json") {
|
|
743
|
-
if (tools.length > 0) {
|
|
744
|
-
warnings.push({
|
|
745
|
-
type: "other",
|
|
746
|
-
message: "JSON response format does not support tools. The provided tools are ignored."
|
|
747
|
-
});
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
742
|
const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
|
|
751
743
|
type: "function",
|
|
752
744
|
name: "json",
|
|
@@ -754,8 +746,8 @@ var BedrockChatLanguageModel = class {
|
|
|
754
746
|
inputSchema: responseFormat.schema
|
|
755
747
|
} : void 0;
|
|
756
748
|
const { toolConfig, additionalTools, toolWarnings, betas } = await prepareTools({
|
|
757
|
-
tools: jsonResponseTool ? [
|
|
758
|
-
toolChoice: jsonResponseTool != null ? { type: "
|
|
749
|
+
tools: jsonResponseTool ? [...tools != null ? tools : [], jsonResponseTool] : tools,
|
|
750
|
+
toolChoice: jsonResponseTool != null ? { type: "required" } : toolChoice,
|
|
759
751
|
modelId: this.modelId
|
|
760
752
|
});
|
|
761
753
|
warnings.push(...toolWarnings);
|
|
@@ -899,11 +891,10 @@ var BedrockChatLanguageModel = class {
|
|
|
899
891
|
fetch: this.config.fetch
|
|
900
892
|
});
|
|
901
893
|
const content = [];
|
|
894
|
+
let isJsonResponseFromTool = false;
|
|
902
895
|
for (const part of response.output.message.content) {
|
|
903
896
|
if (part.text) {
|
|
904
|
-
|
|
905
|
-
content.push({ type: "text", text: part.text });
|
|
906
|
-
}
|
|
897
|
+
content.push({ type: "text", text: part.text });
|
|
907
898
|
}
|
|
908
899
|
if (part.reasoningContent) {
|
|
909
900
|
if ("reasoningText" in part.reasoningContent) {
|
|
@@ -932,21 +923,24 @@ var BedrockChatLanguageModel = class {
|
|
|
932
923
|
}
|
|
933
924
|
}
|
|
934
925
|
if (part.toolUse) {
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
926
|
+
const isJsonResponseTool = usesJsonResponseTool && part.toolUse.name === "json";
|
|
927
|
+
if (isJsonResponseTool) {
|
|
928
|
+
isJsonResponseFromTool = true;
|
|
929
|
+
content.push({
|
|
938
930
|
type: "text",
|
|
939
931
|
text: JSON.stringify(part.toolUse.input)
|
|
940
|
-
}
|
|
932
|
+
});
|
|
933
|
+
} else {
|
|
934
|
+
content.push({
|
|
941
935
|
type: "tool-call",
|
|
942
936
|
toolCallId: (_c = (_b = part.toolUse) == null ? void 0 : _b.toolUseId) != null ? _c : this.config.generateId(),
|
|
943
937
|
toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
|
|
944
938
|
input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : "")
|
|
945
|
-
}
|
|
946
|
-
|
|
939
|
+
});
|
|
940
|
+
}
|
|
947
941
|
}
|
|
948
942
|
}
|
|
949
|
-
const providerMetadata = response.trace || response.usage ||
|
|
943
|
+
const providerMetadata = response.trace || response.usage || isJsonResponseFromTool ? {
|
|
950
944
|
bedrock: {
|
|
951
945
|
...response.trace && typeof response.trace === "object" ? { trace: response.trace } : {},
|
|
952
946
|
...((_h = response.usage) == null ? void 0 : _h.cacheWriteInputTokens) != null && {
|
|
@@ -954,13 +948,14 @@ var BedrockChatLanguageModel = class {
|
|
|
954
948
|
cacheWriteInputTokens: response.usage.cacheWriteInputTokens
|
|
955
949
|
}
|
|
956
950
|
},
|
|
957
|
-
...
|
|
951
|
+
...isJsonResponseFromTool && { isJsonResponseFromTool: true }
|
|
958
952
|
}
|
|
959
953
|
} : void 0;
|
|
960
954
|
return {
|
|
961
955
|
content,
|
|
962
956
|
finishReason: mapBedrockFinishReason(
|
|
963
|
-
response.stopReason
|
|
957
|
+
response.stopReason,
|
|
958
|
+
isJsonResponseFromTool
|
|
964
959
|
),
|
|
965
960
|
usage: {
|
|
966
961
|
inputTokens: (_i = response.usage) == null ? void 0 : _i.inputTokens,
|
|
@@ -1002,6 +997,7 @@ var BedrockChatLanguageModel = class {
|
|
|
1002
997
|
totalTokens: void 0
|
|
1003
998
|
};
|
|
1004
999
|
let providerMetadata = void 0;
|
|
1000
|
+
let isJsonResponseFromTool = false;
|
|
1005
1001
|
const contentBlocks = {};
|
|
1006
1002
|
return {
|
|
1007
1003
|
stream: response.pipeThrough(
|
|
@@ -1041,7 +1037,8 @@ var BedrockChatLanguageModel = class {
|
|
|
1041
1037
|
}
|
|
1042
1038
|
if (value.messageStop) {
|
|
1043
1039
|
finishReason = mapBedrockFinishReason(
|
|
1044
|
-
value.messageStop.stopReason
|
|
1040
|
+
value.messageStop.stopReason,
|
|
1041
|
+
isJsonResponseFromTool
|
|
1045
1042
|
);
|
|
1046
1043
|
}
|
|
1047
1044
|
if (value.metadata) {
|
|
@@ -1057,14 +1054,11 @@ var BedrockChatLanguageModel = class {
|
|
|
1057
1054
|
const trace = value.metadata.trace ? {
|
|
1058
1055
|
trace: value.metadata.trace
|
|
1059
1056
|
} : void 0;
|
|
1060
|
-
if (cacheUsage || trace
|
|
1057
|
+
if (cacheUsage || trace) {
|
|
1061
1058
|
providerMetadata = {
|
|
1062
1059
|
bedrock: {
|
|
1063
1060
|
...cacheUsage,
|
|
1064
|
-
...trace
|
|
1065
|
-
...usesJsonResponseTool && {
|
|
1066
|
-
isJsonResponseFromTool: true
|
|
1067
|
-
}
|
|
1061
|
+
...trace
|
|
1068
1062
|
}
|
|
1069
1063
|
};
|
|
1070
1064
|
}
|
|
@@ -1081,20 +1075,16 @@ var BedrockChatLanguageModel = class {
|
|
|
1081
1075
|
const blockIndex = value.contentBlockDelta.contentBlockIndex || 0;
|
|
1082
1076
|
if (contentBlocks[blockIndex] == null) {
|
|
1083
1077
|
contentBlocks[blockIndex] = { type: "text" };
|
|
1084
|
-
if (!usesJsonResponseTool) {
|
|
1085
|
-
controller.enqueue({
|
|
1086
|
-
type: "text-start",
|
|
1087
|
-
id: String(blockIndex)
|
|
1088
|
-
});
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
if (!usesJsonResponseTool) {
|
|
1092
1078
|
controller.enqueue({
|
|
1093
|
-
type: "text-
|
|
1094
|
-
id: String(blockIndex)
|
|
1095
|
-
delta: value.contentBlockDelta.delta.text
|
|
1079
|
+
type: "text-start",
|
|
1080
|
+
id: String(blockIndex)
|
|
1096
1081
|
});
|
|
1097
1082
|
}
|
|
1083
|
+
controller.enqueue({
|
|
1084
|
+
type: "text-delta",
|
|
1085
|
+
id: String(blockIndex),
|
|
1086
|
+
delta: value.contentBlockDelta.delta.text
|
|
1087
|
+
});
|
|
1098
1088
|
}
|
|
1099
1089
|
if (((_n = value.contentBlockStop) == null ? void 0 : _n.contentBlockIndex) != null) {
|
|
1100
1090
|
const blockIndex = value.contentBlockStop.contentBlockIndex;
|
|
@@ -1106,14 +1096,13 @@ var BedrockChatLanguageModel = class {
|
|
|
1106
1096
|
id: String(blockIndex)
|
|
1107
1097
|
});
|
|
1108
1098
|
} else if (contentBlock.type === "text") {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
});
|
|
1114
|
-
}
|
|
1099
|
+
controller.enqueue({
|
|
1100
|
+
type: "text-end",
|
|
1101
|
+
id: String(blockIndex)
|
|
1102
|
+
});
|
|
1115
1103
|
} else if (contentBlock.type === "tool-call") {
|
|
1116
|
-
if (
|
|
1104
|
+
if (contentBlock.isJsonResponseTool) {
|
|
1105
|
+
isJsonResponseFromTool = true;
|
|
1117
1106
|
controller.enqueue({
|
|
1118
1107
|
type: "text-start",
|
|
1119
1108
|
id: String(blockIndex)
|
|
@@ -1187,13 +1176,15 @@ var BedrockChatLanguageModel = class {
|
|
|
1187
1176
|
if (((_p = contentBlockStart == null ? void 0 : contentBlockStart.start) == null ? void 0 : _p.toolUse) != null) {
|
|
1188
1177
|
const toolUse = contentBlockStart.start.toolUse;
|
|
1189
1178
|
const blockIndex = contentBlockStart.contentBlockIndex;
|
|
1179
|
+
const isJsonResponseTool = usesJsonResponseTool && toolUse.name === "json";
|
|
1190
1180
|
contentBlocks[blockIndex] = {
|
|
1191
1181
|
type: "tool-call",
|
|
1192
1182
|
toolCallId: toolUse.toolUseId,
|
|
1193
1183
|
toolName: toolUse.name,
|
|
1194
|
-
jsonText: ""
|
|
1184
|
+
jsonText: "",
|
|
1185
|
+
isJsonResponseTool
|
|
1195
1186
|
};
|
|
1196
|
-
if (!
|
|
1187
|
+
if (!isJsonResponseTool) {
|
|
1197
1188
|
controller.enqueue({
|
|
1198
1189
|
type: "tool-input-start",
|
|
1199
1190
|
id: toolUse.toolUseId,
|
|
@@ -1207,7 +1198,7 @@ var BedrockChatLanguageModel = class {
|
|
|
1207
1198
|
const contentBlock = contentBlocks[blockIndex];
|
|
1208
1199
|
if ((contentBlock == null ? void 0 : contentBlock.type) === "tool-call") {
|
|
1209
1200
|
const delta = (_q = contentBlockDelta.delta.toolUse.input) != null ? _q : "";
|
|
1210
|
-
if (!
|
|
1201
|
+
if (!contentBlock.isJsonResponseTool) {
|
|
1211
1202
|
controller.enqueue({
|
|
1212
1203
|
type: "tool-input-delta",
|
|
1213
1204
|
id: contentBlock.toolCallId,
|
|
@@ -1219,6 +1210,20 @@ var BedrockChatLanguageModel = class {
|
|
|
1219
1210
|
}
|
|
1220
1211
|
},
|
|
1221
1212
|
flush(controller) {
|
|
1213
|
+
if (isJsonResponseFromTool) {
|
|
1214
|
+
if (providerMetadata) {
|
|
1215
|
+
providerMetadata.bedrock = {
|
|
1216
|
+
...providerMetadata.bedrock,
|
|
1217
|
+
isJsonResponseFromTool: true
|
|
1218
|
+
};
|
|
1219
|
+
} else {
|
|
1220
|
+
providerMetadata = {
|
|
1221
|
+
bedrock: {
|
|
1222
|
+
isJsonResponseFromTool: true
|
|
1223
|
+
}
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1222
1227
|
controller.enqueue({
|
|
1223
1228
|
type: "finish",
|
|
1224
1229
|
finishReason,
|