@librechat/agents 3.4.6 → 3.5.0

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 (1027) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +0 -356
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/agents/projection.cjs +0 -9
  4. package/dist/cjs/agents/projection.cjs.map +1 -1
  5. package/dist/cjs/common/constants.cjs +0 -26
  6. package/dist/cjs/common/constants.cjs.map +1 -1
  7. package/dist/cjs/common/enum.cjs +0 -85
  8. package/dist/cjs/common/enum.cjs.map +1 -1
  9. package/dist/cjs/events.cjs +0 -14
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1 -909
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +7 -272
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/applyGraphRuntimeConfig.cjs.map +1 -1
  16. package/dist/cjs/graphs/createGraph.cjs.map +1 -1
  17. package/dist/cjs/hitl/askUserQuestion.cjs +0 -53
  18. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  19. package/dist/cjs/hitl/askUserQuestions.cjs +0 -20
  20. package/dist/cjs/hitl/askUserQuestions.cjs.map +1 -1
  21. package/dist/cjs/hitl/askUserQuestionsInterrupt.cjs +0 -6
  22. package/dist/cjs/hitl/askUserQuestionsInterrupt.cjs.map +1 -1
  23. package/dist/cjs/hooks/HookRegistry.cjs +0 -127
  24. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  25. package/dist/cjs/hooks/createToolPolicyHook.cjs +0 -38
  26. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  27. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +0 -77
  28. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  29. package/dist/cjs/hooks/executeHooks.cjs +0 -79
  30. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  31. package/dist/cjs/hooks/index.cjs +0 -16
  32. package/dist/cjs/hooks/index.cjs.map +1 -1
  33. package/dist/cjs/hooks/matchers.cjs +0 -104
  34. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  35. package/dist/cjs/hooks/types.cjs +0 -8
  36. package/dist/cjs/hooks/types.cjs.map +1 -1
  37. package/dist/cjs/instrumentation.cjs +0 -14
  38. package/dist/cjs/instrumentation.cjs.map +1 -1
  39. package/dist/cjs/langfuse.cjs +0 -75
  40. package/dist/cjs/langfuse.cjs.map +1 -1
  41. package/dist/cjs/langfuseConfig.cjs.map +1 -1
  42. package/dist/cjs/langfuseRuntimeContext.cjs +0 -13
  43. package/dist/cjs/langfuseRuntimeContext.cjs.map +1 -1
  44. package/dist/cjs/langfuseRuntimeScope.cjs +0 -4
  45. package/dist/cjs/langfuseRuntimeScope.cjs.map +1 -1
  46. package/dist/cjs/langfuseSpanRegistry.cjs +0 -28
  47. package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
  48. package/dist/cjs/langfuseToolOutputTracing.cjs +0 -3
  49. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  50. package/dist/cjs/langfuseTraceShaping.cjs +0 -74
  51. package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/index.cjs +0 -3
  53. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  55. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -111
  56. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  57. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +0 -1
  58. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  59. package/dist/cjs/llm/anthropic/utils/stream_events.cjs +0 -8
  60. package/dist/cjs/llm/anthropic/utils/stream_events.cjs.map +1 -1
  61. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  62. package/dist/cjs/llm/bedrock/cachePoints.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/index.cjs +1 -95
  64. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  65. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +0 -78
  67. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  68. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +0 -24
  69. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  70. package/dist/cjs/llm/contextOverflowRecovery.cjs +0 -62
  71. package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -1
  72. package/dist/cjs/llm/fake.cjs.map +1 -1
  73. package/dist/cjs/llm/google/index.cjs +2 -21
  74. package/dist/cjs/llm/google/index.cjs.map +1 -1
  75. package/dist/cjs/llm/google/utils/common.cjs +5 -35
  76. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  77. package/dist/cjs/llm/init.cjs +0 -9
  78. package/dist/cjs/llm/init.cjs.map +1 -1
  79. package/dist/cjs/llm/invoke.cjs +1 -270
  80. package/dist/cjs/llm/invoke.cjs.map +1 -1
  81. package/dist/cjs/llm/mistral/index.cjs.map +1 -1
  82. package/dist/cjs/llm/openai/index.cjs +0 -99
  83. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  84. package/dist/cjs/llm/openai/streamMetadata.cjs +0 -21
  85. package/dist/cjs/llm/openai/streamMetadata.cjs.map +1 -1
  86. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  87. package/dist/cjs/llm/openrouter/index.cjs +0 -1
  88. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  89. package/dist/cjs/llm/openrouter/toolCache.cjs +0 -6
  90. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  91. package/dist/cjs/llm/preempt.cjs +0 -75
  92. package/dist/cjs/llm/preempt.cjs.map +1 -1
  93. package/dist/cjs/llm/providers.cjs.map +1 -1
  94. package/dist/cjs/llm/request.cjs +0 -10
  95. package/dist/cjs/llm/request.cjs.map +1 -1
  96. package/dist/cjs/llm/stream/chunkAdapters.cjs +0 -62
  97. package/dist/cjs/llm/stream/chunkAdapters.cjs.map +1 -1
  98. package/dist/cjs/llm/stream/smoother.cjs +0 -58
  99. package/dist/cjs/llm/stream/smoother.cjs.map +1 -1
  100. package/dist/cjs/llm/streamLimits.cjs +4 -293
  101. package/dist/cjs/llm/streamLimits.cjs.map +1 -1
  102. package/dist/cjs/llm/truncation.cjs +0 -36
  103. package/dist/cjs/llm/truncation.cjs.map +1 -1
  104. package/dist/cjs/llm/vertexai/index.cjs +0 -330
  105. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  106. package/dist/cjs/messages/alternation.cjs +0 -43
  107. package/dist/cjs/messages/alternation.cjs.map +1 -1
  108. package/dist/cjs/messages/anthropicToolCache.cjs +0 -45
  109. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  110. package/dist/cjs/messages/assistantPhase.cjs +0 -12
  111. package/dist/cjs/messages/assistantPhase.cjs.map +1 -1
  112. package/dist/cjs/messages/budget.cjs +0 -9
  113. package/dist/cjs/messages/budget.cjs.map +1 -1
  114. package/dist/cjs/messages/cache.cjs +0 -172
  115. package/dist/cjs/messages/cache.cjs.map +1 -1
  116. package/dist/cjs/messages/content.cjs +0 -9
  117. package/dist/cjs/messages/content.cjs.map +1 -1
  118. package/dist/cjs/messages/contextPruning.cjs +0 -15
  119. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  120. package/dist/cjs/messages/contextPruningSettings.cjs +0 -3
  121. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  122. package/dist/cjs/messages/core.cjs +0 -48
  123. package/dist/cjs/messages/core.cjs.map +1 -1
  124. package/dist/cjs/messages/format.cjs +1 -345
  125. package/dist/cjs/messages/format.cjs.map +1 -1
  126. package/dist/cjs/messages/handoffCue.cjs +0 -36
  127. package/dist/cjs/messages/handoffCue.cjs.map +1 -1
  128. package/dist/cjs/messages/ids.cjs.map +1 -1
  129. package/dist/cjs/messages/injected.cjs +0 -33
  130. package/dist/cjs/messages/injected.cjs.map +1 -1
  131. package/dist/cjs/messages/langchain.cjs +0 -14
  132. package/dist/cjs/messages/langchain.cjs.map +1 -1
  133. package/dist/cjs/messages/prune.cjs +1 -184
  134. package/dist/cjs/messages/prune.cjs.map +1 -1
  135. package/dist/cjs/messages/recency.cjs +0 -32
  136. package/dist/cjs/messages/recency.cjs.map +1 -1
  137. package/dist/cjs/messages/reducer.cjs +0 -30
  138. package/dist/cjs/messages/reducer.cjs.map +1 -1
  139. package/dist/cjs/messages/tools.cjs +0 -14
  140. package/dist/cjs/messages/tools.cjs.map +1 -1
  141. package/dist/cjs/openai/index.cjs.map +1 -1
  142. package/dist/cjs/prompts/activityLabel.cjs +9 -79
  143. package/dist/cjs/prompts/activityLabel.cjs.map +1 -1
  144. package/dist/cjs/responses/index.cjs.map +1 -1
  145. package/dist/cjs/run.cjs +2 -538
  146. package/dist/cjs/run.cjs.map +1 -1
  147. package/dist/cjs/session/AgentSession.cjs +1 -17
  148. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  149. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  150. package/dist/cjs/session/handlers.cjs +0 -7
  151. package/dist/cjs/session/handlers.cjs.map +1 -1
  152. package/dist/cjs/session/ids.cjs.map +1 -1
  153. package/dist/cjs/session/messageSerialization.cjs +0 -4
  154. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  155. package/dist/cjs/stream.cjs +1 -93
  156. package/dist/cjs/stream.cjs.map +1 -1
  157. package/dist/cjs/summarization/index.cjs +0 -27
  158. package/dist/cjs/summarization/index.cjs.map +1 -1
  159. package/dist/cjs/summarization/node.cjs +0 -273
  160. package/dist/cjs/summarization/node.cjs.map +1 -1
  161. package/dist/cjs/tools/BashExecutor.cjs +0 -35
  162. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  163. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +0 -24
  164. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  165. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  166. package/dist/cjs/tools/CodeExecutor.cjs +0 -13
  167. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  168. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  169. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +0 -101
  170. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  171. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  172. package/dist/cjs/tools/SkillTool.cjs +0 -5
  173. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  174. package/dist/cjs/tools/SubagentTool.cjs +0 -10
  175. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  176. package/dist/cjs/tools/ToolNode.cjs +6 -1038
  177. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  178. package/dist/cjs/tools/ToolSearch.cjs +0 -179
  179. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  180. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  181. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  182. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +0 -39
  183. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  184. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  185. package/dist/cjs/tools/eagerEventExecution.cjs +0 -6
  186. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  187. package/dist/cjs/tools/handlers.cjs +1 -41
  188. package/dist/cjs/tools/handlers.cjs.map +1 -1
  189. package/dist/cjs/tools/intentArg.cjs +1 -132
  190. package/dist/cjs/tools/intentArg.cjs.map +1 -1
  191. package/dist/cjs/tools/local/CompileCheckTool.cjs +0 -25
  192. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  193. package/dist/cjs/tools/local/FileCheckpointer.cjs +0 -23
  194. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  195. package/dist/cjs/tools/local/LocalCodingTools.cjs +0 -80
  196. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  197. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +0 -126
  198. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  199. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  200. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +0 -12
  201. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  202. package/dist/cjs/tools/local/attachments.cjs +0 -44
  203. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  204. package/dist/cjs/tools/local/bashAst.cjs +0 -16
  205. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  206. package/dist/cjs/tools/local/editStrategies.cjs +0 -14
  207. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  208. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  209. package/dist/cjs/tools/local/syntaxCheck.cjs +0 -31
  210. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  211. package/dist/cjs/tools/local/textEncoding.cjs +0 -11
  212. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  213. package/dist/cjs/tools/local/workspaceFS.cjs +0 -33
  214. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  215. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  216. package/dist/cjs/tools/schema.cjs +0 -8
  217. package/dist/cjs/tools/schema.cjs.map +1 -1
  218. package/dist/cjs/tools/search/anthropic.cjs +0 -9
  219. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  220. package/dist/cjs/tools/search/content.cjs.map +1 -1
  221. package/dist/cjs/tools/search/crw-scraper.cjs +0 -33
  222. package/dist/cjs/tools/search/crw-scraper.cjs.map +1 -1
  223. package/dist/cjs/tools/search/crw-search.cjs +0 -2
  224. package/dist/cjs/tools/search/crw-search.cjs.map +1 -1
  225. package/dist/cjs/tools/search/firecrawl.cjs +0 -25
  226. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  227. package/dist/cjs/tools/search/format.cjs +0 -30
  228. package/dist/cjs/tools/search/format.cjs.map +1 -1
  229. package/dist/cjs/tools/search/highlights.cjs +0 -16
  230. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  231. package/dist/cjs/tools/search/keenable-scraper.cjs +0 -8
  232. package/dist/cjs/tools/search/keenable-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/keenable-search.cjs +0 -7
  234. package/dist/cjs/tools/search/keenable-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/rerankers.cjs +0 -35
  236. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  237. package/dist/cjs/tools/search/schema.cjs +0 -1
  238. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  239. package/dist/cjs/tools/search/search.cjs +1 -14
  240. package/dist/cjs/tools/search/search.cjs.map +1 -1
  241. package/dist/cjs/tools/search/serper-scraper.cjs +0 -46
  242. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  243. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  244. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  245. package/dist/cjs/tools/search/tool.cjs +0 -25
  246. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  247. package/dist/cjs/tools/search/utils.cjs +0 -8
  248. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  249. package/dist/cjs/tools/skillCatalog.cjs +0 -6
  250. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  251. package/dist/cjs/tools/streamedToolCallSeals.cjs +0 -6
  252. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  253. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +0 -2
  254. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
  255. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +3 -213
  256. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  257. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  258. package/dist/cjs/tools/subagent/childGraphConfig.cjs +0 -4
  259. package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
  260. package/dist/cjs/tools/subagent/runtimeLimits.cjs.map +1 -1
  261. package/dist/cjs/tools/toolOutputReferences.cjs +1 -322
  262. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  263. package/dist/cjs/types/hitl.cjs +0 -5
  264. package/dist/cjs/types/hitl.cjs.map +1 -1
  265. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  266. package/dist/cjs/utils/errors.cjs +14 -165
  267. package/dist/cjs/utils/errors.cjs.map +1 -1
  268. package/dist/cjs/utils/events.cjs +0 -10
  269. package/dist/cjs/utils/events.cjs.map +1 -1
  270. package/dist/cjs/utils/graph.cjs.map +1 -1
  271. package/dist/cjs/utils/handlers.cjs +0 -3
  272. package/dist/cjs/utils/handlers.cjs.map +1 -1
  273. package/dist/cjs/utils/llm.cjs +0 -1
  274. package/dist/cjs/utils/llm.cjs.map +1 -1
  275. package/dist/cjs/utils/misc.cjs +0 -16
  276. package/dist/cjs/utils/misc.cjs.map +1 -1
  277. package/dist/cjs/utils/proxy.cjs +0 -26
  278. package/dist/cjs/utils/proxy.cjs.map +1 -1
  279. package/dist/cjs/utils/run.cjs +0 -6
  280. package/dist/cjs/utils/run.cjs.map +1 -1
  281. package/dist/cjs/utils/schema.cjs +0 -5
  282. package/dist/cjs/utils/schema.cjs.map +1 -1
  283. package/dist/cjs/utils/title.cjs +0 -6
  284. package/dist/cjs/utils/title.cjs.map +1 -1
  285. package/dist/cjs/utils/tokens.cjs +0 -113
  286. package/dist/cjs/utils/tokens.cjs.map +1 -1
  287. package/dist/cjs/utils/toolContent.cjs +0 -41
  288. package/dist/cjs/utils/toolContent.cjs.map +1 -1
  289. package/dist/cjs/utils/truncation.cjs +0 -61
  290. package/dist/cjs/utils/truncation.cjs.map +1 -1
  291. package/dist/esm/agents/AgentContext.mjs +0 -356
  292. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  293. package/dist/esm/agents/projection.mjs +0 -9
  294. package/dist/esm/agents/projection.mjs.map +1 -1
  295. package/dist/esm/common/constants.mjs +0 -26
  296. package/dist/esm/common/constants.mjs.map +1 -1
  297. package/dist/esm/common/enum.mjs +0 -85
  298. package/dist/esm/common/enum.mjs.map +1 -1
  299. package/dist/esm/events.mjs +0 -14
  300. package/dist/esm/events.mjs.map +1 -1
  301. package/dist/esm/graphs/Graph.mjs +1 -909
  302. package/dist/esm/graphs/Graph.mjs.map +1 -1
  303. package/dist/esm/graphs/MultiAgentGraph.mjs +7 -272
  304. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  305. package/dist/esm/graphs/applyGraphRuntimeConfig.mjs.map +1 -1
  306. package/dist/esm/graphs/createGraph.mjs.map +1 -1
  307. package/dist/esm/hitl/askUserQuestion.mjs +0 -53
  308. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  309. package/dist/esm/hitl/askUserQuestions.mjs +0 -20
  310. package/dist/esm/hitl/askUserQuestions.mjs.map +1 -1
  311. package/dist/esm/hitl/askUserQuestionsInterrupt.mjs +0 -6
  312. package/dist/esm/hitl/askUserQuestionsInterrupt.mjs.map +1 -1
  313. package/dist/esm/hooks/HookRegistry.mjs +0 -127
  314. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  315. package/dist/esm/hooks/createToolPolicyHook.mjs +0 -38
  316. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  317. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +0 -77
  318. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  319. package/dist/esm/hooks/executeHooks.mjs +0 -79
  320. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  321. package/dist/esm/hooks/index.mjs +0 -16
  322. package/dist/esm/hooks/index.mjs.map +1 -1
  323. package/dist/esm/hooks/matchers.mjs +0 -104
  324. package/dist/esm/hooks/matchers.mjs.map +1 -1
  325. package/dist/esm/hooks/types.mjs +0 -8
  326. package/dist/esm/hooks/types.mjs.map +1 -1
  327. package/dist/esm/instrumentation.mjs +0 -14
  328. package/dist/esm/instrumentation.mjs.map +1 -1
  329. package/dist/esm/langfuse.mjs +0 -75
  330. package/dist/esm/langfuse.mjs.map +1 -1
  331. package/dist/esm/langfuseConfig.mjs.map +1 -1
  332. package/dist/esm/langfuseRuntimeContext.mjs +0 -13
  333. package/dist/esm/langfuseRuntimeContext.mjs.map +1 -1
  334. package/dist/esm/langfuseRuntimeScope.mjs +0 -4
  335. package/dist/esm/langfuseRuntimeScope.mjs.map +1 -1
  336. package/dist/esm/langfuseSpanRegistry.mjs +0 -28
  337. package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
  338. package/dist/esm/langfuseToolOutputTracing.mjs +0 -3
  339. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  340. package/dist/esm/langfuseTraceShaping.mjs +0 -74
  341. package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
  342. package/dist/esm/llm/anthropic/index.mjs +0 -3
  343. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  344. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  345. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -111
  346. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  347. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +0 -1
  348. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  349. package/dist/esm/llm/anthropic/utils/stream_events.mjs +0 -8
  350. package/dist/esm/llm/anthropic/utils/stream_events.mjs.map +1 -1
  351. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  352. package/dist/esm/llm/bedrock/cachePoints.mjs.map +1 -1
  353. package/dist/esm/llm/bedrock/index.mjs +1 -95
  354. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  355. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  356. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +0 -78
  357. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  358. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +0 -24
  359. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  360. package/dist/esm/llm/contextOverflowRecovery.mjs +0 -62
  361. package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -1
  362. package/dist/esm/llm/fake.mjs.map +1 -1
  363. package/dist/esm/llm/google/index.mjs +2 -21
  364. package/dist/esm/llm/google/index.mjs.map +1 -1
  365. package/dist/esm/llm/google/utils/common.mjs +5 -35
  366. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  367. package/dist/esm/llm/init.mjs +0 -9
  368. package/dist/esm/llm/init.mjs.map +1 -1
  369. package/dist/esm/llm/invoke.mjs +1 -270
  370. package/dist/esm/llm/invoke.mjs.map +1 -1
  371. package/dist/esm/llm/mistral/index.mjs.map +1 -1
  372. package/dist/esm/llm/openai/index.mjs +0 -99
  373. package/dist/esm/llm/openai/index.mjs.map +1 -1
  374. package/dist/esm/llm/openai/streamMetadata.mjs +0 -21
  375. package/dist/esm/llm/openai/streamMetadata.mjs.map +1 -1
  376. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  377. package/dist/esm/llm/openrouter/index.mjs +0 -1
  378. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  379. package/dist/esm/llm/openrouter/toolCache.mjs +0 -6
  380. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  381. package/dist/esm/llm/preempt.mjs +0 -75
  382. package/dist/esm/llm/preempt.mjs.map +1 -1
  383. package/dist/esm/llm/providers.mjs.map +1 -1
  384. package/dist/esm/llm/request.mjs +0 -10
  385. package/dist/esm/llm/request.mjs.map +1 -1
  386. package/dist/esm/llm/stream/chunkAdapters.mjs +0 -62
  387. package/dist/esm/llm/stream/chunkAdapters.mjs.map +1 -1
  388. package/dist/esm/llm/stream/smoother.mjs +0 -58
  389. package/dist/esm/llm/stream/smoother.mjs.map +1 -1
  390. package/dist/esm/llm/streamLimits.mjs +4 -293
  391. package/dist/esm/llm/streamLimits.mjs.map +1 -1
  392. package/dist/esm/llm/truncation.mjs +0 -36
  393. package/dist/esm/llm/truncation.mjs.map +1 -1
  394. package/dist/esm/llm/vertexai/index.mjs +0 -330
  395. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  396. package/dist/esm/messages/alternation.mjs +0 -43
  397. package/dist/esm/messages/alternation.mjs.map +1 -1
  398. package/dist/esm/messages/anthropicToolCache.mjs +0 -45
  399. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  400. package/dist/esm/messages/assistantPhase.mjs +0 -12
  401. package/dist/esm/messages/assistantPhase.mjs.map +1 -1
  402. package/dist/esm/messages/budget.mjs +0 -9
  403. package/dist/esm/messages/budget.mjs.map +1 -1
  404. package/dist/esm/messages/cache.mjs +0 -172
  405. package/dist/esm/messages/cache.mjs.map +1 -1
  406. package/dist/esm/messages/content.mjs +0 -9
  407. package/dist/esm/messages/content.mjs.map +1 -1
  408. package/dist/esm/messages/contextPruning.mjs +0 -15
  409. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  410. package/dist/esm/messages/contextPruningSettings.mjs +0 -3
  411. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  412. package/dist/esm/messages/core.mjs +0 -48
  413. package/dist/esm/messages/core.mjs.map +1 -1
  414. package/dist/esm/messages/format.mjs +1 -345
  415. package/dist/esm/messages/format.mjs.map +1 -1
  416. package/dist/esm/messages/handoffCue.mjs +0 -36
  417. package/dist/esm/messages/handoffCue.mjs.map +1 -1
  418. package/dist/esm/messages/ids.mjs.map +1 -1
  419. package/dist/esm/messages/injected.mjs +0 -33
  420. package/dist/esm/messages/injected.mjs.map +1 -1
  421. package/dist/esm/messages/langchain.mjs +0 -14
  422. package/dist/esm/messages/langchain.mjs.map +1 -1
  423. package/dist/esm/messages/prune.mjs +1 -184
  424. package/dist/esm/messages/prune.mjs.map +1 -1
  425. package/dist/esm/messages/recency.mjs +0 -32
  426. package/dist/esm/messages/recency.mjs.map +1 -1
  427. package/dist/esm/messages/reducer.mjs +0 -30
  428. package/dist/esm/messages/reducer.mjs.map +1 -1
  429. package/dist/esm/messages/tools.mjs +0 -14
  430. package/dist/esm/messages/tools.mjs.map +1 -1
  431. package/dist/esm/openai/index.mjs.map +1 -1
  432. package/dist/esm/prompts/activityLabel.mjs +9 -79
  433. package/dist/esm/prompts/activityLabel.mjs.map +1 -1
  434. package/dist/esm/responses/index.mjs.map +1 -1
  435. package/dist/esm/run.mjs +2 -538
  436. package/dist/esm/run.mjs.map +1 -1
  437. package/dist/esm/session/AgentSession.mjs +1 -17
  438. package/dist/esm/session/AgentSession.mjs.map +1 -1
  439. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  440. package/dist/esm/session/handlers.mjs +0 -7
  441. package/dist/esm/session/handlers.mjs.map +1 -1
  442. package/dist/esm/session/ids.mjs.map +1 -1
  443. package/dist/esm/session/messageSerialization.mjs +0 -4
  444. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  445. package/dist/esm/stream.mjs +1 -93
  446. package/dist/esm/stream.mjs.map +1 -1
  447. package/dist/esm/summarization/index.mjs +0 -27
  448. package/dist/esm/summarization/index.mjs.map +1 -1
  449. package/dist/esm/summarization/node.mjs +0 -273
  450. package/dist/esm/summarization/node.mjs.map +1 -1
  451. package/dist/esm/tools/BashExecutor.mjs +0 -35
  452. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  453. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +0 -24
  454. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  455. package/dist/esm/tools/Calculator.mjs.map +1 -1
  456. package/dist/esm/tools/CodeExecutor.mjs +0 -13
  457. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  458. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  459. package/dist/esm/tools/ProgrammaticToolCalling.mjs +0 -101
  460. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  461. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  462. package/dist/esm/tools/SkillTool.mjs +0 -5
  463. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  464. package/dist/esm/tools/SubagentTool.mjs +0 -10
  465. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  466. package/dist/esm/tools/ToolNode.mjs +6 -1038
  467. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  468. package/dist/esm/tools/ToolSearch.mjs +0 -179
  469. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  470. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  471. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  472. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +0 -39
  473. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  474. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  475. package/dist/esm/tools/eagerEventExecution.mjs +0 -6
  476. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  477. package/dist/esm/tools/handlers.mjs +1 -41
  478. package/dist/esm/tools/handlers.mjs.map +1 -1
  479. package/dist/esm/tools/intentArg.mjs +1 -132
  480. package/dist/esm/tools/intentArg.mjs.map +1 -1
  481. package/dist/esm/tools/local/CompileCheckTool.mjs +0 -25
  482. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  483. package/dist/esm/tools/local/FileCheckpointer.mjs +0 -23
  484. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  485. package/dist/esm/tools/local/LocalCodingTools.mjs +0 -80
  486. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  487. package/dist/esm/tools/local/LocalExecutionEngine.mjs +0 -126
  488. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  489. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  490. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +0 -12
  491. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  492. package/dist/esm/tools/local/attachments.mjs +0 -44
  493. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  494. package/dist/esm/tools/local/bashAst.mjs +0 -16
  495. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  496. package/dist/esm/tools/local/editStrategies.mjs +0 -14
  497. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  498. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  499. package/dist/esm/tools/local/syntaxCheck.mjs +0 -31
  500. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  501. package/dist/esm/tools/local/textEncoding.mjs +0 -11
  502. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  503. package/dist/esm/tools/local/workspaceFS.mjs +0 -33
  504. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  505. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  506. package/dist/esm/tools/schema.mjs +0 -8
  507. package/dist/esm/tools/schema.mjs.map +1 -1
  508. package/dist/esm/tools/search/anthropic.mjs +0 -9
  509. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  510. package/dist/esm/tools/search/content.mjs.map +1 -1
  511. package/dist/esm/tools/search/crw-scraper.mjs +0 -33
  512. package/dist/esm/tools/search/crw-scraper.mjs.map +1 -1
  513. package/dist/esm/tools/search/crw-search.mjs +0 -2
  514. package/dist/esm/tools/search/crw-search.mjs.map +1 -1
  515. package/dist/esm/tools/search/firecrawl.mjs +0 -25
  516. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  517. package/dist/esm/tools/search/format.mjs +0 -30
  518. package/dist/esm/tools/search/format.mjs.map +1 -1
  519. package/dist/esm/tools/search/highlights.mjs +0 -16
  520. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  521. package/dist/esm/tools/search/keenable-scraper.mjs +0 -8
  522. package/dist/esm/tools/search/keenable-scraper.mjs.map +1 -1
  523. package/dist/esm/tools/search/keenable-search.mjs +0 -7
  524. package/dist/esm/tools/search/keenable-search.mjs.map +1 -1
  525. package/dist/esm/tools/search/rerankers.mjs +0 -35
  526. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  527. package/dist/esm/tools/search/schema.mjs +0 -1
  528. package/dist/esm/tools/search/schema.mjs.map +1 -1
  529. package/dist/esm/tools/search/search.mjs +1 -14
  530. package/dist/esm/tools/search/search.mjs.map +1 -1
  531. package/dist/esm/tools/search/serper-scraper.mjs +0 -46
  532. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  533. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  534. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  535. package/dist/esm/tools/search/tool.mjs +0 -25
  536. package/dist/esm/tools/search/tool.mjs.map +1 -1
  537. package/dist/esm/tools/search/utils.mjs +0 -8
  538. package/dist/esm/tools/search/utils.mjs.map +1 -1
  539. package/dist/esm/tools/skillCatalog.mjs +0 -6
  540. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  541. package/dist/esm/tools/streamedToolCallSeals.mjs +0 -6
  542. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  543. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +0 -2
  544. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
  545. package/dist/esm/tools/subagent/SubagentExecutor.mjs +3 -213
  546. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  547. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  548. package/dist/esm/tools/subagent/childGraphConfig.mjs +0 -4
  549. package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
  550. package/dist/esm/tools/subagent/runtimeLimits.mjs.map +1 -1
  551. package/dist/esm/tools/toolOutputReferences.mjs +1 -322
  552. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  553. package/dist/esm/types/hitl.mjs +0 -5
  554. package/dist/esm/types/hitl.mjs.map +1 -1
  555. package/dist/esm/utils/callbacks.mjs.map +1 -1
  556. package/dist/esm/utils/errors.mjs +14 -165
  557. package/dist/esm/utils/errors.mjs.map +1 -1
  558. package/dist/esm/utils/events.mjs +0 -10
  559. package/dist/esm/utils/events.mjs.map +1 -1
  560. package/dist/esm/utils/graph.mjs.map +1 -1
  561. package/dist/esm/utils/handlers.mjs +0 -3
  562. package/dist/esm/utils/handlers.mjs.map +1 -1
  563. package/dist/esm/utils/llm.mjs +0 -1
  564. package/dist/esm/utils/llm.mjs.map +1 -1
  565. package/dist/esm/utils/misc.mjs +0 -16
  566. package/dist/esm/utils/misc.mjs.map +1 -1
  567. package/dist/esm/utils/proxy.mjs +0 -26
  568. package/dist/esm/utils/proxy.mjs.map +1 -1
  569. package/dist/esm/utils/run.mjs +0 -6
  570. package/dist/esm/utils/run.mjs.map +1 -1
  571. package/dist/esm/utils/schema.mjs +0 -5
  572. package/dist/esm/utils/schema.mjs.map +1 -1
  573. package/dist/esm/utils/title.mjs +0 -6
  574. package/dist/esm/utils/title.mjs.map +1 -1
  575. package/dist/esm/utils/tokens.mjs +0 -113
  576. package/dist/esm/utils/tokens.mjs.map +1 -1
  577. package/dist/esm/utils/toolContent.mjs +0 -41
  578. package/dist/esm/utils/toolContent.mjs.map +1 -1
  579. package/dist/esm/utils/truncation.mjs +0 -61
  580. package/dist/esm/utils/truncation.mjs.map +1 -1
  581. package/dist/types/agents/AgentContext.d.ts +3 -3
  582. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +3 -3
  583. package/dist/types/agents/projection.d.ts +1 -1
  584. package/dist/types/events.d.ts +2 -2
  585. package/dist/types/graphs/Graph.d.ts +11 -11
  586. package/dist/types/graphs/MultiAgentGraph.d.ts +2 -2
  587. package/dist/types/graphs/createGraph.d.ts +4 -4
  588. package/dist/types/graphs/graphFactory.d.ts +1 -1
  589. package/dist/types/hitl/askUserQuestion.d.ts +1 -1
  590. package/dist/types/hitl/askUserQuestions.d.ts +1 -1
  591. package/dist/types/hitl/askUserQuestionsInterrupt.d.ts +1 -1
  592. package/dist/types/hooks/types.d.ts +1 -1
  593. package/dist/types/instrumentation.d.ts +1 -1
  594. package/dist/types/langfuse.d.ts +3 -3
  595. package/dist/types/langfuseConfig.d.ts +2 -2
  596. package/dist/types/langfuseRuntimeContext.d.ts +1 -1
  597. package/dist/types/langfuseRuntimeScope.d.ts +2 -2
  598. package/dist/types/langfuseSpanRegistry.d.ts +1 -1
  599. package/dist/types/langfuseToolOutputTracing.d.ts +3 -3
  600. package/dist/types/llm/anthropic/index.d.ts +1 -1
  601. package/dist/types/llm/bedrock/index.d.ts +1 -1
  602. package/dist/types/llm/bedrock/toolCache.d.ts +2 -2
  603. package/dist/types/llm/contextOverflowRecovery.d.ts +2 -2
  604. package/dist/types/llm/google/index.d.ts +1 -1
  605. package/dist/types/llm/init.d.ts +2 -2
  606. package/dist/types/llm/invoke.d.ts +6 -6
  607. package/dist/types/llm/mistral/index.d.ts +1 -1
  608. package/dist/types/llm/openai/index.d.ts +2 -2
  609. package/dist/types/llm/openrouter/index.d.ts +2 -2
  610. package/dist/types/llm/openrouter/toolCache.d.ts +2 -2
  611. package/dist/types/llm/providers.d.ts +2 -2
  612. package/dist/types/llm/request.d.ts +2 -2
  613. package/dist/types/llm/stream/chunkAdapters.d.ts +1 -1
  614. package/dist/types/llm/streamLimits.d.ts +1 -1
  615. package/dist/types/llm/truncation.d.ts +1 -1
  616. package/dist/types/llm/vertexai/index.d.ts +1 -1
  617. package/dist/types/messages/alternation.d.ts +1 -1
  618. package/dist/types/messages/anthropicToolCache.d.ts +2 -2
  619. package/dist/types/messages/assistantPhase.d.ts +3 -3
  620. package/dist/types/messages/budget.d.ts +1 -1
  621. package/dist/types/messages/cache.d.ts +1 -1
  622. package/dist/types/messages/contextPruning.d.ts +2 -2
  623. package/dist/types/messages/core.d.ts +2 -2
  624. package/dist/types/messages/format.d.ts +2 -2
  625. package/dist/types/messages/ids.d.ts +2 -2
  626. package/dist/types/messages/injected.d.ts +1 -1
  627. package/dist/types/messages/langchain.d.ts +1 -1
  628. package/dist/types/messages/prune.d.ts +3 -3
  629. package/dist/types/openai/index.d.ts +1 -1
  630. package/dist/types/prompts/activityLabel.d.ts +2 -2
  631. package/dist/types/responses/index.d.ts +1 -1
  632. package/dist/types/run.d.ts +3 -3
  633. package/dist/types/session/handlers.d.ts +1 -1
  634. package/dist/types/session/types.d.ts +1 -1
  635. package/dist/types/stream.d.ts +4 -4
  636. package/dist/types/summarization/index.d.ts +1 -1
  637. package/dist/types/summarization/node.d.ts +6 -6
  638. package/dist/types/test/mockTools.d.ts +1 -1
  639. package/dist/types/tools/BashExecutor.d.ts +2 -2
  640. package/dist/types/tools/BashProgrammaticToolCalling.d.ts +2 -2
  641. package/dist/types/tools/CodeExecutor.d.ts +3 -3
  642. package/dist/types/tools/CodeSessionFileSummary.d.ts +1 -1
  643. package/dist/types/tools/ProgrammaticToolCalling.d.ts +2 -2
  644. package/dist/types/tools/ReadFile.d.ts +1 -1
  645. package/dist/types/tools/SkillTool.d.ts +1 -1
  646. package/dist/types/tools/SubagentTool.d.ts +3 -3
  647. package/dist/types/tools/ToolNode.d.ts +5 -5
  648. package/dist/types/tools/ToolSearch.d.ts +2 -2
  649. package/dist/types/tools/cloudflare/CloudflareBridgeRuntime.d.ts +1 -1
  650. package/dist/types/tools/cloudflare/CloudflareProgrammaticToolCalling.d.ts +1 -1
  651. package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +2 -2
  652. package/dist/types/tools/cloudflare/CloudflareSandboxTools.d.ts +1 -1
  653. package/dist/types/tools/eagerEventExecution.d.ts +1 -1
  654. package/dist/types/tools/handlers.d.ts +3 -3
  655. package/dist/types/tools/intentArg.d.ts +1 -1
  656. package/dist/types/tools/local/CompileCheckTool.d.ts +2 -2
  657. package/dist/types/tools/local/FileCheckpointer.d.ts +1 -1
  658. package/dist/types/tools/local/LocalCodingTools.d.ts +2 -2
  659. package/dist/types/tools/local/LocalExecutionEngine.d.ts +1 -1
  660. package/dist/types/tools/local/LocalExecutionTools.d.ts +1 -1
  661. package/dist/types/tools/local/LocalProgrammaticToolCalling.d.ts +1 -1
  662. package/dist/types/tools/local/bashAst.d.ts +1 -1
  663. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +1 -1
  664. package/dist/types/tools/local/syntaxCheck.d.ts +1 -1
  665. package/dist/types/tools/ptcTimeout.d.ts +1 -1
  666. package/dist/types/tools/schema.d.ts +1 -1
  667. package/dist/types/tools/search/anthropic.d.ts +1 -1
  668. package/dist/types/tools/skillCatalog.d.ts +1 -1
  669. package/dist/types/tools/subagent/SubagentExecutor.d.ts +5 -5
  670. package/dist/types/tools/subagent/SubagentReplay.d.ts +3 -3
  671. package/dist/types/tools/subagent/childGraphConfig.d.ts +2 -2
  672. package/dist/types/types/activityLabel.d.ts +3 -3
  673. package/dist/types/types/graph.d.ts +7 -7
  674. package/dist/types/types/llm.d.ts +9 -9
  675. package/dist/types/types/run.d.ts +7 -7
  676. package/dist/types/types/stream.d.ts +5 -5
  677. package/dist/types/types/summarize.d.ts +2 -2
  678. package/dist/types/types/tools.d.ts +5 -5
  679. package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +1 -1
  680. package/dist/types/utils/errors.d.ts +1 -1
  681. package/dist/types/utils/events.d.ts +1 -1
  682. package/dist/types/utils/handlers.d.ts +3 -3
  683. package/dist/types/utils/llm.d.ts +1 -1
  684. package/dist/types/utils/llmConfig.d.ts +1 -1
  685. package/dist/types/utils/title.d.ts +1 -1
  686. package/package.json +10 -3
  687. package/src/llm/google/utils/common.ts +6 -4
  688. package/src/__tests__/stream.eagerArgsDivergence.test.ts +0 -911
  689. package/src/__tests__/stream.eagerEventExecution.test.ts +0 -5046
  690. package/src/__tests__/stream.streamLimits.test.ts +0 -1982
  691. package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +0 -448
  692. package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +0 -655
  693. package/src/agents/__tests__/AgentContext.openrouter.live.test.ts +0 -128
  694. package/src/agents/__tests__/AgentContext.overflow.test.ts +0 -205
  695. package/src/agents/__tests__/AgentContext.test.ts +0 -2425
  696. package/src/agents/__tests__/projection.test.ts +0 -73
  697. package/src/agents/__tests__/promptCacheLiveHelpers.ts +0 -175
  698. package/src/aggregator.test.ts +0 -1214
  699. package/src/graphs/__tests__/Graph.breakerLifecycle.test.ts +0 -273
  700. package/src/graphs/__tests__/Graph.closeRunStep.test.ts +0 -385
  701. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +0 -1766
  702. package/src/graphs/__tests__/Graph.preemptSignal.test.ts +0 -126
  703. package/src/graphs/__tests__/Graph.reasoning.test.ts +0 -1717
  704. package/src/graphs/__tests__/Graph.subagentResumeState.test.ts +0 -80
  705. package/src/graphs/__tests__/MultiAgentGraph.test.ts +0 -177
  706. package/src/graphs/__tests__/composition.smoke.test.ts +0 -509
  707. package/src/graphs/__tests__/createGraph.test.ts +0 -206
  708. package/src/hooks/__tests__/HookRegistry.test.ts +0 -334
  709. package/src/hooks/__tests__/compactHooks.test.ts +0 -250
  710. package/src/hooks/__tests__/createToolPolicyHook.test.ts +0 -268
  711. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +0 -405
  712. package/src/hooks/__tests__/executeHooks.test.ts +0 -1294
  713. package/src/hooks/__tests__/integration.test.ts +0 -337
  714. package/src/hooks/__tests__/matchers.test.ts +0 -238
  715. package/src/hooks/__tests__/preemptBoundary.test.ts +0 -152
  716. package/src/hooks/__tests__/toolHooks.test.ts +0 -669
  717. package/src/llm/__tests__/contextOverflowRecovery.test.ts +0 -401
  718. package/src/llm/__tests__/fallbackOverflow.test.ts +0 -287
  719. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  720. package/src/llm/anthropic/inherited-content-utils.spec.ts +0 -249
  721. package/src/llm/anthropic/inherited-stream-events.spec.ts +0 -1259
  722. package/src/llm/anthropic/inherited-strict.spec.ts +0 -302
  723. package/src/llm/anthropic/llm.spec.ts +0 -3394
  724. package/src/llm/anthropic/utils/cross-provider-reasoning.test.ts +0 -383
  725. package/src/llm/anthropic/utils/cross-provider-server-tools.test.ts +0 -110
  726. package/src/llm/anthropic/utils/server-tool-inputs.test.ts +0 -508
  727. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +0 -361
  728. package/src/llm/anthropic/utils/stripPrefillCache.test.ts +0 -111
  729. package/src/llm/anthropic/utils/tool-id-normalization.test.ts +0 -287
  730. package/src/llm/bedrock/inherited-cache.spec.ts +0 -144
  731. package/src/llm/bedrock/inherited.spec.ts +0 -724
  732. package/src/llm/bedrock/llm.spec.ts +0 -1533
  733. package/src/llm/bedrock/streamSealDispatch.test.ts +0 -331
  734. package/src/llm/bedrock/toolCache.test.ts +0 -194
  735. package/src/llm/bedrock/utils/cross-provider-reasoning.test.ts +0 -131
  736. package/src/llm/bedrock/utils/cross-provider-server-tools.test.ts +0 -122
  737. package/src/llm/bedrock/utils/message_inputs.test.ts +0 -650
  738. package/src/llm/bedrock/utils/message_outputs.test.ts +0 -85
  739. package/src/llm/bedrock/utils/toolResultCachePoint.test.ts +0 -118
  740. package/src/llm/custom-chat-models.smoke.test.ts +0 -1966
  741. package/src/llm/google/data/gettysburg10.wav +0 -0
  742. package/src/llm/google/data/hotdog.jpg +0 -0
  743. package/src/llm/google/inherited-stream-events.spec.ts +0 -350
  744. package/src/llm/google/llm.spec.ts +0 -1388
  745. package/src/llm/google/streamSmoothing.test.ts +0 -121
  746. package/src/llm/google/utils/common.test.ts +0 -185
  747. package/src/llm/invoke.alternation.test.ts +0 -87
  748. package/src/llm/invoke.handoffCue.test.ts +0 -112
  749. package/src/llm/invoke.streamLimits.test.ts +0 -142
  750. package/src/llm/invoke.test.ts +0 -1198
  751. package/src/llm/mistral/streamSmoothing.test.ts +0 -97
  752. package/src/llm/openai/cacheWriteTokens.test.ts +0 -112
  753. package/src/llm/openai/contentBlocks.test.ts +0 -381
  754. package/src/llm/openai/deepseek.test.ts +0 -747
  755. package/src/llm/openai/inherited-deepseek.spec.ts +0 -347
  756. package/src/llm/openai/inherited-xai.spec.ts +0 -416
  757. package/src/llm/openai/llm.spec.ts +0 -1774
  758. package/src/llm/openai/managedRequests.test.ts +0 -182
  759. package/src/llm/openai/sequentialToolCallSeals.test.ts +0 -199
  760. package/src/llm/openai/streamMetadata.spec.ts +0 -86
  761. package/src/llm/openai/streamMetadataDedup.spec.ts +0 -166
  762. package/src/llm/openai/utils/isReasoningModel.test.ts +0 -90
  763. package/src/llm/openai/utils/messages.test.ts +0 -488
  764. package/src/llm/openrouter/reasoning.test.ts +0 -561
  765. package/src/llm/openrouter/toolCache.test.ts +0 -134
  766. package/src/llm/preempt.test.ts +0 -323
  767. package/src/llm/stream/chunkAdapters.test.ts +0 -202
  768. package/src/llm/stream/reassembly.test.ts +0 -241
  769. package/src/llm/stream/smoother.bench.test.ts +0 -155
  770. package/src/llm/stream/smoother.test.ts +0 -519
  771. package/src/llm/streamLimits.test.ts +0 -450
  772. package/src/llm/truncation.test.ts +0 -242
  773. package/src/llm/vertexai/fixThoughtSignatures.test.ts +0 -154
  774. package/src/llm/vertexai/inherited-stream-events.spec.ts +0 -271
  775. package/src/llm/vertexai/llm.spec.ts +0 -159
  776. package/src/llm/vertexai/repairUsageMetadata.test.ts +0 -54
  777. package/src/llm/vertexai/sealStreamedToolCalls.test.ts +0 -88
  778. package/src/llm/vertexai/streamSealDispatch.test.ts +0 -148
  779. package/src/llm/vertexai/streamSmoothing.test.ts +0 -109
  780. package/src/messages/__tests__/anthropicToolCache.test.ts +0 -339
  781. package/src/messages/__tests__/observationMasking.test.ts +0 -312
  782. package/src/messages/__tests__/recency.test.ts +0 -267
  783. package/src/messages/__tests__/tools.test.ts +0 -473
  784. package/src/messages/alternation.test.ts +0 -212
  785. package/src/messages/assistantPhase.test.ts +0 -75
  786. package/src/messages/cache.tail.test.ts +0 -533
  787. package/src/messages/cache.test.ts +0 -2166
  788. package/src/messages/content.test.ts +0 -362
  789. package/src/messages/contextPruning.test.ts +0 -184
  790. package/src/messages/ensureThinkingBlock.test.ts +0 -1427
  791. package/src/messages/foldToollessToolBlocks.test.ts +0 -596
  792. package/src/messages/formatAgentMessages.reducer.test.ts +0 -162
  793. package/src/messages/formatAgentMessages.skills.test.ts +0 -513
  794. package/src/messages/formatAgentMessages.steer.test.ts +0 -598
  795. package/src/messages/formatAgentMessages.test.ts +0 -8111
  796. package/src/messages/formatAgentMessages.tools.test.ts +0 -522
  797. package/src/messages/formatMessage.test.ts +0 -693
  798. package/src/messages/handoffCue.test.ts +0 -96
  799. package/src/messages/injected.test.ts +0 -107
  800. package/src/messages/labelContentByAgent.test.ts +0 -962
  801. package/src/messages/reducer.spec.ts +0 -32
  802. package/src/messages/shiftIndexTokenCountMap.test.ts +0 -81
  803. package/src/messages/tailCacheConversion.test.ts +0 -161
  804. package/src/openai/__tests__/openai.test.ts +0 -337
  805. package/src/responses/__tests__/responses.test.ts +0 -652
  806. package/src/scripts/abort.ts +0 -157
  807. package/src/scripts/activity-labels/captured.json +0 -56
  808. package/src/scripts/activity-labels/checks.cjs +0 -205
  809. package/src/scripts/activity-labels/corpus.cjs +0 -473
  810. package/src/scripts/activity-labels/report.cjs +0 -203
  811. package/src/scripts/activity-labels/rescore.cjs +0 -102
  812. package/src/scripts/activity-labels/run.ts +0 -705
  813. package/src/scripts/activity-labels/variants.ts +0 -71
  814. package/src/scripts/ant_web_search.ts +0 -159
  815. package/src/scripts/ant_web_search_edge_case.ts +0 -163
  816. package/src/scripts/ant_web_search_error_edge_case.ts +0 -149
  817. package/src/scripts/args.ts +0 -48
  818. package/src/scripts/bedrock-cache-debug.ts +0 -250
  819. package/src/scripts/bedrock-content-aggregation-test.ts +0 -266
  820. package/src/scripts/bedrock-merge-test.ts +0 -107
  821. package/src/scripts/bedrock-parallel-tools-test.ts +0 -204
  822. package/src/scripts/bench-prompt-cache.ts +0 -479
  823. package/src/scripts/caching.ts +0 -132
  824. package/src/scripts/cli.ts +0 -172
  825. package/src/scripts/cli2.ts +0 -133
  826. package/src/scripts/cli3.ts +0 -184
  827. package/src/scripts/cli4.ts +0 -191
  828. package/src/scripts/cli5.ts +0 -191
  829. package/src/scripts/code_exec.ts +0 -214
  830. package/src/scripts/code_exec_files.ts +0 -237
  831. package/src/scripts/code_exec_multi_session.ts +0 -237
  832. package/src/scripts/code_exec_ptc.ts +0 -335
  833. package/src/scripts/code_exec_session.ts +0 -283
  834. package/src/scripts/code_exec_simple.ts +0 -148
  835. package/src/scripts/compare_pi_vs_ours.ts +0 -1259
  836. package/src/scripts/content.ts +0 -139
  837. package/src/scripts/context-overflow-probe.ts +0 -997
  838. package/src/scripts/empty_input.ts +0 -137
  839. package/src/scripts/handoff-test.ts +0 -134
  840. package/src/scripts/local_engine.ts +0 -166
  841. package/src/scripts/local_engine_checkpointer.ts +0 -205
  842. package/src/scripts/local_engine_compile.ts +0 -263
  843. package/src/scripts/local_engine_hooks.ts +0 -226
  844. package/src/scripts/local_engine_image.ts +0 -201
  845. package/src/scripts/local_engine_ptc.ts +0 -151
  846. package/src/scripts/local_engine_workspace.ts +0 -258
  847. package/src/scripts/memory.ts +0 -107
  848. package/src/scripts/multi-agent-chain.ts +0 -332
  849. package/src/scripts/multi-agent-conditional.ts +0 -222
  850. package/src/scripts/multi-agent-document-review-chain.ts +0 -198
  851. package/src/scripts/multi-agent-hybrid-flow.ts +0 -311
  852. package/src/scripts/multi-agent-parallel-start.ts +0 -265
  853. package/src/scripts/multi-agent-parallel.ts +0 -395
  854. package/src/scripts/multi-agent-sequence.ts +0 -217
  855. package/src/scripts/multi-agent-subagent.ts +0 -246
  856. package/src/scripts/multi-agent-supervisor.ts +0 -366
  857. package/src/scripts/multi-agent-test.ts +0 -187
  858. package/src/scripts/openrouter_prompt_cache_live.ts +0 -310
  859. package/src/scripts/parallel-asymmetric-tools-test.ts +0 -275
  860. package/src/scripts/parallel-full-metadata-test.ts +0 -241
  861. package/src/scripts/parallel-tools-test.ts +0 -341
  862. package/src/scripts/preempt-probe.ts +0 -330
  863. package/src/scripts/preempt-scenarios.ts +0 -388
  864. package/src/scripts/programmatic_exec.ts +0 -387
  865. package/src/scripts/programmatic_exec_agent.ts +0 -232
  866. package/src/scripts/search.ts +0 -147
  867. package/src/scripts/sequential-full-metadata-test.ts +0 -198
  868. package/src/scripts/session_live.ts +0 -548
  869. package/src/scripts/simple.ts +0 -226
  870. package/src/scripts/single-agent-metadata-test.ts +0 -196
  871. package/src/scripts/stream.ts +0 -141
  872. package/src/scripts/subagent-configurable-inheritance.ts +0 -252
  873. package/src/scripts/subagent-event-driven-debug.ts +0 -190
  874. package/src/scripts/subagent-tools-debug.ts +0 -160
  875. package/src/scripts/subagent-usage-sink.ts +0 -176
  876. package/src/scripts/summarization-recency.ts +0 -462
  877. package/src/scripts/test-custom-prompt-key.ts +0 -145
  878. package/src/scripts/test-handoff-input.ts +0 -170
  879. package/src/scripts/test-handoff-preamble.ts +0 -278
  880. package/src/scripts/test-handoff-steering.ts +0 -430
  881. package/src/scripts/test-multi-agent-list-handoff.ts +0 -418
  882. package/src/scripts/test-parallel-agent-labeling.ts +0 -327
  883. package/src/scripts/test-parallel-handoffs.ts +0 -292
  884. package/src/scripts/test-thinking-handoff-bedrock.ts +0 -154
  885. package/src/scripts/test-thinking-handoff.ts +0 -156
  886. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +0 -166
  887. package/src/scripts/test-tool-before-handoff-role-order.ts +0 -276
  888. package/src/scripts/test-tools-before-handoff.ts +0 -222
  889. package/src/scripts/test_code_api.ts +0 -354
  890. package/src/scripts/thinking-bedrock.ts +0 -160
  891. package/src/scripts/thinking-vertexai.ts +0 -168
  892. package/src/scripts/thinking.ts +0 -172
  893. package/src/scripts/tool_search.ts +0 -153
  894. package/src/scripts/tools.ts +0 -163
  895. package/src/session/__tests__/JsonlSessionStore.test.ts +0 -1463
  896. package/src/session/__tests__/handlers.test.ts +0 -161
  897. package/src/specs/activity-label-observability.live.test.ts +0 -262
  898. package/src/specs/activity-label-observability.test.ts +0 -167
  899. package/src/specs/activity-label-prompt.test.ts +0 -359
  900. package/src/specs/activity-label-trace-seed.test.ts +0 -47
  901. package/src/specs/activity-phase-label.test.ts +0 -306
  902. package/src/specs/agent-handoffs.live.test.ts +0 -140
  903. package/src/specs/agent-handoffs.test.ts +0 -2465
  904. package/src/specs/anthropic.simple.test.ts +0 -453
  905. package/src/specs/ask-user-question-batch.test.ts +0 -289
  906. package/src/specs/ask-user-questions.live.test.ts +0 -185
  907. package/src/specs/ask-user-questions.test.ts +0 -293
  908. package/src/specs/azure.simple.test.ts +0 -502
  909. package/src/specs/bedrock-toolless.live.test.ts +0 -123
  910. package/src/specs/bedrock-truncation.live.test.ts +0 -191
  911. package/src/specs/cache.simple.test.ts +0 -416
  912. package/src/specs/context-accuracy.live.test.ts +0 -409
  913. package/src/specs/context-overflow-recovery.live.test.ts +0 -213
  914. package/src/specs/context-usage-event.test.ts +0 -117
  915. package/src/specs/context-usage.live.test.ts +0 -297
  916. package/src/specs/custom-event-await.test.ts +0 -304
  917. package/src/specs/deepseek.simple.test.ts +0 -290
  918. package/src/specs/deterministic-trace-id.test.ts +0 -43
  919. package/src/specs/discovered-tools.test.ts +0 -217
  920. package/src/specs/durability-checkpoint.integration.test.ts +0 -243
  921. package/src/specs/graph-subagent.live.test.ts +0 -242
  922. package/src/specs/graph-subagent.test.ts +0 -322
  923. package/src/specs/handoffCue.test.ts +0 -165
  924. package/src/specs/langfuse-callbacks.test.ts +0 -1578
  925. package/src/specs/langfuse-config.test.ts +0 -247
  926. package/src/specs/langfuse-instrumentation.test.ts +0 -393
  927. package/src/specs/langfuse-metadata.test.ts +0 -245
  928. package/src/specs/langfuse-routing.integration.test.ts +0 -844
  929. package/src/specs/langfuse-runtime-context.test.ts +0 -92
  930. package/src/specs/langfuse-span-registry.test.ts +0 -87
  931. package/src/specs/langfuse-tool-output-tracing.test.ts +0 -1858
  932. package/src/specs/langfuse-trace-shaping.test.ts +0 -591
  933. package/src/specs/moonshot.simple.test.ts +0 -367
  934. package/src/specs/multi-agent-summarization.test.ts +0 -396
  935. package/src/specs/openai.simple.test.ts +0 -315
  936. package/src/specs/openrouter.simple.test.ts +0 -275
  937. package/src/specs/preemptSeal.test.ts +0 -678
  938. package/src/specs/prune.test.ts +0 -3741
  939. package/src/specs/reasoning.test.ts +0 -201
  940. package/src/specs/run-step-timestamps.test.ts +0 -414
  941. package/src/specs/spec.utils.ts +0 -15
  942. package/src/specs/subagent.test.ts +0 -864
  943. package/src/specs/summarization-unit.test.ts +0 -973
  944. package/src/specs/summarization.test.ts +0 -3823
  945. package/src/specs/summarize-prune.test.ts +0 -376
  946. package/src/specs/thinking-handoff.test.ts +0 -621
  947. package/src/specs/thinking-prune.test.ts +0 -827
  948. package/src/specs/token-accounting-e2e.test.ts +0 -1034
  949. package/src/specs/token-accounting-pipeline.test.ts +0 -1008
  950. package/src/specs/token-distribution-edge-case.test.ts +0 -315
  951. package/src/specs/token-memoization.test.ts +0 -40
  952. package/src/specs/tokens.test.ts +0 -1000
  953. package/src/specs/tool-error-resume.test.ts +0 -194
  954. package/src/specs/tool-error.test.ts +0 -198
  955. package/src/specs/vllm-reasoning-toolcalls.test.ts +0 -340
  956. package/src/stream.dispatch.test.ts +0 -63
  957. package/src/stream.test.ts +0 -144
  958. package/src/summarization/__tests__/aggregator.test.ts +0 -236
  959. package/src/summarization/__tests__/node.test.ts +0 -1996
  960. package/src/summarization/__tests__/trigger.test.ts +0 -149
  961. package/src/summarization/chunkHandler.test.ts +0 -196
  962. package/src/test/mockTools.ts +0 -386
  963. package/src/tools/Calculator.test.ts +0 -278
  964. package/src/tools/__tests__/BashExecutor.test.ts +0 -108
  965. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +0 -939
  966. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +0 -858
  967. package/src/tools/__tests__/CodeExecutor.stateful.test.ts +0 -124
  968. package/src/tools/__tests__/LocalExecutionRoots.test.ts +0 -8
  969. package/src/tools/__tests__/LocalExecutionTools.test.ts +0 -2733
  970. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.ts +0 -318
  971. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -1557
  972. package/src/tools/__tests__/ReadFile.test.ts +0 -44
  973. package/src/tools/__tests__/SkillTool.test.ts +0 -442
  974. package/src/tools/__tests__/SubagentExecutor.test.ts +0 -3728
  975. package/src/tools/__tests__/SubagentReplay.test.ts +0 -329
  976. package/src/tools/__tests__/SubagentTool.test.ts +0 -149
  977. package/src/tools/__tests__/ToolNode.breakerSignal.test.ts +0 -595
  978. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +0 -1191
  979. package/src/tools/__tests__/ToolNode.invalidToolCalls.test.ts +0 -757
  980. package/src/tools/__tests__/ToolNode.langfuse.test.ts +0 -57
  981. package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +0 -736
  982. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +0 -1710
  983. package/src/tools/__tests__/ToolNode.runtimeState.test.ts +0 -120
  984. package/src/tools/__tests__/ToolNode.session.test.ts +0 -1352
  985. package/src/tools/__tests__/ToolNode.streamLimits.test.ts +0 -69
  986. package/src/tools/__tests__/ToolSearch.integration.test.ts +0 -161
  987. package/src/tools/__tests__/ToolSearch.test.ts +0 -1227
  988. package/src/tools/__tests__/annotateMessagesForLLM.test.ts +0 -561
  989. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +0 -980
  990. package/src/tools/__tests__/directToolHooks.test.ts +0 -700
  991. package/src/tools/__tests__/eagerEventExecution.session.test.ts +0 -92
  992. package/src/tools/__tests__/handlers.test.ts +0 -997
  993. package/src/tools/__tests__/hitl.test.ts +0 -4663
  994. package/src/tools/__tests__/intentArg.test.ts +0 -357
  995. package/src/tools/__tests__/intentCoverage.test.ts +0 -139
  996. package/src/tools/__tests__/localToolNames.test.ts +0 -75
  997. package/src/tools/__tests__/skillCatalog.test.ts +0 -161
  998. package/src/tools/__tests__/subagentHooks.test.ts +0 -1651
  999. package/src/tools/__tests__/toolOutputReferences.test.ts +0 -515
  1000. package/src/tools/__tests__/workspaceSeam.test.ts +0 -147
  1001. package/src/tools/local/__tests__/FileCheckpointer.test.ts +0 -162
  1002. package/src/tools/local/__tests__/editStrategies.test.ts +0 -134
  1003. package/src/tools/search/content.test.ts +0 -173
  1004. package/src/tools/search/crw.test.ts +0 -836
  1005. package/src/tools/search/format.test.ts +0 -242
  1006. package/src/tools/search/http-agent.test.ts +0 -133
  1007. package/src/tools/search/jina-reranker.test.ts +0 -306
  1008. package/src/tools/search/keenable-scraper.test.ts +0 -153
  1009. package/src/tools/search/keenable.test.ts +0 -183
  1010. package/src/tools/search/outcome.test.ts +0 -90
  1011. package/src/tools/search/output.md +0 -2775
  1012. package/src/tools/search/rag-api-reranker.test.ts +0 -891
  1013. package/src/tools/search/source-processing.test.ts +0 -516
  1014. package/src/tools/search/tavily.test.ts +0 -965
  1015. package/src/tools/search/test.html +0 -884
  1016. package/src/tools/search/test.md +0 -643
  1017. package/src/tools/subagent/__tests__/SubagentExecutionRegistry.test.ts +0 -637
  1018. package/src/tools/subagent/__tests__/SubagentExecutor.lazy.test.ts +0 -3054
  1019. package/src/tools/subagent/__tests__/childGraphConfig.test.ts +0 -521
  1020. package/src/utils/__tests__/apportion.test.ts +0 -32
  1021. package/src/utils/__tests__/errors.test.ts +0 -270
  1022. package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +0 -336
  1023. package/src/utils/__tests__/redactSecrets.test.ts +0 -56
  1024. package/src/utils/__tests__/truncation.test.ts +0 -66
  1025. package/src/utils/llm.test.ts +0 -18
  1026. package/src/utils/proxy.test.ts +0 -176
  1027. package/src/utils/toolContent.test.ts +0 -1432
