@librechat/agents 3.2.32 → 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 (573) 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 -731
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -256
  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 +305 -418
  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 -1387
  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 -725
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -253
  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 +305 -416
  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 -1383
  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/tools/search/tool.d.ts +17 -0
  545. package/dist/types/tools/search/types.d.ts +4 -0
  546. package/package.json +4 -10
  547. package/src/tools/search/highlights.ts +9 -1
  548. package/src/tools/search/search.ts +41 -3
  549. package/src/tools/search/source-processing.test.ts +373 -0
  550. package/src/tools/search/tool.ts +22 -2
  551. package/src/tools/search/types.ts +4 -0
  552. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  553. package/dist/cjs/langchain/index.cjs.map +0 -1
  554. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  555. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  556. package/dist/cjs/langchain/messages.cjs.map +0 -1
  557. package/dist/cjs/langchain/openai.cjs.map +0 -1
  558. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  559. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  560. package/dist/cjs/langchain/tools.cjs.map +0 -1
  561. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  562. package/dist/cjs/main.cjs.map +0 -1
  563. package/dist/esm/langchain/google-common.mjs.map +0 -1
  564. package/dist/esm/langchain/index.mjs.map +0 -1
  565. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  566. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  567. package/dist/esm/langchain/messages.mjs.map +0 -1
  568. package/dist/esm/langchain/openai.mjs.map +0 -1
  569. package/dist/esm/langchain/prompts.mjs.map +0 -1
  570. package/dist/esm/langchain/runnables.mjs.map +0 -1
  571. package/dist/esm/langchain/tools.mjs.map +0 -1
  572. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  573. package/dist/esm/main.mjs.map +0 -1
@@ -1,829 +1,673 @@
1
- import { nanoid } from 'nanoid';
2
- import { HumanMessage } from '@langchain/core/messages';
3
- import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
4
- import { GraphEvents, Callback, StepTypes } from '../../common/enum.mjs';
5
- import { executeHooks } from '../../hooks/executeHooks.mjs';
6
- import '../../hooks/createWorkspacePolicyHook.mjs';
7
-
1
+ import "../../common/enum.mjs";
2
+ import "../../common/index.mjs";
3
+ import { executeHooks } from "../../hooks/executeHooks.mjs";
4
+ import "../../hooks/index.mjs";
5
+ import { HumanMessage } from "@langchain/core/messages";
6
+ import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
7
+ import { nanoid } from "nanoid";
8
+ //#region src/tools/subagent/SubagentExecutor.ts
8
9
  const DEFAULT_MAX_TURNS = 25;
9
10
  const RECURSION_MULTIPLIER = 3;
10
11
  const ERROR_MESSAGE_MAX_CHARS = 200;
11
12
  const MAX_PENDING_SUBAGENT_UPDATES = 64;
12
13
  const HOOK_FALLBACK = Object.freeze({
13
- additionalContexts: [],
14
- errors: [],
14
+ additionalContexts: [],
15
+ errors: []
15
16
  });
16
- const LANGGRAPH_RUNTIME_CONFIG_PREFIX = '__pregel_';
17
+ const LANGGRAPH_RUNTIME_CONFIG_PREFIX = "__pregel_";
17
18
  const LANGGRAPH_CHECKPOINT_CONFIG_KEYS = new Set([
18
- 'checkpoint_id',
19
- 'checkpoint_map',
20
- 'checkpoint_ns',
19
+ "checkpoint_id",
20
+ "checkpoint_map",
21
+ "checkpoint_ns"
21
22
  ]);
