@illuma-ai/agents 1.0.90 → 1.0.94

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 (839) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +98 -49
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/constants.cjs +25 -0
  4. package/dist/cjs/common/constants.cjs.map +1 -0
  5. package/dist/cjs/common/enum.cjs +30 -0
  6. package/dist/cjs/common/enum.cjs.map +1 -1
  7. package/dist/cjs/events.cjs +9 -4
  8. package/dist/cjs/events.cjs.map +1 -1
  9. package/dist/cjs/graphs/Graph.cjs +397 -92
  10. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  11. package/dist/cjs/graphs/MultiAgentGraph.cjs +223 -92
  12. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  13. package/dist/cjs/instrumentation.cjs +30 -14
  14. package/dist/cjs/instrumentation.cjs.map +1 -1
  15. package/dist/cjs/llm/anthropic/index.cjs +43 -11
  16. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  17. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +10 -7
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +32 -0
  21. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  22. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  23. package/dist/cjs/llm/bedrock/index.cjs +129 -101
  24. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  25. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +489 -0
  26. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -0
  27. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +176 -0
  28. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -0
  29. package/dist/cjs/llm/fake.cjs.map +1 -1
  30. package/dist/cjs/llm/google/index.cjs.map +1 -1
  31. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  32. package/dist/cjs/llm/openai/index.cjs +1 -1
  33. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  34. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  35. package/dist/cjs/llm/openrouter/index.cjs +59 -5
  36. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  37. package/dist/cjs/llm/providers.cjs.map +1 -1
  38. package/dist/cjs/llm/text.cjs.map +1 -1
  39. package/dist/cjs/llm/vertexai/index.cjs +80 -2
  40. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  41. package/dist/cjs/main.cjs +60 -27
  42. package/dist/cjs/main.cjs.map +1 -1
  43. package/dist/cjs/messages/cache.cjs +131 -108
  44. package/dist/cjs/messages/cache.cjs.map +1 -1
  45. package/dist/cjs/messages/content.cjs.map +1 -1
  46. package/dist/cjs/messages/core.cjs +3 -0
  47. package/dist/cjs/messages/core.cjs.map +1 -1
  48. package/dist/cjs/messages/format.cjs +265 -47
  49. package/dist/cjs/messages/format.cjs.map +1 -1
  50. package/dist/cjs/messages/ids.cjs.map +1 -1
  51. package/dist/cjs/messages/prune.cjs +55 -2
  52. package/dist/cjs/messages/prune.cjs.map +1 -1
  53. package/dist/cjs/messages/summarize.cjs +170 -0
  54. package/dist/cjs/messages/summarize.cjs.map +1 -0
  55. package/dist/cjs/messages/tools.cjs.map +1 -1
  56. package/dist/cjs/run.cjs +87 -30
  57. package/dist/cjs/run.cjs.map +1 -1
  58. package/dist/cjs/schemas/validate.cjs.map +1 -1
  59. package/dist/cjs/splitStream.cjs.map +1 -1
  60. package/dist/cjs/stream.cjs +59 -25
  61. package/dist/cjs/stream.cjs.map +1 -1
  62. package/dist/cjs/tools/AskUser.cjs +131 -0
  63. package/dist/cjs/tools/AskUser.cjs.map +1 -0
  64. package/dist/cjs/tools/BrowserTools.cjs +11 -7
  65. package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
  66. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  67. package/dist/cjs/tools/CodeExecutor.cjs +60 -5
  68. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  69. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +36 -53
  70. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  71. package/dist/cjs/tools/StreamingToolCallBuffer.cjs +208 -0
  72. package/dist/cjs/tools/StreamingToolCallBuffer.cjs.map +1 -0
  73. package/dist/cjs/tools/ToolNode.cjs +333 -30
  74. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  75. package/dist/cjs/tools/ToolSearch.cjs +66 -30
  76. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  77. package/dist/cjs/tools/handlers.cjs +94 -8
  78. package/dist/cjs/tools/handlers.cjs.map +1 -1
  79. package/dist/cjs/tools/schema.cjs.map +1 -1
  80. package/dist/cjs/tools/search/content.cjs.map +1 -1
  81. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  82. package/dist/cjs/tools/search/format.cjs.map +1 -1
  83. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  84. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  85. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  86. package/dist/cjs/tools/search/search.cjs +1 -0
  87. package/dist/cjs/tools/search/search.cjs.map +1 -1
  88. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  89. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  90. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  91. package/dist/cjs/types/graph.cjs +1 -1
  92. package/dist/cjs/types/graph.cjs.map +1 -1
  93. package/dist/cjs/utils/contextAnalytics.cjs +23 -6
  94. package/dist/cjs/utils/contextAnalytics.cjs.map +1 -1
  95. package/dist/cjs/utils/events.cjs.map +1 -1
  96. package/dist/cjs/utils/graph.cjs.map +1 -1
  97. package/dist/cjs/utils/handlers.cjs.map +1 -1
  98. package/dist/cjs/utils/llm.cjs.map +1 -1
  99. package/dist/cjs/utils/misc.cjs.map +1 -1
  100. package/dist/cjs/utils/run.cjs +3 -1
  101. package/dist/cjs/utils/run.cjs.map +1 -1
  102. package/dist/cjs/utils/schema.cjs.map +1 -1
  103. package/dist/cjs/utils/title.cjs.map +1 -1
  104. package/dist/cjs/utils/tokens.cjs +33 -58
  105. package/dist/cjs/utils/tokens.cjs.map +1 -1
  106. package/dist/cjs/utils/toolCallContinuation.cjs +55 -0
  107. package/dist/cjs/utils/toolCallContinuation.cjs.map +1 -0
  108. package/dist/cjs/utils/toonFormat.cjs.map +1 -1
  109. package/dist/esm/agents/AgentContext.mjs +98 -49
  110. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  111. package/dist/esm/common/constants.mjs +22 -0
  112. package/dist/esm/common/constants.mjs.map +1 -0
  113. package/dist/esm/common/enum.mjs +31 -1
  114. package/dist/esm/common/enum.mjs.map +1 -1
  115. package/dist/esm/events.mjs +9 -4
  116. package/dist/esm/events.mjs.map +1 -1
  117. package/dist/esm/graphs/Graph.mjs +393 -88
  118. package/dist/esm/graphs/Graph.mjs.map +1 -1
  119. package/dist/esm/graphs/MultiAgentGraph.mjs +224 -93
  120. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  121. package/dist/esm/instrumentation.mjs +30 -14
  122. package/dist/esm/instrumentation.mjs.map +1 -1
  123. package/dist/esm/llm/anthropic/index.mjs +43 -11
  124. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  125. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  126. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +10 -7
  127. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  128. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +32 -0
  129. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  130. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  131. package/dist/esm/llm/bedrock/index.mjs +128 -101
  132. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  133. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +484 -0
  134. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -0
  135. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +171 -0
  136. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -0
  137. package/dist/esm/llm/fake.mjs.map +1 -1
  138. package/dist/esm/llm/google/index.mjs.map +1 -1
  139. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  140. package/dist/esm/llm/openai/index.mjs +1 -1
  141. package/dist/esm/llm/openai/index.mjs.map +1 -1
  142. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  143. package/dist/esm/llm/openrouter/index.mjs +59 -5
  144. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  145. package/dist/esm/llm/providers.mjs.map +1 -1
  146. package/dist/esm/llm/text.mjs.map +1 -1
  147. package/dist/esm/llm/vertexai/index.mjs +80 -2
  148. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  149. package/dist/esm/main.mjs +8 -3
  150. package/dist/esm/main.mjs.map +1 -1
  151. package/dist/esm/messages/cache.mjs +131 -108
  152. package/dist/esm/messages/cache.mjs.map +1 -1
  153. package/dist/esm/messages/content.mjs.map +1 -1
  154. package/dist/esm/messages/core.mjs +4 -1
  155. package/dist/esm/messages/core.mjs.map +1 -1
  156. package/dist/esm/messages/format.mjs +267 -49
  157. package/dist/esm/messages/format.mjs.map +1 -1
  158. package/dist/esm/messages/ids.mjs.map +1 -1
  159. package/dist/esm/messages/prune.mjs +56 -4
  160. package/dist/esm/messages/prune.mjs.map +1 -1
  161. package/dist/esm/messages/summarize.mjs +161 -0
  162. package/dist/esm/messages/summarize.mjs.map +1 -0
  163. package/dist/esm/messages/tools.mjs.map +1 -1
  164. package/dist/esm/run.mjs +88 -31
  165. package/dist/esm/run.mjs.map +1 -1
  166. package/dist/esm/schemas/validate.mjs.map +1 -1
  167. package/dist/esm/splitStream.mjs.map +1 -1
  168. package/dist/esm/stream.mjs +60 -26
  169. package/dist/esm/stream.mjs.map +1 -1
  170. package/dist/esm/tools/AskUser.mjs +125 -0
  171. package/dist/esm/tools/AskUser.mjs.map +1 -0
  172. package/dist/esm/tools/BrowserTools.mjs +11 -7
  173. package/dist/esm/tools/BrowserTools.mjs.map +1 -1
  174. package/dist/esm/tools/Calculator.mjs.map +1 -1
  175. package/dist/esm/tools/CodeExecutor.mjs +60 -5
  176. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  177. package/dist/esm/tools/ProgrammaticToolCalling.mjs +37 -54
  178. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  179. package/dist/esm/tools/StreamingToolCallBuffer.mjs +206 -0
  180. package/dist/esm/tools/StreamingToolCallBuffer.mjs.map +1 -0
  181. package/dist/esm/tools/ToolNode.mjs +333 -30
  182. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  183. package/dist/esm/tools/ToolSearch.mjs +66 -30
  184. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  185. package/dist/esm/tools/handlers.mjs +95 -9
  186. package/dist/esm/tools/handlers.mjs.map +1 -1
  187. package/dist/esm/tools/schema.mjs.map +1 -1
  188. package/dist/esm/tools/search/content.mjs.map +1 -1
  189. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  190. package/dist/esm/tools/search/format.mjs.map +1 -1
  191. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  192. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  193. package/dist/esm/tools/search/schema.mjs.map +1 -1
  194. package/dist/esm/tools/search/search.mjs +1 -0
  195. package/dist/esm/tools/search/search.mjs.map +1 -1
  196. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  197. package/dist/esm/tools/search/tool.mjs.map +1 -1
  198. package/dist/esm/tools/search/utils.mjs.map +1 -1
  199. package/dist/esm/types/graph.mjs +1 -1
  200. package/dist/esm/types/graph.mjs.map +1 -1
  201. package/dist/esm/utils/contextAnalytics.mjs +23 -6
  202. package/dist/esm/utils/contextAnalytics.mjs.map +1 -1
  203. package/dist/esm/utils/events.mjs.map +1 -1
  204. package/dist/esm/utils/graph.mjs.map +1 -1
  205. package/dist/esm/utils/handlers.mjs.map +1 -1
  206. package/dist/esm/utils/llm.mjs.map +1 -1
  207. package/dist/esm/utils/misc.mjs.map +1 -1
  208. package/dist/esm/utils/run.mjs +3 -1
  209. package/dist/esm/utils/run.mjs.map +1 -1
  210. package/dist/esm/utils/schema.mjs.map +1 -1
  211. package/dist/esm/utils/title.mjs.map +1 -1
  212. package/dist/esm/utils/tokens.mjs +33 -59
  213. package/dist/esm/utils/tokens.mjs.map +1 -1
  214. package/dist/esm/utils/toolCallContinuation.mjs +52 -0
  215. package/dist/esm/utils/toolCallContinuation.mjs.map +1 -0
  216. package/dist/esm/utils/toonFormat.mjs.map +1 -1
  217. package/dist/types/agents/AgentContext.d.ts +14 -7
  218. package/dist/types/common/constants.d.ts +18 -0
  219. package/dist/types/common/enum.d.ts +28 -0
  220. package/dist/types/common/index.d.ts +1 -0
  221. package/dist/types/events.d.ts +10 -3
  222. package/dist/types/graphs/Graph.d.ts +37 -0
  223. package/dist/types/index.d.ts +4 -0
  224. package/dist/types/llm/anthropic/index.d.ts +7 -1
  225. package/dist/types/llm/anthropic/types.d.ts +5 -2
  226. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +1 -1
  227. package/dist/types/llm/bedrock/index.d.ts +40 -33
  228. package/dist/types/llm/bedrock/utils/message_outputs.d.ts +1 -1
  229. package/dist/types/llm/google/index.d.ts +2 -3
  230. package/dist/types/llm/openrouter/index.d.ts +21 -1
  231. package/dist/types/llm/vertexai/index.d.ts +3 -2
  232. package/dist/types/messages/cache.d.ts +1 -1
  233. package/dist/types/messages/index.d.ts +1 -0
  234. package/dist/types/messages/prune.d.ts +2 -7
  235. package/dist/types/messages/summarize.d.ts +33 -0
  236. package/dist/types/run.d.ts +6 -0
  237. package/dist/types/tools/AskUser.d.ts +408 -0
  238. package/dist/types/tools/BrowserTools.d.ts +2 -2
  239. package/dist/types/tools/CodeExecutor.d.ts +28 -4
  240. package/dist/types/tools/StreamingToolCallBuffer.d.ts +106 -0
  241. package/dist/types/tools/ToolNode.d.ts +55 -3
  242. package/dist/types/tools/ToolSearch.d.ts +9 -5
  243. package/dist/types/tools/handlers.d.ts +2 -2
  244. package/dist/types/types/graph.d.ts +9 -2
  245. package/dist/types/types/llm.d.ts +8 -3
  246. package/dist/types/types/run.d.ts +2 -0
  247. package/dist/types/types/tools.d.ts +20 -2
  248. package/dist/types/utils/contextAnalytics.d.ts +5 -4
  249. package/dist/types/utils/index.d.ts +1 -0
  250. package/dist/types/utils/tokens.d.ts +6 -19
  251. package/dist/types/utils/toolCallContinuation.d.ts +30 -0
  252. package/package.json +15 -8
  253. package/src/agents/AgentContext.js +782 -0
  254. package/src/agents/AgentContext.js.map +1 -0
  255. package/src/agents/AgentContext.test.js +421 -0
  256. package/src/agents/AgentContext.test.js.map +1 -0
  257. package/src/agents/AgentContext.ts +132 -64
  258. package/src/agents/__tests__/AgentContext.test.js +678 -0
  259. package/src/agents/__tests__/AgentContext.test.js.map +1 -0
  260. package/src/agents/__tests__/AgentContext.test.ts +25 -4
  261. package/src/agents/__tests__/resolveStructuredOutputMode.test.js +117 -0
  262. package/src/agents/__tests__/resolveStructuredOutputMode.test.js.map +1 -0
  263. package/src/common/__tests__/enum.test.ts +135 -0
  264. package/src/common/constants.ts +21 -0
  265. package/src/common/enum.js +192 -0
  266. package/src/common/enum.js.map +1 -0
  267. package/src/common/enum.ts +30 -0
  268. package/src/common/index.js +3 -0
  269. package/src/common/index.js.map +1 -0
  270. package/src/common/index.ts +2 -1
  271. package/src/events.js +166 -0
  272. package/src/events.js.map +1 -0
  273. package/src/events.ts +11 -14
  274. package/src/graphs/Graph.js +1857 -0
  275. package/src/graphs/Graph.js.map +1 -0
  276. package/src/graphs/Graph.ts +580 -162
  277. package/src/graphs/MultiAgentGraph.js +1092 -0
  278. package/src/graphs/MultiAgentGraph.js.map +1 -0
  279. package/src/graphs/MultiAgentGraph.ts +331 -112
  280. package/src/graphs/__tests__/adaptive-thinking.test.ts +369 -0
  281. package/src/graphs/__tests__/graph-direct-tool-names.test.ts +210 -0
  282. package/src/graphs/__tests__/multi-agent-edges.test.ts +237 -0
  283. package/src/graphs/__tests__/structured-output.integration.test.js +624 -0
  284. package/src/graphs/__tests__/structured-output.integration.test.js.map +1 -0
  285. package/src/graphs/__tests__/structured-output.test.js +144 -0
  286. package/src/graphs/__tests__/structured-output.test.js.map +1 -0
  287. package/src/graphs/contextManagement.e2e.test.js +718 -0
  288. package/src/graphs/contextManagement.e2e.test.js.map +1 -0
  289. package/src/graphs/contextManagement.e2e.test.ts +990 -0
  290. package/src/graphs/contextManagement.test.js +485 -0
  291. package/src/graphs/contextManagement.test.js.map +1 -0
  292. package/src/graphs/contextManagement.test.ts +625 -0
  293. package/src/graphs/handoffValidation.test.js +276 -0
  294. package/src/graphs/handoffValidation.test.js.map +1 -0
  295. package/src/graphs/handoffValidation.test.ts +353 -0
  296. package/src/graphs/index.js +3 -0
  297. package/src/graphs/index.js.map +1 -0
  298. package/src/index.js +28 -0
  299. package/src/index.js.map +1 -0
  300. package/src/index.ts +13 -0
  301. package/src/instrumentation.js +21 -0
  302. package/src/instrumentation.js.map +1 -0
  303. package/src/instrumentation.ts +38 -17
  304. package/src/llm/anthropic/index.js +319 -0
  305. package/src/llm/anthropic/index.js.map +1 -0
  306. package/src/llm/anthropic/index.ts +68 -15
  307. package/src/llm/anthropic/llm.spec.ts +402 -0
  308. package/src/llm/anthropic/types.js +46 -0
  309. package/src/llm/anthropic/types.js.map +1 -0
  310. package/src/llm/anthropic/types.ts +8 -2
  311. package/src/llm/anthropic/utils/message_inputs.js +627 -0
  312. package/src/llm/anthropic/utils/message_inputs.js.map +1 -0
  313. package/src/llm/anthropic/utils/message_inputs.ts +16 -33
  314. package/src/llm/anthropic/utils/message_outputs.js +290 -0
  315. package/src/llm/anthropic/utils/message_outputs.js.map +1 -0
  316. package/src/llm/anthropic/utils/message_outputs.ts +40 -1
  317. package/src/llm/anthropic/utils/output_parsers.js +89 -0
  318. package/src/llm/anthropic/utils/output_parsers.js.map +1 -0
  319. package/src/llm/anthropic/utils/tools.js +25 -0
  320. package/src/llm/anthropic/utils/tools.js.map +1 -0
  321. package/src/llm/bedrock/__tests__/bedrock-caching.test.js +392 -0
  322. package/src/llm/bedrock/__tests__/bedrock-caching.test.js.map +1 -0
  323. package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +24 -40
  324. package/src/llm/bedrock/index.js +303 -0
  325. package/src/llm/bedrock/index.js.map +1 -0
  326. package/src/llm/bedrock/index.ts +171 -134
  327. package/src/llm/bedrock/llm.spec.ts +395 -52
  328. package/src/llm/bedrock/types.js +2 -0
  329. package/src/llm/bedrock/types.js.map +1 -0
  330. package/src/llm/bedrock/utils/index.js +6 -0
  331. package/src/llm/bedrock/utils/index.js.map +1 -0
  332. package/src/llm/bedrock/utils/message_inputs.js +463 -0
  333. package/src/llm/bedrock/utils/message_inputs.js.map +1 -0
  334. package/src/llm/bedrock/utils/message_inputs.ts +30 -5
  335. package/src/llm/bedrock/utils/message_outputs.js +269 -0
  336. package/src/llm/bedrock/utils/message_outputs.js.map +1 -0
  337. package/src/llm/bedrock/utils/message_outputs.ts +70 -22
  338. package/src/llm/fake.js +92 -0
  339. package/src/llm/fake.js.map +1 -0
  340. package/src/llm/google/index.js +215 -0
  341. package/src/llm/google/index.js.map +1 -0
  342. package/src/llm/google/index.ts +2 -3
  343. package/src/llm/google/types.js +12 -0
  344. package/src/llm/google/types.js.map +1 -0
  345. package/src/llm/google/utils/common.js +670 -0
  346. package/src/llm/google/utils/common.js.map +1 -0
  347. package/src/llm/google/utils/tools.js +111 -0
  348. package/src/llm/google/utils/tools.js.map +1 -0
  349. package/src/llm/google/utils/zod_to_genai_parameters.js +47 -0
  350. package/src/llm/google/utils/zod_to_genai_parameters.js.map +1 -0
  351. package/src/llm/openai/index.js +1033 -0
  352. package/src/llm/openai/index.js.map +1 -0
  353. package/src/llm/openai/types.js +2 -0
  354. package/src/llm/openai/types.js.map +1 -0
  355. package/src/llm/openai/utils/index.js +756 -0
  356. package/src/llm/openai/utils/index.js.map +1 -0
  357. package/src/llm/openai/utils/isReasoningModel.test.js +79 -0
  358. package/src/llm/openai/utils/isReasoningModel.test.js.map +1 -0
  359. package/src/llm/openrouter/index.js +261 -0
  360. package/src/llm/openrouter/index.js.map +1 -0
  361. package/src/llm/openrouter/index.ts +117 -6
  362. package/src/llm/openrouter/reasoning.test.js +181 -0
  363. package/src/llm/openrouter/reasoning.test.js.map +1 -0
  364. package/src/llm/openrouter/reasoning.test.ts +207 -0
  365. package/src/llm/providers.js +36 -0
  366. package/src/llm/providers.js.map +1 -0
  367. package/src/llm/text.js +65 -0
  368. package/src/llm/text.js.map +1 -0
  369. package/src/llm/vertexai/index.js +402 -0
  370. package/src/llm/vertexai/index.js.map +1 -0
  371. package/src/llm/vertexai/index.ts +115 -5
  372. package/src/llm/vertexai/llm.spec.ts +114 -0
  373. package/src/messages/__tests__/tools.test.js +392 -0
  374. package/src/messages/__tests__/tools.test.js.map +1 -0
  375. package/src/messages/cache.js +404 -0
  376. package/src/messages/cache.js.map +1 -0
  377. package/src/messages/cache.test.js +1167 -0
  378. package/src/messages/cache.test.js.map +1 -0
  379. package/src/messages/cache.test.ts +178 -16
  380. package/src/messages/cache.ts +152 -147
  381. package/src/messages/content.js +48 -0
  382. package/src/messages/content.js.map +1 -0
  383. package/src/messages/content.test.js +314 -0
  384. package/src/messages/content.test.js.map +1 -0
  385. package/src/messages/core.js +359 -0
  386. package/src/messages/core.js.map +1 -0
  387. package/src/messages/core.ts +5 -0
  388. package/src/messages/ensureThinkingBlock.test.js +997 -0
  389. package/src/messages/ensureThinkingBlock.test.js.map +1 -0
  390. package/src/messages/ensureThinkingBlock.test.ts +751 -10
  391. package/src/messages/format.js +973 -0
  392. package/src/messages/format.js.map +1 -0
  393. package/src/messages/format.ts +334 -57
  394. package/src/messages/formatAgentMessages.test.js +2278 -0
  395. package/src/messages/formatAgentMessages.test.js.map +1 -0
  396. package/src/messages/formatAgentMessages.test.ts +1175 -1
  397. package/src/messages/formatAgentMessages.tools.test.js +362 -0
  398. package/src/messages/formatAgentMessages.tools.test.js.map +1 -0
  399. package/src/messages/formatMessage.test.js +608 -0
  400. package/src/messages/formatMessage.test.js.map +1 -0
  401. package/src/messages/ids.js +18 -0
  402. package/src/messages/ids.js.map +1 -0
  403. package/src/messages/index.js +9 -0
  404. package/src/messages/index.js.map +1 -0
  405. package/src/messages/index.ts +1 -0
  406. package/src/messages/labelContentByAgent.test.js +725 -0
  407. package/src/messages/labelContentByAgent.test.js.map +1 -0
  408. package/src/messages/prune.js +438 -0
  409. package/src/messages/prune.js.map +1 -0
  410. package/src/messages/prune.ts +87 -25
  411. package/src/messages/reducer.js +60 -0
  412. package/src/messages/reducer.js.map +1 -0
  413. package/src/messages/shiftIndexTokenCountMap.test.js +63 -0
  414. package/src/messages/shiftIndexTokenCountMap.test.js.map +1 -0
  415. package/src/messages/summarize.js +146 -0
  416. package/src/messages/summarize.js.map +1 -0
  417. package/src/messages/summarize.test.js +332 -0
  418. package/src/messages/summarize.test.js.map +1 -0
  419. package/src/messages/summarize.test.ts +466 -0
  420. package/src/messages/summarize.ts +222 -0
  421. package/src/messages/tools.js +90 -0
  422. package/src/messages/tools.js.map +1 -0
  423. package/src/mockStream.js +81 -0
  424. package/src/mockStream.js.map +1 -0
  425. package/src/prompts/collab.js +7 -0
  426. package/src/prompts/collab.js.map +1 -0
  427. package/src/prompts/index.js +3 -0
  428. package/src/prompts/index.js.map +1 -0
  429. package/src/prompts/taskmanager.js +58 -0
  430. package/src/prompts/taskmanager.js.map +1 -0
  431. package/src/run.js +427 -0
  432. package/src/run.js.map +1 -0
  433. package/src/run.ts +101 -33
  434. package/src/schemas/index.js +3 -0
  435. package/src/schemas/index.js.map +1 -0
  436. package/src/schemas/schema-preparation.test.js +370 -0
  437. package/src/schemas/schema-preparation.test.js.map +1 -0
  438. package/src/schemas/validate.js +314 -0
  439. package/src/schemas/validate.js.map +1 -0
  440. package/src/schemas/validate.test.js +264 -0
  441. package/src/schemas/validate.test.js.map +1 -0
  442. package/src/scripts/abort.js +127 -0
  443. package/src/scripts/abort.js.map +1 -0
  444. package/src/scripts/ant_web_search.js +130 -0
  445. package/src/scripts/ant_web_search.js.map +1 -0
  446. package/src/scripts/ant_web_search.ts +1 -0
  447. package/src/scripts/ant_web_search_edge_case.js +133 -0
  448. package/src/scripts/ant_web_search_edge_case.js.map +1 -0
  449. package/src/scripts/ant_web_search_edge_case.ts +1 -0
  450. package/src/scripts/ant_web_search_error_edge_case.js +119 -0
  451. package/src/scripts/ant_web_search_error_edge_case.js.map +1 -0
  452. package/src/scripts/ant_web_search_error_edge_case.ts +1 -0
  453. package/src/scripts/args.js +41 -0
  454. package/src/scripts/args.js.map +1 -0
  455. package/src/scripts/bedrock-cache-debug.js +186 -0
  456. package/src/scripts/bedrock-cache-debug.js.map +1 -0
  457. package/src/scripts/bedrock-cache-debug.ts +250 -0
  458. package/src/scripts/bedrock-content-aggregation-test.js +195 -0
  459. package/src/scripts/bedrock-content-aggregation-test.js.map +1 -0
  460. package/src/scripts/bedrock-content-aggregation-test.ts +266 -0
  461. package/src/scripts/bedrock-merge-test.js +80 -0
  462. package/src/scripts/bedrock-merge-test.js.map +1 -0
  463. package/src/scripts/bedrock-merge-test.ts +107 -0
  464. package/src/scripts/bedrock-parallel-tools-test.js +150 -0
  465. package/src/scripts/bedrock-parallel-tools-test.js.map +1 -0
  466. package/src/scripts/bedrock-parallel-tools-test.ts +204 -0
  467. package/src/scripts/caching.js +106 -0
  468. package/src/scripts/caching.js.map +1 -0
  469. package/src/scripts/caching.ts +1 -0
  470. package/src/scripts/cli.js +152 -0
  471. package/src/scripts/cli.js.map +1 -0
  472. package/src/scripts/cli2.js +119 -0
  473. package/src/scripts/cli2.js.map +1 -0
  474. package/src/scripts/cli3.js +163 -0
  475. package/src/scripts/cli3.js.map +1 -0
  476. package/src/scripts/cli4.js +165 -0
  477. package/src/scripts/cli4.js.map +1 -0
  478. package/src/scripts/cli5.js +165 -0
  479. package/src/scripts/cli5.js.map +1 -0
  480. package/src/scripts/code_exec.js +171 -0
  481. package/src/scripts/code_exec.js.map +1 -0
  482. package/src/scripts/code_exec.ts +1 -0
  483. package/src/scripts/code_exec_files.js +180 -0
  484. package/src/scripts/code_exec_files.js.map +1 -0
  485. package/src/scripts/code_exec_files.ts +1 -0
  486. package/src/scripts/code_exec_multi_session.js +185 -0
  487. package/src/scripts/code_exec_multi_session.js.map +1 -0
  488. package/src/scripts/code_exec_multi_session.ts +9 -13
  489. package/src/scripts/code_exec_ptc.js +265 -0
  490. package/src/scripts/code_exec_ptc.js.map +1 -0
  491. package/src/scripts/code_exec_ptc.ts +1 -0
  492. package/src/scripts/code_exec_session.js +217 -0
  493. package/src/scripts/code_exec_session.js.map +1 -0
  494. package/src/scripts/code_exec_session.ts +1 -0
  495. package/src/scripts/code_exec_simple.js +120 -0
  496. package/src/scripts/code_exec_simple.js.map +1 -0
  497. package/src/scripts/code_exec_simple.ts +1 -0
  498. package/src/scripts/content.js +111 -0
  499. package/src/scripts/content.js.map +1 -0
  500. package/src/scripts/content.ts +1 -0
  501. package/src/scripts/empty_input.js +125 -0
  502. package/src/scripts/empty_input.js.map +1 -0
  503. package/src/scripts/handoff-test.js +96 -0
  504. package/src/scripts/handoff-test.js.map +1 -0
  505. package/src/scripts/image.js +138 -0
  506. package/src/scripts/image.js.map +1 -0
  507. package/src/scripts/image.ts +3 -1
  508. package/src/scripts/memory.js +83 -0
  509. package/src/scripts/memory.js.map +1 -0
  510. package/src/scripts/memory.ts +16 -6
  511. package/src/scripts/multi-agent-chain.js +271 -0
  512. package/src/scripts/multi-agent-chain.js.map +1 -0
  513. package/src/scripts/multi-agent-chain.ts +1 -0
  514. package/src/scripts/multi-agent-conditional.js +185 -0
  515. package/src/scripts/multi-agent-conditional.js.map +1 -0
  516. package/src/scripts/multi-agent-conditional.ts +1 -0
  517. package/src/scripts/multi-agent-document-review-chain.js +171 -0
  518. package/src/scripts/multi-agent-document-review-chain.js.map +1 -0
  519. package/src/scripts/multi-agent-document-review-chain.ts +1 -0
  520. package/src/scripts/multi-agent-hybrid-flow.js +264 -0
  521. package/src/scripts/multi-agent-hybrid-flow.js.map +1 -0
  522. package/src/scripts/multi-agent-hybrid-flow.ts +1 -0
  523. package/src/scripts/multi-agent-parallel-start.js +214 -0
  524. package/src/scripts/multi-agent-parallel-start.js.map +1 -0
  525. package/src/scripts/multi-agent-parallel-start.ts +4 -4
  526. package/src/scripts/multi-agent-parallel.js +346 -0
  527. package/src/scripts/multi-agent-parallel.js.map +1 -0
  528. package/src/scripts/multi-agent-parallel.ts +1 -0
  529. package/src/scripts/multi-agent-sequence.js +184 -0
  530. package/src/scripts/multi-agent-sequence.js.map +1 -0
  531. package/src/scripts/multi-agent-sequence.ts +4 -4
  532. package/src/scripts/multi-agent-supervisor.js +324 -0
  533. package/src/scripts/multi-agent-supervisor.js.map +1 -0
  534. package/src/scripts/multi-agent-supervisor.ts +1 -0
  535. package/src/scripts/multi-agent-test.js +147 -0
  536. package/src/scripts/multi-agent-test.js.map +1 -0
  537. package/src/scripts/multi-agent-test.ts +1 -0
  538. package/src/scripts/parallel-asymmetric-tools-test.js +202 -0
  539. package/src/scripts/parallel-asymmetric-tools-test.js.map +1 -0
  540. package/src/scripts/parallel-asymmetric-tools-test.ts +1 -0
  541. package/src/scripts/parallel-full-metadata-test.js +176 -0
  542. package/src/scripts/parallel-full-metadata-test.js.map +1 -0
  543. package/src/scripts/parallel-full-metadata-test.ts +1 -0
  544. package/src/scripts/parallel-tools-test.js +256 -0
  545. package/src/scripts/parallel-tools-test.js.map +1 -0
  546. package/src/scripts/parallel-tools-test.ts +1 -0
  547. package/src/scripts/poc-multi-agent-comprehensive.ts +1222 -0
  548. package/src/scripts/programmatic_exec.js +277 -0
  549. package/src/scripts/programmatic_exec.js.map +1 -0
  550. package/src/scripts/programmatic_exec_agent.js +168 -0
  551. package/src/scripts/programmatic_exec_agent.js.map +1 -0
  552. package/src/scripts/programmatic_exec_agent.ts +1 -0
  553. package/src/scripts/search.js +118 -0
  554. package/src/scripts/search.js.map +1 -0
  555. package/src/scripts/search.ts +1 -0
  556. package/src/scripts/sequential-full-metadata-test.js +143 -0
  557. package/src/scripts/sequential-full-metadata-test.js.map +1 -0
  558. package/src/scripts/sequential-full-metadata-test.ts +1 -0
  559. package/src/scripts/simple.js +174 -0
  560. package/src/scripts/simple.js.map +1 -0
  561. package/src/scripts/simple.ts +2 -1
  562. package/src/scripts/single-agent-metadata-test.js +152 -0
  563. package/src/scripts/single-agent-metadata-test.js.map +1 -0
  564. package/src/scripts/single-agent-metadata-test.ts +4 -6
  565. package/src/scripts/stream.js +113 -0
  566. package/src/scripts/stream.js.map +1 -0
  567. package/src/scripts/stream.ts +1 -0
  568. package/src/scripts/test-custom-prompt-key.js +132 -0
  569. package/src/scripts/test-custom-prompt-key.js.map +1 -0
  570. package/src/scripts/test-handoff-input.js +143 -0
  571. package/src/scripts/test-handoff-input.js.map +1 -0
  572. package/src/scripts/test-handoff-preamble.js +227 -0
  573. package/src/scripts/test-handoff-preamble.js.map +1 -0
  574. package/src/scripts/test-handoff-preamble.ts +1 -0
  575. package/src/scripts/test-handoff-steering.js +353 -0
  576. package/src/scripts/test-handoff-steering.js.map +1 -0
  577. package/src/scripts/test-handoff-steering.ts +430 -0
  578. package/src/scripts/test-multi-agent-list-handoff.js +318 -0
  579. package/src/scripts/test-multi-agent-list-handoff.js.map +1 -0
  580. package/src/scripts/test-multi-agent-list-handoff.ts +1 -0
  581. package/src/scripts/test-parallel-agent-labeling.js +253 -0
  582. package/src/scripts/test-parallel-agent-labeling.js.map +1 -0
  583. package/src/scripts/test-parallel-agent-labeling.ts +2 -0
  584. package/src/scripts/test-parallel-handoffs.js +229 -0
  585. package/src/scripts/test-parallel-handoffs.js.map +1 -0
  586. package/src/scripts/test-parallel-handoffs.ts +1 -0
  587. package/src/scripts/test-thinking-handoff-bedrock.js +132 -0
  588. package/src/scripts/test-thinking-handoff-bedrock.js.map +1 -0
  589. package/src/scripts/test-thinking-handoff-bedrock.ts +1 -0
  590. package/src/scripts/test-thinking-handoff.js +132 -0
  591. package/src/scripts/test-thinking-handoff.js.map +1 -0
  592. package/src/scripts/test-thinking-handoff.ts +1 -0
  593. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +140 -0
  594. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js.map +1 -0
  595. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +166 -0
  596. package/src/scripts/test-tool-before-handoff-role-order.js +223 -0
  597. package/src/scripts/test-tool-before-handoff-role-order.js.map +1 -0
  598. package/src/scripts/test-tool-before-handoff-role-order.ts +276 -0
  599. package/src/scripts/test-tools-before-handoff.js +187 -0
  600. package/src/scripts/test-tools-before-handoff.js.map +1 -0
  601. package/src/scripts/test-tools-before-handoff.ts +4 -8
  602. package/src/scripts/test_code_api.js +263 -0
  603. package/src/scripts/test_code_api.js.map +1 -0
  604. package/src/scripts/thinking-bedrock.js +128 -0
  605. package/src/scripts/thinking-bedrock.js.map +1 -0
  606. package/src/scripts/thinking-bedrock.ts +1 -0
  607. package/src/scripts/thinking-vertexai.js +130 -0
  608. package/src/scripts/thinking-vertexai.js.map +1 -0
  609. package/src/scripts/thinking-vertexai.ts +168 -0
  610. package/src/scripts/thinking.js +134 -0
  611. package/src/scripts/thinking.js.map +1 -0
  612. package/src/scripts/thinking.ts +1 -0
  613. package/src/scripts/tool_search.js +114 -0
  614. package/src/scripts/tool_search.js.map +1 -0
  615. package/src/scripts/tools.js +125 -0
  616. package/src/scripts/tools.js.map +1 -0
  617. package/src/scripts/tools.ts +5 -19
  618. package/src/specs/agent-handoffs-bedrock.integration.test.js +280 -0
  619. package/src/specs/agent-handoffs-bedrock.integration.test.js.map +1 -0
  620. package/src/specs/agent-handoffs-bedrock.integration.test.ts +412 -375
  621. package/src/specs/agent-handoffs.test.js +924 -0
  622. package/src/specs/agent-handoffs.test.js.map +1 -0
  623. package/src/specs/agent-handoffs.test.ts +152 -39
  624. package/src/specs/anthropic.simple.test.js +287 -0
  625. package/src/specs/anthropic.simple.test.js.map +1 -0
  626. package/src/specs/anthropic.simple.test.ts +7 -4
  627. package/src/specs/azure.simple.test.js +381 -0
  628. package/src/specs/azure.simple.test.js.map +1 -0
  629. package/src/specs/azure.simple.test.ts +143 -5
  630. package/src/specs/cache.simple.test.js +282 -0
  631. package/src/specs/cache.simple.test.js.map +1 -0
  632. package/src/specs/cache.simple.test.ts +9 -2
  633. package/src/specs/custom-event-await.test.js +148 -0
  634. package/src/specs/custom-event-await.test.js.map +1 -0
  635. package/src/specs/custom-event-await.test.ts +215 -0
  636. package/src/specs/deepseek.simple.test.js +189 -0
  637. package/src/specs/deepseek.simple.test.js.map +1 -0
  638. package/src/specs/deepseek.simple.test.ts +4 -2
  639. package/src/specs/emergency-prune.test.js +308 -0
  640. package/src/specs/emergency-prune.test.js.map +1 -0
  641. package/src/specs/moonshot.simple.test.js +237 -0
  642. package/src/specs/moonshot.simple.test.js.map +1 -0
  643. package/src/specs/moonshot.simple.test.ts +6 -2
  644. package/src/specs/observability.integration.test.js +1337 -0
  645. package/src/specs/observability.integration.test.js.map +1 -0
  646. package/src/specs/observability.integration.test.ts +2223 -0
  647. package/src/specs/openai.simple.test.js +233 -0
  648. package/src/specs/openai.simple.test.js.map +1 -0
  649. package/src/specs/openai.simple.test.ts +4 -2
  650. package/src/specs/openrouter.simple.test.js +202 -0
  651. package/src/specs/openrouter.simple.test.js.map +1 -0
  652. package/src/specs/openrouter.simple.test.ts +165 -4
  653. package/src/specs/prune.test.js +733 -0
  654. package/src/specs/prune.test.js.map +1 -0
  655. package/src/specs/prune.test.ts +1 -0
  656. package/src/specs/reasoning.test.js +144 -0
  657. package/src/specs/reasoning.test.js.map +1 -0
  658. package/src/specs/reasoning.test.ts +2 -2
  659. package/src/specs/spec.utils.js +4 -0
  660. package/src/specs/spec.utils.js.map +1 -0
  661. package/src/specs/thinking-handoff.test.js +486 -0
  662. package/src/specs/thinking-handoff.test.js.map +1 -0
  663. package/src/specs/thinking-handoff.test.ts +3 -2
  664. package/src/specs/thinking-prune.test.js +600 -0
  665. package/src/specs/thinking-prune.test.js.map +1 -0
  666. package/src/specs/token-distribution-edge-case.test.js +246 -0
  667. package/src/specs/token-distribution-edge-case.test.js.map +1 -0
  668. package/src/specs/token-memoization.test.js +32 -0
  669. package/src/specs/token-memoization.test.js.map +1 -0
  670. package/src/specs/token-memoization.test.ts +14 -5
  671. package/src/specs/tokens.test.js +49 -0
  672. package/src/specs/tokens.test.js.map +1 -0
  673. package/src/specs/tokens.test.ts +64 -0
  674. package/src/specs/tool-error.test.js +139 -0
  675. package/src/specs/tool-error.test.js.map +1 -0
  676. package/src/specs/tool-error.test.ts +2 -2
  677. package/src/splitStream.js +204 -0
  678. package/src/splitStream.js.map +1 -0
  679. package/src/splitStream.test.js +504 -0
  680. package/src/splitStream.test.js.map +1 -0
  681. package/src/stream.js +650 -0
  682. package/src/stream.js.map +1 -0
  683. package/src/stream.test.js +225 -0
  684. package/src/stream.test.js.map +1 -0
  685. package/src/stream.test.ts +25 -15
  686. package/src/stream.ts +82 -32
  687. package/src/test/mockTools.js +340 -0
  688. package/src/test/mockTools.js.map +1 -0
  689. package/src/tools/AskUser.ts +159 -0
  690. package/src/tools/BrowserTools.js +245 -0
  691. package/src/tools/BrowserTools.js.map +1 -0
  692. package/src/tools/BrowserTools.ts +12 -8
  693. package/src/tools/Calculator.js +38 -0
  694. package/src/tools/Calculator.js.map +1 -0
  695. package/src/tools/Calculator.test.js +225 -0
  696. package/src/tools/Calculator.test.js.map +1 -0
  697. package/src/tools/CodeExecutor.js +233 -0
  698. package/src/tools/CodeExecutor.js.map +1 -0
  699. package/src/tools/CodeExecutor.selfhealing.test.ts +435 -0
  700. package/src/tools/CodeExecutor.ts +82 -5
  701. package/src/tools/ProgrammaticToolCalling.js +602 -0
  702. package/src/tools/ProgrammaticToolCalling.js.map +1 -0
  703. package/src/tools/ProgrammaticToolCalling.ts +40 -52
  704. package/src/tools/StreamingToolCallBuffer.js +179 -0
  705. package/src/tools/StreamingToolCallBuffer.js.map +1 -0
  706. package/src/tools/StreamingToolCallBuffer.ts +218 -0
  707. package/src/tools/ToolNode.js +930 -0
  708. package/src/tools/ToolNode.js.map +1 -0
  709. package/src/tools/ToolNode.ts +454 -41
  710. package/src/tools/ToolSearch.js +904 -0
  711. package/src/tools/ToolSearch.js.map +1 -0
  712. package/src/tools/ToolSearch.ts +84 -33
  713. package/src/tools/__tests__/AskUser.test.ts +537 -0
  714. package/src/tools/__tests__/BrowserTools.test.js +306 -0
  715. package/src/tools/__tests__/BrowserTools.test.js.map +1 -0
  716. package/src/tools/__tests__/BrowserTools.test.ts +131 -6
  717. package/src/tools/__tests__/CodeExecutor.test.ts +76 -0
  718. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js +276 -0
  719. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js.map +1 -0
  720. package/src/tools/__tests__/ProgrammaticToolCalling.test.js +807 -0
  721. package/src/tools/__tests__/ProgrammaticToolCalling.test.js.map +1 -0
  722. package/src/tools/__tests__/StreamingToolCallBuffer.test.js +175 -0
  723. package/src/tools/__tests__/StreamingToolCallBuffer.test.js.map +1 -0
  724. package/src/tools/__tests__/StreamingToolCallBuffer.test.ts +263 -0
  725. package/src/tools/__tests__/ToolApproval.test.js +675 -0
  726. package/src/tools/__tests__/ToolApproval.test.js.map +1 -0
  727. package/src/tools/__tests__/ToolApproval.test.ts +194 -20
  728. package/src/tools/__tests__/ToolNode.hitl.test.ts +267 -0
  729. package/src/tools/__tests__/ToolNode.recovery.test.js +200 -0
  730. package/src/tools/__tests__/ToolNode.recovery.test.js.map +1 -0
  731. package/src/tools/__tests__/ToolNode.recovery.test.ts +276 -0
  732. package/src/tools/__tests__/ToolNode.session.test.js +319 -0
  733. package/src/tools/__tests__/ToolNode.session.test.js.map +1 -0
  734. package/src/tools/__tests__/ToolNode.session.test.ts +465 -0
  735. package/src/tools/__tests__/ToolSearch.integration.test.js +125 -0
  736. package/src/tools/__tests__/ToolSearch.integration.test.js.map +1 -0
  737. package/src/tools/__tests__/ToolSearch.test.js +812 -0
  738. package/src/tools/__tests__/ToolSearch.test.js.map +1 -0
  739. package/src/tools/__tests__/ToolSearch.test.ts +78 -5
  740. package/src/tools/__tests__/handlers.test.js +799 -0
  741. package/src/tools/__tests__/handlers.test.js.map +1 -0
  742. package/src/tools/__tests__/handlers.test.ts +1100 -0
  743. package/src/tools/__tests__/truncation-recovery.integration.test.js +362 -0
  744. package/src/tools/__tests__/truncation-recovery.integration.test.js.map +1 -0
  745. package/src/tools/__tests__/truncation-recovery.integration.test.ts +560 -0
  746. package/src/tools/handlers.js +306 -0
  747. package/src/tools/handlers.js.map +1 -0
  748. package/src/tools/handlers.ts +119 -16
  749. package/src/tools/schema.js +25 -0
  750. package/src/tools/schema.js.map +1 -0
  751. package/src/tools/search/anthropic.js +34 -0
  752. package/src/tools/search/anthropic.js.map +1 -0
  753. package/src/tools/search/content.js +116 -0
  754. package/src/tools/search/content.js.map +1 -0
  755. package/src/tools/search/content.test.js +133 -0
  756. package/src/tools/search/content.test.js.map +1 -0
  757. package/src/tools/search/firecrawl.js +173 -0
  758. package/src/tools/search/firecrawl.js.map +1 -0
  759. package/src/tools/search/format.js +198 -0
  760. package/src/tools/search/format.js.map +1 -0
  761. package/src/tools/search/highlights.js +241 -0
  762. package/src/tools/search/highlights.js.map +1 -0
  763. package/src/tools/search/index.js +3 -0
  764. package/src/tools/search/index.js.map +1 -0
  765. package/src/tools/search/jina-reranker.test.js +106 -0
  766. package/src/tools/search/jina-reranker.test.js.map +1 -0
  767. package/src/tools/search/rerankers.js +165 -0
  768. package/src/tools/search/rerankers.js.map +1 -0
  769. package/src/tools/search/schema.js +102 -0
  770. package/src/tools/search/schema.js.map +1 -0
  771. package/src/tools/search/search.js +561 -0
  772. package/src/tools/search/search.js.map +1 -0
  773. package/src/tools/search/serper-scraper.js +126 -0
  774. package/src/tools/search/serper-scraper.js.map +1 -0
  775. package/src/tools/search/test.js +129 -0
  776. package/src/tools/search/test.js.map +1 -0
  777. package/src/tools/search/tool.js +453 -0
  778. package/src/tools/search/tool.js.map +1 -0
  779. package/src/tools/search/types.js +2 -0
  780. package/src/tools/search/types.js.map +1 -0
  781. package/src/tools/search/utils.js +59 -0
  782. package/src/tools/search/utils.js.map +1 -0
  783. package/src/types/graph.js +24 -0
  784. package/src/types/graph.js.map +1 -0
  785. package/src/types/graph.test.js +192 -0
  786. package/src/types/graph.test.js.map +1 -0
  787. package/src/types/graph.ts +26 -6
  788. package/src/types/index.js +7 -0
  789. package/src/types/index.js.map +1 -0
  790. package/src/types/llm.js +2 -0
  791. package/src/types/llm.js.map +1 -0
  792. package/src/types/llm.ts +8 -3
  793. package/src/types/messages.js +2 -0
  794. package/src/types/messages.js.map +1 -0
  795. package/src/types/run.js +2 -0
  796. package/src/types/run.js.map +1 -0
  797. package/src/types/run.ts +2 -0
  798. package/src/types/stream.js +2 -0
  799. package/src/types/stream.js.map +1 -0
  800. package/src/types/tools.js +2 -0
  801. package/src/types/tools.js.map +1 -0
  802. package/src/types/tools.ts +21 -2
  803. package/src/utils/contextAnalytics.js +79 -0
  804. package/src/utils/contextAnalytics.js.map +1 -0
  805. package/src/utils/contextAnalytics.test.js +166 -0
  806. package/src/utils/contextAnalytics.test.js.map +1 -0
  807. package/src/utils/contextAnalytics.test.ts +222 -0
  808. package/src/utils/contextAnalytics.ts +27 -9
  809. package/src/utils/events.js +26 -0
  810. package/src/utils/events.js.map +1 -0
  811. package/src/utils/graph.js +11 -0
  812. package/src/utils/graph.js.map +1 -0
  813. package/src/utils/handlers.js +65 -0
  814. package/src/utils/handlers.js.map +1 -0
  815. package/src/utils/index.js +10 -0
  816. package/src/utils/index.js.map +1 -0
  817. package/src/utils/index.ts +1 -0
  818. package/src/utils/llm.js +21 -0
  819. package/src/utils/llm.js.map +1 -0
  820. package/src/utils/llmConfig.js +205 -0
  821. package/src/utils/llmConfig.js.map +1 -0
  822. package/src/utils/llmConfig.ts +5 -5
  823. package/src/utils/logging.js +37 -0
  824. package/src/utils/logging.js.map +1 -0
  825. package/src/utils/misc.js +51 -0
  826. package/src/utils/misc.js.map +1 -0
  827. package/src/utils/run.js +69 -0
  828. package/src/utils/run.js.map +1 -0
  829. package/src/utils/run.ts +108 -106
  830. package/src/utils/schema.js +21 -0
  831. package/src/utils/schema.js.map +1 -0
  832. package/src/utils/title.js +119 -0
  833. package/src/utils/title.js.map +1 -0
  834. package/src/utils/tokens.js +92 -0
  835. package/src/utils/tokens.js.map +1 -0
  836. package/src/utils/tokens.ts +118 -142
  837. package/src/utils/toolCallContinuation.ts +55 -0
  838. package/src/utils/toonFormat.js +379 -0
  839. package/src/utils/toonFormat.js.map +1 -0
