@librechat/agents 2.4.321 → 3.0.0-rc1

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 (266) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +218 -0
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -0
  3. package/dist/cjs/common/enum.cjs +14 -5
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/events.cjs +10 -6
  6. package/dist/cjs/events.cjs.map +1 -1
  7. package/dist/cjs/graphs/Graph.cjs +309 -212
  8. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs +322 -0
  10. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
  11. package/dist/cjs/llm/anthropic/index.cjs +54 -9
  12. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  13. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  14. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +52 -6
  15. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  16. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +22 -2
  17. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
  19. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
  20. package/dist/cjs/llm/google/index.cjs +144 -0
  21. package/dist/cjs/llm/google/index.cjs.map +1 -0
  22. package/dist/cjs/llm/google/utils/common.cjs +477 -0
  23. package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
  24. package/dist/cjs/llm/ollama/index.cjs +67 -0
  25. package/dist/cjs/llm/ollama/index.cjs.map +1 -0
  26. package/dist/cjs/llm/ollama/utils.cjs +158 -0
  27. package/dist/cjs/llm/ollama/utils.cjs.map +1 -0
  28. package/dist/cjs/llm/openai/index.cjs +389 -3
  29. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  30. package/dist/cjs/llm/openai/utils/index.cjs +672 -0
  31. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
  32. package/dist/cjs/llm/providers.cjs +15 -15
  33. package/dist/cjs/llm/providers.cjs.map +1 -1
  34. package/dist/cjs/llm/text.cjs +14 -3
  35. package/dist/cjs/llm/text.cjs.map +1 -1
  36. package/dist/cjs/llm/vertexai/index.cjs +330 -0
  37. package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
  38. package/dist/cjs/main.cjs +11 -0
  39. package/dist/cjs/main.cjs.map +1 -1
  40. package/dist/cjs/run.cjs +120 -81
  41. package/dist/cjs/run.cjs.map +1 -1
  42. package/dist/cjs/stream.cjs +85 -51
  43. package/dist/cjs/stream.cjs.map +1 -1
  44. package/dist/cjs/tools/ToolNode.cjs +10 -4
  45. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  46. package/dist/cjs/tools/handlers.cjs +119 -13
  47. package/dist/cjs/tools/handlers.cjs.map +1 -1
  48. package/dist/cjs/tools/search/anthropic.cjs +40 -0
  49. package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
  50. package/dist/cjs/tools/search/firecrawl.cjs +61 -13
  51. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  52. package/dist/cjs/tools/search/format.cjs +9 -3
  53. package/dist/cjs/tools/search/format.cjs.map +1 -1
  54. package/dist/cjs/tools/search/rerankers.cjs +35 -50
  55. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  56. package/dist/cjs/tools/search/schema.cjs +70 -0
  57. package/dist/cjs/tools/search/schema.cjs.map +1 -0
  58. package/dist/cjs/tools/search/search.cjs +145 -38
  59. package/dist/cjs/tools/search/search.cjs.map +1 -1
  60. package/dist/cjs/tools/search/tool.cjs +165 -48
  61. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  62. package/dist/cjs/tools/search/utils.cjs +34 -5
  63. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  64. package/dist/cjs/utils/events.cjs +31 -0
  65. package/dist/cjs/utils/events.cjs.map +1 -0
  66. package/dist/cjs/utils/title.cjs +57 -21
  67. package/dist/cjs/utils/title.cjs.map +1 -1
  68. package/dist/cjs/utils/tokens.cjs +54 -7
  69. package/dist/cjs/utils/tokens.cjs.map +1 -1
  70. package/dist/esm/agents/AgentContext.mjs +216 -0
  71. package/dist/esm/agents/AgentContext.mjs.map +1 -0
  72. package/dist/esm/common/enum.mjs +15 -6
  73. package/dist/esm/common/enum.mjs.map +1 -1
  74. package/dist/esm/events.mjs +10 -6
  75. package/dist/esm/events.mjs.map +1 -1
  76. package/dist/esm/graphs/Graph.mjs +311 -214
  77. package/dist/esm/graphs/Graph.mjs.map +1 -1
  78. package/dist/esm/graphs/MultiAgentGraph.mjs +320 -0
  79. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
  80. package/dist/esm/llm/anthropic/index.mjs +54 -9
  81. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  82. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  83. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +52 -6
  84. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  85. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +22 -2
  86. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  87. package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
  88. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
  89. package/dist/esm/llm/google/index.mjs +142 -0
  90. package/dist/esm/llm/google/index.mjs.map +1 -0
  91. package/dist/esm/llm/google/utils/common.mjs +471 -0
  92. package/dist/esm/llm/google/utils/common.mjs.map +1 -0
  93. package/dist/esm/llm/ollama/index.mjs +65 -0
  94. package/dist/esm/llm/ollama/index.mjs.map +1 -0
  95. package/dist/esm/llm/ollama/utils.mjs +155 -0
  96. package/dist/esm/llm/ollama/utils.mjs.map +1 -0
  97. package/dist/esm/llm/openai/index.mjs +388 -4
  98. package/dist/esm/llm/openai/index.mjs.map +1 -1
  99. package/dist/esm/llm/openai/utils/index.mjs +666 -0
  100. package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
  101. package/dist/esm/llm/providers.mjs +5 -5
  102. package/dist/esm/llm/providers.mjs.map +1 -1
  103. package/dist/esm/llm/text.mjs +14 -3
  104. package/dist/esm/llm/text.mjs.map +1 -1
  105. package/dist/esm/llm/vertexai/index.mjs +328 -0
  106. package/dist/esm/llm/vertexai/index.mjs.map +1 -0
  107. package/dist/esm/main.mjs +6 -5
  108. package/dist/esm/main.mjs.map +1 -1
  109. package/dist/esm/run.mjs +121 -83
  110. package/dist/esm/run.mjs.map +1 -1
  111. package/dist/esm/stream.mjs +87 -54
  112. package/dist/esm/stream.mjs.map +1 -1
  113. package/dist/esm/tools/ToolNode.mjs +10 -4
  114. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  115. package/dist/esm/tools/handlers.mjs +119 -15
  116. package/dist/esm/tools/handlers.mjs.map +1 -1
  117. package/dist/esm/tools/search/anthropic.mjs +37 -0
  118. package/dist/esm/tools/search/anthropic.mjs.map +1 -0
  119. package/dist/esm/tools/search/firecrawl.mjs +61 -13
  120. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  121. package/dist/esm/tools/search/format.mjs +10 -4
  122. package/dist/esm/tools/search/format.mjs.map +1 -1
  123. package/dist/esm/tools/search/rerankers.mjs +35 -50
  124. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  125. package/dist/esm/tools/search/schema.mjs +61 -0
  126. package/dist/esm/tools/search/schema.mjs.map +1 -0
  127. package/dist/esm/tools/search/search.mjs +146 -39
  128. package/dist/esm/tools/search/search.mjs.map +1 -1
  129. package/dist/esm/tools/search/tool.mjs +164 -47
  130. package/dist/esm/tools/search/tool.mjs.map +1 -1
  131. package/dist/esm/tools/search/utils.mjs +33 -6
  132. package/dist/esm/tools/search/utils.mjs.map +1 -1
  133. package/dist/esm/utils/events.mjs +29 -0
  134. package/dist/esm/utils/events.mjs.map +1 -0
  135. package/dist/esm/utils/title.mjs +57 -22
  136. package/dist/esm/utils/title.mjs.map +1 -1
  137. package/dist/esm/utils/tokens.mjs +54 -8
  138. package/dist/esm/utils/tokens.mjs.map +1 -1
  139. package/dist/types/agents/AgentContext.d.ts +91 -0
  140. package/dist/types/common/enum.d.ts +15 -6
  141. package/dist/types/events.d.ts +5 -4
  142. package/dist/types/graphs/Graph.d.ts +64 -67
  143. package/dist/types/graphs/MultiAgentGraph.d.ts +37 -0
  144. package/dist/types/graphs/index.d.ts +1 -0
  145. package/dist/types/llm/anthropic/index.d.ts +11 -0
  146. package/dist/types/llm/anthropic/types.d.ts +9 -3
  147. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  148. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +4 -4
  149. package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
  150. package/dist/types/llm/google/index.d.ts +13 -0
  151. package/dist/types/llm/google/types.d.ts +32 -0
  152. package/dist/types/llm/google/utils/common.d.ts +19 -0
  153. package/dist/types/llm/google/utils/tools.d.ts +10 -0
  154. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
  155. package/dist/types/llm/ollama/index.d.ts +7 -0
  156. package/dist/types/llm/ollama/utils.d.ts +7 -0
  157. package/dist/types/llm/openai/index.d.ts +72 -3
  158. package/dist/types/llm/openai/types.d.ts +10 -0
  159. package/dist/types/llm/openai/utils/index.d.ts +20 -0
  160. package/dist/types/llm/text.d.ts +1 -1
  161. package/dist/types/llm/vertexai/index.d.ts +293 -0
  162. package/dist/types/messages/reducer.d.ts +9 -0
  163. package/dist/types/run.d.ts +19 -12
  164. package/dist/types/scripts/ant_web_search.d.ts +1 -0
  165. package/dist/types/scripts/args.d.ts +2 -1
  166. package/dist/types/scripts/handoff-test.d.ts +1 -0
  167. package/dist/types/scripts/multi-agent-conditional.d.ts +1 -0
  168. package/dist/types/scripts/multi-agent-parallel.d.ts +1 -0
  169. package/dist/types/scripts/multi-agent-sequence.d.ts +1 -0
  170. package/dist/types/scripts/multi-agent-test.d.ts +1 -0
  171. package/dist/types/stream.d.ts +10 -3
  172. package/dist/types/tools/CodeExecutor.d.ts +2 -2
  173. package/dist/types/tools/ToolNode.d.ts +1 -1
  174. package/dist/types/tools/handlers.d.ts +17 -4
  175. package/dist/types/tools/search/anthropic.d.ts +16 -0
  176. package/dist/types/tools/search/firecrawl.d.ts +16 -0
  177. package/dist/types/tools/search/rerankers.d.ts +8 -5
  178. package/dist/types/tools/search/schema.d.ts +16 -0
  179. package/dist/types/tools/search/tool.d.ts +13 -0
  180. package/dist/types/tools/search/types.d.ts +64 -9
  181. package/dist/types/tools/search/utils.d.ts +9 -2
  182. package/dist/types/types/graph.d.ts +95 -15
  183. package/dist/types/types/llm.d.ts +24 -10
  184. package/dist/types/types/run.d.ts +46 -8
  185. package/dist/types/types/stream.d.ts +16 -2
  186. package/dist/types/types/tools.d.ts +1 -1
  187. package/dist/types/utils/events.d.ts +6 -0
  188. package/dist/types/utils/title.d.ts +2 -1
  189. package/dist/types/utils/tokens.d.ts +24 -0
  190. package/package.json +35 -18
  191. package/src/agents/AgentContext.ts +315 -0
  192. package/src/common/enum.ts +14 -5
  193. package/src/events.ts +24 -13
  194. package/src/graphs/Graph.ts +495 -312
  195. package/src/graphs/MultiAgentGraph.ts +381 -0
  196. package/src/graphs/index.ts +2 -1
  197. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  198. package/src/llm/anthropic/index.ts +78 -13
  199. package/src/llm/anthropic/llm.spec.ts +491 -115
  200. package/src/llm/anthropic/types.ts +39 -3
  201. package/src/llm/anthropic/utils/message_inputs.ts +67 -11
  202. package/src/llm/anthropic/utils/message_outputs.ts +21 -2
  203. package/src/llm/anthropic/utils/output_parsers.ts +25 -6
  204. package/src/llm/anthropic/utils/tools.ts +29 -0
  205. package/src/llm/google/index.ts +218 -0
  206. package/src/llm/google/types.ts +43 -0
  207. package/src/llm/google/utils/common.ts +646 -0
  208. package/src/llm/google/utils/tools.ts +160 -0
  209. package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
  210. package/src/llm/ollama/index.ts +89 -0
  211. package/src/llm/ollama/utils.ts +193 -0
  212. package/src/llm/openai/index.ts +600 -14
  213. package/src/llm/openai/types.ts +24 -0
  214. package/src/llm/openai/utils/index.ts +912 -0
  215. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
  216. package/src/llm/providers.ts +10 -9
  217. package/src/llm/text.ts +26 -7
  218. package/src/llm/vertexai/index.ts +360 -0
  219. package/src/messages/reducer.ts +80 -0
  220. package/src/run.ts +181 -112
  221. package/src/scripts/ant_web_search.ts +158 -0
  222. package/src/scripts/args.ts +12 -8
  223. package/src/scripts/cli4.ts +29 -21
  224. package/src/scripts/cli5.ts +29 -21
  225. package/src/scripts/code_exec.ts +54 -23
  226. package/src/scripts/code_exec_files.ts +48 -17
  227. package/src/scripts/code_exec_simple.ts +46 -27
  228. package/src/scripts/handoff-test.ts +135 -0
  229. package/src/scripts/image.ts +52 -20
  230. package/src/scripts/multi-agent-conditional.ts +220 -0
  231. package/src/scripts/multi-agent-example-output.md +110 -0
  232. package/src/scripts/multi-agent-parallel.ts +337 -0
  233. package/src/scripts/multi-agent-sequence.ts +212 -0
  234. package/src/scripts/multi-agent-test.ts +186 -0
  235. package/src/scripts/search.ts +4 -12
  236. package/src/scripts/simple.ts +25 -10
  237. package/src/scripts/tools.ts +48 -18
  238. package/src/specs/anthropic.simple.test.ts +150 -34
  239. package/src/specs/azure.simple.test.ts +325 -0
  240. package/src/specs/openai.simple.test.ts +140 -33
  241. package/src/specs/openrouter.simple.test.ts +107 -0
  242. package/src/specs/prune.test.ts +4 -9
  243. package/src/specs/reasoning.test.ts +80 -44
  244. package/src/specs/token-memoization.test.ts +39 -0
  245. package/src/stream.test.ts +94 -0
  246. package/src/stream.ts +139 -60
  247. package/src/tools/ToolNode.ts +21 -7
  248. package/src/tools/handlers.ts +192 -18
  249. package/src/tools/search/anthropic.ts +51 -0
  250. package/src/tools/search/firecrawl.ts +78 -24
  251. package/src/tools/search/format.ts +10 -5
  252. package/src/tools/search/rerankers.ts +50 -62
  253. package/src/tools/search/schema.ts +63 -0
  254. package/src/tools/search/search.ts +167 -34
  255. package/src/tools/search/tool.ts +222 -46
  256. package/src/tools/search/types.ts +65 -10
  257. package/src/tools/search/utils.ts +37 -5
  258. package/src/types/graph.ts +272 -103
  259. package/src/types/llm.ts +25 -12
  260. package/src/types/run.ts +51 -13
  261. package/src/types/stream.ts +22 -1
  262. package/src/types/tools.ts +16 -10
  263. package/src/utils/events.ts +32 -0
  264. package/src/utils/llmConfig.ts +20 -8
  265. package/src/utils/title.ts +104 -30
  266. package/src/utils/tokens.ts +69 -10
