@ai-sdk/amazon-bedrock 5.0.74 → 5.0.75

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,16 @@
1
1
  # @ai-sdk/amazon-bedrock
2
2
 
3
+ ## 5.0.75
4
+
5
+ ### Patch Changes
6
+
7
+ - d0b6d6d: fix(bedrock): preserve provider-executed tool results when replaying messages
8
+ - 770c214: fix(amazon-bedrock): sanitize document filenames before sending them to Bedrock
9
+ - 1ee6b1f: fix(amazon-bedrock): return text from citation content responses
10
+ - Updated dependencies [4af00d1]
11
+ - Updated dependencies [abb9ebf]
12
+ - @ai-sdk/openai@4.0.59
13
+
3
14
  ## 5.0.74
4
15
 
5
16
  ### 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.74" : "0.0.0-test";
27
+ var VERSION = true ? "5.0.75" : "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
@@ -526,6 +526,9 @@ function pushCachePoint(content, providerMetadata) {
526
526
  function sanitizeToolName(toolName) {
527
527
  return toolName.replace(/[^a-zA-Z0-9_-]/g, "") || "_";
528
528
  }
529
+ function sanitizeDocumentName(filename) {
530
+ return stripFileExtension(filename).replace(/\s+/g, " ").replace(/[^a-zA-Z0-9 ()[\]-]/g, "").trim().slice(0, 200).trim();
531
+ }
529
532
  function getAmazonBedrockMediaSource({
530
533
  data,
531
534
  functionality
@@ -588,6 +591,7 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
588
591
  const messages = [];
589
592
  let documentCounter = 0;
590
593
  const generateDocumentName = () => `document-${++documentCounter}`;
594
+ const getDocumentName = (filename) => filename && sanitizeDocumentName(filename) || generateDocumentName();
591
595
  for (let i = 0; i < blocks.length; i++) {
592
596
  const block = blocks[i];
593
597
  const isLastBlock = i === blocks.length - 1;
@@ -692,7 +696,7 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
692
696
  amazonBedrockContent.push({
693
697
  document: {
694
698
  format: getAmazonBedrockDocumentFormat(textMediaType),
695
- name: part.filename ? stripFileExtension(part.filename) : generateDocumentName(),
699
+ name: getDocumentName(part.filename),
696
700
  source: {
697
701
  bytes: convertToBase64(
698
702
  new TextEncoder().encode(part.data.text)
@@ -749,7 +753,7 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
749
753
  amazonBedrockContent.push({
750
754
  document: {
751
755
  format: getAmazonBedrockDocumentFormat(fullMediaType),
752
- name: part.filename ? stripFileExtension(part.filename) : generateDocumentName(),
756
+ name: getDocumentName(part.filename),
753
757
  source: {
754
758
  bytes: convertToBase64(part.data.data)
755
759
  },
@@ -775,110 +779,13 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
775
779
  if (part.type === "tool-approval-response") {
776
780
  continue;
777
781
  }
778
- let toolResultContent;
779
- const output = part.output;
780
- switch (output.type) {
781
- case "content": {
782
- toolResultContent = await Promise.all(
783
- output.value.map(async (contentPart) => {
784
- switch (contentPart.type) {
785
- case "text":
786
- return { text: contentPart.text };
787
- case "file": {
788
- if (contentPart.data.type !== "data" && (contentPart.data.type !== "url" || contentPart.data.url.protocol !== "s3:")) {
789
- throw new UnsupportedFunctionalityError2({
790
- functionality: `tool result file data of type "${contentPart.data.type}"`
791
- });
792
- }
793
- const fullMediaType = resolveFullMediaType({
794
- part: contentPart
795
- });
796
- switch (getTopLevelMediaType(fullMediaType)) {
797
- case "image": {
798
- return {
799
- image: {
800
- format: getAmazonBedrockImageFormat(
801
- fullMediaType
802
- ),
803
- source: getAmazonBedrockMediaSource({
804
- data: contentPart.data,
805
- functionality: `tool result file data of type "${contentPart.data.type}"`
806
- })
807
- }
808
- };
809
- }
810
- case "video": {
811
- return {
812
- video: {
813
- format: getAmazonBedrockVideoFormat(
814
- fullMediaType
815
- ),
816
- source: getAmazonBedrockMediaSource({
817
- data: contentPart.data,
818
- functionality: `tool result file data of type "${contentPart.data.type}"`
819
- })
820
- }
821
- };
822
- }
823
- default: {
824
- if (contentPart.data.type !== "data") {
825
- throw new UnsupportedFunctionalityError2({
826
- functionality: `tool result file data of type "${contentPart.data.type}"`
827
- });
828
- }
829
- const enableCitations = await shouldEnableCitations(
830
- contentPart.providerOptions
831
- );
832
- return {
833
- document: {
834
- format: getAmazonBedrockDocumentFormat(
835
- fullMediaType
836
- ),
837
- name: contentPart.filename ? stripFileExtension(contentPart.filename) : generateDocumentName(),
838
- source: {
839
- bytes: convertToBase64(
840
- contentPart.data.data
841
- )
842
- },
843
- ...enableCitations && {
844
- citations: { enabled: true }
845
- }
846
- }
847
- };
848
- }
849
- }
850
- }
851
- default: {
852
- throw new UnsupportedFunctionalityError2({
853
- functionality: `unsupported tool content part type: ${contentPart.type}`
854
- });
855
- }
856
- }
857
- })
858
- );
859
- break;
860
- }
861
- case "text":
862
- case "error-text":
863
- toolResultContent = [{ text: output.value }];
864
- break;
865
- case "execution-denied":
866
- toolResultContent = [
867
- { text: (_a = output.reason) != null ? _a : "Tool call execution denied." }
868
- ];
869
- break;
870
- case "json":
871
- case "error-json":
872
- default:
873
- toolResultContent = [
874
- { text: JSON.stringify(output.value) }
875
- ];
876
- break;
877
- }
878
782
  amazonBedrockContent.push({
879
783
  toolResult: {
880
784
  toolUseId: normalizeToolCallId(part.toolCallId, isMistral),
881
- content: toolResultContent
785
+ content: await convertToolResultOutput({
786
+ output: part.output,
787
+ getDocumentName
788
+ })
882
789
  }
883
790
  });
884
791
  pushCachePoint(amazonBedrockContent, part.providerOptions);
@@ -892,11 +799,24 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
892
799
  }
893
800
  pushCachePoint(amazonBedrockContent, providerOptions);
894
801
  }
895
- messages.push({ role: "user", content: amazonBedrockContent });
802
+ appendToUserMessage(messages, amazonBedrockContent);
896
803
  break;
897
804
  }
898
805
  case "assistant": {
899
- const amazonBedrockContent = [];
806
+ let assistantContent = [];
807
+ let toolResultContent = [];
808
+ const flushAssistantContent = () => {
809
+ if (assistantContent.some((block2) => !("cachePoint" in block2))) {
810
+ messages.push({ role: "assistant", content: assistantContent });
811
+ }
812
+ assistantContent = [];
813
+ };
814
+ const flushToolResultContent = () => {
815
+ if (toolResultContent.length > 0) {
816
+ appendToUserMessage(messages, toolResultContent);
817
+ toolResultContent = [];
818
+ }
819
+ };
900
820
  for (let j = 0; j < block.messages.length; j++) {
901
821
  const message = block.messages[j];
902
822
  const isLastMessage = j === block.messages.length - 1;
@@ -907,12 +827,15 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
907
827
  for (let k = 0; k < content.length; k++) {
908
828
  const part = content[k];
909
829
  const isLastContentPart = k === content.length - 1;
830
+ if (part.type !== "tool-result") {
831
+ flushToolResultContent();
832
+ }
910
833
  switch (part.type) {
911
834
  case "text": {
912
835
  if (!part.text.trim() && !hasReasoningBlocks) {
913
836
  break;
914
837
  }
915
- amazonBedrockContent.push({
838
+ assistantContent.push({
916
839
  text: (
917
840
  // trim the last text part if it's the last message in the block
918
841
  // because Bedrock does not allow trailing whitespace
@@ -928,17 +851,17 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
928
851
  break;
929
852
  }
930
853
  case "reasoning": {
931
- const reasoningMetadata = (_b = await parseProviderOptions({
854
+ const reasoningMetadata = (_a = await parseProviderOptions({
932
855
  provider: "amazonBedrock",
933
856
  providerOptions: part.providerOptions,
934
857
  schema: amazonBedrockReasoningMetadataSchema
935
- })) != null ? _b : await parseProviderOptions({
858
+ })) != null ? _a : await parseProviderOptions({
936
859
  provider: "bedrock",
937
860
  providerOptions: part.providerOptions,
938
861
  schema: amazonBedrockReasoningMetadataSchema
939
862
  });
940
863
  if ((reasoningMetadata == null ? void 0 : reasoningMetadata.signature) != null) {
941
- amazonBedrockContent.push({
864
+ assistantContent.push({
942
865
  reasoningContent: {
943
866
  reasoningText: {
944
867
  text: part.text,
@@ -947,13 +870,13 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
947
870
  }
948
871
  });
949
872
  } else if ((reasoningMetadata == null ? void 0 : reasoningMetadata.redactedContent) != null) {
950
- amazonBedrockContent.push({
873
+ assistantContent.push({
951
874
  reasoningContent: {
952
875
  redactedContent: reasoningMetadata.redactedContent
953
876
  }
954
877
  });
955
878
  } else if ((reasoningMetadata == null ? void 0 : reasoningMetadata.redactedData) != null) {
956
- amazonBedrockContent.push({
879
+ assistantContent.push({
957
880
  reasoningContent: {
958
881
  redactedReasoning: {
959
882
  data: reasoningMetadata.redactedData
@@ -964,7 +887,7 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
964
887
  break;
965
888
  }
966
889
  case "tool-call": {
967
- amazonBedrockContent.push({
890
+ assistantContent.push({
968
891
  toolUse: {
969
892
  toolUseId: normalizeToolCallId(part.toolCallId, isMistral),
970
893
  name: sanitizeToolName(part.toolName),
@@ -973,14 +896,32 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
973
896
  });
974
897
  break;
975
898
  }
899
+ case "tool-result": {
900
+ flushAssistantContent();
901
+ toolResultContent.push({
902
+ toolResult: {
903
+ toolUseId: normalizeToolCallId(part.toolCallId, isMistral),
904
+ content: await convertToolResultOutput({
905
+ output: part.output,
906
+ getDocumentName
907
+ })
908
+ }
909
+ });
910
+ break;
911
+ }
976
912
  }
977
- pushCachePoint(amazonBedrockContent, part.providerOptions);
913
+ pushCachePoint(
914
+ part.type === "tool-result" ? toolResultContent : assistantContent,
915
+ part.providerOptions
916
+ );
978
917
  }
979
- pushCachePoint(amazonBedrockContent, message.providerOptions);
980
- }
981
- if (amazonBedrockContent.some((block2) => !("cachePoint" in block2))) {
982
- messages.push({ role: "assistant", content: amazonBedrockContent });
918
+ pushCachePoint(
919
+ ((_b = content[content.length - 1]) == null ? void 0 : _b.type) === "tool-result" ? toolResultContent : assistantContent,
920
+ message.providerOptions
921
+ );
983
922
  }
923
+ flushToolResultContent();
924
+ flushAssistantContent();
984
925
  break;
985
926
  }
986
927
  default: {
@@ -991,6 +932,97 @@ async function convertToAmazonBedrockChatMessages(prompt, isMistral = false) {
991
932
  }
992
933
  return { system, messages };
993
934
  }
935
+ function appendToUserMessage(messages, content) {
936
+ const lastMessage = messages[messages.length - 1];
937
+ if ((lastMessage == null ? void 0 : lastMessage.role) === "user" && lastMessage.content.some((block) => "toolResult" in block)) {
938
+ lastMessage.content.push(...content);
939
+ } else {
940
+ messages.push({ role: "user", content });
941
+ }
942
+ }
943
+ async function convertToolResultOutput({
944
+ output,
945
+ getDocumentName
946
+ }) {
947
+ var _a;
948
+ switch (output.type) {
949
+ case "content": {
950
+ return Promise.all(
951
+ output.value.map(async (contentPart) => {
952
+ switch (contentPart.type) {
953
+ case "text":
954
+ return { text: contentPart.text };
955
+ case "file": {
956
+ if (contentPart.data.type !== "data" && (contentPart.data.type !== "url" || contentPart.data.url.protocol !== "s3:")) {
957
+ throw new UnsupportedFunctionalityError2({
958
+ functionality: `tool result file data of type "${contentPart.data.type}"`
959
+ });
960
+ }
961
+ const fullMediaType = resolveFullMediaType({ part: contentPart });
962
+ switch (getTopLevelMediaType(fullMediaType)) {
963
+ case "image":
964
+ return {
965
+ image: {
966
+ format: getAmazonBedrockImageFormat(fullMediaType),
967
+ source: getAmazonBedrockMediaSource({
968
+ data: contentPart.data,
969
+ functionality: `tool result file data of type "${contentPart.data.type}"`
970
+ })
971
+ }
972
+ };
973
+ case "video":
974
+ return {
975
+ video: {
976
+ format: getAmazonBedrockVideoFormat(fullMediaType),
977
+ source: getAmazonBedrockMediaSource({
978
+ data: contentPart.data,
979
+ functionality: `tool result file data of type "${contentPart.data.type}"`
980
+ })
981
+ }
982
+ };
983
+ default: {
984
+ if (contentPart.data.type !== "data") {
985
+ throw new UnsupportedFunctionalityError2({
986
+ functionality: `tool result file data of type "${contentPart.data.type}"`
987
+ });
988
+ }
989
+ const enableCitations = await shouldEnableCitations(
990
+ contentPart.providerOptions
991
+ );
992
+ return {
993
+ document: {
994
+ format: getAmazonBedrockDocumentFormat(fullMediaType),
995
+ name: getDocumentName(contentPart.filename),
996
+ source: {
997
+ bytes: convertToBase64(contentPart.data.data)
998
+ },
999
+ ...enableCitations && {
1000
+ citations: { enabled: true }
1001
+ }
1002
+ }
1003
+ };
1004
+ }
1005
+ }
1006
+ }
1007
+ default:
1008
+ throw new UnsupportedFunctionalityError2({
1009
+ functionality: `unsupported tool content part type: ${contentPart.type}`
1010
+ });
1011
+ }
1012
+ })
1013
+ );
1014
+ }
1015
+ case "text":
1016
+ case "error-text":
1017
+ return [{ text: output.value }];
1018
+ case "execution-denied":
1019
+ return [{ text: (_a = output.reason) != null ? _a : "Tool call execution denied." }];
1020
+ case "json":
1021
+ case "error-json":
1022
+ default:
1023
+ return [{ text: JSON.stringify(output.value) }];
1024
+ }
1025
+ }
994
1026
  function toBedrockToolInput(input) {
995
1027
  return typeof input === "object" && input !== null && !Array.isArray(input) ? input : { rawInvalidInput: input };
996
1028
  }
@@ -1463,7 +1495,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1463
1495
  );
1464
1496
  }
1465
1497
  async doGenerate(options) {
1466
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1498
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
1467
1499
  const {
1468
1500
  command: args,
1469
1501
  warnings,
@@ -1492,10 +1524,13 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1492
1524
  let isJsonResponseFromTool = false;
1493
1525
  const jsonObjectTextExtractor = usesJsonInstruction ? new JsonObjectTextExtractor() : void 0;
1494
1526
  for (const part of response.output.message.content) {
1495
- if (part.text != null) {
1527
+ const textParts = part.text != null ? [part.text] : (_c = (_b = (_a = part.citationsContent) == null ? void 0 : _a.content) == null ? void 0 : _b.flatMap(
1528
+ (content2) => content2.text == null ? [] : [content2.text]
1529
+ )) != null ? _c : [];
1530
+ for (const text of textParts) {
1496
1531
  content.push({
1497
1532
  type: "text",
1498
- text: (_a = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(part.text)) != null ? _a : part.text
1533
+ text: (_d = jsonObjectTextExtractor == null ? void 0 : jsonObjectTextExtractor.process(text)) != null ? _d : text
1499
1534
  });
1500
1535
  }
1501
1536
  if (part.reasoningContent) {
@@ -1516,7 +1551,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1516
1551
  content.push(reasoning);
1517
1552
  } else if ("redactedReasoning" in part.reasoningContent) {
1518
1553
  const redactedPayload = {
1519
- redactedData: (_b = part.reasoningContent.redactedReasoning.data) != null ? _b : ""
1554
+ redactedData: (_e = part.reasoningContent.redactedReasoning.data) != null ? _e : ""
1520
1555
  };
1521
1556
  content.push({
1522
1557
  type: "reasoning",
@@ -1550,17 +1585,17 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1550
1585
  });
1551
1586
  } else {
1552
1587
  const isMistral = isMistralModel(this.modelId);
1553
- const rawToolCallId = ((_c = part.toolUse) == null ? void 0 : _c.toolUseId) || this.config.generateId();
1588
+ const rawToolCallId = ((_f = part.toolUse) == null ? void 0 : _f.toolUseId) || this.config.generateId();
1554
1589
  content.push({
1555
1590
  type: "tool-call",
1556
1591
  toolCallId: normalizeToolCallId(rawToolCallId, isMistral),
1557
- toolName: (_e = (_d = part.toolUse) == null ? void 0 : _d.name) != null ? _e : `tool-${this.config.generateId()}`,
1558
- input: JSON.stringify((_g = (_f = part.toolUse) == null ? void 0 : _f.input) != null ? _g : {})
1592
+ toolName: (_h = (_g = part.toolUse) == null ? void 0 : _g.name) != null ? _h : `tool-${this.config.generateId()}`,
1593
+ input: JSON.stringify((_j = (_i = part.toolUse) == null ? void 0 : _i.input) != null ? _j : {})
1559
1594
  });
1560
1595
  }
1561
1596
  }
1562
1597
  }
1563
- const stopSequence = (_j = (_i = (_h = response.additionalModelResponseFields) == null ? void 0 : _h.delta) == null ? void 0 : _i.stop_sequence) != null ? _j : null;
1598
+ const stopSequence = (_m = (_l = (_k = response.additionalModelResponseFields) == null ? void 0 : _k.delta) == null ? void 0 : _l.stop_sequence) != null ? _m : null;
1564
1599
  const providerMetadataPayload = response.trace || response.usage || response.performanceConfig || response.serviceTier || isJsonResponseFromTool || stopSequence ? {
1565
1600
  ...response.trace && typeof response.trace === "object" ? { trace: response.trace } : {},
1566
1601
  ...response.performanceConfig && {
@@ -1569,7 +1604,7 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1569
1604
  ...response.serviceTier && {
1570
1605
  serviceTier: response.serviceTier
1571
1606
  },
1572
- ...(((_k = response.usage) == null ? void 0 : _k.cacheWriteInputTokens) != null || ((_l = response.usage) == null ? void 0 : _l.cacheDetails) != null) && {
1607
+ ...(((_n = response.usage) == null ? void 0 : _n.cacheWriteInputTokens) != null || ((_o = response.usage) == null ? void 0 : _o.cacheDetails) != null) && {
1573
1608
  usage: {
1574
1609
  ...response.usage.cacheWriteInputTokens != null && {
1575
1610
  cacheWriteInputTokens: response.usage.cacheWriteInputTokens
@@ -1593,11 +1628,11 @@ var AmazonBedrockChatLanguageModel = class _AmazonBedrockChatLanguageModel {
1593
1628
  response.stopReason,
1594
1629
  isJsonResponseFromTool
1595
1630
  ),
1596
- raw: (_m = response.stopReason) != null ? _m : void 0
1631
+ raw: (_p = response.stopReason) != null ? _p : void 0
1597
1632
  },
1598
1633
  usage: convertAmazonBedrockUsage(response.usage),
1599
1634
  response: {
1600
- id: (_n = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _n : void 0,
1635
+ id: (_q = responseHeaders == null ? void 0 : responseHeaders["x-amzn-requestid"]) != null ? _q : void 0,
1601
1636
  timestamp: (responseHeaders == null ? void 0 : responseHeaders["date"]) != null ? new Date(responseHeaders["date"]) : void 0,
1602
1637
  modelId: this.modelId,
1603
1638
  headers: responseHeaders
@@ -2063,6 +2098,13 @@ var AmazonBedrockResponseSchema = z4.object({
2063
2098
  content: z4.array(
2064
2099
  z4.object({
2065
2100
  text: z4.string().nullish(),
2101
+ citationsContent: z4.object({
2102
+ content: z4.array(
2103
+ z4.object({
2104
+ text: z4.string().nullish()
2105
+ })
2106
+ ).nullish()
2107
+ }).nullish(),
2066
2108
  toolUse: AmazonBedrockToolUseSchema.nullish(),
2067
2109
  reasoningContent: z4.union([
2068
2110
  z4.object({
@@ -2736,7 +2778,7 @@ import {
2736
2778
  import { AwsV4Signer } from "aws4fetch";
2737
2779
 
2738
2780
  // src/version.ts
2739
- var VERSION = true ? "5.0.74" : "0.0.0-test";
2781
+ var VERSION = true ? "5.0.75" : "0.0.0-test";
2740
2782
 
2741
2783
  // src/amazon-bedrock-sigv4-fetch.ts
2742
2784
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {