@librechat/agents 3.2.32 → 3.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (573) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/agents/AgentContext.cjs +844 -1046
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/constants.cjs +13 -13
  5. package/dist/cjs/common/constants.cjs.map +1 -1
  6. package/dist/cjs/common/enum.cjs +233 -240
  7. package/dist/cjs/common/enum.cjs.map +1 -1
  8. package/dist/cjs/common/index.cjs +2 -0
  9. package/dist/cjs/events.cjs +121 -169
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1389 -1807
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/index.cjs +2 -0
  16. package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
  17. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  18. package/dist/cjs/hitl/index.cjs +1 -0
  19. package/dist/cjs/hooks/HookRegistry.cjs +176 -202
  20. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  21. package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
  22. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  23. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
  24. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  25. package/dist/cjs/hooks/executeHooks.cjs +227 -282
  26. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  27. package/dist/cjs/hooks/index.cjs +6 -0
  28. package/dist/cjs/hooks/matchers.cjs +196 -230
  29. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  30. package/dist/cjs/hooks/types.cjs +24 -24
  31. package/dist/cjs/hooks/types.cjs.map +1 -1
  32. package/dist/cjs/instrumentation.cjs +110 -137
  33. package/dist/cjs/instrumentation.cjs.map +1 -1
  34. package/dist/cjs/langchain/google-common.cjs +0 -3
  35. package/dist/cjs/langchain/index.cjs +80 -43
  36. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  37. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  38. package/dist/cjs/langchain/messages.cjs +35 -18
  39. package/dist/cjs/langchain/openai.cjs +0 -3
  40. package/dist/cjs/langchain/prompts.cjs +5 -8
  41. package/dist/cjs/langchain/runnables.cjs +11 -10
  42. package/dist/cjs/langchain/tools.cjs +14 -11
  43. package/dist/cjs/langchain/utils/env.cjs +5 -8
  44. package/dist/cjs/langfuse.cjs +60 -79
  45. package/dist/cjs/langfuse.cjs.map +1 -1
  46. package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
  47. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  48. package/dist/cjs/llm/anthropic/index.cjs +432 -562
  49. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  50. package/dist/cjs/llm/anthropic/types.cjs +23 -47
  51. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -731
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -256
  55. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  56. package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
  57. package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
  58. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  59. package/dist/cjs/llm/bedrock/index.cjs +195 -240
  60. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  61. package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
  62. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
  64. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
  65. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +105 -149
  67. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  68. package/dist/cjs/llm/fake.cjs +86 -96
  69. package/dist/cjs/llm/fake.cjs.map +1 -1
  70. package/dist/cjs/llm/google/index.cjs +183 -237
  71. package/dist/cjs/llm/google/index.cjs.map +1 -1
  72. package/dist/cjs/llm/google/utils/common.cjs +398 -674
  73. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  74. package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
  75. package/dist/cjs/llm/init.cjs +44 -53
  76. package/dist/cjs/llm/init.cjs.map +1 -1
  77. package/dist/cjs/llm/invoke.cjs +142 -182
  78. package/dist/cjs/llm/invoke.cjs.map +1 -1
  79. package/dist/cjs/llm/openai/index.cjs +991 -1276
  80. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  81. package/dist/cjs/llm/openai/utils/index.cjs +189 -316
  82. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  83. package/dist/cjs/llm/openrouter/index.cjs +102 -153
  84. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  85. package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
  86. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  87. package/dist/cjs/llm/providers.cjs +29 -37
  88. package/dist/cjs/llm/providers.cjs.map +1 -1
  89. package/dist/cjs/llm/request.cjs +20 -33
  90. package/dist/cjs/llm/request.cjs.map +1 -1
  91. package/dist/cjs/llm/vertexai/index.cjs +427 -453
  92. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  93. package/dist/cjs/main.cjs +547 -528
  94. package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
  95. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  96. package/dist/cjs/messages/cache.cjs +305 -418
  97. package/dist/cjs/messages/cache.cjs.map +1 -1
  98. package/dist/cjs/messages/content.cjs +36 -49
  99. package/dist/cjs/messages/content.cjs.map +1 -1
  100. package/dist/cjs/messages/contextPruning.cjs +112 -145
  101. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  102. package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
  103. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  104. package/dist/cjs/messages/core.cjs +256 -397
  105. package/dist/cjs/messages/core.cjs.map +1 -1
  106. package/dist/cjs/messages/format.cjs +904 -1387
  107. package/dist/cjs/messages/format.cjs.map +1 -1
  108. package/dist/cjs/messages/ids.cjs +16 -20
  109. package/dist/cjs/messages/ids.cjs.map +1 -1
  110. package/dist/cjs/messages/index.cjs +12 -0
  111. package/dist/cjs/messages/langchain.cjs +18 -18
  112. package/dist/cjs/messages/langchain.cjs.map +1 -1
  113. package/dist/cjs/messages/prune.cjs +1054 -1517
  114. package/dist/cjs/messages/prune.cjs.map +1 -1
  115. package/dist/cjs/messages/recency.cjs +77 -95
  116. package/dist/cjs/messages/recency.cjs.map +1 -1
  117. package/dist/cjs/messages/reducer.cjs +63 -78
  118. package/dist/cjs/messages/reducer.cjs.map +1 -1
  119. package/dist/cjs/messages/tools.cjs +51 -79
  120. package/dist/cjs/messages/tools.cjs.map +1 -1
  121. package/dist/cjs/openai/index.cjs +171 -217
  122. package/dist/cjs/openai/index.cjs.map +1 -1
  123. package/dist/cjs/responses/index.cjs +302 -391
  124. package/dist/cjs/responses/index.cjs.map +1 -1
  125. package/dist/cjs/run.cjs +903 -1113
  126. package/dist/cjs/run.cjs.map +1 -1
  127. package/dist/cjs/session/AgentSession.cjs +805 -986
  128. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  129. package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
  130. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  131. package/dist/cjs/session/handlers.cjs +192 -208
  132. package/dist/cjs/session/handlers.cjs.map +1 -1
  133. package/dist/cjs/session/ids.cjs +9 -10
  134. package/dist/cjs/session/ids.cjs.map +1 -1
  135. package/dist/cjs/session/index.cjs +4 -0
  136. package/dist/cjs/session/messageSerialization.cjs +94 -156
  137. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  138. package/dist/cjs/splitStream.cjs +147 -206
  139. package/dist/cjs/splitStream.cjs.map +1 -1
  140. package/dist/cjs/stream.cjs +856 -1344
  141. package/dist/cjs/stream.cjs.map +1 -1
  142. package/dist/cjs/summarization/index.cjs +57 -101
  143. package/dist/cjs/summarization/index.cjs.map +1 -1
  144. package/dist/cjs/summarization/node.cjs +643 -796
  145. package/dist/cjs/summarization/node.cjs.map +1 -1
  146. package/dist/cjs/tools/BashExecutor.cjs +110 -136
  147. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  148. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
  149. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  150. package/dist/cjs/tools/Calculator.cjs +36 -57
  151. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  152. package/dist/cjs/tools/CodeExecutor.cjs +126 -168
  153. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  154. package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
  155. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  156. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
  157. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  158. package/dist/cjs/tools/ReadFile.cjs +17 -20
  159. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  160. package/dist/cjs/tools/SkillTool.cjs +26 -27
  161. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  162. package/dist/cjs/tools/SubagentTool.cjs +59 -61
  163. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  164. package/dist/cjs/tools/ToolNode.cjs +2109 -2686
  165. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  166. package/dist/cjs/tools/ToolSearch.cjs +663 -825
  167. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  168. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
  169. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  170. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
  171. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  172. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
  173. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  174. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
  175. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  176. package/dist/cjs/tools/cloudflare/index.cjs +4 -0
  177. package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
  178. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  179. package/dist/cjs/tools/handlers.cjs +200 -262
  180. package/dist/cjs/tools/handlers.cjs.map +1 -1
  181. package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
  182. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  183. package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
  184. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  185. package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
  186. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  187. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
  188. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  189. package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
  190. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  191. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
  192. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  193. package/dist/cjs/tools/local/attachments.cjs +108 -165
  194. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  195. package/dist/cjs/tools/local/bashAst.cjs +99 -113
  196. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  197. package/dist/cjs/tools/local/editStrategies.cjs +126 -169
  198. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  199. package/dist/cjs/tools/local/index.cjs +12 -0
  200. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
  201. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  202. package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
  203. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  204. package/dist/cjs/tools/local/textEncoding.cjs +25 -23
  205. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  206. package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
  207. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  208. package/dist/cjs/tools/ptcTimeout.cjs +27 -47
  209. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  210. package/dist/cjs/tools/schema.cjs +24 -23
  211. package/dist/cjs/tools/schema.cjs.map +1 -1
  212. package/dist/cjs/tools/search/anthropic.cjs +24 -33
  213. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  214. package/dist/cjs/tools/search/content.cjs +95 -137
  215. package/dist/cjs/tools/search/content.cjs.map +1 -1
  216. package/dist/cjs/tools/search/firecrawl.cjs +141 -172
  217. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  218. package/dist/cjs/tools/search/format.cjs +128 -196
  219. package/dist/cjs/tools/search/format.cjs.map +1 -1
  220. package/dist/cjs/tools/search/highlights.cjs +165 -232
  221. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  222. package/dist/cjs/tools/search/index.cjs +2 -0
  223. package/dist/cjs/tools/search/rerankers.cjs +151 -174
  224. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  225. package/dist/cjs/tools/search/schema.cjs +40 -39
  226. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  227. package/dist/cjs/tools/search/search.cjs +428 -530
  228. package/dist/cjs/tools/search/search.cjs.map +1 -1
  229. package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
  230. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  231. package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
  232. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/tavily-search.cjs +295 -359
  234. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/tool.cjs +260 -299
  236. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  237. package/dist/cjs/tools/search/utils.cjs +74 -117
  238. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  239. package/dist/cjs/tools/skillCatalog.cjs +54 -72
  240. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  241. package/dist/cjs/tools/streamedToolCallSeals.cjs +19 -36
  242. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  243. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
  244. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  245. package/dist/cjs/tools/subagent/index.cjs +1 -0
  246. package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
  247. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  248. package/dist/cjs/utils/callbacks.cjs +11 -21
  249. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  250. package/dist/cjs/utils/errors.cjs +70 -95
  251. package/dist/cjs/utils/errors.cjs.map +1 -1
  252. package/dist/cjs/utils/events.cjs +32 -42
  253. package/dist/cjs/utils/events.cjs.map +1 -1
  254. package/dist/cjs/utils/graph.cjs +8 -12
  255. package/dist/cjs/utils/graph.cjs.map +1 -1
  256. package/dist/cjs/utils/handlers.cjs +60 -82
  257. package/dist/cjs/utils/handlers.cjs.map +1 -1
  258. package/dist/cjs/utils/index.cjs +9 -0
  259. package/dist/cjs/utils/llm.cjs +19 -27
  260. package/dist/cjs/utils/llm.cjs.map +1 -1
  261. package/dist/cjs/utils/misc.cjs +30 -46
  262. package/dist/cjs/utils/misc.cjs.map +1 -1
  263. package/dist/cjs/utils/run.cjs +50 -66
  264. package/dist/cjs/utils/run.cjs.map +1 -1
  265. package/dist/cjs/utils/schema.cjs +11 -19
  266. package/dist/cjs/utils/schema.cjs.map +1 -1
  267. package/dist/cjs/utils/title.cjs +71 -106
  268. package/dist/cjs/utils/title.cjs.map +1 -1
  269. package/dist/cjs/utils/tokens.cjs +186 -283
  270. package/dist/cjs/utils/tokens.cjs.map +1 -1
  271. package/dist/cjs/utils/truncation.cjs +95 -114
  272. package/dist/cjs/utils/truncation.cjs.map +1 -1
  273. package/dist/esm/agents/AgentContext.mjs +844 -1044
  274. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  275. package/dist/esm/common/constants.mjs +13 -11
  276. package/dist/esm/common/constants.mjs.map +1 -1
  277. package/dist/esm/common/enum.mjs +221 -238
  278. package/dist/esm/common/enum.mjs.map +1 -1
  279. package/dist/esm/common/index.mjs +3 -0
  280. package/dist/esm/events.mjs +121 -167
  281. package/dist/esm/events.mjs.map +1 -1
  282. package/dist/esm/graphs/Graph.mjs +1388 -1804
  283. package/dist/esm/graphs/Graph.mjs.map +1 -1
  284. package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
  285. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  286. package/dist/esm/graphs/index.mjs +3 -0
  287. package/dist/esm/hitl/askUserQuestion.mjs +60 -60
  288. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  289. package/dist/esm/hitl/index.mjs +2 -0
  290. package/dist/esm/hooks/HookRegistry.mjs +176 -200
  291. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  292. package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
  293. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  294. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
  295. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  296. package/dist/esm/hooks/executeHooks.mjs +227 -280
  297. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  298. package/dist/esm/hooks/index.mjs +7 -0
  299. package/dist/esm/hooks/matchers.mjs +196 -228
  300. package/dist/esm/hooks/matchers.mjs.map +1 -1
  301. package/dist/esm/hooks/types.mjs +24 -22
  302. package/dist/esm/hooks/types.mjs.map +1 -1
  303. package/dist/esm/instrumentation.mjs +109 -132
  304. package/dist/esm/instrumentation.mjs.map +1 -1
  305. package/dist/esm/langchain/google-common.mjs +1 -2
  306. package/dist/esm/langchain/index.mjs +5 -5
  307. package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
  308. package/dist/esm/langchain/messages/tool.mjs +1 -2
  309. package/dist/esm/langchain/messages.mjs +2 -2
  310. package/dist/esm/langchain/openai.mjs +1 -2
  311. package/dist/esm/langchain/prompts.mjs +2 -2
  312. package/dist/esm/langchain/runnables.mjs +2 -2
  313. package/dist/esm/langchain/tools.mjs +2 -2
  314. package/dist/esm/langchain/utils/env.mjs +2 -2
  315. package/dist/esm/langfuse.mjs +60 -76
  316. package/dist/esm/langfuse.mjs.map +1 -1
  317. package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
  318. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  319. package/dist/esm/llm/anthropic/index.mjs +432 -559
  320. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  321. package/dist/esm/llm/anthropic/types.mjs +23 -45
  322. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  323. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -725
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -253
  326. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  327. package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
  328. package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
  329. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  330. package/dist/esm/llm/bedrock/index.mjs +195 -238
  331. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  332. package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
  333. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  334. package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
  335. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
  336. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  337. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +105 -147
  338. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  339. package/dist/esm/llm/fake.mjs +86 -94
  340. package/dist/esm/llm/fake.mjs.map +1 -1
  341. package/dist/esm/llm/google/index.mjs +183 -235
  342. package/dist/esm/llm/google/index.mjs.map +1 -1
  343. package/dist/esm/llm/google/utils/common.mjs +397 -666
  344. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  345. package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
  346. package/dist/esm/llm/init.mjs +44 -51
  347. package/dist/esm/llm/init.mjs.map +1 -1
  348. package/dist/esm/llm/invoke.mjs +142 -180
  349. package/dist/esm/llm/invoke.mjs.map +1 -1
  350. package/dist/esm/llm/openai/index.mjs +991 -1271
  351. package/dist/esm/llm/openai/index.mjs.map +1 -1
  352. package/dist/esm/llm/openai/utils/index.mjs +188 -312
  353. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  354. package/dist/esm/llm/openrouter/index.mjs +102 -151
  355. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  356. package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
  357. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  358. package/dist/esm/llm/providers.mjs +29 -34
  359. package/dist/esm/llm/providers.mjs.map +1 -1
  360. package/dist/esm/llm/request.mjs +20 -31
  361. package/dist/esm/llm/request.mjs.map +1 -1
  362. package/dist/esm/llm/vertexai/index.mjs +427 -449
  363. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  364. package/dist/esm/main.mjs +99 -87
  365. package/dist/esm/messages/anthropicToolCache.mjs +68 -117
  366. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  367. package/dist/esm/messages/cache.mjs +305 -416
  368. package/dist/esm/messages/cache.mjs.map +1 -1
  369. package/dist/esm/messages/content.mjs +36 -47
  370. package/dist/esm/messages/content.mjs.map +1 -1
  371. package/dist/esm/messages/contextPruning.mjs +112 -143
  372. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  373. package/dist/esm/messages/contextPruningSettings.mjs +36 -44
  374. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  375. package/dist/esm/messages/core.mjs +254 -393
  376. package/dist/esm/messages/core.mjs.map +1 -1
  377. package/dist/esm/messages/format.mjs +902 -1383
  378. package/dist/esm/messages/format.mjs.map +1 -1
  379. package/dist/esm/messages/ids.mjs +16 -18
  380. package/dist/esm/messages/ids.mjs.map +1 -1
  381. package/dist/esm/messages/index.mjs +13 -0
  382. package/dist/esm/messages/langchain.mjs +18 -16
  383. package/dist/esm/messages/langchain.mjs.map +1 -1
  384. package/dist/esm/messages/prune.mjs +1053 -1514
  385. package/dist/esm/messages/prune.mjs.map +1 -1
  386. package/dist/esm/messages/recency.mjs +77 -93
  387. package/dist/esm/messages/recency.mjs.map +1 -1
  388. package/dist/esm/messages/reducer.mjs +63 -76
  389. package/dist/esm/messages/reducer.mjs.map +1 -1
  390. package/dist/esm/messages/tools.mjs +49 -75
  391. package/dist/esm/messages/tools.mjs.map +1 -1
  392. package/dist/esm/openai/index.mjs +170 -215
  393. package/dist/esm/openai/index.mjs.map +1 -1
  394. package/dist/esm/responses/index.mjs +301 -389
  395. package/dist/esm/responses/index.mjs.map +1 -1
  396. package/dist/esm/run.mjs +903 -1111
  397. package/dist/esm/run.mjs.map +1 -1
  398. package/dist/esm/session/AgentSession.mjs +806 -985
  399. package/dist/esm/session/AgentSession.mjs.map +1 -1
  400. package/dist/esm/session/JsonlSessionStore.mjs +326 -407
  401. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  402. package/dist/esm/session/handlers.mjs +192 -206
  403. package/dist/esm/session/handlers.mjs.map +1 -1
  404. package/dist/esm/session/ids.mjs +9 -8
  405. package/dist/esm/session/ids.mjs.map +1 -1
  406. package/dist/esm/session/index.mjs +5 -0
  407. package/dist/esm/session/messageSerialization.mjs +94 -154
  408. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  409. package/dist/esm/splitStream.mjs +147 -204
  410. package/dist/esm/splitStream.mjs.map +1 -1
  411. package/dist/esm/stream.mjs +854 -1341
  412. package/dist/esm/stream.mjs.map +1 -1
  413. package/dist/esm/summarization/index.mjs +57 -99
  414. package/dist/esm/summarization/index.mjs.map +1 -1
  415. package/dist/esm/summarization/node.mjs +640 -790
  416. package/dist/esm/summarization/node.mjs.map +1 -1
  417. package/dist/esm/tools/BashExecutor.mjs +103 -129
  418. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  419. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
  420. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  421. package/dist/esm/tools/Calculator.mjs +34 -36
  422. package/dist/esm/tools/Calculator.mjs.map +1 -1
  423. package/dist/esm/tools/CodeExecutor.mjs +123 -164
  424. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  425. package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
  426. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  427. package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
  428. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  429. package/dist/esm/tools/ReadFile.mjs +17 -18
  430. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  431. package/dist/esm/tools/SkillTool.mjs +26 -25
  432. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  433. package/dist/esm/tools/SubagentTool.mjs +59 -59
  434. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  435. package/dist/esm/tools/ToolNode.mjs +2107 -2684
  436. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  437. package/dist/esm/tools/ToolSearch.mjs +659 -804
  438. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  439. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
  440. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  441. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
  442. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  443. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
  444. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  445. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
  446. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  447. package/dist/esm/tools/cloudflare/index.mjs +5 -0
  448. package/dist/esm/tools/eagerEventExecution.mjs +75 -96
  449. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  450. package/dist/esm/tools/handlers.mjs +200 -260
  451. package/dist/esm/tools/handlers.mjs.map +1 -1
  452. package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
  453. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  454. package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
  455. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  456. package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
  457. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  458. package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
  459. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  460. package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
  461. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  462. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
  463. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  464. package/dist/esm/tools/local/attachments.mjs +108 -163
  465. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  466. package/dist/esm/tools/local/bashAst.mjs +99 -111
  467. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  468. package/dist/esm/tools/local/editStrategies.mjs +126 -167
  469. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  470. package/dist/esm/tools/local/index.mjs +13 -0
  471. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
  472. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  473. package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
  474. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  475. package/dist/esm/tools/local/textEncoding.mjs +25 -21
  476. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  477. package/dist/esm/tools/local/workspaceFS.mjs +38 -44
  478. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  479. package/dist/esm/tools/ptcTimeout.mjs +27 -42
  480. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  481. package/dist/esm/tools/schema.mjs +24 -21
  482. package/dist/esm/tools/schema.mjs.map +1 -1
  483. package/dist/esm/tools/search/anthropic.mjs +24 -31
  484. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  485. package/dist/esm/tools/search/content.mjs +93 -116
  486. package/dist/esm/tools/search/content.mjs.map +1 -1
  487. package/dist/esm/tools/search/firecrawl.mjs +139 -169
  488. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  489. package/dist/esm/tools/search/format.mjs +128 -194
  490. package/dist/esm/tools/search/format.mjs.map +1 -1
  491. package/dist/esm/tools/search/highlights.mjs +165 -230
  492. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  493. package/dist/esm/tools/search/index.mjs +3 -0
  494. package/dist/esm/tools/search/rerankers.mjs +149 -168
  495. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  496. package/dist/esm/tools/search/schema.mjs +39 -37
  497. package/dist/esm/tools/search/schema.mjs.map +1 -1
  498. package/dist/esm/tools/search/search.mjs +426 -528
  499. package/dist/esm/tools/search/search.mjs.map +1 -1
  500. package/dist/esm/tools/search/serper-scraper.mjs +104 -124
  501. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  502. package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
  503. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  504. package/dist/esm/tools/search/tavily-search.mjs +293 -357
  505. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  506. package/dist/esm/tools/search/tool.mjs +259 -297
  507. package/dist/esm/tools/search/tool.mjs.map +1 -1
  508. package/dist/esm/tools/search/utils.mjs +74 -115
  509. package/dist/esm/tools/search/utils.mjs.map +1 -1
  510. package/dist/esm/tools/skillCatalog.mjs +54 -70
  511. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  512. package/dist/esm/tools/streamedToolCallSeals.mjs +19 -31
  513. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  514. package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
  515. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  516. package/dist/esm/tools/subagent/index.mjs +2 -0
  517. package/dist/esm/tools/toolOutputReferences.mjs +523 -624
  518. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  519. package/dist/esm/utils/callbacks.mjs +11 -19
  520. package/dist/esm/utils/callbacks.mjs.map +1 -1
  521. package/dist/esm/utils/errors.mjs +70 -93
  522. package/dist/esm/utils/errors.mjs.map +1 -1
  523. package/dist/esm/utils/events.mjs +32 -40
  524. package/dist/esm/utils/events.mjs.map +1 -1
  525. package/dist/esm/utils/graph.mjs +8 -10
  526. package/dist/esm/utils/graph.mjs.map +1 -1
  527. package/dist/esm/utils/handlers.mjs +60 -80
  528. package/dist/esm/utils/handlers.mjs.map +1 -1
  529. package/dist/esm/utils/index.mjs +10 -0
  530. package/dist/esm/utils/llm.mjs +19 -25
  531. package/dist/esm/utils/llm.mjs.map +1 -1
  532. package/dist/esm/utils/misc.mjs +30 -44
  533. package/dist/esm/utils/misc.mjs.map +1 -1
  534. package/dist/esm/utils/run.mjs +50 -64
  535. package/dist/esm/utils/run.mjs.map +1 -1
  536. package/dist/esm/utils/schema.mjs +11 -17
  537. package/dist/esm/utils/schema.mjs.map +1 -1
  538. package/dist/esm/utils/title.mjs +71 -104
  539. package/dist/esm/utils/title.mjs.map +1 -1
  540. package/dist/esm/utils/tokens.mjs +186 -281
  541. package/dist/esm/utils/tokens.mjs.map +1 -1
  542. package/dist/esm/utils/truncation.mjs +95 -112
  543. package/dist/esm/utils/truncation.mjs.map +1 -1
  544. package/dist/types/tools/search/tool.d.ts +17 -0
  545. package/dist/types/tools/search/types.d.ts +4 -0
  546. package/package.json +4 -10
  547. package/src/tools/search/highlights.ts +9 -1
  548. package/src/tools/search/search.ts +41 -3
  549. package/src/tools/search/source-processing.test.ts +373 -0
  550. package/src/tools/search/tool.ts +22 -2
  551. package/src/tools/search/types.ts +4 -0
  552. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  553. package/dist/cjs/langchain/index.cjs.map +0 -1
  554. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  555. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  556. package/dist/cjs/langchain/messages.cjs.map +0 -1
  557. package/dist/cjs/langchain/openai.cjs.map +0 -1
  558. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  559. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  560. package/dist/cjs/langchain/tools.cjs.map +0 -1
  561. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  562. package/dist/cjs/main.cjs.map +0 -1
  563. package/dist/esm/langchain/google-common.mjs.map +0 -1
  564. package/dist/esm/langchain/index.mjs.map +0 -1
  565. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  566. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  567. package/dist/esm/langchain/messages.mjs.map +0 -1
  568. package/dist/esm/langchain/openai.mjs.map +0 -1
  569. package/dist/esm/langchain/prompts.mjs.map +0 -1
  570. package/dist/esm/langchain/runnables.mjs.map +0 -1
  571. package/dist/esm/langchain/tools.mjs.map +0 -1
  572. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  573. package/dist/esm/main.mjs.map +0 -1