@@ -0,0 +1,6 @@
1
+ import type { RunnableConfig } from '@langchain/core/runnables';
2
+ /**
3
+ * Safely dispatches a custom event and properly awaits it to avoid
4
+ * race conditions where events are dispatched after run cleanup.
5
+ */
6
+ export declare function safeDispatchCustomEvent(event: string, payload: unknown, config?: RunnableConfig): Promise<void>;
@@ -1,3 +1,4 @@
1
1
  import type { Runnable } from '@langchain/core/runnables';
2
- import * as t from '@/types';
2
+ import type * as t from '@/types';
3
3
  export declare const createTitleRunnable: (model: t.ChatModelInstance, _titlePrompt?: string) => Promise<Runnable>;
4
+ export declare const createCompletionTitleRunnable: (model: t.ChatModelInstance, titlePrompt?: string) => Promise<Runnable>;
@@ -1,3 +1,27 @@
1
1
  import type { BaseMessage } from '@langchain/core/messages';
2
2
  export declare function getTokenCountForMessage(message: BaseMessage, getTokenCount: (text: string) => number): number;
3
+ /**
4
+ * Creates a singleton token counter function that reuses the same encoder instance.
5
+ * This avoids creating multiple function closures and prevents potential memory issues.
6
+ */
3
7
  export declare const createTokenCounter: () => Promise<(message: BaseMessage) => number>;