22
- class SubagentExecutor {
23
- configs;
24
- parentSignal;
25
- hookRegistry;
26
- parentRunId;
27
- parentAgentId;
28
- langfuse;
29
- tokenCounter;
30
- maxDepth;
31
- createChildGraph;
32
- resolveParentHandlerRegistry;
33
- constructor(options) {
34
- this.configs = options.configs;
35
- this.parentSignal = options.parentSignal;
36
- this.hookRegistry = options.hookRegistry;
37
- this.parentRunId = options.parentRunId;
38
- this.parentAgentId = options.parentAgentId;
39
- this.langfuse = options.langfuse;
40
- this.tokenCounter = options.tokenCounter;
41
- this.maxDepth = options.maxDepth ?? 1;
42
- this.createChildGraph = options.createChildGraph;
43
- const rawRegistry = options.parentHandlerRegistry;
44
- if (typeof rawRegistry === 'function') {
45
- this.resolveParentHandlerRegistry = rawRegistry;
46
- }
47
- else if (rawRegistry != null) {
48
- this.resolveParentHandlerRegistry = () => rawRegistry;
49
- }
50
- }
51
- /** Snapshot of the parent's registry at the moment a subagent is dispatched. */
52
- getParentHandlerRegistry() {
53
- return this.resolveParentHandlerRegistry?.();
54
- }
55
- async execute(params) {
56
- const { description, subagentType, threadId, parentToolCallId } = params;
57
- const config = this.configs.get(subagentType);
58
- if (!config) {
59
- const available = [...this.configs.keys()].join(', ');
60
- return {
61
- content: `Error: Unknown subagent type "${subagentType}". Available types: ${available}`,
62
- messages: [],
63
- };
64
- }
65
- if (this.maxDepth <= 0) {
66
- return {
67
- content: 'Error: Maximum subagent nesting depth exceeded.',
68
- messages: [],
69
- };
70
- }
71
- const childAgentId = config.agentInputs.agentId ||
72
- `${this.parentAgentId ?? 'agent'}_sub_${nanoid(8)}`;
73
- if (this.hookRegistry?.hasHookFor('SubagentStart', this.parentRunId) === true) {
74
- const hookResult = await executeHooks({
75
- registry: this.hookRegistry,
76
- input: {
77
- hook_event_name: 'SubagentStart',
78
- runId: this.parentRunId,
79
- threadId,
80
- parentAgentId: this.parentAgentId,
81
- agentId: childAgentId,
82
- agentType: subagentType,
83
- inputs: [new HumanMessage(description)],
84
- },
85
- sessionId: this.parentRunId,
86
- matchQuery: subagentType,
87
- }).catch(() => HOOK_FALLBACK);
88
- /**
89
- * `ask` is treated identically to `deny` in the subagent context:
90
- * subagents are non-interactive, so there is no prompt path for `ask`.
91
- * Both decisions block execution and return a "Blocked" tool result.
92
- */
93
- if (hookResult.decision === 'deny' || hookResult.decision === 'ask') {
94
- return {
95
- content: `Blocked: ${hookResult.reason ?? 'Blocked by hook'}`,
96
- messages: [],
97
- };
98
- }
99
- }
100
- const parentRegistry = this.getParentHandlerRegistry();
101
- const forwardingEnabled = parentRegistry != null;
102
- /**
103
- * Keep `toolDefinitions` only when the host has actually wired an
104
- * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,
105
- * so treating any registry as "forwarding enabled" would leak
106
- * `toolDefinitions` into children whose hosts cannot execute them — the
107
- * child's `ToolNode` batch promise would hang forever with no handler to
108
- * resolve/reject. Gating on the tool-execute handler preserves the
109
- * recoverable "no tools" path for registry-but-no-handler configs.
110
- */
111
- const hasToolExecuteHandler = parentRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) != null;
112
- const childInputs = buildChildInputs(config, childAgentId, this.maxDepth,
113
- /* keepToolDefinitions */ hasToolExecuteHandler);
114
- const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;
115
- const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
116
- const childGraph = this.createChildGraph({
117
- runId: childRunId,
118
- signal: this.parentSignal,
119
- agents: [childInputs],
120
- langfuse: this.langfuse,
121
- tokenCounter: this.tokenCounter,
122
- });
123
- let forwarding;
124
- if (forwardingEnabled) {
125
- forwarding = this.createForwarderCallback({
126
- parentRegistry: parentRegistry,
127
- subagentType,
128
- subagentAgentId: childAgentId,
129
- childRunId,
130
- parentToolCallId,
131
- });
132
- }
133
- const forwarder = forwarding?.handler;
134
- if (forwarder) {
135
- await this.emitSubagentUpdate(parentRegistry, {
136
- childRunId,
137
- subagentType,
138
- subagentAgentId: childAgentId,
139
- parentToolCallId,
140
- phase: 'start',
141
- label: `Subagent "${subagentType}" started`,
142
- });
143
- }
144
- let result;
145
- try {
146
- const workflow = childGraph.createWorkflow();
147
- /**
148
- * When `parentHandlerRegistry` is provided (forwarding mode), attach a
149
- * lightweight callback that intercepts the child's `on_custom_event`
150
- * dispatches and routes them to the parent's registry — either as
151
- * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE
152
- * envelopes. Native LangChain streaming events (on_chat_model_stream,
153
- * etc.) still do NOT propagate to the parent's outer streamEvents
154
- * iterator — the `callbacks` array REPLACES the inherited chain, so
155
- * parent handlers won't receive child stream chunks and raise "No
156
- * agent context found" lookups on the parent's agentContexts map.
157
- *
158
- * When no registry is provided (legacy isolation), `callbacks: []`
159
- * fully detaches the child.
160
- *
161
- * `runName` gives the child a distinct LangSmith trace root (avoids
162
- * nested trace pollution).
163
- */
164
- const callbacks = forwarder ? [forwarder] : [];
165
- /**
166
- * Inherit the parent's host `configurable` — host-set fields
167
- * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-
168
- * identity fields (`run_id`, `parent_run_id`, `thread_id`) all
169
- * propagate. LangGraph's own runtime keys are excluded because the
170
- * child graph creates its own scratchpad/checkpoint/abort plumbing.
171
- *
172
- * Run-identity propagation is intentional and matches the
173
- * convention this executor itself already uses for `SubagentStart`
174
- * / `SubagentStop` hooks (`sessionId: this.parentRunId`): the
175
- * subagent runs under the parent's session scope, not its own.
176
- * Forwarding `run_id` / `parent_run_id` / `thread_id` makes
177
- * `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),
178
- * `ToolOutputReferenceRegistry` keying, and trace lineage all
179
- * resolve to the parent's session for tools dispatched from the
180
- * subagent — so `PreToolUse` / `PostToolUse` hooks the host
181
- * registered against the parent's run fire for subagent tool
182
- * calls too. "Same run" matches the user-perceptual mental model.
183
- *
184
- * `thread_id` falls back to `childRunId` only when the parent
185
- * didn't supply one (legacy behavior preserved for hosts that
186
- * never set thread_id).
187
- *
188
- * NOTE: a future revision will likely make this configurable per
189
- * spawn type — e.g. a background / async subagent that runs after
190
- * the parent's run completes wants isolation, not inheritance.
191
- * For now the inheritance path matches LibreChat's primary use
192
- * case (synchronous subagents within a single user turn).
193
- */
194
- const inheritedConfigurable = sanitizeChildConfigurable(params.parentConfigurable);
195
- result = await workflow.invoke({ messages: [new HumanMessage(description)] }, {
196
- recursionLimit: maxTurns * RECURSION_MULTIPLIER,
197
- signal: this.parentSignal,
198
- callbacks,
199
- runName: `subagent:${subagentType}`,
200
- configurable: {
201
- thread_id: childRunId,
202
- ...inheritedConfigurable,
203
- },
204
- });
205
- }
206
- catch (error) {
207
- const errorMessage = truncateErrorMessage(error);
208
- if (forwarding) {
209
- await forwarding.drain();
210
- await this.emitSubagentUpdate(parentRegistry, {
211
- childRunId,
212
- subagentType,
213
- subagentAgentId: childAgentId,
214
- parentToolCallId,
215
- phase: 'error',
216
- label: `Subagent "${subagentType}" errored: ${errorMessage}`,
217
- data: { message: errorMessage },
218
- });
219
- }
220
- childGraph.clearHeavyState();
221
- return {
222
- content: `Subagent error: ${errorMessage}`,
223
- messages: [],
224
- };
225
- }
226
- const filteredContent = filterSubagentResult(result.messages);
227
- if (this.hookRegistry?.hasHookFor('SubagentStop', this.parentRunId) === true) {
228
- /**
229
- * Awaited (not fire-and-forget) for deterministic test synchronization
230
- * and consistency with PostCompact. The parent is already waiting on the
231
- * tool result, so the small extra latency is acceptable. Errors are
232
- * swallowed — SubagentStop is observational.
233
- */
234
- await executeHooks({
235
- registry: this.hookRegistry,
236
- input: {
237
- hook_event_name: 'SubagentStop',
238
- runId: this.parentRunId,
239
- threadId,
240
- agentId: childAgentId,
241
- agentType: subagentType,
242
- messages: result.messages,
243
- },
244
- sessionId: this.parentRunId,
245
- matchQuery: subagentType,
246
- }).catch(() => {
247
- /* SubagentStop is observational swallow errors */
248
- });
249
- }
250
- if (forwarding) {
251
- await forwarding.drain();
252
- await this.emitSubagentUpdate(parentRegistry, {
253
- childRunId,
254
- subagentType,
255
- subagentAgentId: childAgentId,
256
- parentToolCallId,
257
- phase: 'stop',
258
- label: `Subagent "${subagentType}" finished`,
259
- });
260
- }
261
- childGraph.clearHeavyState();
262
- return { content: filteredContent, messages: result.messages };
263
- }
264
- /**
265
- * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the
266
- * parent's handler registry. Silent no-op when no parent registry is set.
267
- * Errors are swallowed — update events are observational.
268
- */
269
- async emitSubagentUpdate(parentRegistry, args) {
270
- const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);
271
- if (!handler) {
272
- return;
273
- }
274
- const event = {
275
- runId: this.parentRunId,
276
- subagentRunId: args.childRunId,
277
- subagentType: args.subagentType,
278
- subagentAgentId: args.subagentAgentId,
279
- parentAgentId: this.parentAgentId,
280
- parentToolCallId: args.parentToolCallId,
281
- phase: args.phase,
282
- data: args.data,
283
- label: args.label,
284
- timestamp: new Date().toISOString(),
285
- };
286
- try {
287
- await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);
288
- }
289
- catch {
290
- /* observational swallow */
291
- }
292
- }
293
- /**
294
- * Builds a BaseCallbackHandler that intercepts the child graph's custom
295
- * events. Routing rules:
296
- * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE
297
- * handler (so event-driven tools work identically for child and parent).
298
- * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /
299
- * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a
300
- * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable
301
- * label, delivered to the parent's subagent-update handler.
302
- * - Everything else → ignored (keeps parent's UI scoped to the events it
303
- * cares about; host apps can extend by registering more phases).
304
- */
305
- createForwarderCallback(args) {
306
- const { parentRegistry, subagentType, subagentAgentId, childRunId, parentToolCallId, } = args;
307
- const parentRunId = this.parentRunId;
308
- const parentAgentId = this.parentAgentId;
309
- const wrap = async (eventName, phase, data) => {
310
- const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);
311
- if (!handler) {
312
- return;
313
- }
314
- try {
315
- const event = {
316
- runId: parentRunId,
317
- subagentRunId: childRunId,
318
- subagentType,
319
- subagentAgentId,
320
- parentAgentId,
321
- parentToolCallId,
322
- phase,
323
- data: sanitizeForwardedSubagentUpdateData(eventName, data),
324
- label: summarizeEvent(eventName, data),
325
- timestamp: new Date().toISOString(),
326
- };
327
- await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);
328
- }
329
- catch {
330
- /* observational swallow */
331
- }
332
- };
333
- const queuedUpdates = [];
334
- let drainPromise;
335
- const enqueue = (update) => {
336
- if (queuedUpdates.length >= MAX_PENDING_SUBAGENT_UPDATES) {
337
- const dropIndex = queuedUpdates.findIndex((queued) => isDroppableSubagentUpdatePhase(queued.phase));
338
- if (dropIndex >= 0) {
339
- queuedUpdates.splice(dropIndex, 1);
340
- }
341
- else if (isDroppableSubagentUpdatePhase(update.phase)) {
342
- return;
343
- }
344
- }
345
- queuedUpdates.push(update);
346
- };
347
- const drain = async () => {
348
- if (drainPromise != null) {
349
- await drainPromise;
350
- return;
351
- }
352
- drainPromise = (async () => {
353
- while (queuedUpdates.length > 0) {
354
- const update = queuedUpdates.shift();
355
- if (update == null) {
356
- continue;
357
- }
358
- await wrap(update.eventName, update.phase, update.data);
359
- }
360
- })();
361
- try {
362
- await drainPromise;
363
- }
364
- finally {
365
- drainPromise = undefined;
366
- if (queuedUpdates.length > 0) {
367
- await drain();
368
- }
369
- }
370
- };
371
- const scheduleWrap = (eventName, phase, data) => {
372
- enqueue({ eventName, phase, data });
373
- void drain();
374
- };
375
- const handler = BaseCallbackHandler.fromMethods({
376
- [Callback.CUSTOM_EVENT]: async (eventName, data) => {
377
- if (eventName === GraphEvents.ON_TOOL_EXECUTE) {
378
- const toolHandler = parentRegistry.getHandler(GraphEvents.ON_TOOL_EXECUTE);
379
- if (toolHandler) {
380
- await toolHandler.handle(GraphEvents.ON_TOOL_EXECUTE, data);
381
- }
382
- /**
383
- * We also surface a short notice in the subagent-update stream so
384
- * the UI can show "calling <tool>" for each tool the child spawns.
385
- */
386
- scheduleWrap(eventName, 'run_step', data);
387
- return;
388
- }
389
- if (eventName === GraphEvents.ON_RUN_STEP) {
390
- scheduleWrap(eventName, 'run_step', data);
391
- return;
392
- }
393
- if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {
394
- scheduleWrap(eventName, 'run_step_delta', data);
395
- return;
396
- }
397
- if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {
398
- scheduleWrap(eventName, 'run_step_completed', data);
399
- return;
400
- }
401
- if (eventName === GraphEvents.ON_MESSAGE_DELTA) {
402
- scheduleWrap(eventName, 'message_delta', data);
403
- return;
404
- }
405
- if (eventName === GraphEvents.ON_REASONING_DELTA) {
406
- scheduleWrap(eventName, 'reasoning_delta', data);
407
- return;
408
- }
409
- },
410
- });
411
- /**
412
- * `awaitHandlers = true` is required so the child's `ToolNode` actually
413
- * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves
414
- * the batch request. Observational `ON_SUBAGENT_UPDATE` calls are queued
415
- * behind a bounded sequential dispatcher so host UI publication cannot
416
- * backpressure each child emission or run unbounded concurrent publishes.
417
- * The executor drains this queue before terminal stop/error envelopes to
418
- * preserve phase ordering.
419
- */
420
- handler.awaitHandlers = true;
421
- return { handler, drain };
422
- }
423
- }
23
+ var SubagentExecutor = class {
24
+ configs;
25
+ parentSignal;
26
+ hookRegistry;
27
+ parentRunId;
28
+ parentAgentId;
29
+ langfuse;
30
+ tokenCounter;
31
+ maxDepth;
32
+ createChildGraph;
33
+ resolveParentHandlerRegistry;
34
+ constructor(options) {
35
+ this.configs = options.configs;
36
+ this.parentSignal = options.parentSignal;
37
+ this.hookRegistry = options.hookRegistry;
38
+ this.parentRunId = options.parentRunId;
39
+ this.parentAgentId = options.parentAgentId;
40
+ this.langfuse = options.langfuse;
41
+ this.tokenCounter = options.tokenCounter;
42
+ this.maxDepth = options.maxDepth ?? 1;
43
+ this.createChildGraph = options.createChildGraph;
44
+ const rawRegistry = options.parentHandlerRegistry;
45
+ if (typeof rawRegistry === "function") this.resolveParentHandlerRegistry = rawRegistry;
46
+ else if (rawRegistry != null) this.resolveParentHandlerRegistry = () => rawRegistry;
47
+ }
48
+ /** Snapshot of the parent's registry at the moment a subagent is dispatched. */
49
+ getParentHandlerRegistry() {
50
+ return this.resolveParentHandlerRegistry?.();
51
+ }
52
+ async execute(params) {
53
+ const { description, subagentType, threadId, parentToolCallId } = params;
54
+ const config = this.configs.get(subagentType);
55
+ if (!config) return {
56
+ content: `Error: Unknown subagent type "${subagentType}". Available types: ${[...this.configs.keys()].join(", ")}`,
57
+ messages: []
58
+ };
59
+ if (this.maxDepth <= 0) return {
60
+ content: "Error: Maximum subagent nesting depth exceeded.",
61
+ messages: []
62
+ };
63
+ const childAgentId = config.agentInputs.agentId || `${this.parentAgentId ?? "agent"}_sub_${nanoid(8)}`;
64
+ if (this.hookRegistry?.hasHookFor("SubagentStart", this.parentRunId) === true) {
65
+ const hookResult = await executeHooks({
66
+ registry: this.hookRegistry,
67
+ input: {
68
+ hook_event_name: "SubagentStart",
69
+ runId: this.parentRunId,
70
+ threadId,
71
+ parentAgentId: this.parentAgentId,
72
+ agentId: childAgentId,
73
+ agentType: subagentType,
74
+ inputs: [new HumanMessage(description)]
75
+ },
76
+ sessionId: this.parentRunId,
77
+ matchQuery: subagentType
78
+ }).catch(() => HOOK_FALLBACK);
79
+ /**
80
+ * `ask` is treated identically to `deny` in the subagent context:
81
+ * subagents are non-interactive, so there is no prompt path for `ask`.
82
+ * Both decisions block execution and return a "Blocked" tool result.
83
+ */
84
+ if (hookResult.decision === "deny" || hookResult.decision === "ask") return {
85
+ content: `Blocked: ${hookResult.reason ?? "Blocked by hook"}`,
86
+ messages: []
87
+ };
88
+ }
89
+ const parentRegistry = this.getParentHandlerRegistry();
90
+ const forwardingEnabled = parentRegistry != null;
91
+ /**
92
+ * Keep `toolDefinitions` only when the host has actually wired an
93
+ * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,
94
+ * so treating any registry as "forwarding enabled" would leak
95
+ * `toolDefinitions` into children whose hosts cannot execute them — the
96
+ * child's `ToolNode` batch promise would hang forever with no handler to
97
+ * resolve/reject. Gating on the tool-execute handler preserves the
98
+ * recoverable "no tools" path for registry-but-no-handler configs.
99
+ */
100
+ const hasToolExecuteHandler = parentRegistry?.getHandler("on_tool_execute") != null;
101
+ const childInputs = buildChildInputs(config, childAgentId, this.maxDepth, hasToolExecuteHandler);
102
+ const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;
103
+ const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;
104
+ const childGraph = this.createChildGraph({
105
+ runId: childRunId,
106
+ signal: this.parentSignal,
107
+ agents: [childInputs],
108
+ langfuse: this.langfuse,
109
+ tokenCounter: this.tokenCounter
110
+ });
111
+ let forwarding;
112
+ if (forwardingEnabled) forwarding = this.createForwarderCallback({
113
+ parentRegistry,
114
+ subagentType,
115
+ subagentAgentId: childAgentId,
116
+ childRunId,
117
+ parentToolCallId
118
+ });
119
+ const forwarder = forwarding?.handler;
120
+ if (forwarder) await this.emitSubagentUpdate(parentRegistry, {
121
+ childRunId,
122
+ subagentType,
123
+ subagentAgentId: childAgentId,
124
+ parentToolCallId,
125
+ phase: "start",
126
+ label: `Subagent "${subagentType}" started`
127
+ });
128
+ let result;
129
+ try {
130
+ const workflow = childGraph.createWorkflow();
131
+ /**
132
+ * When `parentHandlerRegistry` is provided (forwarding mode), attach a
133
+ * lightweight callback that intercepts the child's `on_custom_event`
134
+ * dispatches and routes them to the parent's registry — either as
135
+ * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE
136
+ * envelopes. Native LangChain streaming events (on_chat_model_stream,
137
+ * etc.) still do NOT propagate to the parent's outer streamEvents
138
+ * iterator — the `callbacks` array REPLACES the inherited chain, so
139
+ * parent handlers won't receive child stream chunks and raise "No
140
+ * agent context found" lookups on the parent's agentContexts map.
141
+ *
142
+ * When no registry is provided (legacy isolation), `callbacks: []`
143
+ * fully detaches the child.
144
+ *
145
+ * `runName` gives the child a distinct LangSmith trace root (avoids
146
+ * nested trace pollution).
147
+ */
148
+ const callbacks = forwarder ? [forwarder] : [];
149
+ /**
150
+ * Inherit the parent's host `configurable` — host-set fields
151
+ * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-
152
+ * identity fields (`run_id`, `parent_run_id`, `thread_id`) all
153
+ * propagate. LangGraph's own runtime keys are excluded because the
154
+ * child graph creates its own scratchpad/checkpoint/abort plumbing.
155
+ *
156
+ * Run-identity propagation is intentional and matches the
157
+ * convention this executor itself already uses for `SubagentStart`
158
+ * / `SubagentStop` hooks (`sessionId: this.parentRunId`): the
159
+ * subagent runs under the parent's session scope, not its own.
160
+ * Forwarding `run_id` / `parent_run_id` / `thread_id` makes
161
+ * `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),
162
+ * `ToolOutputReferenceRegistry` keying, and trace lineage all
163
+ * resolve to the parent's session for tools dispatched from the
164
+ * subagent — so `PreToolUse` / `PostToolUse` hooks the host
165
+ * registered against the parent's run fire for subagent tool
166
+ * calls too. "Same run" matches the user-perceptual mental model.
167
+ *
168
+ * `thread_id` falls back to `childRunId` only when the parent
169
+ * didn't supply one (legacy behavior preserved for hosts that
170
+ * never set thread_id).
171
+ *
172
+ * NOTE: a future revision will likely make this configurable per
173
+ * spawn type e.g. a background / async subagent that runs after
174
+ * the parent's run completes wants isolation, not inheritance.
175
+ * For now the inheritance path matches LibreChat's primary use
176
+ * case (synchronous subagents within a single user turn).
177
+ */
178
+ const inheritedConfigurable = sanitizeChildConfigurable(params.parentConfigurable);
179
+ result = await workflow.invoke({ messages: [new HumanMessage(description)] }, {
180
+ recursionLimit: maxTurns * RECURSION_MULTIPLIER,
181
+ signal: this.parentSignal,
182
+ callbacks,
183
+ runName: `subagent:${subagentType}`,
184
+ configurable: {
185
+ thread_id: childRunId,
186
+ ...inheritedConfigurable
187
+ }
188
+ });
189
+ } catch (error) {
190
+ const errorMessage = truncateErrorMessage(error);
191
+ if (forwarding) {
192
+ await forwarding.drain();
193
+ await this.emitSubagentUpdate(parentRegistry, {
194
+ childRunId,
195
+ subagentType,
196
+ subagentAgentId: childAgentId,
197
+ parentToolCallId,
198
+ phase: "error",
199
+ label: `Subagent "${subagentType}" errored: ${errorMessage}`,
200
+ data: { message: errorMessage }
201
+ });
202
+ }
203
+ childGraph.clearHeavyState();
204
+ return {
205
+ content: `Subagent error: ${errorMessage}`,
206
+ messages: []
207
+ };
208
+ }
209
+ const filteredContent = filterSubagentResult(result.messages);
210
+ if (this.hookRegistry?.hasHookFor("SubagentStop", this.parentRunId) === true)
211
+ /**
212
+ * Awaited (not fire-and-forget) for deterministic test synchronization
213
+ * and consistency with PostCompact. The parent is already waiting on the
214
+ * tool result, so the small extra latency is acceptable. Errors are
215
+ * swallowed — SubagentStop is observational.
216
+ */
217
+ await executeHooks({
218
+ registry: this.hookRegistry,
219
+ input: {
220
+ hook_event_name: "SubagentStop",
221
+ runId: this.parentRunId,
222
+ threadId,
223
+ agentId: childAgentId,
224
+ agentType: subagentType,
225
+ messages: result.messages
226
+ },
227
+ sessionId: this.parentRunId,
228
+ matchQuery: subagentType
229
+ }).catch(() => {});
230
+ if (forwarding) {
231
+ await forwarding.drain();
232
+ await this.emitSubagentUpdate(parentRegistry, {
233
+ childRunId,
234
+ subagentType,
235
+ subagentAgentId: childAgentId,
236
+ parentToolCallId,
237
+ phase: "stop",
238
+ label: `Subagent "${subagentType}" finished`
239
+ });
240
+ }
241
+ childGraph.clearHeavyState();
242
+ return {
243
+ content: filteredContent,
244
+ messages: result.messages
245
+ };
246
+ }
247
+ /**
248
+ * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the
249
+ * parent's handler registry. Silent no-op when no parent registry is set.
250
+ * Errors are swallowed — update events are observational.
251
+ */
252
+ async emitSubagentUpdate(parentRegistry, args) {
253
+ const handler = parentRegistry.getHandler("on_subagent_update");
254
+ if (!handler) return;
255
+ const event = {
256
+ runId: this.parentRunId,
257
+ subagentRunId: args.childRunId,
258
+ subagentType: args.subagentType,
259
+ subagentAgentId: args.subagentAgentId,
260
+ parentAgentId: this.parentAgentId,
261
+ parentToolCallId: args.parentToolCallId,
262
+ phase: args.phase,
263
+ data: args.data,
264
+ label: args.label,
265
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
266
+ };
267
+ try {
268
+ await handler.handle("on_subagent_update", event);
269
+ } catch {}
270
+ }
271
+ /**
272
+ * Builds a BaseCallbackHandler that intercepts the child graph's custom
273
+ * events. Routing rules:
274
+ * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE
275
+ * handler (so event-driven tools work identically for child and parent).
276
+ * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /
277
+ * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a
278
+ * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable
279
+ * label, delivered to the parent's subagent-update handler.
280
+ * - Everything else → ignored (keeps parent's UI scoped to the events it
281
+ * cares about; host apps can extend by registering more phases).
282
+ */
283
+ createForwarderCallback(args) {
284
+ const { parentRegistry, subagentType, subagentAgentId, childRunId, parentToolCallId } = args;
285
+ const parentRunId = this.parentRunId;
286
+ const parentAgentId = this.parentAgentId;
287
+ const wrap = async (eventName, phase, data) => {
288
+ const handler = parentRegistry.getHandler("on_subagent_update");
289
+ if (!handler) return;
290
+ try {
291
+ const event = {
292
+ runId: parentRunId,
293
+ subagentRunId: childRunId,
294
+ subagentType,
295
+ subagentAgentId,
296
+ parentAgentId,
297
+ parentToolCallId,
298
+ phase,
299
+ data: sanitizeForwardedSubagentUpdateData(eventName, data),
300
+ label: summarizeEvent(eventName, data),
301
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
302
+ };
303
+ await handler.handle("on_subagent_update", event);
304
+ } catch {}
305
+ };
306
+ const queuedUpdates = [];
307
+ let drainPromise;
308
+ const enqueue = (update) => {
309
+ if (queuedUpdates.length >= MAX_PENDING_SUBAGENT_UPDATES) {
310
+ const dropIndex = queuedUpdates.findIndex((queued) => isDroppableSubagentUpdatePhase(queued.phase));
311
+ if (dropIndex >= 0) queuedUpdates.splice(dropIndex, 1);
312
+ else if (isDroppableSubagentUpdatePhase(update.phase)) return;
313
+ }
314
+ queuedUpdates.push(update);
315
+ };
316
+ const drain = async () => {
317
+ if (drainPromise != null) {
318
+ await drainPromise;
319
+ return;
320
+ }
321
+ drainPromise = (async () => {
322
+ while (queuedUpdates.length > 0) {
323
+ const update = queuedUpdates.shift();
324
+ if (update == null) continue;
325
+ await wrap(update.eventName, update.phase, update.data);
326
+ }
327
+ })();
328
+ try {
329
+ await drainPromise;
330
+ } finally {
331
+ drainPromise = void 0;
332
+ if (queuedUpdates.length > 0) await drain();
333
+ }
334
+ };
335
+ const scheduleWrap = (eventName, phase, data) => {
336
+ enqueue({
337
+ eventName,
338
+ phase,
339
+ data
340
+ });
341
+ drain();
342
+ };
343
+ const handler = BaseCallbackHandler.fromMethods({ ["handleCustomEvent"]: async (eventName, data) => {
344
+ if (eventName === "on_tool_execute") {
345
+ const toolHandler = parentRegistry.getHandler("on_tool_execute");
346
+ if (toolHandler) await toolHandler.handle("on_tool_execute", data);
347
+ /**
348
+ * We also surface a short notice in the subagent-update stream so
349
+ * the UI can show "calling <tool>" for each tool the child spawns.
350
+ */
351
+ scheduleWrap(eventName, "run_step", data);
352
+ return;
353
+ }
354
+ if (eventName === "on_run_step") {
355
+ scheduleWrap(eventName, "run_step", data);
356
+ return;
357
+ }
358
+ if (eventName === "on_run_step_delta") {
359
+ scheduleWrap(eventName, "run_step_delta", data);
360
+ return;
361
+ }
362
+ if (eventName === "on_run_step_completed") {
363
+ scheduleWrap(eventName, "run_step_completed", data);
364
+ return;
365
+ }
366
+ if (eventName === "on_message_delta") {
367
+ scheduleWrap(eventName, "message_delta", data);
368
+ return;
369
+ }
370
+ if (eventName === "on_reasoning_delta") {
371
+ scheduleWrap(eventName, "reasoning_delta", data);
372
+ return;
373
+ }
374
+ } });
375
+ /**
376
+ * `awaitHandlers = true` is required so the child's `ToolNode` actually
377
+ * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves
378
+ * the batch request. Observational `ON_SUBAGENT_UPDATE` calls are queued
379
+ * behind a bounded sequential dispatcher so host UI publication cannot
380
+ * backpressure each child emission or run unbounded concurrent publishes.
381
+ * The executor drains this queue before terminal stop/error envelopes to
382
+ * preserve phase ordering.
383
+ */
384
+ handler.awaitHandlers = true;
385
+ return {
386
+ handler,
387
+ drain
388
+ };
389
+ }
390
+ };
424
391
  function sanitizeChildConfigurable(parentConfigurable) {
425
- if (parentConfigurable == null) {
426
- return {};
427
- }
428
- return Object.fromEntries(Object.entries(parentConfigurable).filter(([key]) => !isLangGraphRuntimeConfigKey(key)));
392
+ if (parentConfigurable == null) return {};
393
+ return Object.fromEntries(Object.entries(parentConfigurable).filter(([key]) => !isLangGraphRuntimeConfigKey(key)));
429
394
  }
