@ai-sdk/amazon-bedrock 3.0.0-beta.10 → 3.0.0-beta.12

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,19 @@
1
1
  # @ai-sdk/amazon-bedrock
2
2
 
3
+ ## 3.0.0-beta.12
4
+
5
+ ### Patch Changes
6
+
7
+ - 0893170: fix(amazon-bedrock): handle empty activeTools with tool conversation history
8
+ - Updated dependencies [e7fcc86]
9
+ - @ai-sdk/provider-utils@3.0.0-beta.7
10
+
11
+ ## 3.0.0-beta.11
12
+
13
+ ### Patch Changes
14
+
15
+ - a89add7: fix(amazon-bedrock): add structured output support for claude models
16
+
3
17
  ## 3.0.0-beta.10
4
18
 
5
19
  ### Patch Changes
package/dist/index.js CHANGED
@@ -181,7 +181,7 @@ function prepareTools({
181
181
  if (tools == null) {
182
182
  return {
183
183
  toolConfig: {
184
- tools: hasToolContent ? [] : void 0,
184
+ tools: void 0,
185
185
  toolChoice: void 0
186
186
  },
187
187
  toolWarnings: []
@@ -225,7 +225,7 @@ function prepareTools({
225
225
  case "none":
226
226
  return {
227
227
  toolConfig: {
228
- tools: hasToolContent ? [] : void 0,
228
+ tools: void 0,
229
229
  toolChoice: void 0
230
230
  },
231
231
  toolWarnings
@@ -630,14 +630,27 @@ var BedrockChatLanguageModel = class {
630
630
  setting: "topK"
631
631
  });
632
632
  }
633
- if (responseFormat != null && responseFormat.type !== "text") {
633
+ if (responseFormat != null && responseFormat.type !== "text" && responseFormat.type !== "json") {
634
634
  warnings.push({
635
635
  type: "unsupported-setting",
636
636
  setting: "responseFormat",
637
- details: "JSON response format is not supported."
637
+ details: "Only text and json response formats are supported."
638
638
  });
639
639
  }
640
- const { system, messages } = await convertToBedrockChatMessages(prompt);
640
+ if (tools != null && (responseFormat == null ? void 0 : responseFormat.type) === "json") {
641
+ if (tools.length > 0) {
642
+ warnings.push({
643
+ type: "other",
644
+ message: "JSON response format does not support tools. The provided tools are ignored."
645
+ });
646
+ }
647
+ }
648
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
649
+ type: "function",
650
+ name: "json",
651
+ description: "Respond with a JSON object.",
652
+ inputSchema: responseFormat.schema
653
+ } : void 0;
641
654
  const isThinking = ((_b = bedrockOptions.reasoningConfig) == null ? void 0 : _b.type) === "enabled";
642
655
  const thinkingBudget = (_c = bedrockOptions.reasoningConfig) == null ? void 0 : _c.budgetTokens;
643
656
  const inferenceConfig = {
@@ -676,10 +689,37 @@ var BedrockChatLanguageModel = class {
676
689
  details: "topP is not supported when thinking is enabled"
677
690
  });
678
691
  }
692
+ const activeTools = jsonResponseTool != null ? [jsonResponseTool] : tools != null ? tools : [];
693
+ let filteredPrompt = prompt;
694
+ if (activeTools.length === 0) {
695
+ const hasToolContent = prompt.some(
696
+ (message) => "content" in message && Array.isArray(message.content) && message.content.some(
697
+ (part) => part.type === "tool-call" || part.type === "tool-result"
698
+ )
699
+ );
700
+ if (hasToolContent) {
701
+ filteredPrompt = prompt.map(
702
+ (message) => message.role === "system" ? message : {
703
+ ...message,
704
+ content: message.content.filter(
705
+ (part) => part.type !== "tool-call" && part.type !== "tool-result"
706
+ )
707
+ }
708
+ ).filter(
709
+ (message) => message.role === "system" || message.content.length > 0
710
+ );
711
+ warnings.push({
712
+ type: "unsupported-setting",
713
+ setting: "toolContent",
714
+ details: "Tool calls and results removed from conversation because Bedrock does not support tool content without active tools."
715
+ });
716
+ }
717
+ }
718
+ const { system, messages } = await convertToBedrockChatMessages(filteredPrompt);
679
719
  const { toolConfig, toolWarnings } = prepareTools({
680
- tools,
681
- toolChoice,
682
- prompt
720
+ tools: activeTools,
721
+ toolChoice: jsonResponseTool != null ? { type: "tool", toolName: jsonResponseTool.name } : toolChoice,
722
+ prompt: filteredPrompt
683
723
  });
684
724
  const { reasoningConfig: _, ...filteredBedrockOptions } = (providerOptions == null ? void 0 : providerOptions.bedrock) || {};
685
725
  return {
@@ -693,12 +733,17 @@ var BedrockChatLanguageModel = class {
693
733
  ...filteredBedrockOptions,
694
734
  ...toolConfig.tools !== void 0 ? { toolConfig } : {}
695
735
  },
696
- warnings: [...warnings, ...toolWarnings]
736
+ warnings: [...warnings, ...toolWarnings],
737
+ usesJsonResponseTool: jsonResponseTool != null
697
738
  };
698
739
  }
699
740
  async doGenerate(options) {
700
741
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
701
- const { command: args, warnings } = await this.getArgs(options);
742
+ const {
743
+ command: args,
744
+ warnings,
745
+ usesJsonResponseTool
746
+ } = await this.getArgs(options);
702
747
  const url = `${this.getUrl(this.modelId)}/converse`;
703
748
  const { value: response, responseHeaders } = await (0, import_provider_utils3.postJsonToApi)({
704
749
  url,
@@ -723,7 +768,9 @@ var BedrockChatLanguageModel = class {
723
768
  const content = [];
724
769
  for (const part of response.output.message.content) {
725
770
  if (part.text) {
726
- content.push({ type: "text", text: part.text });
771
+ if (!usesJsonResponseTool) {
772
+ content.push({ type: "text", text: part.text });
773
+ }
727
774
  }
728
775
  if (part.reasoningContent) {
729
776
  if ("reasoningText" in part.reasoningContent) {
@@ -752,22 +799,29 @@ var BedrockChatLanguageModel = class {
752
799
  }
753
800
  }
754
801
  if (part.toolUse) {
755
- content.push({
756
- type: "tool-call",
757
- toolCallId: (_c = (_b = part.toolUse) == null ? void 0 : _b.toolUseId) != null ? _c : this.config.generateId(),
758
- toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
759
- input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : "")
760
- });
802
+ content.push(
803
+ // when a json response tool is used, the tool call becomes the text:
804
+ usesJsonResponseTool ? {
805
+ type: "text",
806
+ text: JSON.stringify(part.toolUse.input)
807
+ } : {
808
+ type: "tool-call",
809
+ toolCallId: (_c = (_b = part.toolUse) == null ? void 0 : _b.toolUseId) != null ? _c : this.config.generateId(),
810
+ toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
811
+ input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : "")
812
+ }
813
+ );
761
814
  }
762
815
  }
763
- const providerMetadata = response.trace || response.usage ? {
816
+ const providerMetadata = response.trace || response.usage || usesJsonResponseTool ? {
764
817
  bedrock: {
765
818
  ...response.trace && typeof response.trace === "object" ? { trace: response.trace } : {},
766
819
  ...((_h = response.usage) == null ? void 0 : _h.cacheWriteInputTokens) != null && {
767
820
  usage: {
768
821
  cacheWriteInputTokens: response.usage.cacheWriteInputTokens
769
822
  }
770
- }
823
+ },
824
+ ...usesJsonResponseTool && { isJsonResponseFromTool: true }
771
825
  }
772
826
  } : void 0;
773
827
  return {
@@ -790,7 +844,11 @@ var BedrockChatLanguageModel = class {
790
844
  };
791
845
  }
792
846
  async doStream(options) {
793
- const { command: args, warnings } = await this.getArgs(options);
847
+ const {
848
+ command: args,
849
+ warnings,
850
+ usesJsonResponseTool
851
+ } = await this.getArgs(options);
794
852
  const url = `${this.getUrl(this.modelId)}/converse-stream`;
795
853
  const { value: response, responseHeaders } = await (0, import_provider_utils3.postJsonToApi)({
796
854
  url,
@@ -869,11 +927,14 @@ var BedrockChatLanguageModel = class {
869
927
  const trace = value.metadata.trace ? {
870
928
  trace: value.metadata.trace
871
929
  } : void 0;
872
- if (cacheUsage || trace) {
930
+ if (cacheUsage || trace || usesJsonResponseTool) {
873
931
  providerMetadata = {
874
932
  bedrock: {
875
933
  ...cacheUsage,
876
- ...trace
934
+ ...trace,
935
+ ...usesJsonResponseTool && {
936
+ isJsonResponseFromTool: true
937
+ }
877
938
  }
878
939
  };
879
940
  }
@@ -890,16 +951,20 @@ var BedrockChatLanguageModel = class {
890
951
  const blockIndex = value.contentBlockDelta.contentBlockIndex || 0;
891
952
  if (contentBlocks[blockIndex] == null) {
892
953
  contentBlocks[blockIndex] = { type: "text" };
954
+ if (!usesJsonResponseTool) {
955
+ controller.enqueue({
956
+ type: "text-start",
957
+ id: String(blockIndex)
958
+ });
959
+ }
960
+ }
961
+ if (!usesJsonResponseTool) {
893
962
  controller.enqueue({
894
- type: "text-start",
895
- id: String(blockIndex)
963
+ type: "text-delta",
964
+ id: String(blockIndex),
965
+ delta: value.contentBlockDelta.delta.text
896
966
  });
897
967
  }
898
- controller.enqueue({
899
- type: "text-delta",
900
- id: String(blockIndex),
901
- delta: value.contentBlockDelta.delta.text
902
- });
903
968
  }
904
969
  if (((_n = value.contentBlockStop) == null ? void 0 : _n.contentBlockIndex) != null) {
905
970
  const blockIndex = value.contentBlockStop.contentBlockIndex;
@@ -911,21 +976,39 @@ var BedrockChatLanguageModel = class {
911
976
  id: String(blockIndex)
912
977
  });
913
978
  } else if (contentBlock.type === "text") {
914
- controller.enqueue({
915
- type: "text-end",
916
- id: String(blockIndex)
917
- });
979
+ if (!usesJsonResponseTool) {
980
+ controller.enqueue({
981
+ type: "text-end",
982
+ id: String(blockIndex)
983
+ });
984
+ }
918
985
  } else if (contentBlock.type === "tool-call") {
919
- controller.enqueue({
920
- type: "tool-input-end",
921
- id: contentBlock.toolCallId
922
- });
923
- controller.enqueue({
924
- type: "tool-call",
925
- toolCallId: contentBlock.toolCallId,
926
- toolName: contentBlock.toolName,
927
- input: contentBlock.jsonText
928
- });
986
+ if (usesJsonResponseTool) {
987
+ controller.enqueue({
988
+ type: "text-start",
989
+ id: String(blockIndex)
990
+ });
991
+ controller.enqueue({
992
+ type: "text-delta",
993
+ id: String(blockIndex),
994
+ delta: contentBlock.jsonText
995
+ });
996
+ controller.enqueue({
997
+ type: "text-end",
998
+ id: String(blockIndex)
999
+ });
1000
+ } else {
1001
+ controller.enqueue({
1002
+ type: "tool-input-end",
1003
+ id: contentBlock.toolCallId
1004
+ });
1005
+ controller.enqueue({
1006
+ type: "tool-call",
1007
+ toolCallId: contentBlock.toolCallId,
1008
+ toolName: contentBlock.toolName,
1009
+ input: contentBlock.jsonText
1010
+ });
1011
+ }
929
1012
  }
930
1013
  delete contentBlocks[blockIndex];
931
1014
  }
@@ -980,11 +1063,13 @@ var BedrockChatLanguageModel = class {
980
1063
  toolName: toolUse.name,
981
1064
  jsonText: ""
982
1065
  };
983
- controller.enqueue({
984
- type: "tool-input-start",
985
- id: toolUse.toolUseId,
986
- toolName: toolUse.name
987
- });
1066
+ if (!usesJsonResponseTool) {
1067
+ controller.enqueue({
1068
+ type: "tool-input-start",
1069
+ id: toolUse.toolUseId,
1070
+ toolName: toolUse.name
1071
+ });
1072
+ }
988
1073
  }
989
1074
  const contentBlockDelta = value.contentBlockDelta;
990
1075
  if ((contentBlockDelta == null ? void 0 : contentBlockDelta.delta) && "toolUse" in contentBlockDelta.delta && contentBlockDelta.delta.toolUse) {
@@ -992,11 +1077,13 @@ var BedrockChatLanguageModel = class {
992
1077
  const contentBlock = contentBlocks[blockIndex];
993
1078
  if ((contentBlock == null ? void 0 : contentBlock.type) === "tool-call") {
994
1079
  const delta = (_q = contentBlockDelta.delta.toolUse.input) != null ? _q : "";
995
- controller.enqueue({
996
- type: "tool-input-delta",
997
- id: contentBlock.toolCallId,
998
- delta
999
- });
1080
+ if (!usesJsonResponseTool) {
1081
+ controller.enqueue({
1082
+ type: "tool-input-delta",
1083
+ id: contentBlock.toolCallId,
1084
+ delta
1085
+ });
1086
+ }
1000
1087
  contentBlock.jsonText += delta;
1001
1088
  }
1002
1089
  }