@librechat/agents 3.2.64 → 3.2.66

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 (106) hide show
  1. package/dist/cjs/graphs/Graph.cjs +18 -2
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/instrumentation.cjs +15 -3
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/langfuseToolOutputTracing.cjs +1 -2
  6. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  7. package/dist/cjs/langfuseTraceShaping.cjs +51 -24
  8. package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
  9. package/dist/cjs/llm/anthropic/index.cjs +73 -9
  10. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  11. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  12. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +49 -9
  13. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  14. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +3 -1
  15. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  16. package/dist/cjs/llm/anthropic/utils/stream_events.cjs +337 -0
  17. package/dist/cjs/llm/anthropic/utils/stream_events.cjs.map +1 -0
  18. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +8 -0
  19. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/tools/BashExecutor.cjs +9 -8
  21. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  22. package/dist/cjs/tools/CodeExecutor.cjs +9 -7
  23. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  24. package/dist/cjs/tools/search/crw-scraper.cjs +165 -0
  25. package/dist/cjs/tools/search/crw-scraper.cjs.map +1 -0
  26. package/dist/cjs/tools/search/crw-search.cjs +105 -0
  27. package/dist/cjs/tools/search/crw-search.cjs.map +1 -0
  28. package/dist/cjs/tools/search/search.cjs +4 -2
  29. package/dist/cjs/tools/search/search.cjs.map +1 -1
  30. package/dist/cjs/tools/search/tool.cjs +15 -3
  31. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  32. package/dist/esm/graphs/Graph.mjs +18 -2
  33. package/dist/esm/graphs/Graph.mjs.map +1 -1
  34. package/dist/esm/instrumentation.mjs +15 -3
  35. package/dist/esm/instrumentation.mjs.map +1 -1
  36. package/dist/esm/langfuseToolOutputTracing.mjs +1 -2
  37. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  38. package/dist/esm/langfuseTraceShaping.mjs +51 -24
  39. package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
  40. package/dist/esm/llm/anthropic/index.mjs +73 -9
  41. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  42. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  43. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +49 -9
  44. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  45. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +3 -2
  46. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  47. package/dist/esm/llm/anthropic/utils/stream_events.mjs +337 -0
  48. package/dist/esm/llm/anthropic/utils/stream_events.mjs.map +1 -0
  49. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +8 -0
  50. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  51. package/dist/esm/tools/BashExecutor.mjs +9 -8
  52. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  53. package/dist/esm/tools/CodeExecutor.mjs +9 -7
  54. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  55. package/dist/esm/tools/search/crw-scraper.mjs +163 -0
  56. package/dist/esm/tools/search/crw-scraper.mjs.map +1 -0
  57. package/dist/esm/tools/search/crw-search.mjs +103 -0
  58. package/dist/esm/tools/search/crw-search.mjs.map +1 -0
  59. package/dist/esm/tools/search/search.mjs +4 -2
  60. package/dist/esm/tools/search/search.mjs.map +1 -1
  61. package/dist/esm/tools/search/tool.mjs +15 -3
  62. package/dist/esm/tools/search/tool.mjs.map +1 -1
  63. package/dist/types/graphs/Graph.d.ts +2 -0
  64. package/dist/types/langfuseTraceShaping.d.ts +12 -6
  65. package/dist/types/llm/anthropic/index.d.ts +2 -0
  66. package/dist/types/llm/anthropic/types.d.ts +2 -0
  67. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -2
  68. package/dist/types/llm/anthropic/utils/stream_events.d.ts +25 -0
  69. package/dist/types/tools/BashExecutor.d.ts +7 -6
  70. package/dist/types/tools/CodeExecutor.d.ts +7 -5
  71. package/dist/types/tools/search/crw-scraper.d.ts +41 -0
  72. package/dist/types/tools/search/crw-search.d.ts +4 -0
  73. package/dist/types/tools/search/types.d.ts +88 -3
  74. package/dist/types/types/graph.d.ts +10 -3
  75. package/package.json +1 -1
  76. package/src/graphs/Graph.ts +36 -3
  77. package/src/instrumentation.ts +20 -0
  78. package/src/langfuseToolOutputTracing.ts +2 -4
  79. package/src/langfuseTraceShaping.ts +73 -20
  80. package/src/llm/anthropic/index.ts +134 -10
  81. package/src/llm/anthropic/inherited-content-utils.spec.ts +10 -5
  82. package/src/llm/anthropic/inherited-stream-events.spec.ts +513 -9
  83. package/src/llm/anthropic/llm.spec.ts +100 -16
  84. package/src/llm/anthropic/types.ts +3 -0
  85. package/src/llm/anthropic/utils/cross-provider-server-tools.test.ts +110 -0
  86. package/src/llm/anthropic/utils/message_inputs.ts +75 -3
  87. package/src/llm/anthropic/utils/message_outputs.ts +10 -2
  88. package/src/llm/anthropic/utils/stream_events.ts +471 -0
  89. package/src/llm/bedrock/utils/cross-provider-server-tools.test.ts +122 -0
  90. package/src/llm/bedrock/utils/message_inputs.ts +13 -0
  91. package/src/specs/langfuse-instrumentation.test.ts +64 -0
  92. package/src/specs/langfuse-routing.integration.test.ts +49 -4
  93. package/src/specs/langfuse-tool-output-tracing.test.ts +5 -4
  94. package/src/specs/langfuse-trace-shaping.test.ts +80 -9
  95. package/src/specs/subagent.test.ts +180 -0
  96. package/src/tools/BashExecutor.ts +9 -8
  97. package/src/tools/CodeExecutor.ts +9 -7
  98. package/src/tools/__tests__/BashExecutor.test.ts +16 -5
  99. package/src/tools/__tests__/CodeExecutor.stateful.test.ts +17 -6
  100. package/src/tools/search/crw-scraper.ts +244 -0
  101. package/src/tools/search/crw-search.ts +167 -0
  102. package/src/tools/search/crw.test.ts +836 -0
  103. package/src/tools/search/search.ts +7 -1
  104. package/src/tools/search/tool.ts +23 -3
  105. package/src/tools/search/types.ts +103 -3
  106. package/src/types/graph.ts +10 -3