430
395
  function isLangGraphRuntimeConfigKey(key) {
431
- return (key.startsWith(LANGGRAPH_RUNTIME_CONFIG_PREFIX) ||
432
- LANGGRAPH_CHECKPOINT_CONFIG_KEYS.has(key));
396
+ return key.startsWith(LANGGRAPH_RUNTIME_CONFIG_PREFIX) || LANGGRAPH_CHECKPOINT_CONFIG_KEYS.has(key);
433
397
  }
434
398
  function sanitizeForwardedSubagentUpdateData(eventName, data) {
435
- if (eventName === GraphEvents.ON_TOOL_EXECUTE) {
436
- return sanitizeToolExecuteUpdateData(data);
437
- }
438
- if (eventName === GraphEvents.ON_RUN_STEP) {
439
- return sanitizeRunStepUpdateData(data);
440
- }
441
- if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {
442
- return sanitizeRunStepDeltaUpdateData(data);
443
- }
444
- if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {
445
- return sanitizeRunStepCompletedUpdateData(data);
446
- }
447
- if (eventName === GraphEvents.ON_MESSAGE_DELTA) {
448
- return sanitizeMessageDeltaUpdateData(data);
449
- }
450
- if (eventName === GraphEvents.ON_REASONING_DELTA) {
451
- return sanitizeReasoningDeltaUpdateData(data);
452
- }
453
- return undefined;
399
+ if (eventName === "on_tool_execute") return sanitizeToolExecuteUpdateData(data);
400
+ if (eventName === "on_run_step") return sanitizeRunStepUpdateData(data);
401
+ if (eventName === "on_run_step_delta") return sanitizeRunStepDeltaUpdateData(data);
402
+ if (eventName === "on_run_step_completed") return sanitizeRunStepCompletedUpdateData(data);
403
+ if (eventName === "on_message_delta") return sanitizeMessageDeltaUpdateData(data);
404
+ if (eventName === "on_reasoning_delta") return sanitizeReasoningDeltaUpdateData(data);
454
405
  }