@@ -1,34 +1,35 @@
1
- import { ToolMessage, HumanMessage, SystemMessage, AIMessage } from '@langchain/core/messages';
2
- import { ContentTypes, StepTypes, GraphEvents } from '../common/enum.mjs';
3
- import { emitAgentLog, safeDispatchCustomEvent } from '../utils/events.mjs';
4
- import { tryFallbackProviders, attemptInvoke } from '../llm/invoke.mjs';
5
- import { createRemoveAllMessage } from '../messages/reducer.mjs';
6
- import { splitAtRecencyBoundary } from '../messages/recency.mjs';
7
- import { getMaxOutputTokensKey } from '../llm/request.mjs';
8
- import { addCacheControl } from '../messages/cache.mjs';
9
- import { initializeModel } from '../llm/init.mjs';
10
- import { getChunkContent } from '../stream.mjs';
11
- import { executeHooks } from '../hooks/executeHooks.mjs';
12
- import '../hooks/createWorkspacePolicyHook.mjs';
13
-
14
- const SUMMARIZATION_PARAM_KEYS = new Set(['maxSummaryTokens']);
1
+ import "../common/enum.mjs";
2
+ import "../common/index.mjs";
3
+ import { emitAgentLog, safeDispatchCustomEvent } from "../utils/events.mjs";
4
+ import { addCacheControl } from "../messages/cache.mjs";
5
+ import { createRemoveAllMessage } from "../messages/reducer.mjs";
6
+ import { splitAtRecencyBoundary } from "../messages/recency.mjs";
7
+ import { getChunkContent } from "../stream.mjs";
8
+ import { executeHooks } from "../hooks/executeHooks.mjs";
9
+ import "../hooks/index.mjs";
10
+ import { initializeModel } from "../llm/init.mjs";
11
+ import { attemptInvoke, tryFallbackProviders } from "../llm/invoke.mjs";
12
+ import { getMaxOutputTokensKey } from "../llm/request.mjs";
13
+ import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
14
+ //#region src/summarization/node.ts
15
+ const SUMMARIZATION_PARAM_KEYS = new Set(["maxSummaryTokens"]);
15
16
  /**
16
- * Default number of recent user-led turns preserved verbatim during
17
- * compaction. A turn begins at a HumanMessage and includes every
18
- * following AIMessage and ToolMessage up to the next HumanMessage.
19
- * The most recent turn is always retained regardless of this value;
20
- * the default of `2` additionally keeps the prior exchange so the
21
- * model has fresh context on what just happened. Setting
22
- * `retainRecent.turns` to `0` reverts to the legacy "summarize every
23
- * message" behavior.
24
- */
17
+ * Default number of recent user-led turns preserved verbatim during
18
+ * compaction. A turn begins at a HumanMessage and includes every
19
+ * following AIMessage and ToolMessage up to the next HumanMessage.
20
+ * The most recent turn is always retained regardless of this value;
21
+ * the default of `2` additionally keeps the prior exchange so the
22
+ * model has fresh context on what just happened. Setting
23
+ * `retainRecent.turns` to `0` reverts to the legacy "summarize every
24
+ * message" behavior.
25
+ */
25
26
  const DEFAULT_RETAIN_RECENT_TURNS = 2;
