@librechat/agents 3.2.21 → 3.2.31

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 (398) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +3 -2
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/events.cjs.map +1 -1
  4. package/dist/cjs/graphs/Graph.cjs +200 -54
  5. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +13 -7
  8. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  9. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  10. package/dist/cjs/hooks/types.cjs.map +1 -1
  11. package/dist/cjs/instrumentation.cjs +2 -2
  12. package/dist/cjs/instrumentation.cjs.map +1 -1
  13. package/dist/cjs/langfuse.cjs +17 -1
  14. package/dist/cjs/langfuse.cjs.map +1 -1
  15. package/dist/cjs/langfuseToolOutputTracing.cjs +2 -2
  16. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  17. package/dist/cjs/llm/anthropic/index.cjs +1 -1
  18. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +1 -1
  21. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  22. package/dist/cjs/llm/bedrock/index.cjs +2 -2
  23. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  24. package/dist/cjs/llm/bedrock/toolCache.cjs +8 -5
  25. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  26. package/dist/cjs/llm/fake.cjs +16 -14
  27. package/dist/cjs/llm/fake.cjs.map +1 -1
  28. package/dist/cjs/llm/google/index.cjs +22 -0
  29. package/dist/cjs/llm/google/index.cjs.map +1 -1
  30. package/dist/cjs/llm/google/utils/common.cjs +88 -27
  31. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  32. package/dist/cjs/llm/init.cjs +2 -2
  33. package/dist/cjs/llm/invoke.cjs +108 -11
  34. package/dist/cjs/llm/invoke.cjs.map +1 -1
  35. package/dist/cjs/llm/openai/index.cjs +1 -1
  36. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  37. package/dist/cjs/llm/openai/utils/index.cjs +1 -1
  38. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  39. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  40. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  41. package/dist/cjs/main.cjs +1 -0
  42. package/dist/cjs/main.cjs.map +1 -1
  43. package/dist/cjs/messages/cache.cjs +8 -7
  44. package/dist/cjs/messages/cache.cjs.map +1 -1
  45. package/dist/cjs/messages/content.cjs.map +1 -1
  46. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  47. package/dist/cjs/messages/format.cjs +124 -17
  48. package/dist/cjs/messages/format.cjs.map +1 -1
  49. package/dist/cjs/messages/prune.cjs.map +1 -1
  50. package/dist/cjs/messages/reducer.cjs +1 -1
  51. package/dist/cjs/messages/reducer.cjs.map +1 -1
  52. package/dist/cjs/messages/tools.cjs +1 -1
  53. package/dist/cjs/messages/tools.cjs.map +1 -1
  54. package/dist/cjs/openai/index.cjs.map +1 -1
  55. package/dist/cjs/responses/index.cjs.map +1 -1
  56. package/dist/cjs/run.cjs +41 -20
  57. package/dist/cjs/run.cjs.map +1 -1
  58. package/dist/cjs/session/AgentSession.cjs +4 -4
  59. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  60. package/dist/cjs/session/JsonlSessionStore.cjs +2 -2
  61. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  62. package/dist/cjs/session/handlers.cjs +2 -2
  63. package/dist/cjs/session/handlers.cjs.map +1 -1
  64. package/dist/cjs/stream.cjs +248 -25
  65. package/dist/cjs/stream.cjs.map +1 -1
  66. package/dist/cjs/summarization/node.cjs.map +1 -1
  67. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +1 -1
  68. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  69. package/dist/cjs/tools/Calculator.cjs +1 -1
  70. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  71. package/dist/cjs/tools/CodeExecutor.cjs +1 -1
  72. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  73. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  74. package/dist/cjs/tools/ToolNode.cjs +37 -18
  75. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  76. package/dist/cjs/tools/ToolSearch.cjs +1 -1
  77. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  78. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +7 -4
  79. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  80. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +4 -4
  81. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  82. package/dist/cjs/tools/handlers.cjs +2 -1
  83. package/dist/cjs/tools/handlers.cjs.map +1 -1
  84. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  85. package/dist/cjs/tools/local/FileCheckpointer.cjs +2 -1
  86. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  87. package/dist/cjs/tools/local/LocalCodingTools.cjs +45 -19
  88. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  89. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +3 -3
  90. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  91. package/dist/cjs/tools/local/LocalExecutionTools.cjs +2 -2
  92. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  93. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +4 -3
  94. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  95. package/dist/cjs/tools/local/attachments.cjs +0 -5
  96. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  97. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +4 -4
  98. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  99. package/dist/cjs/tools/search/firecrawl.cjs +1 -1
  100. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  101. package/dist/cjs/tools/search/rerankers.cjs +7 -3
  102. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  103. package/dist/cjs/tools/search/tavily-search.cjs +1 -1
  104. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  105. package/dist/cjs/tools/search/utils.cjs +76 -8
  106. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  107. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
  108. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  109. package/dist/cjs/utils/handlers.cjs +1 -1
  110. package/dist/cjs/utils/handlers.cjs.map +1 -1
  111. package/dist/cjs/utils/run.cjs +1 -1
  112. package/dist/cjs/utils/run.cjs.map +1 -1
  113. package/dist/esm/agents/AgentContext.mjs +3 -2
  114. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  115. package/dist/esm/events.mjs.map +1 -1
  116. package/dist/esm/graphs/Graph.mjs +200 -54
  117. package/dist/esm/graphs/Graph.mjs.map +1 -1
  118. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  119. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +13 -7
  120. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  121. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  122. package/dist/esm/hooks/types.mjs.map +1 -1
  123. package/dist/esm/instrumentation.mjs +2 -2
  124. package/dist/esm/instrumentation.mjs.map +1 -1
  125. package/dist/esm/langfuse.mjs +17 -2
  126. package/dist/esm/langfuse.mjs.map +1 -1
  127. package/dist/esm/langfuseToolOutputTracing.mjs +2 -2
  128. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  129. package/dist/esm/llm/anthropic/index.mjs +1 -1
  130. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  131. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  132. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +1 -1
  133. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  134. package/dist/esm/llm/bedrock/index.mjs +2 -2
  135. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  136. package/dist/esm/llm/bedrock/toolCache.mjs +8 -5
  137. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  138. package/dist/esm/llm/fake.mjs +16 -14
  139. package/dist/esm/llm/fake.mjs.map +1 -1
  140. package/dist/esm/llm/google/index.mjs +23 -1
  141. package/dist/esm/llm/google/index.mjs.map +1 -1
  142. package/dist/esm/llm/google/utils/common.mjs +88 -27
  143. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  144. package/dist/esm/llm/init.mjs +2 -2
  145. package/dist/esm/llm/invoke.mjs +104 -7
  146. package/dist/esm/llm/invoke.mjs.map +1 -1
  147. package/dist/esm/llm/openai/index.mjs +1 -1
  148. package/dist/esm/llm/openai/index.mjs.map +1 -1
  149. package/dist/esm/llm/openai/utils/index.mjs +1 -1
  150. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  151. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  152. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  153. package/dist/esm/main.mjs +1 -1
  154. package/dist/esm/messages/cache.mjs +8 -7
  155. package/dist/esm/messages/cache.mjs.map +1 -1
  156. package/dist/esm/messages/content.mjs.map +1 -1
  157. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  158. package/dist/esm/messages/format.mjs +124 -18
  159. package/dist/esm/messages/format.mjs.map +1 -1
  160. package/dist/esm/messages/prune.mjs.map +1 -1
  161. package/dist/esm/messages/reducer.mjs +1 -1
  162. package/dist/esm/messages/reducer.mjs.map +1 -1
  163. package/dist/esm/messages/tools.mjs +1 -1
  164. package/dist/esm/messages/tools.mjs.map +1 -1
  165. package/dist/esm/openai/index.mjs.map +1 -1
  166. package/dist/esm/responses/index.mjs.map +1 -1
  167. package/dist/esm/run.mjs +41 -20
  168. package/dist/esm/run.mjs.map +1 -1
  169. package/dist/esm/session/AgentSession.mjs +4 -4
  170. package/dist/esm/session/AgentSession.mjs.map +1 -1
  171. package/dist/esm/session/JsonlSessionStore.mjs +2 -2
  172. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  173. package/dist/esm/session/handlers.mjs +2 -2
  174. package/dist/esm/session/handlers.mjs.map +1 -1
  175. package/dist/esm/stream.mjs +248 -25
  176. package/dist/esm/stream.mjs.map +1 -1
  177. package/dist/esm/summarization/node.mjs.map +1 -1
  178. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +1 -1
  179. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  180. package/dist/esm/tools/Calculator.mjs +1 -1
  181. package/dist/esm/tools/Calculator.mjs.map +1 -1
  182. package/dist/esm/tools/CodeExecutor.mjs +1 -1
  183. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  184. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  185. package/dist/esm/tools/ToolNode.mjs +37 -18
  186. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  187. package/dist/esm/tools/ToolSearch.mjs +1 -1
  188. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  189. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +7 -4
  190. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  191. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +4 -4
  192. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  193. package/dist/esm/tools/handlers.mjs +2 -1
  194. package/dist/esm/tools/handlers.mjs.map +1 -1
  195. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  196. package/dist/esm/tools/local/FileCheckpointer.mjs +2 -1
  197. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  198. package/dist/esm/tools/local/LocalCodingTools.mjs +45 -19
  199. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  200. package/dist/esm/tools/local/LocalExecutionEngine.mjs +3 -3
  201. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  202. package/dist/esm/tools/local/LocalExecutionTools.mjs +2 -2
  203. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  204. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +4 -3
  205. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  206. package/dist/esm/tools/local/attachments.mjs +0 -5
  207. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  208. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +4 -4
  209. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  210. package/dist/esm/tools/search/firecrawl.mjs +1 -1
  211. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  212. package/dist/esm/tools/search/rerankers.mjs +8 -4
  213. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  214. package/dist/esm/tools/search/tavily-search.mjs +1 -1
  215. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  216. package/dist/esm/tools/search/utils.mjs +76 -9
  217. package/dist/esm/tools/search/utils.mjs.map +1 -1
  218. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
  219. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  220. package/dist/esm/utils/handlers.mjs +1 -1
  221. package/dist/esm/utils/handlers.mjs.map +1 -1
  222. package/dist/esm/utils/run.mjs +1 -1
  223. package/dist/esm/utils/run.mjs.map +1 -1
  224. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +1 -1
  225. package/dist/types/events.d.ts +1 -1
  226. package/dist/types/graphs/Graph.d.ts +7 -1
  227. package/dist/types/hooks/executeHooks.d.ts +1 -1
  228. package/dist/types/hooks/types.d.ts +5 -0
  229. package/dist/types/langfuse.d.ts +4 -0
  230. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  231. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
  232. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +2 -2
  233. package/dist/types/llm/bedrock/index.d.ts +2 -2
  234. package/dist/types/llm/fake.d.ts +3 -3
  235. package/dist/types/llm/google/index.d.ts +1 -0
  236. package/dist/types/llm/google/types.d.ts +1 -1
  237. package/dist/types/llm/google/utils/common.d.ts +2 -2
  238. package/dist/types/llm/google/utils/tools.d.ts +1 -1
  239. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +1 -1
  240. package/dist/types/llm/openai/index.d.ts +2 -2
  241. package/dist/types/llm/openai/utils/index.d.ts +1 -1
  242. package/dist/types/llm/openrouter/index.d.ts +4 -4
  243. package/dist/types/messages/contextPruning.d.ts +1 -1
  244. package/dist/types/messages/format.d.ts +9 -4
  245. package/dist/types/messages/prune.d.ts +1 -1
  246. package/dist/types/session/JsonlSessionStore.d.ts +1 -1
  247. package/dist/types/session/handlers.d.ts +1 -1
  248. package/dist/types/session/types.d.ts +1 -1
  249. package/dist/types/summarization/node.d.ts +1 -1
  250. package/dist/types/tools/SubagentTool.d.ts +2 -2
  251. package/dist/types/tools/ToolNode.d.ts +9 -2
  252. package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +1 -1
  253. package/dist/types/tools/search/types.d.ts +1 -1
  254. package/dist/types/tools/search/utils.d.ts +11 -0
  255. package/dist/types/types/graph.d.ts +4 -4
  256. package/dist/types/types/llm.d.ts +4 -3
  257. package/dist/types/types/messages.d.ts +1 -1
  258. package/dist/types/types/run.d.ts +6 -6
  259. package/dist/types/types/stream.d.ts +2 -2
  260. package/dist/types/types/tools.d.ts +5 -1
  261. package/dist/types/utils/handlers.d.ts +2 -2
  262. package/dist/types/utils/run.d.ts +1 -1
  263. package/package.json +6 -3
  264. package/src/__tests__/stream.eagerEventExecution.test.ts +543 -6
  265. package/src/agents/AgentContext.ts +2 -2
  266. package/src/agents/__tests__/AgentContext.test.ts +3 -3
  267. package/src/agents/__tests__/promptCacheLiveHelpers.ts +1 -1
  268. package/src/events.ts +1 -1
  269. package/src/graphs/Graph.ts +329 -72
  270. package/src/graphs/MultiAgentGraph.ts +1 -1
  271. package/src/graphs/__tests__/Graph.reasoning.test.ts +919 -6
  272. package/src/graphs/__tests__/MultiAgentGraph.test.ts +1 -1
  273. package/src/graphs/__tests__/composition.smoke.test.ts +1 -1
  274. package/src/hooks/__tests__/HookRegistry.test.ts +1 -1
  275. package/src/hooks/__tests__/compactHooks.test.ts +8 -8
  276. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +34 -22
  277. package/src/hooks/__tests__/executeHooks.test.ts +3 -3
  278. package/src/hooks/__tests__/integration.test.ts +3 -3
  279. package/src/hooks/__tests__/toolHooks.test.ts +10 -10
  280. package/src/hooks/createWorkspacePolicyHook.ts +17 -14
  281. package/src/hooks/executeHooks.ts +1 -1
  282. package/src/hooks/types.ts +5 -0
  283. package/src/instrumentation.ts +11 -11
  284. package/src/langfuse.ts +35 -1
  285. package/src/langfuseToolOutputTracing.ts +2 -2
  286. package/src/llm/anthropic/index.ts +1 -1
  287. package/src/llm/anthropic/utils/message_inputs.ts +1 -1
  288. package/src/llm/anthropic/utils/message_outputs.ts +3 -5
  289. package/src/llm/anthropic/utils/output_parsers.ts +5 -5
  290. package/src/llm/bedrock/index.ts +4 -4
  291. package/src/llm/bedrock/toolCache.test.ts +48 -9
  292. package/src/llm/bedrock/toolCache.ts +11 -6
  293. package/src/llm/fake.ts +30 -25
  294. package/src/llm/google/index.ts +43 -1
  295. package/src/llm/google/llm.spec.ts +173 -1
  296. package/src/llm/google/types.ts +1 -1
  297. package/src/llm/google/utils/common.ts +154 -45
  298. package/src/llm/google/utils/tools.ts +8 -8
  299. package/src/llm/google/utils/zod_to_genai_parameters.ts +4 -4
  300. package/src/llm/invoke.test.ts +3 -3
  301. package/src/llm/invoke.ts +170 -10
  302. package/src/llm/openai/index.ts +4 -4
  303. package/src/llm/openai/utils/index.ts +14 -14
  304. package/src/llm/openrouter/index.ts +4 -4
  305. package/src/llm/openrouter/reasoning.test.ts +2 -2
  306. package/src/llm/vertexai/fixThoughtSignatures.test.ts +1 -1
  307. package/src/llm/vertexai/index.ts +1 -1
  308. package/src/messages/cache.test.ts +22 -0
  309. package/src/messages/cache.ts +25 -12
  310. package/src/messages/content.ts +1 -1
  311. package/src/messages/contextPruning.ts +1 -1
  312. package/src/messages/format.ts +227 -43
  313. package/src/messages/formatAgentMessages.skills.test.ts +105 -26
  314. package/src/messages/formatAgentMessages.test.ts +841 -10
  315. package/src/messages/labelContentByAgent.test.ts +2 -2
  316. package/src/messages/prune.ts +1 -1
  317. package/src/messages/reducer.ts +1 -1
  318. package/src/messages/tools.ts +1 -1
  319. package/src/openai/__tests__/openai.test.ts +2 -2
  320. package/src/openai/index.ts +1 -1
  321. package/src/responses/__tests__/responses.test.ts +2 -2
  322. package/src/responses/index.ts +1 -1
  323. package/src/run.ts +68 -41
  324. package/src/session/AgentSession.ts +6 -6
  325. package/src/session/JsonlSessionStore.ts +3 -3
  326. package/src/session/__tests__/JsonlSessionStore.test.ts +5 -5
  327. package/src/session/__tests__/handlers.test.ts +2 -2
  328. package/src/session/handlers.ts +5 -5
  329. package/src/session/types.ts +1 -1
  330. package/src/specs/agent-handoffs.test.ts +1 -1
  331. package/src/specs/langfuse-callbacks.test.ts +2 -2
  332. package/src/specs/langfuse-metadata.test.ts +39 -0
  333. package/src/specs/langfuse-tool-output-tracing.test.ts +1 -1
  334. package/src/specs/multi-agent-summarization.test.ts +4 -4
  335. package/src/specs/subagent.test.ts +3 -3
  336. package/src/specs/summarization-unit.test.ts +1 -1
  337. package/src/specs/thinking-handoff.test.ts +1 -1
  338. package/src/splitStream.test.ts +48 -0
  339. package/src/stream.test.ts +53 -3
  340. package/src/stream.ts +450 -39
  341. package/src/summarization/__tests__/aggregator.test.ts +2 -2
  342. package/src/summarization/__tests__/node.test.ts +2 -2
  343. package/src/summarization/node.ts +1 -1
  344. package/src/tools/BashProgrammaticToolCalling.ts +5 -5
  345. package/src/tools/Calculator.ts +1 -1
  346. package/src/tools/CodeExecutor.ts +2 -4
  347. package/src/tools/SubagentTool.ts +2 -2
  348. package/src/tools/ToolNode.ts +37 -16
  349. package/src/tools/ToolSearch.ts +1 -1
  350. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +4 -4
  351. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +12 -12
  352. package/src/tools/__tests__/LocalExecutionTools.test.ts +125 -93
  353. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +29 -5
  354. package/src/tools/__tests__/ReadFile.test.ts +1 -1
  355. package/src/tools/__tests__/SkillTool.test.ts +4 -4
  356. package/src/tools/__tests__/SubagentExecutor.test.ts +17 -13
  357. package/src/tools/__tests__/SubagentTool.test.ts +2 -2
  358. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +1 -1
  359. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +2 -5
  360. package/src/tools/__tests__/ToolNode.session.test.ts +1 -1
  361. package/src/tools/__tests__/ToolSearch.test.ts +1 -1
  362. package/src/tools/__tests__/annotateMessagesForLLM.test.ts +1 -1
  363. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +35 -32
  364. package/src/tools/__tests__/directToolHooks.test.ts +41 -0
  365. package/src/tools/__tests__/handlers.test.ts +2 -2
  366. package/src/tools/__tests__/hitl.test.ts +11 -11
  367. package/src/tools/__tests__/localToolNames.test.ts +8 -6
  368. package/src/tools/__tests__/skillCatalog.test.ts +1 -1
  369. package/src/tools/__tests__/subagentHooks.test.ts +20 -10
  370. package/src/tools/__tests__/workspaceSeam.test.ts +20 -7
  371. package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +9 -6
  372. package/src/tools/cloudflare/CloudflareSandboxTools.ts +19 -19
  373. package/src/tools/handlers.ts +5 -5
  374. package/src/tools/local/CompileCheckTool.ts +4 -7
  375. package/src/tools/local/FileCheckpointer.ts +6 -5
  376. package/src/tools/local/LocalCodingTools.ts +100 -45
  377. package/src/tools/local/LocalExecutionEngine.ts +5 -5
  378. package/src/tools/local/LocalExecutionTools.ts +9 -9
  379. package/src/tools/local/LocalProgrammaticToolCalling.ts +5 -4
  380. package/src/tools/local/attachments.ts +0 -6
  381. package/src/tools/local/resolveLocalExecutionTools.ts +15 -15
  382. package/src/tools/search/firecrawl.ts +1 -1
  383. package/src/tools/search/jina-reranker.test.ts +148 -37
  384. package/src/tools/search/rerankers.ts +14 -4
  385. package/src/tools/search/tavily-search.ts +2 -2
  386. package/src/tools/search/types.ts +1 -1
  387. package/src/tools/search/utils.ts +99 -9
  388. package/src/tools/subagent/SubagentExecutor.ts +12 -6
  389. package/src/types/graph.ts +12 -12
  390. package/src/types/llm.ts +7 -6
  391. package/src/types/messages.ts +1 -1
  392. package/src/types/run.ts +7 -7
  393. package/src/types/stream.ts +2 -2
  394. package/src/types/tools.ts +5 -1
  395. package/src/utils/handlers.ts +2 -2
  396. package/src/utils/llmConfig.ts +1 -1
  397. package/src/utils/logging.ts +20 -10
  398. package/src/utils/run.ts +2 -2
