@librechat/agents 3.1.85 → 3.1.87

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 (166) hide show
  1. package/README.md +69 -0
  2. package/dist/cjs/agents/AgentContext.cjs +7 -2
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/events.cjs +23 -0
  5. package/dist/cjs/events.cjs.map +1 -1
  6. package/dist/cjs/graphs/Graph.cjs +133 -18
  7. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  10. package/dist/cjs/llm/anthropic/index.cjs +251 -53
  11. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  12. package/dist/cjs/llm/init.cjs +1 -5
  13. package/dist/cjs/llm/init.cjs.map +1 -1
  14. package/dist/cjs/llm/openai/index.cjs +113 -24
  15. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  16. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openrouter/index.cjs +3 -1
  18. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  19. package/dist/cjs/main.cjs +18 -5
  20. package/dist/cjs/main.cjs.map +1 -1
  21. package/dist/cjs/openai/index.cjs +253 -0
  22. package/dist/cjs/openai/index.cjs.map +1 -0
  23. package/dist/cjs/responses/index.cjs +448 -0
  24. package/dist/cjs/responses/index.cjs.map +1 -0
  25. package/dist/cjs/run.cjs +108 -7
  26. package/dist/cjs/run.cjs.map +1 -1
  27. package/dist/cjs/session/AgentSession.cjs +1057 -0
  28. package/dist/cjs/session/AgentSession.cjs.map +1 -0
  29. package/dist/cjs/session/JsonlSessionStore.cjs +425 -0
  30. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -0
  31. package/dist/cjs/session/handlers.cjs +221 -0
  32. package/dist/cjs/session/handlers.cjs.map +1 -0
  33. package/dist/cjs/session/ids.cjs +22 -0
  34. package/dist/cjs/session/ids.cjs.map +1 -0
  35. package/dist/cjs/session/messageSerialization.cjs +179 -0
  36. package/dist/cjs/session/messageSerialization.cjs.map +1 -0
  37. package/dist/cjs/stream.cjs +472 -11
  38. package/dist/cjs/stream.cjs.map +1 -1
  39. package/dist/cjs/summarization/node.cjs +1 -1
  40. package/dist/cjs/summarization/node.cjs.map +1 -1
  41. package/dist/cjs/tools/ToolNode.cjs +177 -59
  42. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  43. package/dist/cjs/tools/eagerEventExecution.cjs +113 -0
  44. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -0
  45. package/dist/cjs/tools/handlers.cjs +1 -1
  46. package/dist/cjs/tools/handlers.cjs.map +1 -1
  47. package/dist/cjs/tools/streamedToolCallSeals.cjs +42 -0
  48. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -0
  49. package/dist/esm/agents/AgentContext.mjs +7 -2
  50. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  51. package/dist/esm/events.mjs +23 -1
  52. package/dist/esm/events.mjs.map +1 -1
  53. package/dist/esm/graphs/Graph.mjs +133 -18
  54. package/dist/esm/graphs/Graph.mjs.map +1 -1
  55. package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
  56. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  57. package/dist/esm/llm/anthropic/index.mjs +251 -53
  58. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  59. package/dist/esm/llm/init.mjs +1 -5
  60. package/dist/esm/llm/init.mjs.map +1 -1
  61. package/dist/esm/llm/openai/index.mjs +113 -25
  62. package/dist/esm/llm/openai/index.mjs.map +1 -1
  63. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  64. package/dist/esm/llm/openrouter/index.mjs +4 -2
  65. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  66. package/dist/esm/main.mjs +5 -1
  67. package/dist/esm/main.mjs.map +1 -1
  68. package/dist/esm/openai/index.mjs +246 -0
  69. package/dist/esm/openai/index.mjs.map +1 -0
  70. package/dist/esm/responses/index.mjs +440 -0
  71. package/dist/esm/responses/index.mjs.map +1 -0
  72. package/dist/esm/run.mjs +108 -7
  73. package/dist/esm/run.mjs.map +1 -1
  74. package/dist/esm/session/AgentSession.mjs +1054 -0
  75. package/dist/esm/session/AgentSession.mjs.map +1 -0
  76. package/dist/esm/session/JsonlSessionStore.mjs +422 -0
  77. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -0
  78. package/dist/esm/session/handlers.mjs +219 -0
  79. package/dist/esm/session/handlers.mjs.map +1 -0
  80. package/dist/esm/session/ids.mjs +17 -0
  81. package/dist/esm/session/ids.mjs.map +1 -0
  82. package/dist/esm/session/messageSerialization.mjs +173 -0
  83. package/dist/esm/session/messageSerialization.mjs.map +1 -0
  84. package/dist/esm/stream.mjs +473 -12
  85. package/dist/esm/stream.mjs.map +1 -1
  86. package/dist/esm/summarization/node.mjs +1 -1
  87. package/dist/esm/summarization/node.mjs.map +1 -1
  88. package/dist/esm/tools/ToolNode.mjs +177 -59
  89. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  90. package/dist/esm/tools/eagerEventExecution.mjs +107 -0
  91. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -0
  92. package/dist/esm/tools/handlers.mjs +1 -1
  93. package/dist/esm/tools/handlers.mjs.map +1 -1
  94. package/dist/esm/tools/streamedToolCallSeals.mjs +36 -0
  95. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -0
  96. package/dist/types/events.d.ts +1 -0
  97. package/dist/types/graphs/Graph.d.ts +24 -9
  98. package/dist/types/index.d.ts +1 -0
  99. package/dist/types/llm/openai/index.d.ts +1 -0
  100. package/dist/types/openai/index.d.ts +75 -0
  101. package/dist/types/responses/index.d.ts +97 -0
  102. package/dist/types/run.d.ts +2 -0
  103. package/dist/types/session/AgentSession.d.ts +32 -0
  104. package/dist/types/session/JsonlSessionStore.d.ts +67 -0
  105. package/dist/types/session/handlers.d.ts +8 -0
  106. package/dist/types/session/ids.d.ts +4 -0
  107. package/dist/types/session/index.d.ts +5 -0
  108. package/dist/types/session/messageSerialization.d.ts +7 -0
  109. package/dist/types/session/types.d.ts +191 -0
  110. package/dist/types/tools/ToolNode.d.ts +12 -1
  111. package/dist/types/tools/eagerEventExecution.d.ts +23 -0
  112. package/dist/types/tools/streamedToolCallSeals.d.ts +13 -0
  113. package/dist/types/types/hitl.d.ts +4 -0
  114. package/dist/types/types/run.d.ts +11 -1
  115. package/dist/types/types/tools.d.ts +36 -0
  116. package/package.json +19 -2
  117. package/src/__tests__/stream.eagerEventExecution.test.ts +2458 -0
  118. package/src/agents/AgentContext.ts +7 -2
  119. package/src/agents/__tests__/AgentContext.test.ts +254 -5
  120. package/src/events.ts +29 -0
  121. package/src/graphs/Graph.ts +224 -50
  122. package/src/graphs/MultiAgentGraph.ts +1 -1
  123. package/src/graphs/__tests__/composition.smoke.test.ts +30 -0
  124. package/src/index.ts +3 -0
  125. package/src/llm/anthropic/index.ts +356 -84
  126. package/src/llm/anthropic/llm.spec.ts +64 -0
  127. package/src/llm/custom-chat-models.smoke.test.ts +175 -4
  128. package/src/llm/openai/contentBlocks.test.ts +35 -0
  129. package/src/llm/openai/deepseek.test.ts +201 -2
  130. package/src/llm/openai/index.ts +171 -26
  131. package/src/llm/openai/utils/index.ts +22 -0
  132. package/src/llm/openrouter/index.ts +4 -2
  133. package/src/openai/__tests__/openai.test.ts +337 -0
  134. package/src/openai/index.ts +404 -0
  135. package/src/responses/__tests__/responses.test.ts +652 -0
  136. package/src/responses/index.ts +677 -0
  137. package/src/run.ts +158 -8
  138. package/src/scripts/compare_pi_vs_ours.ts +592 -173
  139. package/src/scripts/session_live.ts +548 -0
  140. package/src/session/AgentSession.ts +1432 -0
  141. package/src/session/JsonlSessionStore.ts +572 -0
  142. package/src/session/__tests__/JsonlSessionStore.test.ts +1410 -0
  143. package/src/session/__tests__/handlers.test.ts +161 -0
  144. package/src/session/handlers.ts +272 -0
  145. package/src/session/ids.ts +17 -0
  146. package/src/session/index.ts +44 -0
  147. package/src/session/messageSerialization.ts +207 -0
  148. package/src/session/types.ts +275 -0
  149. package/src/specs/custom-event-await.test.ts +89 -0
  150. package/src/specs/summarization.test.ts +1 -1
  151. package/src/stream.ts +755 -48
  152. package/src/summarization/node.ts +1 -1
  153. package/src/tools/ToolNode.ts +299 -126
  154. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +373 -0
  155. package/src/tools/__tests__/handlers.test.ts +2 -1
  156. package/src/tools/__tests__/hitl.test.ts +206 -110
  157. package/src/tools/eagerEventExecution.ts +153 -0
  158. package/src/tools/handlers.ts +8 -4
  159. package/src/tools/streamedToolCallSeals.ts +57 -0
  160. package/src/types/hitl.ts +4 -0
  161. package/src/types/run.ts +11 -0
  162. package/src/types/tools.ts +36 -0
  163. package/dist/cjs/llm/text.cjs +0 -69
  164. package/dist/cjs/llm/text.cjs.map +0 -1
  165. package/dist/esm/llm/text.mjs +0 -67
  166. package/dist/esm/llm/text.mjs.map +0 -1
