@librechat/agents 3.2.21 → 3.2.32

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 (402) 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 +38 -3
  20. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  21. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +6 -2
  22. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  23. package/dist/cjs/llm/bedrock/index.cjs +2 -2
  24. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  25. package/dist/cjs/llm/bedrock/toolCache.cjs +8 -5
  26. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  27. package/dist/cjs/llm/fake.cjs +16 -14
  28. package/dist/cjs/llm/fake.cjs.map +1 -1
  29. package/dist/cjs/llm/google/index.cjs +22 -0
  30. package/dist/cjs/llm/google/index.cjs.map +1 -1
  31. package/dist/cjs/llm/google/utils/common.cjs +88 -27
  32. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  33. package/dist/cjs/llm/init.cjs +2 -2
  34. package/dist/cjs/llm/invoke.cjs +108 -11
  35. package/dist/cjs/llm/invoke.cjs.map +1 -1
  36. package/dist/cjs/llm/openai/index.cjs +1 -1
  37. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  38. package/dist/cjs/llm/openai/utils/index.cjs +1 -1
  39. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  40. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  41. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  42. package/dist/cjs/main.cjs +1 -0
  43. package/dist/cjs/main.cjs.map +1 -1
  44. package/dist/cjs/messages/cache.cjs +29 -8
  45. package/dist/cjs/messages/cache.cjs.map +1 -1
  46. package/dist/cjs/messages/content.cjs.map +1 -1
  47. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  48. package/dist/cjs/messages/format.cjs +129 -17
  49. package/dist/cjs/messages/format.cjs.map +1 -1
  50. package/dist/cjs/messages/prune.cjs.map +1 -1
  51. package/dist/cjs/messages/reducer.cjs +1 -1
  52. package/dist/cjs/messages/reducer.cjs.map +1 -1
  53. package/dist/cjs/messages/tools.cjs +1 -1
  54. package/dist/cjs/messages/tools.cjs.map +1 -1
  55. package/dist/cjs/openai/index.cjs.map +1 -1
  56. package/dist/cjs/responses/index.cjs.map +1 -1
  57. package/dist/cjs/run.cjs +41 -20
  58. package/dist/cjs/run.cjs.map +1 -1
  59. package/dist/cjs/session/AgentSession.cjs +4 -4
  60. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  61. package/dist/cjs/session/JsonlSessionStore.cjs +2 -2
  62. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  63. package/dist/cjs/session/handlers.cjs +2 -2
  64. package/dist/cjs/session/handlers.cjs.map +1 -1
  65. package/dist/cjs/stream.cjs +248 -25
  66. package/dist/cjs/stream.cjs.map +1 -1
  67. package/dist/cjs/summarization/node.cjs.map +1 -1
  68. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +1 -1
  69. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  70. package/dist/cjs/tools/Calculator.cjs +1 -1
  71. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  72. package/dist/cjs/tools/CodeExecutor.cjs +1 -1
  73. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  74. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  75. package/dist/cjs/tools/ToolNode.cjs +37 -18
  76. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  77. package/dist/cjs/tools/ToolSearch.cjs +1 -1
  78. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  79. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +7 -4
  80. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  81. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +4 -4
  82. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  83. package/dist/cjs/tools/handlers.cjs +2 -1
  84. package/dist/cjs/tools/handlers.cjs.map +1 -1
  85. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  86. package/dist/cjs/tools/local/FileCheckpointer.cjs +2 -1
  87. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  88. package/dist/cjs/tools/local/LocalCodingTools.cjs +45 -19
  89. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  90. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +3 -3
  91. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  92. package/dist/cjs/tools/local/LocalExecutionTools.cjs +2 -2
  93. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  94. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +4 -3
  95. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  96. package/dist/cjs/tools/local/attachments.cjs +0 -5
  97. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  98. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +4 -4
  99. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  100. package/dist/cjs/tools/search/firecrawl.cjs +1 -1
  101. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  102. package/dist/cjs/tools/search/rerankers.cjs +7 -3
  103. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  104. package/dist/cjs/tools/search/tavily-search.cjs +1 -1
  105. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  106. package/dist/cjs/tools/search/utils.cjs +76 -8
  107. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  108. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
  109. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  110. package/dist/cjs/utils/handlers.cjs +1 -1
  111. package/dist/cjs/utils/handlers.cjs.map +1 -1
  112. package/dist/cjs/utils/run.cjs +1 -1
  113. package/dist/cjs/utils/run.cjs.map +1 -1
  114. package/dist/esm/agents/AgentContext.mjs +3 -2
  115. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  116. package/dist/esm/events.mjs.map +1 -1
  117. package/dist/esm/graphs/Graph.mjs +200 -54
  118. package/dist/esm/graphs/Graph.mjs.map +1 -1
  119. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  120. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +13 -7
  121. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  122. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  123. package/dist/esm/hooks/types.mjs.map +1 -1
  124. package/dist/esm/instrumentation.mjs +2 -2
  125. package/dist/esm/instrumentation.mjs.map +1 -1
  126. package/dist/esm/langfuse.mjs +17 -2
  127. package/dist/esm/langfuse.mjs.map +1 -1
  128. package/dist/esm/langfuseToolOutputTracing.mjs +2 -2
  129. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  130. package/dist/esm/llm/anthropic/index.mjs +1 -1
  131. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  132. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +38 -3
  133. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  134. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +6 -2
  135. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  136. package/dist/esm/llm/bedrock/index.mjs +2 -2
  137. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  138. package/dist/esm/llm/bedrock/toolCache.mjs +8 -5
  139. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  140. package/dist/esm/llm/fake.mjs +16 -14
  141. package/dist/esm/llm/fake.mjs.map +1 -1
  142. package/dist/esm/llm/google/index.mjs +23 -1
  143. package/dist/esm/llm/google/index.mjs.map +1 -1
  144. package/dist/esm/llm/google/utils/common.mjs +88 -27
  145. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  146. package/dist/esm/llm/init.mjs +2 -2
  147. package/dist/esm/llm/invoke.mjs +104 -7
  148. package/dist/esm/llm/invoke.mjs.map +1 -1
  149. package/dist/esm/llm/openai/index.mjs +1 -1
  150. package/dist/esm/llm/openai/index.mjs.map +1 -1
  151. package/dist/esm/llm/openai/utils/index.mjs +1 -1
  152. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  153. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  154. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  155. package/dist/esm/main.mjs +1 -1
  156. package/dist/esm/messages/cache.mjs +29 -8
  157. package/dist/esm/messages/cache.mjs.map +1 -1
  158. package/dist/esm/messages/content.mjs.map +1 -1
  159. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  160. package/dist/esm/messages/format.mjs +129 -18
  161. package/dist/esm/messages/format.mjs.map +1 -1
  162. package/dist/esm/messages/prune.mjs.map +1 -1
  163. package/dist/esm/messages/reducer.mjs +1 -1
  164. package/dist/esm/messages/reducer.mjs.map +1 -1
  165. package/dist/esm/messages/tools.mjs +1 -1
  166. package/dist/esm/messages/tools.mjs.map +1 -1
  167. package/dist/esm/openai/index.mjs.map +1 -1
  168. package/dist/esm/responses/index.mjs.map +1 -1
  169. package/dist/esm/run.mjs +41 -20
  170. package/dist/esm/run.mjs.map +1 -1
  171. package/dist/esm/session/AgentSession.mjs +4 -4
  172. package/dist/esm/session/AgentSession.mjs.map +1 -1
  173. package/dist/esm/session/JsonlSessionStore.mjs +2 -2
  174. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  175. package/dist/esm/session/handlers.mjs +2 -2
  176. package/dist/esm/session/handlers.mjs.map +1 -1
  177. package/dist/esm/stream.mjs +248 -25
  178. package/dist/esm/stream.mjs.map +1 -1
  179. package/dist/esm/summarization/node.mjs.map +1 -1
  180. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +1 -1
  181. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  182. package/dist/esm/tools/Calculator.mjs +1 -1
  183. package/dist/esm/tools/Calculator.mjs.map +1 -1
  184. package/dist/esm/tools/CodeExecutor.mjs +1 -1
  185. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  186. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  187. package/dist/esm/tools/ToolNode.mjs +37 -18
  188. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  189. package/dist/esm/tools/ToolSearch.mjs +1 -1
  190. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  191. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +7 -4
  192. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  193. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +4 -4
  194. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  195. package/dist/esm/tools/handlers.mjs +2 -1
  196. package/dist/esm/tools/handlers.mjs.map +1 -1
  197. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  198. package/dist/esm/tools/local/FileCheckpointer.mjs +2 -1
  199. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  200. package/dist/esm/tools/local/LocalCodingTools.mjs +45 -19
  201. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  202. package/dist/esm/tools/local/LocalExecutionEngine.mjs +3 -3
  203. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  204. package/dist/esm/tools/local/LocalExecutionTools.mjs +2 -2
  205. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  206. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +4 -3
  207. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  208. package/dist/esm/tools/local/attachments.mjs +0 -5
  209. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  210. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +4 -4
  211. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  212. package/dist/esm/tools/search/firecrawl.mjs +1 -1
  213. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  214. package/dist/esm/tools/search/rerankers.mjs +8 -4
  215. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  216. package/dist/esm/tools/search/tavily-search.mjs +1 -1
  217. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  218. package/dist/esm/tools/search/utils.mjs +76 -9
  219. package/dist/esm/tools/search/utils.mjs.map +1 -1
  220. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
  221. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  222. package/dist/esm/utils/handlers.mjs +1 -1
  223. package/dist/esm/utils/handlers.mjs.map +1 -1
  224. package/dist/esm/utils/run.mjs +1 -1
  225. package/dist/esm/utils/run.mjs.map +1 -1
  226. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +1 -1
  227. package/dist/types/events.d.ts +1 -1
  228. package/dist/types/graphs/Graph.d.ts +7 -1
  229. package/dist/types/hooks/executeHooks.d.ts +1 -1
  230. package/dist/types/hooks/types.d.ts +5 -0
  231. package/dist/types/langfuse.d.ts +4 -0
  232. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +1 -1
  233. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
  234. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +2 -2
  235. package/dist/types/llm/bedrock/index.d.ts +2 -2
  236. package/dist/types/llm/fake.d.ts +3 -3
  237. package/dist/types/llm/google/index.d.ts +1 -0
  238. package/dist/types/llm/google/types.d.ts +1 -1
  239. package/dist/types/llm/google/utils/common.d.ts +2 -2
  240. package/dist/types/llm/google/utils/tools.d.ts +1 -1
  241. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +1 -1
  242. package/dist/types/llm/openai/index.d.ts +2 -2
  243. package/dist/types/llm/openai/utils/index.d.ts +1 -1
  244. package/dist/types/llm/openrouter/index.d.ts +4 -4
  245. package/dist/types/messages/contextPruning.d.ts +1 -1
  246. package/dist/types/messages/format.d.ts +14 -4
  247. package/dist/types/messages/prune.d.ts +1 -1
  248. package/dist/types/session/JsonlSessionStore.d.ts +1 -1
  249. package/dist/types/session/handlers.d.ts +1 -1
  250. package/dist/types/session/types.d.ts +1 -1
  251. package/dist/types/summarization/node.d.ts +1 -1
  252. package/dist/types/tools/SubagentTool.d.ts +2 -2
  253. package/dist/types/tools/ToolNode.d.ts +9 -2
  254. package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +1 -1
  255. package/dist/types/tools/search/types.d.ts +1 -1
  256. package/dist/types/tools/search/utils.d.ts +11 -0
  257. package/dist/types/types/graph.d.ts +4 -4
  258. package/dist/types/types/llm.d.ts +4 -3
  259. package/dist/types/types/messages.d.ts +1 -1
  260. package/dist/types/types/run.d.ts +6 -6
  261. package/dist/types/types/stream.d.ts +2 -2
  262. package/dist/types/types/tools.d.ts +5 -1
  263. package/dist/types/utils/handlers.d.ts +2 -2
  264. package/dist/types/utils/run.d.ts +1 -1
  265. package/package.json +13 -10
  266. package/src/__tests__/stream.eagerEventExecution.test.ts +543 -6
  267. package/src/agents/AgentContext.ts +2 -2
  268. package/src/agents/__tests__/AgentContext.test.ts +3 -3
  269. package/src/agents/__tests__/promptCacheLiveHelpers.ts +1 -1
  270. package/src/events.ts +1 -1
  271. package/src/graphs/Graph.ts +329 -72
  272. package/src/graphs/MultiAgentGraph.ts +1 -1
  273. package/src/graphs/__tests__/Graph.reasoning.test.ts +919 -6
  274. package/src/graphs/__tests__/MultiAgentGraph.test.ts +1 -1
  275. package/src/graphs/__tests__/composition.smoke.test.ts +1 -1
  276. package/src/hooks/__tests__/HookRegistry.test.ts +1 -1
  277. package/src/hooks/__tests__/compactHooks.test.ts +8 -8
  278. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +34 -22
  279. package/src/hooks/__tests__/executeHooks.test.ts +3 -3
  280. package/src/hooks/__tests__/integration.test.ts +3 -3
  281. package/src/hooks/__tests__/toolHooks.test.ts +10 -10
  282. package/src/hooks/createWorkspacePolicyHook.ts +17 -14
  283. package/src/hooks/executeHooks.ts +1 -1
  284. package/src/hooks/types.ts +5 -0
  285. package/src/instrumentation.ts +11 -11
  286. package/src/langfuse.ts +35 -1
  287. package/src/langfuseToolOutputTracing.ts +2 -2
  288. package/src/llm/anthropic/index.ts +1 -1
  289. package/src/llm/anthropic/llm.spec.ts +36 -0
  290. package/src/llm/anthropic/utils/message_inputs.ts +46 -4
  291. package/src/llm/anthropic/utils/message_outputs.ts +9 -7
  292. package/src/llm/anthropic/utils/output_parsers.ts +5 -5
  293. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
  294. package/src/llm/bedrock/index.ts +4 -4
  295. package/src/llm/bedrock/toolCache.test.ts +48 -9
  296. package/src/llm/bedrock/toolCache.ts +11 -6
  297. package/src/llm/fake.ts +30 -25
  298. package/src/llm/google/index.ts +43 -1
  299. package/src/llm/google/llm.spec.ts +173 -1
  300. package/src/llm/google/types.ts +1 -1
  301. package/src/llm/google/utils/common.ts +154 -45
  302. package/src/llm/google/utils/tools.ts +8 -8
  303. package/src/llm/google/utils/zod_to_genai_parameters.ts +4 -4
  304. package/src/llm/invoke.test.ts +3 -3
  305. package/src/llm/invoke.ts +170 -10
  306. package/src/llm/openai/index.ts +4 -4
  307. package/src/llm/openai/utils/index.ts +14 -14
  308. package/src/llm/openrouter/index.ts +4 -4
  309. package/src/llm/openrouter/reasoning.test.ts +2 -2
  310. package/src/llm/vertexai/fixThoughtSignatures.test.ts +1 -1
  311. package/src/llm/vertexai/index.ts +1 -1
  312. package/src/messages/cache.test.ts +144 -0
  313. package/src/messages/cache.ts +50 -13
  314. package/src/messages/content.ts +1 -1
  315. package/src/messages/contextPruning.ts +1 -1
  316. package/src/messages/format.ts +236 -43
  317. package/src/messages/formatAgentMessages.skills.test.ts +205 -26
  318. package/src/messages/formatAgentMessages.test.ts +841 -10
  319. package/src/messages/labelContentByAgent.test.ts +2 -2
  320. package/src/messages/prune.ts +1 -1
  321. package/src/messages/reducer.ts +1 -1
  322. package/src/messages/tools.ts +1 -1
  323. package/src/openai/__tests__/openai.test.ts +2 -2
  324. package/src/openai/index.ts +1 -1
  325. package/src/responses/__tests__/responses.test.ts +2 -2
  326. package/src/responses/index.ts +1 -1
  327. package/src/run.ts +68 -41
  328. package/src/session/AgentSession.ts +6 -6
  329. package/src/session/JsonlSessionStore.ts +3 -3
  330. package/src/session/__tests__/JsonlSessionStore.test.ts +5 -5
  331. package/src/session/__tests__/handlers.test.ts +2 -2
  332. package/src/session/handlers.ts +5 -5
  333. package/src/session/types.ts +1 -1
  334. package/src/specs/agent-handoffs.test.ts +1 -1
  335. package/src/specs/langfuse-callbacks.test.ts +2 -2
  336. package/src/specs/langfuse-metadata.test.ts +39 -0
  337. package/src/specs/langfuse-tool-output-tracing.test.ts +1 -1
  338. package/src/specs/multi-agent-summarization.test.ts +4 -4
  339. package/src/specs/subagent.test.ts +3 -3
  340. package/src/specs/summarization-unit.test.ts +1 -1
  341. package/src/specs/thinking-handoff.test.ts +1 -1
  342. package/src/splitStream.test.ts +48 -0
  343. package/src/stream.test.ts +53 -3
  344. package/src/stream.ts +450 -39
  345. package/src/summarization/__tests__/aggregator.test.ts +2 -2
  346. package/src/summarization/__tests__/node.test.ts +2 -2
  347. package/src/summarization/node.ts +1 -1
  348. package/src/tools/BashProgrammaticToolCalling.ts +5 -5
  349. package/src/tools/Calculator.ts +1 -1
  350. package/src/tools/CodeExecutor.ts +2 -4
  351. package/src/tools/SubagentTool.ts +2 -2
  352. package/src/tools/ToolNode.ts +37 -16
  353. package/src/tools/ToolSearch.ts +1 -1
  354. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +4 -4
  355. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +12 -12
  356. package/src/tools/__tests__/LocalExecutionTools.test.ts +125 -93
  357. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +29 -5
  358. package/src/tools/__tests__/ReadFile.test.ts +1 -1
  359. package/src/tools/__tests__/SkillTool.test.ts +4 -4
  360. package/src/tools/__tests__/SubagentExecutor.test.ts +17 -13
  361. package/src/tools/__tests__/SubagentTool.test.ts +2 -2
  362. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +1 -1
  363. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +2 -5
  364. package/src/tools/__tests__/ToolNode.session.test.ts +1 -1
  365. package/src/tools/__tests__/ToolSearch.test.ts +1 -1
  366. package/src/tools/__tests__/annotateMessagesForLLM.test.ts +1 -1
  367. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +35 -32
  368. package/src/tools/__tests__/directToolHooks.test.ts +41 -0
  369. package/src/tools/__tests__/handlers.test.ts +2 -2
  370. package/src/tools/__tests__/hitl.test.ts +11 -11
  371. package/src/tools/__tests__/localToolNames.test.ts +8 -6
  372. package/src/tools/__tests__/skillCatalog.test.ts +1 -1
  373. package/src/tools/__tests__/subagentHooks.test.ts +20 -10
  374. package/src/tools/__tests__/workspaceSeam.test.ts +20 -7
  375. package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +9 -6
  376. package/src/tools/cloudflare/CloudflareSandboxTools.ts +19 -19
  377. package/src/tools/handlers.ts +5 -5
  378. package/src/tools/local/CompileCheckTool.ts +4 -7
  379. package/src/tools/local/FileCheckpointer.ts +6 -5
  380. package/src/tools/local/LocalCodingTools.ts +100 -45
  381. package/src/tools/local/LocalExecutionEngine.ts +5 -5
  382. package/src/tools/local/LocalExecutionTools.ts +9 -9
  383. package/src/tools/local/LocalProgrammaticToolCalling.ts +5 -4
  384. package/src/tools/local/attachments.ts +0 -6
  385. package/src/tools/local/resolveLocalExecutionTools.ts +15 -15
  386. package/src/tools/search/firecrawl.ts +1 -1
  387. package/src/tools/search/jina-reranker.test.ts +148 -37
  388. package/src/tools/search/rerankers.ts +14 -4
  389. package/src/tools/search/tavily-search.ts +2 -2
  390. package/src/tools/search/types.ts +1 -1
  391. package/src/tools/search/utils.ts +99 -9
  392. package/src/tools/subagent/SubagentExecutor.ts +12 -6
  393. package/src/types/graph.ts +12 -12
  394. package/src/types/llm.ts +7 -6
  395. package/src/types/messages.ts +1 -1
  396. package/src/types/run.ts +7 -7
  397. package/src/types/stream.ts +2 -2
  398. package/src/types/tools.ts +5 -1
  399. package/src/utils/handlers.ts +2 -2
  400. package/src/utils/llmConfig.ts +1 -1
  401. package/src/utils/logging.ts +20 -10
  402. package/src/utils/run.ts +2 -2
