@librechat/agents 2.4.21 → 2.4.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/cjs/llm/anthropic/index.cjs +1 -1
  2. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  3. package/dist/cjs/llm/anthropic/types.cjs +50 -0
  4. package/dist/cjs/llm/anthropic/types.cjs.map +1 -0
  5. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +227 -21
  6. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +1 -0
  8. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  9. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  10. package/dist/cjs/messages/core.cjs +91 -51
  11. package/dist/cjs/messages/core.cjs.map +1 -1
  12. package/dist/cjs/run.cjs.map +1 -1
  13. package/dist/esm/llm/anthropic/index.mjs +1 -1
  14. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  15. package/dist/esm/llm/anthropic/types.mjs +48 -0
  16. package/dist/esm/llm/anthropic/types.mjs.map +1 -0
  17. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +228 -22
  18. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  19. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +1 -0
  20. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  21. package/dist/esm/llm/openai/index.mjs.map +1 -1
  22. package/dist/esm/messages/core.mjs +91 -51
  23. package/dist/esm/messages/core.mjs.map +1 -1
  24. package/dist/esm/run.mjs.map +1 -1
  25. package/dist/types/llm/anthropic/index.d.ts +3 -4
  26. package/dist/types/llm/anthropic/types.d.ts +4 -35
  27. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +2 -2
  28. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -3
  29. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +22 -0
  30. package/dist/types/llm/openai/index.d.ts +3 -2
  31. package/dist/types/messages/core.d.ts +1 -1
  32. package/dist/types/tools/example.d.ts +21 -3
  33. package/package.json +9 -9
  34. package/src/llm/anthropic/index.ts +6 -5
  35. package/src/llm/anthropic/llm.spec.ts +176 -179
  36. package/src/llm/anthropic/types.ts +64 -39
  37. package/src/llm/anthropic/utils/message_inputs.ts +275 -37
  38. package/src/llm/anthropic/utils/message_outputs.ts +4 -21
  39. package/src/llm/anthropic/utils/output_parsers.ts +114 -0
  40. package/src/llm/openai/index.ts +7 -6
  41. package/src/messages/core.ts +197 -96
  42. package/src/run.ts +1 -1
@@ -1,6 +1,4 @@
1
-
2
1
  import Anthropic from '@anthropic-ai/sdk';
3
- import type { Tool as AnthropicTool } from '@anthropic-ai/sdk/resources';
4
2
  import { BindToolsInput } from '@langchain/core/language_models/chat_models';
5
3
 
