@langchain/anthropic 0.3.26 → 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/_virtual/rolldown_runtime.cjs +25 -0
- package/dist/chat_models.cjs +772 -1000
- package/dist/chat_models.cjs.map +1 -0
- package/dist/chat_models.d.cts +615 -0
- package/dist/chat_models.d.cts.map +1 -0
- package/dist/chat_models.d.ts +222 -206
- package/dist/chat_models.d.ts.map +1 -0
- package/dist/chat_models.js +766 -991
- package/dist/chat_models.js.map +1 -0
- package/dist/index.cjs +6 -20
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -2
- package/dist/output_parsers.cjs +65 -104
- package/dist/output_parsers.cjs.map +1 -0
- package/dist/output_parsers.js +64 -100
- package/dist/output_parsers.js.map +1 -0
- package/dist/types.d.cts +32 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.ts +29 -31
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/content.cjs +153 -0
- package/dist/utils/content.cjs.map +1 -0
- package/dist/utils/content.js +148 -0
- package/dist/utils/content.js.map +1 -0
- package/dist/utils/errors.cjs +16 -27
- package/dist/utils/errors.cjs.map +1 -0
- package/dist/utils/errors.js +17 -25
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.cjs +7 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/message_inputs.cjs +218 -535
- package/dist/utils/message_inputs.cjs.map +1 -0
- package/dist/utils/message_inputs.js +219 -533
- package/dist/utils/message_inputs.js.map +1 -0
- package/dist/utils/message_outputs.cjs +185 -246
- package/dist/utils/message_outputs.cjs.map +1 -0
- package/dist/utils/message_outputs.js +184 -243
- package/dist/utils/message_outputs.js.map +1 -0
- package/dist/utils/prompts.cjs +46 -45
- package/dist/utils/prompts.cjs.map +1 -0
- package/dist/utils/prompts.d.cts +45 -0
- package/dist/utils/prompts.d.cts.map +1 -0
- package/dist/utils/prompts.d.ts +8 -2
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +46 -42
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/standard.cjs +127 -0
- package/dist/utils/standard.cjs.map +1 -0
- package/dist/utils/standard.js +127 -0
- package/dist/utils/standard.js.map +1 -0
- package/dist/utils/tools.cjs +14 -25
- package/dist/utils/tools.cjs.map +1 -0
- package/dist/utils/tools.js +14 -23
- package/dist/utils/tools.js.map +1 -0
- package/package.json +30 -53
- package/dist/experimental/index.cjs +0 -17
- package/dist/experimental/index.d.ts +0 -1
- package/dist/experimental/index.js +0 -1
- package/dist/experimental/tool_calling.cjs +0 -318
- package/dist/experimental/tool_calling.d.ts +0 -57
- package/dist/experimental/tool_calling.js +0 -314
- package/dist/experimental/utils/tool_calling.cjs +0 -106
- package/dist/experimental/utils/tool_calling.d.ts +0 -10
- package/dist/experimental/utils/tool_calling.js +0 -101
- package/dist/load/import_constants.cjs +0 -5
- package/dist/load/import_constants.d.ts +0 -1
- package/dist/load/import_constants.js +0 -2
- package/dist/load/import_map.cjs +0 -39
- package/dist/load/import_map.d.ts +0 -2
- package/dist/load/import_map.js +0 -3
- package/dist/load/import_type.cjs +0 -3
- package/dist/load/import_type.d.ts +0 -5
- package/dist/load/import_type.js +0 -2
- package/dist/load/index.cjs +0 -63
- package/dist/load/index.d.ts +0 -14
- package/dist/load/index.js +0 -25
- package/dist/load/map_keys.cjs +0 -2
- package/dist/load/map_keys.d.ts +0 -3
- package/dist/load/map_keys.js +0 -1
- package/dist/load/serializable.cjs +0 -17
- package/dist/load/serializable.d.ts +0 -1
- package/dist/load/serializable.js +0 -1
- package/dist/output_parsers.d.ts +0 -22
- package/dist/types.cjs +0 -48
- package/dist/types.js +0 -45
- package/dist/utils/errors.d.ts +0 -3
- package/dist/utils/message_inputs.d.ts +0 -14
- package/dist/utils/message_outputs.d.ts +0 -14
- package/dist/utils/tools.d.ts +0 -3
- package/experimental.cjs +0 -1
- package/experimental.d.cts +0 -1
- package/experimental.d.ts +0 -1
- package/experimental.js +0 -1
- package/index.cjs +0 -1
- package/index.d.cts +0 -1
- package/index.d.ts +0 -1
- package/index.js +0 -1
|
@@ -1,544 +1,230 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { _isAnthropicImageBlockParam, _isAnthropicRedactedThinkingBlock, _isAnthropicSearchResultBlock, _isAnthropicThinkingBlock, standardContentBlockConverter } from "./content.js";
|
|
2
|
+
import { _formatStandardContent } from "./standard.js";
|
|
3
|
+
import { HumanMessage, convertToProviderContentBlock, isAIMessage, isDataContentBlock, parseBase64DataUrl } from "@langchain/core/messages";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/message_inputs.ts
|
|
6
6
|
function _formatImage(imageUrl) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new Error([
|
|
33
|
-
`Invalid image URL protocol: ${JSON.stringify(parsedUrl.protocol)}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,
|
|
34
|
-
"Example: data:image/png;base64,/9j/4AAQSk...",
|
|
35
|
-
"Example: https://example.com/image.jpg",
|
|
36
|
-
].join("\n\n"));
|
|
7
|
+
const parsed = parseBase64DataUrl({ dataUrl: imageUrl });
|
|
8
|
+
if (parsed) return {
|
|
9
|
+
type: "base64",
|
|
10
|
+
media_type: parsed.mime_type,
|
|
11
|
+
data: parsed.data
|
|
12
|
+
};
|
|
13
|
+
let parsedUrl;
|
|
14
|
+
try {
|
|
15
|
+
parsedUrl = new URL(imageUrl);
|
|
16
|
+
} catch {
|
|
17
|
+
throw new Error([
|
|
18
|
+
`Malformed image URL: ${JSON.stringify(imageUrl)}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,
|
|
19
|
+
"Example: data:image/png;base64,/9j/4AAQSk...",
|
|
20
|
+
"Example: https://example.com/image.jpg"
|
|
21
|
+
].join("\n\n"));
|
|
22
|
+
}
|
|
23
|
+
if (parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:") return {
|
|
24
|
+
type: "url",
|
|
25
|
+
url: imageUrl
|
|
26
|
+
};
|
|
27
|
+
throw new Error([
|
|
28
|
+
`Invalid image URL protocol: ${JSON.stringify(parsedUrl.protocol)}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,
|
|
29
|
+
"Example: data:image/png;base64,/9j/4AAQSk...",
|
|
30
|
+
"Example: https://example.com/image.jpg"
|
|
31
|
+
].join("\n\n"));
|
|
37
32
|
}
|
|
38
33
|
function _ensureMessageContents(messages) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
updatedMsgs.push(new HumanMessage({
|
|
71
|
-
content: [
|
|
72
|
-
{
|
|
73
|
-
type: "tool_result",
|
|
74
|
-
// rare case: message.content could be undefined
|
|
75
|
-
...(message.content != null
|
|
76
|
-
? { content: _formatContent(message) }
|
|
77
|
-
: {}),
|
|
78
|
-
tool_use_id: message.tool_call_id,
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
updatedMsgs.push(message);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return updatedMsgs;
|
|
34
|
+
const updatedMsgs = [];
|
|
35
|
+
for (const message of messages) if (message._getType() === "tool") if (typeof message.content === "string") {
|
|
36
|
+
const previousMessage = updatedMsgs[updatedMsgs.length - 1];
|
|
37
|
+
if (previousMessage?._getType() === "human" && Array.isArray(previousMessage.content) && "type" in previousMessage.content[0] && previousMessage.content[0].type === "tool_result") previousMessage.content.push({
|
|
38
|
+
type: "tool_result",
|
|
39
|
+
content: message.content,
|
|
40
|
+
tool_use_id: message.tool_call_id
|
|
41
|
+
});
|
|
42
|
+
else updatedMsgs.push(new HumanMessage({ content: [{
|
|
43
|
+
type: "tool_result",
|
|
44
|
+
content: message.content,
|
|
45
|
+
tool_use_id: message.tool_call_id
|
|
46
|
+
}] }));
|
|
47
|
+
} else updatedMsgs.push(new HumanMessage({ content: [{
|
|
48
|
+
type: "tool_result",
|
|
49
|
+
...message.content != null ? { content: _formatContent(message) } : {},
|
|
50
|
+
tool_use_id: message.tool_call_id
|
|
51
|
+
}] }));
|
|
52
|
+
else updatedMsgs.push(message);
|
|
53
|
+
return updatedMsgs;
|
|
54
|
+
}
|
|
55
|
+
function _convertLangChainToolCallToAnthropic(toolCall) {
|
|
56
|
+
if (toolCall.id === void 0) throw new Error(`Anthropic requires all tool calls to have an "id".`);
|
|
57
|
+
return {
|
|
58
|
+
type: "tool_use",
|
|
59
|
+
id: toolCall.id,
|
|
60
|
+
name: toolCall.name,
|
|
61
|
+
input: toolCall.args
|
|
62
|
+
};
|
|
89
63
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
64
|
+
function* _formatContentBlocks(content) {
|
|
65
|
+
const toolTypes = [
|
|
66
|
+
"tool_use",
|
|
67
|
+
"tool_result",
|
|
68
|
+
"input_json_delta",
|
|
69
|
+
"server_tool_use",
|
|
70
|
+
"web_search_tool_result",
|
|
71
|
+
"web_search_result"
|
|
72
|
+
];
|
|
73
|
+
const textTypes = ["text", "text_delta"];
|
|
74
|
+
for (const contentPart of content) {
|
|
75
|
+
if (isDataContentBlock(contentPart)) yield convertToProviderContentBlock(contentPart, standardContentBlockConverter);
|
|
76
|
+
const cacheControl = "cache_control" in contentPart ? contentPart.cache_control : void 0;
|
|
77
|
+
if (contentPart.type === "image_url") {
|
|
78
|
+
let source;
|
|
79
|
+
if (typeof contentPart.image_url === "string") source = _formatImage(contentPart.image_url);
|
|
80
|
+
else if (typeof contentPart.image_url === "object" && contentPart.image_url !== null && "url" in contentPart.image_url && typeof contentPart.image_url.url === "string") source = _formatImage(contentPart.image_url.url);
|
|
81
|
+
if (source) yield {
|
|
82
|
+
type: "image",
|
|
83
|
+
source,
|
|
84
|
+
...cacheControl ? { cache_control: cacheControl } : {}
|
|
85
|
+
};
|
|
86
|
+
} else if (_isAnthropicImageBlockParam(contentPart)) return contentPart;
|
|
87
|
+
else if (contentPart.type === "document") yield {
|
|
88
|
+
...contentPart,
|
|
89
|
+
...cacheControl ? { cache_control: cacheControl } : {}
|
|
90
|
+
};
|
|
91
|
+
else if (_isAnthropicThinkingBlock(contentPart)) {
|
|
92
|
+
const block = {
|
|
93
|
+
type: "thinking",
|
|
94
|
+
thinking: contentPart.thinking,
|
|
95
|
+
signature: contentPart.signature,
|
|
96
|
+
...cacheControl ? { cache_control: cacheControl } : {}
|
|
97
|
+
};
|
|
98
|
+
yield block;
|
|
99
|
+
} else if (_isAnthropicRedactedThinkingBlock(contentPart)) {
|
|
100
|
+
const block = {
|
|
101
|
+
type: "redacted_thinking",
|
|
102
|
+
data: contentPart.data,
|
|
103
|
+
...cacheControl ? { cache_control: cacheControl } : {}
|
|
104
|
+
};
|
|
105
|
+
yield block;
|
|
106
|
+
} else if (_isAnthropicSearchResultBlock(contentPart)) {
|
|
107
|
+
const block = {
|
|
108
|
+
type: "search_result",
|
|
109
|
+
title: contentPart.title,
|
|
110
|
+
source: contentPart.source,
|
|
111
|
+
..."cache_control" in contentPart && contentPart.cache_control ? { cache_control: contentPart.cache_control } : {},
|
|
112
|
+
..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {},
|
|
113
|
+
content: contentPart.content
|
|
114
|
+
};
|
|
115
|
+
yield block;
|
|
116
|
+
} else if (textTypes.find((t) => t === contentPart.type) && "text" in contentPart) yield {
|
|
117
|
+
type: "text",
|
|
118
|
+
text: contentPart.text,
|
|
119
|
+
...cacheControl ? { cache_control: cacheControl } : {},
|
|
120
|
+
..."citations" in contentPart && contentPart.citations ? { citations: contentPart.citations } : {}
|
|
121
|
+
};
|
|
122
|
+
else if (toolTypes.find((t) => t === contentPart.type)) {
|
|
123
|
+
const contentPartCopy = { ...contentPart };
|
|
124
|
+
if ("index" in contentPartCopy) delete contentPartCopy.index;
|
|
125
|
+
if (contentPartCopy.type === "input_json_delta") contentPartCopy.type = "tool_use";
|
|
126
|
+
if ("input" in contentPartCopy) {
|
|
127
|
+
if (typeof contentPartCopy.input === "string") try {
|
|
128
|
+
contentPartCopy.input = JSON.parse(contentPartCopy.input);
|
|
129
|
+
} catch {
|
|
130
|
+
contentPartCopy.input = {};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
yield {
|
|
134
|
+
...contentPartCopy,
|
|
135
|
+
...cacheControl ? { cache_control: cacheControl } : {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
100
139
|
}
|
|
101
|
-
const standardContentBlockConverter = {
|
|
102
|
-
providerName: "anthropic",
|
|
103
|
-
fromStandardTextBlock(block) {
|
|
104
|
-
return {
|
|
105
|
-
type: "text",
|
|
106
|
-
text: block.text,
|
|
107
|
-
...("citations" in (block.metadata ?? {})
|
|
108
|
-
? { citations: block.metadata.citations }
|
|
109
|
-
: {}),
|
|
110
|
-
...("cache_control" in (block.metadata ?? {})
|
|
111
|
-
? { cache_control: block.metadata.cache_control }
|
|
112
|
-
: {}),
|
|
113
|
-
};
|
|
114
|
-
},
|
|
115
|
-
fromStandardImageBlock(block) {
|
|
116
|
-
if (block.source_type === "url") {
|
|
117
|
-
const data = parseBase64DataUrl({
|
|
118
|
-
dataUrl: block.url,
|
|
119
|
-
asTypedArray: false,
|
|
120
|
-
});
|
|
121
|
-
if (data) {
|
|
122
|
-
return {
|
|
123
|
-
type: "image",
|
|
124
|
-
source: {
|
|
125
|
-
type: "base64",
|
|
126
|
-
data: data.data,
|
|
127
|
-
media_type: data.mime_type,
|
|
128
|
-
},
|
|
129
|
-
...("cache_control" in (block.metadata ?? {})
|
|
130
|
-
? { cache_control: block.metadata.cache_control }
|
|
131
|
-
: {}),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
return {
|
|
136
|
-
type: "image",
|
|
137
|
-
source: {
|
|
138
|
-
type: "url",
|
|
139
|
-
url: block.url,
|
|
140
|
-
media_type: block.mime_type ?? "",
|
|
141
|
-
},
|
|
142
|
-
...("cache_control" in (block.metadata ?? {})
|
|
143
|
-
? { cache_control: block.metadata.cache_control }
|
|
144
|
-
: {}),
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
if (block.source_type === "base64") {
|
|
150
|
-
return {
|
|
151
|
-
type: "image",
|
|
152
|
-
source: {
|
|
153
|
-
type: "base64",
|
|
154
|
-
data: block.data,
|
|
155
|
-
media_type: block.mime_type ?? "",
|
|
156
|
-
},
|
|
157
|
-
...("cache_control" in (block.metadata ?? {})
|
|
158
|
-
? { cache_control: block.metadata.cache_control }
|
|
159
|
-
: {}),
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
throw new Error(`Unsupported image source type: ${block.source_type}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
fromStandardFileBlock(block) {
|
|
168
|
-
const mime_type = (block.mime_type ?? "").split(";")[0];
|
|
169
|
-
if (block.source_type === "url") {
|
|
170
|
-
if (mime_type === "application/pdf" || mime_type === "") {
|
|
171
|
-
return {
|
|
172
|
-
type: "document",
|
|
173
|
-
source: {
|
|
174
|
-
type: "url",
|
|
175
|
-
url: block.url,
|
|
176
|
-
media_type: block.mime_type ?? "",
|
|
177
|
-
},
|
|
178
|
-
...("cache_control" in (block.metadata ?? {})
|
|
179
|
-
? { cache_control: block.metadata.cache_control }
|
|
180
|
-
: {}),
|
|
181
|
-
...("citations" in (block.metadata ?? {})
|
|
182
|
-
? { citations: block.metadata.citations }
|
|
183
|
-
: {}),
|
|
184
|
-
...("context" in (block.metadata ?? {})
|
|
185
|
-
? { context: block.metadata.context }
|
|
186
|
-
: {}),
|
|
187
|
-
...("title" in (block.metadata ?? {})
|
|
188
|
-
? { title: block.metadata.title }
|
|
189
|
-
: {}),
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
throw new Error(`Unsupported file mime type for file url source: ${block.mime_type}`);
|
|
193
|
-
}
|
|
194
|
-
else if (block.source_type === "text") {
|
|
195
|
-
if (mime_type === "text/plain" || mime_type === "") {
|
|
196
|
-
return {
|
|
197
|
-
type: "document",
|
|
198
|
-
source: {
|
|
199
|
-
type: "text",
|
|
200
|
-
data: block.text,
|
|
201
|
-
media_type: block.mime_type ?? "",
|
|
202
|
-
},
|
|
203
|
-
...("cache_control" in (block.metadata ?? {})
|
|
204
|
-
? { cache_control: block.metadata.cache_control }
|
|
205
|
-
: {}),
|
|
206
|
-
...("citations" in (block.metadata ?? {})
|
|
207
|
-
? { citations: block.metadata.citations }
|
|
208
|
-
: {}),
|
|
209
|
-
...("context" in (block.metadata ?? {})
|
|
210
|
-
? { context: block.metadata.context }
|
|
211
|
-
: {}),
|
|
212
|
-
...("title" in (block.metadata ?? {})
|
|
213
|
-
? { title: block.metadata.title }
|
|
214
|
-
: {}),
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
throw new Error(`Unsupported file mime type for file text source: ${block.mime_type}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else if (block.source_type === "base64") {
|
|
222
|
-
if (mime_type === "application/pdf" || mime_type === "") {
|
|
223
|
-
return {
|
|
224
|
-
type: "document",
|
|
225
|
-
source: {
|
|
226
|
-
type: "base64",
|
|
227
|
-
data: block.data,
|
|
228
|
-
media_type: "application/pdf",
|
|
229
|
-
},
|
|
230
|
-
...("cache_control" in (block.metadata ?? {})
|
|
231
|
-
? { cache_control: block.metadata.cache_control }
|
|
232
|
-
: {}),
|
|
233
|
-
...("citations" in (block.metadata ?? {})
|
|
234
|
-
? { citations: block.metadata.citations }
|
|
235
|
-
: {}),
|
|
236
|
-
...("context" in (block.metadata ?? {})
|
|
237
|
-
? { context: block.metadata.context }
|
|
238
|
-
: {}),
|
|
239
|
-
...("title" in (block.metadata ?? {})
|
|
240
|
-
? { title: block.metadata.title }
|
|
241
|
-
: {}),
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
else if (["image/jpeg", "image/png", "image/gif", "image/webp"].includes(mime_type)) {
|
|
245
|
-
return {
|
|
246
|
-
type: "document",
|
|
247
|
-
source: {
|
|
248
|
-
type: "content",
|
|
249
|
-
content: [
|
|
250
|
-
{
|
|
251
|
-
type: "image",
|
|
252
|
-
source: {
|
|
253
|
-
type: "base64",
|
|
254
|
-
data: block.data,
|
|
255
|
-
media_type: mime_type,
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
],
|
|
259
|
-
},
|
|
260
|
-
...("cache_control" in (block.metadata ?? {})
|
|
261
|
-
? { cache_control: block.metadata.cache_control }
|
|
262
|
-
: {}),
|
|
263
|
-
...("citations" in (block.metadata ?? {})
|
|
264
|
-
? { citations: block.metadata.citations }
|
|
265
|
-
: {}),
|
|
266
|
-
...("context" in (block.metadata ?? {})
|
|
267
|
-
? { context: block.metadata.context }
|
|
268
|
-
: {}),
|
|
269
|
-
...("title" in (block.metadata ?? {})
|
|
270
|
-
? { title: block.metadata.title }
|
|
271
|
-
: {}),
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
throw new Error(`Unsupported file mime type for file base64 source: ${block.mime_type}`);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
throw new Error(`Unsupported file source type: ${block.source_type}`);
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
};
|
|
283
140
|
function _formatContent(message) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
"input_json_delta",
|
|
288
|
-
"server_tool_use",
|
|
289
|
-
"web_search_tool_result",
|
|
290
|
-
"web_search_result",
|
|
291
|
-
];
|
|
292
|
-
const textTypes = ["text", "text_delta"];
|
|
293
|
-
const { content } = message;
|
|
294
|
-
if (typeof content === "string") {
|
|
295
|
-
return content;
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
const contentBlocks = content.map((contentPart) => {
|
|
299
|
-
if (isDataContentBlock(contentPart)) {
|
|
300
|
-
return convertToProviderContentBlock(contentPart, standardContentBlockConverter);
|
|
301
|
-
}
|
|
302
|
-
const cacheControl = "cache_control" in contentPart ? contentPart.cache_control : undefined;
|
|
303
|
-
if (contentPart.type === "image_url") {
|
|
304
|
-
let source;
|
|
305
|
-
if (typeof contentPart.image_url === "string") {
|
|
306
|
-
source = _formatImage(contentPart.image_url);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
source = _formatImage(contentPart.image_url.url);
|
|
310
|
-
}
|
|
311
|
-
return {
|
|
312
|
-
type: "image", // Explicitly setting the type as "image"
|
|
313
|
-
source,
|
|
314
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
else if (isAnthropicImageBlockParam(contentPart)) {
|
|
318
|
-
return contentPart;
|
|
319
|
-
}
|
|
320
|
-
else if (contentPart.type === "document") {
|
|
321
|
-
// PDF
|
|
322
|
-
return {
|
|
323
|
-
...contentPart,
|
|
324
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
else if (contentPart.type === "thinking") {
|
|
328
|
-
const block = {
|
|
329
|
-
type: "thinking", // Explicitly setting the type as "thinking"
|
|
330
|
-
thinking: contentPart.thinking,
|
|
331
|
-
signature: contentPart.signature,
|
|
332
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
333
|
-
};
|
|
334
|
-
return block;
|
|
335
|
-
}
|
|
336
|
-
else if (contentPart.type === "redacted_thinking") {
|
|
337
|
-
const block = {
|
|
338
|
-
type: "redacted_thinking", // Explicitly setting the type as "redacted_thinking"
|
|
339
|
-
data: contentPart.data,
|
|
340
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
341
|
-
};
|
|
342
|
-
return block;
|
|
343
|
-
}
|
|
344
|
-
else if (contentPart.type === "search_result") {
|
|
345
|
-
const block = {
|
|
346
|
-
type: "search_result", // Explicitly setting the type as "search_result"
|
|
347
|
-
title: contentPart.title,
|
|
348
|
-
source: contentPart.source,
|
|
349
|
-
...("cache_control" in contentPart && contentPart.cache_control
|
|
350
|
-
? { cache_control: contentPart.cache_control }
|
|
351
|
-
: {}),
|
|
352
|
-
...("citations" in contentPart && contentPart.citations
|
|
353
|
-
? { citations: contentPart.citations }
|
|
354
|
-
: {}),
|
|
355
|
-
content: contentPart.content,
|
|
356
|
-
};
|
|
357
|
-
return block;
|
|
358
|
-
}
|
|
359
|
-
else if (textTypes.find((t) => t === contentPart.type) &&
|
|
360
|
-
"text" in contentPart) {
|
|
361
|
-
// Assuming contentPart is of type MessageContentText here
|
|
362
|
-
return {
|
|
363
|
-
type: "text", // Explicitly setting the type as "text"
|
|
364
|
-
text: contentPart.text,
|
|
365
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
366
|
-
...("citations" in contentPart && contentPart.citations
|
|
367
|
-
? { citations: contentPart.citations }
|
|
368
|
-
: {}),
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
else if (toolTypes.find((t) => t === contentPart.type)) {
|
|
372
|
-
const contentPartCopy = { ...contentPart };
|
|
373
|
-
if ("index" in contentPartCopy) {
|
|
374
|
-
// Anthropic does not support passing the index field here, so we remove it.
|
|
375
|
-
delete contentPartCopy.index;
|
|
376
|
-
}
|
|
377
|
-
if (contentPartCopy.type === "input_json_delta") {
|
|
378
|
-
// `input_json_delta` type only represents yielding partial tool inputs
|
|
379
|
-
// and is not a valid type for Anthropic messages.
|
|
380
|
-
contentPartCopy.type = "tool_use";
|
|
381
|
-
}
|
|
382
|
-
if ("input" in contentPartCopy) {
|
|
383
|
-
// Anthropic tool use inputs should be valid objects, when applicable.
|
|
384
|
-
if (typeof contentPartCopy.input === "string") {
|
|
385
|
-
try {
|
|
386
|
-
contentPartCopy.input = JSON.parse(contentPartCopy.input);
|
|
387
|
-
}
|
|
388
|
-
catch {
|
|
389
|
-
contentPartCopy.input = {};
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
// TODO: Fix when SDK types are fixed
|
|
394
|
-
return {
|
|
395
|
-
...contentPartCopy,
|
|
396
|
-
...(cacheControl ? { cache_control: cacheControl } : {}),
|
|
397
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
else if ("functionCall" in contentPart &&
|
|
401
|
-
contentPart.functionCall &&
|
|
402
|
-
typeof contentPart.functionCall === "object" &&
|
|
403
|
-
isAIMessage(message)) {
|
|
404
|
-
const correspondingToolCall = message.tool_calls?.find((toolCall) => toolCall.name === contentPart.functionCall.name);
|
|
405
|
-
if (!correspondingToolCall) {
|
|
406
|
-
throw new Error(`Could not find tool call for function call ${contentPart.functionCall.name}`);
|
|
407
|
-
}
|
|
408
|
-
// Google GenAI models include a `functionCall` object inside content. We should ignore it as Anthropic will not support it.
|
|
409
|
-
return {
|
|
410
|
-
id: correspondingToolCall.id,
|
|
411
|
-
type: "tool_use",
|
|
412
|
-
name: correspondingToolCall.name,
|
|
413
|
-
input: contentPart.functionCall.args,
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
throw new Error("Unsupported message content format");
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
return contentBlocks;
|
|
421
|
-
}
|
|
141
|
+
const { content } = message;
|
|
142
|
+
if (typeof content === "string") return content;
|
|
143
|
+
else return Array.from(_formatContentBlocks(content));
|
|
422
144
|
}
|
|
423
145
|
/**
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
contentPart.type === "input_json_delta" ||
|
|
475
|
-
contentPart.type === "server_tool_use") &&
|
|
476
|
-
contentPart.id === toolCall.id));
|
|
477
|
-
if (hasMismatchedToolCalls) {
|
|
478
|
-
console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
|
|
479
|
-
}
|
|
480
|
-
return {
|
|
481
|
-
role,
|
|
482
|
-
content: _formatContent(message),
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
return {
|
|
488
|
-
role,
|
|
489
|
-
content: _formatContent(message),
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
return {
|
|
494
|
-
messages: mergeMessages(formattedMessages),
|
|
495
|
-
system,
|
|
496
|
-
};
|
|
146
|
+
* Formats messages as a prompt for the model.
|
|
147
|
+
* Used in LangSmith, export is important here.
|
|
148
|
+
* @param messages The base messages to format as a prompt.
|
|
149
|
+
* @returns The formatted prompt.
|
|
150
|
+
*/
|
|
151
|
+
function _convertMessagesToAnthropicPayload(messages) {
|
|
152
|
+
const mergedMessages = _ensureMessageContents(messages);
|
|
153
|
+
let system;
|
|
154
|
+
if (mergedMessages.length > 0 && mergedMessages[0]._getType() === "system") system = messages[0].content;
|
|
155
|
+
const conversationMessages = system !== void 0 ? mergedMessages.slice(1) : mergedMessages;
|
|
156
|
+
const formattedMessages = conversationMessages.map((message) => {
|
|
157
|
+
let role;
|
|
158
|
+
if (message._getType() === "human") role = "user";
|
|
159
|
+
else if (message._getType() === "ai") role = "assistant";
|
|
160
|
+
else if (message._getType() === "tool") role = "user";
|
|
161
|
+
else if (message._getType() === "system") throw new Error("System messages are only permitted as the first passed message.");
|
|
162
|
+
else throw new Error(`Message type "${message._getType()}" is not supported.`);
|
|
163
|
+
if (isAIMessage(message) && message.response_metadata?.output_version === "v1") return {
|
|
164
|
+
role,
|
|
165
|
+
content: _formatStandardContent(message)
|
|
166
|
+
};
|
|
167
|
+
if (isAIMessage(message) && !!message.tool_calls?.length) if (typeof message.content === "string") if (message.content === "") return {
|
|
168
|
+
role,
|
|
169
|
+
content: message.tool_calls.map(_convertLangChainToolCallToAnthropic)
|
|
170
|
+
};
|
|
171
|
+
else return {
|
|
172
|
+
role,
|
|
173
|
+
content: [{
|
|
174
|
+
type: "text",
|
|
175
|
+
text: message.content
|
|
176
|
+
}, ...message.tool_calls.map(_convertLangChainToolCallToAnthropic)]
|
|
177
|
+
};
|
|
178
|
+
else {
|
|
179
|
+
const { content } = message;
|
|
180
|
+
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));
|
|
181
|
+
if (hasMismatchedToolCalls) console.warn(`The "tool_calls" field on a message is only respected if content is a string.`);
|
|
182
|
+
return {
|
|
183
|
+
role,
|
|
184
|
+
content: _formatContent(message)
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
else return {
|
|
188
|
+
role,
|
|
189
|
+
content: _formatContent(message)
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
messages: mergeMessages(formattedMessages),
|
|
194
|
+
system
|
|
195
|
+
};
|
|
497
196
|
}
|
|
498
197
|
function mergeMessages(messages) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
isToolResultMessage(nextMessage)) {
|
|
528
|
-
// Merge the messages by combining their content arrays
|
|
529
|
-
currentMessage = {
|
|
530
|
-
...currentMessage,
|
|
531
|
-
content: [
|
|
532
|
-
...normalizeContent(currentMessage.content),
|
|
533
|
-
...normalizeContent(nextMessage.content),
|
|
534
|
-
],
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
result.push(currentMessage);
|
|
539
|
-
currentMessage = nextMessage;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
result.push(currentMessage);
|
|
543
|
-
return result;
|
|
198
|
+
if (!messages || messages.length <= 1) return messages;
|
|
199
|
+
const result = [];
|
|
200
|
+
let currentMessage = messages[0];
|
|
201
|
+
const normalizeContent = (content) => {
|
|
202
|
+
if (typeof content === "string") return [{
|
|
203
|
+
type: "text",
|
|
204
|
+
text: content
|
|
205
|
+
}];
|
|
206
|
+
return content;
|
|
207
|
+
};
|
|
208
|
+
const isToolResultMessage = (msg) => {
|
|
209
|
+
if (msg.role !== "user") return false;
|
|
210
|
+
if (typeof msg.content === "string") return false;
|
|
211
|
+
return Array.isArray(msg.content) && msg.content.every((item) => item.type === "tool_result");
|
|
212
|
+
};
|
|
213
|
+
for (let i = 1; i < messages.length; i += 1) {
|
|
214
|
+
const nextMessage = messages[i];
|
|
215
|
+
if (isToolResultMessage(currentMessage) && isToolResultMessage(nextMessage)) currentMessage = {
|
|
216
|
+
...currentMessage,
|
|
217
|
+
content: [...normalizeContent(currentMessage.content), ...normalizeContent(nextMessage.content)]
|
|
218
|
+
};
|
|
219
|
+
else {
|
|
220
|
+
result.push(currentMessage);
|
|
221
|
+
currentMessage = nextMessage;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
result.push(currentMessage);
|
|
225
|
+
return result;
|
|
544
226
|
}
|
|
227
|
+
|
|
228
|
+
//#endregion
|
|
229
|
+
export { _convertMessagesToAnthropicPayload };
|
|
230
|
+
//# sourceMappingURL=message_inputs.js.map
|