@illuma-ai/agents 1.0.90 → 1.0.93

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 (838) 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 +46 -4
  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 +46 -4
  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 +2 -2
  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 +62 -4
  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__/ProgrammaticToolCalling.integration.test.js +276 -0
  718. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.js.map +1 -0
  719. package/src/tools/__tests__/ProgrammaticToolCalling.test.js +807 -0
  720. package/src/tools/__tests__/ProgrammaticToolCalling.test.js.map +1 -0
  721. package/src/tools/__tests__/StreamingToolCallBuffer.test.js +175 -0
  722. package/src/tools/__tests__/StreamingToolCallBuffer.test.js.map +1 -0
  723. package/src/tools/__tests__/StreamingToolCallBuffer.test.ts +263 -0
  724. package/src/tools/__tests__/ToolApproval.test.js +675 -0
  725. package/src/tools/__tests__/ToolApproval.test.js.map +1 -0
  726. package/src/tools/__tests__/ToolApproval.test.ts +194 -20
  727. package/src/tools/__tests__/ToolNode.hitl.test.ts +267 -0
  728. package/src/tools/__tests__/ToolNode.recovery.test.js +200 -0
  729. package/src/tools/__tests__/ToolNode.recovery.test.js.map +1 -0
  730. package/src/tools/__tests__/ToolNode.recovery.test.ts +276 -0
  731. package/src/tools/__tests__/ToolNode.session.test.js +319 -0
  732. package/src/tools/__tests__/ToolNode.session.test.js.map +1 -0
  733. package/src/tools/__tests__/ToolNode.session.test.ts +465 -0
  734. package/src/tools/__tests__/ToolSearch.integration.test.js +125 -0
  735. package/src/tools/__tests__/ToolSearch.integration.test.js.map +1 -0
  736. package/src/tools/__tests__/ToolSearch.test.js +812 -0
  737. package/src/tools/__tests__/ToolSearch.test.js.map +1 -0
  738. package/src/tools/__tests__/ToolSearch.test.ts +78 -5
  739. package/src/tools/__tests__/handlers.test.js +799 -0
  740. package/src/tools/__tests__/handlers.test.js.map +1 -0
  741. package/src/tools/__tests__/handlers.test.ts +1100 -0
  742. package/src/tools/__tests__/truncation-recovery.integration.test.js +362 -0
  743. package/src/tools/__tests__/truncation-recovery.integration.test.js.map +1 -0
  744. package/src/tools/__tests__/truncation-recovery.integration.test.ts +560 -0
  745. package/src/tools/handlers.js +306 -0
  746. package/src/tools/handlers.js.map +1 -0
  747. package/src/tools/handlers.ts +119 -16
  748. package/src/tools/schema.js +25 -0
  749. package/src/tools/schema.js.map +1 -0
  750. package/src/tools/search/anthropic.js +34 -0
  751. package/src/tools/search/anthropic.js.map +1 -0
  752. package/src/tools/search/content.js +116 -0
  753. package/src/tools/search/content.js.map +1 -0
  754. package/src/tools/search/content.test.js +133 -0
  755. package/src/tools/search/content.test.js.map +1 -0
  756. package/src/tools/search/firecrawl.js +173 -0
  757. package/src/tools/search/firecrawl.js.map +1 -0
  758. package/src/tools/search/format.js +198 -0
  759. package/src/tools/search/format.js.map +1 -0
  760. package/src/tools/search/highlights.js +241 -0
  761. package/src/tools/search/highlights.js.map +1 -0
  762. package/src/tools/search/index.js +3 -0
  763. package/src/tools/search/index.js.map +1 -0
  764. package/src/tools/search/jina-reranker.test.js +106 -0
  765. package/src/tools/search/jina-reranker.test.js.map +1 -0
  766. package/src/tools/search/rerankers.js +165 -0
  767. package/src/tools/search/rerankers.js.map +1 -0
  768. package/src/tools/search/schema.js +102 -0
  769. package/src/tools/search/schema.js.map +1 -0
  770. package/src/tools/search/search.js +561 -0
  771. package/src/tools/search/search.js.map +1 -0
  772. package/src/tools/search/serper-scraper.js +126 -0
  773. package/src/tools/search/serper-scraper.js.map +1 -0
  774. package/src/tools/search/test.js +129 -0
  775. package/src/tools/search/test.js.map +1 -0
  776. package/src/tools/search/tool.js +453 -0
  777. package/src/tools/search/tool.js.map +1 -0
  778. package/src/tools/search/types.js +2 -0
  779. package/src/tools/search/types.js.map +1 -0
  780. package/src/tools/search/utils.js +59 -0
  781. package/src/tools/search/utils.js.map +1 -0
  782. package/src/types/graph.js +24 -0
  783. package/src/types/graph.js.map +1 -0
  784. package/src/types/graph.test.js +192 -0
  785. package/src/types/graph.test.js.map +1 -0
  786. package/src/types/graph.ts +26 -6
  787. package/src/types/index.js +7 -0
  788. package/src/types/index.js.map +1 -0
  789. package/src/types/llm.js +2 -0
  790. package/src/types/llm.js.map +1 -0
  791. package/src/types/llm.ts +8 -3
  792. package/src/types/messages.js +2 -0
  793. package/src/types/messages.js.map +1 -0
  794. package/src/types/run.js +2 -0
  795. package/src/types/run.js.map +1 -0
  796. package/src/types/run.ts +2 -0
  797. package/src/types/stream.js +2 -0
  798. package/src/types/stream.js.map +1 -0
  799. package/src/types/tools.js +2 -0
  800. package/src/types/tools.js.map +1 -0
  801. package/src/types/tools.ts +21 -2
  802. package/src/utils/contextAnalytics.js +79 -0
  803. package/src/utils/contextAnalytics.js.map +1 -0
  804. package/src/utils/contextAnalytics.test.js +166 -0
  805. package/src/utils/contextAnalytics.test.js.map +1 -0
  806. package/src/utils/contextAnalytics.test.ts +222 -0
  807. package/src/utils/contextAnalytics.ts +27 -9
  808. package/src/utils/events.js +26 -0
  809. package/src/utils/events.js.map +1 -0
  810. package/src/utils/graph.js +11 -0
  811. package/src/utils/graph.js.map +1 -0
  812. package/src/utils/handlers.js +65 -0
  813. package/src/utils/handlers.js.map +1 -0
  814. package/src/utils/index.js +10 -0
  815. package/src/utils/index.js.map +1 -0
  816. package/src/utils/index.ts +1 -0
  817. package/src/utils/llm.js +21 -0
  818. package/src/utils/llm.js.map +1 -0
  819. package/src/utils/llmConfig.js +205 -0
  820. package/src/utils/llmConfig.js.map +1 -0
  821. package/src/utils/llmConfig.ts +5 -5
  822. package/src/utils/logging.js +37 -0
  823. package/src/utils/logging.js.map +1 -0
  824. package/src/utils/misc.js +51 -0
  825. package/src/utils/misc.js.map +1 -0
  826. package/src/utils/run.js +69 -0
  827. package/src/utils/run.js.map +1 -0
  828. package/src/utils/run.ts +108 -106
  829. package/src/utils/schema.js +21 -0
  830. package/src/utils/schema.js.map +1 -0
  831. package/src/utils/title.js +119 -0
  832. package/src/utils/title.js.map +1 -0
  833. package/src/utils/tokens.js +92 -0
  834. package/src/utils/tokens.js.map +1 -0
  835. package/src/utils/tokens.ts +118 -142
  836. package/src/utils/toolCallContinuation.ts +55 -0
  837. package/src/utils/toonFormat.js +379 -0
  838. package/src/utils/toonFormat.js.map +1 -0