455
406
  function isDroppableSubagentUpdatePhase(phase) {
456
- return (phase === 'message_delta' ||
457
- phase === 'reasoning_delta' ||
458
- phase === 'run_step_delta');
407
+ return phase === "message_delta" || phase === "reasoning_delta" || phase === "run_step_delta";
459
408
  }
460
409
  function sanitizeToolExecuteUpdateData(data) {
461
- const request = data;
462
- const toolCalls = Array.isArray(request.toolCalls)
463
- ? request.toolCalls.map(sanitizeToolCallForUpdate)
464
- : [];
465
- const sanitized = { toolCalls };
466
- if (typeof request.agentId === 'string') {
467
- sanitized.agentId = request.agentId;
468
- }
469
- return sanitized;
410
+ const request = data;
411
+ const sanitized = { toolCalls: Array.isArray(request.toolCalls) ? request.toolCalls.map(sanitizeToolCallForUpdate) : [] };
412
+ if (typeof request.agentId === "string") sanitized.agentId = request.agentId;
413
+ return sanitized;
470
414
  }
471
415
  function sanitizeToolCallForUpdate(call) {
472
- const sanitized = {
473
- id: call.id,
474
- name: call.name,
475
- args: call.args,
476
- };
477
- return sanitized;
416
+ return {
417
+ id: call.id,
418
+ name: call.name,
419
+ args: call.args
420
+ };
478
421
  }