26
27
  /**
27
- * Token overhead of the XML wrapper + instruction text added around the
28
- * summary at injection time in AgentContext.buildSystemRunnable:
29
- * `<summary>\n${text}\n</summary>\n\nYour context window was compacted...`
30
- * ~33 tokens on Anthropic, ~24-27 on OpenAI. Using 33 as a safe ceiling.
31
- */
28
+ * Token overhead of the XML wrapper + instruction text added around the
29
+ * summary at injection time in AgentContext.buildSystemRunnable:
30
+ * `<summary>\n${text}\n</summary>\n\nYour context window was compacted...`
31
+ * ~33 tokens on Anthropic, ~24-27 on OpenAI. Using 33 as a safe ceiling.
32
+ */
32
33
  const SUMMARY_WRAPPER_OVERHEAD_TOKENS = 33;
33
34
  /** Structured checkpoint prompt for fresh summarization (no prior summary). */
34
35
  const DEFAULT_SUMMARIZATION_PROMPT = `Hold on, before you continue I need you to write me a checkpoint of everything so far. Your context window is filling up and this checkpoint replaces the messages above, so capture everything you need to pick right back up.
@@ -81,819 +82,668 @@ Rules:
81
82
  - Preserve exact identifiers, names, errors, and references verbatim
82
83
  - Skip empty sections`;
83
84
  function separateParameters(parameters) {
84
- const llmParams = {};
85
- let maxSummaryTokens;
86
- for (const [key, value] of Object.entries(parameters)) {
87
- if (SUMMARIZATION_PARAM_KEYS.has(key)) {
88
- if (key === 'maxSummaryTokens' &&
89
- typeof value === 'number' &&
90
- value > 0) {
91
- maxSummaryTokens = value;
92
- }
93
- }
94
- else {
95
- llmParams[key] = value;
96
- }
97
- }
98
- return { llmParams, maxSummaryTokens };
85
+ const llmParams = {};
86
+ let maxSummaryTokens;
87
+ for (const [key, value] of Object.entries(parameters)) if (SUMMARIZATION_PARAM_KEYS.has(key)) {
88
+ if (key === "maxSummaryTokens" && typeof value === "number" && value > 0) maxSummaryTokens = value;
89
+ } else llmParams[key] = value;
90
+ return {
91
+ llmParams,
92
+ maxSummaryTokens
93
+ };
99
94
  }
100
95
  /**
101
- * Generates a structural metadata summary without making an LLM call.
102
- * Used as a last-resort fallback when all summarization attempts fail.
103
- * Preserves tool names and message counts so the agent retains basic context.
104
- */
96
+ * Generates a structural metadata summary without making an LLM call.
97
+ * Used as a last-resort fallback when all summarization attempts fail.
98
+ * Preserves tool names and message counts so the agent retains basic context.
99
+ */
105
100
  function generateMetadataStub(messages) {
106
- const counts = {};
107
- const toolNames = new Set();
108
- for (const msg of messages) {
109
- const role = msg.getType();
110
- counts[role] = (counts[role] ?? 0) + 1;
111
- if (role === 'tool' && msg.name != null && msg.name !== '') {
112
- toolNames.add(msg.name);
113
- }
114
- if (role === 'ai' &&
115
- msg instanceof AIMessage &&
116
- msg.tool_calls &&
117
- msg.tool_calls.length > 0) {
118
- for (const tc of msg.tool_calls) {
119
- toolNames.add(tc.name);
120
- }
121
- }
122
- }
123
- const countParts = Object.entries(counts)
124
- .map(([role, count]) => `${count} ${role}`)
125
- .join(', ');
126
- const lines = [
127
- `[Metadata summary: ${messages.length} messages (${countParts})]`,
128
- ];
129
- if (toolNames.size > 0) {
130
- lines.push(`[Tools used: ${Array.from(toolNames).join(', ')}]`);
131
- }
132
- return lines.join('\n');
101
+ const counts = {};
102
+ const toolNames = /* @__PURE__ */ new Set();
103
+ for (const msg of messages) {
104
+ const role = msg.getType();
105
+ counts[role] = (counts[role] ?? 0) + 1;
106
+ if (role === "tool" && msg.name != null && msg.name !== "") toolNames.add(msg.name);
107
+ if (role === "ai" && msg instanceof AIMessage && msg.tool_calls && msg.tool_calls.length > 0) for (const tc of msg.tool_calls) toolNames.add(tc.name);
108
+ }
109
+ const countParts = Object.entries(counts).map(([role, count]) => `${count} ${role}`).join(", ");
110
+ const lines = [`[Metadata summary: ${messages.length} messages (${countParts})]`];
111
+ if (toolNames.size > 0) lines.push(`[Tools used: ${Array.from(toolNames).join(", ")}]`);
112
+ return lines.join("\n");
133
113
  }
134
114
  /** Maximum number of tool failures to include in the enrichment section. */
135
115
  const MAX_TOOL_FAILURES = 8;
136
116
  /** Maximum chars per failure summary line. */
137
117
  const MAX_TOOL_FAILURE_CHARS = 240;