@@ -0,0 +1,337 @@
1
+ const require_message_outputs = require("./message_outputs.cjs");
2
+ //#region src/llm/anthropic/utils/stream_events.ts
3
+ /**
4
+ * Convert an async iterable of raw Anthropic stream events into
5
+ * LangChain `ChatModelStreamEvent`s with typed deltas.
6
+ */
7
+ async function* convertAnthropicStream(source, options = {}) {
8
+ const shouldStreamUsage = options.streamUsage ?? true;
9
+ const blockAccumulators = /* @__PURE__ */ new Map();
10
+ let usageSnapshot;
11
+ let eventUsage;
12
+ let stopReason = null;
13
+ for await (const data of source) switch (data.type) {
14
+ case "message_start": {
15
+ const { usage, id, model } = data.message;
16
+ if (shouldStreamUsage) {
17
+ eventUsage = {
18
+ inputTokens: usage.input_tokens,
19
+ cacheCreationInputTokens: usage.cache_creation_input_tokens ?? 0,
20
+ cacheReadInputTokens: usage.cache_read_input_tokens ?? 0,
21
+ outputTokens: usage.output_tokens
22
+ };
23
+ usageSnapshot = buildUsageSnapshot(eventUsage);
24
+ }
25
+ yield {
26
+ event: "message-start",
27
+ id,
28
+ ...usageSnapshot ? { usage: usageSnapshot } : {}
29
+ };
30
+ yield {
31
+ event: "provider",
32
+ provider: "anthropic",
33
+ name: "message_start",
34
+ payload: {
35
+ model,
36
+ id
37
+ }
38
+ };
39
+ break;
40
+ }
41
+ case "message_delta":
42
+ stopReason = data.delta.stop_reason;
43
+ if (shouldStreamUsage) {
44
+ eventUsage = updateEventUsage(eventUsage, data.usage);
45
+ usageSnapshot = buildUsageSnapshot(eventUsage);
46
+ yield {
47
+ event: "usage",
48
+ usage: usageSnapshot
49
+ };
50
+ }
51
+ if ("context_management" in data.delta && data.delta.context_management != null) yield {
52
+ event: "provider",
53
+ provider: "anthropic",
54
+ name: "context_management",
55
+ payload: data.delta.context_management
56
+ };
57
+ break;
58
+ case "message_stop":
59
+ yield {
60
+ event: "message-finish",
61
+ reason: mapStopReason(stopReason),
62
+ ...usageSnapshot ? { usage: usageSnapshot } : {},
63
+ responseMetadata: { model_provider: "anthropic" }
64
+ };
65
+ break;
66
+ case "error": {
67
+ const streamError = new Error(data.error.message);
68
+ streamError.name = data.error.type;
69
+ throw streamError;
70
+ }
71
+ case "content_block_start": {
72
+ const { index, content_block } = data;
73
+ const mapped = mapBlockToContentBlock(content_block, index);
74
+ blockAccumulators.set(index, { ...mapped });
75
+ yield {
76
+ event: "content-block-start",
77
+ index,
78
+ content: mapped
79
+ };
80
+ break;
81
+ }
82
+ case "content_block_delta": {
83
+ const { index, delta } = data;
84
+ const acc = blockAccumulators.get(index);
85
+ if (!acc) break;
86
+ const { contentDelta, accumulated } = applyAnthropicDelta(acc, delta);
87
+ blockAccumulators.set(index, accumulated);
88
+ yield {
89
+ event: "content-block-delta",
90
+ index,
91
+ delta: contentDelta
92
+ };
93
+ break;
94
+ }
95
+ case "content_block_stop": {
96
+ const { index } = data;
97
+ const acc = blockAccumulators.get(index);
98
+ if (!acc) break;
99
+ yield {
100
+ event: "content-block-finish",
101
+ index,
102
+ content: finalizeBlock(acc)
103
+ };
104
+ blockAccumulators.delete(index);
105
+ break;
106
+ }
107
+ default: {
108
+ const providerData = data;
109
+ yield {
110
+ event: "provider",
111
+ provider: "anthropic",
112
+ name: providerData.type,
113
+ payload: providerData
114
+ };
115
+ break;
116
+ }
117
+ }
118
+ }
119
+ function mapStopReason(stopReason) {
120
+ switch (stopReason) {
121
+ case "end_turn":
122
+ case "stop_sequence": return "stop";
123
+ case "tool_use": return "tool_use";
124
+ case "max_tokens":
125
+ case "model_context_window_exceeded": return "length";
126
+ case "refusal": return "content_filter";
127
+ default: return "stop";
128
+ }
129
+ }
130
+ function updateEventUsage(previous, current) {
131
+ return {
132
+ inputTokens: getCumulativeUsageValue(current.input_tokens, previous?.inputTokens),
133
+ cacheCreationInputTokens: getCumulativeUsageValue(current.cache_creation_input_tokens, previous?.cacheCreationInputTokens),
134
+ cacheReadInputTokens: getCumulativeUsageValue(current.cache_read_input_tokens, previous?.cacheReadInputTokens),
135
+ outputTokens: getCumulativeUsageValue(current.output_tokens, previous?.outputTokens)
136
+ };
137
+ }
138
+ function getCumulativeUsageValue(current, previous) {
139
+ return Math.max(previous ?? 0, current ?? 0);
140
+ }
141
+ function buildUsageSnapshot(usage) {
142
+ const metadata = require_message_outputs.getAnthropicUsageMetadata({
143
+ input_tokens: usage.inputTokens,
144
+ output_tokens: usage.outputTokens,
145
+ cache_creation_input_tokens: usage.cacheCreationInputTokens,
146
+ cache_read_input_tokens: usage.cacheReadInputTokens
147
+ });
148
+ if (metadata == null) throw new Error("Anthropic usage metadata was not created");
149
+ return metadata;
150
+ }
151
+ function getStringField(record, key) {
152
+ const value = record[key];
153
+ return typeof value === "string" ? value : "";
154
+ }
155
+ function getArrayField(record, key) {
156
+ const value = record[key];
157
+ return Array.isArray(value) ? value : [];
158
+ }
159
+ function mapBlockToContentBlock(block, index) {
160
+ switch (block.type) {
161
+ case "text": return {
162
+ type: "text",
163
+ text: block.text,
164
+ ...block.citations != null ? { citations: block.citations } : {},
165
+ index
166
+ };
167
+ case "thinking": return {
168
+ type: "reasoning",
169
+ reasoning: block.thinking,
170
+ index
171
+ };
172
+ case "redacted_thinking": return {
173
+ ...block,
174
+ index
175
+ };
176
+ case "tool_use": return {
177
+ type: "tool_call_chunk",
178
+ id: block.id,
179
+ name: block.name,
180
+ args: "",
181
+ index
182
+ };
183
+ case "server_tool_use": return {
184
+ type: "server_tool_call_chunk",
185
+ id: block.id,
186
+ name: block.name,
187
+ args: "",
188
+ index
189
+ };
190
+ case "web_search_tool_result": return {
191
+ ...block,
192
+ index
193
+ };
194
+ case "compaction": return {
195
+ ...block,
196
+ index
197
+ };
198
+ default: return {
199
+ type: "non_standard",
200
+ value: { ...block },
201
+ index
202
+ };
203
+ }
204
+ }
205
+ /**
206
+ * Map an Anthropic content_block_delta to a content block delta
207
+ * and update the accumulated state.
208
+ */
209
+ function applyAnthropicDelta(accumulated, delta) {
210
+ const rawDelta = delta;
211
+ switch (delta.type) {
212
+ case "text_delta": return {
213
+ contentDelta: {
214
+ type: "text-delta",
215
+ text: delta.text
216
+ },
217
+ accumulated: {
218
+ ...accumulated,
219
+ text: getStringField(accumulated, "text") + delta.text
220
+ }
221
+ };
222
+ case "thinking_delta": return {
223
+ contentDelta: {
224
+ type: "reasoning-delta",
225
+ reasoning: delta.thinking
226
+ },
227
+ accumulated: {
228
+ ...accumulated,
229
+ reasoning: getStringField(accumulated, "reasoning") + delta.thinking
230
+ }
231
+ };
232
+ case "input_json_delta": {
233
+ const newArgs = getStringField(accumulated, "args") + delta.partial_json;
234
+ return {
235
+ contentDelta: {
236
+ type: "block-delta",
237
+ fields: {
238
+ type: getStringField(accumulated, "type"),
239
+ args: newArgs
240
+ }
241
+ },
242
+ accumulated: {
243
+ ...accumulated,
244
+ args: newArgs
245
+ }
246
+ };
247
+ }
248
+ case "citations_delta": {
249
+ const citations = [...getArrayField(accumulated, "citations"), delta.citation];
250
+ return {
251
+ contentDelta: {
252
+ type: "block-delta",
253
+ fields: {
254
+ type: getStringField(accumulated, "type"),
255
+ citations
256
+ }
257
+ },
258
+ accumulated: {
259
+ ...accumulated,
260
+ citations
261
+ }
262
+ };
263
+ }
264
+ case "signature_delta": return {
265
+ contentDelta: {
266
+ type: "block-delta",
267
+ fields: {
268
+ type: getStringField(accumulated, "type"),
269
+ signature: delta.signature
270
+ }
271
+ },
272
+ accumulated: {
273
+ ...accumulated,
274
+ signature: delta.signature
275
+ }
276
+ };
277
+ case "compaction_delta": {
278
+ const previousContent = accumulated.content;
279
+ const content = delta.content == null ? previousContent ?? null : getStringField(accumulated, "content") + delta.content;
280
+ return {
281
+ contentDelta: {
282
+ type: "block-delta",
283
+ fields: {
284
+ type: "compaction",
285
+ content,
286
+ encrypted_content: delta.encrypted_content
287
+ }
288
+ },
289
+ accumulated: {
290
+ ...accumulated,
291
+ content,
292
+ encrypted_content: delta.encrypted_content
293
+ }
294
+ };
295
+ }
296
+ default: return {
297
+ contentDelta: {
298
+ type: "block-delta",
299
+ fields: {
300
+ type: getStringField(accumulated, "type"),
301
+ ...rawDelta
302
+ }
303
+ },
304
+ accumulated
305
+ };
306
+ }
307
+ }
308
+ function finalizeBlock(accumulated) {
309
+ if (accumulated.type === "tool_call_chunk" || accumulated.type === "server_tool_call_chunk") {
310
+ const finalType = accumulated.type === "tool_call_chunk" ? "tool_call" : "server_tool_call";
311
+ const args = getStringField(accumulated, "args");
312
+ let parsedArgs;
313
+ try {
314
+ parsedArgs = JSON.parse(args || "{}");
315
+ } catch {
316
+ return {
317
+ type: "invalid_tool_call",
318
+ id: getStringField(accumulated, "id"),
319
+ name: getStringField(accumulated, "name"),
320
+ args,
321
+ error: "Failed to parse tool call arguments as JSON"
322
+ };
323
+ }
324
+ return {
325
+ type: finalType,
326
+ id: getStringField(accumulated, "id"),
327
+ name: getStringField(accumulated, "name"),
328
+ args: parsedArgs
329
+ };
330
+ }
331
+ const { index: _index, ...rest } = accumulated;
332
+ return rest;
333
+ }
334
+ //#endregion
335
+ exports.convertAnthropicStream = convertAnthropicStream;
336
+
337
+ //# sourceMappingURL=stream_events.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream_events.cjs","names":["getAnthropicUsageMetadata"],"sources":["../../../../../src/llm/anthropic/utils/stream_events.ts"],"sourcesContent":["/**\n * Converts a raw Anthropic SSE event stream into LangChain ChatModelStreamEvents.\n *\n * @module\n */\n\nimport type {\n ChatModelStreamEvent,\n ContentBlockDelta,\n FinishReason,\n} from '@langchain/core/language_models/event';\nimport type { ContentBlock, UsageMetadata } from '@langchain/core/messages';\nimport type {\n AnthropicCompactionBlock,\n AnthropicCompactionContentBlockDelta,\n AnthropicMessageStreamEvent,\n} from '../types';\nimport type { AnthropicUsageData } from './message_outputs';\nimport { getAnthropicUsageMetadata } from './message_outputs';\n\ntype AnthropicContentBlock =\n | Extract<\n AnthropicMessageStreamEvent,\n { type: 'content_block_start' }\n >['content_block']\n | AnthropicCompactionBlock;\n\ntype AnthropicContentDelta =\n | Extract<\n AnthropicMessageStreamEvent,\n { type: 'content_block_delta' }\n >['delta']\n | AnthropicCompactionContentBlockDelta;\n\ninterface AnthropicStreamErrorEvent {\n type: 'error';\n error: {\n type: string;\n message: string;\n };\n request_id?: string | null;\n}\n\ntype AnthropicStreamInputEvent =\n | AnthropicMessageStreamEvent\n | AnthropicStreamErrorEvent;\n\ntype BlockAccumulator = Record<string, unknown>;\n\ninterface AnthropicEventUsage {\n inputTokens: number;\n cacheCreationInputTokens: number;\n cacheReadInputTokens: number;\n outputTokens: number;\n}\n\n// ─── Public API ─────────────────────────────────────────────────\n\nexport interface ConvertAnthropicStreamOptions {\n streamUsage?: boolean;\n}\n\n/**\n * Convert an async iterable of raw Anthropic stream events into\n * LangChain `ChatModelStreamEvent`s with typed deltas.\n */\nexport async function* convertAnthropicStream(\n source: AsyncIterable<AnthropicStreamInputEvent>,\n options: ConvertAnthropicStreamOptions = {}\n): AsyncGenerator<ChatModelStreamEvent> {\n const shouldStreamUsage = options.streamUsage ?? true;\n\n // Track accumulated state per content block (for finalization)\n const blockAccumulators = new Map<number, BlockAccumulator>();\n let usageSnapshot: UsageMetadata | undefined;\n let eventUsage: AnthropicEventUsage | undefined;\n let stopReason: string | null = null;\n\n for await (const data of source) {\n switch (data.type) {\n // ── Message lifecycle ──────────────────────────────────\n case 'message_start': {\n const { usage, id, model } = data.message;\n if (shouldStreamUsage) {\n eventUsage = {\n inputTokens: usage.input_tokens,\n cacheCreationInputTokens: usage.cache_creation_input_tokens ?? 0,\n cacheReadInputTokens: usage.cache_read_input_tokens ?? 0,\n outputTokens: usage.output_tokens,\n };\n usageSnapshot = buildUsageSnapshot(eventUsage);\n }\n yield {\n event: 'message-start' as const,\n id,\n ...(usageSnapshot ? { usage: usageSnapshot } : {}),\n };\n yield {\n event: 'provider' as const,\n provider: 'anthropic',\n name: 'message_start',\n payload: { model, id },\n };\n break;\n }\n\n case 'message_delta': {\n stopReason = data.delta.stop_reason;\n if (shouldStreamUsage) {\n eventUsage = updateEventUsage(eventUsage, data.usage);\n usageSnapshot = buildUsageSnapshot(eventUsage);\n yield { event: 'usage' as const, usage: usageSnapshot };\n }\n if (\n 'context_management' in data.delta &&\n data.delta.context_management != null\n ) {\n yield {\n event: 'provider' as const,\n provider: 'anthropic',\n name: 'context_management',\n payload: data.delta.context_management,\n };\n }\n break;\n }\n\n case 'message_stop': {\n const finishEvent = {\n event: 'message-finish' as const,\n reason: mapStopReason(stopReason),\n ...(usageSnapshot ? { usage: usageSnapshot } : {}),\n responseMetadata: { model_provider: 'anthropic' },\n };\n yield finishEvent;\n break;\n }\n\n case 'error': {\n const streamError = new Error(data.error.message);\n streamError.name = data.error.type;\n throw streamError;\n }\n\n // ── Content block lifecycle ───────────────────────────\n case 'content_block_start': {\n const { index, content_block } = data;\n const mapped = mapBlockToContentBlock(content_block, index);\n blockAccumulators.set(index, { ...mapped });\n yield {\n event: 'content-block-start' as const,\n index,\n content: mapped as unknown as ContentBlock,\n };\n break;\n }\n\n case 'content_block_delta': {\n const { index, delta } = data;\n const acc = blockAccumulators.get(index);\n if (!acc) break;\n\n const { contentDelta, accumulated } = applyAnthropicDelta(acc, delta);\n blockAccumulators.set(index, accumulated);\n\n yield {\n event: 'content-block-delta' as const,\n index,\n delta: contentDelta,\n };\n break;\n }\n\n case 'content_block_stop': {\n const { index } = data;\n const acc = blockAccumulators.get(index);\n if (!acc) break;\n\n const finalized = finalizeBlock(acc);\n yield {\n event: 'content-block-finish' as const,\n index,\n content: finalized,\n };\n blockAccumulators.delete(index);\n break;\n }\n\n // ── Unhandled → provider passthrough ───────────────────\n default: {\n const providerData = data as AnthropicMessageStreamEvent;\n yield {\n event: 'provider' as const,\n provider: 'anthropic',\n name: providerData.type,\n payload: providerData,\n };\n break;\n }\n }\n }\n}\n\n// ─── Internal helpers ───────────────────────────────────────────\n\nfunction mapStopReason(stopReason: string | null | undefined): FinishReason {\n switch (stopReason) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool_use';\n case 'max_tokens':\n case 'model_context_window_exceeded':\n return 'length';\n case 'refusal':\n return 'content_filter';\n default:\n return 'stop';\n }\n}\n\nfunction updateEventUsage(\n previous: AnthropicEventUsage | undefined,\n current: AnthropicUsageData\n): AnthropicEventUsage {\n return {\n inputTokens: getCumulativeUsageValue(\n current.input_tokens,\n previous?.inputTokens\n ),\n cacheCreationInputTokens: getCumulativeUsageValue(\n current.cache_creation_input_tokens,\n previous?.cacheCreationInputTokens\n ),\n cacheReadInputTokens: getCumulativeUsageValue(\n current.cache_read_input_tokens,\n previous?.cacheReadInputTokens\n ),\n outputTokens: getCumulativeUsageValue(\n current.output_tokens,\n previous?.outputTokens\n ),\n };\n}\n\nfunction getCumulativeUsageValue(\n current: number | null | undefined,\n previous: number | undefined\n): number {\n return Math.max(previous ?? 0, current ?? 0);\n}\n\nfunction buildUsageSnapshot(usage: AnthropicEventUsage): UsageMetadata {\n const metadata = getAnthropicUsageMetadata({\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_creation_input_tokens: usage.cacheCreationInputTokens,\n cache_read_input_tokens: usage.cacheReadInputTokens,\n });\n if (metadata == null) {\n throw new Error('Anthropic usage metadata was not created');\n }\n return metadata;\n}\n\nfunction getStringField(record: BlockAccumulator, key: string): string {\n const value = record[key];\n return typeof value === 'string' ? value : '';\n}\n\nfunction getArrayField(record: BlockAccumulator, key: string): unknown[] {\n const value = record[key];\n return Array.isArray(value) ? value : [];\n}\n\nfunction mapBlockToContentBlock(\n block: AnthropicContentBlock,\n index: number\n): BlockAccumulator {\n switch (block.type) {\n case 'text':\n return {\n type: 'text' as const,\n text: block.text,\n ...(block.citations != null ? { citations: block.citations } : {}),\n index,\n };\n case 'thinking':\n return {\n type: 'reasoning' as const,\n reasoning: block.thinking,\n index,\n };\n case 'redacted_thinking':\n return { ...block, index };\n case 'tool_use':\n return {\n type: 'tool_call_chunk' as const,\n id: block.id,\n name: block.name,\n args: '',\n index,\n };\n case 'server_tool_use':\n return {\n type: 'server_tool_call_chunk' as const,\n id: block.id,\n name: block.name,\n args: '',\n index,\n };\n case 'web_search_tool_result':\n return { ...block, index };\n case 'compaction':\n return { ...block, index };\n default:\n return { type: 'non_standard' as const, value: { ...block }, index };\n }\n}\n\n/**\n * Map an Anthropic content_block_delta to a content block delta\n * and update the accumulated state.\n */\nfunction applyAnthropicDelta(\n accumulated: BlockAccumulator,\n delta: AnthropicContentDelta\n): {\n contentDelta: ContentBlockDelta;\n accumulated: BlockAccumulator;\n} {\n const rawDelta = delta as unknown as Record<string, unknown>;\n switch (delta.type) {\n case 'text_delta':\n return {\n contentDelta: { type: 'text-delta' as const, text: delta.text },\n accumulated: {\n ...accumulated,\n text: getStringField(accumulated, 'text') + delta.text,\n },\n };\n\n case 'thinking_delta':\n return {\n contentDelta: {\n type: 'reasoning-delta' as const,\n reasoning: delta.thinking,\n },\n accumulated: {\n ...accumulated,\n reasoning: getStringField(accumulated, 'reasoning') + delta.thinking,\n },\n };\n\n case 'input_json_delta': {\n const newArgs = getStringField(accumulated, 'args') + delta.partial_json;\n return {\n contentDelta: {\n type: 'block-delta' as const,\n fields: {\n type: getStringField(accumulated, 'type'),\n args: newArgs,\n },\n },\n accumulated: { ...accumulated, args: newArgs },\n };\n }\n\n case 'citations_delta': {\n const citations = [\n ...getArrayField(accumulated, 'citations'),\n delta.citation,\n ];\n return {\n contentDelta: {\n type: 'block-delta' as const,\n fields: {\n type: getStringField(accumulated, 'type'),\n citations,\n },\n },\n accumulated: {\n ...accumulated,\n citations,\n },\n };\n }\n\n case 'signature_delta':\n return {\n contentDelta: {\n type: 'block-delta' as const,\n fields: {\n type: getStringField(accumulated, 'type'),\n signature: delta.signature,\n },\n },\n accumulated: { ...accumulated, signature: delta.signature },\n };\n\n case 'compaction_delta': {\n const previousContent = accumulated.content;\n const content =\n delta.content == null\n ? (previousContent ?? null)\n : getStringField(accumulated, 'content') + delta.content;\n return {\n contentDelta: {\n type: 'block-delta' as const,\n fields: {\n type: 'compaction',\n content,\n encrypted_content: delta.encrypted_content,\n },\n },\n accumulated: {\n ...accumulated,\n content,\n encrypted_content: delta.encrypted_content,\n },\n };\n }\n\n default:\n return {\n contentDelta: {\n type: 'block-delta' as const,\n fields: {\n type: getStringField(accumulated, 'type'),\n ...rawDelta,\n },\n },\n accumulated,\n };\n }\n}\n\nfunction finalizeBlock(accumulated: BlockAccumulator): ContentBlock {\n if (\n accumulated.type === 'tool_call_chunk' ||\n accumulated.type === 'server_tool_call_chunk'\n ) {\n const finalType =\n accumulated.type === 'tool_call_chunk'\n ? ('tool_call' as const)\n : ('server_tool_call' as const);\n const args = getStringField(accumulated, 'args');\n let parsedArgs: unknown;\n try {\n parsedArgs = JSON.parse(args || '{}');\n } catch {\n return {\n type: 'invalid_tool_call' as const,\n id: getStringField(accumulated, 'id'),\n name: getStringField(accumulated, 'name'),\n args,\n error: 'Failed to parse tool call arguments as JSON',\n } as ContentBlock.Tools.InvalidToolCall;\n }\n return {\n type: finalType,\n id: getStringField(accumulated, 'id'),\n name: getStringField(accumulated, 'name'),\n args: parsedArgs,\n } as ContentBlock;\n }\n\n const { index: _index, ...rest } = accumulated;\n return rest as ContentBlock;\n}\n"],"mappings":"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"}
@@ -17,6 +17,13 @@ const FOREIGN_REASONING_TYPES = [
17
17
  "think"
18
18
  ];
