@librechat/agents 3.1.75 → 3.1.77-dev.1

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.
Files changed (272) hide show
  1. package/dist/cjs/graphs/Graph.cjs +22 -3
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/hitl/askUserQuestion.cjs +67 -0
  4. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -0
  5. package/dist/cjs/hooks/HookRegistry.cjs +54 -0
  6. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  7. package/dist/cjs/hooks/createToolPolicyHook.cjs +115 -0
  8. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -0
  9. package/dist/cjs/hooks/executeHooks.cjs +40 -1
  10. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  11. package/dist/cjs/hooks/types.cjs +1 -0
  12. package/dist/cjs/hooks/types.cjs.map +1 -1
  13. package/dist/cjs/langchain/google-common.cjs +3 -0
  14. package/dist/cjs/langchain/google-common.cjs.map +1 -0
  15. package/dist/cjs/langchain/index.cjs +86 -0
  16. package/dist/cjs/langchain/index.cjs.map +1 -0
  17. package/dist/cjs/langchain/language_models/chat_models.cjs +3 -0
  18. package/dist/cjs/langchain/language_models/chat_models.cjs.map +1 -0
  19. package/dist/cjs/langchain/messages/tool.cjs +3 -0
  20. package/dist/cjs/langchain/messages/tool.cjs.map +1 -0
  21. package/dist/cjs/langchain/messages.cjs +51 -0
  22. package/dist/cjs/langchain/messages.cjs.map +1 -0
  23. package/dist/cjs/langchain/openai.cjs +3 -0
  24. package/dist/cjs/langchain/openai.cjs.map +1 -0
  25. package/dist/cjs/langchain/prompts.cjs +11 -0
  26. package/dist/cjs/langchain/prompts.cjs.map +1 -0
  27. package/dist/cjs/langchain/runnables.cjs +19 -0
  28. package/dist/cjs/langchain/runnables.cjs.map +1 -0
  29. package/dist/cjs/langchain/tools.cjs +23 -0
  30. package/dist/cjs/langchain/tools.cjs.map +1 -0
  31. package/dist/cjs/langchain/utils/env.cjs +11 -0
  32. package/dist/cjs/langchain/utils/env.cjs.map +1 -0
  33. package/dist/cjs/llm/anthropic/index.cjs +145 -52
  34. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  35. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  36. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +21 -14
  37. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  38. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +84 -70
  39. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  40. package/dist/cjs/llm/bedrock/index.cjs +1 -1
  41. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  42. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +213 -3
  43. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  44. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +2 -1
  45. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  46. package/dist/cjs/llm/google/utils/common.cjs +5 -4
  47. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  48. package/dist/cjs/llm/openai/index.cjs +519 -655
  49. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  50. package/dist/cjs/llm/openai/utils/index.cjs +20 -458
  51. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  52. package/dist/cjs/llm/openrouter/index.cjs +57 -175
  53. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  54. package/dist/cjs/llm/vertexai/index.cjs +5 -3
  55. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  56. package/dist/cjs/main.cjs +112 -3
  57. package/dist/cjs/main.cjs.map +1 -1
  58. package/dist/cjs/messages/cache.cjs +2 -1
  59. package/dist/cjs/messages/cache.cjs.map +1 -1
  60. package/dist/cjs/messages/core.cjs +7 -6
  61. package/dist/cjs/messages/core.cjs.map +1 -1
  62. package/dist/cjs/messages/format.cjs +73 -15
  63. package/dist/cjs/messages/format.cjs.map +1 -1
  64. package/dist/cjs/messages/langchain.cjs +26 -0
  65. package/dist/cjs/messages/langchain.cjs.map +1 -0
  66. package/dist/cjs/messages/prune.cjs +7 -6
  67. package/dist/cjs/messages/prune.cjs.map +1 -1
  68. package/dist/cjs/run.cjs +400 -42
  69. package/dist/cjs/run.cjs.map +1 -1
  70. package/dist/cjs/tools/ToolNode.cjs +556 -56
  71. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  72. package/dist/cjs/tools/search/search.cjs +55 -66
  73. package/dist/cjs/tools/search/search.cjs.map +1 -1
  74. package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
  75. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
  76. package/dist/cjs/tools/search/tavily-search.cjs +372 -0
  77. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
  78. package/dist/cjs/tools/search/tool.cjs +26 -4
  79. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  80. package/dist/cjs/tools/search/utils.cjs +10 -3
  81. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  82. package/dist/esm/graphs/Graph.mjs +22 -3
  83. package/dist/esm/graphs/Graph.mjs.map +1 -1
  84. package/dist/esm/hitl/askUserQuestion.mjs +65 -0
  85. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -0
  86. package/dist/esm/hooks/HookRegistry.mjs +54 -0
  87. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  88. package/dist/esm/hooks/createToolPolicyHook.mjs +113 -0
  89. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -0
  90. package/dist/esm/hooks/executeHooks.mjs +40 -1
  91. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  92. package/dist/esm/hooks/types.mjs +1 -0
  93. package/dist/esm/hooks/types.mjs.map +1 -1
  94. package/dist/esm/langchain/google-common.mjs +2 -0
  95. package/dist/esm/langchain/google-common.mjs.map +1 -0
  96. package/dist/esm/langchain/index.mjs +5 -0
  97. package/dist/esm/langchain/index.mjs.map +1 -0
  98. package/dist/esm/langchain/language_models/chat_models.mjs +2 -0
  99. package/dist/esm/langchain/language_models/chat_models.mjs.map +1 -0
  100. package/dist/esm/langchain/messages/tool.mjs +2 -0
  101. package/dist/esm/langchain/messages/tool.mjs.map +1 -0
  102. package/dist/esm/langchain/messages.mjs +2 -0
  103. package/dist/esm/langchain/messages.mjs.map +1 -0
  104. package/dist/esm/langchain/openai.mjs +2 -0
  105. package/dist/esm/langchain/openai.mjs.map +1 -0
  106. package/dist/esm/langchain/prompts.mjs +2 -0
  107. package/dist/esm/langchain/prompts.mjs.map +1 -0
  108. package/dist/esm/langchain/runnables.mjs +2 -0
  109. package/dist/esm/langchain/runnables.mjs.map +1 -0
  110. package/dist/esm/langchain/tools.mjs +2 -0
  111. package/dist/esm/langchain/tools.mjs.map +1 -0
  112. package/dist/esm/langchain/utils/env.mjs +2 -0
  113. package/dist/esm/langchain/utils/env.mjs.map +1 -0
  114. package/dist/esm/llm/anthropic/index.mjs +146 -54
  115. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  116. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  117. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +21 -14
  118. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  119. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +84 -71
  120. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  121. package/dist/esm/llm/bedrock/index.mjs +1 -1
  122. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  123. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +214 -4
  124. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  125. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +2 -1
  126. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  127. package/dist/esm/llm/google/utils/common.mjs +5 -4
  128. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  129. package/dist/esm/llm/openai/index.mjs +520 -656
  130. package/dist/esm/llm/openai/index.mjs.map +1 -1
  131. package/dist/esm/llm/openai/utils/index.mjs +23 -459
  132. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  133. package/dist/esm/llm/openrouter/index.mjs +57 -175
  134. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  135. package/dist/esm/llm/vertexai/index.mjs +5 -3
  136. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  137. package/dist/esm/main.mjs +7 -0
  138. package/dist/esm/main.mjs.map +1 -1
  139. package/dist/esm/messages/cache.mjs +2 -1
  140. package/dist/esm/messages/cache.mjs.map +1 -1
  141. package/dist/esm/messages/core.mjs +7 -6
  142. package/dist/esm/messages/core.mjs.map +1 -1
  143. package/dist/esm/messages/format.mjs +73 -15
  144. package/dist/esm/messages/format.mjs.map +1 -1
  145. package/dist/esm/messages/langchain.mjs +23 -0
  146. package/dist/esm/messages/langchain.mjs.map +1 -0
  147. package/dist/esm/messages/prune.mjs +7 -6
  148. package/dist/esm/messages/prune.mjs.map +1 -1
  149. package/dist/esm/run.mjs +400 -42
  150. package/dist/esm/run.mjs.map +1 -1
  151. package/dist/esm/tools/ToolNode.mjs +557 -57
  152. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  153. package/dist/esm/tools/search/search.mjs +55 -66
  154. package/dist/esm/tools/search/search.mjs.map +1 -1
  155. package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
  156. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
  157. package/dist/esm/tools/search/tavily-search.mjs +370 -0
  158. package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
  159. package/dist/esm/tools/search/tool.mjs +26 -4
  160. package/dist/esm/tools/search/tool.mjs.map +1 -1
  161. package/dist/esm/tools/search/utils.mjs +10 -3
  162. package/dist/esm/tools/search/utils.mjs.map +1 -1
  163. package/dist/types/graphs/Graph.d.ts +7 -0
  164. package/dist/types/hitl/askUserQuestion.d.ts +55 -0
  165. package/dist/types/hitl/index.d.ts +6 -0
  166. package/dist/types/hooks/HookRegistry.d.ts +58 -0
  167. package/dist/types/hooks/createToolPolicyHook.d.ts +87 -0
  168. package/dist/types/hooks/index.d.ts +4 -1
  169. package/dist/types/hooks/types.d.ts +109 -3
  170. package/dist/types/index.d.ts +10 -0
  171. package/dist/types/langchain/google-common.d.ts +1 -0
  172. package/dist/types/langchain/index.d.ts +8 -0
  173. package/dist/types/langchain/language_models/chat_models.d.ts +1 -0
  174. package/dist/types/langchain/messages/tool.d.ts +1 -0
  175. package/dist/types/langchain/messages.d.ts +2 -0
  176. package/dist/types/langchain/openai.d.ts +1 -0
  177. package/dist/types/langchain/prompts.d.ts +1 -0
  178. package/dist/types/langchain/runnables.d.ts +2 -0
  179. package/dist/types/langchain/tools.d.ts +2 -0
  180. package/dist/types/langchain/utils/env.d.ts +1 -0
  181. package/dist/types/llm/anthropic/index.d.ts +22 -9
  182. package/dist/types/llm/anthropic/types.d.ts +5 -1
  183. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +13 -6
  184. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +1 -1
  185. package/dist/types/llm/openai/index.d.ts +21 -24
  186. package/dist/types/llm/openrouter/index.d.ts +11 -9
  187. package/dist/types/llm/vertexai/index.d.ts +1 -0
  188. package/dist/types/messages/cache.d.ts +4 -1
  189. package/dist/types/messages/format.d.ts +4 -1
  190. package/dist/types/messages/langchain.d.ts +27 -0
  191. package/dist/types/run.d.ts +117 -1
  192. package/dist/types/tools/ToolNode.d.ts +26 -1
  193. package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
  194. package/dist/types/tools/search/tavily-search.d.ts +4 -0
  195. package/dist/types/tools/search/types.d.ts +99 -5
  196. package/dist/types/tools/search/utils.d.ts +2 -2
  197. package/dist/types/types/graph.d.ts +23 -37
  198. package/dist/types/types/hitl.d.ts +272 -0
  199. package/dist/types/types/index.d.ts +1 -0
  200. package/dist/types/types/llm.d.ts +3 -3
  201. package/dist/types/types/run.d.ts +33 -0
  202. package/dist/types/types/stream.d.ts +1 -1
  203. package/dist/types/types/tools.d.ts +19 -0
  204. package/package.json +80 -17
  205. package/src/graphs/Graph.ts +33 -4
  206. package/src/graphs/__tests__/composition.smoke.test.ts +188 -0
  207. package/src/hitl/askUserQuestion.ts +72 -0
  208. package/src/hitl/index.ts +7 -0
  209. package/src/hooks/HookRegistry.ts +71 -0
  210. package/src/hooks/__tests__/createToolPolicyHook.test.ts +259 -0
  211. package/src/hooks/createToolPolicyHook.ts +184 -0
  212. package/src/hooks/executeHooks.ts +50 -1
  213. package/src/hooks/index.ts +6 -0
  214. package/src/hooks/types.ts +112 -0
  215. package/src/index.ts +22 -0
  216. package/src/langchain/google-common.ts +1 -0
  217. package/src/langchain/index.ts +8 -0
  218. package/src/langchain/language_models/chat_models.ts +1 -0
  219. package/src/langchain/messages/tool.ts +5 -0
  220. package/src/langchain/messages.ts +21 -0
  221. package/src/langchain/openai.ts +1 -0
  222. package/src/langchain/prompts.ts +1 -0
  223. package/src/langchain/runnables.ts +7 -0
  224. package/src/langchain/tools.ts +8 -0
  225. package/src/langchain/utils/env.ts +1 -0
  226. package/src/llm/anthropic/index.ts +252 -84
  227. package/src/llm/anthropic/llm.spec.ts +751 -102
  228. package/src/llm/anthropic/types.ts +9 -1
  229. package/src/llm/anthropic/utils/message_inputs.ts +37 -19
  230. package/src/llm/anthropic/utils/message_outputs.ts +119 -101
  231. package/src/llm/bedrock/index.ts +2 -2
  232. package/src/llm/bedrock/llm.spec.ts +341 -0
  233. package/src/llm/bedrock/utils/message_inputs.ts +303 -4
  234. package/src/llm/bedrock/utils/message_outputs.ts +2 -1
  235. package/src/llm/custom-chat-models.smoke.test.ts +836 -0
  236. package/src/llm/google/llm.spec.ts +339 -57
  237. package/src/llm/google/utils/common.ts +53 -48
  238. package/src/llm/openai/contentBlocks.test.ts +346 -0
  239. package/src/llm/openai/index.ts +856 -833
  240. package/src/llm/openai/utils/index.ts +107 -78
  241. package/src/llm/openai/utils/messages.test.ts +159 -0
  242. package/src/llm/openrouter/index.ts +124 -247
  243. package/src/llm/openrouter/reasoning.test.ts +8 -1
  244. package/src/llm/vertexai/index.ts +11 -5
  245. package/src/llm/vertexai/llm.spec.ts +28 -1
  246. package/src/messages/cache.test.ts +4 -3
  247. package/src/messages/cache.ts +3 -2
  248. package/src/messages/core.ts +16 -9
  249. package/src/messages/format.ts +96 -16
  250. package/src/messages/formatAgentMessages.test.ts +166 -1
  251. package/src/messages/langchain.ts +39 -0
  252. package/src/messages/prune.ts +12 -8
  253. package/src/run.ts +456 -47
  254. package/src/scripts/caching.ts +2 -3
  255. package/src/specs/summarization.test.ts +51 -58
  256. package/src/tools/ToolNode.ts +706 -63
  257. package/src/tools/__tests__/hitl.test.ts +3593 -0
  258. package/src/tools/search/search.ts +83 -73
  259. package/src/tools/search/tavily-scraper.ts +235 -0
  260. package/src/tools/search/tavily-search.ts +424 -0
  261. package/src/tools/search/tavily.test.ts +965 -0
  262. package/src/tools/search/tool.ts +36 -26
  263. package/src/tools/search/types.ts +133 -8
  264. package/src/tools/search/utils.ts +13 -5
  265. package/src/types/graph.ts +32 -87
  266. package/src/types/hitl.ts +303 -0
  267. package/src/types/index.ts +1 -0
  268. package/src/types/llm.ts +3 -3
  269. package/src/types/run.ts +33 -0
  270. package/src/types/stream.ts +1 -1
  271. package/src/types/tools.ts +19 -0
  272. package/src/utils/llmConfig.ts +1 -6