@@ -1,6 +1,6 @@
1
- import { ContentTypes } from '@/common';
2
- import { labelContentByAgent } from './format';
3
1
  import type { MessageContentComplex, ToolCallContent } from '@/types';
2
+ import { labelContentByAgent } from './format';
3
+ import { ContentTypes } from '@/common';
4
4
 
5
5
  /**
6
6
  * Type guard to check if content is ToolCallContent
@@ -9,8 +9,8 @@ import type {
9
9
  MessageContentComplex,
10
10
  ReasoningContentText,
11
11
  } from '@/types/stream';
12
- import type { TokenCounter } from '@/types/run';
13
12
  import type { ContextPruningConfig } from '@/types/graph';
13
+ import type { TokenCounter } from '@/types/run';
14
14
  import {
15
15
  calculateMaxToolResultChars,
16
16
  truncateToolResultContent,
@@ -1,10 +1,10 @@
1
+ import { v4 } from 'uuid';
1
2
  import {
2
3
  BaseMessage,
3
4
  RemoveMessage,
4
5
  BaseMessageLike,
5
6
  coerceMessageLikeToMessage,
6
7
  } from '@langchain/core/messages';
7
- import { v4 } from 'uuid';
8
8
 
9
9
  export const REMOVE_ALL_MESSAGES = '__remove_all__';
10
10
 
@@ -1,8 +1,8 @@
1
1
  // src/messages/toolDiscovery.ts
2
2
  import { AIMessageChunk, ToolMessage } from '@langchain/core/messages';
3
3
  import type { BaseMessage } from '@langchain/core/messages';
4
- import { Constants } from '@/common';
5
4
  import { findLastIndex } from './core';
5
+ import { Constants } from '@/common';
6
6
 
7
7
  type ToolSearchArtifact = {
8
8
  tool_references?: Array<{ tool_name: string }>;
@@ -1,11 +1,11 @@
1
- import { GraphEvents } from '@/common';
1
+ import type * as t from '@/types';
2
2
  import {
3
3
  createChatCompletionChunk,
4
4
  createOpenAIHandlers,
5
5
  createOpenAIStreamTracker,
6
6
  sendOpenAIFinalChunk,
7
7
  } from '@/openai';
8
- import type * as t from '@/types';
8
+ import { GraphEvents } from '@/common';
9
9
 
10
10
  describe('OpenAI-compatible adapters', () => {
11
11
  it('creates chunks and streams message deltas as SSE data', async () => {
@@ -1,6 +1,6 @@
1
- import { GraphEvents } from '@/common';
2
1
  import type { UsageMetadata } from '@langchain/core/messages';
3
2
  import type * as t from '@/types';
3
+ import { GraphEvents } from '@/common';
4
4
 
5
5
  export interface OpenAICompatibleWriter {
6
6
  write(data: string): void | Promise<void>;
@@ -1,11 +1,11 @@
1
- import { GraphEvents } from '@/common';
1
+ import type * as t from '@/types';
2
2
  import {
3
3
  buildResponse,
4
4
  createResponseTracker,
5
5
  createResponsesEventHandlers,
6
6
  emitResponseCompleted,
7
7
  } from '@/responses';
8
- import type * as t from '@/types';
8
+ import { GraphEvents } from '@/common';
9
9
 
10
10
  describe('Responses-compatible adapters', () => {
11
11
  it('streams semantic response events through a generic writer', async () => {
@@ -1,6 +1,6 @@
1
- import { GraphEvents } from '@/common';
2
1
  import type { UsageMetadata } from '@langchain/core/messages';
3
2
  import type * as t from '@/types';
3
+ import { GraphEvents } from '@/common';
4
4
 
5
5
  export interface ResponsesCompatibleWriter {
6
6
  write(data: string): void | Promise<void>;
package/src/run.ts CHANGED
@@ -1,55 +1,56 @@
1
1
  // src/run.ts
2
- import {
3
- initializeLangfuseTracing,
4
- runWithTraceIdSeed,
5
- } from './instrumentation';
2
+ import { HumanMessage } from '@langchain/core/messages';
6
3
  import { PromptTemplate } from '@langchain/core/prompts';
7
4
  import { RunnableLambda } from '@langchain/core/runnables';
8
5
  import { AzureChatOpenAI, ChatOpenAI } from '@langchain/openai';
6
+ import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
9
7
  import {
10
8
  Command,
11
9
  INTERRUPT,
12
10
  MemorySaver,
13
11
  isInterrupted,
14
12
  } from '@langchain/langgraph';
15
- import { HumanMessage } from '@langchain/core/messages';
16
- import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
17
13
  import type {
18
14
  MessageContentComplex,
19
15
  BaseMessage,
20
16
  } from '@langchain/core/messages';
21
17
  import type { StringPromptValue } from '@langchain/core/prompt_values';
22
18
  import type { RunnableConfig } from '@langchain/core/runnables';
19
+ import type { HookRegistry } from '@/hooks';
23
20
  import type * as t from '@/types';
24
- import {
25
- createCompletionTitleRunnable,
26
- createTitleRunnable,
27
- } from '@/utils/title';
28
- import { createTokenCounter, encodingForModel } from '@/utils/tokens';
29
- import { GraphEvents, Callback, TitleMethod } from '@/common';
30
- import { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
31
- import { StandardGraph } from '@/graphs/Graph';
32
- import { initializeModel } from '@/llm/init';
33
- import { HandlerRegistry } from '@/events';
34
- import { executeHooks } from '@/hooks';
35
- import { isOpenAILike } from '@/utils/llm';
36
- import {
37
- appendCallbacks,
38
- findCallback,
39
- type CallbackEntry,
40
- } from '@/utils/callbacks';
41
21
  import {
42
22
  createLangfuseTraceMetadata,
43
23
  createLangfuseHandler,
44
24
  disposeLangfuseHandler,
45
25
  getLangfuseTraceName,
46
26
  isLangfuseCallbackHandler,
27
+ withLangfuseAttributes,
47
28
  } from '@/langfuse';
48
29
  import {
49
30
  resolveLangfuseConfig,
50
31
  withLangfuseToolOutputTracingConfig,
51
32
  } from '@/langfuseToolOutputTracing';
52
- import type { HookRegistry } from '@/hooks';
33
+ import {
34
+ appendCallbacks,
35
+ findCallback,
36
+ type CallbackEntry,
37
+ } from '@/utils/callbacks';
38
+ import {
39
+ createCompletionTitleRunnable,
40
+ createTitleRunnable,
41
+ } from '@/utils/title';
42
+ import {
43
+ initializeLangfuseTracing,
44
+ runWithTraceIdSeed,
45
+ } from './instrumentation';
46
+ import { createTokenCounter, encodingForModel } from '@/utils/tokens';
47
+ import { GraphEvents, Callback, TitleMethod } from '@/common';
48
+ import { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
49
+ import { StandardGraph } from '@/graphs/Graph';
50
+ import { initializeModel } from '@/llm/init';
51
+ import { HandlerRegistry } from '@/events';
52
+ import { isOpenAILike } from '@/utils/llm';
53
+ import { executeHooks } from '@/hooks';
53
54
 
54
55
  export const defaultOmitOptions = new Set([
55
56
  'stream',
@@ -731,6 +732,7 @@ export class Run<_T extends t.BaseGraphState> {
731
732
  agentId: graph.defaultAgentId,
732
733
  agentName: primaryContext?.name,
733
734
  });
735
+ const traceName = config.runName ?? getLangfuseTraceName(traceMetadata);
734
736
  const streamLangfuseConfig = this.getStreamLangfuseConfig(graph);
735
737
  initializeLangfuseTracing(streamLangfuseConfig);
736
738
  const langfuseHandler = createLangfuseHandler({
@@ -741,7 +743,7 @@ export class Run<_T extends t.BaseGraphState> {
741
743
  tags: ['librechat', 'agent'],
742
744
  });
743
745
  if (langfuseHandler != null) {
744
- config.runName = config.runName ?? getLangfuseTraceName(traceMetadata);
746
+ config.runName = traceName;
745
747
  config.callbacks = appendCallbacks(config.callbacks, [langfuseHandler]);
746
748
  }
747
749
 
@@ -915,7 +917,18 @@ export class Run<_T extends t.BaseGraphState> {
915
917
  () =>
916
918
  withLangfuseToolOutputTracingConfig(
917
919
  streamLangfuseConfig,
918
- consumeStream,
920
+ () =>
921
+ withLangfuseAttributes(
922
+ {
923
+ langfuse: streamLangfuseConfig,
924
+ userId,
925
+ sessionId,
926
+ traceName,
927
+ traceMetadata,
928
+ tags: ['librechat', 'agent'],
929
+ },
930
+ consumeStream
931
+ ),
919
932
  this.getStreamToolOutputTracingLangfuseConfig(graph)
920
933
  )
921
934
  );
@@ -1261,6 +1274,9 @@ export class Run<_T extends t.BaseGraphState> {
1261
1274
  titlePromptTemplate,
1262
1275
  }: t.RunTitleOptions): Promise<{ language?: string; title?: string }> {
1263
1276
  let titleLangfuseHandler: CallbackEntry | undefined;
1277
+ let titleLangfuseConfig: t.LangfuseConfig | undefined;
1278
+ let titleUserId: string | undefined;
1279
+ let titleSessionId: string | undefined;
1264
1280
  const titleContext =
1265
1281
  this.Graph == null
1266
1282
  ? undefined
@@ -1272,23 +1288,23 @@ export class Run<_T extends t.BaseGraphState> {
1272
1288
  const titleRunName = getLangfuseTraceName(traceMetadata, 'LibreChat Title');
1273
1289
 
1274
1290
  if (chainOptions != null) {
1275
- const userId =
1291
+ titleUserId =
1276
1292
  typeof chainOptions.configurable?.user_id === 'string'
1277
1293
  ? chainOptions.configurable.user_id
1278
1294
  : undefined;
1279
- const sessionId =
1295
+ titleSessionId =
1280
1296
  typeof chainOptions.configurable?.thread_id === 'string'
1281
1297
  ? chainOptions.configurable.thread_id
1282
1298
  : undefined;
1283
- const titleLangfuseConfig = resolveLangfuseConfig(
1299
+ titleLangfuseConfig = resolveLangfuseConfig(
1284
1300
  this.langfuse,
1285
1301
  titleContext?.langfuse
1286
1302
  );
1287
1303
  initializeLangfuseTracing(titleLangfuseConfig);
1288
1304
  titleLangfuseHandler = createLangfuseHandler({
1289
1305
  langfuse: titleLangfuseConfig,
1290
- userId,
1291
- sessionId,
1306
+ userId: titleUserId,
1307
+ sessionId: titleSessionId,
1292
1308
  traceMetadata,
1293
1309
  tags: ['librechat', 'title'],
1294
1310
  });
@@ -1362,15 +1378,30 @@ export class Run<_T extends t.BaseGraphState> {
1362
1378
  runName: chainOptions?.runName ?? titleRunName,
1363
1379
  });
1364
1380
 
1381
+ const invokeTitleChain = (
1382
+ runtimeConfig: Partial<RunnableConfig>
1383
+ ): Promise<{ language?: string; title?: string }> =>
1384
+ withLangfuseAttributes(
1385
+ {
1386
+ langfuse: titleLangfuseConfig,
1387
+ userId: titleUserId,
1388
+ sessionId: titleSessionId,
1389
+ traceName: runtimeConfig.runName ?? titleRunName,
1390
+ traceMetadata,
1391
+ tags: ['librechat', 'title'],
1392
+ },
1393
+ () =>
1394
+ fullChain.invoke(
1395
+ { input: inputText, output: response },
1396
+ runtimeConfig
1397
+ )
1398
+ );
1399
+
1365
1400
  try {
1366
1401
  try {
1367
1402
  return await withLangfuseToolOutputTracingConfig(
1368
1403
  this.langfuse,
1369
- () =>
1370
- fullChain.invoke(
1371
- { input: inputText, output: response },
1372
- invokeConfig
1373
- ),
1404
+ () => invokeTitleChain(invokeConfig),
1374
1405
  titleContext?.langfuse
1375
1406
  );
1376
1407
  } catch (_e) {
@@ -1386,11 +1417,7 @@ export class Run<_T extends t.BaseGraphState> {
1386
1417
  });
1387
1418
  return await withLangfuseToolOutputTracingConfig(
1388
1419
  this.langfuse,
1389
- () =>
1390
- fullChain.invoke(
1391
- { input: inputText, output: response },
1392
- safeConfig as Partial<RunnableConfig>
1393
- ),
1420
+ () => invokeTitleChain(safeConfig as Partial<RunnableConfig>),
1394
1421
  titleContext?.langfuse
1395
1422
  );
1396
1423
  }
@@ -1,11 +1,10 @@
1
1
  import { MemorySaver } from '@langchain/langgraph';
2
2
  import { HumanMessage, BaseMessage } from '@langchain/core/messages';
3
- import type { RunnableConfig } from '@langchain/core/runnables';
4
3
  import type {
5
4
  BaseCheckpointSaver,
6
5
  CheckpointTuple,
7
6
  } from '@langchain/langgraph';
8
- import type { HookRegistry } from '@/hooks';
7
+ import type { RunnableConfig } from '@langchain/core/runnables';
9
8
  import type {
10
9
  AgentSessionConfig,
11
10
  AgentSessionCheckpointing,
@@ -22,15 +21,16 @@ import type {
22
21
  SessionEntry,
23
22
  SessionForkOptions,
24
23
  } from './types';
24
+ import type { HookRegistry } from '@/hooks';
25
25
  import type * as t from '@/types';
26
+ import { deserializeMessage } from './messageSerialization';
27
+ import { createSummarizeNode } from '@/summarization/node';
28
+ import { JsonlSessionStore } from './JsonlSessionStore';
26
29
  import { AgentContext } from '@/agents/AgentContext';
27
30
  import { ContentTypes, GraphEvents } from '@/common';
28
- import { Run } from '@/run';
29
31
  import { createRunId, createSessionId } from './ids';
30
- import { deserializeMessage } from './messageSerialization';
31
- import { JsonlSessionStore } from './JsonlSessionStore';
32
32
  import { createRunHandlers } from './handlers';
33
- import { createSummarizeNode } from '@/summarization/node';
33
+ import { Run } from '@/run';
34
34
 
35
35
  function isBaseMessage(value: unknown): value is BaseMessage {
36
36
  return (
@@ -1,5 +1,6 @@
1
1
  import { homedir } from 'os';
2
2
  import { createHash } from 'crypto';
3
+ import { SystemMessage } from '@langchain/core/messages';
3
4
  import { basename, dirname, isAbsolute, join, resolve } from 'path';
4
5
  import {
5
6
  access,
@@ -10,6 +11,7 @@ import {
10
11
  stat,
11
12
  writeFile,
12
13
  } from 'fs/promises';
14
+ import type { BaseMessage } from '@langchain/core/messages';
13
15
  import type {
14
16
  CreateSessionFileOptions,
15
17
  SessionBranchOptions,
@@ -26,15 +28,13 @@ import type {
26
28
  SessionStateEntry,
27
29
  SessionTreeNode,
28
30
  } from './types';
29
- import type { BaseMessage } from '@langchain/core/messages';
30
- import { SystemMessage } from '@langchain/core/messages';
31
- import { createEntryId, createSessionId, createTimestamp } from './ids';
32
31
  import {
33
32
  deserializeMessage,
34
33
  getMessageRole,
35
34
  serializeMessage,
36
35
  toJsonValue,
37
36
  } from './messageSerialization';
37
+ import { createEntryId, createSessionId, createTimestamp } from './ids';
38
38
 
39
39
  const SESSION_VERSION = 1;
40
40
  const DEFAULT_SESSION_ROOT = join(
@@ -1,19 +1,19 @@
1
- import { mkdtemp, readFile, rm, writeFile } from 'fs/promises';
2
- import { dirname, join } from 'path';
3
1
  import { tmpdir } from 'os';
2
+ import { dirname, join } from 'path';
3
+ import { MemorySaver } from '@langchain/langgraph';
4
+ import { mkdtemp, readFile, rm, writeFile } from 'fs/promises';
4
5
  import {
5
6
  AIMessage,
6
7
  HumanMessage,
7
8
  RemoveMessage,
8
9
  } from '@langchain/core/messages';
9
- import { MemorySaver } from '@langchain/langgraph';
10
- import type { BaseMessage } from '@langchain/core/messages';
11
10
  import type { Checkpoint, CheckpointMetadata } from '@langchain/langgraph';
11
+ import type { BaseMessage } from '@langchain/core/messages';
12
+ import type * as t from '@/types';
12
13
  import { JsonlSessionStore, createAgentSession } from '@/session';
13
14
  import { toJsonValue } from '@/session/messageSerialization';
14
15
  import * as providers from '@/llm/providers';
15
16
  import { GraphEvents } from '@/common';
16
- import type * as t from '@/types';
17
17
  import { Run } from '@/run';
18
18
 
19
19
  type MockRun = {
@@ -1,8 +1,8 @@
1
+ import type { AgentSessionStreamEvent } from '@/session';
2
+ import type * as t from '@/types';
1
3
  import { ContentTypes, GraphEvents, StepTypes } from '@/common';
2
4
  import { composeEventHandlers } from '@/events';
3
5
  import { createRunHandlers } from '@/session';
4
- import type { AgentSessionStreamEvent } from '@/session';
5
- import type * as t from '@/types';
6
6
 
7
7
  describe('createRunHandlers', () => {
8
8
  it('emits live session events through the same graph handlers before user handlers', async () => {
@@ -1,15 +1,15 @@
1
1
  import type { UsageMetadata } from '@langchain/core/messages';
2
- import { GraphEvents } from '@/common';
3
- import { ModelEndHandler, ToolEndHandler } from '@/events';
4
- import { createContentAggregator } from '@/stream';
5
- import type * as t from '@/types';
6
2
  import type {
7
3
  AgentSessionHandlersResult,
8
4
  AgentSessionStreamEvent,
9
5
  AgentSessionUsage,
10
6
  } from './types';
11
- import { createTimestamp } from './ids';
7
+ import type * as t from '@/types';
8
+ import { ModelEndHandler, ToolEndHandler } from '@/events';
12
9
  import { toJsonValue } from './messageSerialization';
10
+ import { createContentAggregator } from '@/stream';
11
+ import { createTimestamp } from './ids';
12
+ import { GraphEvents } from '@/common';
13
13
 
14
14
  type CompletedRunStepResult =
15
15
  | t.ToolEndEvent
@@ -1,6 +1,6 @@
1
1
  import type { RunnableConfig } from '@langchain/core/runnables';
2
- import type { BaseMessage } from '@langchain/core/messages';
3
2
  import type { BaseCheckpointSaver } from '@langchain/langgraph';
3
+ import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type * as t from '@/types';
5
5
 
6
6
  export type JsonPrimitive = string | number | boolean | null;
@@ -1,8 +1,8 @@
1
1
  // src/specs/agent-handoffs.test.ts
2
2
  import { DynamicStructuredTool } from '@langchain/core/tools';
3
3
  import { AIMessage, HumanMessage, ToolMessage } from '@langchain/core/messages';
4
- import type { ToolCall } from '@langchain/core/messages/tool';
5
4
  import type { RunnableConfig } from '@langchain/core/runnables';
5
+ import type { ToolCall } from '@langchain/core/messages/tool';
6
6
  import type * as t from '@/types';
7
7
  import { Providers, GraphEvents, Constants } from '@/common';
8
8
  import { StandardGraph } from '@/graphs/Graph';
@@ -1,8 +1,8 @@
1
- import { CallbackManager } from '@langchain/core/callbacks/manager';
2
1
  import { HumanMessage } from '@langchain/core/messages';
2
+ import { CallbackManager } from '@langchain/core/callbacks/manager';
3
+ import type * as t from '@/types';
3
4
  import { Providers } from '@/common';
4
5
  import { Run } from '@/run';
5
- import type * as t from '@/types';
6
6
 
7
7
  const mockSpan = {
8
8
  end: jest.fn(),
@@ -1,4 +1,5 @@
1
1
  import { CallbackHandler } from '@langfuse/langchain';
2
+ import { propagateAttributes } from '@langfuse/tracing';
2
3
  import { Providers } from '@/common';
3
4
  import { Run } from '@/run';
4
5
 
@@ -6,9 +7,17 @@ jest.mock('@langfuse/langchain', () => ({
6
7
  CallbackHandler: jest.fn().mockImplementation(() => ({})),
7
8
  }));
8
9
 
10
+ jest.mock('@langfuse/tracing', () => ({
11
+ ...jest.requireActual('@langfuse/tracing'),
12
+ propagateAttributes: jest.fn((_params, action: () => unknown) => action()),
13
+ }));
14
+
9
15
  const MockedCallbackHandler = CallbackHandler as jest.MockedClass<
10
16
  typeof CallbackHandler
11
17
  >;
18
+ const MockedPropagateAttributes = propagateAttributes as jest.MockedFunction<
19
+ typeof propagateAttributes
20
+ >;
12
21
 
13
22
  async function createTestRun(
14
23
  agentName?: string,
@@ -70,6 +79,35 @@ describe('Langfuse trace metadata includes agentName', () => {
70
79
  expect(ctorArgs?.traceMetadata).toMatchObject({ agentName: 'DWAINE' });
71
80
  });
72
81
 
82
+ it('propagates Langfuse identity around processStream observations', async () => {
83
+ const run = await createTestRun('DWAINE');
84
+ await run.processStream(
85
+ { messages: [] },
86
+ {
87
+ configurable: {
88
+ thread_id: 'thread-123',
89
+ user_id: 'user-456',
90
+ requestBody: { parentMessageId: 'parent-789' },
91
+ },
92
+ version: 'v2',
93
+ }
94
+ );
95
+
96
+ expect(MockedPropagateAttributes).toHaveBeenCalledTimes(1);
97
+ expect(MockedPropagateAttributes.mock.calls[0][0]).toMatchObject({
98
+ userId: 'user-456',
99
+ sessionId: 'thread-123',
100
+ traceName: 'LibreChat Agent: DWAINE',
101
+ tags: ['librechat', 'agent'],
102
+ metadata: {
103
+ messageId: 'test-run-id',
104
+ parentMessageId: 'parent-789',
105
+ agentId: 'agent_abc123',
106
+ agentName: 'DWAINE',
107
+ },
108
+ });
109
+ });
110
+
73
111
  it('falls back to agentId when agent has no explicit name', async () => {
74
112
  const run = await createTestRun();
75
113
  await run.processStream(
@@ -93,6 +131,7 @@ describe('Langfuse trace metadata includes agentName', () => {
93
131
  );
94
132
 
95
133
  expect(MockedCallbackHandler).not.toHaveBeenCalled();
134
+ expect(MockedPropagateAttributes).not.toHaveBeenCalled();
96
135
  });
97
136
 
98
137
  it('does not create the legacy CallbackHandler when explicit agent config is supplied', async () => {
@@ -1,5 +1,5 @@
1
- import { AIMessage, ToolMessage, HumanMessage } from '@langchain/core/messages';
2
1
  import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
2
+ import { AIMessage, ToolMessage, HumanMessage } from '@langchain/core/messages';
3
3
  import type { ReadableSpan } from '@opentelemetry/sdk-trace-base';
4
4
  import type { BaseMessage } from '@langchain/core/messages';
5
5
  import type { TPayload } from '@/types';
@@ -9,21 +9,21 @@
9
9
  *
10
10
  * Uses FakeListChatModel — no API keys required.
11
11
  */
