@librechat/agents 3.3.0 → 3.3.2

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 (130) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +116 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/enum.cjs +2 -0
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/graphs/Graph.cjs +229 -48
  6. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  7. package/dist/cjs/graphs/MultiAgentGraph.cjs +102 -27
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  9. package/dist/cjs/llm/bedrock/index.cjs +11 -2
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  11. package/dist/cjs/llm/contextOverflowRecovery.cjs +132 -0
  12. package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -0
  13. package/dist/cjs/llm/google/index.cjs +1 -1
  14. package/dist/cjs/llm/invoke.cjs +60 -3
  15. package/dist/cjs/llm/invoke.cjs.map +1 -1
  16. package/dist/cjs/main.cjs +20 -7
  17. package/dist/cjs/messages/prune.cjs +16 -5
  18. package/dist/cjs/messages/prune.cjs.map +1 -1
  19. package/dist/cjs/messages/recency.cjs +2 -0
  20. package/dist/cjs/messages/recency.cjs.map +1 -1
  21. package/dist/cjs/run.cjs +15 -2
  22. package/dist/cjs/run.cjs.map +1 -1
  23. package/dist/cjs/stream.cjs +205 -49
  24. package/dist/cjs/stream.cjs.map +1 -1
  25. package/dist/cjs/summarization/node.cjs +55 -7
  26. package/dist/cjs/summarization/node.cjs.map +1 -1
  27. package/dist/cjs/tools/BashExecutor.cjs +2 -2
  28. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  29. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -2
  30. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  31. package/dist/cjs/tools/CodeExecutor.cjs +69 -8
  32. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  33. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +19 -15
  34. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  35. package/dist/cjs/tools/ToolNode.cjs +32 -3
  36. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  37. package/dist/cjs/utils/errors.cjs +317 -52
  38. package/dist/cjs/utils/errors.cjs.map +1 -1
  39. package/dist/esm/agents/AgentContext.mjs +117 -3
  40. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  41. package/dist/esm/common/enum.mjs +2 -0
  42. package/dist/esm/common/enum.mjs.map +1 -1
  43. package/dist/esm/graphs/Graph.mjs +227 -46
  44. package/dist/esm/graphs/Graph.mjs.map +1 -1
  45. package/dist/esm/graphs/MultiAgentGraph.mjs +102 -27
  46. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  47. package/dist/esm/llm/bedrock/index.mjs +11 -2
  48. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  49. package/dist/esm/llm/contextOverflowRecovery.mjs +130 -0
  50. package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -0
  51. package/dist/esm/llm/google/index.mjs +1 -1
  52. package/dist/esm/llm/invoke.mjs +59 -4
  53. package/dist/esm/llm/invoke.mjs.map +1 -1
  54. package/dist/esm/main.mjs +9 -9
  55. package/dist/esm/messages/prune.mjs +14 -6
  56. package/dist/esm/messages/prune.mjs.map +1 -1
  57. package/dist/esm/messages/recency.mjs +2 -1
  58. package/dist/esm/messages/recency.mjs.map +1 -1
  59. package/dist/esm/run.mjs +15 -2
  60. package/dist/esm/run.mjs.map +1 -1
  61. package/dist/esm/stream.mjs +205 -49
  62. package/dist/esm/stream.mjs.map +1 -1
  63. package/dist/esm/summarization/node.mjs +55 -7
  64. package/dist/esm/summarization/node.mjs.map +1 -1
  65. package/dist/esm/tools/BashExecutor.mjs +3 -3
  66. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  67. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +3 -3
  68. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  69. package/dist/esm/tools/CodeExecutor.mjs +62 -9
  70. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  71. package/dist/esm/tools/ProgrammaticToolCalling.mjs +20 -16
  72. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  73. package/dist/esm/tools/ToolNode.mjs +32 -3
  74. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  75. package/dist/esm/utils/errors.mjs +317 -53
  76. package/dist/esm/utils/errors.mjs.map +1 -1
  77. package/dist/types/agents/AgentContext.d.ts +62 -3
  78. package/dist/types/common/enum.d.ts +2 -0
  79. package/dist/types/graphs/Graph.d.ts +16 -2
  80. package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
  81. package/dist/types/llm/contextOverflowRecovery.d.ts +85 -0
  82. package/dist/types/llm/invoke.d.ts +35 -6
  83. package/dist/types/messages/prune.d.ts +10 -2
  84. package/dist/types/messages/recency.d.ts +1 -0
  85. package/dist/types/run.d.ts +2 -0
  86. package/dist/types/tools/CodeExecutor.d.ts +14 -1
  87. package/dist/types/types/llm.d.ts +7 -4
  88. package/dist/types/types/stream.d.ts +5 -4
  89. package/dist/types/types/summarize.d.ts +22 -0
  90. package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +40 -0
  91. package/dist/types/utils/errors.d.ts +65 -16
  92. package/dist/types/utils/redactSecrets.d.ts +3 -0
  93. package/package.json +10 -11
  94. package/src/agents/AgentContext.ts +188 -7
  95. package/src/agents/__tests__/AgentContext.overflow.test.ts +205 -0
  96. package/src/common/enum.ts +2 -0
  97. package/src/graphs/Graph.ts +389 -58
  98. package/src/graphs/MultiAgentGraph.ts +184 -46
  99. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +631 -0
  100. package/src/llm/__tests__/contextOverflowRecovery.test.ts +401 -0
  101. package/src/llm/__tests__/fallbackOverflow.test.ts +287 -0
  102. package/src/llm/anthropic/llm.spec.ts +8 -0
  103. package/src/llm/bedrock/index.ts +25 -12
  104. package/src/llm/contextOverflowRecovery.ts +292 -0
  105. package/src/llm/invoke.ts +119 -4
  106. package/src/messages/prune.ts +24 -11
  107. package/src/messages/recency.ts +3 -1
  108. package/src/run.ts +24 -1
  109. package/src/scripts/context-overflow-probe.ts +997 -0
  110. package/src/specs/agent-handoffs.test.ts +903 -1
  111. package/src/specs/context-overflow-recovery.live.test.ts +213 -0
  112. package/src/splitStream.test.ts +882 -0
  113. package/src/stream.ts +315 -51
  114. package/src/summarization/__tests__/aggregator.test.ts +83 -0
  115. package/src/summarization/__tests__/node.test.ts +139 -0
  116. package/src/summarization/node.ts +99 -14
  117. package/src/tools/BashExecutor.ts +4 -2
  118. package/src/tools/BashProgrammaticToolCalling.ts +4 -7
  119. package/src/tools/CodeExecutor.ts +119 -8
  120. package/src/tools/ProgrammaticToolCalling.ts +29 -27
  121. package/src/tools/ToolNode.ts +50 -8
  122. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +297 -3
  123. package/src/types/llm.ts +8 -1
  124. package/src/types/stream.ts +5 -4
  125. package/src/types/summarize.ts +22 -0
  126. package/src/utils/__tests__/errors.test.ts +270 -0
  127. package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +336 -0
  128. package/src/utils/__tests__/redactSecrets.test.ts +56 -0
  129. package/src/utils/errors.ts +484 -66
  130. package/src/utils/redactSecrets.ts +61 -0
