@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,16 +1,8 @@
1
- import {
2
- POSSIBLE_ROLES,
3
- type Part,
4
- type Content,
5
- type TextPart,
6
- type FileDataPart,
7
- type InlineDataPart,
8
- type FunctionCallPart,
9
- type GenerateContentCandidate,
10
- type EnhancedGenerateContentResponse,
11
- type FunctionDeclaration as GenerativeAIFunctionDeclaration,
12
- type FunctionDeclarationsTool as GoogleGenerativeAIFunctionDeclarationsTool,
13
- } from '@google/generative-ai';
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ import { ChatGenerationChunk } from '@langchain/core/outputs';
3
+ import { ToolCallChunk } from '@langchain/core/messages/tool';
4
+ import { isOpenAITool } from '@langchain/core/language_models/base';
5
+ import { isLangChainTool } from '@langchain/core/utils/function_calling';
14
6
  import {
15
7
  AIMessage,
16
8
  AIMessageChunk,
@@ -29,18 +21,26 @@ import {
29
21
  convertToProviderContentBlock,
30
22
  isDataContentBlock,
31
23
  } from '@langchain/core/messages';
32
- import { ChatGenerationChunk } from '@langchain/core/outputs';
24
+ import {
25
+ POSSIBLE_ROLES,
26
+ type Part,
27
+ type Content,
28
+ type TextPart,
29
+ type FileDataPart,
30
+ type InlineDataPart,
31
+ type FunctionCallPart,
32
+ type GenerateContentCandidate,
33
+ type EnhancedGenerateContentResponse,
34
+ type FunctionDeclaration as GenerativeAIFunctionDeclaration,
35
+ type FunctionDeclarationsTool as GoogleGenerativeAIFunctionDeclarationsTool,
36
+ } from '@google/generative-ai';
33
37
  import type { ChatGeneration, ChatResult } from '@langchain/core/outputs';
34
- import { isLangChainTool } from '@langchain/core/utils/function_calling';
35
- import { isOpenAITool } from '@langchain/core/language_models/base';
36
- import { ToolCallChunk } from '@langchain/core/messages/tool';
37
- import { v4 as uuidv4 } from 'uuid';
38
38
  import {
39
39
  jsonSchemaToGeminiParameters,
40
40
  schemaToGenerativeAIParameters,
41
41
  } from './zod_to_genai_parameters';
42
- import { GoogleGenerativeAIToolType } from '../types';
43
42
  import { toLangChainContent } from '@/messages/langchain';
43
+ import { GoogleGenerativeAIToolType } from '../types';
44
44
 
45
45
  export const _FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY =
46
46
  '__gemini_function_call_thought_signatures__';
@@ -48,6 +48,49 @@ export const _FUNCTION_CALL_THOUGHT_SIGNATURES_MAP_KEY =
48
48
  const DUMMY_SIGNATURE =
49
49
  'ErYCCrMCAdHtim9kOoOkrPiCNVsmlpMIKd7ZMxgiFbVQOkgp7nlLcDMzVsZwIzvuT7nQROivoXA72ccC2lSDvR0Gh7dkWaGuj7ctv6t7ZceHnecx0QYa+ix8tYpRfjhyWozQ49lWiws6+YGjCt10KRTyWsZ2h6O7iHTYJwKIRwGUHRKy/qK/6kFxJm5ML00gLq4D8s5Z6DBpp2ZlR+uF4G8jJgeWQgyHWVdx2wGYElaceVAc66tZdPQRdOHpWtgYSI1YdaXgVI8KHY3/EfNc2YqqMIulvkDBAnuMhkAjV9xmBa54Tq+ih3Im4+r3DzqhGqYdsSkhS0kZMwte4Hjs65dZzCw9lANxIqYi1DJ639WNPYihp/DCJCos7o+/EeSPJaio5sgWDyUnMGkY1atsJZ+m7pj7DD5tvQ==';
50
50
 
51
+ type GoogleServerSideToolPart = Part & {
52
+ type?: 'toolCall' | 'toolResponse';
53
+ toolCall?: object;
54
+ toolResponse?: object;
55
+ };
56
+
57
+ type GoogleServerSideToolPartMetadata = {
58
+ thought?: boolean;
59
+ thoughtSignature?: string;
60
+ };
61
+
62
+ type GoogleFunctionCallWithId = FunctionCallPart['functionCall'] & {
63
+ id?: string;
64
+ };
65
+
66
+ type GoogleFunctionResponseWithId = {
67
+ name: string;
68
+ response: object;
69
+ id?: string;
70
+ };
71
+
72
+ function getGoogleFunctionId(id?: string): string | undefined {
73
+ return id != null && id !== '' ? id : undefined;
74
+ }
75
+
76
+ function createGoogleFunctionResponsePart({
77
+ name,
78
+ response,
79
+ id,
80
+ }: {
81
+ name: string;
82
+ response: object;
83
+ id?: string;
84
+ }): Part {
85
+ const functionId = getGoogleFunctionId(id);
86
+ const functionResponse: GoogleFunctionResponseWithId = {
87
+ name,
88
+ response,
89
+ ...(functionId != null ? { id: functionId } : {}),
90
+ };
91
+ return { functionResponse };
92
+ }
93
+
51
94
  /**
52
95
  * Executes a function immediately and returns its result.
53
96
  * Functional utility similar to an Immediately Invoked Function Expression (IIFE).
@@ -118,6 +161,63 @@ function messageContentMedia(content: MessageContentComplex): Part {
118
161
  throw new Error('Invalid media content');
119
162
  }
120
163
 
164
+ function isGoogleServerSideToolPart(
165
+ content: MessageContentComplex
166
+ ): content is MessageContentComplex & GoogleServerSideToolPart {
167
+ return (
168
+ 'toolCall' in content ||
169
+ 'toolResponse' in content ||
170
+ content.type === 'toolCall' ||
171
+ content.type === 'toolResponse'
172
+ );
173
+ }
174
+
175
+ function convertGoogleServerSideToolPart(
176
+ content: MessageContentComplex & GoogleServerSideToolPart
177
+ ): Part {
178
+ const metadata: GoogleServerSideToolPartMetadata = {};
179
+ if ('thought' in content && typeof content.thought === 'boolean') {
180
+ metadata.thought = content.thought;
181
+ }
182
+ if (
183
+ 'thoughtSignature' in content &&
184
+ typeof content.thoughtSignature === 'string'
185
+ ) {
186
+ metadata.thoughtSignature = content.thoughtSignature;
187
+ }
188
+ if ('toolCall' in content && content.toolCall != null) {
189
+ return { toolCall: content.toolCall, ...metadata } as unknown as Part;
190
+ }
191
+ if ('toolResponse' in content && content.toolResponse != null) {
192
+ return {
193
+ toolResponse: content.toolResponse,
194
+ ...metadata,
195
+ } as unknown as Part;
196
+ }
197
+
198
+ return content as Part;
199
+ }
200
+
201
+ function convertGoogleServerSideToolResponsePart(
202
+ part: Part
203
+ ): GoogleServerSideToolPart | undefined {
204
+ if (
205
+ 'toolCall' in part &&
206
+ typeof part.toolCall === 'object' &&
207
+ part.toolCall != null
208
+ ) {
209
+ return { ...part, type: 'toolCall', toolCall: part.toolCall };
210
+ }
211
+ if (
212
+ 'toolResponse' in part &&
213
+ typeof part.toolResponse === 'object' &&
214
+ part.toolResponse != null
215
+ ) {
216
+ return { ...part, type: 'toolResponse', toolResponse: part.toolResponse };
217
+ }
218
+ return undefined;
219
+ }
220
+
121
221
  function inferToolNameFromPreviousMessages(
122
222
  message: ToolMessage | ToolMessageChunk,
123
223
  previousMessages: BaseMessage[]
@@ -280,6 +380,10 @@ function _convertLangChainContentToPart(
280
380
  );
281
381
  }
282
382
 
383
+ if (isGoogleServerSideToolPart(content)) {
384
+ return convertGoogleServerSideToolPart(content);
385
+ }
386
+
283
387
  if (content.type === 'text') {
284
388
  return { text: content.text };
285
389
  } else if (content.type === 'executableCode') {
@@ -375,25 +479,23 @@ export function convertMessageContentToParts(
375
479
 
376
480
  if (message.status === 'error') {
377
481
  return [
378
- {
379
- functionResponse: {
380
- name: messageName,
381
- // The API expects an object with an `error` field if the function call fails.
382
- // `error` must be a valid object (not a string or array), so we wrap `message.content` here
383
- response: { error: { details: result } },
384
- },
385
- },
482
+ createGoogleFunctionResponsePart({
483
+ name: messageName,
484
+ // The API expects an object with an `error` field if the function call fails.
485
+ // `error` must be a valid object (not a string or array), so we wrap `message.content` here
486
+ response: { error: { details: result } },
487
+ id: message.tool_call_id,
488
+ }),
386
489
  ];
387
490
  }
388
491
 
389
492
  return [
390
- {
391
- functionResponse: {
392
- name: messageName,
393
- // again, can't have a string or array value for `response`, so we wrap it as an object here
394
- response: { result },
395
- },
396
- },
493
+ createGoogleFunctionResponsePart({
494
+ name: messageName,
495
+ // again, can't have a string or array value for `response`, so we wrap it as an object here
496
+ response: { result },
497
+ id: message.tool_call_id,
498
+ }),
397
499
  ];
398
500
  }
399
501
 
@@ -432,12 +534,15 @@ export function convertMessageContentToParts(
432
534
  }
433
535
  return '';
434
536
  });
537
+ const functionId = getGoogleFunctionId(tc.id);
538
+ const functionCall: GoogleFunctionCallWithId = {
539
+ name: tc.name,
540
+ args: tc.args,
541
+ ...(functionId != null ? { id: functionId } : {}),
542
+ };
435
543
 
436
544
  return {
437
- functionCall: {
438
- name: tc.name,
439
- args: tc.args,
440
- },
545
+ functionCall,
441
546
  ...(thoughtSignature ? { thoughtSignature } : {}),
442
547
  };
443
548
  });
@@ -598,6 +703,10 @@ export function convertResponseContentToChatGenerationChunk(
598
703
  codeExecutionResult: p.codeExecutionResult,
599
704
  };
600
705
  }
706
+ const serverSideToolPart = convertGoogleServerSideToolResponsePart(p);
707
+ if (serverSideToolPart !== undefined) {
708
+ return serverSideToolPart;
709
+ }
601
710
  return p;
602
711
  })
603
712
  .filter((p) => p !== undefined)
@@ -685,11 +794,7 @@ export function mapGenerateContentResultToChatResult(
685
794
  usageMetadata: UsageMetadata | undefined;
686
795
  }
687
796
  ): ChatResult {
688
- if (
689
- !response.candidates ||
690
- response.candidates.length === 0 ||
691
- !response.candidates[0]
692
- ) {
797
+ if (!response.candidates || response.candidates.length === 0) {
693
798
  return {
694
799
  generations: [],
695
800
  llmOutput: {
@@ -725,7 +830,7 @@ export function mapGenerateContentResultToChatResult(
725
830
  if (
726
831
  Array.isArray(candidateContent?.parts) &&
727
832
  candidateContent.parts.length === 1 &&
728
- candidateContent.parts[0].text &&
833
+ (candidateContent.parts[0].text ?? '') !== '' &&
729
834
  !(
730
835
  'thought' in candidateContent.parts[0] &&
731
836
  candidateContent.parts[0].thought === true
@@ -758,6 +863,10 @@ export function mapGenerateContentResultToChatResult(
758
863
  codeExecutionResult: p.codeExecutionResult,
759
864
  };
760
865
  }
866
+ const serverSideToolPart = convertGoogleServerSideToolResponsePart(p);
867
+ if (serverSideToolPart !== undefined) {
868
+ return serverSideToolPart;
869
+ }
761
870
  return p;
762
871
  })
763
872
  .filter((p) => p !== undefined)
@@ -807,7 +916,7 @@ export function mapGenerateContentResultToChatResult(
807
916
  const generation: ChatGeneration = {
808
917
  text,
809
918
  message: new AIMessage({
810
- content: content ?? '',
919
+ content,
811
920
  tool_calls,
812
921
  additional_kwargs,
813
922
  usage_metadata: extra?.usageMetadata,
@@ -1,3 +1,10 @@
1
+ import { StructuredToolInterface } from '@langchain/core/tools';
2
+ import { ToolChoice } from '@langchain/core/language_models/chat_models';
3
+ import { isLangChainTool } from '@langchain/core/utils/function_calling';
4
+ import {
5
+ isOpenAITool,
6
+ ToolDefinition,
7
+ } from '@langchain/core/language_models/base';
1
8
  import {
2
9
  Tool as GenerativeAITool,
3
10
  ToolConfig,
@@ -6,16 +13,9 @@ import {
6
13
  FunctionDeclarationsTool,
7
14
  FunctionDeclarationSchema,
8
15
  } from '@google/generative-ai';
9
- import { ToolChoice } from '@langchain/core/language_models/chat_models';
10
- import { StructuredToolInterface } from '@langchain/core/tools';
11
- import { isLangChainTool } from '@langchain/core/utils/function_calling';
12
- import {
13
- isOpenAITool,
14
- ToolDefinition,
15
- } from '@langchain/core/language_models/base';
16
+ import { removeAdditionalProperties } from './zod_to_genai_parameters';
16
17
  import { convertToGenerativeAITools } from './common';
17
18
  import { GoogleGenerativeAIToolType } from '../types';
18
- import { removeAdditionalProperties } from './zod_to_genai_parameters';
19
19
 
20
20
  export function convertToolsToGenAI(
21
21
  tools: GoogleGenerativeAIToolType[],
@@ -1,7 +1,3 @@
1
- import {
2
- type FunctionDeclarationSchema as GenerativeAIFunctionDeclarationSchema,
3
- type SchemaType as FunctionDeclarationSchemaType,
4
- } from '@google/generative-ai';
5
1
  import {
6
2
  InteropZodType,
7
3
  isInteropZodSchema,
@@ -10,6 +6,10 @@ import {
10
6
  type JsonSchema7Type,
11
7
  toJsonSchema,
12
8
  } from '@langchain/core/utils/json_schema';
9
+ import {
10
+ type FunctionDeclarationSchema as GenerativeAIFunctionDeclarationSchema,
11
+ type SchemaType as FunctionDeclarationSchemaType,
12
+ } from '@google/generative-ai';
13
13
 
14
14
  export interface GenerativeAIJsonSchema extends Record<string, unknown> {
15
15
  properties?: Record<string, GenerativeAIJsonSchema>;
@@ -1,17 +1,17 @@
1
1
  import { z } from 'zod';
2
2
  import { tool } from '@langchain/core/tools';
3
+ import { describe, it, expect, jest } from '@jest/globals';
3
4
  import {
4
5
  AIMessage,
5
6
  AIMessageChunk,
6
7
  HumanMessage,
7
8
  ToolMessage,
8
9
  } from '@langchain/core/messages';
9
- import { describe, it, expect, jest } from '@jest/globals';
10
- import type { BaseMessage } from '@langchain/core/messages';
11
10
  import type { StructuredToolInterface } from '@langchain/core/tools';
11
+ import type { BaseMessage } from '@langchain/core/messages';
12
12
  import type * as t from '@/types';
13
- import { attemptInvoke, tryFallbackProviders } from '@/llm/invoke';
14
13
  import { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
14
+ import { attemptInvoke, tryFallbackProviders } from '@/llm/invoke';
15
15
  import { ToolNode } from '@/tools/ToolNode';
16
16
  import { Providers } from '@/common';
17
17
 
package/src/llm/invoke.ts CHANGED
@@ -5,8 +5,8 @@ import type { ToolCall } from '@langchain/core/messages/tool';
5
5
  import type { BaseMessage } from '@langchain/core/messages';
6
6
  import type { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
7
7
  import type * as t from '@/types';
8
- import { manualToolStreamProviders } from '@/llm/providers';
9
8
  import { annotateMessagesForLLM } from '@/tools/toolOutputReferences';
9
+ import { manualToolStreamProviders } from '@/llm/providers';
10
10
  import { modifyDeltaProperties } from '@/messages';
11
11
  import { ChatModelStreamHandler } from '@/stream';
12
12
  import { GraphEvents, Providers } from '@/common';
@@ -51,6 +51,127 @@ export type InvokeContext = NonNullable<
51
51
  */
52
52
  export type OnChunk = (chunk: AIMessageChunk) => void | Promise<void>;
53
53
 
54
+ function getRegisteredDefaultChatStreamHandler(
55
+ context?: InvokeContext
56
+ ): ChatModelStreamHandler | undefined {
57
+ const handler = context?.handlerRegistry?.getHandler(
58
+ GraphEvents.CHAT_MODEL_STREAM
59
+ );
60
+ return handler instanceof ChatModelStreamHandler ? handler : undefined;
61
+ }
62
+
63
+ function hasReasoningDetails(chunk: AIMessageChunk): boolean {
64
+ const reasoningDetails = chunk.additional_kwargs.reasoning_details;
65
+ return Array.isArray(reasoningDetails) && reasoningDetails.length > 0;
66
+ }
67
+
68
+ function removeOpenRouterFinalReasoningReplayContent({
69
+ current,
70
+ next,
71
+ provider,
72
+ }: {
73
+ current?: AIMessageChunk;
74
+ next: AIMessageChunk;
75
+ provider: Providers;
76
+ }): AIMessageChunk {
77
+ const content = getOpenRouterFinalReasoningContent({
78
+ current,
79
+ next,
80
+ provider,
81
+ });
82
+ if (content == null || content === next.content) {
83
+ return next;
84
+ }
85
+
86
+ return new AIMessageChunk(
87
+ Object.assign({}, next, {
88
+ content,
89
+ })
90
+ );
91
+ }
92
+
93
+ function getOpenRouterFinalReasoningContent({
94
+ current,
95
+ next,
96
+ provider,
97
+ }: {
98
+ current?: AIMessageChunk;
99
+ next: AIMessageChunk;
100
+ provider: Providers;
101
+ }): string | undefined {
102
+ if (
103
+ provider !== Providers.OPENROUTER ||
104
+ current == null ||
105
+ !hasReasoningDetails(next) ||
106
+ typeof current.content !== 'string' ||
107
+ current.content === '' ||
108
+ typeof next.content !== 'string' ||
109
+ next.content === ''
110
+ ) {
111
+ return undefined;
112
+ }
113
+ if (!next.content.startsWith(current.content)) {
114
+ return next.content;
115
+ }
116
+ return next.content.slice(current.content.length);
117
+ }
118
+
119
+ function removeReasoningDetails(
120
+ additionalKwargs: AIMessageChunk['additional_kwargs']
121
+ ): AIMessageChunk['additional_kwargs'] {
122
+ return Object.fromEntries(
123
+ Object.entries(additionalKwargs).filter(
124
+ ([key]) => key !== 'reasoning_details'
125
+ )
126
+ );
127
+ }
128
+
129
+ function getStreamHandlingChunk({
130
+ current,
131
+ next,
132
+ provider,
133
+ }: {
134
+ current?: AIMessageChunk;
135
+ next: AIMessageChunk;
136
+ provider: Providers;
137
+ }): AIMessageChunk | undefined {
138
+ const content = getOpenRouterFinalReasoningContent({
139
+ current,
140
+ next,
141
+ provider,
142
+ });
143
+ if (content == null) {
144
+ return next;
145
+ }
146
+ if (content === '') {
147
+ return undefined;
148
+ }
149
+ return new AIMessageChunk(
150
+ Object.assign({}, next, {
151
+ content,
152
+ additional_kwargs: removeReasoningDetails(next.additional_kwargs),
153
+ })
154
+ );
155
+ }
156
+
157
+ function appendStreamChunk({
158
+ current,
159
+ next,
160
+ provider,
161
+ }: {
162
+ current?: AIMessageChunk;
163
+ next: AIMessageChunk;
164
+ provider: Providers;
165
+ }): AIMessageChunk {
166
+ if (current == null) {
167
+ return next;
168
+ }
169
+ return concat(
170
+ current,
171
+ removeOpenRouterFinalReasoningReplayContent({ current, next, provider })
172
+ );
173
+ }
174
+
54
175
  /**
55
176
  * Invokes a chat model with the given messages, handling both streaming and
56
177
  * non-streaming paths.
@@ -90,23 +211,62 @@ export async function attemptInvoke(
90
211
  if (model.stream) {
91
212
  const stream = await model.stream(messagesForProvider, config);
92
213
  let finalChunk: AIMessageChunk | undefined;
214
+ const registeredStreamHandler =
215
+ getRegisteredDefaultChatStreamHandler(context);
93
216
 
94
217
  if (onChunk) {
95
218
  for await (const chunk of stream) {
96
219
  await onChunk(chunk);
97
- finalChunk = finalChunk ? concat(finalChunk, chunk) : chunk;
220
+ finalChunk = appendStreamChunk({
221
+ current: finalChunk,
222
+ next: chunk,
223
+ provider,
224
+ });
98
225
  }
99
- } else {
226
+ } else if (registeredStreamHandler == null) {
100
227
  const metadata = config?.metadata as Record<string, unknown> | undefined;
101
228
  const streamHandler = new ChatModelStreamHandler();
102
229
  for await (const chunk of stream) {
103
- await streamHandler.handle(
104
- GraphEvents.CHAT_MODEL_STREAM,
105
- { chunk },
106
- metadata,
107
- context
108
- );
109
- finalChunk = finalChunk ? concat(finalChunk, chunk) : chunk;
230
+ const handlingChunk = getStreamHandlingChunk({
231
+ current: finalChunk,
232
+ next: chunk,
233
+ provider,
234
+ });
235
+ if (handlingChunk != null) {
236
+ await streamHandler.handle(
237
+ GraphEvents.CHAT_MODEL_STREAM,
238
+ { chunk: handlingChunk },
239
+ metadata,
240
+ context
241
+ );
242
+ }
243
+ finalChunk = appendStreamChunk({
244
+ current: finalChunk,
245
+ next: chunk,
246
+ provider,
247
+ });
248
+ }
249
+ } else {
250
+ const metadata = config?.metadata as Record<string, unknown> | undefined;
251
+ for await (const chunk of stream) {
252
+ const handlingChunk = getStreamHandlingChunk({
253
+ current: finalChunk,
254
+ next: chunk,
255
+ provider,
256
+ });
257
+ if (handlingChunk != null && handlingChunk !== chunk) {
258
+ await registeredStreamHandler.handle(
259
+ GraphEvents.CHAT_MODEL_STREAM,
260
+ { chunk: handlingChunk },
261
+ metadata,
262
+ context
263
+ );
264
+ }
265
+ finalChunk = appendStreamChunk({
266
+ current: finalChunk,
267
+ next: chunk,
268
+ provider,
269
+ });
110
270
  }
111
271
  }
112
272
 
@@ -1,18 +1,18 @@
1
1
  import { AzureOpenAI as AzureOpenAIClient } from 'openai';
2
2
  import { ChatXAI as OriginalChatXAI } from '@langchain/xai';
3
3
  import { ChatGenerationChunk } from '@langchain/core/outputs';
4
+ import { ToolDefinition } from '@langchain/core/language_models/base';
5
+ import { ChatDeepSeek as OriginalChatDeepSeek } from '@langchain/deepseek';
6
+ import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
4
7
  import {
5
8
  AIMessage,
6
9
  AIMessageChunk,
7
10
  isAIMessage,
8
11
  } from '@langchain/core/messages';
9
- import { ToolDefinition } from '@langchain/core/language_models/base';
10
12
  import {
11
13
  convertToOpenAITool,
12
14
  isLangChainTool,
13
15
  } from '@langchain/core/utils/function_calling';
14
- import { ChatDeepSeek as OriginalChatDeepSeek } from '@langchain/deepseek';
15
- import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
16
16
  import {
17
17
  getEndpoint,
18
18
  OpenAIClient,
@@ -24,7 +24,6 @@ import {
24
24
  AzureChatOpenAIResponses as OriginalAzureChatOpenAIResponses,
25
25
  AzureChatOpenAICompletions as OriginalAzureChatOpenAICompletions,
26
26
  } from '@langchain/openai';
27
- import type { HeaderValue, HeadersLike } from './types';
28
27
  import type {
29
28
  BaseMessage,
30
29
  BaseMessageChunk,
@@ -34,6 +33,7 @@ import type { BindToolsInput } from '@langchain/core/language_models/chat_models
34
33
  import type { ChatGeneration, ChatResult } from '@langchain/core/outputs';
35
34
  import type { ChatXAIInput } from '@langchain/xai';
36
35
  import type * as t from '@langchain/openai';
36
+ import type { HeaderValue, HeadersLike } from './types';
37
37
  import { isReasoningModel, _convertMessagesToOpenAIParams } from './utils';
38
38
 
39
39
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable @typescript-eslint/ban-ts-comment */
2
2
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
3
3
  import { type OpenAI as OpenAIClient } from 'openai';
4
- import type {
5
- ChatCompletionContentPartText,
6
- ChatCompletionContentPartImage,
7
- ChatCompletionContentPartInputAudio,
8
- ChatCompletionContentPart,
9
- } from 'openai/resources/chat/completions';
4
+ import { ChatGenerationChunk } from '@langchain/core/outputs';
5
+ import {
6
+ convertLangChainToolCallToOpenAI,
7
+ makeInvalidToolCall,
8
+ parseToolCall,
9
+ } from '@langchain/core/output_parsers/openai_tools';
10
10
  import {
11
11
  AIMessage,
12
12
  AIMessageChunk,
@@ -25,24 +25,24 @@ import {
25
25
  convertToProviderContentBlock,
26
26
  isDataContentBlock,
27
27
  } from '@langchain/core/messages';
28
- import { ChatGenerationChunk } from '@langchain/core/outputs';
29
- import {
30
- convertLangChainToolCallToOpenAI,
31
- makeInvalidToolCall,
32
- parseToolCall,
33
- } from '@langchain/core/output_parsers/openai_tools';
34
- import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
28
+ import type {
29
+ ChatCompletionContentPartText,
30
+ ChatCompletionContentPartImage,
31
+ ChatCompletionContentPartInputAudio,
32
+ ChatCompletionContentPart,
33
+ } from 'openai/resources/chat/completions';
35
34
  import type {
36
35
  OpenAICallOptions,
37
36
  OpenAIChatInput,
38
37
  ChatOpenAIReasoningSummary,
39
38
  } from '@langchain/openai';
40
- import { toLangChainContent } from '@/messages/langchain';
39
+ import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
41
40
  import {
42
41
  STREAMED_TOOL_CALL_SEAL_METADATA_KEY,
43
42
  STREAMED_TOOL_CALL_ADAPTER_METADATA_KEY,
44
43
  OPENAI_RESPONSES_STREAMED_TOOL_CALL_ADAPTER,
45
44
  } from '@/tools/streamedToolCallSeals';
45
+ import { toLangChainContent } from '@/messages/langchain';
46
46
 
47
47
  export type { OpenAICallOptions, OpenAIChatInput };
48
48
 
@@ -1,12 +1,12 @@
1
- import { ChatOpenAI, emitStreamChunkCallback } from '@/llm/openai';
2
- import type { BaseMessage } from '@langchain/core/messages';
3
- import type { ChatGenerationChunk } from '@langchain/core/outputs';
4
- import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
5
1
  import type {
6
2
  ChatOpenAICallOptions,
7
3
  OpenAIChatInput,
8
4
  OpenAIClient,
9
5
  } from '@langchain/openai';
6
+ import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
7
+ import type { ChatGenerationChunk } from '@langchain/core/outputs';
8
+ import type { BaseMessage } from '@langchain/core/messages';
9
+ import { ChatOpenAI, emitStreamChunkCallback } from '@/llm/openai';
10
10
 
11
11
  export type OpenRouterReasoningEffort =
12
12
  | 'xhigh'
@@ -1,6 +1,6 @@
1
- import { ChatOpenRouter } from './index';
2
- import type { OpenRouterReasoning, ChatOpenRouterCallOptions } from './index';
3
1
  import type { OpenAIChatInput } from '@langchain/openai';
2
+ import type { OpenRouterReasoning, ChatOpenRouterCallOptions } from './index';
3
+ import { ChatOpenRouter } from './index';
4
4
 
5
5
  type CreateRouterOptions = Partial<
6
6
  ChatOpenRouterCallOptions &