@@ -25,32 +25,35 @@ import {
25
25
  } from '@langchain/core/messages';
26
26
  import type {
27
27
  BaseMessageFields,
28
+ MessageContent,
28
29
  UsageMetadata,
29
30
  BaseMessage,
30
31
  } from '@langchain/core/messages';
31
32
  import type { ToolCall } from '@langchain/core/messages/tool';
32
33
  import type * as t from '@/types';
33
- import {
34
- GraphNodeKeys,
35
- ContentTypes,
36
- GraphEvents,
37
- Providers,
38
- StepTypes,
39
- MessageTypes,
40
- Constants,
41
- } from '@/common';
42
34
  import {
43
35
  formatAnthropicArtifactContent,
44
36
  ensureThinkingBlockInMessages,
45
37
  convertMessagesToContent,
46
38
  addBedrockCacheControl,
39
+ extractToolDiscoveries,
47
40
  modifyDeltaProperties,
48
41
  formatArtifactPayload,
49
42
  formatContentStrings,
50
43
  createPruneMessages,
51
44
  addCacheControl,
52
- extractToolDiscoveries,
45
+ getMessageId,
53
46
  } from '@/messages';
47
+ import {
48
+ GraphNodeKeys,
49
+ ContentTypes,
50
+ GraphEvents,
51
+ Providers,
52
+ StepTypes,
53
+ MessageTypes,
54
+ Constants,
55
+ TOOL_TURN_THINKING_BUDGET,
56
+ } from '@/common';
54
57
  import {
55
58
  resetIfNotEmpty,
56
59
  isOpenAILike,
@@ -69,9 +72,15 @@ import { safeDispatchCustomEvent } from '@/utils/events';
69
72
  import { createSchemaOnlyTools } from '@/tools/schema';
70
73
  import { prepareSchemaForProvider } from '@/schemas/validate';
71
74
  import { AgentContext } from '@/agents/AgentContext';
72
- import { StructuredOutputRefusalError, StructuredOutputTruncatedError } from '@/types/graph';
75
+ import {
76
+ StructuredOutputRefusalError,
77
+ StructuredOutputTruncatedError,
78
+ } from '@/types/graph';
73
79
  import { createFakeStreamingLLM } from '@/llm/fake';
80
+ import { handleToolCalls } from '@/tools/handlers';
81
+ import { ChatModelStreamHandler } from '@/stream';
74
82
  import { HandlerRegistry } from '@/events';
83
+ import { StreamingToolCallBuffer } from '@/tools/StreamingToolCallBuffer';
75
84
 
76
85
  const { AGENT, TOOLS } = GraphNodeKeys;
77
86
 
@@ -151,6 +160,34 @@ export abstract class Graph<
151
160
  * Currently supports code execution session tracking (session_id, files).
152
161
  */
153
162
  sessions: t.ToolSessionMap = new Map();
163
+ /**
164
+ * Streaming tool call buffer — accumulates raw arg strings during streaming
165
+ * so that truncated tool call content can be recovered by the ToolNode.
166
+ * Fed by handleToolCallChunks, consumed by ToolNode.run when args are incomplete.
167
+ */
168
+ streamingToolCallBuffer: StreamingToolCallBuffer =
169
+ new StreamingToolCallBuffer();
170
+
171
+ /**
172
+ * Clears heavy references to allow GC to reclaim memory held by
173
+ * LangGraph's internal config / AsyncLocalStorage RunTree chain.
174
+ * Call after a run completes and content has been extracted.
175
+ */
176
+ clearHeavyState(): void {
177
+ this.config = undefined;
178
+ this.signal = undefined;
179
+ this.contentData = [];
180
+ this.contentIndexMap = new Map();
181
+ this.stepKeyIds = new Map();
182
+ this.toolCallStepIds.clear();
183
+ this.messageIdsByStepKey = new Map();
184
+ this.messageStepHasToolCalls = new Map();
185
+ this.prelimMessageIdsByStepKey = new Map();
186
+ this.invokedToolIds = undefined;
187
+ this.handlerRegistry = undefined;
188
+ this.sessions.clear();
189
+ this.streamingToolCallBuffer.clearAll();
190
+ }
154
191
  }
