@librechat/agents 3.2.31 → 3.2.33

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 (582) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/agents/AgentContext.cjs +844 -1046
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/constants.cjs +13 -13
  5. package/dist/cjs/common/constants.cjs.map +1 -1
  6. package/dist/cjs/common/enum.cjs +233 -240
  7. package/dist/cjs/common/enum.cjs.map +1 -1
  8. package/dist/cjs/common/index.cjs +2 -0
  9. package/dist/cjs/events.cjs +121 -169
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1389 -1807
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/index.cjs +2 -0
  16. package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
  17. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  18. package/dist/cjs/hitl/index.cjs +1 -0
  19. package/dist/cjs/hooks/HookRegistry.cjs +176 -202
  20. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  21. package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
  22. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  23. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
  24. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  25. package/dist/cjs/hooks/executeHooks.cjs +227 -282
  26. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  27. package/dist/cjs/hooks/index.cjs +6 -0
  28. package/dist/cjs/hooks/matchers.cjs +196 -230
  29. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  30. package/dist/cjs/hooks/types.cjs +24 -24
  31. package/dist/cjs/hooks/types.cjs.map +1 -1
  32. package/dist/cjs/instrumentation.cjs +110 -137
  33. package/dist/cjs/instrumentation.cjs.map +1 -1
  34. package/dist/cjs/langchain/google-common.cjs +0 -3
  35. package/dist/cjs/langchain/index.cjs +80 -43
  36. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  37. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  38. package/dist/cjs/langchain/messages.cjs +35 -18
  39. package/dist/cjs/langchain/openai.cjs +0 -3
  40. package/dist/cjs/langchain/prompts.cjs +5 -8
  41. package/dist/cjs/langchain/runnables.cjs +11 -10
  42. package/dist/cjs/langchain/tools.cjs +14 -11
  43. package/dist/cjs/langchain/utils/env.cjs +5 -8
  44. package/dist/cjs/langfuse.cjs +60 -79
  45. package/dist/cjs/langfuse.cjs.map +1 -1
  46. package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
  47. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  48. package/dist/cjs/llm/anthropic/index.cjs +432 -562
  49. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  50. package/dist/cjs/llm/anthropic/types.cjs +23 -47
  51. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -696
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -252
  55. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  56. package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
  57. package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
  58. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  59. package/dist/cjs/llm/bedrock/index.cjs +195 -240
  60. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  61. package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
  62. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
  64. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
  65. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +105 -149
  67. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  68. package/dist/cjs/llm/fake.cjs +86 -96
  69. package/dist/cjs/llm/fake.cjs.map +1 -1
  70. package/dist/cjs/llm/google/index.cjs +183 -237
  71. package/dist/cjs/llm/google/index.cjs.map +1 -1
  72. package/dist/cjs/llm/google/utils/common.cjs +398 -674
  73. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  74. package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
  75. package/dist/cjs/llm/init.cjs +44 -53
  76. package/dist/cjs/llm/init.cjs.map +1 -1
  77. package/dist/cjs/llm/invoke.cjs +142 -182
  78. package/dist/cjs/llm/invoke.cjs.map +1 -1
  79. package/dist/cjs/llm/openai/index.cjs +991 -1276
  80. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  81. package/dist/cjs/llm/openai/utils/index.cjs +189 -316
  82. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  83. package/dist/cjs/llm/openrouter/index.cjs +102 -153
  84. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  85. package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
  86. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  87. package/dist/cjs/llm/providers.cjs +29 -37
  88. package/dist/cjs/llm/providers.cjs.map +1 -1
  89. package/dist/cjs/llm/request.cjs +20 -33
  90. package/dist/cjs/llm/request.cjs.map +1 -1
  91. package/dist/cjs/llm/vertexai/index.cjs +427 -453
  92. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  93. package/dist/cjs/main.cjs +547 -528
  94. package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
  95. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  96. package/dist/cjs/messages/cache.cjs +308 -401
  97. package/dist/cjs/messages/cache.cjs.map +1 -1
  98. package/dist/cjs/messages/content.cjs +36 -49
  99. package/dist/cjs/messages/content.cjs.map +1 -1
  100. package/dist/cjs/messages/contextPruning.cjs +112 -145
  101. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  102. package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
  103. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  104. package/dist/cjs/messages/core.cjs +256 -397
  105. package/dist/cjs/messages/core.cjs.map +1 -1
  106. package/dist/cjs/messages/format.cjs +904 -1382
  107. package/dist/cjs/messages/format.cjs.map +1 -1
  108. package/dist/cjs/messages/ids.cjs +16 -20
  109. package/dist/cjs/messages/ids.cjs.map +1 -1
  110. package/dist/cjs/messages/index.cjs +12 -0
  111. package/dist/cjs/messages/langchain.cjs +18 -18
  112. package/dist/cjs/messages/langchain.cjs.map +1 -1
  113. package/dist/cjs/messages/prune.cjs +1054 -1517
  114. package/dist/cjs/messages/prune.cjs.map +1 -1
  115. package/dist/cjs/messages/recency.cjs +77 -95
  116. package/dist/cjs/messages/recency.cjs.map +1 -1
  117. package/dist/cjs/messages/reducer.cjs +63 -78
  118. package/dist/cjs/messages/reducer.cjs.map +1 -1
  119. package/dist/cjs/messages/tools.cjs +51 -79
  120. package/dist/cjs/messages/tools.cjs.map +1 -1
  121. package/dist/cjs/openai/index.cjs +171 -217
  122. package/dist/cjs/openai/index.cjs.map +1 -1
  123. package/dist/cjs/responses/index.cjs +302 -391
  124. package/dist/cjs/responses/index.cjs.map +1 -1
  125. package/dist/cjs/run.cjs +903 -1113
  126. package/dist/cjs/run.cjs.map +1 -1
  127. package/dist/cjs/session/AgentSession.cjs +805 -986
  128. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  129. package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
  130. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  131. package/dist/cjs/session/handlers.cjs +192 -208
  132. package/dist/cjs/session/handlers.cjs.map +1 -1
  133. package/dist/cjs/session/ids.cjs +9 -10
  134. package/dist/cjs/session/ids.cjs.map +1 -1
  135. package/dist/cjs/session/index.cjs +4 -0
  136. package/dist/cjs/session/messageSerialization.cjs +94 -156
  137. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  138. package/dist/cjs/splitStream.cjs +147 -206
  139. package/dist/cjs/splitStream.cjs.map +1 -1
  140. package/dist/cjs/stream.cjs +856 -1344
  141. package/dist/cjs/stream.cjs.map +1 -1
  142. package/dist/cjs/summarization/index.cjs +57 -101
  143. package/dist/cjs/summarization/index.cjs.map +1 -1
  144. package/dist/cjs/summarization/node.cjs +643 -796
  145. package/dist/cjs/summarization/node.cjs.map +1 -1
  146. package/dist/cjs/tools/BashExecutor.cjs +110 -136
  147. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  148. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
  149. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  150. package/dist/cjs/tools/Calculator.cjs +36 -57
  151. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  152. package/dist/cjs/tools/CodeExecutor.cjs +126 -168
  153. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  154. package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
  155. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  156. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
  157. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  158. package/dist/cjs/tools/ReadFile.cjs +17 -20
  159. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  160. package/dist/cjs/tools/SkillTool.cjs +26 -27
  161. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  162. package/dist/cjs/tools/SubagentTool.cjs +59 -61
  163. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  164. package/dist/cjs/tools/ToolNode.cjs +2109 -2686
  165. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  166. package/dist/cjs/tools/ToolSearch.cjs +663 -825
  167. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  168. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
  169. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  170. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
  171. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  172. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
  173. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  174. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
  175. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  176. package/dist/cjs/tools/cloudflare/index.cjs +4 -0
  177. package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
  178. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  179. package/dist/cjs/tools/handlers.cjs +200 -262
  180. package/dist/cjs/tools/handlers.cjs.map +1 -1
  181. package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
  182. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  183. package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
  184. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  185. package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
  186. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  187. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
  188. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  189. package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
  190. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  191. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
  192. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  193. package/dist/cjs/tools/local/attachments.cjs +108 -165
  194. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  195. package/dist/cjs/tools/local/bashAst.cjs +99 -113
  196. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  197. package/dist/cjs/tools/local/editStrategies.cjs +126 -169
  198. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  199. package/dist/cjs/tools/local/index.cjs +12 -0
  200. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
  201. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  202. package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
  203. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  204. package/dist/cjs/tools/local/textEncoding.cjs +25 -23
  205. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  206. package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
  207. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  208. package/dist/cjs/tools/ptcTimeout.cjs +27 -47
  209. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  210. package/dist/cjs/tools/schema.cjs +24 -23
  211. package/dist/cjs/tools/schema.cjs.map +1 -1
  212. package/dist/cjs/tools/search/anthropic.cjs +24 -33
  213. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  214. package/dist/cjs/tools/search/content.cjs +95 -137
  215. package/dist/cjs/tools/search/content.cjs.map +1 -1
  216. package/dist/cjs/tools/search/firecrawl.cjs +141 -172
  217. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  218. package/dist/cjs/tools/search/format.cjs +128 -196
  219. package/dist/cjs/tools/search/format.cjs.map +1 -1
  220. package/dist/cjs/tools/search/highlights.cjs +165 -232
  221. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  222. package/dist/cjs/tools/search/index.cjs +2 -0
  223. package/dist/cjs/tools/search/rerankers.cjs +151 -174
  224. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  225. package/dist/cjs/tools/search/schema.cjs +40 -39
  226. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  227. package/dist/cjs/tools/search/search.cjs +428 -530
  228. package/dist/cjs/tools/search/search.cjs.map +1 -1
  229. package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
  230. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  231. package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
  232. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/tavily-search.cjs +295 -359
  234. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/tool.cjs +260 -299
  236. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  237. package/dist/cjs/tools/search/utils.cjs +74 -117
  238. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  239. package/dist/cjs/tools/skillCatalog.cjs +54 -72
  240. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  241. package/dist/cjs/tools/streamedToolCallSeals.cjs +19 -36
  242. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  243. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
  244. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  245. package/dist/cjs/tools/subagent/index.cjs +1 -0
  246. package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
  247. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  248. package/dist/cjs/utils/callbacks.cjs +11 -21
  249. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  250. package/dist/cjs/utils/errors.cjs +70 -95
  251. package/dist/cjs/utils/errors.cjs.map +1 -1
  252. package/dist/cjs/utils/events.cjs +32 -42
  253. package/dist/cjs/utils/events.cjs.map +1 -1
  254. package/dist/cjs/utils/graph.cjs +8 -12
  255. package/dist/cjs/utils/graph.cjs.map +1 -1
  256. package/dist/cjs/utils/handlers.cjs +60 -82
  257. package/dist/cjs/utils/handlers.cjs.map +1 -1
  258. package/dist/cjs/utils/index.cjs +9 -0
  259. package/dist/cjs/utils/llm.cjs +19 -27
  260. package/dist/cjs/utils/llm.cjs.map +1 -1
  261. package/dist/cjs/utils/misc.cjs +30 -46
  262. package/dist/cjs/utils/misc.cjs.map +1 -1
  263. package/dist/cjs/utils/run.cjs +50 -66
  264. package/dist/cjs/utils/run.cjs.map +1 -1
  265. package/dist/cjs/utils/schema.cjs +11 -19
  266. package/dist/cjs/utils/schema.cjs.map +1 -1
  267. package/dist/cjs/utils/title.cjs +71 -106
  268. package/dist/cjs/utils/title.cjs.map +1 -1
  269. package/dist/cjs/utils/tokens.cjs +186 -283
  270. package/dist/cjs/utils/tokens.cjs.map +1 -1
  271. package/dist/cjs/utils/truncation.cjs +95 -114
  272. package/dist/cjs/utils/truncation.cjs.map +1 -1
  273. package/dist/esm/agents/AgentContext.mjs +844 -1044
  274. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  275. package/dist/esm/common/constants.mjs +13 -11
  276. package/dist/esm/common/constants.mjs.map +1 -1
  277. package/dist/esm/common/enum.mjs +221 -238
  278. package/dist/esm/common/enum.mjs.map +1 -1
  279. package/dist/esm/common/index.mjs +3 -0
  280. package/dist/esm/events.mjs +121 -167
  281. package/dist/esm/events.mjs.map +1 -1
  282. package/dist/esm/graphs/Graph.mjs +1388 -1804
  283. package/dist/esm/graphs/Graph.mjs.map +1 -1
  284. package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
  285. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  286. package/dist/esm/graphs/index.mjs +3 -0
  287. package/dist/esm/hitl/askUserQuestion.mjs +60 -60
  288. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  289. package/dist/esm/hitl/index.mjs +2 -0
  290. package/dist/esm/hooks/HookRegistry.mjs +176 -200
  291. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  292. package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
  293. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  294. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
  295. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  296. package/dist/esm/hooks/executeHooks.mjs +227 -280
  297. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  298. package/dist/esm/hooks/index.mjs +7 -0
  299. package/dist/esm/hooks/matchers.mjs +196 -228
  300. package/dist/esm/hooks/matchers.mjs.map +1 -1
  301. package/dist/esm/hooks/types.mjs +24 -22
  302. package/dist/esm/hooks/types.mjs.map +1 -1
  303. package/dist/esm/instrumentation.mjs +109 -132
  304. package/dist/esm/instrumentation.mjs.map +1 -1
  305. package/dist/esm/langchain/google-common.mjs +1 -2
  306. package/dist/esm/langchain/index.mjs +5 -5
  307. package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
  308. package/dist/esm/langchain/messages/tool.mjs +1 -2
  309. package/dist/esm/langchain/messages.mjs +2 -2
  310. package/dist/esm/langchain/openai.mjs +1 -2
  311. package/dist/esm/langchain/prompts.mjs +2 -2
  312. package/dist/esm/langchain/runnables.mjs +2 -2
  313. package/dist/esm/langchain/tools.mjs +2 -2
  314. package/dist/esm/langchain/utils/env.mjs +2 -2
  315. package/dist/esm/langfuse.mjs +60 -76
  316. package/dist/esm/langfuse.mjs.map +1 -1
  317. package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
  318. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  319. package/dist/esm/llm/anthropic/index.mjs +432 -559
  320. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  321. package/dist/esm/llm/anthropic/types.mjs +23 -45
  322. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  323. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -690
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -249
  326. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  327. package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
  328. package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
  329. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  330. package/dist/esm/llm/bedrock/index.mjs +195 -238
  331. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  332. package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
  333. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  334. package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
  335. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
  336. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  337. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +105 -147
  338. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  339. package/dist/esm/llm/fake.mjs +86 -94
  340. package/dist/esm/llm/fake.mjs.map +1 -1
  341. package/dist/esm/llm/google/index.mjs +183 -235
  342. package/dist/esm/llm/google/index.mjs.map +1 -1
  343. package/dist/esm/llm/google/utils/common.mjs +397 -666
  344. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  345. package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
  346. package/dist/esm/llm/init.mjs +44 -51
  347. package/dist/esm/llm/init.mjs.map +1 -1
  348. package/dist/esm/llm/invoke.mjs +142 -180
  349. package/dist/esm/llm/invoke.mjs.map +1 -1
  350. package/dist/esm/llm/openai/index.mjs +991 -1271
  351. package/dist/esm/llm/openai/index.mjs.map +1 -1
  352. package/dist/esm/llm/openai/utils/index.mjs +188 -312
  353. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  354. package/dist/esm/llm/openrouter/index.mjs +102 -151
  355. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  356. package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
  357. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  358. package/dist/esm/llm/providers.mjs +29 -34
  359. package/dist/esm/llm/providers.mjs.map +1 -1
  360. package/dist/esm/llm/request.mjs +20 -31
  361. package/dist/esm/llm/request.mjs.map +1 -1
  362. package/dist/esm/llm/vertexai/index.mjs +427 -449
  363. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  364. package/dist/esm/main.mjs +99 -87
  365. package/dist/esm/messages/anthropicToolCache.mjs +68 -117
  366. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  367. package/dist/esm/messages/cache.mjs +308 -399
  368. package/dist/esm/messages/cache.mjs.map +1 -1
  369. package/dist/esm/messages/content.mjs +36 -47
  370. package/dist/esm/messages/content.mjs.map +1 -1
  371. package/dist/esm/messages/contextPruning.mjs +112 -143
  372. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  373. package/dist/esm/messages/contextPruningSettings.mjs +36 -44
  374. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  375. package/dist/esm/messages/core.mjs +254 -393
  376. package/dist/esm/messages/core.mjs.map +1 -1
  377. package/dist/esm/messages/format.mjs +902 -1378
  378. package/dist/esm/messages/format.mjs.map +1 -1
  379. package/dist/esm/messages/ids.mjs +16 -18
  380. package/dist/esm/messages/ids.mjs.map +1 -1
  381. package/dist/esm/messages/index.mjs +13 -0
  382. package/dist/esm/messages/langchain.mjs +18 -16
  383. package/dist/esm/messages/langchain.mjs.map +1 -1
  384. package/dist/esm/messages/prune.mjs +1053 -1514
  385. package/dist/esm/messages/prune.mjs.map +1 -1
  386. package/dist/esm/messages/recency.mjs +77 -93
  387. package/dist/esm/messages/recency.mjs.map +1 -1
  388. package/dist/esm/messages/reducer.mjs +63 -76
  389. package/dist/esm/messages/reducer.mjs.map +1 -1
  390. package/dist/esm/messages/tools.mjs +49 -75
  391. package/dist/esm/messages/tools.mjs.map +1 -1
  392. package/dist/esm/openai/index.mjs +170 -215
  393. package/dist/esm/openai/index.mjs.map +1 -1
  394. package/dist/esm/responses/index.mjs +301 -389
  395. package/dist/esm/responses/index.mjs.map +1 -1
  396. package/dist/esm/run.mjs +903 -1111
  397. package/dist/esm/run.mjs.map +1 -1
  398. package/dist/esm/session/AgentSession.mjs +806 -985
  399. package/dist/esm/session/AgentSession.mjs.map +1 -1
  400. package/dist/esm/session/JsonlSessionStore.mjs +326 -407
  401. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  402. package/dist/esm/session/handlers.mjs +192 -206
  403. package/dist/esm/session/handlers.mjs.map +1 -1
  404. package/dist/esm/session/ids.mjs +9 -8
  405. package/dist/esm/session/ids.mjs.map +1 -1
  406. package/dist/esm/session/index.mjs +5 -0
  407. package/dist/esm/session/messageSerialization.mjs +94 -154
  408. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  409. package/dist/esm/splitStream.mjs +147 -204
  410. package/dist/esm/splitStream.mjs.map +1 -1
  411. package/dist/esm/stream.mjs +854 -1341
  412. package/dist/esm/stream.mjs.map +1 -1
  413. package/dist/esm/summarization/index.mjs +57 -99
  414. package/dist/esm/summarization/index.mjs.map +1 -1
  415. package/dist/esm/summarization/node.mjs +640 -790
  416. package/dist/esm/summarization/node.mjs.map +1 -1
  417. package/dist/esm/tools/BashExecutor.mjs +103 -129
  418. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  419. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
  420. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  421. package/dist/esm/tools/Calculator.mjs +34 -36
  422. package/dist/esm/tools/Calculator.mjs.map +1 -1
  423. package/dist/esm/tools/CodeExecutor.mjs +123 -164
  424. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  425. package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
  426. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  427. package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
  428. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  429. package/dist/esm/tools/ReadFile.mjs +17 -18
  430. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  431. package/dist/esm/tools/SkillTool.mjs +26 -25
  432. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  433. package/dist/esm/tools/SubagentTool.mjs +59 -59
  434. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  435. package/dist/esm/tools/ToolNode.mjs +2107 -2684
  436. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  437. package/dist/esm/tools/ToolSearch.mjs +659 -804
  438. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  439. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
  440. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  441. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
  442. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  443. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
  444. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  445. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
  446. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  447. package/dist/esm/tools/cloudflare/index.mjs +5 -0
  448. package/dist/esm/tools/eagerEventExecution.mjs +75 -96
  449. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  450. package/dist/esm/tools/handlers.mjs +200 -260
  451. package/dist/esm/tools/handlers.mjs.map +1 -1
  452. package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
  453. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  454. package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
  455. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  456. package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
  457. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  458. package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
  459. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  460. package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
  461. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  462. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
  463. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  464. package/dist/esm/tools/local/attachments.mjs +108 -163
  465. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  466. package/dist/esm/tools/local/bashAst.mjs +99 -111
  467. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  468. package/dist/esm/tools/local/editStrategies.mjs +126 -167
  469. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  470. package/dist/esm/tools/local/index.mjs +13 -0
  471. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
  472. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  473. package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
  474. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  475. package/dist/esm/tools/local/textEncoding.mjs +25 -21
  476. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  477. package/dist/esm/tools/local/workspaceFS.mjs +38 -44
  478. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  479. package/dist/esm/tools/ptcTimeout.mjs +27 -42
  480. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  481. package/dist/esm/tools/schema.mjs +24 -21
  482. package/dist/esm/tools/schema.mjs.map +1 -1
  483. package/dist/esm/tools/search/anthropic.mjs +24 -31
  484. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  485. package/dist/esm/tools/search/content.mjs +93 -116
  486. package/dist/esm/tools/search/content.mjs.map +1 -1
  487. package/dist/esm/tools/search/firecrawl.mjs +139 -169
  488. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  489. package/dist/esm/tools/search/format.mjs +128 -194
  490. package/dist/esm/tools/search/format.mjs.map +1 -1
  491. package/dist/esm/tools/search/highlights.mjs +165 -230
  492. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  493. package/dist/esm/tools/search/index.mjs +3 -0
  494. package/dist/esm/tools/search/rerankers.mjs +149 -168
  495. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  496. package/dist/esm/tools/search/schema.mjs +39 -37
  497. package/dist/esm/tools/search/schema.mjs.map +1 -1
  498. package/dist/esm/tools/search/search.mjs +426 -528
  499. package/dist/esm/tools/search/search.mjs.map +1 -1
  500. package/dist/esm/tools/search/serper-scraper.mjs +104 -124
  501. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  502. package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
  503. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  504. package/dist/esm/tools/search/tavily-search.mjs +293 -357
  505. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  506. package/dist/esm/tools/search/tool.mjs +259 -297
  507. package/dist/esm/tools/search/tool.mjs.map +1 -1
  508. package/dist/esm/tools/search/utils.mjs +74 -115
  509. package/dist/esm/tools/search/utils.mjs.map +1 -1
  510. package/dist/esm/tools/skillCatalog.mjs +54 -70
  511. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  512. package/dist/esm/tools/streamedToolCallSeals.mjs +19 -31
  513. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  514. package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
  515. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  516. package/dist/esm/tools/subagent/index.mjs +2 -0
  517. package/dist/esm/tools/toolOutputReferences.mjs +523 -624
  518. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  519. package/dist/esm/utils/callbacks.mjs +11 -19
  520. package/dist/esm/utils/callbacks.mjs.map +1 -1
  521. package/dist/esm/utils/errors.mjs +70 -93
  522. package/dist/esm/utils/errors.mjs.map +1 -1
  523. package/dist/esm/utils/events.mjs +32 -40
  524. package/dist/esm/utils/events.mjs.map +1 -1
  525. package/dist/esm/utils/graph.mjs +8 -10
  526. package/dist/esm/utils/graph.mjs.map +1 -1
  527. package/dist/esm/utils/handlers.mjs +60 -80
  528. package/dist/esm/utils/handlers.mjs.map +1 -1
  529. package/dist/esm/utils/index.mjs +10 -0
  530. package/dist/esm/utils/llm.mjs +19 -25
  531. package/dist/esm/utils/llm.mjs.map +1 -1
  532. package/dist/esm/utils/misc.mjs +30 -44
  533. package/dist/esm/utils/misc.mjs.map +1 -1
  534. package/dist/esm/utils/run.mjs +50 -64
  535. package/dist/esm/utils/run.mjs.map +1 -1
  536. package/dist/esm/utils/schema.mjs +11 -17
  537. package/dist/esm/utils/schema.mjs.map +1 -1
  538. package/dist/esm/utils/title.mjs +71 -104
  539. package/dist/esm/utils/title.mjs.map +1 -1
  540. package/dist/esm/utils/tokens.mjs +186 -281
  541. package/dist/esm/utils/tokens.mjs.map +1 -1
  542. package/dist/esm/utils/truncation.mjs +95 -112
  543. package/dist/esm/utils/truncation.mjs.map +1 -1
  544. package/dist/types/messages/format.d.ts +5 -0
  545. package/dist/types/tools/search/tool.d.ts +17 -0
  546. package/dist/types/tools/search/types.d.ts +4 -0
  547. package/package.json +11 -17
  548. package/src/llm/anthropic/llm.spec.ts +36 -0
  549. package/src/llm/anthropic/utils/message_inputs.ts +45 -3
  550. package/src/llm/anthropic/utils/message_outputs.ts +6 -2
  551. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
  552. package/src/messages/cache.test.ts +122 -0
  553. package/src/messages/cache.ts +25 -1
  554. package/src/messages/format.ts +9 -0
  555. package/src/messages/formatAgentMessages.skills.test.ts +100 -0
  556. package/src/tools/search/highlights.ts +9 -1
  557. package/src/tools/search/search.ts +41 -3
  558. package/src/tools/search/source-processing.test.ts +373 -0
  559. package/src/tools/search/tool.ts +22 -2
  560. package/src/tools/search/types.ts +4 -0
  561. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  562. package/dist/cjs/langchain/index.cjs.map +0 -1
  563. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  564. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  565. package/dist/cjs/langchain/messages.cjs.map +0 -1
  566. package/dist/cjs/langchain/openai.cjs.map +0 -1
  567. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  568. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  569. package/dist/cjs/langchain/tools.cjs.map +0 -1
  570. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  571. package/dist/cjs/main.cjs.map +0 -1
  572. package/dist/esm/langchain/google-common.mjs.map +0 -1
  573. package/dist/esm/langchain/index.mjs.map +0 -1
  574. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  575. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  576. package/dist/esm/langchain/messages.mjs.map +0 -1
  577. package/dist/esm/langchain/openai.mjs.map +0 -1
  578. package/dist/esm/langchain/prompts.mjs.map +0 -1
  579. package/dist/esm/langchain/runnables.mjs.map +0 -1
  580. package/dist/esm/langchain/tools.mjs.map +0 -1
  581. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  582. package/dist/esm/main.mjs.map +0 -1