6
4
  export type AnthropicToolResponse = {
@@ -11,9 +9,10 @@ export type AnthropicToolResponse = {
11
9
  input: Record<string, any>;
12
10
  };
13
11
 
12
+ export type AnthropicStreamUsage = Anthropic.Usage;
14
13
  export type AnthropicMessageParam = Anthropic.MessageParam;
15
- export type AnthropicMessageDeltaEvent= Anthropic.MessageDeltaEvent;
16
- export type AnthropicMessageStartEvent= Anthropic.MessageStartEvent;
14
+ export type AnthropicMessageDeltaEvent = Anthropic.MessageDeltaEvent;
15
+ export type AnthropicMessageStartEvent = Anthropic.MessageStartEvent;
17
16
  export type AnthropicMessageResponse =
18
17
  | Anthropic.ContentBlock
19
18
  | AnthropicToolResponse;
@@ -21,6 +20,7 @@ export type AnthropicMessageCreateParams =
21
20
  Anthropic.MessageCreateParamsNonStreaming;
22
21
  export type AnthropicStreamingMessageCreateParams =
23
22
  Anthropic.MessageCreateParamsStreaming;
23
+ export type AnthropicThinkingConfigParam = Anthropic.ThinkingConfigParam;
24
24
  export type AnthropicMessageStreamEvent = Anthropic.MessageStreamEvent;
25
25
  export type AnthropicRequestOptions = Anthropic.RequestOptions;
26
26
  export type AnthropicToolChoice =
@@ -32,7 +32,7 @@ export type AnthropicToolChoice =
32
32
  | 'auto'
33
33
  | 'none'
34
34
  | string;
35
- export type ChatAnthropicToolType = AnthropicTool | BindToolsInput;
35
+ export type ChatAnthropicToolType = Anthropic.Messages.Tool | BindToolsInput;
36
36
  export type AnthropicTextBlockParam = Anthropic.Messages.TextBlockParam;
37
37
  export type AnthropicImageBlockParam = Anthropic.Messages.ImageBlockParam;
38
38
  export type AnthropicToolUseBlockParam = Anthropic.Messages.ToolUseBlockParam;
@@ -41,39 +41,64 @@ export type AnthropicToolResultBlockParam =
41
41
  export type AnthropicDocumentBlockParam = Anthropic.Messages.DocumentBlockParam;
42
42
  export type AnthropicThinkingBlockParam = Anthropic.Messages.ThinkingBlockParam;
43
43
  export type AnthropicRedactedThinkingBlockParam =
44
- Anthropic.Messages.RedactedThinkingBlockParam;
44
+ Anthropic.Messages.RedactedThinkingBlockParam;
45
+
46
+ export function isAnthropicImageBlockParam(
47
+ block: unknown
48
+ ): block is AnthropicImageBlockParam {
49
+ if (block == null) {
50
+ return false;
51
+ }
52
+ if (typeof block !== 'object') {
53
+ return false;
54
+ }
55
+ if (!('type' in block) || block.type !== 'image') {
56
+ return false;
57
+ }
58
+
59
+ if (!('source' in block) || typeof block.source !== 'object') {
60
+ return false;
61
+ }
62
+
63
+ if (block.source == null) {
64
+ return false;
65
+ }
66
+
67
+ if (!('type' in block.source)) {
68
+ return false;
69
+ }
70
+
71
+ if (block.source.type === 'base64') {
72
+ if (!('media_type' in block.source)) {
73
+ return false;
74
+ }
75
+
76
+ if (typeof block.source.media_type !== 'string') {
77
+ return false;
78
+ }
79
+
80
+ if (!('data' in block.source)) {
81
+ return false;
82
+ }
83
+
84
+ if (typeof block.source.data !== 'string') {
85
+ return false;
86
+ }
87
+
88
+ return true;
89
+ }
90
+
91
+ if (block.source.type === 'url') {
92
+ if (!('url' in block.source)) {
93
+ return false;
94
+ }
95
+
96
+ if (typeof block.source.url !== 'string') {
97
+ return false;
98
+ }
45
99
 
46
- /**
47
- * Stream usage information for Anthropic API calls
48
- * @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching#pricing
49
- */
50
- export interface AnthropicStreamUsage {
51
- /**
52
- * The number of input tokens used in the request
53
- */
54
- input_tokens: number;
100
+ return true;
101
+ }
55
102
 
56
- /**
57
- * The number of cache creation input tokens used (write operations)
58
- */
59
- cache_creation_input_tokens?: number;
60
- /**
61
- * The number of cache input tokens used (read operations)
62
- */
63
- cache_read_input_tokens?: number;
64
- /**
65
- * The number of output tokens generated in the response
66
- */
67
- output_tokens: number;
68
- /**
69
- * The total number of tokens generated in the response
70
- */
71
- total_tokens: number;
72
- /**
73
- * Details about input token usage
74
- */
75
- input_token_details?: {
76
- cache_creation: number;
77
- cache_read: number;
78
- };
79
- }
103
+ return false;
104
+ }
@@ -1,47 +1,80 @@
1
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
1
2
  /* eslint-disable no-console */
2
3
  /**
3
4
  * This util file contains functions for converting LangChain messages to Anthropic messages.
4
5
  */
5
6
  import {
6
- AIMessage,
7
- BaseMessage,
8
- ToolMessage,
9
- isAIMessage,
7
+ type BaseMessage,
8
+ type SystemMessage,
10
9
  HumanMessage,
11
- SystemMessage,
12
- MessageContent,
10
+ type AIMessage,
11
+ type ToolMessage,
12
+ type MessageContent,
13
+ isAIMessage,
14
+ type StandardContentBlockConverter,
15
+ type StandardTextBlock,
16
+ type StandardImageBlock,
17
+ type StandardFileBlock,
18
+ MessageContentComplex,
19
+ isDataContentBlock,
20
+ convertToProviderContentBlock,
21
+ parseBase64DataUrl,
13
22
  } from '@langchain/core/messages';
14
23
  import { ToolCall } from '@langchain/core/messages/tool';
15
24
  import type {
16
- AnthropicToolResponse,
17
- AnthropicMessageParam,
18
- AnthropicTextBlockParam,
19
25
  AnthropicImageBlockParam,
20
- AnthropicToolUseBlockParam,
21
26
  AnthropicMessageCreateParams,
27
+ AnthropicTextBlockParam,
28
+ AnthropicToolResponse,
22
29
  AnthropicToolResultBlockParam,
30
+ AnthropicToolUseBlockParam,
23
31
  AnthropicDocumentBlockParam,
24
32
  AnthropicThinkingBlockParam,
25
33
  AnthropicRedactedThinkingBlockParam,
26
34
  } from '@/llm/anthropic/types';
35
+ import { isAnthropicImageBlockParam } from '@/llm/anthropic/types';
36
+
37
+ function _formatImage(imageUrl: string) {
38
+ const parsed = parseBase64DataUrl({ dataUrl: imageUrl });
39
+ if (parsed) {
40
+ return {
41
+ type: 'base64',
42
+ media_type: parsed.mime_type,
43
+ data: parsed.data,
44
+ };
45
+ }
46
+ let parsedUrl: URL;
27
47
 
28
- function _formatImage(imageUrl: string): { type: string; media_type: string; data: string } {
29
- const regex = /^data:(image\/.+);base64,(.+)$/;
30
- const match = imageUrl.match(regex);
31
- if (match === null) {
48
+ try {
49
+ parsedUrl = new URL(imageUrl);
50
+ } catch {
32
51
  throw new Error(
33
52
  [
34
- 'Anthropic only supports base64-encoded images currently.',
53
+ `Malformed image URL: ${JSON.stringify(
54
+ imageUrl
55
+ )}. Content blocks of type 'image_url' must be a valid http, https, or base64-encoded data URL.`,
35
56
  'Example: data:image/png;base64,/9j/4AAQSk...',
57
+ 'Example: https://example.com/image.jpg',
36
58
  ].join('\n\n')
37
59
  );
38
60
  }
39
- return {
40
- type: 'base64',
41
- media_type: match[1] ?? '',
42
- data: match[2] ?? '',
43
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
- } as any;
61
+
62
+ if (parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:') {
63
+ return {
64
+ type: 'url',
65
+ url: imageUrl,
66
+ };
67
+ }
68
+
69
+ throw new Error(
70
+ [
71
+ `Invalid image URL protocol: ${JSON.stringify(
72
+ parsedUrl.protocol
73
+ )}. Anthropic only supports images as http, https, or base64-encoded data URLs on 'image_url' content blocks.`,
74
+ 'Example: data:image/png;base64,/9j/4AAQSk...',
75
+ 'Example: https://example.com/image.jpg',
76
+ ].join('\n\n')
77
+ );
45
78
  }
46
79
 
47
80
  function _ensureMessageContents(
@@ -52,16 +85,15 @@ function _ensureMessageContents(
52
85
  for (const message of messages) {
53
86
  if (message._getType() === 'tool') {
54
87
  if (typeof message.content === 'string') {
55
- const previousMessage = updatedMsgs[updatedMsgs.length - 1] as BaseMessage | undefined;
88
+ const previousMessage = updatedMsgs[updatedMsgs.length - 1];
56
89
  if (
57
- previousMessage &&
58
90
  previousMessage._getType() === 'human' &&
59
91
  Array.isArray(previousMessage.content) &&
60
92
  'type' in previousMessage.content[0] &&
61
93
  previousMessage.content[0].type === 'tool_result'
62
94
  ) {
63
95
  // If the previous message was a tool result, we merge this tool message into it.
64
- previousMessage.content.push({
96
+ (previousMessage.content as MessageContentComplex[]).push({
65
97
  type: 'tool_result',
66
98
  content: message.content,
67
99
  tool_use_id: (message as ToolMessage).tool_call_id,
@@ -114,8 +146,203 @@ export function _convertLangChainToolCallToAnthropic(
114
146
  };
115
147
  }
116
148
 
117
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
- function _formatContent(content: MessageContent): string | Record<string, any>[] {
149
+ const standardContentBlockConverter: StandardContentBlockConverter<{
150
+ text: AnthropicTextBlockParam;
151
+ image: AnthropicImageBlockParam;
152
+ file: AnthropicDocumentBlockParam;
153
+ }> = {
154
+ providerName: 'anthropic',
155
+
156
+ fromStandardTextBlock(block: StandardTextBlock): AnthropicTextBlockParam {
157
+ return {
158
+ type: 'text',
159
+ text: block.text,
160
+ ...('citations' in (block.metadata ?? {})
161
+ ? { citations: block.metadata!.citations }
162
+ : {}),
163
+ ...('cache_control' in (block.metadata ?? {})
164
+ ? { cache_control: block.metadata!.cache_control }
165
+ : {}),
166
+ } as AnthropicTextBlockParam;
167
+ },
168
+
169
+ fromStandardImageBlock(block: StandardImageBlock): AnthropicImageBlockParam {
170
+ if (block.source_type === 'url') {
171
+ const data = parseBase64DataUrl({
172
+ dataUrl: block.url,
173
+ asTypedArray: false,
174
+ });
175
+ if (data) {
176
+ return {
177
+ type: 'image',
178
+ source: {
179
+ type: 'base64',
180
+ data: data.data,
181
+ media_type: data.mime_type,
182
+ },
183
+ ...('cache_control' in (block.metadata ?? {})
184
+ ? { cache_control: block.metadata!.cache_control }
185
+ : {}),
186
+ } as AnthropicImageBlockParam;
187
+ } else {
188
+ return {
189
+ type: 'image',
190
+ source: {
191
+ type: 'url',
192
+ url: block.url,
193
+ media_type: block.mime_type ?? '',
194
+ },
195
+ ...('cache_control' in (block.metadata ?? {})
196
+ ? { cache_control: block.metadata!.cache_control }
197
+ : {}),
198
+ } as AnthropicImageBlockParam;
199
+ }
200
+ } else {
201
+ if (block.source_type === 'base64') {
202
+ return {
203
+ type: 'image',
204
+ source: {
205
+ type: 'base64',
206
+ data: block.data,
207
+ media_type: block.mime_type ?? '',
208
+ },
209
+ ...('cache_control' in (block.metadata ?? {})
210
+ ? { cache_control: block.metadata!.cache_control }
211
+ : {}),
212
+ } as AnthropicImageBlockParam;
213
+ } else {
214
+ throw new Error(`Unsupported image source type: ${block.source_type}`);
215
+ }
216
+ }
217
+ },
218
+
219
+ fromStandardFileBlock(block: StandardFileBlock): AnthropicDocumentBlockParam {
220
+ const mime_type = (block.mime_type ?? '').split(';')[0];
221
+
222
+ if (block.source_type === 'url') {
223
+ if (mime_type === 'application/pdf' || mime_type === '') {
224
+ return {
225
+ type: 'document',
226
+ source: {
227
+ type: 'url',
228
+ url: block.url,
229
+ media_type: block.mime_type ?? '',
230
+ },
231
+ ...('cache_control' in (block.metadata ?? {})
232
+ ? { cache_control: block.metadata!.cache_control }
233
+ : {}),
234
+ ...('citations' in (block.metadata ?? {})
235
+ ? { citations: block.metadata!.citations }
236
+ : {}),
237
+ ...('context' in (block.metadata ?? {})
238
+ ? { context: block.metadata!.context }
239
+ : {}),
240
+ ...('title' in (block.metadata ?? {})
241
+ ? { title: block.metadata!.title }
242
+ : {}),
243
+ } as AnthropicDocumentBlockParam;
244
+ }
245
+ throw new Error(
246
+ `Unsupported file mime type for file url source: ${block.mime_type}`
247
+ );
248
+ } else if (block.source_type === 'text') {
249
+ if (mime_type === 'text/plain' || mime_type === '') {
250
+ return {
251
+ type: 'document',
252
+ source: {
253
+ type: 'text',
254
+ data: block.text,
255
+ media_type: block.mime_type ?? '',
256
+ },
257
+ ...('cache_control' in (block.metadata ?? {})
258
+ ? { cache_control: block.metadata!.cache_control }
259
+ : {}),
260
+ ...('citations' in (block.metadata ?? {})
261
+ ? { citations: block.metadata!.citations }
262
+ : {}),
263
+ ...('context' in (block.metadata ?? {})
264
+ ? { context: block.metadata!.context }
265
+ : {}),
266
+ ...('title' in (block.metadata ?? {})
267
+ ? { title: block.metadata!.title }
268
+ : {}),
269
+ } as AnthropicDocumentBlockParam;
270
+ } else {
271
+ throw new Error(
272
+ `Unsupported file mime type for file text source: ${block.mime_type}`
273
+ );
274
+ }
275
+ } else if (block.source_type === 'base64') {
276
+ if (mime_type === 'application/pdf' || mime_type === '') {
277
+ return {
278
+ type: 'document',
279
+ source: {
280
+ type: 'base64',
281
+ data: block.data,
282
+ media_type: 'application/pdf',
283
+ },
284
+ ...('cache_control' in (block.metadata ?? {})
285
+ ? { cache_control: block.metadata!.cache_control }
286
+ : {}),
287
+ ...('citations' in (block.metadata ?? {})
288
+ ? { citations: block.metadata!.citations }
289
+ : {}),
290
+ ...('context' in (block.metadata ?? {})
291
+ ? { context: block.metadata!.context }
292
+ : {}),
293
+ ...('title' in (block.metadata ?? {})
294
+ ? { title: block.metadata!.title }
295
+ : {}),
296
+ } as AnthropicDocumentBlockParam;
297
+ } else if (
298
+ ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(
299
+ mime_type
300
+ )
301
+ ) {
302
+ return {
303
+ type: 'document',
304
+ source: {
305
+ type: 'content',
306
+ content: [
307
+ {
308
+ type: 'image',
309
+ source: {
310
+ type: 'base64',
311
+ data: block.data,
312
+ media_type: mime_type as
313
+ | 'image/jpeg'
314
+ | 'image/png'
315
+ | 'image/gif'
316
+ | 'image/webp',
317
+ },
318
+ },
319
+ ],
320
+ },
321
+ ...('cache_control' in (block.metadata ?? {})
322
+ ? { cache_control: block.metadata!.cache_control }
323
+ : {}),
324
+ ...('citations' in (block.metadata ?? {})
325
+ ? { citations: block.metadata!.citations }
326
+ : {}),
327
+ ...('context' in (block.metadata ?? {})
328
+ ? { context: block.metadata!.context }
329
+ : {}),
330
+ ...('title' in (block.metadata ?? {})
331
+ ? { title: block.metadata!.title }
332
+ : {}),
333
+ } as AnthropicDocumentBlockParam;
334
+ } else {
335
+ throw new Error(
336
+ `Unsupported file mime type for file base64 source: ${block.mime_type}`
337
+ );
338
+ }
339
+ } else {
340
+ throw new Error(`Unsupported file source type: ${block.source_type}`);
341
+ }
342
+ },
343
+ };
344
+
345
+ function _formatContent(content: MessageContent) {
119
346
  const toolTypes = ['tool_use', 'tool_result', 'input_json_delta'];
120
347
  const textTypes = ['text', 'text_delta'];
121
348
 
@@ -123,6 +350,13 @@ function _formatContent(content: MessageContent): string | Record<string, any>[]
123
350
  return content;
124
351
  } else {
125
352
  const contentBlocks = content.map((contentPart) => {
353
+ if (isDataContentBlock(contentPart)) {
354
+ return convertToProviderContentBlock(
355
+ contentPart,
356
+ standardContentBlockConverter
357
+ );
358
+ }
359
+
126
360
  const cacheControl =
127
361
  'cache_control' in contentPart ? contentPart.cache_control : undefined;
128
362
 
@@ -138,6 +372,8 @@ function _formatContent(content: MessageContent): string | Record<string, any>[]
138
372
  source,
139
373
  ...(cacheControl ? { cache_control: cacheControl } : {}),
140
374
  };
375
+ } else if (isAnthropicImageBlockParam(contentPart)) {
376
+ return contentPart;
141
377
  } else if (contentPart.type === 'document') {
142
378
  // PDF
143
379
  return {
@@ -160,7 +396,7 @@ function _formatContent(content: MessageContent): string | Record<string, any>[]
160
396
  };
161
397
  return block;
162
398
  } else if (
163
- textTypes.find((t) => t === contentPart.type) != null &&
399
+ textTypes.find((t) => t === contentPart.type) &&
164
400
  'text' in contentPart
165
401
  ) {
166
402
  // Assuming contentPart is of type MessageContentText here
@@ -169,7 +405,7 @@ function _formatContent(content: MessageContent): string | Record<string, any>[]
169
405
  text: contentPart.text,
170
406
  ...(cacheControl ? { cache_control: cacheControl } : {}),
171
407
  };
172
- } else if (toolTypes.find((t) => t === contentPart.type) != null) {
408
+ } else if (toolTypes.find((t) => t === contentPart.type)) {
173
409
  const contentPartCopy = { ...contentPart };
174
410
  if ('index' in contentPartCopy) {
175
411
  // Anthropic does not support passing the index field here, so we remove it.
@@ -184,10 +420,12 @@ function _formatContent(content: MessageContent): string | Record<string, any>[]
184
420
 
185
421
  if ('input' in contentPartCopy) {
186
422
  // Anthropic tool use inputs should be valid objects, when applicable.
187
- try {
188
- contentPartCopy.input = JSON.parse(contentPartCopy.input);
189
- } catch {
190
- contentPartCopy.input = {};
423
+ if (typeof contentPartCopy.input === 'string') {
424
+ try {
425
+ contentPartCopy.input = JSON.parse(contentPartCopy.input);
426
+ } catch {
427
+ contentPartCopy.input = {};
428
+ }
191
429
  }
192
430
  }
193
431
 
@@ -282,14 +520,14 @@ export function _convertMessagesToAnthropicPayload(
282
520
  }
283
521
  });
284
522
  return {
285
- messages: mergeMessages(formattedMessages as AnthropicMessageCreateParams['messages']),
523
+ messages: mergeMessages(formattedMessages),
286
524
  system,
287
525
  } as AnthropicMessageCreateParams;
288
526
  }
289
527
 
290
- function mergeMessages(messages?: AnthropicMessageCreateParams['messages']): AnthropicMessageParam[] {
528
+ function mergeMessages(messages: AnthropicMessageCreateParams['messages']) {
291
529
  if (!messages || messages.length <= 1) {
292
- return messages ?? [];
530
+ return messages;
293
531
  }
294
532
 
295
533
  const result: AnthropicMessageCreateParams['messages'] = [];
@@ -327,7 +565,7 @@ function mergeMessages(messages?: AnthropicMessageCreateParams['messages']): Ant
327
565
  return content;
328
566
  };
329
567
 
330
- const isToolResultMessage = (msg: (typeof messages)[0]): boolean => {
568
+ const isToolResultMessage = (msg: (typeof messages)[0]) => {
331
569
  if (msg.role !== 'user') return false;
332
570
 
333
571
  if (typeof msg.content === 'string') {
@@ -363,4 +601,4 @@ function mergeMessages(messages?: AnthropicMessageCreateParams['messages']): Ant
363
601
 
364
602
  result.push(currentMessage);
365
603
  return result;
366
- }
604
+ }
@@ -4,29 +4,13 @@
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
5
  import {
6
6
  AIMessage,
7
- UsageMetadata,
8
7
  AIMessageChunk,
8
+ UsageMetadata,
9
9
  } from '@langchain/core/messages';
10
10
  import type { ToolCallChunk } from '@langchain/core/messages/tool';
11
- import { ToolCall } from '@langchain/core/messages/tool';
12
11
  import { ChatGeneration } from '@langchain/core/outputs';
13
- import { AnthropicMessageResponse } from '../types.js';
14
-
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
- export function extractToolCalls(content: Record<string, any>[]): ToolCall[] {
17
- const toolCalls: ToolCall[] = [];
18
- for (const block of content) {
19
- if (block.type === 'tool_use') {
20
- toolCalls.push({
21
- name: block.name,
22
- args: block.input,
23
- id: block.id,
24
- type: 'tool_call',
25
- });
26
- }
27
- }
28
- return toolCalls;
29
- }
12
+ import { extractToolCalls } from './output_parsers';
13
+ import { AnthropicMessageResponse } from '../types';
30
14
 
31
15
  export function _makeMessageChunkFromAnthropicEvent(
32
16
  data: Anthropic.Messages.RawMessageStreamEvent,
@@ -231,7 +215,6 @@ export function _makeMessageChunkFromAnthropicEvent(
231
215
  }),
232
216
  };
233
217
  }
234
-
235
218
  return null;
236
219
  }
237
220
 
@@ -284,4 +267,4 @@ export function anthropicResponseToChatMessages(
284
267
  ];
285
268
  return generations;
286
269
  }
287
- }
270
+ }