@illuma-ai/agents 1.0.89 → 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
@@ -0,0 +1,1222 @@
1
+ /**
2
+ * Comprehensive Multi-Agent POC — All Combinations
3
+ *
4
+ * Tests every combination of edge type (handoff vs direct/sequential) and
5
+ * tool usage (none, single, multiple) end-to-end with Bedrock.
6
+ *
7
+ * S1: Handoff — No tools
8
+ * S2: Handoff — Single tool call
9
+ * S3: Handoff — Multiple tool calls (3 tools)
10
+ * S4: Sequential (direct edges) — No tools
11
+ * S5: Sequential — Single tool per agent
12
+ * S6: Sequential — Multiple tools per agent
13
+ * S7: Hybrid (direct + handoff) — Mixed tools
14
+ *
15
+ * Usage:
16
+ * npx tsx --tsconfig tsconfig.json -r tsconfig-paths/register src/scripts/poc-multi-agent-comprehensive.ts
17
+ */
18
+ import { config } from 'dotenv';
19
+ config();
20
+
21
+ import {
22
+ HumanMessage,
23
+ BaseMessage,
24
+ getBufferString,
25
+ } from '@langchain/core/messages';
26
+ import { DynamicStructuredTool } from '@langchain/core/tools';
27
+ import { z } from 'zod';
28
+ import { Run } from '@/run';
29
+ import { Providers, GraphEvents } from '@/common';
30
+ import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
31
+ import { ToolEndHandler, ModelEndHandler } from '@/events';
32
+ import type * as t from '@/types';
33
+
34
+ /* ------------------------------------------------------------------ */
35
+ /* Shared helpers */
36
+ /* ------------------------------------------------------------------ */
37
+
38
+ /** Bedrock client options reused across all agents */
39
+ const bedrockOptions: t.ClientOptions = {
40
+ region: process.env.BEDROCK_AWS_DEFAULT_REGION ?? 'us-east-1',
41
+ credentials: {
42
+ accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!,
43
+ secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!,
44
+ },
45
+ model: 'us.anthropic.claude-3-5-haiku-20241022-v1:0',
46
+ };
47
+
48
+ /** Create standard event handlers for observability */
49
+ function createHandlers(label: string) {
50
+ const { contentParts, aggregateContent, stepMap } = createContentAggregator();
51
+
52
+ let currentAgent = '';
53
+
54
+ const handlers: Record<string, t.EventHandler> = {
55
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
56
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
57
+ [GraphEvents.CHAT_MODEL_STREAM]: {
58
+ handle: (
59
+ event: string,
60
+ data: t.StreamEventData,
61
+ metadata?: Record<string, unknown>,
62
+ graph?: unknown
63
+ ): void => {
64
+ const chunk = data.chunk as Record<string, unknown> | undefined;
65
+ if (!chunk) return;
66
+ const content = chunk.content;
67
+ if (typeof content === 'string' && content) {
68
+ process.stdout.write(content);
69
+ } else if (Array.isArray(content)) {
70
+ for (const block of content) {
71
+ if (
72
+ typeof block === 'object' &&
73
+ block !== null &&
74
+ 'type' in block &&
75
+ block.type === 'text' &&
76
+ 'text' in block &&
77
+ typeof block.text === 'string'
78
+ ) {
79
+ process.stdout.write(block.text);
80
+ }
81
+ }
82
+ }
83
+ },
84
+ },
85
+ [GraphEvents.ON_RUN_STEP]: {
86
+ handle: (
87
+ event: GraphEvents.ON_RUN_STEP,
88
+ data: t.StreamEventData
89
+ ): void => {
90
+ const runStepData = data as Record<string, unknown>;
91
+ const name =
92
+ typeof runStepData?.name === 'string' ? runStepData.name : undefined;
93
+ if (name && name !== currentAgent) {
94
+ currentAgent = name;
95
+ console.log(`\n\n>>> [${label}] Agent "${currentAgent}" starting...`);
96
+ }
97
+ aggregateContent({ event, data: data as t.RunStep });
98
+ },
99
+ },
100
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
101
+ handle: (
102
+ event: GraphEvents.ON_RUN_STEP_COMPLETED,
103
+ data: t.StreamEventData
104
+ ): void => {
105
+ const runStepData = data as Record<string, unknown>;
106
+ const name =
107
+ typeof runStepData?.name === 'string' ? runStepData.name : undefined;
108
+ if (name) {
109
+ console.log(`\n<<< [${label}] Agent "${name}" completed`);
110
+ }
111
+ aggregateContent({
112
+ event,
113
+ data: data as unknown as { result: t.ToolEndEvent },
114
+ });
115
+ },
116
+ },
117
+ [GraphEvents.ON_RUN_STEP_DELTA]: {
118
+ handle: (
119
+ event: GraphEvents.ON_RUN_STEP_DELTA,
120
+ data: t.StreamEventData
121
+ ): void => {
122
+ aggregateContent({ event, data: data as t.RunStepDeltaEvent });
123
+ },
124
+ },
125
+ [GraphEvents.ON_MESSAGE_DELTA]: {
126
+ handle: (
127
+ event: GraphEvents.ON_MESSAGE_DELTA,
128
+ data: t.StreamEventData
129
+ ): void => {
130
+ aggregateContent({ event, data: data as t.MessageDeltaEvent });
131
+ },
132
+ },
133
+ };
134
+
135
+ return { handlers, contentParts, stepMap };
136
+ }
137
+
138
+ function printHeader(title: string) {
139
+ console.log('\n' + '='.repeat(80));
140
+ console.log(` ${title}`);
141
+ console.log('='.repeat(80));
142
+ }
143
+
144
+ function printResult(label: string, success: boolean, details?: string) {
145
+ const icon = success ? '[PASS]' : '[FAIL]';
146
+ console.log(`\n${icon} ${label}`);
147
+ if (details) console.log(` ${details}`);
148
+ }
149
+
150
+ /** Helper to build a default agent config */
151
+ function agent(
152
+ agentId: string,
153
+ name: string,
154
+ instructions: string,
155
+ extras?: Partial<t.AgentInputs>
156
+ ): t.AgentInputs {
157
+ return {
158
+ agentId,
159
+ name,
160
+ provider: Providers.BEDROCK,
161
+ clientOptions: bedrockOptions,
162
+ instructions,
163
+ maxContextTokens: 8000,
164
+ ...extras,
165
+ };
166
+ }
167
+
168
+ /* ------------------------------------------------------------------ */
169
+ /* Mock Tools */
170
+ /* ------------------------------------------------------------------ */
171
+
172
+ const getWeatherTool = new DynamicStructuredTool({
173
+ name: 'get_weather',
174
+ description:
175
+ 'Get the current weather for a city. Returns temperature in Fahrenheit and conditions.',
176
+ schema: z.object({
177
+ city: z.string().describe('The city name'),
178
+ }),
179
+ func: async ({ city }) => {
180
+ const temps: Record<string, number> = {
181
+ boston: 45,
182
+ miami: 82,
183
+ 'new york': 55,
184
+ 'los angeles': 72,
185
+ chicago: 40,
186
+ london: 50,
187
+ tokyo: 60,
188
+ paris: 55,
189
+ sydney: 75,
190
+ };
191
+ const temp = temps[city.toLowerCase()] ?? 65;
192
+ return JSON.stringify({
193
+ city,
194
+ temperature: temp,
195
+ unit: 'F',
196
+ condition: temp > 70 ? 'Sunny' : temp > 50 ? 'Partly Cloudy' : 'Cold',
197
+ });
198
+ },
199
+ });
200
+
201
+ const getStockPriceTool = new DynamicStructuredTool({
202
+ name: 'get_stock_price',
203
+ description: 'Get the current stock price for a ticker symbol.',
204
+ schema: z.object({
205
+ ticker: z.string().describe('Stock ticker symbol (e.g. AAPL, GOOGL)'),
206
+ }),
207
+ func: async ({ ticker }) => {
208
+ const prices: Record<string, number> = {
209
+ AAPL: 178.5,
210
+ GOOGL: 141.2,
211
+ MSFT: 378.9,
212
+ AMZN: 185.6,
213
+ TSLA: 245.3,
214
+ META: 505.75,
215
+ NVDA: 875.4,
216
+ };
217
+ const price = prices[ticker.toUpperCase()] ?? 100.0;
218
+ const change = (Math.random() * 6 - 3).toFixed(2);
219
+ return JSON.stringify({
220
+ ticker: ticker.toUpperCase(),
221
+ price,
222
+ change: parseFloat(change),
223
+ currency: 'USD',
224
+ });
225
+ },
226
+ });
227
+
228
+ const searchDatabaseTool = new DynamicStructuredTool({
229
+ name: 'search_database',
230
+ description:
231
+ 'Search the company database for employee or project information.',
232
+ schema: z.object({
233
+ query: z.string().describe('Search query'),
234
+ category: z
235
+ .enum(['employees', 'projects', 'departments'])
236
+ .describe('Category to search'),
237
+ }),
238
+ func: async ({ query, category }) => {
239
+ const results: Record<string, Record<string, string[]>> = {
240
+ employees: {
241
+ engineering: [
242
+ 'Alice Chen (Senior Engineer)',
243
+ 'Bob Kumar (Tech Lead)',
244
+ 'Carol Smith (Staff Engineer)',
245
+ ],
246
+ marketing: ['Dan Lee (VP Marketing)', 'Eva Brown (Content Manager)'],
247
+ },
248
+ projects: {
249
+ active: [
250
+ 'Project Phoenix (AI Platform)',
251
+ 'Project Atlas (Data Migration)',
252
+ 'Project Nexus (API Gateway)',
253
+ ],
254
+ completed: ['Project Omega (Auth System)', 'Project Delta (Dashboard)'],
255
+ },
256
+ departments: {
257
+ all: [
258
+ 'Engineering (45 people)',
259
+ 'Marketing (12 people)',
260
+ 'Sales (20 people)',
261
+ 'Operations (8 people)',
262
+ ],
263
+ },
264
+ };
265
+ const catResults = results[category] ?? {};
266
+ const matchingValues = Object.values(catResults)
267
+ .flat()
268
+ .filter((v) => v.toLowerCase().includes(query.toLowerCase()));
269
+ return JSON.stringify({
270
+ category,
271
+ query,
272
+ results:
273
+ matchingValues.length > 0
274
+ ? matchingValues
275
+ : Object.values(catResults).flat().slice(0, 3),
276
+ totalMatches: matchingValues.length || 3,
277
+ });
278
+ },
279
+ });
280
+
281
+ const translateTextTool = new DynamicStructuredTool({
282
+ name: 'translate_text',
283
+ description: 'Translate text from one language to another.',
284
+ schema: z.object({
285
+ text: z.string().describe('Text to translate'),
286
+ targetLanguage: z
287
+ .string()
288
+ .describe('Target language (e.g. Spanish, French, Japanese)'),
289
+ }),
290
+ func: async ({ text, targetLanguage }) => {
291
+ const translations: Record<string, string> = {
292
+ spanish: `[ES] ${text} (traducción simulada)`,
293
+ french: `[FR] ${text} (traduction simulée)`,
294
+ japanese: `[JA] ${text} (模擬翻訳)`,
295
+ german: `[DE] ${text} (simulierte Übersetzung)`,
296
+ };
297
+ return JSON.stringify({
298
+ original: text,
299
+ translated:
300
+ translations[targetLanguage.toLowerCase()] ??
301
+ `[${targetLanguage}] ${text} (simulated)`,
302
+ targetLanguage,
303
+ });
304
+ },
305
+ });
306
+
307
+ const getTimeTool = new DynamicStructuredTool({
308
+ name: 'get_time',
309
+ description: 'Get the current time in a specific timezone.',
310
+ schema: z.object({
311
+ timezone: z.string().describe('Timezone (e.g. EST, PST, UTC, JST)'),
312
+ }),
313
+ func: async ({ timezone }) => {
314
+ const offsets: Record<string, number> = {
315
+ EST: -5,
316
+ PST: -8,
317
+ CST: -6,
318
+ MST: -7,
319
+ UTC: 0,
320
+ GMT: 0,
321
+ JST: 9,
322
+ CET: 1,
323
+ IST: 5.5,
324
+ AEST: 11,
325
+ };
326
+ const offset = offsets[timezone.toUpperCase()] ?? 0;
327
+ const now = new Date();
328
+ const utcHour = now.getUTCHours();
329
+ const localHour = (utcHour + offset + 24) % 24;
330
+ const mins = now.getUTCMinutes().toString().padStart(2, '0');
331
+ return JSON.stringify({
332
+ timezone: timezone.toUpperCase(),
333
+ time: `${Math.floor(localHour)}:${mins}`,
334
+ date: now.toISOString().split('T')[0],
335
+ });
336
+ },
337
+ });
338
+
339
+ const sentimentAnalysisTool = new DynamicStructuredTool({
340
+ name: 'analyze_sentiment',
341
+ description:
342
+ 'Analyze the sentiment of a piece of text. Returns positive, negative, or neutral with a confidence score.',
343
+ schema: z.object({
344
+ text: z.string().describe('Text to analyze for sentiment'),
345
+ }),
346
+ func: async ({ text }) => {
347
+ const words = text.toLowerCase().split(/\s+/);
348
+ const positive = [
349
+ 'good',
350
+ 'great',
351
+ 'excellent',
352
+ 'amazing',
353
+ 'love',
354
+ 'best',
355
+ 'happy',
356
+ 'wonderful',
357
+ 'fantastic',
358
+ ];
359
+ const negative = [
360
+ 'bad',
361
+ 'terrible',
362
+ 'awful',
363
+ 'hate',
364
+ 'worst',
365
+ 'poor',
366
+ 'disappointed',
367
+ 'horrible',
368
+ ];
369
+ const posCount = words.filter((w) => positive.includes(w)).length;
370
+ const negCount = words.filter((w) => negative.includes(w)).length;
371
+ const sentiment =
372
+ posCount > negCount
373
+ ? 'positive'
374
+ : negCount > posCount
375
+ ? 'negative'
376
+ : 'neutral';
377
+ const confidence = Math.min(
378
+ 0.95,
379
+ 0.6 + Math.abs(posCount - negCount) * 0.1
380
+ );
381
+ return JSON.stringify({ sentiment, confidence, wordCount: words.length });
382
+ },
383
+ });
384
+
385
+ /* ================================================================== */
386
+ /* S1: Handoff — No Tools */
387
+ /* flight_assistant -> hotel_assistant (pure conversation handoff) */
388
+ /* ================================================================== */
389
+ async function s1_handoff_noTools(): Promise<boolean> {
390
+ printHeader('S1: HANDOFF — NO TOOLS');
391
+ console.log(' flight_assistant -> hotel_assistant');
392
+ console.log(' Pure conversation handoff, no tools involved\n');
393
+
394
+ const agents: t.AgentInputs[] = [
395
+ agent(
396
+ 'flight_assistant',
397
+ 'Flight Assistant',
398
+ `You are a flight booking assistant. Help users with flight-related queries.
399
+ When the user also needs hotel assistance, first briefly address the flight part (2-3 sentences),
400
+ then use the handoff tool to transfer to the hotel assistant.
401
+ Do NOT try to answer hotel questions yourself.`
402
+ ),
403
+ agent(
404
+ 'hotel_assistant',
405
+ 'Hotel Assistant',
406
+ `You are a hotel booking assistant. Help users with hotel-related queries.
407
+ Provide your hotel recommendations (2-3 sentences) and complete the conversation.
408
+ Do NOT transfer back to the flight assistant.`
409
+ ),
410
+ ];
411
+
412
+ const edges: t.GraphEdge[] = [
413
+ {
414
+ from: 'flight_assistant',
415
+ to: 'hotel_assistant',
416
+ description:
417
+ 'Transfer to hotel assistant when user needs hotel booking help',
418
+ },
419
+ ];
420
+
421
+ const { handlers, contentParts } = createHandlers('S1');
422
+
423
+ try {
424
+ const run = await Run.create({
425
+ runId: `s1-${Date.now()}`,
426
+ graphConfig: { type: 'multi-agent', agents, edges },
427
+ customHandlers: handlers,
428
+ returnContent: true,
429
+ skipCleanup: true,
430
+ });
431
+
432
+ await run.processStream(
433
+ {
434
+ messages: [
435
+ new HumanMessage(
436
+ 'I need a flight from Boston to Miami, and also need a hotel near South Beach for 3 nights.'
437
+ ),
438
+ ],
439
+ },
440
+ { configurable: { thread_id: 's1' }, version: 'v2' as const }
441
+ );
442
+
443
+ const runMessages = run.getRunMessages();
444
+ const aiCount =
445
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
446
+ const lastAgent = run.getLastActiveAgentId?.();
447
+
448
+ console.log(`\n\n--- S1 Results ---`);
449
+ console.log(` AI messages: ${aiCount}, Last agent: ${lastAgent}`);
450
+
451
+ const success = aiCount >= 2 && lastAgent === 'hotel_assistant';
452
+ printResult(
453
+ 'S1: Handoff — No Tools',
454
+ success,
455
+ success
456
+ ? `Both agents participated (${aiCount} AI msgs), handoff to hotel confirmed`
457
+ : `Expected 2+ AI msgs & hotel_assistant last, got ${aiCount} msgs & ${lastAgent}`
458
+ );
459
+ return success;
460
+ } catch (error) {
461
+ console.error('S1 error:', error);
462
+ printResult('S1: Handoff — No Tools', false, String(error));
463
+ return false;
464
+ }
465
+ }
466
+
467
+ /* ================================================================== */
468
+ /* S2: Handoff — Single Tool */
469
+ /* weather_agent (get_weather) -> activity_advisor */
470
+ /* ================================================================== */
471
+ async function s2_handoff_singleTool(): Promise<boolean> {
472
+ printHeader('S2: HANDOFF — SINGLE TOOL');
473
+ console.log(' weather_agent [get_weather] -> activity_advisor');
474
+ console.log(' Agent calls one tool, then hands off\n');
475
+
476
+ const agents: t.AgentInputs[] = [
477
+ agent(
478
+ 'weather_agent',
479
+ 'Weather Agent',
480
+ `You are a Weather Agent. When the user asks about weather:
481
+ 1. Use the get_weather tool to get the data for the requested city
482
+ 2. Briefly report the temperature and condition (1 sentence)
483
+ 3. Then IMMEDIATELY hand off to the activity advisor
484
+ You MUST hand off after reporting the weather. Do NOT suggest activities yourself.`,
485
+ { tools: [getWeatherTool], description: 'Gets weather data using tools' }
486
+ ),
487
+ agent(
488
+ 'activity_advisor',
489
+ 'Activity Advisor',
490
+ `You are an Activity Advisor. Based on the weather information from the previous agent:
491
+ 1. Suggest 2-3 activities suited for the conditions
492
+ 2. Recommend what to wear or pack
493
+ Keep it brief (2-3 sentences).`,
494
+ { description: 'Recommends activities based on weather' }
495
+ ),
496
+ ];
497
+
498
+ const edges: t.GraphEdge[] = [
499
+ {
500
+ from: 'weather_agent',
501
+ to: 'activity_advisor',
502
+ description: 'Transfer to activity advisor after getting weather data',
503
+ },
504
+ ];
505
+
506
+ const { handlers, contentParts } = createHandlers('S2');
507
+
508
+ try {
509
+ const run = await Run.create({
510
+ runId: `s2-${Date.now()}`,
511
+ graphConfig: { type: 'multi-agent', agents, edges },
512
+ customHandlers: handlers,
513
+ returnContent: true,
514
+ skipCleanup: true,
515
+ });
516
+
517
+ await run.processStream(
518
+ {
519
+ messages: [
520
+ new HumanMessage(
521
+ 'What is the weather like in Miami? What activities should I plan?'
522
+ ),
523
+ ],
524
+ },
525
+ { configurable: { thread_id: 's2' }, version: 'v2' as const }
526
+ );
527
+
528
+ const runMessages = run.getRunMessages();
529
+ const aiCount =
530
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
531
+ const toolCount =
532
+ runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
533
+ const lastAgent = run.getLastActiveAgentId?.();
534
+
535
+ console.log(`\n\n--- S2 Results ---`);
536
+ console.log(
537
+ ` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
538
+ );
539
+
540
+ const success = aiCount >= 2 && toolCount >= 1;
541
+ printResult(
542
+ 'S2: Handoff — Single Tool',
543
+ success,
544
+ `Tool used: ${toolCount >= 1}, Handoff: ${lastAgent === 'activity_advisor'}, AI msgs: ${aiCount}`
545
+ );
546
+ return success;
547
+ } catch (error) {
548
+ console.error('S2 error:', error);
549
+ printResult('S2: Handoff — Single Tool', false, String(error));
550
+ return false;
551
+ }
552
+ }
553
+
554
+ /* ================================================================== */
555
+ /* S3: Handoff — Multiple Tools */
556
+ /* research_agent [weather + stock + time] -> report_agent */
557
+ /* ================================================================== */
558
+ async function s3_handoff_multipleTools(): Promise<boolean> {
559
+ printHeader('S3: HANDOFF — MULTIPLE TOOLS (3 tools)');
560
+ console.log(
561
+ ' research_agent [get_weather, get_stock_price, get_time] -> report_agent'
562
+ );
563
+ console.log(' Agent calls multiple tools, then hands off\n');
564
+
565
+ const agents: t.AgentInputs[] = [
566
+ agent(
567
+ 'research_agent',
568
+ 'Research Agent',
569
+ `You are a Research Agent with three tools: get_weather, get_stock_price, and get_time.
570
+ When the user asks for a briefing:
571
+ 1. Use get_weather to check weather in the requested city
572
+ 2. Use get_stock_price to check the requested stock
573
+ 3. Use get_time to check the time in the requested timezone
574
+ After gathering ALL data from all three tools, briefly summarize your findings (2-3 sentences).
575
+ Then IMMEDIATELY hand off to the report agent. Do NOT write the full report yourself.`,
576
+ {
577
+ tools: [getWeatherTool, getStockPriceTool, getTimeTool],
578
+ description: 'Gathers data from multiple tools',
579
+ }
580
+ ),
581
+ agent(
582
+ 'report_agent',
583
+ 'Report Agent',
584
+ `You are a Report Agent. Based on the research data provided:
585
+ 1. Create a formatted executive morning briefing
586
+ 2. Include weather, market, and time sections
587
+ 3. End with a brief recommendation for the day
588
+ Keep it to 4-6 sentences total.`,
589
+ { description: 'Creates formatted reports from gathered data' }
590
+ ),
591
+ ];
592
+
593
+ const edges: t.GraphEdge[] = [
594
+ {
595
+ from: 'research_agent',
596
+ to: 'report_agent',
597
+ description:
598
+ 'Transfer to report agent after gathering all research data to create a formatted report',
599
+ },
600
+ ];
601
+
602
+ const { handlers, contentParts } = createHandlers('S3');
603
+
604
+ try {
605
+ const run = await Run.create({
606
+ runId: `s3-${Date.now()}`,
607
+ graphConfig: { type: 'multi-agent', agents, edges },
608
+ customHandlers: handlers,
609
+ returnContent: true,
610
+ skipCleanup: true,
611
+ });
612
+
613
+ await run.processStream(
614
+ {
615
+ messages: [
616
+ new HumanMessage(
617
+ 'Give me a morning briefing: weather in New York, AAPL stock price, and current time in EST.'
618
+ ),
619
+ ],
620
+ },
621
+ { configurable: { thread_id: 's3' }, version: 'v2' as const }
622
+ );
623
+
624
+ const runMessages = run.getRunMessages();
625
+ const aiCount =
626
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
627
+ const toolCount =
628
+ runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
629
+ const lastAgent = run.getLastActiveAgentId?.();
630
+
631
+ console.log(`\n\n--- S3 Results ---`);
632
+ console.log(
633
+ ` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
634
+ );
635
+
636
+ /** Expect at least 3 tool calls (weather + stock + time) */
637
+ const success = aiCount >= 2 && toolCount >= 3;
638
+ printResult(
639
+ 'S3: Handoff — Multiple Tools',
640
+ success,
641
+ `Tools called: ${toolCount} (expected ≥3), Handoff: ${lastAgent === 'report_agent'}, AI msgs: ${aiCount}`
642
+ );
643
+ return success;
644
+ } catch (error) {
645
+ console.error('S3 error:', error);
646
+ printResult('S3: Handoff — Multiple Tools', false, String(error));
647
+ return false;
648
+ }
649
+ }
650
+
651
+ /* ================================================================== */
652
+ /* S4: Sequential (Direct Edges) — No Tools */
653
+ /* researcher -> analyst -> summarizer (sim-style DAG) */
654
+ /* ================================================================== */
655
+ async function s4_sequential_noTools(): Promise<boolean> {
656
+ printHeader('S4: SEQUENTIAL (DIRECT) — NO TOOLS');
657
+ console.log(' researcher -> analyst -> summarizer');
658
+ console.log(' Each agent receives previous outputs as context, no tools\n');
659
+
660
+ const agents: t.AgentInputs[] = [
661
+ agent(
662
+ 'researcher',
663
+ 'Researcher',
664
+ `You are a Research Agent. Your task:
665
+ 1. Analyze the user's question
666
+ 2. List 3-4 key facts or considerations
667
+ Keep it to 3-4 bullet points. Start with "RESEARCH:"`
668
+ ),
669
+ agent(
670
+ 'analyst',
671
+ 'Analyst',
672
+ `You are an Analysis Agent. Your task:
673
+ 1. Read the research findings from the previous agent
674
+ 2. Identify patterns, risks, and opportunities
675
+ 3. Add deeper analytical insights
676
+ Keep it to 3-4 bullet points. Start with "ANALYSIS:"`
677
+ ),
678
+ agent(
679
+ 'summarizer',
680
+ 'Summarizer',
681
+ `You are a Summary Agent. Your task:
682
+ 1. Synthesize the research AND analysis from previous agents
683
+ 2. Create a cohesive 2-3 sentence executive summary
684
+ 3. End with one key recommendation
685
+ Start with "SUMMARY:" and end with "RECOMMENDATION:"`
686
+ ),
687
+ ];
688
+
689
+ const edges: t.GraphEdge[] = [
690
+ {
691
+ from: 'researcher',
692
+ to: 'analyst',
693
+ edgeType: 'direct',
694
+ prompt: (messages: BaseMessage[], startIndex: number) => {
695
+ const buffer = getBufferString(messages.slice(startIndex));
696
+ return `Here are the research findings. Analyze them and provide insights:\n\n${buffer}`;
697
+ },
698
+ excludeResults: true,
699
+ },
700
+ {
701
+ from: 'analyst',
702
+ to: 'summarizer',
703
+ edgeType: 'direct',
704
+ prompt: (messages: BaseMessage[], startIndex: number) => {
705
+ const buffer = getBufferString(messages.slice(startIndex));
706
+ return `Here are the combined research and analysis. Synthesize into a final summary:\n\n${buffer}`;
707
+ },
708
+ excludeResults: true,
709
+ },
710
+ ];
711
+
712
+ const { handlers, contentParts } = createHandlers('S4');
713
+
714
+ try {
715
+ const run = await Run.create({
716
+ runId: `s4-${Date.now()}`,
717
+ graphConfig: { type: 'multi-agent', agents, edges },
718
+ customHandlers: handlers,
719
+ returnContent: true,
720
+ skipCleanup: true,
721
+ });
722
+
723
+ await run.processStream(
724
+ {
725
+ messages: [
726
+ new HumanMessage(
727
+ 'What are the key considerations for migrating a monolithic application to microservices?'
728
+ ),
729
+ ],
730
+ },
731
+ { configurable: { thread_id: 's4' }, version: 'v2' as const }
732
+ );
733
+
734
+ const runMessages = run.getRunMessages();
735
+ const aiMessages = runMessages?.filter((m) => m._getType() === 'ai') ?? [];
736
+
737
+ console.log(`\n\n--- S4 Results ---`);
738
+ console.log(` AI messages: ${aiMessages.length}`);
739
+ for (let i = 0; i < aiMessages.length; i++) {
740
+ const name = ['researcher', 'analyst', 'summarizer'][i] ?? `agent_${i}`;
741
+ const content =
742
+ typeof aiMessages[i].content === 'string'
743
+ ? aiMessages[i].content
744
+ : JSON.stringify(aiMessages[i].content);
745
+ console.log(` ${name}: ${(content as string).slice(0, 80)}...`);
746
+ }
747
+
748
+ const success = aiMessages.length === 3;
749
+ printResult(
750
+ 'S4: Sequential — No Tools',
751
+ success,
752
+ success
753
+ ? `All 3 agents produced output sequentially`
754
+ : `Expected 3 AI messages, got ${aiMessages.length}`
755
+ );
756
+ return success;
757
+ } catch (error) {
758
+ console.error('S4 error:', error);
759
+ printResult('S4: Sequential — No Tools', false, String(error));
760
+ return false;
761
+ }
762
+ }
763
+
764
+ /* ================================================================== */
765
+ /* S5: Sequential (Direct Edges) — Single Tool Per Agent */
766
+ /* data_collector [search_database] -> translator [translate_text] */
767
+ /* -> reviewer (no tool) */
768
+ /* ================================================================== */
769
+ async function s5_sequential_singleTool(): Promise<boolean> {
770
+ printHeader('S5: SEQUENTIAL (DIRECT) — SINGLE TOOL PER AGENT');
771
+ console.log(
772
+ ' data_collector [search_database] -> translator [translate_text] -> reviewer'
773
+ );
774
+ console.log(' Each agent has one tool, output flows sequentially\n');
775
+
776
+ const agents: t.AgentInputs[] = [
777
+ agent(
778
+ 'data_collector',
779
+ 'Data Collector',
780
+ `You are a Data Collector Agent. When given a query:
781
+ 1. Use the search_database tool to find relevant information
782
+ 2. Present the search results in a clear, organized format (3-4 bullet points)
783
+ Start with "DATA COLLECTED:"`,
784
+ {
785
+ tools: [searchDatabaseTool],
786
+ description: 'Searches database for information',
787
+ }
788
+ ),
789
+ agent(
790
+ 'translator',
791
+ 'Translator',
792
+ `You are a Translator Agent. When you receive data from the previous agent:
793
+ 1. Use the translate_text tool to translate the KEY findings to the requested language
794
+ 2. Present both original and translated versions
795
+ Keep it brief. Start with "TRANSLATED:"`,
796
+ {
797
+ tools: [translateTextTool],
798
+ description: 'Translates text between languages',
799
+ }
800
+ ),
801
+ agent(
802
+ 'reviewer',
803
+ 'Quality Reviewer',
804
+ `You are a Quality Reviewer. Review the collected and translated data:
805
+ 1. Confirm data accuracy and translation quality
806
+ 2. Note any issues
807
+ 3. Give a quality score (1-10)
808
+ Start with "REVIEW:" and keep it to 3-4 lines.`
809
+ ),
810
+ ];
811
+
812
+ const edges: t.GraphEdge[] = [
813
+ {
814
+ from: 'data_collector',
815
+ to: 'translator',
816
+ edgeType: 'direct',
817
+ prompt: (messages: BaseMessage[], startIndex: number) => {
818
+ const buffer = getBufferString(messages.slice(startIndex));
819
+ return `Here is the collected data. Translate the key findings to Spanish:\n\n${buffer}`;
820
+ },
821
+ excludeResults: true,
822
+ },
823
+ {
824
+ from: 'translator',
825
+ to: 'reviewer',
826
+ edgeType: 'direct',
827
+ prompt: (messages: BaseMessage[], startIndex: number) => {
828
+ const buffer = getBufferString(messages.slice(startIndex));
829
+ return `Here is the collected and translated data. Review it for quality:\n\n${buffer}`;
830
+ },
831
+ excludeResults: true,
832
+ },
833
+ ];
834
+
835
+ const { handlers, contentParts } = createHandlers('S5');
836
+
837
+ try {
838
+ const run = await Run.create({
839
+ runId: `s5-${Date.now()}`,
840
+ graphConfig: { type: 'multi-agent', agents, edges },
841
+ customHandlers: handlers,
842
+ returnContent: true,
843
+ skipCleanup: true,
844
+ });
845
+
846
+ await run.processStream(
847
+ {
848
+ messages: [
849
+ new HumanMessage(
850
+ 'Search for engineering employees and translate the key findings to Spanish.'
851
+ ),
852
+ ],
853
+ },
854
+ { configurable: { thread_id: 's5' }, version: 'v2' as const }
855
+ );
856
+
857
+ const runMessages = run.getRunMessages();
858
+ const aiCount =
859
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
860
+ const toolCount =
861
+ runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
862
+
863
+ console.log(`\n\n--- S5 Results ---`);
864
+ console.log(` AI messages: ${aiCount}, Tool messages: ${toolCount}`);
865
+
866
+ /** Expect at least 2 tool calls (search + translate) across the chain */
867
+ const success = aiCount >= 3 && toolCount >= 2;
868
+ printResult(
869
+ 'S5: Sequential — Single Tool',
870
+ success,
871
+ `AI msgs: ${aiCount} (expected 3), Tool calls: ${toolCount} (expected ≥2)`
872
+ );
873
+ return success;
874
+ } catch (error) {
875
+ console.error('S5 error:', error);
876
+ printResult('S5: Sequential — Single Tool', false, String(error));
877
+ return false;
878
+ }
879
+ }
880
+
881
+ /* ================================================================== */
882
+ /* S6: Sequential (Direct Edges) — Multiple Tools Per Agent */
883
+ /* intel_gatherer [weather+stock+time] -> analyst [sentiment+search] */
884
+ /* -> presenter (no tools) */
885
+ /* ================================================================== */
886
+ async function s6_sequential_multipleTools(): Promise<boolean> {
887
+ printHeader('S6: SEQUENTIAL (DIRECT) — MULTIPLE TOOLS PER AGENT');
888
+ console.log(
889
+ ' intel_gatherer [weather, stock, time] -> analyst [sentiment, search_db] -> presenter'
890
+ );
891
+ console.log(' Agents have 2-3 tools each, output flows sequentially\n');
892
+
893
+ const agents: t.AgentInputs[] = [
894
+ agent(
895
+ 'intel_gatherer',
896
+ 'Intelligence Gatherer',
897
+ `You are an Intelligence Gatherer Agent with three tools: get_weather, get_stock_price, and get_time.
898
+ For the morning intelligence report:
899
+ 1. Use get_weather to check weather in Tokyo
900
+ 2. Use get_stock_price to check NVDA stock
901
+ 3. Use get_time to check current time in JST
902
+ Present all gathered data clearly. Start with "INTEL GATHERED:"`,
903
+ {
904
+ tools: [getWeatherTool, getStockPriceTool, getTimeTool],
905
+ description: 'Gathers intelligence from multiple data sources',
906
+ }
907
+ ),
908
+ agent(
909
+ 'market_analyst',
910
+ 'Market Analyst',
911
+ `You are a Market Analyst Agent with two tools: analyze_sentiment and search_database.
912
+ Based on the intelligence gathered:
913
+ 1. Use analyze_sentiment on a summary of the market conditions described by the previous agent
914
+ 2. Use search_database to find relevant projects in the "projects" category related to "AI"
915
+ 3. Combine insights into a brief market analysis
916
+ Start with "MARKET ANALYSIS:"`,
917
+ {
918
+ tools: [sentimentAnalysisTool, searchDatabaseTool],
919
+ description: 'Analyzes market sentiment and cross-references data',
920
+ }
921
+ ),
922
+ agent(
923
+ 'presenter',
924
+ 'Executive Presenter',
925
+ `You are an Executive Presenter Agent. Create a polished executive summary from the intelligence and analysis:
926
+ 1. Lead with the most important insight
927
+ 2. Include key metrics (weather, market, time)
928
+ 3. End with an actionable recommendation
929
+ Format as a brief executive memo (4-5 sentences). Start with "EXECUTIVE SUMMARY:"`
930
+ ),
931
+ ];
932
+
933
+ const edges: t.GraphEdge[] = [
934
+ {
935
+ from: 'intel_gatherer',
936
+ to: 'market_analyst',
937
+ edgeType: 'direct',
938
+ prompt: (messages: BaseMessage[], startIndex: number) => {
939
+ const buffer = getBufferString(messages.slice(startIndex));
940
+ return `Here is the gathered intelligence. Analyze the market sentiment and cross-reference with our database:\n\n${buffer}`;
941
+ },
942
+ excludeResults: true,
943
+ },
944
+ {
945
+ from: 'market_analyst',
946
+ to: 'presenter',
947
+ edgeType: 'direct',
948
+ prompt: (messages: BaseMessage[], startIndex: number) => {
949
+ const buffer = getBufferString(messages.slice(startIndex));
950
+ return `Here is the intelligence and market analysis. Create a polished executive summary:\n\n${buffer}`;
951
+ },
952
+ excludeResults: true,
953
+ },
954
+ ];
955
+
956
+ const { handlers, contentParts } = createHandlers('S6');
957
+
958
+ try {
959
+ const run = await Run.create({
960
+ runId: `s6-${Date.now()}`,
961
+ graphConfig: { type: 'multi-agent', agents, edges },
962
+ customHandlers: handlers,
963
+ returnContent: true,
964
+ skipCleanup: true,
965
+ });
966
+
967
+ await run.processStream(
968
+ {
969
+ messages: [
970
+ new HumanMessage(
971
+ 'Create a morning intelligence briefing: check Tokyo weather, NVDA stock, and JST time. Then analyze market sentiment and find relevant AI projects.'
972
+ ),
973
+ ],
974
+ },
975
+ { configurable: { thread_id: 's6' }, version: 'v2' as const }
976
+ );
977
+
978
+ const runMessages = run.getRunMessages();
979
+ const aiCount =
980
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
981
+ const toolCount =
982
+ runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
983
+
984
+ console.log(`\n\n--- S6 Results ---`);
985
+ console.log(` AI messages: ${aiCount}, Tool messages: ${toolCount}`);
986
+
987
+ /** Expect at least 5 tool calls (3 from gatherer + 2 from analyst) */
988
+ const success = aiCount >= 3 && toolCount >= 5;
989
+ printResult(
990
+ 'S6: Sequential — Multiple Tools',
991
+ success,
992
+ `AI msgs: ${aiCount} (expected 3+), Tool calls: ${toolCount} (expected ≥5)`
993
+ );
994
+ return success;
995
+ } catch (error) {
996
+ console.error('S6 error:', error);
997
+ printResult('S6: Sequential — Multiple Tools', false, String(error));
998
+ return false;
999
+ }
1000
+ }
1001
+
1002
+ /* ================================================================== */
1003
+ /* S7: Hybrid (Direct + Handoff) — Mixed Tools */
1004
+ /* planner --(direct)--> researcher [weather+stock] --(handoff)--> */
1005
+ /* writer OR analyst [sentiment] */
1006
+ /* Direct sequential flow + dynamic handoff with tools */
1007
+ /* ================================================================== */
1008
+ async function s7_hybrid_mixedTools(): Promise<boolean> {
1009
+ printHeader('S7: HYBRID (DIRECT + HANDOFF) — MIXED TOOLS');
1010
+ console.log(' planner --(direct)--> researcher [weather, stock]');
1011
+ console.log(' --(handoff)--> writer (no tools) OR analyst [sentiment]');
1012
+ console.log(' Combines direct sequential + dynamic handoff + tools\n');
1013
+
1014
+ const agents: t.AgentInputs[] = [
1015
+ agent(
1016
+ 'planner',
1017
+ 'Content Planner',
1018
+ `You are a Content Planner. Given a topic:
1019
+ 1. Create a brief 3-point outline for a market report
1020
+ 2. Specify what data needs to be gathered (weather and stock)
1021
+ 3. Note the target audience
1022
+ Keep it to 3-4 lines. Start with "PLAN:"`,
1023
+ { description: 'Plans content structure and outlines' }
1024
+ ),
1025
+ agent(
1026
+ 'researcher',
1027
+ 'Data Researcher',
1028
+ `You are a Data Researcher with get_weather and get_stock_price tools.
1029
+ Based on the content plan:
1030
+ 1. Use get_weather to get weather for the city mentioned in the plan (default: Los Angeles)
1031
+ 2. Use get_stock_price to get the stock price mentioned in the plan (default: GOOGL)
1032
+ 3. Briefly summarize your data findings (2-3 sentences)
1033
+ Then transfer to the writer to create the full report.
1034
+ IMPORTANT: After gathering data, you MUST use the transfer tool to send to the writer.
1035
+ Start with "RESEARCH DATA:"`,
1036
+ {
1037
+ tools: [getWeatherTool, getStockPriceTool],
1038
+ description:
1039
+ 'Gathers data using research tools, can route to writer or analyst',
1040
+ }
1041
+ ),
1042
+ agent(
1043
+ 'writer',
1044
+ 'Report Writer',
1045
+ `You are a Report Writer. Based on the plan and research data:
1046
+ 1. Write a brief market report (3-4 sentences)
1047
+ 2. Include specific data points from the research
1048
+ 3. Add a conclusion
1049
+ Start with "REPORT:" and keep it professional.`,
1050
+ { description: 'Writes formatted reports from research data' }
1051
+ ),
1052
+ agent(
1053
+ 'analyst',
1054
+ 'Sentiment Analyst',
1055
+ `You are a Sentiment Analyst with the analyze_sentiment tool.
1056
+ If you receive research data:
1057
+ 1. Use analyze_sentiment on a summary of the market conditions
1058
+ 2. Provide your sentiment assessment
1059
+ 3. Give a market outlook (bullish/bearish/neutral)
1060
+ Start with "SENTIMENT ANALYSIS:"`,
1061
+ {
1062
+ tools: [sentimentAnalysisTool],
1063
+ description: 'Analyzes sentiment of market data',
1064
+ }
1065
+ ),
1066
+ ];
1067
+
1068
+ const edges: t.GraphEdge[] = [
1069
+ /** Direct: planner always flows to researcher */
1070
+ {
1071
+ from: 'planner',
1072
+ to: 'researcher',
1073
+ edgeType: 'direct',
1074
+ prompt: (messages: BaseMessage[], startIndex: number) => {
1075
+ const buffer = getBufferString(messages.slice(startIndex));
1076
+ return `Here is the content plan. Gather the required data:\n\n${buffer}`;
1077
+ },
1078
+ excludeResults: true,
1079
+ },
1080
+ /** Handoff: researcher dynamically chooses writer or analyst */
1081
+ {
1082
+ from: 'researcher',
1083
+ to: 'writer',
1084
+ description:
1085
+ 'Transfer to the report writer to create a formatted market report from the gathered data',
1086
+ },
1087
+ {
1088
+ from: 'researcher',
1089
+ to: 'analyst',
1090
+ description:
1091
+ 'Transfer to the sentiment analyst for deeper market sentiment analysis',
1092
+ },
1093
+ ];
1094
+
1095
+ const { handlers, contentParts } = createHandlers('S7');
1096
+
1097
+ try {
1098
+ const run = await Run.create({
1099
+ runId: `s7-${Date.now()}`,
1100
+ graphConfig: { type: 'multi-agent', agents, edges },
1101
+ customHandlers: handlers,
1102
+ returnContent: true,
1103
+ skipCleanup: true,
1104
+ });
1105
+
1106
+ await run.processStream(
1107
+ {
1108
+ messages: [
1109
+ new HumanMessage(
1110
+ 'Create a market report: plan the structure, gather weather for Los Angeles and GOOGL stock data, then write the full report.'
1111
+ ),
1112
+ ],
1113
+ },
1114
+ { configurable: { thread_id: 's7' }, version: 'v2' as const }
1115
+ );
1116
+
1117
+ const runMessages = run.getRunMessages();
1118
+ const aiCount =
1119
+ runMessages?.filter((m) => m._getType() === 'ai').length ?? 0;
1120
+ const toolCount =
1121
+ runMessages?.filter((m) => m._getType() === 'tool').length ?? 0;
1122
+ const lastAgent = run.getLastActiveAgentId?.();
1123
+
1124
+ console.log(`\n\n--- S7 Results ---`);
1125
+ console.log(
1126
+ ` AI messages: ${aiCount}, Tool messages: ${toolCount}, Last agent: ${lastAgent}`
1127
+ );
1128
+
1129
+ /** Expect: planner (1 AI) + researcher (1+ AI with 2+ tools) + writer or analyst (1 AI) = 3+ AI, 2+ tools */
1130
+ const success = aiCount >= 3 && toolCount >= 2;
1131
+ printResult(
1132
+ 'S7: Hybrid — Mixed Tools',
1133
+ success,
1134
+ `AI msgs: ${aiCount} (expected 3+), Tools: ${toolCount} (expected ≥2), ` +
1135
+ `Last: ${lastAgent}, Direct (planner→researcher) + handoff (researcher→${lastAgent}) verified`
1136
+ );
1137
+ return success;
1138
+ } catch (error) {
1139
+ console.error('S7 error:', error);
1140
+ printResult('S7: Hybrid — Mixed Tools', false, String(error));
1141
+ return false;
1142
+ }
1143
+ }
1144
+
1145
+ /* ================================================================== */
1146
+ /* Main Runner */
1147
+ /* ================================================================== */
1148
+ async function main() {
1149
+ console.log('\n');
1150
+ console.log('*'.repeat(80));
1151
+ console.log('* ILLUMA AGENTS — COMPREHENSIVE MULTI-AGENT POC');
1152
+ console.log('* Provider: AWS Bedrock (Claude 3.5 Haiku)');
1153
+ console.log('*');
1154
+ console.log('* HANDOFF scenarios:');
1155
+ console.log(
1156
+ '* S1: No tools S2: Single tool S3: Multiple tools'
1157
+ );
1158
+ console.log('* SEQUENTIAL scenarios:');
1159
+ console.log(
1160
+ '* S4: No tools S5: Single tool S6: Multiple tools'
1161
+ );
1162
+ console.log('* HYBRID:');
1163
+ console.log('* S7: Direct + Handoff + Mixed tools');
1164
+ console.log('*'.repeat(80));
1165
+
1166
+ const results: Record<string, boolean> = {};
1167
+
1168
+ /** Run all scenarios sequentially for clear output */
1169
+ results['S1: Handoff — No Tools'] = await s1_handoff_noTools();
1170
+ results['S2: Handoff — Single Tool'] = await s2_handoff_singleTool();
1171
+ results['S3: Handoff — Multiple Tools (3)'] =
1172
+ await s3_handoff_multipleTools();
1173
+ results['S4: Sequential — No Tools'] = await s4_sequential_noTools();
1174
+ results['S5: Sequential — Single Tool'] = await s5_sequential_singleTool();
1175
+ results['S6: Sequential — Multiple Tools (2-3)'] =
1176
+ await s6_sequential_multipleTools();
1177
+ results['S7: Hybrid — Direct + Handoff + Tools'] =
1178
+ await s7_hybrid_mixedTools();
1179
+
1180
+ /** Final summary */
1181
+ printHeader('POC RESULTS SUMMARY');
1182
+
1183
+ const entries = Object.entries(results);
1184
+ let passCount = 0;
1185
+
1186
+ console.log('\n HANDOFF:');
1187
+ for (const [name, passed] of entries.filter(
1188
+ ([n]) => n.startsWith('S1') || n.startsWith('S2') || n.startsWith('S3')
1189
+ )) {
1190
+ console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
1191
+ if (passed) passCount++;
1192
+ }
1193
+
1194
+ console.log('\n SEQUENTIAL:');
1195
+ for (const [name, passed] of entries.filter(
1196
+ ([n]) => n.startsWith('S4') || n.startsWith('S5') || n.startsWith('S6')
1197
+ )) {
1198
+ console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
1199
+ if (passed) passCount++;
1200
+ }
1201
+
1202
+ console.log('\n HYBRID:');
1203
+ for (const [name, passed] of entries.filter(([n]) => n.startsWith('S7'))) {
1204
+ console.log(` ${passed ? '[PASS]' : '[FAIL]'} ${name}`);
1205
+ if (passed) passCount++;
1206
+ }
1207
+
1208
+ console.log(`\n ${passCount}/${entries.length} scenarios passed`);
1209
+
1210
+ if (passCount === entries.length) {
1211
+ console.log('\n All scenarios passed! Multi-agent system fully verified.');
1212
+ } else {
1213
+ console.log('\n Some scenarios failed. Check output above for details.');
1214
+ }
1215
+
1216
+ console.log('\n' + '='.repeat(80));
1217
+ }
1218
+
1219
+ main().catch((err) => {
1220
+ console.error('Fatal error:', err);
1221
+ process.exit(1);
1222
+ });