@librechat/agents 2.3.1 → 2.3.3

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 (77) hide show
  1. package/dist/cjs/graphs/Graph.cjs +6 -6
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/llm/anthropic/llm.cjs +7 -7
  4. package/dist/cjs/llm/anthropic/llm.cjs.map +1 -1
  5. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +6 -6
  6. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +24 -24
  8. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  9. package/dist/cjs/llm/fake.cjs.map +1 -1
  10. package/dist/cjs/llm/text.cjs.map +1 -1
  11. package/dist/cjs/main.cjs +3 -0
  12. package/dist/cjs/main.cjs.map +1 -1
  13. package/dist/cjs/messages/core.cjs +6 -6
  14. package/dist/cjs/messages/core.cjs.map +1 -1
  15. package/dist/cjs/messages/format.cjs +11 -9
  16. package/dist/cjs/messages/format.cjs.map +1 -1
  17. package/dist/cjs/messages/prune.cjs +155 -205
  18. package/dist/cjs/messages/prune.cjs.map +1 -1
  19. package/dist/cjs/run.cjs.map +1 -1
  20. package/dist/cjs/stream.cjs +7 -7
  21. package/dist/cjs/stream.cjs.map +1 -1
  22. package/dist/cjs/tools/ToolNode.cjs +1 -1
  23. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  24. package/dist/cjs/utils/tokens.cjs +3 -3
  25. package/dist/cjs/utils/tokens.cjs.map +1 -1
  26. package/dist/esm/graphs/Graph.mjs +6 -6
  27. package/dist/esm/graphs/Graph.mjs.map +1 -1
  28. package/dist/esm/llm/anthropic/llm.mjs +7 -7
  29. package/dist/esm/llm/anthropic/llm.mjs.map +1 -1
  30. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +6 -6
  31. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  32. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +24 -24
  33. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  34. package/dist/esm/llm/fake.mjs.map +1 -1
  35. package/dist/esm/llm/text.mjs.map +1 -1
  36. package/dist/esm/main.mjs +1 -1
  37. package/dist/esm/messages/core.mjs +6 -6
  38. package/dist/esm/messages/core.mjs.map +1 -1
  39. package/dist/esm/messages/format.mjs +11 -9
  40. package/dist/esm/messages/format.mjs.map +1 -1
  41. package/dist/esm/messages/prune.mjs +153 -206
  42. package/dist/esm/messages/prune.mjs.map +1 -1
  43. package/dist/esm/run.mjs.map +1 -1
  44. package/dist/esm/stream.mjs +7 -7
  45. package/dist/esm/stream.mjs.map +1 -1
  46. package/dist/esm/tools/ToolNode.mjs +1 -1
  47. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  48. package/dist/esm/utils/tokens.mjs +3 -3
  49. package/dist/esm/utils/tokens.mjs.map +1 -1
  50. package/dist/types/messages/format.d.ts +1 -2
  51. package/dist/types/messages/prune.d.ts +31 -2
  52. package/dist/types/types/stream.d.ts +2 -2
  53. package/dist/types/utils/tokens.d.ts +1 -1
  54. package/package.json +4 -3
  55. package/src/graphs/Graph.ts +8 -8
  56. package/src/llm/anthropic/llm.ts +7 -8
  57. package/src/llm/anthropic/types.ts +4 -4
  58. package/src/llm/anthropic/utils/message_inputs.ts +6 -6
  59. package/src/llm/anthropic/utils/message_outputs.ts +39 -39
  60. package/src/llm/fake.ts +2 -2
  61. package/src/llm/text.ts +1 -1
  62. package/src/messages/core.ts +9 -9
  63. package/src/messages/format.ts +43 -42
  64. package/src/messages/formatAgentMessages.test.ts +35 -35
  65. package/src/messages/formatAgentMessages.tools.test.ts +30 -30
  66. package/src/messages/prune.ts +182 -255
  67. package/src/messages/shiftIndexTokenCountMap.test.ts +18 -18
  68. package/src/mockStream.ts +1 -1
  69. package/src/run.ts +2 -2
  70. package/src/specs/prune.test.ts +89 -89
  71. package/src/specs/reasoning.test.ts +1 -1
  72. package/src/specs/thinking-prune.test.ts +265 -261
  73. package/src/specs/tool-error.test.ts +16 -17
  74. package/src/stream.ts +21 -18
  75. package/src/tools/ToolNode.ts +1 -1
  76. package/src/types/stream.ts +4 -3
  77. package/src/utils/tokens.ts +12 -12