138
118
  /**
139
- * Extracts failed tool results from messages and formats them as a structured
140
- * section. LLMs often omit specific failure details (exit codes, error messages)
141
- * from their summaries, this mechanical enrichment guarantees they survive.
142
- */
119
+ * Extracts failed tool results from messages and formats them as a structured
120
+ * section. LLMs often omit specific failure details (exit codes, error messages)
121
+ * from their summaries, this mechanical enrichment guarantees they survive.
122
+ */
143
123
  function extractToolFailuresSection(messages) {
144
- const failures = [];
145
- const seen = new Set();
146
- for (const msg of messages) {
147
- if (msg.getType() !== 'tool') {
148
- continue;
149
- }
150
- const toolMsg = msg;
151
- if (toolMsg.status !== 'error') {
152
- continue;
153
- }
154
- // Deduplicate by tool_call_id
155
- const callId = toolMsg.tool_call_id;
156
- if (callId && seen.has(callId)) {
157
- continue;
158
- }
159
- if (callId) {
160
- seen.add(callId);
161
- }
162
- const toolName = toolMsg.name ?? 'tool';
163
- const content = typeof toolMsg.content === 'string'
164
- ? toolMsg.content
165
- : JSON.stringify(toolMsg.content);
166
- const normalized = content.replace(/\s+/g, ' ').trim();
167
- const summary = normalized.length > MAX_TOOL_FAILURE_CHARS
168
- ? `${normalized.slice(0, MAX_TOOL_FAILURE_CHARS - 3)}...`
169
- : normalized;
170
- failures.push({ toolName, summary });
171
- }
172
- if (failures.length === 0) {
173
- return '';
174
- }
175
- const lines = failures
176
- .slice(0, MAX_TOOL_FAILURES)
177
- .map((f) => `- ${f.toolName}: ${f.summary}`);
178
- if (failures.length > MAX_TOOL_FAILURES) {
179
- lines.push(`- ...and ${failures.length - MAX_TOOL_FAILURES} more`);
180
- }
181
- return `\n\n## Tool Failures\n${lines.join('\n')}`;
124
+ const failures = [];
125
+ const seen = /* @__PURE__ */ new Set();
126
+ for (const msg of messages) {
127
+ if (msg.getType() !== "tool") continue;
128
+ const toolMsg = msg;
129
+ if (toolMsg.status !== "error") continue;
130
+ const callId = toolMsg.tool_call_id;
131
+ if (callId && seen.has(callId)) continue;
132
+ if (callId) seen.add(callId);
133
+ const toolName = toolMsg.name ?? "tool";
134
+ const normalized = (typeof toolMsg.content === "string" ? toolMsg.content : JSON.stringify(toolMsg.content)).replace(/\s+/g, " ").trim();
135
+ const summary = normalized.length > MAX_TOOL_FAILURE_CHARS ? `${normalized.slice(0, MAX_TOOL_FAILURE_CHARS - 3)}...` : normalized;
136
+ failures.push({
137
+ toolName,
138
+ summary
139
+ });
140
+ }
141
+ if (failures.length === 0) return "";
142
+ const lines = failures.slice(0, MAX_TOOL_FAILURES).map((f) => `- ${f.toolName}: ${f.summary}`);
143
+ if (failures.length > MAX_TOOL_FAILURES) lines.push(`- ...and ${failures.length - MAX_TOOL_FAILURES} more`);
144
+ return `\n\n## Tool Failures\n${lines.join("\n")}`;
182
145
  }
183
146
  /**
184
- * Appends mechanical enrichment sections to an LLM-generated summary.
185
- * Tool failures are appended verbatim because LLMs often omit specific
186
- * error details from their summaries.
187
- */
147
+ * Appends mechanical enrichment sections to an LLM-generated summary.
148
+ * Tool failures are appended verbatim because LLMs often omit specific
149
+ * error details from their summaries.
150
+ */
188
151
  function enrichSummary(summaryText, messages) {
189
- return summaryText + extractToolFailuresSection(messages);
152
+ return summaryText + extractToolFailuresSection(messages);
190
153
  }
191
154
  /**
192
- * Restores pre-masking tool content onto the messages array using
193
- * `pendingOriginalToolContent` stored on AgentContext. Only allocates
194
- * a new array when there are entries to restore; otherwise returns the
195
- * input reference unchanged.
196
- */
155
+ * Restores pre-masking tool content onto the messages array using
156
+ * `pendingOriginalToolContent` stored on AgentContext. Only allocates
157
+ * a new array when there are entries to restore; otherwise returns the
158
+ * input reference unchanged.
159
+ */
197
160
  function restoreOriginalToolContent(messages, originalToolContent) {
198
- if (originalToolContent == null || originalToolContent.size === 0) {
199
- return messages;
200
- }
201
- const restored = [...messages];
202
- for (const [idx, content] of originalToolContent) {
203
- const msg = restored[idx];
204
- if (msg instanceof ToolMessage) {
205
- restored[idx] = new ToolMessage({
206
- content,
207
- tool_call_id: msg.tool_call_id,
208
- name: msg.name,
209
- id: msg.id,
210
- additional_kwargs: msg.additional_kwargs,
211
- response_metadata: msg.response_metadata,
212
- });
213
- }
214
- }
215
- return restored;
161
+ if (originalToolContent == null || originalToolContent.size === 0) return messages;
162
+ const restored = [...messages];
163
+ for (const [idx, content] of originalToolContent) {
164
+ const msg = restored[idx];
165
+ if (msg instanceof ToolMessage) restored[idx] = new ToolMessage({
166
+ content,
167
+ tool_call_id: msg.tool_call_id,
168
+ name: msg.name,
169
+ id: msg.id,
170
+ additional_kwargs: msg.additional_kwargs,
171
+ response_metadata: msg.response_metadata
172
+ });
173
+ }
174
+ return restored;
216
175
  }
217
176
  /** Assembles the summarization model's client options from agent and config. */
218
177
  function buildSummarizationClientConfig(agentContext, summarizationConfig) {
219
- const provider = (summarizationConfig?.provider ??
220
- agentContext.provider);
221
- const modelName = summarizationConfig?.model;
222
- const parameters = summarizationConfig?.parameters ?? {};
223
- const promptText = summarizationConfig?.prompt ?? DEFAULT_SUMMARIZATION_PROMPT;
224
- const updatePromptText = summarizationConfig?.updatePrompt ?? DEFAULT_UPDATE_SUMMARIZATION_PROMPT;
225
- const { llmParams, maxSummaryTokens: paramMaxSummaryTokens } = separateParameters(parameters);
226
- const isSelfSummarize = provider === agentContext.provider;
227
- const baseOptions = isSelfSummarize && agentContext.clientOptions
228
- ? { ...agentContext.clientOptions }
229
- : {};
230
- const clientOptions = {
231
- ...baseOptions,
232
- ...llmParams,
233
- };
234
- if (modelName != null && modelName !== '') {
235
- clientOptions.model = modelName;
236
- clientOptions.modelName = modelName;
237
- }
238
- const effectiveMaxSummaryTokens = paramMaxSummaryTokens ?? summarizationConfig?.maxSummaryTokens;
239
- if (effectiveMaxSummaryTokens != null) {
240
- clientOptions[getMaxOutputTokensKey(provider)] = effectiveMaxSummaryTokens;
241
- }
242
- return {
243
- provider,
244
- modelName,
245
- clientOptions,
246
- effectiveMaxSummaryTokens,
247
- promptText,
248
- updatePromptText,
249
- };
178
+ const provider = summarizationConfig?.provider ?? agentContext.provider;
179
+ const modelName = summarizationConfig?.model;
180
+ const parameters = summarizationConfig?.parameters ?? {};
181
+ const promptText = summarizationConfig?.prompt ?? DEFAULT_SUMMARIZATION_PROMPT;
182
+ const updatePromptText = summarizationConfig?.updatePrompt ?? DEFAULT_UPDATE_SUMMARIZATION_PROMPT;
183
+ const { llmParams, maxSummaryTokens: paramMaxSummaryTokens } = separateParameters(parameters);
184
+ const clientOptions = {
185
+ ...provider === agentContext.provider && agentContext.clientOptions ? { ...agentContext.clientOptions } : {},
186
+ ...llmParams
187
+ };
188
+ if (modelName != null && modelName !== "") {
189
+ clientOptions.model = modelName;
190
+ clientOptions.modelName = modelName;
191
+ }
192
+ const effectiveMaxSummaryTokens = paramMaxSummaryTokens ?? summarizationConfig?.maxSummaryTokens;
193
+ if (effectiveMaxSummaryTokens != null) clientOptions[getMaxOutputTokensKey(provider)] = effectiveMaxSummaryTokens;
194
+ return {
195
+ provider,
196
+ modelName,
197
+ clientOptions,
198
+ effectiveMaxSummaryTokens,
199
+ promptText,
200
+ updatePromptText
201
+ };
250
202
  }
251
203
  /** Computes the token count for a summary, preferring provider output tokens when available. */
252
204
  function computeSummaryTokenCount(summaryText, summaryUsage, tokenCounter) {
253
- const providerOutputTokens = Number(summaryUsage?.output_tokens) || 0;
254
- if (providerOutputTokens > 0) {
255
- return providerOutputTokens + SUMMARY_WRAPPER_OVERHEAD_TOKENS;
256
- }
257
- if (tokenCounter) {
258
- return (tokenCounter(new SystemMessage(summaryText)) +
259
- SUMMARY_WRAPPER_OVERHEAD_TOKENS);
260
- }
261
- return 0;
205
+ const providerOutputTokens = Number(summaryUsage?.output_tokens) || 0;
206
+ if (providerOutputTokens > 0) return providerOutputTokens + SUMMARY_WRAPPER_OVERHEAD_TOKENS;
207
+ if (tokenCounter) return tokenCounter(new SystemMessage(summaryText)) + SUMMARY_WRAPPER_OVERHEAD_TOKENS;
208
+ return 0;
262
209
  }
263
210
  /** Constructs the SummaryContentBlock persisted in the run step and dispatched to events. */
264
211
  function buildSummaryBlock(params) {
265
- return {
266
- type: ContentTypes.SUMMARY,
267
- content: [
268
- {
269
- type: ContentTypes.TEXT,
270
- text: params.summaryText,
271
- },
272
- ],
273
- tokenCount: params.tokenCount,
274
- summaryVersion: params.summaryVersion,
275
- boundary: {
276
- messageId: params.stepId,
277
- contentIndex: params.stepIndex,
278
- },
279
- model: params.modelName,
280
- provider: params.provider,
281
- createdAt: new Date().toISOString(),
282
- };
212
+ return {
213
+ type: "summary",
214
+ content: [{
215
+ type: "text",
216
+ text: params.summaryText
217
+ }],
218
+ tokenCount: params.tokenCount,
219
+ summaryVersion: params.summaryVersion,
220
+ boundary: {
221
+ messageId: params.stepId,
222
+ contentIndex: params.stepIndex
223
+ },
224
+ model: params.modelName,
225
+ provider: params.provider,
226
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
227
+ };
283
228
  }
284
229
  /**
285
- * Extracts an HTTP status code from a thrown LLM-provider error. Returns
286
- * `undefined` for non-object values (including `null` or `undefined`, both
287
- * valid `throw` targets in JS) so callers never dereference a nullish
288
- * value.
289
- */
230
+ * Extracts an HTTP status code from a thrown LLM-provider error. Returns
231
+ * `undefined` for non-object values (including `null` or `undefined`, both
232
+ * valid `throw` targets in JS) so callers never dereference a nullish
233
+ * value.
234
+ */
290
235
  function extractHttpStatus(err) {
291
- if (err == null || typeof err !== 'object') {
292
- return undefined;
293
- }
294
- const errRecord = err;
295
- const direct = errRecord.status;
296
- if (typeof direct === 'number') {
297
- return direct;
298
- }
299
- const statusCode = errRecord.statusCode;
300
- if (typeof statusCode === 'number') {
301
- return statusCode;
302
- }
303
- const response = errRecord.response;
304
- if (response != null && typeof response === 'object') {
305
- const nested = response.status;
306
- if (typeof nested === 'number') {
307
- return nested;
308
- }
309
- }
310
- return undefined;
236
+ if (err == null || typeof err !== "object") return;
237
+ const errRecord = err;
238
+ const direct = errRecord.status;
239
+ if (typeof direct === "number") return direct;
240
+ const statusCode = errRecord.statusCode;
241
+ if (typeof statusCode === "number") return statusCode;
242
+ const response = errRecord.response;
243
+ if (response != null && typeof response === "object") {
244
+ const nested = response.status;
245
+ if (typeof nested === "number") return nested;
246
+ }
311
247
  }