@@ -1,13 +1,11 @@
1
1
  /** This util file contains functions for converting Anthropic messages to LangChain messages. */
2
2
  import { AIMessage, AIMessageChunk } from '@langchain/core/messages';
3
-
4
- import type Anthropic from '@anthropic-ai/sdk';
5
- import type { UsageMetadata } from '@langchain/core/messages';
6
3
  import type { ToolCallChunk } from '@langchain/core/messages/tool';
4
+ import type { UsageMetadata } from '@langchain/core/messages';
7
5
  import type { ChatGeneration } from '@langchain/core/outputs';
8
- import type { MessageContentComplex } from '@/types';
6
+ import type Anthropic from '@anthropic-ai/sdk';
9
7
  import type { AnthropicMessageResponse } from '../types';
10
-
8
+ import type { MessageContentComplex } from '@/types';
11
9
  import { toLangChainContent } from '@/messages/langchain';
12
10
  import { extractToolCalls } from './output_parsers';
13
11
 
@@ -205,10 +203,14 @@ export function _makeMessageChunkFromAnthropicEvent(
205
203
  ) {
206
204
  const content = [
207
205
  {
206
+ // No `type`: core's streaming aggregation merges this partial input into the
207
+ // sibling tool_use/server_tool_use block at the same index, keeping its type.
208
+ // A typed delta block won't merge under core >= 1.1.46 ("keep different block
209
+ // types separate"), which would orphan the input and empty the tool_use input.
208
210
  index: data.index,
209
211
  input: data.delta.partial_json,
210
- type: data.delta.type,
211
- },
212
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
213
+ } as any,
212
214
  ];