@@ -1,966 +1,668 @@
1
- import { LOCAL_CODING_BUNDLE_NAMES, StepTypes, ContentTypes, Providers, GraphEvents, Constants, ToolCallTypes, CODE_EXECUTION_TOOLS } from './common/enum.mjs';
2
- import { getStreamedToolCallSeal, getStreamedToolCallAdapter } from './tools/streamedToolCallSeals.mjs';
3
- import { normalizeError, buildToolExecutionRequestPlan, coerceRecordArgs } from './tools/eagerEventExecution.mjs';
4
- import { handleServerToolResult, handleToolCalls, handleToolCallChunks } from './tools/handlers.mjs';
5
- import { calculateMaxToolResultChars, truncateToolResultContent } from './utils/truncation.mjs';
6
- import { TOOL_OUTPUT_REF_PATTERN } from './tools/toolOutputReferences.mjs';
7
- import { safeDispatchCustomEvent } from './utils/events.mjs';
8
- import { isGoogleLike } from './utils/llm.mjs';
9
- import './messages/core.mjs';
10
- import { getMessageId } from './messages/ids.mjs';
11
- import '@langchain/core/messages';
12
- import 'node:crypto';
13
- import 'uuid';
14
-
1
+ import { CODE_EXECUTION_TOOLS, LOCAL_CODING_BUNDLE_NAMES } from "./common/enum.mjs";
2
+ import "./common/index.mjs";
3
+ import { getMessageId } from "./messages/ids.mjs";
4
+ import { calculateMaxToolResultChars, truncateToolResultContent } from "./utils/truncation.mjs";
5
+ import { safeDispatchCustomEvent } from "./utils/events.mjs";
6
+ import "./messages/index.mjs";
7
+ import { isGoogleLike } from "./utils/llm.mjs";
8
+ import { getStreamedToolCallAdapter, getStreamedToolCallSeal } from "./tools/streamedToolCallSeals.mjs";
9
+ import { buildToolExecutionRequestPlan, coerceRecordArgs, normalizeError } from "./tools/eagerEventExecution.mjs";
10
+ import { handleServerToolResult, handleToolCallChunks, handleToolCalls } from "./tools/handlers.mjs";
11
+ import { TOOL_OUTPUT_REF_PATTERN } from "./tools/toolOutputReferences.mjs";
12
+ //#region src/stream.ts
15
13
  const LOCAL_CODING_BUNDLE_NAME_SET = new Set(LOCAL_CODING_BUNDLE_NAMES);
16
14
  /**
17
- * Parses content to extract thinking sections enclosed in <think> tags using string operations
18
- * @param content The content to parse
19
- * @returns An object with separated text and thinking content
20
- */
15
+ * Parses content to extract thinking sections enclosed in <think> tags using string operations
16
+ * @param content The content to parse
17
+ * @returns An object with separated text and thinking content
18
+ */
21
19
  function parseThinkingContent(content) {
22
- // If no think tags, return the original content as text
23
- if (!content.includes('<think>')) {
24
- return { text: content, thinking: '' };
25
- }
26
- let textResult = '';
27
- const thinkingResult = [];
28
- let position = 0;
29
- while (position < content.length) {
30
- const thinkStart = content.indexOf('<think>', position);
31
- if (thinkStart === -1) {
32
- // No more think tags, add the rest and break
33
- textResult += content.slice(position);
34
- break;
35
- }
36
- // Add text before the think tag
37
- textResult += content.slice(position, thinkStart);
38
- const thinkEnd = content.indexOf('</think>', thinkStart);
39
- if (thinkEnd === -1) {
40
- // Malformed input, no closing tag
41
- textResult += content.slice(thinkStart);
42
- break;
43
- }
44
- // Add the thinking content
45
- const thinkContent = content.slice(thinkStart + 7, thinkEnd);
46
- thinkingResult.push(thinkContent);
47
- // Move position to after the think tag
48
- position = thinkEnd + 8; // 8 is the length of '</think>'
49
- }
50
- return {
51
- text: textResult.trim(),
52
- thinking: thinkingResult.join('\n').trim(),
53
- };
20
+ if (!content.includes("<think>")) return {
21
+ text: content,
22
+ thinking: ""
23
+ };
24
+ let textResult = "";
25
+ const thinkingResult = [];
26
+ let position = 0;
27
+ while (position < content.length) {
28
+ const thinkStart = content.indexOf("<think>", position);
29
+ if (thinkStart === -1) {
30
+ textResult += content.slice(position);
31
+ break;
32
+ }
33
+ textResult += content.slice(position, thinkStart);
34
+ const thinkEnd = content.indexOf("</think>", thinkStart);
35
+ if (thinkEnd === -1) {
36
+ textResult += content.slice(thinkStart);
37
+ break;
38
+ }
39
+ const thinkContent = content.slice(thinkStart + 7, thinkEnd);
40
+ thinkingResult.push(thinkContent);
41
+ position = thinkEnd + 8;
42
+ }
43
+ return {
44
+ text: textResult.trim(),
45
+ thinking: thinkingResult.join("\n").trim()
46
+ };
54
47
  }
55
48
  function getNonEmptyValue(possibleValues) {
56
- for (const value of possibleValues) {
57
- if (value && value.trim() !== '') {
58
- return value;
59
- }
60
- }
61
- return undefined;
49
+ for (const value of possibleValues) if (value && value.trim() !== "") return value;
62
50
  }
63
51
  function isBatchSensitiveToolExecution(graph) {
64
- return graph.hookRegistry != null || graph.humanInTheLoop?.enabled === true;
52
+ return graph.hookRegistry != null || graph.humanInTheLoop?.enabled === true;
65
53
  }
66
54
  function hasToolOutputReference(value) {
67
- if (typeof value === 'string') {
68
- return TOOL_OUTPUT_REF_PATTERN.test(value);
69
- }
70
- if (Array.isArray(value)) {
71
- return value.some((item) => hasToolOutputReference(item));
72
- }
73
- if (value !== null && typeof value === 'object') {
74
- return Object.values(value).some((item) => hasToolOutputReference(item));
75
- }
76
- return false;
55
+ if (typeof value === "string") return TOOL_OUTPUT_REF_PATTERN.test(value);
56
+ if (Array.isArray(value)) return value.some((item) => hasToolOutputReference(item));
57
+ if (value !== null && typeof value === "object") return Object.values(value).some((item) => hasToolOutputReference(item));
58
+ return false;
77
59
  }