155
192
 
156
193
  export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
@@ -208,7 +245,13 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
208
245
  this.contentIndexMap = resetIfNotEmpty(this.contentIndexMap, new Map());
209
246
  }
210
247
  this.stepKeyIds = resetIfNotEmpty(this.stepKeyIds, new Map());
211
- this.toolCallStepIds = resetIfNotEmpty(this.toolCallStepIds, new Map());
248
+ /**
249
+ * Clear in-place instead of replacing with a new Map to preserve the
250
+ * shared reference held by ToolNode (passed at construction time).
251
+ * Using resetIfNotEmpty would create a new Map, leaving ToolNode with
252
+ * a stale reference on 2nd+ processStream calls.
253
+ */
254
+ this.toolCallStepIds.clear();
212
255
  this.messageIdsByStepKey = resetIfNotEmpty(
213
256
  this.messageIdsByStepKey,
214
257
  new Map()
@@ -227,6 +270,107 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
227
270
  }
228
271
  }
229
272
 
273
+ override clearHeavyState(): void {
274
+ super.clearHeavyState();
275
+ this.messages = [];
276
+ this.overrideModel = undefined;
277
+ for (const context of this.agentContexts.values()) {
278
+ context.reset();
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Returns clientOptions with a reduced thinking budget for subsequent
284
+ * ReAct loop iterations (tool-result turns).
285
+ *
286
+ * **Rationale:** The first LLM call in a conversation processes the user's
287
+ * original query and may benefit from deep extended thinking. Subsequent
288
+ * iterations — where the model receives tool results and decides whether
289
+ * to call another tool or produce a final response — require minimal
290
+ * reasoning. Reducing the thinking budget from the user's configured
291
+ * value to TOOL_TURN_THINKING_BUDGET (1024 tokens) cuts wall-clock
292
+ * latency by ~15-20s per iteration, compounding across multi-tool flows.
293
+ *
294
+ * Provider handling:
295
+ * - **Anthropic (direct):** Reduces `thinking.budget_tokens` if > threshold
296
+ * - **Bedrock (Anthropic models):** Reduces `additionalModelRequestFields.thinking.budget_tokens`
297
+ * - **VertexAI / Google:** Reduces `thinkingConfig.thinkingBudget` if > threshold
298
+ * - **All others:** Returns clientOptions unchanged (no-op)
299
+ *
300
+ * @param clientOptions - The original client options from AgentContext
301
+ * @param provider - The LLM provider enum value
302
+ * @returns Shallow-cloned clientOptions with reduced thinking budget, or the original if no reduction needed
303
+ */
304
+ getAdaptiveClientOptions(
305
+ clientOptions: t.ClientOptions,
306
+ provider: Providers
307
+ ): t.ClientOptions {
308
+ if (provider === Providers.ANTHROPIC) {
309
+ const anthropicOpts = clientOptions as t.AnthropicClientOptions;
310
+ if (
311
+ anthropicOpts.thinking != null &&
312
+ typeof anthropicOpts.thinking === 'object' &&
313
+ 'type' in anthropicOpts.thinking &&
314
+ (anthropicOpts.thinking.type === 'enabled' ||
315
+ anthropicOpts.thinking.type === 'adaptive') &&
316
+ 'budget_tokens' in anthropicOpts.thinking &&
317
+ (anthropicOpts.thinking.budget_tokens as number) >
318
+ TOOL_TURN_THINKING_BUDGET
319
+ ) {
320
+ return {
321
+ ...anthropicOpts,
322
+ thinking: {
323
+ ...anthropicOpts.thinking,
324
+ budget_tokens: TOOL_TURN_THINKING_BUDGET,
325
+ },
326
+ } as t.AnthropicClientOptions;
327
+ }
328
+ }
329
+
330
+ if (provider === Providers.BEDROCK) {
331
+ const bedrockOpts = clientOptions as t.BedrockAnthropicClientOptions;
332
+ const thinkingField = bedrockOpts.additionalModelRequestFields?.thinking;
333
+ if (
334
+ thinkingField != null &&
335
+ typeof thinkingField === 'object' &&
336
+ 'budget_tokens' in thinkingField &&
337
+ (thinkingField.budget_tokens as number) > TOOL_TURN_THINKING_BUDGET
338
+ ) {
339
+ return {
340
+ ...bedrockOpts,
341
+ additionalModelRequestFields: {
342
+ ...((bedrockOpts.additionalModelRequestFields ?? {}) as Record<
343
+ string,
344
+ unknown
345
+ >),
346
+ thinking: {
347
+ ...thinkingField,
348
+ budget_tokens: TOOL_TURN_THINKING_BUDGET,
349
+ },
350
+ },
351
+ } as t.BedrockAnthropicClientOptions;
352
+ }
353
+ }
354
+
355
+ if (provider === Providers.VERTEXAI || provider === Providers.GOOGLE) {
356
+ const googleOpts = clientOptions as t.GoogleClientOptions;
357
+ if (
358
+ googleOpts.thinkingConfig?.thinkingBudget != null &&
359
+ googleOpts.thinkingConfig.thinkingBudget > TOOL_TURN_THINKING_BUDGET
360
+ ) {
361
+ return {
362
+ ...googleOpts,
363
+ thinkingConfig: {
364
+ ...googleOpts.thinkingConfig,
365
+ thinkingBudget: TOOL_TURN_THINKING_BUDGET,
366
+ },
367
+ } as t.GoogleClientOptions;
368
+ }
369
+ }
370
+
371
+ return clientOptions;
372
+ }
373
+
230
374
  /**
231
375
  * Returns the normalized finish/stop reason from the last LLM invocation.
232
376
  * Used by callers to detect when the response was truncated due to max_tokens.
@@ -260,7 +404,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
260
404
  } else if (messageCount <= 150) {
261
405
  return 'the past few hours';
262
406
  } else if (messageCount <= 300) {
263
- return 'roughly a day\'s worth';
407
+ return "roughly a day's worth";
264
408
  } else if (messageCount <= 700) {
265
409
  return 'the past few days';
266
410
  } else {
@@ -366,7 +510,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
366
510
  ) {
367
511
  keyList.push('reasoning');
368
512
  } else if (agentContext.tokenTypeSwitch === 'content') {
369
- keyList.push('post-reasoning');
513
+ keyList.push(`post-reasoning-${agentContext.reasoningTransitionCount}`);
370
514
  }
371
515
 
372
516
  if (this.invokedToolIds != null && this.invokedToolIds.size > 0) {
@@ -383,7 +527,11 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
383
527
  /* Misc.*/
384
528
 
385
529
  getRunMessages(): BaseMessage[] | undefined {
386
- return this.messages.slice(this.startIndex);
530
+ const result = this.messages.slice(this.startIndex);
531
+ console.debug(
532
+ `[Graph] getRunMessages() | totalMessages=${this.messages.length} | startIndex=${this.startIndex} | runMessages=${result.length}`
533
+ );
534
+ return result;
387
535
  }
388
536
 
389
537
  getContentParts(): t.MessageContentComplex[] | undefined {
@@ -548,30 +696,91 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
548
696
  if (eventDrivenMode) {
549
697
  const schemaTools = createSchemaOnlyTools(toolDefinitions);
550
698
  const toolDefMap = new Map(toolDefinitions.map((def) => [def.name, def]));
699
+ const graphTools = agentContext?.graphTools as
700
+ | t.GenericTool[]
701
+ | undefined;
702
+
703
+ const directToolNames = new Set<string>();
704
+ const allTools = [...schemaTools] as t.GenericTool[];
705
+ const allToolMap: t.ToolMap = new Map(
706
+ schemaTools.map((tool) => [tool.name, tool])
707
+ );
708
+
709
+ if (graphTools && graphTools.length > 0) {
710
+ for (const tool of graphTools) {
711
+ if ('name' in tool) {
712
+ allTools.push(tool);
713
+ allToolMap.set(tool.name, tool);
714
+ directToolNames.add(tool.name);
715
+ }
716
+ }
717
+ }
551
718
 
552
719
  return new CustomToolNode<t.BaseGraphState>({
553
- tools: schemaTools as t.GenericTool[],
554
- toolMap: new Map(schemaTools.map((tool) => [tool.name, tool])),
555
- toolCallStepIds: this.toolCallStepIds,
556
- errorHandler: (data, metadata) =>
557
- StandardGraph.handleToolCallErrorStatic(this, data, metadata),
558
- toolRegistry: agentContext?.toolRegistry,
559
- sessions: this.sessions,
720
+ tools: allTools,
721
+ toolMap: allToolMap,
560
722
  eventDrivenMode: true,
723
+ sessions: this.sessions,
561
724
  toolDefinitions: toolDefMap,
562
725
  agentId: agentContext?.agentId,
726
+ toolCallStepIds: this.toolCallStepIds,
727
+ toolRegistry: agentContext?.toolRegistry,
728
+ directToolNames: directToolNames.size > 0 ? directToolNames : undefined,
729
+ streamingToolCallBuffer: this.streamingToolCallBuffer,
730
+ errorHandler: (data, metadata) =>
731
+ StandardGraph.handleToolCallErrorStatic(this, data, metadata),
563
732
  toolApprovalConfig,
564
733
  });
565
734
  }
566
735
 
736
+ const graphTools = agentContext?.graphTools as t.GenericTool[] | undefined;
737
+ const baseTools = (currentTools as t.GenericTool[] | undefined) ?? [];
738
+ const allTraditionalTools =
739
+ graphTools && graphTools.length > 0
740
+ ? [...baseTools, ...graphTools]
741
+ : baseTools;
742
+ /**
743
+ * Build tool map from all sources: agent's toolMap, agent's tools array, and graph tools.
744
+ * Previously, baseTools were missing from the map when no explicit toolMap was provided,
745
+ * causing ToolNode to not find agent-defined tools (e.g., custom DynamicStructuredTools).
746
+ */
747
+ const traditionalToolMap =
748
+ graphTools && graphTools.length > 0
749
+ ? new Map([
750
+ ...(currentToolMap ?? new Map()),
751
+ ...baseTools
752
+ .filter((t): t is t.GenericTool & { name: string } => 'name' in t)
753
+ .map((t) => [t.name, t] as [string, t.GenericTool]),
754
+ ...graphTools
755
+ .filter((t): t is t.GenericTool & { name: string } => 'name' in t)
756
+ .map((t) => [t.name, t] as [string, t.GenericTool]),
757
+ ])
758
+ : currentToolMap;
759
+
760
+ /** Build directToolNames from graph-managed tools (handoff/transfer) so HITL can bypass them */
761
+ let directToolNames: Set<string> | undefined;
762
+ if (graphTools && graphTools.length > 0) {
763
+ directToolNames = new Set<string>();
764
+ for (const tool of graphTools) {
765
+ if ('name' in tool) {
766
+ directToolNames.add(tool.name);
767
+ }
768
+ }
769
+ if (directToolNames.size === 0) {
770
+ directToolNames = undefined;
771
+ }
772
+ }
773
+
567
774
  return new CustomToolNode<t.BaseGraphState>({
568
- tools: (currentTools as t.GenericTool[] | undefined) ?? [],
569
- toolMap: currentToolMap,
775
+ tools: allTraditionalTools,
776
+ toolMap: traditionalToolMap,
570
777
  toolCallStepIds: this.toolCallStepIds,
778
+ streamingToolCallBuffer: this.streamingToolCallBuffer,
571
779
  errorHandler: (data, metadata) =>
572
780
  StandardGraph.handleToolCallErrorStatic(this, data, metadata),
573
781
  toolRegistry: agentContext?.toolRegistry,
574
782
  sessions: this.sessions,
783
+ directToolNames,
575
784
  toolApprovalConfig,
576
785
  });
577
786
  }
@@ -666,7 +875,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
666
875
  currentModel,
667
876
  finalMessages,
668
877
  provider,
669
- tools,
878
+ tools: _tools,
670
879
  }: {
671
880
  currentModel?: t.ChatModel;
672
881
  finalMessages: BaseMessage[];
@@ -680,23 +889,54 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
680
889
  throw new Error('No model found');
681
890
  }
682
891
 
683
- if ((tools?.length ?? 0) > 0 && manualToolStreamProviders.has(provider)) {
684
- if (!model.stream) {
685
- throw new Error('Model does not support stream');
686
- }
892
+ if (model.stream) {
893
+ /**
894
+ * Process all model output through a local ChatModelStreamHandler in the
895
+ * graph execution context. Each chunk is awaited before the next one is
896
+ * consumed, so by the time the stream is exhausted every run step
897
+ * (MESSAGE_CREATION, TOOL_CALLS) has been created and toolCallStepIds is
898
+ * fully populated — the graph will not transition to ToolNode until this
899
+ * is done.
900
+ *
901
+ * This replaces the previous pattern where ChatModelStreamHandler lived
902
+ * in the for-await stream consumer (handler registry). That consumer
903
+ * runs concurrently with graph execution, so the graph could advance to
904
+ * ToolNode before the consumer had processed all events. By handling
905
+ * chunks here, inside the agent node, the race is eliminated.
906
+ *
907
+ * The for-await consumer no longer needs a ChatModelStreamHandler; its
908
+ * on_chat_model_stream events are simply ignored (no handler registered).
909
+ * The dispatched custom events (ON_RUN_STEP, ON_MESSAGE_DELTA, etc.)
910
+ * still reach the content aggregator and SSE handlers through the custom
911
+ * event callback in Run.createCustomEventCallback.
912
+ */
913
+ const metadata = config?.metadata as Record<string, unknown> | undefined;
914
+ const streamHandler = new ChatModelStreamHandler();
687
915
  const stream = await model.stream(finalMessages, config);
688
916
  let finalChunk: AIMessageChunk | undefined;
689
917
  for await (const chunk of stream) {
690
- await safeDispatchCustomEvent(
918
+ await streamHandler.handle(
691
919
  GraphEvents.CHAT_MODEL_STREAM,
692
- { chunk, emitted: true },
693
- config
920
+ { chunk },
921
+ metadata,
922
+ this
694
923
  );
695
924
  finalChunk = finalChunk ? concat(finalChunk, chunk) : chunk;
696
925
  }
697
- finalChunk = modifyDeltaProperties(provider, finalChunk);
926
+
927
+ if (manualToolStreamProviders.has(provider)) {
928
+ finalChunk = modifyDeltaProperties(provider, finalChunk);
929
+ }
930
+
931
+ if ((finalChunk?.tool_calls?.length ?? 0) > 0) {
932
+ finalChunk!.tool_calls = finalChunk!.tool_calls?.filter(
933
+ (tool_call: ToolCall) => !!tool_call.name
934
+ );
935
+ }
936
+
698
937
  return { messages: [finalChunk as AIMessageChunk] };
699
938
  } else {
939
+ /** Fallback for models without stream support. */
700
940
  const finalMessage = await model.invoke(finalMessages, config);
701
941
  if ((finalMessage.tool_calls?.length ?? 0) > 0) {
702
942
  finalMessage.tool_calls = finalMessage.tool_calls?.filter(
@@ -739,17 +979,14 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
739
979
  rawMessage?: AIMessageChunk;
740
980
  }> {
741
981
  const model = this.overrideModel ?? currentModel;
742
- if (!model) {
743
- throw new Error('No model found');
744
- }
745
982
 
746
983
  // Check if model supports withStructuredOutput
747
984
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
748
985
  if (typeof (model as any).withStructuredOutput !== 'function') {
749
986
  throw new Error(
750
- `The selected model does not support structured output. ` +
751
- `Please use a model that supports JSON schema output (e.g., OpenAI GPT-4, Anthropic Claude, Google Gemini) ` +
752
- `or disable structured output for this agent.`
987
+ 'The selected model does not support structured output. ' +
988
+ 'Please use a model that supports JSON schema output (e.g., OpenAI GPT-4, Anthropic Claude, Google Gemini) ' +
989
+ 'or disable structured output for this agent.'
753
990
  );
754
991
  }
755
992
 
@@ -766,7 +1003,10 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
766
1003
  const resolved = agentContext.resolveStructuredOutputMode();
767
1004
  method = resolved.method;
768
1005
  if (resolved.warnings.length > 0) {
769
- console.warn('[Graph] Structured output mode warnings:', resolved.warnings);
1006
+ console.warn(
1007
+ '[Graph] Structured output mode warnings:',
1008
+ resolved.warnings
1009
+ );
770
1010
  }
771
1011
  } else {
772
1012
  // Legacy fallback: use the old mode-based resolution
@@ -774,7 +1014,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
774
1014
  if (mode === 'tool') {
775
1015
  method = 'functionCalling';
776
1016
  } else if (mode === 'provider') {
777
- method = provider === Providers.BEDROCK ? 'functionCalling' : 'jsonMode';
1017
+ method =
1018
+ provider === Providers.BEDROCK ? 'functionCalling' : 'jsonMode';
778
1019
  } else {
779
1020
  method = undefined;
780
1021
  }
@@ -782,36 +1023,30 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
782
1023
 
783
1024
  // Prepare schema for provider-specific constraints when using native/jsonSchema mode
784
1025
  let preparedSchema = schema;
785
- if (method === 'jsonSchema' && provider) {
1026
+ if (method === 'jsonSchema' && provider != null) {
786
1027
  const { schema: prepared, warnings } = prepareSchemaForProvider(
787
1028
  schema,
788
1029
  provider,
789
- structuredOutputConfig.strict !== false,
1030
+ structuredOutputConfig.strict !== false
790
1031
  );
791
1032
  preparedSchema = prepared;
792
1033
  if (warnings.length > 0) {
793
- console.log('[Graph] Schema preparation warnings:', warnings);
1034
+ console.warn('[Graph] Schema preparation warnings:', warnings);
794
1035
  }
795
1036
  }
796
1037
 
797
1038
  // Use withStructuredOutput to bind the schema
798
1039
  // Always use includeRaw: true internally so we can debug what's returned
799
1040
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
800
- const structuredModel = (model as any).withStructuredOutput(preparedSchema, {
801
- name,
802
- method: method === 'native' ? undefined : method,
803
- includeRaw: true, // Always true internally for debugging
804
- strict: structuredOutputConfig.strict !== false,
805
- });
806
-
807
- console.log('[Graph] Structured output config:', {
808
- name,
809
- method,
810
- provider,
811
- schemaKeys: Object.keys(preparedSchema),
812
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
813
- modelName: (model as any).model || (model as any).modelId || 'unknown',
814
- });
1041
+ const structuredModel = (model as any).withStructuredOutput(
1042
+ preparedSchema,
1043
+ {
1044
+ name,
1045
+ method: method === 'native' ? undefined : method,
1046
+ includeRaw: true, // Always true internally for debugging
1047
+ strict: structuredOutputConfig.strict !== false,
1048
+ }
1049
+ );
815
1050
 
816
1051
  let lastError: Error | undefined;
817
1052
  let attempts = 0;
@@ -822,24 +1057,16 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
822
1057
  // the synthetic "response" tool call events from withStructuredOutput()
823
1058
  const result = await structuredModel.invoke(finalMessages, config);
824
1059
 
825
- // Debug: log what we got back
826
- console.log('[Graph] Structured output raw result type:', typeof result);
827
-
828
1060
  // Check for refusal or truncation in the raw message
829
- if (result?.raw) {
1061
+ if (result?.raw != null) {
830
1062
  const rawMsg = result.raw as AIMessageChunk;
831
- console.log('[Graph] Raw message content type:', typeof rawMsg?.content);
832
- console.log('[Graph] Raw message tool_calls:', rawMsg?.tool_calls?.length ?? 0);
833
- if (rawMsg?.content && typeof rawMsg.content === 'string' && rawMsg.content.length > 0) {
834
- console.log('[Graph] Raw message text content (first 200):', rawMsg.content.substring(0, 200));
835
- }
836
1063
 
837
1064
  // Check stop reason for refusal or truncation
838
- const responseMetadata = rawMsg.response_metadata ?? {};
1065
+ const responseMetadata = rawMsg.response_metadata;
839
1066
  const stopReason =
840
- responseMetadata.stop_reason ?? // Anthropic
841
- responseMetadata.finish_reason ?? // OpenAI
842
- responseMetadata.stopReason; // Bedrock
1067
+ responseMetadata.stop_reason ?? // Anthropic
1068
+ responseMetadata.finish_reason ?? // OpenAI
1069
+ responseMetadata.stopReason; // Bedrock
843
1070
 
844
1071
  if (stopReason === 'max_tokens' || stopReason === 'length') {
845
1072
  throw new StructuredOutputTruncatedError(stopReason);
@@ -847,14 +1074,15 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
847
1074
 
848
1075
  // Check for Anthropic refusal (stop_reason won't be 'refusal' but content may indicate it)
849
1076
  // OpenAI uses message.refusal field
850
- const refusal = (rawMsg as AIMessageChunk & { refusal?: string }).refusal;
851
- if (refusal) {
1077
+ const refusal = (rawMsg as AIMessageChunk & { refusal?: string })
1078
+ .refusal;
1079
+ if (refusal != null && refusal !== '') {
852
1080
  throw new StructuredOutputRefusalError(refusal);
853
1081
  }
854
1082
  }
855
1083
 
856
1084
  // Handle response - we always use includeRaw internally
857
- if (result?.raw && result?.parsed !== undefined) {
1085
+ if (result?.raw != null && result?.parsed !== undefined) {
858
1086
  return {
859
1087
  structuredResponse: result.parsed as Record<string, unknown>,
860
1088
  rawMessage: result.raw as AIMessageChunk,
@@ -952,12 +1180,15 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
952
1180
  // Get a fresh model WITHOUT tools bound
953
1181
  // bindTools() returns RunnableBinding which lacks withStructuredOutput
954
1182
  // Also disable thinking mode - Anthropic/Bedrock doesn't allow tool_choice with thinking enabled
955
- const structuredClientOptions = { ...agentContext.clientOptions } as t.ClientOptions;
1183
+ const structuredClientOptions = {
1184
+ ...agentContext.clientOptions,
1185
+ } as t.ClientOptions;
956
1186
 
957
1187
  // Determine if streaming is possible for this structured output mode
958
1188
  // Native/jsonSchema modes can stream; tool/functionCalling modes cannot (synthetic tool calls break UX)
959
1189
  const resolved = agentContext.resolveStructuredOutputMode();
960
- const canStream = resolved.method === 'jsonSchema' || resolved.method === 'jsonMode';
1190
+ const canStream =
1191
+ resolved.method === 'jsonSchema' || resolved.method === 'jsonMode';
961
1192
  if (!canStream) {
962
1193
  // Disable streaming for function calling mode (synthetic tool calls break streaming UX)
963
1194
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -972,19 +1203,24 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
972
1203
  if (needsThinkingDisabled) {
973
1204
  // Remove thinking configuration for Bedrock
974
1205
  if (agentContext.provider === Providers.BEDROCK) {
975
- const bedrockOpts = structuredClientOptions as t.BedrockAnthropicClientOptions;
976
- if (bedrockOpts.additionalModelRequestFields) {
977
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
978
- const additionalFields = Object.assign({}, bedrockOpts.additionalModelRequestFields) as any;
1206
+ const bedrockOpts =
1207
+ structuredClientOptions as t.BedrockAnthropicClientOptions;
1208
+ if (bedrockOpts.additionalModelRequestFields != null) {
1209
+ const additionalFields = Object.assign(
1210
+ {},
1211
+ bedrockOpts.additionalModelRequestFields
1212
+ ) as Record<string, unknown>;
979
1213
  delete additionalFields.thinking;
980
1214
  delete additionalFields.budgetTokens;
981
- bedrockOpts.additionalModelRequestFields = additionalFields;
1215
+ bedrockOpts.additionalModelRequestFields =
1216
+ additionalFields as t.BedrockAnthropicInput['additionalModelRequestFields'];
982
1217
  }
983
1218
  }
984
1219
 
985
1220
  // Remove thinking configuration for Anthropic direct API
986
1221
  if (agentContext.provider === Providers.ANTHROPIC) {
987
- const anthropicOpts = structuredClientOptions as t.AnthropicClientOptions;
1222
+ const anthropicOpts =
1223
+ structuredClientOptions as t.AnthropicClientOptions;
988
1224
  if (anthropicOpts.thinking) {
989
1225
  delete anthropicOpts.thinking;
990
1226
  }
@@ -1064,7 +1300,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1064
1300
  // (timestamps, user info, tool context) as conversation content instead.
1065
1301
  // Only inject on the first turn when messages don't already have the context marker.
1066
1302
  if (
1067
- agentContext.dynamicContext &&
1303
+ agentContext.dynamicContext != null &&
1304
+ agentContext.dynamicContext !== '' &&
1068
1305
  messages.length > 0 &&
1069
1306
  !messages.some(
1070
1307
  (m) =>
@@ -1090,12 +1327,28 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1090
1327
  }
1091
1328
 
1092
1329
  const toolsForBinding = agentContext.getToolsForBinding();
1330
+
1331
+ // PERF: Detect subsequent ReAct iterations (tool results present in messages)
1332
+ // and reduce thinking budget to minimize per-iteration latency.
1333
+ // First iteration gets the user's configured budget; follow-up turns
1334
+ // use TOOL_TURN_THINKING_BUDGET (1024) since they only need to route
1335
+ // "call next tool" or "produce final response".
1336
+ const isSubsequentIteration = messages.some(
1337
+ (m) => m._getType() === 'tool'
1338
+ );
1339
+ const effectiveClientOptions =
1340
+ isSubsequentIteration && agentContext.clientOptions
1341
+ ? this.getAdaptiveClientOptions(
1342
+ agentContext.clientOptions,
1343
+ agentContext.provider
1344
+ )
1345
+ : agentContext.clientOptions;
1093
1346
  let model =
1094
1347
  this.overrideModel ??
1095
1348
  this.initializeModel({
1096
1349
  tools: toolsForBinding,
1097
1350
  provider: agentContext.provider,
1098
- clientOptions: agentContext.clientOptions,
1351
+ clientOptions: effectiveClientOptions,
1099
1352
  });
1100
1353
 
1101
1354
  if (agentContext.systemRunnable) {
@@ -1120,17 +1373,16 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1120
1373
  // the content for the LLM to understand what to delegate.
1121
1374
  // ====================================================================
1122
1375
  let delegationInjectedPrePrune = false;
1123
- const hasTaskToolPrePrune = agentContext.tools?.some(
1124
- (tool) => {
1125
- const toolName = typeof tool === 'object' && 'name' in tool
1376
+ const hasTaskToolPrePrune = agentContext.tools?.some((tool) => {
1377
+ const toolName =
1378
+ typeof tool === 'object' && 'name' in tool
1126
1379
  ? (tool as { name: string }).name
1127
1380
  : '';
1128
- return toolName === 'task';
1129
- }
1130
- );
1381
+ return toolName === 'task';
1382
+ });
1131
1383
 
1132
1384
  if (
1133
- hasTaskToolPrePrune &&
1385
+ hasTaskToolPrePrune === true &&
1134
1386
  agentContext.tokenCounter &&
1135
1387
  agentContext.maxContextTokens != null
1136
1388
  ) {
@@ -1140,15 +1392,16 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1140
1392
  prePruneTokens += agentContext.tokenCounter(msg);
1141
1393
  }
1142
1394
  // Add instruction tokens (system prompt)
1143
- prePruneTokens += agentContext.instructionTokens ?? 0;
1395
+ prePruneTokens += agentContext.instructionTokens;
1144
1396
 
1145
- const prePruneUtilization = (prePruneTokens / agentContext.maxContextTokens) * 100;
1397
+ const prePruneUtilization =
1398
+ (prePruneTokens / agentContext.maxContextTokens) * 100;
1146
1399
 
1147
1400
  if (prePruneUtilization > 70) {
1148
1401
  console.warn(
1149
1402
  `[Graph] PRE-PRUNE delegation check: ${prePruneUtilization.toFixed(1)}% utilization ` +
1150
- `(${prePruneTokens}/${agentContext.maxContextTokens} tokens). ` +
1151
- `Injecting delegation hint INSTEAD of pruning.`
1403
+ `(${prePruneTokens}/${agentContext.maxContextTokens} tokens). ` +
1404
+ 'Injecting delegation hint INSTEAD of pruning.'
1152
1405
  );
1153
1406
  delegationInjectedPrePrune = true;
1154
1407
  }
@@ -1184,34 +1437,56 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1184
1437
  }
1185
1438
 
1186
1439
  if (agentContext.pruneMessages && !delegationInjectedPrePrune) {
1187
- const { context, indexTokenCountMap, messagesToRefine } = agentContext.pruneMessages({
1188
- messages,
1189
- usageMetadata: agentContext.currentUsage,
1190
- // startOnMessageType: 'human',
1191
- });
1440
+ console.info(
1441
+ `[Graph:ContextMgmt] Pruning messages | inputCount=${messages.length} | maxTokens=${agentContext.maxContextTokens}`
1442
+ );
1443
+ const { context, indexTokenCountMap, messagesToRefine } =
1444
+ agentContext.pruneMessages({
1445
+ messages,
1446
+ usageMetadata: agentContext.currentUsage,
1447
+ // startOnMessageType: 'human',
1448
+ });
1192
1449
  agentContext.indexTokenCountMap = indexTokenCountMap;
1193
1450
  messagesToUse = context;
1451
+ console.info(
1452
+ `[Graph:ContextMgmt] Pruned | kept=${context.length} | discarded=${messagesToRefine.length} | originalCount=${messages.length}`
1453
+ );
1194
1454
 
1195
1455
  // Summarize discarded messages if callback provided
1196
- if (messagesToRefine && messagesToRefine.length > 0 && agentContext.summarizeCallback) {
1456
+ if (messagesToRefine.length > 0 && agentContext.summarizeCallback) {
1457
+ console.info(
1458
+ `[Graph:ContextMgmt] Summarizing ${messagesToRefine.length} discarded messages`
1459
+ );
1197
1460
  try {
1198
- const summary = await agentContext.summarizeCallback(messagesToRefine);
1199
- if (summary) {
1200
- const summaryMsg = new SystemMessage(`[Conversation Summary]\n${summary}`);
1461
+ const summary =
1462
+ await agentContext.summarizeCallback(messagesToRefine);
1463
+ console.info(
1464
+ `[Graph:ContextMgmt] Summary received | len=${summary?.length ?? 0} | hasContent=${summary != null && summary !== ''}`
1465
+ );
1466
+ if (summary != null && summary !== '') {
1467
+ const summaryMsg = new SystemMessage(
1468
+ `[Conversation Summary]\n${summary}`
1469
+ );
1201
1470
  // Insert after system message (if present), before conversation messages
1202
- const systemIdx = messagesToUse[0]?.getType() === 'system' ? 1 : 0;
1471
+ const systemIdx =
1472
+ messagesToUse[0]?.getType() === 'system' ? 1 : 0;
1203
1473
  messagesToUse = [
1204
1474
  ...messagesToUse.slice(0, systemIdx),
1205
1475
  summaryMsg,
1206
1476
  ...messagesToUse.slice(systemIdx),
1207
1477
  ];
1478
+ console.info(
1479
+ `[Graph:ContextMgmt] Summary injected at index ${systemIdx} | finalMsgCount=${messagesToUse.length}`
1480
+ );
1208
1481
  }
1209
1482
  } catch (err) {
1210
1483
  console.error('[Graph] Summarization callback failed:', err);
1211
1484
  }
1212
1485
  }
1213
1486
  } else if (delegationInjectedPrePrune) {
1214
- console.info('[Graph] Skipping pruning — delegation will handle context pressure');
1487
+ console.info(
1488
+ '[Graph] Skipping pruning — delegation will handle context pressure'
1489
+ );
1215
1490
  }
1216
1491
 
1217
1492
  let finalMessages = messagesToUse;
@@ -1338,11 +1613,11 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1338
1613
  | t.BedrockAnthropicClientOptions
1339
1614
  | undefined;
1340
1615
  const modelId =
1341
- bedrockOpts?.model ||
1616
+ bedrockOpts?.model ??
1342
1617
  (agentContext.clientOptions as t.AnthropicClientOptions | undefined)
1343
1618
  ?.modelName;
1344
1619
  const thinkingConfig =
1345
- bedrockOpts?.additionalModelRequestFields?.['thinking'] ||
1620
+ bedrockOpts?.additionalModelRequestFields?.['thinking'] ??
1346
1621
  (agentContext.clientOptions as t.AnthropicClientOptions | undefined)
1347
1622
  ?.thinking;
1348
1623
 
@@ -1383,17 +1658,16 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1383
1658
  // This runs mid-chain — so even if tool responses push context up
1384
1659
  // after the first LLM call, subsequent iterations get the hint.
1385
1660
  // ====================================================================
1386
- const hasTaskToolInContext = agentContext.tools?.some(
1387
- (tool) => {
1388
- const toolName = typeof tool === 'object' && 'name' in tool
1661
+ const hasTaskToolInContext = agentContext.tools?.some((tool) => {
1662
+ const toolName =
1663
+ typeof tool === 'object' && 'name' in tool
1389
1664
  ? (tool as { name: string }).name
1390
1665
  : '';
1391
- return toolName === 'task';
1392
- }
1393
- );
1666
+ return toolName === 'task';
1667
+ });
1394
1668
 
1395
1669
  if (
1396
- hasTaskToolInContext &&
1670
+ hasTaskToolInContext === true &&
1397
1671
  contextAnalytics.utilizationPercent != null &&
1398
1672
  contextAnalytics.maxContextTokens != null
1399
1673
  ) {
@@ -1409,14 +1683,17 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1409
1683
  let documentCount = 0;
1410
1684
  const documentNames: string[] = [];
1411
1685
  for (const msg of finalMessages) {
1412
- const content = typeof msg.content === 'string'
1413
- ? msg.content
1414
- : Array.isArray(msg.content)
1415
- ? msg.content.map((p: unknown) => {
1416
- const part = p as Record<string, unknown>;
1417
- return String(part.text || part.content || '');
1418
- }).join(' ')
1419
- : '';
1686
+ const content =
1687
+ typeof msg.content === 'string'
1688
+ ? msg.content
1689
+ : Array.isArray(msg.content)
1690
+ ? msg.content
1691
+ .map((p: unknown) => {
1692
+ const part = p as Record<string, unknown>;
1693
+ return String(part.text ?? part.content ?? '');
1694
+ })
1695
+ .join(' ')
1696
+ : '';
1420
1697
  // Pattern 1: # "filename" headers in attached document blocks
1421
1698
  const docMatches = content.match(/# "([^"]+)"/g);
1422
1699
  if (docMatches) {
@@ -1429,9 +1706,14 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1429
1706
  }
1430
1707
  }
1431
1708
  // Pattern 2: "The user has attached: **file1, file2**" (embedded files)
1432
- const attachedMatch = content.match(/user has attached:\s*\*\*([^*]+)\*\*/i);
1709
+ const attachedMatch = content.match(
1710
+ /user has attached:\s*\*\*([^*]+)\*\*/i
1711
+ );
1433
1712
  if (attachedMatch) {
1434
- const names = attachedMatch[1].split(',').map((n: string) => n.trim()).filter(Boolean);
1713
+ const names = attachedMatch[1]
1714
+ .split(',')
1715
+ .map((n: string) => n.trim())
1716
+ .filter(Boolean);
1435
1717
  for (const name of names) {
1436
1718
  if (!documentNames.includes(name)) {
1437
1719
  documentNames.push(name);
@@ -1444,61 +1726,67 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1444
1726
  // BASELINE LOG: Always fires so we can verify this code path runs
1445
1727
  console.info(
1446
1728
  `[Graph] Context utilization: ${utilization.toFixed(1)}% ` +
1447
- `(${totalTokens}/${maxTokens} tokens, ${remainingTokens} remaining) | ` +
1448
- `hasTaskTool: true | messages: ${finalMessages.length} | docs: ${documentCount}`
1729
+ `(${totalTokens}/${maxTokens} tokens, ${remainingTokens} remaining) | ` +
1730
+ `hasTaskTool: true | messages: ${finalMessages.length} | docs: ${documentCount}`
1449
1731
  );
1450
1732
 
1451
1733
  // TRIGGER 1: Multi-document delegation (3+ documents detected)
1452
1734
  // Only inject on first iteration (no AI messages yet = agent hasn't responded)
1453
1735
  const hasAiResponse = finalMessages.some(
1454
- (m) => m._getType?.() === 'ai' || m._getType?.() === 'tool'
1736
+ (m) => m._getType() === 'ai' || m._getType() === 'tool'
1455
1737
  );
1456
1738
  if (documentCount >= 3 && !hasAiResponse) {
1457
1739
  const pressureMsg = new HumanMessage({
1458
- content: `[MULTI-DOCUMENT PROCESSING — ${documentCount} documents detected]\n` +
1740
+ content:
1741
+ `[MULTI-DOCUMENT PROCESSING — ${documentCount} documents detected]\n` +
1459
1742
  `Documents: ${documentNames.join(', ')}\n\n` +
1460
1743
  `You have ${documentCount} documents attached. For thorough analysis, use the "task" tool ` +
1461
- `to delegate each document (or group of related documents) to a sub-agent.\n` +
1462
- `Each sub-agent has its own fresh context window and can use file_search to retrieve the full document content.\n` +
1463
- `After all sub-agents complete, synthesize their results into a comprehensive response.\n\n` +
1464
- `This approach ensures each document gets full attention without context limitations.`,
1744
+ 'to delegate each document (or group of related documents) to a sub-agent.\n' +
1745
+ 'Each sub-agent has its own fresh context window and can use file_search to retrieve the full document content.\n' +
1746
+ 'After all sub-agents complete, synthesize their results into a comprehensive response.\n\n' +
1747
+ 'This approach ensures each document gets full attention without context limitations.',
1465
1748
  });
1466
1749
  finalMessages = [...finalMessages, pressureMsg];
1467
1750
  console.info(
1468
1751
  `[Graph] Multi-document delegation hint injected for ${documentCount} documents: ` +
1469
- `${documentNames.join(', ')}`
1752
+ `${documentNames.join(', ')}`
1470
1753
  );
1471
1754
  }
1472
1755
 
1473
1756
  // TRIGGER 2: Token utilization thresholds (mid-chain safety net)
1474
1757
  // Also fires when we skipped pruning due to delegationInjectedPrePrune
1475
- if (utilization > 85 || (delegationInjectedPrePrune && utilization > 50)) {
1758
+ if (
1759
+ utilization > 85 ||
1760
+ (delegationInjectedPrePrune && utilization > 50)
1761
+ ) {
1476
1762
  // CRITICAL: Context is high — MANDATE delegation
1477
1763
  const pressureMsg = new HumanMessage({
1478
- content: `[CONTEXT BUDGET CRITICAL — ${utilization.toFixed(0)}% used]\n` +
1764
+ content:
1765
+ `[CONTEXT BUDGET CRITICAL — ${utilization.toFixed(0)}% used]\n` +
1479
1766
  `You have used ${totalTokens} of ${maxTokens} tokens (${remainingTokens} remaining).\n` +
1480
- `Your context is very large. You MUST use the "task" tool to delegate work to sub-agents.\n` +
1481
- `Each sub-agent runs in its own fresh context window and can use file_search to access documents.\n` +
1482
- `Do NOT attempt to process documents directly — delegate each document to a sub-agent, then synthesize results.`,
1767
+ 'Your context is very large. You MUST use the "task" tool to delegate work to sub-agents.\n' +
1768
+ 'Each sub-agent runs in its own fresh context window and can use file_search to access documents.\n' +
1769
+ 'Do NOT attempt to process documents directly — delegate each document to a sub-agent, then synthesize results.',
1483
1770
  });
1484
1771
  finalMessages = [...finalMessages, pressureMsg];
1485
1772
  console.warn(
1486
1773
  `[Graph] Context pressure CRITICAL (${utilization.toFixed(0)}%): ` +
1487
- `Injected mandatory delegation hint. ${remainingTokens} tokens remaining. ` +
1488
- `prePruneSkipped: ${delegationInjectedPrePrune}`
1774
+ `Injected mandatory delegation hint. ${remainingTokens} tokens remaining. ` +
1775
+ `prePruneSkipped: ${delegationInjectedPrePrune}`
1489
1776
  );
1490
1777
  } else if (utilization > 70) {
1491
1778
  // WARNING: Context filling up — suggest delegation
1492
1779
  const pressureMsg = new HumanMessage({
1493
- content: `[CONTEXT BUDGET WARNING — ${utilization.toFixed(0)}% used]\n` +
1780
+ content:
1781
+ `[CONTEXT BUDGET WARNING — ${utilization.toFixed(0)}% used]\n` +
1494
1782
  `You have used ${totalTokens} of ${maxTokens} tokens (${remainingTokens} remaining).\n` +
1495
- `Your context is filling up. Consider using the "task" tool to delegate complex operations to sub-agents.\n` +
1496
- `Sub-agents run in fresh context windows and won't consume your remaining budget.`,
1783
+ 'Your context is filling up. Consider using the "task" tool to delegate complex operations to sub-agents.\n' +
1784
+ "Sub-agents run in fresh context windows and won't consume your remaining budget.",
1497
1785
  });
1498
1786
  finalMessages = [...finalMessages, pressureMsg];
1499
1787
  console.info(
1500
1788
  `[Graph] Context pressure WARNING (${utilization.toFixed(0)}%): ` +
1501
- `Injected delegation suggestion. ${remainingTokens} tokens remaining.`
1789
+ `Injected delegation suggestion. ${remainingTokens} tokens remaining.`
1502
1790
  );
1503
1791
  }
1504
1792
  }
@@ -1541,8 +1829,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1541
1829
  );
1542
1830
  } catch (primaryError) {
1543
1831
  // Check if this is a "input too long" error from Bedrock/Anthropic
1544
- const errorMessage =
1545
- (primaryError as Error).message.toLowerCase() ?? '';
1832
+ const errorMessage = (primaryError as Error).message.toLowerCase();
1546
1833
  const isInputTooLongError =
1547
1834
  errorMessage.includes('too long') ||
1548
1835
  errorMessage.includes('input is too long') ||
@@ -1569,7 +1856,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1569
1856
  // If input too long and we have pruning capability OR tokenCounter, retry with progressively more aggressive pruning
1570
1857
  // Note: We can create emergency pruneMessages dynamically if we have tokenCounter and maxContextTokens
1571
1858
  const canPrune =
1572
- agentContext.tokenCounter && agentContext.maxContextTokens;
1859
+ agentContext.tokenCounter != null &&
1860
+ agentContext.maxContextTokens != null &&
1861
+ agentContext.maxContextTokens > 0;
1573
1862
  if (isInputTooLongError && canPrune) {
1574
1863
  // Progressive reduction: 50% -> 25% -> 10% of original context
1575
1864
  const reductionLevels = [0.5, 0.25, 0.1];
@@ -1689,8 +1978,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1689
1978
  `[Graph] ✅ Retry successful at ${reductionFactor * 100}% with ${reducedMessages.length} messages (reduced from ${finalMessages.length})`
1690
1979
  );
1691
1980
  } catch (retryError) {
1692
- const retryErrorMsg =
1693
- (retryError as Error).message.toLowerCase() ?? '';
1981
+ const retryErrorMsg = (retryError as Error).message.toLowerCase();
1694
1982
  const stillTooLong =
1695
1983
  retryErrorMsg.includes('too long') ||
1696
1984
  retryErrorMsg.includes('context length') ||
@@ -1752,6 +2040,128 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1752
2040
  if (!result) {
1753
2041
  throw new Error('No result after model invocation');
1754
2042
  }
2043
+
2044
+ /**
2045
+ * Fallback: populate toolCallStepIds in the graph execution context.
2046
+ *
2047
+ * When model.stream() is available (the common case), attemptInvoke
2048
+ * processes all chunks through a local ChatModelStreamHandler which
2049
+ * creates run steps and populates toolCallStepIds before returning.
2050
+ * The code below is a fallback for the rare case where model.stream
2051
+ * is unavailable and model.invoke() was used instead.
2052
+ *
2053
+ * Text content is dispatched FIRST so that MESSAGE_CREATION is the
2054
+ * current step when handleToolCalls runs. handleToolCalls then creates
2055
+ * TOOL_CALLS on top of it. The dedup in getMessageId and
2056
+ * toolCallStepIds.has makes this safe when attemptInvoke already
2057
+ * handled everything — both paths become no-ops.
2058
+ */
2059
+ const responseMessage = result.messages?.[0];
2060
+ const toolCalls = (responseMessage as AIMessageChunk | undefined)
2061
+ ?.tool_calls;
2062
+ const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
2063
+
2064
+ if (hasToolCalls) {
2065
+ const metadata = config.metadata as Record<string, unknown>;
2066
+ const stepKey = this.getStepKey(metadata);
2067
+ const content = responseMessage?.content as MessageContent | undefined;
2068
+ const hasTextContent =
2069
+ content != null &&
2070
+ (typeof content === 'string'
2071
+ ? content !== ''
2072
+ : Array.isArray(content) && content.length > 0);
2073
+
2074
+ /**
2075
+ * Dispatch text content BEFORE creating TOOL_CALLS steps.
2076
+ * getMessageId returns a new ID only on the first call for a step key;
2077
+ * if the for-await consumer already claimed it, this is a no-op.
2078
+ */
2079
+ if (hasTextContent) {
2080
+ const messageId = getMessageId(stepKey, this) ?? '';
2081
+ if (messageId) {
2082
+ await this.dispatchRunStep(
2083
+ stepKey,
2084
+ {
2085
+ type: StepTypes.MESSAGE_CREATION,
2086
+ message_creation: { message_id: messageId },
2087
+ },
2088
+ metadata
2089
+ );
2090
+ const stepId = this.getStepIdByKey(stepKey);
2091
+ if (typeof content === 'string') {
2092
+ await this.dispatchMessageDelta(stepId, {
2093
+ content: [{ type: ContentTypes.TEXT, text: content }],
2094
+ });
2095
+ } else if (
2096
+ Array.isArray(content) &&
2097
+ content.every(
2098
+ (c) =>
2099
+ typeof c === 'object' &&
2100
+ 'type' in c &&
2101
+ typeof c.type === 'string' &&
2102
+ c.type.startsWith('text')
2103
+ )
2104
+ ) {
2105
+ await this.dispatchMessageDelta(stepId, {
2106
+ content: content as t.MessageDelta['content'],
2107
+ });
2108
+ }
2109
+ }
2110
+ }
2111
+
2112
+ await handleToolCalls(toolCalls as ToolCall[], metadata, this);
2113
+ }
2114
+
2115
+ /**
2116
+ * When streaming is disabled, on_chat_model_stream events are never
2117
+ * emitted so ChatModelStreamHandler never fires. Dispatch the text
2118
+ * content as MESSAGE_CREATION + MESSAGE_DELTA here.
2119
+ */
2120
+ const disableStreaming =
2121
+ (agentContext.clientOptions as t.OpenAIClientOptions | undefined)
2122
+ ?.disableStreaming === true;
2123
+
2124
+ if (
2125
+ disableStreaming &&
2126
+ !hasToolCalls &&
2127
+ responseMessage != null &&
2128
+ (responseMessage.content as MessageContent | undefined) != null
2129
+ ) {
2130
+ const metadata = config.metadata as Record<string, unknown>;
2131
+ const stepKey = this.getStepKey(metadata);
2132
+ const messageId = getMessageId(stepKey, this) ?? '';
2133
+ if (messageId) {
2134
+ await this.dispatchRunStep(
2135
+ stepKey,
2136
+ {
2137
+ type: StepTypes.MESSAGE_CREATION,
2138
+ message_creation: { message_id: messageId },
2139
+ },
2140
+ metadata
2141
+ );
2142
+ const stepId = this.getStepIdByKey(stepKey);
2143
+ const content = responseMessage.content;
2144
+ if (typeof content === 'string') {
2145
+ await this.dispatchMessageDelta(stepId, {
2146
+ content: [{ type: ContentTypes.TEXT, text: content }],
2147
+ });
2148
+ } else if (
2149
+ Array.isArray(content) &&
2150
+ content.every(
2151
+ (c) =>
2152
+ typeof c === 'object' &&
2153
+ 'type' in c &&
2154
+ typeof c.type === 'string' &&
2155
+ c.type.startsWith('text')
2156
+ )
2157
+ ) {
2158
+ await this.dispatchMessageDelta(stepId, {
2159
+ content: content as t.MessageDelta['content'],
2160
+ });
2161
+ }
2162
+ }
2163
+ }
2164
+
1755
2165
  agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
1756
2166
 
1757
2167
  // Extract and normalize the LLM's finish/stop reason for auto-continuation support
@@ -1759,14 +2169,15 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1759
2169
  if (finalMsg && 'response_metadata' in finalMsg) {
1760
2170
  const meta = finalMsg.response_metadata as Record<string, unknown>;
1761
2171
  // Bedrock streaming nests stopReason inside messageStop: { stopReason: '...' }
1762
- const messageStop = meta.messageStop as Record<string, unknown> | undefined;
2172
+ const messageStop = meta.messageStop as
2173
+ | Record<string, unknown>
2174
+ | undefined;
1763
2175
  this.lastFinishReason =
1764
- (meta.finish_reason as string) ?? // OpenAI/Azure
1765
- (meta.stop_reason as string) ?? // Anthropic direct API
1766
- (meta.stopReason as string) ?? // Bedrock invoke (non-streaming)
1767
- (messageStop?.stopReason as string) ?? // Bedrock streaming
1768
- (meta.finishReason as string) ?? // VertexAI/Google
1769
- undefined;
2176
+ (meta.finish_reason as string | undefined) ?? // OpenAI/Azure
2177
+ (meta.stop_reason as string | undefined) ?? // Anthropic direct API
2178
+ (meta.stopReason as string | undefined) ?? // Bedrock invoke (non-streaming)
2179
+ (messageStop?.stopReason as string | undefined) ?? // Bedrock streaming
2180
+ (meta.finishReason as string | undefined); // VertexAI/Google
1770
2181
  }
1771
2182
 
1772
2183
  this.cleanupSignalListener();
@@ -1776,16 +2187,15 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1776
2187
  // has NO tool_calls (it's done with tools), we produce the final structured JSON response.
1777
2188
  if (
1778
2189
  agentContext.isStructuredOutputMode &&
1779
- agentContext.structuredOutput &&
1780
- result
2190
+ agentContext.structuredOutput != null
1781
2191
  ) {
1782
2192
  const lastMessage = result.messages?.[0];
1783
2193
  const resultHasToolCalls =
1784
- lastMessage &&
2194
+ lastMessage != null &&
1785
2195
  'tool_calls' in lastMessage &&
1786
2196
  ((lastMessage as AIMessageChunk).tool_calls?.length ?? 0) > 0;
1787
2197
 
1788
- if (!resultHasToolCalls) {
2198
+ if (resultHasToolCalls !== true) {
1789
2199
  try {
1790
2200
  // Build messages for structured output: include the full conversation
1791
2201
  // plus the agent's text response from attemptInvoke, so the structured
@@ -1892,6 +2302,13 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1892
2302
  reducer: (a, b) => {
1893
2303
  if (!a.length) {
1894
2304
  this.startIndex = a.length + b.length;
2305
+ console.info(
2306
+ `[Graph:Reducer] Initial messages | startIndex=${this.startIndex} | inputMsgCount=${b.length}`
2307
+ );
2308
+ } else {
2309
+ console.debug(
2310
+ `[Graph:Reducer] Appending messages | existing=${a.length} | new=${b.length} | startIndex=${this.startIndex}`
2311
+ );
1895
2312
  }
1896
2313
  const result = messagesStateReducer(a, b);
1897
2314
  this.messages = result;
@@ -2121,6 +2538,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
2121
2538
  this
2122
2539
  );
2123
2540
  }
2541
+
2124
2542
  /**
2125
2543
  * Static version of handleToolCallError to avoid creating strong references
2126
2544
  * that prevent garbage collection