@librechat/agents 3.2.63 → 3.2.65
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/cjs/graphs/Graph.cjs +3 -0
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +73 -9
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +41 -9
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +3 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/stream_events.cjs +337 -0
- package/dist/cjs/llm/anthropic/utils/stream_events.cjs.map +1 -0
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +82 -34
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/tools/search/crw-scraper.cjs +165 -0
- package/dist/cjs/tools/search/crw-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/crw-search.cjs +105 -0
- package/dist/cjs/tools/search/crw-search.cjs.map +1 -0
- package/dist/cjs/tools/search/search.cjs +4 -2
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +15 -3
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +3 -0
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +73 -9
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/types.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +41 -9
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +3 -2
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/stream_events.mjs +337 -0
- package/dist/esm/llm/anthropic/utils/stream_events.mjs.map +1 -0
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +82 -34
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/tools/search/crw-scraper.mjs +163 -0
- package/dist/esm/tools/search/crw-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/crw-search.mjs +103 -0
- package/dist/esm/tools/search/crw-search.mjs.map +1 -0
- package/dist/esm/tools/search/search.mjs +4 -2
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +15 -3
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/types/llm/anthropic/index.d.ts +2 -0
- package/dist/types/llm/anthropic/types.d.ts +2 -0
- package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -2
- package/dist/types/llm/anthropic/utils/stream_events.d.ts +25 -0
- package/dist/types/tools/search/crw-scraper.d.ts +41 -0
- package/dist/types/tools/search/crw-search.d.ts +4 -0
- package/dist/types/tools/search/types.d.ts +88 -3
- package/package.json +1 -1
- package/src/graphs/Graph.ts +15 -0
- package/src/llm/anthropic/index.ts +134 -10
- package/src/llm/anthropic/inherited-content-utils.spec.ts +10 -5
- package/src/llm/anthropic/inherited-stream-events.spec.ts +513 -9
- package/src/llm/anthropic/llm.spec.ts +100 -16
- package/src/llm/anthropic/types.ts +3 -0
- package/src/llm/anthropic/utils/message_inputs.ts +60 -3
- package/src/llm/anthropic/utils/message_outputs.ts +10 -2
- package/src/llm/anthropic/utils/stream_events.ts +471 -0
- package/src/llm/bedrock/utils/message_inputs.test.ts +276 -1
- package/src/llm/bedrock/utils/message_inputs.ts +121 -73
- package/src/tools/search/crw-scraper.ts +244 -0
- package/src/tools/search/crw-search.ts +167 -0
- package/src/tools/search/crw.test.ts +836 -0
- package/src/tools/search/search.ts +7 -1
- package/src/tools/search/tool.ts +23 -3
- package/src/tools/search/types.ts +103 -3
|
@@ -961,7 +961,7 @@ class RecordingStreamingAnthropic extends ChatAnthropic {
|
|
|
961
961
|
}
|
|
962
962
|
}
|
|
963
963
|
|
|
964
|
-
test('Anthropic message_delta usage
|
|
964
|
+
test('Anthropic message_delta usage preserves cumulative input totals', () => {
|
|
965
965
|
const event: AnthropicStreamEvent = {
|
|
966
966
|
type: 'message_delta',
|
|
967
967
|
context_management: null,
|
|
@@ -978,6 +978,7 @@ test('Anthropic message_delta usage emits only output token totals', () => {
|
|
|
978
978
|
cache_read_input_tokens: 13,
|
|
979
979
|
server_tool_use: null,
|
|
980
980
|
iterations: null,
|
|
981
|
+
output_tokens_details: null,
|
|
981
982
|
},
|
|
982
983
|
};
|
|
983
984
|
|
|
@@ -987,9 +988,13 @@ test('Anthropic message_delta usage emits only output token totals', () => {
|
|
|
987
988
|
});
|
|
988
989
|
|
|
989
990
|
expect(result?.chunk.usage_metadata).toEqual({
|
|
990
|
-
input_tokens:
|
|
991
|
+
input_tokens: 267,
|
|
991
992
|
output_tokens: 375,
|
|
992
|
-
total_tokens:
|
|
993
|
+
total_tokens: 642,
|
|
994
|
+
input_token_details: {
|
|
995
|
+
cache_creation: 11,
|
|
996
|
+
cache_read: 13,
|
|
997
|
+
},
|
|
993
998
|
});
|
|
994
999
|
});
|
|
995
1000
|
|
|
@@ -1002,6 +1007,7 @@ test('Anthropic stream usage does not double-count cumulative input tokens', asy
|
|
|
1002
1007
|
container: null,
|
|
1003
1008
|
context_management: null,
|
|
1004
1009
|
content: [],
|
|
1010
|
+
diagnostics: null,
|
|
1005
1011
|
model: modelName,
|
|
1006
1012
|
role: 'assistant',
|
|
1007
1013
|
stop_details: null,
|
|
@@ -1010,15 +1016,16 @@ test('Anthropic stream usage does not double-count cumulative input tokens', asy
|
|
|
1010
1016
|
type: 'message',
|
|
1011
1017
|
usage: {
|
|
1012
1018
|
cache_creation: null,
|
|
1013
|
-
cache_creation_input_tokens:
|
|
1014
|
-
cache_read_input_tokens:
|
|
1019
|
+
cache_creation_input_tokens: 20,
|
|
1020
|
+
cache_read_input_tokens: 30,
|
|
1015
1021
|
inference_geo: null,
|
|
1016
1022
|
input_tokens: 243,
|
|
1017
1023
|
iterations: null,
|
|
1018
|
-
output_tokens:
|
|
1024
|
+
output_tokens: 7,
|
|
1019
1025
|
server_tool_use: null,
|
|
1020
1026
|
service_tier: null,
|
|
1021
1027
|
speed: null,
|
|
1028
|
+
output_tokens_details: null,
|
|
1022
1029
|
},
|
|
1023
1030
|
},
|
|
1024
1031
|
},
|
|
@@ -1034,10 +1041,11 @@ test('Anthropic stream usage does not double-count cumulative input tokens', asy
|
|
|
1034
1041
|
usage: {
|
|
1035
1042
|
input_tokens: 243,
|
|
1036
1043
|
output_tokens: 375,
|
|
1037
|
-
cache_creation_input_tokens:
|
|
1038
|
-
cache_read_input_tokens:
|
|
1044
|
+
cache_creation_input_tokens: 20,
|
|
1045
|
+
cache_read_input_tokens: 30,
|
|
1039
1046
|
server_tool_use: null,
|
|
1040
1047
|
iterations: null,
|
|
1048
|
+
output_tokens_details: null,
|
|
1041
1049
|
},
|
|
1042
1050
|
},
|
|
1043
1051
|
{ type: 'message_stop' },
|
|
@@ -1050,12 +1058,83 @@ test('Anthropic stream usage does not double-count cumulative input tokens', asy
|
|
|
1050
1058
|
}
|
|
1051
1059
|
|
|
1052
1060
|
expect(full?.usage_metadata).toEqual({
|
|
1053
|
-
input_tokens:
|
|
1061
|
+
input_tokens: 293,
|
|
1054
1062
|
output_tokens: 375,
|
|
1055
|
-
total_tokens:
|
|
1063
|
+
total_tokens: 668,
|
|
1056
1064
|
input_token_details: {
|
|
1057
|
-
cache_creation:
|
|
1058
|
-
cache_read:
|
|
1065
|
+
cache_creation: 20,
|
|
1066
|
+
cache_read: 30,
|
|
1067
|
+
},
|
|
1068
|
+
output_token_details: {},
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
test('Anthropic stream usage accepts input first reported at message_delta', async () => {
|
|
1073
|
+
const events: AnthropicStreamEvent[] = [
|
|
1074
|
+
{
|
|
1075
|
+
type: 'message_start',
|
|
1076
|
+
message: {
|
|
1077
|
+
id: 'msg_late_input_usage',
|
|
1078
|
+
container: null,
|
|
1079
|
+
context_management: null,
|
|
1080
|
+
content: [],
|
|
1081
|
+
diagnostics: null,
|
|
1082
|
+
model: modelName,
|
|
1083
|
+
role: 'assistant',
|
|
1084
|
+
stop_details: null,
|
|
1085
|
+
stop_reason: null,
|
|
1086
|
+
stop_sequence: null,
|
|
1087
|
+
type: 'message',
|
|
1088
|
+
usage: {
|
|
1089
|
+
cache_creation: null,
|
|
1090
|
+
cache_creation_input_tokens: 0,
|
|
1091
|
+
cache_read_input_tokens: 0,
|
|
1092
|
+
inference_geo: null,
|
|
1093
|
+
input_tokens: 0,
|
|
1094
|
+
iterations: null,
|
|
1095
|
+
output_tokens: 0,
|
|
1096
|
+
server_tool_use: null,
|
|
1097
|
+
service_tier: null,
|
|
1098
|
+
speed: null,
|
|
1099
|
+
output_tokens_details: null,
|
|
1100
|
+
},
|
|
1101
|
+
},
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
type: 'message_delta',
|
|
1105
|
+
context_management: null,
|
|
1106
|
+
delta: {
|
|
1107
|
+
container: null,
|
|
1108
|
+
stop_details: null,
|
|
1109
|
+
stop_reason: 'end_turn',
|
|
1110
|
+
stop_sequence: null,
|
|
1111
|
+
},
|
|
1112
|
+
usage: {
|
|
1113
|
+
input_tokens: 100,
|
|
1114
|
+
output_tokens: 42,
|
|
1115
|
+
cache_creation_input_tokens: 500,
|
|
1116
|
+
cache_read_input_tokens: 200,
|
|
1117
|
+
server_tool_use: null,
|
|
1118
|
+
iterations: null,
|
|
1119
|
+
output_tokens_details: null,
|
|
1120
|
+
},
|
|
1121
|
+
},
|
|
1122
|
+
{ type: 'message_stop' },
|
|
1123
|
+
];
|
|
1124
|
+
const model = new MockStreamingAnthropic(events);
|
|
1125
|
+
|
|
1126
|
+
let full: AIMessageChunk | undefined;
|
|
1127
|
+
for await (const chunk of await model.stream('hello')) {
|
|
1128
|
+
full = !full ? chunk : concat(full, chunk);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
expect(full?.usage_metadata).toEqual({
|
|
1132
|
+
input_tokens: 800,
|
|
1133
|
+
output_tokens: 42,
|
|
1134
|
+
total_tokens: 842,
|
|
1135
|
+
input_token_details: {
|
|
1136
|
+
cache_creation: 500,
|
|
1137
|
+
cache_read: 200,
|
|
1059
1138
|
},
|
|
1060
1139
|
output_token_details: {},
|
|
1061
1140
|
});
|
|
@@ -1070,6 +1149,7 @@ test('Anthropic stream usage handles multiple cumulative message_delta events',
|
|
|
1070
1149
|
container: null,
|
|
1071
1150
|
context_management: null,
|
|
1072
1151
|
content: [],
|
|
1152
|
+
diagnostics: null,
|
|
1073
1153
|
model: modelName,
|
|
1074
1154
|
role: 'assistant',
|
|
1075
1155
|
stop_details: null,
|
|
@@ -1083,10 +1163,11 @@ test('Anthropic stream usage handles multiple cumulative message_delta events',
|
|
|
1083
1163
|
inference_geo: null,
|
|
1084
1164
|
input_tokens: 243,
|
|
1085
1165
|
iterations: null,
|
|
1086
|
-
output_tokens:
|
|
1166
|
+
output_tokens: 7,
|
|
1087
1167
|
server_tool_use: null,
|
|
1088
1168
|
service_tier: null,
|
|
1089
1169
|
speed: null,
|
|
1170
|
+
output_tokens_details: null,
|
|
1090
1171
|
},
|
|
1091
1172
|
},
|
|
1092
1173
|
},
|
|
@@ -1106,6 +1187,7 @@ test('Anthropic stream usage handles multiple cumulative message_delta events',
|
|
|
1106
1187
|
cache_read_input_tokens: 0,
|
|
1107
1188
|
server_tool_use: null,
|
|
1108
1189
|
iterations: null,
|
|
1190
|
+
output_tokens_details: null,
|
|
1109
1191
|
},
|
|
1110
1192
|
},
|
|
1111
1193
|
{
|
|
@@ -1124,6 +1206,7 @@ test('Anthropic stream usage handles multiple cumulative message_delta events',
|
|
|
1124
1206
|
cache_read_input_tokens: 0,
|
|
1125
1207
|
server_tool_use: null,
|
|
1126
1208
|
iterations: null,
|
|
1209
|
+
output_tokens_details: null,
|
|
1127
1210
|
},
|
|
1128
1211
|
},
|
|
1129
1212
|
{ type: 'message_stop' },
|
|
@@ -1230,9 +1313,10 @@ test('Anthropic live stream usage matches raw cumulative output snapshots', asyn
|
|
|
1230
1313
|
expect(model.messageDeltaOutputTokens.length).toBeGreaterThan(0);
|
|
1231
1314
|
const rawOutputTokens =
|
|
1232
1315
|
model.messageDeltaOutputTokens[model.messageDeltaOutputTokens.length - 1];
|
|
1233
|
-
expect(
|
|
1234
|
-
model.messageStartOutputTokens
|
|
1316
|
+
expect(rawOutputTokens).toBeGreaterThanOrEqual(
|
|
1317
|
+
model.messageStartOutputTokens
|
|
1235
1318
|
);
|
|
1319
|
+
expect(full?.usage_metadata?.output_tokens).toBe(rawOutputTokens);
|
|
1236
1320
|
expect(full?.usage_metadata?.total_tokens).toBe(
|
|
1237
1321
|
(full?.usage_metadata?.input_tokens ?? 0) +
|
|
1238
1322
|
(full?.usage_metadata?.output_tokens ?? 0)
|
|
@@ -1244,7 +1328,7 @@ test('Anthropic live stream usage matches raw cumulative output snapshots', asyn
|
|
|
1244
1328
|
0
|
|
1245
1329
|
);
|
|
1246
1330
|
expect(full?.usage_metadata?.output_tokens).toBeLessThan(
|
|
1247
|
-
|
|
1331
|
+
summedOutputTokens
|
|
1248
1332
|
);
|
|
1249
1333
|
}
|
|
1250
1334
|
});
|
|
@@ -61,6 +61,9 @@ export type AnthropicSearchResultBlockParam =
|
|
|
61
61
|
Anthropic.Beta.BetaSearchResultBlockParam;
|
|
62
62
|
export type AnthropicCompactionBlockParam =
|
|
63
63
|
Anthropic.Beta.BetaCompactionBlockParam;
|
|
64
|
+
export type AnthropicCompactionBlock = Anthropic.Beta.BetaCompactionBlock;
|
|
65
|
+
export type AnthropicCompactionContentBlockDelta =
|
|
66
|
+
Anthropic.Beta.BetaCompactionContentBlockDelta;
|
|
64
67
|
export type AnthropicOutputConfig = Anthropic.Messages.OutputConfig;
|
|
65
68
|
export type ChatAnthropicOutputFormat = Anthropic.Messages.JSONOutputFormat;
|
|
66
69
|
|
|
@@ -482,8 +482,8 @@ function _formatContent(message: BaseMessage) {
|
|
|
482
482
|
const contentBlocks = contentParts.map((contentPart) => {
|
|
483
483
|
/**
|
|
484
484
|
* Normalize server_tool_use blocks into a clean shape the API accepts.
|
|
485
|
-
* These blocks may arrive with the correct type (server_tool_use)
|
|
486
|
-
*
|
|
485
|
+
* These blocks may arrive with the correct type (server_tool_use), as a
|
|
486
|
+
* standardized server_tool_call, or mislabeled after state serialization.
|
|
487
487
|
* Regardless of current type, if the id starts with 'srvtoolu_' we rebuild
|
|
488
488
|
* a clean block with only the properties the API expects.
|
|
489
489
|
*/
|
|
@@ -496,7 +496,7 @@ function _formatContent(message: BaseMessage) {
|
|
|
496
496
|
'name' in contentPart
|
|
497
497
|
) {
|
|
498
498
|
const rawPart = contentPart as Record<string, unknown>;
|
|
499
|
-
let input = rawPart.input;
|
|
499
|
+
let input = rawPart.input ?? rawPart.args;
|
|
500
500
|
if (typeof input === 'string') {
|
|
501
501
|
try {
|
|
502
502
|
input = JSON.parse(input);
|
|
@@ -549,6 +549,60 @@ function _formatContent(message: BaseMessage) {
|
|
|
549
549
|
return null;
|
|
550
550
|
}
|
|
551
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Native ChatModelStream output standardizes client tool uses as
|
|
554
|
+
* `tool_call` blocks. Convert those blocks back to Anthropic's wire shape
|
|
555
|
+
* before the generic content formatter sees them.
|
|
556
|
+
*/
|
|
557
|
+
if (
|
|
558
|
+
contentPart.type === 'tool_call' &&
|
|
559
|
+
'id' in contentPart &&
|
|
560
|
+
typeof contentPart.id === 'string' &&
|
|
561
|
+
'name' in contentPart &&
|
|
562
|
+
typeof contentPart.name === 'string' &&
|
|
563
|
+
'args' in contentPart
|
|
564
|
+
) {
|
|
565
|
+
let args = contentPart.args;
|
|
566
|
+
if (typeof args === 'string') {
|
|
567
|
+
try {
|
|
568
|
+
args = JSON.parse(args);
|
|
569
|
+
} catch {
|
|
570
|
+
args = {};
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
if (args == null || typeof args !== 'object' || Array.isArray(args)) {
|
|
574
|
+
args = {};
|
|
575
|
+
}
|
|
576
|
+
return _convertLangChainToolCallToAnthropic({
|
|
577
|
+
id: contentPart.id,
|
|
578
|
+
name: contentPart.name,
|
|
579
|
+
args: args as Record<string, unknown>,
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Native Anthropic thinking is exposed through the standard reasoning
|
|
585
|
+
* stream, but its signature makes it safe and necessary to round-trip.
|
|
586
|
+
* Keep unsigned or cross-provider reasoning on the existing drop path.
|
|
587
|
+
*/
|
|
588
|
+
if (
|
|
589
|
+
contentPart.type === 'reasoning' &&
|
|
590
|
+
isAIMessage(message) &&
|
|
591
|
+
message.response_metadata.model_provider === 'anthropic' &&
|
|
592
|
+
'reasoning' in contentPart &&
|
|
593
|
+
typeof contentPart.reasoning === 'string' &&
|
|
594
|
+
'signature' in contentPart &&
|
|
595
|
+
typeof contentPart.signature === 'string' &&
|
|
596
|
+
contentPart.signature !== ''
|
|
597
|
+
) {
|
|
598
|
+
const block: AnthropicThinkingBlockParam = {
|
|
599
|
+
type: 'thinking',
|
|
600
|
+
thinking: contentPart.reasoning,
|
|
601
|
+
signature: contentPart.signature,
|
|
602
|
+
};
|
|
603
|
+
return block;
|
|
604
|
+
}
|
|
605
|
+
|
|
552
606
|
/**
|
|
553
607
|
* Skip non-server malformed blocks that have tool fields mixed with text type.
|
|
554
608
|
*/
|
|
@@ -665,6 +719,9 @@ function _formatContent(message: BaseMessage) {
|
|
|
665
719
|
const block: AnthropicCompactionBlockParam = {
|
|
666
720
|
type: 'compaction' as const,
|
|
667
721
|
content: compactionPart.content,
|
|
722
|
+
...('encrypted_content' in compactionPart
|
|
723
|
+
? { encrypted_content: compactionPart.encrypted_content }
|
|
724
|
+
: {}),
|
|
668
725
|
...(cacheControl != null ? { cache_control: cacheControl } : {}),
|
|
669
726
|
};
|
|
670
727
|
return block;
|
|
@@ -9,7 +9,7 @@ import type { MessageContentComplex } from '@/types';
|
|
|
9
9
|
import { toLangChainContent } from '@/messages/langchain';
|
|
10
10
|
import { extractToolCalls } from './output_parsers';
|
|
11
11
|
|
|
12
|
-
interface AnthropicUsageData {
|
|
12
|
+
export interface AnthropicUsageData {
|
|
13
13
|
input_tokens?: number | null;
|
|
14
14
|
output_tokens?: number | null;
|
|
15
15
|
cache_creation_input_tokens?: number | null;
|
|
@@ -92,7 +92,15 @@ export function _makeMessageChunkFromAnthropicEvent(
|
|
|
92
92
|
context_management: data.delta.context_management,
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
const
|
|
95
|
+
const deltaUsage: AnthropicUsageData = data.usage;
|
|
96
|
+
const hasInputUsage =
|
|
97
|
+
deltaUsage.input_tokens != null ||
|
|
98
|
+
deltaUsage.cache_creation_input_tokens != null ||
|
|
99
|
+
deltaUsage.cache_read_input_tokens != null;
|
|
100
|
+
const cumulativeUsageMetadata = hasInputUsage
|
|
101
|
+
? getAnthropicUsageMetadata(deltaUsage)
|
|
102
|
+
: undefined;
|
|
103
|
+
const usageMetadata: UsageMetadata = cumulativeUsageMetadata ?? {
|
|
96
104
|
input_tokens: 0,
|
|
97
105
|
output_tokens: data.usage.output_tokens,
|
|
98
106
|
total_tokens: data.usage.output_tokens,
|