78
60
  function isDirectGraphTool(name, agentContext) {
79
- if (name.startsWith(Constants.LC_TRANSFER_TO_)) {
80
- return true;
81
- }
82
- return (agentContext?.graphTools?.some((tool) => 'name' in tool && tool.name === name) === true);
61
+ if (name.startsWith("lc_transfer_to_")) return true;
62
+ return (agentContext?.graphTools)?.some((tool) => "name" in tool && tool.name === name) === true;
83
63
  }
84
64
  function isDirectLocalTool(name, graph) {
85
- const toolExecution = graph.toolExecution;
86
- const engine = toolExecution?.engine;
87
- if (toolExecution == null ||
88
- (engine !== 'local' && engine !== 'cloudflare-sandbox')) {
89
- return false;
90
- }
91
- const includeCodingTools = engine === 'cloudflare-sandbox'
92
- ? toolExecution.cloudflare?.includeCodingTools
93
- : toolExecution.local?.includeCodingTools;
94
- if (includeCodingTools === false) {
95
- return CODE_EXECUTION_TOOLS.has(name);
96
- }
97
- return LOCAL_CODING_BUNDLE_NAME_SET.has(name);
65
+ const toolExecution = graph.toolExecution;
66
+ const engine = toolExecution?.engine;
67
+ if (toolExecution == null || engine !== "local" && engine !== "cloudflare-sandbox") return false;
68
+ if ((engine === "cloudflare-sandbox" ? toolExecution.cloudflare?.includeCodingTools : toolExecution.local?.includeCodingTools) === false) return CODE_EXECUTION_TOOLS.has(name);
69
+ return LOCAL_CODING_BUNDLE_NAME_SET.has(name);
98
70
  }
99
71
  function toCodeEnvFile(file, execSessionId) {
100
- const base = {
101
- id: file.id,
102
- resource_id: file.resource_id ?? file.id,
103
- name: file.name,
104
- storage_session_id: file.storage_session_id ?? execSessionId,
105
- };
106
- const kind = file.kind ?? 'user';
107
- if (kind === 'skill' && file.version != null) {
108
- return { ...base, kind: 'skill', version: file.version };
109
- }
110
- if (kind === 'agent') {
111
- return { ...base, kind: 'agent' };
112
- }
113
- return { ...base, kind: 'user' };
72
+ const base = {
73
+ id: file.id,
74
+ resource_id: file.resource_id ?? file.id,
75
+ name: file.name,
76
+ storage_session_id: file.storage_session_id ?? execSessionId
77
+ };
78
+ const kind = file.kind ?? "user";
79
+ if (kind === "skill" && file.version != null) return {
80
+ ...base,
81
+ kind: "skill",
82
+ version: file.version
83
+ };
84
+ if (kind === "agent") return {
85
+ ...base,
86
+ kind: "agent"
87
+ };
88
+ return {
89
+ ...base,
90
+ kind: "user"
91
+ };
114
92
  }
115
93
  function getCodeSessionContext(graph, name) {
116
- if (!CODE_EXECUTION_TOOLS.has(name) &&
117
- name !== Constants.SKILL_TOOL &&
118
- name !== Constants.READ_FILE) {
119
- return undefined;
120
- }
121
- const codeSession = graph.sessions.get(Constants.EXECUTE_CODE);
122
- if (codeSession?.session_id == null || codeSession.session_id === '') {
123
- return undefined;
124
- }
125
- return {
126
- session_id: codeSession.session_id,
127
- files: codeSession.files?.map((file) => toCodeEnvFile(file, codeSession.session_id)),
128
- };
94
+ if (!CODE_EXECUTION_TOOLS.has(name) && name !== "skill" && name !== "read_file") return;
95
+ const codeSession = graph.sessions.get("execute_code");
96
+ if (codeSession?.session_id == null || codeSession.session_id === "") return;
97
+ return {
98
+ session_id: codeSession.session_id,
99
+ files: codeSession.files?.map((file) => toCodeEnvFile(file, codeSession.session_id))
100
+ };
129
101
  }
130
102
  function isEagerToolExecutionEnabledForBatch(args) {
131
- const { graph, metadata, agentContext } = args;
132
- if (graph.eagerEventToolExecution?.enabled !== true) {
133
- return false;
134
- }
135
- if ((agentContext?.toolDefinitions?.length ?? 0) === 0) {
136
- return false;
137
- }
138
- if (isBatchSensitiveToolExecution(graph)) {
139
- return false;
140
- }
141
- if (metadata?.[Constants.PROGRAMMATIC_TOOL_CALLING] === true ||
142
- metadata?.[Constants.BASH_PROGRAMMATIC_TOOL_CALLING] === true) {
143
- return false;
144
- }
145
- if (graph.handlerRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) == null &&
146
- graph.eventToolExecutionAvailable !== true) {
147
- return false;
148
- }
149
- return true;
103
+ const { graph, metadata, agentContext } = args;
104
+ if (graph.eagerEventToolExecution?.enabled !== true) return false;
105
+ if ((agentContext?.toolDefinitions?.length ?? 0) === 0) return false;
106
+ if (isBatchSensitiveToolExecution(graph)) return false;
107
+ if (metadata?.["run_tools_with_code"] === true || metadata?.["run_tools_with_bash"] === true) return false;
108
+ if (graph.handlerRegistry?.getHandler("on_tool_execute") == null && graph.eventToolExecutionAvailable !== true) return false;
109
+ return true;
150
110
  }
151
111
  function hasFinalToolCallSignal(chunk) {
152
- const metadata = chunk.response_metadata;
153
- const finishReason = metadata?.finish_reason ??
154
- metadata?.finishReason ??
155
- metadata?.stop_reason ??
156
- metadata?.stopReason;
157
- return finishReason === 'tool_calls' || finishReason === 'tool_use';
112
+ const metadata = chunk.response_metadata;
113
+ const finishReason = metadata?.finish_reason ?? metadata?.finishReason ?? metadata?.stop_reason ?? metadata?.stopReason;
114
+ return finishReason === "tool_calls" || finishReason === "tool_use";
158
115
  }
159
116
  function canPrestartSequentialStreamedToolChunks(agentContext) {
160
- // Anthropic seals each prior streamed tool-use block when the next indexed
161
- // tool-use block begins. Live Kimi/Moonshot streams can still revise prior
162
- // args after advancing to the next index, so keep those on the final
163
- // tool-call path unless they grow an explicit adapter seal.
164
- return agentContext?.provider === Providers.ANTHROPIC;
117
+ return agentContext?.provider === "anthropic";
165
118
  }
166
119
  function hasExplicitStreamedToolCallSeals(chunk) {
167
- return (getStreamedToolCallAdapter(chunk.response_metadata) != null);
120
+ return getStreamedToolCallAdapter(chunk.response_metadata) != null;
168
121
  }
169
122
  function hasDirectToolCallInBatch(args) {
170
- const { graph, agentContext, toolCalls } = args;
171
- return toolCalls.some((toolCall) => toolCall.name !== '' &&
172
- (isDirectGraphTool(toolCall.name, agentContext) ||
173
- isDirectLocalTool(toolCall.name, graph)));
123
+ const { graph, agentContext, toolCalls } = args;
124
+ return toolCalls.some((toolCall) => toolCall.name !== "" && (isDirectGraphTool(toolCall.name, agentContext) || isDirectLocalTool(toolCall.name, graph)));
174
125
  }
175
126
  function hasPotentialDirectToolInStreamContext(args) {
176
- const { graph, agentContext } = args;
177
- const engine = graph.toolExecution?.engine;
178
- if (engine === 'local' || engine === 'cloudflare-sandbox') {
179
- return true;
180
- }
181
- if ((agentContext?.graphTools?.length ?? 0) > 0) {
182
- return true;
183
- }
184
- return false;
127
+ const { graph, agentContext } = args;
128
+ const engine = graph.toolExecution?.engine;
129
+ if (engine === "local" || engine === "cloudflare-sandbox") return true;
130
+ if ((agentContext?.graphTools?.length ?? 0) > 0) return true;
131
+ return false;
185
132
  }
186
133
  function hasDirectToolCallChunkInBatch(args) {
187
- const { graph, agentContext, toolCallChunks } = args;
188
- return (toolCallChunks?.some((toolCallChunk) => toolCallChunk.name != null &&
189
- toolCallChunk.name !== '' &&
190
- (isDirectGraphTool(toolCallChunk.name, agentContext) ||
191
- isDirectLocalTool(toolCallChunk.name, graph))) === true);
134
+ const { graph, agentContext, toolCallChunks } = args;
135
+ return toolCallChunks?.some((toolCallChunk) => toolCallChunk.name != null && toolCallChunk.name !== "" && (isDirectGraphTool(toolCallChunk.name, agentContext) || isDirectLocalTool(toolCallChunk.name, graph))) === true;
192
136
  }
193
137
  function hasDirectToolCallChunkStateInStep(args) {
194
- const { graph, agentContext, stepKey } = args;
195
- const prefix = `${stepKey}\u0000`;
196
- for (const [key, state] of graph.eagerEventToolCallChunks) {
197
- if (!key.startsWith(prefix)) {
198
- continue;
199
- }
200
- const name = state.name;
201
- if (name != null &&
202
- name !== '' &&
203
- (isDirectGraphTool(name, agentContext) || isDirectLocalTool(name, graph))) {
204
- return true;
205
- }
206
- }
207
- return false;
138
+ const { graph, agentContext, stepKey } = args;
139
+ const prefix = `${stepKey}\u0000`;
140
+ for (const [key, state] of graph.eagerEventToolCallChunks) {
141
+ if (!key.startsWith(prefix)) continue;
142
+ const name = state.name;
143
+ if (name != null && name !== "" && (isDirectGraphTool(name, agentContext) || isDirectLocalTool(name, graph))) return true;
144
+ }
145
+ return false;
208
146
  }
209
147
  function isGoogleServerSideToolContentPart(contentPart) {
210
- return contentPart.type === 'toolCall' || contentPart.type === 'toolResponse';
148
+ return contentPart.type === "toolCall" || contentPart.type === "toolResponse";
211
149
  }
212
150
  function isTextContentPart(contentPart) {
213
- return contentPart.type?.startsWith(ContentTypes.TEXT) ?? false;
151
+ return contentPart.type?.startsWith("text") ?? false;
214
152
  }
215
153
  function isReasoningContentPart(contentPart) {
216
- return ((contentPart.type?.startsWith(ContentTypes.THINKING) ?? false) ||
217
- (contentPart.type?.startsWith(ContentTypes.REASONING) ?? false) ||
218
- (contentPart.type?.startsWith(ContentTypes.REASONING_CONTENT) ?? false) ||
219
- contentPart.type === 'redacted_thinking');
154
+ return (contentPart.type?.startsWith("thinking") ?? false) || (contentPart.type?.startsWith("reasoning") ?? false) || (contentPart.type?.startsWith("reasoning_content") ?? false) || contentPart.type === "redacted_thinking";
220
155
  }
221
156
  function getReasoningTextFromContentPart(contentPart) {
222
- return (contentPart.thinking ??
223
- contentPart.reasoning ??
224
- contentPart.reasoningText
225
- ?.text ??
226
- '');
157
+ return contentPart.thinking ?? contentPart.reasoning ?? contentPart.reasoningText?.text ?? "";
227
158
  }
228
159
  function getReasoningTextFromChunk(chunk, agentContext) {
229
- const reasoning = chunk.additional_kwargs?.[agentContext.reasoningKey];
230
- if (typeof reasoning === 'string') {
231
- return reasoning;
232
- }
233
- return reasoning?.summary?.[0]?.text ?? '';
160
+ const reasoning = chunk.additional_kwargs?.[agentContext.reasoningKey];
161
+ if (typeof reasoning === "string") return reasoning;
162
+ return reasoning?.summary?.[0]?.text ?? "";
234
163
  }
235
- const googleServerSideToolStepIdsByGraph = new WeakMap();
164
+ const googleServerSideToolStepIdsByGraph = /* @__PURE__ */ new WeakMap();
236
165
  function markGoogleServerSideToolMessageStep(graph, stepId) {
237
- const stepIds = googleServerSideToolStepIdsByGraph.get(graph) ?? new Set();
238
- stepIds.add(stepId);
239
- googleServerSideToolStepIdsByGraph.set(graph, stepIds);
166
+ const stepIds = googleServerSideToolStepIdsByGraph.get(graph) ?? /* @__PURE__ */ new Set();
167
+ stepIds.add(stepId);
168
+ googleServerSideToolStepIdsByGraph.set(graph, stepIds);
240
169
  }
241
170
  function isGoogleServerSideToolMessageStep(graph, stepId) {
242
- return googleServerSideToolStepIdsByGraph.get(graph)?.has(stepId) === true;
243
- }
244
- function shouldStartFreshMessageStepAfterGoogleServerSideTool({ graph, stepId, runStep, content, }) {
245
- if (runStep?.type !== StepTypes.MESSAGE_CREATION ||
246
- !isGoogleServerSideToolMessageStep(graph, stepId)) {
247
- return false;
248
- }
249
- if (typeof content === 'string') {
250
- return true;
251
- }
252
- return (content.every((c) => isTextContentPart(c)) ||
253
- content.every((c) => isReasoningContentPart(c)));
254
- }
255
- async function dispatchMessageCreationStep({ graph, stepKey, metadata, }) {
256
- const messageId = getMessageId(stepKey, graph, true) ?? '';
257
- return graph.dispatchRunStep(stepKey, {
258
- type: StepTypes.MESSAGE_CREATION,
259
- message_creation: {
260
- message_id: messageId,
261
- },
262
- }, metadata);
263
- }
264
- async function dispatchMessageContentParts({ graph, stepKey, content, metadata, }) {
265
- for (const contentPart of content) {
266
- const currentStepId = await dispatchMessageCreationStep({
267
- graph,
268
- stepKey,
269
- metadata,
270
- });
271
- if (isGoogleServerSideToolContentPart(contentPart)) {
272
- markGoogleServerSideToolMessageStep(graph, currentStepId);
273
- }
274
- await graph.dispatchMessageDelta(currentStepId, {
275
- content: [contentPart],
276
- }, metadata);
277
- }
278
- }
279
- async function dispatchReasoningContentParts({ graph, stepKey, content, metadata, }) {
280
- if (content.length === 0) {
281
- return;
282
- }
283
- const currentStepId = await dispatchMessageCreationStep({
284
- graph,
285
- stepKey,
286
- metadata,
287
- });
288
- await graph.dispatchReasoningDelta(currentStepId, {
289
- content,
290
- }, metadata);
291
- }
292
- async function dispatchGoogleServerSideToolStreamContent({ graph, stepKey, chunk, agentContext, content, metadata, }) {
293
- const reasoningContent = [];
294
- const reasoningText = getReasoningTextFromChunk(chunk, agentContext);
295
- if (reasoningText !== '') {
296
- reasoningContent.push({
297
- type: ContentTypes.THINK,
298
- think: reasoningText,
299
- });
300
- }
301
- reasoningContent.push(...content
302
- .filter((contentPart) => isReasoningContentPart(contentPart))
303
- .map((contentPart) => ({
304
- type: ContentTypes.THINK,
305
- think: getReasoningTextFromContentPart(contentPart),
306
- }))
307
- .filter((contentPart) => contentPart.think !== ''));
308
- await dispatchReasoningContentParts({
309
- graph,
310
- stepKey,
311
- content: reasoningContent,
312
- metadata,
313
- });
314
- const messageContent = content.filter((contentPart) => isTextContentPart(contentPart) ||
315
- isGoogleServerSideToolContentPart(contentPart));
316
- await dispatchMessageContentParts({
317
- graph,
318
- stepKey,
319
- content: messageContent,
320
- metadata,
321
- });
171
+ return googleServerSideToolStepIdsByGraph.get(graph)?.has(stepId) === true;
172
+ }
173
+ function shouldStartFreshMessageStepAfterGoogleServerSideTool({ graph, stepId, runStep, content }) {
174
+ if (runStep?.type !== "message_creation" || !isGoogleServerSideToolMessageStep(graph, stepId)) return false;
175
+ if (typeof content === "string") return true;
176
+ return content.every((c) => isTextContentPart(c)) || content.every((c) => isReasoningContentPart(c));
177
+ }
178
+ async function dispatchMessageCreationStep({ graph, stepKey, metadata }) {
179
+ const messageId = getMessageId(stepKey, graph, true) ?? "";
180
+ return graph.dispatchRunStep(stepKey, {
181
+ type: "message_creation",
182
+ message_creation: { message_id: messageId }
183
+ }, metadata);
184
+ }
185
+ async function dispatchMessageContentParts({ graph, stepKey, content, metadata }) {
186
+ for (const contentPart of content) {
187
+ const currentStepId = await dispatchMessageCreationStep({
188
+ graph,
189
+ stepKey,
190
+ metadata
191
+ });
192
+ if (isGoogleServerSideToolContentPart(contentPart)) markGoogleServerSideToolMessageStep(graph, currentStepId);
193
+ await graph.dispatchMessageDelta(currentStepId, { content: [contentPart] }, metadata);
194
+ }
195
+ }
196
+ async function dispatchReasoningContentParts({ graph, stepKey, content, metadata }) {
197
+ if (content.length === 0) return;
198
+ const currentStepId = await dispatchMessageCreationStep({
199
+ graph,
200
+ stepKey,
201
+ metadata
202
+ });
203
+ await graph.dispatchReasoningDelta(currentStepId, { content }, metadata);
204
+ }
205
+ async function dispatchGoogleServerSideToolStreamContent({ graph, stepKey, chunk, agentContext, content, metadata }) {
206
+ const reasoningContent = [];
207
+ const reasoningText = getReasoningTextFromChunk(chunk, agentContext);
208
+ if (reasoningText !== "") reasoningContent.push({
209
+ type: "think",
210
+ think: reasoningText
211
+ });
212
+ reasoningContent.push(...content.filter((contentPart) => isReasoningContentPart(contentPart)).map((contentPart) => ({
213
+ type: "think",
214
+ think: getReasoningTextFromContentPart(contentPart)
215
+ })).filter((contentPart) => contentPart.think !== ""));
216
+ await dispatchReasoningContentParts({
217
+ graph,
218
+ stepKey,
219
+ content: reasoningContent,
220
+ metadata
221
+ });
222
+ await dispatchMessageContentParts({
223
+ graph,
224
+ stepKey,
225
+ content: content.filter((contentPart) => isTextContentPart(contentPart) || isGoogleServerSideToolContentPart(contentPart)),
226
+ metadata
227
+ });
322
228
  }
