@librechat/agents 3.2.64 → 3.2.66

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 (106) hide show
  1. package/dist/cjs/graphs/Graph.cjs +18 -2
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/instrumentation.cjs +15 -3
  4. package/dist/cjs/instrumentation.cjs.map +1 -1
  5. package/dist/cjs/langfuseToolOutputTracing.cjs +1 -2
  6. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  7. package/dist/cjs/langfuseTraceShaping.cjs +51 -24
  8. package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
  9. package/dist/cjs/llm/anthropic/index.cjs +73 -9
  10. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  11. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  12. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +49 -9
  13. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  14. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +3 -1
  15. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  16. package/dist/cjs/llm/anthropic/utils/stream_events.cjs +337 -0
  17. package/dist/cjs/llm/anthropic/utils/stream_events.cjs.map +1 -0
  18. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +8 -0
  19. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/tools/BashExecutor.cjs +9 -8
  21. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  22. package/dist/cjs/tools/CodeExecutor.cjs +9 -7
  23. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  24. package/dist/cjs/tools/search/crw-scraper.cjs +165 -0
  25. package/dist/cjs/tools/search/crw-scraper.cjs.map +1 -0
  26. package/dist/cjs/tools/search/crw-search.cjs +105 -0
  27. package/dist/cjs/tools/search/crw-search.cjs.map +1 -0
  28. package/dist/cjs/tools/search/search.cjs +4 -2
  29. package/dist/cjs/tools/search/search.cjs.map +1 -1
  30. package/dist/cjs/tools/search/tool.cjs +15 -3
  31. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  32. package/dist/esm/graphs/Graph.mjs +18 -2
  33. package/dist/esm/graphs/Graph.mjs.map +1 -1
  34. package/dist/esm/instrumentation.mjs +15 -3
  35. package/dist/esm/instrumentation.mjs.map +1 -1
  36. package/dist/esm/langfuseToolOutputTracing.mjs +1 -2
  37. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  38. package/dist/esm/langfuseTraceShaping.mjs +51 -24
  39. package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
  40. package/dist/esm/llm/anthropic/index.mjs +73 -9
  41. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  42. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  43. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +49 -9
  44. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  45. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +3 -2
  46. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  47. package/dist/esm/llm/anthropic/utils/stream_events.mjs +337 -0
  48. package/dist/esm/llm/anthropic/utils/stream_events.mjs.map +1 -0
  49. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +8 -0
  50. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  51. package/dist/esm/tools/BashExecutor.mjs +9 -8
  52. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  53. package/dist/esm/tools/CodeExecutor.mjs +9 -7
  54. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  55. package/dist/esm/tools/search/crw-scraper.mjs +163 -0
  56. package/dist/esm/tools/search/crw-scraper.mjs.map +1 -0
  57. package/dist/esm/tools/search/crw-search.mjs +103 -0
  58. package/dist/esm/tools/search/crw-search.mjs.map +1 -0
  59. package/dist/esm/tools/search/search.mjs +4 -2
  60. package/dist/esm/tools/search/search.mjs.map +1 -1
  61. package/dist/esm/tools/search/tool.mjs +15 -3
  62. package/dist/esm/tools/search/tool.mjs.map +1 -1
  63. package/dist/types/graphs/Graph.d.ts +2 -0
  64. package/dist/types/langfuseTraceShaping.d.ts +12 -6
  65. package/dist/types/llm/anthropic/index.d.ts +2 -0
  66. package/dist/types/llm/anthropic/types.d.ts +2 -0
  67. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -2
  68. package/dist/types/llm/anthropic/utils/stream_events.d.ts +25 -0
  69. package/dist/types/tools/BashExecutor.d.ts +7 -6
  70. package/dist/types/tools/CodeExecutor.d.ts +7 -5
  71. package/dist/types/tools/search/crw-scraper.d.ts +41 -0
  72. package/dist/types/tools/search/crw-search.d.ts +4 -0
  73. package/dist/types/tools/search/types.d.ts +88 -3
  74. package/dist/types/types/graph.d.ts +10 -3
  75. package/package.json +1 -1
  76. package/src/graphs/Graph.ts +36 -3
  77. package/src/instrumentation.ts +20 -0
  78. package/src/langfuseToolOutputTracing.ts +2 -4
  79. package/src/langfuseTraceShaping.ts +73 -20
  80. package/src/llm/anthropic/index.ts +134 -10
  81. package/src/llm/anthropic/inherited-content-utils.spec.ts +10 -5
  82. package/src/llm/anthropic/inherited-stream-events.spec.ts +513 -9
  83. package/src/llm/anthropic/llm.spec.ts +100 -16
  84. package/src/llm/anthropic/types.ts +3 -0
  85. package/src/llm/anthropic/utils/cross-provider-server-tools.test.ts +110 -0
  86. package/src/llm/anthropic/utils/message_inputs.ts +75 -3
  87. package/src/llm/anthropic/utils/message_outputs.ts +10 -2
  88. package/src/llm/anthropic/utils/stream_events.ts +471 -0
  89. package/src/llm/bedrock/utils/cross-provider-server-tools.test.ts +122 -0
  90. package/src/llm/bedrock/utils/message_inputs.ts +13 -0
  91. package/src/specs/langfuse-instrumentation.test.ts +64 -0
  92. package/src/specs/langfuse-routing.integration.test.ts +49 -4
  93. package/src/specs/langfuse-tool-output-tracing.test.ts +5 -4
  94. package/src/specs/langfuse-trace-shaping.test.ts +80 -9
  95. package/src/specs/subagent.test.ts +180 -0
  96. package/src/tools/BashExecutor.ts +9 -8
  97. package/src/tools/CodeExecutor.ts +9 -7
  98. package/src/tools/__tests__/BashExecutor.test.ts +16 -5
  99. package/src/tools/__tests__/CodeExecutor.stateful.test.ts +17 -6
  100. package/src/tools/search/crw-scraper.ts +244 -0
  101. package/src/tools/search/crw-search.ts +167 -0
  102. package/src/tools/search/crw.test.ts +836 -0
  103. package/src/tools/search/search.ts +7 -1
  104. package/src/tools/search/tool.ts +23 -3
  105. package/src/tools/search/types.ts +103 -3
  106. package/src/types/graph.ts +10 -3