312
248
  /**
313
- * Formats a provider-level error for logging. Returns both a human-readable
314
- * suffix (safe to include in the message string so it survives any host-side
315
- * formatter) and a structured metadata bag for rich log backends.
316
- */
249
+ * Formats a provider-level error for logging. Returns both a human-readable
250
+ * suffix (safe to include in the message string so it survives any host-side
251
+ * formatter) and a structured metadata bag for rich log backends.
252
+ */
317
253
  function describeProviderError(err, provider, modelName) {
318
- const providerLabel = `${provider}/${modelName ?? '(no-model)'}`;
319
- const errMsg = err instanceof Error ? err.message : String(err);
320
- const data = {
321
- provider,
322
- model: modelName,
323
- };
324
- if (err instanceof Error) {
325
- data.errorName = err.name;
326
- data.errorStack = err.stack;
327
- }
328
- const status = extractHttpStatus(err);
329
- const statusSuffix = status != null ? ` (HTTP ${status})` : '';
330
- if (status != null) {
331
- data.status = status;
332
- }
333
- return {
334
- suffix: `[${providerLabel}]${statusSuffix}: ${errMsg}`,
335
- data,
336
- };
254
+ const providerLabel = `${provider}/${modelName ?? "(no-model)"}`;
255
+ const errMsg = err instanceof Error ? err.message : String(err);
256
+ const data = {
257
+ provider,
258
+ model: modelName
259
+ };
260
+ if (err instanceof Error) {
261
+ data.errorName = err.name;
262
+ data.errorStack = err.stack;
263
+ }
264
+ const status = extractHttpStatus(err);
265
+ const statusSuffix = status != null ? ` (HTTP ${status})` : "";
266
+ if (status != null) data.status = status;
267
+ return {
268
+ suffix: `[${providerLabel}]${statusSuffix}: ${errMsg}`,
269
+ data
270
+ };
337
271
  }
338
272
  /**
339
- * Formats an exhausted-fallback error. `tryFallbackProviders` throws the
340
- * last fallback provider's error, which may be from any of the configured
341
- * fallbacks — not the primary — so we label the log with the list of
342
- * fallback providers attempted rather than mis-attributing to the primary.
343
- *
344
- * Entries in `fallbacks` are normally strongly typed, but we defend against
345
- * malformed runtime config (null/undefined entries, missing `provider`
346
- * field) so a recoverable summarization failure is never promoted to an
347
- * uncaught exception from inside the logging path.
348
- */
273
+ * Formats an exhausted-fallback error. `tryFallbackProviders` throws the
274
+ * last fallback provider's error, which may be from any of the configured
275
+ * fallbacks — not the primary — so we label the log with the list of
276
+ * fallback providers attempted rather than mis-attributing to the primary.
277
+ *
278
+ * Entries in `fallbacks` are normally strongly typed, but we defend against
279
+ * malformed runtime config (null/undefined entries, missing `provider`
280
+ * field) so a recoverable summarization failure is never promoted to an
281
+ * uncaught exception from inside the logging path.
282
+ */
349
283
  function describeFallbackError(err, fallbacks) {
350
- const errMsg = err instanceof Error ? err.message : String(err);
351
- const list = Array.isArray(fallbacks)
352
- ? fallbacks
353
- : [];
354
- const providerNames = list
355
- .map((f) => {
356
- if (f == null || typeof f !== 'object') {
357
- return undefined;
358
- }
359
- const raw = f.provider;
360
- return raw != null ? String(raw) : undefined;
361
- })
362
- .filter((p) => typeof p === 'string');
363
- const label = providerNames.length > 0
364
- ? `fallbacks=[${providerNames.join(',')}]`
365
- : 'no-fallbacks';
366
- const data = {
367
- fallbackProviders: providerNames,
368
- fallbackCount: list.length,
369
- };
370
- if (err instanceof Error) {
371
- data.errorName = err.name;
372
- data.errorStack = err.stack;
373
- }
374
- const status = extractHttpStatus(err);
375
- const statusSuffix = status != null ? ` (HTTP ${status})` : '';
376
- if (status != null) {
377
- data.status = status;
378
- }
379
- return {
380
- suffix: `[${label}]${statusSuffix}: ${errMsg}`,
381
- data,
382
- };
284
+ const errMsg = err instanceof Error ? err.message : String(err);
285
+ const list = Array.isArray(fallbacks) ? fallbacks : [];
286
+ const providerNames = list.map((f) => {
287
+ if (f == null || typeof f !== "object") return;
288
+ const raw = f.provider;
289
+ return raw != null ? String(raw) : void 0;
290
+ }).filter((p) => typeof p === "string");
291
+ const label = providerNames.length > 0 ? `fallbacks=[${providerNames.join(",")}]` : "no-fallbacks";
292
+ const data = {
293
+ fallbackProviders: providerNames,
294
+ fallbackCount: list.length
295
+ };
296
+ if (err instanceof Error) {
297
+ data.errorName = err.name;
298
+ data.errorStack = err.stack;
299
+ }
300
+ const status = extractHttpStatus(err);
301
+ const statusSuffix = status != null ? ` (HTTP ${status})` : "";
302
+ if (status != null) data.status = status;
303
+ return {
304
+ suffix: `[${label}]${statusSuffix}: ${errMsg}`,
305
+ data
306
+ };
383
307
  }
384
308
  /**
385
- * Runs the summarization LLM call with primary + fallback providers,
386
- * falling back to a metadata stub when all calls fail.
387
- */
309
+ * Runs the summarization LLM call with primary + fallback providers,
310
+ * falling back to a metadata stub when all calls fail.
311
+ */
388
312
  async function executeSummarizationWithFallback(params) {
389
- const { agentContext, messages, clientConfig, summarizeConfig, stepId, usePromptCache, log, } = params;
390
- const priorSummaryText = agentContext.getSummaryText()?.trim() ?? '';
391
- let summaryText = '';
392
- let summaryUsage;
393
- try {
394
- /**
395
- * Initialize inside the try so that a misconfigured provider
396
- * (e.g. an unrecognized summarization.provider) surfaces through the
397
- * `log('error', ...)` path below rather than bubbling up silently.
398
- */
399
- const summarizationModel = initializeModel({
400
- provider: clientConfig.provider,
401
- clientOptions: clientConfig.clientOptions,
402
- tools: agentContext.getToolsForBinding(),
403
- });
404
- const result = await summarizeWithCacheHit({
405
- model: summarizationModel,
406
- messages,
407
- promptText: clientConfig.promptText,
408
- updatePromptText: clientConfig.updatePromptText,
409
- priorSummaryText,
410
- config: summarizeConfig,
411
- stepId,
412
- provider: clientConfig.provider,
413
- reasoningKey: agentContext.reasoningKey,
414
- usePromptCache,
415
- log,
416
- });
417
- summaryText = result.text;
418
- summaryUsage = result.usage;
419
- }
420
- catch (primaryError) {
421
- const primaryDescribed = describeProviderError(primaryError, clientConfig.provider, clientConfig.modelName);
422
- log('error', `Summarization LLM call failed ${primaryDescribed.suffix}`, {
423
- ...primaryDescribed.data,
424
- messagesToRefineCount: messages.length,
425
- });
426
- const rawFallbacks = clientConfig.clientOptions?.fallbacks;
427
- const fallbacks = Array.isArray(rawFallbacks) ? rawFallbacks : [];
428
- if (fallbacks.length > 0) {
429
- try {
430
- const onChunk = createSummarizationChunkHandler({
431
- stepId,
432
- config: traceConfig(summarizeConfig, 'cache_hit_compaction'),
433
- provider: clientConfig.provider,
434
- reasoningKey: agentContext.reasoningKey,
435
- });
436
- const fbResult = await tryFallbackProviders({
437
- fallbacks,
438
- tools: agentContext.getToolsForBinding(),
439
- messages: [
440
- ...messages,
441
- new HumanMessage(buildSummarizationInstruction(clientConfig.promptText, clientConfig.updatePromptText, priorSummaryText)),
442
- ],
443
- config: traceConfig(summarizeConfig, 'cache_hit_compaction'),
444
- primaryError,
445
- onChunk,
446
- });
447
- const fbMsg = fbResult?.messages?.[0];
448
- if (fbMsg) {
449
- summaryText = extractResponseText(fbMsg);
450
- }
451
- }
452
- catch (fbErr) {
453
- const fbDescribed = describeFallbackError(fbErr, fallbacks);
454
- log('warn', `Fallback providers also failed ${fbDescribed.suffix}`, {
455
- ...fbDescribed.data,
456
- });
457
- }
458
- }
459
- if (!summaryText) {
460
- log('warn', `Summarization failed, falling back to metadata stub ${primaryDescribed.suffix}`, {
461
- ...primaryDescribed.data,
462
- messagesToRefineCount: messages.length,
463
- });
464
- summaryText = generateMetadataStub(messages);
465
- }
466
- }
467
- return { text: summaryText, usage: summaryUsage };
313
+ const { agentContext, messages, clientConfig, summarizeConfig, stepId, usePromptCache, log } = params;
314
+ const priorSummaryText = agentContext.getSummaryText()?.trim() ?? "";
315
+ let summaryText = "";
316
+ let summaryUsage;
317
+ try {
318
+ const result = await summarizeWithCacheHit({
319
+ model: initializeModel({
320
+ provider: clientConfig.provider,
321
+ clientOptions: clientConfig.clientOptions,
322
+ tools: agentContext.getToolsForBinding()
323
+ }),
324
+ messages,
325
+ promptText: clientConfig.promptText,
326
+ updatePromptText: clientConfig.updatePromptText,
327
+ priorSummaryText,
328
+ config: summarizeConfig,
329
+ stepId,
330
+ provider: clientConfig.provider,
331
+ reasoningKey: agentContext.reasoningKey,
332
+ usePromptCache,
333
+ log
334
+ });
335
+ summaryText = result.text;
336
+ summaryUsage = result.usage;
337
+ } catch (primaryError) {
338
+ const primaryDescribed = describeProviderError(primaryError, clientConfig.provider, clientConfig.modelName);
339
+ log("error", `Summarization LLM call failed ${primaryDescribed.suffix}`, {
340
+ ...primaryDescribed.data,
341
+ messagesToRefineCount: messages.length
342
+ });
343
+ const rawFallbacks = clientConfig.clientOptions?.fallbacks;
344
+ const fallbacks = Array.isArray(rawFallbacks) ? rawFallbacks : [];
345
+ if (fallbacks.length > 0) try {
346
+ const onChunk = createSummarizationChunkHandler({
347
+ stepId,
348
+ config: traceConfig(summarizeConfig, "cache_hit_compaction"),
349
+ provider: clientConfig.provider,
350
+ reasoningKey: agentContext.reasoningKey
351
+ });
352
+ const fbMsg = (await tryFallbackProviders({
353
+ fallbacks,
354
+ tools: agentContext.getToolsForBinding(),
355
+ messages: [...messages, new HumanMessage(buildSummarizationInstruction(clientConfig.promptText, clientConfig.updatePromptText, priorSummaryText))],
356
+ config: traceConfig(summarizeConfig, "cache_hit_compaction"),
357
+ primaryError,
358
+ onChunk
359
+ }))?.messages?.[0];
360
+ if (fbMsg) summaryText = extractResponseText(fbMsg);
361
+ } catch (fbErr) {
362
+ const fbDescribed = describeFallbackError(fbErr, fallbacks);
363
+ log("warn", `Fallback providers also failed ${fbDescribed.suffix}`, { ...fbDescribed.data });
364
+ }
365
+ if (!summaryText) {
366
+ log("warn", `Summarization failed, falling back to metadata stub ${primaryDescribed.suffix}`, {
367
+ ...primaryDescribed.data,
368
+ messagesToRefineCount: messages.length
369
+ });
370
+ summaryText = generateMetadataStub(messages);
371
+ }
372
+ }
373
+ return {
374
+ text: summaryText,
375
+ usage: summaryUsage
376
+ };
468
377
  }
469
378
  /** Dispatches run step completion, ON_SUMMARIZE_COMPLETE, and rebuilds token map. */