323
229
  function createEagerToolExecutionPlan(args) {
324
- const { graph, metadata, agentContext, toolCalls, skipExisting = false, } = args;
325
- if (!isEagerToolExecutionEnabledForBatch({
326
- graph,
327
- metadata,
328
- agentContext,
329
- })) {
330
- return undefined;
331
- }
332
- if (hasDirectToolCallInBatch({ graph, agentContext, toolCalls })) {
333
- return undefined;
334
- }
335
- if (graph.toolOutputReferences?.enabled === true &&
336
- toolCalls.some((toolCall) => hasToolOutputReference(toolCall.args))) {
337
- return undefined;
338
- }
339
- const candidateToolCalls = skipExisting
340
- ? toolCalls.filter((toolCall) => {
341
- if (toolCall.id == null || toolCall.id === '') {
342
- return true;
343
- }
344
- return !graph.eagerEventToolExecutions.has(toolCall.id);
345
- })
346
- : toolCalls;
347
- if (candidateToolCalls.length === 0) {
348
- return [];
349
- }
350
- // Eager execution must preserve ToolNode batch semantics exactly for every
351
- // unstarted call. If any candidate cannot be planned, fall back for that
352
- // candidate set.
353
- if (candidateToolCalls.some((toolCall) => toolCall.id == null ||
354
- toolCall.id === '' ||
355
- toolCall.name === '' ||
356
- (!skipExisting && graph.eagerEventToolExecutions.has(toolCall.id)))) {
357
- return undefined;
358
- }
359
- const plan = buildToolExecutionRequestPlan({
360
- toolCalls: candidateToolCalls.map((toolCall) => ({
361
- id: toolCall.id,
362
- name: toolCall.name,
363
- args: toolCall.args,
364
- stepId: graph.toolCallStepIds.get(toolCall.id) ?? '',
365
- codeSessionContext: getCodeSessionContext(graph, toolCall.name),
366
- })),
367
- usageCount: graph.getEagerEventToolUsageCount(agentContext?.agentId),
368
- });
369
- if (plan == null) {
370
- return undefined;
371
- }
372
- return plan.requests.map((request) => ({
373
- id: request.id,
374
- toolName: request.name,
375
- coercedArgs: request.args,
376
- request,
377
- }));
230
+ const { graph, metadata, agentContext, toolCalls, skipExisting = false } = args;
231
+ if (!isEagerToolExecutionEnabledForBatch({
232
+ graph,
233
+ metadata,
234
+ agentContext
235
+ })) return;
236
+ if (hasDirectToolCallInBatch({
237
+ graph,
238
+ agentContext,
239
+ toolCalls
240
+ })) return;
241
+ if (graph.toolOutputReferences?.enabled === true && toolCalls.some((toolCall) => hasToolOutputReference(toolCall.args))) return;
242
+ const candidateToolCalls = skipExisting ? toolCalls.filter((toolCall) => {
243
+ if (toolCall.id == null || toolCall.id === "") return true;
244
+ return !graph.eagerEventToolExecutions.has(toolCall.id);
245
+ }) : toolCalls;
246
+ if (candidateToolCalls.length === 0) return [];
247
+ if (candidateToolCalls.some((toolCall) => toolCall.id == null || toolCall.id === "" || toolCall.name === "" || !skipExisting && graph.eagerEventToolExecutions.has(toolCall.id))) return;
248
+ const plan = buildToolExecutionRequestPlan({
249
+ toolCalls: candidateToolCalls.map((toolCall) => ({
250
+ id: toolCall.id,
251
+ name: toolCall.name,
252
+ args: toolCall.args,
253
+ stepId: graph.toolCallStepIds.get(toolCall.id) ?? "",
254
+ codeSessionContext: getCodeSessionContext(graph, toolCall.name)
255
+ })),
256
+ usageCount: graph.getEagerEventToolUsageCount(agentContext?.agentId)
257
+ });
258
+ if (plan == null) return;
259
+ return plan.requests.map((request) => ({
260
+ id: request.id,
261
+ toolName: request.name,
262
+ coercedArgs: request.args,
263
+ request
264
+ }));
378
265
  }
379
266
  function startEagerToolExecutions(args) {
380
- const { graph, metadata, agentContext, toolCalls, skipExisting } = args;
381
- const entries = createEagerToolExecutionPlan({
382
- graph,
383
- metadata,
384
- agentContext,
385
- toolCalls,
386
- skipExisting,
387
- });
388
- if (entries == null || entries.length === 0) {
389
- return;
390
- }
391
- const records = [];
392
- const promise = new Promise((resolve, reject) => {
393
- let dispatchSettled = false;
394
- let resultSettled = false;
395
- let settledResults;
396
- const maybeResolve = () => {
397
- if (dispatchSettled && resultSettled) {
398
- resolve(settledResults ?? []);
399
- }
400
- };
401
- const batchRequest = {
402
- toolCalls: entries.map((entry) => entry.request),
403
- userId: graph.config?.configurable?.user_id,
404
- agentId: agentContext?.agentId,
405
- configurable: graph.config?.configurable,
406
- metadata,
407
- resolve: (results) => {
408
- resultSettled = true;
409
- settledResults = results;
410
- maybeResolve();
411
- },
412
- reject,
413
- };
414
- void safeDispatchCustomEvent(GraphEvents.ON_TOOL_EXECUTE, batchRequest, graph.config)
415
- .then(() => {
416
- dispatchSettled = true;
417
- maybeResolve();
418
- })
419
- .catch(reject);
420
- }).then(async (results) => {
421
- await dispatchEagerToolCompletions({
422
- graph,
423
- agentContext,
424
- records,
425
- results,
426
- });
427
- return { results };
428
- }, (error) => ({
429
- error: normalizeError(error),
430
- }));
431
- for (const entry of entries) {
432
- const record = {
433
- toolCallId: entry.id,
434
- toolName: entry.toolName,
435
- args: entry.coercedArgs,
436
- request: entry.request,
437
- promise,
438
- };
439
- records.push(record);
440
- graph.eagerEventToolExecutions.set(entry.id, record);
441
- }
267
+ const { graph, metadata, agentContext, toolCalls, skipExisting } = args;
268
+ const entries = createEagerToolExecutionPlan({
269
+ graph,
270
+ metadata,
271
+ agentContext,
272
+ toolCalls,
273
+ skipExisting
274
+ });
275
+ if (entries == null || entries.length === 0) return;
276
+ const records = [];
277
+ const promise = new Promise((resolve, reject) => {
278
+ let dispatchSettled = false;
279
+ let resultSettled = false;
280
+ let settledResults;
281
+ const maybeResolve = () => {
282
+ if (dispatchSettled && resultSettled) resolve(settledResults ?? []);
283
+ };
284
+ safeDispatchCustomEvent("on_tool_execute", {
285
+ toolCalls: entries.map((entry) => entry.request),
286
+ userId: graph.config?.configurable?.user_id,
287
+ agentId: agentContext?.agentId,
288
+ configurable: graph.config?.configurable,
289
+ metadata,
290
+ resolve: (results) => {
291
+ resultSettled = true;
292
+ settledResults = results;
293
+ maybeResolve();
294
+ },
295
+ reject
296
+ }, graph.config).then(() => {
297
+ dispatchSettled = true;
298
+ maybeResolve();
299
+ }).catch(reject);
300
+ }).then(async (results) => {
301
+ await dispatchEagerToolCompletions({
302
+ graph,
303
+ agentContext,
304
+ records,
305
+ results
306
+ });
307
+ return { results };
308
+ }, (error) => ({ error: normalizeError(error) }));
309
+ for (const entry of entries) {
310
+ const record = {
311
+ toolCallId: entry.id,
312
+ toolName: entry.toolName,
313
+ args: entry.coercedArgs,
314
+ request: entry.request,
315
+ promise
316
+ };
317
+ records.push(record);
318
+ graph.eagerEventToolExecutions.set(entry.id, record);
319
+ }
442
320
  }
443
321
  async function dispatchEagerToolCompletions(args) {
444
- const { graph, agentContext, records, results } = args;
445
- const recordById = new Map(records.map((record) => [record.toolCallId, record]));
446
- const maxToolResultChars = agentContext?.maxToolResultChars ??
447
- calculateMaxToolResultChars(agentContext?.maxContextTokens);
448
- for (const result of results) {
449
- const record = recordById.get(result.toolCallId);
450
- if (record == null) {
451
- continue;
452
- }
453
- if (graph.eagerEventToolExecutions.get(result.toolCallId) !== record) {
454
- continue;
455
- }
456
- const stepId = record.request.stepId ??
457
- graph.toolCallStepIds.get(result.toolCallId) ??
458
- '';
459
- if (stepId === '') {
460
- continue;
461
- }
462
- const output = result.status === 'error'
463
- ? `Error: ${result.errorMessage ?? 'Unknown error'}\n Please fix your mistakes.`
464
- : truncateToolResultContent(typeof result.content === 'string'
465
- ? result.content
466
- : JSON.stringify(result.content), maxToolResultChars);
467
- try {
468
- const dispatched = await safeDispatchCustomEvent(GraphEvents.ON_RUN_STEP_COMPLETED, {
469
- result: {
470
- id: stepId,
471
- index: record.request.turn ?? 0,
472
- type: 'tool_call',
473
- eager: true,
474
- tool_call: {
475
- args: JSON.stringify(record.request.args),
476
- name: record.toolName,
477
- id: result.toolCallId,
478
- output,
479
- progress: 1,
480
- },
481
- },
482
- }, graph.config);
483
- if (dispatched === false) {
484
- continue;
485
- }
486
- record.completionDispatched = true;
487
- }
488
- catch (error) {
489
- // Let ToolNode dispatch the completion through the normal path later.
490
- console.warn(`[stream] eager completion dispatch failed for toolCallId=${result.toolCallId}:`, error instanceof Error ? error.message : error);
491
- }
492
- }
322
+ const { graph, agentContext, records, results } = args;
323
+ const recordById = new Map(records.map((record) => [record.toolCallId, record]));
324
+ const maxToolResultChars = agentContext?.maxToolResultChars ?? calculateMaxToolResultChars(agentContext?.maxContextTokens);
325
+ for (const result of results) {
326
+ const record = recordById.get(result.toolCallId);
327
+ if (record == null) continue;
328
+ if (graph.eagerEventToolExecutions.get(result.toolCallId) !== record) continue;
329
+ const stepId = record.request.stepId ?? graph.toolCallStepIds.get(result.toolCallId) ?? "";
330
+ if (stepId === "") continue;
331
+ const output = result.status === "error" ? `Error: ${result.errorMessage ?? "Unknown error"}\n Please fix your mistakes.` : truncateToolResultContent(typeof result.content === "string" ? result.content : JSON.stringify(result.content), maxToolResultChars);
332
+ try {
333
+ if (await safeDispatchCustomEvent("on_run_step_completed", { result: {
334
+ id: stepId,
335
+ index: record.request.turn ?? 0,
336
+ type: "tool_call",
337
+ eager: true,
338
+ tool_call: {
339
+ args: JSON.stringify(record.request.args),
340
+ name: record.toolName,
341
+ id: result.toolCallId,
342
+ output,
343
+ progress: 1
344
+ }
345
+ } }, graph.config) === false) continue;
346
+ record.completionDispatched = true;
347
+ } catch (error) {
348
+ console.warn(`[stream] eager completion dispatch failed for toolCallId=${result.toolCallId}:`, error instanceof Error ? error.message : error);
349
+ }
350
+ }
493
351
  }
494
352
  function getEagerToolChunkKey(stepKey, toolCallChunk) {
495
- let chunkKey;
496
- if (typeof toolCallChunk.index === 'number') {
497
- chunkKey = String(toolCallChunk.index);
498
- }
499
- else if (toolCallChunk.id != null && toolCallChunk.id !== '') {
500
- chunkKey = toolCallChunk.id;
501
- }
502
- if (chunkKey == null) {
503
- return undefined;
504
- }
505
- return `${stepKey}\u0000${chunkKey}`;
353
+ let chunkKey;
354
+ if (typeof toolCallChunk.index === "number") chunkKey = String(toolCallChunk.index);
355
+ else if (toolCallChunk.id != null && toolCallChunk.id !== "") chunkKey = toolCallChunk.id;
356
+ if (chunkKey == null) return;
357
+ return `${stepKey}\u0000${chunkKey}`;
506
358
  }
507
359
  function getEagerToolChunkIndex(toolCallChunk) {
508
- return typeof toolCallChunk.index === 'number'
509
- ? toolCallChunk.index
510
- : undefined;
360
+ return typeof toolCallChunk.index === "number" ? toolCallChunk.index : void 0;
511
361
  }
512
362
  function pruneEagerToolCallChunkStates(args) {
513
- const { graph, stepKey, toolCallIds, clearStep = false } = args;
514
- const prefix = `${stepKey}\u0000`;
515
- for (const [key, state] of graph.eagerEventToolCallChunks) {
516
- if (!key.startsWith(prefix)) {
517
- continue;
518
- }
519
- if (clearStep ||
520
- (state.id != null && toolCallIds?.has(state.id) === true)) {
521
- graph.eagerEventToolCallChunks.delete(key);
522
- }
523
- }
363
+ const { graph, stepKey, toolCallIds, clearStep = false } = args;
364
+ const prefix = `${stepKey}\u0000`;
365
+ for (const [key, state] of graph.eagerEventToolCallChunks) {
366
+ if (!key.startsWith(prefix)) continue;
367
+ if (clearStep || state.id != null && toolCallIds?.has(state.id) === true) graph.eagerEventToolCallChunks.delete(key);
368
+ }
524
369
  }
525
370
  function isEagerToolChunkStateComplete(state) {
526
- return (state.id != null &&
527
- state.id !== '' &&
528
- state.name != null &&
529
- state.name !== '' &&
530
- coerceRecordArgs(state.argsText) != null);
371
+ return state.id != null && state.id !== "" && state.name != null && state.name !== "" && coerceRecordArgs(state.argsText) != null;
531
372
  }