8
+ /**
9
+ * Utility to manage the token encoder lifecycle explicitly.
10
+ * Useful for applications that need fine-grained control over resource management.
11
+ */
12
+ export declare const TokenEncoderManager: {
13
+ /**
14
+ * Pre-initializes the encoder. This can be called during app startup
15
+ * to avoid lazy loading delays later.
16
+ */
17
+ initialize(): Promise<void>;
18
+ /**
19
+ * Clears the cached encoder and token counter.
20
+ * Useful for testing or when you need to force a fresh reload.
21
+ */
22
+ reset(): void;
23
+ /**
24
+ * Checks if the encoder has been initialized.
25
+ */
26
+ isInitialized(): boolean;
27
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "2.4.321",
3
+ "version": "3.0.00-rc1",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -47,14 +47,19 @@
47
47
  "image": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/image.ts --provider 'google' --name 'Jo' --location 'New York, NY'",
48
48
  "code_exec_files": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec_files.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
49
49
  "code_exec_simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec_simple.ts --provider 'google' --name 'Jo' --location 'New York, NY'",
50
- "simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'xai' --name 'Jo' --location 'New York, NY'",
50
+ "simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
51
51
  "caching": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/caching.ts --name 'Jo' --location 'New York, NY'",
52
52
  "thinking": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/thinking.ts --name 'Jo' --location 'New York, NY'",
53
53
  "memory": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/memory.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
54
- "tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'alibaba' --name 'Jo' --location 'New York, NY'",
54
+ "tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'bedrock' --name 'Jo' --location 'New York, NY'",
55
55
  "search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/search.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
56
+ "ant_web_search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/ant_web_search.ts --name 'Jo' --location 'New York, NY'",
56
57
  "abort": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/abort.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
57
58
  "start:cli2": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli2.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
59
+ "multi-agent-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-test.ts",
60
+ "multi-agent-parallel": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-parallel.ts",
61
+ "multi-agent-sequence": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-sequence.ts",
62
+ "multi-agent-conditional": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-conditional.ts",
58
63
  "script2": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/proto/example_test.ts",
59
64
  "script3": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/proto/example_test_anthropic.ts",
60
65
  "script4": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli4.ts --name 'Jo' --location 'New York, NY'",
@@ -65,35 +70,46 @@
65
70
  "start:collab": "node --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/main.ts",
66
71
  "start:collab5": "node --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/collab_design_v5.ts",
67
72
  "start:dev": "node --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/main.ts",
73
+ "supervised": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/supervised.ts --provider anthropic --name Jo --location \"New York, NY\"",
68
74
  "test": "jest",
75
+ "test:memory": "NODE_OPTIONS='--expose-gc' npx jest src/specs/title.memory-leak.test.ts",
76
+ "test:all": "npm test -- --testPathIgnorePatterns=title.memory-leak.test.ts && npm run test:memory",
69
77
  "reinstall": "npm run clean && npm ci && rm -rf ./dist && npm run build",
70
78
  "re": "bun run clean && bun install && rm -rf ./dist && turbo build",
71
79
  "lint": "eslint \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\" --fix",
72
80
  "format": "prettier --write ."
73
81
  },
