@librechat/agents 3.2.32 → 3.2.34

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 (597) 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 +214 -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 +141 -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 +404 -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 +1035 -1273
  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 +446 -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 +874 -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 +2146 -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 +46 -34
  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 +214 -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 +140 -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 +403 -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 +1035 -1268
  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 +446 -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 +872 -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 +2144 -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 +42 -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/llm/bedrock/utils/index.d.ts +1 -1
  545. package/dist/types/llm/bedrock/utils/message_outputs.d.ts +9 -0
  546. package/dist/types/llm/vertexai/index.d.ts +10 -0
  547. package/dist/types/tools/ToolNode.d.ts +8 -0
  548. package/dist/types/tools/search/tool.d.ts +17 -0
  549. package/dist/types/tools/search/types.d.ts +4 -0
  550. package/dist/types/tools/streamedToolCallSeals.d.ts +5 -1
  551. package/dist/types/types/tools.d.ts +10 -0
  552. package/package.json +4 -10
  553. package/src/__tests__/stream.eagerEventExecution.test.ts +703 -0
  554. package/src/llm/bedrock/index.ts +40 -0
  555. package/src/llm/bedrock/streamSealDispatch.test.ts +158 -0
  556. package/src/llm/bedrock/utils/index.ts +1 -0
  557. package/src/llm/bedrock/utils/message_outputs.test.ts +85 -0
  558. package/src/llm/bedrock/utils/message_outputs.ts +43 -0
  559. package/src/llm/google/utils/common.test.ts +64 -0
  560. package/src/llm/google/utils/common.ts +18 -0
  561. package/src/llm/openai/index.ts +95 -1
  562. package/src/llm/openai/sequentialToolCallSeals.test.ts +199 -0
  563. package/src/llm/vertexai/index.ts +31 -0
  564. package/src/llm/vertexai/sealStreamedToolCalls.test.ts +88 -0
  565. package/src/llm/vertexai/streamSealDispatch.test.ts +148 -0
  566. package/src/stream.ts +40 -6
  567. package/src/tools/ToolNode.ts +85 -3
  568. package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +368 -0
  569. package/src/tools/search/highlights.ts +9 -1
  570. package/src/tools/search/search.ts +41 -3
  571. package/src/tools/search/source-processing.test.ts +373 -0
  572. package/src/tools/search/tool.ts +22 -2
  573. package/src/tools/search/types.ts +4 -0
  574. package/src/tools/streamedToolCallSeals.ts +37 -9
  575. package/src/types/tools.ts +10 -0
  576. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  577. package/dist/cjs/langchain/index.cjs.map +0 -1
  578. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  579. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  580. package/dist/cjs/langchain/messages.cjs.map +0 -1
  581. package/dist/cjs/langchain/openai.cjs.map +0 -1
  582. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  583. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  584. package/dist/cjs/langchain/tools.cjs.map +0 -1
  585. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  586. package/dist/cjs/main.cjs.map +0 -1
  587. package/dist/esm/langchain/google-common.mjs.map +0 -1
  588. package/dist/esm/langchain/index.mjs.map +0 -1
  589. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  590. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  591. package/dist/esm/langchain/messages.mjs.map +0 -1
  592. package/dist/esm/langchain/openai.mjs.map +0 -1
  593. package/dist/esm/langchain/prompts.mjs.map +0 -1
  594. package/dist/esm/langchain/runnables.mjs.map +0 -1
  595. package/dist/esm/langchain/tools.mjs.map +0 -1
  596. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  597. package/dist/esm/main.mjs.map +0 -1
@@ -1,1839 +1,1421 @@
1
- 'use strict';
2
-
3
- var nanoid = require('nanoid');
4
- var tools$1 = require('@langchain/core/tools');
5
- var messages = require('@langchain/core/messages');
6
- var langgraph = require('@langchain/langgraph');
7
- var core = require('../messages/core.cjs');
8
- var ids = require('../messages/ids.cjs');
9
- var prune = require('../messages/prune.cjs');
10
- var format = require('../messages/format.cjs');
11
- var cache = require('../messages/cache.cjs');
12
- var anthropicToolCache = require('../messages/anthropicToolCache.cjs');
13
- var content = require('../messages/content.cjs');
14
- var tools = require('../messages/tools.cjs');
15
- var reducer = require('../messages/reducer.cjs');
16
- var langfuseToolOutputTracing = require('../langfuseToolOutputTracing.cjs');
17
- var langfuse = require('../langfuse.cjs');
18
- var graph = require('../utils/graph.cjs');
19
- var llm = require('../utils/llm.cjs');
20
- require('../stream.cjs');
21
- var _enum = require('../common/enum.cjs');
22
- var run = require('../utils/run.cjs');
23
- require('ai-tokenizer');
24
- require('zod-to-json-schema');
25
- var callbacks = require('../utils/callbacks.cjs');
26
- var toolCache = require('../llm/openrouter/toolCache.cjs');
27
- var ToolNode = require('../tools/ToolNode.cjs');
28
- var LocalCodingTools = require('../tools/local/LocalCodingTools.cjs');
29
- var SubagentExecutor = require('../tools/subagent/SubagentExecutor.cjs');
30
- var toolOutputReferences = require('../tools/toolOutputReferences.cjs');
31
- var toolCache$1 = require('../llm/bedrock/toolCache.cjs');
32
- var events = require('../utils/events.cjs');
33
- require('path');
34
- require('../tools/cloudflare/CloudflareProgrammaticToolCalling.cjs');
35
- require('stream');
36
- require('events');
37
- require('../tools/local/LocalExecutionEngine.cjs');
38
- var CloudflareSandboxTools = require('../tools/cloudflare/CloudflareSandboxTools.cjs');
39
- var invoke = require('../llm/invoke.cjs');
40
- var SubagentTool = require('../tools/SubagentTool.cjs');
41
- var instrumentation = require('../instrumentation.cjs');
42
- var index = require('../summarization/index.cjs');
43
- require('../tools/local/CompileCheckTool.cjs');
44
- require('fs/promises');
45
- require('../tools/BashExecutor.cjs');
46
- require('../tools/CodeExecutor.cjs');
47
- require('http');
48
- require('crypto');
49
- require('../tools/ProgrammaticToolCalling.cjs');
50
- require('../tools/BashProgrammaticToolCalling.cjs');
51
- require('../hooks/createWorkspacePolicyHook.cjs');
52
- var resolveLocalExecutionTools = require('../tools/local/resolveLocalExecutionTools.cjs');
53
- var node = require('../summarization/node.cjs');
54
- var schema = require('../tools/schema.cjs');
55
- var AgentContext = require('../agents/AgentContext.cjs');
56
- var fake = require('../llm/fake.cjs');
57
- var handlers = require('../tools/handlers.cjs');
58
- var request = require('../llm/request.cjs');
59
- var init = require('../llm/init.cjs');
60
-
61
- /* eslint-disable no-console */
62
- const { AGENT, TOOLS, SUMMARIZE } = _enum.GraphNodeKeys;
1
+ const require_langfuse = require("../langfuse.cjs");
2
+ const require_langfuseToolOutputTracing = require("../langfuseToolOutputTracing.cjs");
3
+ const require_callbacks = require("../utils/callbacks.cjs");
4
+ const require_enum = require("../common/enum.cjs");
5
+ require("../common/index.cjs");
6
+ const require_instrumentation = require("../instrumentation.cjs");
7
+ const require_core = require("../messages/core.cjs");
8
+ const require_ids = require("../messages/ids.cjs");
9
+ const require_prune = require("../messages/prune.cjs");
10
+ const require_events = require("../utils/events.cjs");
11
+ const require_format = require("../messages/format.cjs");
12
+ const require_cache = require("../messages/cache.cjs");
13
+ const require_anthropicToolCache = require("../messages/anthropicToolCache.cjs");
14
+ const require_content = require("../messages/content.cjs");
15
+ const require_tools = require("../messages/tools.cjs");
16
+ const require_reducer = require("../messages/reducer.cjs");
17
+ require("../messages/index.cjs");
18
+ const require_graph = require("../utils/graph.cjs");
19
+ const require_llm = require("../utils/llm.cjs");
20
+ const require_handlers = require("../tools/handlers.cjs");
21
+ const require_toolOutputReferences = require("../tools/toolOutputReferences.cjs");
22
+ const require_run = require("../utils/run.cjs");
23
+ require("../utils/index.cjs");
24
+ const require_toolCache = require("../llm/openrouter/toolCache.cjs");
25
+ const require_LocalCodingTools = require("../tools/local/LocalCodingTools.cjs");
26
+ const require_CloudflareSandboxTools = require("../tools/cloudflare/CloudflareSandboxTools.cjs");
27
+ require("../tools/cloudflare/index.cjs");
28
+ const require_resolveLocalExecutionTools = require("../tools/local/resolveLocalExecutionTools.cjs");
29
+ require("../tools/local/index.cjs");
30
+ const require_ToolNode = require("../tools/ToolNode.cjs");
31
+ const require_SubagentExecutor = require("../tools/subagent/SubagentExecutor.cjs");
32
+ require("../tools/subagent/index.cjs");
33
+ const require_toolCache$1 = require("../llm/bedrock/toolCache.cjs");
34
+ const require_init = require("../llm/init.cjs");
35
+ const require_invoke = require("../llm/invoke.cjs");
36
+ const require_SubagentTool = require("../tools/SubagentTool.cjs");
37
+ const require_index$6 = require("../summarization/index.cjs");
38
+ const require_request = require("../llm/request.cjs");
39
+ const require_node = require("../summarization/node.cjs");
40
+ const require_schema = require("../tools/schema.cjs");
41
+ const require_AgentContext = require("../agents/AgentContext.cjs");
42
+ const require_fake = require("../llm/fake.cjs");
43
+ let _langchain_core_messages = require("@langchain/core/messages");
44
+ let _langchain_langgraph = require("@langchain/langgraph");
45
+ let _langchain_core_tools = require("@langchain/core/tools");
46
+ let nanoid = require("nanoid");
47
+ //#region src/graphs/Graph.ts
48
+ const { AGENT, TOOLS, SUMMARIZE } = require_enum.GraphNodeKeys;
63
49
  /** Minimum relative variance before calibrated toolSchemaTokens overrides current value. */
64
- const CALIBRATION_VARIANCE_THRESHOLD = 0.15;
50
+ const CALIBRATION_VARIANCE_THRESHOLD = .15;
65
51
  function getHandlerDispatchedEventKey(eventName, stepId) {
66
- return `${eventName}:${stepId}`;
52
+ return `${eventName}:${stepId}`;
67
53
  }
68
54
  function getReasoningText(value) {
69
- if (typeof value === 'string') {
70
- return value !== '' ? value : undefined;
71
- }
72
- const summaryText = value?.summary
73
- ?.map((summary) => summary.text ?? '')
74
- .filter((text) => text !== '')
75
- .join('');
76
- return summaryText != null && summaryText !== '' ? summaryText : undefined;
55
+ if (typeof value === "string") return value !== "" ? value : void 0;
56
+ const summaryText = value?.summary?.map((summary) => summary.text ?? "").filter((text) => text !== "").join("");
57
+ return summaryText != null && summaryText !== "" ? summaryText : void 0;
77
58
  }
78
59
  function getReasoningDetailsText(value) {
79
- if (!Array.isArray(value)) {
80
- return undefined;
81
- }
82
- const reasoningText = value
83
- .filter((detail) => detail.type === 'reasoning.text')
84
- .map((detail) => detail.text ?? '')
85
- .filter((text) => text !== '')
86
- .join('');
87
- return reasoningText !== '' ? reasoningText : undefined;
60
+ if (!Array.isArray(value)) return;
61
+ const reasoningText = value.filter((detail) => detail.type === "reasoning.text").map((detail) => detail.text ?? "").filter((text) => text !== "").join("");
62
+ return reasoningText !== "" ? reasoningText : void 0;
88
63
  }