@@ -1,1996 +0,0 @@
1
- import { AIMessage, HumanMessage, ToolMessage } from '@langchain/core/messages';
2
- import type { RunnableConfig } from '@langchain/core/runnables';
3
- import type { BaseMessage } from '@langchain/core/messages';
4
- import type * as t from '@/types';
5
- import {
6
- createSummarizeNode,
7
- DEFAULT_SUMMARIZATION_PROMPT,
8
- DEFAULT_UPDATE_SUMMARIZATION_PROMPT,
9
- } from '@/summarization/node';
10
- import { StreamLimitExceededError } from '@/llm/streamLimits';
11
- import { convertInjectedMessages } from '@/messages/injected';
12
- import { Constants, GraphEvents, Providers } from '@/common';
13
- import { AgentContext } from '@/agents/AgentContext';
14
- import * as providers from '@/llm/providers';
15
- import * as eventUtils from '@/utils/events';
16
-
17
- // ---------------------------------------------------------------------------
18
- // Helpers
19
- // ---------------------------------------------------------------------------
20
-
21
- /** Creates a real AgentContext via fromConfig with sensible defaults.
22
- * Extra properties are assigned directly for test-specific overrides.
23
- *
24
- * Defaults `retainRecent.turns` to `0` so that tests which use 1–2 message
25
- * states still exercise the LLM-call summarization path. The recency-window
26
- * default of `2` turns would otherwise short-circuit summarization for those
27
- * inputs. Tests that target recency-window behavior should pass an explicit
28
- * `summarizationConfig.retainRecent` value. */
29
- function createAgentContext(
30
- overrides: Record<string, unknown> = {}
31
- ): AgentContext {
32
- const {
33
- // AgentInputs fields
34
- agentId = 'agent_0',
35
- provider = Providers.OPENAI,
36
- instructions = 'Test agent',
37
- summarizationEnabled = true,
38
- summarizationConfig,
39
- maxContextTokens,
40
- tools,
41
- ...extra
42
- } = overrides;
43
-
44
- const effectiveSummarizationConfig =
45
- summarizationConfig != null
46
- ? summarizationConfig
47
- : { retainRecent: { turns: 0 } };
48
-
49
- const ctx = AgentContext.fromConfig({
50
- agentId: agentId as string,
51
- provider: provider as Providers,
52
- instructions: instructions as string,
53
- summarizationEnabled: summarizationEnabled as boolean,
54
- summarizationConfig: effectiveSummarizationConfig,
55
- ...(maxContextTokens != null ? { maxContextTokens } : {}),
56
- ...(tools != null ? { tools } : {}),
57
- } as import('@/types').AgentInputs);
58
-
59
- // Apply direct property overrides for test-specific internal state
60
- for (const [key, value] of Object.entries(extra)) {
61
- (ctx as unknown as Record<string, unknown>)[key] = value;
62
- }
63
-
64
- return ctx;
65
- }
66
-
67
- /** Creates a mock graph container for createSummarizeNode. */
68
- function mockGraph(
69
- onStepCompleted?: (stepId: string, result: t.StepCompleted) => void
70
- ): {
71
- contentData: t.RunStep[];
72
- contentIndexMap: Map<string, number>;
73
- config: RunnableConfig;
74
- runId: string;
75
- isMultiAgent: boolean;
76
- dispatchRunStep: (
77
- runStep: t.RunStep,
78
- config?: RunnableConfig
79
- ) => Promise<void>;
80
- dispatchRunStepCompleted: (
81
- stepId: string,
82
- result: t.StepCompleted,
83
- config?: RunnableConfig
84
- ) => Promise<void>;
85
- } {
86
- const contentData: t.RunStep[] = [];
87
- const contentIndexMap = new Map<string, number>();
88
- return {
89
- contentData,
90
- contentIndexMap,
91
- config: {} as RunnableConfig,
92
- runId: 'run_1',
93
- isMultiAgent: false,
94
- dispatchRunStep: async (runStep: t.RunStep): Promise<void> => {
95
- contentData.push(runStep);
96
- contentIndexMap.set(runStep.id, runStep.index);
97
- },
98
- dispatchRunStepCompleted: async (
99
- stepId: string,
100
- result: t.StepCompleted
101
- ): Promise<void> => {
102
- onStepCompleted?.(stepId, result);
103
- },
104
- };
105
- }
106
-
107
- let stepCounter = 0;
108
- function generateStepId(_stepKey: string): [string, number] {
109
- const id = `step_test_${stepCounter++}`;
110
- return [id, 0];
111
- }
112
-
113
- /** Collects custom events dispatched during the node execution. */
114
- function captureEvents(): Array<{ event: string; data: unknown }> {
115
- const events: Array<{ event: string; data: unknown }> = [];
116
- jest.spyOn(eventUtils, 'safeDispatchCustomEvent').mockImplementation((async (
117
- ...args: unknown[]
118
- ) => {
119
- events.push({ event: args[0] as string, data: args[1] });
120
- }) as never);
121
- return events;
122
- }
123
-
124
- /** Creates a mock model that returns a canned response via invoke(). */
125
- function mockInvokeModel(response: string): { invoke: jest.Mock } {
126
- return {
127
- invoke: jest.fn().mockResolvedValue({ content: response }),
128
- };
129
- }
130
-
131
- /**
132
- * Creates a mock model that streams text chunk-by-chunk.
133
- * invoke() returns the full text; stream() yields one chunk per word.
134
- */
135
- function mockStreamingModel(response: string): {
136
- invoke: jest.Mock;
137
- stream: jest.Mock;
138
- } {
139
- const words = response.split(' ');
140
- return {
141
- invoke: jest.fn().mockResolvedValue({ content: response }),
142
- stream: jest.fn().mockImplementation(async () => {
143
- return (async function* (): AsyncGenerator<{ content: string }> {
144
- for (const word of words) {
145
- // Add space back except for first word
146
- yield { content: word + ' ' };
147
- }
148
- })();
149
- }),
150
- };
151
- }
152
-
153
- // ---------------------------------------------------------------------------
154
- // Tests
155
- // ---------------------------------------------------------------------------
156
-
157
- beforeEach(() => {
158
- stepCounter = 0;
159
- jest.restoreAllMocks();
160
- });
161
-
162
- describe('createSummarizeNode', () => {
163
- it('emits ON_SUMMARIZE_START and ON_SUMMARIZE_COMPLETE on success', async () => {
164
- const events = captureEvents();
165
-
166
- // Mock getChatModelClass to return our mock model
167
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
168
- class {
169
- constructor() {
170
- return mockInvokeModel('Test summary output');
171
- }
172
- } as never
173
- );
174
-
175
- const agentContext = createAgentContext();
176
- const graph = mockGraph((_stepId, result) => {
177
- if (result.type === 'summary') {
178
- events.push({
179
- event: GraphEvents.ON_SUMMARIZE_COMPLETE,
180
- data: { summary: result.summary },
181
- });
182
- }
183
- });
184
- const node = createSummarizeNode({
185
- agentContext,
186
- graph,
187
- generateStepId,
188
- });
189
-
190
- await node(
191
- {
192
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
193
- summarizationRequest: {
194
- remainingContextTokens: 1000,
195
- agentId: 'agent_0',
196
- },
197
- },
198
- {} as RunnableConfig
199
- );
200
-
201
- const eventNames = events.map((e) => e.event);
202
- // ON_RUN_STEP now goes through graph.dispatchRunStep, not safeDispatchCustomEvent
203
- expect(graph.contentData.length).toBeGreaterThan(0);
204
- expect(eventNames).toContain(GraphEvents.ON_SUMMARIZE_START);
205
- expect(eventNames).toContain(GraphEvents.ON_SUMMARIZE_COMPLETE);
206
-
207
- // Complete event should have the summary text
208
- const completeEvent = events.find(
209
- (e) => e.event === GraphEvents.ON_SUMMARIZE_COMPLETE
210
- );
211
- expect(
212
- (
213
- (completeEvent?.data as t.SummarizeCompleteEvent).summary!
214
- .content?.[0] as { text: string } | undefined
215
- )?.text
216
- ).toBe('Test summary output');
217
- expect(
218
- (completeEvent?.data as t.SummarizeCompleteEvent).error
219
- ).toBeUndefined();
220
- });
221
-
222
- it('stamps INVOKED_MODEL/INVOKED_PROVIDER metadata for a dedicated summarizer model', async () => {
223
- captureEvents();
224
-
225
- const capturedConfigs: unknown[] = [];
226
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
227
- class {
228
- constructor() {
229
- return {
230
- invoke: jest
231
- .fn()
232
- .mockImplementation(
233
- async (_messages: unknown, config?: unknown) => {
234
- capturedConfigs.push(config);
235
- return { content: 'Summary text' };
236
- }
237
- ),
238
- };
239
- }
240
- } as never
241
- );
242
-
243
- const agentContext = createAgentContext({
244
- summarizationConfig: {
245
- retainRecent: { turns: 0 },
246
- model: 'gpt-4.1-mini',
247
- },
248
- });
249
- const graph = mockGraph();
250
- const node = createSummarizeNode({
251
- agentContext,
252
- graph,
253
- generateStepId,
254
- });
255
-
256
- await node(
257
- {
258
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
259
- summarizationRequest: {
260
- remainingContextTokens: 1000,
261
- agentId: 'agent_0',
262
- },
263
- },
264
- {} as RunnableConfig
265
- );
266
-
267
- /**
268
- * Usage consumers (the subagent usage-capture handler) attribute the
269
- * call from these keys — without them, a summarizer model that differs
270
- * from the agent's primary would be billed against the primary config.
271
- */
272
- const config = capturedConfigs[0] as {
273
- metadata?: Record<string, unknown>;
274
- };
275
- expect(config.metadata?.[Constants.INVOKED_MODEL]).toBe('gpt-4.1-mini');
276
- expect(config.metadata?.[Constants.INVOKED_PROVIDER]).toBe(
277
- Providers.OPENAI
278
- );
279
- });
280
-
281
- it('collects streamed text when model supports stream()', async () => {
282
- captureEvents();
283
-
284
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
285
- class {
286
- constructor() {
287
- return mockStreamingModel('one two three');
288
- }
289
- } as never
290
- );
291
-
292
- const setSummary = jest.fn();
293
- const agentContext = createAgentContext({ setSummary } as never);
294
- const graph = mockGraph();
295
- const node = createSummarizeNode({
296
- agentContext,
297
- graph,
298
- generateStepId,
299
- });
300
-
301
- await node(
302
- {
303
- messages: [new HumanMessage('Test message')],
304
- summarizationRequest: {
305
- remainingContextTokens: 1000,
306
- agentId: 'agent_0',
307
- },
308
- },
309
- {} as RunnableConfig
310
- );
311
-
312
- // Node collects the full streamed text and calls setSummary.
313
- // Delta events are dispatched by ChatModelStreamHandler, not the node.
314
- expect(setSummary).toHaveBeenCalledWith(
315
- 'one two three',
316
- expect.any(Number)
317
- );
318
- });
319
-
320
- it('falls back to invoke when model has no stream()', async () => {
321
- captureEvents();
322
-
323
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
324
- class {
325
- constructor() {
326
- return mockInvokeModel('Full summary text');
327
- }
328
- } as never
329
- );
330
-
331
- const setSummary = jest.fn();
332
- const agentContext = createAgentContext({ setSummary } as never);
333
- const graph = mockGraph();
334
- const node = createSummarizeNode({
335
- agentContext,
336
- graph,
337
- generateStepId,
338
- });
339
-
340
- await node(
341
- {
342
- messages: [new HumanMessage('Test message')],
343
- summarizationRequest: {
344
- remainingContextTokens: 1000,
345
- agentId: 'agent_0',
346
- },
347
- },
348
- {} as RunnableConfig
349
- );
350
-
351
- // Falls back to invoke and still collects the text
352
- expect(setSummary).toHaveBeenCalledWith(
353
- 'Full summary text',
354
- expect.any(Number)
355
- );
356
- });
357
-
358
- it('produces metadata stub when all LLM attempts fail', async () => {
359
- const events = captureEvents();
360
-
361
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
362
- class {
363
- constructor() {
364
- return {
365
- invoke: jest.fn().mockRejectedValue(new Error('Model error')),
366
- };
367
- }
368
- } as never
369
- );
370
-
371
- const setSummary = jest.fn();
372
- const agentContext = createAgentContext({ setSummary } as never);
373
- const graph = mockGraph((_stepId, result) => {
374
- if (result.type === 'summary') {
375
- events.push({
376
- event: GraphEvents.ON_SUMMARIZE_COMPLETE,
377
- data: { summary: result.summary },
378
- });
379
- }
380
- });
381
- const node = createSummarizeNode({
382
- agentContext,
383
- graph,
384
- generateStepId,
385
- });
386
-
387
- const result = await node(
388
- {
389
- messages: [new HumanMessage('Test')],
390
- summarizationRequest: {
391
- remainingContextTokens: 1000,
392
- agentId: 'agent_0',
393
- },
394
- },
395
- {} as RunnableConfig
396
- );
397
-
398
- expect(result.summarizationRequest).toBeUndefined();
399
- // After summarization, REMOVE_ALL + surviving context is returned
400
- expect(result.messages).toBeDefined();
401
- expect(result.messages!.length).toBeGreaterThanOrEqual(1);
402
- expect(result.messages![0]._getType()).toBe('remove');
403
-
404
- // Tier 3 fallback: metadata stub is used as summary text
405
- const completeEvent = events.find(
406
- (e) => e.event === GraphEvents.ON_SUMMARIZE_COMPLETE
407
- );
408
- expect(
409
- (
410
- (completeEvent?.data as t.SummarizeCompleteEvent).summary!
411
- .content?.[0] as { text: string } | undefined
412
- )?.text
413
- ).toMatch(/^\[Metadata summary:/);
414
- expect(
415
- (completeEvent?.data as t.SummarizeCompleteEvent).error
416
- ).toBeUndefined();
417
- });
418
-
419
- it('catches model initialization errors and falls back to metadata stub', async () => {
420
- captureEvents();
421
-
422
- /**
423
- * Simulate the "Unsupported LLM provider" case — e.g. when a caller
424
- * forwards an unrecognized provider name (custom-endpoint label) that
425
- * getChatModelClass cannot resolve. Prior to the defense-in-depth fix,
426
- * this error was thrown outside the try/catch in executeSummarizationWithFallback
427
- * and bubbled up silently. Now it is caught and the metadata stub is used.
428
- */
429
- jest.spyOn(providers, 'getChatModelClass').mockImplementation(() => {
430
- throw new Error('Unsupported LLM provider: Ollama');
431
- });
432
-
433
- const setSummary = jest.fn();
434
- const agentContext = createAgentContext({ setSummary } as never);
435
- const graph = mockGraph();
436
- const node = createSummarizeNode({
437
- agentContext,
438
- graph,
439
- generateStepId,
440
- });
441
-
442
- await expect(
443
- node(
444
- {
445
- messages: [new HumanMessage('Test message')],
446
- summarizationRequest: {
447
- remainingContextTokens: 1000,
448
- agentId: 'agent_0',
449
- },
450
- },
451
- {} as RunnableConfig
452
- )
453
- ).resolves.not.toThrow();
454
-
455
- expect(setSummary).toHaveBeenCalledWith(
456
- expect.stringContaining('[Metadata summary:'),
457
- expect.any(Number)
458
- );
459
- });
460
-
461
- it('falls back to metadata stub when primary LLM call fails', async () => {
462
- captureEvents();
463
-
464
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
465
- class {
466
- constructor() {
467
- return {
468
- invoke: jest.fn().mockRejectedValue(new Error('LLM unavailable')),
469
- };
470
- }
471
- } as never
472
- );
473
-
474
- const setSummary = jest.fn();
475
- const agentContext = createAgentContext({ setSummary } as never);
476
- const graph = mockGraph();
477
- const node = createSummarizeNode({
478
- agentContext,
479
- graph,
480
- generateStepId,
481
- });
482
-
483
- await node(
484
- {
485
- messages: [new HumanMessage('Test message')],
486
- summarizationRequest: {
487
- remainingContextTokens: 1000,
488
- agentId: 'agent_0',
489
- },
490
- },
491
- {} as RunnableConfig
492
- );
493
-
494
- expect(setSummary).toHaveBeenCalledWith(
495
- expect.stringContaining('[Metadata summary:'),
496
- expect.any(Number)
497
- );
498
- });
499
-
500
- it('calls setSummary with the final text', async () => {
501
- captureEvents();
502
-
503
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
504
- class {
505
- constructor() {
506
- return mockInvokeModel('Final summary');
507
- }
508
- } as never
509
- );
510
-
511
- const setSummary = jest.fn();
512
- const agentContext = createAgentContext({ setSummary } as never);
513
- const graph = mockGraph();
514
- const node = createSummarizeNode({
515
- agentContext,
516
- graph,
517
- generateStepId,
518
- });
519
-
520
- await node(
521
- {
522
- messages: [new HumanMessage('Test')],
523
- summarizationRequest: {
524
- remainingContextTokens: 1000,
525
- agentId: 'agent_0',
526
- },
527
- },
528
- {} as RunnableConfig
529
- );
530
-
531
- expect(setSummary).toHaveBeenCalledWith(
532
- 'Final summary',
533
- expect.any(Number)
534
- );
535
- });
536
-
537
- it('cache-hit path sends raw messages with instruction appended as final HumanMessage', async () => {
538
- captureEvents();
539
-
540
- const capturedMessages: Array<{ type: string; content: string }> = [];
541
-
542
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
543
- class {
544
- constructor() {
545
- return {
546
- invoke: jest
547
- .fn()
548
- .mockImplementation(async (messages: unknown[]) => {
549
- for (const msg of messages as {
550
- getType: () => string;
551
- content: string | unknown[];
552
- }[]) {
553
- capturedMessages.push({
554
- type: msg.getType(),
555
- content:
556
- typeof msg.content === 'string'
557
- ? msg.content
558
- : JSON.stringify(msg.content),
559
- });
560
- }
561
- return {
562
- content:
563
- '## Goal\nTest goal\n\n<events>\n<event key="test" turn="0">value</event>\n</events>',
564
- };
565
- }),
566
- };
567
- }
568
- } as never
569
- );
570
-
571
- const agentContext = createAgentContext();
572
- const graph = mockGraph();
573
- const node = createSummarizeNode({
574
- agentContext,
575
- graph: graph as never,
576
- generateStepId,
577
- });
578
-
579
- await node(
580
- {
581
- messages: [
582
- new HumanMessage('Message 1'),
583
- new HumanMessage('Message 2'),
584
- new HumanMessage('Message 3'),
585
- ],
586
- summarizationRequest: {
587
- remainingContextTokens: 1000,
588
- agentId: 'agent_0',
589
- },
590
- },
591
- {} as RunnableConfig
592
- );
593
-
594
- // The raw messages should be sent + instruction appended as the last HumanMessage
595
- // messagesToRefine has 3 HumanMessages, instruction adds 1 more
596
- expect(capturedMessages.length).toBe(4);
597
- expect(capturedMessages[0].type).toBe('human');
598
- expect(capturedMessages[0].content).toBe('Message 1');
599
- expect(capturedMessages[3].type).toBe('human');
600
- // The last message should contain the summarization prompt
601
- expect(capturedMessages[3].content).toContain(
602
- 'context window is filling up'
603
- );
604
- });
605
-
606
- it('cache-hit path includes prior summary in the instruction message', async () => {
607
- captureEvents();
608
-
609
- const capturedMessages: Array<{ type: string; content: string }> = [];
610
-
611
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
612
- class {
613
- constructor() {
614
- return {
615
- invoke: jest
616
- .fn()
617
- .mockImplementation(async (messages: unknown[]) => {
618
- for (const msg of messages as {
619
- getType: () => string;
620
- content: string | unknown[];
621
- }[]) {
622
- capturedMessages.push({
623
- type: msg.getType(),
624
- content:
625
- typeof msg.content === 'string'
626
- ? msg.content
627
- : JSON.stringify(msg.content),
628
- });
629
- }
630
- return { content: '## Goal\nUpdated summary' };
631
- }),
632
- };
633
- }
634
- } as never
635
- );
636
-
637
- // Create context with a prior summary
638
- const agentContext = createAgentContext();
639
- agentContext.setSummary('## Goal\nPrior summary content.', 50);
640
-
641
- const graph = mockGraph();
642
- const node = createSummarizeNode({
643
- agentContext,
644
- graph: graph as never,
645
- generateStepId,
646
- });
647
-
648
- await node(
649
- {
650
- messages: [new HumanMessage('New message')],
651
- summarizationRequest: {
652
- remainingContextTokens: 1000,
653
- agentId: 'agent_0',
654
- },
655
- },
656
- {} as RunnableConfig
657
- );
658
-
659
- // The last message should contain the update prompt (prior summary exists)
660
- const lastMsg = capturedMessages[capturedMessages.length - 1];
661
- expect(lastMsg.type).toBe('human');
662
- expect(lastMsg.content).toContain('Merge the new messages');
663
- // Should include the prior summary
664
- expect(lastMsg.content).toContain('<previous-summary>');
665
- expect(lastMsg.content).toContain('Prior summary content');
666
- });
667
- });
668
-
669
- describe('DEFAULT_SUMMARIZATION_PROMPT', () => {
670
- it('is exported and non-empty', () => {
671
- expect(typeof DEFAULT_SUMMARIZATION_PROMPT).toBe('string');
672
- expect(DEFAULT_SUMMARIZATION_PROMPT.length).toBeGreaterThan(0);
673
- });
674
-
675
- it('contains structured checkpoint sections', () => {
676
- expect(DEFAULT_SUMMARIZATION_PROMPT).toContain('## Goal');
677
- expect(DEFAULT_SUMMARIZATION_PROMPT).toContain('## Progress');
678
- expect(DEFAULT_SUMMARIZATION_PROMPT).toContain('## Key Decisions');
679
- expect(DEFAULT_SUMMARIZATION_PROMPT).toContain('## Next Steps');
680
- });
681
- });
682
-
683
- describe('DEFAULT_UPDATE_SUMMARIZATION_PROMPT', () => {
684
- it('is exported and non-empty', () => {
685
- expect(typeof DEFAULT_UPDATE_SUMMARIZATION_PROMPT).toBe('string');
686
- expect(DEFAULT_UPDATE_SUMMARIZATION_PROMPT.length).toBeGreaterThan(0);
687
- });
688
-
689
- it('instructs merging new content', () => {
690
- expect(DEFAULT_UPDATE_SUMMARIZATION_PROMPT).toMatch(
691
- /Merge the new messages/i
692
- );
693
- });
694
-
695
- it('instructs updating progress tracking', () => {
696
- expect(DEFAULT_UPDATE_SUMMARIZATION_PROMPT).toMatch(/Done/);
697
- expect(DEFAULT_UPDATE_SUMMARIZATION_PROMPT).toMatch(/In Progress/);
698
- });
699
- });
700
-
701
- describe('budget check — instructions exceed context', () => {
702
- it('skips summarization when instructionTokens >= maxContextTokens', async () => {
703
- const events = captureEvents();
704
- const agentContext = createAgentContext({
705
- maxContextTokens: 4000,
706
- systemMessageTokens: 5000,
707
- formatTokenBudgetBreakdown: () => 'mock breakdown',
708
- });
709
-
710
- const graph = mockGraph();
711
- const summarizeNode = createSummarizeNode({
712
- agentContext,
713
- graph: graph as never,
714
- generateStepId,
715
- });
716
-
717
- const result = await summarizeNode(
718
- {
719
- messages: [new HumanMessage('test')],
720
- summarizationRequest: {
721
- remainingContextTokens: -1000,
722
- agentId: 'agent_0',
723
- },
724
- },
725
- {} as RunnableConfig
726
- );
727
-
728
- expect(result.summarizationRequest).toBeUndefined();
729
- expect(result.messages).toBeUndefined();
730
-
731
- // No summarization events should have fired
732
- const summarizeEvents = events.filter(
733
- (e) =>
734
- e.event === GraphEvents.ON_SUMMARIZE_START ||
735
- e.event === GraphEvents.ON_SUMMARIZE_DELTA ||
736
- e.event === GraphEvents.ON_SUMMARIZE_COMPLETE
737
- );
738
- expect(summarizeEvents).toHaveLength(0);
739
- });
740
-
741
- it('proceeds normally when instructionTokens < maxContextTokens', async () => {
742
- captureEvents();
743
-
744
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
745
- class {
746
- constructor() {
747
- return mockInvokeModel('Budget is fine summary');
748
- }
749
- } as never
750
- );
751
-
752
- const agentContext = createAgentContext({
753
- maxContextTokens: 8000,
754
- systemMessageTokens: 2000,
755
- formatTokenBudgetBreakdown: () => 'mock breakdown',
756
- });
757
-
758
- const graph = mockGraph();
759
- const summarizeNode = createSummarizeNode({
760
- agentContext,
761
- graph: graph as never,
762
- generateStepId,
763
- });
764
-
765
- const result = await summarizeNode(
766
- {
767
- messages: [new HumanMessage('hello')],
768
- summarizationRequest: {
769
- remainingContextTokens: 500,
770
- agentId: 'agent_0',
771
- },
772
- },
773
- {} as RunnableConfig
774
- );
775
-
776
- // Should have summarized — messages returned for state replacement
777
- expect(result.messages).toBeDefined();
778
- expect(result.messages!.length).toBeGreaterThan(0);
779
- });
780
- });
781
-
782
- describe('recency window — first-turn protection', () => {
783
- it('skips the LLM call when only one turn exists (default turns: 2)', async () => {
784
- const events = captureEvents();
785
-
786
- const invokeMock = jest
787
- .fn()
788
- .mockResolvedValue({ content: 'should not be called' });
789
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
790
- class {
791
- constructor() {
792
- return { invoke: invokeMock };
793
- }
794
- } as never
795
- );
796
-
797
- const setSummary = jest.fn();
798
- const agentContext = createAgentContext({
799
- summarizationConfig: {} /* defaults to retainRecent.turns = 2 */,
800
- setSummary,
801
- } as never);
802
- const graph = mockGraph();
803
- const summarizeNode = createSummarizeNode({
804
- agentContext,
805
- graph: graph as never,
806
- generateStepId,
807
- });
808
-
809
- const largePayload = 'paste'.repeat(10_000);
810
- const result = await summarizeNode(
811
- {
812
- messages: [new HumanMessage(largePayload)],
813
- summarizationRequest: {
814
- remainingContextTokens: 0,
815
- agentId: 'agent_0',
816
- },
817
- },
818
- {} as RunnableConfig
819
- );
820
-
821
- // No LLM call — first user message is preserved verbatim.
822
- expect(invokeMock).not.toHaveBeenCalled();
823
- expect(setSummary).not.toHaveBeenCalled();
824
- // No state mutation — original messages stay.
825
- expect(result.messages).toBeUndefined();
826
- expect(result.summarizationRequest).toBeUndefined();
827
- // No ON_SUMMARIZE_START emitted on the skip path.
828
- const eventNames = events.map((e) => e.event);
829
- expect(eventNames).not.toContain(GraphEvents.ON_SUMMARIZE_START);
830
- expect(eventNames).not.toContain(GraphEvents.ON_SUMMARIZE_COMPLETE);
831
- });
832
-
833
- it('skips when a single-turn includes assistant + tool messages', async () => {
834
- captureEvents();
835
-
836
- const invokeMock = jest.fn().mockResolvedValue({ content: 'unused' });
837
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
838
- class {
839
- constructor() {
840
- return { invoke: invokeMock };
841
- }
842
- } as never
843
- );
844
-
845
- const setSummary = jest.fn();
846
- const agentContext = createAgentContext({
847
- summarizationConfig: {},
848
- setSummary,
849
- } as never);
850
- const graph = mockGraph();
851
- const summarizeNode = createSummarizeNode({
852
- agentContext,
853
- graph: graph as never,
854
- generateStepId,
855
- });
856
-
857
- const result = await summarizeNode(
858
- {
859
- messages: [
860
- new HumanMessage('the first user prompt'),
861
- new AIMessage({
862
- content: '',
863
- tool_calls: [{ id: 'c', name: 'search', args: {} }],
864
- }),
865
- new ToolMessage({
866
- content: 'result',
867
- tool_call_id: 'c',
868
- name: 'search',
869
- }),
870
- new AIMessage('here is what i found'),
871
- ],
872
- summarizationRequest: {
873
- remainingContextTokens: 0,
874
- agentId: 'agent_0',
875
- },
876
- },
877
- {} as RunnableConfig
878
- );
879
-
880
- expect(invokeMock).not.toHaveBeenCalled();
881
- expect(setSummary).not.toHaveBeenCalled();
882
- expect(result.messages).toBeUndefined();
883
- });
884
-
885
- it('still summarizes the head when older turns exist beyond the recency window', async () => {
886
- captureEvents();
887
-
888
- let capturedMessages: { type: string; content: unknown }[] = [];
889
- const invokeMock = jest.fn().mockImplementation((messages: unknown) => {
890
- capturedMessages = (
891
- messages as Array<{ getType: () => string; content: unknown }>
892
- ).map((m) => ({ type: m.getType(), content: m.content }));
893
- return Promise.resolve({ content: 'Summary of older turns' });
894
- });
895
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
896
- class {
897
- constructor() {
898
- return { invoke: invokeMock };
899
- }
900
- } as never
901
- );
902
-
903
- const setSummary = jest.fn();
904
- const agentContext = createAgentContext({
905
- summarizationConfig: { retainRecent: { turns: 1 } },
906
- setSummary,
907
- } as never);
908
- const graph = mockGraph();
909
- const summarizeNode = createSummarizeNode({
910
- agentContext,
911
- graph: graph as never,
912
- generateStepId,
913
- });
914
-
915
- const messages = [
916
- new HumanMessage('turn 1 query'),
917
- new AIMessage('turn 1 reply'),
918
- new HumanMessage('turn 2 query'),
919
- new AIMessage('turn 2 reply'),
920
- ];
921
- const result = await summarizeNode(
922
- {
923
- messages,
924
- summarizationRequest: {
925
- remainingContextTokens: 0,
926
- agentId: 'agent_0',
927
- },
928
- },
929
- {} as RunnableConfig
930
- );
931
-
932
- // Head (turn 1) summarized; tail (turn 2) preserved verbatim.
933
- expect(setSummary).toHaveBeenCalledWith(
934
- expect.stringContaining('Summary of older turns'),
935
- expect.any(Number)
936
- );
937
- // Captured messages are the head + the appended summarization instruction.
938
- // Head has 2 messages (turn 1) + 1 instruction = 3 total.
939
- expect(capturedMessages).toHaveLength(3);
940
- expect(capturedMessages[0]?.content).toBe('turn 1 query');
941
- expect(capturedMessages[1]?.content).toBe('turn 1 reply');
942
-
943
- // Returned messages: removeAll marker + tail.
944
- expect(result.messages).toBeDefined();
945
- expect(result.messages![0]?._getType()).toBe('remove');
946
- expect(result.messages!.slice(1)).toHaveLength(2);
947
- expect((result.messages![1] as HumanMessage).content).toBe('turn 2 query');
948
- expect((result.messages![2] as AIMessage).content).toBe('turn 2 reply');
949
- });
950
-
951
- describe('summary coverage', () => {
952
- const runCompaction = async (
953
- messages: BaseMessage[],
954
- turns = 1
955
- ): Promise<t.SummaryContentBlock | undefined> => {
956
- captureEvents();
957
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
958
- class {
959
- constructor() {
960
- return mockInvokeModel('Summary of older turns');
961
- }
962
- } as never
963
- );
964
-
965
- let summaryBlock: t.SummaryContentBlock | undefined;
966
- const graph = mockGraph((_stepId, result) => {
967
- if (result.type === 'summary') {
968
- summaryBlock = result.summary;
969
- }
970
- });
971
- const summarizeNode = createSummarizeNode({
972
- agentContext: createAgentContext({
973
- summarizationConfig: { retainRecent: { turns } },
974
- } as never),
975
- graph: graph as never,
976
- generateStepId,
977
- });
978
-
979
- await summarizeNode(
980
- {
981
- messages,
982
- summarizationRequest: {
983
- remainingContextTokens: 0,
984
- agentId: 'agent_0',
985
- },
986
- },
987
- {} as RunnableConfig
988
- );
989
-
990
- return summaryBlock;
991
- };
992
-
993
- it('records the first retained message as the coverage anchor', async () => {
994
- const summaryBlock = await runCompaction([
995
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
996
- new AIMessage({ content: 'turn 1 reply', id: 'm2' }),
997
- new HumanMessage({ content: 'turn 2 query', id: 'm3' }),
998
- new AIMessage({ content: 'turn 2 reply', id: 'm4' }),
999
- ]);
1000
-
1001
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm3' });
1002
- });
1003
-
1004
- it('skips a retained message that carries no source id', async () => {
1005
- const summaryBlock = await runCompaction([
1006
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1007
- new AIMessage({ content: 'turn 1 reply', id: 'm2' }),
1008
- new HumanMessage({ content: 'turn 2 query' }),
1009
- new AIMessage({ content: 'turn 2 reply', id: 'm4' }),
1010
- ]);
1011
-
1012
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm4' });
1013
- });
1014
-
1015
- it('omits coverage when no retained message carries a source id', async () => {
1016
- const summaryBlock = await runCompaction([
1017
- new HumanMessage('turn 1 query'),
1018
- new AIMessage('turn 1 reply'),
1019
- new HumanMessage('turn 2 query'),
1020
- new AIMessage('turn 2 reply'),
1021
- ]);
1022
-
1023
- expect(summaryBlock?.coverage).toBeUndefined();
1024
- });
1025
-
1026
- /** A steer expands one source message into pre-steer, steer, and post-steer
1027
- * messages sharing its ID, and the recency split lands on the steer. The
1028
- * straddling message is the anchor, so it survives whole. */
1029
- it('anchors on a source id that straddles the recency boundary', async () => {
1030
- const summaryBlock = await runCompaction([
1031
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1032
- new AIMessage({ content: 'pre-steer reply', id: 'm2' }),
1033
- new HumanMessage({
1034
- content: 'steer',
1035
- id: 'm2',
1036
- additional_kwargs: { role: 'user', source: 'steer' },
1037
- }),
1038
- new AIMessage({ content: 'post-steer reply', id: 'm2' }),
1039
- ]);
1040
-
1041
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm2' });
1042
- });
1043
-
1044
- /** A steer carries `source: 'steer'` but is replayed from a payload entry
1045
- * and stamped with its ID, so it is a valid anchor. When compaction lands
1046
- * before any post-steer message exists it is the *only* retained entry —
1047
- * treating every marked message as synthetic drops it. */
1048
- it('anchors on a retained steer with no post-steer message', async () => {
1049
- const summaryBlock = await runCompaction([
1050
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1051
- new AIMessage({ content: 'pre-steer reply', id: 'm2' }),
1052
- new HumanMessage({
1053
- content: 'steer',
1054
- id: 'm2',
1055
- additional_kwargs: { role: 'user', source: 'steer' },
1056
- }),
1057
- ]);
1058
-
1059
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm2' });
1060
- });
1061
-
1062
- it('anchors a derived retained message on its persisted source id', async () => {
1063
- const summaryBlock = await runCompaction([
1064
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1065
- new AIMessage({ content: 'pre-steer reply', id: 'm2' }),
1066
- new HumanMessage({
1067
- content: 'steer',
1068
- id: 'reducer-uuid',
1069
- additional_kwargs: {
1070
- role: 'user',
1071
- source: 'steer',
1072
- sourceMessageId: 'm2',
1073
- },
1074
- }),
1075
- ]);
1076
-
1077
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm2' });
1078
- });
1079
-
1080
- /** `formatAgentMessages` reconstructs skill bodies inside its payload loop
1081
- * and keeps processing payload entries after, so this unstamped entry — a
1082
- * reducer UUID by the time compaction sees it — precedes stamped messages.
1083
- * Anchoring on it would resolve to nothing on the next run. */
1084
- it('skips a reconstructed skill body to reach the stamped message behind it', async () => {
1085
- const summaryBlock = await runCompaction(
1086
- [
1087
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1088
- new AIMessage({ content: 'turn 1 reply', id: 'm2' }),
1089
- new HumanMessage({
1090
- content: 'skill body',
1091
- id: 'reducer-uuid',
1092
- additional_kwargs: {
1093
- role: 'user',
1094
- isMeta: true,
1095
- source: 'skill',
1096
- skillName: 'demo',
1097
- },
1098
- }),
1099
- new HumanMessage({ content: 'turn 2 query', id: 'm3' }),
1100
- new AIMessage({ content: 'turn 2 reply', id: 'm4' }),
1101
- ],
1102
- 2
1103
- );
1104
-
1105
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm3' });
1106
- });
1107
-
1108
- /** `InjectedMessage` leaves both `isMeta` and `source` optional, so a bare
1109
- * injected turn carries no marker of its own — and an injected `steer` is
1110
- * otherwise indistinguishable from a replayed one. `convertInjectedMessages`
1111
- * records `injected` on everything it builds, which decides both. */
1112
- it.each([
1113
- ['a bare injected turn', { role: 'user' as const, content: 'injected' }],
1114
- [
1115
- 'an injected steer',
1116
- {
1117
- role: 'user' as const,
1118
- content: 'injected steer',
1119
- source: 'steer' as const,
1120
- },
1121
- ],
1122
- ])('skips %s when anchoring', async (_label, injected) => {
1123
- const [converted] = convertInjectedMessages([injected]);
1124
- converted.id = 'reducer-uuid';
1125
-
1126
- const summaryBlock = await runCompaction(
1127
- [
1128
- new HumanMessage({ content: 'turn 1 query', id: 'm1' }),
1129
- new AIMessage({ content: 'turn 1 reply', id: 'm2' }),
1130
- converted,
1131
- new HumanMessage({ content: 'turn 2 query', id: 'm3' }),
1132
- new AIMessage({ content: 'turn 2 reply', id: 'm4' }),
1133
- ],
1134
- 2
1135
- );
1136
-
1137
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm3' });
1138
- });
1139
-
1140
- it('anchors on the straddling id when it is the only source', async () => {
1141
- const summaryBlock = await runCompaction([
1142
- new AIMessage({ content: 'pre-steer reply', id: 'm1' }),
1143
- new HumanMessage({
1144
- content: 'steer',
1145
- id: 'm1',
1146
- additional_kwargs: { role: 'user', source: 'steer' },
1147
- }),
1148
- new AIMessage({ content: 'post-steer reply', id: 'm1' }),
1149
- ]);
1150
-
1151
- expect(summaryBlock?.coverage).toEqual({ retainedFromMessageId: 'm1' });
1152
- });
1153
- });
1154
-
1155
- it('keeps the masked tail content (does not re-inject restored tool payloads into state)', async () => {
1156
- captureEvents();
1157
-
1158
- let summarizerSawRestored = false;
1159
- const invokeMock = jest.fn().mockImplementation((messages: unknown) => {
1160
- const arr = messages as Array<{
1161
- getType: () => string;
1162
- content: unknown;
1163
- tool_call_id?: string;
1164
- }>;
1165
- // Confirm the summarizer's input for the restored tool result has
1166
- // the FULL content, not the masked stub.
1167
- summarizerSawRestored = arr.some(
1168
- (m) =>
1169
- m.getType() === 'tool' &&
1170
- typeof m.content === 'string' &&
1171
- (m.content as string).includes('FULL_ORIGINAL_OUTPUT')
1172
- );
1173
- return Promise.resolve({ content: 'summary' });
1174
- });
1175
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1176
- class {
1177
- constructor() {
1178
- return { invoke: invokeMock };
1179
- }
1180
- } as never
1181
- );
1182
-
1183
- const setSummary = jest.fn();
1184
- const agentContext = createAgentContext({
1185
- summarizationConfig: { retainRecent: { turns: 1 } },
1186
- setSummary,
1187
- } as never);
1188
- // Restoration map keyed by message index — applies to head (idx 2)
1189
- // AND to a tool message inside the retained tail (idx 5). Only the
1190
- // head's restoration should leak into the summarizer; the tail must
1191
- // keep the masked content.
1192
- agentContext.pendingOriginalToolContent = new Map<number, string>([
1193
- [2, 'FULL_ORIGINAL_OUTPUT for head tool result'],
1194
- [5, 'FULL_ORIGINAL_OUTPUT for tail tool result — must NOT survive'],
1195
- ]);
1196
-
1197
- const graph = mockGraph();
1198
- const summarizeNode = createSummarizeNode({
1199
- agentContext,
1200
- graph: graph as never,
1201
- generateStepId,
1202
- });
1203
-
1204
- const headToolCall = new AIMessage({
1205
- content: '',
1206
- tool_calls: [{ id: 'h', name: 'search', args: {} }],
1207
- });
1208
- const headToolResult = new ToolMessage({
1209
- content: 'masked-head-stub',
1210
- tool_call_id: 'h',
1211
- name: 'search',
1212
- });
1213
- const tailToolCall = new AIMessage({
1214
- content: '',
1215
- tool_calls: [{ id: 't', name: 'search', args: {} }],
1216
- });
1217
- const tailToolResult = new ToolMessage({
1218
- content: 'masked-tail-stub',
1219
- tool_call_id: 't',
1220
- name: 'search',
1221
- });
1222
- const messages = [
1223
- new HumanMessage('turn 1 query'),
1224
- headToolCall,
1225
- headToolResult, // index 2 — restored for summarizer
1226
- new HumanMessage('turn 2 query'),
1227
- tailToolCall,
1228
- tailToolResult, // index 5 — must stay masked in returned tail
1229
- ];
1230
-
1231
- const result = await summarizeNode(
1232
- {
1233
- messages,
1234
- summarizationRequest: {
1235
- remainingContextTokens: 0,
1236
- agentId: 'agent_0',
1237
- },
1238
- },
1239
- {} as RunnableConfig
1240
- );
1241
-
1242
- // Summarizer saw the full restored head tool result.
1243
- expect(summarizerSawRestored).toBe(true);
1244
-
1245
- // Returned tail must contain the MASKED tool result, not the restored one.
1246
- expect(result.messages).toBeDefined();
1247
- const tailToolMsg = result.messages!.find(
1248
- (m) => m._getType() === 'tool'
1249
- ) as ToolMessage | undefined;
1250
- expect(tailToolMsg).toBeDefined();
1251
- expect(tailToolMsg!.content).toBe('masked-tail-stub');
1252
- expect(tailToolMsg!.content).not.toContain('FULL_ORIGINAL_OUTPUT');
1253
- });
1254
-
1255
- it('bounds restored tool originals and preserves ToolMessage metadata', async () => {
1256
- captureEvents();
1257
-
1258
- let restoredToolMessage: ToolMessage | undefined;
1259
- const invokeMock = jest.fn().mockImplementation((messages: unknown) => {
1260
- restoredToolMessage = (messages as Array<unknown>).find(
1261
- (message) => message instanceof ToolMessage
1262
- ) as ToolMessage | undefined;
1263
- return Promise.resolve({ content: 'summary' });
1264
- });
1265
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1266
- class {
1267
- constructor() {
1268
- return { invoke: invokeMock };
1269
- }
1270
- } as never
1271
- );
1272
-
1273
- const artifact = { source: 'clickhouse', rows: 1_000 };
1274
- const originalToolMessage = new ToolMessage({
1275
- content: 'masked-stub',
1276
- tool_call_id: 'bounded',
1277
- name: 'run_select_query',
1278
- status: 'success',
1279
- artifact,
1280
- metadata: { traceId: 'trace-1' },
1281
- additional_kwargs: { retained: true },
1282
- response_metadata: { requestId: 'request-1' },
1283
- });
1284
- const agentContext = createAgentContext({
1285
- maxContextTokens: 2_000,
1286
- summarizationConfig: { retainRecent: { turns: 0 } },
1287
- setSummary: jest.fn(),
1288
- });
1289
- agentContext.pendingOriginalToolContent = new Map([
1290
- [2, `[{"rows":"${'x'.repeat(20_000)}"}]`],
1291
- ]);
1292
-
1293
- const summarizeNode = createSummarizeNode({
1294
- agentContext,
1295
- graph: mockGraph() as never,
1296
- generateStepId,
1297
- });
1298
- await summarizeNode(
1299
- {
1300
- messages: [
1301
- new HumanMessage('query the table'),
1302
- new AIMessage({
1303
- content: '',
1304
- tool_calls: [{ id: 'bounded', name: 'run_select_query', args: {} }],
1305
- }),
1306
- originalToolMessage,
1307
- ],
1308
- summarizationRequest: {
1309
- remainingContextTokens: 0,
1310
- agentId: 'agent_0',
1311
- },
1312
- },
1313
- {} as RunnableConfig
1314
- );
1315
-
1316
- expect(restoredToolMessage).toBeDefined();
1317
- expect(typeof restoredToolMessage!.content).toBe('string');
1318
- expect(String(restoredToolMessage!.content).length).toBeLessThanOrEqual(
1319
- 2_400
1320
- );
1321
- expect(restoredToolMessage!.content).toContain('[truncated:');
1322
- expect(restoredToolMessage!.status).toBe('success');
1323
- expect(restoredToolMessage!.artifact).toBe(artifact);
1324
- expect(restoredToolMessage!.metadata).toEqual({ traceId: 'trace-1' });
1325
- expect(restoredToolMessage!.additional_kwargs).toEqual({ retained: true });
1326
- expect(restoredToolMessage!.response_metadata).toEqual({
1327
- requestId: 'request-1',
1328
- });
1329
- expect(originalToolMessage.content).toBe('masked-stub');
1330
- });
1331
-
1332
- it('preserves tail-relevant pendingOriginalToolContent entries (reindexed) for future summaries', async () => {
1333
- captureEvents();
1334
-
1335
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1336
- class {
1337
- constructor() {
1338
- return mockInvokeModel('summary');
1339
- }
1340
- } as never
1341
- );
1342
-
1343
- const setSummary = jest.fn();
1344
- const agentContext = createAgentContext({
1345
- summarizationConfig: { retainRecent: { turns: 1 } },
1346
- setSummary,
1347
- } as never);
1348
- // Original-content map covers BOTH a head index (1) and tail indices
1349
- // (3, 5). Only the tail entries should survive, reindexed to the
1350
- // post-removeAll state where tail messages start at 0.
1351
- agentContext.pendingOriginalToolContent = new Map<number, string>([
1352
- [1, 'fullHead'], // belongs to summarized head — should be dropped
1353
- [3, 'fullTailA'], // tail position 3 → reindexed to 0
1354
- [5, 'fullTailB'], // tail position 5 → reindexed to 2
1355
- ]);
1356
-
1357
- const graph = mockGraph();
1358
- const summarizeNode = createSummarizeNode({
1359
- agentContext,
1360
- graph: graph as never,
1361
- generateStepId,
1362
- });
1363
-
1364
- const messages = [
1365
- new HumanMessage('turn 1 query'),
1366
- new AIMessage('turn 1 reply'), // idx 1
1367
- new HumanMessage('turn 2 query'), // idx 2 — tail starts here
1368
- new ToolMessage({
1369
- // idx 3
1370
- content: 'masked-stub-A',
1371
- tool_call_id: 'a',
1372
- name: 'search',
1373
- }),
1374
- new AIMessage('turn 2 reply'), // idx 4
1375
- new ToolMessage({
1376
- // idx 5
1377
- content: 'masked-stub-B',
1378
- tool_call_id: 'b',
1379
- name: 'search',
1380
- }),
1381
- ];
1382
-
1383
- await summarizeNode(
1384
- {
1385
- messages,
1386
- summarizationRequest: {
1387
- remainingContextTokens: 0,
1388
- agentId: 'agent_0',
1389
- },
1390
- },
1391
- {} as RunnableConfig
1392
- );
1393
-
1394
- // Summarize fired (we used a real summary text), so head index 1
1395
- // is gone. Tail entries should remain, reindexed by subtracting
1396
- // tailStartIndex (=2): 3→1, 5→3.
1397
- const carryOver = agentContext.pendingOriginalToolContent;
1398
- expect(carryOver).toBeDefined();
1399
- expect(carryOver!.size).toBe(2);
1400
- expect(carryOver!.get(1)).toBe('fullTailA');
1401
- expect(carryOver!.get(3)).toBe('fullTailB');
1402
- expect(carryOver!.has(0)).toBe(false);
1403
- expect(carryOver!.has(5)).toBe(false);
1404
- });
1405
-
1406
- it('aligns the dedupe baseline with the surviving tail length after compaction', async () => {
1407
- captureEvents();
1408
-
1409
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1410
- class {
1411
- constructor() {
1412
- return mockInvokeModel('summary');
1413
- }
1414
- } as never
1415
- );
1416
-
1417
- const agentContext = createAgentContext({
1418
- summarizationConfig: { retainRecent: { turns: 1 } },
1419
- } as never);
1420
- const graph = mockGraph();
1421
- const summarizeNode = createSummarizeNode({
1422
- agentContext,
1423
- graph: graph as never,
1424
- generateStepId,
1425
- });
1426
-
1427
- const messages = [
1428
- new HumanMessage('turn 1 query'),
1429
- new AIMessage('turn 1 reply'),
1430
- new HumanMessage('turn 2 query'),
1431
- new AIMessage('turn 2 reply'),
1432
- ];
1433
-
1434
- await summarizeNode(
1435
- {
1436
- messages,
1437
- summarizationRequest: {
1438
- remainingContextTokens: 0,
1439
- agentId: 'agent_0',
1440
- },
1441
- },
1442
- {} as RunnableConfig
1443
- );
1444
-
1445
- // Tail = last turn = 2 messages. Baseline must equal that count
1446
- // so a follow-up prune call on the unchanged tail short-circuits
1447
- // via shouldSkipSummarization rather than re-triggering compaction.
1448
- expect(agentContext.shouldSkipSummarization(2)).toBe(true);
1449
- expect(agentContext.shouldSkipSummarization(3)).toBe(false);
1450
- });
1451
-
1452
- it('does not clear pendingOriginalToolContent on the skip path (state unchanged)', async () => {
1453
- captureEvents();
1454
-
1455
- const invokeMock = jest.fn();
1456
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1457
- class {
1458
- constructor() {
1459
- return { invoke: invokeMock };
1460
- }
1461
- } as never
1462
- );
1463
-
1464
- const agentContext = createAgentContext({
1465
- summarizationConfig: { retainRecent: { turns: 2 } },
1466
- } as never);
1467
- const seededMap = new Map<number, string>([[1, 'preserved-original']]);
1468
- agentContext.pendingOriginalToolContent = seededMap;
1469
-
1470
- const graph = mockGraph();
1471
- const summarizeNode = createSummarizeNode({
1472
- agentContext,
1473
- graph: graph as never,
1474
- generateStepId,
1475
- });
1476
-
1477
- await summarizeNode(
1478
- {
1479
- messages: [
1480
- new HumanMessage('only turn'),
1481
- new ToolMessage({
1482
- content: 'masked',
1483
- tool_call_id: 'x',
1484
- name: 'search',
1485
- }),
1486
- ],
1487
- summarizationRequest: {
1488
- remainingContextTokens: 0,
1489
- agentId: 'agent_0',
1490
- },
1491
- },
1492
- {} as RunnableConfig
1493
- );
1494
-
1495
- // No LLM call (skip path); pendingOriginalToolContent must still be
1496
- // available so a future summarization can restore the original.
1497
- expect(invokeMock).not.toHaveBeenCalled();
1498
- expect(agentContext.pendingOriginalToolContent).toBe(seededMap);
1499
- expect(agentContext.pendingOriginalToolContent!.get(1)).toBe(
1500
- 'preserved-original'
1501
- );
1502
- });
1503
-
1504
- it('preserves the legacy "remove all, summary only" shape when retainRecent.turns is 0', async () => {
1505
- captureEvents();
1506
-
1507
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1508
- class {
1509
- constructor() {
1510
- return mockInvokeModel('Legacy summary');
1511
- }
1512
- } as never
1513
- );
1514
-
1515
- const setSummary = jest.fn();
1516
- const agentContext = createAgentContext({
1517
- summarizationConfig: { retainRecent: { turns: 0 } },
1518
- setSummary,
1519
- } as never);
1520
- const graph = mockGraph();
1521
- const summarizeNode = createSummarizeNode({
1522
- agentContext,
1523
- graph: graph as never,
1524
- generateStepId,
1525
- });
1526
-
1527
- const result = await summarizeNode(
1528
- {
1529
- messages: [
1530
- new HumanMessage('only message'),
1531
- new AIMessage('only reply'),
1532
- ],
1533
- summarizationRequest: {
1534
- remainingContextTokens: 0,
1535
- agentId: 'agent_0',
1536
- },
1537
- },
1538
- {} as RunnableConfig
1539
- );
1540
-
1541
- expect(setSummary).toHaveBeenCalled();
1542
- // Legacy: remove-all only, no tail re-injection.
1543
- expect(result.messages).toHaveLength(1);
1544
- expect(result.messages![0]?._getType()).toBe('remove');
1545
- });
1546
- });
1547
-
1548
- describe('emoji-heavy content does not break summarization', () => {
1549
- it('summarization completes without JSON errors on emoji-heavy messages', async () => {
1550
- captureEvents();
1551
-
1552
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1553
- class {
1554
- constructor() {
1555
- return mockInvokeModel('Summary of emoji conversation');
1556
- }
1557
- } as never
1558
- );
1559
-
1560
- const emojiContent = '👨‍💻 coding 🎉 party 🌍 world 🚀 rocket '.repeat(30);
1561
- const agentContext = createAgentContext({
1562
- maxContextTokens: 8000,
1563
- systemMessageTokens: 100,
1564
- formatTokenBudgetBreakdown: () => 'mock breakdown',
1565
- });
1566
-
1567
- const graph = mockGraph();
1568
- const summarizeNode = createSummarizeNode({
1569
- agentContext,
1570
- graph: graph as never,
1571
- generateStepId,
1572
- });
1573
-
1574
- const result = await summarizeNode(
1575
- {
1576
- messages: [new HumanMessage(emojiContent)],
1577
- summarizationRequest: {
1578
- remainingContextTokens: 500,
1579
- agentId: 'agent_0',
1580
- },
1581
- },
1582
- {} as RunnableConfig
1583
- );
1584
-
1585
- // Should complete without throwing JSON serialization errors
1586
- expect(result.messages).toBeDefined();
1587
- expect(result.messages!.length).toBeGreaterThan(0);
1588
- });
1589
- });
1590
-
1591
- describe('createSummarizeNode — overflow recovery', () => {
1592
- /**
1593
- * The first recovery compacts deterministically: re-pruning under the
1594
- * corrected budget drives the pruner's tool-output compression. Spending a
1595
- * summarization call there would cost money and risk replacing message
1596
- * content that compression alone can shrink.
1597
- */
1598
- it('skips the model call when summarization is not yet escalated', async () => {
1599
- const modelFactory = jest.spyOn(providers, 'getChatModelClass');
1600
- const agentContext = createAgentContext();
1601
- const graph = mockGraph(() => {});
1602
- const node = createSummarizeNode({ agentContext, graph, generateStepId });
1603
-
1604
- const result = await node(
1605
- {
1606
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1607
- summarizationRequest: {
1608
- remainingContextTokens: 0,
1609
- agentId: 'agent_0',
1610
- reason: 'overflow',
1611
- allowSummarization: false,
1612
- },
1613
- },
1614
- {} as RunnableConfig
1615
- );
1616
-
1617
- expect(modelFactory).not.toHaveBeenCalled();
1618
- expect(result.summarizationRequest).toBeUndefined();
1619
- /** State untouched, so the agent node re-prunes and retries. */
1620
- expect(result.messages).toBeUndefined();
1621
- });
1622
-
1623
- it('runs the model call once the recovery escalates', async () => {
1624
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1625
- class {
1626
- constructor() {
1627
- return mockInvokeModel('Escalated summary');
1628
- }
1629
- } as never
1630
- );
1631
- const agentContext = createAgentContext();
1632
- const graph = mockGraph(() => {});
1633
- const node = createSummarizeNode({ agentContext, graph, generateStepId });
1634
-
1635
- await node(
1636
- {
1637
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1638
- summarizationRequest: {
1639
- remainingContextTokens: 0,
1640
- agentId: 'agent_0',
1641
- reason: 'overflow',
1642
- allowSummarization: true,
1643
- },
1644
- },
1645
- {} as RunnableConfig
1646
- );
1647
-
1648
- expect(agentContext.getSummaryText()).toContain('Escalated summary');
1649
- });
1650
-
1651
- /**
1652
- * The metadata stub describes the history instead of summarizing it, so
1653
- * committing it removes the head and keeps nothing of what it said. That is
1654
- * never an acceptable way to paper over an overflow.
1655
- */
1656
- it('keeps history when the escalated summarizer falls back to a stub', async () => {
1657
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1658
- class {
1659
- constructor() {
1660
- return {
1661
- invoke: (): never => {
1662
- throw new Error(
1663
- '400 prompt is too long: 900 tokens > 500 maximum'
1664
- );
1665
- },
1666
- stream: (): never => {
1667
- throw new Error(
1668
- '400 prompt is too long: 900 tokens > 500 maximum'
1669
- );
1670
- },
1671
- };
1672
- }
1673
- } as never
1674
- );
1675
- const agentContext = createAgentContext();
1676
- const graph = mockGraph(() => {});
1677
- const node = createSummarizeNode({ agentContext, graph, generateStepId });
1678
-
1679
- const result = await node(
1680
- {
1681
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1682
- summarizationRequest: {
1683
- remainingContextTokens: 0,
1684
- agentId: 'agent_0',
1685
- reason: 'overflow',
1686
- allowSummarization: true,
1687
- },
1688
- },
1689
- {} as RunnableConfig
1690
- );
1691
-
1692
- expect(agentContext.hasSummary()).toBe(false);
1693
- expect(result.messages).toBeUndefined();
1694
- });
1695
-
1696
- it('still commits a stub for a configured trigger, preserving prior behavior', async () => {
1697
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1698
- class {
1699
- constructor() {
1700
- return {
1701
- invoke: (): never => {
1702
- throw new Error('upstream unavailable');
1703
- },
1704
- stream: (): never => {
1705
- throw new Error('upstream unavailable');
1706
- },
1707
- };
1708
- }
1709
- } as never
1710
- );
1711
- const agentContext = createAgentContext();
1712
- const graph = mockGraph(() => {});
1713
- const node = createSummarizeNode({ agentContext, graph, generateStepId });
1714
-
1715
- await node(
1716
- {
1717
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1718
- summarizationRequest: {
1719
- remainingContextTokens: 0,
1720
- agentId: 'agent_0',
1721
- },
1722
- },
1723
- {} as RunnableConfig
1724
- );
1725
-
1726
- expect(agentContext.hasSummary()).toBe(true);
1727
- });
1728
- });
1729
-
1730
- describe('summarize node breaker capture', () => {
1731
- it('stamps the entry-captured breaker epoch into summary attempt metadata', async () => {
1732
- captureEvents();
1733
- const capturedConfigs: Array<{ metadata?: Record<string, unknown> }> = [];
1734
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1735
- class {
1736
- constructor() {
1737
- return {
1738
- invoke: jest
1739
- .fn()
1740
- .mockImplementation(
1741
- async (_messages: unknown, config?: unknown) => {
1742
- capturedConfigs.push(
1743
- config as { metadata?: Record<string, unknown> }
1744
- );
1745
- return { content: 'Summary text' };
1746
- }
1747
- ),
1748
- };
1749
- }
1750
- } as never
1751
- );
1752
-
1753
- const agentContext = createAgentContext();
1754
- const graph = {
1755
- ...mockGraph(),
1756
- getBreakerEpoch: (): number => 7,
1757
- };
1758
- const node = createSummarizeNode({
1759
- agentContext,
1760
- graph,
1761
- generateStepId,
1762
- });
1763
-
1764
- await node(
1765
- {
1766
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1767
- summarizationRequest: {
1768
- remainingContextTokens: 1000,
1769
- agentId: 'agent_0',
1770
- },
1771
- },
1772
- {} as RunnableConfig
1773
- );
1774
-
1775
- expect(capturedConfigs.length).toBeGreaterThan(0);
1776
- for (const config of capturedConfigs) {
1777
- expect(config.metadata?.lc_stream_limit_epoch).toBe(7);
1778
- }
1779
- });
1780
-
1781
- it('rejects before the model call when the breaker trips during pre-call awaits', async () => {
1782
- const trip = new StreamLimitExceededError({
1783
- kind: 'tool_call_args',
1784
- limit: 10,
1785
- observed: 11,
1786
- toolName: 'db_query',
1787
- });
1788
- const entryBreaker = new AbortController();
1789
- /** The trip lands while ON_SUMMARIZE_START is awaited — after the
1790
- * entry check already passed. */
1791
- jest
1792
- .spyOn(eventUtils, 'safeDispatchCustomEvent')
1793
- .mockImplementation((async (...args: unknown[]) => {
1794
- if (args[0] === GraphEvents.ON_SUMMARIZE_START) {
1795
- entryBreaker.abort(trip);
1796
- }
1797
- }) as never);
1798
- const modelClassSpy = jest
1799
- .spyOn(providers, 'getChatModelClass')
1800
- .mockReturnValue(
1801
- class {
1802
- constructor() {
1803
- return mockInvokeModel('should never run');
1804
- }
1805
- } as never
1806
- );
1807
-
1808
- const agentContext = createAgentContext();
1809
- const graph = {
1810
- ...mockGraph(),
1811
- getBreakerSignal: (): AbortSignal => entryBreaker.signal,
1812
- };
1813
- const node = createSummarizeNode({
1814
- agentContext,
1815
- graph,
1816
- generateStepId,
1817
- });
1818
-
1819
- await expect(
1820
- node(
1821
- {
1822
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1823
- summarizationRequest: {
1824
- remainingContextTokens: 1000,
1825
- agentId: 'agent_0',
1826
- },
1827
- },
1828
- {} as RunnableConfig
1829
- )
1830
- ).rejects.toBe(trip);
1831
- expect(modelClassSpy).not.toHaveBeenCalled();
1832
- });
1833
-
1834
- it('rethrows a parent trip on the config signal instead of degrading to the stub', async () => {
1835
- const trip = new StreamLimitExceededError({
1836
- kind: 'tool_call_args',
1837
- limit: 10,
1838
- observed: 11,
1839
- toolName: 'db_query',
1840
- });
1841
- /** Child graph's own breaker stays live: in a subagent, a ROOT
1842
- * sibling's trip arrives only through the composed invocation signal. */
1843
- const childBreaker = new AbortController();
1844
- const configAbort = new AbortController();
1845
- captureEvents();
1846
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1847
- class {
1848
- constructor() {
1849
- return {
1850
- invoke: jest.fn().mockImplementation(async () => {
1851
- configAbort.abort(trip);
1852
- throw new Error('The operation was aborted');
1853
- }),
1854
- };
1855
- }
1856
- } as never
1857
- );
1858
-
1859
- const agentContext = createAgentContext();
1860
- const graph = {
1861
- ...mockGraph(),
1862
- getBreakerSignal: (): AbortSignal => childBreaker.signal,
1863
- };
1864
- const node = createSummarizeNode({
1865
- agentContext,
1866
- graph,
1867
- generateStepId,
1868
- });
1869
-
1870
- await expect(
1871
- node(
1872
- {
1873
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1874
- summarizationRequest: {
1875
- remainingContextTokens: 1000,
1876
- agentId: 'agent_0',
1877
- },
1878
- },
1879
- { signal: configAbort.signal } as RunnableConfig
1880
- )
1881
- ).rejects.toBe(trip);
1882
- });
1883
-
1884
- it('rejects at entry when the breaker has already tripped', async () => {
1885
- const trip = new StreamLimitExceededError({
1886
- kind: 'tool_call_args',
1887
- limit: 10,
1888
- observed: 11,
1889
- toolName: 'db_query',
1890
- });
1891
- const entryBreaker = new AbortController();
1892
- entryBreaker.abort(trip);
1893
-
1894
- const modelClassSpy = jest
1895
- .spyOn(providers, 'getChatModelClass')
1896
- .mockReturnValue(
1897
- class {
1898
- constructor() {
1899
- return mockInvokeModel('should never run');
1900
- }
1901
- } as never
1902
- );
1903
-
1904
- const agentContext = createAgentContext();
1905
- const graph = {
1906
- ...mockGraph(),
1907
- getBreakerSignal: (): AbortSignal => entryBreaker.signal,
1908
- };
1909
- const node = createSummarizeNode({
1910
- agentContext,
1911
- graph,
1912
- generateStepId,
1913
- });
1914
-
1915
- await expect(
1916
- node(
1917
- {
1918
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1919
- summarizationRequest: {
1920
- remainingContextTokens: 1000,
1921
- agentId: 'agent_0',
1922
- },
1923
- },
1924
- {} as RunnableConfig
1925
- )
1926
- ).rejects.toBe(trip);
1927
-
1928
- expect(graph.contentData).toHaveLength(0);
1929
- expect(modelClassSpy).not.toHaveBeenCalled();
1930
- });
1931
-
1932
- it('binds the model call to the breaker signal read at node entry', async () => {
1933
- const entryBreaker = new AbortController();
1934
- const lateBreaker = new AbortController();
1935
- let started = false;
1936
- jest
1937
- .spyOn(eventUtils, 'safeDispatchCustomEvent')
1938
- .mockImplementation((async (...args: unknown[]) => {
1939
- if (args[0] === GraphEvents.ON_SUMMARIZE_START) {
1940
- started = true;
1941
- }
1942
- }) as never);
1943
-
1944
- const capturedSignals: Array<AbortSignal | undefined> = [];
1945
- jest.spyOn(providers, 'getChatModelClass').mockReturnValue(
1946
- class {
1947
- constructor() {
1948
- return {
1949
- invoke: jest
1950
- .fn()
1951
- .mockImplementation(
1952
- async (_messages: unknown, config?: unknown) => {
1953
- capturedSignals.push(
1954
- (config as RunnableConfig | undefined)?.signal
1955
- );
1956
- return { content: 'Summary text' };
1957
- }
1958
- ),
1959
- };
1960
- }
1961
- } as never
1962
- );
1963
-
1964
- const agentContext = createAgentContext();
1965
- /** Simulates a graph reset between node entry and the model call: once
1966
- * ON_SUMMARIZE_START has been awaited, the live accessor hands out a
1967
- * fresh controller's signal. The model call must still see the signal
1968
- * captured at entry. */
1969
- const graph = {
1970
- ...mockGraph(),
1971
- getBreakerSignal: (): AbortSignal =>
1972
- started ? lateBreaker.signal : entryBreaker.signal,
1973
- };
1974
- const node = createSummarizeNode({
1975
- agentContext,
1976
- graph,
1977
- generateStepId,
1978
- });
1979
-
1980
- await node(
1981
- {
1982
- messages: [new HumanMessage('Hello'), new HumanMessage('World')],
1983
- summarizationRequest: {
1984
- remainingContextTokens: 1000,
1985
- agentId: 'agent_0',
1986
- },
1987
- },
1988
- {} as RunnableConfig
1989
- );
1990
-
1991
- expect(capturedSignals.length).toBeGreaterThan(0);
1992
- for (const signal of capturedSignals) {
1993
- expect(signal).toBe(entryBreaker.signal);
1994
- }
1995
- });
1996
- });