@@ -362,14 +362,14 @@ describe('formatAgentMessages', () => {
362
362
  { role: 'user', content: 'Hello' },
363
363
  { role: 'assistant', content: 'Hi there!' },
364
364
  ];
365
-
365
+
366
366
  const indexTokenCountMap = {
367
367
  0: 5, // 5 tokens for "Hello"
368
368
  1: 10, // 10 tokens for "Hi there!"
369
369
  };
370
-
370
+
371
371
  const result = formatAgentMessages(payload, indexTokenCountMap);
372
-
372
+
373
373
  expect(result.messages).toHaveLength(2);
374
374
  expect(result.indexTokenCountMap).toBeDefined();
375
375
  expect(result.indexTokenCountMap?.[0]).toBe(5);
@@ -399,23 +399,23 @@ describe('formatAgentMessages', () => {
399
399
  ],
400
400
  },
401
401
  ];
402
-
402
+
403
403
  const indexTokenCountMap = {
404
404
  0: 10, // 10 tokens for "What's the weather?"
405
405
  1: 50, // 50 tokens for the assistant message with tool call
406
406
  };
407
-
407
+
408
408
  const result = formatAgentMessages(payload, indexTokenCountMap);
409
-
409
+
410
410
  // The original message at index 1 should be split into two messages
411
411
  expect(result.messages).toHaveLength(3);
412
412
  expect(result.indexTokenCountMap).toBeDefined();
413
413
  expect(result.indexTokenCountMap?.[0]).toBe(10); // User message stays the same
414
-
414
+
415
415
  // The assistant message tokens should be distributed across the resulting messages
416
416
  const totalAssistantTokens = Object.values(result.indexTokenCountMap || {})
417
417
  .reduce((sum, count) => sum + count, 0) - 10; // Subtract user message tokens
418
-
418
+
419
419
  expect(totalAssistantTokens).toBe(50); // Should match the original token count
420
420
  });
421
421
 
@@ -460,23 +460,23 @@ describe('formatAgentMessages', () => {
460
460
  ],
461
461
  },
462
462
  ];
463
-
463
+
464
464
  const indexTokenCountMap = {
465
465
  0: 100, // 100 tokens for the complex assistant message
466
466
  };
467
-
467
+
468
468
  const result = formatAgentMessages(payload, indexTokenCountMap);
469
-
469
+
470
470
  // One message expands to 5 messages (2 tool calls + text before, between, and after)
471
471
  expect(result.messages).toHaveLength(5);
472
472
  expect(result.indexTokenCountMap).toBeDefined();
473
-
473
+
474
474
  // The sum of all token counts should equal the original
475
475
  const totalTokens = Object.values(result.indexTokenCountMap || {})
476
476
  .reduce((sum, count) => sum + count, 0);
477
-
477
+
478
478
  expect(totalTokens).toBe(100);
479
-
479
+
480
480
  // Check that each resulting message has a token count
481
481
  for (let i = 0; i < result.messages.length; i++) {
482
482
  expect(result.indexTokenCountMap?.[i]).toBeDefined();
@@ -495,17 +495,17 @@ describe('formatAgentMessages', () => {
495
495
  ],
496
496
  },
497
497
  ];
498
-
498
+
499
499
  const indexTokenCountMap = {
500
500
  0: 60, // 60 tokens for the message with filtered content
501
501
  };
502
-
502
+
503
503
  const result = formatAgentMessages(payload, indexTokenCountMap);
504
-
504
+
505
505
  // Only one message should remain after filtering
506
506
  expect(result.messages).toHaveLength(1);
507
507
  expect(result.indexTokenCountMap).toBeDefined();
508
-
508
+
509
509
  // All tokens should be assigned to the remaining message
510
510
  expect(result.indexTokenCountMap?.[0]).toBe(60);
511
511
  });
@@ -522,17 +522,17 @@ describe('formatAgentMessages', () => {
522
522
  ],
523
523
  },
524
524
  ];
525
-
525
+
526
526
  const indexTokenCountMap = {
527
527
  0: 40, // 40 tokens for the message with filtered content
528
528
  };
529
-
529
+
530
530
  const result = formatAgentMessages(payload, indexTokenCountMap);
531
-
531
+
532
532
  // No messages should remain after filtering
533
533
  expect(result.messages).toHaveLength(0);
534
534
  expect(result.indexTokenCountMap).toBeDefined();
535
-
535
+
536
536
  // The token count map should be empty since there are no messages
537
537
  expect(Object.keys(result.indexTokenCountMap || {})).toHaveLength(0);
538
538
  });
@@ -561,29 +561,29 @@ describe('formatAgentMessages', () => {
561
561
  ],
562
562
  },
563
563
  ];