479
422
  function sanitizeRunStepUpdateData(data) {
480
- if (!isObjectLike(data)) {
481
- return undefined;
482
- }
483
- const step = data;
484
- const sanitized = {};
485
- assignString(sanitized, 'agentId', step.agentId);
486
- assignNumber(sanitized, 'groupId', step.groupId);
487
- assignString(sanitized, 'id', step.id);
488
- assignNumber(sanitized, 'index', step.index);
489
- assignString(sanitized, 'runId', step.runId);
490
- assignNumber(sanitized, 'stepIndex', step.stepIndex);
491
- assignString(sanitized, 'type', step.type);
492
- if (step.summary !== undefined) {
493
- sanitized.summary = step.summary;
494
- }
495
- if (step.usage !== undefined) {
496
- sanitized.usage = step.usage;
497
- }
498
- sanitized.stepDetails = sanitizeStepDetails(step.stepDetails);
499
- return sanitized;
423
+ if (!isObjectLike(data)) return;
424
+ const step = data;
425
+ const sanitized = {};
426
+ assignString(sanitized, "agentId", step.agentId);
427
+ assignNumber(sanitized, "groupId", step.groupId);
428
+ assignString(sanitized, "id", step.id);
429
+ assignNumber(sanitized, "index", step.index);
430
+ assignString(sanitized, "runId", step.runId);
431
+ assignNumber(sanitized, "stepIndex", step.stepIndex);
432
+ assignString(sanitized, "type", step.type);
433
+ if (step.summary !== void 0) sanitized.summary = step.summary;
434
+ if (step.usage !== void 0) sanitized.usage = step.usage;
435
+ sanitized.stepDetails = sanitizeStepDetails(step.stepDetails);
436
+ return sanitized;
500
437
  }