@@ -6,6 +6,7 @@ import type {
6
6
  BaseMessage,
7
7
  MessageContentComplex,
8
8
  } from '@langchain/core/messages';
9
+ import type { ChatModelStreamEvent } from '@langchain/core/language_models/event';
9
10
  import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
10
11
  import type { AnthropicInput } from '@langchain/anthropic';
11
12
  import type { Anthropic } from '@anthropic-ai/sdk';
@@ -18,12 +19,15 @@ import type {
18
19
  AnthropicMCPServerURLDefinition,
19
20
  AnthropicContextManagementConfigParam,
20
21
  AnthropicRequestOptions,
22
+ AnthropicMessageStreamEvent,
21
23
  } from '@/llm/anthropic/types';
24
+ import type { AnthropicUsageData } from './utils/message_outputs';
22
25
  import {
23
26
  _convertMessagesToAnthropicPayload,
24
27
  stripUnsupportedAssistantPrefill,
25
28
  } from './utils/message_inputs';
26
29
  import { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';
30
+ import { convertAnthropicStream } from './utils/stream_events';
27
31
  import { handleToolChoice } from './utils/tools';
28
32
 
29
33
  const DEFAULT_STREAM_DELAY = 25;
@@ -34,6 +38,23 @@ const STREAM_BOUNDARIES = new Set([' ', '.', ',', '!', '?', ';', ':']);
34
38
 
35
39
  type StreamTokenType = 'string' | 'input' | 'content';
36
40
 
41
+ interface AnthropicStreamUsage {
42
+ inputTokens: number;
43
+ cacheCreationInputTokens: number;
44
+ cacheReadInputTokens: number;
45
+ outputTokens: number;
46
+ }
47
+
48
+ interface CumulativeUsageValue {
49
+ cumulative: number;
50
+ increment: number;
51
+ }
52
+
53
+ interface AnthropicEventStream
54
+ extends AsyncIterable<AnthropicMessageStreamEvent> {
55
+ controller?: { abort: () => void };
56
+ }
57
+
37
58
  const ANTHROPIC_TOOL_BETAS: Partial<Record<string, AnthropicBeta>> = {
38
59
  tool_search_tool_regex_20251119: 'advanced-tool-use-2025-11-20',
39
60
  tool_search_tool_bm25_20251119: 'advanced-tool-use-2025-11-20',
@@ -324,6 +345,19 @@ function isSignalAborted(signal?: AbortSignal): boolean {
324
345
  return signal?.aborted === true;
325
346
  }
326
347
 
348
+ async function* abortableAnthropicStream(
349
+ source: AnthropicEventStream,
350
+ signal?: AbortSignal
351
+ ): AsyncGenerator<AnthropicMessageStreamEvent> {
352
+ for await (const data of source) {
353
+ if (isSignalAborted(signal)) {
354
+ source.controller?.abort();
355
+ return;
356
+ }
357
+ yield data;
358
+ }
359
+ }
360
+
327
361
  function extractToken(
328
362
  chunk: AIMessageChunk
329
363
  ): [string, StreamTokenType] | [undefined] {
@@ -392,27 +426,77 @@ function cloneChunk(
392
426
  return chunk;
393
427
  }
394
428
 
429
+ function resolveCumulativeUsageValue(
430
+ current: number | null | undefined,
431
+ previous: number
432
+ ): CumulativeUsageValue {
433
+ if (current == null) {
434
+ return { cumulative: previous, increment: 0 };
435
+ }
436
+ const cumulative = Math.max(previous, current);
437
+ return { cumulative, increment: cumulative - previous };
438
+ }
439
+
395
440
  function withIncrementalMessageDeltaUsage(
396
441
  chunk: AIMessageChunk,
397
- previousOutputTokens: number
398
- ): { chunk: AIMessageChunk; outputTokens: number } {
442
+ previousUsage: AnthropicStreamUsage,
443
+ cumulativeUsage: AnthropicUsageData
444
+ ): { chunk: AIMessageChunk; usage: AnthropicStreamUsage } {
399
445
  const usage = chunk.usage_metadata;
400
446
  if (usage == null) {
401
- return { chunk, outputTokens: previousOutputTokens };
447
+ return { chunk, usage: previousUsage };
402
448
  }
403
449
 
404
- const outputTokens = Math.max(0, usage.output_tokens - previousOutputTokens);
450
+ const inputTokens = resolveCumulativeUsageValue(
451
+ cumulativeUsage.input_tokens,
452
+ previousUsage.inputTokens
453
+ );
454
+ const cacheCreationInputTokens = resolveCumulativeUsageValue(
455
+ cumulativeUsage.cache_creation_input_tokens,
456
+ previousUsage.cacheCreationInputTokens
457
+ );
458
+ const cacheReadInputTokens = resolveCumulativeUsageValue(
459
+ cumulativeUsage.cache_read_input_tokens,
460
+ previousUsage.cacheReadInputTokens
461
+ );
462
+ const outputTokens = resolveCumulativeUsageValue(
463
+ cumulativeUsage.output_tokens,
464
+ previousUsage.outputTokens
465
+ );
466
+ const incrementalInputTokens =
467
+ inputTokens.increment +
468
+ cacheCreationInputTokens.increment +
469
+ cacheReadInputTokens.increment;
470
+ const hasCacheUsage =
471
+ cumulativeUsage.cache_creation_input_tokens != null ||
472
+ cumulativeUsage.cache_read_input_tokens != null;
473
+ const inputTokenDetails = {
474
+ ...(cumulativeUsage.cache_creation_input_tokens != null && {
475
+ cache_creation: cacheCreationInputTokens.increment,
476
+ }),
477
+ ...(cumulativeUsage.cache_read_input_tokens != null && {
478
+ cache_read: cacheReadInputTokens.increment,
479
+ }),
480
+ };
481
+
405
482
  return {
406
483
  chunk: new AIMessageChunk(
407
484
  Object.assign({}, chunk, {
408
485
  usage_metadata: {
409
486
  ...usage,
410
- output_tokens: outputTokens,
411
- total_tokens: usage.input_tokens + outputTokens,
487
+ input_tokens: incrementalInputTokens,
488
+ output_tokens: outputTokens.increment,
489
+ total_tokens: incrementalInputTokens + outputTokens.increment,
490
+ input_token_details: hasCacheUsage ? inputTokenDetails : undefined,
412
491
  },
413
492
  })
414
493
  ),
415
- outputTokens: usage.output_tokens,
494
+ usage: {
495
+ inputTokens: inputTokens.cumulative,
496
+ cacheCreationInputTokens: cacheCreationInputTokens.cumulative,
497
+ cacheReadInputTokens: cacheReadInputTokens.cumulative,
498
+ outputTokens: outputTokens.cumulative,
499
+ },
416
500
  };
417
501
  }
418
502
 
@@ -626,6 +710,29 @@ export class CustomAnthropic extends ChatAnthropicMessages {
626
710
  );
627
711
  }
628
712
 
713
+ async *_streamChatModelEvents(
714
+ messages: BaseMessage[],
715
+ options: this['ParsedCallOptions'],
716
+ _runManager?: CallbackManagerForLLMRun
717
+ ): AsyncGenerator<ChatModelStreamEvent> {
718
+ const params = this.invocationParams(options);
719
+ const formattedMessages = _convertMessagesToAnthropicPayload(messages);
720
+ const payload = stripUnsupportedAssistantPrefill({
721
+ ...params,
722
+ ...formattedMessages,
723
+ stream: true,
724
+ } as const);
725
+ const stream = await this.createStreamWithRetry(payload, {
726
+ headers: options.headers,
727
+ signal: options.signal,
728
+ });
729
+ const shouldStreamUsage = options.streamUsage ?? this.streamUsage;
730
+ yield* convertAnthropicStream(
731
+ abortableAnthropicStream(stream, options.signal),
732
+ { streamUsage: shouldStreamUsage }
733
+ );
734
+ }
735
+
629
736
  async *_streamResponseChunks(
630
737
  messages: BaseMessage[],
631
738
  options: this['ParsedCallOptions'],
@@ -651,7 +758,12 @@ export class CustomAnthropic extends ChatAnthropicMessages {
651
758
  });
652
759
 
653
760
  const shouldStreamUsage = options.streamUsage ?? this.streamUsage;
654
- let messageDeltaOutputTokens = 0;
761
+ let streamUsage: AnthropicStreamUsage = {
762
+ inputTokens: 0,
763
+ cacheCreationInputTokens: 0,
764
+ cacheReadInputTokens: 0,
765
+ outputTokens: 0,
766
+ };
655
767
  const queuedChunks: QueuedGenerationChunk[] = [];
656
768
  const producerState: {
657
769
  done: boolean;
@@ -833,13 +945,25 @@ export class CustomAnthropic extends ChatAnthropicMessages {
833
945
  }
834
946
 
835
947
  let { chunk } = result;
948
+ if (data.type === 'message_start') {
949
+ streamUsage = {
950
+ ...streamUsage,
951
+ inputTokens: data.message.usage.input_tokens,
952
+ outputTokens: data.message.usage.output_tokens,
953
+ cacheCreationInputTokens:
954
+ data.message.usage.cache_creation_input_tokens ?? 0,
955
+ cacheReadInputTokens:
956
+ data.message.usage.cache_read_input_tokens ?? 0,
957
+ };
958
+ }
836
959
  if (data.type === 'message_delta') {
837
960
  const incremental = withIncrementalMessageDeltaUsage(
838
961
  chunk,
839
- messageDeltaOutputTokens
962
+ streamUsage,
963
+ data.usage
840
964
  );
841
965
  chunk = incremental.chunk;
842
- messageDeltaOutputTokens = incremental.outputTokens;
966
+ streamUsage = incremental.usage;
843
967
  }
844
968
 
845
969
  const [token = '', tokenType] = extractToken(chunk);
@@ -185,7 +185,7 @@ describe('_makeMessageChunkFromAnthropicEvent (ported from message_outputs.test.
185
185
  expect(usage.input_token_details?.cache_read).toBe(1000);
186
186
  });
187
187
 
188
- it('message_delta chunk has input_tokens=0 and no cache token details', () => {
188
+ it('message_delta chunk preserves cumulative input and cache usage', () => {
189
189
  const event = {
190
190
  type: 'message_delta' as const,
191
191
  delta: { stop_reason: 'end_turn' as const, stop_sequence: null },
@@ -202,10 +202,15 @@ describe('_makeMessageChunkFromAnthropicEvent (ported from message_outputs.test.
202
202
  expect(result).not.toBeNull();
203
203
 
204
204
  const usage = result!.chunk.usage_metadata!;
205
- expect(usage.output_tokens).toBe(42);
206
- expect(usage.input_tokens).toBe(0);
207
- expect(usage.input_token_details?.cache_creation).toBeUndefined();
208
- expect(usage.input_token_details?.cache_read).toBeUndefined();
205
+ expect(usage).toEqual({
206
+ input_tokens: 1600,
207
+ output_tokens: 42,
208
+ total_tokens: 1642,
209
+ input_token_details: {
210
+ cache_creation: 500,
211
+ cache_read: 1000,
212
+ },
213
+ });
209
214
  });
210
215
  });
211
216