@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,2425 +0,0 @@
1
- // src/agents/__tests__/AgentContext.test.ts
2
- import { AIMessage, HumanMessage, ToolMessage } from '@langchain/core/messages';
3
- import type * as t from '@/types';
4
- import { addBedrockCacheControl } from '@/messages/cache';
5
- import { Constants, Providers } from '@/common';
6
- import { AgentContext } from '../AgentContext';
7
-
8
- describe('AgentContext', () => {
9
- type TestSystemContentBlock =
10
- | {
11
- type: 'text';
12
- text: string;
13
- cache_control?: { type: 'ephemeral'; ttl?: '1h' };
14
- }
15
- | { cachePoint: { type: 'default'; ttl?: '1h' } };
16
-
17
- type ContextOptions = {
18
- agentConfig?: Partial<t.AgentInputs>;
19
- tokenCounter?: t.TokenCounter;
20
- indexTokenCountMap?: Record<string, number>;
21
- };
22
-
23
- const createBasicContext = (options: ContextOptions = {}): AgentContext => {
24
- const { agentConfig = {}, tokenCounter, indexTokenCountMap } = options;
25
- return AgentContext.fromConfig(
26
- {
27
- agentId: 'test-agent',
28
- provider: Providers.OPENAI,
29
- instructions: 'Test instructions',
30
- ...agentConfig,
31
- },
32
- tokenCounter,
33
- indexTokenCountMap
34
- );
35
- };
36
-
37
- const createMockTool = (name: string): t.GenericTool =>
38
- ({
39
- name,
40
- description: `Mock ${name} tool`,
41
- invoke: jest.fn(),
42
- schema: { type: 'object', properties: {} },
43
- }) as unknown as t.GenericTool;
44
-
45
- describe('fromConfig — host-supplied graphTools', () => {
46
- it('copies graphTools onto the context without aliasing the host array', () => {
47
- const askTool = createMockTool('ask_user_question');
48
- const hostGraphTools = [askTool];
49
- const ctx = createBasicContext({
50
- agentConfig: { graphTools: hostGraphTools },
51
- });
52
-
53
- expect(ctx.graphTools).toEqual([askTool]);
54
- expect(ctx.graphTools).not.toBe(hostGraphTools);
55
-
56
- /** The SDK pushes graph-managed tools (handoff/subagent) into this
57
- * array later — that must never mutate the host's input. */
58
- (ctx.graphTools as t.GenericTool[]).push(createMockTool('subagent'));
59
- expect(hostGraphTools).toHaveLength(1);
60
- });
61
-
62
- it('leaves graphTools undefined when the host supplies none (or an empty list)', () => {
63
- expect(createBasicContext().graphTools).toBeUndefined();
64
- expect(
65
- createBasicContext({ agentConfig: { graphTools: [] } }).graphTools
66
- ).toBeUndefined();
67
- });
68
-
69
- it('binds host graphTools to the model in event-driven mode', () => {
70
- const askTool = createMockTool('ask_user_question');
71
- const ctx = createBasicContext({
72
- agentConfig: {
73
- graphTools: [askTool],
74
- toolDefinitions: [{ name: 'echo', description: 'host event tool' }],
75
- },
76
- });
77
-
78
- const bound = ctx.getToolsForBinding() ?? [];
79
- const names = (bound as Array<{ name?: string }>).map((t) => t.name);
80
- expect(names).toContain('ask_user_question');
81
- expect(names).toContain('echo');
82
- });
83
- });
84
-
85
- describe('System Runnable - Lazy Creation', () => {
86
- it('creates system runnable on first access', () => {
87
- const ctx = createBasicContext({
88
- agentConfig: { instructions: 'Hello world' },
89
- });
90
- expect(ctx.systemRunnable).toBeDefined();
91
- });
92
-
93
- it('returns cached system runnable on subsequent access', () => {
94
- const ctx = createBasicContext({
95
- agentConfig: { instructions: 'Hello world' },
96
- });
97
- const first = ctx.systemRunnable;
98
- const second = ctx.systemRunnable;
99
- expect(first).toBe(second);
100
- });
101
-
102
- it('returns undefined when no instructions provided', () => {
103
- const ctx = createBasicContext({
104
- agentConfig: {
105
- instructions: undefined,
106
- additional_instructions: undefined,
107
- },
108
- });
109
- expect(ctx.systemRunnable).toBeUndefined();
110
- });
111
-
112
- it('keeps additional_instructions after stable instructions', async () => {
113
- const ctx = createBasicContext({
114
- agentConfig: {
115
- instructions: 'Base instructions',
116
- additional_instructions: 'Additional instructions',
117
- },
118
- });
119
-
120
- const result = await ctx.systemRunnable!.invoke([]);
121
- expect(result[0].content).toBe(
122
- 'Base instructions\n\nAdditional instructions'
123
- );
124
- });
125
-
126
- it('moves Anthropic dynamic instructions behind stable history', async () => {
127
- const ctx = createBasicContext({
128
- agentConfig: {
129
- provider: Providers.ANTHROPIC,
130
- clientOptions: { model: 'claude-3-5-sonnet', promptCache: true },
131
- instructions: 'Stable instructions',
132
- additional_instructions: 'Dynamic instructions',
133
- },
134
- });
135
-
136
- const result = await ctx.systemRunnable!.invoke([
137
- new HumanMessage('Hello'),
138
- new HumanMessage('Second'),
139
- ]);
140
- const content = result[0].content as TestSystemContentBlock[];
141
- expect(content).toEqual([
142
- {
143
- type: 'text',
144
- text: 'Stable instructions',
145
- cache_control: { type: 'ephemeral', ttl: '1h' },
146
- },
147
- ]);
148
- expect(result[1].content).toBe('Hello');
149
- expect(result[2].content).toBe('Dynamic instructions');
150
- expect(result[3].content).toBe('Second');
151
- });
152
-
153
- it('places Anthropic dynamic instructions before a single latest user prompt', async () => {
154
- const ctx = createBasicContext({
155
- agentConfig: {
156
- provider: Providers.ANTHROPIC,
157
- clientOptions: { model: 'claude-3-5-sonnet', promptCache: true },
158
- instructions: 'Stable instructions',
159
- additional_instructions: 'Dynamic instructions',
160
- },
161
- });
162
-
163
- const result = await ctx.systemRunnable!.invoke([
164
- new HumanMessage('Latest'),
165
- ]);
166
-
167
- expect(result[1].content).toBe('Dynamic instructions');
168
- expect(result[2].content).toBe('Latest');
169
- });
170
-
171
- it('omits Anthropic cache control when only dynamic system text exists', async () => {
172
- const ctx = createBasicContext({
173
- agentConfig: {
174
- provider: Providers.ANTHROPIC,
175
- clientOptions: { model: 'claude-3-5-sonnet', promptCache: true },
176
- instructions: undefined,
177
- additional_instructions: 'Dynamic only',
178
- },
179
- });
180
-
181
- const result = await ctx.systemRunnable!.invoke([]);
182
- const content = result[0].content as TestSystemContentBlock[];
183
- expect(content).toEqual([{ type: 'text', text: 'Dynamic only' }]);
184
- expect(content[0]).not.toHaveProperty('cache_control');
185
- });
186
-
187
- it('keeps cross-run summaries in the dynamic Anthropic tail', async () => {
188
- const ctx = createBasicContext({
189
- agentConfig: {
190
- provider: Providers.ANTHROPIC,
191
- clientOptions: { model: 'claude-3-5-sonnet', promptCache: true },
192
- instructions: 'Stable instructions',
193
- },
194
- });
195
- ctx.setInitialSummary('Prior summary', 13);
196
-
197
- const result = await ctx.systemRunnable!.invoke([]);
198
- const content = result[0].content as TestSystemContentBlock[];
199
- expect(content).toHaveLength(1);
200
- expect(content[0]).toHaveProperty('cache_control');
201
- expect(result[1].content).toBe(
202
- '## Conversation Summary\n\nPrior summary'
203
- );
204
- });
205
-
206
- it('places the Bedrock cache point before dynamic system text', async () => {
207
- const ctx = createBasicContext({
208
- agentConfig: {
209
- provider: Providers.BEDROCK,
210
- clientOptions: {
211
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
212
- promptCache: true,
213
- },
214
- instructions: 'Stable instructions',
215
- additional_instructions: 'Dynamic instructions',
216
- },
217
- });
218
-
219
- const result = await ctx.systemRunnable!.invoke([]);
220
- const content = result[0].content as TestSystemContentBlock[];
221
- expect(content).toEqual([
222
- { type: 'text', text: 'Stable instructions' },
223
- { cachePoint: { type: 'default', ttl: '1h' } },
224
- { type: 'text', text: 'Dynamic instructions' },
225
- ]);
226
- });
227
-
228
- it('uses plain Bedrock system text when only dynamic system text exists', async () => {
229
- const ctx = createBasicContext({
230
- agentConfig: {
231
- provider: Providers.BEDROCK,
232
- clientOptions: {
233
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
234
- promptCache: true,
235
- },
236
- instructions: undefined,
237
- additional_instructions: 'Dynamic only',
238
- },
239
- });
240
-
241
- const result = await ctx.systemRunnable!.invoke([]);
242
- expect(result[0].content).toBe('Dynamic only');
243
- });
244
-
245
- it('keeps non-cache providers as plain system text with promptCache-like options', async () => {
246
- const clientOptions: t.OpenAIClientOptions & { promptCache: true } = {
247
- modelName: 'gpt-4o-mini',
248
- promptCache: true,
249
- };
250
- const ctx = createBasicContext({
251
- agentConfig: {
252
- provider: Providers.OPENAI,
253
- clientOptions,
254
- instructions: 'Stable instructions',
255
- additional_instructions: 'Dynamic instructions',
256
- },
257
- });
258
-
259
- const result = await ctx.systemRunnable!.invoke([]);
260
- expect(result[0].content).toBe(
261
- 'Stable instructions\n\nDynamic instructions'
262
- );
263
- });
264
-
265
- it('moves OpenRouter dynamic instructions behind stable history', async () => {
266
- const ctx = createBasicContext({
267
- agentConfig: {
268
- provider: Providers.OPENROUTER,
269
- clientOptions: {
270
- model: 'anthropic/claude-haiku-4.5',
271
- promptCache: true,
272
- },
273
- instructions: 'Stable instructions',
274
- additional_instructions: 'Dynamic instructions',
275
- },
276
- });
277
-
278
- const result = await ctx.systemRunnable!.invoke([
279
- new HumanMessage('Hello'),
280
- new HumanMessage('Second'),
281
- ]);
282
- const content = result[0].content as TestSystemContentBlock[];
283
- expect(content).toEqual([
284
- {
285
- type: 'text',
286
- text: 'Stable instructions',
287
- cache_control: { type: 'ephemeral', ttl: '1h' },
288
- },
289
- ]);
290
- expect(result[1].content).toBe('Hello');
291
- expect(result[2].content).toBe('Dynamic instructions');
292
- expect(result[3].content).toBe('Second');
293
- });
294
-
295
- it('keeps dynamic-only OpenRouter instructions as system text', async () => {
296
- const tokenCounter = (msg: { content: unknown }): number => {
297
- const content =
298
- typeof msg.content === 'string'
299
- ? msg.content
300
- : JSON.stringify(msg.content);
301
- return content.length;
302
- };
303
- const ctx = createBasicContext({
304
- agentConfig: {
305
- provider: Providers.OPENROUTER,
306
- clientOptions: {
307
- model: 'anthropic/claude-haiku-4.5',
308
- promptCache: true,
309
- },
310
- instructions: undefined,
311
- additional_instructions: 'Dynamic only',
312
- },
313
- tokenCounter,
314
- });
315
-
316
- ctx.initializeSystemRunnable();
317
- const result = await ctx.systemRunnable!.invoke([
318
- new HumanMessage('First'),
319
- new HumanMessage('Second'),
320
- ]);
321
- const secondContent = result[2].content as TestSystemContentBlock[];
322
-
323
- expect(result).toHaveLength(3);
324
- expect(result[0].content).toBe('Dynamic only');
325
- expect(result[1].content).toBe('First');
326
- expect(secondContent[0]).toMatchObject({
327
- type: 'text',
328
- text: 'Second',
329
- cache_control: { type: 'ephemeral' },
330
- });
331
- expect(ctx.systemMessageTokens).toBeGreaterThan(0);
332
- expect(ctx.dynamicInstructionTokens).toBe(0);
333
- expect(ctx.instructionTokens).toBe(ctx.systemMessageTokens);
334
- });
335
-
336
- it('does not cache OpenRouter body messages after dynamic instructions', async () => {
337
- const ctx = createBasicContext({
338
- agentConfig: {
339
- provider: Providers.OPENROUTER,
340
- clientOptions: {
341
- model: 'google/gemini-2.5-flash',
342
- promptCache: true,
343
- },
344
- instructions: 'Stable instructions',
345
- additional_instructions: 'Dynamic instructions',
346
- },
347
- });
348
-
349
- const result = await ctx.systemRunnable!.invoke([
350
- new HumanMessage('First'),
351
- new HumanMessage('Second'),
352
- ]);
353
-
354
- expect(result[1].content).toBe('First');
355
- expect(result[2].content).toBe('Dynamic instructions');
356
- expect(result[3].content).toBe('Second');
357
- });
358
-
359
- it('keeps the first OpenRouter user message before single-turn dynamic instructions', async () => {
360
- const ctx = createBasicContext({
361
- agentConfig: {
362
- provider: Providers.OPENROUTER,
363
- clientOptions: {
364
- model: 'anthropic/claude-haiku-4.5',
365
- promptCache: true,
366
- },
367
- instructions: 'Stable instructions',
368
- additional_instructions: 'Dynamic instructions',
369
- },
370
- });
371
-
372
- const result = await ctx.systemRunnable!.invoke([
373
- new HumanMessage('Latest'),
374
- ]);
375
-
376
- expect(result[1].content).toBe('Latest');
377
- expect(result[2].content).toBe('Dynamic instructions');
378
- });
379
-
380
- it('caches stable Anthropic history before dynamic instructions', async () => {
381
- const ctx = createBasicContext({
382
- agentConfig: {
383
- provider: Providers.ANTHROPIC,
384
- clientOptions: {
385
- model: 'claude-3-5-sonnet',
386
- promptCache: true,
387
- },
388
- instructions: 'Stable instructions',
389
- additional_instructions: 'Dynamic instructions',
390
- },
391
- });
392
-
393
- const result = await ctx.systemRunnable!.invoke([
394
- new HumanMessage('First'),
395
- new AIMessage('Stable assistant history'),
396
- new HumanMessage('Latest'),
397
- ]);
398
- const stableHistory = result[2].content as TestSystemContentBlock[];
399
-
400
- expect(result[1].content).toBe('First');
401
- expect(stableHistory[0]).toMatchObject({
402
- type: 'text',
403
- text: 'Stable assistant history',
404
- cache_control: { type: 'ephemeral' },
405
- });
406
- expect(result[3].content).toBe('Dynamic instructions');
407
- expect(result[4].content).toBe('Latest');
408
- });
409
-
410
- it('keeps Anthropic dynamic instructions attached to the latest user turn during tool follow-up', async () => {
411
- const ctx = createBasicContext({
412
- agentConfig: {
413
- provider: Providers.ANTHROPIC,
414
- clientOptions: {
415
- model: 'claude-3-5-sonnet',
416
- promptCache: true,
417
- },
418
- instructions: 'Stable instructions',
419
- additional_instructions: 'Dynamic instructions',
420
- },
421
- });
422
-
423
- const result = await ctx.systemRunnable!.invoke([
424
- new HumanMessage('Use the tool'),
425
- new AIMessage({
426
- content: '',
427
- tool_calls: [
428
- {
429
- id: 'call_1',
430
- name: 'calculator',
431
- args: { expression: '2+2' },
432
- type: 'tool_call',
433
- },
434
- ],
435
- }),
436
- new ToolMessage({
437
- content: '4',
438
- name: 'calculator',
439
- tool_call_id: 'call_1',
440
- }),
441
- ]);
442
-
443
- expect(result[1].content).toBe('Dynamic instructions');
444
- expect(result[2].content).toBe('Use the tool');
445
- expect((result[3] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
446
- expect(result[4].getType()).toBe('tool');
447
- });
448
-
449
- it('keeps Anthropic stable history cacheable before dynamic tool-follow-up context', async () => {
450
- const ctx = createBasicContext({
451
- agentConfig: {
452
- provider: Providers.ANTHROPIC,
453
- clientOptions: {
454
- model: 'claude-3-5-sonnet',
455
- promptCache: true,
456
- },
457
- instructions: 'Stable instructions',
458
- additional_instructions: 'Dynamic instructions',
459
- },
460
- });
461
-
462
- const result = await ctx.systemRunnable!.invoke([
463
- new HumanMessage('Earlier'),
464
- new AIMessage('Earlier assistant response'),
465
- new HumanMessage('Use the tool'),
466
- new AIMessage({
467
- content: '',
468
- tool_calls: [
469
- {
470
- id: 'call_1',
471
- name: 'calculator',
472
- args: { expression: '2+2' },
473
- type: 'tool_call',
474
- },
475
- ],
476
- }),
477
- new ToolMessage({
478
- content: '4',
479
- name: 'calculator',
480
- tool_call_id: 'call_1',
481
- }),
482
- ]);
483
- const stableAssistant = result[2].content as TestSystemContentBlock[];
484
-
485
- expect(result[1].content).toBe('Earlier');
486
- expect(stableAssistant[0]).toMatchObject({
487
- type: 'text',
488
- text: 'Earlier assistant response',
489
- cache_control: { type: 'ephemeral' },
490
- });
491
- expect(result[3].content).toBe('Dynamic instructions');
492
- expect(result[4].content).toBe('Use the tool');
493
- expect((result[5] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
494
- expect(result[6].getType()).toBe('tool');
495
- });
496
-
497
- it('keeps Anthropic dynamic context on latest no-tool turn after mixed prior turns', async () => {
498
- const ctx = createBasicContext({
499
- agentConfig: {
500
- provider: Providers.ANTHROPIC,
501
- clientOptions: {
502
- model: 'claude-3-5-sonnet',
503
- promptCache: true,
504
- },
505
- instructions: 'Stable instructions',
506
- additional_instructions: 'Dynamic instructions',
507
- },
508
- });
509
-
510
- const result = await ctx.systemRunnable!.invoke([
511
- new HumanMessage('First turn, no tools'),
512
- new AIMessage('First assistant response'),
513
- new HumanMessage('Use the tool'),
514
- new AIMessage({
515
- content: '',
516
- tool_calls: [
517
- {
518
- id: 'call_1',
519
- name: 'calculator',
520
- args: { expression: '2+2' },
521
- type: 'tool_call',
522
- },
523
- ],
524
- }),
525
- new ToolMessage({
526
- content: '4',
527
- name: 'calculator',
528
- tool_call_id: 'call_1',
529
- }),
530
- new AIMessage('4'),
531
- new HumanMessage('Now answer without tools'),
532
- ]);
533
- const firstAssistant = result[2].content as TestSystemContentBlock[];
534
- const toolAnswer = result[6].content as TestSystemContentBlock[];
535
-
536
- expect(result[1].content).toBe('First turn, no tools');
537
- expect(firstAssistant[0]).toMatchObject({
538
- type: 'text',
539
- text: 'First assistant response',
540
- cache_control: { type: 'ephemeral' },
541
- });
542
- expect(result[3].content).toBe('Use the tool');
543
- expect((result[4] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
544
- expect(result[5].getType()).toBe('tool');
545
- expect(toolAnswer[0]).toMatchObject({
546
- type: 'text',
547
- text: '4',
548
- cache_control: { type: 'ephemeral' },
549
- });
550
- expect(result[7].content).toBe('Dynamic instructions');
551
- expect(result[8].content).toBe('Now answer without tools');
552
- });
553
-
554
- it('caches stable OpenRouter history before dynamic instructions', async () => {
555
- const ctx = createBasicContext({
556
- agentConfig: {
557
- provider: Providers.OPENROUTER,
558
- clientOptions: {
559
- model: 'anthropic/claude-haiku-4.5',
560
- promptCache: true,
561
- },
562
- instructions: 'Stable instructions',
563
- additional_instructions: 'Dynamic instructions',
564
- },
565
- });
566
-
567
- const result = await ctx.systemRunnable!.invoke([
568
- new HumanMessage('First'),
569
- new AIMessage('Stable assistant history'),
570
- new HumanMessage('Latest'),
571
- ]);
572
- const stableHistory = result[2].content as TestSystemContentBlock[];
573
-
574
- expect(result[1].content).toBe('First');
575
- expect(stableHistory[0]).toMatchObject({
576
- type: 'text',
577
- text: 'Stable assistant history',
578
- cache_control: { type: 'ephemeral' },
579
- });
580
- expect(result[3].content).toBe('Dynamic instructions');
581
- expect(result[4].content).toBe('Latest');
582
- });
583
-
584
- it('keeps OpenRouter opening user message before dynamic tool-follow-up context', async () => {
585
- const ctx = createBasicContext({
586
- agentConfig: {
587
- provider: Providers.OPENROUTER,
588
- clientOptions: {
589
- model: 'anthropic/claude-haiku-4.5',
590
- promptCache: true,
591
- },
592
- instructions: 'Stable instructions',
593
- additional_instructions: 'Dynamic instructions',
594
- },
595
- });
596
-
597
- const result = await ctx.systemRunnable!.invoke([
598
- new HumanMessage('Use the tool'),
599
- new AIMessage({
600
- content: '',
601
- tool_calls: [
602
- {
603
- id: 'call_1',
604
- name: 'calculator',
605
- args: { expression: '2+2' },
606
- type: 'tool_call',
607
- },
608
- ],
609
- }),
610
- new ToolMessage({
611
- content: '4',
612
- name: 'calculator',
613
- tool_call_id: 'call_1',
614
- }),
615
- ]);
616
-
617
- expect(result[1].content).toBe('Use the tool');
618
- expect(result[2].content).toBe('Dynamic instructions');
619
- expect((result[3] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
620
- expect(result[4].getType()).toBe('tool');
621
- });
622
-
623
- it('keeps OpenRouter stable history cacheable before dynamic tool-follow-up context', async () => {
624
- const ctx = createBasicContext({
625
- agentConfig: {
626
- provider: Providers.OPENROUTER,
627
- clientOptions: {
628
- model: 'anthropic/claude-haiku-4.5',
629
- promptCache: true,
630
- },
631
- instructions: 'Stable instructions',
632
- additional_instructions: 'Dynamic instructions',
633
- },
634
- });
635
-
636
- const result = await ctx.systemRunnable!.invoke([
637
- new HumanMessage('Earlier'),
638
- new AIMessage('Earlier assistant response'),
639
- new HumanMessage('Use the tool'),
640
- new AIMessage({
641
- content: '',
642
- tool_calls: [
643
- {
644
- id: 'call_1',
645
- name: 'calculator',
646
- args: { expression: '2+2' },
647
- type: 'tool_call',
648
- },
649
- ],
650
- }),
651
- new ToolMessage({
652
- content: '4',
653
- name: 'calculator',
654
- tool_call_id: 'call_1',
655
- }),
656
- ]);
657
- const stableAssistant = result[2].content as TestSystemContentBlock[];
658
-
659
- expect(result[1].content).toBe('Earlier');
660
- expect(stableAssistant[0]).toMatchObject({
661
- type: 'text',
662
- text: 'Earlier assistant response',
663
- cache_control: { type: 'ephemeral' },
664
- });
665
- expect(result[3].content).toBe('Dynamic instructions');
666
- expect(result[4].content).toBe('Use the tool');
667
- expect((result[5] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
668
- expect(result[6].getType()).toBe('tool');
669
- });
670
-
671
- it('keeps OpenRouter dynamic context on latest no-tool turn after mixed prior turns', async () => {
672
- const ctx = createBasicContext({
673
- agentConfig: {
674
- provider: Providers.OPENROUTER,
675
- clientOptions: {
676
- model: 'anthropic/claude-haiku-4.5',
677
- promptCache: true,
678
- },
679
- instructions: 'Stable instructions',
680
- additional_instructions: 'Dynamic instructions',
681
- },
682
- });
683
-
684
- const result = await ctx.systemRunnable!.invoke([
685
- new HumanMessage('First turn, no tools'),
686
- new AIMessage('First assistant response'),
687
- new HumanMessage('Use the tool'),
688
- new AIMessage({
689
- content: '',
690
- tool_calls: [
691
- {
692
- id: 'call_1',
693
- name: 'calculator',
694
- args: { expression: '2+2' },
695
- type: 'tool_call',
696
- },
697
- ],
698
- }),
699
- new ToolMessage({
700
- content: '4',
701
- name: 'calculator',
702
- tool_call_id: 'call_1',
703
- }),
704
- new AIMessage('4'),
705
- new HumanMessage('Now answer without tools'),
706
- ]);
707
- const firstAssistant = result[2].content as TestSystemContentBlock[];
708
- const toolAnswer = result[6].content as TestSystemContentBlock[];
709
-
710
- expect(result[1].content).toBe('First turn, no tools');
711
- expect(firstAssistant[0]).toMatchObject({
712
- type: 'text',
713
- text: 'First assistant response',
714
- cache_control: { type: 'ephemeral' },
715
- });
716
- expect(result[3].content).toBe('Use the tool');
717
- expect((result[4] as AIMessage).tool_calls?.[0]?.id).toBe('call_1');
718
- expect(result[5].getType()).toBe('tool');
719
- expect(toolAnswer[0]).toMatchObject({
720
- type: 'text',
721
- text: '4',
722
- cache_control: { type: 'ephemeral' },
723
- });
724
- expect(result[7].content).toBe('Dynamic instructions');
725
- expect(result[8].content).toBe('Now answer without tools');
726
- });
727
-
728
- it('adds a single OpenRouter body cache point on the tail when there is no dynamic tail', async () => {
729
- const ctx = createBasicContext({
730
- agentConfig: {
731
- provider: Providers.OPENROUTER,
732
- clientOptions: {
733
- model: 'google/gemini-3.1-pro-preview',
734
- promptCache: true,
735
- },
736
- instructions: 'Stable instructions',
737
- },
738
- });
739
-
740
- const result = await ctx.systemRunnable!.invoke([
741
- new HumanMessage('First'),
742
- new HumanMessage('Second'),
743
- ]);
744
- const secondContent = result[2].content as TestSystemContentBlock[];
745
- expect(result[1].content).toBe('First');
746
- expect(secondContent[0]).toHaveProperty('cache_control');
747
- });
748
-
749
- it('places OpenRouter user-message summaries after the first stable message', async () => {
750
- const ctx = createBasicContext({
751
- agentConfig: {
752
- provider: Providers.OPENROUTER,
753
- clientOptions: {
754
- model: 'google/gemini-3.1-pro-preview',
755
- promptCache: true,
756
- },
757
- instructions: 'Stable instructions',
758
- },
759
- });
760
- ctx.setSummary('Rotating summary', 7);
761
-
762
- const result = await ctx.systemRunnable!.invoke([
763
- new HumanMessage('First'),
764
- new HumanMessage('Second'),
765
- ]);
766
-
767
- expect(result[1].content).toBe('First');
768
- expect(result[2].content).toContain('Rotating summary');
769
- expect(result[3].content).toBe('Second');
770
- });
771
-
772
- it('preserves the Bedrock system cache point through message cache-control pass', async () => {
773
- const ctx = createBasicContext({
774
- agentConfig: {
775
- provider: Providers.BEDROCK,
776
- clientOptions: {
777
- model: 'anthropic.claude-sonnet-4-5-20250929-v1:0',
778
- promptCache: true,
779
- },
780
- instructions: 'Stable instructions',
781
- additional_instructions: 'Dynamic instructions',
782
- },
783
- });
784
-
785
- const result = await ctx.systemRunnable!.invoke([
786
- new HumanMessage('Hello'),
787
- ]);
788
- // The graph applies the same resolved TTL it stamped on the system
789
- // checkpoint, so the 1h system cachePoint is preserved (normalized to 1h).
790
- const finalMessages = addBedrockCacheControl(result, '1h');
791
- expect(finalMessages[0].content).toEqual([
792
- { type: 'text', text: 'Stable instructions' },
793
- { cachePoint: { type: 'default', ttl: '1h' } },
794
- { type: 'text', text: 'Dynamic instructions' },
795
- ]);
796
- });
797
- });
798
-
799
- describe('System Runnable - Stale Flag', () => {
800
- it('rebuilds when marked stale via markToolsAsDiscovered', () => {
801
- const toolRegistry: t.LCToolRegistry = new Map([
802
- [
803
- 'deferred_tool',
804
- {
805
- name: 'deferred_tool',
806
- description: 'A deferred code-only tool',
807
- allowed_callers: ['code_execution'],
808
- defer_loading: true,
809
- },
810
- ],
811
- ]);
812
-
813
- const ctx = createBasicContext({
814
- agentConfig: { instructions: 'Test', toolRegistry },
815
- });
816
-
817
- const firstRunnable = ctx.systemRunnable;
818
- const hasNew = ctx.markToolsAsDiscovered(['deferred_tool']);
819
- expect(hasNew).toBe(true);
820
-
821
- const secondRunnable = ctx.systemRunnable;
822
- expect(secondRunnable).not.toBe(firstRunnable);
823
- });
824
-
825
- it('does not rebuild when discovering already-known tools', () => {
826
- const toolRegistry: t.LCToolRegistry = new Map([
827
- [
828
- 'tool1',
829
- {
830
- name: 'tool1',
831
- description: 'Tool 1',
832
- allowed_callers: ['code_execution'],
833
- defer_loading: true,
834
- },
835
- ],
836
- ]);
837
-
838
- const ctx = createBasicContext({
839
- agentConfig: { instructions: 'Test', toolRegistry },
840
- });
841
-
842
- ctx.markToolsAsDiscovered(['tool1']);
843
- const firstRunnable = ctx.systemRunnable;
844
-
845
- const hasNew = ctx.markToolsAsDiscovered(['tool1']);
846
- expect(hasNew).toBe(false);
847
-
848
- const secondRunnable = ctx.systemRunnable;
849
- expect(secondRunnable).toBe(firstRunnable);
850
- });
851
- });
852
-
853
- describe('markToolsAsDiscovered', () => {
854
- it('returns true when new tools are discovered', () => {
855
- const ctx = createBasicContext();
856
- const result = ctx.markToolsAsDiscovered(['tool1', 'tool2']);
857
- expect(result).toBe(true);
858
- expect(ctx.discoveredToolNames.has('tool1')).toBe(true);
859
- expect(ctx.discoveredToolNames.has('tool2')).toBe(true);
860
- });
861
-
862
- it('returns false when all tools already discovered', () => {
863
- const ctx = createBasicContext();
864
- ctx.markToolsAsDiscovered(['tool1']);
865
- const result = ctx.markToolsAsDiscovered(['tool1']);
866
- expect(result).toBe(false);
867
- });
868
-
869
- it('returns true if at least one tool is new', () => {
870
- const ctx = createBasicContext();
871
- ctx.markToolsAsDiscovered(['tool1']);
872
- const result = ctx.markToolsAsDiscovered(['tool1', 'tool2']);
873
- expect(result).toBe(true);
874
- expect(ctx.discoveredToolNames.size).toBe(2);
875
- });
876
-
877
- it('handles empty array gracefully', () => {
878
- const ctx = createBasicContext();
879
- const result = ctx.markToolsAsDiscovered([]);
880
- expect(result).toBe(false);
881
- });
882
- });
883
-
884
- describe('buildProgrammaticOnlyToolsInstructions', () => {
885
- it('includes code_execution-only tools in system message', async () => {
886
- const toolRegistry: t.LCToolRegistry = new Map([
887
- [
888
- 'programmatic_tool',
889
- {
890
- name: 'programmatic_tool',
891
- description: 'Only callable via code execution',
892
- allowed_callers: ['code_execution'],
893
- },
894
- ],
895
- ]);
896
-
897
- const ctx = createBasicContext({
898
- agentConfig: {
899
- instructions: 'Base',
900
- toolDefinitions: [{ name: Constants.BASH_PROGRAMMATIC_TOOL_CALLING }],
901
- toolRegistry,
902
- },
903
- });
904
-
905
- const runnable = ctx.systemRunnable;
906
- expect(runnable).toBeDefined();
907
- const result = await runnable!.invoke([]);
908
- expect(result[0].content).toContain('run_tools_with_bash');
909
- expect(result[0].content).not.toContain('run_tools_with_code');
910
- });
911
-
912
- it('uses Python PTC guidance when only run_tools_with_code is available', async () => {
913
- const toolRegistry: t.LCToolRegistry = new Map([
914
- [
915
- 'programmatic_tool',
916
- {
917
- name: 'programmatic_tool',
918
- description: 'Only callable via code execution',
919
- allowed_callers: ['code_execution'],
920
- },
921
- ],
922
- ]);
923
-
924
- const ctx = createBasicContext({
925
- agentConfig: {
926
- instructions: 'Base',
927
- toolDefinitions: [{ name: Constants.PROGRAMMATIC_TOOL_CALLING }],
928
- toolRegistry,
929
- },
930
- });
931
-
932
- const result = await ctx.systemRunnable!.invoke([]);
933
- expect(result[0].content).toContain('run_tools_with_code');
934
- expect(result[0].content).toContain('Python code');
935
- expect(result[0].content).not.toContain('run_tools_with_bash');
936
- });
937
-
938
- it('excludes direct-callable tools from programmatic section', () => {
939
- const toolRegistry: t.LCToolRegistry = new Map([
940
- [
941
- 'direct_tool',
942
- {
943
- name: 'direct_tool',
944
- description: 'Direct callable',
945
- allowed_callers: ['direct'],
946
- },
947
- ],
948
- [
949
- 'both_tool',
950
- {
951
- name: 'both_tool',
952
- description: 'Both direct and code',
953
- allowed_callers: ['direct', 'code_execution'],
954
- },
955
- ],
956
- ]);
957
-
958
- const ctx = createBasicContext({
959
- agentConfig: { instructions: 'Base', toolRegistry },
960
- });
961
-
962
- expect(ctx.systemRunnable).toBeDefined();
963
- });
964
-
965
- it('excludes deferred code_execution-only tools until discovered', () => {
966
- const toolRegistry: t.LCToolRegistry = new Map([
967
- [
968
- 'deferred_code_tool',
969
- {
970
- name: 'deferred_code_tool',
971
- description: 'Deferred and code-only',
972
- allowed_callers: ['code_execution'],
973
- defer_loading: true,
974
- },
975
- ],
976
- [
977
- 'immediate_code_tool',
978
- {
979
- name: 'immediate_code_tool',
980
- description: 'Immediate and code-only',
981
- allowed_callers: ['code_execution'],
982
- defer_loading: false,
983
- },
984
- ],
985
- ]);
986
-
987
- const ctx = createBasicContext({
988
- agentConfig: { instructions: 'Base', toolRegistry },
989
- });
990
-
991
- const firstRunnable = ctx.systemRunnable;
992
- expect(firstRunnable).toBeDefined();
993
-
994
- ctx.markToolsAsDiscovered(['deferred_code_tool']);
995
-
996
- const secondRunnable = ctx.systemRunnable;
997
- expect(secondRunnable).not.toBe(firstRunnable);
998
- });
999
- });
1000
-
1001
- describe('getToolsForBinding', () => {
1002
- it('returns all tools when no toolRegistry', () => {
1003
- const tools = [createMockTool('tool1'), createMockTool('tool2')];
1004
- const ctx = createBasicContext({ agentConfig: { tools } });
1005
- const result = ctx.getToolsForBinding();
1006
- expect(result).toEqual(tools);
1007
- });
1008
-
1009
- it('excludes code_execution-only tools', () => {
1010
- const tools = [
1011
- createMockTool('direct_tool'),
1012
- createMockTool('code_only_tool'),
1013
- ];
1014
- const toolRegistry: t.LCToolRegistry = new Map([
1015
- ['direct_tool', { name: 'direct_tool', allowed_callers: ['direct'] }],
1016
- [
1017
- 'code_only_tool',
1018
- { name: 'code_only_tool', allowed_callers: ['code_execution'] },
1019
- ],
1020
- ]);
1021
-
1022
- const ctx = createBasicContext({ agentConfig: { tools, toolRegistry } });
1023
- const result = ctx.getToolsForBinding();
1024
- expect(result?.length).toBe(1);
1025
- expect((result?.[0] as t.GenericTool).name).toBe('direct_tool');
1026
- });
1027
-
1028
- it('excludes deferred tools until discovered', () => {
1029
- const tools = [
1030
- createMockTool('immediate_tool'),
1031
- createMockTool('deferred_tool'),
1032
- ];
1033
- const toolRegistry: t.LCToolRegistry = new Map([
1034
- [
1035
- 'immediate_tool',
1036
- {
1037
- name: 'immediate_tool',
1038
- allowed_callers: ['direct'],
1039
- defer_loading: false,
1040
- },
1041
- ],
1042
- [
1043
- 'deferred_tool',
1044
- {
1045
- name: 'deferred_tool',
1046
- allowed_callers: ['direct'],
1047
- defer_loading: true,
1048
- },
1049
- ],
1050
- ]);
1051
-
1052
- const ctx = createBasicContext({ agentConfig: { tools, toolRegistry } });
1053
-
1054
- let result = ctx.getToolsForBinding();
1055
- expect(result?.length).toBe(1);
1056
- expect((result?.[0] as t.GenericTool).name).toBe('immediate_tool');
1057
-
1058
- ctx.markToolsAsDiscovered(['deferred_tool']);
1059
- result = ctx.getToolsForBinding();
1060
- expect(result?.length).toBe(2);
1061
- });
1062
-
1063
- it('includes tools with both direct and code_execution callers', () => {
1064
- const tools = [createMockTool('hybrid_tool')];
1065
- const toolRegistry: t.LCToolRegistry = new Map([
1066
- [
1067
- 'hybrid_tool',
1068
- {
1069
- name: 'hybrid_tool',
1070
- allowed_callers: ['direct', 'code_execution'],
1071
- },
1072
- ],
1073
- ]);
1074
-
1075
- const ctx = createBasicContext({ agentConfig: { tools, toolRegistry } });
1076
- const result = ctx.getToolsForBinding();
1077
- expect(result?.length).toBe(1);
1078
- });
1079
-
1080
- it('defaults to direct when allowed_callers not specified', () => {
1081
- const tools = [createMockTool('default_tool')];
1082
- const toolRegistry: t.LCToolRegistry = new Map([
1083
- ['default_tool', { name: 'default_tool' }],
1084
- ]);
1085
-
1086
- const ctx = createBasicContext({ agentConfig: { tools, toolRegistry } });
1087
- const result = ctx.getToolsForBinding();
1088
- expect(result?.length).toBe(1);
1089
- });
1090
- });
1091
-
1092
- describe('Token Accounting', () => {
1093
- const mockTokenCounter = (msg: { content: unknown }): number => {
1094
- const content =
1095
- typeof msg.content === 'string'
1096
- ? msg.content
1097
- : JSON.stringify(msg.content);
1098
- return content.length;
1099
- };
1100
-
1101
- it('counts system message tokens on first access', () => {
1102
- const ctx = createBasicContext({
1103
- agentConfig: { instructions: 'Hello' },
1104
- tokenCounter: mockTokenCounter,
1105
- });
1106
-
1107
- ctx.initializeSystemRunnable();
1108
- expect(ctx.instructionTokens).toBeGreaterThan(0);
1109
- });
1110
-
1111
- it('updates token count when system message changes', () => {
1112
- const toolRegistry: t.LCToolRegistry = new Map([
1113
- [
1114
- 'code_tool',
1115
- {
1116
- name: 'code_tool',
1117
- description: 'A tool with a long description that adds tokens',
1118
- allowed_callers: ['code_execution'],
1119
- defer_loading: true,
1120
- },
1121
- ],
1122
- ]);
1123
-
1124
- const ctx = createBasicContext({
1125
- agentConfig: { instructions: 'Short', toolRegistry },
1126
- tokenCounter: mockTokenCounter,
1127
- });
1128
-
1129
- ctx.initializeSystemRunnable();
1130
- const initialTokens = ctx.instructionTokens;
1131
-
1132
- ctx.markToolsAsDiscovered(['code_tool']);
1133
- void ctx.systemRunnable;
1134
-
1135
- expect(ctx.instructionTokens).toBeGreaterThan(initialTokens);
1136
- });
1137
-
1138
- it('excludes deferred-undiscovered toolDefinitions from toolSchemaTokens', async () => {
1139
- const activeDef: t.LCTool = {
1140
- name: 'active_tool',
1141
- description: 'Always loaded',
1142
- parameters: { type: 'object', properties: {} },
1143
- };
1144
- const deferredDef: t.LCTool = {
1145
- name: 'deferred_tool',
1146
- description: 'Loaded via tool search',
1147
- parameters: { type: 'object', properties: {} },
1148
- defer_loading: true,
1149
- };
1150
-
1151
- const ctxBase = createBasicContext({
1152
- agentConfig: { toolDefinitions: [activeDef] },
1153
- tokenCounter: mockTokenCounter,
1154
- });
1155
- const ctxWithDeferred = createBasicContext({
1156
- agentConfig: { toolDefinitions: [activeDef, deferredDef] },
1157
- tokenCounter: mockTokenCounter,
1158
- });
1159
-
1160
- await ctxBase.tokenCalculationPromise;
1161
- await ctxWithDeferred.tokenCalculationPromise;
1162
-
1163
- expect(ctxWithDeferred.toolSchemaTokens).toBe(ctxBase.toolSchemaTokens);
1164
- });
1165
-
1166
- it('counts OpenRouter dynamic instructions outside the system message', () => {
1167
- const ctx = createBasicContext({
1168
- agentConfig: {
1169
- provider: Providers.OPENROUTER,
1170
- clientOptions: {
1171
- model: 'google/gemini-3.1-pro-preview',
1172
- promptCache: true,
1173
- },
1174
- instructions: 'Stable',
1175
- additional_instructions: 'Dynamic tail',
1176
- },
1177
- tokenCounter: mockTokenCounter,
1178
- });
1179
-
1180
- ctx.initializeSystemRunnable();
1181
-
1182
- expect(ctx.systemMessageTokens).toBeGreaterThan(0);
1183
- expect(ctx.dynamicInstructionTokens).toBeGreaterThan(0);
1184
- expect(ctx.instructionTokens).toBe(
1185
- ctx.systemMessageTokens + ctx.dynamicInstructionTokens
1186
- );
1187
- expect(ctx.getTokenBudgetBreakdown().dynamicInstructionTokens).toBe(
1188
- ctx.dynamicInstructionTokens
1189
- );
1190
- });
1191
-
1192
- it('clears OpenRouter dynamic instruction tokens when no prompt remains', () => {
1193
- const ctx = createBasicContext({
1194
- agentConfig: {
1195
- provider: Providers.OPENROUTER,
1196
- clientOptions: {
1197
- model: 'google/gemini-3.1-pro-preview',
1198
- promptCache: true,
1199
- },
1200
- instructions: 'Stable instructions',
1201
- },
1202
- tokenCounter: mockTokenCounter,
1203
- });
1204
-
1205
- ctx.setInitialSummary('Volatile summary', 8);
1206
- ctx.initializeSystemRunnable();
1207
- expect(ctx.dynamicInstructionTokens).toBeGreaterThan(0);
1208
-
1209
- ctx.instructions = undefined;
1210
- ctx.clearSummary();
1211
- ctx.initializeSystemRunnable();
1212
-
1213
- expect(ctx.systemRunnable).toBeUndefined();
1214
- expect(ctx.systemMessageTokens).toBe(0);
1215
- expect(ctx.dynamicInstructionTokens).toBe(0);
1216
- expect(ctx.instructionTokens).toBe(0);
1217
- });
1218
-
1219
- it('excludes programmatic-only toolDefinitions from toolSchemaTokens', async () => {
1220
- // getEventDrivenToolsForBinding excludes definitions whose
1221
- // allowed_callers omit 'direct'. Accounting must mirror that — a
1222
- // programmatic-only definition is never bound to the model and
1223
- // shouldn't inflate toolSchemaTokens.
1224
- const activeDef: t.LCTool = {
1225
- name: 'active_tool',
1226
- description: 'Always loaded',
1227
- parameters: { type: 'object', properties: {} },
1228
- };
1229
- const programmaticDef: t.LCTool = {
1230
- name: 'programmatic_tool',
1231
- description: 'Only callable via code execution',
1232
- parameters: { type: 'object', properties: {} },
1233
- allowed_callers: ['code_execution'],
1234
- };
1235
-
1236
- const ctxBase = createBasicContext({
1237
- agentConfig: { toolDefinitions: [activeDef] },
1238
- tokenCounter: mockTokenCounter,
1239
- });
1240
- const ctxWithProgrammatic = createBasicContext({
1241
- agentConfig: { toolDefinitions: [activeDef, programmaticDef] },
1242
- tokenCounter: mockTokenCounter,
1243
- });
1244
-
1245
- await ctxBase.tokenCalculationPromise;
1246
- await ctxWithProgrammatic.tokenCalculationPromise;
1247
-
1248
- expect(ctxWithProgrammatic.toolSchemaTokens).toBe(
1249
- ctxBase.toolSchemaTokens
1250
- );
1251
- });
1252
-
1253
- it('excludes deferred-undiscovered instance tools from toolSchemaTokens', async () => {
1254
- const activeTool = createMockTool('active_tool');
1255
- const deferredTool = createMockTool('deferred_tool');
1256
- const programmaticTool = createMockTool('programmatic_tool');
1257
- const toolRegistry: t.LCToolRegistry = new Map([
1258
- ['active_tool', { name: 'active_tool' }],
1259
- ['deferred_tool', { name: 'deferred_tool', defer_loading: true }],
1260
- [
1261
- 'programmatic_tool',
1262
- {
1263
- name: 'programmatic_tool',
1264
- allowed_callers: ['code_execution'],
1265
- },
1266
- ],
1267
- ]);
1268
-
1269
- const ctxBase = createBasicContext({
1270
- agentConfig: { tools: [activeTool], toolRegistry },
1271
- tokenCounter: mockTokenCounter,
1272
- });
1273
- const ctxWithExcluded = createBasicContext({
1274
- agentConfig: {
1275
- tools: [activeTool, deferredTool, programmaticTool],
1276
- toolRegistry,
1277
- },
1278
- tokenCounter: mockTokenCounter,
1279
- });
1280
-
1281
- await ctxBase.tokenCalculationPromise;
1282
- await ctxWithExcluded.tokenCalculationPromise;
1283
-
1284
- expect(ctxWithExcluded.toolSchemaTokens).toBe(ctxBase.toolSchemaTokens);
1285
- });
1286
-
1287
- it('includes deferred instance tools once discovered via discoveredTools input', async () => {
1288
- const tools = [createMockTool('deferred_tool')];
1289
- const toolRegistry: t.LCToolRegistry = new Map([
1290
- ['deferred_tool', { name: 'deferred_tool', defer_loading: true }],
1291
- ]);
1292
-
1293
- const ctxUndiscovered = createBasicContext({
1294
- agentConfig: { tools, toolRegistry },
1295
- tokenCounter: mockTokenCounter,
1296
- });
1297
- const ctxDiscovered = createBasicContext({
1298
- agentConfig: {
1299
- tools,
1300
- toolRegistry,
1301
- discoveredTools: ['deferred_tool'],
1302
- },
1303
- tokenCounter: mockTokenCounter,
1304
- });
1305
-
1306
- await ctxUndiscovered.tokenCalculationPromise;
1307
- await ctxDiscovered.tokenCalculationPromise;
1308
-
1309
- expect(ctxUndiscovered.toolSchemaTokens).toBe(0);
1310
- expect(ctxDiscovered.toolSchemaTokens).toBeGreaterThan(0);
1311
- });
1312
-
1313
- it('does not filter instance tools in event-driven mode (matches getEventDrivenToolsForBinding)', async () => {
1314
- // In event-driven mode, getEventDrivenToolsForBinding appends
1315
- // `this.tools` UNFILTERED. Accounting must do the same — otherwise we
1316
- // under-count and risk exceeding the model's context budget.
1317
- const activeDef: t.LCTool = {
1318
- name: 'active_def',
1319
- description: 'Always loaded',
1320
- parameters: { type: 'object', properties: {} },
1321
- };
1322
- const nativeTool = createMockTool('native_tool');
1323
- // Registry marks the native tool as deferred-undiscovered. In the
1324
- // non-event-driven path this would exclude it; in event-driven mode
1325
- // it is still bound and must still be counted.
1326
- const toolRegistry: t.LCToolRegistry = new Map([
1327
- ['native_tool', { name: 'native_tool', defer_loading: true }],
1328
- ]);
1329
-
1330
- const ctxWithoutNative = createBasicContext({
1331
- agentConfig: {
1332
- toolDefinitions: [activeDef],
1333
- toolRegistry,
1334
- },
1335
- tokenCounter: mockTokenCounter,
1336
- });
1337
- const ctxWithNative = createBasicContext({
1338
- agentConfig: {
1339
- toolDefinitions: [activeDef],
1340
- tools: [nativeTool],
1341
- toolRegistry,
1342
- },
1343
- tokenCounter: mockTokenCounter,
1344
- });
1345
-
1346
- await ctxWithoutNative.tokenCalculationPromise;
1347
- await ctxWithNative.tokenCalculationPromise;
1348
-
1349
- expect(ctxWithNative.toolSchemaTokens).toBeGreaterThan(
1350
- ctxWithoutNative.toolSchemaTokens
1351
- );
1352
- });
1353
-
1354
- it('includes deferred toolDefinitions once discovered via discoveredTools input', async () => {
1355
- const toolDefinitions: t.LCTool[] = [
1356
- {
1357
- name: 'deferred_tool',
1358
- description: 'Loaded via tool search',
1359
- parameters: { type: 'object', properties: {} },
1360
- defer_loading: true,
1361
- },
1362
- ];
1363
-
1364
- const ctxUndiscovered = createBasicContext({
1365
- agentConfig: { toolDefinitions },
1366
- tokenCounter: mockTokenCounter,
1367
- });
1368
- const ctxDiscovered = createBasicContext({
1369
- agentConfig: { toolDefinitions, discoveredTools: ['deferred_tool'] },
1370
- tokenCounter: mockTokenCounter,
1371
- });
1372
-
1373
- await ctxUndiscovered.tokenCalculationPromise;
1374
- await ctxDiscovered.tokenCalculationPromise;
1375
-
1376
- expect(ctxUndiscovered.toolSchemaTokens).toBe(0);
1377
- expect(ctxDiscovered.toolSchemaTokens).toBeGreaterThan(0);
1378
- });
1379
-
1380
- it('getTokenBudgetBreakdown toolCount excludes deferred-undiscovered toolDefinitions', () => {
1381
- const toolDefinitions: t.LCTool[] = [
1382
- {
1383
- name: 'active',
1384
- parameters: { type: 'object', properties: {} },
1385
- },
1386
- {
1387
- name: 'deferred',
1388
- defer_loading: true,
1389
- parameters: { type: 'object', properties: {} },
1390
- },
1391
- ];
1392
-
1393
- const ctx = createBasicContext({ agentConfig: { toolDefinitions } });
1394
-
1395
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(1);
1396
- });
1397
-
1398
- it('getTokenBudgetBreakdown toolCount excludes deferred-undiscovered instance tools', () => {
1399
- // Mirrors the toolDefinitions test for the instance-tools path so
1400
- // toolCount stays aligned with toolSchemaTokens (and with what
1401
- // getToolsForBinding actually emits) for non-event-driven runs.
1402
- const tools = [
1403
- createMockTool('active_tool'),
1404
- createMockTool('deferred_tool'),
1405
- createMockTool('programmatic_tool'),
1406
- ];
1407
- const toolRegistry: t.LCToolRegistry = new Map([
1408
- ['active_tool', { name: 'active_tool' }],
1409
- ['deferred_tool', { name: 'deferred_tool', defer_loading: true }],
1410
- [
1411
- 'programmatic_tool',
1412
- {
1413
- name: 'programmatic_tool',
1414
- allowed_callers: ['code_execution'],
1415
- },
1416
- ],
1417
- ]);
1418
-
1419
- const ctx = createBasicContext({
1420
- agentConfig: { tools, toolRegistry },
1421
- });
1422
-
1423
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(1);
1424
- ctx.markToolsAsDiscovered(['deferred_tool']);
1425
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(2);
1426
- });
1427
-
1428
- it('getTokenBudgetBreakdown toolCount reflects newly discovered deferred tools', () => {
1429
- const toolDefinitions: t.LCTool[] = [
1430
- {
1431
- name: 'deferred',
1432
- defer_loading: true,
1433
- parameters: { type: 'object', properties: {} },
1434
- },
1435
- ];
1436
-
1437
- const ctx = createBasicContext({ agentConfig: { toolDefinitions } });
1438
-
1439
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(0);
1440
- ctx.markToolsAsDiscovered(['deferred']);
1441
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(1);
1442
- });
1443
-
1444
- it('getTokenBudgetBreakdown toolCount includes graphTools', () => {
1445
- // graphTools (handoff/subagent) are bound to the model alongside
1446
- // instance tools. Now that toolCount derives from getToolsForBinding(),
1447
- // graphTools are reflected in the diagnostic just like they're
1448
- // counted in toolSchemaTokens. Locks in that alignment.
1449
- const ctx = createBasicContext({
1450
- agentConfig: { tools: [createMockTool('direct_tool')] },
1451
- });
1452
- ctx.graphTools = [createMockTool('handoff_tool')];
1453
-
1454
- expect(ctx.getTokenBudgetBreakdown().toolCount).toBe(2);
1455
- });
1456
-
1457
- it('refreshes toolSchemaTokens and per-tool counts after markToolsAsDiscovered', async () => {
1458
- const toolDefinitions: t.LCTool[] = [
1459
- {
1460
- name: 'deferred',
1461
- description: 'Loaded via tool search',
1462
- parameters: { type: 'object', properties: {} },
1463
- defer_loading: true,
1464
- },
1465
- ];
1466
-
1467
- const ctx = createBasicContext({
1468
- agentConfig: { toolDefinitions },
1469
- tokenCounter: mockTokenCounter,
1470
- });
1471
-
1472
- await ctx.tokenCalculationPromise;
1473
- expect(ctx.toolSchemaTokens).toBe(0);
1474
- expect(ctx.toolTokenCounts).toEqual({});
1475
-
1476
- ctx.markToolsAsDiscovered(['deferred']);
1477
- await ctx.tokenCalculationPromise;
1478
- expect(ctx.toolSchemaTokens).toBeGreaterThan(0);
1479
- expect(ctx.toolTokenCounts?.deferred).toBeGreaterThan(0);
1480
- expect(ctx.deferredToolNames).toContain('deferred');
1481
- });
1482
- });
1483
-
1484
- describe('reset()', () => {
1485
- it('clears all cached state', () => {
1486
- const ctx = createBasicContext({ agentConfig: { instructions: 'Test' } });
1487
-
1488
- ctx.markToolsAsDiscovered(['tool1']);
1489
- void ctx.systemRunnable;
1490
- ctx.systemMessageTokens = 100;
1491
- ctx.indexTokenCountMap = { '0': 50 };
1492
- ctx.currentUsage = { input_tokens: 100 };
1493
-
1494
- ctx.reset();
1495
-
1496
- expect(ctx.discoveredToolNames.size).toBe(0);
1497
- expect(ctx.instructionTokens).toBe(0);
1498
- expect(ctx.indexTokenCountMap).toEqual({});
1499
- expect(ctx.currentUsage).toBeUndefined();
1500
- });
1501
-
1502
- it('preserves summarization settings across resets', () => {
1503
- const ctx = createBasicContext({
1504
- agentConfig: {
1505
- summarizationEnabled: true,
1506
- summarizationConfig: {
1507
- provider: Providers.ANTHROPIC,
1508
- model: 'claude-sonnet-4-5',
1509
- prompt: 'Keep decisions and next steps concise.',
1510
- trigger: {
1511
- type: 'token_ratio',
1512
- value: 0.8,
1513
- },
1514
- },
1515
- },
1516
- });
1517
-
1518
- ctx.reset();
1519
-
1520
- expect(ctx.summarizationEnabled).toBe(true);
1521
- expect(ctx.summarizationConfig).toEqual({
1522
- provider: 'anthropic',
1523
- model: 'claude-sonnet-4-5',
1524
- prompt: 'Keep decisions and next steps concise.',
1525
- trigger: {
1526
- type: 'token_ratio',
1527
- value: 0.8,
1528
- },
1529
- });
1530
- });
1531
-
1532
- it('shouldSkipSummarization returns true when message count unchanged', () => {
1533
- const ctx = createBasicContext({
1534
- agentConfig: { summarizationEnabled: true },
1535
- });
1536
- ctx.markSummarizationTriggered(10);
1537
- expect(ctx.shouldSkipSummarization(10)).toBe(true);
1538
- });
1539
-
1540
- it('shouldSkipSummarization returns false with any new messages', () => {
1541
- const ctx = createBasicContext({
1542
- agentConfig: { summarizationEnabled: true },
1543
- });
1544
- ctx.markSummarizationTriggered(10);
1545
- expect(ctx.shouldSkipSummarization(11)).toBe(false);
1546
- });
1547
-
1548
- it('shouldSkipSummarization returns false when no prior summarization', () => {
1549
- const ctx = createBasicContext({
1550
- agentConfig: { summarizationEnabled: true },
1551
- });
1552
- expect(ctx.shouldSkipSummarization(5)).toBe(false);
1553
- });
1554
-
1555
- it('shouldSkipSummarization allows unlimited summarizations per run', () => {
1556
- const ctx = createBasicContext({
1557
- agentConfig: { summarizationEnabled: true },
1558
- });
1559
- for (let i = 0; i < 10; i++) {
1560
- ctx.markSummarizationTriggered(i * 5);
1561
- }
1562
- // Even after 10 summarizations, new messages allow another
1563
- expect(ctx.shouldSkipSummarization(50)).toBe(false);
1564
- });
1565
-
1566
- it('rebuilds indexTokenCountMap from base map after reset', async () => {
1567
- const tokenCounter = jest.fn(() => 5);
1568
- const ctx = createBasicContext({
1569
- tokenCounter,
1570
- indexTokenCountMap: { '0': 10, '1': 20 },
1571
- });
1572
-
1573
- await ctx.tokenCalculationPromise;
1574
- ctx.indexTokenCountMap = {};
1575
-
1576
- ctx.reset();
1577
- await ctx.tokenCalculationPromise;
1578
-
1579
- expect(ctx.indexTokenCountMap['1']).toBe(20);
1580
- expect(ctx.indexTokenCountMap['0'] ?? 0).toBeGreaterThanOrEqual(10);
1581
- });
1582
-
1583
- it('forces rebuild on next systemRunnable access', () => {
1584
- const ctx = createBasicContext({ agentConfig: { instructions: 'Test' } });
1585
-
1586
- const firstRunnable = ctx.systemRunnable;
1587
- ctx.reset();
1588
-
1589
- ctx.instructions = 'Test';
1590
- const secondRunnable = ctx.systemRunnable;
1591
-
1592
- expect(secondRunnable).not.toBe(firstRunnable);
1593
- });
1594
- });
1595
-
1596
- describe('initializeSystemRunnable()', () => {
1597
- it('explicitly initializes system runnable', () => {
1598
- const ctx = createBasicContext({ agentConfig: { instructions: 'Test' } });
1599
-
1600
- expect(ctx['cachedSystemRunnable']).toBeUndefined();
1601
- ctx.initializeSystemRunnable();
1602
- expect(ctx['cachedSystemRunnable']).toBeDefined();
1603
- });
1604
-
1605
- it('is idempotent when not stale', () => {
1606
- const ctx = createBasicContext({ agentConfig: { instructions: 'Test' } });
1607
-
1608
- ctx.initializeSystemRunnable();
1609
- const first = ctx['cachedSystemRunnable'];
1610
-
1611
- ctx.initializeSystemRunnable();
1612
- const second = ctx['cachedSystemRunnable'];
1613
-
1614
- expect(first).toBe(second);
1615
- });
1616
- });
1617
-
1618
- describe('Edge Cases', () => {
1619
- it('handles empty toolRegistry gracefully', () => {
1620
- const ctx = createBasicContext({
1621
- agentConfig: {
1622
- instructions: 'Test',
1623
- toolRegistry: new Map(),
1624
- tools: [],
1625
- },
1626
- });
1627
-
1628
- expect(ctx.systemRunnable).toBeDefined();
1629
- expect(ctx.getToolsForBinding()).toEqual([]);
1630
- });
1631
-
1632
- it('handles undefined tools array', () => {
1633
- const ctx = createBasicContext({
1634
- agentConfig: { instructions: 'Test', tools: undefined },
1635
- });
1636
-
1637
- expect(ctx.getToolsForBinding()).toBeUndefined();
1638
- });
1639
-
1640
- it('handles tool not in registry', () => {
1641
- const tools = [createMockTool('unknown_tool')];
1642
- const toolRegistry: t.LCToolRegistry = new Map();
1643
-
1644
- const ctx = createBasicContext({ agentConfig: { tools, toolRegistry } });
1645
- const result = ctx.getToolsForBinding();
1646
-
1647
- expect(result?.length).toBe(1);
1648
- });
1649
-
1650
- it('handles tool without name property', () => {
1651
- const toolWithoutName = { invoke: jest.fn() } as unknown as t.GenericTool;
1652
- const toolRegistry: t.LCToolRegistry = new Map();
1653
-
1654
- const ctx = createBasicContext({
1655
- agentConfig: { tools: [toolWithoutName], toolRegistry },
1656
- });
1657
-
1658
- const result = ctx.getToolsForBinding();
1659
- expect(result?.length).toBe(1);
1660
- });
1661
-
1662
- it('handles discovery of non-existent tool', () => {
1663
- const toolRegistry: t.LCToolRegistry = new Map([
1664
- [
1665
- 'real_tool',
1666
- { name: 'real_tool', allowed_callers: ['code_execution'] },
1667
- ],
1668
- ]);
1669
-
1670
- const ctx = createBasicContext({
1671
- agentConfig: { instructions: 'Test', toolRegistry },
1672
- });
1673
-
1674
- const result = ctx.markToolsAsDiscovered(['fake_tool']);
1675
- expect(result).toBe(true);
1676
- expect(ctx.discoveredToolNames.has('fake_tool')).toBe(true);
1677
- });
1678
- });
1679
-
1680
- describe('Multi-Step Run Flow (emulating createCallModel)', () => {
1681
- /**
1682
- * This test emulates the flow in Graph.createCallModel across multiple turns:
1683
- *
1684
- * Turn 1: User asks a question
1685
- * - No tool search results yet
1686
- * - System runnable built with initial instructions
1687
- * - Token map initialized
1688
- *
1689
- * Turn 2: Tool results come back (including tool search)
1690
- * - extractToolDiscoveries() finds new tools
1691
- * - markToolsAsDiscovered() called → sets stale flag
1692
- * - systemRunnable getter rebuilds with discovered tools
1693
- * - Token counts updated
1694
- *
1695
- * Turn 3: Another turn with same discovered tools
1696
- * - No new discoveries
1697
- * - systemRunnable returns cached (not rebuilt)
1698
- * - Token counts unchanged
1699
- */
1700
-
1701
- const mockTokenCounter = (msg: { content: unknown }): number => {
1702
- const content =
1703
- typeof msg.content === 'string'
1704
- ? msg.content
1705
- : JSON.stringify(msg.content);
1706
- return Math.ceil(content.length / 4); // ~4 chars per token (realistic)
1707
- };
1708
-
1709
- it('handles complete multi-step run with tool discovery', () => {
1710
- // Setup: Tools with different configurations
1711
- const tools = [
1712
- createMockTool('always_available'),
1713
- createMockTool('deferred_direct_tool'),
1714
- createMockTool('deferred_code_tool'),
1715
- ];
1716
-
1717
- const toolRegistry: t.LCToolRegistry = new Map([
1718
- [
1719
- 'always_available',
1720
- {
1721
- name: 'always_available',
1722
- description: 'Always available tool',
1723
- allowed_callers: ['direct'],
1724
- defer_loading: false,
1725
- },
1726
- ],
1727
- [
1728
- 'deferred_direct_tool',
1729
- {
1730
- name: 'deferred_direct_tool',
1731
- description: 'Deferred but direct-callable',
1732
- allowed_callers: ['direct'],
1733
- defer_loading: true,
1734
- },
1735
- ],
1736
- [
1737
- 'deferred_code_tool',
1738
- {
1739
- name: 'deferred_code_tool',
1740
- description:
1741
- 'Deferred and code-execution only - hidden until discovered',
1742
- allowed_callers: ['code_execution'],
1743
- defer_loading: true,
1744
- },
1745
- ],
1746
- ]);
1747
-
1748
- const ctx = createBasicContext({
1749
- agentConfig: {
1750
- instructions: 'You are a helpful assistant.',
1751
- tools,
1752
- toolRegistry,
1753
- },
1754
- tokenCounter: mockTokenCounter,
1755
- });
1756
-
1757
- // ========== TURN 1: Initial call (like first createCallModel) ==========
1758
-
1759
- // In createCallModel, we first check for tool discoveries (none yet)
1760
- const turn1Discoveries: string[] = []; // No tool search results
1761
- if (turn1Discoveries.length > 0) {
1762
- ctx.markToolsAsDiscovered(turn1Discoveries);
1763
- }
1764
-
1765
- // Get tools for binding
1766
- const turn1Tools = ctx.getToolsForBinding();
1767
- expect(turn1Tools?.length).toBe(1); // Only 'always_available'
1768
- expect(turn1Tools?.map((t) => (t as t.GenericTool).name)).toEqual([
1769
- 'always_available',
1770
- ]);
1771
-
1772
- // Access system runnable (triggers lazy build)
1773
- const turn1Runnable = ctx.systemRunnable;
1774
- expect(turn1Runnable).toBeDefined();
1775
-
1776
- // Store initial token count
1777
- const turn1Tokens = ctx.instructionTokens;
1778
- expect(turn1Tokens).toBeGreaterThan(0);
1779
-
1780
- // Simulate token map update (as done in fromConfig flow)
1781
- ctx.updateTokenMapWithInstructions({ '0': 10, '1': 20 });
1782
- expect(ctx.indexTokenCountMap['0']).toBe(10);
1783
- expect(ctx.indexTokenCountMap['1']).toBe(20);
1784
-
1785
- // ========== TURN 2: Tool search results come back ==========
1786
-
1787
- // Simulate tool search discovering tools
1788
- const turn2Discoveries = ['deferred_direct_tool', 'deferred_code_tool'];
1789
- const hasNewDiscoveries = ctx.markToolsAsDiscovered(turn2Discoveries);
1790
- expect(hasNewDiscoveries).toBe(true);
1791
-
1792
- // Get tools for binding - now includes discovered direct tool
1793
- const turn2Tools = ctx.getToolsForBinding();
1794
- expect(turn2Tools?.length).toBe(2); // 'always_available' + 'deferred_direct_tool'
1795
- expect(turn2Tools?.map((t) => (t as t.GenericTool).name)).toContain(
1796
- 'always_available'
1797
- );
1798
- expect(turn2Tools?.map((t) => (t as t.GenericTool).name)).toContain(
1799
- 'deferred_direct_tool'
1800
- );
1801
- // Note: 'deferred_code_tool' is NOT in binding (code_execution only)
1802
-
1803
- // Access system runnable - should rebuild due to stale flag
1804
- const turn2Runnable = ctx.systemRunnable;
1805
- expect(turn2Runnable).not.toBe(turn1Runnable); // Different instance = rebuilt
1806
-
1807
- // Token count should increase (now includes deferred_code_tool in system message)
1808
- const turn2Tokens = ctx.instructionTokens;
1809
- expect(turn2Tokens).toBeGreaterThan(turn1Tokens);
1810
-
1811
- // ========== TURN 3: Another turn, same discoveries ==========
1812
-
1813
- // Same discoveries (duplicates)
1814
- const turn3Discoveries = ['deferred_direct_tool'];
1815
- const hasNewDiscoveriesTurn3 =
1816
- ctx.markToolsAsDiscovered(turn3Discoveries);
1817
- expect(hasNewDiscoveriesTurn3).toBe(false); // No NEW discoveries
1818
-
1819
- // Tools should be same as turn 2
1820
- const turn3Tools = ctx.getToolsForBinding();
1821
- expect(turn3Tools?.length).toBe(2);
1822
-
1823
- // System runnable should be CACHED (same reference)
1824
- const turn3Runnable = ctx.systemRunnable;
1825
- expect(turn3Runnable).toBe(turn2Runnable); // Same instance = cached
1826
-
1827
- // Token count unchanged
1828
- expect(ctx.instructionTokens).toBe(turn2Tokens);
1829
- });
1830
-
1831
- it('maintains consistent indexTokenCountMap across turns', () => {
1832
- const ctx = createBasicContext({
1833
- agentConfig: { instructions: 'Base instructions' },
1834
- tokenCounter: mockTokenCounter,
1835
- });
1836
-
1837
- // Initial setup (simulating fromConfig flow)
1838
- ctx.initializeSystemRunnable();
1839
- const initialSystemTokens = ctx.instructionTokens;
1840
-
1841
- // Simulate message token counts from conversation
1842
- const messageTokenCounts = { '0': 50, '1': 100, '2': 75 };
1843
- ctx.updateTokenMapWithInstructions(messageTokenCounts);
1844
-
1845
- // Verify token map: first message keeps its real token count (no inflation)
1846
- expect(ctx.indexTokenCountMap['0']).toBe(50);
1847
- expect(ctx.indexTokenCountMap['1']).toBe(100);
1848
- expect(ctx.indexTokenCountMap['2']).toBe(75);
1849
-
1850
- // Simulate turn where system message changes
1851
- const toolRegistry: t.LCToolRegistry = new Map([
1852
- [
1853
- 'new_code_tool',
1854
- {
1855
- name: 'new_code_tool',
1856
- description:
1857
- 'A newly discovered code-only tool with detailed documentation',
1858
- allowed_callers: ['code_execution'],
1859
- defer_loading: true,
1860
- },
1861
- ],
1862
- ]);
1863
- ctx.toolRegistry = toolRegistry;
1864
-
1865
- // Discover the tool
1866
- ctx.markToolsAsDiscovered(['new_code_tool']);
1867
-
1868
- // Access system runnable to trigger rebuild
1869
- void ctx.systemRunnable;
1870
-
1871
- // Token count should have increased
1872
- const newSystemTokens = ctx.instructionTokens;
1873
- expect(newSystemTokens).toBeGreaterThan(initialSystemTokens);
1874
-
1875
- // If we update token map again, it should use NEW instruction tokens
1876
- const newMessageTokenCounts = { '0': 60, '1': 110 };
1877
- ctx.updateTokenMapWithInstructions(newMessageTokenCounts);
1878
-
1879
- expect(ctx.indexTokenCountMap['0']).toBe(60);
1880
- expect(ctx.indexTokenCountMap['1']).toBe(110);
1881
- });
1882
-
1883
- it('correctly tracks token delta when system message content changes', () => {
1884
- const toolRegistry: t.LCToolRegistry = new Map([
1885
- [
1886
- 'tool_a',
1887
- {
1888
- name: 'tool_a',
1889
- description: 'Short description',
1890
- allowed_callers: ['code_execution'],
1891
- defer_loading: true,
1892
- },
1893
- ],
1894
- [
1895
- 'tool_b',
1896
- {
1897
- name: 'tool_b',
1898
- description: 'Another tool that adds more content',
1899
- allowed_callers: ['code_execution'],
1900
- defer_loading: true,
1901
- },
1902
- ],
1903
- ]);
1904
-
1905
- const ctx = createBasicContext({
1906
- agentConfig: {
1907
- instructions: 'You are helpful.',
1908
- toolRegistry,
1909
- },
1910
- tokenCounter: mockTokenCounter,
1911
- });
1912
-
1913
- ctx.initializeSystemRunnable();
1914
- const baseTokens = ctx.instructionTokens;
1915
-
1916
- // Discover tool_a
1917
- ctx.markToolsAsDiscovered(['tool_a']);
1918
- void ctx.systemRunnable;
1919
- const tokensAfterA = ctx.instructionTokens;
1920
- expect(tokensAfterA).toBeGreaterThan(baseTokens);
1921
-
1922
- // Discover tool_b - adds more content
1923
- ctx.markToolsAsDiscovered(['tool_b']);
1924
- void ctx.systemRunnable;
1925
- const tokensAfterB = ctx.instructionTokens;
1926
- expect(tokensAfterB).toBeGreaterThan(tokensAfterA);
1927
-
1928
- // Both deltas should be positive (each discovery adds tokens)
1929
- const deltaBaseToA = tokensAfterA - baseTokens;
1930
- const deltaAToB = tokensAfterB - tokensAfterA;
1931
- expect(deltaBaseToA).toBeGreaterThan(0);
1932
- expect(deltaAToB).toBeGreaterThan(0);
1933
- });
1934
-
1935
- it('handles reset between runs correctly', () => {
1936
- const toolRegistry: t.LCToolRegistry = new Map([
1937
- [
1938
- 'discovered_tool',
1939
- {
1940
- name: 'discovered_tool',
1941
- description: 'Will be discovered',
1942
- allowed_callers: ['code_execution'],
1943
- defer_loading: true,
1944
- },
1945
- ],
1946
- ]);
1947
-
1948
- const ctx = createBasicContext({
1949
- agentConfig: {
1950
- instructions: 'Assistant instructions',
1951
- toolRegistry,
1952
- },
1953
- tokenCounter: mockTokenCounter,
1954
- });
1955
-
1956
- // ========== RUN 1 ==========
1957
- ctx.initializeSystemRunnable();
1958
- ctx.markToolsAsDiscovered(['discovered_tool']);
1959
- void ctx.systemRunnable;
1960
-
1961
- expect(ctx.discoveredToolNames.has('discovered_tool')).toBe(true);
1962
- const run1Tokens = ctx.instructionTokens;
1963
- expect(run1Tokens).toBeGreaterThan(0);
1964
-
1965
- // ========== RESET (new run) ==========
1966
- ctx.reset();
1967
-
1968
- // Verify state is cleared
1969
- expect(ctx.discoveredToolNames.size).toBe(0);
1970
- const resetTokens = ctx.instructionTokens;
1971
- expect(resetTokens).toBeGreaterThan(0);
1972
- expect(resetTokens).toBeLessThan(run1Tokens);
1973
-
1974
- // ========== RUN 2 ==========
1975
- // Re-initialize (as fromConfig would do)
1976
- ctx.initializeSystemRunnable();
1977
-
1978
- // System runnable should NOT include the previously discovered tool
1979
- // (because discoveredToolNames was cleared)
1980
- const run2Tokens = ctx.instructionTokens;
1981
- expect(run2Tokens).toBe(resetTokens);
1982
-
1983
- // Token count should be lower than run 1 (no discovered tool in system message)
1984
- expect(run2Tokens).toBeLessThan(run1Tokens);
1985
-
1986
- // Discover again
1987
- ctx.markToolsAsDiscovered(['discovered_tool']);
1988
- void ctx.systemRunnable;
1989
-
1990
- // Now should match run 1
1991
- expect(ctx.instructionTokens).toBe(run1Tokens);
1992
- });
1993
- });
1994
-
1995
- describe('Summary Token Accounting', () => {
1996
- const charTokenCounter: t.TokenCounter = (msg) => {
1997
- const raw = msg.content;
1998
- if (typeof raw === 'string') return raw.length;
1999
- if (Array.isArray(raw)) {
2000
- let total = 0;
2001
- for (let i = 0; i < raw.length; i++) {
2002
- const item = raw[i] as unknown;
2003
- if (typeof item === 'string') {
2004
- total += item.length;
2005
- } else if (
2006
- typeof item === 'object' &&
2007
- item != null &&
2008
- 'text' in item
2009
- ) {
2010
- const text = (item as Record<string, unknown>).text;
2011
- if (typeof text === 'string') total += text.length;
2012
- }
2013
- }
2014
- return total;
2015
- }
2016
- return 0;
2017
- };
2018
-
2019
- it('mid-run setSummary increases instructionTokens by the summary token count', () => {
2020
- const ctx = createBasicContext({
2021
- agentConfig: { instructions: 'Be helpful.' },
2022
- tokenCounter: charTokenCounter,
2023
- });
2024
-
2025
- void ctx.systemRunnable;
2026
- const baseInstructionTokens = ctx.instructionTokens;
2027
- expect(baseInstructionTokens).toBeGreaterThan(0);
2028
-
2029
- // Mid-run summary is injected as HumanMessage but still counts as
2030
- // instruction overhead so the pruner reserves budget for it.
2031
- ctx.setSummary('User asked about math. Key results: 2+2=4, 3*5=15.', 50);
2032
- expect(ctx.hasSummary()).toBe(true);
2033
-
2034
- void ctx.systemRunnable;
2035
- expect(ctx.instructionTokens).toBe(baseInstructionTokens + 50);
2036
- });
2037
-
2038
- it('summary text appears in rebuilt system message', () => {
2039
- const ctx = createBasicContext({
2040
- agentConfig: { instructions: 'Be helpful.' },
2041
- tokenCounter: charTokenCounter,
2042
- });
2043
-
2044
- void ctx.systemRunnable;
2045
- ctx.setSummary('Prior context: user computed factorials.', 40);
2046
-
2047
- const runnable = ctx.systemRunnable;
2048
- expect(runnable).toBeDefined();
2049
- });
2050
-
2051
- it('clearSummary removes summary overhead from instructionTokens', () => {
2052
- const ctx = createBasicContext({
2053
- agentConfig: { instructions: 'Be helpful.' },
2054
- tokenCounter: charTokenCounter,
2055
- });
2056
-
2057
- void ctx.systemRunnable;
2058
- const baseTokens = ctx.instructionTokens;
2059
-
2060
- ctx.setSummary('Summary of the conversation so far.', 35);
2061
- void ctx.systemRunnable;
2062
- expect(ctx.instructionTokens).toBe(baseTokens + 35);
2063
-
2064
- ctx.clearSummary();
2065
- void ctx.systemRunnable;
2066
- expect(ctx.instructionTokens).toBe(baseTokens);
2067
- });
2068
-
2069
- it('reset preserves durable summary and maintains token counts', () => {
2070
- const ctx = createBasicContext({
2071
- agentConfig: { instructions: 'Be helpful.' },
2072
- tokenCounter: charTokenCounter,
2073
- indexTokenCountMap: { '0': 10, '1': 20 },
2074
- });
2075
-
2076
- void ctx.systemRunnable;
2077
- ctx.setSummary('Summary text.', 15);
2078
- void ctx.systemRunnable;
2079
- expect(ctx.hasSummary()).toBe(true);
2080
- const tokensWithSummary = ctx.instructionTokens;
2081
-
2082
- ctx.reset();
2083
- // Summary should survive reset (durable cross-run state)
2084
- expect(ctx.hasSummary()).toBe(true);
2085
- expect(ctx.getSummaryText()).toBe('Summary text.');
2086
-
2087
- void ctx.systemRunnable;
2088
- const postResetTokens = ctx.instructionTokens;
2089
- expect(postResetTokens).toBeGreaterThan(0);
2090
- // Token count should be the same since summary is preserved
2091
- expect(postResetTokens).toBe(tokensWithSummary);
2092
- });
2093
-
2094
- it('updateTokenMapWithInstructions copies base map without inflating index 0', () => {
2095
- const ctx = createBasicContext({
2096
- agentConfig: { instructions: 'Be helpful.' },
2097
- tokenCounter: charTokenCounter,
2098
- });
2099
-
2100
- void ctx.systemRunnable;
2101
- ctx.setSummary('Summary of prior context with key facts.', 40);
2102
- void ctx.systemRunnable;
2103
-
2104
- const instructionTokens = ctx.instructionTokens;
2105
- expect(instructionTokens).toBeGreaterThan(0);
2106
-
2107
- const baseMap: Record<string, number> = { '0': 5, '1': 10 };
2108
- ctx.updateTokenMapWithInstructions(baseMap);
2109
-
2110
- // Index 0 should contain the real message token count, NOT inflated
2111
- // with instruction tokens. Instruction overhead is now handled by
2112
- // getInstructionTokens() in the pruning factory.
2113
- expect(ctx.indexTokenCountMap['0']).toBe(5);
2114
- expect(ctx.indexTokenCountMap['1']).toBe(10);
2115
- });
2116
-
2117
- it('hasSummary returns false before setSummary and true after', () => {
2118
- const ctx = createBasicContext({
2119
- agentConfig: { instructions: 'Be helpful.' },
2120
- });
2121
-
2122
- expect(ctx.hasSummary()).toBe(false);
2123
- ctx.setSummary('Some summary.', 10);
2124
- expect(ctx.hasSummary()).toBe(true);
2125
- ctx.clearSummary();
2126
- expect(ctx.hasSummary()).toBe(false);
2127
- });
2128
- });
2129
-
2130
- describe('shouldSkipSummarization — re-trigger after summary', () => {
2131
- it('allows re-summarization after rebuildTokenMapAfterSummarization resets baseline', () => {
2132
- const ctx = createBasicContext();
2133
-
2134
- expect(ctx.shouldSkipSummarization(25)).toBe(false);
2135
- ctx.markSummarizationTriggered(25);
2136
-
2137
- // Same count — skip
2138
- expect(ctx.shouldSkipSummarization(25)).toBe(true);
2139
-
2140
- ctx.setSummary('Summary of conversation', 100);
2141
- // Full compaction: empty state, baseline resets to 0
2142
- ctx.rebuildTokenMapAfterSummarization({});
2143
-
2144
- // Baseline is 0 after full compaction. Guard `_lastSummarizationMsgCount > 0`
2145
- // is false, so all counts are allowed.
2146
- expect(ctx.shouldSkipSummarization(0)).toBe(false);
2147
- expect(ctx.shouldSkipSummarization(1)).toBe(false);
2148
- });
2149
-
2150
- it('allows summarization after full compaction resets to empty state', () => {
2151
- const ctx = createBasicContext();
2152
-
2153
- ctx.markSummarizationTriggered(20);
2154
- ctx.setSummary('Summary', 50);
2155
- ctx.rebuildTokenMapAfterSummarization({});
2156
-
2157
- // Baseline is 0 after full compaction. The guard `_lastSummarizationMsgCount > 0`
2158
- // is false, so summarization is always allowed — the model starts fresh.
2159
- expect(ctx.shouldSkipSummarization(0)).toBe(false);
2160
- expect(ctx.shouldSkipSummarization(1)).toBe(false);
2161
- });
2162
- });
2163
-
2164
- describe('updateLastCallUsage', () => {
2165
- it('records usage without modifying toolSchemaTokens', () => {
2166
- const ctx = createBasicContext();
2167
- ctx.toolSchemaTokens = 200;
2168
-
2169
- ctx.updateLastCallUsage({ input_tokens: 500, output_tokens: 30 });
2170
-
2171
- expect(ctx.lastCallUsage).toBeDefined();
2172
- expect(ctx.lastCallUsage!.inputTokens).toBe(500);
2173
- expect(ctx.lastCallUsage!.outputTokens).toBe(30);
2174
- expect(ctx.toolSchemaTokens).toBe(200);
2175
- });
2176
-
2177
- it('handles additive cache tokens', () => {
2178
- const ctx = createBasicContext();
2179
-
2180
- ctx.updateLastCallUsage({
2181
- input_tokens: 5,
2182
- output_tokens: 100,
2183
- input_token_details: { cache_creation: 8000, cache_read: 0 },
2184
- });
2185
-
2186
- // cache_creation (8000) > input_tokens (5) → additive
2187
- expect(ctx.lastCallUsage!.inputTokens).toBe(8005);
2188
- });
2189
- });
2190
-
2191
- describe('projectContextUsage', () => {
2192
- const countByChars = (msg: { content: unknown }): number => {
2193
- const content =
2194
- typeof msg.content === 'string'
2195
- ? msg.content
2196
- : JSON.stringify(msg.content);
2197
- return content.length;
2198
- };
2199
-
2200
- const buildBranch = (
2201
- maxContextTokens: number,
2202
- perMessageTokens: number,
2203
- count: number
2204
- ): { ctx: AgentContext; messages: AIMessage[] } => {
2205
- const ctx = createBasicContext({ tokenCounter: countByChars });
2206
- ctx.maxContextTokens = maxContextTokens;
2207
- const messages: AIMessage[] = [];
2208
- for (let i = 0; i < count; i++) {
2209
- // countByChars counts content length, and projectContextUsage recounts
2210
- // the supplied messages — so size content to the intended per-msg tokens.
2211
- const content = 'x'.repeat(perMessageTokens);
2212
- messages.push(
2213
- i % 2 === 0
2214
- ? (new HumanMessage(content) as unknown as AIMessage)
2215
- : new AIMessage(content)
2216
- );
2217
- }
2218
- return { ctx, messages };
2219
- };
2220
-
2221
- it('returns null without a tokenizer or a window', () => {
2222
- const noCounter = createBasicContext({});
2223
- noCounter.maxContextTokens = 1000;
2224
- expect(
2225
- noCounter.projectContextUsage([new HumanMessage('hi')])
2226
- ).toBeNull();
2227
-
2228
- const noWindow = createBasicContext({ tokenCounter: countByChars });
2229
- noWindow.maxContextTokens = undefined;
2230
- expect(noWindow.projectContextUsage([new HumanMessage('hi')])).toBeNull();
2231
- });
2232
-
2233
- it('keeps the whole branch and reports headroom when it fits', () => {
2234
- const { ctx, messages } = buildBranch(100_000, 1_000, 4);
2235
- const usage = ctx.projectContextUsage(messages);
2236
-
2237
- expect(usage).not.toBeNull();
2238
- expect(usage!.breakdown.messageCount).toBe(4);
2239
- expect(usage!.breakdown.maxContextTokens).toBe(100_000);
2240
- expect(usage!.remainingContextTokens).toBeGreaterThan(0);
2241
- expect(usage!.breakdown.messageTokens).toBeGreaterThan(0);
2242
-
2243
- const max = usage!.contextBudget ?? usage!.breakdown.maxContextTokens;
2244
- const used = max - (usage!.remainingContextTokens ?? 0);
2245
- expect(used).toBeLessThanOrEqual(max);
2246
- });
2247
-
2248
- it('prunes older messages when the branch exceeds the window', () => {
2249
- const { ctx, messages } = buildBranch(3_000, 1_000, 6);
2250
- const usage = ctx.projectContextUsage(messages);
2251
-
2252
- expect(usage).not.toBeNull();
2253
- expect(usage!.breakdown.messageCount).toBeGreaterThan(0);
2254
- expect(usage!.breakdown.messageCount).toBeLessThan(6);
2255
- expect(usage!.remainingContextTokens).toBeGreaterThanOrEqual(0);
2256
-
2257
- const max = usage!.contextBudget ?? usage!.breakdown.maxContextTokens;
2258
- expect(max - (usage!.remainingContextTokens ?? 0)).toBeLessThanOrEqual(
2259
- max
2260
- );
2261
- });
2262
-
2263
- it('does not mutate the context (local pruner, no field writes)', () => {
2264
- const { ctx, messages } = buildBranch(3_000, 1_000, 6);
2265
- const mapBefore = { ...ctx.indexTokenCountMap };
2266
-
2267
- expect(ctx.pruneMessages).toBeUndefined();
2268
- ctx.projectContextUsage(messages);
2269
-
2270
- expect(ctx.pruneMessages).toBeUndefined();
2271
- expect(ctx.indexTokenCountMap).toEqual(mapBefore);
2272
- });
2273
-
2274
- it('does not mutate the caller messages under context pressure', () => {
2275
- const ctx = createBasicContext({ tokenCounter: countByChars });
2276
- ctx.maxContextTokens = 400;
2277
- const consumed = new ToolMessage({
2278
- content: 'x'.repeat(20_000),
2279
- tool_call_id: 't1',
2280
- name: 'tool',
2281
- });
2282
- const messages: AIMessage[] = [
2283
- new HumanMessage('question') as unknown as AIMessage,
2284
- new AIMessage({
2285
- content: '',
2286
- tool_calls: [{ id: 't1', name: 'tool', args: {} }],
2287
- }),
2288
- consumed as unknown as AIMessage,
2289
- new AIMessage('final answer'),
2290
- ];
2291
- const originalRef = messages[2];
2292
- const originalContent = (messages[2] as unknown as ToolMessage).content;
2293
-
2294
- ctx.projectContextUsage(messages);
2295
-
2296
- expect(messages[2]).toBe(originalRef);
2297
- expect((messages[2] as unknown as ToolMessage).content).toBe(
2298
- originalContent
2299
- );
2300
- });
2301
-
2302
- it('recounts the supplied branch, ignoring a stale context token map', () => {
2303
- const ctx = createBasicContext({ tokenCounter: countByChars });
2304
- ctx.maxContextTokens = 3_000;
2305
- // Empty/stale map — if it were reused, every message would count as 0 and
2306
- // nothing would prune. The fresh recount must drive pruning instead.
2307
- ctx.indexTokenCountMap = {};
2308
- const messages: AIMessage[] = [];
2309
- for (let i = 0; i < 6; i++) {
2310
- messages.push(
2311
- new HumanMessage('x'.repeat(1_000)) as unknown as AIMessage
2312
- );
2313
- }
2314
-
2315
- const usage = ctx.projectContextUsage(messages);
2316
-
2317
- expect(usage).not.toBeNull();
2318
- expect(usage!.breakdown.messageCount).toBeLessThan(6);
2319
- });
2320
-
2321
- it('uses a caller-supplied token map when provided', () => {
2322
- const { ctx, messages } = buildBranch(3_000, 1, 6);
2323
- // Each message is ~1 char, so a recount would fit all 6. The supplied map
2324
- // claims 1000 each, forcing a prune — proving the map is honored.
2325
- const indexTokenCountMap: Record<string, number> = {};
2326
- for (let i = 0; i < messages.length; i++) {
2327
- indexTokenCountMap[String(i)] = 1_000;
2328
- }
2329
-
2330
- const usage = ctx.projectContextUsage(messages, { indexTokenCountMap });
2331
-
2332
- expect(usage!.breakdown.messageCount).toBeLessThan(6);
2333
- });
2334
-
2335
- it('ignores this context live usage so projections are not recalibrated', () => {
2336
- const build = (): { ctx: AgentContext; messages: AIMessage[] } => {
2337
- const ctx = createBasicContext({ tokenCounter: countByChars });
2338
- ctx.maxContextTokens = 5_000;
2339
- const messages: AIMessage[] = [0, 1, 2].map(
2340
- () => new HumanMessage('x'.repeat(1_000)) as unknown as AIMessage
2341
- );
2342
- return { ctx, messages };
2343
- };
2344
-
2345
- const clean = build();
2346
- const cleanUsage = clean.ctx.projectContextUsage(clean.messages);
2347
-
2348
- const dirty = build();
2349
- dirty.ctx.currentUsage = {
2350
- input_tokens: 4_000,
2351
- output_tokens: 50,
2352
- total_tokens: 4_050,
2353
- };
2354
- dirty.ctx.updateLastCallUsage({ input_tokens: 4_000, output_tokens: 50 });
2355
- const dirtyUsage = dirty.ctx.projectContextUsage(dirty.messages);
2356
-
2357
- expect(dirtyUsage!.remainingContextTokens).toBe(
2358
- cleanUsage!.remainingContextTokens
2359
- );
2360
- expect(dirtyUsage!.calibrationRatio).toBe(cleanUsage!.calibrationRatio);
2361
- });
2362
-
2363
- it('does not mutate AI message content arrays during projection', () => {
2364
- const ctx = createBasicContext({
2365
- agentConfig: {
2366
- provider: Providers.ANTHROPIC,
2367
- clientOptions: {
2368
- model: 'claude-x',
2369
- thinking: { type: 'enabled', budget_tokens: 1024 },
2370
- } as never,
2371
- },
2372
- tokenCounter: countByChars,
2373
- });
2374
- ctx.maxContextTokens = 2_000;
2375
- const aiContent = [
2376
- { type: 'thinking', thinking: 'step by step', signature: 'sig' },
2377
- { type: 'text', text: 'the answer' },
2378
- ];
2379
- const ai = new AIMessage({ content: aiContent as never });
2380
- const messages: AIMessage[] = [
2381
- new HumanMessage('question') as unknown as AIMessage,
2382
- ai,
2383
- new HumanMessage('another') as unknown as AIMessage,
2384
- ];
2385
- const contentRef = ai.content;
2386
- const lenBefore = (ai.content as unknown[]).length;
2387
-
2388
- ctx.projectContextUsage(messages);
2389
-
2390
- expect(messages[1].content).toBe(contentRef);
2391
- expect((messages[1].content as unknown[]).length).toBe(lenBefore);
2392
- });
2393
-
2394
- it('honors an explicit calibrationRatio seed', () => {
2395
- const base = buildBranch(100_000, 1_000, 4);
2396
- const baseUsage = base.ctx.projectContextUsage(base.messages);
2397
-
2398
- const scaled = buildBranch(100_000, 1_000, 4);
2399
- const scaledUsage = scaled.ctx.projectContextUsage(scaled.messages, {
2400
- calibrationRatio: 3,
2401
- });
2402
-
2403
- expect(scaledUsage!.calibrationRatio).toBe(3);
2404
- expect(scaledUsage!.remainingContextTokens).not.toBe(
2405
- baseUsage!.remainingContextTokens
2406
- );
2407
- });
2408
-
2409
- it('refreshes a stale system runnable before projecting', () => {
2410
- const ctx = createBasicContext({
2411
- agentConfig: { instructions: 'system prompt' },
2412
- tokenCounter: countByChars,
2413
- });
2414
- ctx.maxContextTokens = 5_000;
2415
- ctx.initializeSystemRunnable();
2416
- const systemBefore = ctx.systemMessageTokens;
2417
-
2418
- // Adds a handoff preamble + marks stale, but defers the token recount.
2419
- ctx.setHandoffContext('PriorAgent', ['SiblingA', 'SiblingB']);
2420
- ctx.projectContextUsage([new HumanMessage('hi') as unknown as AIMessage]);
2421
-
2422
- expect(ctx.systemMessageTokens).toBeGreaterThan(systemBefore);
2423
- });
2424
- });
2425
- });