501
438
  function sanitizeRunStepDeltaUpdateData(data) {
502
- if (!isObjectLike(data)) {
503
- return undefined;
504
- }
505
- const event = data;
506
- const sanitized = {};
507
- assignString(sanitized, 'id', event.id);
508
- sanitized.delta = sanitizeToolCallDelta(event.delta);
509
- return sanitized;
439
+ if (!isObjectLike(data)) return;
440
+ const event = data;
441
+ const sanitized = {};
442
+ assignString(sanitized, "id", event.id);
443
+ sanitized.delta = sanitizeToolCallDelta(event.delta);
444
+ return sanitized;
510
445
  }
511
446
  function sanitizeRunStepCompletedUpdateData(data) {
512
- if (!isObjectLike(data)) {
513
- return undefined;
514
- }
515
- const event = data;
516
- return { result: sanitizeStepCompleted(event.result) };
447
+ if (!isObjectLike(data)) return;
448
+ return { result: sanitizeStepCompleted(data.result) };
517
449
  }
518
450
  function sanitizeMessageDeltaUpdateData(data) {
519
- if (!isObjectLike(data)) {
520
- return undefined;
521
- }
522
- const event = data;
523
- const sanitized = {};
524
- assignString(sanitized, 'id', event.id);
525
- if (event.delta != null) {
526
- sanitized.delta = {};
527
- if (event.delta.content !== undefined) {
528
- sanitized.delta.content = event.delta.content;
529
- }
530
- if (event.delta.tool_call_ids !== undefined) {
531
- sanitized.delta.tool_call_ids = event.delta.tool_call_ids;
532
- }
533
- }
534
- return sanitized;
451
+ if (!isObjectLike(data)) return;
452
+ const event = data;
453
+ const sanitized = {};
454
+ assignString(sanitized, "id", event.id);
455
+ if (event.delta != null) {
456
+ sanitized.delta = {};
457
+ if (event.delta.content !== void 0) sanitized.delta.content = event.delta.content;
458
+ if (event.delta.tool_call_ids !== void 0) sanitized.delta.tool_call_ids = event.delta.tool_call_ids;
459
+ }
460
+ return sanitized;
535
461
  }
536
462
  function sanitizeReasoningDeltaUpdateData(data) {
537
- if (!isObjectLike(data)) {
538
- return undefined;
539
- }
540
- const event = data;
541
- const sanitized = {};
542
- assignString(sanitized, 'id', event.id);
543
- if (event.delta?.content !== undefined) {
544
- sanitized.delta = { content: event.delta.content };
545
- }
546
- return sanitized;
463
+ if (!isObjectLike(data)) return;
464
+ const event = data;
465
+ const sanitized = {};
466
+ assignString(sanitized, "id", event.id);
467
+ if (event.delta?.content !== void 0) sanitized.delta = { content: event.delta.content };
468
+ return sanitized;
547
469
  }
548
470
  function sanitizeStepDetails(stepDetails) {
549
- if (!isObjectLike(stepDetails)) {
550
- return undefined;
551
- }
552
- const rawDetails = stepDetails;
553
- if (rawDetails.type === StepTypes.MESSAGE_CREATION) {
554
- const sanitized = {
555
- type: StepTypes.MESSAGE_CREATION,
556
- };
557
- const messageId = rawDetails.message_creation?.message_id;
558
- if (typeof messageId === 'string') {
559
- sanitized.message_creation = { message_id: messageId };
560
- }
561
- return sanitized;
562
- }
563
- if (rawDetails.type === StepTypes.TOOL_CALLS) {
564
- const sanitized = {
565
- type: StepTypes.TOOL_CALLS,
566
- };
567
- if (Array.isArray(rawDetails.tool_calls)) {
568
- sanitized.tool_calls = rawDetails.tool_calls.map(sanitizeAgentToolCall);
569
- }
570
- return sanitized;
571
- }
572
- return undefined;
471
+ if (!isObjectLike(stepDetails)) return;
472
+ const rawDetails = stepDetails;
473
+ if (rawDetails.type === "message_creation") {
474
+ const sanitized = { type: "message_creation" };
475
+ const messageId = rawDetails.message_creation?.message_id;
476
+ if (typeof messageId === "string") sanitized.message_creation = { message_id: messageId };
477
+ return sanitized;
478
+ }
479
+ if (rawDetails.type === "tool_calls") {
480
+ const sanitized = { type: "tool_calls" };
481
+ if (Array.isArray(rawDetails.tool_calls)) sanitized.tool_calls = rawDetails.tool_calls.map(sanitizeAgentToolCall);
482
+ return sanitized;
483
+ }
573
484
  }
574
485
  function sanitizeToolCallDelta(delta) {
575
- if (!isObjectLike(delta)) {
576
- return undefined;
577
- }
578
- const sanitized = {};
579
- assignString(sanitized, 'auth', delta.auth);
580
- assignNumber(sanitized, 'expires_at', delta.expires_at);
581
- assignString(sanitized, 'type', delta.type);
582
- if (delta.summary !== undefined) {
583
- sanitized.summary = delta.summary;
584
- }
585
- if (Array.isArray(delta.tool_calls)) {
586
- sanitized.tool_calls = delta.tool_calls.map(sanitizeAgentToolCall);
587
- }
588
- return sanitized;
486
+ if (!isObjectLike(delta)) return;
487
+ const sanitized = {};
488
+ assignString(sanitized, "auth", delta.auth);
489
+ assignNumber(sanitized, "expires_at", delta.expires_at);
490
+ assignString(sanitized, "type", delta.type);
491
+ if (delta.summary !== void 0) sanitized.summary = delta.summary;
492
+ if (Array.isArray(delta.tool_calls)) sanitized.tool_calls = delta.tool_calls.map(sanitizeAgentToolCall);
493
+ return sanitized;
589
494
  }
590
495
  function sanitizeStepCompleted(data) {
591
- if (!isObjectLike(data)) {
592
- return undefined;
593
- }
594
- const completed = data;
595
- if (completed.type === 'summary') {
596
- return {
597
- type: 'summary',
598
- summary: completed.summary,
599
- };
600
- }
601
- if (completed.type !== 'tool_call') {
602
- return undefined;
603
- }
604
- const sanitized = { type: 'tool_call' };
605
- assignString(sanitized, 'id', completed.id);
606
- assignNumber(sanitized, 'index', completed.index);
607
- sanitized.tool_call = sanitizeProcessedToolCall(completed.tool_call);
608
- return sanitized;
496
+ if (!isObjectLike(data)) return;
497
+ const completed = data;
498
+ if (completed.type === "summary") return {
499
+ type: "summary",
500
+ summary: completed.summary
501
+ };
502
+ if (completed.type !== "tool_call") return;
503
+ const sanitized = { type: "tool_call" };
504
+ assignString(sanitized, "id", completed.id);
505
+ assignNumber(sanitized, "index", completed.index);
506
+ sanitized.tool_call = sanitizeProcessedToolCall(completed.tool_call);
507
+ return sanitized;
609
508
  }