82
+ "overrides": {
83
+ "@langchain/openai": "0.5.18",
84
+ "@browserbasehq/stagehand": {
85
+ "openai": "$openai"
86
+ }
87
+ },
74
88
  "dependencies": {
75
- "@langchain/anthropic": "^0.3.20",
76
- "@langchain/aws": "0.1.8",
77
- "@langchain/community": "^0.3.42",
78
- "@langchain/core": "^0.3.55",
79
- "@langchain/deepseek": "^0.0.1",
80
- "@langchain/google-genai": "^0.2.8",
81
- "@langchain/google-vertexai": "^0.2.8",
82
- "@langchain/langgraph": "^0.2.72",
83
- "@langchain/mistralai": "^0.2.0",
84
- "@langchain/ollama": "^0.2.0",
85
- "@langchain/openai": "^0.5.10",
86
- "@langchain/xai": "^0.0.2",
89
+ "@langchain/anthropic": "^0.3.26",
90
+ "@langchain/aws": "^0.1.12",
91
+ "@langchain/community": "^0.3.47",
92
+ "@langchain/core": "^0.3.72",
93
+ "@langchain/deepseek": "^0.0.2",
94
+ "@langchain/google-genai": "^0.2.13",
95
+ "@langchain/google-vertexai": "^0.2.13",
96
+ "@langchain/langgraph": "^0.4.9",
97
+ "@langchain/mistralai": "^0.2.1",
98
+ "@langchain/ollama": "^0.2.3",
99
+ "@langchain/openai": "0.5.18",
100
+ "@langchain/xai": "^0.0.3",
87
101
  "cheerio": "^1.0.0",
88
102
  "dotenv": "^16.4.7",
89
103
  "https-proxy-agent": "^7.0.6",
90
- "nanoid": "^3.3.7"
104
+ "nanoid": "^3.3.7",
105
+ "openai": "^5.10.1"
91
106
  },
