@langchain/anthropic 1.3.17 → 1.3.18

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 (126) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +11 -7
  3. package/dist/chat_models.cjs +56 -70
  4. package/dist/chat_models.cjs.map +1 -1
  5. package/dist/chat_models.d.cts +0 -1
  6. package/dist/chat_models.d.cts.map +1 -1
  7. package/dist/chat_models.d.ts +0 -1
  8. package/dist/chat_models.d.ts.map +1 -1
  9. package/dist/chat_models.js +28 -42
  10. package/dist/chat_models.js.map +1 -1
  11. package/dist/index.cjs +1 -0
  12. package/dist/output_parsers.cjs +9 -11
  13. package/dist/output_parsers.cjs.map +1 -1
  14. package/dist/output_parsers.js +2 -4
  15. package/dist/output_parsers.js.map +1 -1
  16. package/dist/profiles.cjs +96 -29
  17. package/dist/profiles.cjs.map +1 -1
  18. package/dist/profiles.js +96 -29
  19. package/dist/profiles.js.map +1 -1
  20. package/dist/tools/bash.cjs +3 -3
  21. package/dist/tools/bash.cjs.map +1 -1
  22. package/dist/tools/bash.d.cts +7 -7
  23. package/dist/tools/bash.d.cts.map +1 -1
  24. package/dist/tools/bash.d.ts +7 -7
  25. package/dist/tools/bash.d.ts.map +1 -1
  26. package/dist/tools/bash.js.map +1 -1
  27. package/dist/tools/codeExecution.cjs.map +1 -1
  28. package/dist/tools/codeExecution.d.cts +0 -1
  29. package/dist/tools/codeExecution.d.cts.map +1 -1
  30. package/dist/tools/codeExecution.d.ts +0 -1
  31. package/dist/tools/codeExecution.d.ts.map +1 -1
  32. package/dist/tools/codeExecution.js.map +1 -1
  33. package/dist/tools/computer.cjs +4 -4
  34. package/dist/tools/computer.cjs.map +1 -1
  35. package/dist/tools/computer.d.cts +101 -101
  36. package/dist/tools/computer.d.cts.map +1 -1
  37. package/dist/tools/computer.d.ts +101 -101
  38. package/dist/tools/computer.d.ts.map +1 -1
  39. package/dist/tools/computer.js.map +1 -1
  40. package/dist/tools/index.cjs.map +1 -1
  41. package/dist/tools/index.d.cts.map +1 -1
  42. package/dist/tools/index.d.ts.map +1 -1
  43. package/dist/tools/index.js.map +1 -1
  44. package/dist/tools/mcpToolset.cjs.map +1 -1
  45. package/dist/tools/mcpToolset.d.cts +0 -1
  46. package/dist/tools/mcpToolset.d.cts.map +1 -1
  47. package/dist/tools/mcpToolset.d.ts +0 -1
  48. package/dist/tools/mcpToolset.d.ts.map +1 -1
  49. package/dist/tools/mcpToolset.js.map +1 -1
  50. package/dist/tools/memory.cjs +3 -3
  51. package/dist/tools/memory.cjs.map +1 -1
  52. package/dist/tools/memory.d.cts +27 -28
  53. package/dist/tools/memory.d.cts.map +1 -1
  54. package/dist/tools/memory.d.ts +25 -26
  55. package/dist/tools/memory.d.ts.map +1 -1
  56. package/dist/tools/memory.js.map +1 -1
  57. package/dist/tools/textEditor.cjs +3 -3
  58. package/dist/tools/textEditor.cjs.map +1 -1
  59. package/dist/tools/textEditor.d.cts +19 -19
  60. package/dist/tools/textEditor.d.cts.map +1 -1
  61. package/dist/tools/textEditor.d.ts +21 -21
  62. package/dist/tools/textEditor.d.ts.map +1 -1
  63. package/dist/tools/textEditor.js.map +1 -1
  64. package/dist/tools/toolSearch.cjs.map +1 -1
  65. package/dist/tools/toolSearch.d.cts +0 -1
  66. package/dist/tools/toolSearch.d.cts.map +1 -1
  67. package/dist/tools/toolSearch.d.ts +0 -1
  68. package/dist/tools/toolSearch.d.ts.map +1 -1
  69. package/dist/tools/toolSearch.js.map +1 -1
  70. package/dist/tools/types.cjs +2 -2
  71. package/dist/tools/types.cjs.map +1 -1
  72. package/dist/tools/types.d.cts +0 -1
  73. package/dist/tools/types.d.cts.map +1 -1
  74. package/dist/tools/types.d.ts +0 -1
  75. package/dist/tools/types.d.ts.map +1 -1
  76. package/dist/tools/types.js.map +1 -1
  77. package/dist/tools/webFetch.cjs.map +1 -1
  78. package/dist/tools/webFetch.d.cts +0 -1
  79. package/dist/tools/webFetch.d.cts.map +1 -1
  80. package/dist/tools/webFetch.d.ts +0 -1
  81. package/dist/tools/webFetch.d.ts.map +1 -1
  82. package/dist/tools/webFetch.js.map +1 -1
  83. package/dist/tools/webSearch.cjs.map +1 -1
  84. package/dist/tools/webSearch.d.cts +0 -1
  85. package/dist/tools/webSearch.d.cts.map +1 -1
  86. package/dist/tools/webSearch.d.ts +0 -1
  87. package/dist/tools/webSearch.d.ts.map +1 -1
  88. package/dist/tools/webSearch.js.map +1 -1
  89. package/dist/types.d.cts +0 -1
  90. package/dist/types.d.cts.map +1 -1
  91. package/dist/types.d.ts +0 -1
  92. package/dist/types.d.ts.map +1 -1
  93. package/dist/utils/content.cjs +3 -3
  94. package/dist/utils/content.cjs.map +1 -1
  95. package/dist/utils/content.js.map +1 -1
  96. package/dist/utils/errors.cjs +4 -1
  97. package/dist/utils/errors.cjs.map +1 -1
  98. package/dist/utils/errors.js +4 -1
  99. package/dist/utils/errors.js.map +1 -1
  100. package/dist/utils/index.cjs.map +1 -1
  101. package/dist/utils/index.js.map +1 -1
  102. package/dist/utils/message_inputs.cjs +79 -100
  103. package/dist/utils/message_inputs.cjs.map +1 -1
  104. package/dist/utils/message_inputs.js +73 -94
  105. package/dist/utils/message_inputs.js.map +1 -1
  106. package/dist/utils/message_outputs.cjs +28 -32
  107. package/dist/utils/message_outputs.cjs.map +1 -1
  108. package/dist/utils/message_outputs.js +13 -17
  109. package/dist/utils/message_outputs.js.map +1 -1
  110. package/dist/utils/prompts.cjs +1 -2
  111. package/dist/utils/prompts.cjs.map +1 -1
  112. package/dist/utils/prompts.d.cts +0 -1
  113. package/dist/utils/prompts.d.cts.map +1 -1
  114. package/dist/utils/prompts.d.ts +0 -1
  115. package/dist/utils/prompts.d.ts.map +1 -1
  116. package/dist/utils/prompts.js +1 -2
  117. package/dist/utils/prompts.js.map +1 -1
  118. package/dist/utils/standard.cjs +2 -4
  119. package/dist/utils/standard.cjs.map +1 -1
  120. package/dist/utils/standard.js +2 -4
  121. package/dist/utils/standard.js.map +1 -1
  122. package/dist/utils/tools.cjs +4 -3
  123. package/dist/utils/tools.cjs.map +1 -1
  124. package/dist/utils/tools.js +1 -1
  125. package/dist/utils/tools.js.map +1 -1
  126. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fn: () => T"],"sources":["../../src/utils/index.ts"],"sourcesContent":["export const iife = <T>(fn: () => T) => fn();\n\nexport const safeParseJson = <T>(json: string): T | object => {\n try {\n return JSON.parse(json);\n } catch {\n return {};\n }\n};\n"],"mappings":";AAAA,MAAa,OAAO,CAAIA,OAAgB,IAAI"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["export const iife = <T>(fn: () => T) => fn();\n\nexport const safeParseJson = <T>(json: string): T | object => {\n try {\n return JSON.parse(json);\n } catch {\n return {};\n }\n};\n"],"mappings":";AAAA,MAAa,QAAW,OAAgB,IAAI"}