@@ -5,10 +5,22 @@
5
5
  import {
6
6
  type BaseMessage,
7
7
  isAIMessage,
8
+ type Data,
8
9
  parseBase64DataUrl,
9
10
  parseMimeType,
10
11
  MessageContentComplex,
12
+ type StandardContentBlockConverter,
13
+ convertToProviderContentBlock,
14
+ isDataContentBlock,
11
15
  } from '@langchain/core/messages';
16
+ import type {
17
+ AudioFormat,
18
+ AudioSource,
19
+ DocumentFormat,
20
+ DocumentSource,
21
+ VideoFormat,
22
+ VideoSource,
23
+ } from '@aws-sdk/client-bedrock-runtime';
12
24
  import type {
13
25
  BedrockMessage,
14
26
  BedrockSystemContentBlock,
@@ -127,6 +139,258 @@ export function extractImageInfo(base64: string): BedrockContentBlock {
127
139
  };
128
140
  }
129
141
 
142
+ type MediaContentBlock = MessageContentComplex & {
143
+ data?: string | Uint8Array;
144
+ url?: string;
145
+ fileId?: string;
146
+ mimeType?: string;
147
+ };
148
+
149
+ const mimeTypeToVideoFormat: Record<string, VideoFormat> = {
150
+ 'video/flv': 'flv',
151
+ 'video/mkv': 'mkv',
152
+ 'video/mov': 'mov',
153
+ 'video/mp4': 'mp4',
154
+ 'video/mpeg': 'mpeg',
155
+ 'video/mpg': 'mpg',
156
+ 'video/three_gp': 'three_gp',
157
+ 'video/webm': 'webm',
158
+ 'video/wmv': 'wmv',
159
+ };
160
+
161
+ const mimeTypeToAudioFormat: Record<string, AudioFormat> = {
162
+ 'audio/aac': 'aac',
163
+ 'audio/flac': 'flac',
164
+ 'audio/m4a': 'm4a',
165
+ 'audio/mka': 'mka',
166
+ 'audio/mkv': 'mkv',
167
+ 'audio/mp3': 'mp3',
168
+ 'audio/mp4': 'mp4',
169
+ 'audio/mpeg': 'mpeg',
170
+ 'audio/mpga': 'mpga',
171
+ 'audio/ogg': 'ogg',
172
+ 'audio/opus': 'opus',
173
+ 'audio/pcm': 'pcm',
174
+ 'audio/wav': 'wav',
175
+ 'audio/webm': 'webm',
176
+ 'audio/x-aac': 'x-aac',
177
+ };
178
+
179
+ const mimeTypeToDocumentFormat: Partial<Record<string, DocumentFormat>> = {
180
+ 'text/csv': 'csv',
181
+ 'application/msword': 'doc',
182
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
183
+ 'docx',
184
+ 'text/html': 'html',
185
+ 'text/markdown': 'md',
186
+ 'application/pdf': 'pdf',
187
+ 'text/plain': 'txt',
188
+ 'application/vnd.ms-excel': 'xls',
189
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
190
+ };
191
+
192
+ function base64ToBytes(data: string): Uint8Array {
193
+ return Uint8Array.from(atob(data), (char) => char.charCodeAt(0));
194
+ }
195
+
196
+ function getMediaFormat<T extends string>(
197
+ mimeType: string | undefined,
198
+ formatMap: Record<string, T>
199
+ ): T | undefined {
200
+ if (mimeType == null || mimeType === '') {
201
+ return undefined;
202
+ }
203
+ return formatMap[mimeType] ?? (parseMimeType(mimeType).subtype as T);
204
+ }
205
+
206
+ function resolveMediaSource(
207
+ block: MediaContentBlock
208
+ ): AudioSource | VideoSource {
209
+ if (typeof block.data === 'string') {
210
+ return { bytes: base64ToBytes(block.data) };
211
+ }
212
+ if (block.data instanceof Uint8Array) {
213
+ return { bytes: block.data };
214
+ }
215
+ if (typeof block.url === 'string') {
216
+ const parsedData = parseBase64DataUrl({
217
+ dataUrl: block.url,
218
+ asTypedArray: true,
219
+ });
220
+ if (parsedData != null) {
221
+ return { bytes: parsedData.data as Uint8Array };
222
+ }
223
+ throw new Error(
224
+ `Only base64 data URLs are supported for ${block.type} blocks with 'url' field with ChatBedrockConverse.`
225
+ );
226
+ }
227
+ if (typeof block.fileId === 'string') {
228
+ return { s3Location: { uri: block.fileId } };
229
+ }
230
+ throw new Error(
231
+ `${block.type} block must include one of: 'data' (base64 string or Uint8Array), 'url' (base64 data URL), or 'fileId' (S3 URI).`
232
+ );
233
+ }
234
+
235
+ function convertMultimodalVideoBlock(
236
+ block: MediaContentBlock
237
+ ): BedrockContentBlock {
238
+ return {
239
+ video: {
240
+ format: getMediaFormat(block.mimeType, mimeTypeToVideoFormat),
241
+ source: resolveMediaSource(block) as VideoSource,
242
+ },
243
+ } as BedrockContentBlock;
244
+ }
245
+
246
+ function convertMultimodalAudioBlock(
247
+ block: MediaContentBlock
248
+ ): BedrockContentBlock {
249
+ return {
250
+ audio: {
251
+ format: getMediaFormat(block.mimeType, mimeTypeToAudioFormat),
252
+ source: resolveMediaSource(block) as AudioSource,
253
+ },
254
+ } as BedrockContentBlock;
255
+ }
256
+
257
+ function getDocumentName(block: Data.StandardFileBlock): string {
258
+ return (
259
+ (block.metadata?.name as string | undefined) ??
260
+ (block.metadata?.filename as string | undefined) ??
261
+ (block.metadata?.title as string | undefined) ??
262
+ globalThis.crypto.randomUUID().replace(/-/g, '').slice(0, 12)
263
+ );
264
+ }
265
+
266
+ function getDocumentFormat(
267
+ mimeType: string | undefined
268
+ ): DocumentFormat | undefined {
269
+ if (mimeType == null || mimeType === '') {
270
+ return undefined;
271
+ }
272
+ const parsedMimeType = parseMimeType(mimeType);
273
+ const format =
274
+ mimeTypeToDocumentFormat[
275
+ `${parsedMimeType.type}/${parsedMimeType.subtype}`
276
+ ];
277
+ if (format === undefined) {
278
+ throw new Error(
279
+ `Unsupported file mime type: "${mimeType}" ChatBedrockConverse only supports ${Object.keys(
280
+ mimeTypeToDocumentFormat
281
+ ).join(', ')} formats.`
282
+ );
283
+ }
284
+ return format;
285
+ }
286
+
287
+ const standardContentBlockConverter: StandardContentBlockConverter<{
288
+ text: BedrockContentBlock;
289
+ image: BedrockContentBlock;
290
+ file: BedrockContentBlock;
291
+ }> = {
292
+ providerName: 'ChatBedrockConverse',
293
+
294
+ fromStandardTextBlock(block: Data.StandardTextBlock): BedrockContentBlock {
295
+ return { text: block.text };
296
+ },
297
+
298
+ fromStandardImageBlock(block: Data.StandardImageBlock): BedrockContentBlock {
299
+ if (block.source_type === 'url') {
300
+ const parsedData = parseBase64DataUrl({
301
+ dataUrl: block.url,
302
+ asTypedArray: true,
303
+ });
304
+ if (parsedData == null) {
305
+ throw new Error(
306
+ [
307
+ 'Only base64 data URLs are supported for image blocks with source type ',
308
+ 'url',
309
+ ' with ChatBedrockConverse.',
310
+ ].join(String.fromCharCode(39))
311
+ );
312
+ }
313
+ return {
314
+ image: {
315
+ format: parseMimeType(parsedData.mime_type).subtype as
316
+ | 'gif'
317
+ | 'jpeg'
318
+ | 'png'
319
+ | 'webp',
320
+ source: { bytes: parsedData.data as Uint8Array },
321
+ },
322
+ };
323
+ }
324
+ if (block.source_type === 'base64') {
325
+ let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;
326
+ if (block.mime_type != null && block.mime_type !== '') {
327
+ format = parseMimeType(block.mime_type).subtype as typeof format;
328
+ }
329
+ if (format != null && !['gif', 'jpeg', 'png', 'webp'].includes(format)) {
330
+ throw new Error(
331
+ `Unsupported image mime type: "${block.mime_type}" ChatBedrockConverse only supports "image/gif", "image/jpeg", "image/png", and "image/webp" formats.`
332
+ );
333
+ }
334
+ return {
335
+ image: {
336
+ format,
337
+ source: { bytes: base64ToBytes(block.data) },
338
+ },
339
+ };
340
+ }
341
+ throw new Error(
342
+ `Image source type '${block.source_type}' not supported with ChatBedrockConverse.`
343
+ );
344
+ },
345
+
346
+ fromStandardFileBlock(block: Data.StandardFileBlock): BedrockContentBlock {
347
+ const name = getDocumentName(block);
348
+ if (block.source_type === 'text') {
349
+ return {
350
+ document: {
351
+ name,
352
+ format: 'txt',
353
+ source: { bytes: new TextEncoder().encode(block.text) },
354
+ },
355
+ } as BedrockContentBlock;
356
+ }
357
+ if (block.source_type === 'url') {
358
+ const parsedData = parseBase64DataUrl({
359
+ dataUrl: block.url,
360
+ asTypedArray: true,
361
+ });
362
+ if (parsedData == null) {
363
+ throw new Error(
364
+ [
365
+ 'Only base64 data URLs are supported for file blocks with source type ',
366
+ 'url',
367
+ ' with ChatBedrockConverse.',
368
+ ].join(String.fromCharCode(39))
369
+ );
370
+ }
371
+ return {
372
+ document: {
373
+ name,
374
+ format: getDocumentFormat(parsedData.mime_type),
375
+ source: { bytes: parsedData.data as Uint8Array } as DocumentSource,
376
+ },
377
+ } as BedrockContentBlock;
378
+ }
379
+ if (block.source_type === 'base64') {
380
+ return {
381
+ document: {
382
+ name,
383
+ format: getDocumentFormat(block.mime_type),
384
+ source: { bytes: base64ToBytes(block.data) } as DocumentSource,
385
+ },
386
+ } as BedrockContentBlock;
387
+ }
388
+ throw new Error(
389
+ `File source type '${block.source_type}' not supported with ChatBedrockConverse.`
390
+ );
391
+ },
392
+ };
393
+
130
394
  /**
131
395
  * Check if a block has a cache point.
132
396
  */