470
379
  async function dispatchCompletionEvents(params) {
471
- const { graph, runnableConfig, stepId, summaryBlock, agentContext, runStep, summaryUsage, agentId, messagesAfterCount, } = params;
472
- runStep.summary = summaryBlock;
473
- if (summaryUsage) {
474
- runStep.usage = {
475
- prompt_tokens: Number(summaryUsage.input_tokens) || 0,
476
- completion_tokens: Number(summaryUsage.output_tokens) || 0,
477
- total_tokens: (Number(summaryUsage.input_tokens) || 0) +
478
- (Number(summaryUsage.output_tokens) || 0),
479
- };
480
- }
481
- await graph.dispatchRunStepCompleted(stepId, { type: 'summary', summary: summaryBlock }, runnableConfig);
482
- if (runnableConfig) {
483
- await safeDispatchCustomEvent(GraphEvents.ON_SUMMARIZE_COMPLETE, {
484
- id: stepId,
485
- agentId,
486
- summary: summaryBlock,
487
- }, runnableConfig);
488
- }
489
- const sessionId = graph.runId ?? '';
490
- if (graph.hookRegistry?.hasHookFor('PostCompact', sessionId) === true) {
491
- const threadId = runnableConfig?.configurable?.thread_id;
492
- const firstBlock = summaryBlock.content?.[0];
493
- const summaryText = firstBlock != null &&
494
- typeof firstBlock === 'object' &&
495
- 'text' in firstBlock &&
496
- typeof firstBlock.text === 'string'
497
- ? firstBlock.text
498
- : '';
499
- await executeHooks({
500
- registry: graph.hookRegistry,
501
- input: {
502
- hook_event_name: 'PostCompact',
503
- runId: sessionId,
504
- threadId,
505
- agentId,
506
- summary: summaryText,
507
- messagesAfterCount,
508
- },
509
- sessionId,
510
- }).catch(() => {
511
- /* PostCompact is observational — swallow errors */
512
- });
513
- }
514
- agentContext.rebuildTokenMapAfterSummarization({});
380
+ const { graph, runnableConfig, stepId, summaryBlock, agentContext, runStep, summaryUsage, agentId, messagesAfterCount } = params;
381
+ runStep.summary = summaryBlock;
382
+ if (summaryUsage) runStep.usage = {
383
+ prompt_tokens: Number(summaryUsage.input_tokens) || 0,
384
+ completion_tokens: Number(summaryUsage.output_tokens) || 0,
385
+ total_tokens: (Number(summaryUsage.input_tokens) || 0) + (Number(summaryUsage.output_tokens) || 0)
386
+ };
387
+ await graph.dispatchRunStepCompleted(stepId, {
388
+ type: "summary",
389
+ summary: summaryBlock
390
+ }, runnableConfig);
391
+ if (runnableConfig) await safeDispatchCustomEvent("on_summarize_complete", {
392
+ id: stepId,
393
+ agentId,
394
+ summary: summaryBlock
395
+ }, runnableConfig);
396
+ const sessionId = graph.runId ?? "";
397
+ if (graph.hookRegistry?.hasHookFor("PostCompact", sessionId) === true) {
398
+ const threadId = (runnableConfig?.configurable)?.thread_id;
399
+ const firstBlock = summaryBlock.content?.[0];
400
+ const summaryText = firstBlock != null && typeof firstBlock === "object" && "text" in firstBlock && typeof firstBlock.text === "string" ? firstBlock.text : "";
401
+ await executeHooks({
402
+ registry: graph.hookRegistry,
403
+ input: {
404
+ hook_event_name: "PostCompact",
405
+ runId: sessionId,
406
+ threadId,
407
+ agentId,
408
+ summary: summaryText,
409
+ messagesAfterCount
410
+ },
411
+ sessionId
412
+ }).catch(() => {});
413
+ }
414
+ agentContext.rebuildTokenMapAfterSummarization({});
515
415
  }