@@ -4,17 +4,21 @@ import { ChatVertexAI } from '@langchain/google-vertexai';
4
4
  import { Annotation, messagesStateReducer, StateGraph, START, END } from '@langchain/langgraph';
5
5
  import { RunnableLambda } from '@langchain/core/runnables';
6
6
  import { SystemMessage, HumanMessage, AIMessageChunk } from '@langchain/core/messages';
7
- import { GraphNodeKeys, ContentTypes, Providers, GraphEvents, MessageTypes, StepTypes, Constants } from '../common/enum.mjs';
8
7
  import { convertMessagesToContent, modifyDeltaProperties, formatAnthropicArtifactContent, formatArtifactPayload } from '../messages/core.mjs';
8
+ import { getMessageId } from '../messages/ids.mjs';
9
9
  import { createPruneMessages } from '../messages/prune.mjs';
10
10
  import { ensureThinkingBlockInMessages } from '../messages/format.mjs';
11
11
  import { addCacheControl, addBedrockCacheControl } from '../messages/cache.mjs';
12
12
  import { formatContentStrings } from '../messages/content.mjs';
13
13
  import { extractToolDiscoveries } from '../messages/tools.mjs';
14
+ import { GraphNodeKeys, Providers, ContentTypes, GraphEvents, MessageTypes, StepTypes, Constants } from '../common/enum.mjs';
15
+ import { TOOL_TURN_THINKING_BUDGET } from '../common/constants.mjs';
14
16
  import { resetIfNotEmpty, joinKeys } from '../utils/graph.mjs';
15
17
  import { isOpenAILike, isGoogleLike } from '../utils/llm.mjs';
18
+ import { ChatModelStreamHandler } from '../stream.mjs';
19
+ import { handleToolCalls } from '../tools/handlers.mjs';
16
20
  import { sleep } from '../utils/run.mjs';
17
- import 'js-tiktoken';
21
+ import 'ai-tokenizer';
18
22
  import '../utils/toonFormat.mjs';
19
23
  import { buildContextAnalytics } from '../utils/contextAnalytics.mjs';
20
24
  import 'zod-to-json-schema';
@@ -27,6 +31,7 @@ import { prepareSchemaForProvider } from '../schemas/validate.mjs';
27
31
  import { AgentContext } from '../agents/AgentContext.mjs';
28
32
  import { StructuredOutputTruncatedError, StructuredOutputRefusalError } from '../types/graph.mjs';
29
33
  import { createFakeStreamingLLM } from '../llm/fake.mjs';
34
+ import { StreamingToolCallBuffer } from '../tools/StreamingToolCallBuffer.mjs';
30
35
 
31
36
  /* eslint-disable no-console */
32
37
  // src/graphs/Graph.ts
@@ -50,6 +55,32 @@ class Graph {
50
55
  * Currently supports code execution session tracking (session_id, files).
51
56
  */
52
57
  sessions = new Map();
58
+ /**
59
+ * Streaming tool call buffer — accumulates raw arg strings during streaming
60
+ * so that truncated tool call content can be recovered by the ToolNode.
61
+ * Fed by handleToolCallChunks, consumed by ToolNode.run when args are incomplete.
62
+ */
63
+ streamingToolCallBuffer = new StreamingToolCallBuffer();
64
+ /**
65
+ * Clears heavy references to allow GC to reclaim memory held by
66
+ * LangGraph's internal config / AsyncLocalStorage RunTree chain.
67
+ * Call after a run completes and content has been extracted.
68
+ */
69
+ clearHeavyState() {
70
+ this.config = undefined;
71
+ this.signal = undefined;
72
+ this.contentData = [];
73
+ this.contentIndexMap = new Map();
74
+ this.stepKeyIds = new Map();
75
+ this.toolCallStepIds.clear();
76
+ this.messageIdsByStepKey = new Map();
77
+ this.messageStepHasToolCalls = new Map();
78
+ this.prelimMessageIdsByStepKey = new Map();
79
+ this.invokedToolIds = undefined;
80
+ this.handlerRegistry = undefined;
81
+ this.sessions.clear();
82
+ this.streamingToolCallBuffer.clearAll();
83
+ }
53
84
  }
54
85
  class StandardGraph extends Graph {
55
86
  overrideModel;
@@ -90,7 +121,13 @@ class StandardGraph extends Graph {
90
121
  this.contentIndexMap = resetIfNotEmpty(this.contentIndexMap, new Map());
91
122
  }
92
123
  this.stepKeyIds = resetIfNotEmpty(this.stepKeyIds, new Map());
93
- this.toolCallStepIds = resetIfNotEmpty(this.toolCallStepIds, new Map());
124
+ /**
125
+ * Clear in-place instead of replacing with a new Map to preserve the
126
+ * shared reference held by ToolNode (passed at construction time).
127
+ * Using resetIfNotEmpty would create a new Map, leaving ToolNode with
128
+ * a stale reference on 2nd+ processStream calls.
129
+ */
130
+ this.toolCallStepIds.clear();
94
131
  this.messageIdsByStepKey = resetIfNotEmpty(this.messageIdsByStepKey, new Map());
95
132
  this.messageStepHasToolCalls = resetIfNotEmpty(this.messageStepHasToolCalls, new Map());
96
133
  this.prelimMessageIdsByStepKey = resetIfNotEmpty(this.prelimMessageIdsByStepKey, new Map());
@@ -99,6 +136,90 @@ class StandardGraph extends Graph {
99
136
  context.reset();
100
137
  }
101
138
  }