12
+ import { FakeListChatModel } from '@langchain/core/utils/testing';
12
13
  import {
13
14
  HumanMessage,
14
15
  AIMessage,
15
16
  BaseMessage,
16
17
  UsageMetadata,
17
18
  } from '@langchain/core/messages';
18
- import { FakeListChatModel } from '@langchain/core/utils/testing';
19
19
  import type * as t from '@/types';
20
20
  import { ToolEndHandler, ModelEndHandler } from '@/events';
21
- import { GraphEvents, Providers } from '@/common';
22
- import { createContentAggregator } from '@/stream';
23
21
  import { createTokenCounter } from '@/utils/tokens';
22
+ import { createContentAggregator } from '@/stream';
23
+ import { GraphEvents, Providers } from '@/common';
24
24
  import { getLLMConfig } from '@/utils/llmConfig';
25
- import { Run } from '@/run';
26
25
  import * as providers from '@/llm/providers';
26
+ import { Run } from '@/run';
27
27
 
28
28
  function getSummaryText(summary: t.SummaryContentBlock | undefined): string {
29
29
  if (!summary) return '';
@@ -1,9 +1,8 @@
1
- import { AIMessage, HumanMessage } from '@langchain/core/messages';
2
1
  import { FakeListChatModel } from '@langchain/core/utils/testing';
3
- import type { ToolCall } from '@langchain/core/messages/tool';
2
+ import { AIMessage, HumanMessage } from '@langchain/core/messages';
4
3
  import type { RunnableConfig } from '@langchain/core/runnables';
4
+ import type { ToolCall } from '@langchain/core/messages/tool';
5
5
  import type * as t from '@/types';
6
- import { Run } from '@/run';
7
6
  import {
8
7
  Constants,
9
8
  GraphEvents,
@@ -13,6 +12,7 @@ import {
13
12
  StandardGraph,
14
13
  } from '@/index';
15
14
  import * as providers from '@/llm/providers';
15
+ import { Run } from '@/run';
16
16
 
17
17
  const CHILD_RESPONSE = 'Research result: Paris is the capital of France.';
18
18
 
@@ -12,8 +12,8 @@ import {
12
12
  createPruneMessages,
13
13
  } from '@/messages/prune';
14
14
  import { shouldTriggerSummarization } from '@/summarization/index';
15
- import { Providers } from '@/common';
16
15
  import { SummarizationTrigger } from '@/types';
16
+ import { Providers } from '@/common';
17
17
 
18
18
  // ---------------------------------------------------------------------------
19
19
  // Shared helpers
@@ -1,7 +1,7 @@
1
1
  // src/specs/thinking-handoff.test.ts
2
2
  import { HumanMessage, ToolMessage } from '@langchain/core/messages';
3
- import type { ToolCall } from '@langchain/core/messages/tool';
4
3
  import type { RunnableConfig } from '@langchain/core/runnables';
4
+ import type { ToolCall } from '@langchain/core/messages/tool';
5
5
  import type * as t from '@/types';
6
6
  import { Providers, Constants } from '@/common';
7
7
  import { StandardGraph } from '@/graphs/Graph';
@@ -225,6 +225,54 @@ describe('ContentAggregator empty deltas', () => {
225
225
  });
226
226
  });