92
107
  "imports": {
93
108
  "@/*": "./src/*",
94
109
  "~/*": "./*"
95
110
  },
96
111
  "devDependencies": {
112
+ "@anthropic-ai/vertex-sdk": "^0.12.0",
97
113
  "@eslint/compat": "^1.2.7",
98
114
  "@rollup/plugin-alias": "^5.1.0",
99
115
  "@rollup/plugin-commonjs": "^28.0.3",
@@ -107,7 +123,7 @@
107
123
  "@types/yargs-parser": "^21.0.3",
108
124
  "@typescript-eslint/eslint-plugin": "^8.24.0",
109
125
  "@typescript-eslint/parser": "^8.24.0",
110
- "eslint": "^9.22.0",
126
+ "eslint": "^9.31.0",
111
127
  "eslint-import-resolver-typescript": "^3.7.0",
112
128
  "eslint-plugin-import": "^2.31.0",
113
129
  "husky": "^9.1.7",
@@ -122,7 +138,8 @@
122
138
  "tsc-alias": "^1.8.10",
123
139
  "tsconfig-paths": "^4.2.0",
124
140
  "tslib": "^2.6.3",
125
- "typescript": "^5.5.3"
141
+ "typescript": "^5.5.3",
142
+ "winston": "^3.17.0"
126
143
  },