139
+ clearHeavyState() {
140
+ super.clearHeavyState();
141
+ this.messages = [];
142
+ this.overrideModel = undefined;
143
+ for (const context of this.agentContexts.values()) {
144
+ context.reset();
145
+ }
146
+ }
147
+ /**
148
+ * Returns clientOptions with a reduced thinking budget for subsequent
149
+ * ReAct loop iterations (tool-result turns).
150
+ *
151
+ * **Rationale:** The first LLM call in a conversation processes the user's
152
+ * original query and may benefit from deep extended thinking. Subsequent
153
+ * iterations — where the model receives tool results and decides whether
154
+ * to call another tool or produce a final response — require minimal
155
+ * reasoning. Reducing the thinking budget from the user's configured
156
+ * value to TOOL_TURN_THINKING_BUDGET (1024 tokens) cuts wall-clock
157
+ * latency by ~15-20s per iteration, compounding across multi-tool flows.
158
+ *
159
+ * Provider handling:
160
+ * - **Anthropic (direct):** Reduces `thinking.budget_tokens` if > threshold
161
+ * - **Bedrock (Anthropic models):** Reduces `additionalModelRequestFields.thinking.budget_tokens`
162
+ * - **VertexAI / Google:** Reduces `thinkingConfig.thinkingBudget` if > threshold
163
+ * - **All others:** Returns clientOptions unchanged (no-op)
164
+ *
165
+ * @param clientOptions - The original client options from AgentContext
166
+ * @param provider - The LLM provider enum value
167
+ * @returns Shallow-cloned clientOptions with reduced thinking budget, or the original if no reduction needed
168
+ */
169
+ getAdaptiveClientOptions(clientOptions, provider) {
170
+ if (provider === Providers.ANTHROPIC) {
171
+ const anthropicOpts = clientOptions;
172
+ if (anthropicOpts.thinking != null &&
173
+ typeof anthropicOpts.thinking === 'object' &&
174
+ 'type' in anthropicOpts.thinking &&
175
+ (anthropicOpts.thinking.type === 'enabled' ||
176
+ anthropicOpts.thinking.type === 'adaptive') &&
177
+ 'budget_tokens' in anthropicOpts.thinking &&
178
+ anthropicOpts.thinking.budget_tokens >
179
+ TOOL_TURN_THINKING_BUDGET) {
180
+ return {
181
+ ...anthropicOpts,
182
+ thinking: {
183
+ ...anthropicOpts.thinking,
184
+ budget_tokens: TOOL_TURN_THINKING_BUDGET,
185
+ },
186
+ };
187
+ }
188
+ }
189
+ if (provider === Providers.BEDROCK) {
190
+ const bedrockOpts = clientOptions;
191
+ const thinkingField = bedrockOpts.additionalModelRequestFields?.thinking;
192
+ if (thinkingField != null &&
193
+ typeof thinkingField === 'object' &&
194
+ 'budget_tokens' in thinkingField &&
195
+ thinkingField.budget_tokens > TOOL_TURN_THINKING_BUDGET) {
196
+ return {
197
+ ...bedrockOpts,
198
+ additionalModelRequestFields: {
199
+ ...(bedrockOpts.additionalModelRequestFields ?? {}),
200
+ thinking: {
201
+ ...thinkingField,
202
+ budget_tokens: TOOL_TURN_THINKING_BUDGET,
203
+ },
204
+ },
205
+ };
206
+ }
207
+ }
208
+ if (provider === Providers.VERTEXAI || provider === Providers.GOOGLE) {
209
+ const googleOpts = clientOptions;
210
+ if (googleOpts.thinkingConfig?.thinkingBudget != null &&
211
+ googleOpts.thinkingConfig.thinkingBudget > TOOL_TURN_THINKING_BUDGET) {
212
+ return {
213
+ ...googleOpts,
214
+ thinkingConfig: {
215
+ ...googleOpts.thinkingConfig,
216
+ thinkingBudget: TOOL_TURN_THINKING_BUDGET,
217
+ },
218
+ };
219
+ }
220
+ }
221
+ return clientOptions;
222
+ }
102
223
  /**
103
224
  * Returns the normalized finish/stop reason from the last LLM invocation.
104
225
  * Used by callers to detect when the response was truncated due to max_tokens.
@@ -135,7 +256,7 @@ class StandardGraph extends Graph {
135
256
  return 'the past few hours';
136
257
  }
137
258
  else if (messageCount <= 300) {
138
- return 'roughly a day\'s worth';
259
+ return "roughly a day's worth";
139
260
  }
140
261
  else if (messageCount <= 700) {
141
262
  return 'the past few days';
@@ -224,7 +345,7 @@ class StandardGraph extends Graph {
224
345
  keyList.push('reasoning');
225
346
  }
226
347
  else if (agentContext.tokenTypeSwitch === 'content') {
227
- keyList.push('post-reasoning');
348
+ keyList.push(`post-reasoning-${agentContext.reasoningTransitionCount}`);
228
349
  }
229
350
  if (this.invokedToolIds != null && this.invokedToolIds.size > 0) {
230
351
  keyList.push(this.invokedToolIds.size + '');
@@ -236,7 +357,9 @@ class StandardGraph extends Graph {
236
357
  }
237
358
  /* Misc.*/
238
359
  getRunMessages() {
239
- return this.messages.slice(this.startIndex);
360
+ const result = this.messages.slice(this.startIndex);
361
+ console.debug(`[Graph] getRunMessages() | totalMessages=${this.messages.length} | startIndex=${this.startIndex} | runMessages=${result.length}`);
362
+ return result;
240
363
  }