@@ -80,10 +80,18 @@ export function enforceOriginalContentCap(map: Map<number, string>): void {
80
80
 
81
81
  /** Minimum cumulative calibration ratio — provider can't count fewer tokens
82
82
  * than our raw estimate (within reason). Prevents divide-by-zero edge cases. */
83
- const CALIBRATION_RATIO_MIN = 0.5;
83
+ export const CALIBRATION_RATIO_MIN = 0.5;
84
84
 
85
85
  /** Maximum cumulative calibration ratio — sanity cap for the running ratio. */
86
- const CALIBRATION_RATIO_MAX = 5;
86
+ export const CALIBRATION_RATIO_MAX = 5;
87
+
88
+ /** Keeps provider/local token calibration within the shared safe range. */
89
+ export function clampCalibrationRatio(ratio: number): number {
90
+ return Math.max(
91
+ CALIBRATION_RATIO_MIN,
92
+ Math.min(CALIBRATION_RATIO_MAX, ratio)
93
+ );
94
+ }
87
95
 
88
96
  export type PruneMessagesFactoryParams = {
89
97
  provider?: Providers;
@@ -1002,8 +1010,8 @@ export function maskConsumedToolResults(params: {
1002
1010
  /** When provided, original (pre-masking) content is stored here keyed by
1003
1011
  * message index — only for entries that actually get truncated. */
1004
1012
  originalContentStore?: Map<number, string>;
1005
- /** Called after storing content with the char length of the stored entry. */
1006
- onContentStored?: (charLength: number) => void;
1013
+ /** Called after storing a newly captured entry. */
1014
+ onContentStored?: (index: number, content: string) => void;
1007
1015
  }): number {
1008
1016
  const { messages, indexTokenCountMap, tokenCounter } = params;
1009
1017
  let maskedCount = 0;
@@ -1079,7 +1087,7 @@ export function maskConsumedToolResults(params: {
1079
1087
  if (params.originalContentStore && !params.originalContentStore.has(i)) {
1080
1088
  params.originalContentStore.set(i, content);
1081
1089
  if (params.onContentStored) {
1082
- params.onContentStored(content.length);
1090
+ params.onContentStored(i, content);
1083
1091
  }
1084
1092
  }
1085
1093
 
@@ -1311,6 +1319,7 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
1311
1319
  remainingContextTokens?: number;
1312
1320
  contextPressure?: number;
1313
1321
  originalToolContent?: Map<number, string>;
1322
+ newOriginalToolContent?: Map<number, string>;
1314
1323
  calibrationRatio?: number;
1315
1324
  resolvedInstructionOverhead?: number;
1316
1325
  /** Usable budget this call: maxTokens minus output reserve */
@@ -1318,6 +1327,7 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
1318
1327
  /** Calibrated instruction overhead actually applied this call */
1319
1328
  effectiveInstructionTokens?: number;
1320
1329
  } {
1330
+ let newOriginalToolContent: Map<number, string> | undefined;
1321
1331
  if (params.messages.length === 0) {
1322
1332
  /** Post-compaction calls still invoke the model — report the same
1323
1333
  * reserve-adjusted budget fields as the populated paths */
@@ -1479,10 +1489,7 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
1479
1489
  cumulativeRawSent += rawSentThisTurn;
1480
1490
  cumulativeProviderReported += providerMessageTokens;
1481
1491
  const newRatio = cumulativeProviderReported / cumulativeRawSent;
1482
- calibrationRatio = Math.max(
1483
- CALIBRATION_RATIO_MIN,
1484
- Math.min(CALIBRATION_RATIO_MAX, newRatio)
1485
- );
1492
+ calibrationRatio = clampCalibrationRatio(newRatio);
1486
1493
 
1487
1494
  const calibratedOurTotal =
1488
1495
  instructionOverhead + rawSentThisTurn * calibrationRatio;
@@ -1661,8 +1668,12 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
1661
1668
  : undefined,
1662
1669
  onContentStored:
1663
1670
  factoryParams.summarizationEnabled === true
1664
- ? (charLen: number): void => {
1665
- originalToolContentSize += charLen;
1671
+ ? (index: number, content: string): void => {
1672
+ originalToolContentSize += content.length;
1673
+ if (newOriginalToolContent == null) {
1674
+ newOriginalToolContent = new Map();
1675
+ }
1676
+ newOriginalToolContent.set(index, content);
1666
1677
  while (
1667
1678
  originalToolContentSize > ORIGINAL_CONTENT_MAX_CHARS &&
1668
1679
  originalToolContent.size > 0
@@ -1798,6 +1809,7 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
1798
1809
  contextPressure,
1799
1810
  originalToolContent:
1800
1811
  originalToolContent.size > 0 ? originalToolContent : undefined,
1812
+ newOriginalToolContent,
1801
1813
  calibrationRatio,
1802
1814
  resolvedInstructionOverhead: bestInstructionOverhead,
1803
1815
  contextBudget: pruningBudget,
@@ -2182,6 +2194,7 @@ export function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {
2182
2194
  contextPressure,
2183
2195
  originalToolContent:
2184
2196
  originalToolContent.size > 0 ? originalToolContent : undefined,
2197
+ newOriginalToolContent,
2185
2198
  calibrationRatio,
2186
2199
  resolvedInstructionOverhead: bestInstructionOverhead,
2187
2200
  contextBudget: pruningBudget,
@@ -1,5 +1,7 @@
1
1
  import type { BaseMessage } from '@langchain/core/messages';
2
2
 
3
+ export const DEFAULT_RETAIN_RECENT_TURNS = 2;
4
+
3
5
  /**
4
6
  * Configuration for splitting a message list into a head (to be summarized)
5
7
  * and a tail (to be preserved verbatim).
@@ -68,7 +70,7 @@ export function splitAtRecencyBoundary(
68
70
  messages: BaseMessage[],
69
71
  options: RecencyWindowOptions = {}
70
72
  ): RecencySplit {
71
- const turnsCap = options.turns ?? 2;
73
+ const turnsCap = options.turns ?? DEFAULT_RETAIN_RECENT_TURNS;
72
74
 
73
75
  if (messages.length === 0 || turnsCap <= 0) {
74
76
  return {
package/src/run.ts CHANGED
@@ -164,6 +164,8 @@ export class Run<_T extends t.BaseGraphState> {
164
164
  private _interrupt: t.RunInterruptResult<unknown> | undefined;
165
165
  /** Per-run sequence for batch-unique activity-label trace-seed fallbacks. */
166
166
  private activityLabelSeq = 0;
167
+ /** Distinguishes sibling forks started from the same explicit checkpoint. */
168
+ private checkpointForkSeq = 0;
167
169
  private _haltedReason: string | undefined;
168
170
 
169
171
  private constructor(config: Partial<t.RunConfig>) {
@@ -719,7 +721,28 @@ export class Run<_T extends t.BaseGraphState> {
719
721
  * boundary.
720
722
  */
721
723
  if (!isResume) {
722
- graph.resetValues(streamOptions?.keepContent);
724
+ const checkpointThreadId =
725
+ typeof config.configurable?.thread_id === 'string'
726
+ ? config.configurable.thread_id
727
+ : undefined;
728
+ const checkpointNamespace =
729
+ typeof config.configurable?.checkpoint_ns === 'string'
730
+ ? config.configurable.checkpoint_ns
731
+ : '';
732
+ const checkpointId =
733
+ typeof config.configurable?.checkpoint_id === 'string'
734
+ ? config.configurable.checkpoint_id
735
+ : '';
736
+ const checkpointScope =
737
+ checkpointThreadId == null
738
+ ? undefined
739
+ : JSON.stringify([
740
+ checkpointThreadId,
741
+ checkpointNamespace,
742
+ checkpointId,
743
+ checkpointId === '' ? 0 : ++this.checkpointForkSeq,
744
+ ]);
745
+ graph.resetValues(streamOptions?.keepContent, checkpointScope);
723
746
  }
724
747
  this._interrupt = undefined;
725
748
  this._haltedReason = undefined;