@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.
- package/CHANGELOG.md +24 -0
- package/dist/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +11 -7
- package/dist/chat_models.cjs +56 -70
- package/dist/chat_models.cjs.map +1 -1
- package/dist/chat_models.d.cts +0 -1
- package/dist/chat_models.d.cts.map +1 -1
- package/dist/chat_models.d.ts +0 -1
- package/dist/chat_models.d.ts.map +1 -1
- package/dist/chat_models.js +28 -42
- package/dist/chat_models.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/output_parsers.cjs +9 -11
- package/dist/output_parsers.cjs.map +1 -1
- package/dist/output_parsers.js +2 -4
- package/dist/output_parsers.js.map +1 -1
- package/dist/profiles.cjs +96 -29
- package/dist/profiles.cjs.map +1 -1
- package/dist/profiles.js +96 -29
- package/dist/profiles.js.map +1 -1
- package/dist/tools/bash.cjs +3 -3
- package/dist/tools/bash.cjs.map +1 -1
- package/dist/tools/bash.d.cts +7 -7
- package/dist/tools/bash.d.cts.map +1 -1
- package/dist/tools/bash.d.ts +7 -7
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/codeExecution.cjs.map +1 -1
- package/dist/tools/codeExecution.d.cts +0 -1
- package/dist/tools/codeExecution.d.cts.map +1 -1
- package/dist/tools/codeExecution.d.ts +0 -1
- package/dist/tools/codeExecution.d.ts.map +1 -1
- package/dist/tools/codeExecution.js.map +1 -1
- package/dist/tools/computer.cjs +4 -4
- package/dist/tools/computer.cjs.map +1 -1
- package/dist/tools/computer.d.cts +101 -101
- package/dist/tools/computer.d.cts.map +1 -1
- package/dist/tools/computer.d.ts +101 -101
- package/dist/tools/computer.d.ts.map +1 -1
- package/dist/tools/computer.js.map +1 -1
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.cts.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcpToolset.cjs.map +1 -1
- package/dist/tools/mcpToolset.d.cts +0 -1
- package/dist/tools/mcpToolset.d.cts.map +1 -1
- package/dist/tools/mcpToolset.d.ts +0 -1
- package/dist/tools/mcpToolset.d.ts.map +1 -1
- package/dist/tools/mcpToolset.js.map +1 -1
- package/dist/tools/memory.cjs +3 -3
- package/dist/tools/memory.cjs.map +1 -1
- package/dist/tools/memory.d.cts +27 -28
- package/dist/tools/memory.d.cts.map +1 -1
- package/dist/tools/memory.d.ts +25 -26
- package/dist/tools/memory.d.ts.map +1 -1
- package/dist/tools/memory.js.map +1 -1
- package/dist/tools/textEditor.cjs +3 -3
- package/dist/tools/textEditor.cjs.map +1 -1
- package/dist/tools/textEditor.d.cts +19 -19
- package/dist/tools/textEditor.d.cts.map +1 -1
- package/dist/tools/textEditor.d.ts +21 -21
- package/dist/tools/textEditor.d.ts.map +1 -1
- package/dist/tools/textEditor.js.map +1 -1
- package/dist/tools/toolSearch.cjs.map +1 -1
- package/dist/tools/toolSearch.d.cts +0 -1
- package/dist/tools/toolSearch.d.cts.map +1 -1
- package/dist/tools/toolSearch.d.ts +0 -1
- package/dist/tools/toolSearch.d.ts.map +1 -1
- package/dist/tools/toolSearch.js.map +1 -1
- package/dist/tools/types.cjs +2 -2
- package/dist/tools/types.cjs.map +1 -1
- package/dist/tools/types.d.cts +0 -1
- package/dist/tools/types.d.cts.map +1 -1
- package/dist/tools/types.d.ts +0 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/webFetch.cjs.map +1 -1
- package/dist/tools/webFetch.d.cts +0 -1
- package/dist/tools/webFetch.d.cts.map +1 -1
- package/dist/tools/webFetch.d.ts +0 -1
- package/dist/tools/webFetch.d.ts.map +1 -1
- package/dist/tools/webFetch.js.map +1 -1
- package/dist/tools/webSearch.cjs.map +1 -1
- package/dist/tools/webSearch.d.cts +0 -1
- package/dist/tools/webSearch.d.cts.map +1 -1
- package/dist/tools/webSearch.d.ts +0 -1
- package/dist/tools/webSearch.d.ts.map +1 -1
- package/dist/tools/webSearch.js.map +1 -1
- package/dist/types.d.cts +0 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/content.cjs +3 -3
- package/dist/utils/content.cjs.map +1 -1
- package/dist/utils/content.js.map +1 -1
- package/dist/utils/errors.cjs +4 -1
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.js +4 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/message_inputs.cjs +79 -100
- package/dist/utils/message_inputs.cjs.map +1 -1
- package/dist/utils/message_inputs.js +73 -94
- package/dist/utils/message_inputs.js.map +1 -1
- package/dist/utils/message_outputs.cjs +28 -32
- package/dist/utils/message_outputs.cjs.map +1 -1
- package/dist/utils/message_outputs.js +13 -17
- package/dist/utils/message_outputs.js.map +1 -1
- package/dist/utils/prompts.cjs +1 -2
- package/dist/utils/prompts.cjs.map +1 -1
- package/dist/utils/prompts.d.cts +0 -1
- package/dist/utils/prompts.d.cts.map +1 -1
- package/dist/utils/prompts.d.ts +0 -1
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +1 -2
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/standard.cjs +2 -4
- package/dist/utils/standard.cjs.map +1 -1
- package/dist/utils/standard.js +2 -4
- package/dist/utils/standard.js.map +1 -1
- package/dist/utils/tools.cjs +4 -3
- package/dist/utils/tools.cjs.map +1 -1
- package/dist/utils/tools.js +1 -1
- package/dist/utils/tools.js.map +1 -1
- package/package.json +4 -4
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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:
|
|
212
|
+
content: require_standard._formatStandardContent(message)
|
|
249
213
|
};
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
...
|
|
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":";;;;;;AA0CA,SAAS,aAAaA,UAAkB;CACtC,MAAM,2DAA4B,EAAE,SAAS,SAAU,EAAC;AACxD,KAAI,OACF,QAAO;EACL,MAAM;EACN,YAAY,OAAO;EACnB,MAAM,OAAO;CACd;CAEH,IAAIC;AAEJ,KAAI;EACF,YAAY,IAAI,IAAI;CACrB,QAAO;AACN,QAAM,IAAI,MACR;GACE,CAAC,qBAAqB,EAAE,KAAK,UAC3B,SACD,CAAC,6FAA6F,CAAC;GAChG;GACA;EACD,EAAC,KAAK,OAAO;CAEjB;AAED,KAAI,UAAU,aAAa,WAAW,UAAU,aAAa,SAC3D,QAAO;EACL,MAAM;EACN,KAAK;CACN;AAGH,OAAM,IAAI,MACR;EACE,CAAC,4BAA4B,EAAE,KAAK,UAClC,UAAU,SACX,CAAC,2GAA2G,CAAC;EAC9G;EACA;CACD,EAAC,KAAK,OAAO;AAEjB;AAED,SAAS,uBAAuBC,UAAwC;CAEtE,MAAM,cAAc,CAAE;AACtB,MAAK,MAAM,WAAW,SACpB,KAAI,QAAQ,UAAU,KAAK,OACzB,KAAI,OAAO,QAAQ,YAAY,UAAU;EACvC,MAAM,kBAAkB,YAAY,YAAY,SAAS;AACzD,MACE,iBAAiB,UAAU,KAAK,WAChC,MAAM,QAAQ,gBAAgB,QAAQ,IACtC,UAAU,gBAAgB,QAAQ,MAClC,gBAAgB,QAAQ,GAAG,SAAS,eAGnC,gBAAgB,QAAoC,KAAK;GACxD,MAAM;GACN,SAAS,QAAQ;GACjB,aAAc,QAAwB;EACvC,EAAC;OAGF,YAAY,KACV,IAAIC,uCAAa,EACf,SAAS,CACP;GACE,MAAM;GACN,SAAS,QAAQ;GACjB,aAAc,QAAwB;EACvC,CACF,EACF,GACF;CAEJ,OACC,YAAY,KACV,IAAIA,uCAAa,EACf,SAAS,CACP;EACE,MAAM;EAEN,GAAI,QAAQ,WAAW,OACnB,EAAE,SAAS,eAAe,QAAQ,CAAE,IACpC,CAAE;EACN,aAAc,QAAwB;CACvC,CACF,EACF,GACF;MAGH,YAAY,KAAK,QAAQ;AAG7B,QAAO;AACR;AAED,SAAgB,qCACdC,UACuB;AACvB,KAAI,SAAS,OAAO,OAClB,OAAM,IAAI,MAAM,CAAC,kDAAkD,CAAC;AAEtE,QAAO;EACL,MAAM;EACN,IAAI,SAAS;EACb,MAAM,SAAS;EACf,OAAO,SAAS;CACjB;AACF;AAED,UAAU,qBACRC,SACAC,WACiD;CACjD,MAAM,YAAY;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD;CACD,MAAM,YAAY,CAAC,QAAQ,YAAa;AACxC,MAAK,MAAM,eAAe,SAAS;AACjC,wDAAuB,YAAY,EACjC,mEACE,aACAC,8CACD;EAGH,MAAM,eACJ,mBAAmB,cACd,YAAY,gBACb;AAEN,MAAI,YAAY,SAAS,aAAa;GACpC,IAAI;AACJ,OAAI,OAAO,YAAY,cAAc,UACnC,SAAS,aAAa,YAAY,UAAU;YAE5C,OAAO,YAAY,cAAc,YACjC,YAAY,cAAc,QAC1B,SAAS,YAAY,aACrB,OAAO,YAAY,UAAU,QAAQ,UAErC,SAAS,aAAa,YAAY,UAAU,IAAI;AAElD,OAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;EAEJ,WAAUC,4CAA4B,YAAY,EACjD,MAAM;WACG,YAAY,SAAS,SAAS;GAEvC,IAAI;AAEJ,OAAI,SAAS,eAAe,OAAO,YAAY,QAAQ,UAErD,SAAS,aAAa,YAAY,IAAI;YAEtC,UAAU,gBACT,OAAO,YAAY,SAAS,YAE3B,YAAY,gBAAgB,aAC9B;IAEA,MAAM,WACJ,cAAc,eAAe,OAAO,YAAY,aAAa,WACzD,YAAY,WACZ;IACN,MAAM,OACJ,OAAO,YAAY,SAAS,WACxB,YAAY,OACZ,OAAO,KAAK,YAAY,KAAK,CAAC,SAAS,SAAS;IACtD,SAAS;KACP,MAAM;KACN,YAAY;KAKZ;IACD;GACF,WACC,YAAY,eACZ,OAAO,YAAY,WAAW,UAK9B,SAAS;IACP,MAAM;IACN,SAAS,YAAY;GACtB;AAGH,OAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;EAEJ,WAAU,YAAY,SAAS,QAAQ;GAEtC,IAAIC;AAMJ,OAAI,SAAS,eAAe,OAAO,YAAY,QAAQ,UAErD,SAAS;IACP,MAAM;IACN,KAAK,YAAY;GAClB;YAED,UAAU,gBACT,OAAO,YAAY,SAAS,YAE3B,YAAY,gBAAgB,aAC9B;IAEA,MAAM,aACJ,cAAc,eAAe,OAAO,YAAY,aAAa,WACzD,YAAY,WACZ;IACN,MAAM,OACJ,OAAO,YAAY,SAAS,WACxB,YAAY,OACZ,OAAO,KAAK,YAAY,KAAK,CAAC,SAAS,SAAS;IAEtD,SAAS;KACP,MAAM;KACN;KACA;IACD;GACF,WACC,YAAY,eACZ,OAAO,YAAY,WAAW,UAI9B,SAAS;IACP,MAAM;IACN,SAAS,YAAY;GACtB;AAGH,OAAI,QACF,MAAM;IACJ,MAAM;IACN;IACA,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;EAEJ,WAAU,YAAY,SAAS,YAE9B,MAAM;GACJ,GAAG;GACH,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;EACxD;WACQC,0CAA0B,YAAY,EAAE;GACjD,MAAMC,QAAqC;IACzC,MAAM;IACN,UAAU,YAAY;IACtB,WAAW,YAAY;IACvB,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;GACD,MAAM;EACP,WAAUC,kDAAkC,YAAY,EAAE;GACzD,MAAMC,QAA6C;IACjD,MAAM;IACN,MAAM,YAAY;IAClB,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;GACD,MAAM;EACP,WAAUC,4CAA4B,YAAY,EAAE;GACnD,MAAMC,QAAuC;IAC3C,MAAM;IACN,SAAS,YAAY;IACrB,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACxD;GACD,MAAM;EACP,WAAUC,8CAA8B,YAAY,EAAE;GACrD,MAAMC,QAAyC;IAC7C,MAAM;IACN,OAAO,YAAY;IACnB,QAAQ,YAAY;IACpB,GAAI,mBAAmB,eAAe,YAAY,gBAC9C,EAAE,eAAe,YAAY,cAAe,IAC5C,CAAE;IACN,GAAI,eAAe,eAAe,YAAY,YAC1C,EAAE,WAAW,YAAY,UAAW,IACpC,CAAE;IACN,SAAS,YAAY;GACtB;GACD,MAAM;EACP,WACC,UAAU,KAAK,CAAC,MAAM,MAAM,YAAY,KAAK,IAC7C,UAAU,aAGV,MAAM;GACJ,MAAM;GACN,MAAM,YAAY;GAClB,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GACvD,GAAI,eAAe,eAAe,YAAY,YAC1C,EAAE,WAAW,YAAY,UAAW,IACpC,CAAE;EACP;WACQ,UAAU,KAAK,CAAC,MAAM,MAAM,YAAY,KAAK,EAAE;GACxD,MAAM,kBAAkB,EAAE,GAAG,YAAa;AAE1C,OAAI,gBAAgB,SAAS,mBAK3B;AAGF,OACE,gBAAgB,SAAS,cACzB,OAAO,gBAAgB,UAAU,UACjC;IAIA,MAAM,mBAAmB,WAAW,KAClC,CAAC,OAAO,GAAG,OAAO,gBAAgB,GACnC;AACD,QAAI,kBACF,gBAAgB,QAAQ,iBAAiB;SACpC;KAIL,MAAM,cAAc,QAAQ,OAC1B,CAAC,sBACC,kBAAkB,UAAU,gBAAgB,SAC5C,kBAAkB,SAAS,sBAC3B,OAAO,kBAAkB,UAAU,SACtC;KAGD,gBAAgB,QAAQ,YAAY,OAClC,CAAC,aAAa,sBACZ,cAAc,kBAAkB,OAClC,gBAAgB,MACjB;IACF;GACF;AAED,OAAI,WAAW,iBAEb,OAAO,gBAAgB;AAGzB,OAAI,WAAW,iBAEb;QAAI,OAAO,gBAAgB,UAAU,SACnC,KAAI;KACF,gBAAgB,QAAQ,KAAK,MAAM,gBAAgB,MAAM;IAC1D,QAAO;KACN,gBAAgB,QAAQ,CAAE;IAC3B;GACF;GAGH,MAAM;IACJ,GAAG;IACH,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;GAExD;EACF,WAAU,YAAY,SAAS,oBAC9B,MAAM;GACJ,GAAG;GACH,GAAI,eAAe,EAAE,eAAe,aAAc,IAAG,CAAE;EACxD;CAQJ;AACF;AAED,SAAS,eAAeC,SAAsBZ,WAAwB;CACpE,MAAM,EAAE,SAAS,GAAG;AAEpB,KAAI,OAAO,YAAY,SACrB,QAAO;KAEP,QAAO,MAAM,KAAK,qBAAqB,SAAS,UAAU,CAAC;AAE9D;;;;;;;AAQD,SAAgB,mCACdJ,UAC8B;CAC9B,MAAM,iBAAiB,uBAAuB,SAAS;CACvD,IAAI;AACJ,KAAI,eAAe,SAAS,KAAK,eAAe,GAAG,UAAU,KAAK,UAChE,SAAS,SAAS,GAAG;CAEvB,MAAM,uBACJ,WAAW,SAAY,eAAe,MAAM,EAAE,GAAG;CACnD,MAAM,oBAAoB,qBAAqB,IAAI,CAAC,YAAY;EAC9D,IAAI;AACJ,MAAI,QAAQ,UAAU,KAAK,SACzB,OAAO;WACE,QAAQ,UAAU,KAAK,MAChC,OAAO;WACE,QAAQ,UAAU,KAAK,QAChC,OAAO;WACE,QAAQ,UAAU,KAAK,SAChC,OAAM,IAAI,MACR;MAGF,OAAM,IAAI,MAAM,CAAC,cAAc,EAAE,QAAQ,KAAK,mBAAmB,CAAC;AAEpE,MACEiB,oCAAU,WAAW,QAAQ,IAC7B,QAAQ,mBAAmB,mBAAmB,KAE9C,QAAO;GACL;GACA,SAASC,wCAAuB,QAAQ;EACzC;AAEH,MAAID,oCAAU,WAAW,QAAQ,IAAI,CAAC,CAAC,QAAQ,YAAY,OACzD,KAAI,OAAO,QAAQ,YAAY,SAC7B,KAAI,QAAQ,YAAY,GACtB,QAAO;GACL;GACA,SAAS,QAAQ,WAAW,IAC1B,qCACD;EACF;MAED,QAAO;GACL;GACA,SAAS,CACP;IAAE,MAAM;IAAQ,MAAM,QAAQ;GAAS,GACvC,GAAG,QAAQ,WAAW,IAAI,qCAAqC,AAChE;EACF;OAEE;GACL,MAAM,EAAE,SAAS,GAAG;GACpB,MAAM,yBAAyB,CAAC,QAAQ,WAAW,MAAM,CAAC,aACxD,QAAQ,KACN,CAAC,iBACE,YAAY,SAAS,cACpB,YAAY,SAAS,sBACrB,YAAY,SAAS,sBACvB,YAAY,OAAO,SAAS,GAC/B,CACF;AACD,OAAI,wBACF,QAAQ,KACN,CAAC,6EAA6E,CAAC,CAChF;AAEH,UAAO;IACL;IACA,SAAS,eAAe,SAAS,QAAQ,WAAW;GACrD;EACF;MAED,QAAO;GACL;GACA,SAAS,eACP,SACAA,oCAAU,WAAW,QAAQ,GAAG,QAAQ,aAAa,OACtD;EACF;CAEJ,EAAC;AACF,QAAO;EACL,UAAU,cACR,kBACD;EACD;CACD;AACF;;;;;;;;;;;;;AAsBD,SAAgB,2BACdE,SACAC,cAC8B;AAC9B,KAAI,CAAC,QAAQ,YAAY,QAAQ,SAAS,WAAW,EACnD,QAAO;CAGT,MAAM,WAAW,CAAC,GAAG,QAAQ,QAAS;CACtC,MAAM,mBAAmB,SAAS,SAAS;CAC3C,MAAM,cAAc,SAAS;AAE7B,KAAI,CAAC,YACH,QAAO;AAIT,KAAI,OAAO,YAAY,YAAY,UAAU;EAC3C,SAAS,oBAAoB;GAC3B,GAAG;GACH,SAAS,CACP;IACE,MAAM;IACN,MAAM,YAAY;IAClB,eAAe;GAChB,CACF;EACF;AACD,SAAO;GAAE,GAAG;GAAS;EAAU;CAChC;AAGD,KAAI,MAAM,QAAQ,YAAY,QAAQ,IAAI,YAAY,QAAQ,SAAS,GAAG;EACxE,MAAM,UAAU,CAAC,GAAG,YAAY,OAAQ;EACxC,MAAM,iBAAiB,QAAQ,SAAS;EACxC,MAAM,YAAY,QAAQ;EAG1B,QAAQ,kBAAkB;GACxB,GAAG;GACH,eAAe;EAEhB;EAED,SAAS,oBAAoB;GAC3B,GAAG;GACH;EACD;AACD,SAAO;GAAE,GAAG;GAAS;EAAU;CAChC;AAED,QAAO;AACR;AAED,SAAS,cAAcC,UAAoD;AACzE,KAAI,CAAC,YAAY,SAAS,UAAU,EAClC,QAAO;CAGT,MAAMC,SAAmD,CAAE;CAC3D,IAAI,iBAAiB,SAAS;CAE9B,MAAM,mBAAmB,CACvBC,YAyBG;AACH,MAAI,OAAO,YAAY,SACrB,QAAO,CACL;GACE,MAAM;GACN,MAAM;EACP,CACF;AAEH,SAAO;CACR;CAED,MAAM,sBAAsB,CAACC,QAA8B;AACzD,MAAI,IAAI,SAAS,OAAQ,QAAO;AAEhC,MAAI,OAAO,IAAI,YAAY,SACzB,QAAO;AAGT,SACE,MAAM,QAAQ,IAAI,QAAQ,IAC1B,IAAI,QAAQ,MAAM,CAAC,SAAS,KAAK,SAAS,cAAc;CAE3D;AAED,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG;EAC3C,MAAM,cAAc,SAAS;AAE7B,MACE,oBAAoB,eAAe,IACnC,oBAAoB,YAAY,EAGhC,iBAAiB;GACf,GAAG;GACH,SAAS,CACP,GAAG,iBAAiB,eAAe,QAAQ,EAC3C,GAAG,iBAAiB,YAAY,QAAQ,AACzC;EACF;OACI;GACL,OAAO,KAAK,eAAe;GAC3B,iBAAiB;EAClB;CACF;CAED,OAAO,KAAK,eAAe;AAC3B,QAAO;AACR"}
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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:
|
|
211
|
+
content: _formatStandardContent(message)
|
|
248
212
|
};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
...
|
|
276
|
+
...content[lastBlockIndex],
|
|
298
277
|
cache_control: cacheControl
|
|
299
278
|
};
|
|
300
279
|
messages[lastMessageIndex] = {
|