532
373
  function mergeToolCallArgsText(existing, incoming) {
533
- if (incoming === '') {
534
- return existing;
535
- }
536
- if (existing === '') {
537
- return incoming;
538
- }
539
- if (incoming === existing) {
540
- try {
541
- JSON.parse(incoming);
542
- return incoming;
543
- }
544
- catch {
545
- return `${existing}${incoming}`;
546
- }
547
- }
548
- if (incoming.startsWith(existing)) {
549
- return incoming;
550
- }
551
- if (existing.startsWith(incoming)) {
552
- return existing;
553
- }
554
- try {
555
- JSON.parse(existing);
556
- JSON.parse(incoming);
557
- return incoming;
558
- }
559
- catch {
560
- // Fall through to delta concatenation.
561
- }
562
- for (let overlap = Math.min(existing.length, incoming.length); overlap >= 8; overlap -= 1) {
563
- if (existing.endsWith(incoming.slice(0, overlap))) {
564
- return `${existing}${incoming.slice(overlap)}`;
565
- }
566
- }
567
- return `${existing}${incoming}`;
374
+ if (incoming === "") return existing;
375
+ if (existing === "") return incoming;
376
+ if (incoming === existing) try {
377
+ JSON.parse(incoming);
378
+ return incoming;
379
+ } catch {
380
+ return `${existing}${incoming}`;
381
+ }
382
+ if (incoming.startsWith(existing)) return incoming;
383
+ if (existing.startsWith(incoming)) return existing;
384
+ try {
385
+ JSON.parse(existing);
386
+ JSON.parse(incoming);
387
+ return incoming;
388
+ } catch {}
389
+ for (let overlap = Math.min(existing.length, incoming.length); overlap >= 8; overlap -= 1) if (existing.endsWith(incoming.slice(0, overlap))) return `${existing}${incoming.slice(overlap)}`;
390
+ return `${existing}${incoming}`;
568
391
  }
569
392
  function recordEagerToolCallChunks(args) {
570
- const { graph, stepKey, toolCallChunks } = args;
571
- if (toolCallChunks == null || toolCallChunks.length === 0) {
572
- return;
573
- }
574
- // Streamed args can be cumulative and parseable before the provider has
575
- // sealed the call. Recording stays separate from dispatch so the boundary
576
- // logic can wait for either a later tool index or the final tool-call signal.
577
- for (const toolCallChunk of toolCallChunks) {
578
- const key = getEagerToolChunkKey(stepKey, toolCallChunk);
579
- if (key == null) {
580
- continue;
581
- }
582
- const incomingId = toolCallChunk.id != null && toolCallChunk.id !== ''
583
- ? toolCallChunk.id
584
- : undefined;
585
- const incomingName = toolCallChunk.name != null && toolCallChunk.name !== ''
586
- ? toolCallChunk.name
587
- : undefined;
588
- const previous = graph.eagerEventToolCallChunks.get(key);
589
- const shouldReset = previous != null &&
590
- ((incomingId != null &&
591
- previous.id != null &&
592
- incomingId !== previous.id) ||
593
- (incomingName != null &&
594
- previous.name != null &&
595
- incomingName !== previous.name));
596
- const existing = previous == null || shouldReset
597
- ? {
598
- argsText: '',
599
- }
600
- : previous;
601
- const id = incomingId ?? existing.id;
602
- const name = incomingName ?? existing.name;
603
- const incomingArgs = toolCallChunk.args ?? '';
604
- const isRepeatedObservedFragment = incomingArgs !== '' &&
605
- incomingArgs.length > 1 &&
606
- incomingArgs === existing.lastArgsFragment;
607
- const argsText = isRepeatedObservedFragment
608
- ? existing.argsText
609
- : mergeToolCallArgsText(existing.argsText, incomingArgs);
610
- const next = {
611
- id,
612
- name,
613
- argsText,
614
- index: getEagerToolChunkIndex(toolCallChunk) ?? existing.index,
615
- lastArgsFragment: incomingArgs !== '' ? incomingArgs : existing.lastArgsFragment,
616
- };
617
- graph.eagerEventToolCallChunks.set(key, next);
618
- }
393
+ const { graph, stepKey, toolCallChunks } = args;
394
+ if (toolCallChunks == null || toolCallChunks.length === 0) return;
395
+ for (const toolCallChunk of toolCallChunks) {
396
+ const key = getEagerToolChunkKey(stepKey, toolCallChunk);
397
+ if (key == null) continue;
398
+ const incomingId = toolCallChunk.id != null && toolCallChunk.id !== "" ? toolCallChunk.id : void 0;
399
+ const incomingName = toolCallChunk.name != null && toolCallChunk.name !== "" ? toolCallChunk.name : void 0;
400
+ const previous = graph.eagerEventToolCallChunks.get(key);
401
+ const shouldReset = previous != null && (incomingId != null && previous.id != null && incomingId !== previous.id || incomingName != null && previous.name != null && incomingName !== previous.name);
402
+ const existing = previous == null || shouldReset ? { argsText: "" } : previous;
403
+ const id = incomingId ?? existing.id;
404
+ const name = incomingName ?? existing.name;
405
+ const incomingArgs = toolCallChunk.args ?? "";
406
+ const next = {
407
+ id,
408
+ name,
409
+ argsText: incomingArgs !== "" && incomingArgs.length > 1 && incomingArgs === existing.lastArgsFragment ? existing.argsText : mergeToolCallArgsText(existing.argsText, incomingArgs),
410
+ index: getEagerToolChunkIndex(toolCallChunk) ?? existing.index,
411
+ lastArgsFragment: incomingArgs !== "" ? incomingArgs : existing.lastArgsFragment
412
+ };
413
+ graph.eagerEventToolCallChunks.set(key, next);
414
+ }
619
415
  }
620
416
  function getStreamedReadyToolCalls(args) {
621
- const { graph, stepKey, toolCallChunks, seal, allowSequentialSeal = false, sealAll = false, } = args;
622
- const currentIndices = new Set();
623
- for (const toolCallChunk of toolCallChunks ?? []) {
624
- const index = getEagerToolChunkIndex(toolCallChunk);
625
- if (index != null) {
626
- currentIndices.add(index);
627
- }
628
- }
629
- const highestCurrentIndex = currentIndices.size > 0 ? Math.max(...currentIndices) : undefined;
630
- const prefix = `${stepKey}\u0000`;
631
- const readyEntries = [];
632
- for (const [key, state] of graph.eagerEventToolCallChunks) {
633
- if (!key.startsWith(prefix)) {
634
- continue;
635
- }
636
- if (state.id != null && graph.eagerEventToolExecutions.has(state.id)) {
637
- graph.eagerEventToolCallChunks.delete(key);
638
- continue;
639
- }
640
- if (!isEagerToolChunkStateComplete(state)) {
641
- continue;
642
- }
643
- const isSealedByLaterChunk = allowSequentialSeal &&
644
- highestCurrentIndex != null &&
645
- state.index != null &&
646
- state.index < highestCurrentIndex &&
647
- !currentIndices.has(state.index);
648
- const isSealedExplicitly = seal?.kind === 'single' &&
649
- ((seal.id != null && state.id === seal.id) ||
650
- (seal.index != null && state.index === seal.index));
651
- if (sealAll ||
652
- seal?.kind === 'all' ||
653
- isSealedByLaterChunk ||
654
- isSealedExplicitly) {
655
- readyEntries.push({ key, state });
656
- }
657
- }
658
- pruneEagerToolCallChunkStates({
659
- graph,
660
- stepKey,
661
- toolCallIds: new Set(readyEntries
662
- .map(({ state }) => state.id)
663
- .filter((id) => id != null && id !== '')),
664
- });
665
- if (sealAll) {
666
- pruneEagerToolCallChunkStates({ graph, stepKey, clearStep: true });
667
- }
668
- return readyEntries
669
- .sort((left, right) => (left.state.index ?? 0) - (right.state.index ?? 0))
670
- .flatMap(({ state }) => {
671
- const args = coerceRecordArgs(state.argsText);
672
- if (args == null) {
673
- return [];
674
- }
675
- return [
676
- {
677
- id: state.id,
678
- name: state.name ?? '',
679
- args,
680
- },
681
- ];
682
- });
417
+ const { graph, stepKey, toolCallChunks, seal, allowSequentialSeal = false, sealAll = false } = args;
418
+ const currentIndices = /* @__PURE__ */ new Set();
419
+ for (const toolCallChunk of toolCallChunks ?? []) {
420
+ const index = getEagerToolChunkIndex(toolCallChunk);
421
+ if (index != null) currentIndices.add(index);
422
+ }
423
+ const highestCurrentIndex = currentIndices.size > 0 ? Math.max(...currentIndices) : void 0;
424
+ const prefix = `${stepKey}\u0000`;
425
+ const readyEntries = [];
426
+ for (const [key, state] of graph.eagerEventToolCallChunks) {
427
+ if (!key.startsWith(prefix)) continue;
428
+ if (state.id != null && graph.eagerEventToolExecutions.has(state.id)) {
429
+ graph.eagerEventToolCallChunks.delete(key);
430
+ continue;
431
+ }
432
+ if (!isEagerToolChunkStateComplete(state)) continue;
433
+ const isSealedByLaterChunk = allowSequentialSeal && highestCurrentIndex != null && state.index != null && state.index < highestCurrentIndex && !currentIndices.has(state.index);
434
+ const isSealedExplicitly = seal?.kind === "single" && (seal.id != null && state.id === seal.id || seal.index != null && state.index === seal.index);
435
+ if (sealAll || seal?.kind === "all" || isSealedByLaterChunk || isSealedExplicitly) readyEntries.push({
436
+ key,
437
+ state
438
+ });
439
+ }
440
+ pruneEagerToolCallChunkStates({
441
+ graph,
442
+ stepKey,
443
+ toolCallIds: new Set(readyEntries.map(({ state }) => state.id).filter((id) => id != null && id !== ""))
444
+ });
445
+ if (sealAll) pruneEagerToolCallChunkStates({
446
+ graph,
447
+ stepKey,
448
+ clearStep: true
449
+ });
450
+ return readyEntries.sort((left, right) => (left.state.index ?? 0) - (right.state.index ?? 0)).flatMap(({ state }) => {
451
+ const args = coerceRecordArgs(state.argsText);
452
+ if (args == null) return [];
453
+ return [{
454
+ id: state.id,
455
+ name: state.name ?? "",
456
+ args
457
+ }];
458
+ });
683
459
  }
684
460
  function startReadyStreamedEagerToolExecutions(args) {
685
- const { graph, metadata, agentContext, stepKey, toolCallChunks, seal, allowSequentialSeal, sealAll, } = args;
686
- if (hasPotentialDirectToolInStreamContext({ graph, agentContext }) ||
687
- hasDirectToolCallChunkInBatch({ graph, agentContext, toolCallChunks }) ||
688
- hasDirectToolCallChunkStateInStep({ graph, agentContext, stepKey }) ||
689
- !isEagerToolExecutionEnabledForBatch({ graph, metadata, agentContext })) {
690
- return;
691
- }
692
- const toolCalls = getStreamedReadyToolCalls({
693
- graph,
694
- stepKey,
695
- toolCallChunks,
696
- seal,
697
- allowSequentialSeal,
698
- sealAll,
699
- });
700
- if (toolCalls.length === 0) {
701
- return;
702
- }
703
- startEagerToolExecutions({
704
- graph,
705
- metadata,
706
- agentContext,
707
- toolCalls,
708
- skipExisting: true,
709
- });
710
- }
711
- function getChunkContent({ chunk, provider, reasoningKey, }) {
712
- if (isGoogleLike(provider) &&
713
- Array.isArray(chunk?.content) &&
714
- chunk.content.some((c) => isGoogleServerSideToolContentPart(c))) {
715
- return chunk.content;
716
- }
717
- if ((provider === Providers.OPENAI || provider === Providers.AZURE) &&
718
- chunk?.additional_kwargs?.reasoning?.summary?.[0]?.text != null &&
719
- (chunk?.additional_kwargs?.reasoning?.summary?.[0]?.text?.length ?? 0) > 0) {
720
- return chunk?.additional_kwargs?.reasoning?.summary?.[0]?.text;
721
- }
722
- if (provider === Providers.OPENROUTER) {
723
- // Content presence signals end of reasoning phase - prefer content over reasoning
724
- // This handles transitional chunks that may have both reasoning and content
725
- if (typeof chunk?.content === 'string' && chunk.content !== '') {
726
- return chunk.content;
727
- }
728
- const reasoning = chunk?.additional_kwargs?.reasoning;
729
- if (reasoning != null && reasoning !== '') {
730
- return reasoning;
731
- }
732
- const reasoningContent = chunk?.additional_kwargs?.reasoning_content;
733
- if (reasoningContent != null && reasoningContent !== '') {
734
- return reasoningContent;
735
- }
736
- return chunk?.content;
737
- }
738
- const keyedReasoning = chunk?.additional_kwargs?.[reasoningKey];
739
- if (typeof chunk?.content === 'string' &&
740
- chunk.content !== '' &&
741
- keyedReasoning != null &&
742
- keyedReasoning !== '') {
743
- return chunk.content;
744
- }
745
- return (keyedReasoning ?? '') || chunk?.content;
461
+ const { graph, metadata, agentContext, stepKey, toolCallChunks, seal, allowSequentialSeal, sealAll } = args;
462
+ if (hasPotentialDirectToolInStreamContext({
463
+ graph,
464
+ agentContext
465
+ }) || hasDirectToolCallChunkInBatch({
466
+ graph,
467
+ agentContext,
468
+ toolCallChunks
469
+ }) || hasDirectToolCallChunkStateInStep({
470
+ graph,
471
+ agentContext,
472
+ stepKey
473
+ }) || !isEagerToolExecutionEnabledForBatch({
474
+ graph,
475
+ metadata,
476
+ agentContext
477
+ })) return;
478
+ const toolCalls = getStreamedReadyToolCalls({
479
+ graph,
480
+ stepKey,
481
+ toolCallChunks,
482
+ seal,
483
+ allowSequentialSeal,
484
+ sealAll
485
+ });
486
+ if (toolCalls.length === 0) return;
487
+ startEagerToolExecutions({
488
+ graph,
489
+ metadata,
490
+ agentContext,
491
+ toolCalls,
492
+ skipExisting: true
493
+ });
494
+ }
495
+ function getChunkContent({ chunk, provider, reasoningKey }) {
496
+ if (isGoogleLike(provider) && Array.isArray(chunk?.content) && chunk.content.some((c) => isGoogleServerSideToolContentPart(c))) return chunk.content;
497
+ if ((provider === "openAI" || provider === "azureOpenAI") && (chunk?.additional_kwargs?.reasoning)?.summary?.[0]?.text != null && ((chunk?.additional_kwargs?.reasoning)?.summary?.[0]?.text?.length ?? 0) > 0) return (chunk?.additional_kwargs?.reasoning)?.summary?.[0]?.text;
498
+ if (provider === "openrouter") {
499
+ if (typeof chunk?.content === "string" && chunk.content !== "") return chunk.content;
500
+ const reasoning = chunk?.additional_kwargs?.reasoning;
501
+ if (reasoning != null && reasoning !== "") return reasoning;
502
+ const reasoningContent = chunk?.additional_kwargs?.reasoning_content;
503
+ if (reasoningContent != null && reasoningContent !== "") return reasoningContent;
504
+ return chunk?.content;
505
+ }
506
+ const keyedReasoning = chunk?.additional_kwargs?.[reasoningKey];
507
+ if (typeof chunk?.content === "string" && chunk.content !== "" && keyedReasoning != null && keyedReasoning !== "") return chunk.content;
508
+ return (keyedReasoning ?? "") || chunk?.content;
746
509
  }
747
510
  function isDisableStreamingEnabled(clientOptions) {
748
- return (clientOptions != null &&
749
- 'disableStreaming' in clientOptions &&
750
- clientOptions.disableStreaming === true);
511
+ return clientOptions != null && "disableStreaming" in clientOptions && clientOptions.disableStreaming === true;
751
512
  }
