@langchain/anthropic 0.2.2 → 0.2.4
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/dist/chat_models.cjs +271 -106
- package/dist/chat_models.d.ts +6 -6
- package/dist/chat_models.js +271 -106
- package/dist/output_parsers.cjs +6 -1
- package/dist/output_parsers.js +6 -1
- package/package.json +2 -2
package/dist/chat_models.cjs
CHANGED
|
@@ -10,7 +10,11 @@ const base_1 = require("@langchain/core/language_models/base");
|
|
|
10
10
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
11
11
|
const runnables_1 = require("@langchain/core/runnables");
|
|
12
12
|
const types_1 = require("@langchain/core/utils/types");
|
|
13
|
+
const stream_1 = require("@langchain/core/utils/stream");
|
|
13
14
|
const output_parsers_js_1 = require("./output_parsers.cjs");
|
|
15
|
+
function _toolsInParams(params) {
|
|
16
|
+
return !!(params.tools && params.tools.length > 0);
|
|
17
|
+
}
|
|
14
18
|
function _formatImage(imageUrl) {
|
|
15
19
|
const regex = /^data:(image\/.+);base64,(.+)$/;
|
|
16
20
|
const match = imageUrl.match(regex);
|
|
@@ -44,6 +48,7 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
44
48
|
content: messages[0].text,
|
|
45
49
|
additional_kwargs: additionalKwargs,
|
|
46
50
|
usage_metadata: usageMetadata,
|
|
51
|
+
response_metadata: additionalKwargs,
|
|
47
52
|
}),
|
|
48
53
|
},
|
|
49
54
|
];
|
|
@@ -59,6 +64,7 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
59
64
|
additional_kwargs: additionalKwargs,
|
|
60
65
|
tool_calls: toolCalls,
|
|
61
66
|
usage_metadata: usageMetadata,
|
|
67
|
+
response_metadata: additionalKwargs,
|
|
62
68
|
}),
|
|
63
69
|
},
|
|
64
70
|
];
|
|
@@ -69,6 +75,115 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
69
75
|
function isAnthropicTool(tool) {
|
|
70
76
|
return "input_schema" in tool;
|
|
71
77
|
}
|
|
78
|
+
function _makeMessageChunkFromAnthropicEvent(data, fields) {
|
|
79
|
+
let usageDataCopy = { ...fields.usageData };
|
|
80
|
+
if (data.type === "message_start") {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
|
+
const { content, usage, ...additionalKwargs } = data.message;
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
const filteredAdditionalKwargs = {};
|
|
85
|
+
for (const [key, value] of Object.entries(additionalKwargs)) {
|
|
86
|
+
if (value !== undefined && value !== null) {
|
|
87
|
+
filteredAdditionalKwargs[key] = value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
usageDataCopy = usage;
|
|
91
|
+
let usageMetadata;
|
|
92
|
+
if (fields.streamUsage) {
|
|
93
|
+
usageMetadata = {
|
|
94
|
+
input_tokens: usage.input_tokens,
|
|
95
|
+
output_tokens: usage.output_tokens,
|
|
96
|
+
total_tokens: usage.input_tokens + usage.output_tokens,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
chunk: new messages_1.AIMessageChunk({
|
|
101
|
+
content: fields.coerceContentToString ? "" : [],
|
|
102
|
+
additional_kwargs: filteredAdditionalKwargs,
|
|
103
|
+
usage_metadata: usageMetadata,
|
|
104
|
+
}),
|
|
105
|
+
usageData: usageDataCopy,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else if (data.type === "message_delta") {
|
|
109
|
+
let usageMetadata;
|
|
110
|
+
if (fields.streamUsage) {
|
|
111
|
+
usageMetadata = {
|
|
112
|
+
input_tokens: data.usage.output_tokens,
|
|
113
|
+
output_tokens: 0,
|
|
114
|
+
total_tokens: data.usage.output_tokens,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (data?.usage !== undefined) {
|
|
118
|
+
usageDataCopy.output_tokens += data.usage.output_tokens;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
chunk: new messages_1.AIMessageChunk({
|
|
122
|
+
content: fields.coerceContentToString ? "" : [],
|
|
123
|
+
additional_kwargs: { ...data.delta },
|
|
124
|
+
usage_metadata: usageMetadata,
|
|
125
|
+
}),
|
|
126
|
+
usageData: usageDataCopy,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
else if (data.type === "content_block_start" &&
|
|
130
|
+
data.content_block.type === "tool_use") {
|
|
131
|
+
return {
|
|
132
|
+
chunk: new messages_1.AIMessageChunk({
|
|
133
|
+
content: fields.coerceContentToString
|
|
134
|
+
? ""
|
|
135
|
+
: [
|
|
136
|
+
{
|
|
137
|
+
index: data.index,
|
|
138
|
+
...data.content_block,
|
|
139
|
+
input: "",
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
additional_kwargs: {},
|
|
143
|
+
}),
|
|
144
|
+
usageData: usageDataCopy,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else if (data.type === "content_block_delta" &&
|
|
148
|
+
data.delta.type === "text_delta") {
|
|
149
|
+
const content = data.delta?.text;
|
|
150
|
+
if (content !== undefined) {
|
|
151
|
+
return {
|
|
152
|
+
chunk: new messages_1.AIMessageChunk({
|
|
153
|
+
content: fields.coerceContentToString
|
|
154
|
+
? content
|
|
155
|
+
: [
|
|
156
|
+
{
|
|
157
|
+
index: data.index,
|
|
158
|
+
...data.delta,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
additional_kwargs: {},
|
|
162
|
+
}),
|
|
163
|
+
usageData: usageDataCopy,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (data.type === "content_block_delta" &&
|
|
168
|
+
data.delta.type === "input_json_delta") {
|
|
169
|
+
return {
|
|
170
|
+
chunk: new messages_1.AIMessageChunk({
|
|
171
|
+
content: fields.coerceContentToString
|
|
172
|
+
? ""
|
|
173
|
+
: [
|
|
174
|
+
{
|
|
175
|
+
index: data.index,
|
|
176
|
+
input: data.delta.partial_json,
|
|
177
|
+
type: data.delta.type,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
additional_kwargs: {},
|
|
181
|
+
}),
|
|
182
|
+
usageData: usageDataCopy,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
72
187
|
function _mergeMessages(messages) {
|
|
73
188
|
// Merge runs of human/tool messages into single human messages with content blocks.
|
|
74
189
|
const merged = [];
|
|
@@ -243,6 +358,90 @@ function _formatMessagesForAnthropic(messages) {
|
|
|
243
358
|
system,
|
|
244
359
|
};
|
|
245
360
|
}
|
|
361
|
+
function extractToolCallChunk(chunk) {
|
|
362
|
+
let newToolCallChunk;
|
|
363
|
+
// Initial chunk for tool calls from anthropic contains identifying information like ID and name.
|
|
364
|
+
// This chunk does not contain any input JSON.
|
|
365
|
+
const toolUseChunks = Array.isArray(chunk.content)
|
|
366
|
+
? chunk.content.find((c) => c.type === "tool_use")
|
|
367
|
+
: undefined;
|
|
368
|
+
if (toolUseChunks &&
|
|
369
|
+
"index" in toolUseChunks &&
|
|
370
|
+
"name" in toolUseChunks &&
|
|
371
|
+
"id" in toolUseChunks) {
|
|
372
|
+
newToolCallChunk = {
|
|
373
|
+
args: "",
|
|
374
|
+
id: toolUseChunks.id,
|
|
375
|
+
name: toolUseChunks.name,
|
|
376
|
+
index: toolUseChunks.index,
|
|
377
|
+
type: "tool_call_chunk",
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
// Chunks after the initial chunk only contain the index and partial JSON.
|
|
381
|
+
const inputJsonDeltaChunks = Array.isArray(chunk.content)
|
|
382
|
+
? chunk.content.find((c) => c.type === "input_json_delta")
|
|
383
|
+
: undefined;
|
|
384
|
+
if (inputJsonDeltaChunks &&
|
|
385
|
+
"index" in inputJsonDeltaChunks &&
|
|
386
|
+
"input" in inputJsonDeltaChunks) {
|
|
387
|
+
if (typeof inputJsonDeltaChunks.input === "string") {
|
|
388
|
+
newToolCallChunk = {
|
|
389
|
+
args: inputJsonDeltaChunks.input,
|
|
390
|
+
index: inputJsonDeltaChunks.index,
|
|
391
|
+
type: "tool_call_chunk",
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
newToolCallChunk = {
|
|
396
|
+
args: JSON.stringify(inputJsonDeltaChunks.input, null, 2),
|
|
397
|
+
index: inputJsonDeltaChunks.index,
|
|
398
|
+
type: "tool_call_chunk",
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return newToolCallChunk;
|
|
403
|
+
}
|
|
404
|
+
function extractToken(chunk) {
|
|
405
|
+
return typeof chunk.content === "string" && chunk.content !== ""
|
|
406
|
+
? chunk.content
|
|
407
|
+
: undefined;
|
|
408
|
+
}
|
|
409
|
+
function extractToolUseContent(chunk, concatenatedChunks) {
|
|
410
|
+
let newConcatenatedChunks = concatenatedChunks;
|
|
411
|
+
// Remove `tool_use` content types until the last chunk.
|
|
412
|
+
let toolUseContent;
|
|
413
|
+
if (!newConcatenatedChunks) {
|
|
414
|
+
newConcatenatedChunks = chunk;
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
newConcatenatedChunks = (0, stream_1.concat)(newConcatenatedChunks, chunk);
|
|
418
|
+
}
|
|
419
|
+
if (Array.isArray(newConcatenatedChunks.content) &&
|
|
420
|
+
newConcatenatedChunks.content.find((c) => c.type === "tool_use")) {
|
|
421
|
+
try {
|
|
422
|
+
const toolUseMsg = newConcatenatedChunks.content.find((c) => c.type === "tool_use");
|
|
423
|
+
if (!toolUseMsg ||
|
|
424
|
+
!("input" in toolUseMsg || "name" in toolUseMsg || "id" in toolUseMsg))
|
|
425
|
+
return;
|
|
426
|
+
const parsedArgs = JSON.parse(toolUseMsg.input);
|
|
427
|
+
if (parsedArgs) {
|
|
428
|
+
toolUseContent = {
|
|
429
|
+
type: "tool_use",
|
|
430
|
+
id: toolUseMsg.id,
|
|
431
|
+
name: toolUseMsg.name,
|
|
432
|
+
input: parsedArgs,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
catch (_) {
|
|
437
|
+
// no-op
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
toolUseContent,
|
|
442
|
+
concatenatedChunks: newConcatenatedChunks,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
246
445
|
/**
|
|
247
446
|
* Wrapper around Anthropic large language models.
|
|
248
447
|
*
|
|
@@ -516,119 +715,82 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
|
|
|
516
715
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
517
716
|
const params = this.invocationParams(options);
|
|
518
717
|
const formattedMessages = _formatMessagesForAnthropic(messages);
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
const stream = await this.createStreamWithRetry({
|
|
541
|
-
...params,
|
|
542
|
-
...formattedMessages,
|
|
543
|
-
stream: true,
|
|
718
|
+
const coerceContentToString = !_toolsInParams({
|
|
719
|
+
...params,
|
|
720
|
+
...formattedMessages,
|
|
721
|
+
stream: false,
|
|
722
|
+
});
|
|
723
|
+
const stream = await this.createStreamWithRetry({
|
|
724
|
+
...params,
|
|
725
|
+
...formattedMessages,
|
|
726
|
+
stream: true,
|
|
727
|
+
});
|
|
728
|
+
let usageData = { input_tokens: 0, output_tokens: 0 };
|
|
729
|
+
let concatenatedChunks;
|
|
730
|
+
for await (const data of stream) {
|
|
731
|
+
if (options.signal?.aborted) {
|
|
732
|
+
stream.controller.abort();
|
|
733
|
+
throw new Error("AbortError: User aborted the request.");
|
|
734
|
+
}
|
|
735
|
+
const result = _makeMessageChunkFromAnthropicEvent(data, {
|
|
736
|
+
streamUsage: !!(this.streamUsage || options.streamUsage),
|
|
737
|
+
coerceContentToString,
|
|
738
|
+
usageData,
|
|
544
739
|
});
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
usageData = usage;
|
|
562
|
-
let usageMetadata;
|
|
563
|
-
if (this.streamUsage || options.streamUsage) {
|
|
564
|
-
usageMetadata = {
|
|
565
|
-
input_tokens: usage.input_tokens,
|
|
566
|
-
output_tokens: usage.output_tokens,
|
|
567
|
-
total_tokens: usage.input_tokens + usage.output_tokens,
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
yield new outputs_1.ChatGenerationChunk({
|
|
571
|
-
message: new messages_1.AIMessageChunk({
|
|
572
|
-
content: "",
|
|
573
|
-
additional_kwargs: filteredAdditionalKwargs,
|
|
574
|
-
usage_metadata: usageMetadata,
|
|
575
|
-
}),
|
|
576
|
-
text: "",
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
else if (data.type === "message_delta") {
|
|
580
|
-
let usageMetadata;
|
|
581
|
-
if (this.streamUsage || options.streamUsage) {
|
|
582
|
-
usageMetadata = {
|
|
583
|
-
input_tokens: data.usage.output_tokens,
|
|
584
|
-
output_tokens: 0,
|
|
585
|
-
total_tokens: data.usage.output_tokens,
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
yield new outputs_1.ChatGenerationChunk({
|
|
589
|
-
message: new messages_1.AIMessageChunk({
|
|
590
|
-
content: "",
|
|
591
|
-
additional_kwargs: { ...data.delta },
|
|
592
|
-
usage_metadata: usageMetadata,
|
|
593
|
-
}),
|
|
594
|
-
text: "",
|
|
595
|
-
});
|
|
596
|
-
if (data?.usage !== undefined) {
|
|
597
|
-
usageData.output_tokens += data.usage.output_tokens;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
else if (data.type === "content_block_delta" &&
|
|
601
|
-
data.delta.type === "text_delta") {
|
|
602
|
-
const content = data.delta?.text;
|
|
603
|
-
if (content !== undefined) {
|
|
604
|
-
yield new outputs_1.ChatGenerationChunk({
|
|
605
|
-
message: new messages_1.AIMessageChunk({
|
|
606
|
-
content,
|
|
607
|
-
additional_kwargs: {},
|
|
608
|
-
}),
|
|
609
|
-
text: content,
|
|
610
|
-
});
|
|
611
|
-
await runManager?.handleLLMNewToken(content);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
740
|
+
if (!result)
|
|
741
|
+
continue;
|
|
742
|
+
const { chunk, usageData: updatedUsageData } = result;
|
|
743
|
+
usageData = updatedUsageData;
|
|
744
|
+
const newToolCallChunk = extractToolCallChunk(chunk);
|
|
745
|
+
// Maintain concatenatedChunks for accessing the complete `tool_use` content block.
|
|
746
|
+
concatenatedChunks = concatenatedChunks
|
|
747
|
+
? (0, stream_1.concat)(concatenatedChunks, chunk)
|
|
748
|
+
: chunk;
|
|
749
|
+
let toolUseContent;
|
|
750
|
+
const extractedContent = extractToolUseContent(chunk, concatenatedChunks);
|
|
751
|
+
if (extractedContent) {
|
|
752
|
+
toolUseContent = extractedContent.toolUseContent;
|
|
753
|
+
concatenatedChunks = extractedContent.concatenatedChunks;
|
|
614
754
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
};
|
|
755
|
+
// Filter partial `tool_use` content, and only add `tool_use` chunks if complete JSON available.
|
|
756
|
+
const chunkContent = Array.isArray(chunk.content)
|
|
757
|
+
? chunk.content.filter((c) => c.type !== "tool_use")
|
|
758
|
+
: chunk.content;
|
|
759
|
+
if (Array.isArray(chunkContent) && toolUseContent) {
|
|
760
|
+
chunkContent.push(toolUseContent);
|
|
622
761
|
}
|
|
762
|
+
// Extract the text content token for text field and runManager.
|
|
763
|
+
const token = extractToken(chunk);
|
|
623
764
|
yield new outputs_1.ChatGenerationChunk({
|
|
624
765
|
message: new messages_1.AIMessageChunk({
|
|
625
|
-
content:
|
|
626
|
-
additional_kwargs:
|
|
627
|
-
|
|
766
|
+
content: chunkContent,
|
|
767
|
+
additional_kwargs: chunk.additional_kwargs,
|
|
768
|
+
tool_call_chunks: newToolCallChunk ? [newToolCallChunk] : undefined,
|
|
769
|
+
usage_metadata: chunk.usage_metadata,
|
|
770
|
+
response_metadata: chunk.response_metadata,
|
|
628
771
|
}),
|
|
629
|
-
text: "",
|
|
772
|
+
text: token ?? "",
|
|
630
773
|
});
|
|
774
|
+
if (token) {
|
|
775
|
+
await runManager?.handleLLMNewToken(token);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
let usageMetadata;
|
|
779
|
+
if (this.streamUsage || options.streamUsage) {
|
|
780
|
+
usageMetadata = {
|
|
781
|
+
input_tokens: usageData.input_tokens,
|
|
782
|
+
output_tokens: usageData.output_tokens,
|
|
783
|
+
total_tokens: usageData.input_tokens + usageData.output_tokens,
|
|
784
|
+
};
|
|
631
785
|
}
|
|
786
|
+
yield new outputs_1.ChatGenerationChunk({
|
|
787
|
+
message: new messages_1.AIMessageChunk({
|
|
788
|
+
content: coerceContentToString ? "" : [],
|
|
789
|
+
additional_kwargs: { usage: usageData },
|
|
790
|
+
usage_metadata: usageMetadata,
|
|
791
|
+
}),
|
|
792
|
+
text: "",
|
|
793
|
+
});
|
|
632
794
|
}
|
|
633
795
|
/** @ignore */
|
|
634
796
|
async _generateNonStreaming(messages, params, requestOptions) {
|
|
@@ -784,7 +946,10 @@ class ChatAnthropicMessages extends chat_models_1.BaseChatModel {
|
|
|
784
946
|
}
|
|
785
947
|
const llm = this.bind({
|
|
786
948
|
tools,
|
|
787
|
-
tool_choice:
|
|
949
|
+
tool_choice: {
|
|
950
|
+
type: "tool",
|
|
951
|
+
name: functionName,
|
|
952
|
+
},
|
|
788
953
|
});
|
|
789
954
|
if (!includeRaw) {
|
|
790
955
|
return llm.pipe(outputParser).withConfig({
|
package/dist/chat_models.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ChatGeneration, ChatGenerationChunk, type ChatResult } from "@langchain
|
|
|
6
6
|
import { BaseChatModel, LangSmithParams, type BaseChatModelParams } from "@langchain/core/language_models/chat_models";
|
|
7
7
|
import { type StructuredOutputMethodOptions, type BaseLanguageModelCallOptions, type BaseLanguageModelInput, type ToolDefinition } from "@langchain/core/language_models/base";
|
|
8
8
|
import { StructuredToolInterface } from "@langchain/core/tools";
|
|
9
|
-
import { Runnable } from "@langchain/core/runnables";
|
|
9
|
+
import { Runnable, RunnableToolLike } from "@langchain/core/runnables";
|
|
10
10
|
import { ToolCall } from "@langchain/core/messages/tool";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import type { Tool as AnthropicTool } from "@anthropic-ai/sdk/resources/index.mjs";
|
|
@@ -20,7 +20,7 @@ type AnthropicToolChoice = {
|
|
|
20
20
|
name: string;
|
|
21
21
|
} | "any" | "auto";
|
|
22
22
|
export interface ChatAnthropicCallOptions extends BaseLanguageModelCallOptions, Pick<AnthropicInput, "streamUsage"> {
|
|
23
|
-
tools?: (StructuredToolInterface | AnthropicTool | Record<string, unknown> | ToolDefinition)[];
|
|
23
|
+
tools?: (StructuredToolInterface | AnthropicTool | Record<string, unknown> | ToolDefinition | RunnableToolLike)[];
|
|
24
24
|
/**
|
|
25
25
|
* Whether or not to specify what tool the model should use
|
|
26
26
|
* @default "auto"
|
|
@@ -150,7 +150,7 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
|
|
|
150
150
|
* @throws {Error} If a mix of AnthropicTools and StructuredTools are passed.
|
|
151
151
|
*/
|
|
152
152
|
formatStructuredToolToAnthropic(tools: ChatAnthropicCallOptions["tools"]): AnthropicTool[] | undefined;
|
|
153
|
-
bindTools(tools: (AnthropicTool | Record<string, unknown> | StructuredToolInterface | ToolDefinition)[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions>;
|
|
153
|
+
bindTools(tools: (AnthropicTool | Record<string, unknown> | StructuredToolInterface | ToolDefinition | RunnableToolLike)[], kwargs?: Partial<CallOptions>): Runnable<BaseLanguageModelInput, AIMessageChunk, CallOptions>;
|
|
154
154
|
/**
|
|
155
155
|
* Get the parameters used to invoke the model
|
|
156
156
|
*/
|
|
@@ -163,8 +163,8 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
|
|
|
163
163
|
temperature?: number | undefined;
|
|
164
164
|
model: "claude-2.1" | (string & {}) | "claude-3-opus-20240229" | "claude-3-sonnet-20240229" | "claude-3-haiku-20240307" | "claude-2.0" | "claude-instant-1.2";
|
|
165
165
|
system?: string | undefined;
|
|
166
|
-
stream?: boolean | undefined;
|
|
167
166
|
max_tokens: number;
|
|
167
|
+
stream?: boolean | undefined;
|
|
168
168
|
stop_sequences?: string[] | undefined;
|
|
169
169
|
top_k?: number | undefined;
|
|
170
170
|
top_p?: number | undefined;
|
|
@@ -180,8 +180,8 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
|
|
|
180
180
|
temperature?: number | undefined;
|
|
181
181
|
model: "claude-2.1" | (string & {}) | "claude-3-opus-20240229" | "claude-3-sonnet-20240229" | "claude-3-haiku-20240307" | "claude-2.0" | "claude-instant-1.2";
|
|
182
182
|
system?: string | undefined;
|
|
183
|
-
stream?: boolean | undefined;
|
|
184
183
|
max_tokens: number;
|
|
184
|
+
stream?: boolean | undefined;
|
|
185
185
|
stop_sequences?: string[] | undefined;
|
|
186
186
|
top_k?: number | undefined;
|
|
187
187
|
top_p?: number | undefined;
|
|
@@ -194,7 +194,7 @@ export declare class ChatAnthropicMessages<CallOptions extends ChatAnthropicCall
|
|
|
194
194
|
llmOutput: {
|
|
195
195
|
id: string;
|
|
196
196
|
model: string;
|
|
197
|
-
stop_reason: "tool_use" | "
|
|
197
|
+
stop_reason: "tool_use" | "stop_sequence" | "end_turn" | "max_tokens" | null;
|
|
198
198
|
stop_sequence: string | null;
|
|
199
199
|
usage: Anthropic.Messages.Usage;
|
|
200
200
|
};
|
package/dist/chat_models.js
CHANGED
|
@@ -7,7 +7,11 @@ import { isOpenAITool, } from "@langchain/core/language_models/base";
|
|
|
7
7
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
8
8
|
import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
|
|
9
9
|
import { isZodSchema } from "@langchain/core/utils/types";
|
|
10
|
+
import { concat } from "@langchain/core/utils/stream";
|
|
10
11
|
import { AnthropicToolsOutputParser, extractToolCalls, } from "./output_parsers.js";
|
|
12
|
+
function _toolsInParams(params) {
|
|
13
|
+
return !!(params.tools && params.tools.length > 0);
|
|
14
|
+
}
|
|
11
15
|
function _formatImage(imageUrl) {
|
|
12
16
|
const regex = /^data:(image\/.+);base64,(.+)$/;
|
|
13
17
|
const match = imageUrl.match(regex);
|
|
@@ -41,6 +45,7 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
41
45
|
content: messages[0].text,
|
|
42
46
|
additional_kwargs: additionalKwargs,
|
|
43
47
|
usage_metadata: usageMetadata,
|
|
48
|
+
response_metadata: additionalKwargs,
|
|
44
49
|
}),
|
|
45
50
|
},
|
|
46
51
|
];
|
|
@@ -56,6 +61,7 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
56
61
|
additional_kwargs: additionalKwargs,
|
|
57
62
|
tool_calls: toolCalls,
|
|
58
63
|
usage_metadata: usageMetadata,
|
|
64
|
+
response_metadata: additionalKwargs,
|
|
59
65
|
}),
|
|
60
66
|
},
|
|
61
67
|
];
|
|
@@ -66,6 +72,115 @@ function anthropicResponseToChatMessages(messages, additionalKwargs) {
|
|
|
66
72
|
function isAnthropicTool(tool) {
|
|
67
73
|
return "input_schema" in tool;
|
|
68
74
|
}
|
|
75
|
+
function _makeMessageChunkFromAnthropicEvent(data, fields) {
|
|
76
|
+
let usageDataCopy = { ...fields.usageData };
|
|
77
|
+
if (data.type === "message_start") {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
79
|
+
const { content, usage, ...additionalKwargs } = data.message;
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
const filteredAdditionalKwargs = {};
|
|
82
|
+
for (const [key, value] of Object.entries(additionalKwargs)) {
|
|
83
|
+
if (value !== undefined && value !== null) {
|
|
84
|
+
filteredAdditionalKwargs[key] = value;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
usageDataCopy = usage;
|
|
88
|
+
let usageMetadata;
|
|
89
|
+
if (fields.streamUsage) {
|
|
90
|
+
usageMetadata = {
|
|
91
|
+
input_tokens: usage.input_tokens,
|
|
92
|
+
output_tokens: usage.output_tokens,
|
|
93
|
+
total_tokens: usage.input_tokens + usage.output_tokens,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
chunk: new AIMessageChunk({
|
|
98
|
+
content: fields.coerceContentToString ? "" : [],
|
|
99
|
+
additional_kwargs: filteredAdditionalKwargs,
|
|
100
|
+
usage_metadata: usageMetadata,
|
|
101
|
+
}),
|
|
102
|
+
usageData: usageDataCopy,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else if (data.type === "message_delta") {
|
|
106
|
+
let usageMetadata;
|
|
107
|
+
if (fields.streamUsage) {
|
|
108
|
+
usageMetadata = {
|
|
109
|
+
input_tokens: data.usage.output_tokens,
|
|
110
|
+
output_tokens: 0,
|
|
111
|
+
total_tokens: data.usage.output_tokens,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (data?.usage !== undefined) {
|
|
115
|
+
usageDataCopy.output_tokens += data.usage.output_tokens;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
chunk: new AIMessageChunk({
|
|
119
|
+
content: fields.coerceContentToString ? "" : [],
|
|
120
|
+
additional_kwargs: { ...data.delta },
|
|
121
|
+
usage_metadata: usageMetadata,
|
|
122
|
+
}),
|
|
123
|
+
usageData: usageDataCopy,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
else if (data.type === "content_block_start" &&
|
|
127
|
+
data.content_block.type === "tool_use") {
|
|
128
|
+
return {
|
|
129
|
+
chunk: new AIMessageChunk({
|
|
130
|
+
content: fields.coerceContentToString
|
|
131
|
+
? ""
|
|
132
|
+
: [
|
|
133
|
+
{
|
|
134
|
+
index: data.index,
|
|
135
|
+
...data.content_block,
|
|
136
|
+
input: "",
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
additional_kwargs: {},
|
|
140
|
+
}),
|
|
141
|
+
usageData: usageDataCopy,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
else if (data.type === "content_block_delta" &&
|
|
145
|
+
data.delta.type === "text_delta") {
|
|
146
|
+
const content = data.delta?.text;
|
|
147
|
+
if (content !== undefined) {
|
|
148
|
+
return {
|
|
149
|
+
chunk: new AIMessageChunk({
|
|
150
|
+
content: fields.coerceContentToString
|
|
151
|
+
? content
|
|
152
|
+
: [
|
|
153
|
+
{
|
|
154
|
+
index: data.index,
|
|
155
|
+
...data.delta,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
additional_kwargs: {},
|
|
159
|
+
}),
|
|
160
|
+
usageData: usageDataCopy,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (data.type === "content_block_delta" &&
|
|
165
|
+
data.delta.type === "input_json_delta") {
|
|
166
|
+
return {
|
|
167
|
+
chunk: new AIMessageChunk({
|
|
168
|
+
content: fields.coerceContentToString
|
|
169
|
+
? ""
|
|
170
|
+
: [
|
|
171
|
+
{
|
|
172
|
+
index: data.index,
|
|
173
|
+
input: data.delta.partial_json,
|
|
174
|
+
type: data.delta.type,
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
additional_kwargs: {},
|
|
178
|
+
}),
|
|
179
|
+
usageData: usageDataCopy,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
69
184
|
function _mergeMessages(messages) {
|
|
70
185
|
// Merge runs of human/tool messages into single human messages with content blocks.
|
|
71
186
|
const merged = [];
|
|
@@ -239,6 +354,90 @@ function _formatMessagesForAnthropic(messages) {
|
|
|
239
354
|
system,
|
|
240
355
|
};
|
|
241
356
|
}
|
|
357
|
+
function extractToolCallChunk(chunk) {
|
|
358
|
+
let newToolCallChunk;
|
|
359
|
+
// Initial chunk for tool calls from anthropic contains identifying information like ID and name.
|
|
360
|
+
// This chunk does not contain any input JSON.
|
|
361
|
+
const toolUseChunks = Array.isArray(chunk.content)
|
|
362
|
+
? chunk.content.find((c) => c.type === "tool_use")
|
|
363
|
+
: undefined;
|
|
364
|
+
if (toolUseChunks &&
|
|
365
|
+
"index" in toolUseChunks &&
|
|
366
|
+
"name" in toolUseChunks &&
|
|
367
|
+
"id" in toolUseChunks) {
|
|
368
|
+
newToolCallChunk = {
|
|
369
|
+
args: "",
|
|
370
|
+
id: toolUseChunks.id,
|
|
371
|
+
name: toolUseChunks.name,
|
|
372
|
+
index: toolUseChunks.index,
|
|
373
|
+
type: "tool_call_chunk",
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
// Chunks after the initial chunk only contain the index and partial JSON.
|
|
377
|
+
const inputJsonDeltaChunks = Array.isArray(chunk.content)
|
|
378
|
+
? chunk.content.find((c) => c.type === "input_json_delta")
|
|
379
|
+
: undefined;
|
|
380
|
+
if (inputJsonDeltaChunks &&
|
|
381
|
+
"index" in inputJsonDeltaChunks &&
|
|
382
|
+
"input" in inputJsonDeltaChunks) {
|
|
383
|
+
if (typeof inputJsonDeltaChunks.input === "string") {
|
|
384
|
+
newToolCallChunk = {
|
|
385
|
+
args: inputJsonDeltaChunks.input,
|
|
386
|
+
index: inputJsonDeltaChunks.index,
|
|
387
|
+
type: "tool_call_chunk",
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
newToolCallChunk = {
|
|
392
|
+
args: JSON.stringify(inputJsonDeltaChunks.input, null, 2),
|
|
393
|
+
index: inputJsonDeltaChunks.index,
|
|
394
|
+
type: "tool_call_chunk",
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return newToolCallChunk;
|
|
399
|
+
}
|
|
400
|
+
function extractToken(chunk) {
|
|
401
|
+
return typeof chunk.content === "string" && chunk.content !== ""
|
|
402
|
+
? chunk.content
|
|
403
|
+
: undefined;
|
|
404
|
+
}
|
|
405
|
+
function extractToolUseContent(chunk, concatenatedChunks) {
|
|
406
|
+
let newConcatenatedChunks = concatenatedChunks;
|
|
407
|
+
// Remove `tool_use` content types until the last chunk.
|
|
408
|
+
let toolUseContent;
|
|
409
|
+
if (!newConcatenatedChunks) {
|
|
410
|
+
newConcatenatedChunks = chunk;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
newConcatenatedChunks = concat(newConcatenatedChunks, chunk);
|
|
414
|
+
}
|
|
415
|
+
if (Array.isArray(newConcatenatedChunks.content) &&
|
|
416
|
+
newConcatenatedChunks.content.find((c) => c.type === "tool_use")) {
|
|
417
|
+
try {
|
|
418
|
+
const toolUseMsg = newConcatenatedChunks.content.find((c) => c.type === "tool_use");
|
|
419
|
+
if (!toolUseMsg ||
|
|
420
|
+
!("input" in toolUseMsg || "name" in toolUseMsg || "id" in toolUseMsg))
|
|
421
|
+
return;
|
|
422
|
+
const parsedArgs = JSON.parse(toolUseMsg.input);
|
|
423
|
+
if (parsedArgs) {
|
|
424
|
+
toolUseContent = {
|
|
425
|
+
type: "tool_use",
|
|
426
|
+
id: toolUseMsg.id,
|
|
427
|
+
name: toolUseMsg.name,
|
|
428
|
+
input: parsedArgs,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch (_) {
|
|
433
|
+
// no-op
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return {
|
|
437
|
+
toolUseContent,
|
|
438
|
+
concatenatedChunks: newConcatenatedChunks,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
242
441
|
/**
|
|
243
442
|
* Wrapper around Anthropic large language models.
|
|
244
443
|
*
|
|
@@ -512,119 +711,82 @@ export class ChatAnthropicMessages extends BaseChatModel {
|
|
|
512
711
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
513
712
|
const params = this.invocationParams(options);
|
|
514
713
|
const formattedMessages = _formatMessagesForAnthropic(messages);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
const stream = await this.createStreamWithRetry({
|
|
537
|
-
...params,
|
|
538
|
-
...formattedMessages,
|
|
539
|
-
stream: true,
|
|
714
|
+
const coerceContentToString = !_toolsInParams({
|
|
715
|
+
...params,
|
|
716
|
+
...formattedMessages,
|
|
717
|
+
stream: false,
|
|
718
|
+
});
|
|
719
|
+
const stream = await this.createStreamWithRetry({
|
|
720
|
+
...params,
|
|
721
|
+
...formattedMessages,
|
|
722
|
+
stream: true,
|
|
723
|
+
});
|
|
724
|
+
let usageData = { input_tokens: 0, output_tokens: 0 };
|
|
725
|
+
let concatenatedChunks;
|
|
726
|
+
for await (const data of stream) {
|
|
727
|
+
if (options.signal?.aborted) {
|
|
728
|
+
stream.controller.abort();
|
|
729
|
+
throw new Error("AbortError: User aborted the request.");
|
|
730
|
+
}
|
|
731
|
+
const result = _makeMessageChunkFromAnthropicEvent(data, {
|
|
732
|
+
streamUsage: !!(this.streamUsage || options.streamUsage),
|
|
733
|
+
coerceContentToString,
|
|
734
|
+
usageData,
|
|
540
735
|
});
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
usageData = usage;
|
|
558
|
-
let usageMetadata;
|
|
559
|
-
if (this.streamUsage || options.streamUsage) {
|
|
560
|
-
usageMetadata = {
|
|
561
|
-
input_tokens: usage.input_tokens,
|
|
562
|
-
output_tokens: usage.output_tokens,
|
|
563
|
-
total_tokens: usage.input_tokens + usage.output_tokens,
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
yield new ChatGenerationChunk({
|
|
567
|
-
message: new AIMessageChunk({
|
|
568
|
-
content: "",
|
|
569
|
-
additional_kwargs: filteredAdditionalKwargs,
|
|
570
|
-
usage_metadata: usageMetadata,
|
|
571
|
-
}),
|
|
572
|
-
text: "",
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
else if (data.type === "message_delta") {
|
|
576
|
-
let usageMetadata;
|
|
577
|
-
if (this.streamUsage || options.streamUsage) {
|
|
578
|
-
usageMetadata = {
|
|
579
|
-
input_tokens: data.usage.output_tokens,
|
|
580
|
-
output_tokens: 0,
|
|
581
|
-
total_tokens: data.usage.output_tokens,
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
yield new ChatGenerationChunk({
|
|
585
|
-
message: new AIMessageChunk({
|
|
586
|
-
content: "",
|
|
587
|
-
additional_kwargs: { ...data.delta },
|
|
588
|
-
usage_metadata: usageMetadata,
|
|
589
|
-
}),
|
|
590
|
-
text: "",
|
|
591
|
-
});
|
|
592
|
-
if (data?.usage !== undefined) {
|
|
593
|
-
usageData.output_tokens += data.usage.output_tokens;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
else if (data.type === "content_block_delta" &&
|
|
597
|
-
data.delta.type === "text_delta") {
|
|
598
|
-
const content = data.delta?.text;
|
|
599
|
-
if (content !== undefined) {
|
|
600
|
-
yield new ChatGenerationChunk({
|
|
601
|
-
message: new AIMessageChunk({
|
|
602
|
-
content,
|
|
603
|
-
additional_kwargs: {},
|
|
604
|
-
}),
|
|
605
|
-
text: content,
|
|
606
|
-
});
|
|
607
|
-
await runManager?.handleLLMNewToken(content);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
736
|
+
if (!result)
|
|
737
|
+
continue;
|
|
738
|
+
const { chunk, usageData: updatedUsageData } = result;
|
|
739
|
+
usageData = updatedUsageData;
|
|
740
|
+
const newToolCallChunk = extractToolCallChunk(chunk);
|
|
741
|
+
// Maintain concatenatedChunks for accessing the complete `tool_use` content block.
|
|
742
|
+
concatenatedChunks = concatenatedChunks
|
|
743
|
+
? concat(concatenatedChunks, chunk)
|
|
744
|
+
: chunk;
|
|
745
|
+
let toolUseContent;
|
|
746
|
+
const extractedContent = extractToolUseContent(chunk, concatenatedChunks);
|
|
747
|
+
if (extractedContent) {
|
|
748
|
+
toolUseContent = extractedContent.toolUseContent;
|
|
749
|
+
concatenatedChunks = extractedContent.concatenatedChunks;
|
|
610
750
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
};
|
|
751
|
+
// Filter partial `tool_use` content, and only add `tool_use` chunks if complete JSON available.
|
|
752
|
+
const chunkContent = Array.isArray(chunk.content)
|
|
753
|
+
? chunk.content.filter((c) => c.type !== "tool_use")
|
|
754
|
+
: chunk.content;
|
|
755
|
+
if (Array.isArray(chunkContent) && toolUseContent) {
|
|
756
|
+
chunkContent.push(toolUseContent);
|
|
618
757
|
}
|
|
758
|
+
// Extract the text content token for text field and runManager.
|
|
759
|
+
const token = extractToken(chunk);
|
|
619
760
|
yield new ChatGenerationChunk({
|
|
620
761
|
message: new AIMessageChunk({
|
|
621
|
-
content:
|
|
622
|
-
additional_kwargs:
|
|
623
|
-
|
|
762
|
+
content: chunkContent,
|
|
763
|
+
additional_kwargs: chunk.additional_kwargs,
|
|
764
|
+
tool_call_chunks: newToolCallChunk ? [newToolCallChunk] : undefined,
|
|
765
|
+
usage_metadata: chunk.usage_metadata,
|
|
766
|
+
response_metadata: chunk.response_metadata,
|
|
624
767
|
}),
|
|
625
|
-
text: "",
|
|
768
|
+
text: token ?? "",
|
|
626
769
|
});
|
|
770
|
+
if (token) {
|
|
771
|
+
await runManager?.handleLLMNewToken(token);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
let usageMetadata;
|
|
775
|
+
if (this.streamUsage || options.streamUsage) {
|
|
776
|
+
usageMetadata = {
|
|
777
|
+
input_tokens: usageData.input_tokens,
|
|
778
|
+
output_tokens: usageData.output_tokens,
|
|
779
|
+
total_tokens: usageData.input_tokens + usageData.output_tokens,
|
|
780
|
+
};
|
|
627
781
|
}
|
|
782
|
+
yield new ChatGenerationChunk({
|
|
783
|
+
message: new AIMessageChunk({
|
|
784
|
+
content: coerceContentToString ? "" : [],
|
|
785
|
+
additional_kwargs: { usage: usageData },
|
|
786
|
+
usage_metadata: usageMetadata,
|
|
787
|
+
}),
|
|
788
|
+
text: "",
|
|
789
|
+
});
|
|
628
790
|
}
|
|
629
791
|
/** @ignore */
|
|
630
792
|
async _generateNonStreaming(messages, params, requestOptions) {
|
|
@@ -780,7 +942,10 @@ export class ChatAnthropicMessages extends BaseChatModel {
|
|
|
780
942
|
}
|
|
781
943
|
const llm = this.bind({
|
|
782
944
|
tools,
|
|
783
|
-
tool_choice:
|
|
945
|
+
tool_choice: {
|
|
946
|
+
type: "tool",
|
|
947
|
+
name: functionName,
|
|
948
|
+
},
|
|
784
949
|
});
|
|
785
950
|
if (!includeRaw) {
|
|
786
951
|
return llm.pipe(outputParser).withConfig({
|
package/dist/output_parsers.cjs
CHANGED
|
@@ -79,7 +79,12 @@ function extractToolCalls(content) {
|
|
|
79
79
|
const toolCalls = [];
|
|
80
80
|
for (const block of content) {
|
|
81
81
|
if (block.type === "tool_use") {
|
|
82
|
-
toolCalls.push({
|
|
82
|
+
toolCalls.push({
|
|
83
|
+
name: block.name,
|
|
84
|
+
args: block.input,
|
|
85
|
+
id: block.id,
|
|
86
|
+
type: "tool_call",
|
|
87
|
+
});
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
return toolCalls;
|
package/dist/output_parsers.js
CHANGED
|
@@ -75,7 +75,12 @@ export function extractToolCalls(content) {
|
|
|
75
75
|
const toolCalls = [];
|
|
76
76
|
for (const block of content) {
|
|
77
77
|
if (block.type === "tool_use") {
|
|
78
|
-
toolCalls.push({
|
|
78
|
+
toolCalls.push({
|
|
79
|
+
name: block.name,
|
|
80
|
+
args: block.input,
|
|
81
|
+
id: block.id,
|
|
82
|
+
type: "tool_call",
|
|
83
|
+
});
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
return toolCalls;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langchain/anthropic",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Anthropic integrations for LangChain.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@anthropic-ai/sdk": "^0.22.0",
|
|
39
|
-
"@langchain/core": ">=0.2.
|
|
39
|
+
"@langchain/core": ">=0.2.16 <0.3.0",
|
|
40
40
|
"fast-xml-parser": "^4.3.5",
|
|
41
41
|
"zod": "^3.22.4",
|
|
42
42
|
"zod-to-json-schema": "^3.22.4"
|