227
227
 
228
+ describe('ContentAggregator provider-specific parts', () => {
229
+ it('should preserve Gemini server-side tool content blocks', () => {
230
+ const { contentParts, aggregateContent } = createContentAggregator();
231
+ const toolCallPart: t.MessageContentComplex = {
232
+ type: 'toolCall',
233
+ toolCall: {
234
+ id: 'server-search-1',
235
+ name: 'google_search',
236
+ args: {},
237
+ },
238
+ };
239
+ const toolResponsePart: t.MessageContentComplex = {
240
+ type: 'toolResponse',
241
+ toolResponse: {
242
+ id: 'server-search-1',
243
+ name: 'google_search',
244
+ response: { results: [] },
245
+ },
246
+ };
247
+
248
+ aggregateContent({
249
+ event: GraphEvents.ON_RUN_STEP,
250
+ data: createRunStep('step_tool_call'),
251
+ });
252
+ aggregateContent({
253
+ event: GraphEvents.ON_MESSAGE_DELTA,
254
+ data: {
255
+ id: 'step_tool_call',
256
+ delta: { content: [toolCallPart] },
257
+ },
258
+ });
259
+ aggregateContent({
260
+ event: GraphEvents.ON_RUN_STEP,
261
+ data: { ...createRunStep('step_tool_response'), index: 1 },
262
+ });
263
+ aggregateContent({
264
+ event: GraphEvents.ON_MESSAGE_DELTA,
265
+ data: {
266
+ id: 'step_tool_response',
267
+ delta: { content: [toolResponsePart] },
268
+ },
269
+ });
270
+
271
+ expect(contentParts[0]).toEqual(toolCallPart);
272
+ expect(contentParts[1]).toEqual(toolResponsePart);
273
+ });
274
+ });
275
+
228
276
  describe('ContentAggregator with SplitStreamHandler', () => {
229
277
  it('should aggregate content from multiple message blocks', async () => {
230
278
  const runId = nanoid();