516
- function createSummarizeNode({ agentContext, graph, generateStepId, }) {
517
- return async (state, config) => {
518
- const request = state.summarizationRequest;
519
- if (request == null) {
520
- return { summarizationRequest: undefined };
521
- }
522
- const maxCtx = agentContext.maxContextTokens ?? 0;
523
- if (maxCtx > 0 && agentContext.instructionTokens >= maxCtx) {
524
- emitAgentLog(config, 'warn', 'summarize', 'Summarization skipped, instructions exceed context budget. Reduce the number of tools or increase maxContextTokens.', {
525
- instructionTokens: agentContext.instructionTokens,
526
- maxContextTokens: maxCtx,
527
- breakdown: agentContext.formatTokenBudgetBreakdown(),
528
- }, { runId: graph.runId, agentId: request.agentId });
529
- return { summarizationRequest: undefined };
530
- }
531
- /**
532
- * Capture the original-tool-content map locally before doing the
533
- * split. We need it in three places: to restore the head for
534
- * summarizer quality, to leave intact on the skip path (state is
535
- * unchanged), and critically to carry forward the tail-relevant
536
- * entries on the summarize-fired path. Clearing it eagerly here
537
- * would lose the originals for masked tool messages that the
538
- * recency window keeps in the tail; a future summarization could
539
- * then only summarize the masked stub instead of the full payload.
540
- */
541
- const originalPending = agentContext.pendingOriginalToolContent;
542
- const restoredMessages = restoreOriginalToolContent(state.messages, originalPending);
543
- const runnableConfig = config ?? graph.config;
544
- const retainRecent = agentContext.summarizationConfig?.retainRecent;
545
- const { head: messagesToRefine, tailStartIndex } = splitAtRecencyBoundary(restoredMessages, {
546
- turns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS,
547
- tokens: retainRecent?.tokens,
548
- tokenCounter: agentContext.tokenCounter,
549
- });
550
- /**
551
- * Use the *masked* messages for the retained tail so that any
552
- * truncation prune applied to oversized ToolMessage content stays
553
- * truncated in live state. The summarizer above reads the restored
554
- * (full-content) head for summary quality, but reinjecting restored
555
- * tool payloads into state would defeat masking and bloat the
556
- * checkpoint, forcing more expensive re-pruning on later turns.
557
- * `restoreOriginalToolContent` returns an array with identical
558
- * length and structure to `state.messages` (replacements only at
559
- * specific indices), so the same tailStartIndex slices both arrays
560
- * at the same turn boundary.
561
- */
562
- const messagesToRetain = state.messages.slice(tailStartIndex);
563
- if (messagesToRefine.length === 0) {
564
- /**
565
- * Recency window covers the entire conversation — there is no
566
- * older content to summarize. Skipping prevents the model from
567
- * destroying the user's most recent message (e.g. a large pasted
568
- * payload on the first turn) by replacing it with a generic
569
- * checkpoint summary. Mark the trigger so the same unchanged
570
- * state is not re-evaluated on the next prune cycle.
571
- */
572
- emitAgentLog(config, 'debug', 'summarize', 'Summarization skipped — recency window retains all messages', {
573
- messagesRetained: messagesToRetain.length,
574
- retainTurns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS,
575
- }, { runId: graph.runId, agentId: request.agentId });
576
- agentContext.markSummarizationTriggered(state.messages.length);
577
- return { summarizationRequest: undefined };
578
- }
579
- const clientConfig = buildSummarizationClientConfig(agentContext, agentContext.summarizationConfig);
580
- const stepKey = `summarize-${request.agentId}`;
581
- const [stepId, stepIndex] = generateStepId(stepKey);
582
- const placeholderSummary = {
583
- type: ContentTypes.SUMMARY,
584
- model: clientConfig.modelName,
585
- provider: clientConfig.provider,
586
- };
587
- const runStep = {
588
- stepIndex,
589
- id: stepId,
590
- type: StepTypes.MESSAGE_CREATION,
591
- index: graph.contentData.length,
592
- stepDetails: {
593
- type: StepTypes.MESSAGE_CREATION,
594
- message_creation: { message_id: stepId },
595
- },
596
- summary: placeholderSummary,
597
- usage: null,
598
- };
599
- if (graph.runId != null && graph.runId !== '') {
600
- runStep.runId = graph.runId;
601
- }
602
- if (graph.isMultiAgent && agentContext.agentId) {
603
- runStep.agentId = agentContext.agentId;
604
- }
605
- await graph.dispatchRunStep(runStep, runnableConfig);
606
- if (runnableConfig) {
607
- await safeDispatchCustomEvent(GraphEvents.ON_SUMMARIZE_START, {
608
- agentId: request.agentId,
609
- provider: clientConfig.provider,
610
- model: clientConfig.modelName,
611
- messagesToRefineCount: messagesToRefine.length,
612
- summaryVersion: agentContext.summaryVersion + 1,
613
- }, runnableConfig);
614
- }
615
- const sessionId = graph.runId ?? '';
616
- if (graph.hookRegistry?.hasHookFor('PreCompact', sessionId) === true) {
617
- const threadId = runnableConfig?.configurable?.thread_id;
618
- await executeHooks({
619
- registry: graph.hookRegistry,
620
- input: {
621
- hook_event_name: 'PreCompact',
622
- runId: sessionId,
623
- threadId,
624
- agentId: request.agentId,
625
- messagesBeforeCount: messagesToRefine.length,
626
- trigger: agentContext.summarizationConfig?.trigger?.type ?? 'default',
627
- },
628
- sessionId,
629
- }).catch(() => {
630
- /* PreCompact is observational swallow errors */
631
- });
632
- }
633
- const isSelfSummarizeModel = clientConfig.provider === agentContext.provider;
634
- const hasPromptCache = isSelfSummarizeModel &&
635
- agentContext.clientOptions
636
- ?.promptCache === true;
637
- const log = (level, message, data) => {
638
- emitAgentLog(runnableConfig, level, 'summarize', message, data, {
639
- runId: graph.runId,
640
- agentId: request.agentId,
641
- });
642
- };
643
- log('debug', 'Summarization starting', {
644
- messagesToRefineCount: messagesToRefine.length,
645
- hasPriorSummary: (agentContext.getSummaryText()?.trim() ?? '') !== '',
646
- summaryVersion: agentContext.summaryVersion + 1,
647
- isSelfSummarize: isSelfSummarizeModel,
648
- hasPromptCache,
649
- provider: clientConfig.provider,
650
- });
651
- const summarizeConfig = config
652
- ? {
653
- ...config,
654
- metadata: {
655
- ...config.metadata,
656
- agent_id: request.agentId,
657
- summarization_provider: clientConfig.provider,
658
- summarization_model: clientConfig.modelName,
659
- },
660
- }
661
- : undefined;
662
- const { text: rawText, usage: summaryUsage } = await executeSummarizationWithFallback({
663
- agentContext,
664
- messages: messagesToRefine,
665
- clientConfig,
666
- summarizeConfig,
667
- stepId,
668
- usePromptCache: isSelfSummarizeModel && hasPromptCache,
669
- log,
670
- });
671
- if (!rawText) {
672
- agentContext.markSummarizationTriggered(0);
673
- if (runnableConfig) {
674
- await safeDispatchCustomEvent(GraphEvents.ON_SUMMARIZE_COMPLETE, {
675
- id: stepId,
676
- agentId: request.agentId,
677
- error: 'Summarization produced empty output',
678
- }, runnableConfig);
679
- }
680
- return { summarizationRequest: undefined };
681
- }
682
- const summaryText = enrichSummary(rawText, messagesToRefine);
683
- const tokenCount = computeSummaryTokenCount(summaryText, summaryUsage, agentContext.tokenCounter);
684
- agentContext.setSummary(summaryText, tokenCount);
685
- log('info', 'Summary persisted');
686
- log('debug', 'Summary details', {
687
- summaryTokens: tokenCount,
688
- textLength: summaryText.length,
689
- messagesCompacted: messagesToRefine.length,
690
- summaryVersion: agentContext.summaryVersion,
691
- ...(summaryUsage != null
692
- ? {
693
- input_tokens: summaryUsage.input_tokens,
694
- output_tokens: summaryUsage.output_tokens,
695
- cache_read: summaryUsage.input_token_details?.cache_read,
696
- cache_creation: summaryUsage.input_token_details?.cache_creation,
697
- }
698
- : {}),
699
- });
700
- const summaryBlock = buildSummaryBlock({
701
- summaryText,
702
- tokenCount,
703
- stepId,
704
- stepIndex: runStep.index,
705
- modelName: clientConfig.modelName,
706
- provider: clientConfig.provider,
707
- summaryVersion: agentContext.summaryVersion,
708
- });
709
- await dispatchCompletionEvents({
710
- graph,
711
- runnableConfig,
712
- stepId,
713
- summaryBlock,
714
- agentContext,
715
- runStep,
716
- summaryUsage,
717
- agentId: request.agentId,
718
- messagesAfterCount: messagesToRetain.length,
719
- });
720
- /**
721
- * `dispatchCompletionEvents` calls `rebuildTokenMapAfterSummarization({})`
722
- * which resets the dedupe baseline to 0 correct under the legacy
723
- * "remove-all only" shape where no messages survived, but stale once
724
- * the recency window keeps a tail. Realign the baseline to the
725
- * surviving tail length so a subsequent prune cycle on the unchanged
726
- * tail short-circuits via `shouldSkipSummarization` instead of
727
- * looping back into another summarize call.
728
- */
729
- agentContext.markSummarizationTriggered(messagesToRetain.length);
730
- /**
731
- * Carry forward the original-content entries that correspond to the
732
- * retained tail, reindexed for the post-removeAll state where tail
733
- * messages start at index 0. Without this, a future summarization
734
- * that pulls these tail messages into its head would only see the
735
- * masked stubs (since `setSummary` clears `pruneMessages`, and the
736
- * fresh pruner at the next turn has no record of prior masks).
737
- * Entries for indices < `tailStartIndex` belong to messages we just
738
- * summarized — they are no longer reachable so they are dropped.
739
- */
740
- if (originalPending != null && originalPending.size > 0) {
741
- const tailPending = new Map();
742
- for (const [idx, content] of originalPending) {
743
- if (idx >= tailStartIndex) {
744
- tailPending.set(idx - tailStartIndex, content);
745
- }
746
- }
747
- agentContext.pendingOriginalToolContent =
748
- tailPending.size > 0 ? tailPending : undefined;
749
- }
750
- else {
751
- agentContext.pendingOriginalToolContent = undefined;
752
- }
753
- return {
754
- summarizationRequest: undefined,
755
- messages: messagesToRetain.length > 0
756
- ? [createRemoveAllMessage(), ...messagesToRetain]
757
- : [createRemoveAllMessage()],
758
- };
759
- };
416
+ function createSummarizeNode({ agentContext, graph, generateStepId }) {
417
+ return async (state, config) => {
418
+ const request = state.summarizationRequest;
419
+ if (request == null) return { summarizationRequest: void 0 };
420
+ const maxCtx = agentContext.maxContextTokens ?? 0;
421
+ if (maxCtx > 0 && agentContext.instructionTokens >= maxCtx) {
422
+ emitAgentLog(config, "warn", "summarize", "Summarization skipped, instructions exceed context budget. Reduce the number of tools or increase maxContextTokens.", {
423
+ instructionTokens: agentContext.instructionTokens,
424
+ maxContextTokens: maxCtx,
425
+ breakdown: agentContext.formatTokenBudgetBreakdown()
426
+ }, {
427
+ runId: graph.runId,
428
+ agentId: request.agentId
429
+ });
430
+ return { summarizationRequest: void 0 };
431
+ }
432
+ /**
433
+ * Capture the original-tool-content map locally before doing the
434
+ * split. We need it in three places: to restore the head for
435
+ * summarizer quality, to leave intact on the skip path (state is
436
+ * unchanged), and critically to carry forward the tail-relevant
437
+ * entries on the summarize-fired path. Clearing it eagerly here
438
+ * would lose the originals for masked tool messages that the
439
+ * recency window keeps in the tail; a future summarization could
440
+ * then only summarize the masked stub instead of the full payload.
441
+ */
442
+ const originalPending = agentContext.pendingOriginalToolContent;
443
+ const restoredMessages = restoreOriginalToolContent(state.messages, originalPending);
444
+ const runnableConfig = config ?? graph.config;
445
+ const retainRecent = agentContext.summarizationConfig?.retainRecent;
446
+ const { head: messagesToRefine, tailStartIndex } = splitAtRecencyBoundary(restoredMessages, {
447
+ turns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS,
448
+ tokens: retainRecent?.tokens,
449
+ tokenCounter: agentContext.tokenCounter
450
+ });
451
+ /**
452
+ * Use the *masked* messages for the retained tail so that any
453
+ * truncation prune applied to oversized ToolMessage content stays
454
+ * truncated in live state. The summarizer above reads the restored
455
+ * (full-content) head for summary quality, but reinjecting restored
456
+ * tool payloads into state would defeat masking and bloat the
457
+ * checkpoint, forcing more expensive re-pruning on later turns.
458
+ * `restoreOriginalToolContent` returns an array with identical
459
+ * length and structure to `state.messages` (replacements only at
460
+ * specific indices), so the same tailStartIndex slices both arrays
461
+ * at the same turn boundary.
462
+ */
463
+ const messagesToRetain = state.messages.slice(tailStartIndex);
464
+ if (messagesToRefine.length === 0) {
465
+ /**
466
+ * Recency window covers the entire conversation there is no
467
+ * older content to summarize. Skipping prevents the model from
468
+ * destroying the user's most recent message (e.g. a large pasted
469
+ * payload on the first turn) by replacing it with a generic
470
+ * checkpoint summary. Mark the trigger so the same unchanged
471
+ * state is not re-evaluated on the next prune cycle.
472
+ */
473
+ emitAgentLog(config, "debug", "summarize", "Summarization skipped — recency window retains all messages", {
474
+ messagesRetained: messagesToRetain.length,
475
+ retainTurns: retainRecent?.turns ?? DEFAULT_RETAIN_RECENT_TURNS
476
+ }, {
477
+ runId: graph.runId,
478
+ agentId: request.agentId
479
+ });
480
+ agentContext.markSummarizationTriggered(state.messages.length);
481
+ return { summarizationRequest: void 0 };
482
+ }
483
+ const clientConfig = buildSummarizationClientConfig(agentContext, agentContext.summarizationConfig);
484
+ const [stepId, stepIndex] = generateStepId(`summarize-${request.agentId}`);
485
+ const placeholderSummary = {
486
+ type: "summary",
487
+ model: clientConfig.modelName,
488
+ provider: clientConfig.provider
489
+ };
490
+ const runStep = {
491
+ stepIndex,
492
+ id: stepId,
493
+ type: "message_creation",
494
+ index: graph.contentData.length,
495
+ stepDetails: {
496
+ type: "message_creation",
497
+ message_creation: { message_id: stepId }
498
+ },
499
+ summary: placeholderSummary,
500
+ usage: null
501
+ };
502
+ if (graph.runId != null && graph.runId !== "") runStep.runId = graph.runId;
503
+ if (graph.isMultiAgent && agentContext.agentId) runStep.agentId = agentContext.agentId;
504
+ await graph.dispatchRunStep(runStep, runnableConfig);
505
+ if (runnableConfig) await safeDispatchCustomEvent("on_summarize_start", {
506
+ agentId: request.agentId,
507
+ provider: clientConfig.provider,
508
+ model: clientConfig.modelName,
509
+ messagesToRefineCount: messagesToRefine.length,
510
+ summaryVersion: agentContext.summaryVersion + 1
511
+ }, runnableConfig);
512
+ const sessionId = graph.runId ?? "";
513
+ if (graph.hookRegistry?.hasHookFor("PreCompact", sessionId) === true) {
514
+ const threadId = (runnableConfig?.configurable)?.thread_id;
515
+ await executeHooks({
516
+ registry: graph.hookRegistry,
517
+ input: {
518
+ hook_event_name: "PreCompact",
519
+ runId: sessionId,
520
+ threadId,
521
+ agentId: request.agentId,
522
+ messagesBeforeCount: messagesToRefine.length,
523
+ trigger: agentContext.summarizationConfig?.trigger?.type ?? "default"
524
+ },
525
+ sessionId
526
+ }).catch(() => {});
527
+ }
528
+ const isSelfSummarizeModel = clientConfig.provider === agentContext.provider;
529
+ const hasPromptCache = isSelfSummarizeModel && agentContext.clientOptions?.promptCache === true;
530
+ const log = (level, message, data) => {
531
+ emitAgentLog(runnableConfig, level, "summarize", message, data, {
532
+ runId: graph.runId,
533
+ agentId: request.agentId
534
+ });
535
+ };
536
+ log("debug", "Summarization starting", {
537
+ messagesToRefineCount: messagesToRefine.length,
538
+ hasPriorSummary: (agentContext.getSummaryText()?.trim() ?? "") !== "",
539
+ summaryVersion: agentContext.summaryVersion + 1,
540
+ isSelfSummarize: isSelfSummarizeModel,
541
+ hasPromptCache,
542
+ provider: clientConfig.provider
543
+ });
544
+ const { text: rawText, usage: summaryUsage } = await executeSummarizationWithFallback({
545
+ agentContext,
546
+ messages: messagesToRefine,
547
+ clientConfig,
548
+ summarizeConfig: config ? {
549
+ ...config,
550
+ metadata: {
551
+ ...config.metadata,
552
+ agent_id: request.agentId,
553
+ summarization_provider: clientConfig.provider,
554
+ summarization_model: clientConfig.modelName
555
+ }
556
+ } : void 0,
557
+ stepId,
558
+ usePromptCache: isSelfSummarizeModel && hasPromptCache,
559
+ log
560
+ });
561
+ if (!rawText) {
562
+ agentContext.markSummarizationTriggered(0);
563
+ if (runnableConfig) await safeDispatchCustomEvent("on_summarize_complete", {
564
+ id: stepId,
565
+ agentId: request.agentId,
566
+ error: "Summarization produced empty output"
567
+ }, runnableConfig);
568
+ return { summarizationRequest: void 0 };
569
+ }
570
+ const summaryText = enrichSummary(rawText, messagesToRefine);
571
+ const tokenCount = computeSummaryTokenCount(summaryText, summaryUsage, agentContext.tokenCounter);
572
+ agentContext.setSummary(summaryText, tokenCount);
573
+ log("info", "Summary persisted");
574
+ log("debug", "Summary details", {
575
+ summaryTokens: tokenCount,
576
+ textLength: summaryText.length,
577
+ messagesCompacted: messagesToRefine.length,
578
+ summaryVersion: agentContext.summaryVersion,
579
+ ...summaryUsage != null ? {
580
+ input_tokens: summaryUsage.input_tokens,
581
+ output_tokens: summaryUsage.output_tokens,
582
+ cache_read: summaryUsage.input_token_details?.cache_read,
583
+ cache_creation: summaryUsage.input_token_details?.cache_creation
584
+ } : {}
585
+ });
586
+ await dispatchCompletionEvents({
587
+ graph,
588
+ runnableConfig,
589
+ stepId,
590
+ summaryBlock: buildSummaryBlock({
591
+ summaryText,
592
+ tokenCount,
593
+ stepId,
594
+ stepIndex: runStep.index,
595
+ modelName: clientConfig.modelName,
596
+ provider: clientConfig.provider,
597
+ summaryVersion: agentContext.summaryVersion
598
+ }),
599
+ agentContext,
600
+ runStep,
601
+ summaryUsage,
602
+ agentId: request.agentId,
603
+ messagesAfterCount: messagesToRetain.length
604
+ });
605
+ /**
606
+ * `dispatchCompletionEvents` calls `rebuildTokenMapAfterSummarization({})`
607
+ * which resets the dedupe baseline to 0 — correct under the legacy
608
+ * "remove-all only" shape where no messages survived, but stale once
609
+ * the recency window keeps a tail. Realign the baseline to the
610
+ * surviving tail length so a subsequent prune cycle on the unchanged
611
+ * tail short-circuits via `shouldSkipSummarization` instead of
612
+ * looping back into another summarize call.
613
+ */
614
+ agentContext.markSummarizationTriggered(messagesToRetain.length);
615
+ /**
616
+ * Carry forward the original-content entries that correspond to the
617
+ * retained tail, reindexed for the post-removeAll state where tail
618
+ * messages start at index 0. Without this, a future summarization
619
+ * that pulls these tail messages into its head would only see the
620
+ * masked stubs (since `setSummary` clears `pruneMessages`, and the
621
+ * fresh pruner at the next turn has no record of prior masks).
622
+ * Entries for indices < `tailStartIndex` belong to messages we just
623
+ * summarized they are no longer reachable so they are dropped.
624
+ */
625
+ if (originalPending != null && originalPending.size > 0) {
626
+ const tailPending = /* @__PURE__ */ new Map();
627
+ for (const [idx, content] of originalPending) if (idx >= tailStartIndex) tailPending.set(idx - tailStartIndex, content);
628
+ agentContext.pendingOriginalToolContent = tailPending.size > 0 ? tailPending : void 0;
629
+ } else agentContext.pendingOriginalToolContent = void 0;
630
+ return {
631
+ summarizationRequest: void 0,
632
+ messages: messagesToRetain.length > 0 ? [createRemoveAllMessage(), ...messagesToRetain] : [createRemoveAllMessage()]
633
+ };
634
+ };
760
635
  }
761
636
  /** Extracts text from an LLM response, skipping reasoning/thinking blocks. */
762
637
  function extractResponseText(response) {
763
- const { content } = response;
764
- if (typeof content === 'string') {
765
- return content.trim();
766
- }
767
- if (!Array.isArray(content)) {
768
- return '';
769
- }
770
- const parts = [];
771
- for (const block of content) {
772
- if (typeof block === 'string') {
773
- parts.push(block);
774
- continue;
775
- }
776
- if (block == null || typeof block !== 'object') {
777
- continue;
778
- }
779
- const rec = block;
780
- if (rec.type === ContentTypes.THINKING ||
781
- rec.type === ContentTypes.REASONING_CONTENT ||
782
- rec.type === 'redacted_thinking') {
783
- continue;
784
- }
785
- if (rec.type === 'text' && typeof rec.text === 'string') {
786
- parts.push(rec.text);
787
- }
788
- }
789
- return parts.join('').trim();
638
+ const { content } = response;
639
+ if (typeof content === "string") return content.trim();
640
+ if (!Array.isArray(content)) return "";
641
+ const parts = [];
642
+ for (const block of content) {
643
+ if (typeof block === "string") {
644
+ parts.push(block);
645
+ continue;
646
+ }
647
+ if (block == null || typeof block !== "object") continue;
648
+ const rec = block;
649
+ if (rec.type === "thinking" || rec.type === "reasoning_content" || rec.type === "redacted_thinking") continue;
650
+ if (rec.type === "text" && typeof rec.text === "string") parts.push(rec.text);
651
+ }
652
+ return parts.join("").trim();
790
653
  }
791
654
  function buildSummarizationInstruction(promptText, updatePromptText, priorSummaryText) {
792
- const effectivePrompt = priorSummaryText
793
- ? (updatePromptText ?? promptText)
794
- : promptText;
795
- const parts = [effectivePrompt];
796
- if (priorSummaryText) {
797
- parts.push(`\n\n<previous-summary>\n${priorSummaryText}\n</previous-summary>`);
798
- }
799
- return parts.join('');
655
+ const parts = [priorSummaryText ? updatePromptText ?? promptText : promptText];
656
+ if (priorSummaryText) parts.push(`\n\n<previous-summary>\n${priorSummaryText}\n</previous-summary>`);
657
+ return parts.join("");
800
658
  }
801
659
  /** Creates an `onChunk` callback that dispatches `ON_SUMMARIZE_DELTA` events for streaming. */
802
- function createSummarizationChunkHandler({ stepId, config, provider, reasoningKey = 'reasoning_content', }) {
803
- if (stepId == null || stepId === '' || !config) {
804
- return undefined;
805
- }
806
- return (chunk) => {
807
- const chunkAny = chunk;
808
- const raw = getChunkContent({ chunk: chunkAny, provider, reasoningKey });
809
- if (raw == null || (typeof raw === 'string' && !raw)) {
810
- return;
811
- }
812
- const contentBlocks = typeof raw === 'string'
813
- ? [{ type: ContentTypes.TEXT, text: raw }]
814
- : raw;
815
- void safeDispatchCustomEvent(GraphEvents.ON_SUMMARIZE_DELTA, {
816
- id: stepId,
817
- delta: {
818
- summary: {
819
- type: ContentTypes.SUMMARY,
820
- content: contentBlocks,
821
- provider: String(config.metadata?.summarization_provider ?? ''),
822
- model: String(config.metadata?.summarization_model ?? ''),
823
- },
824
- },
825
- }, config);
826
- };
660
+ function createSummarizationChunkHandler({ stepId, config, provider, reasoningKey = "reasoning_content" }) {
661
+ if (stepId == null || stepId === "" || !config) return;
662
+ return (chunk) => {
663
+ const raw = getChunkContent({
664
+ chunk,
665
+ provider,
666
+ reasoningKey
667
+ });
668
+ if (raw == null || typeof raw === "string" && !raw) return;
669
+ safeDispatchCustomEvent("on_summarize_delta", {
670
+ id: stepId,
671
+ delta: { summary: {
672
+ type: "summary",
673
+ content: typeof raw === "string" ? [{
674
+ type: "text",
675
+ text: raw
676
+ }] : raw,
677
+ provider: String(config.metadata?.summarization_provider ?? ""),
678
+ model: String(config.metadata?.summarization_model ?? "")
679
+ } }
680
+ }, config);
681
+ };
827
682
  }
828
683
  function traceConfig(config, stage) {
829
- if (!config) {
830
- return undefined;
831
- }
832
- return {
833
- ...config,
834
- runName: `summarization:${stage}`,
835
- metadata: { ...config.metadata, summarization: true, stage },
836
- };
684
+ if (!config) return;
685
+ return {
686
+ ...config,
687
+ runName: `summarization:${stage}`,
688
+ metadata: {
689
+ ...config.metadata,
690
+ summarization: true,
691
+ stage
692
+ }
693
+ };
837
694
  }
838
695
  /**
839
- * Cache-friendly compaction: sends raw conversation messages with the
840
- * summarization instruction appended as the final HumanMessage.
841
- * Providers with prompt caching get a cache hit on the system prompt +
842
- * tool definitions prefix.
843
- */
844
- async function summarizeWithCacheHit({ model, messages, promptText, updatePromptText, priorSummaryText, config, stepId, provider, reasoningKey, usePromptCache, log, }) {
845
- const instruction = buildSummarizationInstruction(promptText, updatePromptText, priorSummaryText);
846
- const fullMessages = [...messages, new HumanMessage(instruction)];
847
- const invokeMessages = usePromptCache === true ? addCacheControl(fullMessages) : fullMessages;
848
- const result = await attemptInvoke({
849
- model,
850
- messages: invokeMessages,
851
- provider,
852
- onChunk: createSummarizationChunkHandler({
853
- stepId,
854
- config: traceConfig(config, 'cache_hit_compaction'),
855
- provider,
856
- reasoningKey,
857
- }),
858
- }, traceConfig(config, 'cache_hit_compaction'));
859
- const responseMsg = result.messages?.[0];
860
- const text = responseMsg
861
- ? extractResponseText(responseMsg)
862
- : '';
863
- let usage;
864
- let usageSource = 'none';
865
- if (responseMsg != null &&
866
- 'usage_metadata' in responseMsg &&
867
- responseMsg.usage_metadata != null) {
868
- usage = responseMsg.usage_metadata;
869
- usageSource = 'usage_metadata';
870
- }
871
- else if (responseMsg != null) {
872
- const respMeta = responseMsg.response_metadata;
873
- const raw = respMeta?.metadata
874
- ?.usage;
875
- if (raw != null) {
876
- usage = {
877
- input_tokens: Number(raw.inputTokens) || undefined,
878
- output_tokens: Number(raw.outputTokens) || undefined,
879
- };
880
- usageSource = 'response_metadata';
881
- }
882
- }
883
- const cacheDetails = usage?.input_token_details;
884
- log?.('debug', 'Summarization LLM usage', {
885
- source: usageSource,
886
- input_tokens: usage?.input_tokens,
887
- output_tokens: usage?.output_tokens,
888
- ...(cacheDetails?.cache_read != null || cacheDetails?.cache_creation != null
889
- ? {
890
- 'input_token_details.cache_read': cacheDetails.cache_read,
891
- 'input_token_details.cache_creation': cacheDetails.cache_creation,
892
- }
893
- : {}),
894
- });
895
- return { text, usage };
696
+ * Cache-friendly compaction: sends raw conversation messages with the
697
+ * summarization instruction appended as the final HumanMessage.
698
+ * Providers with prompt caching get a cache hit on the system prompt +
699
+ * tool definitions prefix.
700
+ */
701
+ async function summarizeWithCacheHit({ model, messages, promptText, updatePromptText, priorSummaryText, config, stepId, provider, reasoningKey, usePromptCache, log }) {
702
+ const instruction = buildSummarizationInstruction(promptText, updatePromptText, priorSummaryText);
703
+ const fullMessages = [...messages, new HumanMessage(instruction)];
704
+ const responseMsg = (await attemptInvoke({
705
+ model,
706
+ messages: usePromptCache === true ? addCacheControl(fullMessages) : fullMessages,
707
+ provider,
708
+ onChunk: createSummarizationChunkHandler({
709
+ stepId,
710
+ config: traceConfig(config, "cache_hit_compaction"),
711
+ provider,
712
+ reasoningKey
713
+ })
714
+ }, traceConfig(config, "cache_hit_compaction"))).messages?.[0];
715
+ const text = responseMsg ? extractResponseText(responseMsg) : "";
716
+ let usage;
717
+ let usageSource = "none";
718
+ if (responseMsg != null && "usage_metadata" in responseMsg && responseMsg.usage_metadata != null) {
719
+ usage = responseMsg.usage_metadata;
720
+ usageSource = "usage_metadata";
721
+ } else if (responseMsg != null) {
722
+ const raw = (responseMsg.response_metadata?.metadata)?.usage;
723
+ if (raw != null) {
724
+ usage = {
725
+ input_tokens: Number(raw.inputTokens) || void 0,
726
+ output_tokens: Number(raw.outputTokens) || void 0
727
+ };
728
+ usageSource = "response_metadata";
729
+ }
730
+ }
731
+ const cacheDetails = usage?.input_token_details;
732
+ log?.("debug", "Summarization LLM usage", {
733
+ source: usageSource,
734
+ input_tokens: usage?.input_tokens,
735
+ output_tokens: usage?.output_tokens,
736
+ ...cacheDetails?.cache_read != null || cacheDetails?.cache_creation != null ? {
737
+ "input_token_details.cache_read": cacheDetails.cache_read,
738
+ "input_token_details.cache_creation": cacheDetails.cache_creation
739
+ } : {}
740
+ });
741
+ return {
742
+ text,
743
+ usage
744
+ };
896
745
  }
746
+ //#endregion
747
+ export { createSummarizeNode };
897
748
 
898
- export { DEFAULT_SUMMARIZATION_PROMPT, DEFAULT_UPDATE_SUMMARIZATION_PROMPT, createSummarizeNode };
899
- //# sourceMappingURL=node.mjs.map
749
+ //# sourceMappingURL=node.mjs.map