610
509
  function sanitizeProcessedToolCall(toolCall) {
611
- if (!isObjectLike(toolCall)) {
612
- return undefined;
613
- }
614
- const call = toolCall;
615
- const sanitized = {};
616
- assignString(sanitized, 'id', call.id);
617
- assignString(sanitized, 'name', call.name);
618
- if (call.args !== undefined) {
619
- sanitized.args = call.args;
620
- }
621
- assignString(sanitized, 'output', call.output);
622
- assignNumber(sanitized, 'progress', call.progress);
623
- return sanitized;
510
+ if (!isObjectLike(toolCall)) return;
511
+ const call = toolCall;
512
+ const sanitized = {};
513
+ assignString(sanitized, "id", call.id);
514
+ assignString(sanitized, "name", call.name);
515
+ if (call.args !== void 0) sanitized.args = call.args;
516
+ assignString(sanitized, "output", call.output);
517
+ assignNumber(sanitized, "progress", call.progress);
518
+ return sanitized;
624
519
  }
625
520
  function sanitizeAgentToolCall(toolCall) {
626
- if (!isObjectLike(toolCall)) {
627
- return {};
628
- }
629
- const call = toolCall;
630
- const sanitized = {};
631
- assignString(sanitized, 'id', call.id);
632
- assignString(sanitized, 'name', call.name);
633
- assignString(sanitized, 'type', call.type);
634
- if (call.args !== undefined) {
635
- sanitized.args = call.args;
636
- }
637
- if (isObjectLike(call.function)) {
638
- const fn = {};
639
- assignString(fn, 'name', call.function.name);
640
- if (typeof call.function.arguments === 'string' ||
641
- isObjectLike(call.function.arguments)) {
642
- fn.arguments = call.function.arguments;
643
- }
644
- sanitized.function = fn;
645
- }
646
- return sanitized;
521
+ if (!isObjectLike(toolCall)) return {};
522
+ const call = toolCall;
523
+ const sanitized = {};
524
+ assignString(sanitized, "id", call.id);
525
+ assignString(sanitized, "name", call.name);
526
+ assignString(sanitized, "type", call.type);
527
+ if (call.args !== void 0) sanitized.args = call.args;
528
+ if (isObjectLike(call.function)) {
529
+ const fn = {};
530
+ assignString(fn, "name", call.function.name);
531
+ if (typeof call.function.arguments === "string" || isObjectLike(call.function.arguments)) fn.arguments = call.function.arguments;
532
+ sanitized.function = fn;
533
+ }
534
+ return sanitized;
647
535
  }
648
536
  function isObjectLike(value) {
649
- return value != null && typeof value === 'object' && !Array.isArray(value);
537
+ return value != null && typeof value === "object" && !Array.isArray(value);
650
538
  }
651
539
  function assignString(target, key, value) {
652
- if (typeof value === 'string') {
653
- target[key] = value;
654
- }
540
+ if (typeof value === "string") target[key] = value;
655
541
  }
656
542
  function assignNumber(target, key, value) {
657
- if (typeof value === 'number') {
658
- target[key] = value;
659
- }
543
+ if (typeof value === "number") target[key] = value;
660
544
  }
661
545
  /**
662
- * Produces a short single-line label for an arbitrary forwarded child event.
663
- * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show
664
- * a compact status ticker without parsing the raw payload.
665
- */
546
+ * Produces a short single-line label for an arbitrary forwarded child event.
547
+ * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show
548
+ * a compact status ticker without parsing the raw payload.
549
+ */
666
550
  function summarizeEvent(eventName, data) {
667
- if (eventName === GraphEvents.ON_TOOL_EXECUTE) {
668
- const req = data;
669
- const names = (req.toolCalls ?? [])
670
- .map((c) => c.name)
671
- .filter((n) => typeof n === 'string');
672
- return names.length > 0 ? `Calling ${names.join(', ')}` : 'Calling tool';
673
- }
674
- if (eventName === GraphEvents.ON_RUN_STEP) {
675
- const step = data;
676
- const detailType = step.stepDetails?.type ?? step.type ?? 'step';
677
- if (detailType === 'tool_calls') {
678
- const names = (step.stepDetails?.tool_calls ?? [])
679
- .map((c) => c.name)
680
- .filter((n) => typeof n === 'string');
681
- return names.length > 0
682
- ? `Using tool: ${names.join(', ')}`
683
- : 'Planning tool call';
684
- }
685
- if (detailType === 'message_creation') {
686
- return 'Thinking';
687
- }
688
- return `Step: ${detailType}`;
689
- }
690
- if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {
691
- const step = data;
692
- const tool = step.result?.tool_call;
693
- if (tool?.name != null && tool.name !== '') {
694
- return `Tool ${tool.name} complete`;
695
- }
696
- return 'Step complete';
697
- }
698
- if (eventName === GraphEvents.ON_MESSAGE_DELTA) {
699
- return 'Streaming…';
700
- }
701
- return eventName;
551
+ if (eventName === "on_tool_execute") {
552
+ const names = (data.toolCalls ?? []).map((c) => c.name).filter((n) => typeof n === "string");
553
+ return names.length > 0 ? `Calling ${names.join(", ")}` : "Calling tool";
554
+ }
555
+ if (eventName === "on_run_step") {
556
+ const step = data;
557
+ const detailType = step.stepDetails?.type ?? step.type ?? "step";
558
+ if (detailType === "tool_calls") {
559
+ const names = (step.stepDetails?.tool_calls ?? []).map((c) => c.name).filter((n) => typeof n === "string");
560
+ return names.length > 0 ? `Using tool: ${names.join(", ")}` : "Planning tool call";
561
+ }
562
+ if (detailType === "message_creation") return "Thinking…";
563
+ return `Step: ${detailType}`;
564
+ }
565
+ if (eventName === "on_run_step_completed") {
566
+ const tool = data.result?.tool_call;
567
+ if (tool?.name != null && tool.name !== "") return `Tool ${tool.name} complete`;
568
+ return "Step complete";
569
+ }
570
+ if (eventName === "on_message_delta") return "Streaming";
571
+ return eventName;
702
572
  }
703
573
  /**
704
- * Walk messages from last to first, returning the text content of the most
705
- * recent AIMessage that has any. Non-text blocks (tool_use, thinking,
706
- * redacted_thinking, tool_result) are stripped. If the last AIMessage is
707
- * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk
708
- * continues to earlier AIMessages so partial progress is salvaged — this
709
- * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.
710
- * Returns "Task completed" only when no AIMessage in the history contains
711
- * any text.
712
- */
574
+ * Walk messages from last to first, returning the text content of the most
575
+ * recent AIMessage that has any. Non-text blocks (tool_use, thinking,
576
+ * redacted_thinking, tool_result) are stripped. If the last AIMessage is
577
+ * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk
578
+ * continues to earlier AIMessages so partial progress is salvaged — this
579
+ * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.
580
+ * Returns "Task completed" only when no AIMessage in the history contains
581
+ * any text.
582
+ */
713
583
  function filterSubagentResult(messages) {
714
- for (let i = messages.length - 1; i >= 0; i--) {
715
- if (messages[i]._getType() !== 'ai') {
716
- continue;
717
- }
718
- const content = messages[i].content;
719
- if (typeof content === 'string') {
720
- if (content)
721
- return content;
722
- continue;
723
- }
724
- if (!Array.isArray(content)) {
725
- continue;
726
- }
727
- const textParts = [];
728
- for (const block of content) {
729
- if (typeof block === 'string') {
730
- textParts.push(block);
731
- }
732
- else if ('type' in block && block.type === 'text' && 'text' in block) {
733
- textParts.push(block.text);
734
- }
735
- }
736
- if (textParts.length > 0) {
737
- return textParts.join('\n');
738
- }
739
- }
740
- return 'Task completed';
584
+ for (let i = messages.length - 1; i >= 0; i--) {
585
+ if (messages[i]._getType() !== "ai") continue;
586
+ const content = messages[i].content;
587
+ if (typeof content === "string") {
588
+ if (content) return content;
589
+ continue;
590
+ }
591
+ if (!Array.isArray(content)) continue;
592
+ const textParts = [];
593
+ for (const block of content) if (typeof block === "string") textParts.push(block);
594
+ else if ("type" in block && block.type === "text" && "text" in block) textParts.push(block.text);
595
+ if (textParts.length > 0) return textParts.join("\n");
596
+ }
597
+ return "Task completed";
741
598
  }