241
364
  getContentParts() {
242
365
  return convertMessagesToContent(this.messages.slice(this.startIndex));
@@ -349,26 +472,77 @@ class StandardGraph extends Graph {
349
472
  if (eventDrivenMode) {
350
473
  const schemaTools = createSchemaOnlyTools(toolDefinitions);
351
474
  const toolDefMap = new Map(toolDefinitions.map((def) => [def.name, def]));
475
+ const graphTools = agentContext?.graphTools;
476
+ const directToolNames = new Set();
477
+ const allTools = [...schemaTools];
478
+ const allToolMap = new Map(schemaTools.map((tool) => [tool.name, tool]));
479
+ if (graphTools && graphTools.length > 0) {
480
+ for (const tool of graphTools) {
481
+ if ('name' in tool) {
482
+ allTools.push(tool);
483
+ allToolMap.set(tool.name, tool);
484
+ directToolNames.add(tool.name);
485
+ }
486
+ }
487
+ }
352
488
  return new ToolNode({
353
- tools: schemaTools,
354
- toolMap: new Map(schemaTools.map((tool) => [tool.name, tool])),
355
- toolCallStepIds: this.toolCallStepIds,
356
- errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
357
- toolRegistry: agentContext?.toolRegistry,
358
- sessions: this.sessions,
489
+ tools: allTools,
490
+ toolMap: allToolMap,
359
491
  eventDrivenMode: true,
492
+ sessions: this.sessions,
360
493
  toolDefinitions: toolDefMap,
361
494
  agentId: agentContext?.agentId,
495
+ toolCallStepIds: this.toolCallStepIds,
496
+ toolRegistry: agentContext?.toolRegistry,
497
+ directToolNames: directToolNames.size > 0 ? directToolNames : undefined,
498
+ streamingToolCallBuffer: this.streamingToolCallBuffer,
499
+ errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
362
500
  toolApprovalConfig,
363
501
  });
364
502
  }
503
+ const graphTools = agentContext?.graphTools;
504
+ const baseTools = currentTools ?? [];
505
+ const allTraditionalTools = graphTools && graphTools.length > 0
506
+ ? [...baseTools, ...graphTools]
507
+ : baseTools;
508
+ /**
509
+ * Build tool map from all sources: agent's toolMap, agent's tools array, and graph tools.
510
+ * Previously, baseTools were missing from the map when no explicit toolMap was provided,
511
+ * causing ToolNode to not find agent-defined tools (e.g., custom DynamicStructuredTools).
512
+ */
513
+ const traditionalToolMap = graphTools && graphTools.length > 0
514
+ ? new Map([
515
+ ...(currentToolMap ?? new Map()),
516
+ ...baseTools
517
+ .filter((t) => 'name' in t)
518
+ .map((t) => [t.name, t]),
519
+ ...graphTools
520
+ .filter((t) => 'name' in t)
521
+ .map((t) => [t.name, t]),
522
+ ])
523
+ : currentToolMap;
524
+ /** Build directToolNames from graph-managed tools (handoff/transfer) so HITL can bypass them */
525
+ let directToolNames;
526
+ if (graphTools && graphTools.length > 0) {
527
+ directToolNames = new Set();
528
+ for (const tool of graphTools) {
529
+ if ('name' in tool) {
530
+ directToolNames.add(tool.name);
531
+ }
532
+ }
533
+ if (directToolNames.size === 0) {
534
+ directToolNames = undefined;
535
+ }
536
+ }
365
537
  return new ToolNode({
366
- tools: currentTools ?? [],
367
- toolMap: currentToolMap,
538
+ tools: allTraditionalTools,
539
+ toolMap: traditionalToolMap,
368
540
  toolCallStepIds: this.toolCallStepIds,
541
+ streamingToolCallBuffer: this.streamingToolCallBuffer,
369
542
  errorHandler: (data, metadata) => StandardGraph.handleToolCallErrorStatic(this, data, metadata),
370
543
  toolRegistry: agentContext?.toolRegistry,
371
544
  sessions: this.sessions,
545
+ directToolNames,
372
546
  toolApprovalConfig,
373
547
  });
374
548
  }
@@ -425,25 +599,50 @@ class StandardGraph extends Graph {
425
599
  }
426
600
  }
427
601
  /** Execute model invocation with streaming support */