564
-
564
+
565
565
  const indexTokenCountMap = {
566
566
  0: 15, // 15 tokens for the user message
567
567
  1: 45, // 45 tokens for the assistant message with tool call
568
568
  };
569
-
569
+
570
570
  const result = formatAgentMessages(payload, indexTokenCountMap);
571
-
571
+
572
572
  // 2 input messages become 3 output messages (user + assistant + tool)
573
573
  expect(payload).toHaveLength(2);
574
574
  expect(result.messages).toHaveLength(3);
575
575
  expect(result.indexTokenCountMap).toBeDefined();
576
576
  expect(Object.keys(result.indexTokenCountMap ?? {}).length).toBe(3);
577
-
577
+
578
578
  // Check message types
579
579
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
580
580
  expect(result.messages[1]).toBeInstanceOf(AIMessage);
581
581
  expect(result.messages[2]).toBeInstanceOf(ToolMessage);
582
-
582
+
583
583
  // The sum of all token counts should equal the original total
584
584
  const totalTokens = Object.values(result.indexTokenCountMap || {})
585
585
  .reduce((sum, count) => sum + count, 0);
586
-
586
+
587
587
  expect(totalTokens).toBe(60); // 15 + 45
588
588
  });
589
589
 
@@ -600,30 +600,30 @@ describe('formatAgentMessages', () => {
600
600
  ],
601
601
  },
602
602
  ];
603
-
603
+
604
604
  const indexTokenCountMap = {
605
605
  0: 10, // 10 tokens for the user message
606
606
  1: 30, // 30 tokens for the assistant message that will be filtered out
607
607
  };
608
-
608
+
609
609
  const result = formatAgentMessages(payload, indexTokenCountMap);
610
-
610
+
611
611
  // 2 input messages become 1 output message (only the user message remains)
612
612
  expect(payload).toHaveLength(2);
613
613
  expect(result.messages).toHaveLength(1);
614
614
  expect(result.indexTokenCountMap).toBeDefined();
615
615
  expect(Object.keys(result.indexTokenCountMap ?? {}).length).toBe(1);
616
-
616
+
617
617
  // Check message type
618
618
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
619
-
619
+
620
620
  // Only the user message tokens should remain
621
621
  expect(result.indexTokenCountMap?.[0]).toBe(10);
622
-
622
+
623
623
  // The total tokens should be just the user message tokens
624
624
  const totalTokens = Object.values(result.indexTokenCountMap || {})
625
625
  .reduce((sum, count) => sum + count, 0);
626
-
626
+
627
627
  expect(totalTokens).toBe(10);
628
628
  });
629
629
  });
@@ -1,4 +1,4 @@
1
- import { HumanMessage, AIMessage, SystemMessage, ToolMessage } from '@langchain/core/messages';
1
+ import { HumanMessage, AIMessage, ToolMessage } from '@langchain/core/messages';
2
2
  import type { TPayload } from '@/types';
3
3
  import { formatAgentMessages } from './format';
4
4
  import { ContentTypes } from '@/common';
@@ -27,9 +27,9 @@ describe('formatAgentMessages with tools parameter', () => {
27
27
  ],
28
28
  },
29
29
  ];
30
-
30
+
31
31
  const result = formatAgentMessages(payload);
32
-
32
+
33
33
  expect(result.messages).toHaveLength(3);
34
34
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
35
35
  expect(result.messages[1]).toBeInstanceOf(AIMessage);
@@ -61,17 +61,17 @@ describe('formatAgentMessages with tools parameter', () => {
61
61
  ],
62
62
  },
63
63
  ];
64
-
64
+
65
65
  // Provide an empty set of allowed tools
66
66
  const allowedTools = new Set<string>();
67
-
67
+
68
68
  const result = formatAgentMessages(payload, undefined, allowedTools);
69
-
69
+
70
70
  // Should convert to a single AIMessage with string content
71
71
  expect(result.messages).toHaveLength(2);
72
72
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
73
73
  expect(result.messages[1]).toBeInstanceOf(AIMessage);
74
-
74
+
75
75
  // The content should be a string representation of both messages
76
76
  expect(typeof result.messages[1].content).toBe('string');
77
77
  expect(result.messages[1].content).toEqual('AI: Let me check the weather for you.\nTool: check_weather, Sunny, 75°F');
@@ -100,17 +100,17 @@ describe('formatAgentMessages with tools parameter', () => {
100
100
  ],
101
101
  },
102
102
  ];
103
-
103
+
104
104
  // Provide a set of allowed tools that doesn't include 'check_weather'
105
105
  const allowedTools = new Set(['search', 'calculator']);
106
-
106
+
107
107
  const result = formatAgentMessages(payload, undefined, allowedTools);