@@ -8,17 +8,11 @@ var function_calling = require('@langchain/core/utils/function_calling');
8
8
  var deepseek = require('@langchain/deepseek');
9
9
  var openai = require('@langchain/openai');
10
10
  var index = require('./utils/index.cjs');
11
- require('../../common/enum.cjs');
12
- require('nanoid');
13
- require('../../messages/core.cjs');
14
- require('@langchain/core/callbacks/dispatch');
15
- require('uuid');
16
- var run = require('../../utils/run.cjs');
17
- require('ai-tokenizer');
18
- require('zod-to-json-schema');
19
11
 
20
12
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
21
13
  const iife = (fn) => fn();
14
+ const STREAM_CHUNK_MIN_SIZE = 4;
15
+ const STREAM_BOUNDARIES = new Set([' ', '.', ',', '!', '?', ';', ':']);
22
16
  function isHeaders(headers) {
23
17
  return (typeof Headers !== 'undefined' &&
24
18
  headers !== null &&
@@ -239,14 +233,113 @@ function getCustomOpenAIClientOptions(owner, options) {
239
233
  };
240
234
  return requestOptions;
241
235
  }
242
- async function* delayStreamChunks(chunks, delay) {
236
+ function findStreamChunkBoundary(text, minSize) {
237
+ if (minSize >= text.length) {
238
+ return text.length;
239
+ }
240
+ for (let position = minSize; position < text.length; position++) {
241
+ if (STREAM_BOUNDARIES.has(text[position])) {
242
+ return position + 1;
243
+ }
244
+ }
245
+ return text.length;
246
+ }
247
+ function splitStreamToken(text) {
248
+ const chunks = [];
249
+ let currentIndex = 0;
250
+ while (currentIndex < text.length) {
251
+ const remainingText = text.slice(currentIndex);
252
+ const chunkSize = findStreamChunkBoundary(remainingText, STREAM_CHUNK_MIN_SIZE);
253
+ chunks.push(text.slice(currentIndex, currentIndex + chunkSize));
254
+ currentIndex += chunkSize;
255
+ }
256
+ return chunks;
257
+ }
258
+ function splitTextGenerationChunk(chunk) {
259
+ const { message } = chunk;
260
+ if (!chunk.text ||
261
+ !(message instanceof messages.AIMessageChunk) ||
262
+ typeof message.content !== 'string' ||
263
+ message.content !== chunk.text ||
264
+ chunk.generationInfo?.logprobs != null ||
265
+ chunk.generationInfo?.finish_reason != null) {
266
+ return [chunk];
267
+ }
268
+ const tokenChunks = splitStreamToken(chunk.text);
269
+ if (tokenChunks.length <= 1) {
270
+ return [chunk];
271
+ }
272
+ let emittedUsage = false;
273
+ return tokenChunks.map((token) => {
274
+ const usageMetadata = emittedUsage && message.usage_metadata != null
275
+ ? undefined
276
+ : message.usage_metadata;
277
+ if (message.usage_metadata != null && !emittedUsage) {
278
+ emittedUsage = true;
279
+ }
280
+ return new outputs.ChatGenerationChunk({
281
+ text: token,
282
+ generationInfo: chunk.generationInfo,
283
+ message: new messages.AIMessageChunk(Object.assign({}, message, {
284
+ content: token,
285
+ usage_metadata: usageMetadata,
286
+ })),
287
+ });
288
+ });
289
+ }
290
+ async function emitStreamChunkCallback(chunk, runManager) {
291
+ await runManager?.handleLLMNewToken(chunk.text, getStreamChunkTokenIndices(chunk), undefined, undefined, undefined, { chunk });
292
+ }
293
+ function getStreamChunkTokenIndices(chunk) {
294
+ const prompt = chunk.generationInfo?.prompt;
295
+ const completion = chunk.generationInfo?.completion;
296
+ if (typeof prompt === 'number' && typeof completion === 'number') {
297
+ return { prompt, completion };
298
+ }
299
+ return undefined;
300
+ }
301
+ async function* delayStreamChunks(chunks, delay, signal, runManager) {
302
+ let lastYieldedAt;
243
303
  for await (const chunk of chunks) {
244
- yield chunk;
245
- if (delay != null) {
246
- await run.sleep(delay);
304
+ const outputChunks = delay != null && delay > 0 ? splitTextGenerationChunk(chunk) : [chunk];
305
+ for (const outputChunk of outputChunks) {
306
+ signal?.throwIfAborted();
307
+ if (delay != null && delay > 0 && lastYieldedAt != null) {
308
+ const timeSinceLastYield = Date.now() - lastYieldedAt;
309
+ const timeToWait = Math.max(0, delay - timeSinceLastYield);
310
+ if (timeToWait > 0) {
311
+ await sleepWithAbort(timeToWait, signal);
312
+ }
313
+ }
314
+ signal?.throwIfAborted();
315
+ lastYieldedAt = Date.now();
316
+ await emitStreamChunkCallback(outputChunk, runManager);
317
+ signal?.throwIfAborted();
318
+ yield outputChunk;
247
319
  }
248
320
  }
249
321
  }
322
+ async function sleepWithAbort(delay, signal) {
323
+ if (delay <= 0) {
324
+ return;
325
+ }
326
+ signal?.throwIfAborted();
327
+ await new Promise((resolve, reject) => {
328
+ const timeout = setTimeout(() => {
329
+ signal?.removeEventListener('abort', onAbort);
330
+ resolve();
331
+ }, delay);
332
+ const onAbort = () => {
333
+ clearTimeout(timeout);
334
+ signal?.removeEventListener('abort', onAbort);
335
+ reject(signal?.reason ?? new Error('AbortError: User aborted request.'));
336
+ };
337
+ signal?.addEventListener('abort', onAbort, { once: true });
338
+ if (signal?.aborted === true) {
339
+ onAbort();
340
+ }
341
+ });
342
+ }
250
343
  function createAbortHandler(controller) {
251
344
  return function () {
252
345
  controller.abort();
@@ -281,7 +374,7 @@ class CustomOpenAIClient extends openai.OpenAIClient {
281
374
  this.abortHandler = handler;
282
375
  if (signal)
283
376
  signal.addEventListener('abort', handler, { once: true });
284
- const timeout = setTimeout(() => handler, ms);
377
+ const timeout = setTimeout(handler, ms);
285
378
  const fetchOptions = {
286
379
  signal: controller.signal,
287
380
  ...options,
@@ -308,7 +401,7 @@ class CustomAzureOpenAIClient extends openai$1.AzureOpenAI {
308
401
  this.abortHandler = handler;
309
402
  if (signal)
310
403
  signal.addEventListener('abort', handler, { once: true });
311
- const timeout = setTimeout(() => handler, ms);
404
+ const timeout = setTimeout(handler, ms);
312
405
  const fetchOptions = {
313
406
  signal: controller.signal,
314
407
  ...options,
@@ -775,7 +868,7 @@ class ChatOpenAI extends openai.ChatOpenAI {
775
868
  return this.getReasoningParams(options);
776
869
  }
777
870
  async *_streamResponseChunks(messages, options, runManager) {
778
- yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
871
+ yield* delayStreamChunks(super._streamResponseChunks(messages, options, undefined), this._lc_stream_delay, options.signal, runManager);
779
872
  }
780
873
  }
781
874
  class AzureChatOpenAI extends openai.AzureChatOpenAI {
@@ -855,7 +948,7 @@ class AzureChatOpenAI extends openai.AzureChatOpenAI {
855
948
  return requestOptions;
856
949
  }
857
950
  async *_streamResponseChunks(messages, options, runManager) {
858
- yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
951
+ yield* delayStreamChunks(super._streamResponseChunks(messages, options, undefined), this._lc_stream_delay, options.signal, runManager);
859
952
  }
860
953
  }
861
954
  class ChatDeepSeek extends deepseek.ChatDeepSeek {
@@ -942,7 +1035,7 @@ class ChatDeepSeek extends deepseek.ChatDeepSeek {
942
1035
  return requestOptions;
943
1036
  }
944
1037
  async *_streamResponseChunks(messages, options, runManager) {
945
- yield* delayStreamChunks(this._streamResponseChunksWithReasoning(messages, options, runManager), this._lc_stream_delay);
1038
+ yield* delayStreamChunks(this._streamResponseChunksWithReasoning(messages, options, undefined), this._lc_stream_delay, options.signal, runManager);
946
1039
  }
947
1040
  /** Parses raw `<think>` fallback tags across chunks and emits sanitized DeepSeek stream chunks. */
948
1041
  async *_streamResponseChunksWithReasoning(messages$1, options, runManager) {
@@ -1156,12 +1249,7 @@ class ChatDeepSeek extends deepseek.ChatDeepSeek {
1156
1249
  await runManager?.handleLLMNewToken(chunk.text, this._getDeepSeekTokenIndices(chunk), undefined, undefined, undefined, { chunk });
1157
1250
  }
1158
1251
  _getDeepSeekTokenIndices(chunk) {
1159
- const prompt = chunk.generationInfo?.prompt;
1160
- const completion = chunk.generationInfo?.completion;
1161
- if (typeof prompt === 'number' && typeof completion === 'number') {
1162
- return { prompt, completion };
1163
- }
1164
- return undefined;
1252
+ return getStreamChunkTokenIndices(chunk);
1165
1253
  }
1166
1254
  _getDeepSeekPartialTagSplitIndex(text, tag) {
1167
1255
  for (let i = tag.length - 1; i >= 1; i--) {
@@ -1229,7 +1317,7 @@ class ChatXAI extends xai.ChatXAI {
1229
1317
  return requestOptions;
1230
1318
  }
1231
1319
  async *_streamResponseChunks(messages, options, runManager) {
1232
- yield* delayStreamChunks(super._streamResponseChunks(messages, options, runManager), this._lc_stream_delay);
1320
+ yield* delayStreamChunks(super._streamResponseChunks(messages, options, undefined), this._lc_stream_delay, options.signal, runManager);
1233
1321
  }
1234
1322
  }
1235
1323
 
@@ -1241,6 +1329,7 @@ exports.ChatXAI = ChatXAI;
1241
1329
  exports.CustomAzureOpenAIClient = CustomAzureOpenAIClient;
1242
1330
  exports.CustomOpenAIClient = CustomOpenAIClient;
1243
1331
  exports._convertToOpenAITool = _convertToOpenAITool;
1332
+ exports.emitStreamChunkCallback = emitStreamChunkCallback;
1244
1333
  exports.isHeaders = isHeaders;
1245
1334
  exports.normalizeHeaders = normalizeHeaders;
1246
1335
  //# sourceMappingURL=index.cjs.map