@@ -1,11 +1,11 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
1
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
2
2
  const require_content = require('./content.cjs');
3
3
  const require_standard = require('./standard.cjs');
4
- const __langchain_core_messages = require_rolldown_runtime.__toESM(require("@langchain/core/messages"));
4
+ let _langchain_core_messages = require("@langchain/core/messages");
5
5
 
6
6
  //#region src/utils/message_inputs.ts
7
7
  function _formatImage(imageUrl) {
8
- const parsed = (0, __langchain_core_messages.parseBase64DataUrl)({ dataUrl: imageUrl });
8
+ const parsed = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: imageUrl });
9
9
  if (parsed) return {
10
10
  type: "base64",
11
11
  media_type: parsed.mime_type,
@@ -40,12 +40,12 @@ function _ensureMessageContents(messages) {
40
40
  content: message.content,
41
41
  tool_use_id: message.tool_call_id
42
42
  });
43
- else updatedMsgs.push(new __langchain_core_messages.HumanMessage({ content: [{
43
+ else updatedMsgs.push(new _langchain_core_messages.HumanMessage({ content: [{
44
44
  type: "tool_result",
45
45
  content: message.content,
46
46
  tool_use_id: message.tool_call_id
47
47
  }] }));
48
- } else updatedMsgs.push(new __langchain_core_messages.HumanMessage({ content: [{
48
+ } else updatedMsgs.push(new _langchain_core_messages.HumanMessage({ content: [{
49
49
  type: "tool_result",
50
50
  ...message.content != null ? { content: _formatContent(message) } : {},
51
51
  tool_use_id: message.tool_call_id
@@ -75,7 +75,7 @@ function* _formatContentBlocks(content, toolCalls) {
75
75
  ];
76
76
  const textTypes = ["text", "text_delta"];
77
77
  for (const contentPart of content) {
78
- if ((0, __langchain_core_messages.isDataContentBlock)(contentPart)) yield (0, __langchain_core_messages.convertToProviderContentBlock)(contentPart, require_content.standardContentBlockConverter);
78
+ if ((0, _langchain_core_messages.isDataContentBlock)(contentPart)) yield (0, _langchain_core_messages.convertToProviderContentBlock)(contentPart, require_content.standardContentBlockConverter);
79
79
  const cacheControl = "cache_control" in contentPart ? contentPart.cache_control : void 0;
80
80
  if (contentPart.type === "image_url") {
81
81
  let source;
@@ -90,15 +90,12 @@ function* _formatContentBlocks(content, toolCalls) {
90
90
  else if (contentPart.type === "image") {
91
91
  let source;
92
92
  if ("url" in contentPart && typeof contentPart.url === "string") source = _formatImage(contentPart.url);
93
- else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) {
94
- const mimeType = "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "image/jpeg";
95
- const data = typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64");
96
- source = {
97
- type: "base64",
98
- media_type: mimeType,
99
- data
100
- };
101
- } else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
93
+ else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) source = {
94
+ type: "base64",
95
+ media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "image/jpeg",
96
+ data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64")
97
+ };
98
+ else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
102
99
  type: "file",
103
100
  file_id: contentPart.fileId
104
101
  };
@@ -113,15 +110,12 @@ function* _formatContentBlocks(content, toolCalls) {
113
110
  type: "url",
114
111
  url: contentPart.url
115
112
  };
116
- else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) {
117
- const media_type = "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "application/pdf";
118
- const data = typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64");
119
- source = {
120
- type: "base64",
121
- media_type,
122
- data
123
- };
124
- } else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
113
+ else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) source = {
114
+ type: "base64",
115
+ media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "application/pdf",
116
+ data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64")
117
+ };
118
+ else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
125
119
  type: "file",
126
120
  file_id: contentPart.fileId
127
121
  };
@@ -134,39 +128,31 @@ function* _formatContentBlocks(content, toolCalls) {
134
128
  ...contentPart,
135
129
  ...cacheControl ? { cache_control: cacheControl } : {}
136
130
  };
137
- else if (require_content._isAnthropicThinkingBlock(contentPart)) {
138
- const block = {
139
- type: "thinking",
140
- thinking: contentPart.thinking,
141
- signature: contentPart.signature,
142
- ...cacheControl ? { cache_control: cacheControl } : {}
143
- };
144
- yield block;
145
- } else if (require_content._isAnthropicRedactedThinkingBlock(contentPart)) {
146
- const block = {
147
- type: "redacted_thinking",
148
- data: contentPart.data,
149
- ...cacheControl ? { cache_control: cacheControl } : {}
150
- };
151
- yield block;
152
- } else if (require_content._isAnthropicCompactionBlock(contentPart)) {
153
- const block = {
154
- type: "compaction",
155
- content: contentPart.content,
156
- ...cacheControl ? { cache_control: cacheControl } : {}
157
- };
158
- yield block;
159
- } else if (require_content._isAnthropicSearchResultBlock(contentPart)) {
160
- const block = {
161
- type: "search_result",
162
- title: contentPart.title,
163
- source: contentPart.source,
164
- ..."cache_control" in contentPart && contentPart.cache_control ? { cache_control: contentPart.cache_control } : {},
165
- ..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {},
166
- content: contentPart.content
167
- };
168
- yield block;
169
- } else if (textTypes.find((t) => t === contentPart.type) && "text" in contentPart) yield {
131
+ else if (require_content._isAnthropicThinkingBlock(contentPart)) yield {
132
+ type: "thinking",
133
+ thinking: contentPart.thinking,
134
+ signature: contentPart.signature,
135
+ ...cacheControl ? { cache_control: cacheControl } : {}
136
+ };
137
+ else if (require_content._isAnthropicRedactedThinkingBlock(contentPart)) yield {
138
+ type: "redacted_thinking",
139
+ data: contentPart.data,
140
+ ...cacheControl ? { cache_control: cacheControl } : {}
141
+ };
142
+ else if (require_content._isAnthropicCompactionBlock(contentPart)) yield {
143
+ type: "compaction",
144
+ content: contentPart.content,
145
+ ...cacheControl ? { cache_control: cacheControl } : {}
146
+ };
147
+ else if (require_content._isAnthropicSearchResultBlock(contentPart)) yield {
148
+ type: "search_result",
149
+ title: contentPart.title,
150
+ source: contentPart.source,
151
+ ..."cache_control" in contentPart && contentPart.cache_control ? { cache_control: contentPart.cache_control } : {},
152
+ ..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {},
153
+ content: contentPart.content
154
+ };
155
+ else if (textTypes.find((t) => t === contentPart.type) && "text" in contentPart) yield {
170
156
  type: "text",
171
157
  text: contentPart.text,
172
158
  ...cacheControl ? { cache_control: cacheControl } : {},
@@ -178,10 +164,7 @@ function* _formatContentBlocks(content, toolCalls) {
178
164
  if (contentPartCopy.type === "tool_use" && typeof contentPartCopy.input === "string") {
179
165
  const matchingToolCall = toolCalls?.find((tc) => tc.id === contentPartCopy.id);
180
166
  if (matchingToolCall) contentPartCopy.input = matchingToolCall.args;
181
- else {
182
- const inputDeltas = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string");
183
- contentPartCopy.input = inputDeltas.reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
184
- }
167
+ else contentPartCopy.input = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string").reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
185
168
  }
186
169
  if ("index" in contentPartCopy) delete contentPartCopy.index;
187
170
  if ("input" in contentPartCopy) {
@@ -216,45 +199,42 @@ function _convertMessagesToAnthropicPayload(messages) {
216
199
  const mergedMessages = _ensureMessageContents(messages);
217
200
  let system;
218
201
  if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") system = messages[0].content;
219
- const conversationMessages = system !== void 0 ? mergedMessages.slice(1) : mergedMessages;
220
- const formattedMessages = conversationMessages.map((message) => {
221
- let role;
222
- if (message._getType() === "human") role = "user";
223
- else if (message._getType() === "ai") role = "assistant";
224
- else if (message._getType() === "tool") role = "user";
225
- else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
226
- else throw new Error(`Message type "${message.type}" is not supported.`);
227
- if (__langchain_core_messages.AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
228
- role,
229
- content: require_standard._formatStandardContent(message)
230
- };
231
- if (__langchain_core_messages.AIMessage.isInstance(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return {
232
- role,
233
- content: message.tool_calls.map(_convertLangChainToolCallToAnthropic)
234
- };
235
- else return {
236
- role,
237
- content: [{
238
- type: "text",
239
- text: message.content
240
- }, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)]
241
- };
242
- else {
243
- const { content } = message;
244
- const hasMismatchedToolCalls = !message.tool_calls.every((toolCall) => content.find((contentPart) => (contentPart.type === "tool_use" || contentPart.type === "input_json_delta" || contentPart.type === "server_tool_use") && contentPart.id === toolCall.id));
245
- if (hasMismatchedToolCalls) console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
246
- return {
202
+ return {
203
+ messages: mergeMessages((system !== void 0 ? mergedMessages.slice(1) : mergedMessages).map((message) => {
204
+ let role;
205
+ if (message._getType() === "human") role = "user";
206
+ else if (message._getType() === "ai") role = "assistant";
207
+ else if (message._getType() === "tool") role = "user";
208
+ else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
209
+ else throw new Error(`Message type "${message.type}" is not supported.`);
210
+ if (_langchain_core_messages.AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
247
211
  role,
248
- content: _formatContent(message, message.tool_calls)
212
+ content: require_standard._formatStandardContent(message)
249
213
  };
250
- }
251
- else return {
252
- role,
253
- content: _formatContent(message, __langchain_core_messages.AIMessage.isInstance(message) ? message.tool_calls : void 0)
254
- };
255
- });
256
- return {
257
- messages: mergeMessages(formattedMessages),
214
+ if (_langchain_core_messages.AIMessage.isInstance(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return {
215
+ role,
216
+ content: message.tool_calls.map(_convertLangChainToolCallToAnthropic)
217
+ };
218
+ else return {
219
+ role,
220
+ content: [{
221
+ type: "text",
222
+ text: message.content
223
+ }, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)]
224
+ };
225
+ else {
226
+ const { content } = message;
227
+ if (!message.tool_calls.every((toolCall) => content.find((contentPart) => (contentPart.type === "tool_use" || contentPart.type === "input_json_delta" || contentPart.type === "server_tool_use") && contentPart.id === toolCall.id))) console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
228
+ return {
229
+ role,
230
+ content: _formatContent(message, message.tool_calls)
231
+ };
232
+ }
233
+ else return {
234
+ role,
235
+ content: _formatContent(message, _langchain_core_messages.AIMessage.isInstance(message) ? message.tool_calls : void 0)
236
+ };
237
+ })),
258
238
  system
259
239
  };
260
240
  }
@@ -293,9 +273,8 @@ function applyCacheControlToPayload(payload, cacheControl) {
293
273
  if (Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {
294
274
  const content = [...lastMessage.content];
295
275
  const lastBlockIndex = content.length - 1;
296
- const lastBlock = content[lastBlockIndex];
297
276
  content[lastBlockIndex] = {
298
- ...lastBlock,
277
+ ...content[lastBlockIndex],
299
278
  cache_control: cacheControl
300
279
  };
301
280
  messages[lastMessageIndex] = {
@@ -1 +1 @@
1
- {"version":3,"file":"message_inputs.cjs","names":["imageUrl: string","parsedUrl: URL","messages: BaseMessage[]","HumanMessage","toolCall: ToolCall","content: ContentBlock[]","toolCalls?: ToolCall[]","standardContentBlockConverter","_isAnthropicImageBlockParam","source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined","_isAnthropicThinkingBlock","block: AnthropicThinkingBlockParam","_isAnthropicRedactedThinkingBlock","block: AnthropicRedactedThinkingBlockParam","_isAnthropicCompactionBlock","block: AnthropicCompactionBlockParam","_isAnthropicSearchResultBlock","block: AnthropicSearchResultBlockParam","message: BaseMessage","AIMessage","_formatStandardContent","payload: AnthropicMessageCreateParams","cacheControl: CacheControl","messages: AnthropicMessageCreateParams[\"messages\"]","result: AnthropicMessageCreateParams[\"messages\"]","content:\n | string\n | Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n >","msg: (typeof messages)[0]"],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicImageBlockParam,\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicToolResultBlockParam,\n AnthropicToolUseBlockParam,\n AnthropicDocumentBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicServerToolUseBlockParam,\n AnthropicWebSearchToolResultBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // eslint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // eslint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n contentPartCopy.type === \"tool_use\" &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` content part may be followed by `input_json_delta`\n // content parts which are chunks of a stringified JSON input,\n // so we need to collect them and merge their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n let system;\n if (mergedMessages.length > 0 && mergedMessages[0]._getType() === \"system\") {\n system = messages[0].content;\n }\n const conversationMessages =\n system !== undefined ? mergedMessages.slice(1) : mergedMessages;\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n throw new Error(\n \"System messages are only permitted as the first passed message.\"\n );\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const hasMismatchedToolCalls = !message.tool_calls.every((toolCall) =>\n content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n if (hasMismatchedToolCalls) {\n console.warn(\n `The \"tool_calls\" field on a message is only respected if content is a string.`\n );\n }\n return {\n role,\n content: _formatContent(message, message.tool_calls),\n };\n }\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Cache control configuration for Anthropic prompt caching.\n */\ninterface CacheControl {\n type: \"ephemeral\";\n ttl?: \"5m\" | \"1h\";\n}\n\n/**\n * Applies cache_control to the last content block of the last message in the payload.\n * This is the recommended approach for prompt caching as it applies the cache_control\n * at the final formatting layer, after all message processing is complete.\n *\n * This matches the Python langchain-anthropic implementation where cache_control\n * is applied via model_settings rather than modifying message content blocks directly.\n *\n * @param payload - The formatted Anthropic message payload\n * @param cacheControl - The cache control configuration to apply\n * @returns The payload with cache_control applied to the last content block\n */\nexport function applyCacheControlToPayload(\n payload: AnthropicMessageCreateParams,\n cacheControl: CacheControl\n): AnthropicMessageCreateParams {\n if (!payload.messages || payload.messages.length === 0) {\n return payload;\n }\n\n const messages = [...payload.messages];\n const lastMessageIndex = messages.length - 1;\n const lastMessage = messages[lastMessageIndex];\n\n if (!lastMessage) {\n return payload;\n }\n\n // Handle string content - convert to text block with cache_control\n if (typeof lastMessage.content === \"string\") {\n messages[lastMessageIndex] = {\n ...lastMessage,\n content: [\n {\n type: \"text\",\n text: lastMessage.content,\n cache_control: cacheControl,\n },\n ],\n };\n return { ...payload, messages };\n }\n\n // Handle array content - add cache_control to the last block\n if (Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {\n const content = [...lastMessage.content];\n const lastBlockIndex = content.length - 1;\n const lastBlock = content[lastBlockIndex];\n\n // Add cache_control to the last block\n content[lastBlockIndex] = {\n ...lastBlock,\n cache_control: cacheControl,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n\n messages[lastMessageIndex] = {\n ...lastMessage,\n content,\n };\n return { ...payload, messages };\n }\n\n return payload;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content:\n | string\n | Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n >\n ): Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n > => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"message_inputs.cjs","names":["HumanMessage","standardContentBlockConverter","_isAnthropicImageBlockParam","_isAnthropicThinkingBlock","_isAnthropicRedactedThinkingBlock","_isAnthropicCompactionBlock","_isAnthropicSearchResultBlock","AIMessage","_formatStandardContent"],"sources":["../../src/utils/message_inputs.ts"],"sourcesContent":["/**\n * This util file contains functions for converting LangChain messages to Anthropic messages.\n */\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport {\n type BaseMessage,\n HumanMessage,\n ToolMessage,\n MessageContentComplex,\n isDataContentBlock,\n convertToProviderContentBlock,\n parseBase64DataUrl,\n ContentBlock,\n AIMessage,\n} from \"@langchain/core/messages\";\nimport { ToolCall } from \"@langchain/core/messages/tool\";\nimport {\n AnthropicImageBlockParam,\n AnthropicMessageCreateParams,\n AnthropicTextBlockParam,\n AnthropicToolResultBlockParam,\n AnthropicToolUseBlockParam,\n AnthropicDocumentBlockParam,\n AnthropicThinkingBlockParam,\n AnthropicRedactedThinkingBlockParam,\n AnthropicServerToolUseBlockParam,\n AnthropicWebSearchToolResultBlockParam,\n AnthropicSearchResultBlockParam,\n AnthropicToolResponse,\n AnthropicContainerUploadBlockParam,\n AnthropicCompactionBlockParam,\n} from \"../types.js\";\nimport {\n _isAnthropicImageBlockParam,\n _isAnthropicRedactedThinkingBlock,\n _isAnthropicSearchResultBlock,\n _isAnthropicThinkingBlock,\n _isAnthropicCompactionBlock,\n standardContentBlockConverter,\n} from \"./content.js\";\nimport { _formatStandardContent } from \"./standard.js\";\n\nfunction _formatImage(imageUrl: string) {\n const parsed = parseBase64DataUrl({ dataUrl: imageUrl });\n if (parsed) {\n return {\n type: \"base64\",\n media_type: parsed.mime_type,\n data: parsed.data,\n };\n }\n let parsedUrl: URL;\n\n try {\n parsedUrl = new URL(imageUrl);\n } catch {\n throw new Error(\n [\n `Malformed image URL: ${JSON.stringify(\n imageUrl\n )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n }\n\n if (parsedUrl.protocol === \"http:\" || parsedUrl.protocol === \"https:\") {\n return {\n type: \"url\",\n url: imageUrl,\n };\n }\n\n throw new Error(\n [\n `Invalid image URL protocol: ${JSON.stringify(\n parsedUrl.protocol\n )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,\n \"Example: data:image/png;base64,/9j/4AAQSk...\",\n \"Example: https://example.com/image.jpg\",\n ].join(\"\\n\\n\")\n );\n}\n\nfunction _ensureMessageContents(messages: BaseMessage[]): BaseMessage[] {\n // Merge runs of human/tool messages into single human messages with content blocks.\n const updatedMsgs = [];\n for (const message of messages) {\n if (message._getType() === \"tool\") {\n if (typeof message.content === \"string\") {\n const previousMessage = updatedMsgs[updatedMsgs.length - 1];\n if (\n previousMessage?._getType() === \"human\" &&\n Array.isArray(previousMessage.content) &&\n \"type\" in previousMessage.content[0] &&\n previousMessage.content[0].type === \"tool_result\"\n ) {\n // If the previous message was a tool result, we merge this tool message into it.\n (previousMessage.content as MessageContentComplex[]).push({\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n });\n } else {\n // If not, we create a new human message with the tool result.\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n content: message.content,\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(\n new HumanMessage({\n content: [\n {\n type: \"tool_result\",\n // rare case: message.content could be undefined\n ...(message.content != null\n ? { content: _formatContent(message) }\n : {}),\n tool_use_id: (message as ToolMessage).tool_call_id,\n },\n ],\n })\n );\n }\n } else {\n updatedMsgs.push(message);\n }\n }\n return updatedMsgs;\n}\n\nexport function _convertLangChainToolCallToAnthropic(\n toolCall: ToolCall\n): AnthropicToolResponse {\n if (toolCall.id === undefined) {\n throw new Error(`Anthropic requires all tool calls to have an \"id\".`);\n }\n return {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args,\n };\n}\n\nfunction* _formatContentBlocks(\n content: ContentBlock[],\n toolCalls?: ToolCall[]\n): Generator<Anthropic.Beta.BetaContentBlockParam> {\n const toolTypes = [\n \"bash_code_execution_tool_result\",\n \"input_json_delta\",\n \"server_tool_use\",\n \"text_editor_code_execution_tool_result\",\n \"tool_result\",\n \"tool_use\",\n \"web_search_result\",\n \"web_search_tool_result\",\n ];\n const textTypes = [\"text\", \"text_delta\"];\n for (const contentPart of content) {\n if (isDataContentBlock(contentPart)) {\n yield convertToProviderContentBlock(\n contentPart,\n standardContentBlockConverter\n );\n }\n\n const cacheControl =\n \"cache_control\" in contentPart\n ? (contentPart.cache_control as Anthropic.Beta.BetaCacheControlEphemeral)\n : undefined;\n\n if (contentPart.type === \"image_url\") {\n let source;\n if (typeof contentPart.image_url === \"string\") {\n source = _formatImage(contentPart.image_url);\n } else if (\n typeof contentPart.image_url === \"object\" &&\n contentPart.image_url !== null &&\n \"url\" in contentPart.image_url &&\n typeof contentPart.image_url.url === \"string\"\n ) {\n source = _formatImage(contentPart.image_url.url);\n }\n if (source) {\n yield {\n type: \"image\" as const, // Explicitly setting the type as \"image\"\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (_isAnthropicImageBlockParam(contentPart)) {\n yield contentPart;\n } else if (contentPart.type === \"image\") {\n // Handle new ContentBlock.Multimodal.Image format\n let source;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // URL-based image\n source = _formatImage(contentPart.url);\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // eslint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // Base64-based image\n const mimeType =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"image/jpeg\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n source = {\n type: \"base64\" as const,\n media_type: mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID-based image\n // Note: Anthropic supports file IDs for images that have been uploaded\n // to their servers via the Files API\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"image\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.ImageBlockParam;\n }\n } else if (contentPart.type === \"file\") {\n // Handle new ContentBlock.Multimodal.File format\n let source:\n | { type: \"url\"; url: string }\n | { type: \"base64\"; media_type: string; data: string }\n | { type: \"file\"; file_id: string }\n | undefined;\n\n if (\"url\" in contentPart && typeof contentPart.url === \"string\") {\n // File with URL\n source = {\n type: \"url\" as const,\n url: contentPart.url,\n };\n } else if (\n \"data\" in contentPart &&\n (typeof contentPart.data === \"string\" ||\n // eslint-disable-next-line no-instanceof/no-instanceof\n contentPart.data instanceof Uint8Array)\n ) {\n // File with base64 data (string or Uint8Array)\n const media_type =\n \"mimeType\" in contentPart && typeof contentPart.mimeType === \"string\"\n ? contentPart.mimeType\n : \"application/pdf\";\n const data =\n typeof contentPart.data === \"string\"\n ? contentPart.data\n : Buffer.from(contentPart.data).toString(\"base64\");\n\n source = {\n type: \"base64\" as const,\n media_type,\n data,\n };\n } else if (\n \"fileId\" in contentPart &&\n typeof contentPart.fileId === \"string\"\n ) {\n // File ID from Anthropic Files API\n // https://platform.claude.com/docs/en/build-with-claude/pdf-support#option-3-files-api\n source = {\n type: \"file\" as const,\n file_id: contentPart.fileId,\n };\n }\n\n if (source) {\n yield {\n type: \"document\" as const,\n source,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n }\n } else if (contentPart.type === \"document\") {\n // PDF\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as Anthropic.Messages.DocumentBlockParam;\n } else if (_isAnthropicThinkingBlock(contentPart)) {\n const block: AnthropicThinkingBlockParam = {\n type: \"thinking\" as const, // Explicitly setting the type as \"thinking\"\n thinking: contentPart.thinking,\n signature: contentPart.signature,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {\n const block: AnthropicRedactedThinkingBlockParam = {\n type: \"redacted_thinking\" as const, // Explicitly setting the type as \"redacted_thinking\"\n data: contentPart.data,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicCompactionBlock(contentPart)) {\n const block: AnthropicCompactionBlockParam = {\n type: \"compaction\" as const,\n content: contentPart.content,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n };\n yield block;\n } else if (_isAnthropicSearchResultBlock(contentPart)) {\n const block: AnthropicSearchResultBlockParam = {\n type: \"search_result\" as const, // Explicitly setting the type as \"search_result\"\n title: contentPart.title,\n source: contentPart.source,\n ...(\"cache_control\" in contentPart && contentPart.cache_control\n ? { cache_control: contentPart.cache_control }\n : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n content: contentPart.content,\n };\n yield block as Anthropic.Beta.BetaSearchResultBlockParam;\n } else if (\n textTypes.find((t) => t === contentPart.type) &&\n \"text\" in contentPart\n ) {\n // Assuming contentPart is of type MessageContentText here\n yield {\n type: \"text\" as const, // Explicitly setting the type as \"text\"\n text: contentPart.text,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n ...(\"citations\" in contentPart && contentPart.citations\n ? { citations: contentPart.citations }\n : {}),\n } as Anthropic.Messages.TextBlockParam;\n } else if (toolTypes.find((t) => t === contentPart.type)) {\n const contentPartCopy = { ...contentPart };\n\n if (contentPartCopy.type === \"input_json_delta\") {\n // `input_json_delta` type only represents yielding partial tool inputs\n // and is not a valid type for Anthropic messages.\n // These blocks appear in streaming responses and should be skipped\n // as their input data is already captured in tool_calls.\n continue;\n }\n\n if (\n contentPartCopy.type === \"tool_use\" &&\n typeof contentPartCopy.input === \"string\"\n ) {\n // First, try to get the input from the corresponding tool_call.\n // This is the most reliable source since tool_calls are properly\n // consolidated from tool_call_chunks during streaming.\n const matchingToolCall = toolCalls?.find(\n (tc) => tc.id === contentPartCopy.id\n );\n if (matchingToolCall) {\n contentPartCopy.input = matchingToolCall.args;\n } else {\n // Fallback: `tool_use` content part may be followed by `input_json_delta`\n // content parts which are chunks of a stringified JSON input,\n // so we need to collect them and merge their inputs.\n const inputDeltas = content.filter(\n (nestedContentPart) =>\n nestedContentPart.index === contentPartCopy.index &&\n nestedContentPart.type === \"input_json_delta\" &&\n typeof nestedContentPart.input === \"string\"\n );\n // If no `input_json_delta` parts are found, this line will just\n // return `contentPartCopy.input`, so no additional check is needed\n contentPartCopy.input = inputDeltas.reduce(\n (accumulator, nestedContentPart) =>\n accumulator + nestedContentPart.input,\n contentPartCopy.input\n );\n }\n }\n\n if (\"index\" in contentPartCopy) {\n // Anthropic does not support passing the index field here, so we remove it.\n delete contentPartCopy.index;\n }\n\n if (\"input\" in contentPartCopy) {\n // Anthropic tool use inputs should be valid objects, when applicable.\n if (typeof contentPartCopy.input === \"string\") {\n try {\n contentPartCopy.input = JSON.parse(contentPartCopy.input);\n } catch {\n contentPartCopy.input = {};\n }\n }\n }\n // TODO: Fix when SDK types are fixed\n yield {\n ...contentPartCopy,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n } else if (contentPart.type === \"container_upload\") {\n yield {\n ...contentPart,\n ...(cacheControl ? { cache_control: cacheControl } : {}),\n } as AnthropicContainerUploadBlockParam;\n }\n\n // Note that we are intentionally dropping any blocks that we don't\n // recognize. This is to allow for cross-compatibility between different\n // providers that may have different block types. Ie if we take a message\n // output from OpenAI and send it to Anthropic, we want to drop any blocks\n // that Anthropic doesn't understand.\n }\n}\n\nfunction _formatContent(message: BaseMessage, toolCalls?: ToolCall[]) {\n const { content } = message;\n\n if (typeof content === \"string\") {\n return content;\n } else {\n return Array.from(_formatContentBlocks(content, toolCalls));\n }\n}\n\n/**\n * Formats messages as a prompt for the model.\n * Used in LangSmith, export is important here.\n * @param messages The base messages to format as a prompt.\n * @returns The formatted prompt.\n */\nexport function _convertMessagesToAnthropicPayload(\n messages: BaseMessage[]\n): AnthropicMessageCreateParams {\n const mergedMessages = _ensureMessageContents(messages);\n let system;\n if (mergedMessages.length > 0 && mergedMessages[0]._getType() === \"system\") {\n system = messages[0].content;\n }\n const conversationMessages =\n system !== undefined ? mergedMessages.slice(1) : mergedMessages;\n const formattedMessages = conversationMessages.map((message) => {\n let role;\n if (message._getType() === \"human\") {\n role = \"user\" as const;\n } else if (message._getType() === \"ai\") {\n role = \"assistant\" as const;\n } else if (message._getType() === \"tool\") {\n role = \"user\" as const;\n } else if (message._getType() === \"system\") {\n throw new Error(\n \"System messages are only permitted as the first passed message.\"\n );\n } else {\n throw new Error(`Message type \"${message.type}\" is not supported.`);\n }\n if (\n AIMessage.isInstance(message) &&\n message.response_metadata?.output_version === \"v1\"\n ) {\n return {\n role,\n content: _formatStandardContent(message),\n };\n }\n if (AIMessage.isInstance(message) && !!message.tool_calls?.length) {\n if (typeof message.content === \"string\") {\n if (message.content === \"\") {\n return {\n role,\n content: message.tool_calls.map(\n _convertLangChainToolCallToAnthropic\n ),\n };\n } else {\n return {\n role,\n content: [\n { type: \"text\", text: message.content },\n ...message.tool_calls.map(_convertLangChainToolCallToAnthropic),\n ],\n };\n }\n } else {\n const { content } = message;\n const hasMismatchedToolCalls = !message.tool_calls.every((toolCall) =>\n content.find(\n (contentPart) =>\n (contentPart.type === \"tool_use\" ||\n contentPart.type === \"input_json_delta\" ||\n contentPart.type === \"server_tool_use\") &&\n contentPart.id === toolCall.id\n )\n );\n if (hasMismatchedToolCalls) {\n console.warn(\n `The \"tool_calls\" field on a message is only respected if content is a string.`\n );\n }\n return {\n role,\n content: _formatContent(message, message.tool_calls),\n };\n }\n } else {\n return {\n role,\n content: _formatContent(\n message,\n AIMessage.isInstance(message) ? message.tool_calls : undefined\n ),\n };\n }\n });\n return {\n messages: mergeMessages(\n formattedMessages as AnthropicMessageCreateParams[\"messages\"]\n ),\n system,\n } as AnthropicMessageCreateParams;\n}\n\n/**\n * Cache control configuration for Anthropic prompt caching.\n */\ninterface CacheControl {\n type: \"ephemeral\";\n ttl?: \"5m\" | \"1h\";\n}\n\n/**\n * Applies cache_control to the last content block of the last message in the payload.\n * This is the recommended approach for prompt caching as it applies the cache_control\n * at the final formatting layer, after all message processing is complete.\n *\n * This matches the Python langchain-anthropic implementation where cache_control\n * is applied via model_settings rather than modifying message content blocks directly.\n *\n * @param payload - The formatted Anthropic message payload\n * @param cacheControl - The cache control configuration to apply\n * @returns The payload with cache_control applied to the last content block\n */\nexport function applyCacheControlToPayload(\n payload: AnthropicMessageCreateParams,\n cacheControl: CacheControl\n): AnthropicMessageCreateParams {\n if (!payload.messages || payload.messages.length === 0) {\n return payload;\n }\n\n const messages = [...payload.messages];\n const lastMessageIndex = messages.length - 1;\n const lastMessage = messages[lastMessageIndex];\n\n if (!lastMessage) {\n return payload;\n }\n\n // Handle string content - convert to text block with cache_control\n if (typeof lastMessage.content === \"string\") {\n messages[lastMessageIndex] = {\n ...lastMessage,\n content: [\n {\n type: \"text\",\n text: lastMessage.content,\n cache_control: cacheControl,\n },\n ],\n };\n return { ...payload, messages };\n }\n\n // Handle array content - add cache_control to the last block\n if (Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {\n const content = [...lastMessage.content];\n const lastBlockIndex = content.length - 1;\n const lastBlock = content[lastBlockIndex];\n\n // Add cache_control to the last block\n content[lastBlockIndex] = {\n ...lastBlock,\n cache_control: cacheControl,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n\n messages[lastMessageIndex] = {\n ...lastMessage,\n content,\n };\n return { ...payload, messages };\n }\n\n return payload;\n}\n\nfunction mergeMessages(messages: AnthropicMessageCreateParams[\"messages\"]) {\n if (!messages || messages.length <= 1) {\n return messages;\n }\n\n const result: AnthropicMessageCreateParams[\"messages\"] = [];\n let currentMessage = messages[0];\n\n const normalizeContent = (\n content:\n | string\n | Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n >\n ): Array<\n | AnthropicTextBlockParam\n | AnthropicImageBlockParam\n | AnthropicToolUseBlockParam\n | AnthropicToolResultBlockParam\n | AnthropicDocumentBlockParam\n | AnthropicThinkingBlockParam\n | AnthropicRedactedThinkingBlockParam\n | AnthropicServerToolUseBlockParam\n | AnthropicWebSearchToolResultBlockParam\n | AnthropicSearchResultBlockParam\n > => {\n if (typeof content === \"string\") {\n return [\n {\n type: \"text\",\n text: content,\n },\n ];\n }\n return content;\n };\n\n const isToolResultMessage = (msg: (typeof messages)[0]) => {\n if (msg.role !== \"user\") return false;\n\n if (typeof msg.content === \"string\") {\n return false;\n }\n\n return (\n Array.isArray(msg.content) &&\n msg.content.every((item) => item.type === \"tool_result\")\n );\n };\n\n for (let i = 1; i < messages.length; i += 1) {\n const nextMessage = messages[i];\n\n if (\n isToolResultMessage(currentMessage) &&\n isToolResultMessage(nextMessage)\n ) {\n // Merge the messages by combining their content arrays\n currentMessage = {\n ...currentMessage,\n content: [\n ...normalizeContent(currentMessage.content),\n ...normalizeContent(nextMessage.content),\n ],\n };\n } else {\n result.push(currentMessage);\n currentMessage = nextMessage;\n }\n }\n\n result.push(currentMessage);\n return result;\n}\n"],"mappings":"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"}
@@ -89,15 +89,12 @@ function* _formatContentBlocks(content, toolCalls) {
89
89
  else if (contentPart.type === "image") {
90
90
  let source;
91
91
  if ("url" in contentPart && typeof contentPart.url === "string") source = _formatImage(contentPart.url);
92
- else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) {
93
- const mimeType = "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "image/jpeg";
94
- const data = typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64");
95
- source = {
96
- type: "base64",
97
- media_type: mimeType,
98
- data
99
- };
100
- } else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
92
+ else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) source = {
93
+ type: "base64",
94
+ media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "image/jpeg",
95
+ data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64")
96
+ };
97
+ else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
101
98
  type: "file",
102
99
  file_id: contentPart.fileId
103
100
  };
@@ -112,15 +109,12 @@ function* _formatContentBlocks(content, toolCalls) {
112
109
  type: "url",
113
110
  url: contentPart.url
114
111
  };
115
- else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) {
116
- const media_type = "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "application/pdf";
117
- const data = typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64");
118
- source = {
119
- type: "base64",
120
- media_type,
121
- data
122
- };
123
- } else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
112
+ else if ("data" in contentPart && (typeof contentPart.data === "string" || contentPart.data instanceof Uint8Array)) source = {
113
+ type: "base64",
114
+ media_type: "mimeType" in contentPart && typeof contentPart.mimeType === "string" ? contentPart.mimeType : "application/pdf",
115
+ data: typeof contentPart.data === "string" ? contentPart.data : Buffer.from(contentPart.data).toString("base64")
116
+ };
117
+ else if ("fileId" in contentPart && typeof contentPart.fileId === "string") source = {
124
118
  type: "file",
125
119
  file_id: contentPart.fileId
126
120
  };
@@ -133,39 +127,31 @@ function* _formatContentBlocks(content, toolCalls) {
133
127
  ...contentPart,
134
128
  ...cacheControl ? { cache_control: cacheControl } : {}
135
129
  };
136
- else if (_isAnthropicThinkingBlock(contentPart)) {
137
- const block = {
138
- type: "thinking",
139
- thinking: contentPart.thinking,
140
- signature: contentPart.signature,
141
- ...cacheControl ? { cache_control: cacheControl } : {}
142
- };
143
- yield block;
144
- } else if (_isAnthropicRedactedThinkingBlock(contentPart)) {
145
- const block = {
146
- type: "redacted_thinking",
147
- data: contentPart.data,
148
- ...cacheControl ? { cache_control: cacheControl } : {}
149
- };
150
- yield block;
151
- } else if (_isAnthropicCompactionBlock(contentPart)) {
152
- const block = {
153
- type: "compaction",
154
- content: contentPart.content,
155
- ...cacheControl ? { cache_control: cacheControl } : {}
156
- };
157
- yield block;
158
- } else if (_isAnthropicSearchResultBlock(contentPart)) {
159
- const block = {
160
- type: "search_result",
161
- title: contentPart.title,
162
- source: contentPart.source,
163
- ..."cache_control" in contentPart && contentPart.cache_control ? { cache_control: contentPart.cache_control } : {},
164
- ..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {},
165
- content: contentPart.content
166
- };
167
- yield block;
168
- } else if (textTypes.find((t) => t === contentPart.type) && "text" in contentPart) yield {
130
+ else if (_isAnthropicThinkingBlock(contentPart)) yield {
131
+ type: "thinking",
132
+ thinking: contentPart.thinking,
133
+ signature: contentPart.signature,
134
+ ...cacheControl ? { cache_control: cacheControl } : {}
135
+ };
136
+ else if (_isAnthropicRedactedThinkingBlock(contentPart)) yield {
137
+ type: "redacted_thinking",
138
+ data: contentPart.data,
139
+ ...cacheControl ? { cache_control: cacheControl } : {}
140
+ };
141
+ else if (_isAnthropicCompactionBlock(contentPart)) yield {
142
+ type: "compaction",
143
+ content: contentPart.content,
144
+ ...cacheControl ? { cache_control: cacheControl } : {}
145
+ };
146
+ else if (_isAnthropicSearchResultBlock(contentPart)) yield {
147
+ type: "search_result",
148
+ title: contentPart.title,
149
+ source: contentPart.source,
150
+ ..."cache_control" in contentPart && contentPart.cache_control ? { cache_control: contentPart.cache_control } : {},
151
+ ..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {},
152
+ content: contentPart.content
153
+ };
154
+ else if (textTypes.find((t) => t === contentPart.type) && "text" in contentPart) yield {
169
155
  type: "text",
170
156
  text: contentPart.text,
171
157
  ...cacheControl ? { cache_control: cacheControl } : {},
@@ -177,10 +163,7 @@ function* _formatContentBlocks(content, toolCalls) {
177
163
  if (contentPartCopy.type === "tool_use" && typeof contentPartCopy.input === "string") {
178
164
  const matchingToolCall = toolCalls?.find((tc) => tc.id === contentPartCopy.id);
179
165
  if (matchingToolCall) contentPartCopy.input = matchingToolCall.args;
180
- else {
181
- const inputDeltas = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string");
182
- contentPartCopy.input = inputDeltas.reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
183
- }
166
+ else contentPartCopy.input = content.filter((nestedContentPart) => nestedContentPart.index === contentPartCopy.index && nestedContentPart.type === "input_json_delta" && typeof nestedContentPart.input === "string").reduce((accumulator, nestedContentPart) => accumulator + nestedContentPart.input, contentPartCopy.input);
184
167
  }
185
168
  if ("index" in contentPartCopy) delete contentPartCopy.index;
186
169
  if ("input" in contentPartCopy) {
@@ -215,45 +198,42 @@ function _convertMessagesToAnthropicPayload(messages) {
215
198
  const mergedMessages = _ensureMessageContents(messages);
216
199
  let system;
217
200
  if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") system = messages[0].content;
218
- const conversationMessages = system !== void 0 ? mergedMessages.slice(1) : mergedMessages;
219
- const formattedMessages = conversationMessages.map((message) => {
220
- let role;
221
- if (message._getType() === "human") role = "user";
222
- else if (message._getType() === "ai") role = "assistant";
223
- else if (message._getType() === "tool") role = "user";
224
- else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
225
- else throw new Error(`Message type "${message.type}" is not supported.`);
226
- if (AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
227
- role,
228
- content: _formatStandardContent(message)
229
- };
230
- if (AIMessage.isInstance(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return {
231
- role,
232
- content: message.tool_calls.map(_convertLangChainToolCallToAnthropic)
233
- };
234
- else return {
235
- role,
236
- content: [{
237
- type: "text",
238
- text: message.content
239
- }, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)]
240
- };
241
- else {
242
- const { content } = message;
243
- const hasMismatchedToolCalls = !message.tool_calls.every((toolCall) => content.find((contentPart) => (contentPart.type === "tool_use" || contentPart.type === "input_json_delta" || contentPart.type === "server_tool_use") && contentPart.id === toolCall.id));
244
- if (hasMismatchedToolCalls) console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
245
- return {
201
+ return {
202
+ messages: mergeMessages((system !== void 0 ? mergedMessages.slice(1) : mergedMessages).map((message) => {
203
+ let role;
204
+ if (message._getType() === "human") role = "user";
205
+ else if (message._getType() === "ai") role = "assistant";
206
+ else if (message._getType() === "tool") role = "user";
207
+ else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
208
+ else throw new Error(`Message type "${message.type}" is not supported.`);
209
+ if (AIMessage.isInstance(message) && message.response_metadata?.output_version === "v1") return {
246
210
  role,
247
- content: _formatContent(message, message.tool_calls)
211
+ content: _formatStandardContent(message)
248
212
  };
249
- }
250
- else return {
251
- role,
252
- content: _formatContent(message, AIMessage.isInstance(message) ? message.tool_calls : void 0)
253
- };
254
- });
255
- return {
256
- messages: mergeMessages(formattedMessages),
213
+ if (AIMessage.isInstance(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return {
214
+ role,
215
+ content: message.tool_calls.map(_convertLangChainToolCallToAnthropic)
216
+ };
217
+ else return {
218
+ role,
219
+ content: [{
220
+ type: "text",
221
+ text: message.content
222
+ }, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)]
223
+ };
224
+ else {
225
+ const { content } = message;
226
+ if (!message.tool_calls.every((toolCall) => content.find((contentPart) => (contentPart.type === "tool_use" || contentPart.type === "input_json_delta" || contentPart.type === "server_tool_use") && contentPart.id === toolCall.id))) console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
227
+ return {
228
+ role,
229
+ content: _formatContent(message, message.tool_calls)
230
+ };
231
+ }
232
+ else return {
233
+ role,
234
+ content: _formatContent(message, AIMessage.isInstance(message) ? message.tool_calls : void 0)
235
+ };
236
+ })),
257
237
  system
258
238
  };
259
239
  }
@@ -292,9 +272,8 @@ function applyCacheControlToPayload(payload, cacheControl) {
292
272
  if (Array.isArray(lastMessage.content) && lastMessage.content.length > 0) {
293
273
  const content = [...lastMessage.content];
294
274
  const lastBlockIndex = content.length - 1;
295
- const lastBlock = content[lastBlockIndex];
296
275
  content[lastBlockIndex] = {
297
- ...lastBlock,
276
+ ...content[lastBlockIndex],
298
277
  cache_control: cacheControl
299
278
  };
300
279
  messages[lastMessageIndex] = {