428
- async attemptInvoke({ currentModel, finalMessages, provider, tools, }, config) {
602
+ async attemptInvoke({ currentModel, finalMessages, provider, tools: _tools, }, config) {
429
603
  const model = this.overrideModel ?? currentModel;
430
604
  if (!model) {
431
605
  throw new Error('No model found');
432
606
  }
433
- if ((tools?.length ?? 0) > 0 && manualToolStreamProviders.has(provider)) {
434
- if (!model.stream) {
435
- throw new Error('Model does not support stream');
436
- }
607
+ if (model.stream) {
608
+ /**
609
+ * Process all model output through a local ChatModelStreamHandler in the
610
+ * graph execution context. Each chunk is awaited before the next one is
611
+ * consumed, so by the time the stream is exhausted every run step
612
+ * (MESSAGE_CREATION, TOOL_CALLS) has been created and toolCallStepIds is
613
+ * fully populated — the graph will not transition to ToolNode until this
614
+ * is done.
615
+ *
616
+ * This replaces the previous pattern where ChatModelStreamHandler lived
617
+ * in the for-await stream consumer (handler registry). That consumer
618
+ * runs concurrently with graph execution, so the graph could advance to
619
+ * ToolNode before the consumer had processed all events. By handling
620
+ * chunks here, inside the agent node, the race is eliminated.
621
+ *
622
+ * The for-await consumer no longer needs a ChatModelStreamHandler; its
623
+ * on_chat_model_stream events are simply ignored (no handler registered).
624
+ * The dispatched custom events (ON_RUN_STEP, ON_MESSAGE_DELTA, etc.)
625
+ * still reach the content aggregator and SSE handlers through the custom
626
+ * event callback in Run.createCustomEventCallback.
627
+ */
628
+ const metadata = config?.metadata;
629
+ const streamHandler = new ChatModelStreamHandler();
437
630
  const stream = await model.stream(finalMessages, config);
438
631
  let finalChunk;
439
632
  for await (const chunk of stream) {
440
- await safeDispatchCustomEvent(GraphEvents.CHAT_MODEL_STREAM, { chunk, emitted: true }, config);
633
+ await streamHandler.handle(GraphEvents.CHAT_MODEL_STREAM, { chunk }, metadata, this);
441
634
  finalChunk = finalChunk ? concat(finalChunk, chunk) : chunk;
442
635
  }
443
- finalChunk = modifyDeltaProperties(provider, finalChunk);
636
+ if (manualToolStreamProviders.has(provider)) {
637
+ finalChunk = modifyDeltaProperties(provider, finalChunk);
638
+ }
639
+ if ((finalChunk?.tool_calls?.length ?? 0) > 0) {
640
+ finalChunk.tool_calls = finalChunk.tool_calls?.filter((tool_call) => !!tool_call.name);
641
+ }
444
642
  return { messages: [finalChunk] };
445
643
  }
446
644
  else {
645
+ /** Fallback for models without stream support. */
447
646
  const finalMessage = await model.invoke(finalMessages, config);
448
647
  if ((finalMessage.tool_calls?.length ?? 0) > 0) {
449
648
  finalMessage.tool_calls = finalMessage.tool_calls?.filter((tool_call) => !!tool_call.name);
@@ -463,15 +662,12 @@ class StandardGraph extends Graph {
463
662
  */
464
663
  async attemptStructuredInvoke({ currentModel, finalMessages, schema, structuredOutputConfig, provider, agentContext, }, config) {
465
664
  const model = this.overrideModel ?? currentModel;
466
- if (!model) {
467
- throw new Error('No model found');
468
- }
469
665
  // Check if model supports withStructuredOutput
470
666
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
471
667
  if (typeof model.withStructuredOutput !== 'function') {
472
- throw new Error(`The selected model does not support structured output. ` +
473
- `Please use a model that supports JSON schema output (e.g., OpenAI GPT-4, Anthropic Claude, Google Gemini) ` +
474
- `or disable structured output for this agent.`);
668
+ throw new Error('The selected model does not support structured output. ' +
669
+ 'Please use a model that supports JSON schema output (e.g., OpenAI GPT-4, Anthropic Claude, Google Gemini) ' +
670
+ 'or disable structured output for this agent.');
475
671
  }
476
672
  const { name = 'StructuredResponse', includeRaw: _includeRaw = false, handleErrors = true, maxRetries = 2, } = structuredOutputConfig;
477
673
  // Resolve the structured output method using AgentContext's provider-aware logic
@@ -490,7 +686,8 @@ class StandardGraph extends Graph {
490
686
  method = 'functionCalling';
491
687
  }
492
688
  else if (mode === 'provider') {
493
- method = provider === Providers.BEDROCK ? 'functionCalling' : 'jsonMode';
689
+ method =
690
+ provider === Providers.BEDROCK ? 'functionCalling' : 'jsonMode';
494
691
  }
495
692
  else {
496
693
  method = undefined;
@@ -498,11 +695,11 @@ class StandardGraph extends Graph {
498
695
  }
499
696
  // Prepare schema for provider-specific constraints when using native/jsonSchema mode
500
697
  let preparedSchema = schema;
501
- if (method === 'jsonSchema' && provider) {
698
+ if (method === 'jsonSchema' && provider != null) {
502
699
  const { schema: prepared, warnings } = prepareSchemaForProvider(schema, provider, structuredOutputConfig.strict !== false);
503
700
  preparedSchema = prepared;
504
701
  if (warnings.length > 0) {
505
- console.log('[Graph] Schema preparation warnings:', warnings);
702
+ console.warn('[Graph] Schema preparation warnings:', warnings);
506
703
  }
507
704
  }
508
705
  // Use withStructuredOutput to bind the schema
@@ -514,14 +711,6 @@ class StandardGraph extends Graph {
514
711
  includeRaw: true, // Always true internally for debugging
515
712
  strict: structuredOutputConfig.strict !== false,
516
713
  });
517
- console.log('[Graph] Structured output config:', {
518
- name,
519
- method,
520
- provider,
521
- schemaKeys: Object.keys(preparedSchema),
522
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
523
- modelName: model.model || model.modelId || 'unknown',
524
- });
525
714
  let lastError;
526
715
  let attempts = 0;
527
716
  while (attempts <= maxRetries) {
@@ -529,18 +718,11 @@ class StandardGraph extends Graph {
529
718
  // Note: We pass the original config here. The stream aggregator will filter out
530
719
  // the synthetic "response" tool call events from withStructuredOutput()
531
720
  const result = await structuredModel.invoke(finalMessages, config);
532
- // Debug: log what we got back
533
- console.log('[Graph] Structured output raw result type:', typeof result);
534
721
  // Check for refusal or truncation in the raw message
535
- if (result?.raw) {
722
+ if (result?.raw != null) {
536
723
  const rawMsg = result.raw;
537
- console.log('[Graph] Raw message content type:', typeof rawMsg?.content);
538
- console.log('[Graph] Raw message tool_calls:', rawMsg?.tool_calls?.length ?? 0);
539
- if (rawMsg?.content && typeof rawMsg.content === 'string' && rawMsg.content.length > 0) {
540
- console.log('[Graph] Raw message text content (first 200):', rawMsg.content.substring(0, 200));
541
- }
542
724
  // Check stop reason for refusal or truncation
543
- const responseMetadata = rawMsg.response_metadata ?? {};
725
+ const responseMetadata = rawMsg.response_metadata;
544
726
  const stopReason = responseMetadata.stop_reason ?? // Anthropic
545
727
  responseMetadata.finish_reason ?? // OpenAI
546
728
  responseMetadata.stopReason; // Bedrock
@@ -549,13 +731,14 @@ class StandardGraph extends Graph {
549
731
  }
550
732
  // Check for Anthropic refusal (stop_reason won't be 'refusal' but content may indicate it)
551
733
  // OpenAI uses message.refusal field
552
- const refusal = rawMsg.refusal;
553
- if (refusal) {
734
+ const refusal = rawMsg
735
+ .refusal;
736
+ if (refusal != null && refusal !== '') {
554
737
  throw new StructuredOutputRefusalError(refusal);
555
738
  }
556
739
  }
557
740
  // Handle response - we always use includeRaw internally
558
- if (result?.raw && result?.parsed !== undefined) {
741
+ if (result?.raw != null && result?.parsed !== undefined) {
559
742
  return {
560
743
  structuredResponse: result.parsed,
561
744
  rawMessage: result.raw,
@@ -628,7 +811,9 @@ class StandardGraph extends Graph {
628
811
  // Get a fresh model WITHOUT tools bound
629
812
  // bindTools() returns RunnableBinding which lacks withStructuredOutput
630
813
  // Also disable thinking mode - Anthropic/Bedrock doesn't allow tool_choice with thinking enabled
631
- const structuredClientOptions = { ...agentContext.clientOptions };
814
+ const structuredClientOptions = {
815
+ ...agentContext.clientOptions,
816
+ };
632
817
  // Determine if streaming is possible for this structured output mode
633
818
  // Native/jsonSchema modes can stream; tool/functionCalling modes cannot (synthetic tool calls break UX)
634
819
  const resolved = agentContext.resolveStructuredOutputMode();
@@ -646,12 +831,12 @@ class StandardGraph extends Graph {
646
831
  // Remove thinking configuration for Bedrock
647
832
  if (agentContext.provider === Providers.BEDROCK) {
648
833
  const bedrockOpts = structuredClientOptions;
649
- if (bedrockOpts.additionalModelRequestFields) {
650
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
834
+ if (bedrockOpts.additionalModelRequestFields != null) {
651
835
  const additionalFields = Object.assign({}, bedrockOpts.additionalModelRequestFields);
652
836
  delete additionalFields.thinking;
653
837
  delete additionalFields.budgetTokens;
654
- bedrockOpts.additionalModelRequestFields = additionalFields;
838
+ bedrockOpts.additionalModelRequestFields =
839
+ additionalFields;
655
840
  }
656
841
  }
657
842
  // Remove thinking configuration for Anthropic direct API
@@ -715,7 +900,8 @@ class StandardGraph extends Graph {
715
900
  // This keeps the system message static (cacheable) while providing dynamic context
716
901
  // (timestamps, user info, tool context) as conversation content instead.
717
902
  // Only inject on the first turn when messages don't already have the context marker.
718
- if (agentContext.dynamicContext &&
903
+ if (agentContext.dynamicContext != null &&
904
+ agentContext.dynamicContext !== '' &&
719
905
  messages.length > 0 &&
720
906
  !messages.some((m) => m instanceof HumanMessage &&
721
907
  typeof m.content === 'string' &&
@@ -734,11 +920,20 @@ class StandardGraph extends Graph {
734
920
  agentContext.markToolsAsDiscovered(discoveredNames);
735
921
  }
736
922
  const toolsForBinding = agentContext.getToolsForBinding();
923
+ // PERF: Detect subsequent ReAct iterations (tool results present in messages)
924
+ // and reduce thinking budget to minimize per-iteration latency.
925
+ // First iteration gets the user's configured budget; follow-up turns
926
+ // use TOOL_TURN_THINKING_BUDGET (1024) since they only need to route
927
+ // "call next tool" or "produce final response".
928
+ const isSubsequentIteration = messages.some((m) => m._getType() === 'tool');
929
+ const effectiveClientOptions = isSubsequentIteration && agentContext.clientOptions
930
+ ? this.getAdaptiveClientOptions(agentContext.clientOptions, agentContext.provider)
931
+ : agentContext.clientOptions;
737
932
  let model = this.overrideModel ??
738
933
  this.initializeModel({
739
934
  tools: toolsForBinding,
740
935
  provider: agentContext.provider,
741
- clientOptions: agentContext.clientOptions,
936
+ clientOptions: effectiveClientOptions,
742
937
  });
743
938
  if (agentContext.systemRunnable) {
744
939
  model = agentContext.systemRunnable.pipe(model);
@@ -765,7 +960,7 @@ class StandardGraph extends Graph {
765
960
  : '';
766
961
  return toolName === 'task';
767
962
  });
768
- if (hasTaskToolPrePrune &&
963
+ if (hasTaskToolPrePrune === true &&
769
964
  agentContext.tokenCounter &&
770
965
  agentContext.maxContextTokens != null) {
771
966
  // Estimate total tokens in messages BEFORE pruning
@@ -774,12 +969,12 @@ class StandardGraph extends Graph {
774
969
  prePruneTokens += agentContext.tokenCounter(msg);
775
970
  }
776
971
  // Add instruction tokens (system prompt)
777
- prePruneTokens += agentContext.instructionTokens ?? 0;
972
+ prePruneTokens += agentContext.instructionTokens;
778
973
  const prePruneUtilization = (prePruneTokens / agentContext.maxContextTokens) * 100;
779
974
  if (prePruneUtilization > 70) {
780
975
  console.warn(`[Graph] PRE-PRUNE delegation check: ${prePruneUtilization.toFixed(1)}% utilization ` +
781
976
  `(${prePruneTokens}/${agentContext.maxContextTokens} tokens). ` +
782
- `Injecting delegation hint INSTEAD of pruning.`);
977
+ 'Injecting delegation hint INSTEAD of pruning.');
783
978
  delegationInjectedPrePrune = true;
784
979
  }
785
980
  }
@@ -806,6 +1001,7 @@ class StandardGraph extends Graph {
806
1001
  });
807
1002
  }
808
1003
  if (agentContext.pruneMessages && !delegationInjectedPrePrune) {
1004
+ console.info(`[Graph:ContextMgmt] Pruning messages | inputCount=${messages.length} | maxTokens=${agentContext.maxContextTokens}`);
809
1005
  const { context, indexTokenCountMap, messagesToRefine } = agentContext.pruneMessages({
810
1006
  messages,
811
1007
  usageMetadata: agentContext.currentUsage,
@@ -813,11 +1009,14 @@ class StandardGraph extends Graph {
813
1009
  });
814
1010
  agentContext.indexTokenCountMap = indexTokenCountMap;
815
1011
  messagesToUse = context;
1012
+ console.info(`[Graph:ContextMgmt] Pruned | kept=${context.length} | discarded=${messagesToRefine.length} | originalCount=${messages.length}`);
816
1013
  // Summarize discarded messages if callback provided
817
- if (messagesToRefine && messagesToRefine.length > 0 && agentContext.summarizeCallback) {
1014
+ if (messagesToRefine.length > 0 && agentContext.summarizeCallback) {
1015
+ console.info(`[Graph:ContextMgmt] Summarizing ${messagesToRefine.length} discarded messages`);
818
1016
  try {
819
1017
  const summary = await agentContext.summarizeCallback(messagesToRefine);
820
- if (summary) {
1018
+ console.info(`[Graph:ContextMgmt] Summary received | len=${summary?.length ?? 0} | hasContent=${summary != null && summary !== ''}`);
1019
+ if (summary != null && summary !== '') {
821
1020
  const summaryMsg = new SystemMessage(`[Conversation Summary]\n${summary}`);
822
1021
  // Insert after system message (if present), before conversation messages
823
1022
  const systemIdx = messagesToUse[0]?.getType() === 'system' ? 1 : 0;
@@ -826,6 +1025,7 @@ class StandardGraph extends Graph {
826
1025
  summaryMsg,
827
1026
  ...messagesToUse.slice(systemIdx),
828
1027
  ];
1028
+ console.info(`[Graph:ContextMgmt] Summary injected at index ${systemIdx} | finalMsgCount=${messagesToUse.length}`);
829
1029
  }
830
1030
  }
831
1031
  catch (err) {
@@ -924,10 +1124,10 @@ class StandardGraph extends Graph {
924
1124
  }
925
1125
  // Get model info for analytics
926
1126
  const bedrockOpts = agentContext.clientOptions;
927
- const modelId = bedrockOpts?.model ||
1127
+ const modelId = bedrockOpts?.model ??
928
1128
  agentContext.clientOptions
929
1129
  ?.modelName;
930
- const thinkingConfig = bedrockOpts?.additionalModelRequestFields?.['thinking'] ||
1130
+ const thinkingConfig = bedrockOpts?.additionalModelRequestFields?.['thinking'] ??
931
1131
  agentContext.clientOptions
932
1132
  ?.thinking;
933
1133
  // Build and emit context analytics for traces
@@ -966,7 +1166,7 @@ class StandardGraph extends Graph {
966
1166
  : '';
967
1167
  return toolName === 'task';
968
1168
  });
969
- if (hasTaskToolInContext &&
1169
+ if (hasTaskToolInContext === true &&
970
1170
  contextAnalytics.utilizationPercent != null &&
971
1171
  contextAnalytics.maxContextTokens != null) {
972
1172
  const utilization = contextAnalytics.utilizationPercent;
@@ -983,10 +1183,12 @@ class StandardGraph extends Graph {
983
1183
  const content = typeof msg.content === 'string'
984
1184
  ? msg.content
985
1185
  : Array.isArray(msg.content)
986
- ? msg.content.map((p) => {
1186
+ ? msg.content
1187
+ .map((p) => {
987
1188
  const part = p;
988
- return String(part.text || part.content || '');
989
- }).join(' ')
1189
+ return String(part.text ?? part.content ?? '');
1190
+ })
1191
+ .join(' ')
990
1192
  : '';
991
1193
  // Pattern 1: # "filename" headers in attached document blocks
992
1194
  const docMatches = content.match(/# "([^"]+)"/g);
@@ -1002,7 +1204,10 @@ class StandardGraph extends Graph {
1002
1204
  // Pattern 2: "The user has attached: **file1, file2**" (embedded files)
1003
1205
  const attachedMatch = content.match(/user has attached:\s*\*\*([^*]+)\*\*/i);
1004
1206
  if (attachedMatch) {
1005
- const names = attachedMatch[1].split(',').map((n) => n.trim()).filter(Boolean);
1207
+ const names = attachedMatch[1]
1208
+ .split(',')
1209
+ .map((n) => n.trim())
1210
+ .filter(Boolean);
1006
1211
  for (const name of names) {
1007
1212
  if (!documentNames.includes(name)) {
1008
1213
  documentNames.push(name);
@@ -1017,16 +1222,16 @@ class StandardGraph extends Graph {
1017
1222
  `hasTaskTool: true | messages: ${finalMessages.length} | docs: ${documentCount}`);
1018
1223
  // TRIGGER 1: Multi-document delegation (3+ documents detected)
1019
1224
  // Only inject on first iteration (no AI messages yet = agent hasn't responded)
1020
- const hasAiResponse = finalMessages.some((m) => m._getType?.() === 'ai' || m._getType?.() === 'tool');
1225
+ const hasAiResponse = finalMessages.some((m) => m._getType() === 'ai' || m._getType() === 'tool');
1021
1226
  if (documentCount >= 3 && !hasAiResponse) {
1022
1227
  const pressureMsg = new HumanMessage({
1023
1228
  content: `[MULTI-DOCUMENT PROCESSING — ${documentCount} documents detected]\n` +
1024
1229
  `Documents: ${documentNames.join(', ')}\n\n` +
1025
1230
  `You have ${documentCount} documents attached. For thorough analysis, use the "task" tool ` +
1026
- `to delegate each document (or group of related documents) to a sub-agent.\n` +
1027
- `Each sub-agent has its own fresh context window and can use file_search to retrieve the full document content.\n` +
1028
- `After all sub-agents complete, synthesize their results into a comprehensive response.\n\n` +
1029
- `This approach ensures each document gets full attention without context limitations.`,
1231
+ 'to delegate each document (or group of related documents) to a sub-agent.\n' +
1232
+ 'Each sub-agent has its own fresh context window and can use file_search to retrieve the full document content.\n' +
1233
+ 'After all sub-agents complete, synthesize their results into a comprehensive response.\n\n' +
1234
+ 'This approach ensures each document gets full attention without context limitations.',
1030
1235
  });
1031
1236
  finalMessages = [...finalMessages, pressureMsg];
1032
1237
  console.info(`[Graph] Multi-document delegation hint injected for ${documentCount} documents: ` +
@@ -1034,14 +1239,15 @@ class StandardGraph extends Graph {
1034
1239
  }
1035
1240
  // TRIGGER 2: Token utilization thresholds (mid-chain safety net)
1036
1241
  // Also fires when we skipped pruning due to delegationInjectedPrePrune
1037
- if (utilization > 85 || (delegationInjectedPrePrune && utilization > 50)) {
1242
+ if (utilization > 85 ||
1243
+ (delegationInjectedPrePrune && utilization > 50)) {
1038
1244
  // CRITICAL: Context is high — MANDATE delegation
1039
1245
  const pressureMsg = new HumanMessage({
1040
1246
  content: `[CONTEXT BUDGET CRITICAL — ${utilization.toFixed(0)}% used]\n` +
1041
1247
  `You have used ${totalTokens} of ${maxTokens} tokens (${remainingTokens} remaining).\n` +
1042
- `Your context is very large. You MUST use the "task" tool to delegate work to sub-agents.\n` +
1043
- `Each sub-agent runs in its own fresh context window and can use file_search to access documents.\n` +
1044
- `Do NOT attempt to process documents directly — delegate each document to a sub-agent, then synthesize results.`,
1248
+ 'Your context is very large. You MUST use the "task" tool to delegate work to sub-agents.\n' +
1249
+ 'Each sub-agent runs in its own fresh context window and can use file_search to access documents.\n' +
1250
+ 'Do NOT attempt to process documents directly — delegate each document to a sub-agent, then synthesize results.',
1045
1251
  });
1046
1252
  finalMessages = [...finalMessages, pressureMsg];
1047
1253
  console.warn(`[Graph] Context pressure CRITICAL (${utilization.toFixed(0)}%): ` +
@@ -1053,8 +1259,8 @@ class StandardGraph extends Graph {
1053
1259
  const pressureMsg = new HumanMessage({
1054
1260
  content: `[CONTEXT BUDGET WARNING — ${utilization.toFixed(0)}% used]\n` +
1055
1261
  `You have used ${totalTokens} of ${maxTokens} tokens (${remainingTokens} remaining).\n` +
1056
- `Your context is filling up. Consider using the "task" tool to delegate complex operations to sub-agents.\n` +
1057
- `Sub-agents run in fresh context windows and won't consume your remaining budget.`,
1262
+ 'Your context is filling up. Consider using the "task" tool to delegate complex operations to sub-agents.\n' +
1263
+ "Sub-agents run in fresh context windows and won't consume your remaining budget.",
1058
1264
  });
1059
1265
  finalMessages = [...finalMessages, pressureMsg];
1060
1266
  console.info(`[Graph] Context pressure WARNING (${utilization.toFixed(0)}%): ` +
@@ -1093,7 +1299,7 @@ class StandardGraph extends Graph {
1093
1299
  }
1094
1300
  catch (primaryError) {
1095
1301
  // Check if this is a "input too long" error from Bedrock/Anthropic
1096
- const errorMessage = primaryError.message.toLowerCase() ?? '';
1302
+ const errorMessage = primaryError.message.toLowerCase();
1097
1303
  const isInputTooLongError = errorMessage.includes('too long') ||
1098
1304
  errorMessage.includes('input is too long') ||
1099
1305
  errorMessage.includes('context length') ||
@@ -1113,7 +1319,9 @@ class StandardGraph extends Graph {
1113
1319
  }
1114
1320
  // If input too long and we have pruning capability OR tokenCounter, retry with progressively more aggressive pruning
1115
1321
  // Note: We can create emergency pruneMessages dynamically if we have tokenCounter and maxContextTokens
1116
- const canPrune = agentContext.tokenCounter && agentContext.maxContextTokens;
1322
+ const canPrune = agentContext.tokenCounter != null &&
1323
+ agentContext.maxContextTokens != null &&
1324
+ agentContext.maxContextTokens > 0;
1117
1325
  if (isInputTooLongError && canPrune) {
1118
1326
  // Progressive reduction: 50% -> 25% -> 10% of original context
1119
1327
  const reductionLevels = [0.5, 0.25, 0.1];
@@ -1201,7 +1409,7 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1201
1409
  console.info(`[Graph] ✅ Retry successful at ${reductionFactor * 100}% with ${reducedMessages.length} messages (reduced from ${finalMessages.length})`);
1202
1410
  }
1203
1411
  catch (retryError) {
1204
- const retryErrorMsg = retryError.message.toLowerCase() ?? '';
1412
+ const retryErrorMsg = retryError.message.toLowerCase();
1205
1413
  const stillTooLong = retryErrorMsg.includes('too long') ||
1206
1414
  retryErrorMsg.includes('context length') ||
1207
1415
  retryErrorMsg.includes('validationexception');
@@ -1250,6 +1458,101 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1250
1458
  if (!result) {
1251
1459
  throw new Error('No result after model invocation');
1252
1460
  }
1461
+ /**
1462
+ * Fallback: populate toolCallStepIds in the graph execution context.
1463
+ *
1464
+ * When model.stream() is available (the common case), attemptInvoke
1465
+ * processes all chunks through a local ChatModelStreamHandler which
1466
+ * creates run steps and populates toolCallStepIds before returning.
1467
+ * The code below is a fallback for the rare case where model.stream
1468
+ * is unavailable and model.invoke() was used instead.
1469
+ *
1470
+ * Text content is dispatched FIRST so that MESSAGE_CREATION is the
1471
+ * current step when handleToolCalls runs. handleToolCalls then creates
1472
+ * TOOL_CALLS on top of it. The dedup in getMessageId and
1473
+ * toolCallStepIds.has makes this safe when attemptInvoke already
1474
+ * handled everything — both paths become no-ops.
1475
+ */
1476
+ const responseMessage = result.messages?.[0];
1477
+ const toolCalls = responseMessage
1478
+ ?.tool_calls;
1479
+ const hasToolCalls = Array.isArray(toolCalls) && toolCalls.length > 0;
1480
+ if (hasToolCalls) {
1481
+ const metadata = config.metadata;
1482
+ const stepKey = this.getStepKey(metadata);
1483
+ const content = responseMessage?.content;
1484
+ const hasTextContent = content != null &&
1485
+ (typeof content === 'string'
1486
+ ? content !== ''
1487
+ : Array.isArray(content) && content.length > 0);
1488
+ /**
1489
+ * Dispatch text content BEFORE creating TOOL_CALLS steps.
1490
+ * getMessageId returns a new ID only on the first call for a step key;
1491
+ * if the for-await consumer already claimed it, this is a no-op.
1492
+ */
1493
+ if (hasTextContent) {
1494
+ const messageId = getMessageId(stepKey, this) ?? '';
1495
+ if (messageId) {
1496
+ await this.dispatchRunStep(stepKey, {
1497
+ type: StepTypes.MESSAGE_CREATION,
1498
+ message_creation: { message_id: messageId },
1499
+ }, metadata);
1500
+ const stepId = this.getStepIdByKey(stepKey);
1501
+ if (typeof content === 'string') {
1502
+ await this.dispatchMessageDelta(stepId, {
1503
+ content: [{ type: ContentTypes.TEXT, text: content }],
1504
+ });
1505
+ }
1506
+ else if (Array.isArray(content) &&
1507
+ content.every((c) => typeof c === 'object' &&
1508
+ 'type' in c &&
1509
+ typeof c.type === 'string' &&
1510
+ c.type.startsWith('text'))) {
1511
+ await this.dispatchMessageDelta(stepId, {
1512
+ content: content,
1513
+ });
1514
+ }
1515
+ }
1516
+ }
1517
+ await handleToolCalls(toolCalls, metadata, this);
1518
+ }
1519
+ /**
1520
+ * When streaming is disabled, on_chat_model_stream events are never
1521
+ * emitted so ChatModelStreamHandler never fires. Dispatch the text
1522
+ * content as MESSAGE_CREATION + MESSAGE_DELTA here.
1523
+ */
1524
+ const disableStreaming = agentContext.clientOptions
1525
+ ?.disableStreaming === true;
1526
+ if (disableStreaming &&
1527
+ !hasToolCalls &&
1528
+ responseMessage != null &&
1529
+ responseMessage.content != null) {
1530
+ const metadata = config.metadata;
1531
+ const stepKey = this.getStepKey(metadata);
1532
+ const messageId = getMessageId(stepKey, this) ?? '';
1533
+ if (messageId) {
1534
+ await this.dispatchRunStep(stepKey, {
1535
+ type: StepTypes.MESSAGE_CREATION,
1536
+ message_creation: { message_id: messageId },
1537
+ }, metadata);
1538
+ const stepId = this.getStepIdByKey(stepKey);
1539
+ const content = responseMessage.content;
1540
+ if (typeof content === 'string') {
1541
+ await this.dispatchMessageDelta(stepId, {
1542
+ content: [{ type: ContentTypes.TEXT, text: content }],
1543
+ });
1544
+ }
1545
+ else if (Array.isArray(content) &&
1546
+ content.every((c) => typeof c === 'object' &&
1547
+ 'type' in c &&
1548
+ typeof c.type === 'string' &&
1549
+ c.type.startsWith('text'))) {
1550
+ await this.dispatchMessageDelta(stepId, {
1551
+ content: content,
1552
+ });
1553
+ }
1554
+ }
1555
+ }
1253
1556
  agentContext.currentUsage = this.getUsageMetadata(result.messages?.[0]);
1254
1557
  // Extract and normalize the LLM's finish/stop reason for auto-continuation support
1255
1558
  const finalMsg = result.messages?.[0];
@@ -1262,21 +1565,19 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1262
1565
  meta.stop_reason ?? // Anthropic direct API
1263
1566
  meta.stopReason ?? // Bedrock invoke (non-streaming)
1264
1567
  messageStop?.stopReason ?? // Bedrock streaming
1265
- meta.finishReason ?? // VertexAI/Google
1266
- undefined;
1568
+ meta.finishReason; // VertexAI/Google
1267
1569
  }
1268
1570
  this.cleanupSignalListener();
1269
1571
  // DEFERRED STRUCTURED OUTPUT: When the agent has tools AND structured output configured,
1270
1572
  // we let the agent use tools normally via attemptInvoke(). Once the agent's response
1271
1573
  // has NO tool_calls (it's done with tools), we produce the final structured JSON response.
1272
1574
  if (agentContext.isStructuredOutputMode &&
1273
- agentContext.structuredOutput &&
1274
- result) {
1575
+ agentContext.structuredOutput != null) {
1275
1576
  const lastMessage = result.messages?.[0];
1276
- const resultHasToolCalls = lastMessage &&
1577
+ const resultHasToolCalls = lastMessage != null &&
1277
1578
  'tool_calls' in lastMessage &&
1278
1579
  (lastMessage.tool_calls?.length ?? 0) > 0;
1279
- if (!resultHasToolCalls) {
1580
+ if (resultHasToolCalls !== true) {
1280
1581
  try {
1281
1582
  // Build messages for structured output: include the full conversation
1282
1583
  // plus the agent's text response from attemptInvoke, so the structured
@@ -1358,6 +1659,10 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
1358
1659
  reducer: (a, b) => {
1359
1660
  if (!a.length) {
1360
1661
  this.startIndex = a.length + b.length;
1662
+ console.info(`[Graph:Reducer] Initial messages | startIndex=${this.startIndex} | inputMsgCount=${b.length}`);
1663
+ }
1664
+ else {
1665
+ console.debug(`[Graph:Reducer] Appending messages | existing=${a.length} | new=${b.length} | startIndex=${this.startIndex}`);
1361
1666
  }
1362
1667
  const result = messagesStateReducer(a, b);
1363
1668
  this.messages = result;