213
215
  return {
214
216
  chunk: new AIMessageChunk({
@@ -1,16 +1,16 @@
1
1
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
2
2
  /* eslint-disable @typescript-eslint/no-empty-object-type */
3
- import {
4
- BaseLLMOutputParser,
5
- OutputParserException,
6
- } from '@langchain/core/output_parsers';
7
- import { JsonOutputKeyToolsParserParamsInterop } from '@langchain/core/output_parsers/openai_tools';
8
3
  import { ChatGeneration } from '@langchain/core/outputs';
9
4
  import { ToolCall } from '@langchain/core/messages/tool';
10
5
  import {
11
6
  interopSafeParseAsync,
12
7
  InteropZodType,
13
8
  } from '@langchain/core/utils/types';
9
+ import {
10
+ BaseLLMOutputParser,
11
+ OutputParserException,
12
+ } from '@langchain/core/output_parsers';
13
+ import { JsonOutputKeyToolsParserParamsInterop } from '@langchain/core/output_parsers/openai_tools';
14
14
 
15
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
16
  interface AnthropicToolsOutputParserParams<T extends Record<string, any>>
@@ -0,0 +1,186 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { AIMessage, HumanMessage } from '@langchain/core/messages';
3
+ import type { BaseMessage } from '@langchain/core/messages';
4
+ import { _convertMessagesToAnthropicPayload } from './message_inputs';
5
+ import { _makeMessageChunkFromAnthropicEvent } from './message_outputs';
6
+
7
+ /**
8
+ * Regression for @langchain/core >= 1.1.46 streaming aggregation: a tool call's
9
+ * input_json_delta is kept as a separate content block and v1-cast to a `text`
10
+ * block carrying `input` but no `text`, leaving the sibling tool_use block with an
11
+ * empty inline input. The assembled arguments live on `message.tool_calls`.
12
+ * Re-serializing such a message previously threw "Unsupported message content format".
13
+ */
14
+ describe('_convertMessagesToAnthropicPayload — aggregated streaming tool input', () => {
15
+ const buildHistory = (): BaseMessage[] => [
16
+ new HumanMessage('what is 12345 * 6789?'),
17
+ new AIMessage({
18
+ content: [
19
+ { type: 'text', text: 'Let me calculate that.' },
20
+ // tool_use block left with empty inline input by aggregation
21
+ {
22
+ type: 'tool_use',
23
+ id: 'toolu_calc',
24
+ name: 'calculator',
25
+ input: '',
26
+ index: 0,
27
+ } as any,
28
+ // orphaned input delta, v1-cast to `text` with `input` and no `text`
29
+ { type: 'text', index: 0, input: '{"input": "12345 * 6789"}' } as any,
30
+ ],
31
+ tool_calls: [
32
+ {
33
+ id: 'toolu_calc',
34
+ name: 'calculator',
35
+ args: { input: '12345 * 6789' },
36
+ type: 'tool_call',
37
+ },
38
+ ],
39
+ }),
40
+ ];
41
+
42
+ it('does not throw on the orphaned text-with-input block', () => {
43
+ expect(() => _convertMessagesToAnthropicPayload(buildHistory())).not.toThrow();
44
+ });
45
+
46
+ it('restores tool_use input from message.tool_calls and drops the orphan block', () => {
47
+ const payload = _convertMessagesToAnthropicPayload(buildHistory());
48
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
49
+ expect(assistant).toBeDefined();
50
+ const blocks = assistant!.content as any[];
51
+
52
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
53
+ expect(toolUse).toMatchObject({
54
+ type: 'tool_use',
55
+ id: 'toolu_calc',
56
+ name: 'calculator',
57
+ input: { input: '12345 * 6789' },
58
+ });
59
+
60
+ // No leftover delta: no text block carrying `input`, no input_json_delta.
61
+ expect(
62
+ blocks.find(
63
+ (b) => (b.type === 'text' && 'input' in b) || b.type === 'input_json_delta'
64
+ )
65
+ ).toBeUndefined();
66
+
67
+ // The real assistant text is preserved.
68
+ expect(
69
+ blocks.some((b) => b.type === 'text' && b.text === 'Let me calculate that.')
70
+ ).toBe(true);
71
+ });
72
+
73
+ it('does not overwrite a tool_use block that already has inline input', () => {
74
+ const history: BaseMessage[] = [
75
+ new HumanMessage('hi'),
76
+ new AIMessage({
77
+ content: [
78
+ {
79
+ type: 'tool_use',
80
+ id: 'toolu_x',
81
+ name: 'calculator',
82
+ input: { input: '2 + 2' },
83
+ } as any,
84
+ ],
85
+ tool_calls: [
86
+ {
87
+ id: 'toolu_x',
88
+ name: 'calculator',
89
+ args: { input: '999' },
90
+ type: 'tool_call',
91
+ },
92
+ ],
93
+ }),
94
+ ];
95
+ const payload = _convertMessagesToAnthropicPayload(history);
96
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
97
+ const toolUse = (assistant!.content as any[]).find((b) => b.type === 'tool_use');
98
+ expect(toolUse.input).toEqual({ input: '2 + 2' });
99
+ });
100
+
101
+ // Adapted from @langchain/anthropic's
102
+ // "partial tool input is correctly merged before calling Anthropic API".
103
+ it('merges sibling input_json_delta blocks into tool_use input (persisted, no tool_calls)', () => {
104
+ const messages: BaseMessage[] = [
105
+ new HumanMessage('What\'s the weather in Seattle tomorrow?'),
106
+ new AIMessage({
107
+ content: [
108
+ { type: 'text', index: 1, text: 'I need to call the get_weather tool' },
109
+ { type: 'tool_use', index: 2, name: 'get_weather', id: 'tool_call_id', input: '' },
110
+ { type: 'input_json_delta', index: 2, input: '{"city": "' },
111
+ { type: 'input_json_delta', index: 2, input: 'Seattle", "da' },
112
+ { type: 'input_json_delta', index: 2, input: 'te": "to' },
113
+ { type: 'input_json_delta', index: 2, input: 'morrow"}' },
114
+ ] as any,
115
+ }),
116
+ ];
117
+
118
+ const payload = _convertMessagesToAnthropicPayload(messages);
119
+ const assistant = payload.messages.find((m: any) => m.role === 'assistant');
120
+ const blocks = assistant!.content as any[];
121
+ expect(blocks.filter((b) => b.type === 'input_json_delta')).toHaveLength(0);
122
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
123
+ expect(toolUse).toMatchObject({
124
+ type: 'tool_use',
125
+ name: 'get_weather',
126
+ id: 'tool_call_id',
127
+ input: { city: 'Seattle', date: 'tomorrow' },
128
+ });
129
+ });
130
+ });
131
+
132
+ describe('_makeMessageChunkFromAnthropicEvent — streamed tool input merges into content', () => {
133
+ const fields = { streamUsage: true, coerceContentToString: false };
134
+
135
+ it('emits input deltas without a type so aggregation merges them into the tool_use block', () => {
136
+ const events: any[] = [
137
+ {
138
+ type: 'content_block_start',
139
+ index: 0,
140
+ content_block: { type: 'tool_use', id: 'toolu_1', name: 'calculator', input: {} },
141
+ },
142
+ {
143
+ type: 'content_block_delta',
144
+ index: 0,
145
+ delta: { type: 'input_json_delta', partial_json: '{"input"' },
146
+ },
147
+ {
148
+ type: 'content_block_delta',
149
+ index: 0,
150
+ delta: { type: 'input_json_delta', partial_json: ': "2 + 2"}' },
151
+ },
152
+ ];
153
+ const chunks = events
154
+ .map((e) => _makeMessageChunkFromAnthropicEvent(e, fields)?.chunk)
155
+ .filter((c): c is NonNullable<typeof c> => c != null);
156
+
157
+ // input-delta chunks must not carry a `type` (so core merges them by index
158
+ // into the sibling tool_use/server_tool_use block rather than orphaning them)
159
+ const deltaBlocks = chunks
160
+ .slice(1)
161
+ .flatMap((c) => (Array.isArray(c.content) ? (c.content as any[]) : []))
162
+ .filter((b) => 'input' in b);
163
+ expect(deltaBlocks.length).toBeGreaterThan(0);
164
+ deltaBlocks.forEach((b) => expect('type' in b).toBe(false));
165
+
166
+ // aggregate the chunks the way core does during streaming
167
+ const merged = chunks.reduce((acc, c) => acc.concat(c));
168
+ const blocks = merged.content as any[];
169
+
170
+ const toolUse = blocks.find((b) => b.type === 'tool_use');
171
+ expect(toolUse).toMatchObject({ type: 'tool_use', id: 'toolu_1', name: 'calculator' });
172
+ const parsed =
173
+ typeof toolUse.input === 'string' ? JSON.parse(toolUse.input) : toolUse.input;
174
+ expect(parsed).toEqual({ input: '2 + 2' });
175
+
176
+ // no orphaned delta block survives aggregation
177
+ expect(blocks.filter((b) => b.type !== 'tool_use' && 'input' in b)).toHaveLength(0);
178
+
179
+ // tool_calls remain correctly aggregated
180
+ expect(merged.tool_calls?.[0]).toMatchObject({
181
+ id: 'toolu_1',
182
+ name: 'calculator',
183
+ args: { input: '2 + 2' },
184
+ });
185
+ });
186
+ });
@@ -22,23 +22,23 @@
22
22
  */
23
23
 
24
24
  import { ChatBedrockConverse } from '@langchain/aws';
25
+ import { AIMessageChunk } from '@langchain/core/messages';
26
+ import { ChatGenerationChunk, ChatResult } from '@langchain/core/outputs';
25
27
  import {
26
28
  ConverseStreamCommand,
27
29
  type GuardrailConfiguration,
28
30
  type GuardrailStreamConfiguration,
29
31
  } from '@aws-sdk/client-bedrock-runtime';
30
- import { AIMessageChunk } from '@langchain/core/messages';
31
- import { ChatGenerationChunk, ChatResult } from '@langchain/core/outputs';
32
32
  import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
33
- import type { ChatBedrockConverseInput } from '@langchain/aws';
34
33
  import type { BaseMessage, ResponseMetadata } from '@langchain/core/messages';
35
- import { insertBedrockToolCachePoint } from './toolCache';
34
+ import type { ChatBedrockConverseInput } from '@langchain/aws';
36
35
  import {
37
36
  convertToConverseMessages,
38
37
  handleConverseStreamContentBlockStart,
39
38
  handleConverseStreamContentBlockDelta,
40
39
  handleConverseStreamMetadata,
41
40
  } from './utils';
41
+ import { insertBedrockToolCachePoint } from './toolCache';
42
42
 
43
43
  /**
44
44
  * Service tier type for Bedrock invocations.
@@ -15,17 +15,30 @@ type OpenAITool = {
15
15
  };
16
16
  };
17
17
 
18
- function createOpenAITool(name: string): OpenAITool {
18
+ type CreateOpenAIToolOptions = {
19
+ description?: string;
20
+ omitDescription?: boolean;
21
+ };
22
+
23
+ function createOpenAITool(
24
+ name: string,
25
+ options: CreateOpenAIToolOptions = {}
26
+ ): OpenAITool {
27
+ const functionDefinition: OpenAITool['function'] = {
28
+ name,
29
+ parameters: {
30
+ type: 'object',
31
+ properties: {},
32
+ },
33
+ };
34
+ const description = options.description ?? `${name} description`;
35
+ if (options.omitDescription !== true) {
36
+ functionDefinition.description = description;
37
+ }
38
+
19
39
  return {
20
40
  type: 'function',
21
- function: {
22
- name,
23
- description: `${name} description`,
24
- parameters: {
25
- type: 'object',
26
- properties: {},
27
- },
28
- },
41
+ function: functionDefinition,
29
42
  };
30
43
  }
31
44
 
@@ -40,6 +53,11 @@ function toolNames(tools: Tool[] | undefined): string[] {
40
53
  return (tools ?? []).map(toolName);
41
54
  }
42
55
 
56
+ function getToolSpec(entry: Tool): Tool.ToolSpecMember['toolSpec'] {
57
+ expect(entry).toHaveProperty('toolSpec');
58
+ return (entry as Tool.ToolSpecMember).toolSpec;
59
+ }
60
+
43
61
  describe('partitionAndMarkBedrockToolCache', () => {
44
62
  it('inserts the Bedrock cache point after the last static tool', () => {
45
63
  const tools = [
@@ -128,4 +146,25 @@ describe('partitionAndMarkBedrockToolCache', () => {
128
146
 
129
147
  expect(toolNames(result?.tools)).toEqual(['direct_tool', 'cachePoint']);
130
148
  });
149
+
150
+ it('omits empty OpenAI tool descriptions when converting for Bedrock', () => {
151
+ const tools = [
152
+ createOpenAITool('missing_description', { omitDescription: true }),
153
+ createOpenAITool('empty_description', { description: '' }),
154
+ createOpenAITool('described_tool'),
155
+ ] as GraphTools;
156
+
157
+ const marked = partitionAndMarkBedrockToolCache(
158
+ tools,
159
+ () => false
160
+ ) as Tool[];
161
+ const result = insertBedrockToolCachePoint({ tools: marked }, false);
162
+ const convertedTools = result?.tools ?? [];
163
+
164
+ expect(getToolSpec(convertedTools[0])).not.toHaveProperty('description');
165
+ expect(getToolSpec(convertedTools[1])).not.toHaveProperty('description');
166
+ expect(getToolSpec(convertedTools[2]).description).toBe(
167
+ 'described_tool description'
168
+ );
169
+ });
131
170
  });
@@ -1,5 +1,5 @@
1
- import type { Tool, ToolConfiguration } from '@aws-sdk/client-bedrock-runtime';
2
1
  import type { BindToolsInput } from '@langchain/core/language_models/chat_models';
2
+ import type { Tool, ToolConfiguration } from '@aws-sdk/client-bedrock-runtime';
3
3
  import type { OpenAIClient } from '@langchain/openai';
4
4
  import type { DocumentType } from '@smithy/types';
5
5
  import type { GraphTools } from '@/types';
@@ -60,12 +60,17 @@ function getToolName(tool: unknown): string | undefined {
60
60
  }
61
61
 
62
62
  function openAIToBedrockTool(tool: OpenAIFunctionTool): Tool.ToolSpecMember {
63
+ const toolSpec: NonNullable<Tool.ToolSpecMember['toolSpec']> = {
64
+ name: tool.function.name,
65
+ inputSchema: { json: tool.function.parameters as DocumentType },
66
+ };
67
+
68
+ if (tool.function.description != null && tool.function.description !== '') {
69
+ toolSpec.description = tool.function.description;
70
+ }
71
+
63
72
  return {
64
- toolSpec: {
65
- name: tool.function.name,
66
- description: tool.function.description,
67
- inputSchema: { json: tool.function.parameters as DocumentType },
68
- },
73
+ toolSpec,
69
74
  };
70
75
  }
71
76
 
package/src/llm/fake.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { ChatGenerationChunk } from '@langchain/core/outputs';
2
1
  import { AIMessageChunk } from '@langchain/core/messages';
3
- import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
4
- import type { BaseMessage } from '@langchain/core/messages';
2
+ import { ChatGenerationChunk } from '@langchain/core/outputs';
5
3
  import { FakeListChatModel } from '@langchain/core/utils/testing';
6
4
  import { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
5
+ import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
6
+ import type { BaseMessage } from '@langchain/core/messages';
7
7
 
8
8
  type SplitStrategy = {
9
9
  type: 'regex' | 'fixed';
@@ -20,7 +20,7 @@ export class FakeChatModel extends FakeListChatModel {
20
20
  sleep,
21
21
  emitCustomEvent,
22
22
  splitStrategy = { type: 'regex', value: /(?<=\s+)|(?=\s+)/ },
23
- toolCalls = []
23
+ toolCalls = [],
24
24
  }: {
25
25
  responses: string[];
26
26
  sleep?: number;
@@ -45,25 +45,31 @@ export class FakeChatModel extends FakeListChatModel {
45
45
  return chunks;
46
46
  }
47
47
  }
48
- _createResponseChunk(text: string, tool_call_chunks?: ToolCallChunk[]): ChatGenerationChunk {
48
+ _createResponseChunk(
49
+ text: string,
50
+ tool_call_chunks?: ToolCallChunk[]
51
+ ): ChatGenerationChunk {
49
52
  return new ChatGenerationChunk({
50
53
  text,
51
54
  generationInfo: {},
52
55
  message: new AIMessageChunk({
53
56
  content: text,
54
57
  tool_call_chunks,
55
- additional_kwargs: tool_call_chunks ? {
56
- tool_calls: tool_call_chunks.map((toolCall) => ({
57
- index: toolCall.index ?? 0,
58
- id: toolCall.id ?? '',
59
- type: 'function',
60
- function: {
61
- name: toolCall.name ?? '',
62
- arguments: toolCall.args ?? '',
63
- },
64
- })),
65
- } : undefined,
66
- })});
58
+ additional_kwargs: tool_call_chunks
59
+ ? {
60
+ tool_calls: tool_call_chunks.map((toolCall) => ({
61
+ index: toolCall.index ?? 0,
62
+ id: toolCall.id ?? '',
63
+ type: 'function',
64
+ function: {
65
+ name: toolCall.name ?? '',
66
+ arguments: toolCall.args ?? '',
67
+ },
68
+ })),
69
+ }
70
+ : undefined,
71
+ }),
72
+ });
67
73
  }
68
74
 
69
75
  async *_streamResponseChunks(
@@ -96,7 +102,7 @@ export class FakeChatModel extends FakeListChatModel {
96
102
  await this._sleepIfRequested();
97
103
  if (this.toolCalls.length > 0 && !this.addedToolCalls) {
98
104
  this.addedToolCalls = true;
99
- const toolCallChunks = this.toolCalls.map((toolCall) => {;
105
+ const toolCallChunks = this.toolCalls.map((toolCall) => {
100
106
  return {
101
107
  name: toolCall.name,
102
108
  args: JSON.stringify(toolCall.args),
@@ -116,13 +122,12 @@ export function createFakeStreamingLLM({
116
122
  sleep,
117
123
  splitStrategy,
118
124
  toolCalls,
119
- } : {
120
- responses: string[],
121
- sleep?: number,
122
- splitStrategy?: SplitStrategy,
123
- toolCalls?: ToolCall[]
124
- }
125
- ): FakeChatModel {
125
+ }: {
126
+ responses: string[];
127
+ sleep?: number;
128
+ splitStrategy?: SplitStrategy;
129
+ toolCalls?: ToolCall[];
130
+ }): FakeChatModel {
126
131
  return new FakeChatModel({
127
132
  sleep,
128
133
  responses,
@@ -3,10 +3,14 @@ import { AIMessageChunk } from '@langchain/core/messages';
3
3
  import { ChatGenerationChunk } from '@langchain/core/outputs';
4
4
  import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
5
5
  import { getEnvironmentVariable } from '@langchain/core/utils/env';
6
- import { GoogleGenerativeAI as GenerativeAI } from '@google/generative-ai';
6
+ import {
7
+ FunctionCallingMode,
8
+ GoogleGenerativeAI as GenerativeAI,
9
+ } from '@google/generative-ai';
7
10
  import type {
8
11
  GenerateContentRequest,
9
12
  SafetySetting,
13
+ ToolConfig,
10
14
  } from '@google/generative-ai';
11
15
  import type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
12
16
  import type { BaseMessage, UsageMetadata } from '@langchain/core/messages';
@@ -18,8 +22,21 @@ import {
18
22
  mapGenerateContentResultToChatResult,
19
23
  } from './utils/common';
20
24
 
25
+ type GoogleToolConfigWithServerSideInvocations = ToolConfig & {
26
+ includeServerSideToolInvocations?: boolean;
27
+ functionCallingConfig?: Omit<
28
+ NonNullable<ToolConfig['functionCallingConfig']>,
29
+ 'mode'
30
+ > & {
31
+ mode?:
32
+ | NonNullable<ToolConfig['functionCallingConfig']>['mode']
33
+ | 'VALIDATED';
34
+ };
35
+ };
36
+
21
37
  export class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI {
22
38
  thinkingConfig?: GoogleThinkingConfig;
39
+ includeServerSideToolInvocations?: boolean;
23
40
 
24
41
  /**
25
42
  * Override to add gemini-3 model support for multimodal and function calling thought signatures
@@ -92,6 +109,9 @@ export class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI {
92
109
  }
93
110
 
94
111
  this.thinkingConfig = fields.thinkingConfig ?? this.thinkingConfig;
112
+ this.includeServerSideToolInvocations =
113
+ fields.includeServerSideToolInvocations ??
114
+ this.includeServerSideToolInvocations;
95
115
 
96
116
  this.streaming = fields.streaming ?? this.streaming;
97
117
  this.json = fields.json;
@@ -191,6 +211,28 @@ export class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI {
191
211
  thinkingConfig: this.thinkingConfig,
192
212
  };
193
213
  }
214
+ if (
215
+ this.includeServerSideToolInvocations === true &&
216
+ Array.isArray(params.tools) &&
217
+ params.tools.length > 0
218
+ ) {
219
+ const toolConfig = params.toolConfig as
220
+ | GoogleToolConfigWithServerSideInvocations
221
+ | undefined;
222
+ const functionCallingConfig = toolConfig?.functionCallingConfig;
223
+ params.toolConfig = {
224
+ ...toolConfig,
225
+ ...(functionCallingConfig?.mode === FunctionCallingMode.AUTO
226
+ ? {
227
+ functionCallingConfig: {
228
+ ...functionCallingConfig,
229
+ mode: 'VALIDATED',
230
+ },
231
+ }
232
+ : {}),
233
+ includeServerSideToolInvocations: true,
234
+ } as ToolConfig;
235
+ }
194
236
  return params;
195
237
  }
196
238