89
- function getResponseReasoningContent({ responseMessage, reasoningKey, }) {
90
- const additionalKwargs = responseMessage?.additional_kwargs;
91
- if (additionalKwargs == null) {
92
- return undefined;
93
- }
94
- const keyedReasoning = getReasoningText(additionalKwargs[reasoningKey]);
95
- if (keyedReasoning != null) {
96
- return keyedReasoning;
97
- }
98
- const reasoningContent = getReasoningText(additionalKwargs.reasoning_content);
99
- if (reasoningContent != null) {
100
- return reasoningContent;
101
- }
102
- const reasoning = getReasoningText(additionalKwargs.reasoning);
103
- if (reasoning != null) {
104
- return reasoning;
105
- }
106
- return getReasoningDetailsText(additionalKwargs.reasoning_details);
64
+ function getResponseReasoningContent({ responseMessage, reasoningKey }) {
65
+ const additionalKwargs = responseMessage?.additional_kwargs;
66
+ if (additionalKwargs == null) return;
67
+ const keyedReasoning = getReasoningText(additionalKwargs[reasoningKey]);
68
+ if (keyedReasoning != null) return keyedReasoning;
69
+ const reasoningContent = getReasoningText(additionalKwargs.reasoning_content);
70
+ if (reasoningContent != null) return reasoningContent;
71
+ const reasoning = getReasoningText(additionalKwargs.reasoning);
72
+ if (reasoning != null) return reasoning;
73
+ return getReasoningDetailsText(additionalKwargs.reasoning_details);
107
74
  }
108
75
  function isTextMessageContentPart(contentPart) {
109
- return (typeof contentPart === 'object' &&
110
- 'type' in contentPart &&
111
- typeof contentPart.type === 'string' &&
112
- contentPart.type.startsWith('text'));
76
+ return typeof contentPart === "object" && "type" in contentPart && typeof contentPart.type === "string" && contentPart.type.startsWith("text");
113
77
  }
114
78
  function isGoogleServerSideToolMessageContentPart(contentPart) {
115
- return (typeof contentPart === 'object' &&
116
- 'type' in contentPart &&
117
- (contentPart.type === 'toolCall' || contentPart.type === 'toolResponse'));
79
+ return typeof contentPart === "object" && "type" in contentPart && (contentPart.type === "toolCall" || contentPart.type === "toolResponse");
118
80
  }
119
81
  function hasGoogleServerSideToolDeltaContent(provider, content) {
120
- return (llm.isGoogleLike(provider) &&
121
- Array.isArray(content) &&
122
- content.some((contentPart) => isGoogleServerSideToolMessageContentPart(contentPart)));
82
+ return require_llm.isGoogleLike(provider) && Array.isArray(content) && content.some((contentPart) => isGoogleServerSideToolMessageContentPart(contentPart));
123
83
  }
124
84
  function getMessageDeltaContent(provider, content) {
125
- if (content == null) {
126
- return undefined;
127
- }
128
- if (typeof content === 'string') {
129
- return content !== ''
130
- ? [{ type: _enum.ContentTypes.TEXT, text: content }]
131
- : undefined;
132
- }
133
- if (content.length === 0) {
134
- return undefined;
135
- }
136
- const hasGoogleServerSideToolPart = llm.isGoogleLike(provider) &&
137
- content.some((contentPart) => isGoogleServerSideToolMessageContentPart(contentPart));
138
- if (content.every((contentPart) => isTextMessageContentPart(contentPart))) {
139
- return content;
140
- }
141
- if (!hasGoogleServerSideToolPart) {
142
- return undefined;
143
- }
144
- const messageContent = content.filter((contentPart) => isTextMessageContentPart(contentPart) ||
145
- isGoogleServerSideToolMessageContentPart(contentPart));
146
- return messageContent.length > 0
147
- ? messageContent
148
- : undefined;
85
+ if (content == null) return;
86
+ if (typeof content === "string") return content !== "" ? [{
87
+ type: "text",
88
+ text: content
89
+ }] : void 0;
90
+ if (content.length === 0) return;
91
+ const hasGoogleServerSideToolPart = require_llm.isGoogleLike(provider) && content.some((contentPart) => isGoogleServerSideToolMessageContentPart(contentPart));
92
+ if (content.every((contentPart) => isTextMessageContentPart(contentPart))) return content;
93
+ if (!hasGoogleServerSideToolPart) return;
94
+ const messageContent = content.filter((contentPart) => isTextMessageContentPart(contentPart) || isGoogleServerSideToolMessageContentPart(contentPart));
95
+ return messageContent.length > 0 ? messageContent : void 0;
149
96
  }
150
97
  function hasTextDeltaContent(content) {
151
- if (content == null) {
152
- return false;
153
- }
154
- return content.some((contentPart) => {
155
- if (contentPart.type?.startsWith(_enum.ContentTypes.TEXT) !== true) {
156
- return false;
157
- }
158
- const text = contentPart.text;
159
- return typeof text === 'string' && text !== '';
160
- });
98
+ if (content == null) return false;
99
+ return content.some((contentPart) => {
100
+ if (contentPart.type?.startsWith("text") !== true) return false;
101
+ const text = contentPart.text;
102
+ return typeof text === "string" && text !== "";
103
+ });
161
104
  }
162
105
  function hasReasoningDeltaContent(content) {
163
- if (content == null) {
164
- return false;
165
- }
166
- return content.some((contentPart) => contentPart.type === _enum.ContentTypes.THINK && contentPart.think !== '');
106
+ if (content == null) return false;
107
+ return content.some((contentPart) => contentPart.type === "think" && contentPart.think !== "");
167
108
  }
168
- function getCurrentStepIds({ graph, metadata, }) {
169
- const baseStepKey = graph.getStepBaseKey(metadata);
170
- const currentStepIds = [];
171
- for (const [stepKey, stepIds] of graph.stepKeyIds) {
172
- if (stepKey !== baseStepKey && !stepKey.startsWith(`${baseStepKey}_`)) {
173
- continue;
174
- }
175
- currentStepIds.push(...stepIds);
176
- }
177
- return currentStepIds;
109
+ function getCurrentStepIds({ graph, metadata }) {
110
+ const baseStepKey = graph.getStepBaseKey(metadata);
111
+ const currentStepIds = [];
112
+ for (const [stepKey, stepIds] of graph.stepKeyIds) {
113
+ if (stepKey !== baseStepKey && !stepKey.startsWith(`${baseStepKey}_`)) continue;
114
+ currentStepIds.push(...stepIds);
115
+ }
116
+ return currentStepIds;
178
117
  }
179
- function hasCurrentTextDeltaStep({ graph, metadata, }) {
180
- return getCurrentStepIds({ graph, metadata }).some((stepId) => graph.messageStepHasTextDeltas.has(stepId));
118
+ function hasCurrentTextDeltaStep({ graph, metadata }) {
119
+ return getCurrentStepIds({
120
+ graph,
121
+ metadata
122
+ }).some((stepId) => graph.messageStepHasTextDeltas.has(stepId));
181
123
  }
182
- function hasCurrentReasoningDeltaStep({ graph, metadata, }) {
183
- return getCurrentStepIds({ graph, metadata }).some((stepId) => graph.reasoningStepHasDeltas.has(stepId));
124
+ function hasCurrentReasoningDeltaStep({ graph, metadata }) {
125
+ return getCurrentStepIds({
126
+ graph,
127
+ metadata
128
+ }).some((stepId) => graph.reasoningStepHasDeltas.has(stepId));
184
129
  }
185
- function clearCurrentDeltaStepMarkers({ graph, metadata, }) {
186
- for (const stepId of getCurrentStepIds({ graph, metadata })) {
187
- graph.messageStepHasTextDeltas.delete(stepId);
188
- graph.reasoningStepHasDeltas.delete(stepId);
189
- }
130
+ function clearCurrentDeltaStepMarkers({ graph, metadata }) {
131
+ for (const stepId of getCurrentStepIds({
132
+ graph,
133
+ metadata
134
+ })) {
135
+ graph.messageStepHasTextDeltas.delete(stepId);
136
+ graph.reasoningStepHasDeltas.delete(stepId);
137
+ }
190
138
  }
191
- async function dispatchMessageCreationStep({ graph, stepKey, messageId, metadata, }) {
192
- await graph.dispatchRunStep(stepKey, {
193
- type: _enum.StepTypes.MESSAGE_CREATION,
194
- message_creation: { message_id: messageId },
195
- }, metadata);
196
- return graph.getStepIdByKey(stepKey);
139
+ async function dispatchMessageCreationStep({ graph, stepKey, messageId, metadata }) {
140
+ await graph.dispatchRunStep(stepKey, {
141
+ type: "message_creation",
142
+ message_creation: { message_id: messageId }
143
+ }, metadata);
144
+ return graph.getStepIdByKey(stepKey);
197
145
  }
198
- async function dispatchTextMessageContent({ graph, stepKey, provider, content, metadata, }) {
199
- const messageId = ids.getMessageId(stepKey, graph) ?? '';
200
- if (!messageId) {
201
- return false;
202
- }
203
- if (hasGoogleServerSideToolDeltaContent(provider, content)) {
204
- for (const contentPart of content) {
205
- const stepId = await dispatchMessageCreationStep({
206
- graph,
207
- stepKey,
208
- messageId,
209
- metadata,
210
- });
211
- await graph.dispatchMessageDelta(stepId, { content: [contentPart] }, metadata);
212
- }
213
- return true;
214
- }
215
- const stepId = await dispatchMessageCreationStep({
216
- graph,
217
- stepKey,
218
- messageId,
219
- metadata,
220
- });
221
- await graph.dispatchMessageDelta(stepId, { content }, metadata);
222
- return true;
146
+ async function dispatchTextMessageContent({ graph, stepKey, provider, content, metadata }) {
147
+ const messageId = require_ids.getMessageId(stepKey, graph) ?? "";
148
+ if (!messageId) return false;
149
+ if (hasGoogleServerSideToolDeltaContent(provider, content)) {
150
+ for (const contentPart of content) {
151
+ const stepId = await dispatchMessageCreationStep({
152
+ graph,
153
+ stepKey,
154
+ messageId,
155
+ metadata
156
+ });
157
+ await graph.dispatchMessageDelta(stepId, { content: [contentPart] }, metadata);
158
+ }
159
+ return true;
160
+ }
161
+ const stepId = await dispatchMessageCreationStep({
162
+ graph,
163
+ stepKey,
164
+ messageId,
165
+ metadata
166
+ });
167
+ await graph.dispatchMessageDelta(stepId, { content }, metadata);
168
+ return true;
223
169
  }
224
- async function dispatchReasoningContent({ graph, agentContext, reasoningContent, metadata, }) {
225
- const previousTokenType = agentContext.currentTokenType;
226
- const previousTokenTypeSwitch = agentContext.tokenTypeSwitch;
227
- const previousTransitionCount = agentContext.reasoningTransitionCount;
228
- agentContext.currentTokenType = _enum.ContentTypes.THINK;
229
- agentContext.tokenTypeSwitch = 'reasoning';
230
- const stepKey = graph.getStepKey(metadata);
231
- const messageId = ids.getMessageId(stepKey, graph) ?? '';
232
- if (!messageId) {
233
- agentContext.currentTokenType = previousTokenType;
234
- agentContext.tokenTypeSwitch = previousTokenTypeSwitch;
235
- agentContext.reasoningTransitionCount = previousTransitionCount;
236
- return false;
237
- }
238
- await graph.dispatchRunStep(stepKey, {
239
- type: _enum.StepTypes.MESSAGE_CREATION,
240
- message_creation: { message_id: messageId },
241
- }, metadata);
242
- const stepId = graph.getStepIdByKey(stepKey);
243
- await graph.dispatchReasoningDelta(stepId, {
244
- content: [{ type: _enum.ContentTypes.THINK, think: reasoningContent }],
245
- }, metadata);
246
- return true;
170
+ async function dispatchReasoningContent({ graph, agentContext, reasoningContent, metadata }) {
171
+ const previousTokenType = agentContext.currentTokenType;
172
+ const previousTokenTypeSwitch = agentContext.tokenTypeSwitch;
173
+ const previousTransitionCount = agentContext.reasoningTransitionCount;
174
+ agentContext.currentTokenType = "think";
175
+ agentContext.tokenTypeSwitch = "reasoning";
176
+ const stepKey = graph.getStepKey(metadata);
177
+ const messageId = require_ids.getMessageId(stepKey, graph) ?? "";
178
+ if (!messageId) {
179
+ agentContext.currentTokenType = previousTokenType;
180
+ agentContext.tokenTypeSwitch = previousTokenTypeSwitch;
181
+ agentContext.reasoningTransitionCount = previousTransitionCount;
182
+ return false;
183
+ }
184
+ await graph.dispatchRunStep(stepKey, {
185
+ type: "message_creation",
186
+ message_creation: { message_id: messageId }
187
+ }, metadata);
188
+ const stepId = graph.getStepIdByKey(stepKey);
189
+ await graph.dispatchReasoningDelta(stepId, { content: [{
190
+ type: "think",
191
+ think: reasoningContent
192
+ }] }, metadata);
193
+ return true;
247
194
  }
248
195
  function markPostReasoningContent(agentContext) {
249
- if (agentContext.tokenTypeSwitch !== 'reasoning' ||
250
- agentContext.currentTokenType === _enum.ContentTypes.TEXT) {
251
- return;
252
- }
253
- agentContext.currentTokenType = _enum.ContentTypes.TEXT;
254
- agentContext.tokenTypeSwitch = 'content';
255
- agentContext.reasoningTransitionCount++;
256
- }
257
- function getDispatchableFinalReasoningContent({ agentContext, responseReasoningContent, hasStreamedTextDeltaStep, hasStreamedReasoningDeltaStep, }) {
258
- if (responseReasoningContent == null || hasStreamedReasoningDeltaStep) {
259
- return undefined;
260
- }
261
- if (agentContext.provider === _enum.Providers.OPENROUTER &&
262
- hasStreamedTextDeltaStep) {
263
- return undefined;
264
- }
265
- return responseReasoningContent;
196
+ if (agentContext.tokenTypeSwitch !== "reasoning" || agentContext.currentTokenType === "text") return;
197
+ agentContext.currentTokenType = "text";
198
+ agentContext.tokenTypeSwitch = "content";
199
+ agentContext.reasoningTransitionCount++;
266
200
  }
267
- class Graph {
268
- messageStepHasTextDeltas = new Set();
269
- messageStepHasToolCalls = new Map();
270
- messageIdsByStepKey = new Map();
271
- prelimMessageIdsByStepKey = new Map();
272
- config;
273
- contentData = [];
274
- stepKeyIds = new Map();
275
- contentIndexMap = new Map();
276
- toolCallStepIds = new Map();
277
- /**
278
- * Step IDs dispatched through the handler registry during this run.
279
- * Event echo suppression is tracked separately so repeated deltas for
280
- * the same step are scoped to the active custom event dispatch.
281
- */
282
- handlerDispatchedStepIds = new Set();
283
- reasoningStepHasDeltas = new Set();
284
- handlerDispatchedEventCounts = new Map();
285
- signal;
286
- /** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
287
- invokedToolIds;
288
- handlerRegistry;
289
- /**
290
- * True when event-driven tool execution can be routed through callbacks even
291
- * though this graph intentionally does not own the full handler registry.
292
- * Self-spawned subagent graphs use this shape: their callback forwarder sends
293
- * `ON_TOOL_EXECUTE` to the parent's handler, while child run-step events stay
294
- * wrapped as `ON_SUBAGENT_UPDATE` instead of leaking as parent events.
295
- */
296
- eventToolExecutionAvailable = false;
297
- hookRegistry;
298
- /**
299
- * Run-scoped HITL configuration. When `humanInTheLoop?.enabled` is
300
- * `true`, `ToolNode` raises a real `interrupt()` for `PreToolUse`
301
- * `ask` decisions instead of treating them as a synchronous deny.
302
- * Threaded from `RunConfig.humanInTheLoop`.
303
- */
304
- humanInTheLoop;
305
- /**
306
- * Run-scoped config for the tool output reference registry. Threaded
307
- * from `RunConfig.toolOutputReferences` down into every ToolNode this
308
- * graph compiles.
309
- */
310
- toolOutputReferences;
311
- /**
312
- * Run-scoped Langfuse defaults. Per-agent config wins when present.
313
- */
314
- langfuse;
315
- /**
316
- * Run-scoped opt-in for eager event-driven tool execution. The stream
317
- * handler may prestart eligible event-driven tools; ToolNode later
318
- * consumes the settled promises while preserving final ToolMessage order.
319
- */
320
- eagerEventToolExecution;
321
- eagerEventToolExecutions = new Map();
322
- eagerEventToolUsageCount = new Map();
323
- eagerEventToolUsageCountsByAgentId = new Map();
324
- eagerEventToolCallChunks = new Map();
325
- /**
326
- * Run-scoped execution backend for built-in code tools. Defaults to the
327
- * remote Code API sandbox when unset.
328
- */
329
- toolExecution;
330
- /**
331
- * Shared registry instance used by every ToolNode compiled from this
332
- * graph. Lazily constructed on first access so multi-agent graphs
333
- * produce one registry per run (not one per agent), letting cross-
334
- * agent `{{tool<i>turn<n>}}` substitutions resolve.
335
- */
336
- _toolOutputRegistry;
337
- /**
338
- * Tool session contexts for automatic state persistence across tool invocations.
339
- * Keyed by tool name (e.g., Constants.EXECUTE_CODE).
340
- * Currently supports code execution session tracking (session_id, files).
341
- */
342
- sessions = new Map();
343
- /**
344
- * Clears heavy references to allow GC to reclaim memory held by
345
- * LangGraph's internal config / AsyncLocalStorage RunTree chain.
346
- * Call after a run completes and content has been extracted.
347
- */
348
- clearHeavyState() {
349
- this.config = undefined;
350
- this.signal = undefined;
351
- this.contentData = [];
352
- this.contentIndexMap = new Map();
353
- this.stepKeyIds = new Map();
354
- this.toolCallStepIds.clear();
355
- this.messageIdsByStepKey = new Map();
356
- this.messageStepHasTextDeltas = new Set();
357
- this.reasoningStepHasDeltas = new Set();
358
- this.messageStepHasToolCalls = new Map();
359
- this.prelimMessageIdsByStepKey = new Map();
360
- this.invokedToolIds = undefined;
361
- this.handlerRegistry = undefined;
362
- this.hookRegistry = undefined;
363
- this.humanInTheLoop = undefined;
364
- this.toolOutputReferences = undefined;
365
- this.eagerEventToolExecution = undefined;
366
- this.eagerEventToolExecutions.clear();
367
- this.clearEagerEventToolUsageCounts();
368
- this.eagerEventToolCallChunks.clear();
369
- this.toolExecution = undefined;
370
- this.handlerDispatchedEventCounts.clear();
371
- /**
372
- * ToolNodes compiled from this graph captured the registry
373
- * instance at construction time, so simply dropping the Graph's
374
- * own reference would leave their captured reference — and every
375
- * stored `tool<i>turn<n>` entry, plus up to `maxTotalSize` of raw
376
- * output — alive across subsequent `processStream()` calls. Wipe
377
- * the registry's contents first so subsequent runs start fresh.
378
- */
379
- this._toolOutputRegistry?.clear();
380
- this._toolOutputRegistry = undefined;
381
- // NB: `_fileCheckpointer` is intentionally NOT cleared here.
382
- // `Run.processStream()` calls `clearHeavyState()` in its
383
- // finally block on natural-completion / error paths — exactly
384
- // when the host is most likely to want `Run.rewindFiles()` (for
385
- // rollback after a failed batch). Per-Run isolation is already
386
- // automatic because each `Run.create()` constructs a brand-new
387
- // Graph instance, so the next Run gets its own checkpointer
388
- // without us needing to reset this field. Codex P1 #32: pre-fix
389
- // the checkpointer was nulled before the caller could reach it.
390
- // Flush each compiled ToolNode's direct-path turn cache so it
391
- // doesn't leak across Runs (Codex P2 #33). The cache survives
392
- // `run()` re-entry by design (resume-stable), but end-of-Run
393
- // is the right point to reset it.
394
- for (const node of this._compiledToolNodes) {
395
- node.clearDirectPathTurns();
396
- }
397
- this._compiledToolNodes.clear();
398
- this.sessions.clear();
399
- }
400
- getEagerEventToolUsageCount(agentId) {
401
- if (agentId == null || agentId === '') {
402
- return this.eagerEventToolUsageCount;
403
- }
404
- let usageCount = this.eagerEventToolUsageCountsByAgentId.get(agentId);
405
- if (usageCount == null) {
406
- usageCount = new Map();
407
- this.eagerEventToolUsageCountsByAgentId.set(agentId, usageCount);
408
- }
409
- return usageCount;
410
- }
411
- clearEagerEventToolUsageCounts() {
412
- this.eagerEventToolUsageCount.clear();
413
- for (const usageCount of this.eagerEventToolUsageCountsByAgentId.values()) {
414
- usageCount.clear();
415
- }
416
- }
417
- markHandlerDispatchedEvent(eventName, stepId) {
418
- const key = getHandlerDispatchedEventKey(eventName, stepId);
419
- this.handlerDispatchedEventCounts.set(key, (this.handlerDispatchedEventCounts.get(key) ?? 0) + 1);
420
- return () => {
421
- const count = this.handlerDispatchedEventCounts.get(key) ?? 0;
422
- if (count <= 1) {
423
- this.handlerDispatchedEventCounts.delete(key);
424
- return;
425
- }
426
- this.handlerDispatchedEventCounts.set(key, count - 1);
427
- };
428
- }
429
- hasHandlerDispatchedEvent(eventName, stepId) {
430
- const key = getHandlerDispatchedEventKey(eventName, stepId);
431
- return (this.handlerDispatchedEventCounts.get(key) ?? 0) > 0;
432
- }
433
- /**
434
- * Subclass hook to register a freshly compiled ToolNode so
435
- * `clearHeavyState` can flush its per-Run direct-path turn cache
436
- * at end-of-Run. Internal — called from `initializeTools` in the
437
- * concrete graph subclasses.
438
- */
439
- registerCompiledToolNode(node) {
440
- this._compiledToolNodes.add(node);
441
- }
442
- /**
443
- * Returns the shared `ToolOutputReferenceRegistry` for this run,
444
- * constructing it on first access. Returns `undefined` when the
445
- * feature is disabled. All ToolNodes compiled from this graph share
446
- * this single instance so cross-agent `{{…}}` references resolve.
447
- *
448
- * @internal Public so `attemptInvoke` can read it through the typed
449
- * `InvokeContext` and project ToolMessages into LLM-facing annotated
450
- * copies right before each provider call (see
451
- * `annotateMessagesForLLM`). Host code should not call this directly
452
- * — registry mutations outside the ToolNode lifecycle break the
453
- * partitioning, eviction, and turn-counter invariants.
454
- */
455
- getOrCreateToolOutputRegistry() {
456
- if (this.toolOutputReferences?.enabled !== true) {
457
- return undefined;
458
- }
459
- if (this._toolOutputRegistry == null) {
460
- this._toolOutputRegistry = new toolOutputReferences.ToolOutputReferenceRegistry({
461
- maxOutputSize: this.toolOutputReferences.maxOutputSize,
462
- maxTotalSize: this.toolOutputReferences.maxTotalSize,
463
- });
464
- }
465
- return this._toolOutputRegistry;
466
- }
467
- /**
468
- * Single per-Run file checkpointer shared across every ToolNode the
469
- * graph compiles. Lazily constructed when
470
- * `toolExecution.local.fileCheckpointing === true` or
471
- * `toolExecution.cloudflare.fileCheckpointing === true` so
472
- * multi-agent graphs see ONE snapshot store, not one-per-agent.
473
- * Returns undefined when checkpointing is disabled or a supported
474
- * coding-tool engine isn't selected. Exposed via
475
- * `Run.getFileCheckpointer()` / `Run.rewindFiles()`.
476
- */
477
- _fileCheckpointer;
478
- /**
479
- * ToolNodes compiled into this Graph's workflow. Tracked so
480
- * `clearHeavyState()` can flush their per-Run direct-path turn
481
- * cache (`directPathTurns`) at end-of-Run — that map intentionally
482
- * survives `run()` re-entry (resume-stable per Codex P2 #30) but
483
- * would otherwise grow linearly with tool calls and could collide
484
- * across Runs if a provider reuses call ids (Codex P2 #33).
485
- */
486
- _compiledToolNodes = new Set();
487
- getOrCreateFileCheckpointer() {
488
- // Return the cached instance unconditionally if one exists. The
489
- // toolExecution check below decides whether to *create* a new
490
- // one — `clearHeavyState` nulls `this.toolExecution` at end-of-
491
- // Run, but we want post-Run `Run.rewindFiles()` to still resolve
492
- // to the checkpointer that captured the writes. Codex P1 #32.
493
- if (this._fileCheckpointer != null) {
494
- return this._fileCheckpointer;
495
- }
496
- // Eagerly create via the bundle factory so the construction path
497
- // matches the bundle-only callers (and future bundle-internal
498
- // cleanup hooks fire). The bundle factory itself accepts a pre-
499
- // supplied checkpointer when present, so re-injecting this one
500
- // into every ToolNode is idempotent.
501
- if (this.toolExecution?.engine === 'local' &&
502
- this.toolExecution.local?.fileCheckpointing === true) {
503
- const bundle = LocalCodingTools.createLocalCodingToolBundle(this.toolExecution.local ?? {});
504
- this._fileCheckpointer = bundle.checkpointer;
505
- return this._fileCheckpointer;
506
- }
507
- if (this.toolExecution?.engine === 'cloudflare-sandbox' &&
508
- this.toolExecution.cloudflare?.fileCheckpointing === true) {
509
- const bundle = CloudflareSandboxTools.createCloudflareCodingToolBundle(this.toolExecution.cloudflare);
510
- this._fileCheckpointer = bundle.checkpointer;
511
- return this._fileCheckpointer;
512
- }
513
- return undefined;
514
- }
201
+ function getDispatchableFinalReasoningContent({ agentContext, responseReasoningContent, hasStreamedTextDeltaStep, hasStreamedReasoningDeltaStep }) {
202
+ if (responseReasoningContent == null || hasStreamedReasoningDeltaStep) return;
203
+ if (agentContext.provider === "openrouter" && hasStreamedTextDeltaStep) return;
204
+ return responseReasoningContent;
515
205
  }
516
- class StandardGraph extends Graph {
517
- overrideModel;
518
- /** Optional compile options passed into workflow.compile() */
519
- compileOptions;
520
- messages = [];
521
- /** Cached run messages preserved before clearHeavyState() so getRunMessages() works after cleanup. */
522
- cachedRunMessages;
523
- runId;
524
- /**
525
- * Boundary between historical messages (loaded from conversation state)
526
- * and messages produced during the current run. Set once in the state
527
- * reducer when messages first arrive. Used by `getRunMessages()` and
528
- * multi-agent message filtering NOT for pruner token counting (the
529
- * pruner maintains its own `lastTurnStartIndex` in its closure).
530
- */
531
- startIndex = 0;
532
- signal;
533
- /** Map of agent contexts by agent ID */
534
- agentContexts = new Map();
535
- /** Default agent ID to use */
536
- defaultAgentId;
537
- constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio, }) {
538
- super();
539
- this.runId = runId;
540
- this.signal = signal;
541
- this.langfuse = langfuse;
542
- if (agents.length === 0) {
543
- throw new Error('At least one agent configuration is required');
544
- }
545
- for (const agentConfig of agents) {
546
- const agentContext = AgentContext.AgentContext.fromConfig(agentConfig, tokenCounter, indexTokenCountMap);
547
- if (calibrationRatio != null && calibrationRatio > 0) {
548
- agentContext.calibrationRatio = calibrationRatio;
549
- }
550
- this.agentContexts.set(agentConfig.agentId, agentContext);
551
- }
552
- this.defaultAgentId = agents[0].agentId;
553
- }
554
- /* Init */
555
- resetValues(keepContent) {
556
- this.messages = [];
557
- this.cachedRunMessages = undefined;
558
- this.config = graph.resetIfNotEmpty(this.config, undefined);
559
- if (keepContent !== true) {
560
- this.contentData = graph.resetIfNotEmpty(this.contentData, []);
561
- this.contentIndexMap = graph.resetIfNotEmpty(this.contentIndexMap, new Map());
562
- }
563
- this.stepKeyIds = graph.resetIfNotEmpty(this.stepKeyIds, new Map());
564
- /**
565
- * Clear in-place instead of replacing with a new Map to preserve the
566
- * shared reference held by ToolNode (passed at construction time).
567
- * Using resetIfNotEmpty would create a new Map, leaving ToolNode with
568
- * a stale reference on 2nd+ processStream calls.
569
- */
570
- this.toolCallStepIds.clear();
571
- this.eagerEventToolExecutions.clear();
572
- this.clearEagerEventToolUsageCounts();
573
- this.eagerEventToolCallChunks.clear();
574
- this.handlerDispatchedStepIds = graph.resetIfNotEmpty(this.handlerDispatchedStepIds, new Set());
575
- this.handlerDispatchedEventCounts = graph.resetIfNotEmpty(this.handlerDispatchedEventCounts, new Map());
576
- this.messageIdsByStepKey = graph.resetIfNotEmpty(this.messageIdsByStepKey, new Map());
577
- this.messageStepHasToolCalls = graph.resetIfNotEmpty(this.messageStepHasToolCalls, new Map());
578
- this.messageStepHasTextDeltas = graph.resetIfNotEmpty(this.messageStepHasTextDeltas, new Set());
579
- this.reasoningStepHasDeltas = graph.resetIfNotEmpty(this.reasoningStepHasDeltas, new Set());
580
- this.prelimMessageIdsByStepKey = graph.resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
581
- this.invokedToolIds = graph.resetIfNotEmpty(this.invokedToolIds, undefined);
582
- for (const context of this.agentContexts.values()) {
583
- context.reset();
584
- }
585
- }
586
- clearHeavyState() {
587
- this.cachedRunMessages = this.messages.slice(this.startIndex);
588
- super.clearHeavyState();
589
- this.messages = [];
590
- this.overrideModel = undefined;
591
- for (const context of this.agentContexts.values()) {
592
- context.reset();
593
- }
594
- }
595
- /* Run Step Processing */
596
- getRunStep(stepId) {
597
- const index = this.contentIndexMap.get(stepId);
598
- if (index !== undefined) {
599
- return this.contentData[index];
600
- }
601
- return undefined;
602
- }
603
- getAgentContext(metadata) {
604
- if (!metadata) {
605
- throw new Error('No metadata provided to retrieve agent context');
606
- }
607
- const currentNode = metadata.langgraph_node;
608
- if (!currentNode) {
609
- throw new Error('No langgraph_node in metadata to retrieve agent context');
610
- }
611
- let agentId;
612
- if (currentNode.startsWith(AGENT)) {
613
- agentId = currentNode.substring(AGENT.length);
614
- }
615
- else if (currentNode.startsWith(TOOLS)) {
616
- agentId = currentNode.substring(TOOLS.length);
617
- }
618
- else if (currentNode.startsWith(SUMMARIZE)) {
619
- agentId = currentNode.substring(SUMMARIZE.length);
620
- }
621
- const agentContext = this.agentContexts.get(agentId ?? '');
622
- if (!agentContext) {
623
- throw new Error(`No agent context found for agent ID ${agentId}`);
624
- }
625
- return agentContext;
626
- }
627
- getStepBaseKey(metadata) {
628
- if (!metadata)
629
- return '';
630
- const keyList = this.getInvocationKeyList(metadata);
631
- if (this.checkKeyList(keyList)) {
632
- throw new Error('Missing metadata');
633
- }
634
- return graph.joinKeys(keyList);
635
- }
636
- getStepKey(metadata) {
637
- if (!metadata)
638
- return '';
639
- const keyList = this.getKeyList(metadata);
640
- if (this.checkKeyList(keyList)) {
641
- throw new Error('Missing metadata');
642
- }
643
- return graph.joinKeys(keyList);
644
- }
645
- getStepIdByKey(stepKey, index) {
646
- const stepIds = this.stepKeyIds.get(stepKey);
647
- if (!stepIds) {
648
- throw new Error(`No step IDs found for stepKey ${stepKey}`);
649
- }
650
- if (index === undefined) {
651
- return stepIds[stepIds.length - 1];
652
- }
653
- return stepIds[index];
654
- }
655
- generateStepId(stepKey) {
656
- const stepIds = this.stepKeyIds.get(stepKey);
657
- let newStepId;
658
- let stepIndex = 0;
659
- if (stepIds) {
660
- stepIndex = stepIds.length;
661
- newStepId = `step_${nanoid.nanoid()}`;
662
- stepIds.push(newStepId);
663
- this.stepKeyIds.set(stepKey, stepIds);
664
- }
665
- else {
666
- newStepId = `step_${nanoid.nanoid()}`;
667
- this.stepKeyIds.set(stepKey, [newStepId]);
668
- }
669
- return [newStepId, stepIndex];
670
- }
671
- getKeyList(metadata) {
672
- if (!metadata)
673
- return [];
674
- const keyList = this.getInvocationKeyList(metadata);
675
- const agentContext = this.getAgentContext(metadata);
676
- if (agentContext.currentTokenType === _enum.ContentTypes.THINK ||
677
- agentContext.currentTokenType === 'think_and_text') {
678
- keyList.push('reasoning');
679
- }
680
- else if (agentContext.tokenTypeSwitch === 'content') {
681
- keyList.push(`post-reasoning-${agentContext.reasoningTransitionCount}`);
682
- }
683
- return keyList;
684
- }
685
- getInvocationKeyList(metadata) {
686
- const keyList = this.getBaseKeyList(metadata);
687
- if (this.invokedToolIds != null && this.invokedToolIds.size > 0) {
688
- keyList.push(this.invokedToolIds.size + '');
689
- }
690
- return keyList;
691
- }
692
- getBaseKeyList(metadata) {
693
- const configurable = this.config?.configurable;
694
- const runId = metadata.run_id ??
695
- configurable?.run_id ??
696
- this.runId;
697
- const threadId = metadata.thread_id ??
698
- configurable?.thread_id ??
699
- runId;
700
- const checkpointNs = metadata.checkpoint_ns ??
701
- metadata.langgraph_checkpoint_ns ??
702
- '';
703
- const keyList = [
704
- runId,
705
- threadId,
706
- metadata.langgraph_node,
707
- metadata.langgraph_step,
708
- checkpointNs,
709
- ];
710
- return keyList;
711
- }
712
- checkKeyList(keyList) {
713
- return keyList.some((key) => key === undefined);
714
- }
715
- /* Misc.*/
716
- getRunMessages() {
717
- if (this.messages.length === 0 && this.cachedRunMessages != null) {
718
- return this.cachedRunMessages;
719
- }
720
- return this.messages.slice(this.startIndex);
721
- }
722
- getContentParts() {
723
- return core.convertMessagesToContent(this.messages.slice(this.startIndex));
724
- }
725
- getCalibrationRatio() {
726
- const context = this.agentContexts.get(this.defaultAgentId);
727
- return context?.calibrationRatio ?? 1;
728
- }
729
- getResolvedInstructionOverhead() {
730
- const context = this.agentContexts.get(this.defaultAgentId);
731
- return context?.resolvedInstructionOverhead;
732
- }
733
- getToolCount() {
734
- const context = this.agentContexts.get(this.defaultAgentId);
735
- return ((context?.tools?.length ?? 0) + (context?.toolDefinitions?.length ?? 0));
736
- }
737
- /**
738
- * Get all run steps, optionally filtered by agent ID
739
- */
740
- getRunSteps(agentId) {
741
- if (agentId == null || agentId === '') {
742
- return [...this.contentData];
743
- }
744
- return this.contentData.filter((step) => step.agentId === agentId);
745
- }
746
- /**
747
- * Get run steps grouped by agent ID
748
- */
749
- getRunStepsByAgent() {
750
- const stepsByAgent = new Map();
751
- for (const step of this.contentData) {
752
- if (step.agentId == null || step.agentId === '')
753
- continue;
754
- const steps = stepsByAgent.get(step.agentId) ?? [];
755
- steps.push(step);
756
- stepsByAgent.set(step.agentId, steps);
757
- }
758
- return stepsByAgent;
759
- }
760
- /**
761
- * Get agent IDs that participated in this run
762
- */
763
- getActiveAgentIds() {
764
- const agentIds = new Set();
765
- for (const step of this.contentData) {
766
- if (step.agentId != null && step.agentId !== '') {
767
- agentIds.add(step.agentId);
768
- }
769
- }
770
- return Array.from(agentIds);
771
- }
772
- /**
773
- * Maps contentPart indices to agent IDs for post-run analysis
774
- * Returns a map where key is the contentPart index and value is the agentId
775
- */
776
- getContentPartAgentMap() {
777
- const contentPartAgentMap = new Map();
778
- for (const step of this.contentData) {
779
- if (step.agentId != null &&
780
- step.agentId !== '' &&
781
- Number.isFinite(step.index)) {
782
- contentPartAgentMap.set(step.index, step.agentId);
783
- }
784
- }
785
- return contentPartAgentMap;
786
- }
787
- /* Graph */
788
- initializeTools({ currentTools, currentToolMap, agentContext, }) {
789
- const toolDefinitions = agentContext?.toolDefinitions;
790
- const eventDrivenMode = toolDefinitions != null && toolDefinitions.length > 0;
791
- const traceToolNode = langfuseToolOutputTracing.shouldTraceToolNodeForLangfuse({
792
- runLangfuse: this.langfuse,
793
- agentLangfuse: agentContext?.langfuse,
794
- });
795
- if (eventDrivenMode) {
796
- const schemaTools = schema.createSchemaOnlyTools(toolDefinitions);
797
- const toolDefMap = new Map(toolDefinitions.map((def) => [def.name, def]));
798
- const graphTools = agentContext?.graphTools;
799
- const directToolNames = new Set();
800
- const allTools = [...schemaTools];
801
- const allToolMap = new Map(schemaTools.map((tool) => [tool.name, tool]));
802
- if (graphTools && graphTools.length > 0) {
803
- for (const tool of graphTools) {
804
- if ('name' in tool) {
805
- allTools.push(tool);
806
- allToolMap.set(tool.name, tool);
807
- directToolNames.add(tool.name);
808
- }
809
- }
810
- }
811
- const node = new ToolNode.ToolNode({
812
- tools: allTools,
813
- toolMap: allToolMap,
814
- trace: traceToolNode,
815
- runLangfuse: this.langfuse,
816
- agentLangfuse: agentContext?.langfuse,
817
- eventDrivenMode: true,
818
- sessions: this.sessions,
819
- toolDefinitions: toolDefMap,
820
- agentId: agentContext?.agentId,
821
- executingAgentId: agentContext?.agentId,
822
- toolCallStepIds: this.toolCallStepIds,
823
- toolRegistry: agentContext?.toolRegistry,
824
- hookRegistry: this.hookRegistry,
825
- humanInTheLoop: this.humanInTheLoop,
826
- eagerEventToolExecution: this.eagerEventToolExecution,
827
- eagerEventToolExecutions: this.eagerEventToolExecutions,
828
- eagerEventToolUsageCount: this.getEagerEventToolUsageCount(agentContext?.agentId),
829
- toolExecution: this.toolExecution,
830
- directToolNames: directToolNames.size > 0 ? directToolNames : undefined,
831
- maxContextTokens: agentContext?.maxContextTokens,
832
- maxToolResultChars: agentContext?.maxToolResultChars,
833
- toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
834
- fileCheckpointer: this.getOrCreateFileCheckpointer(),
835
- errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
836
- });
837
- this.registerCompiledToolNode(node);
838
- return node;
839
- }
840
- const graphTools = agentContext?.graphTools;
841
- const baseTools = currentTools ?? [];
842
- const allTraditionalTools = graphTools && graphTools.length > 0
843
- ? [...baseTools, ...graphTools]
844
- : baseTools;
845
- const traditionalToolMap = graphTools && graphTools.length > 0
846
- ? new Map([
847
- ...(currentToolMap ?? new Map()),
848
- ...graphTools
849
- .filter((t) => 'name' in t)
850
- .map((t) => [t.name, t]),
851
- ])
852
- : currentToolMap;
853
- const node = new ToolNode.ToolNode({
854
- tools: allTraditionalTools,
855
- toolMap: traditionalToolMap,
856
- trace: traceToolNode,
857
- runLangfuse: this.langfuse,
858
- agentLangfuse: agentContext?.langfuse,
859
- // `agentId` is intentionally left unset on this path (it is the
860
- // subagent-scope marker); `executingAgentId` always identifies the owning
861
- // agent so hooks can attribute the batch even at the top level.
862
- executingAgentId: agentContext?.agentId,
863
- toolCallStepIds: this.toolCallStepIds,
864
- errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
865
- toolRegistry: agentContext?.toolRegistry,
866
- sessions: this.sessions,
867
- toolExecution: this.toolExecution,
868
- hookRegistry: this.hookRegistry,
869
- humanInTheLoop: this.humanInTheLoop,
870
- maxContextTokens: agentContext?.maxContextTokens,
871
- maxToolResultChars: agentContext?.maxToolResultChars,
872
- toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
873
- fileCheckpointer: this.getOrCreateFileCheckpointer(),
874
- });
875
- this.registerCompiledToolNode(node);
876
- return node;
877
- }
878
- overrideTestModel(responses, sleep, toolCalls) {
879
- this.overrideModel = fake.createFakeStreamingLLM({
880
- responses,
881
- sleep,
882
- toolCalls,
883
- });
884
- }
885
- getUsageMetadata(finalMessage) {
886
- if (finalMessage &&
887
- 'usage_metadata' in finalMessage &&
888
- finalMessage.usage_metadata != null) {
889
- return finalMessage.usage_metadata;
890
- }
891
- }
892
- cleanupSignalListener(currentModel) {
893
- if (!this.signal) {
894
- return;
895
- }
896
- const model = this.overrideModel ?? currentModel;
897
- if (!model) {
898
- return;
899
- }
900
- const client = model?.exposedClient;
901
- if (!client?.abortHandler) {
902
- return;
903
- }
904
- this.signal.removeEventListener('abort', client.abortHandler);
905
- client.abortHandler = undefined;
906
- }
907
- createCallModel(agentId = 'default') {
908
- return async (state, config) => {
909
- const agentContext = this.agentContexts.get(agentId);
910
- if (!agentContext) {
911
- throw new Error(`Agent context not found for agentId: ${agentId}`);
912
- }
913
- if (!config) {
914
- throw new Error('No config provided');
915
- }
916
- const { messages: messages$1 } = state;
917
- const discoveredNames = tools.extractToolDiscoveries(messages$1);
918
- if (discoveredNames.length > 0) {
919
- agentContext.markToolsAsDiscovered(discoveredNames);
920
- }
921
- const rawToolsForBinding = resolveLocalExecutionTools.resolveLocalToolsForBinding({
922
- tools: agentContext.getToolsForBinding(),
923
- toolExecution: this.toolExecution,
924
- });
925
- /**
926
- * Anthropic prompt-cache breakpoint on the tool definitions.
927
- *
928
- * Without this, the (often static) tool inventory shows up as
929
- * fresh input on every turn — measured at ~28k tokens/turn for
930
- * the local engine's coding-tool bundle, dominating per-turn
931
- * cost even when message-level caching is on.
932
- *
933
- * Strategy: partition tools into [static, deferred] and stamp
934
- * `cache_control: ephemeral` on the last static tool.
935
- * Discovered deferred tools that arrive across turns sit *after*
936
- * the breakpoint and don't invalidate the prefix.
937
- */
938
- let toolsForBinding = rawToolsForBinding;
939
- if (agentContext.provider === _enum.Providers.ANTHROPIC &&
940
- agentContext.clientOptions
941
- ?.promptCache === true) {
942
- toolsForBinding =
943
- anthropicToolCache.partitionAndMarkAnthropicToolCache(rawToolsForBinding, anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
944
- }
945
- else if (agentContext.provider === _enum.Providers.OPENROUTER &&
946
- agentContext.clientOptions?.promptCache === true) {
947
- toolsForBinding =
948
- toolCache.partitionAndMarkOpenRouterToolCache(rawToolsForBinding, anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
949
- }
950
- else if (agentContext.provider === _enum.Providers.BEDROCK &&
951
- agentContext.clientOptions?.promptCache === true) {
952
- toolsForBinding =
953
- toolCache$1.partitionAndMarkBedrockToolCache(rawToolsForBinding, anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
954
- }
955
- let model = this.overrideModel ??
956
- init.initializeModel({
957
- tools: toolsForBinding,
958
- provider: agentContext.provider,
959
- clientOptions: agentContext.clientOptions,
960
- });
961
- if (agentContext.systemRunnable) {
962
- model = agentContext.systemRunnable.pipe(model);
963
- }
964
- if (agentContext.tokenCalculationPromise) {
965
- await agentContext.tokenCalculationPromise;
966
- }
967
- if (!config.signal) {
968
- config.signal = this.signal;
969
- }
970
- this.config = config;
971
- let messagesToUse = messages$1;
972
- if (!agentContext.pruneMessages &&
973
- agentContext.tokenCounter &&
974
- agentContext.maxContextTokens != null) {
975
- agentContext.pruneMessages = prune.createPruneMessages({
976
- startIndex: agentContext.indexTokenCountMap[0] != null ? this.startIndex : 0,
977
- provider: agentContext.provider,
978
- tokenCounter: agentContext.tokenCounter,
979
- maxTokens: agentContext.maxContextTokens,
980
- thinkingEnabled: request.isThinkingEnabled(agentContext.provider, agentContext.clientOptions),
981
- indexTokenCountMap: agentContext.indexTokenCountMap,
982
- contextPruningConfig: agentContext.contextPruningConfig,
983
- summarizationEnabled: agentContext.summarizationEnabled,
984
- reserveRatio: agentContext.summarizationConfig?.reserveRatio,
985
- calibrationRatio: agentContext.calibrationRatio,
986
- getInstructionTokens: () => agentContext.instructionTokens,
987
- log: (level, message, data) => {
988
- events.emitAgentLog(config, level, 'prune', message, data, {
989
- runId: this.runId,
990
- agentId,
991
- });
992
- },
993
- });
994
- }
995
- if (agentContext.pruneMessages) {
996
- const { context, indexTokenCountMap, messagesToRefine, prePruneContextTokens, remainingContextTokens, originalToolContent, calibrationRatio, resolvedInstructionOverhead, } = agentContext.pruneMessages({
997
- messages: messages$1,
998
- usageMetadata: agentContext.currentUsage,
999
- lastCallUsage: agentContext.lastCallUsage,
1000
- totalTokensFresh: agentContext.totalTokensFresh,
1001
- });
1002
- agentContext.indexTokenCountMap = indexTokenCountMap;
1003
- if (calibrationRatio != null && calibrationRatio > 0) {
1004
- agentContext.calibrationRatio = calibrationRatio;
1005
- }
1006
- if (resolvedInstructionOverhead != null) {
1007
- agentContext.resolvedInstructionOverhead =
1008
- resolvedInstructionOverhead;
1009
- const nonToolOverhead = agentContext.instructionTokens - agentContext.toolSchemaTokens;
1010
- const calibratedToolTokens = Math.max(0, resolvedInstructionOverhead - nonToolOverhead);
1011
- const currentToolTokens = agentContext.toolSchemaTokens;
1012
- const variance = currentToolTokens > 0
1013
- ? Math.abs(calibratedToolTokens - currentToolTokens) /
1014
- currentToolTokens
1015
- : 1;
1016
- if (variance > CALIBRATION_VARIANCE_THRESHOLD) {
1017
- agentContext.toolSchemaTokens = calibratedToolTokens;
1018
- }
1019
- }
1020
- messagesToUse = context;
1021
- const hasPrunedMessages = agentContext.summarizationEnabled === true &&
1022
- Array.isArray(messagesToRefine) &&
1023
- messagesToRefine.length > 0;
1024
- if (hasPrunedMessages) {
1025
- const shouldSkip = agentContext.shouldSkipSummarization(messages$1.length);
1026
- const triggerResult = !shouldSkip &&
1027
- index.shouldTriggerSummarization({
1028
- trigger: agentContext.summarizationConfig?.trigger,
1029
- maxContextTokens: agentContext.maxContextTokens,
1030
- prePruneContextTokens: prePruneContextTokens != null
1031
- ? prePruneContextTokens + agentContext.instructionTokens
1032
- : undefined,
1033
- remainingContextTokens,
1034
- messagesToRefineCount: messagesToRefine.length,
1035
- });
1036
- if (triggerResult) {
1037
- if (originalToolContent != null && originalToolContent.size > 0) {
1038
- /**
1039
- * Merge never overwrite the pruner's masking record
1040
- * into pendingOriginalToolContent. Carry-over entries
1041
- * from a prior summarize (preserved by the recency
1042
- * window for masked tool messages still in the tail) and
1043
- * the current pruner's new entries are both keyed by
1044
- * indices in the current `state.messages`, so a key-wise
1045
- * union is correct. Overwriting would discard the
1046
- * carry-over and reduce summary fidelity when those
1047
- * masked tail messages eventually move into the head.
1048
- */
1049
- if (agentContext.pendingOriginalToolContent == null) {
1050
- agentContext.pendingOriginalToolContent = originalToolContent;
1051
- }
1052
- else {
1053
- for (const [idx, content] of originalToolContent) {
1054
- agentContext.pendingOriginalToolContent.set(idx, content);
1055
- }
1056
- /**
1057
- * Re-apply the per-store char cap after the union. The
1058
- * pruner enforces ORIGINAL_CONTENT_MAX_CHARS inside its
1059
- * own map via the onContentStored callback, but a
1060
- * key-wise merge with recency carry-over bypasses that
1061
- * accounting and could let the merged map grow without
1062
- * bound across long sessions.
1063
- */
1064
- prune.enforceOriginalContentCap(agentContext.pendingOriginalToolContent);
1065
- }
1066
- }
1067
- events.emitAgentLog(config, 'info', 'graph', 'Summarization triggered', undefined, { runId: this.runId, agentId });
1068
- events.emitAgentLog(config, 'debug', 'graph', 'Summarization trigger details', {
1069
- totalMessages: messages$1.length,
1070
- remainingContextTokens: remainingContextTokens ?? 0,
1071
- summaryVersion: agentContext.summaryVersion + 1,
1072
- toolSchemaTokens: agentContext.toolSchemaTokens,
1073
- instructionTokens: agentContext.instructionTokens,
1074
- systemMessageTokens: agentContext.systemMessageTokens,
1075
- }, { runId: this.runId, agentId });
1076
- agentContext.markSummarizationTriggered(messages$1.length);
1077
- return {
1078
- summarizationRequest: {
1079
- remainingContextTokens: remainingContextTokens ?? 0,
1080
- agentId: agentId || agentContext.agentId,
1081
- },
1082
- };
1083
- }
1084
- if (shouldSkip) {
1085
- events.emitAgentLog(config, 'debug', 'graph', 'Summarization skipped — no new messages or per-run cap reached', {
1086
- messageCount: messages$1.length,
1087
- messagesToRefineCount: messagesToRefine.length,
1088
- contextLength: context.length,
1089
- }, { runId: this.runId, agentId });
1090
- }
1091
- }
1092
- }
1093
- let finalMessages = messagesToUse;
1094
- if (agentContext.useLegacyContent) {
1095
- finalMessages = content.formatContentStrings(finalMessages);
1096
- }
1097
- const lastMessageX = finalMessages.length >= 2
1098
- ? finalMessages[finalMessages.length - 2]
1099
- : null;
1100
- const lastMessageY = finalMessages.length >= 1
1101
- ? finalMessages[finalMessages.length - 1]
1102
- : null;
1103
- const anthropicLike = llm.isAnthropicLike(agentContext.provider, agentContext.clientOptions);
1104
- if (agentContext.provider === _enum.Providers.BEDROCK &&
1105
- lastMessageX instanceof messages.AIMessageChunk &&
1106
- lastMessageY instanceof messages.ToolMessage &&
1107
- typeof lastMessageX.content === 'string') {
1108
- const trimmed = lastMessageX.content.trim();
1109
- finalMessages[finalMessages.length - 2].content =
1110
- trimmed.length > 0 ? [{ type: 'text', text: trimmed }] : '';
1111
- }
1112
- if (lastMessageY instanceof messages.ToolMessage) {
1113
- if (anthropicLike) {
1114
- core.formatAnthropicArtifactContent(finalMessages);
1115
- }
1116
- else if ((llm.isOpenAILike(agentContext.provider) &&
1117
- agentContext.provider !== _enum.Providers.DEEPSEEK) ||
1118
- llm.isGoogleLike(agentContext.provider)) {
1119
- core.formatArtifactPayload(finalMessages);
1120
- }
1121
- }
1122
- if (agentContext.provider === _enum.Providers.ANTHROPIC) {
1123
- const anthropicOptions = agentContext.clientOptions;
1124
- if (anthropicOptions?.promptCache === true &&
1125
- !agentContext.systemRunnable) {
1126
- finalMessages = cache.addCacheControl(finalMessages);
1127
- }
1128
- }
1129
- else if (agentContext.provider === _enum.Providers.BEDROCK) {
1130
- const bedrockOptions = agentContext.clientOptions;
1131
- if (bedrockOptions?.promptCache === true) {
1132
- finalMessages = cache.addBedrockCacheControl(finalMessages);
1133
- }
1134
- }
1135
- else if (agentContext.provider === _enum.Providers.OPENROUTER) {
1136
- const openRouterOptions = agentContext.clientOptions;
1137
- if (openRouterOptions?.promptCache === true &&
1138
- !agentContext.systemRunnable) {
1139
- finalMessages = cache.addCacheControl(finalMessages);
1140
- }
1141
- }
1142
- if (request.isThinkingEnabled(agentContext.provider, agentContext.clientOptions)) {
1143
- /**
1144
- * Pass `this.startIndex` so the function can distinguish CURRENT-run
1145
- * AI messages (the agent's own iterations — possibly without a
1146
- * leading thinking block, which Claude is allowed to skip) from
1147
- * historical context that genuinely needs the
1148
- * `[Previous agent context]` placeholder. Without this signal the
1149
- * function would convert the agent's own in-run tool_use messages,
1150
- * polluting the next iteration's prompt with a placeholder the
1151
- * model treats as suspicious injected content.
1152
- */
1153
- finalMessages = format.ensureThinkingBlockInMessages(finalMessages, agentContext.provider, config, this.startIndex);
1154
- }
1155
- // Intentionally broad: runs when the pruner wasn't used OR any post-pruning
1156
- // transform (addCacheControl, ensureThinkingBlock, etc.) reassigned finalMessages.
1157
- // sanitizeOrphanToolBlocks fast-paths to a Set diff check when no orphans exist,
1158
- // so the cost is negligible and this acts as a safety net for Anthropic/Bedrock.
1159
- const needsOrphanSanitize = anthropicLike &&
1160
- (!agentContext.pruneMessages || finalMessages !== messagesToUse);
1161
- if (needsOrphanSanitize) {
1162
- const beforeSanitize = finalMessages.length;
1163
- finalMessages = prune.sanitizeOrphanToolBlocks(finalMessages);
1164
- if (finalMessages.length !== beforeSanitize) {
1165
- events.emitAgentLog(config, 'warn', 'sanitize', 'Orphan tool blocks removed', {
1166
- before: beforeSanitize,
1167
- after: finalMessages.length,
1168
- dropped: beforeSanitize - finalMessages.length,
1169
- }, { runId: this.runId, agentId });
1170
- }
1171
- }
1172
- if (agentContext.lastStreamCall != null &&
1173
- agentContext.streamBuffer != null) {
1174
- const timeSinceLastCall = Date.now() - agentContext.lastStreamCall;
1175
- if (timeSinceLastCall < agentContext.streamBuffer) {
1176
- const timeToWait = Math.ceil((agentContext.streamBuffer - timeSinceLastCall) / 1000) *
1177
- 1000;
1178
- await run.sleep(timeToWait);
1179
- }
1180
- }
1181
- agentContext.lastStreamCall = Date.now();
1182
- agentContext.markTokensStale();
1183
- let result;
1184
- const fallbacks = agentContext.clientOptions?.fallbacks ??
1185
- [];
1186
- if (finalMessages.length === 0 &&
1187
- !agentContext.hasPendingCompactionSummary()) {
1188
- const budgetBreakdown = agentContext.getTokenBudgetBreakdown(messages$1);
1189
- const breakdown = agentContext.formatTokenBudgetBreakdown(messages$1);
1190
- const instructionsExceedBudget = budgetBreakdown.instructionTokens > budgetBreakdown.maxContextTokens;
1191
- let guidance;
1192
- if (instructionsExceedBudget) {
1193
- const toolPct = budgetBreakdown.toolSchemaTokens > 0
1194
- ? Math.round((budgetBreakdown.toolSchemaTokens /
1195
- budgetBreakdown.instructionTokens) *
1196
- 100)
1197
- : 0;
1198
- guidance =
1199
- toolPct > 50
1200
- ? `Tool definitions consume ${budgetBreakdown.toolSchemaTokens} tokens (${toolPct}% of instructions) across ${budgetBreakdown.toolCount} tools, exceeding maxContextTokens (${budgetBreakdown.maxContextTokens}). Reduce the number of tools or increase maxContextTokens.`
1201
- : `Instructions (${budgetBreakdown.instructionTokens} tokens) exceed maxContextTokens (${budgetBreakdown.maxContextTokens}). Increase maxContextTokens or shorten the system prompt.`;
1202
- if (agentContext.summarizationEnabled === true) {
1203
- guidance +=
1204
- ' Summarization was skipped because the summary would further increase the instruction overhead.';
1205
- }
1206
- }
1207
- else {
1208
- guidance =
1209
- 'Please increase the context window size or make your message shorter.';
1210
- }
1211
- events.emitAgentLog(config, 'error', 'graph', 'Empty messages after pruning', {
1212
- messageCount: messages$1.length,
1213
- instructionsExceedBudget,
1214
- breakdown,
1215
- }, { runId: this.runId, agentId });
1216
- throw new Error(JSON.stringify({
1217
- type: 'empty_messages',
1218
- info: `Message pruning removed all messages as none fit in the context window. ${guidance}\n${breakdown}`,
1219
- }));
1220
- }
1221
- const invokeStart = Date.now();
1222
- const invokeMeta = { runId: this.runId, agentId };
1223
- events.emitAgentLog(config, 'debug', 'graph', 'Invoking LLM', {
1224
- messageCount: finalMessages.length,
1225
- provider: agentContext.provider,
1226
- }, invokeMeta, { force: true });
1227
- const langfuse$1 = langfuseToolOutputTracing.resolveLangfuseConfig(this.langfuse, agentContext.langfuse);
1228
- const traceMetadata = langfuse.createLangfuseTraceMetadata({
1229
- messageId: this.runId,
1230
- parentMessageId: config.configurable?.requestBody?.parentMessageId,
1231
- agentId,
1232
- agentName: agentContext.name,
1233
- });
1234
- let langfuseHandler;
1235
- let invokeConfig = {
1236
- ...config,
1237
- metadata: {
1238
- ...(config.metadata ?? {}),
1239
- ...traceMetadata,
1240
- },
1241
- };
1242
- instrumentation.initializeLangfuseTracing(langfuse$1);
1243
- if (callbacks.findCallback(config.callbacks, langfuse.isLangfuseCallbackHandler) == null) {
1244
- langfuseHandler = langfuse.createLangfuseHandler({
1245
- langfuse: langfuse$1,
1246
- userId: config.configurable?.user_id,
1247
- sessionId: config.configurable?.thread_id,
1248
- traceMetadata,
1249
- tags: ['librechat', 'agent'],
1250
- });
1251
- if (langfuseHandler != null) {
1252
- invokeConfig = {
1253
- ...invokeConfig,
1254
- callbacks: callbacks.appendCallbacks(invokeConfig.callbacks, [
1255
- langfuseHandler,
1256
- ]),
1257
- };
1258
- }
1259
- }
1260
- const metadata = config.metadata;
1261
- try {
1262
- result = await langfuseToolOutputTracing.withLangfuseToolOutputTracingConfig(this.langfuse, () => invoke.attemptInvoke({
1263
- model: (this.overrideModel ?? model),
1264
- messages: finalMessages,
1265
- provider: agentContext.provider,
1266
- context: this,
1267
- }, invokeConfig), agentContext.langfuse);
1268
- }
1269
- catch (primaryError) {
1270
- clearCurrentDeltaStepMarkers({
1271
- graph: this,
1272
- metadata,
1273
- });
1274
- result = await langfuseToolOutputTracing.withLangfuseToolOutputTracingConfig(this.langfuse, () => invoke.tryFallbackProviders({
1275
- fallbacks,
1276
- tools: agentContext.tools,
1277
- messages: finalMessages,
1278
- config: invokeConfig,
1279
- primaryError,
1280
- context: this,
1281
- }), agentContext.langfuse);
1282
- }
1283
- finally {
1284
- await langfuse.disposeLangfuseHandler(langfuseHandler);
1285
- }
1286
- if (!result) {
1287
- throw new Error('No result after model invocation');
1288
- }
1289
- /**
1290
- * Fallback: populate toolCallStepIds in the graph execution context.
1291
- *
1292
- * When model.stream() is available (the common case), attemptInvoke
1293
- * processes all chunks through a local ChatModelStreamHandler which
1294
- * creates run steps and populates toolCallStepIds before returning.
1295
- * The code below is a fallback for the rare case where model.stream
1296
- * is unavailable and model.invoke() was used instead.
1297
- *
1298
- * Text content is dispatched FIRST so that MESSAGE_CREATION is the
1299
- * current step when handleToolCalls runs. handleToolCalls then creates
1300
- * TOOL_CALLS on top of it. The dedup in getMessageId and
1301
- * toolCallStepIds.has makes this safe when attemptInvoke already
1302
- * handled everything both paths become no-ops.
1303
- */
1304
- const responseMessage = result.messages?.[0];
1305
- const toolCalls = responseMessage
1306
- ?.tool_calls;
1307
- const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
1308
- const responseReasoningContent = getResponseReasoningContent({
1309
- responseMessage: responseMessage,
1310
- reasoningKey: agentContext.reasoningKey,
1311
- });
1312
- const textMessageContent = getMessageDeltaContent(agentContext.provider, responseMessage?.content);
1313
- const hasStreamedTextDeltaStep = hasCurrentTextDeltaStep({
1314
- graph: this,
1315
- metadata,
1316
- });
1317
- const hasStreamedReasoningDeltaStep = hasCurrentReasoningDeltaStep({
1318
- graph: this,
1319
- metadata,
1320
- });
1321
- const dispatchableFinalReasoningContent = getDispatchableFinalReasoningContent({
1322
- agentContext,
1323
- responseReasoningContent,
1324
- hasStreamedTextDeltaStep,
1325
- hasStreamedReasoningDeltaStep,
1326
- });
1327
- if (hasToolCalls) {
1328
- const dispatchedReasoning = dispatchableFinalReasoningContent != null &&
1329
- (await dispatchReasoningContent({
1330
- graph: this,
1331
- agentContext,
1332
- reasoningContent: dispatchableFinalReasoningContent,
1333
- metadata,
1334
- }));
1335
- if (dispatchedReasoning) {
1336
- markPostReasoningContent(agentContext);
1337
- }
1338
- if (textMessageContent != null && !hasStreamedTextDeltaStep) {
1339
- const stepKey = this.getStepKey(metadata);
1340
- const dispatchedText = await dispatchTextMessageContent({
1341
- graph: this,
1342
- stepKey,
1343
- provider: agentContext.provider,
1344
- content: textMessageContent,
1345
- metadata,
1346
- });
1347
- if (dispatchedText) {
1348
- markPostReasoningContent(agentContext);
1349
- }
1350
- }
1351
- await handlers.handleToolCalls(toolCalls, metadata, this);
1352
- }
1353
- /**
1354
- * When streaming events are unavailable, ChatModelStreamHandler never
1355
- * fires. Dispatch final reasoning/text content here. getMessageId makes
1356
- * this a no-op when the streaming path already handled the same step.
1357
- */
1358
- if (!hasToolCalls && responseMessage != null) {
1359
- const dispatchedReasoning = dispatchableFinalReasoningContent != null &&
1360
- (await dispatchReasoningContent({
1361
- graph: this,
1362
- agentContext,
1363
- reasoningContent: dispatchableFinalReasoningContent,
1364
- metadata,
1365
- }));
1366
- if (dispatchedReasoning && textMessageContent != null) {
1367
- markPostReasoningContent(agentContext);
1368
- }
1369
- if (textMessageContent != null && !hasStreamedTextDeltaStep) {
1370
- const stepKey = this.getStepKey(metadata);
1371
- await dispatchTextMessageContent({
1372
- graph: this,
1373
- stepKey,
1374
- provider: agentContext.provider,
1375
- content: textMessageContent,
1376
- metadata,
1377
- });
1378
- }
1379
- }
1380
- const invokeElapsed = ((Date.now() - invokeStart) / 1000).toFixed(2);
1381
- agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
1382
- if (agentContext.currentUsage) {
1383
- agentContext.updateLastCallUsage(agentContext.currentUsage);
1384
- events.emitAgentLog(config, 'debug', 'graph', `LLM call complete (${invokeElapsed}s)`, {
1385
- ...agentContext.currentUsage,
1386
- elapsedSeconds: Number(invokeElapsed),
1387
- instructionTokens: agentContext.instructionTokens,
1388
- toolSchemaTokens: agentContext.toolSchemaTokens,
1389
- messageCount: finalMessages.length,
1390
- }, invokeMeta, { force: true });
1391
- }
1392
- else {
1393
- events.emitAgentLog(config, 'debug', 'graph', `LLM call complete (${invokeElapsed}s)`, {
1394
- elapsedSeconds: Number(invokeElapsed),
1395
- messageCount: finalMessages.length,
1396
- }, invokeMeta, { force: true });
1397
- }
1398
- this.cleanupSignalListener();
1399
- return result;
1400
- };
1401
- }
1402
- createAgentNode(agentId) {
1403
- const getConfig = () => this.config;
1404
- const agentContext = this.agentContexts.get(agentId);
1405
- if (!agentContext) {
1406
- throw new Error(`Agent context not found for agentId: ${agentId}`);
1407
- }
1408
- /**
1409
- * Depth countdown across graph boundaries: the parent's `maxSubagentDepth`
1410
- * becomes this executor's `maxDepth`. When the child graph is constructed,
1411
- * `buildChildInputs()` decrements `maxSubagentDepth` on the child's
1412
- * `AgentInputs` (only when `allowNested: true`; otherwise subagentConfigs
1413
- * are stripped entirely). The child graph's own `createAgentNode()` then
1414
- * reads the decremented value here and creates a narrower executor —
1415
- * recursion is bounded even though each graph has its own separate
1416
- * executor instance.
1417
- */
1418
- const effectiveSubagentDepth = agentContext.maxSubagentDepth ?? 1;
1419
- if (agentContext.subagentConfigs != null &&
1420
- agentContext.subagentConfigs.length > 0 &&
1421
- effectiveSubagentDepth > 0) {
1422
- const resolvedConfigs = SubagentExecutor.resolveSubagentConfigs(agentContext.subagentConfigs, agentContext);
1423
- if (resolvedConfigs.length > 0) {
1424
- const getParentHandlerRegistry = () => this.handlerRegistry;
1425
- const executor = new SubagentExecutor.SubagentExecutor({
1426
- configs: new Map(resolvedConfigs.map((c) => [c.type, c])),
1427
- parentSignal: this.signal,
1428
- hookRegistry: this.hookRegistry,
1429
- /** Lazy — Run wires the registry onto the graph AFTER
1430
- * `createWorkflow()` runs, so a direct capture here would be
1431
- * `undefined` at construction time. */
1432
- parentHandlerRegistry: getParentHandlerRegistry,
1433
- parentRunId: this.runId ?? '',
1434
- parentAgentId: agentContext.agentId,
1435
- langfuse: this.langfuse,
1436
- tokenCounter: agentContext.tokenCounter,
1437
- maxDepth: effectiveSubagentDepth,
1438
- createChildGraph: (input) => {
1439
- const childGraph = new StandardGraph(input);
1440
- childGraph.hookRegistry = this.hookRegistry;
1441
- /**
1442
- * Do not propagate `humanInTheLoop` into the child graph yet:
1443
- * nested subagent interrupts need a stable child checkpoint and
1444
- * resume bridge. Child hooks still fire; `ask` decisions fail
1445
- * closed inside the subagent until that flow is implemented.
1446
- */
1447
- childGraph.toolOutputReferences = this.toolOutputReferences;
1448
- childGraph.eagerEventToolExecution = this.eagerEventToolExecution;
1449
- childGraph.toolExecution = this.toolExecution;
1450
- childGraph.eventToolExecutionAvailable =
1451
- this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_TOOL_EXECUTE) !=
1452
- null;
1453
- return childGraph;
1454
- },
1455
- });
1456
- const subagentTool = tools$1.tool(async (rawInput, config) => {
1457
- const input = rawInput;
1458
- const description = typeof input.description === 'string' &&
1459
- input.description.trim().length > 0
1460
- ? input.description
1461
- : 'No task description provided';
1462
- const subagentType = typeof input.subagent_type === 'string' ? input.subagent_type : '';
1463
- const threadId = config.configurable?.thread_id;
1464
- /**
1465
- * When the tool is dispatched from an LLM's `tool_call`, LangChain
1466
- * threads the originating `ToolCall` onto the RunnableConfig as
1467
- * `config.toolCall` (see `ToolRunnableConfig` in
1468
- * `@langchain/core/tools` — internal but stable since ≥0.3.x).
1469
- * Surfacing its id lets hosts correlate `SubagentUpdateEvent`s
1470
- * back to the parent's `tool_call_id` deterministically — no
1471
- * temporal heuristics needed. If a future LangChain version
1472
- * changes the threading, the type-guarded read falls back to
1473
- * `undefined` and the correlation degrades gracefully.
1474
- */
1475
- const toolCall = config.toolCall;
1476
- const parentToolCallId = typeof toolCall?.id === 'string' ? toolCall.id : undefined;
1477
- const result = await executor.execute({
1478
- description,
1479
- subagentType,
1480
- threadId,
1481
- parentToolCallId,
1482
- /**
1483
- * Forward the parent's `configurable` so host-set fields
1484
- * (`requestBody`, `user`, etc.) propagate into the child
1485
- * workflow. The executor scrubs run-identity fields before
1486
- * forwarding see `SubagentExecuteParams.parentConfigurable`.
1487
- */
1488
- parentConfigurable: config.configurable,
1489
- });
1490
- return result.content;
1491
- }, SubagentTool.buildSubagentToolParams(resolvedConfigs));
1492
- if (!agentContext.graphTools) {
1493
- agentContext.graphTools = [];
1494
- }
1495
- agentContext.graphTools.push(subagentTool);
1496
- /**
1497
- * Refresh toolSchemaTokens to include the subagent tool's schema.
1498
- * `calculateInstructionTokens()` was kicked off in `fromConfig()`
1499
- * before graphTools was populated, so its result did not count this
1500
- * tool. Without this retrigger, token-budget/pruning logic
1501
- * underestimates prompt overhead.
1502
- */
1503
- if (agentContext.tokenCounter) {
1504
- const { tokenCounter, baseIndexTokenCountMap } = agentContext;
1505
- agentContext.tokenCalculationPromise = agentContext
1506
- .calculateInstructionTokens(tokenCounter)
1507
- .then(() => {
1508
- agentContext.updateTokenMapWithInstructions(baseIndexTokenCountMap);
1509
- })
1510
- .catch((err) => {
1511
- console.error('Error recalculating instruction tokens after subagent tool injection:', err);
1512
- });
1513
- }
1514
- }
1515
- }
1516
- const agentNode = `${AGENT}${agentId}`;
1517
- const toolNode = `${TOOLS}${agentId}`;
1518
- const summarizeNode = `${SUMMARIZE}${agentId}`;
1519
- const routeMessage = (state, config) => {
1520
- this.config = config;
1521
- if (state.summarizationRequest != null) {
1522
- return summarizeNode;
1523
- }
1524
- return ToolNode.toolsCondition(state, toolNode, this.invokedToolIds);
1525
- };
1526
- const StateAnnotation = langgraph.Annotation.Root({
1527
- messages: langgraph.Annotation({
1528
- reducer: reducer.messagesStateReducer,
1529
- default: () => [],
1530
- }),
1531
- summarizationRequest: langgraph.Annotation({
1532
- reducer: (_, b) => b,
1533
- default: () => undefined,
1534
- }),
1535
- });
1536
- const workflow = new langgraph.StateGraph(StateAnnotation)
1537
- .addNode(agentNode, this.createCallModel(agentId))
1538
- .addNode(toolNode, this.initializeTools({
1539
- currentTools: agentContext.tools,
1540
- currentToolMap: agentContext.toolMap,
1541
- agentContext,
1542
- }))
1543
- .addNode(summarizeNode, node.createSummarizeNode({
1544
- agentContext,
1545
- graph: {
1546
- contentData: this.contentData,
1547
- contentIndexMap: this.contentIndexMap,
1548
- get config() {
1549
- return getConfig();
1550
- },
1551
- runId: this.runId,
1552
- isMultiAgent: this.isMultiAgentGraph(),
1553
- hookRegistry: this.hookRegistry,
1554
- dispatchRunStep: async (runStep, nodeConfig) => {
1555
- this.contentData.push(runStep);
1556
- this.contentIndexMap.set(runStep.id, runStep.index);
1557
- const resolvedConfig = nodeConfig ?? this.config;
1558
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_RUN_STEP);
1559
- if (handler) {
1560
- await handler.handle(_enum.GraphEvents.ON_RUN_STEP, runStep, resolvedConfig?.configurable, this);
1561
- this.handlerDispatchedStepIds.add(runStep.id);
1562
- }
1563
- const unmarkHandlerDispatchedEvent = handler
1564
- ? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP, runStep.id)
1565
- : undefined;
1566
- try {
1567
- if (resolvedConfig) {
1568
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, resolvedConfig);
1569
- }
1570
- }
1571
- finally {
1572
- unmarkHandlerDispatchedEvent?.();
1573
- }
1574
- },
1575
- dispatchRunStepCompleted: async (stepId, result, nodeConfig) => {
1576
- const resolvedConfig = nodeConfig ?? this.config;
1577
- const runStep = this.contentData.find((s) => s.id === stepId);
1578
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_RUN_STEP_COMPLETED);
1579
- if (handler) {
1580
- await handler.handle(_enum.GraphEvents.ON_RUN_STEP_COMPLETED, {
1581
- result: {
1582
- ...result,
1583
- id: stepId,
1584
- index: runStep?.index ?? 0,
1585
- },
1586
- }, resolvedConfig?.configurable, this);
1587
- }
1588
- },
1589
- },
1590
- generateStepId: (stepKey) => this.generateStepId(stepKey),
1591
- }))
1592
- .addEdge(langgraph.START, agentNode)
1593
- .addConditionalEdges(agentNode, routeMessage)
1594
- .addEdge(summarizeNode, agentNode)
1595
- .addEdge(toolNode, agentContext.toolEnd ? langgraph.END : agentNode);
1596
- return workflow.compile();
1597
- }
1598
- createWorkflow() {
1599
- const agentNode = this.createAgentNode(this.defaultAgentId);
1600
- const StateAnnotation = langgraph.Annotation.Root({
1601
- messages: langgraph.Annotation({
1602
- reducer: (a, b) => {
1603
- if (!this.messages.length) {
1604
- this.startIndex = a.length + b.length;
1605
- }
1606
- const result = reducer.messagesStateReducer(a, b);
1607
- this.messages = result;
1608
- return result;
1609
- },
1610
- default: () => [],
1611
- }),
1612
- });
1613
- const workflow = new langgraph.StateGraph(StateAnnotation)
1614
- .addNode(this.defaultAgentId, agentNode, { ends: [langgraph.END] })
1615
- .addEdge(langgraph.START, this.defaultAgentId)
1616
- // LangGraph compile() types are overly strict for opt-in options
1617
- .compile(this.compileOptions);
1618
- return workflow;
1619
- }
1620
- /**
1621
- * Indicates if this is a multi-agent graph.
1622
- * Override in MultiAgentGraph to return true.
1623
- * Used to conditionally include agentId in RunStep for frontend rendering.
1624
- */
1625
- isMultiAgentGraph() {
1626
- return false;
1627
- }
1628
- /**
1629
- * Get the parallel group ID for an agent, if any.
1630
- * Override in MultiAgentGraph to provide actual group IDs.
1631
- * Group IDs are incrementing numbers (1, 2, 3...) reflecting execution order.
1632
- * @param _agentId - The agent ID to look up
1633
- * @returns undefined for StandardGraph (no parallel groups), or group number for MultiAgentGraph
1634
- */
1635
- getParallelGroupIdForAgent(_agentId) {
1636
- return undefined;
1637
- }
1638
- /* Dispatchers */
1639
- /**
1640
- * Dispatches a run step to the client, returns the step ID
1641
- */
1642
- async dispatchRunStep(stepKey, stepDetails, metadata) {
1643
- if (!this.config) {
1644
- throw new Error('No config provided');
1645
- }
1646
- const [stepId, stepIndex] = this.generateStepId(stepKey);
1647
- if (stepDetails.type === _enum.StepTypes.TOOL_CALLS && stepDetails.tool_calls) {
1648
- for (const tool_call of stepDetails.tool_calls) {
1649
- const toolCallId = tool_call.id ?? '';
1650
- if (!toolCallId || this.toolCallStepIds.has(toolCallId)) {
1651
- continue;
1652
- }
1653
- this.toolCallStepIds.set(toolCallId, stepId);
1654
- }
1655
- }
1656
- const runStep = {
1657
- stepIndex,
1658
- id: stepId,
1659
- type: stepDetails.type,
1660
- index: this.contentData.length,
1661
- stepDetails,
1662
- usage: null,
1663
- };
1664
- const runId = this.runId ?? '';
1665
- if (runId) {
1666
- runStep.runId = runId;
1667
- }
1668
- if (metadata) {
1669
- try {
1670
- const agentContext = this.getAgentContext(metadata);
1671
- if (this.isMultiAgentGraph() && agentContext.agentId) {
1672
- runStep.agentId = agentContext.agentId;
1673
- const groupId = this.getParallelGroupIdForAgent(agentContext.agentId);
1674
- if (groupId != null) {
1675
- runStep.groupId = groupId;
1676
- }
1677
- }
1678
- }
1679
- catch (_e) {
1680
- /** If we can't get agent context, that's okay - agentId remains undefined */
1681
- }
1682
- }
1683
- this.contentData.push(runStep);
1684
- this.contentIndexMap.set(stepId, runStep.index);
1685
- // Primary dispatch: handler registry (reliable, always works).
1686
- // This mirrors how handleToolCallCompleted dispatches ON_RUN_STEP_COMPLETED
1687
- // via the handler registry, ensuring the event always reaches the handler
1688
- // even when LangGraph's callback system drops the custom event.
1689
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_RUN_STEP);
1690
- if (handler) {
1691
- await handler.handle(_enum.GraphEvents.ON_RUN_STEP, runStep, metadata, this);
1692
- this.handlerDispatchedStepIds.add(stepId);
1693
- }
1694
- // Secondary dispatch: custom event for LangGraph callback chain
1695
- // (tracing, Langfuse, external consumers). May be silently dropped
1696
- // in some scenarios (stale run ID, subgraph callback propagation issues),
1697
- // but the primary dispatch above guarantees the event reaches the handler.
1698
- // The customEventCallback in run.ts skips events already dispatched above
1699
- // to prevent double handling.
1700
- const unmarkHandlerDispatchedEvent = handler
1701
- ? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP, stepId)
1702
- : undefined;
1703
- try {
1704
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP, runStep, this.config);
1705
- }
1706
- finally {
1707
- unmarkHandlerDispatchedEvent?.();
1708
- }
1709
- return stepId;
1710
- }
1711
- /**
1712
- * Static version of handleToolCallError to avoid creating strong references
1713
- * that prevent garbage collection
1714
- */
1715
- static async handleToolCallErrorStatic(graph, data, metadata) {
1716
- if (!graph.config) {
1717
- throw new Error('No config provided');
1718
- }
1719
- if (!data.id) {
1720
- console.warn('No Tool ID provided for Tool Error');
1721
- return;
1722
- }
1723
- const stepId = graph.toolCallStepIds.get(data.id) ?? '';
1724
- if (!stepId) {
1725
- throw new Error(`No stepId found for tool_call_id ${data.id}`);
1726
- }
1727
- const { name, input: args, error } = data;
1728
- const runStep = graph.getRunStep(stepId);
1729
- if (!runStep) {
1730
- throw new Error(`No run step found for stepId ${stepId}`);
1731
- }
1732
- const tool_call = {
1733
- id: data.id,
1734
- name: name || '',
1735
- args: typeof args === 'string' ? args : JSON.stringify(args),
1736
- output: `Error processing tool${error?.message != null ? `: ${error.message}` : ''}`,
1737
- progress: 1,
1738
- };
1739
- await graph.handlerRegistry
1740
- ?.getHandler(_enum.GraphEvents.ON_RUN_STEP_COMPLETED)
1741
- ?.handle(_enum.GraphEvents.ON_RUN_STEP_COMPLETED, {
1742
- result: {
1743
- id: stepId,
1744
- index: runStep.index,
1745
- type: 'tool_call',
1746
- tool_call,
1747
- },
1748
- }, metadata, graph);
1749
- }
1750
- /**
1751
- * Instance method that delegates to the static method
1752
- * Kept for backward compatibility
1753
- */
1754
- async handleToolCallError(data, metadata) {
1755
- await StandardGraph.handleToolCallErrorStatic(this, data, metadata);
1756
- }
1757
- async dispatchRunStepDelta(id, delta, metadata) {
1758
- if (!this.config) {
1759
- throw new Error('No config provided');
1760
- }
1761
- else if (!id) {
1762
- throw new Error('No step ID found');
1763
- }
1764
- const runStepDelta = {
1765
- id,
1766
- delta,
1767
- };
1768
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_RUN_STEP_DELTA);
1769
- if (handler) {
1770
- await handler.handle(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, metadata, this);
1771
- this.handlerDispatchedStepIds.add(id);
1772
- }
1773
- const unmarkHandlerDispatchedEvent = handler
1774
- ? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, id)
1775
- : undefined;
1776
- try {
1777
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_RUN_STEP_DELTA, runStepDelta, this.config);
1778
- }
1779
- finally {
1780
- unmarkHandlerDispatchedEvent?.();
1781
- }
1782
- }
1783
- async dispatchMessageDelta(id, delta, metadata) {
1784
- if (!this.config) {
1785
- throw new Error('No config provided');
1786
- }
1787
- const messageDelta = {
1788
- id,
1789
- delta,
1790
- };
1791
- if (hasTextDeltaContent(delta.content)) {
1792
- this.messageStepHasTextDeltas.add(id);
1793
- }
1794
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_MESSAGE_DELTA);
1795
- if (handler) {
1796
- await handler.handle(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, metadata, this);
1797
- this.handlerDispatchedStepIds.add(id);
1798
- }
1799
- const unmarkHandlerDispatchedEvent = handler
1800
- ? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, id)
1801
- : undefined;
1802
- try {
1803
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_MESSAGE_DELTA, messageDelta, this.config);
1804
- }
1805
- finally {
1806
- unmarkHandlerDispatchedEvent?.();
1807
- }
1808
- }
1809
- dispatchReasoningDelta = async (stepId, delta, metadata) => {
1810
- if (!this.config) {
1811
- throw new Error('No config provided');
1812
- }
1813
- const reasoningDelta = {
1814
- id: stepId,
1815
- delta,
1816
- };
1817
- if (hasReasoningDeltaContent(delta.content)) {
1818
- this.reasoningStepHasDeltas.add(stepId);
1819
- }
1820
- const handler = this.handlerRegistry?.getHandler(_enum.GraphEvents.ON_REASONING_DELTA);
1821
- if (handler) {
1822
- await handler.handle(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, metadata, this);
1823
- this.handlerDispatchedStepIds.add(stepId);
1824
- }
1825
- const unmarkHandlerDispatchedEvent = handler
1826
- ? this.markHandlerDispatchedEvent(_enum.GraphEvents.ON_REASONING_DELTA, stepId)
1827
- : undefined;
1828
- try {
1829
- await events.safeDispatchCustomEvent(_enum.GraphEvents.ON_REASONING_DELTA, reasoningDelta, this.config);
1830
- }
1831
- finally {
1832
- unmarkHandlerDispatchedEvent?.();
1833
- }
1834
- };
1835
- }
1836
-
206
+ var Graph = class {
207
+ messageStepHasTextDeltas = /* @__PURE__ */ new Set();
208
+ messageStepHasToolCalls = /* @__PURE__ */ new Map();
209
+ messageIdsByStepKey = /* @__PURE__ */ new Map();
210
+ prelimMessageIdsByStepKey = /* @__PURE__ */ new Map();
211
+ config;
212
+ contentData = [];
213
+ stepKeyIds = /* @__PURE__ */ new Map();
214
+ contentIndexMap = /* @__PURE__ */ new Map();
215
+ toolCallStepIds = /* @__PURE__ */ new Map();
216
+ /**
217
+ * Step IDs dispatched through the handler registry during this run.
218
+ * Event echo suppression is tracked separately so repeated deltas for
219
+ * the same step are scoped to the active custom event dispatch.
220
+ */
221
+ handlerDispatchedStepIds = /* @__PURE__ */ new Set();
222
+ reasoningStepHasDeltas = /* @__PURE__ */ new Set();
223
+ handlerDispatchedEventCounts = /* @__PURE__ */ new Map();
224
+ signal;
225
+ /** Set of invoked tool call IDs from non-message run steps completed mid-run, if any */
226
+ invokedToolIds;
227
+ handlerRegistry;
228
+ /**
229
+ * True when event-driven tool execution can be routed through callbacks even
230
+ * though this graph intentionally does not own the full handler registry.
231
+ * Self-spawned subagent graphs use this shape: their callback forwarder sends
232
+ * `ON_TOOL_EXECUTE` to the parent's handler, while child run-step events stay
233
+ * wrapped as `ON_SUBAGENT_UPDATE` instead of leaking as parent events.
234
+ */
235
+ eventToolExecutionAvailable = false;
236
+ hookRegistry;
237
+ /**
238
+ * Run-scoped HITL configuration. When `humanInTheLoop?.enabled` is
239
+ * `true`, `ToolNode` raises a real `interrupt()` for `PreToolUse`
240
+ * `ask` decisions instead of treating them as a synchronous deny.
241
+ * Threaded from `RunConfig.humanInTheLoop`.
242
+ */
243
+ humanInTheLoop;
244
+ /**
245
+ * Run-scoped config for the tool output reference registry. Threaded
246
+ * from `RunConfig.toolOutputReferences` down into every ToolNode this
247
+ * graph compiles.
248
+ */
249
+ toolOutputReferences;
250
+ /**
251
+ * Run-scoped Langfuse defaults. Per-agent config wins when present.
252
+ */
253
+ langfuse;
254
+ /**
255
+ * Run-scoped opt-in for eager event-driven tool execution. The stream
256
+ * handler may prestart eligible event-driven tools; ToolNode later
257
+ * consumes the settled promises while preserving final ToolMessage order.
258
+ */
259
+ eagerEventToolExecution;
260
+ eagerEventToolExecutions = /* @__PURE__ */ new Map();
261
+ eagerEventToolUsageCount = /* @__PURE__ */ new Map();
262
+ eagerEventToolUsageCountsByAgentId = /* @__PURE__ */ new Map();
263
+ eagerEventToolCallChunks = /* @__PURE__ */ new Map();
264
+ /**
265
+ * Run-scoped execution backend for built-in code tools. Defaults to the
266
+ * remote Code API sandbox when unset.
267
+ */
268
+ toolExecution;
269
+ /**
270
+ * Shared registry instance used by every ToolNode compiled from this
271
+ * graph. Lazily constructed on first access so multi-agent graphs
272
+ * produce one registry per run (not one per agent), letting cross-
273
+ * agent `{{tool<i>turn<n>}}` substitutions resolve.
274
+ */
275
+ _toolOutputRegistry;
276
+ /**
277
+ * Tool session contexts for automatic state persistence across tool invocations.
278
+ * Keyed by tool name (e.g., Constants.EXECUTE_CODE).
279
+ * Currently supports code execution session tracking (session_id, files).
280
+ */
281
+ sessions = /* @__PURE__ */ new Map();
282
+ /**
283
+ * Clears heavy references to allow GC to reclaim memory held by
284
+ * LangGraph's internal config / AsyncLocalStorage RunTree chain.
285
+ * Call after a run completes and content has been extracted.
286
+ */
287
+ clearHeavyState() {
288
+ this.config = void 0;
289
+ this.signal = void 0;
290
+ this.contentData = [];
291
+ this.contentIndexMap = /* @__PURE__ */ new Map();
292
+ this.stepKeyIds = /* @__PURE__ */ new Map();
293
+ this.toolCallStepIds.clear();
294
+ this.messageIdsByStepKey = /* @__PURE__ */ new Map();
295
+ this.messageStepHasTextDeltas = /* @__PURE__ */ new Set();
296
+ this.reasoningStepHasDeltas = /* @__PURE__ */ new Set();
297
+ this.messageStepHasToolCalls = /* @__PURE__ */ new Map();
298
+ this.prelimMessageIdsByStepKey = /* @__PURE__ */ new Map();
299
+ this.invokedToolIds = void 0;
300
+ this.handlerRegistry = void 0;
301
+ this.hookRegistry = void 0;
302
+ this.humanInTheLoop = void 0;
303
+ this.toolOutputReferences = void 0;
304
+ this.eagerEventToolExecution = void 0;
305
+ this.eagerEventToolExecutions.clear();
306
+ this.clearEagerEventToolUsageCounts();
307
+ this.eagerEventToolCallChunks.clear();
308
+ this.toolExecution = void 0;
309
+ this.handlerDispatchedEventCounts.clear();
310
+ /**
311
+ * ToolNodes compiled from this graph captured the registry
312
+ * instance at construction time, so simply dropping the Graph's
313
+ * own reference would leave their captured reference and every
314
+ * stored `tool<i>turn<n>` entry, plus up to `maxTotalSize` of raw
315
+ * output — alive across subsequent `processStream()` calls. Wipe
316
+ * the registry's contents first so subsequent runs start fresh.
317
+ */
318
+ this._toolOutputRegistry?.clear();
319
+ this._toolOutputRegistry = void 0;
320
+ for (const node of this._compiledToolNodes) node.clearDirectPathTurns();
321
+ this._compiledToolNodes.clear();
322
+ this.sessions.clear();
323
+ }
324
+ getEagerEventToolUsageCount(agentId) {
325
+ if (agentId == null || agentId === "") return this.eagerEventToolUsageCount;
326
+ let usageCount = this.eagerEventToolUsageCountsByAgentId.get(agentId);
327
+ if (usageCount == null) {
328
+ usageCount = /* @__PURE__ */ new Map();
329
+ this.eagerEventToolUsageCountsByAgentId.set(agentId, usageCount);
330
+ }
331
+ return usageCount;
332
+ }
333
+ clearEagerEventToolUsageCounts() {
334
+ this.eagerEventToolUsageCount.clear();
335
+ for (const usageCount of this.eagerEventToolUsageCountsByAgentId.values()) usageCount.clear();
336
+ }
337
+ markHandlerDispatchedEvent(eventName, stepId) {
338
+ const key = getHandlerDispatchedEventKey(eventName, stepId);
339
+ this.handlerDispatchedEventCounts.set(key, (this.handlerDispatchedEventCounts.get(key) ?? 0) + 1);
340
+ return () => {
341
+ const count = this.handlerDispatchedEventCounts.get(key) ?? 0;
342
+ if (count <= 1) {
343
+ this.handlerDispatchedEventCounts.delete(key);
344
+ return;
345
+ }
346
+ this.handlerDispatchedEventCounts.set(key, count - 1);
347
+ };
348
+ }
349
+ hasHandlerDispatchedEvent(eventName, stepId) {
350
+ const key = getHandlerDispatchedEventKey(eventName, stepId);
351
+ return (this.handlerDispatchedEventCounts.get(key) ?? 0) > 0;
352
+ }
353
+ /**
354
+ * Subclass hook to register a freshly compiled ToolNode so
355
+ * `clearHeavyState` can flush its per-Run direct-path turn cache
356
+ * at end-of-Run. Internal — called from `initializeTools` in the
357
+ * concrete graph subclasses.
358
+ */
359
+ registerCompiledToolNode(node) {
360
+ this._compiledToolNodes.add(node);
361
+ }
362
+ /**
363
+ * Returns the shared `ToolOutputReferenceRegistry` for this run,
364
+ * constructing it on first access. Returns `undefined` when the
365
+ * feature is disabled. All ToolNodes compiled from this graph share
366
+ * this single instance so cross-agent `{{…}}` references resolve.
367
+ *
368
+ * @internal Public so `attemptInvoke` can read it through the typed
369
+ * `InvokeContext` and project ToolMessages into LLM-facing annotated
370
+ * copies right before each provider call (see
371
+ * `annotateMessagesForLLM`). Host code should not call this directly
372
+ * — registry mutations outside the ToolNode lifecycle break the
373
+ * partitioning, eviction, and turn-counter invariants.
374
+ */
375
+ getOrCreateToolOutputRegistry() {
376
+ if (this.toolOutputReferences?.enabled !== true) return;
377
+ if (this._toolOutputRegistry == null) this._toolOutputRegistry = new require_toolOutputReferences.ToolOutputReferenceRegistry({
378
+ maxOutputSize: this.toolOutputReferences.maxOutputSize,
379
+ maxTotalSize: this.toolOutputReferences.maxTotalSize
380
+ });
381
+ return this._toolOutputRegistry;
382
+ }
383
+ /**
384
+ * Single per-Run file checkpointer shared across every ToolNode the
385
+ * graph compiles. Lazily constructed when
386
+ * `toolExecution.local.fileCheckpointing === true` or
387
+ * `toolExecution.cloudflare.fileCheckpointing === true` so
388
+ * multi-agent graphs see ONE snapshot store, not one-per-agent.
389
+ * Returns undefined when checkpointing is disabled or a supported
390
+ * coding-tool engine isn't selected. Exposed via
391
+ * `Run.getFileCheckpointer()` / `Run.rewindFiles()`.
392
+ */
393
+ _fileCheckpointer;
394
+ /**
395
+ * ToolNodes compiled into this Graph's workflow. Tracked so
396
+ * `clearHeavyState()` can flush their per-Run direct-path turn
397
+ * cache (`directPathTurns`) at end-of-Run — that map intentionally
398
+ * survives `run()` re-entry (resume-stable per Codex P2 #30) but
399
+ * would otherwise grow linearly with tool calls and could collide
400
+ * across Runs if a provider reuses call ids (Codex P2 #33).
401
+ */
402
+ _compiledToolNodes = /* @__PURE__ */ new Set();
403
+ getOrCreateFileCheckpointer() {
404
+ if (this._fileCheckpointer != null) return this._fileCheckpointer;
405
+ if (this.toolExecution?.engine === "local" && this.toolExecution.local?.fileCheckpointing === true) {
406
+ const bundle = require_LocalCodingTools.createLocalCodingToolBundle(this.toolExecution.local ?? {});
407
+ this._fileCheckpointer = bundle.checkpointer;
408
+ return this._fileCheckpointer;
409
+ }
410
+ if (this.toolExecution?.engine === "cloudflare-sandbox" && this.toolExecution.cloudflare?.fileCheckpointing === true) {
411
+ const bundle = require_CloudflareSandboxTools.createCloudflareCodingToolBundle(this.toolExecution.cloudflare);
412
+ this._fileCheckpointer = bundle.checkpointer;
413
+ return this._fileCheckpointer;
414
+ }
415
+ }
416
+ };
417
+ var StandardGraph = class StandardGraph extends Graph {
418
+ overrideModel;
419
+ /** Optional compile options passed into workflow.compile() */
420
+ compileOptions;
421
+ messages = [];
422
+ /** Cached run messages preserved before clearHeavyState() so getRunMessages() works after cleanup. */
423
+ cachedRunMessages;
424
+ runId;
425
+ /**
426
+ * Boundary between historical messages (loaded from conversation state)
427
+ * and messages produced during the current run. Set once in the state
428
+ * reducer when messages first arrive. Used by `getRunMessages()` and
429
+ * multi-agent message filtering — NOT for pruner token counting (the
430
+ * pruner maintains its own `lastTurnStartIndex` in its closure).
431
+ */
432
+ startIndex = 0;
433
+ signal;
434
+ /** Map of agent contexts by agent ID */
435
+ agentContexts = /* @__PURE__ */ new Map();
436
+ /** Default agent ID to use */
437
+ defaultAgentId;
438
+ constructor({ runId, signal, agents, langfuse, tokenCounter, indexTokenCountMap, calibrationRatio }) {
439
+ super();
440
+ this.runId = runId;
441
+ this.signal = signal;
442
+ this.langfuse = langfuse;
443
+ if (agents.length === 0) throw new Error("At least one agent configuration is required");
444
+ for (const agentConfig of agents) {
445
+ const agentContext = require_AgentContext.AgentContext.fromConfig(agentConfig, tokenCounter, indexTokenCountMap);
446
+ if (calibrationRatio != null && calibrationRatio > 0) agentContext.calibrationRatio = calibrationRatio;
447
+ this.agentContexts.set(agentConfig.agentId, agentContext);
448
+ }
449
+ this.defaultAgentId = agents[0].agentId;
450
+ }
451
+ resetValues(keepContent) {
452
+ this.messages = [];
453
+ this.cachedRunMessages = void 0;
454
+ this.config = require_graph.resetIfNotEmpty(this.config, void 0);
455
+ if (keepContent !== true) {
456
+ this.contentData = require_graph.resetIfNotEmpty(this.contentData, []);
457
+ this.contentIndexMap = require_graph.resetIfNotEmpty(this.contentIndexMap, /* @__PURE__ */ new Map());
458
+ }
459
+ this.stepKeyIds = require_graph.resetIfNotEmpty(this.stepKeyIds, /* @__PURE__ */ new Map());
460
+ /**
461
+ * Clear in-place instead of replacing with a new Map to preserve the
462
+ * shared reference held by ToolNode (passed at construction time).
463
+ * Using resetIfNotEmpty would create a new Map, leaving ToolNode with
464
+ * a stale reference on 2nd+ processStream calls.
465
+ */
466
+ this.toolCallStepIds.clear();
467
+ this.eagerEventToolExecutions.clear();
468
+ this.clearEagerEventToolUsageCounts();
469
+ this.eagerEventToolCallChunks.clear();
470
+ this.handlerDispatchedStepIds = require_graph.resetIfNotEmpty(this.handlerDispatchedStepIds, /* @__PURE__ */ new Set());
471
+ this.handlerDispatchedEventCounts = require_graph.resetIfNotEmpty(this.handlerDispatchedEventCounts, /* @__PURE__ */ new Map());
472
+ this.messageIdsByStepKey = require_graph.resetIfNotEmpty(this.messageIdsByStepKey, /* @__PURE__ */ new Map());
473
+ this.messageStepHasToolCalls = require_graph.resetIfNotEmpty(this.messageStepHasToolCalls, /* @__PURE__ */ new Map());
474
+ this.messageStepHasTextDeltas = require_graph.resetIfNotEmpty(this.messageStepHasTextDeltas, /* @__PURE__ */ new Set());
475
+ this.reasoningStepHasDeltas = require_graph.resetIfNotEmpty(this.reasoningStepHasDeltas, /* @__PURE__ */ new Set());
476
+ this.prelimMessageIdsByStepKey = require_graph.resetIfNotEmpty(this.prelimMessageIdsByStepKey, /* @__PURE__ */ new Map());
477
+ this.invokedToolIds = require_graph.resetIfNotEmpty(this.invokedToolIds, void 0);
478
+ for (const context of this.agentContexts.values()) context.reset();
479
+ }
480
+ clearHeavyState() {
481
+ this.cachedRunMessages = this.messages.slice(this.startIndex);
482
+ super.clearHeavyState();
483
+ this.messages = [];
484
+ this.overrideModel = void 0;
485
+ for (const context of this.agentContexts.values()) context.reset();
486
+ }
487
+ getRunStep(stepId) {
488
+ const index = this.contentIndexMap.get(stepId);
489
+ if (index !== void 0) return this.contentData[index];
490
+ }
491
+ getAgentContext(metadata) {
492
+ if (!metadata) throw new Error("No metadata provided to retrieve agent context");
493
+ const currentNode = metadata.langgraph_node;
494
+ if (!currentNode) throw new Error("No langgraph_node in metadata to retrieve agent context");
495
+ let agentId;
496
+ if (currentNode.startsWith(AGENT)) agentId = currentNode.substring(AGENT.length);
497
+ else if (currentNode.startsWith(TOOLS)) agentId = currentNode.substring(TOOLS.length);
498
+ else if (currentNode.startsWith(SUMMARIZE)) agentId = currentNode.substring(SUMMARIZE.length);
499
+ const agentContext = this.agentContexts.get(agentId ?? "");
500
+ if (!agentContext) throw new Error(`No agent context found for agent ID ${agentId}`);
501
+ return agentContext;
502
+ }
503
+ getStepBaseKey(metadata) {
504
+ if (!metadata) return "";
505
+ const keyList = this.getInvocationKeyList(metadata);
506
+ if (this.checkKeyList(keyList)) throw new Error("Missing metadata");
507
+ return require_graph.joinKeys(keyList);
508
+ }
509
+ getStepKey(metadata) {
510
+ if (!metadata) return "";
511
+ const keyList = this.getKeyList(metadata);
512
+ if (this.checkKeyList(keyList)) throw new Error("Missing metadata");
513
+ return require_graph.joinKeys(keyList);
514
+ }
515
+ getStepIdByKey(stepKey, index) {
516
+ const stepIds = this.stepKeyIds.get(stepKey);
517
+ if (!stepIds) throw new Error(`No step IDs found for stepKey ${stepKey}`);
518
+ if (index === void 0) return stepIds[stepIds.length - 1];
519
+ return stepIds[index];
520
+ }
521
+ generateStepId(stepKey) {
522
+ const stepIds = this.stepKeyIds.get(stepKey);
523
+ let newStepId;
524
+ let stepIndex = 0;
525
+ if (stepIds) {
526
+ stepIndex = stepIds.length;
527
+ newStepId = `step_${(0, nanoid.nanoid)()}`;
528
+ stepIds.push(newStepId);
529
+ this.stepKeyIds.set(stepKey, stepIds);
530
+ } else {
531
+ newStepId = `step_${(0, nanoid.nanoid)()}`;
532
+ this.stepKeyIds.set(stepKey, [newStepId]);
533
+ }
534
+ return [newStepId, stepIndex];
535
+ }
536
+ getKeyList(metadata) {
537
+ if (!metadata) return [];
538
+ const keyList = this.getInvocationKeyList(metadata);
539
+ const agentContext = this.getAgentContext(metadata);
540
+ if (agentContext.currentTokenType === "think" || agentContext.currentTokenType === "think_and_text") keyList.push("reasoning");
541
+ else if (agentContext.tokenTypeSwitch === "content") keyList.push(`post-reasoning-${agentContext.reasoningTransitionCount}`);
542
+ return keyList;
543
+ }
544
+ getInvocationKeyList(metadata) {
545
+ const keyList = this.getBaseKeyList(metadata);
546
+ if (this.invokedToolIds != null && this.invokedToolIds.size > 0) keyList.push(this.invokedToolIds.size + "");
547
+ return keyList;
548
+ }
549
+ getBaseKeyList(metadata) {
550
+ const configurable = this.config?.configurable;
551
+ const runId = metadata.run_id ?? configurable?.run_id ?? this.runId;
552
+ const threadId = metadata.thread_id ?? configurable?.thread_id ?? runId;
553
+ const checkpointNs = metadata.checkpoint_ns ?? metadata.langgraph_checkpoint_ns ?? "";
554
+ return [
555
+ runId,
556
+ threadId,
557
+ metadata.langgraph_node,
558
+ metadata.langgraph_step,
559
+ checkpointNs
560
+ ];
561
+ }
562
+ checkKeyList(keyList) {
563
+ return keyList.some((key) => key === void 0);
564
+ }
565
+ getRunMessages() {
566
+ if (this.messages.length === 0 && this.cachedRunMessages != null) return this.cachedRunMessages;
567
+ return this.messages.slice(this.startIndex);
568
+ }
569
+ getContentParts() {
570
+ return require_core.convertMessagesToContent(this.messages.slice(this.startIndex));
571
+ }
572
+ getCalibrationRatio() {
573
+ return this.agentContexts.get(this.defaultAgentId)?.calibrationRatio ?? 1;
574
+ }
575
+ getResolvedInstructionOverhead() {
576
+ return this.agentContexts.get(this.defaultAgentId)?.resolvedInstructionOverhead;
577
+ }
578
+ getToolCount() {
579
+ const context = this.agentContexts.get(this.defaultAgentId);
580
+ return (context?.tools?.length ?? 0) + (context?.toolDefinitions?.length ?? 0);
581
+ }
582
+ /**
583
+ * Get all run steps, optionally filtered by agent ID
584
+ */
585
+ getRunSteps(agentId) {
586
+ if (agentId == null || agentId === "") return [...this.contentData];
587
+ return this.contentData.filter((step) => step.agentId === agentId);
588
+ }
589
+ /**
590
+ * Get run steps grouped by agent ID
591
+ */
592
+ getRunStepsByAgent() {
593
+ const stepsByAgent = /* @__PURE__ */ new Map();
594
+ for (const step of this.contentData) {
595
+ if (step.agentId == null || step.agentId === "") continue;
596
+ const steps = stepsByAgent.get(step.agentId) ?? [];
597
+ steps.push(step);
598
+ stepsByAgent.set(step.agentId, steps);
599
+ }
600
+ return stepsByAgent;
601
+ }
602
+ /**
603
+ * Get agent IDs that participated in this run
604
+ */
605
+ getActiveAgentIds() {
606
+ const agentIds = /* @__PURE__ */ new Set();
607
+ for (const step of this.contentData) if (step.agentId != null && step.agentId !== "") agentIds.add(step.agentId);
608
+ return Array.from(agentIds);
609
+ }
610
+ /**
611
+ * Maps contentPart indices to agent IDs for post-run analysis
612
+ * Returns a map where key is the contentPart index and value is the agentId
613
+ */
614
+ getContentPartAgentMap() {
615
+ const contentPartAgentMap = /* @__PURE__ */ new Map();
616
+ for (const step of this.contentData) if (step.agentId != null && step.agentId !== "" && Number.isFinite(step.index)) contentPartAgentMap.set(step.index, step.agentId);
617
+ return contentPartAgentMap;
618
+ }
619
+ initializeTools({ currentTools, currentToolMap, agentContext }) {
620
+ const toolDefinitions = agentContext?.toolDefinitions;
621
+ const eventDrivenMode = toolDefinitions != null && toolDefinitions.length > 0;
622
+ const traceToolNode = require_langfuseToolOutputTracing.shouldTraceToolNodeForLangfuse({
623
+ runLangfuse: this.langfuse,
624
+ agentLangfuse: agentContext?.langfuse
625
+ });
626
+ if (eventDrivenMode) {
627
+ const schemaTools = require_schema.createSchemaOnlyTools(toolDefinitions);
628
+ const toolDefMap = new Map(toolDefinitions.map((def) => [def.name, def]));
629
+ const graphTools = agentContext?.graphTools;
630
+ const directToolNames = /* @__PURE__ */ new Set();
631
+ const allTools = [...schemaTools];
632
+ const allToolMap = new Map(schemaTools.map((tool) => [tool.name, tool]));
633
+ if (graphTools && graphTools.length > 0) {
634
+ for (const tool of graphTools) if ("name" in tool) {
635
+ allTools.push(tool);
636
+ allToolMap.set(tool.name, tool);
637
+ directToolNames.add(tool.name);
638
+ }
639
+ }
640
+ const node = new require_ToolNode.ToolNode({
641
+ tools: allTools,
642
+ toolMap: allToolMap,
643
+ trace: traceToolNode,
644
+ runLangfuse: this.langfuse,
645
+ agentLangfuse: agentContext?.langfuse,
646
+ eventDrivenMode: true,
647
+ sessions: this.sessions,
648
+ toolDefinitions: toolDefMap,
649
+ agentId: agentContext?.agentId,
650
+ executingAgentId: agentContext?.agentId,
651
+ toolCallStepIds: this.toolCallStepIds,
652
+ toolRegistry: agentContext?.toolRegistry,
653
+ hookRegistry: this.hookRegistry,
654
+ humanInTheLoop: this.humanInTheLoop,
655
+ eagerEventToolExecution: this.eagerEventToolExecution,
656
+ eagerEventToolExecutions: this.eagerEventToolExecutions,
657
+ eagerEventToolUsageCount: this.getEagerEventToolUsageCount(agentContext?.agentId),
658
+ toolExecution: this.toolExecution,
659
+ directToolNames: directToolNames.size > 0 ? directToolNames : void 0,
660
+ maxContextTokens: agentContext?.maxContextTokens,
661
+ maxToolResultChars: agentContext?.maxToolResultChars,
662
+ toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
663
+ fileCheckpointer: this.getOrCreateFileCheckpointer(),
664
+ errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata)
665
+ });
666
+ this.registerCompiledToolNode(node);
667
+ return node;
668
+ }
669
+ const graphTools = agentContext?.graphTools;
670
+ const baseTools = currentTools ?? [];
671
+ const node = new require_ToolNode.ToolNode({
672
+ tools: graphTools && graphTools.length > 0 ? [...baseTools, ...graphTools] : baseTools,
673
+ toolMap: graphTools && graphTools.length > 0 ? new Map([...currentToolMap ?? /* @__PURE__ */ new Map(), ...graphTools.filter((t) => "name" in t).map((t) => [t.name, t])]) : currentToolMap,
674
+ trace: traceToolNode,
675
+ runLangfuse: this.langfuse,
676
+ agentLangfuse: agentContext?.langfuse,
677
+ executingAgentId: agentContext?.agentId,
678
+ toolCallStepIds: this.toolCallStepIds,
679
+ errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
680
+ toolRegistry: agentContext?.toolRegistry,
681
+ sessions: this.sessions,
682
+ toolExecution: this.toolExecution,
683
+ hookRegistry: this.hookRegistry,
684
+ humanInTheLoop: this.humanInTheLoop,
685
+ maxContextTokens: agentContext?.maxContextTokens,
686
+ maxToolResultChars: agentContext?.maxToolResultChars,
687
+ toolOutputRegistry: this.getOrCreateToolOutputRegistry(),
688
+ fileCheckpointer: this.getOrCreateFileCheckpointer()
689
+ });
690
+ this.registerCompiledToolNode(node);
691
+ return node;
692
+ }
693
+ overrideTestModel(responses, sleep, toolCalls) {
694
+ this.overrideModel = require_fake.createFakeStreamingLLM({
695
+ responses,
696
+ sleep,
697
+ toolCalls
698
+ });
699
+ }
700
+ getUsageMetadata(finalMessage) {
701
+ if (finalMessage && "usage_metadata" in finalMessage && finalMessage.usage_metadata != null) return finalMessage.usage_metadata;
702
+ }
703
+ cleanupSignalListener(currentModel) {
704
+ if (!this.signal) return;
705
+ const model = this.overrideModel ?? currentModel;
706
+ if (!model) return;
707
+ const client = model?.exposedClient;
708
+ if (!client?.abortHandler) return;
709
+ this.signal.removeEventListener("abort", client.abortHandler);
710
+ client.abortHandler = void 0;
711
+ }
712
+ createCallModel(agentId = "default") {
713
+ return async (state, config) => {
714
+ const agentContext = this.agentContexts.get(agentId);
715
+ if (!agentContext) throw new Error(`Agent context not found for agentId: ${agentId}`);
716
+ if (!config) throw new Error("No config provided");
717
+ const { messages } = state;
718
+ const discoveredNames = require_tools.extractToolDiscoveries(messages);
719
+ if (discoveredNames.length > 0) agentContext.markToolsAsDiscovered(discoveredNames);
720
+ const rawToolsForBinding = require_resolveLocalExecutionTools.resolveLocalToolsForBinding({
721
+ tools: agentContext.getToolsForBinding(),
722
+ toolExecution: this.toolExecution
723
+ });
724
+ /**
725
+ * Anthropic prompt-cache breakpoint on the tool definitions.
726
+ *
727
+ * Without this, the (often static) tool inventory shows up as
728
+ * fresh input on every turn — measured at ~28k tokens/turn for
729
+ * the local engine's coding-tool bundle, dominating per-turn
730
+ * cost even when message-level caching is on.
731
+ *
732
+ * Strategy: partition tools into [static, deferred] and stamp
733
+ * `cache_control: ephemeral` on the last static tool.
734
+ * Discovered deferred tools that arrive across turns sit *after*
735
+ * the breakpoint and don't invalidate the prefix.
736
+ */
737
+ let toolsForBinding = rawToolsForBinding;
738
+ if (agentContext.provider === "anthropic" && agentContext.clientOptions?.promptCache === true) toolsForBinding = require_anthropicToolCache.partitionAndMarkAnthropicToolCache(rawToolsForBinding, require_anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
739
+ else if (agentContext.provider === "openrouter" && agentContext.clientOptions?.promptCache === true) toolsForBinding = require_toolCache.partitionAndMarkOpenRouterToolCache(rawToolsForBinding, require_anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
740
+ else if (agentContext.provider === "bedrock" && agentContext.clientOptions?.promptCache === true) toolsForBinding = require_toolCache$1.partitionAndMarkBedrockToolCache(rawToolsForBinding, require_anthropicToolCache.makeIsDeferred(agentContext.toolDefinitions)) ?? rawToolsForBinding;
741
+ let model = this.overrideModel ?? require_init.initializeModel({
742
+ tools: toolsForBinding,
743
+ provider: agentContext.provider,
744
+ clientOptions: agentContext.clientOptions
745
+ });
746
+ if (agentContext.systemRunnable) model = agentContext.systemRunnable.pipe(model);
747
+ if (agentContext.tokenCalculationPromise) await agentContext.tokenCalculationPromise;
748
+ if (!config.signal) config.signal = this.signal;
749
+ this.config = config;
750
+ let messagesToUse = messages;
751
+ if (!agentContext.pruneMessages && agentContext.tokenCounter && agentContext.maxContextTokens != null) agentContext.pruneMessages = require_prune.createPruneMessages({
752
+ startIndex: agentContext.indexTokenCountMap[0] != null ? this.startIndex : 0,
753
+ provider: agentContext.provider,
754
+ tokenCounter: agentContext.tokenCounter,
755
+ maxTokens: agentContext.maxContextTokens,
756
+ thinkingEnabled: require_request.isThinkingEnabled(agentContext.provider, agentContext.clientOptions),
757
+ indexTokenCountMap: agentContext.indexTokenCountMap,
758
+ contextPruningConfig: agentContext.contextPruningConfig,
759
+ summarizationEnabled: agentContext.summarizationEnabled,
760
+ reserveRatio: agentContext.summarizationConfig?.reserveRatio,
761
+ calibrationRatio: agentContext.calibrationRatio,
762
+ getInstructionTokens: () => agentContext.instructionTokens,
763
+ log: (level, message, data) => {
764
+ require_events.emitAgentLog(config, level, "prune", message, data, {
765
+ runId: this.runId,
766
+ agentId
767
+ });
768
+ }
769
+ });
770
+ if (agentContext.pruneMessages) {
771
+ const { context, indexTokenCountMap, messagesToRefine, prePruneContextTokens, remainingContextTokens, originalToolContent, calibrationRatio, resolvedInstructionOverhead } = agentContext.pruneMessages({
772
+ messages,
773
+ usageMetadata: agentContext.currentUsage,
774
+ lastCallUsage: agentContext.lastCallUsage,
775
+ totalTokensFresh: agentContext.totalTokensFresh
776
+ });
777
+ agentContext.indexTokenCountMap = indexTokenCountMap;
778
+ if (calibrationRatio != null && calibrationRatio > 0) agentContext.calibrationRatio = calibrationRatio;
779
+ if (resolvedInstructionOverhead != null) {
780
+ agentContext.resolvedInstructionOverhead = resolvedInstructionOverhead;
781
+ const nonToolOverhead = agentContext.instructionTokens - agentContext.toolSchemaTokens;
782
+ const calibratedToolTokens = Math.max(0, resolvedInstructionOverhead - nonToolOverhead);
783
+ const currentToolTokens = agentContext.toolSchemaTokens;
784
+ if ((currentToolTokens > 0 ? Math.abs(calibratedToolTokens - currentToolTokens) / currentToolTokens : 1) > CALIBRATION_VARIANCE_THRESHOLD) agentContext.toolSchemaTokens = calibratedToolTokens;
785
+ }
786
+ messagesToUse = context;
787
+ if (agentContext.summarizationEnabled === true && Array.isArray(messagesToRefine) && messagesToRefine.length > 0) {
788
+ const shouldSkip = agentContext.shouldSkipSummarization(messages.length);
789
+ if (!shouldSkip && require_index$6.shouldTriggerSummarization({
790
+ trigger: agentContext.summarizationConfig?.trigger,
791
+ maxContextTokens: agentContext.maxContextTokens,
792
+ prePruneContextTokens: prePruneContextTokens != null ? prePruneContextTokens + agentContext.instructionTokens : void 0,
793
+ remainingContextTokens,
794
+ messagesToRefineCount: messagesToRefine.length
795
+ })) {
796
+ if (originalToolContent != null && originalToolContent.size > 0)
797
+ /**
798
+ * Merge never overwrite — the pruner's masking record
799
+ * into pendingOriginalToolContent. Carry-over entries
800
+ * from a prior summarize (preserved by the recency
801
+ * window for masked tool messages still in the tail) and
802
+ * the current pruner's new entries are both keyed by
803
+ * indices in the current `state.messages`, so a key-wise
804
+ * union is correct. Overwriting would discard the
805
+ * carry-over and reduce summary fidelity when those
806
+ * masked tail messages eventually move into the head.
807
+ */
808
+ if (agentContext.pendingOriginalToolContent == null) agentContext.pendingOriginalToolContent = originalToolContent;
809
+ else {
810
+ for (const [idx, content] of originalToolContent) agentContext.pendingOriginalToolContent.set(idx, content);
811
+ /**
812
+ * Re-apply the per-store char cap after the union. The
813
+ * pruner enforces ORIGINAL_CONTENT_MAX_CHARS inside its
814
+ * own map via the onContentStored callback, but a
815
+ * key-wise merge with recency carry-over bypasses that
816
+ * accounting and could let the merged map grow without
817
+ * bound across long sessions.
818
+ */
819
+ require_prune.enforceOriginalContentCap(agentContext.pendingOriginalToolContent);
820
+ }
821
+ require_events.emitAgentLog(config, "info", "graph", "Summarization triggered", void 0, {
822
+ runId: this.runId,
823
+ agentId
824
+ });
825
+ require_events.emitAgentLog(config, "debug", "graph", "Summarization trigger details", {
826
+ totalMessages: messages.length,
827
+ remainingContextTokens: remainingContextTokens ?? 0,
828
+ summaryVersion: agentContext.summaryVersion + 1,
829
+ toolSchemaTokens: agentContext.toolSchemaTokens,
830
+ instructionTokens: agentContext.instructionTokens,
831
+ systemMessageTokens: agentContext.systemMessageTokens
832
+ }, {
833
+ runId: this.runId,
834
+ agentId
835
+ });
836
+ agentContext.markSummarizationTriggered(messages.length);
837
+ return { summarizationRequest: {
838
+ remainingContextTokens: remainingContextTokens ?? 0,
839
+ agentId: agentId || agentContext.agentId
840
+ } };
841
+ }
842
+ if (shouldSkip) require_events.emitAgentLog(config, "debug", "graph", "Summarization skipped — no new messages or per-run cap reached", {
843
+ messageCount: messages.length,
844
+ messagesToRefineCount: messagesToRefine.length,
845
+ contextLength: context.length
846
+ }, {
847
+ runId: this.runId,
848
+ agentId
849
+ });
850
+ }
851
+ }
852
+ let finalMessages = messagesToUse;
853
+ if (agentContext.useLegacyContent) finalMessages = require_content.formatContentStrings(finalMessages);
854
+ const lastMessageX = finalMessages.length >= 2 ? finalMessages[finalMessages.length - 2] : null;
855
+ const lastMessageY = finalMessages.length >= 1 ? finalMessages[finalMessages.length - 1] : null;
856
+ const anthropicLike = require_llm.isAnthropicLike(agentContext.provider, agentContext.clientOptions);
857
+ if (agentContext.provider === "bedrock" && lastMessageX instanceof _langchain_core_messages.AIMessageChunk && lastMessageY instanceof _langchain_core_messages.ToolMessage && typeof lastMessageX.content === "string") {
858
+ const trimmed = lastMessageX.content.trim();
859
+ finalMessages[finalMessages.length - 2].content = trimmed.length > 0 ? [{
860
+ type: "text",
861
+ text: trimmed
862
+ }] : "";
863
+ }
864
+ if (lastMessageY instanceof _langchain_core_messages.ToolMessage) {
865
+ if (anthropicLike) require_core.formatAnthropicArtifactContent(finalMessages);
866
+ else if (require_llm.isOpenAILike(agentContext.provider) && agentContext.provider !== "deepseek" || require_llm.isGoogleLike(agentContext.provider)) require_core.formatArtifactPayload(finalMessages);
867
+ }
868
+ if (agentContext.provider === "anthropic") {
869
+ if (agentContext.clientOptions?.promptCache === true && !agentContext.systemRunnable) finalMessages = require_cache.addCacheControl(finalMessages);
870
+ } else if (agentContext.provider === "bedrock") {
871
+ if (agentContext.clientOptions?.promptCache === true) finalMessages = require_cache.addBedrockCacheControl(finalMessages);
872
+ } else if (agentContext.provider === "openrouter") {
873
+ if (agentContext.clientOptions?.promptCache === true && !agentContext.systemRunnable) finalMessages = require_cache.addCacheControl(finalMessages);
874
+ }
875
+ if (require_request.isThinkingEnabled(agentContext.provider, agentContext.clientOptions))
876
+ /**
877
+ * Pass `this.startIndex` so the function can distinguish CURRENT-run
878
+ * AI messages (the agent's own iterations — possibly without a
879
+ * leading thinking block, which Claude is allowed to skip) from
880
+ * historical context that genuinely needs the
881
+ * `[Previous agent context]` placeholder. Without this signal the
882
+ * function would convert the agent's own in-run tool_use messages,
883
+ * polluting the next iteration's prompt with a placeholder the
884
+ * model treats as suspicious injected content.
885
+ */
886
+ finalMessages = require_format.ensureThinkingBlockInMessages(finalMessages, agentContext.provider, config, this.startIndex);
887
+ if (anthropicLike && (!agentContext.pruneMessages || finalMessages !== messagesToUse)) {
888
+ const beforeSanitize = finalMessages.length;
889
+ finalMessages = require_prune.sanitizeOrphanToolBlocks(finalMessages);
890
+ if (finalMessages.length !== beforeSanitize) require_events.emitAgentLog(config, "warn", "sanitize", "Orphan tool blocks removed", {
891
+ before: beforeSanitize,
892
+ after: finalMessages.length,
893
+ dropped: beforeSanitize - finalMessages.length
894
+ }, {
895
+ runId: this.runId,
896
+ agentId
897
+ });
898
+ }
899
+ if (agentContext.lastStreamCall != null && agentContext.streamBuffer != null) {
900
+ const timeSinceLastCall = Date.now() - agentContext.lastStreamCall;
901
+ if (timeSinceLastCall < agentContext.streamBuffer) await require_run.sleep(Math.ceil((agentContext.streamBuffer - timeSinceLastCall) / 1e3) * 1e3);
902
+ }
903
+ agentContext.lastStreamCall = Date.now();
904
+ agentContext.markTokensStale();
905
+ let result;
906
+ const fallbacks = agentContext.clientOptions?.fallbacks ?? [];
907
+ if (finalMessages.length === 0 && !agentContext.hasPendingCompactionSummary()) {
908
+ const budgetBreakdown = agentContext.getTokenBudgetBreakdown(messages);
909
+ const breakdown = agentContext.formatTokenBudgetBreakdown(messages);
910
+ const instructionsExceedBudget = budgetBreakdown.instructionTokens > budgetBreakdown.maxContextTokens;
911
+ let guidance;
912
+ if (instructionsExceedBudget) {
913
+ const toolPct = budgetBreakdown.toolSchemaTokens > 0 ? Math.round(budgetBreakdown.toolSchemaTokens / budgetBreakdown.instructionTokens * 100) : 0;
914
+ guidance = toolPct > 50 ? `Tool definitions consume ${budgetBreakdown.toolSchemaTokens} tokens (${toolPct}% of instructions) across ${budgetBreakdown.toolCount} tools, exceeding maxContextTokens (${budgetBreakdown.maxContextTokens}). Reduce the number of tools or increase maxContextTokens.` : `Instructions (${budgetBreakdown.instructionTokens} tokens) exceed maxContextTokens (${budgetBreakdown.maxContextTokens}). Increase maxContextTokens or shorten the system prompt.`;
915
+ if (agentContext.summarizationEnabled === true) guidance += " Summarization was skipped because the summary would further increase the instruction overhead.";
916
+ } else guidance = "Please increase the context window size or make your message shorter.";
917
+ require_events.emitAgentLog(config, "error", "graph", "Empty messages after pruning", {
918
+ messageCount: messages.length,
919
+ instructionsExceedBudget,
920
+ breakdown
921
+ }, {
922
+ runId: this.runId,
923
+ agentId
924
+ });
925
+ throw new Error(JSON.stringify({
926
+ type: "empty_messages",
927
+ info: `Message pruning removed all messages as none fit in the context window. ${guidance}\n${breakdown}`
928
+ }));
929
+ }
930
+ const invokeStart = Date.now();
931
+ const invokeMeta = {
932
+ runId: this.runId,
933
+ agentId
934
+ };
935
+ require_events.emitAgentLog(config, "debug", "graph", "Invoking LLM", {
936
+ messageCount: finalMessages.length,
937
+ provider: agentContext.provider
938
+ }, invokeMeta, { force: true });
939
+ const langfuse = require_langfuseToolOutputTracing.resolveLangfuseConfig(this.langfuse, agentContext.langfuse);
940
+ const traceMetadata = require_langfuse.createLangfuseTraceMetadata({
941
+ messageId: this.runId,
942
+ parentMessageId: config.configurable?.requestBody?.parentMessageId,
943
+ agentId,
944
+ agentName: agentContext.name
945
+ });
946
+ let langfuseHandler;
947
+ let invokeConfig = {
948
+ ...config,
949
+ metadata: {
950
+ ...config.metadata ?? {},
951
+ ...traceMetadata
952
+ }
953
+ };
954
+ require_instrumentation.initializeLangfuseTracing(langfuse);
955
+ if (require_callbacks.findCallback(config.callbacks, require_langfuse.isLangfuseCallbackHandler) == null) {
956
+ langfuseHandler = require_langfuse.createLangfuseHandler({
957
+ langfuse,
958
+ userId: config.configurable?.user_id,
959
+ sessionId: config.configurable?.thread_id,
960
+ traceMetadata,
961
+ tags: ["librechat", "agent"]
962
+ });
963
+ if (langfuseHandler != null) invokeConfig = {
964
+ ...invokeConfig,
965
+ callbacks: require_callbacks.appendCallbacks(invokeConfig.callbacks, [langfuseHandler])
966
+ };
967
+ }
968
+ const metadata = config.metadata;
969
+ try {
970
+ result = await require_langfuseToolOutputTracing.withLangfuseToolOutputTracingConfig(this.langfuse, () => require_invoke.attemptInvoke({
971
+ model: this.overrideModel ?? model,
972
+ messages: finalMessages,
973
+ provider: agentContext.provider,
974
+ context: this
975
+ }, invokeConfig), agentContext.langfuse);
976
+ } catch (primaryError) {
977
+ clearCurrentDeltaStepMarkers({
978
+ graph: this,
979
+ metadata
980
+ });
981
+ result = await require_langfuseToolOutputTracing.withLangfuseToolOutputTracingConfig(this.langfuse, () => require_invoke.tryFallbackProviders({
982
+ fallbacks,
983
+ tools: agentContext.tools,
984
+ messages: finalMessages,
985
+ config: invokeConfig,
986
+ primaryError,
987
+ context: this
988
+ }), agentContext.langfuse);
989
+ } finally {
990
+ await require_langfuse.disposeLangfuseHandler(langfuseHandler);
991
+ }
992
+ if (!result) throw new Error("No result after model invocation");
993
+ /**
994
+ * Fallback: populate toolCallStepIds in the graph execution context.
995
+ *
996
+ * When model.stream() is available (the common case), attemptInvoke
997
+ * processes all chunks through a local ChatModelStreamHandler which
998
+ * creates run steps and populates toolCallStepIds before returning.
999
+ * The code below is a fallback for the rare case where model.stream
1000
+ * is unavailable and model.invoke() was used instead.
1001
+ *
1002
+ * Text content is dispatched FIRST so that MESSAGE_CREATION is the
1003
+ * current step when handleToolCalls runs. handleToolCalls then creates
1004
+ * TOOL_CALLS on top of it. The dedup in getMessageId and
1005
+ * toolCallStepIds.has makes this safe when attemptInvoke already
1006
+ * handled everything — both paths become no-ops.
1007
+ */
1008
+ const responseMessage = result.messages?.[0];
1009
+ const toolCalls = responseMessage?.tool_calls;
1010
+ const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
1011
+ const responseReasoningContent = getResponseReasoningContent({
1012
+ responseMessage,
1013
+ reasoningKey: agentContext.reasoningKey
1014
+ });
1015
+ const textMessageContent = getMessageDeltaContent(agentContext.provider, responseMessage?.content);
1016
+ const hasStreamedTextDeltaStep = hasCurrentTextDeltaStep({
1017
+ graph: this,
1018
+ metadata
1019
+ });
1020
+ const dispatchableFinalReasoningContent = getDispatchableFinalReasoningContent({
1021
+ agentContext,
1022
+ responseReasoningContent,
1023
+ hasStreamedTextDeltaStep,
1024
+ hasStreamedReasoningDeltaStep: hasCurrentReasoningDeltaStep({
1025
+ graph: this,
1026
+ metadata
1027
+ })
1028
+ });
1029
+ if (hasToolCalls) {
1030
+ if (dispatchableFinalReasoningContent != null && await dispatchReasoningContent({
1031
+ graph: this,
1032
+ agentContext,
1033
+ reasoningContent: dispatchableFinalReasoningContent,
1034
+ metadata
1035
+ })) markPostReasoningContent(agentContext);
1036
+ if (textMessageContent != null && !hasStreamedTextDeltaStep) {
1037
+ const stepKey = this.getStepKey(metadata);
1038
+ if (await dispatchTextMessageContent({
1039
+ graph: this,
1040
+ stepKey,
1041
+ provider: agentContext.provider,
1042
+ content: textMessageContent,
1043
+ metadata
1044
+ })) markPostReasoningContent(agentContext);
1045
+ }
1046
+ await require_handlers.handleToolCalls(toolCalls, metadata, this);
1047
+ }
1048
+ /**
1049
+ * When streaming events are unavailable, ChatModelStreamHandler never
1050
+ * fires. Dispatch final reasoning/text content here. getMessageId makes
1051
+ * this a no-op when the streaming path already handled the same step.
1052
+ */
1053
+ if (!hasToolCalls && responseMessage != null) {
1054
+ if (dispatchableFinalReasoningContent != null && await dispatchReasoningContent({
1055
+ graph: this,
1056
+ agentContext,
1057
+ reasoningContent: dispatchableFinalReasoningContent,
1058
+ metadata
1059
+ }) && textMessageContent != null) markPostReasoningContent(agentContext);
1060
+ if (textMessageContent != null && !hasStreamedTextDeltaStep) {
1061
+ const stepKey = this.getStepKey(metadata);
1062
+ await dispatchTextMessageContent({
1063
+ graph: this,
1064
+ stepKey,
1065
+ provider: agentContext.provider,
1066
+ content: textMessageContent,
1067
+ metadata
1068
+ });
1069
+ }
1070
+ }
1071
+ const invokeElapsed = ((Date.now() - invokeStart) / 1e3).toFixed(2);
1072
+ agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
1073
+ if (agentContext.currentUsage) {
1074
+ agentContext.updateLastCallUsage(agentContext.currentUsage);
1075
+ require_events.emitAgentLog(config, "debug", "graph", `LLM call complete (${invokeElapsed}s)`, {
1076
+ ...agentContext.currentUsage,
1077
+ elapsedSeconds: Number(invokeElapsed),
1078
+ instructionTokens: agentContext.instructionTokens,
1079
+ toolSchemaTokens: agentContext.toolSchemaTokens,
1080
+ messageCount: finalMessages.length
1081
+ }, invokeMeta, { force: true });
1082
+ } else require_events.emitAgentLog(config, "debug", "graph", `LLM call complete (${invokeElapsed}s)`, {
1083
+ elapsedSeconds: Number(invokeElapsed),
1084
+ messageCount: finalMessages.length
1085
+ }, invokeMeta, { force: true });
1086
+ this.cleanupSignalListener();
1087
+ return result;
1088
+ };
1089
+ }
1090
+ createAgentNode(agentId) {
1091
+ const getConfig = () => this.config;
1092
+ const agentContext = this.agentContexts.get(agentId);
1093
+ if (!agentContext) throw new Error(`Agent context not found for agentId: ${agentId}`);
1094
+ /**
1095
+ * Depth countdown across graph boundaries: the parent's `maxSubagentDepth`
1096
+ * becomes this executor's `maxDepth`. When the child graph is constructed,
1097
+ * `buildChildInputs()` decrements `maxSubagentDepth` on the child's
1098
+ * `AgentInputs` (only when `allowNested: true`; otherwise subagentConfigs
1099
+ * are stripped entirely). The child graph's own `createAgentNode()` then
1100
+ * reads the decremented value here and creates a narrower executor —
1101
+ * recursion is bounded even though each graph has its own separate
1102
+ * executor instance.
1103
+ */
1104
+ const effectiveSubagentDepth = agentContext.maxSubagentDepth ?? 1;
1105
+ if (agentContext.subagentConfigs != null && agentContext.subagentConfigs.length > 0 && effectiveSubagentDepth > 0) {
1106
+ const resolvedConfigs = require_SubagentExecutor.resolveSubagentConfigs(agentContext.subagentConfigs, agentContext);
1107
+ if (resolvedConfigs.length > 0) {
1108
+ const getParentHandlerRegistry = () => this.handlerRegistry;
1109
+ const executor = new require_SubagentExecutor.SubagentExecutor({
1110
+ configs: new Map(resolvedConfigs.map((c) => [c.type, c])),
1111
+ parentSignal: this.signal,
1112
+ hookRegistry: this.hookRegistry,
1113
+ /** Lazy Run wires the registry onto the graph AFTER
1114
+ * `createWorkflow()` runs, so a direct capture here would be
1115
+ * `undefined` at construction time. */
1116
+ parentHandlerRegistry: getParentHandlerRegistry,
1117
+ parentRunId: this.runId ?? "",
1118
+ parentAgentId: agentContext.agentId,
1119
+ langfuse: this.langfuse,
1120
+ tokenCounter: agentContext.tokenCounter,
1121
+ maxDepth: effectiveSubagentDepth,
1122
+ createChildGraph: (input) => {
1123
+ const childGraph = new StandardGraph(input);
1124
+ childGraph.hookRegistry = this.hookRegistry;
1125
+ /**
1126
+ * Do not propagate `humanInTheLoop` into the child graph yet:
1127
+ * nested subagent interrupts need a stable child checkpoint and
1128
+ * resume bridge. Child hooks still fire; `ask` decisions fail
1129
+ * closed inside the subagent until that flow is implemented.
1130
+ */
1131
+ childGraph.toolOutputReferences = this.toolOutputReferences;
1132
+ childGraph.eagerEventToolExecution = this.eagerEventToolExecution;
1133
+ childGraph.toolExecution = this.toolExecution;
1134
+ childGraph.eventToolExecutionAvailable = this.handlerRegistry?.getHandler("on_tool_execute") != null;
1135
+ return childGraph;
1136
+ }
1137
+ });
1138
+ const subagentTool = (0, _langchain_core_tools.tool)(async (rawInput, config) => {
1139
+ const input = rawInput;
1140
+ const description = typeof input.description === "string" && input.description.trim().length > 0 ? input.description : "No task description provided";
1141
+ const subagentType = typeof input.subagent_type === "string" ? input.subagent_type : "";
1142
+ const threadId = config.configurable?.thread_id;
1143
+ /**
1144
+ * When the tool is dispatched from an LLM's `tool_call`, LangChain
1145
+ * threads the originating `ToolCall` onto the RunnableConfig as
1146
+ * `config.toolCall` (see `ToolRunnableConfig` in
1147
+ * `@langchain/core/tools` internal but stable since ≥0.3.x).
1148
+ * Surfacing its id lets hosts correlate `SubagentUpdateEvent`s
1149
+ * back to the parent's `tool_call_id` deterministically — no
1150
+ * temporal heuristics needed. If a future LangChain version
1151
+ * changes the threading, the type-guarded read falls back to
1152
+ * `undefined` and the correlation degrades gracefully.
1153
+ */
1154
+ const toolCall = config.toolCall;
1155
+ const parentToolCallId = typeof toolCall?.id === "string" ? toolCall.id : void 0;
1156
+ return (await executor.execute({
1157
+ description,
1158
+ subagentType,
1159
+ threadId,
1160
+ parentToolCallId,
1161
+ /**
1162
+ * Forward the parent's `configurable` so host-set fields
1163
+ * (`requestBody`, `user`, etc.) propagate into the child
1164
+ * workflow. The executor scrubs run-identity fields before
1165
+ * forwarding see `SubagentExecuteParams.parentConfigurable`.
1166
+ */
1167
+ parentConfigurable: config.configurable
1168
+ })).content;
1169
+ }, require_SubagentTool.buildSubagentToolParams(resolvedConfigs));
1170
+ if (!agentContext.graphTools) agentContext.graphTools = [];
1171
+ agentContext.graphTools.push(subagentTool);
1172
+ /**
1173
+ * Refresh toolSchemaTokens to include the subagent tool's schema.
1174
+ * `calculateInstructionTokens()` was kicked off in `fromConfig()`
1175
+ * before graphTools was populated, so its result did not count this
1176
+ * tool. Without this retrigger, token-budget/pruning logic
1177
+ * underestimates prompt overhead.
1178
+ */
1179
+ if (agentContext.tokenCounter) {
1180
+ const { tokenCounter, baseIndexTokenCountMap } = agentContext;
1181
+ agentContext.tokenCalculationPromise = agentContext.calculateInstructionTokens(tokenCounter).then(() => {
1182
+ agentContext.updateTokenMapWithInstructions(baseIndexTokenCountMap);
1183
+ }).catch((err) => {
1184
+ console.error("Error recalculating instruction tokens after subagent tool injection:", err);
1185
+ });
1186
+ }
1187
+ }
1188
+ }
1189
+ const agentNode = `${AGENT}${agentId}`;
1190
+ const toolNode = `${TOOLS}${agentId}`;
1191
+ const summarizeNode = `${SUMMARIZE}${agentId}`;
1192
+ const routeMessage = (state, config) => {
1193
+ this.config = config;
1194
+ if (state.summarizationRequest != null) return summarizeNode;
1195
+ return require_ToolNode.toolsCondition(state, toolNode, this.invokedToolIds);
1196
+ };
1197
+ return new _langchain_langgraph.StateGraph(_langchain_langgraph.Annotation.Root({
1198
+ messages: (0, _langchain_langgraph.Annotation)({
1199
+ reducer: require_reducer.messagesStateReducer,
1200
+ default: () => []
1201
+ }),
1202
+ summarizationRequest: (0, _langchain_langgraph.Annotation)({
1203
+ reducer: (_, b) => b,
1204
+ default: () => void 0
1205
+ })
1206
+ })).addNode(agentNode, this.createCallModel(agentId)).addNode(toolNode, this.initializeTools({
1207
+ currentTools: agentContext.tools,
1208
+ currentToolMap: agentContext.toolMap,
1209
+ agentContext
1210
+ })).addNode(summarizeNode, require_node.createSummarizeNode({
1211
+ agentContext,
1212
+ graph: {
1213
+ contentData: this.contentData,
1214
+ contentIndexMap: this.contentIndexMap,
1215
+ get config() {
1216
+ return getConfig();
1217
+ },
1218
+ runId: this.runId,
1219
+ isMultiAgent: this.isMultiAgentGraph(),
1220
+ hookRegistry: this.hookRegistry,
1221
+ dispatchRunStep: async (runStep, nodeConfig) => {
1222
+ this.contentData.push(runStep);
1223
+ this.contentIndexMap.set(runStep.id, runStep.index);
1224
+ const resolvedConfig = nodeConfig ?? this.config;
1225
+ const handler = this.handlerRegistry?.getHandler("on_run_step");
1226
+ if (handler) {
1227
+ await handler.handle("on_run_step", runStep, resolvedConfig?.configurable, this);
1228
+ this.handlerDispatchedStepIds.add(runStep.id);
1229
+ }
1230
+ const unmarkHandlerDispatchedEvent = handler ? this.markHandlerDispatchedEvent("on_run_step", runStep.id) : void 0;
1231
+ try {
1232
+ if (resolvedConfig) await require_events.safeDispatchCustomEvent("on_run_step", runStep, resolvedConfig);
1233
+ } finally {
1234
+ unmarkHandlerDispatchedEvent?.();
1235
+ }
1236
+ },
1237
+ dispatchRunStepCompleted: async (stepId, result, nodeConfig) => {
1238
+ const resolvedConfig = nodeConfig ?? this.config;
1239
+ const runStep = this.contentData.find((s) => s.id === stepId);
1240
+ const handler = this.handlerRegistry?.getHandler("on_run_step_completed");
1241
+ if (handler) await handler.handle("on_run_step_completed", { result: {
1242
+ ...result,
1243
+ id: stepId,
1244
+ index: runStep?.index ?? 0
1245
+ } }, resolvedConfig?.configurable, this);
1246
+ }
1247
+ },
1248
+ generateStepId: (stepKey) => this.generateStepId(stepKey)
1249
+ })).addEdge(_langchain_langgraph.START, agentNode).addConditionalEdges(agentNode, routeMessage).addEdge(summarizeNode, agentNode).addEdge(toolNode, agentContext.toolEnd ? _langchain_langgraph.END : agentNode).compile();
1250
+ }
1251
+ createWorkflow() {
1252
+ const agentNode = this.createAgentNode(this.defaultAgentId);
1253
+ return new _langchain_langgraph.StateGraph(_langchain_langgraph.Annotation.Root({ messages: (0, _langchain_langgraph.Annotation)({
1254
+ reducer: (a, b) => {
1255
+ if (!this.messages.length) this.startIndex = a.length + b.length;
1256
+ const result = require_reducer.messagesStateReducer(a, b);
1257
+ this.messages = result;
1258
+ return result;
1259
+ },
1260
+ default: () => []
1261
+ }) })).addNode(this.defaultAgentId, agentNode, { ends: [_langchain_langgraph.END] }).addEdge(_langchain_langgraph.START, this.defaultAgentId).compile(this.compileOptions);
1262
+ }
1263
+ /**
1264
+ * Indicates if this is a multi-agent graph.
1265
+ * Override in MultiAgentGraph to return true.
1266
+ * Used to conditionally include agentId in RunStep for frontend rendering.
1267
+ */
1268
+ isMultiAgentGraph() {
1269
+ return false;
1270
+ }
1271
+ /**
1272
+ * Get the parallel group ID for an agent, if any.
1273
+ * Override in MultiAgentGraph to provide actual group IDs.
1274
+ * Group IDs are incrementing numbers (1, 2, 3...) reflecting execution order.
1275
+ * @param _agentId - The agent ID to look up
1276
+ * @returns undefined for StandardGraph (no parallel groups), or group number for MultiAgentGraph
1277
+ */
1278
+ getParallelGroupIdForAgent(_agentId) {}
1279
+ /**
1280
+ * Dispatches a run step to the client, returns the step ID
1281
+ */
1282
+ async dispatchRunStep(stepKey, stepDetails, metadata) {
1283
+ if (!this.config) throw new Error("No config provided");
1284
+ const [stepId, stepIndex] = this.generateStepId(stepKey);
1285
+ if (stepDetails.type === "tool_calls" && stepDetails.tool_calls) for (const tool_call of stepDetails.tool_calls) {
1286
+ const toolCallId = tool_call.id ?? "";
1287
+ if (!toolCallId || this.toolCallStepIds.has(toolCallId)) continue;
1288
+ this.toolCallStepIds.set(toolCallId, stepId);
1289
+ }
1290
+ const runStep = {
1291
+ stepIndex,
1292
+ id: stepId,
1293
+ type: stepDetails.type,
1294
+ index: this.contentData.length,
1295
+ stepDetails,
1296
+ usage: null
1297
+ };
1298
+ const runId = this.runId ?? "";
1299
+ if (runId) runStep.runId = runId;
1300
+ if (metadata) try {
1301
+ const agentContext = this.getAgentContext(metadata);
1302
+ if (this.isMultiAgentGraph() && agentContext.agentId) {
1303
+ runStep.agentId = agentContext.agentId;
1304
+ const groupId = this.getParallelGroupIdForAgent(agentContext.agentId);
1305
+ if (groupId != null) runStep.groupId = groupId;
1306
+ }
1307
+ } catch (_e) {}
1308
+ this.contentData.push(runStep);
1309
+ this.contentIndexMap.set(stepId, runStep.index);
1310
+ const handler = this.handlerRegistry?.getHandler("on_run_step");
1311
+ if (handler) {
1312
+ await handler.handle("on_run_step", runStep, metadata, this);
1313
+ this.handlerDispatchedStepIds.add(stepId);
1314
+ }
1315
+ const unmarkHandlerDispatchedEvent = handler ? this.markHandlerDispatchedEvent("on_run_step", stepId) : void 0;
1316
+ try {
1317
+ await require_events.safeDispatchCustomEvent("on_run_step", runStep, this.config);
1318
+ } finally {
1319
+ unmarkHandlerDispatchedEvent?.();
1320
+ }
1321
+ return stepId;
1322
+ }
1323
+ /**
1324
+ * Static version of handleToolCallError to avoid creating strong references
1325
+ * that prevent garbage collection
1326
+ */
1327
+ static async handleToolCallErrorStatic(graph, data, metadata) {
1328
+ if (!graph.config) throw new Error("No config provided");
1329
+ if (!data.id) {
1330
+ console.warn("No Tool ID provided for Tool Error");
1331
+ return;
1332
+ }
1333
+ const stepId = graph.toolCallStepIds.get(data.id) ?? "";
1334
+ if (!stepId) throw new Error(`No stepId found for tool_call_id ${data.id}`);
1335
+ const { name, input: args, error } = data;
1336
+ const runStep = graph.getRunStep(stepId);
1337
+ if (!runStep) throw new Error(`No run step found for stepId ${stepId}`);
1338
+ const tool_call = {
1339
+ id: data.id,
1340
+ name: name || "",
1341
+ args: typeof args === "string" ? args : JSON.stringify(args),
1342
+ output: `Error processing tool${error?.message != null ? `: ${error.message}` : ""}`,
1343
+ progress: 1
1344
+ };
1345
+ await graph.handlerRegistry?.getHandler("on_run_step_completed")?.handle("on_run_step_completed", { result: {
1346
+ id: stepId,
1347
+ index: runStep.index,
1348
+ type: "tool_call",
1349
+ tool_call
1350
+ } }, metadata, graph);
1351
+ }
1352
+ /**
1353
+ * Instance method that delegates to the static method
1354
+ * Kept for backward compatibility
1355
+ */
1356
+ async handleToolCallError(data, metadata) {
1357
+ await StandardGraph.handleToolCallErrorStatic(this, data, metadata);
1358
+ }
1359
+ async dispatchRunStepDelta(id, delta, metadata) {
1360
+ if (!this.config) throw new Error("No config provided");
1361
+ else if (!id) throw new Error("No step ID found");
1362
+ const runStepDelta = {
1363
+ id,
1364
+ delta
1365
+ };
1366
+ const handler = this.handlerRegistry?.getHandler("on_run_step_delta");
1367
+ if (handler) {
1368
+ await handler.handle("on_run_step_delta", runStepDelta, metadata, this);
1369
+ this.handlerDispatchedStepIds.add(id);
1370
+ }
1371
+ const unmarkHandlerDispatchedEvent = handler ? this.markHandlerDispatchedEvent("on_run_step_delta", id) : void 0;
1372
+ try {
1373
+ await require_events.safeDispatchCustomEvent("on_run_step_delta", runStepDelta, this.config);
1374
+ } finally {
1375
+ unmarkHandlerDispatchedEvent?.();
1376
+ }
1377
+ }
1378
+ async dispatchMessageDelta(id, delta, metadata) {
1379
+ if (!this.config) throw new Error("No config provided");
1380
+ const messageDelta = {
1381
+ id,
1382
+ delta
1383
+ };
1384
+ if (hasTextDeltaContent(delta.content)) this.messageStepHasTextDeltas.add(id);
1385
+ const handler = this.handlerRegistry?.getHandler("on_message_delta");
1386
+ if (handler) {
1387
+ await handler.handle("on_message_delta", messageDelta, metadata, this);
1388
+ this.handlerDispatchedStepIds.add(id);
1389
+ }
1390
+ const unmarkHandlerDispatchedEvent = handler ? this.markHandlerDispatchedEvent("on_message_delta", id) : void 0;
1391
+ try {
1392
+ await require_events.safeDispatchCustomEvent("on_message_delta", messageDelta, this.config);
1393
+ } finally {
1394
+ unmarkHandlerDispatchedEvent?.();
1395
+ }
1396
+ }
1397
+ dispatchReasoningDelta = async (stepId, delta, metadata) => {
1398
+ if (!this.config) throw new Error("No config provided");
1399
+ const reasoningDelta = {
1400
+ id: stepId,
1401
+ delta
1402
+ };
1403
+ if (hasReasoningDeltaContent(delta.content)) this.reasoningStepHasDeltas.add(stepId);
1404
+ const handler = this.handlerRegistry?.getHandler("on_reasoning_delta");
1405
+ if (handler) {
1406
+ await handler.handle("on_reasoning_delta", reasoningDelta, metadata, this);
1407
+ this.handlerDispatchedStepIds.add(stepId);
1408
+ }
1409
+ const unmarkHandlerDispatchedEvent = handler ? this.markHandlerDispatchedEvent("on_reasoning_delta", stepId) : void 0;
1410
+ try {
1411
+ await require_events.safeDispatchCustomEvent("on_reasoning_delta", reasoningDelta, this.config);
1412
+ } finally {
1413
+ unmarkHandlerDispatchedEvent?.();
1414
+ }
1415
+ };
1416
+ };
1417
+ //#endregion
1837
1418
  exports.Graph = Graph;
1838
1419
  exports.StandardGraph = StandardGraph;
1839
- //# sourceMappingURL=Graph.cjs.map
1420
+
1421
+ //# sourceMappingURL=Graph.cjs.map