19
19
  /**
20
+ * Google server-side tool blocks (`toolCall`/`toolResponse` parts from e.g.
21
+ * URL context or Google Search). Only Google can execute these and validate
22
+ * their thought signatures, so they are dropped on a cross-provider handoff
23
+ * (e.g. Google → Bedrock); the assistant's answer text is kept.
24
+ */
25
+ const FOREIGN_SERVER_TOOL_TYPES = ["toolCall", "toolResponse"];
26
+ /**
20
27
  * Bedrock Converse rejects assistant messages with no content blocks. When
21
28
  * filtering (e.g. dropping foreign reasoning) empties an assistant turn that
22
29
  * also has no tool calls, fall back to this placeholder text.
@@ -368,6 +375,7 @@ function convertAIMessageToConverseMessage(msg) {
368
375
  const cachePoint = getDefaultCachePoint(block);
369
376
  if (cachePoint != null) contentBlocks.push({ cachePoint });
370
377
  else if (FOREIGN_REASONING_TYPES.some((t) => t === block.type)) return;
378
+ else if (FOREIGN_SERVER_TOOL_TYPES.some((t) => t === block.type)) return;
371
379
  else {
372
380
  const blockValues = Object.fromEntries(Object.entries(block).filter(([key]) => key !== "type"));
373
381
  throw new Error(`Unsupported content block type: ${block.type} with content of ${JSON.stringify(blockValues, null, 2)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"message_inputs.cjs","names":[],"sources":["../../../../../src/llm/bedrock/utils/message_inputs.ts"],"sourcesContent":["/**\n * Utility functions for converting LangChain messages to Bedrock Converse messages.\n * Ported from @langchain/aws common.js\n */\nimport {\n type BaseMessage,\n isAIMessage,\n type Data,\n parseBase64DataUrl,\n parseMimeType,\n MessageContentComplex,\n type StandardContentBlockConverter,\n convertToProviderContentBlock,\n isDataContentBlock,\n} from '@langchain/core/messages';\nimport type {\n AudioFormat,\n AudioSource,\n DocumentFormat,\n DocumentSource,\n VideoFormat,\n VideoSource,\n} from '@aws-sdk/client-bedrock-runtime';\nimport type {\n BedrockMessage,\n BedrockSystemContentBlock,\n BedrockContentBlock,\n MessageContentReasoningBlock,\n} from '../types';\n\n/**\n * Reasoning blocks from other providers, relative to Bedrock. Bedrock's native\n * reasoning format is `reasoning_content`; these carry provider-specific\n * signatures Bedrock cannot validate, so they are dropped on a cross-provider\n * handoff (e.g. Anthropic → Bedrock) rather than crashing the conversion.\n */\nconst FOREIGN_REASONING_TYPES = [\n 'thinking',\n 'redacted_thinking',\n 'reasoning',\n 'think',\n];\n\n/**\n * Bedrock Converse rejects assistant messages with no content blocks. When\n * filtering (e.g. dropping foreign reasoning) empties an assistant turn that\n * also has no tool calls, fall back to this placeholder text.\n */\nconst BEDROCK_EMPTY_TEXT_PLACEHOLDER = '_';\n\n/**\n * Convert a LangChain reasoning block to a Bedrock reasoning block.\n */\nexport function langchainReasoningBlockToBedrockReasoningBlock(\n content: MessageContentReasoningBlock\n): {\n reasoningText?: { text?: string; signature?: string };\n redactedContent?: Uint8Array;\n} {\n if (content.reasoningText != null) {\n return {\n reasoningText: content.reasoningText,\n };\n }\n if (content.redactedContent != null && content.redactedContent !== '') {\n return {\n redactedContent: new Uint8Array(\n Buffer.from(content.redactedContent, 'base64')\n ),\n };\n }\n throw new Error('Invalid reasoning content');\n}\n\n/**\n * Whether a reasoning block can be serialized to a valid Bedrock\n * `reasoningContent`. Bedrock Converse rejects `reasoningText` with a null/empty\n * `text` (e.g. a signature-only block that never merged with its text), so such\n * blocks must be dropped rather than sent.\n */\nfunction isSerializableBedrockReasoningBlock(\n content: MessageContentReasoningBlock\n): boolean {\n if (content.reasoningText != null) {\n const text = content.reasoningText.text;\n return text != null && text !== '';\n }\n return content.redactedContent != null && content.redactedContent !== '';\n}\n\nfunction appendSerializableBedrockTextBlock(\n contentBlocks: BedrockContentBlock[],\n text: string\n): boolean {\n if (text === '') {\n return false;\n }\n const cleanedText = text.replace(/\\n/g, '').trim();\n if (cleanedText !== '') {\n contentBlocks.push({ text });\n return true;\n }\n const lastBlock = contentBlocks[contentBlocks.length - 1] as\n | BedrockContentBlock\n | undefined;\n if (lastBlock == null || !('text' in lastBlock)) {\n return false;\n }\n const mergedTextContent = `${lastBlock.text}${text}`;\n (lastBlock as { text: string }).text = mergedTextContent;\n return true;\n}\n\n/**\n * Concatenate consecutive reasoning blocks in content array.\n */\nexport function concatenateLangchainReasoningBlocks(\n content: Array<MessageContentComplex | MessageContentReasoningBlock>\n): Array<MessageContentComplex | MessageContentReasoningBlock> {\n const result: Array<MessageContentComplex | MessageContentReasoningBlock> =\n [];\n let pendingReasoning: MessageContentReasoningBlock | undefined;\n\n const flushPendingReasoning = (): void => {\n if (pendingReasoning != null) {\n result.push(pendingReasoning);\n pendingReasoning = undefined;\n }\n };\n\n for (const block of content) {\n if (block.type !== 'reasoning_content') {\n flushPendingReasoning();\n result.push(block);\n continue;\n }\n\n const currentReasoning = block as MessageContentReasoningBlock;\n if (currentReasoning.reasoningText != null) {\n const previousText = pendingReasoning?.reasoningText?.text;\n const previousSignature = pendingReasoning?.reasoningText?.signature;\n const { text, signature } = currentReasoning.reasoningText;\n const mergedReasoningText: { text?: string; signature?: string } = {};\n if (previousText !== undefined || text !== undefined) {\n mergedReasoningText.text = (previousText ?? '') + (text ?? '');\n }\n if (previousSignature !== undefined || signature !== undefined) {\n mergedReasoningText.signature =\n (previousSignature ?? '') + (signature ?? '');\n }\n pendingReasoning = {\n type: 'reasoning_content',\n reasoningText: mergedReasoningText,\n };\n\n // A signature seals the accumulated reasoning text. Any following\n // reasoning block starts a new independently signed Bedrock block.\n if ('signature' in currentReasoning.reasoningText) {\n flushPendingReasoning();\n }\n }\n\n if (currentReasoning.redactedContent != null) {\n flushPendingReasoning();\n result.push({\n type: 'reasoning_content',\n redactedContent: currentReasoning.redactedContent,\n });\n }\n }\n\n flushPendingReasoning();\n return result;\n}\n\n/**\n * Extract image info from a base64 string or URL.\n */\nexport function extractImageInfo(base64: string): BedrockContentBlock {\n // Extract the format from the base64 string\n const formatMatch = base64.match(/^data:image\\/(\\w+);base64,/);\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (formatMatch) {\n const extractedFormat = formatMatch[1].toLowerCase();\n if (['gif', 'jpeg', 'png', 'webp'].includes(extractedFormat)) {\n format = extractedFormat as typeof format;\n }\n }\n\n // Remove the data URL prefix if present\n const base64Data = base64.replace(/^data:image\\/\\w+;base64,/, '');\n\n // Convert base64 to Uint8Array\n const binaryString = atob(base64Data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i += 1) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n return {\n image: {\n format,\n source: {\n bytes,\n },\n },\n };\n}\n\ntype MediaContentBlock = MessageContentComplex & {\n data?: string | Uint8Array;\n url?: string;\n fileId?: string;\n mimeType?: string;\n};\n\nconst mimeTypeToVideoFormat: Record<string, VideoFormat> = {\n 'video/flv': 'flv',\n 'video/mkv': 'mkv',\n 'video/mov': 'mov',\n 'video/mp4': 'mp4',\n 'video/mpeg': 'mpeg',\n 'video/mpg': 'mpg',\n 'video/three_gp': 'three_gp',\n 'video/webm': 'webm',\n 'video/wmv': 'wmv',\n};\n\nconst mimeTypeToAudioFormat: Record<string, AudioFormat> = {\n 'audio/aac': 'aac',\n 'audio/flac': 'flac',\n 'audio/m4a': 'm4a',\n 'audio/mka': 'mka',\n 'audio/mkv': 'mkv',\n 'audio/mp3': 'mp3',\n 'audio/mp4': 'mp4',\n 'audio/mpeg': 'mpeg',\n 'audio/mpga': 'mpga',\n 'audio/ogg': 'ogg',\n 'audio/opus': 'opus',\n 'audio/pcm': 'pcm',\n 'audio/wav': 'wav',\n 'audio/webm': 'webm',\n 'audio/x-aac': 'x-aac',\n};\n\nconst mimeTypeToDocumentFormat: Partial<Record<string, DocumentFormat>> = {\n 'text/csv': 'csv',\n 'application/msword': 'doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n 'docx',\n 'text/html': 'html',\n 'text/markdown': 'md',\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n 'application/vnd.ms-excel': 'xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',\n};\n\nfunction base64ToBytes(data: string): Uint8Array {\n return Uint8Array.from(atob(data), (char) => char.charCodeAt(0));\n}\n\nfunction getMediaFormat<T extends string>(\n mimeType: string | undefined,\n formatMap: Record<string, T>\n): T | undefined {\n if (mimeType == null || mimeType === '') {\n return undefined;\n }\n return formatMap[mimeType] ?? (parseMimeType(mimeType).subtype as T);\n}\n\nfunction resolveMediaSource(\n block: MediaContentBlock\n): AudioSource | VideoSource {\n if (typeof block.data === 'string') {\n return { bytes: base64ToBytes(block.data) };\n }\n if (block.data instanceof Uint8Array) {\n return { bytes: block.data };\n }\n if (typeof block.url === 'string') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData != null) {\n return { bytes: parsedData.data as Uint8Array };\n }\n throw new Error(\n `Only base64 data URLs are supported for ${block.type} blocks with 'url' field with ChatBedrockConverse.`\n );\n }\n if (typeof block.fileId === 'string') {\n return { s3Location: { uri: block.fileId } };\n }\n throw new Error(\n `${block.type} block must include one of: 'data' (base64 string or Uint8Array), 'url' (base64 data URL), or 'fileId' (S3 URI).`\n );\n}\n\nfunction convertMultimodalVideoBlock(\n block: MediaContentBlock\n): BedrockContentBlock {\n return {\n video: {\n format: getMediaFormat(block.mimeType, mimeTypeToVideoFormat),\n source: resolveMediaSource(block) as VideoSource,\n },\n } as BedrockContentBlock;\n}\n\nfunction convertMultimodalAudioBlock(\n block: MediaContentBlock\n): BedrockContentBlock {\n return {\n audio: {\n format: getMediaFormat(block.mimeType, mimeTypeToAudioFormat),\n source: resolveMediaSource(block) as AudioSource,\n },\n } as BedrockContentBlock;\n}\n\nfunction getDocumentName(block: Data.StandardFileBlock): string {\n return (\n (block.metadata?.name as string | undefined) ??\n (block.metadata?.filename as string | undefined) ??\n (block.metadata?.title as string | undefined) ??\n globalThis.crypto.randomUUID().replace(/-/g, '').slice(0, 12)\n );\n}\n\nfunction getDocumentFormat(\n mimeType: string | undefined\n): DocumentFormat | undefined {\n if (mimeType == null || mimeType === '') {\n return undefined;\n }\n const parsedMimeType = parseMimeType(mimeType);\n const format =\n mimeTypeToDocumentFormat[\n `${parsedMimeType.type}/${parsedMimeType.subtype}`\n ];\n if (format === undefined) {\n throw new Error(\n `Unsupported file mime type: \"${mimeType}\" ChatBedrockConverse only supports ${Object.keys(\n mimeTypeToDocumentFormat\n ).join(', ')} formats.`\n );\n }\n return format;\n}\n\nconst standardContentBlockConverter: StandardContentBlockConverter<{\n text: BedrockContentBlock;\n image: BedrockContentBlock;\n file: BedrockContentBlock;\n}> = {\n providerName: 'ChatBedrockConverse',\n\n fromStandardTextBlock(block: Data.StandardTextBlock): BedrockContentBlock {\n return { text: block.text };\n },\n\n fromStandardImageBlock(block: Data.StandardImageBlock): BedrockContentBlock {\n if (block.source_type === 'url') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData == null) {\n throw new Error(\n [\n 'Only base64 data URLs are supported for image blocks with source type ',\n 'url',\n ' with ChatBedrockConverse.',\n ].join(String.fromCharCode(39))\n );\n }\n return {\n image: {\n format: parseMimeType(parsedData.mime_type).subtype as\n | 'gif'\n | 'jpeg'\n | 'png'\n | 'webp',\n source: { bytes: parsedData.data as Uint8Array },\n },\n };\n }\n if (block.source_type === 'base64') {\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (block.mime_type != null && block.mime_type !== '') {\n format = parseMimeType(block.mime_type).subtype as typeof format;\n }\n if (format != null && !['gif', 'jpeg', 'png', 'webp'].includes(format)) {\n throw new Error(\n `Unsupported image mime type: \"${block.mime_type}\" ChatBedrockConverse only supports \"image/gif\", \"image/jpeg\", \"image/png\", and \"image/webp\" formats.`\n );\n }\n return {\n image: {\n format,\n source: { bytes: base64ToBytes(block.data) },\n },\n };\n }\n throw new Error(\n `Image source type '${block.source_type}' not supported with ChatBedrockConverse.`\n );\n },\n\n fromStandardFileBlock(block: Data.StandardFileBlock): BedrockContentBlock {\n const name = getDocumentName(block);\n if (block.source_type === 'text') {\n return {\n document: {\n name,\n format: 'txt',\n source: { bytes: new TextEncoder().encode(block.text) },\n },\n } as BedrockContentBlock;\n }\n if (block.source_type === 'url') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData == null) {\n throw new Error(\n [\n 'Only base64 data URLs are supported for file blocks with source type ',\n 'url',\n ' with ChatBedrockConverse.',\n ].join(String.fromCharCode(39))\n );\n }\n return {\n document: {\n name,\n format: getDocumentFormat(parsedData.mime_type),\n source: { bytes: parsedData.data as Uint8Array } as DocumentSource,\n },\n } as BedrockContentBlock;\n }\n if (block.source_type === 'base64') {\n return {\n document: {\n name,\n format: getDocumentFormat(block.mime_type),\n source: { bytes: base64ToBytes(block.data) } as DocumentSource,\n },\n } as BedrockContentBlock;\n }\n throw new Error(\n `File source type '${block.source_type}' not supported with ChatBedrockConverse.`\n );\n },\n};\n\ntype BedrockPromptCacheTtl = '5m' | '1h';\ntype NormalizedBedrockCachePoint = {\n type: 'default';\n ttl?: BedrockPromptCacheTtl;\n};\n\n/**\n * Check if a block has a default cache point and return its normalized form,\n * preserving an optional extended-TTL `ttl` (`'5m'` | `'1h'`). Returns\n * `undefined` when the block is not a default cache point.\n */\nfunction getDefaultCachePoint(\n block: unknown\n): NormalizedBedrockCachePoint | undefined {\n if (typeof block !== 'object' || block === null) {\n return undefined;\n }\n if (!('cachePoint' in block)) {\n return undefined;\n }\n const cachePoint = (block as { cachePoint?: unknown }).cachePoint;\n if (typeof cachePoint !== 'object' || cachePoint === null) {\n return undefined;\n }\n if (!('type' in cachePoint)) {\n return undefined;\n }\n if ((cachePoint as { type?: string }).type !== 'default') {\n return undefined;\n }\n const ttl = (cachePoint as { ttl?: unknown }).ttl;\n return ttl === '5m' || ttl === '1h'\n ? { type: 'default', ttl }\n : { type: 'default' };\n}\n\n/**\n * Convert a LangChain content block to a Bedrock Converse content block.\n */\nfunction convertLangChainContentBlockToConverseContentBlock({\n block,\n onUnknown = 'throw',\n}: {\n block: string | MessageContentComplex;\n onUnknown?: 'throw' | 'passthrough';\n}): BedrockContentBlock {\n if (typeof block === 'string') {\n return { text: block };\n }\n\n if (isDataContentBlock(block)) {\n return convertToProviderContentBlock(block, standardContentBlockConverter);\n }\n\n if (block.type === 'text') {\n return { text: (block as { text: string }).text };\n }\n\n if (block.type === 'image_url') {\n const imageUrl =\n typeof (block as { image_url: string | { url: string } }).image_url ===\n 'string'\n ? (block as { image_url: string }).image_url\n : (block as { image_url: { url: string } }).image_url.url;\n return extractImageInfo(imageUrl);\n }\n\n if (block.type === 'image') {\n // Handle standard image block format\n const imageBlock = block as {\n source_type?: string;\n url?: string;\n data?: string;\n mime_type?: string;\n };\n if (\n imageBlock.source_type === 'url' &&\n imageBlock.url != null &&\n imageBlock.url !== ''\n ) {\n const parsedData = parseBase64DataUrl({\n dataUrl: imageBlock.url,\n asTypedArray: true,\n });\n if (parsedData != null) {\n const parsedMimeType = parseMimeType(parsedData.mime_type);\n return {\n image: {\n format: parsedMimeType.subtype as 'gif' | 'jpeg' | 'png' | 'webp',\n source: {\n bytes: parsedData.data as Uint8Array,\n },\n },\n };\n }\n } else if (\n imageBlock.source_type === 'base64' &&\n imageBlock.data != null &&\n imageBlock.data !== ''\n ) {\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (imageBlock.mime_type != null && imageBlock.mime_type !== '') {\n const parsedMimeType = parseMimeType(imageBlock.mime_type);\n format = parsedMimeType.subtype as typeof format;\n }\n return {\n image: {\n format,\n source: {\n bytes: Uint8Array.from(atob(imageBlock.data), (c) =>\n c.charCodeAt(0)\n ),\n },\n },\n };\n }\n // If it already has the Bedrock image structure, pass through\n if ((block as { image?: unknown }).image !== undefined) {\n return {\n image: (block as { image: unknown }).image,\n } as BedrockContentBlock;\n }\n }\n\n if (\n block.type === 'video' &&\n (block as { video?: unknown }).video !== undefined\n ) {\n return {\n video: (block as { video: unknown }).video,\n } as BedrockContentBlock;\n }\n\n if (block.type === 'video') {\n return convertMultimodalVideoBlock(block as MediaContentBlock);\n }\n\n if (\n block.type === 'audio' &&\n (block as { audio?: unknown }).audio !== undefined\n ) {\n return {\n audio: (block as { audio: unknown }).audio,\n } as BedrockContentBlock;\n }\n\n if (block.type === 'audio') {\n return convertMultimodalAudioBlock(block as MediaContentBlock);\n }\n\n if (\n block.type === 'document' &&\n (block as { document?: unknown }).document !== undefined\n ) {\n return {\n document: (block as { document: unknown }).document,\n } as BedrockContentBlock;\n }\n\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n return {\n cachePoint,\n } as BedrockContentBlock;\n }\n\n if (onUnknown === 'throw') {\n throw new Error(`Unsupported content block type: ${block.type}`);\n } else {\n return block as unknown as BedrockContentBlock;\n }\n}\n\n/**\n * Convert a system message to Bedrock system content blocks.\n */\nfunction convertSystemMessageToConverseMessage(\n msg: BaseMessage\n): BedrockSystemContentBlock[] {\n if (typeof msg.content === 'string') {\n return [{ text: msg.content }];\n } else if (Array.isArray(msg.content) && msg.content.length > 0) {\n const contentBlocks: BedrockSystemContentBlock[] = [];\n for (const block of msg.content) {\n if (\n typeof block === 'object' &&\n block.type === 'text' &&\n typeof (block as { text?: string }).text === 'string'\n ) {\n contentBlocks.push({\n text: (block as { text: string }).text,\n });\n } else {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint == null) {\n break;\n }\n contentBlocks.push({\n cachePoint,\n } as BedrockSystemContentBlock);\n }\n }\n if (msg.content.length === contentBlocks.length) {\n return contentBlocks;\n }\n }\n throw new Error(\n 'System message content must be either a string, or an array of text blocks, optionally including a cache point.'\n );\n}\n\n/**\n * Convert an AI message to a Bedrock message.\n */\nfunction convertAIMessageToConverseMessage(msg: BaseMessage): BedrockMessage {\n // Check for v1 format from other providers (PR #9766 fix)\n const responseMetadata = msg.response_metadata as\n | { output_version?: string }\n | undefined;\n if (responseMetadata?.output_version === 'v1') {\n return convertFromV1ToChatBedrockConverseMessage(msg);\n }\n\n const assistantMsg: BedrockMessage = {\n role: 'assistant',\n content: [],\n };\n\n if (typeof msg.content === 'string' && msg.content !== '') {\n assistantMsg.content?.push({ text: msg.content });\n } else if (Array.isArray(msg.content)) {\n const concatenatedBlocks = concatenateLangchainReasoningBlocks(\n msg.content as Array<MessageContentComplex | MessageContentReasoningBlock>\n );\n const contentBlocks: BedrockContentBlock[] = [];\n\n concatenatedBlocks.forEach((block) => {\n if (block.type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n appendSerializableBedrockTextBlock(contentBlocks, text);\n } else if (block.type === 'reasoning_content') {\n const reasoningBlock = block as MessageContentReasoningBlock;\n // Bedrock Converse rejects reasoningContent whose reasoningText.text is\n // null/empty (a signature-only block that never merged with its text).\n // Drop it rather than emit an invalid request; the empty-turn\n // placeholder below covers a turn left with no content.\n if (!isSerializableBedrockReasoningBlock(reasoningBlock)) {\n return;\n }\n contentBlocks.push({\n reasoningContent:\n langchainReasoningBlockToBedrockReasoningBlock(reasoningBlock),\n } as BedrockContentBlock);\n } else {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n contentBlocks.push({\n cachePoint,\n } as BedrockContentBlock);\n } else if (FOREIGN_REASONING_TYPES.some((t) => t === block.type)) {\n // Reasoning from another provider (Anthropic `thinking`/\n // `redacted_thinking`, Google `reasoning`, LibreChat `think`).\n // Bedrock's native reasoning is `reasoning_content` (handled above); a\n // foreign block carries a signature Bedrock cannot validate, so drop\n // it on a cross-provider handoff (e.g. Anthropic → Bedrock) rather\n // than crash. The Bedrock model produces its own reasoning. Anything\n // else unknown still throws below — real content must be surfaced.\n return;\n } else {\n const blockValues = Object.fromEntries(\n Object.entries(block).filter(([key]) => key !== 'type')\n );\n throw new Error(\n `Unsupported content block type: ${block.type} with content of ${JSON.stringify(blockValues, null, 2)}`\n );\n }\n }\n });\n\n assistantMsg.content = [...(assistantMsg.content ?? []), ...contentBlocks];\n }\n\n // Important: this must be placed after any reasoning content blocks\n if (isAIMessage(msg) && msg.tool_calls != null && msg.tool_calls.length > 0) {\n const toolUseBlocks = msg.tool_calls.map((tc) => ({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.args as Record<string, unknown>,\n },\n }));\n assistantMsg.content = [\n ...(assistantMsg.content ?? []),\n ...toolUseBlocks,\n ] as BedrockContentBlock[];\n }\n\n // Bedrock rejects an assistant message with no content blocks; if filtering\n // (e.g. dropping foreign reasoning) left it empty, emit a placeholder.\n if (assistantMsg.content == null || assistantMsg.content.length === 0) {\n assistantMsg.content = [{ text: BEDROCK_EMPTY_TEXT_PLACEHOLDER }];\n }\n\n return assistantMsg;\n}\n\n/**\n * Convert a v1 format message from other providers to Bedrock format.\n * This handles messages with standard content blocks like tool_call and reasoning.\n * (Implements PR #9766 fix for output_version v1 detection)\n */\nfunction convertFromV1ToChatBedrockConverseMessage(\n msg: BaseMessage\n): BedrockMessage {\n const contentBlocks: BedrockContentBlock[] = [];\n const assistantMsg: BedrockMessage = {\n role: 'assistant',\n content: contentBlocks,\n };\n let droppedUnserializableContent = false;\n let unconvertedContentType: string | undefined;\n\n if (Array.isArray(msg.content)) {\n const concatenatedBlocks = concatenateLangchainReasoningBlocks(\n msg.content as Array<MessageContentComplex | MessageContentReasoningBlock>\n );\n for (const block of concatenatedBlocks) {\n if (typeof block === 'string') {\n if (!appendSerializableBedrockTextBlock(contentBlocks, block)) {\n droppedUnserializableContent = true;\n }\n } else if (block.type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n if (!appendSerializableBedrockTextBlock(contentBlocks, text)) {\n droppedUnserializableContent = true;\n }\n } else if (block.type === 'tool_call') {\n const toolCall = block as {\n id: string;\n name: string;\n args: Record<string, unknown>;\n };\n contentBlocks.push({\n toolUse: {\n toolUseId: toolCall.id,\n name: toolCall.name,\n input: toolCall.args as Record<string, unknown>,\n },\n } as BedrockContentBlock);\n } else if (block.type === 'reasoning') {\n const reasoning = block as { reasoning?: string };\n /** Bedrock Converse rejects `reasoningText` with a null/empty `text`\n * (`Member must not be null`), e.g. when the producing model omitted\n * reasoning text (`thinking.display: \"omitted\"`) — drop rather than send. */\n if (reasoning.reasoning == null || reasoning.reasoning === '') {\n droppedUnserializableContent = true;\n continue;\n }\n contentBlocks.push({\n reasoningContent: {\n reasoningText: { text: reasoning.reasoning },\n },\n } as BedrockContentBlock);\n } else if (block.type === 'reasoning_content') {\n const reasoningBlock = block as MessageContentReasoningBlock;\n if (!isSerializableBedrockReasoningBlock(reasoningBlock)) {\n droppedUnserializableContent = true;\n continue;\n }\n contentBlocks.push({\n reasoningContent:\n langchainReasoningBlockToBedrockReasoningBlock(reasoningBlock),\n } as BedrockContentBlock);\n } else {\n unconvertedContentType ??= block.type;\n }\n }\n } else if (typeof msg.content === 'string') {\n if (!appendSerializableBedrockTextBlock(contentBlocks, msg.content)) {\n droppedUnserializableContent = true;\n }\n }\n\n // Also handle tool_calls from the message\n if (isAIMessage(msg) && msg.tool_calls != null && msg.tool_calls.length > 0) {\n // Check if tool calls are already in content\n const existingToolUseIds = new Set(\n contentBlocks\n .filter((c) => 'toolUse' in c)\n .map((c) => (c as { toolUse: { toolUseId: string } }).toolUse.toolUseId)\n );\n\n for (const tc of msg.tool_calls) {\n if (!existingToolUseIds.has(tc.id ?? '')) {\n contentBlocks.push({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.args as Record<string, unknown>,\n },\n } as BedrockContentBlock);\n }\n }\n }\n\n const hasNoContent = contentBlocks.length === 0;\n if (hasNoContent && unconvertedContentType != null) {\n throw new Error(\n `Unsupported v1 content block type: ${unconvertedContentType}`\n );\n }\n if (hasNoContent && droppedUnserializableContent) {\n contentBlocks.push({ text: BEDROCK_EMPTY_TEXT_PLACEHOLDER });\n }\n\n return assistantMsg;\n}\n\n/**\n * Convert a human message to a Bedrock message.\n */\nfunction convertHumanMessageToConverseMessage(\n msg: BaseMessage\n): BedrockMessage {\n const userMessage: BedrockMessage = {\n role: 'user',\n content: [],\n };\n\n if (typeof msg.content === 'string') {\n userMessage.content = [{ text: msg.content }];\n } else if (Array.isArray(msg.content)) {\n userMessage.content = msg.content.map((block) =>\n convertLangChainContentBlockToConverseContentBlock({ block })\n );\n }\n\n return userMessage;\n}\n\n/**\n * Convert a tool message to a Bedrock message.\n */\nfunction convertToolMessageToConverseMessage(msg: BaseMessage): BedrockMessage {\n const toolCallId = (msg as { tool_call_id?: string }).tool_call_id;\n\n let content: BedrockContentBlock[];\n if (typeof msg.content === 'string') {\n content = [{ text: msg.content }];\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((block) =>\n convertLangChainContentBlockToConverseContentBlock({\n block,\n onUnknown: 'passthrough',\n })\n );\n } else {\n content = [{ text: String(msg.content) }];\n }\n\n // A `cachePoint` is a message-level ContentBlock — it is NOT a valid\n // ToolResultContentBlock. A tail prompt-cache breakpoint that anchors on a\n // tool result therefore ends up nested inside `toolResult.content`, which\n // Bedrock silently ignores (no cache write, no cache read). Hoist any\n // cachePoint(s) out of the tool result body so they sit as siblings after\n // it, which is the only position Bedrock honors.\n const toolResultContent: BedrockContentBlock[] = [];\n const trailingCachePoints: BedrockContentBlock[] = [];\n for (const block of content) {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n trailingCachePoints.push({\n cachePoint,\n } as BedrockContentBlock);\n } else {\n toolResultContent.push(block);\n }\n }\n\n return {\n role: 'user',\n content: [\n {\n toolResult: {\n toolUseId: toolCallId,\n content: toolResultContent as { text: string }[],\n },\n },\n ...trailingCachePoints,\n ],\n };\n}\n\n/**\n * Convert LangChain messages to Bedrock Converse messages.\n */\nexport function convertToConverseMessages(messages: BaseMessage[]): {\n converseMessages: BedrockMessage[];\n converseSystem: BedrockSystemContentBlock[];\n} {\n const converseSystem = messages\n .filter((msg) => msg._getType() === 'system')\n .flatMap((msg) => convertSystemMessageToConverseMessage(msg));\n\n const converseMessages = messages\n .filter((msg) => msg._getType() !== 'system')\n .map((msg) => {\n if (msg._getType() === 'ai') {\n return convertAIMessageToConverseMessage(msg);\n } else if (msg._getType() === 'human' || msg._getType() === 'generic') {\n return convertHumanMessageToConverseMessage(msg);\n } else if (msg._getType() === 'tool') {\n return convertToolMessageToConverseMessage(msg);\n } else {\n throw new Error(`Unsupported message type: ${msg._getType()}`);\n }\n });\n\n // Combine consecutive user tool result messages into a single message\n const combinedConverseMessages = converseMessages.reduce<BedrockMessage[]>(\n (acc, curr) => {\n if (acc.length === 0) {\n acc.push(curr);\n return acc;\n }\n const lastMessage = acc[acc.length - 1];\n const lastHasToolResult =\n lastMessage.content?.some((c) => 'toolResult' in c) === true;\n const currHasToolResult =\n curr.content?.some((c) => 'toolResult' in c) === true;\n if (\n lastMessage.role === 'user' &&\n lastHasToolResult &&\n curr.role === 'user' &&\n currHasToolResult\n ) {\n lastMessage.content = lastMessage.content?.concat(curr.content ?? []);\n } else {\n acc.push(curr);\n }\n return acc;\n },\n []\n );\n\n return { converseMessages: combinedConverseMessages, converseSystem };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"message_inputs.cjs","names":[],"sources":["../../../../../src/llm/bedrock/utils/message_inputs.ts"],"sourcesContent":["/**\n * Utility functions for converting LangChain messages to Bedrock Converse messages.\n * Ported from @langchain/aws common.js\n */\nimport {\n type BaseMessage,\n isAIMessage,\n type Data,\n parseBase64DataUrl,\n parseMimeType,\n MessageContentComplex,\n type StandardContentBlockConverter,\n convertToProviderContentBlock,\n isDataContentBlock,\n} from '@langchain/core/messages';\nimport type {\n AudioFormat,\n AudioSource,\n DocumentFormat,\n DocumentSource,\n VideoFormat,\n VideoSource,\n} from '@aws-sdk/client-bedrock-runtime';\nimport type {\n BedrockMessage,\n BedrockSystemContentBlock,\n BedrockContentBlock,\n MessageContentReasoningBlock,\n} from '../types';\n\n/**\n * Reasoning blocks from other providers, relative to Bedrock. Bedrock's native\n * reasoning format is `reasoning_content`; these carry provider-specific\n * signatures Bedrock cannot validate, so they are dropped on a cross-provider\n * handoff (e.g. Anthropic → Bedrock) rather than crashing the conversion.\n */\nconst FOREIGN_REASONING_TYPES = [\n 'thinking',\n 'redacted_thinking',\n 'reasoning',\n 'think',\n];\n\n/**\n * Google server-side tool blocks (`toolCall`/`toolResponse` parts from e.g.\n * URL context or Google Search). Only Google can execute these and validate\n * their thought signatures, so they are dropped on a cross-provider handoff\n * (e.g. Google → Bedrock); the assistant's answer text is kept.\n */\nconst FOREIGN_SERVER_TOOL_TYPES = ['toolCall', 'toolResponse'];\n\n/**\n * Bedrock Converse rejects assistant messages with no content blocks. When\n * filtering (e.g. dropping foreign reasoning) empties an assistant turn that\n * also has no tool calls, fall back to this placeholder text.\n */\nconst BEDROCK_EMPTY_TEXT_PLACEHOLDER = '_';\n\n/**\n * Convert a LangChain reasoning block to a Bedrock reasoning block.\n */\nexport function langchainReasoningBlockToBedrockReasoningBlock(\n content: MessageContentReasoningBlock\n): {\n reasoningText?: { text?: string; signature?: string };\n redactedContent?: Uint8Array;\n} {\n if (content.reasoningText != null) {\n return {\n reasoningText: content.reasoningText,\n };\n }\n if (content.redactedContent != null && content.redactedContent !== '') {\n return {\n redactedContent: new Uint8Array(\n Buffer.from(content.redactedContent, 'base64')\n ),\n };\n }\n throw new Error('Invalid reasoning content');\n}\n\n/**\n * Whether a reasoning block can be serialized to a valid Bedrock\n * `reasoningContent`. Bedrock Converse rejects `reasoningText` with a null/empty\n * `text` (e.g. a signature-only block that never merged with its text), so such\n * blocks must be dropped rather than sent.\n */\nfunction isSerializableBedrockReasoningBlock(\n content: MessageContentReasoningBlock\n): boolean {\n if (content.reasoningText != null) {\n const text = content.reasoningText.text;\n return text != null && text !== '';\n }\n return content.redactedContent != null && content.redactedContent !== '';\n}\n\nfunction appendSerializableBedrockTextBlock(\n contentBlocks: BedrockContentBlock[],\n text: string\n): boolean {\n if (text === '') {\n return false;\n }\n const cleanedText = text.replace(/\\n/g, '').trim();\n if (cleanedText !== '') {\n contentBlocks.push({ text });\n return true;\n }\n const lastBlock = contentBlocks[contentBlocks.length - 1] as\n | BedrockContentBlock\n | undefined;\n if (lastBlock == null || !('text' in lastBlock)) {\n return false;\n }\n const mergedTextContent = `${lastBlock.text}${text}`;\n (lastBlock as { text: string }).text = mergedTextContent;\n return true;\n}\n\n/**\n * Concatenate consecutive reasoning blocks in content array.\n */\nexport function concatenateLangchainReasoningBlocks(\n content: Array<MessageContentComplex | MessageContentReasoningBlock>\n): Array<MessageContentComplex | MessageContentReasoningBlock> {\n const result: Array<MessageContentComplex | MessageContentReasoningBlock> =\n [];\n let pendingReasoning: MessageContentReasoningBlock | undefined;\n\n const flushPendingReasoning = (): void => {\n if (pendingReasoning != null) {\n result.push(pendingReasoning);\n pendingReasoning = undefined;\n }\n };\n\n for (const block of content) {\n if (block.type !== 'reasoning_content') {\n flushPendingReasoning();\n result.push(block);\n continue;\n }\n\n const currentReasoning = block as MessageContentReasoningBlock;\n if (currentReasoning.reasoningText != null) {\n const previousText = pendingReasoning?.reasoningText?.text;\n const previousSignature = pendingReasoning?.reasoningText?.signature;\n const { text, signature } = currentReasoning.reasoningText;\n const mergedReasoningText: { text?: string; signature?: string } = {};\n if (previousText !== undefined || text !== undefined) {\n mergedReasoningText.text = (previousText ?? '') + (text ?? '');\n }\n if (previousSignature !== undefined || signature !== undefined) {\n mergedReasoningText.signature =\n (previousSignature ?? '') + (signature ?? '');\n }\n pendingReasoning = {\n type: 'reasoning_content',\n reasoningText: mergedReasoningText,\n };\n\n // A signature seals the accumulated reasoning text. Any following\n // reasoning block starts a new independently signed Bedrock block.\n if ('signature' in currentReasoning.reasoningText) {\n flushPendingReasoning();\n }\n }\n\n if (currentReasoning.redactedContent != null) {\n flushPendingReasoning();\n result.push({\n type: 'reasoning_content',\n redactedContent: currentReasoning.redactedContent,\n });\n }\n }\n\n flushPendingReasoning();\n return result;\n}\n\n/**\n * Extract image info from a base64 string or URL.\n */\nexport function extractImageInfo(base64: string): BedrockContentBlock {\n // Extract the format from the base64 string\n const formatMatch = base64.match(/^data:image\\/(\\w+);base64,/);\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (formatMatch) {\n const extractedFormat = formatMatch[1].toLowerCase();\n if (['gif', 'jpeg', 'png', 'webp'].includes(extractedFormat)) {\n format = extractedFormat as typeof format;\n }\n }\n\n // Remove the data URL prefix if present\n const base64Data = base64.replace(/^data:image\\/\\w+;base64,/, '');\n\n // Convert base64 to Uint8Array\n const binaryString = atob(base64Data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i += 1) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n\n return {\n image: {\n format,\n source: {\n bytes,\n },\n },\n };\n}\n\ntype MediaContentBlock = MessageContentComplex & {\n data?: string | Uint8Array;\n url?: string;\n fileId?: string;\n mimeType?: string;\n};\n\nconst mimeTypeToVideoFormat: Record<string, VideoFormat> = {\n 'video/flv': 'flv',\n 'video/mkv': 'mkv',\n 'video/mov': 'mov',\n 'video/mp4': 'mp4',\n 'video/mpeg': 'mpeg',\n 'video/mpg': 'mpg',\n 'video/three_gp': 'three_gp',\n 'video/webm': 'webm',\n 'video/wmv': 'wmv',\n};\n\nconst mimeTypeToAudioFormat: Record<string, AudioFormat> = {\n 'audio/aac': 'aac',\n 'audio/flac': 'flac',\n 'audio/m4a': 'm4a',\n 'audio/mka': 'mka',\n 'audio/mkv': 'mkv',\n 'audio/mp3': 'mp3',\n 'audio/mp4': 'mp4',\n 'audio/mpeg': 'mpeg',\n 'audio/mpga': 'mpga',\n 'audio/ogg': 'ogg',\n 'audio/opus': 'opus',\n 'audio/pcm': 'pcm',\n 'audio/wav': 'wav',\n 'audio/webm': 'webm',\n 'audio/x-aac': 'x-aac',\n};\n\nconst mimeTypeToDocumentFormat: Partial<Record<string, DocumentFormat>> = {\n 'text/csv': 'csv',\n 'application/msword': 'doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':\n 'docx',\n 'text/html': 'html',\n 'text/markdown': 'md',\n 'application/pdf': 'pdf',\n 'text/plain': 'txt',\n 'application/vnd.ms-excel': 'xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',\n};\n\nfunction base64ToBytes(data: string): Uint8Array {\n return Uint8Array.from(atob(data), (char) => char.charCodeAt(0));\n}\n\nfunction getMediaFormat<T extends string>(\n mimeType: string | undefined,\n formatMap: Record<string, T>\n): T | undefined {\n if (mimeType == null || mimeType === '') {\n return undefined;\n }\n return formatMap[mimeType] ?? (parseMimeType(mimeType).subtype as T);\n}\n\nfunction resolveMediaSource(\n block: MediaContentBlock\n): AudioSource | VideoSource {\n if (typeof block.data === 'string') {\n return { bytes: base64ToBytes(block.data) };\n }\n if (block.data instanceof Uint8Array) {\n return { bytes: block.data };\n }\n if (typeof block.url === 'string') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData != null) {\n return { bytes: parsedData.data as Uint8Array };\n }\n throw new Error(\n `Only base64 data URLs are supported for ${block.type} blocks with 'url' field with ChatBedrockConverse.`\n );\n }\n if (typeof block.fileId === 'string') {\n return { s3Location: { uri: block.fileId } };\n }\n throw new Error(\n `${block.type} block must include one of: 'data' (base64 string or Uint8Array), 'url' (base64 data URL), or 'fileId' (S3 URI).`\n );\n}\n\nfunction convertMultimodalVideoBlock(\n block: MediaContentBlock\n): BedrockContentBlock {\n return {\n video: {\n format: getMediaFormat(block.mimeType, mimeTypeToVideoFormat),\n source: resolveMediaSource(block) as VideoSource,\n },\n } as BedrockContentBlock;\n}\n\nfunction convertMultimodalAudioBlock(\n block: MediaContentBlock\n): BedrockContentBlock {\n return {\n audio: {\n format: getMediaFormat(block.mimeType, mimeTypeToAudioFormat),\n source: resolveMediaSource(block) as AudioSource,\n },\n } as BedrockContentBlock;\n}\n\nfunction getDocumentName(block: Data.StandardFileBlock): string {\n return (\n (block.metadata?.name as string | undefined) ??\n (block.metadata?.filename as string | undefined) ??\n (block.metadata?.title as string | undefined) ??\n globalThis.crypto.randomUUID().replace(/-/g, '').slice(0, 12)\n );\n}\n\nfunction getDocumentFormat(\n mimeType: string | undefined\n): DocumentFormat | undefined {\n if (mimeType == null || mimeType === '') {\n return undefined;\n }\n const parsedMimeType = parseMimeType(mimeType);\n const format =\n mimeTypeToDocumentFormat[\n `${parsedMimeType.type}/${parsedMimeType.subtype}`\n ];\n if (format === undefined) {\n throw new Error(\n `Unsupported file mime type: \"${mimeType}\" ChatBedrockConverse only supports ${Object.keys(\n mimeTypeToDocumentFormat\n ).join(', ')} formats.`\n );\n }\n return format;\n}\n\nconst standardContentBlockConverter: StandardContentBlockConverter<{\n text: BedrockContentBlock;\n image: BedrockContentBlock;\n file: BedrockContentBlock;\n}> = {\n providerName: 'ChatBedrockConverse',\n\n fromStandardTextBlock(block: Data.StandardTextBlock): BedrockContentBlock {\n return { text: block.text };\n },\n\n fromStandardImageBlock(block: Data.StandardImageBlock): BedrockContentBlock {\n if (block.source_type === 'url') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData == null) {\n throw new Error(\n [\n 'Only base64 data URLs are supported for image blocks with source type ',\n 'url',\n ' with ChatBedrockConverse.',\n ].join(String.fromCharCode(39))\n );\n }\n return {\n image: {\n format: parseMimeType(parsedData.mime_type).subtype as\n | 'gif'\n | 'jpeg'\n | 'png'\n | 'webp',\n source: { bytes: parsedData.data as Uint8Array },\n },\n };\n }\n if (block.source_type === 'base64') {\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (block.mime_type != null && block.mime_type !== '') {\n format = parseMimeType(block.mime_type).subtype as typeof format;\n }\n if (format != null && !['gif', 'jpeg', 'png', 'webp'].includes(format)) {\n throw new Error(\n `Unsupported image mime type: \"${block.mime_type}\" ChatBedrockConverse only supports \"image/gif\", \"image/jpeg\", \"image/png\", and \"image/webp\" formats.`\n );\n }\n return {\n image: {\n format,\n source: { bytes: base64ToBytes(block.data) },\n },\n };\n }\n throw new Error(\n `Image source type '${block.source_type}' not supported with ChatBedrockConverse.`\n );\n },\n\n fromStandardFileBlock(block: Data.StandardFileBlock): BedrockContentBlock {\n const name = getDocumentName(block);\n if (block.source_type === 'text') {\n return {\n document: {\n name,\n format: 'txt',\n source: { bytes: new TextEncoder().encode(block.text) },\n },\n } as BedrockContentBlock;\n }\n if (block.source_type === 'url') {\n const parsedData = parseBase64DataUrl({\n dataUrl: block.url,\n asTypedArray: true,\n });\n if (parsedData == null) {\n throw new Error(\n [\n 'Only base64 data URLs are supported for file blocks with source type ',\n 'url',\n ' with ChatBedrockConverse.',\n ].join(String.fromCharCode(39))\n );\n }\n return {\n document: {\n name,\n format: getDocumentFormat(parsedData.mime_type),\n source: { bytes: parsedData.data as Uint8Array } as DocumentSource,\n },\n } as BedrockContentBlock;\n }\n if (block.source_type === 'base64') {\n return {\n document: {\n name,\n format: getDocumentFormat(block.mime_type),\n source: { bytes: base64ToBytes(block.data) } as DocumentSource,\n },\n } as BedrockContentBlock;\n }\n throw new Error(\n `File source type '${block.source_type}' not supported with ChatBedrockConverse.`\n );\n },\n};\n\ntype BedrockPromptCacheTtl = '5m' | '1h';\ntype NormalizedBedrockCachePoint = {\n type: 'default';\n ttl?: BedrockPromptCacheTtl;\n};\n\n/**\n * Check if a block has a default cache point and return its normalized form,\n * preserving an optional extended-TTL `ttl` (`'5m'` | `'1h'`). Returns\n * `undefined` when the block is not a default cache point.\n */\nfunction getDefaultCachePoint(\n block: unknown\n): NormalizedBedrockCachePoint | undefined {\n if (typeof block !== 'object' || block === null) {\n return undefined;\n }\n if (!('cachePoint' in block)) {\n return undefined;\n }\n const cachePoint = (block as { cachePoint?: unknown }).cachePoint;\n if (typeof cachePoint !== 'object' || cachePoint === null) {\n return undefined;\n }\n if (!('type' in cachePoint)) {\n return undefined;\n }\n if ((cachePoint as { type?: string }).type !== 'default') {\n return undefined;\n }\n const ttl = (cachePoint as { ttl?: unknown }).ttl;\n return ttl === '5m' || ttl === '1h'\n ? { type: 'default', ttl }\n : { type: 'default' };\n}\n\n/**\n * Convert a LangChain content block to a Bedrock Converse content block.\n */\nfunction convertLangChainContentBlockToConverseContentBlock({\n block,\n onUnknown = 'throw',\n}: {\n block: string | MessageContentComplex;\n onUnknown?: 'throw' | 'passthrough';\n}): BedrockContentBlock {\n if (typeof block === 'string') {\n return { text: block };\n }\n\n if (isDataContentBlock(block)) {\n return convertToProviderContentBlock(block, standardContentBlockConverter);\n }\n\n if (block.type === 'text') {\n return { text: (block as { text: string }).text };\n }\n\n if (block.type === 'image_url') {\n const imageUrl =\n typeof (block as { image_url: string | { url: string } }).image_url ===\n 'string'\n ? (block as { image_url: string }).image_url\n : (block as { image_url: { url: string } }).image_url.url;\n return extractImageInfo(imageUrl);\n }\n\n if (block.type === 'image') {\n // Handle standard image block format\n const imageBlock = block as {\n source_type?: string;\n url?: string;\n data?: string;\n mime_type?: string;\n };\n if (\n imageBlock.source_type === 'url' &&\n imageBlock.url != null &&\n imageBlock.url !== ''\n ) {\n const parsedData = parseBase64DataUrl({\n dataUrl: imageBlock.url,\n asTypedArray: true,\n });\n if (parsedData != null) {\n const parsedMimeType = parseMimeType(parsedData.mime_type);\n return {\n image: {\n format: parsedMimeType.subtype as 'gif' | 'jpeg' | 'png' | 'webp',\n source: {\n bytes: parsedData.data as Uint8Array,\n },\n },\n };\n }\n } else if (\n imageBlock.source_type === 'base64' &&\n imageBlock.data != null &&\n imageBlock.data !== ''\n ) {\n let format: 'gif' | 'jpeg' | 'png' | 'webp' | undefined;\n if (imageBlock.mime_type != null && imageBlock.mime_type !== '') {\n const parsedMimeType = parseMimeType(imageBlock.mime_type);\n format = parsedMimeType.subtype as typeof format;\n }\n return {\n image: {\n format,\n source: {\n bytes: Uint8Array.from(atob(imageBlock.data), (c) =>\n c.charCodeAt(0)\n ),\n },\n },\n };\n }\n // If it already has the Bedrock image structure, pass through\n if ((block as { image?: unknown }).image !== undefined) {\n return {\n image: (block as { image: unknown }).image,\n } as BedrockContentBlock;\n }\n }\n\n if (\n block.type === 'video' &&\n (block as { video?: unknown }).video !== undefined\n ) {\n return {\n video: (block as { video: unknown }).video,\n } as BedrockContentBlock;\n }\n\n if (block.type === 'video') {\n return convertMultimodalVideoBlock(block as MediaContentBlock);\n }\n\n if (\n block.type === 'audio' &&\n (block as { audio?: unknown }).audio !== undefined\n ) {\n return {\n audio: (block as { audio: unknown }).audio,\n } as BedrockContentBlock;\n }\n\n if (block.type === 'audio') {\n return convertMultimodalAudioBlock(block as MediaContentBlock);\n }\n\n if (\n block.type === 'document' &&\n (block as { document?: unknown }).document !== undefined\n ) {\n return {\n document: (block as { document: unknown }).document,\n } as BedrockContentBlock;\n }\n\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n return {\n cachePoint,\n } as BedrockContentBlock;\n }\n\n if (onUnknown === 'throw') {\n throw new Error(`Unsupported content block type: ${block.type}`);\n } else {\n return block as unknown as BedrockContentBlock;\n }\n}\n\n/**\n * Convert a system message to Bedrock system content blocks.\n */\nfunction convertSystemMessageToConverseMessage(\n msg: BaseMessage\n): BedrockSystemContentBlock[] {\n if (typeof msg.content === 'string') {\n return [{ text: msg.content }];\n } else if (Array.isArray(msg.content) && msg.content.length > 0) {\n const contentBlocks: BedrockSystemContentBlock[] = [];\n for (const block of msg.content) {\n if (\n typeof block === 'object' &&\n block.type === 'text' &&\n typeof (block as { text?: string }).text === 'string'\n ) {\n contentBlocks.push({\n text: (block as { text: string }).text,\n });\n } else {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint == null) {\n break;\n }\n contentBlocks.push({\n cachePoint,\n } as BedrockSystemContentBlock);\n }\n }\n if (msg.content.length === contentBlocks.length) {\n return contentBlocks;\n }\n }\n throw new Error(\n 'System message content must be either a string, or an array of text blocks, optionally including a cache point.'\n );\n}\n\n/**\n * Convert an AI message to a Bedrock message.\n */\nfunction convertAIMessageToConverseMessage(msg: BaseMessage): BedrockMessage {\n // Check for v1 format from other providers (PR #9766 fix)\n const responseMetadata = msg.response_metadata as\n | { output_version?: string }\n | undefined;\n if (responseMetadata?.output_version === 'v1') {\n return convertFromV1ToChatBedrockConverseMessage(msg);\n }\n\n const assistantMsg: BedrockMessage = {\n role: 'assistant',\n content: [],\n };\n\n if (typeof msg.content === 'string' && msg.content !== '') {\n assistantMsg.content?.push({ text: msg.content });\n } else if (Array.isArray(msg.content)) {\n const concatenatedBlocks = concatenateLangchainReasoningBlocks(\n msg.content as Array<MessageContentComplex | MessageContentReasoningBlock>\n );\n const contentBlocks: BedrockContentBlock[] = [];\n\n concatenatedBlocks.forEach((block) => {\n if (block.type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n appendSerializableBedrockTextBlock(contentBlocks, text);\n } else if (block.type === 'reasoning_content') {\n const reasoningBlock = block as MessageContentReasoningBlock;\n // Bedrock Converse rejects reasoningContent whose reasoningText.text is\n // null/empty (a signature-only block that never merged with its text).\n // Drop it rather than emit an invalid request; the empty-turn\n // placeholder below covers a turn left with no content.\n if (!isSerializableBedrockReasoningBlock(reasoningBlock)) {\n return;\n }\n contentBlocks.push({\n reasoningContent:\n langchainReasoningBlockToBedrockReasoningBlock(reasoningBlock),\n } as BedrockContentBlock);\n } else {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n contentBlocks.push({\n cachePoint,\n } as BedrockContentBlock);\n } else if (FOREIGN_REASONING_TYPES.some((t) => t === block.type)) {\n // Reasoning from another provider (Anthropic `thinking`/\n // `redacted_thinking`, Google `reasoning`, LibreChat `think`).\n // Bedrock's native reasoning is `reasoning_content` (handled above); a\n // foreign block carries a signature Bedrock cannot validate, so drop\n // it on a cross-provider handoff (e.g. Anthropic → Bedrock) rather\n // than crash. The Bedrock model produces its own reasoning. Anything\n // else unknown still throws below — real content must be surfaced.\n return;\n } else if (FOREIGN_SERVER_TOOL_TYPES.some((t) => t === block.type)) {\n // Google server-side tool call/response (e.g. URL context) — only\n // Google can execute it or validate its thought signature; drop it\n // on a cross-provider handoff rather than crash.\n return;\n } else {\n const blockValues = Object.fromEntries(\n Object.entries(block).filter(([key]) => key !== 'type')\n );\n throw new Error(\n `Unsupported content block type: ${block.type} with content of ${JSON.stringify(blockValues, null, 2)}`\n );\n }\n }\n });\n\n assistantMsg.content = [...(assistantMsg.content ?? []), ...contentBlocks];\n }\n\n // Important: this must be placed after any reasoning content blocks\n if (isAIMessage(msg) && msg.tool_calls != null && msg.tool_calls.length > 0) {\n const toolUseBlocks = msg.tool_calls.map((tc) => ({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.args as Record<string, unknown>,\n },\n }));\n assistantMsg.content = [\n ...(assistantMsg.content ?? []),\n ...toolUseBlocks,\n ] as BedrockContentBlock[];\n }\n\n // Bedrock rejects an assistant message with no content blocks; if filtering\n // (e.g. dropping foreign reasoning) left it empty, emit a placeholder.\n if (assistantMsg.content == null || assistantMsg.content.length === 0) {\n assistantMsg.content = [{ text: BEDROCK_EMPTY_TEXT_PLACEHOLDER }];\n }\n\n return assistantMsg;\n}\n\n/**\n * Convert a v1 format message from other providers to Bedrock format.\n * This handles messages with standard content blocks like tool_call and reasoning.\n * (Implements PR #9766 fix for output_version v1 detection)\n */\nfunction convertFromV1ToChatBedrockConverseMessage(\n msg: BaseMessage\n): BedrockMessage {\n const contentBlocks: BedrockContentBlock[] = [];\n const assistantMsg: BedrockMessage = {\n role: 'assistant',\n content: contentBlocks,\n };\n let droppedUnserializableContent = false;\n let unconvertedContentType: string | undefined;\n\n if (Array.isArray(msg.content)) {\n const concatenatedBlocks = concatenateLangchainReasoningBlocks(\n msg.content as Array<MessageContentComplex | MessageContentReasoningBlock>\n );\n for (const block of concatenatedBlocks) {\n if (typeof block === 'string') {\n if (!appendSerializableBedrockTextBlock(contentBlocks, block)) {\n droppedUnserializableContent = true;\n }\n } else if (block.type === 'text') {\n const text = (block as { text?: string }).text ?? '';\n if (!appendSerializableBedrockTextBlock(contentBlocks, text)) {\n droppedUnserializableContent = true;\n }\n } else if (block.type === 'tool_call') {\n const toolCall = block as {\n id: string;\n name: string;\n args: Record<string, unknown>;\n };\n contentBlocks.push({\n toolUse: {\n toolUseId: toolCall.id,\n name: toolCall.name,\n input: toolCall.args as Record<string, unknown>,\n },\n } as BedrockContentBlock);\n } else if (block.type === 'reasoning') {\n const reasoning = block as { reasoning?: string };\n /** Bedrock Converse rejects `reasoningText` with a null/empty `text`\n * (`Member must not be null`), e.g. when the producing model omitted\n * reasoning text (`thinking.display: \"omitted\"`) — drop rather than send. */\n if (reasoning.reasoning == null || reasoning.reasoning === '') {\n droppedUnserializableContent = true;\n continue;\n }\n contentBlocks.push({\n reasoningContent: {\n reasoningText: { text: reasoning.reasoning },\n },\n } as BedrockContentBlock);\n } else if (block.type === 'reasoning_content') {\n const reasoningBlock = block as MessageContentReasoningBlock;\n if (!isSerializableBedrockReasoningBlock(reasoningBlock)) {\n droppedUnserializableContent = true;\n continue;\n }\n contentBlocks.push({\n reasoningContent:\n langchainReasoningBlockToBedrockReasoningBlock(reasoningBlock),\n } as BedrockContentBlock);\n } else {\n unconvertedContentType ??= block.type;\n }\n }\n } else if (typeof msg.content === 'string') {\n if (!appendSerializableBedrockTextBlock(contentBlocks, msg.content)) {\n droppedUnserializableContent = true;\n }\n }\n\n // Also handle tool_calls from the message\n if (isAIMessage(msg) && msg.tool_calls != null && msg.tool_calls.length > 0) {\n // Check if tool calls are already in content\n const existingToolUseIds = new Set(\n contentBlocks\n .filter((c) => 'toolUse' in c)\n .map((c) => (c as { toolUse: { toolUseId: string } }).toolUse.toolUseId)\n );\n\n for (const tc of msg.tool_calls) {\n if (!existingToolUseIds.has(tc.id ?? '')) {\n contentBlocks.push({\n toolUse: {\n toolUseId: tc.id,\n name: tc.name,\n input: tc.args as Record<string, unknown>,\n },\n } as BedrockContentBlock);\n }\n }\n }\n\n const hasNoContent = contentBlocks.length === 0;\n if (hasNoContent && unconvertedContentType != null) {\n throw new Error(\n `Unsupported v1 content block type: ${unconvertedContentType}`\n );\n }\n if (hasNoContent && droppedUnserializableContent) {\n contentBlocks.push({ text: BEDROCK_EMPTY_TEXT_PLACEHOLDER });\n }\n\n return assistantMsg;\n}\n\n/**\n * Convert a human message to a Bedrock message.\n */\nfunction convertHumanMessageToConverseMessage(\n msg: BaseMessage\n): BedrockMessage {\n const userMessage: BedrockMessage = {\n role: 'user',\n content: [],\n };\n\n if (typeof msg.content === 'string') {\n userMessage.content = [{ text: msg.content }];\n } else if (Array.isArray(msg.content)) {\n userMessage.content = msg.content.map((block) =>\n convertLangChainContentBlockToConverseContentBlock({ block })\n );\n }\n\n return userMessage;\n}\n\n/**\n * Convert a tool message to a Bedrock message.\n */\nfunction convertToolMessageToConverseMessage(msg: BaseMessage): BedrockMessage {\n const toolCallId = (msg as { tool_call_id?: string }).tool_call_id;\n\n let content: BedrockContentBlock[];\n if (typeof msg.content === 'string') {\n content = [{ text: msg.content }];\n } else if (Array.isArray(msg.content)) {\n content = msg.content.map((block) =>\n convertLangChainContentBlockToConverseContentBlock({\n block,\n onUnknown: 'passthrough',\n })\n );\n } else {\n content = [{ text: String(msg.content) }];\n }\n\n // A `cachePoint` is a message-level ContentBlock — it is NOT a valid\n // ToolResultContentBlock. A tail prompt-cache breakpoint that anchors on a\n // tool result therefore ends up nested inside `toolResult.content`, which\n // Bedrock silently ignores (no cache write, no cache read). Hoist any\n // cachePoint(s) out of the tool result body so they sit as siblings after\n // it, which is the only position Bedrock honors.\n const toolResultContent: BedrockContentBlock[] = [];\n const trailingCachePoints: BedrockContentBlock[] = [];\n for (const block of content) {\n const cachePoint = getDefaultCachePoint(block);\n if (cachePoint != null) {\n trailingCachePoints.push({\n cachePoint,\n } as BedrockContentBlock);\n } else {\n toolResultContent.push(block);\n }\n }\n\n return {\n role: 'user',\n content: [\n {\n toolResult: {\n toolUseId: toolCallId,\n content: toolResultContent as { text: string }[],\n },\n },\n ...trailingCachePoints,\n ],\n };\n}\n\n/**\n * Convert LangChain messages to Bedrock Converse messages.\n */\nexport function convertToConverseMessages(messages: BaseMessage[]): {\n converseMessages: BedrockMessage[];\n converseSystem: BedrockSystemContentBlock[];\n} {\n const converseSystem = messages\n .filter((msg) => msg._getType() === 'system')\n .flatMap((msg) => convertSystemMessageToConverseMessage(msg));\n\n const converseMessages = messages\n .filter((msg) => msg._getType() !== 'system')\n .map((msg) => {\n if (msg._getType() === 'ai') {\n return convertAIMessageToConverseMessage(msg);\n } else if (msg._getType() === 'human' || msg._getType() === 'generic') {\n return convertHumanMessageToConverseMessage(msg);\n } else if (msg._getType() === 'tool') {\n return convertToolMessageToConverseMessage(msg);\n } else {\n throw new Error(`Unsupported message type: ${msg._getType()}`);\n }\n });\n\n // Combine consecutive user tool result messages into a single message\n const combinedConverseMessages = converseMessages.reduce<BedrockMessage[]>(\n (acc, curr) => {\n if (acc.length === 0) {\n acc.push(curr);\n return acc;\n }\n const lastMessage = acc[acc.length - 1];\n const lastHasToolResult =\n lastMessage.content?.some((c) => 'toolResult' in c) === true;\n const currHasToolResult =\n curr.content?.some((c) => 'toolResult' in c) === true;\n if (\n lastMessage.role === 'user' &&\n lastHasToolResult &&\n curr.role === 'user' &&\n currHasToolResult\n ) {\n lastMessage.content = lastMessage.content?.concat(curr.content ?? []);\n } else {\n acc.push(curr);\n }\n return acc;\n },\n []\n );\n\n return { converseMessages: combinedConverseMessages, converseSystem };\n}\n"],"mappings":"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"}