@@ -161,6 +425,10 @@ function convertLangChainContentBlockToConverseContentBlock({
161
425
  return { text: block };
162
426
  }
163
427
 
428
+ if (isDataContentBlock(block)) {
429
+ return convertToProviderContentBlock(block, standardContentBlockConverter);
430
+ }
431
+
164
432
  if (block.type === 'text') {
165
433
  return { text: (block as { text: string }).text };
166
434
  }
@@ -231,6 +499,32 @@ function convertLangChainContentBlockToConverseContentBlock({
231
499
  }
232
500
  }
233
501
 
502
+ if (
503
+ block.type === 'video' &&
504
+ (block as { video?: unknown }).video !== undefined
505
+ ) {
506
+ return {
507
+ video: (block as { video: unknown }).video,
508
+ } as BedrockContentBlock;
509
+ }
510
+
511
+ if (block.type === 'video') {
512
+ return convertMultimodalVideoBlock(block as MediaContentBlock);
513
+ }
514
+
515
+ if (
516
+ block.type === 'audio' &&
517
+ (block as { audio?: unknown }).audio !== undefined
518
+ ) {
519
+ return {
520
+ audio: (block as { audio: unknown }).audio,
521
+ } as BedrockContentBlock;
522
+ }
523
+
524
+ if (block.type === 'audio') {
525
+ return convertMultimodalAudioBlock(block as MediaContentBlock);
526
+ }
527
+
234
528
  if (
235
529
  block.type === 'document' &&
236
530
  (block as { document?: unknown }).document !== undefined
@@ -298,7 +592,10 @@ function convertSystemMessageToConverseMessage(
298
592
  */
299
593
  function convertAIMessageToConverseMessage(msg: BaseMessage): BedrockMessage {
300
594
  // Check for v1 format from other providers (PR #9766 fix)
301
- if (msg.response_metadata.output_version === 'v1') {
595
+ const responseMetadata = msg.response_metadata as
596
+ | { output_version?: string }
597
+ | undefined;
598
+ if (responseMetadata?.output_version === 'v1') {
302
599
  return convertFromV1ToChatBedrockConverseMessage(msg);
303
600
  }
304
601
 
@@ -392,7 +689,9 @@ function convertFromV1ToChatBedrockConverseMessage(
392
689
  };
393
690
 
394
691
  if (Array.isArray(msg.content)) {
395
- for (const block of msg.content) {
692
+ for (const block of msg.content as Array<
693
+ MessageContentComplex | MessageContentReasoningBlock
694
+ >) {
396
695
  if (typeof block === 'string') {
397
696
  assistantMsg.content?.push({ text: block });
398
697
  } else if (block.type === 'text') {
@@ -539,11 +838,11 @@ export function convertToConverseMessages(messages: BaseMessage[]): {
539
838
  // Combine consecutive user tool result messages into a single message
540
839
  const combinedConverseMessages = converseMessages.reduce<BedrockMessage[]>(
541
840
  (acc, curr) => {
542
- const lastMessage = acc[acc.length - 1];
543
- if (lastMessage == null) {
841
+ if (acc.length === 0) {
544
842
  acc.push(curr);
545
843
  return acc;
546
844
  }
845
+ const lastMessage = acc[acc.length - 1];
547
846
  const lastHasToolResult =
548
847
  lastMessage.content?.some((c) => 'toolResult' in c) === true;
549
848
  const currHasToolResult =
@@ -17,6 +17,7 @@ import type {
17
17
  MessageContentReasoningBlockReasoningTextPartial,
18
18
  MessageContentReasoningBlockRedacted,
19
19
  } from '../types';
20
+ import { toLangChainContent } from '@/messages/langchain';
20
21
 
21
22
  /**
22
23
  * Convert a Bedrock reasoning block delta to a LangChain partial reasoning block.
@@ -251,7 +252,7 @@ export function handleConverseStreamContentBlockDelta(
251
252
  return new ChatGenerationChunk({
252
253
  text: '',
253
254
  message: new AIMessageChunk({
254
- content: [reasoningBlock],
255
+ content: toLangChainContent([reasoningBlock]),
255
256
  additional_kwargs: {
256
257
  // Set reasoning_content for stream handler to detect reasoning mode
257
258
  reasoning_content: reasoningText,