127
144
  "lint-staged": {
128
145
  "*.{js,ts}": [
@@ -0,0 +1,315 @@
1
+ /* eslint-disable no-console */
2
+ // src/agents/AgentContext.ts
3
+ import { zodToJsonSchema } from 'zod-to-json-schema';
4
+ import { SystemMessage } from '@langchain/core/messages';
5
+ import { RunnableLambda } from '@langchain/core/runnables';
6
+ import type {
7
+ UsageMetadata,
8
+ BaseMessage,
9
+ BaseMessageFields,
10
+ } from '@langchain/core/messages';
11
+ import type { RunnableConfig, Runnable } from '@langchain/core/runnables';
12
+ import type * as t from '@/types';
13
+ import type { createPruneMessages } from '@/messages';
14
+ import { ContentTypes, Providers } from '@/common';
15
+
16
+ /**
17
+ * Encapsulates agent-specific state that can vary between agents in a multi-agent system
18
+ */
19
+ export class AgentContext {
20
+ /**
21
+ * Create an AgentContext from configuration with token accounting initialization
22
+ */
23
+ static fromConfig(
24
+ agentConfig: t.AgentInputs,
25
+ tokenCounter?: t.TokenCounter,
26
+ indexTokenCountMap?: Record<string, number>
27
+ ): AgentContext {
28
+ const {
29
+ agentId,
30
+ provider,
31
+ clientOptions,
32
+ tools,
33
+ toolMap,
34
+ toolEnd,
35
+ instructions,
36
+ additional_instructions,
37
+ streamBuffer,
38
+ maxContextTokens,
39
+ reasoningKey,
40
+ } = agentConfig;
41
+
42
+ const agentContext = new AgentContext({
43
+ agentId,
44
+ provider,
45
+ clientOptions,
46
+ maxContextTokens,
47
+ streamBuffer,
48
+ tools,
49
+ toolMap,
50
+ instructions,
51
+ additionalInstructions: additional_instructions,
52
+ reasoningKey,
53
+ toolEnd,
54
+ instructionTokens: 0,
55
+ tokenCounter,
56
+ });
57
+
58
+ if (tokenCounter) {
59
+ const tokenMap = indexTokenCountMap || {};
60
+ agentContext.indexTokenCountMap = tokenMap;
61
+ agentContext.tokenCalculationPromise = agentContext
62
+ .calculateInstructionTokens(tokenCounter)
63
+ .then(() => {
64
+ // Update token map with instruction tokens
65
+ agentContext.updateTokenMapWithInstructions(tokenMap);
66
+ })
67
+ .catch((err) => {
68
+ console.error('Error calculating instruction tokens:', err);
69
+ });
70
+ } else if (indexTokenCountMap) {
71
+ agentContext.indexTokenCountMap = indexTokenCountMap;
72
+ }
73
+
74
+ return agentContext;
75
+ }
76
+
77
+ /** Agent identifier */
78
+ agentId: string;
79
+ /** Provider for this specific agent */
80
+ provider: Providers;
81
+ /** Client options for this agent */
82
+ clientOptions?: t.ClientOptions;
83
+ /** Token count map indexed by message position */
84
+ indexTokenCountMap: Record<string, number | undefined> = {};
85
+ /** Maximum context tokens for this agent */
86
+ maxContextTokens?: number;
87
+ /** Current usage metadata for this agent */
88
+ currentUsage?: Partial<UsageMetadata>;
89
+ /** Prune messages function configured for this agent */
90
+ pruneMessages?: ReturnType<typeof createPruneMessages>;
91
+ /** Token counter function for this agent */
92
+ tokenCounter?: t.TokenCounter;
93
+ /** Instructions/system message token count */
94
+ instructionTokens: number = 0;
95
+ /** The amount of time that should pass before another consecutive API call */
96
+ streamBuffer?: number;
97
+ /** Last stream call timestamp for rate limiting */
98
+ lastStreamCall?: number;
99
+ /** Tools available to this agent */
100
+ tools?: t.GraphTools;
101
+ /** Tool map for this agent */
102
+ toolMap?: t.ToolMap;
103
+ /** Instructions for this agent */
104
+ instructions?: string;
105
+ /** Additional instructions for this agent */
106
+ additionalInstructions?: string;
107
+ /** Reasoning key for this agent */
108
+ reasoningKey: 'reasoning_content' | 'reasoning' = 'reasoning_content';
109
+ /** Last token for reasoning detection */
110
+ lastToken?: string;
111
+ /** Token type switch state */
112
+ tokenTypeSwitch?: 'reasoning' | 'content';
113
+ /** Current token type being processed */
114
+ currentTokenType: ContentTypes.TEXT | ContentTypes.THINK | 'think_and_text' =
115
+ ContentTypes.TEXT;
116
+ /** Whether tools should end the workflow */
117
+ toolEnd: boolean = false;
118
+ /** System runnable for this agent */
119
+ systemRunnable?: Runnable<
120
+ BaseMessage[],
121
+ (BaseMessage | SystemMessage)[],
122
+ RunnableConfig<Record<string, unknown>>
123
+ >;
124
+ /** Promise for token calculation initialization */
125
+ tokenCalculationPromise?: Promise<void>;
126
+
127
+ constructor({
128
+ agentId,
129
+ provider,
130
+ clientOptions,
131
+ maxContextTokens,
132
+ streamBuffer,
133
+ tokenCounter,
134
+ tools,
135
+ toolMap,
136
+ instructions,
137
+ additionalInstructions,
138
+ reasoningKey,
139
+ toolEnd,
140
+ instructionTokens,
141
+ }: {
142
+ agentId: string;
143
+ provider: Providers;
144
+ clientOptions?: t.ClientOptions;
145
+ maxContextTokens?: number;
146
+ streamBuffer?: number;
147
+ tokenCounter?: t.TokenCounter;
148
+ tools?: t.GraphTools;
149
+ toolMap?: t.ToolMap;
150
+ instructions?: string;
151
+ additionalInstructions?: string;
152
+ reasoningKey?: 'reasoning_content' | 'reasoning';
153
+ toolEnd?: boolean;
154
+ instructionTokens?: number;
155
+ }) {
156
+ this.agentId = agentId;
157
+ this.provider = provider;
158
+ this.clientOptions = clientOptions;
159
+ this.maxContextTokens = maxContextTokens;
160
+ this.streamBuffer = streamBuffer;
161
+ this.tokenCounter = tokenCounter;
162
+ this.tools = tools;
163
+ this.toolMap = toolMap;
164
+ this.instructions = instructions;
165
+ this.additionalInstructions = additionalInstructions;
166
+ if (reasoningKey) {
167
+ this.reasoningKey = reasoningKey;
168
+ }
169
+ if (toolEnd !== undefined) {
170
+ this.toolEnd = toolEnd;
171
+ }
172
+ if (instructionTokens !== undefined) {
173
+ this.instructionTokens = instructionTokens;
174
+ }
175
+
176
+ this.systemRunnable = this.createSystemRunnable();
177
+ }
178
+
179
+ /**
180
+ * Create system runnable from instructions and calculate tokens if tokenCounter is available
181
+ */
182
+ private createSystemRunnable():
183
+ | Runnable<
184
+ BaseMessage[],
185
+ (BaseMessage | SystemMessage)[],
186
+ RunnableConfig<Record<string, unknown>>
187
+ >
188
+ | undefined {
189
+ let finalInstructions: string | BaseMessageFields | undefined =
190
+ this.instructions;
191
+
192
+ if (
193
+ this.additionalInstructions != null &&
194
+ this.additionalInstructions !== ''
195
+ ) {
196
+ finalInstructions =
197
+ finalInstructions != null && finalInstructions
198
+ ? `${finalInstructions}\n\n${this.additionalInstructions}`
199
+ : this.additionalInstructions;
200
+ }
201
+
202
+ // Handle Anthropic prompt caching
203
+ if (
204
+ finalInstructions != null &&
205
+ finalInstructions !== '' &&
206
+ this.provider === Providers.ANTHROPIC
207
+ ) {
208
+ const anthropicOptions = this.clientOptions as
209
+ | t.AnthropicClientOptions
210
+ | undefined;
211
+ const defaultHeaders = anthropicOptions?.clientOptions?.defaultHeaders as
212
+ | Record<string, string>
213
+ | undefined;
214
+ const anthropicBeta = defaultHeaders?.['anthropic-beta'];
215
+ if (
216
+ typeof anthropicBeta === 'string' &&
217
+ anthropicBeta.includes('prompt-caching')
218
+ ) {
219
+ finalInstructions = {
220
+ content: [
221
+ {
222
+ type: 'text',
223
+ text: this.instructions,
224
+ cache_control: { type: 'ephemeral' },
225
+ },
226
+ ],
227
+ };
228
+ }
229
+ }
230
+
231
+ if (finalInstructions != null && finalInstructions !== '') {
232
+ const systemMessage = new SystemMessage(finalInstructions);
233
+
234
+ if (this.tokenCounter) {
235
+ this.instructionTokens += this.tokenCounter(systemMessage);
236
+ }
237
+
238
+ return RunnableLambda.from((messages: BaseMessage[]) => {
239
+ return [systemMessage, ...messages];
240
+ }).withConfig({ runName: 'prompt' });
241
+ }
242
+
243
+ return undefined;
244
+ }
245
+
246
+ /**
247
+ * Reset context for a new run
248
+ */
249
+ reset(): void {
250
+ this.instructionTokens = 0;
251
+ this.lastToken = undefined;
252
+ this.indexTokenCountMap = {};
253
+ this.currentUsage = undefined;
254
+ this.pruneMessages = undefined;
255
+ this.lastStreamCall = undefined;
256
+ this.tokenTypeSwitch = undefined;
257
+ this.currentTokenType = ContentTypes.TEXT;
258
+ }
259
+
260
+ /**
261
+ * Update the token count map with instruction tokens
262
+ */
263
+ updateTokenMapWithInstructions(baseTokenMap: Record<string, number>): void {
264
+ if (this.instructionTokens > 0) {
265
+ // Shift all indices by the instruction token count
266
+ const shiftedMap: Record<string, number> = {};
267
+ for (const [key, value] of Object.entries(baseTokenMap)) {
268
+ const index = parseInt(key, 10);
269
+ if (!isNaN(index)) {
270
+ shiftedMap[String(index)] =
271
+ value + (index === 0 ? this.instructionTokens : 0);
272
+ }
273
+ }
274
+ this.indexTokenCountMap = shiftedMap;
275
+ } else {
276
+ this.indexTokenCountMap = { ...baseTokenMap };
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Calculate tool tokens and add to instruction tokens
282
+ * Note: System message tokens are calculated during systemRunnable creation
283
+ */
284
+ async calculateInstructionTokens(
285
+ tokenCounter: t.TokenCounter
286
+ ): Promise<void> {
287
+ let toolTokens = 0;
288
+ if (this.tools && this.tools.length > 0) {
289
+ for (const tool of this.tools) {
290
+ const genericTool = tool as Record<string, unknown>;
291
+ if (
292
+ genericTool.schema != null &&
293
+ typeof genericTool.schema === 'object'
294
+ ) {
295
+ const schema = genericTool.schema as {
296
+ describe: (desc: string) => unknown;
297
+ };
298
+ const describedSchema = schema.describe(
299
+ (genericTool.description as string) || ''
300
+ );
301
+ const jsonSchema = zodToJsonSchema(
302
+ describedSchema as Parameters<typeof zodToJsonSchema>[0],
303
+ (genericTool.name as string) || ''
304
+ );
305
+ toolTokens += tokenCounter(
306
+ new SystemMessage(JSON.stringify(jsonSchema))
307
+ );
308
+ }
309
+ }
310
+ }
311
+
312
+ // Add tool tokens to existing instruction tokens (which may already include system message tokens)
313
+ this.instructionTokens += toolTokens;
314
+ }
315
+ }
@@ -87,8 +87,9 @@ export enum Providers {
87
87
  }
88
88
 
89
89
  export enum GraphNodeKeys {
90
- TOOLS = 'tools',
91
- AGENT = 'agent',
90
+ TOOLS = 'tools=',
91
+ AGENT = 'agent=',
92
+ ROUTER = 'router',
92
93
  PRE_TOOLS = 'pre_tools',
93
94
  POST_TOOLS = 'post_tools',
94
95
  }
@@ -117,10 +118,12 @@ export enum ContentTypes {
117
118
  IMAGE_FILE = 'image_file',
118
119
  /** Anthropic */
119
120
  THINKING = 'thinking',
120
- /** Bedrock */
121
- REASONING_CONTENT = 'reasoning_content',
121
+ /** Vertex AI / Google Common */
122
+ REASONING = 'reasoning',
122
123
  /** Multi-Agent Switch */
123
124
  AGENT_UPDATE = 'agent_update',
125
+ /** Bedrock */
126
+ REASONING_CONTENT = 'reasoning_content',
124
127
  }
125
128
 
126
129
  export enum ToolCallTypes {
@@ -136,6 +139,7 @@ export enum Callback {
136
139
  TOOL_ERROR = 'handleToolError',
137
140
  TOOL_START = 'handleToolStart',
138
141
  TOOL_END = 'handleToolEnd',
142
+ CUSTOM_EVENT = 'handleCustomEvent',
139
143
  /*
140
144
  LLM_START = 'handleLLMStart',
141
145
  LLM_NEW_TOKEN = 'handleLLMNewToken',
@@ -151,7 +155,6 @@ export enum Callback {
151
155
  RETRIEVER_START = 'handleRetrieverStart',
152
156
  RETRIEVER_END = 'handleRetrieverEnd',
153
157
  RETRIEVER_ERROR = 'handleRetrieverError',
154
- CUSTOM_EVENT = 'handleCustomEvent'
155
158
  */
156
159
  }
157
160
 
@@ -162,6 +165,12 @@ export enum Constants {
162
165
  CONTENT_AND_ARTIFACT = 'content_and_artifact',
163
166
  }
164
167
 
168
+ export enum TitleMethod {
169
+ STRUCTURED = 'structured',
170
+ FUNCTIONS = 'functions',
171
+ COMPLETION = 'completion',
172
+ }
173
+
165
174
  export enum EnvVar {
166
175
  CODE_API_KEY = 'LIBRECHAT_CODE_API_KEY',
167
176
  CODE_BASEURL = 'LIBRECHAT_CODE_BASEURL',
package/src/events.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  /* eslint-disable no-console */
2
2
  // src/events.ts
3
3
  import type {
4
+ ToolMessage,
4
5
  UsageMetadata,
5
6
  BaseMessageFields,
6
7
  } from '@langchain/core/messages';
7
- import type { Graph } from '@/graphs';
8
+ import type { MultiAgentGraph, StandardGraph } from '@/graphs';
8
9
  import type * as t from '@/types';
9
10
  import { handleToolCalls } from '@/tools/handlers';
10
11
  import { Providers } from '@/common';
@@ -30,12 +31,12 @@ export class ModelEndHandler implements t.EventHandler {
30
31
  this.collectedUsage = collectedUsage;
31
32
  }
32
33
 
33
- handle(
34
+ async handle(
34
35
  event: string,
35
36
  data: t.ModelEndData,
36
37
  metadata?: Record<string, unknown>,
37
- graph?: Graph
38
- ): void {
38
+ graph?: StandardGraph | MultiAgentGraph
39
+ ): Promise<void> {
39
40
  if (!graph || !metadata) {
40
41
  console.warn(`Graph or metadata not found in ${event} event`);
41
42
  return;
@@ -58,25 +59,35 @@ export class ModelEndHandler implements t.EventHandler {
58
59
  { depth: null }
59
60
  );
60
61
 
61
- if (metadata.provider !== Providers.GOOGLE) {
62
+ const agentContext = graph.getAgentContext(metadata);
63
+
64
+ if (
65
+ agentContext.provider !== Providers.GOOGLE &&
66
+ agentContext.provider !== Providers.BEDROCK
67
+ ) {
62
68
  return;
63
69
  }
64
70
 
65
- handleToolCalls(data?.output?.tool_calls, metadata, graph);
71
+ await handleToolCalls(data?.output?.tool_calls, metadata, graph);
66
72
  }
67
73
  }
68
74
 
69
75
  export class ToolEndHandler implements t.EventHandler {
70
76
  private callback?: t.ToolEndCallback;
71
- constructor(callback?: t.ToolEndCallback) {
77
+ private omitOutput?: (name?: string) => boolean;
78
+ constructor(
79
+ callback?: t.ToolEndCallback,
80
+ omitOutput?: (name?: string) => boolean
81
+ ) {
72
82
  this.callback = callback;
83
+ this.omitOutput = omitOutput;
73
84
  }
74
- handle(
85
+ async handle(
75
86
  event: string,
76
87
  data: t.StreamEventData | undefined,
77
88
  metadata?: Record<string, unknown>,
78
- graph?: Graph
79
- ): void {
89
+ graph?: StandardGraph | MultiAgentGraph
90
+ ): Promise<void> {
80
91
  if (!graph || !metadata) {
81
92
  console.warn(`Graph or metadata not found in ${event} event`);
82
93
  return;
@@ -89,10 +100,10 @@ export class ToolEndHandler implements t.EventHandler {
89
100
  }
90
101
 
91
102
  this.callback?.(toolEndData, metadata);
92
-
93
- graph.handleToolCallCompleted(
103
+ await graph.handleToolCallCompleted(
94
104
  { input: toolEndData.input, output: toolEndData.output },
95
- metadata
105
+ metadata,
106
+ this.omitOutput?.((toolEndData.output as ToolMessage | undefined)?.name)
96
107
  );
97
108
  }
98
109
  }