752
513
  function hasReasoningContent(value) {
753
- if (typeof value === 'string') {
754
- return value !== '';
755
- }
756
- if (Array.isArray(value)) {
757
- return value.length > 0;
758
- }
759
- if (value == null) {
760
- return false;
761
- }
762
- return (value.summary?.some((summary) => summary.text != null && summary.text.length > 0) === true);
763
- }
764
- function shouldDeferMixedFinalReasoningChunk({ chunk, agentContext, }) {
765
- if ((chunk.tool_calls?.length ?? 0) > 0 ||
766
- (chunk.tool_call_chunks?.length ?? 0) > 0 ||
767
- typeof chunk.content !== 'string' ||
768
- chunk.content === '') {
769
- return false;
770
- }
771
- const additionalKwargs = chunk.additional_kwargs;
772
- if (agentContext.provider === Providers.OPENROUTER &&
773
- hasReasoningContent(additionalKwargs?.reasoning_details)) {
774
- return true;
775
- }
776
- if (!isDisableStreamingEnabled(agentContext.clientOptions)) {
777
- return false;
778
- }
779
- return (hasReasoningContent(additionalKwargs?.[agentContext.reasoningKey]) ||
780
- hasReasoningContent(additionalKwargs?.reasoning_content) ||
781
- hasReasoningContent(additionalKwargs?.reasoning) ||
782
- hasReasoningContent(additionalKwargs?.reasoning_details));
783
- }
784
- function hasCurrentTextDeltaStep({ graph, metadata, }) {
785
- if (metadata == null) {
786
- return false;
787
- }
788
- const baseStepKey = graph.getStepBaseKey(metadata);
789
- for (const [stepKey, stepIds] of graph.stepKeyIds) {
790
- if (stepKey !== baseStepKey && !stepKey.startsWith(`${baseStepKey}_`)) {
791
- continue;
792
- }
793
- if (stepIds.some((stepId) => graph.messageStepHasTextDeltas.has(stepId))) {
794
- return true;
795
- }
796
- }
797
- return false;
798
- }
799
- function shouldSkipLateOpenRouterReasoningChunk({ chunk, agentContext, graph, metadata, }) {
800
- if (agentContext.provider !== Providers.OPENROUTER ||
801
- (chunk.tool_calls?.length ?? 0) > 0 ||
802
- (chunk.tool_call_chunks?.length ?? 0) > 0 ||
803
- (chunk.content != null && chunk.content !== '')) {
804
- return false;
805
- }
806
- return ((hasReasoningContent(chunk.additional_kwargs?.reasoning) ||
807
- hasReasoningContent(chunk.additional_kwargs?.reasoning_content) ||
808
- hasReasoningContent(chunk.additional_kwargs?.reasoning_details)) &&
809
- hasCurrentTextDeltaStep({ graph, metadata }));
810
- }
811
- class ChatModelStreamHandler {
812
- async handle(event, data, metadata, graph) {
813
- if (!graph) {
814
- throw new Error('Graph not found');
815
- }
816
- if (!graph.config) {
817
- throw new Error('Config not found in graph');
818
- }
819
- if (!data.chunk) {
820
- console.warn(`No chunk found in ${event} event`);
821
- return;
822
- }
823
- const agentContext = graph.getAgentContext(metadata);
824
- const chunk = data.chunk;
825
- const content = getChunkContent({
826
- chunk,
827
- reasoningKey: agentContext.reasoningKey,
828
- provider: agentContext.provider,
829
- });
830
- const skipHandling = await handleServerToolResult({
831
- graph,
832
- content,
833
- metadata,
834
- agentContext,
835
- });
836
- if (skipHandling) {
837
- return;
838
- }
839
- if (shouldDeferMixedFinalReasoningChunk({ chunk, agentContext })) {
840
- return;
841
- }
842
- if (shouldSkipLateOpenRouterReasoningChunk({
843
- chunk,
844
- agentContext,
845
- graph,
846
- metadata,
847
- })) {
848
- return;
849
- }
850
- this.handleReasoning(chunk, agentContext);
851
- const stepKey = graph.getStepKey(metadata);
852
- let hasToolCalls = false;
853
- const hasToolCallChunks = (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) ?? false;
854
- const hasGoogleServerSideToolContent = isGoogleLike(agentContext.provider) &&
855
- Array.isArray(content) &&
856
- content.some((c) => isGoogleServerSideToolContentPart(c));
857
- if (hasGoogleServerSideToolContent && Array.isArray(content)) {
858
- await dispatchGoogleServerSideToolStreamContent({
859
- graph,
860
- stepKey,
861
- chunk,
862
- agentContext,
863
- content,
864
- metadata,
865
- });
866
- }
867
- if (chunk.tool_calls &&
868
- chunk.tool_calls.length > 0 &&
869
- chunk.tool_calls.every((tc) => tc.id != null &&
870
- tc.id !== '' &&
871
- tc.name != null &&
872
- tc.name !== '')) {
873
- hasToolCalls = true;
874
- await handleToolCalls(chunk.tool_calls, metadata, graph);
875
- if (hasFinalToolCallSignal(chunk)) {
876
- startEagerToolExecutions({
877
- graph,
878
- metadata,
879
- agentContext,
880
- toolCalls: chunk.tool_calls,
881
- skipExisting: true,
882
- });
883
- if (!hasToolCallChunks) {
884
- pruneEagerToolCallChunkStates({ graph, stepKey, clearStep: true });
885
- }
886
- }
887
- }
888
- const isEmptyContent = typeof content === 'undefined' ||
889
- !content.length ||
890
- (typeof content === 'string' && !content);
891
- /** Set a preliminary message ID if found in empty chunk */
892
- const isEmptyChunk = isEmptyContent && !hasToolCallChunks;
893
- if (isEmptyChunk &&
894
- (chunk.id ?? '') !== '' &&
895
- !graph.prelimMessageIdsByStepKey.has(chunk.id ?? '')) {
896
- graph.prelimMessageIdsByStepKey.set(stepKey, chunk.id ?? '');
897
- }
898
- else if (isEmptyChunk) {
899
- return;
900
- }
901
- if (hasToolCallChunks &&
902
- chunk.tool_call_chunks &&
903
- chunk.tool_call_chunks.length &&
904
- typeof chunk.tool_call_chunks[0]?.index === 'number') {
905
- const streamedToolCallSeal = getStreamedToolCallSeal(chunk.response_metadata);
906
- const allowSequentialSeal = canPrestartSequentialStreamedToolChunks(agentContext);
907
- const canStreamEager = (allowSequentialSeal || hasExplicitStreamedToolCallSeals(chunk)) &&
908
- !hasPotentialDirectToolInStreamContext({ graph, agentContext }) &&
909
- isEagerToolExecutionEnabledForBatch({ graph, metadata, agentContext });
910
- if (canStreamEager) {
911
- recordEagerToolCallChunks({
912
- graph,
913
- stepKey,
914
- toolCallChunks: chunk.tool_call_chunks,
915
- });
916
- }
917
- await handleToolCallChunks({
918
- graph,
919
- stepKey,
920
- toolCallChunks: chunk.tool_call_chunks,
921
- metadata,
922
- });
923
- if (canStreamEager) {
924
- startReadyStreamedEagerToolExecutions({
925
- graph,
926
- metadata,
927
- agentContext,
928
- stepKey,
929
- toolCallChunks: chunk.tool_call_chunks,
930
- seal: streamedToolCallSeal,
931
- allowSequentialSeal,
932
- sealAll: hasFinalToolCallSignal(chunk),
933
- });
934
- }
935
- }
936
- if (isEmptyContent) {
937
- return;
938
- }
939
- if (hasGoogleServerSideToolContent) {
940
- return;
941
- }
942
- const message_id = getMessageId(stepKey, graph) ?? '';
943
- if (message_id) {
944
- await graph.dispatchRunStep(stepKey, {
945
- type: StepTypes.MESSAGE_CREATION,
946
- message_creation: {
947
- message_id,
948
- },
949
- }, metadata);
950
- }
951
- let stepId = graph.getStepIdByKey(stepKey);
952
- let runStep = graph.getRunStep(stepId);
953
- if (shouldStartFreshMessageStepAfterGoogleServerSideTool({
954
- graph,
955
- stepId,
956
- runStep,
957
- content,
958
- })) {
959
- stepId = await dispatchMessageCreationStep({ graph, stepKey, metadata });
960
- runStep = graph.getRunStep(stepId);
961
- }
962
- if (!runStep) {
963
- console.warn(`\n
514
+ if (typeof value === "string") return value !== "";
515
+ if (Array.isArray(value)) return value.length > 0;
516
+ if (value == null) return false;
517
+ return value.summary?.some((summary) => summary.text != null && summary.text.length > 0) === true;
518
+ }
519
+ function shouldDeferMixedFinalReasoningChunk({ chunk, agentContext }) {
520
+ if ((chunk.tool_calls?.length ?? 0) > 0 || (chunk.tool_call_chunks?.length ?? 0) > 0 || typeof chunk.content !== "string" || chunk.content === "") return false;
521
+ const additionalKwargs = chunk.additional_kwargs;
522
+ if (agentContext.provider === "openrouter" && hasReasoningContent(additionalKwargs?.reasoning_details)) return true;
523
+ if (!isDisableStreamingEnabled(agentContext.clientOptions)) return false;
524
+ return hasReasoningContent(additionalKwargs?.[agentContext.reasoningKey]) || hasReasoningContent(additionalKwargs?.reasoning_content) || hasReasoningContent(additionalKwargs?.reasoning) || hasReasoningContent(additionalKwargs?.reasoning_details);
525
+ }
526
+ function hasCurrentTextDeltaStep({ graph, metadata }) {
527
+ if (metadata == null) return false;
528
+ const baseStepKey = graph.getStepBaseKey(metadata);
529
+ for (const [stepKey, stepIds] of graph.stepKeyIds) {
530
+ if (stepKey !== baseStepKey && !stepKey.startsWith(`${baseStepKey}_`)) continue;
531
+ if (stepIds.some((stepId) => graph.messageStepHasTextDeltas.has(stepId))) return true;
532
+ }
533
+ return false;
534
+ }
535
+ function shouldSkipLateOpenRouterReasoningChunk({ chunk, agentContext, graph, metadata }) {
536
+ if (agentContext.provider !== "openrouter" || (chunk.tool_calls?.length ?? 0) > 0 || (chunk.tool_call_chunks?.length ?? 0) > 0 || chunk.content != null && chunk.content !== "") return false;
537
+ return (hasReasoningContent(chunk.additional_kwargs?.reasoning) || hasReasoningContent(chunk.additional_kwargs?.reasoning_content) || hasReasoningContent(chunk.additional_kwargs?.reasoning_details)) && hasCurrentTextDeltaStep({
538
+ graph,
539
+ metadata
540
+ });
541
+ }
542
+ var ChatModelStreamHandler = class {
543
+ async handle(event, data, metadata, graph) {
544
+ if (!graph) throw new Error("Graph not found");
545
+ if (!graph.config) throw new Error("Config not found in graph");
546
+ if (!data.chunk) {
547
+ console.warn(`No chunk found in ${event} event`);
548
+ return;
549
+ }
550
+ const agentContext = graph.getAgentContext(metadata);
551
+ const chunk = data.chunk;
552
+ const content = getChunkContent({
553
+ chunk,
554
+ reasoningKey: agentContext.reasoningKey,
555
+ provider: agentContext.provider
556
+ });
557
+ if (await handleServerToolResult({
558
+ graph,
559
+ content,
560
+ metadata,
561
+ agentContext
562
+ })) return;
563
+ if (shouldDeferMixedFinalReasoningChunk({
564
+ chunk,
565
+ agentContext
566
+ })) return;
567
+ if (shouldSkipLateOpenRouterReasoningChunk({
568
+ chunk,
569
+ agentContext,
570
+ graph,
571
+ metadata
572
+ })) return;
573
+ this.handleReasoning(chunk, agentContext);
574
+ const stepKey = graph.getStepKey(metadata);
575
+ let hasToolCalls = false;
576
+ const hasToolCallChunks = (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) ?? false;
577
+ const hasGoogleServerSideToolContent = isGoogleLike(agentContext.provider) && Array.isArray(content) && content.some((c) => isGoogleServerSideToolContentPart(c));
578
+ if (hasGoogleServerSideToolContent && Array.isArray(content)) await dispatchGoogleServerSideToolStreamContent({
579
+ graph,
580
+ stepKey,
581
+ chunk,
582
+ agentContext,
583
+ content,
584
+ metadata
585
+ });
586
+ if (chunk.tool_calls && chunk.tool_calls.length > 0 && chunk.tool_calls.every((tc) => tc.id != null && tc.id !== "" && tc.name != null && tc.name !== "")) {
587
+ hasToolCalls = true;
588
+ await handleToolCalls(chunk.tool_calls, metadata, graph);
589
+ if (hasFinalToolCallSignal(chunk)) {
590
+ startEagerToolExecutions({
591
+ graph,
592
+ metadata,
593
+ agentContext,
594
+ toolCalls: chunk.tool_calls,
595
+ skipExisting: true
596
+ });
597
+ if (!hasToolCallChunks) pruneEagerToolCallChunkStates({
598
+ graph,
599
+ stepKey,
600
+ clearStep: true
601
+ });
602
+ }
603
+ }
604
+ const isEmptyContent = typeof content === "undefined" || !content.length || typeof content === "string" && !content;
605
+ /** Set a preliminary message ID if found in empty chunk */
606
+ const isEmptyChunk = isEmptyContent && !hasToolCallChunks;
607
+ if (isEmptyChunk && (chunk.id ?? "") !== "" && !graph.prelimMessageIdsByStepKey.has(chunk.id ?? "")) graph.prelimMessageIdsByStepKey.set(stepKey, chunk.id ?? "");
608
+ else if (isEmptyChunk) return;
609
+ if (hasToolCallChunks && chunk.tool_call_chunks && chunk.tool_call_chunks.length && typeof chunk.tool_call_chunks[0]?.index === "number") {
610
+ const streamedToolCallSeal = getStreamedToolCallSeal(chunk.response_metadata);
611
+ const allowSequentialSeal = canPrestartSequentialStreamedToolChunks(agentContext);
612
+ const canStreamEager = (allowSequentialSeal || hasExplicitStreamedToolCallSeals(chunk)) && !hasPotentialDirectToolInStreamContext({
613
+ graph,
614
+ agentContext
615
+ }) && isEagerToolExecutionEnabledForBatch({
616
+ graph,
617
+ metadata,
618
+ agentContext
619
+ });
620
+ if (canStreamEager) recordEagerToolCallChunks({
621
+ graph,
622
+ stepKey,
623
+ toolCallChunks: chunk.tool_call_chunks
624
+ });
625
+ await handleToolCallChunks({
626
+ graph,
627
+ stepKey,
628
+ toolCallChunks: chunk.tool_call_chunks,
629
+ metadata
630
+ });
631
+ if (canStreamEager) startReadyStreamedEagerToolExecutions({
632
+ graph,
633
+ metadata,
634
+ agentContext,
635
+ stepKey,
636
+ toolCallChunks: chunk.tool_call_chunks,
637
+ seal: streamedToolCallSeal,
638
+ allowSequentialSeal,
639
+ sealAll: hasFinalToolCallSignal(chunk)
640
+ });
641
+ }
642
+ if (isEmptyContent) return;
643
+ if (hasGoogleServerSideToolContent) return;
644
+ const message_id = getMessageId(stepKey, graph) ?? "";
645
+ if (message_id) await graph.dispatchRunStep(stepKey, {
646
+ type: "message_creation",
647
+ message_creation: { message_id }
648
+ }, metadata);
649
+ let stepId = graph.getStepIdByKey(stepKey);
650
+ let runStep = graph.getRunStep(stepId);
651
+ if (shouldStartFreshMessageStepAfterGoogleServerSideTool({
652
+ graph,
653
+ stepId,
654
+ runStep,
655
+ content
656
+ })) {
657
+ stepId = await dispatchMessageCreationStep({
658
+ graph,
659
+ stepKey,
660
+ metadata
661
+ });
662
+ runStep = graph.getRunStep(stepId);
663
+ }
664
+ if (!runStep) {
665
+ console.warn(`\n
964
666
  ==============================================================
965
667
 
966
668
 
@@ -975,456 +677,267 @@ hasToolCallChunks: ${hasToolCallChunks}
975
677
 
976
678
  ==============================================================
977
679
  \n`);
978
- return;
979
- }
980
- /* Note: tool call chunks may have non-empty content that matches the current tool chunk generation */
981
- if (typeof content === 'string' && runStep.type === StepTypes.TOOL_CALLS) {
982
- return;
983
- }
984
- else if (hasToolCallChunks &&
985
- (chunk.tool_call_chunks?.some((tc) => tc.args === content) ?? false)) {
986
- return;
987
- }
988
- else if (typeof content === 'string') {
989
- if (agentContext.currentTokenType === ContentTypes.TEXT) {
990
- await graph.dispatchMessageDelta(stepId, {
991
- content: [
992
- {
993
- type: ContentTypes.TEXT,
994
- text: content,
995
- },
996
- ],
997
- }, metadata);
998
- }
999
- else if (agentContext.currentTokenType === 'think_and_text') {
1000
- const { text, thinking } = parseThinkingContent(content);
1001
- if (thinking) {
1002
- await graph.dispatchReasoningDelta(stepId, {
1003
- content: [
1004
- {
1005
- type: ContentTypes.THINK,
1006
- think: thinking,
1007
- },
1008
- ],
1009
- }, metadata);
1010
- }
1011
- if (text) {
1012
- agentContext.currentTokenType = ContentTypes.TEXT;
1013
- agentContext.tokenTypeSwitch = 'content';
1014
- const newStepKey = graph.getStepKey(metadata);
1015
- const message_id = getMessageId(newStepKey, graph) ?? '';
1016
- await graph.dispatchRunStep(newStepKey, {
1017
- type: StepTypes.MESSAGE_CREATION,
1018
- message_creation: {
1019
- message_id,
1020
- },
1021
- }, metadata);
1022
- const newStepId = graph.getStepIdByKey(newStepKey);
1023
- await graph.dispatchMessageDelta(newStepId, {
1024
- content: [
1025
- {
1026
- type: ContentTypes.TEXT,
1027
- text: text,
1028
- },
1029
- ],
1030
- }, metadata);
1031
- }
1032
- }
1033
- else {
1034
- await graph.dispatchReasoningDelta(stepId, {
1035
- content: [
1036
- {
1037
- type: ContentTypes.THINK,
1038
- think: content,
1039
- },
1040
- ],
1041
- }, metadata);
1042
- }
1043
- }
1044
- else if (content.every((c) => isTextContentPart(c))) {
1045
- await graph.dispatchMessageDelta(stepId, {
1046
- content,
1047
- }, metadata);
1048
- }
1049
- else if (content.every((c) => isReasoningContentPart(c))) {
1050
- await graph.dispatchReasoningDelta(stepId, {
1051
- content: content.map((c) => ({
1052
- type: ContentTypes.THINK,
1053
- think: c.thinking ??
1054
- c.reasoning ??
1055
- c.reasoningText
1056
- ?.text ??
1057
- '',
1058
- })),
1059
- }, metadata);
1060
- }
1061
- }
1062
- handleReasoning(chunk, agentContext) {
1063
- let reasoning_content = chunk.additional_kwargs?.[agentContext.reasoningKey];
1064
- if (Array.isArray(chunk.content) &&
1065
- (chunk.content[0]?.type === ContentTypes.THINKING ||
1066
- chunk.content[0]?.type === ContentTypes.REASONING ||
1067
- chunk.content[0]?.type === ContentTypes.REASONING_CONTENT ||
1068
- chunk.content[0]?.type === 'redacted_thinking')) {
1069
- reasoning_content = 'valid';
1070
- }
1071
- else if ((agentContext.provider === Providers.OPENAI ||
1072
- agentContext.provider === Providers.AZURE) &&
1073
- reasoning_content != null &&
1074
- typeof reasoning_content !== 'string' &&
1075
- reasoning_content.summary?.[0]?.text != null &&
1076
- reasoning_content.summary[0].text) {
1077
- reasoning_content = 'valid';
1078
- }
1079
- else if (agentContext.provider === Providers.OPENROUTER &&
1080
- // Only set reasoning as valid if content is NOT present (content signals end of reasoning)
1081
- (chunk.content == null || chunk.content === '') &&
1082
- // Check for reasoning_details (final chunk) OR reasoning string (intermediate chunks)
1083
- ((chunk.additional_kwargs?.reasoning_details != null &&
1084
- Array.isArray(chunk.additional_kwargs.reasoning_details) &&
1085
- chunk.additional_kwargs.reasoning_details.length > 0) ||
1086
- (typeof chunk.additional_kwargs?.reasoning === 'string' &&
1087
- chunk.additional_kwargs.reasoning !== '') ||
1088
- (typeof chunk.additional_kwargs?.reasoning_content === 'string' &&
1089
- chunk.additional_kwargs.reasoning_content !== ''))) {
1090
- reasoning_content = 'valid';
1091
- }
1092
- if (reasoning_content != null &&
1093
- reasoning_content !== '' &&
1094
- (chunk.content == null ||
1095
- chunk.content === '' ||
1096
- reasoning_content === 'valid')) {
1097
- agentContext.currentTokenType = ContentTypes.THINK;
1098
- agentContext.tokenTypeSwitch = 'reasoning';
1099
- return;
1100
- }
1101
- else if (agentContext.tokenTypeSwitch === 'reasoning' &&
1102
- agentContext.currentTokenType !== ContentTypes.TEXT &&
1103
- ((chunk.content != null && chunk.content !== '') ||
1104
- (chunk.tool_calls?.length ?? 0) > 0 ||
1105
- (chunk.tool_call_chunks?.length ?? 0) > 0)) {
1106
- agentContext.currentTokenType = ContentTypes.TEXT;
1107
- agentContext.tokenTypeSwitch = 'content';
1108
- agentContext.reasoningTransitionCount++;
1109
- }
1110
- else if (chunk.content != null &&
1111
- typeof chunk.content === 'string' &&
1112
- chunk.content.includes('<think>') &&
1113
- chunk.content.includes('</think>')) {
1114
- agentContext.currentTokenType = 'think_and_text';
1115
- agentContext.tokenTypeSwitch = 'content';
1116
- }
1117
- else if (chunk.content != null &&
1118
- typeof chunk.content === 'string' &&
1119
- chunk.content.includes('<think>')) {
1120
- agentContext.currentTokenType = ContentTypes.THINK;
1121
- agentContext.tokenTypeSwitch = 'content';
1122
- }
1123
- else if (agentContext.lastToken != null &&
1124
- agentContext.lastToken.includes('</think>')) {
1125
- agentContext.currentTokenType = ContentTypes.TEXT;
1126
- agentContext.tokenTypeSwitch = 'content';
1127
- }
1128
- if (typeof chunk.content !== 'string') {
1129
- return;
1130
- }
1131
- agentContext.lastToken = chunk.content;
1132
- }
1133
- }
680
+ return;
681
+ }
682
+ if (typeof content === "string" && runStep.type === "tool_calls") return;
683
+ else if (hasToolCallChunks && (chunk.tool_call_chunks?.some((tc) => tc.args === content) ?? false)) return;
684
+ else if (typeof content === "string") if (agentContext.currentTokenType === "text") await graph.dispatchMessageDelta(stepId, { content: [{
685
+ type: "text",
686
+ text: content
687
+ }] }, metadata);
688
+ else if (agentContext.currentTokenType === "think_and_text") {
689
+ const { text, thinking } = parseThinkingContent(content);
690
+ if (thinking) await graph.dispatchReasoningDelta(stepId, { content: [{
691
+ type: "think",
692
+ think: thinking
693
+ }] }, metadata);
694
+ if (text) {
695
+ agentContext.currentTokenType = "text";
696
+ agentContext.tokenTypeSwitch = "content";
697
+ const newStepKey = graph.getStepKey(metadata);
698
+ const message_id = getMessageId(newStepKey, graph) ?? "";
699
+ await graph.dispatchRunStep(newStepKey, {
700
+ type: "message_creation",
701
+ message_creation: { message_id }
702
+ }, metadata);
703
+ const newStepId = graph.getStepIdByKey(newStepKey);
704
+ await graph.dispatchMessageDelta(newStepId, { content: [{
705
+ type: "text",
706
+ text
707
+ }] }, metadata);
708
+ }
709
+ } else await graph.dispatchReasoningDelta(stepId, { content: [{
710
+ type: "think",
711
+ think: content
712
+ }] }, metadata);
713
+ else if (content.every((c) => isTextContentPart(c))) await graph.dispatchMessageDelta(stepId, { content }, metadata);
714
+ else if (content.every((c) => isReasoningContentPart(c))) await graph.dispatchReasoningDelta(stepId, { content: content.map((c) => ({
715
+ type: "think",
716
+ think: c.thinking ?? c.reasoning ?? c.reasoningText?.text ?? ""
717
+ })) }, metadata);
718
+ }
719
+ handleReasoning(chunk, agentContext) {
720
+ let reasoning_content = chunk.additional_kwargs?.[agentContext.reasoningKey];
721
+ if (Array.isArray(chunk.content) && (chunk.content[0]?.type === "thinking" || chunk.content[0]?.type === "reasoning" || chunk.content[0]?.type === "reasoning_content" || chunk.content[0]?.type === "redacted_thinking")) reasoning_content = "valid";
722
+ else if ((agentContext.provider === "openAI" || agentContext.provider === "azureOpenAI") && reasoning_content != null && typeof reasoning_content !== "string" && reasoning_content.summary?.[0]?.text != null && reasoning_content.summary[0].text) reasoning_content = "valid";
723
+ else if (agentContext.provider === "openrouter" && (chunk.content == null || chunk.content === "") && (chunk.additional_kwargs?.reasoning_details != null && Array.isArray(chunk.additional_kwargs.reasoning_details) && chunk.additional_kwargs.reasoning_details.length > 0 || typeof chunk.additional_kwargs?.reasoning === "string" && chunk.additional_kwargs.reasoning !== "" || typeof chunk.additional_kwargs?.reasoning_content === "string" && chunk.additional_kwargs.reasoning_content !== "")) reasoning_content = "valid";
724
+ if (reasoning_content != null && reasoning_content !== "" && (chunk.content == null || chunk.content === "" || reasoning_content === "valid")) {
725
+ agentContext.currentTokenType = "think";
726
+ agentContext.tokenTypeSwitch = "reasoning";
727
+ return;
728
+ } else if (agentContext.tokenTypeSwitch === "reasoning" && agentContext.currentTokenType !== "text" && (chunk.content != null && chunk.content !== "" || (chunk.tool_calls?.length ?? 0) > 0 || (chunk.tool_call_chunks?.length ?? 0) > 0)) {
729
+ agentContext.currentTokenType = "text";
730
+ agentContext.tokenTypeSwitch = "content";
731
+ agentContext.reasoningTransitionCount++;
732
+ } else if (chunk.content != null && typeof chunk.content === "string" && chunk.content.includes("<think>") && chunk.content.includes("</think>")) {
733
+ agentContext.currentTokenType = "think_and_text";
734
+ agentContext.tokenTypeSwitch = "content";
735
+ } else if (chunk.content != null && typeof chunk.content === "string" && chunk.content.includes("<think>")) {
736
+ agentContext.currentTokenType = "think";
737
+ agentContext.tokenTypeSwitch = "content";
738
+ } else if (agentContext.lastToken != null && agentContext.lastToken.includes("</think>")) {
739
+ agentContext.currentTokenType = "text";
740
+ agentContext.tokenTypeSwitch = "content";
741
+ }
742
+ if (typeof chunk.content !== "string") return;
743
+ agentContext.lastToken = chunk.content;
744
+ }
745
+ };
1134
746
  function createContentAggregator() {
1135
- const contentParts = [];
1136
- const stepMap = new Map();
1137
- const toolCallIdMap = new Map();
1138
- // Track agentId and groupId for each content index (applied to content parts)
1139
- const contentMetaMap = new Map();
1140
- const getFirstContentPart = (content) => {
1141
- if (content == null) {
1142
- return undefined;
1143
- }
1144
- return Array.isArray(content) ? content[0] : content;
1145
- };
1146
- const updateContent = (index, contentPart, finalUpdate = false) => {
1147
- if (!contentPart) {
1148
- console.warn('No content part found in \'updateContent\'');
1149
- return;
1150
- }
1151
- const partType = contentPart.type ?? '';
1152
- if (!partType) {
1153
- console.warn('No content type found in content part');
1154
- return;
1155
- }
1156
- if (!contentParts[index] && partType !== ContentTypes.TOOL_CALL) {
1157
- contentParts[index] = { type: partType };
1158
- }
1159
- if (!partType.startsWith(contentParts[index]?.type ?? '')) {
1160
- console.warn('Content type mismatch');
1161
- return;
1162
- }
1163
- if (partType.startsWith(ContentTypes.TEXT) &&
1164
- ContentTypes.TEXT in contentPart &&
1165
- typeof contentPart.text === 'string') {
1166
- // TODO: update this!!
1167
- const currentContent = contentParts[index];
1168
- const update = {
1169
- type: ContentTypes.TEXT,
1170
- text: (currentContent.text || '') + contentPart.text,
1171
- };
1172
- if (contentPart.tool_call_ids) {
1173
- update.tool_call_ids = contentPart.tool_call_ids;
1174
- }
1175
- contentParts[index] = update;
1176
- }
1177
- else if (partType.startsWith(ContentTypes.THINK) &&
1178
- ContentTypes.THINK in contentPart &&
1179
- typeof contentPart.think === 'string') {
1180
- const currentContent = contentParts[index];
1181
- const update = {
1182
- type: ContentTypes.THINK,
1183
- think: (currentContent.think || '') + contentPart.think,
1184
- };
1185
- contentParts[index] = update;
1186
- }
1187
- else if (partType.startsWith(ContentTypes.AGENT_UPDATE) &&
1188
- ContentTypes.AGENT_UPDATE in contentPart &&
1189
- contentPart.agent_update != null) {
1190
- const update = {
1191
- type: ContentTypes.AGENT_UPDATE,
1192
- agent_update: contentPart.agent_update,
1193
- };
1194
- contentParts[index] = update;
1195
- }
1196
- else if (partType === 'toolCall' || partType === 'toolResponse') {
1197
- contentParts[index] = contentPart;
1198
- }
1199
- else if (partType === ContentTypes.SUMMARY) {
1200
- const currentSummary = contentParts[index];
1201
- const incoming = contentPart;
1202
- contentParts[index] = {
1203
- ...incoming,
1204
- content: [
1205
- ...(currentSummary?.content ?? []),
1206
- ...(incoming.content ?? []),
1207
- ],
1208
- };
1209
- }
1210
- else if (partType === ContentTypes.IMAGE_URL &&
1211
- 'image_url' in contentPart) {
1212
- const currentContent = contentParts[index];
1213
- contentParts[index] = {
1214
- ...currentContent,
1215
- };
1216
- }
1217
- else if (partType === ContentTypes.TOOL_CALL &&
1218
- 'tool_call' in contentPart) {
1219
- const incomingName = contentPart.tool_call.name;
1220
- const incomingId = contentPart.tool_call.id;
1221
- const toolCallArgs = contentPart.tool_call.args;
1222
- // When we receive a tool call with a name, it's the complete tool call
1223
- // Consolidate with any previously accumulated args from chunks
1224
- const hasValidName = incomingName != null && incomingName !== '';
1225
- // Only process if incoming has a valid name (complete tool call)
1226
- // or if we're doing a final update with complete data
1227
- if (!hasValidName && !finalUpdate) {
1228
- return;
1229
- }
1230
- const existingContent = contentParts[index];
1231
- if (!finalUpdate && existingContent?.tool_call?.progress === 1) {
1232
- return;
1233
- }
1234
- /** When args are a valid object, they are likely already invoked */
1235
- let args = finalUpdate ||
1236
- typeof existingContent?.tool_call?.args === 'object' ||
1237
- typeof toolCallArgs === 'object'
1238
- ? contentPart.tool_call.args
1239
- : (existingContent?.tool_call?.args ?? '') + (toolCallArgs ?? '');
1240
- if (finalUpdate &&
1241
- args == null &&
1242
- existingContent?.tool_call?.args != null) {
1243
- args = existingContent.tool_call.args;
1244
- }
1245
- const id = getNonEmptyValue([incomingId, existingContent?.tool_call?.id]) ?? '';
1246
- const name = getNonEmptyValue([incomingName, existingContent?.tool_call?.name]) ??
1247
- '';
1248
- const newToolCall = {
1249
- id,
1250
- name,
1251
- args,
1252
- type: ToolCallTypes.TOOL_CALL,
1253
- };
1254
- const auth = contentPart.tool_call.auth ?? existingContent?.tool_call?.auth;
1255
- const expiresAt = contentPart.tool_call.expires_at ??
1256
- existingContent?.tool_call?.expires_at;
1257
- if (auth != null) {
1258
- newToolCall.auth = auth;
1259
- newToolCall.expires_at = expiresAt;
1260
- }
1261
- if (finalUpdate) {
1262
- newToolCall.progress = 1;
1263
- newToolCall.output = contentPart.tool_call.output;
1264
- }
1265
- contentParts[index] = {
1266
- type: ContentTypes.TOOL_CALL,
1267
- tool_call: newToolCall,
1268
- };
1269
- }
1270
- // Apply agentId (for MultiAgentGraph) and groupId (for parallel execution) to content parts
1271
- // - agentId present → MultiAgentGraph (show agent labels)
1272
- // - groupId present → parallel execution (render columns)
1273
- const meta = contentMetaMap.get(index);
1274
- if (meta?.agentId != null) {
1275
- contentParts[index].agentId = meta.agentId;
1276
- }
1277
- if (meta?.groupId != null) {
1278
- contentParts[index].groupId = meta.groupId;
1279
- }
1280
- };
1281
- const aggregateContent = ({ event, data, }) => {
1282
- if (event === GraphEvents.ON_SUMMARIZE_DELTA) {
1283
- const deltaData = data;
1284
- const runStep = stepMap.get(deltaData.id);
1285
- if (!runStep) {
1286
- console.warn('No run step found for summarize delta event');
1287
- return;
1288
- }
1289
- updateContent(runStep.index, deltaData.delta.summary);
1290
- return;
1291
- }
1292
- if (event === GraphEvents.ON_SUMMARIZE_COMPLETE) {
1293
- const completeData = data;
1294
- const summary = completeData.summary;
1295
- if (!summary?.boundary) {
1296
- return;
1297
- }
1298
- const runStep = stepMap.get(summary.boundary.messageId);
1299
- if (!runStep) {
1300
- return;
1301
- }
1302
- // Replace accumulated delta text with the authoritative final summary.
1303
- // Multi-stage summarization streams deltas from each chunk, which
1304
- // concatenate in updateContent. This event carries only the correct
1305
- // final text from the last stage.
1306
- contentParts[runStep.index] = summary;
1307
- return;
1308
- }
1309
- if (event === GraphEvents.ON_RUN_STEP) {
1310
- const runStep = data;
1311
- stepMap.set(runStep.id, runStep);
1312
- // Track agentId (MultiAgentGraph) and groupId (parallel execution) separately
1313
- // - agentId: present for all MultiAgentGraph runs (enables agent labels in UI)
1314
- // - groupId: present only for parallel execution (enables column rendering)
1315
- const hasAgentId = runStep.agentId != null && runStep.agentId !== '';
1316
- const hasGroupId = runStep.groupId != null;
1317
- if (hasAgentId || hasGroupId) {
1318
- const existingMeta = contentMetaMap.get(runStep.index) ?? {};
1319
- if (hasAgentId) {
1320
- existingMeta.agentId = runStep.agentId;
1321
- }
1322
- if (hasGroupId) {
1323
- existingMeta.groupId = runStep.groupId;
1324
- }
1325
- contentMetaMap.set(runStep.index, existingMeta);
1326
- }
1327
- if (runStep.summary != null) {
1328
- updateContent(runStep.index, runStep.summary);
1329
- }
1330
- if (runStep.stepDetails.type === StepTypes.TOOL_CALLS &&
1331
- runStep.stepDetails.tool_calls) {
1332
- runStep.stepDetails.tool_calls.forEach((toolCall) => {
1333
- const toolCallId = toolCall.id ?? '';
1334
- if ('id' in toolCall && toolCallId) {
1335
- toolCallIdMap.set(runStep.id, toolCallId);
1336
- }
1337
- const contentPart = {
1338
- type: ContentTypes.TOOL_CALL,
1339
- tool_call: {
1340
- args: toolCall.args,
1341
- name: toolCall.name,
1342
- id: toolCallId,
1343
- },
1344
- };
1345
- updateContent(runStep.index, contentPart);
1346
- });
1347
- }
1348
- }
1349
- else if (event === GraphEvents.ON_MESSAGE_DELTA) {
1350
- const messageDelta = data;
1351
- const runStep = stepMap.get(messageDelta.id);
1352
- if (!runStep) {
1353
- console.warn('No run step or runId found for message delta event');
1354
- return;
1355
- }
1356
- const contentPart = getFirstContentPart(messageDelta.delta.content);
1357
- if (contentPart != null) {
1358
- updateContent(runStep.index, contentPart);
1359
- }
1360
- }
1361
- else if (event === GraphEvents.ON_AGENT_UPDATE &&
1362
- data?.agent_update) {
1363
- const contentPart = data;
1364
- if (!contentPart) {
1365
- return;
1366
- }
1367
- updateContent(contentPart.agent_update.index, contentPart);
1368
- }
1369
- else if (event === GraphEvents.ON_REASONING_DELTA) {
1370
- const reasoningDelta = data;
1371
- const runStep = stepMap.get(reasoningDelta.id);
1372
- if (!runStep) {
1373
- console.warn('No run step or runId found for reasoning delta event');
1374
- return;
1375
- }
1376
- const contentPart = getFirstContentPart(reasoningDelta.delta.content);
1377
- if (contentPart != null) {
1378
- updateContent(runStep.index, contentPart);
1379
- }
1380
- }
1381
- else if (event === GraphEvents.ON_RUN_STEP_DELTA) {
1382
- const runStepDelta = data;
1383
- const runStep = stepMap.get(runStepDelta.id);
1384
- if (!runStep) {
1385
- console.warn('No run step or runId found for run step delta event');
1386
- return;
1387
- }
1388
- if (runStepDelta.delta.type === StepTypes.TOOL_CALLS &&
1389
- runStepDelta.delta.tool_calls) {
1390
- runStepDelta.delta.tool_calls.forEach((toolCallDelta) => {
1391
- const toolCallId = toolCallIdMap.get(runStepDelta.id);
1392
- const contentPart = {
1393
- type: ContentTypes.TOOL_CALL,
1394
- tool_call: {
1395
- args: toolCallDelta.args ?? '',
1396
- name: toolCallDelta.name,
1397
- id: toolCallId,
1398
- auth: runStepDelta.delta.auth,
1399
- expires_at: runStepDelta.delta.expires_at,
1400
- },
1401
- };
1402
- updateContent(runStep.index, contentPart);
1403
- });
1404
- }
1405
- }
1406
- else if (event === GraphEvents.ON_RUN_STEP_COMPLETED) {
1407
- const { result } = data;
1408
- const { id: stepId } = result;
1409
- const runStep = stepMap.get(stepId);
1410
- if (!runStep) {
1411
- console.warn('No run step or runId found for completed step event');
1412
- return;
1413
- }
1414
- if (result.type === ContentTypes.SUMMARY && 'summary' in result) {
1415
- contentParts[runStep.index] = result.summary;
1416
- }
1417
- else if ('tool_call' in result) {
1418
- const contentPart = {
1419
- type: ContentTypes.TOOL_CALL,
1420
- tool_call: result.tool_call,
1421
- };
1422
- updateContent(runStep.index, contentPart, true);
1423
- }
1424
- }
1425
- };
1426
- return { contentParts, aggregateContent, stepMap };
1427
- }
1428
-
747
+ const contentParts = [];
748
+ const stepMap = /* @__PURE__ */ new Map();
749
+ const toolCallIdMap = /* @__PURE__ */ new Map();
750
+ const contentMetaMap = /* @__PURE__ */ new Map();
751
+ const getFirstContentPart = (content) => {
752
+ if (content == null) return;
753
+ return Array.isArray(content) ? content[0] : content;
754
+ };
755
+ const updateContent = (index, contentPart, finalUpdate = false) => {
756
+ if (!contentPart) {
757
+ console.warn("No content part found in 'updateContent'");
758
+ return;
759
+ }
760
+ const partType = contentPart.type ?? "";
761
+ if (!partType) {
762
+ console.warn("No content type found in content part");
763
+ return;
764
+ }
765
+ if (!contentParts[index] && partType !== "tool_call") contentParts[index] = { type: partType };
766
+ if (!partType.startsWith(contentParts[index]?.type ?? "")) {
767
+ console.warn("Content type mismatch");
768
+ return;
769
+ }
770
+ if (partType.startsWith("text") && "text" in contentPart && typeof contentPart.text === "string") {
771
+ const update = {
772
+ type: "text",
773
+ text: (contentParts[index].text || "") + contentPart.text
774
+ };
775
+ if (contentPart.tool_call_ids) update.tool_call_ids = contentPart.tool_call_ids;
776
+ contentParts[index] = update;
777
+ } else if (partType.startsWith("think") && "think" in contentPart && typeof contentPart.think === "string") contentParts[index] = {
778
+ type: "think",
779
+ think: (contentParts[index].think || "") + contentPart.think
780
+ };
781
+ else if (partType.startsWith("agent_update") && "agent_update" in contentPart && contentPart.agent_update != null) contentParts[index] = {
782
+ type: "agent_update",
783
+ agent_update: contentPart.agent_update
784
+ };
785
+ else if (partType === "toolCall" || partType === "toolResponse") contentParts[index] = contentPart;
786
+ else if (partType === "summary") {
787
+ const currentSummary = contentParts[index];
788
+ const incoming = contentPart;
789
+ contentParts[index] = {
790
+ ...incoming,
791
+ content: [...currentSummary?.content ?? [], ...incoming.content ?? []]
792
+ };
793
+ } else if (partType === "image_url" && "image_url" in contentPart) contentParts[index] = { ...contentParts[index] };
794
+ else if (partType === "tool_call" && "tool_call" in contentPart) {
795
+ const incomingName = contentPart.tool_call.name;
796
+ const incomingId = contentPart.tool_call.id;
797
+ const toolCallArgs = contentPart.tool_call.args;
798
+ if (!(incomingName != null && incomingName !== "") && !finalUpdate) return;
799
+ const existingContent = contentParts[index];
800
+ if (!finalUpdate && existingContent?.tool_call?.progress === 1) return;
801
+ /** When args are a valid object, they are likely already invoked */
802
+ let args = finalUpdate || typeof existingContent?.tool_call?.args === "object" || typeof toolCallArgs === "object" ? contentPart.tool_call.args : (existingContent?.tool_call?.args ?? "") + (toolCallArgs ?? "");
803
+ if (finalUpdate && args == null && existingContent?.tool_call?.args != null) args = existingContent.tool_call.args;
804
+ const newToolCall = {
805
+ id: getNonEmptyValue([incomingId, existingContent?.tool_call?.id]) ?? "",
806
+ name: getNonEmptyValue([incomingName, existingContent?.tool_call?.name]) ?? "",
807
+ args,
808
+ type: "tool_call"
809
+ };
810
+ const auth = contentPart.tool_call.auth ?? existingContent?.tool_call?.auth;
811
+ const expiresAt = contentPart.tool_call.expires_at ?? existingContent?.tool_call?.expires_at;
812
+ if (auth != null) {
813
+ newToolCall.auth = auth;
814
+ newToolCall.expires_at = expiresAt;
815
+ }
816
+ if (finalUpdate) {
817
+ newToolCall.progress = 1;
818
+ newToolCall.output = contentPart.tool_call.output;
819
+ }
820
+ contentParts[index] = {
821
+ type: "tool_call",
822
+ tool_call: newToolCall
823
+ };
824
+ }
825
+ const meta = contentMetaMap.get(index);
826
+ if (meta?.agentId != null) contentParts[index].agentId = meta.agentId;
827
+ if (meta?.groupId != null) contentParts[index].groupId = meta.groupId;
828
+ };
829
+ const aggregateContent = ({ event, data }) => {
830
+ if (event === "on_summarize_delta") {
831
+ const deltaData = data;
832
+ const runStep = stepMap.get(deltaData.id);
833
+ if (!runStep) {
834
+ console.warn("No run step found for summarize delta event");
835
+ return;
836
+ }
837
+ updateContent(runStep.index, deltaData.delta.summary);
838
+ return;
839
+ }
840
+ if (event === "on_summarize_complete") {
841
+ const summary = data.summary;
842
+ if (!summary?.boundary) return;
843
+ const runStep = stepMap.get(summary.boundary.messageId);
844
+ if (!runStep) return;
845
+ contentParts[runStep.index] = summary;
846
+ return;
847
+ }
848
+ if (event === "on_run_step") {
849
+ const runStep = data;
850
+ stepMap.set(runStep.id, runStep);
851
+ const hasAgentId = runStep.agentId != null && runStep.agentId !== "";
852
+ const hasGroupId = runStep.groupId != null;
853
+ if (hasAgentId || hasGroupId) {
854
+ const existingMeta = contentMetaMap.get(runStep.index) ?? {};
855
+ if (hasAgentId) existingMeta.agentId = runStep.agentId;
856
+ if (hasGroupId) existingMeta.groupId = runStep.groupId;
857
+ contentMetaMap.set(runStep.index, existingMeta);
858
+ }
859
+ if (runStep.summary != null) updateContent(runStep.index, runStep.summary);
860
+ if (runStep.stepDetails.type === "tool_calls" && runStep.stepDetails.tool_calls) runStep.stepDetails.tool_calls.forEach((toolCall) => {
861
+ const toolCallId = toolCall.id ?? "";
862
+ if ("id" in toolCall && toolCallId) toolCallIdMap.set(runStep.id, toolCallId);
863
+ const contentPart = {
864
+ type: "tool_call",
865
+ tool_call: {
866
+ args: toolCall.args,
867
+ name: toolCall.name,
868
+ id: toolCallId
869
+ }
870
+ };
871
+ updateContent(runStep.index, contentPart);
872
+ });
873
+ } else if (event === "on_message_delta") {
874
+ const messageDelta = data;
875
+ const runStep = stepMap.get(messageDelta.id);
876
+ if (!runStep) {
877
+ console.warn("No run step or runId found for message delta event");
878
+ return;
879
+ }
880
+ const contentPart = getFirstContentPart(messageDelta.delta.content);
881
+ if (contentPart != null) updateContent(runStep.index, contentPart);
882
+ } else if (event === "on_agent_update" && data?.agent_update) {
883
+ const contentPart = data;
884
+ if (!contentPart) return;
885
+ updateContent(contentPart.agent_update.index, contentPart);
886
+ } else if (event === "on_reasoning_delta") {
887
+ const reasoningDelta = data;
888
+ const runStep = stepMap.get(reasoningDelta.id);
889
+ if (!runStep) {
890
+ console.warn("No run step or runId found for reasoning delta event");
891
+ return;
892
+ }
893
+ const contentPart = getFirstContentPart(reasoningDelta.delta.content);
894
+ if (contentPart != null) updateContent(runStep.index, contentPart);
895
+ } else if (event === "on_run_step_delta") {
896
+ const runStepDelta = data;
897
+ const runStep = stepMap.get(runStepDelta.id);
898
+ if (!runStep) {
899
+ console.warn("No run step or runId found for run step delta event");
900
+ return;
901
+ }
902
+ if (runStepDelta.delta.type === "tool_calls" && runStepDelta.delta.tool_calls) runStepDelta.delta.tool_calls.forEach((toolCallDelta) => {
903
+ const toolCallId = toolCallIdMap.get(runStepDelta.id);
904
+ const contentPart = {
905
+ type: "tool_call",
906
+ tool_call: {
907
+ args: toolCallDelta.args ?? "",
908
+ name: toolCallDelta.name,
909
+ id: toolCallId,
910
+ auth: runStepDelta.delta.auth,
911
+ expires_at: runStepDelta.delta.expires_at
912
+ }
913
+ };
914
+ updateContent(runStep.index, contentPart);
915
+ });
916
+ } else if (event === "on_run_step_completed") {
917
+ const { result } = data;
918
+ const { id: stepId } = result;
919
+ const runStep = stepMap.get(stepId);
920
+ if (!runStep) {
921
+ console.warn("No run step or runId found for completed step event");
922
+ return;
923
+ }
924
+ if (result.type === "summary" && "summary" in result) contentParts[runStep.index] = result.summary;
925
+ else if ("tool_call" in result) {
926
+ const contentPart = {
927
+ type: "tool_call",
928
+ tool_call: result.tool_call
929
+ };
930
+ updateContent(runStep.index, contentPart, true);
931
+ }
932
+ }
933
+ };
934
+ return {
935
+ contentParts,
936
+ aggregateContent,
937
+ stepMap
938
+ };
939
+ }
940
+ //#endregion
1429
941
  export { ChatModelStreamHandler, createContentAggregator, getChunkContent };
1430
- //# sourceMappingURL=stream.mjs.map
942
+
943
+ //# sourceMappingURL=stream.mjs.map