742
599
  /**
743
- * Resolve self-spawn configs by filling in agentInputs from the parent context.
744
- * Returns configs with agentInputs guaranteed present. Throws on duplicate
745
- * `type` values to prevent silent config shadowing.
746
- */
600
+ * Resolve self-spawn configs by filling in agentInputs from the parent context.
601
+ * Returns configs with agentInputs guaranteed present. Throws on duplicate
602
+ * `type` values to prevent silent config shadowing.
603
+ */
747
604
  function resolveSubagentConfigs(configs, parentContext) {
748
- const resolved = configs
749
- .map((config) => {
750
- if (config.agentInputs != null) {
751
- return config;
752
- }
753
- if (config.self !== true || parentContext._sourceInputs == null) {
754
- return null;
755
- }
756
- return {
757
- ...config,
758
- agentInputs: { ...parentContext._sourceInputs },
759
- };
760
- })
761
- .filter((c) => c != null);
762
- const seenTypes = new Set();
763
- for (const config of resolved) {
764
- if (seenTypes.has(config.type)) {
765
- throw new Error(`Duplicate subagent type "${config.type}". Each SubagentConfig must have a unique "type" field.`);
766
- }
767
- seenTypes.add(config.type);
768
- }
769
- return resolved;
605
+ const resolved = configs.map((config) => {
606
+ if (config.agentInputs != null) return config;
607
+ if (config.self !== true || parentContext._sourceInputs == null) return null;
608
+ return {
609
+ ...config,
610
+ agentInputs: { ...parentContext._sourceInputs }
611
+ };
612
+ }).filter((c) => c != null);
613
+ const seenTypes = /* @__PURE__ */ new Set();
614
+ for (const config of resolved) {
615
+ if (seenTypes.has(config.type)) throw new Error(`Duplicate subagent type "${config.type}". Each SubagentConfig must have a unique "type" field.`);
616
+ seenTypes.add(config.type);
617
+ }
618
+ return resolved;
770
619
  }
771
620
  /**
772
- * Build child AgentInputs from a resolved config, stripping nesting and
773
- * (optionally) event-driven fields. When `allowNested: true`, the child's
774
- * `maxSubagentDepth` is decremented so that depth is consumed as the call
775
- * chain deepens across graph boundaries — the parent's executor-level check
776
- * alone cannot see into the child graph's separate executor.
777
- *
778
- * When `keepToolDefinitions` is `true`, the child retains the parent's
779
- * `toolDefinitions` so event-driven tools remain usable. This is only safe
780
- * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a
781
- * registered handler — otherwise the child will hang on tool dispatch.
782
- *
783
- * @remarks Advanced utility: exported primarily for testing and by
784
- * {@link SubagentExecutor}. Host applications configuring subagents should
785
- * not need to call this directly — it is invoked internally when a subagent
786
- * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,
787
- * child's decremented `maxSubagentDepth` on the returned inputs) is the
788
- * mechanism that bounds nesting across graph boundaries; callers must
789
- * respect it.
790
- */
621
+ * Build child AgentInputs from a resolved config, stripping nesting and
622
+ * (optionally) event-driven fields. When `allowNested: true`, the child's
623
+ * `maxSubagentDepth` is decremented so that depth is consumed as the call
624
+ * chain deepens across graph boundaries — the parent's executor-level check
625
+ * alone cannot see into the child graph's separate executor.
626
+ *
627
+ * When `keepToolDefinitions` is `true`, the child retains the parent's
628
+ * `toolDefinitions` so event-driven tools remain usable. This is only safe
629
+ * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a
630
+ * registered handler — otherwise the child will hang on tool dispatch.
631
+ *
632
+ * @remarks Advanced utility: exported primarily for testing and by
633
+ * {@link SubagentExecutor}. Host applications configuring subagents should
634
+ * not need to call this directly — it is invoked internally when a subagent
635
+ * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,
636
+ * child's decremented `maxSubagentDepth` on the returned inputs) is the
637
+ * mechanism that bounds nesting across graph boundaries; callers must
638
+ * respect it.
639
+ */
791
640
  function buildChildInputs(config, childAgentId, parentMaxDepth, keepToolDefinitions = false) {
792
- const { agentInputs } = config;
793
- const childInputs = {
794
- ...agentInputs,
795
- agentId: childAgentId,
796
- toolDefinitions: keepToolDefinitions
797
- ? agentInputs.toolDefinitions
798
- : undefined,
799
- /**
800
- * Subagents run in an isolated context by contract. Parent-run-scoped
801
- * fields that would otherwise survive the shallow-spread clone the
802
- * cross-run conversation summary and the prior-turn tool-discovery
803
- * set are cleared here so the child starts fresh. Host applications
804
- * that want a subagent to see parent context must thread it in
805
- * explicitly (e.g. via the `description` argument to the subagent
806
- * tool), not via inherited state.
807
- */
808
- initialSummary: undefined,
809
- discoveredTools: undefined,
810
- };
811
- if (config.allowNested === true) {
812
- childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);
813
- }
814
- else {
815
- childInputs.subagentConfigs = undefined;
816
- childInputs.maxSubagentDepth = undefined;
817
- }
818
- return childInputs;
641
+ const { agentInputs } = config;
642
+ const childInputs = {
643
+ ...agentInputs,
644
+ agentId: childAgentId,
645
+ toolDefinitions: keepToolDefinitions ? agentInputs.toolDefinitions : void 0,
646
+ /**
647
+ * Subagents run in an isolated context by contract. Parent-run-scoped
648
+ * fields that would otherwise survive the shallow-spread clone — the
649
+ * cross-run conversation summary and the prior-turn tool-discovery
650
+ * set are cleared here so the child starts fresh. Host applications
651
+ * that want a subagent to see parent context must thread it in
652
+ * explicitly (e.g. via the `description` argument to the subagent
653
+ * tool), not via inherited state.
654
+ */
655
+ initialSummary: void 0,
656
+ discoveredTools: void 0
657
+ };
658
+ if (config.allowNested === true) childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);
659
+ else {
660
+ childInputs.subagentConfigs = void 0;
661
+ childInputs.maxSubagentDepth = void 0;
662
+ }
663
+ return childInputs;
819
664
  }
820
665
  function truncateErrorMessage(error) {
821
- const message = error instanceof Error ? error.message : String(error);
822
- if (message.length <= ERROR_MESSAGE_MAX_CHARS) {
823
- return message;
824
- }
825
- return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;
666
+ const message = error instanceof Error ? error.message : String(error);
667
+ if (message.length <= ERROR_MESSAGE_MAX_CHARS) return message;
668
+ return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;
826
669
  }
670
+ //#endregion
671
+ export { SubagentExecutor, buildChildInputs, filterSubagentResult, resolveSubagentConfigs, summarizeEvent };
827
672
 
828
- export { SubagentExecutor, buildChildInputs, filterSubagentResult, resolveSubagentConfigs, sanitizeForwardedSubagentUpdateData, summarizeEvent };
829
- //# sourceMappingURL=SubagentExecutor.mjs.map
673
+ //# sourceMappingURL=SubagentExecutor.mjs.map