108
-
108
+
109
109
  // Should convert to a single AIMessage with string content
110
110
  expect(result.messages).toHaveLength(2);
111
111
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
112
112
  expect(result.messages[1]).toBeInstanceOf(AIMessage);
113
-
113
+
114
114
  // The content should be a string representation of both messages
115
115
  expect(typeof result.messages[1].content).toBe('string');
116
116
  expect(result.messages[1].content).toEqual('AI: Let me check the weather for you.\nTool: check_weather, Sunny, 75°F');
@@ -139,12 +139,12 @@ describe('formatAgentMessages with tools parameter', () => {
139
139
  ],
140
140
  },
141
141
  ];
142
-
142
+
143
143
  // Provide a set of allowed tools that includes 'check_weather'
144
144
  const allowedTools = new Set(['check_weather', 'search']);
145
-
145
+
146
146
  const result = formatAgentMessages(payload, undefined, allowedTools);
147
-
147
+
148
148
  // Should keep the original structure
149
149
  expect(result.messages).toHaveLength(3);
150
150
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
@@ -189,17 +189,17 @@ describe('formatAgentMessages with tools parameter', () => {
189
189
  ],
190
190
  },
191
191
  ];
192
-
192
+
193
193
  // Allow calculator but not check_weather
194
194
  const allowedTools = new Set(['calculator', 'search']);
195
-
195
+
196
196
  const result = formatAgentMessages(payload, undefined, allowedTools);
197
-
197
+
198
198
  // Should convert the entire sequence to a single AIMessage
199
199
  expect(result.messages).toHaveLength(2);
200
200
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
201
201
  expect(result.messages[1]).toBeInstanceOf(AIMessage);
202
-
202
+
203
203
  // The content should include all parts
204
204
  expect(typeof result.messages[1].content).toBe('string');
205
205
  expect(result.messages[1].content).toContain('Let me check the weather first.');
@@ -231,24 +231,24 @@ describe('formatAgentMessages with tools parameter', () => {
231
231
  ],
232
232
  },
233
233
  ];
234
-
234
+
235
235
  const indexTokenCountMap = {
236
236
  0: 10, // 10 tokens for user message
237
237
  1: 40, // 40 tokens for assistant message with tool call
238
238
  };
239
-
239
+
240
240
  // Provide a set of allowed tools that doesn't include 'check_weather'
241
241
  const allowedTools = new Set(['search', 'calculator']);
242
-
242
+
243
243
  const result = formatAgentMessages(payload, indexTokenCountMap, allowedTools);
244
-
244
+
245
245
  // Should have 2 messages and 2 entries in the token count map
246
246
  expect(result.messages).toHaveLength(2);
247
247
  expect(Object.keys(result.indexTokenCountMap || {}).length).toBe(2);
248
-
248
+
249
249
  // User message token count should be unchanged
250
250
  expect(result.indexTokenCountMap?.[0]).toBe(10);
251
-
251
+
252
252
  // All assistant message tokens should be assigned to the single AIMessage
253
253
  expect(result.indexTokenCountMap?.[1]).toBe(40);
254
254
  });
@@ -315,27 +315,27 @@ describe('formatAgentMessages with tools parameter', () => {
315
315
  },
316
316
  { role: 'assistant', content: 'Here\'s your answer based on all that information.' },
317
317
  ];
318
-
318
+
319
319
  // Allow search and calculator but not check_weather
320
320
  const allowedTools = new Set(['search', 'calculator']);
321
-
321
+
322
322
  const result = formatAgentMessages(payload, undefined, allowedTools);
323
-
323
+
324
324
  // Should have the user message, search tool sequence (2 messages),
325
325
  // a combined message for weather and calculator (since one has an invalid tool),
326
326
  // and final message
327
327
  expect(result.messages).toHaveLength(5);
328
-
328
+
329
329
  // Check the types of messages
330
330
  expect(result.messages[0]).toBeInstanceOf(HumanMessage);
331
331
  expect(result.messages[1]).toBeInstanceOf(AIMessage); // Search message
332
332
  expect(result.messages[2]).toBeInstanceOf(ToolMessage); // Search tool response
333
333
  expect(result.messages[3]).toBeInstanceOf(AIMessage); // Converted weather+calculator message
334
334
  expect(result.messages[4]).toBeInstanceOf(AIMessage); // Final message
335
-
335
+
336
336
  // Check that the combined message was converted to a string
337
337
  expect(typeof result.messages[3].content).toBe('string');
338
-
338
+
339
339
  // The format might vary based on the getBufferString implementation
340
340
  // but we should check that all the key information is present
341
341
  const content = result.messages[3].content as string;