@illuma-ai/agents 1.0.81

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 (558) hide show
  1. package/README.md +485 -0
  2. package/dist/cjs/agents/AgentContext.cjs +734 -0
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -0
  4. package/dist/cjs/common/enum.cjs +190 -0
  5. package/dist/cjs/common/enum.cjs.map +1 -0
  6. package/dist/cjs/events.cjs +172 -0
  7. package/dist/cjs/events.cjs.map +1 -0
  8. package/dist/cjs/graphs/Graph.cjs +1615 -0
  9. package/dist/cjs/graphs/Graph.cjs.map +1 -0
  10. package/dist/cjs/graphs/MultiAgentGraph.cjs +890 -0
  11. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -0
  12. package/dist/cjs/instrumentation.cjs +21 -0
  13. package/dist/cjs/instrumentation.cjs.map +1 -0
  14. package/dist/cjs/llm/anthropic/index.cjs +292 -0
  15. package/dist/cjs/llm/anthropic/index.cjs.map +1 -0
  16. package/dist/cjs/llm/anthropic/types.cjs +50 -0
  17. package/dist/cjs/llm/anthropic/types.cjs.map +1 -0
  18. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +630 -0
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -0
  20. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +218 -0
  21. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -0
  22. package/dist/cjs/llm/anthropic/utils/tools.cjs +29 -0
  23. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -0
  24. package/dist/cjs/llm/bedrock/index.cjs +282 -0
  25. package/dist/cjs/llm/bedrock/index.cjs.map +1 -0
  26. package/dist/cjs/llm/fake.cjs +97 -0
  27. package/dist/cjs/llm/fake.cjs.map +1 -0
  28. package/dist/cjs/llm/google/index.cjs +216 -0
  29. package/dist/cjs/llm/google/index.cjs.map +1 -0
  30. package/dist/cjs/llm/google/utils/common.cjs +647 -0
  31. package/dist/cjs/llm/google/utils/common.cjs.map +1 -0
  32. package/dist/cjs/llm/openai/index.cjs +1028 -0
  33. package/dist/cjs/llm/openai/index.cjs.map +1 -0
  34. package/dist/cjs/llm/openai/utils/index.cjs +765 -0
  35. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -0
  36. package/dist/cjs/llm/openrouter/index.cjs +212 -0
  37. package/dist/cjs/llm/openrouter/index.cjs.map +1 -0
  38. package/dist/cjs/llm/providers.cjs +43 -0
  39. package/dist/cjs/llm/providers.cjs.map +1 -0
  40. package/dist/cjs/llm/text.cjs +69 -0
  41. package/dist/cjs/llm/text.cjs.map +1 -0
  42. package/dist/cjs/llm/vertexai/index.cjs +329 -0
  43. package/dist/cjs/llm/vertexai/index.cjs.map +1 -0
  44. package/dist/cjs/main.cjs +240 -0
  45. package/dist/cjs/main.cjs.map +1 -0
  46. package/dist/cjs/messages/cache.cjs +387 -0
  47. package/dist/cjs/messages/cache.cjs.map +1 -0
  48. package/dist/cjs/messages/content.cjs +53 -0
  49. package/dist/cjs/messages/content.cjs.map +1 -0
  50. package/dist/cjs/messages/core.cjs +367 -0
  51. package/dist/cjs/messages/core.cjs.map +1 -0
  52. package/dist/cjs/messages/format.cjs +761 -0
  53. package/dist/cjs/messages/format.cjs.map +1 -0
  54. package/dist/cjs/messages/ids.cjs +23 -0
  55. package/dist/cjs/messages/ids.cjs.map +1 -0
  56. package/dist/cjs/messages/prune.cjs +398 -0
  57. package/dist/cjs/messages/prune.cjs.map +1 -0
  58. package/dist/cjs/messages/tools.cjs +96 -0
  59. package/dist/cjs/messages/tools.cjs.map +1 -0
  60. package/dist/cjs/run.cjs +328 -0
  61. package/dist/cjs/run.cjs.map +1 -0
  62. package/dist/cjs/schemas/validate.cjs +324 -0
  63. package/dist/cjs/schemas/validate.cjs.map +1 -0
  64. package/dist/cjs/splitStream.cjs +210 -0
  65. package/dist/cjs/splitStream.cjs.map +1 -0
  66. package/dist/cjs/stream.cjs +620 -0
  67. package/dist/cjs/stream.cjs.map +1 -0
  68. package/dist/cjs/tools/BrowserTools.cjs +248 -0
  69. package/dist/cjs/tools/BrowserTools.cjs.map +1 -0
  70. package/dist/cjs/tools/Calculator.cjs +66 -0
  71. package/dist/cjs/tools/Calculator.cjs.map +1 -0
  72. package/dist/cjs/tools/CodeExecutor.cjs +234 -0
  73. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -0
  74. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +636 -0
  75. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -0
  76. package/dist/cjs/tools/ToolNode.cjs +548 -0
  77. package/dist/cjs/tools/ToolNode.cjs.map +1 -0
  78. package/dist/cjs/tools/ToolSearch.cjs +909 -0
  79. package/dist/cjs/tools/ToolSearch.cjs.map +1 -0
  80. package/dist/cjs/tools/handlers.cjs +255 -0
  81. package/dist/cjs/tools/handlers.cjs.map +1 -0
  82. package/dist/cjs/tools/schema.cjs +31 -0
  83. package/dist/cjs/tools/schema.cjs.map +1 -0
  84. package/dist/cjs/tools/search/anthropic.cjs +40 -0
  85. package/dist/cjs/tools/search/anthropic.cjs.map +1 -0
  86. package/dist/cjs/tools/search/content.cjs +140 -0
  87. package/dist/cjs/tools/search/content.cjs.map +1 -0
  88. package/dist/cjs/tools/search/firecrawl.cjs +179 -0
  89. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -0
  90. package/dist/cjs/tools/search/format.cjs +203 -0
  91. package/dist/cjs/tools/search/format.cjs.map +1 -0
  92. package/dist/cjs/tools/search/highlights.cjs +245 -0
  93. package/dist/cjs/tools/search/highlights.cjs.map +1 -0
  94. package/dist/cjs/tools/search/rerankers.cjs +174 -0
  95. package/dist/cjs/tools/search/rerankers.cjs.map +1 -0
  96. package/dist/cjs/tools/search/schema.cjs +117 -0
  97. package/dist/cjs/tools/search/schema.cjs.map +1 -0
  98. package/dist/cjs/tools/search/search.cjs +566 -0
  99. package/dist/cjs/tools/search/search.cjs.map +1 -0
  100. package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
  101. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
  102. package/dist/cjs/tools/search/tool.cjs +456 -0
  103. package/dist/cjs/tools/search/tool.cjs.map +1 -0
  104. package/dist/cjs/tools/search/utils.cjs +66 -0
  105. package/dist/cjs/tools/search/utils.cjs.map +1 -0
  106. package/dist/cjs/types/graph.cjs +29 -0
  107. package/dist/cjs/types/graph.cjs.map +1 -0
  108. package/dist/cjs/utils/contextAnalytics.cjs +66 -0
  109. package/dist/cjs/utils/contextAnalytics.cjs.map +1 -0
  110. package/dist/cjs/utils/events.cjs +31 -0
  111. package/dist/cjs/utils/events.cjs.map +1 -0
  112. package/dist/cjs/utils/graph.cjs +16 -0
  113. package/dist/cjs/utils/graph.cjs.map +1 -0
  114. package/dist/cjs/utils/handlers.cjs +70 -0
  115. package/dist/cjs/utils/handlers.cjs.map +1 -0
  116. package/dist/cjs/utils/llm.cjs +27 -0
  117. package/dist/cjs/utils/llm.cjs.map +1 -0
  118. package/dist/cjs/utils/misc.cjs +56 -0
  119. package/dist/cjs/utils/misc.cjs.map +1 -0
  120. package/dist/cjs/utils/run.cjs +73 -0
  121. package/dist/cjs/utils/run.cjs.map +1 -0
  122. package/dist/cjs/utils/schema.cjs +27 -0
  123. package/dist/cjs/utils/schema.cjs.map +1 -0
  124. package/dist/cjs/utils/title.cjs +125 -0
  125. package/dist/cjs/utils/title.cjs.map +1 -0
  126. package/dist/cjs/utils/tokens.cjs +125 -0
  127. package/dist/cjs/utils/tokens.cjs.map +1 -0
  128. package/dist/cjs/utils/toonFormat.cjs +388 -0
  129. package/dist/cjs/utils/toonFormat.cjs.map +1 -0
  130. package/dist/esm/agents/AgentContext.mjs +732 -0
  131. package/dist/esm/agents/AgentContext.mjs.map +1 -0
  132. package/dist/esm/common/enum.mjs +190 -0
  133. package/dist/esm/common/enum.mjs.map +1 -0
  134. package/dist/esm/events.mjs +164 -0
  135. package/dist/esm/events.mjs.map +1 -0
  136. package/dist/esm/graphs/Graph.mjs +1612 -0
  137. package/dist/esm/graphs/Graph.mjs.map +1 -0
  138. package/dist/esm/graphs/MultiAgentGraph.mjs +888 -0
  139. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -0
  140. package/dist/esm/instrumentation.mjs +19 -0
  141. package/dist/esm/instrumentation.mjs.map +1 -0
  142. package/dist/esm/llm/anthropic/index.mjs +290 -0
  143. package/dist/esm/llm/anthropic/index.mjs.map +1 -0
  144. package/dist/esm/llm/anthropic/types.mjs +48 -0
  145. package/dist/esm/llm/anthropic/types.mjs.map +1 -0
  146. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +627 -0
  147. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -0
  148. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +216 -0
  149. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -0
  150. package/dist/esm/llm/anthropic/utils/tools.mjs +27 -0
  151. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -0
  152. package/dist/esm/llm/bedrock/index.mjs +280 -0
  153. package/dist/esm/llm/bedrock/index.mjs.map +1 -0
  154. package/dist/esm/llm/fake.mjs +94 -0
  155. package/dist/esm/llm/fake.mjs.map +1 -0
  156. package/dist/esm/llm/google/index.mjs +214 -0
  157. package/dist/esm/llm/google/index.mjs.map +1 -0
  158. package/dist/esm/llm/google/utils/common.mjs +638 -0
  159. package/dist/esm/llm/google/utils/common.mjs.map +1 -0
  160. package/dist/esm/llm/openai/index.mjs +1018 -0
  161. package/dist/esm/llm/openai/index.mjs.map +1 -0
  162. package/dist/esm/llm/openai/utils/index.mjs +759 -0
  163. package/dist/esm/llm/openai/utils/index.mjs.map +1 -0
  164. package/dist/esm/llm/openrouter/index.mjs +210 -0
  165. package/dist/esm/llm/openrouter/index.mjs.map +1 -0
  166. package/dist/esm/llm/providers.mjs +39 -0
  167. package/dist/esm/llm/providers.mjs.map +1 -0
  168. package/dist/esm/llm/text.mjs +67 -0
  169. package/dist/esm/llm/text.mjs.map +1 -0
  170. package/dist/esm/llm/vertexai/index.mjs +327 -0
  171. package/dist/esm/llm/vertexai/index.mjs.map +1 -0
  172. package/dist/esm/main.mjs +37 -0
  173. package/dist/esm/main.mjs.map +1 -0
  174. package/dist/esm/messages/cache.mjs +382 -0
  175. package/dist/esm/messages/cache.mjs.map +1 -0
  176. package/dist/esm/messages/content.mjs +51 -0
  177. package/dist/esm/messages/content.mjs.map +1 -0
  178. package/dist/esm/messages/core.mjs +359 -0
  179. package/dist/esm/messages/core.mjs.map +1 -0
  180. package/dist/esm/messages/format.mjs +752 -0
  181. package/dist/esm/messages/format.mjs.map +1 -0
  182. package/dist/esm/messages/ids.mjs +21 -0
  183. package/dist/esm/messages/ids.mjs.map +1 -0
  184. package/dist/esm/messages/prune.mjs +393 -0
  185. package/dist/esm/messages/prune.mjs.map +1 -0
  186. package/dist/esm/messages/tools.mjs +93 -0
  187. package/dist/esm/messages/tools.mjs.map +1 -0
  188. package/dist/esm/run.mjs +325 -0
  189. package/dist/esm/run.mjs.map +1 -0
  190. package/dist/esm/schemas/validate.mjs +317 -0
  191. package/dist/esm/schemas/validate.mjs.map +1 -0
  192. package/dist/esm/splitStream.mjs +207 -0
  193. package/dist/esm/splitStream.mjs.map +1 -0
  194. package/dist/esm/stream.mjs +616 -0
  195. package/dist/esm/stream.mjs.map +1 -0
  196. package/dist/esm/tools/BrowserTools.mjs +244 -0
  197. package/dist/esm/tools/BrowserTools.mjs.map +1 -0
  198. package/dist/esm/tools/Calculator.mjs +41 -0
  199. package/dist/esm/tools/Calculator.mjs.map +1 -0
  200. package/dist/esm/tools/CodeExecutor.mjs +226 -0
  201. package/dist/esm/tools/CodeExecutor.mjs.map +1 -0
  202. package/dist/esm/tools/ProgrammaticToolCalling.mjs +622 -0
  203. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -0
  204. package/dist/esm/tools/ToolNode.mjs +545 -0
  205. package/dist/esm/tools/ToolNode.mjs.map +1 -0
  206. package/dist/esm/tools/ToolSearch.mjs +870 -0
  207. package/dist/esm/tools/ToolSearch.mjs.map +1 -0
  208. package/dist/esm/tools/handlers.mjs +250 -0
  209. package/dist/esm/tools/handlers.mjs.map +1 -0
  210. package/dist/esm/tools/schema.mjs +28 -0
  211. package/dist/esm/tools/schema.mjs.map +1 -0
  212. package/dist/esm/tools/search/anthropic.mjs +37 -0
  213. package/dist/esm/tools/search/anthropic.mjs.map +1 -0
  214. package/dist/esm/tools/search/content.mjs +119 -0
  215. package/dist/esm/tools/search/content.mjs.map +1 -0
  216. package/dist/esm/tools/search/firecrawl.mjs +176 -0
  217. package/dist/esm/tools/search/firecrawl.mjs.map +1 -0
  218. package/dist/esm/tools/search/format.mjs +201 -0
  219. package/dist/esm/tools/search/format.mjs.map +1 -0
  220. package/dist/esm/tools/search/highlights.mjs +243 -0
  221. package/dist/esm/tools/search/highlights.mjs.map +1 -0
  222. package/dist/esm/tools/search/rerankers.mjs +168 -0
  223. package/dist/esm/tools/search/rerankers.mjs.map +1 -0
  224. package/dist/esm/tools/search/schema.mjs +104 -0
  225. package/dist/esm/tools/search/schema.mjs.map +1 -0
  226. package/dist/esm/tools/search/search.mjs +563 -0
  227. package/dist/esm/tools/search/search.mjs.map +1 -0
  228. package/dist/esm/tools/search/serper-scraper.mjs +129 -0
  229. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
  230. package/dist/esm/tools/search/tool.mjs +454 -0
  231. package/dist/esm/tools/search/tool.mjs.map +1 -0
  232. package/dist/esm/tools/search/utils.mjs +61 -0
  233. package/dist/esm/tools/search/utils.mjs.map +1 -0
  234. package/dist/esm/types/graph.mjs +26 -0
  235. package/dist/esm/types/graph.mjs.map +1 -0
  236. package/dist/esm/utils/contextAnalytics.mjs +64 -0
  237. package/dist/esm/utils/contextAnalytics.mjs.map +1 -0
  238. package/dist/esm/utils/events.mjs +29 -0
  239. package/dist/esm/utils/events.mjs.map +1 -0
  240. package/dist/esm/utils/graph.mjs +13 -0
  241. package/dist/esm/utils/graph.mjs.map +1 -0
  242. package/dist/esm/utils/handlers.mjs +68 -0
  243. package/dist/esm/utils/handlers.mjs.map +1 -0
  244. package/dist/esm/utils/llm.mjs +24 -0
  245. package/dist/esm/utils/llm.mjs.map +1 -0
  246. package/dist/esm/utils/misc.mjs +53 -0
  247. package/dist/esm/utils/misc.mjs.map +1 -0
  248. package/dist/esm/utils/run.mjs +70 -0
  249. package/dist/esm/utils/run.mjs.map +1 -0
  250. package/dist/esm/utils/schema.mjs +24 -0
  251. package/dist/esm/utils/schema.mjs.map +1 -0
  252. package/dist/esm/utils/title.mjs +122 -0
  253. package/dist/esm/utils/title.mjs.map +1 -0
  254. package/dist/esm/utils/tokens.mjs +121 -0
  255. package/dist/esm/utils/tokens.mjs.map +1 -0
  256. package/dist/esm/utils/toonFormat.mjs +381 -0
  257. package/dist/esm/utils/toonFormat.mjs.map +1 -0
  258. package/dist/types/agents/AgentContext.d.ts +293 -0
  259. package/dist/types/common/enum.d.ts +155 -0
  260. package/dist/types/common/index.d.ts +1 -0
  261. package/dist/types/events.d.ts +31 -0
  262. package/dist/types/graphs/Graph.d.ts +216 -0
  263. package/dist/types/graphs/MultiAgentGraph.d.ts +104 -0
  264. package/dist/types/graphs/index.d.ts +2 -0
  265. package/dist/types/index.d.ts +21 -0
  266. package/dist/types/instrumentation.d.ts +1 -0
  267. package/dist/types/llm/anthropic/index.d.ts +39 -0
  268. package/dist/types/llm/anthropic/types.d.ts +37 -0
  269. package/dist/types/llm/anthropic/utils/message_inputs.d.ts +14 -0
  270. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +14 -0
  271. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +22 -0
  272. package/dist/types/llm/anthropic/utils/tools.d.ts +3 -0
  273. package/dist/types/llm/bedrock/index.d.ts +141 -0
  274. package/dist/types/llm/bedrock/types.d.ts +27 -0
  275. package/dist/types/llm/bedrock/utils/index.d.ts +5 -0
  276. package/dist/types/llm/bedrock/utils/message_inputs.d.ts +31 -0
  277. package/dist/types/llm/bedrock/utils/message_outputs.d.ts +33 -0
  278. package/dist/types/llm/fake.d.ts +31 -0
  279. package/dist/types/llm/google/index.d.ts +24 -0
  280. package/dist/types/llm/google/types.d.ts +42 -0
  281. package/dist/types/llm/google/utils/common.d.ts +34 -0
  282. package/dist/types/llm/google/utils/tools.d.ts +10 -0
  283. package/dist/types/llm/google/utils/zod_to_genai_parameters.d.ts +14 -0
  284. package/dist/types/llm/openai/index.d.ts +127 -0
  285. package/dist/types/llm/openai/types.d.ts +10 -0
  286. package/dist/types/llm/openai/utils/index.d.ts +29 -0
  287. package/dist/types/llm/openrouter/index.d.ts +15 -0
  288. package/dist/types/llm/providers.d.ts +5 -0
  289. package/dist/types/llm/text.d.ts +21 -0
  290. package/dist/types/llm/vertexai/index.d.ts +293 -0
  291. package/dist/types/messages/cache.d.ts +54 -0
  292. package/dist/types/messages/content.d.ts +7 -0
  293. package/dist/types/messages/core.d.ts +14 -0
  294. package/dist/types/messages/format.d.ts +137 -0
  295. package/dist/types/messages/ids.d.ts +3 -0
  296. package/dist/types/messages/index.d.ts +7 -0
  297. package/dist/types/messages/prune.d.ts +52 -0
  298. package/dist/types/messages/reducer.d.ts +9 -0
  299. package/dist/types/messages/tools.d.ts +17 -0
  300. package/dist/types/mockStream.d.ts +32 -0
  301. package/dist/types/prompts/collab.d.ts +1 -0
  302. package/dist/types/prompts/index.d.ts +2 -0
  303. package/dist/types/prompts/taskmanager.d.ts +41 -0
  304. package/dist/types/run.d.ts +41 -0
  305. package/dist/types/schemas/index.d.ts +1 -0
  306. package/dist/types/schemas/validate.d.ts +59 -0
  307. package/dist/types/splitStream.d.ts +37 -0
  308. package/dist/types/stream.d.ts +15 -0
  309. package/dist/types/test/mockTools.d.ts +28 -0
  310. package/dist/types/tools/BrowserTools.d.ts +87 -0
  311. package/dist/types/tools/Calculator.d.ts +34 -0
  312. package/dist/types/tools/CodeExecutor.d.ts +57 -0
  313. package/dist/types/tools/ProgrammaticToolCalling.d.ts +138 -0
  314. package/dist/types/tools/ToolNode.d.ts +51 -0
  315. package/dist/types/tools/ToolSearch.d.ts +219 -0
  316. package/dist/types/tools/handlers.d.ts +22 -0
  317. package/dist/types/tools/schema.d.ts +12 -0
  318. package/dist/types/tools/search/anthropic.d.ts +16 -0
  319. package/dist/types/tools/search/content.d.ts +4 -0
  320. package/dist/types/tools/search/firecrawl.d.ts +54 -0
  321. package/dist/types/tools/search/format.d.ts +5 -0
  322. package/dist/types/tools/search/highlights.d.ts +13 -0
  323. package/dist/types/tools/search/index.d.ts +3 -0
  324. package/dist/types/tools/search/rerankers.d.ts +38 -0
  325. package/dist/types/tools/search/schema.d.ts +103 -0
  326. package/dist/types/tools/search/search.d.ts +8 -0
  327. package/dist/types/tools/search/serper-scraper.d.ts +59 -0
  328. package/dist/types/tools/search/test.d.ts +1 -0
  329. package/dist/types/tools/search/tool.d.ts +3 -0
  330. package/dist/types/tools/search/types.d.ts +575 -0
  331. package/dist/types/tools/search/utils.d.ts +10 -0
  332. package/dist/types/types/graph.d.ts +399 -0
  333. package/dist/types/types/index.d.ts +5 -0
  334. package/dist/types/types/llm.d.ts +105 -0
  335. package/dist/types/types/messages.d.ts +4 -0
  336. package/dist/types/types/run.d.ts +112 -0
  337. package/dist/types/types/stream.d.ts +308 -0
  338. package/dist/types/types/tools.d.ts +296 -0
  339. package/dist/types/utils/contextAnalytics.d.ts +37 -0
  340. package/dist/types/utils/events.d.ts +6 -0
  341. package/dist/types/utils/graph.d.ts +2 -0
  342. package/dist/types/utils/handlers.d.ts +34 -0
  343. package/dist/types/utils/index.d.ts +9 -0
  344. package/dist/types/utils/llm.d.ts +3 -0
  345. package/dist/types/utils/llmConfig.d.ts +3 -0
  346. package/dist/types/utils/logging.d.ts +1 -0
  347. package/dist/types/utils/misc.d.ts +7 -0
  348. package/dist/types/utils/run.d.ts +27 -0
  349. package/dist/types/utils/schema.d.ts +8 -0
  350. package/dist/types/utils/title.d.ts +4 -0
  351. package/dist/types/utils/tokens.d.ts +28 -0
  352. package/dist/types/utils/toonFormat.d.ts +111 -0
  353. package/package.json +190 -0
  354. package/src/agents/AgentContext.test.ts +458 -0
  355. package/src/agents/AgentContext.ts +972 -0
  356. package/src/agents/__tests__/AgentContext.test.ts +805 -0
  357. package/src/agents/__tests__/resolveStructuredOutputMode.test.ts +137 -0
  358. package/src/common/enum.ts +203 -0
  359. package/src/common/index.ts +2 -0
  360. package/src/events.ts +223 -0
  361. package/src/graphs/Graph.ts +2228 -0
  362. package/src/graphs/MultiAgentGraph.ts +1063 -0
  363. package/src/graphs/__tests__/structured-output.integration.test.ts +809 -0
  364. package/src/graphs/__tests__/structured-output.test.ts +183 -0
  365. package/src/graphs/index.ts +2 -0
  366. package/src/index.ts +34 -0
  367. package/src/instrumentation.ts +22 -0
  368. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  369. package/src/llm/anthropic/index.ts +413 -0
  370. package/src/llm/anthropic/llm.spec.ts +1442 -0
  371. package/src/llm/anthropic/types.ts +140 -0
  372. package/src/llm/anthropic/utils/message_inputs.ts +757 -0
  373. package/src/llm/anthropic/utils/message_outputs.ts +289 -0
  374. package/src/llm/anthropic/utils/output_parsers.ts +133 -0
  375. package/src/llm/anthropic/utils/tools.ts +29 -0
  376. package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +495 -0
  377. package/src/llm/bedrock/index.ts +411 -0
  378. package/src/llm/bedrock/llm.spec.ts +616 -0
  379. package/src/llm/bedrock/types.ts +51 -0
  380. package/src/llm/bedrock/utils/index.ts +18 -0
  381. package/src/llm/bedrock/utils/message_inputs.ts +563 -0
  382. package/src/llm/bedrock/utils/message_outputs.ts +310 -0
  383. package/src/llm/fake.ts +133 -0
  384. package/src/llm/google/data/gettysburg10.wav +0 -0
  385. package/src/llm/google/data/hotdog.jpg +0 -0
  386. package/src/llm/google/index.ts +337 -0
  387. package/src/llm/google/llm.spec.ts +934 -0
  388. package/src/llm/google/types.ts +56 -0
  389. package/src/llm/google/utils/common.ts +873 -0
  390. package/src/llm/google/utils/tools.ts +160 -0
  391. package/src/llm/google/utils/zod_to_genai_parameters.ts +86 -0
  392. package/src/llm/openai/index.ts +1366 -0
  393. package/src/llm/openai/types.ts +24 -0
  394. package/src/llm/openai/utils/index.ts +1035 -0
  395. package/src/llm/openai/utils/isReasoningModel.test.ts +90 -0
  396. package/src/llm/openrouter/index.ts +291 -0
  397. package/src/llm/providers.ts +52 -0
  398. package/src/llm/text.ts +94 -0
  399. package/src/llm/vertexai/index.ts +359 -0
  400. package/src/messages/__tests__/tools.test.ts +473 -0
  401. package/src/messages/cache.test.ts +1261 -0
  402. package/src/messages/cache.ts +518 -0
  403. package/src/messages/content.test.ts +362 -0
  404. package/src/messages/content.ts +63 -0
  405. package/src/messages/core.ts +473 -0
  406. package/src/messages/ensureThinkingBlock.test.ts +468 -0
  407. package/src/messages/format.ts +1029 -0
  408. package/src/messages/formatAgentMessages.test.ts +1513 -0
  409. package/src/messages/formatAgentMessages.tools.test.ts +419 -0
  410. package/src/messages/formatMessage.test.ts +693 -0
  411. package/src/messages/ids.ts +26 -0
  412. package/src/messages/index.ts +7 -0
  413. package/src/messages/labelContentByAgent.test.ts +887 -0
  414. package/src/messages/prune.ts +568 -0
  415. package/src/messages/reducer.ts +80 -0
  416. package/src/messages/shiftIndexTokenCountMap.test.ts +81 -0
  417. package/src/messages/tools.ts +108 -0
  418. package/src/mockStream.ts +99 -0
  419. package/src/prompts/collab.ts +6 -0
  420. package/src/prompts/index.ts +2 -0
  421. package/src/prompts/taskmanager.ts +61 -0
  422. package/src/run.ts +467 -0
  423. package/src/schemas/index.ts +2 -0
  424. package/src/schemas/schema-preparation.test.ts +500 -0
  425. package/src/schemas/validate.test.ts +358 -0
  426. package/src/schemas/validate.ts +454 -0
  427. package/src/scripts/abort.ts +157 -0
  428. package/src/scripts/ant_web_search.ts +158 -0
  429. package/src/scripts/ant_web_search_edge_case.ts +162 -0
  430. package/src/scripts/ant_web_search_error_edge_case.ts +148 -0
  431. package/src/scripts/args.ts +48 -0
  432. package/src/scripts/caching.ts +132 -0
  433. package/src/scripts/cli.ts +172 -0
  434. package/src/scripts/cli2.ts +133 -0
  435. package/src/scripts/cli3.ts +184 -0
  436. package/src/scripts/cli4.ts +191 -0
  437. package/src/scripts/cli5.ts +191 -0
  438. package/src/scripts/code_exec.ts +213 -0
  439. package/src/scripts/code_exec_files.ts +236 -0
  440. package/src/scripts/code_exec_multi_session.ts +241 -0
  441. package/src/scripts/code_exec_ptc.ts +334 -0
  442. package/src/scripts/code_exec_session.ts +282 -0
  443. package/src/scripts/code_exec_simple.ts +147 -0
  444. package/src/scripts/content.ts +138 -0
  445. package/src/scripts/empty_input.ts +137 -0
  446. package/src/scripts/handoff-test.ts +135 -0
  447. package/src/scripts/image.ts +178 -0
  448. package/src/scripts/memory.ts +97 -0
  449. package/src/scripts/multi-agent-chain.ts +331 -0
  450. package/src/scripts/multi-agent-conditional.ts +221 -0
  451. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  452. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  453. package/src/scripts/multi-agent-parallel-start.ts +265 -0
  454. package/src/scripts/multi-agent-parallel.ts +394 -0
  455. package/src/scripts/multi-agent-sequence.ts +217 -0
  456. package/src/scripts/multi-agent-supervisor.ts +365 -0
  457. package/src/scripts/multi-agent-test.ts +186 -0
  458. package/src/scripts/parallel-asymmetric-tools-test.ts +274 -0
  459. package/src/scripts/parallel-full-metadata-test.ts +240 -0
  460. package/src/scripts/parallel-tools-test.ts +340 -0
  461. package/src/scripts/programmatic_exec.ts +396 -0
  462. package/src/scripts/programmatic_exec_agent.ts +231 -0
  463. package/src/scripts/search.ts +146 -0
  464. package/src/scripts/sequential-full-metadata-test.ts +197 -0
  465. package/src/scripts/simple.ts +225 -0
  466. package/src/scripts/single-agent-metadata-test.ts +198 -0
  467. package/src/scripts/stream.ts +140 -0
  468. package/src/scripts/test-custom-prompt-key.ts +145 -0
  469. package/src/scripts/test-handoff-input.ts +170 -0
  470. package/src/scripts/test-handoff-preamble.ts +277 -0
  471. package/src/scripts/test-multi-agent-list-handoff.ts +417 -0
  472. package/src/scripts/test-parallel-agent-labeling.ts +325 -0
  473. package/src/scripts/test-parallel-handoffs.ts +291 -0
  474. package/src/scripts/test-thinking-handoff-bedrock.ts +153 -0
  475. package/src/scripts/test-thinking-handoff.ts +155 -0
  476. package/src/scripts/test-tools-before-handoff.ts +226 -0
  477. package/src/scripts/test_code_api.ts +361 -0
  478. package/src/scripts/thinking-bedrock.ts +159 -0
  479. package/src/scripts/thinking.ts +171 -0
  480. package/src/scripts/tool_search.ts +162 -0
  481. package/src/scripts/tools.ts +177 -0
  482. package/src/specs/agent-handoffs.test.ts +888 -0
  483. package/src/specs/anthropic.simple.test.ts +387 -0
  484. package/src/specs/azure.simple.test.ts +364 -0
  485. package/src/specs/cache.simple.test.ts +396 -0
  486. package/src/specs/deepseek.simple.test.ts +283 -0
  487. package/src/specs/emergency-prune.test.ts +407 -0
  488. package/src/specs/moonshot.simple.test.ts +358 -0
  489. package/src/specs/openai.simple.test.ts +311 -0
  490. package/src/specs/openrouter.simple.test.ts +107 -0
  491. package/src/specs/prune.test.ts +901 -0
  492. package/src/specs/reasoning.test.ts +201 -0
  493. package/src/specs/spec.utils.ts +3 -0
  494. package/src/specs/thinking-handoff.test.ts +620 -0
  495. package/src/specs/thinking-prune.test.ts +703 -0
  496. package/src/specs/token-distribution-edge-case.test.ts +316 -0
  497. package/src/specs/token-memoization.test.ts +32 -0
  498. package/src/specs/tool-error.test.ts +198 -0
  499. package/src/splitStream.test.ts +691 -0
  500. package/src/splitStream.ts +234 -0
  501. package/src/stream.test.ts +94 -0
  502. package/src/stream.ts +801 -0
  503. package/src/test/mockTools.ts +386 -0
  504. package/src/tools/BrowserTools.ts +393 -0
  505. package/src/tools/Calculator.test.ts +278 -0
  506. package/src/tools/Calculator.ts +46 -0
  507. package/src/tools/CodeExecutor.ts +270 -0
  508. package/src/tools/ProgrammaticToolCalling.ts +785 -0
  509. package/src/tools/ToolNode.ts +674 -0
  510. package/src/tools/ToolSearch.ts +1095 -0
  511. package/src/tools/__tests__/BrowserTools.test.ts +265 -0
  512. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.ts +319 -0
  513. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +1006 -0
  514. package/src/tools/__tests__/ToolSearch.integration.test.ts +162 -0
  515. package/src/tools/__tests__/ToolSearch.test.ts +1003 -0
  516. package/src/tools/handlers.ts +363 -0
  517. package/src/tools/schema.ts +37 -0
  518. package/src/tools/search/anthropic.ts +51 -0
  519. package/src/tools/search/content.test.ts +173 -0
  520. package/src/tools/search/content.ts +147 -0
  521. package/src/tools/search/firecrawl.ts +210 -0
  522. package/src/tools/search/format.ts +250 -0
  523. package/src/tools/search/highlights.ts +320 -0
  524. package/src/tools/search/index.ts +3 -0
  525. package/src/tools/search/jina-reranker.test.ts +130 -0
  526. package/src/tools/search/output.md +2775 -0
  527. package/src/tools/search/rerankers.ts +242 -0
  528. package/src/tools/search/schema.ts +113 -0
  529. package/src/tools/search/search.ts +768 -0
  530. package/src/tools/search/serper-scraper.ts +155 -0
  531. package/src/tools/search/test.html +884 -0
  532. package/src/tools/search/test.md +643 -0
  533. package/src/tools/search/test.ts +159 -0
  534. package/src/tools/search/tool.ts +657 -0
  535. package/src/tools/search/types.ts +665 -0
  536. package/src/tools/search/utils.ts +79 -0
  537. package/src/types/graph.test.ts +218 -0
  538. package/src/types/graph.ts +533 -0
  539. package/src/types/index.ts +6 -0
  540. package/src/types/llm.ts +140 -0
  541. package/src/types/messages.ts +4 -0
  542. package/src/types/run.ts +128 -0
  543. package/src/types/stream.ts +417 -0
  544. package/src/types/tools.ts +355 -0
  545. package/src/utils/contextAnalytics.ts +103 -0
  546. package/src/utils/events.ts +32 -0
  547. package/src/utils/graph.ts +11 -0
  548. package/src/utils/handlers.ts +107 -0
  549. package/src/utils/index.ts +9 -0
  550. package/src/utils/llm.ts +26 -0
  551. package/src/utils/llmConfig.ts +208 -0
  552. package/src/utils/logging.ts +48 -0
  553. package/src/utils/misc.ts +57 -0
  554. package/src/utils/run.ts +106 -0
  555. package/src/utils/schema.ts +35 -0
  556. package/src/utils/title.ts +177 -0
  557. package/src/utils/tokens.ts +142 -0
  558. package/src/utils/toonFormat.ts +475 -0
@@ -0,0 +1,888 @@
1
+ // src/specs/agent-handoffs.test.ts
2
+ import { DynamicStructuredTool } from '@langchain/core/tools';
3
+ import { HumanMessage, ToolMessage } from '@langchain/core/messages';
4
+ import type { ToolCall } from '@langchain/core/messages/tool';
5
+ import type { RunnableConfig } from '@langchain/core/runnables';
6
+ import type * as t from '@/types';
7
+ import { Providers, Constants } from '@/common';
8
+ import { StandardGraph } from '@/graphs/Graph';
9
+ import { Run } from '@/run';
10
+
11
+ /**
12
+ * Helper to safely get tool name from tool object
13
+ */
14
+ const getToolName = (tool: t.GraphTools[0]): string | undefined => {
15
+ return (tool as { name?: string }).name;
16
+ };
17
+
18
+ /**
19
+ * Helper to safely get tool description from tool object
20
+ */
21
+ const getToolDescription = (tool: t.GraphTools[0]): string | undefined => {
22
+ return (tool as { description?: string }).description;
23
+ };
24
+
25
+ /**
26
+ * Helper to safely get tool schema from tool object
27
+ */
28
+ const getToolSchema = (tool: t.GraphTools[0]): unknown => {
29
+ return (tool as { schema?: unknown }).schema;
30
+ };
31
+
32
+ /**
33
+ * Helper to find tool by name
34
+ */
35
+ const findToolByName = (
36
+ tools: t.GraphTools | undefined,
37
+ name: string
38
+ ): t.GraphTools[0] | undefined => {
39
+ return tools?.find((tool) => getToolName(tool) === name);
40
+ };
41
+
42
+ /**
43
+ * Test suite for Agent Handoffs feature
44
+ *
45
+ * Tests cover:
46
+ * - Basic handoff between two agents
47
+ * - Handoffs with custom descriptions
48
+ * - Handoffs with prompts and prompt keys
49
+ * - Sequential handoffs (A -> B -> C)
50
+ * - Bidirectional handoffs (A <-> B)
51
+ * - Multiple handoff options from single agent
52
+ * - Handoff tool creation and execution
53
+ * - Error cases and edge conditions
54
+ */
55
+ describe('Agent Handoffs Tests', () => {
56
+ jest.setTimeout(30000);
57
+
58
+ const createTestConfig = (
59
+ agents: t.AgentInputs[],
60
+ edges: t.GraphEdge[]
61
+ ): t.RunConfig => ({
62
+ runId: `handoff-test-${Date.now()}-${Math.random()}`,
63
+ graphConfig: {
64
+ type: 'multi-agent',
65
+ agents,
66
+ edges,
67
+ },
68
+ returnContent: true,
69
+ });
70
+
71
+ const createBasicAgent = (
72
+ agentId: string,
73
+ instructions: string
74
+ ): t.AgentInputs => ({
75
+ agentId,
76
+ provider: Providers.ANTHROPIC,
77
+ clientOptions: {
78
+ modelName: 'claude-haiku-4-5',
79
+ apiKey: 'test-key',
80
+ },
81
+ instructions,
82
+ maxContextTokens: 28000,
83
+ });
84
+
85
+ describe('Basic Handoff Tests', () => {
86
+ it('should create handoff tool for agent with outgoing handoff edge', async () => {
87
+ const agents: t.AgentInputs[] = [
88
+ createBasicAgent('agent_a', 'You are agent A'),
89
+ createBasicAgent('agent_b', 'You are agent B'),
90
+ ];
91
+
92
+ const edges: t.GraphEdge[] = [
93
+ {
94
+ from: 'agent_a',
95
+ to: 'agent_b',
96
+ edgeType: 'handoff',
97
+ description: 'Transfer to agent B',
98
+ },
99
+ ];
100
+
101
+ const run = await Run.create(createTestConfig(agents, edges));
102
+
103
+ expect(run.Graph).toBeDefined();
104
+
105
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
106
+ 'agent_a'
107
+ );
108
+ expect(agentAContext).toBeDefined();
109
+ expect(agentAContext?.tools).toBeDefined();
110
+
111
+ // Check that handoff tool was created
112
+ const handoffTool = findToolByName(
113
+ agentAContext?.tools,
114
+ `${Constants.LC_TRANSFER_TO_}agent_b`
115
+ );
116
+ expect(handoffTool).toBeDefined();
117
+ expect(getToolDescription(handoffTool!)).toBe('Transfer to agent B');
118
+ });
119
+
120
+ it('should successfully handoff from agent A to agent B', async () => {
121
+ const agents: t.AgentInputs[] = [
122
+ createBasicAgent('agent_a', 'You are agent A. Transfer to agent B.'),
123
+ createBasicAgent('agent_b', 'You are agent B. Respond to the user.'),
124
+ ];
125
+
126
+ const edges: t.GraphEdge[] = [
127
+ {
128
+ from: 'agent_a',
129
+ to: 'agent_b',
130
+ edgeType: 'handoff',
131
+ description: 'Transfer to agent B when needed',
132
+ },
133
+ ];
134
+
135
+ const run = await Run.create(createTestConfig(agents, edges));
136
+
137
+ // Override models to simulate handoff behavior
138
+ run.Graph?.overrideTestModel(
139
+ [
140
+ 'Transferring to agent B', // Agent A response
141
+ 'Hello from agent B', // Agent B response
142
+ ],
143
+ 10,
144
+ [
145
+ {
146
+ id: 'tool_call_1',
147
+ name: `${Constants.LC_TRANSFER_TO_}agent_b`,
148
+ args: {},
149
+ } as ToolCall,
150
+ ]
151
+ );
152
+
153
+ const messages = [new HumanMessage('Hello')];
154
+
155
+ const config: Partial<RunnableConfig> & {
156
+ version: 'v1' | 'v2';
157
+ streamMode: string;
158
+ } = {
159
+ configurable: {
160
+ thread_id: 'test-handoff-thread',
161
+ },
162
+ streamMode: 'values',
163
+ version: 'v2' as const,
164
+ };
165
+
166
+ await run.processStream({ messages }, config);
167
+
168
+ const finalMessages = run.getRunMessages();
169
+ expect(finalMessages).toBeDefined();
170
+ expect(finalMessages!.length).toBeGreaterThan(1);
171
+
172
+ // Check for tool message indicating handoff
173
+ const toolMessages = finalMessages!.filter(
174
+ (msg) => msg.getType() === 'tool'
175
+ ) as ToolMessage[];
176
+
177
+ const handoffToolMessage = toolMessages.find(
178
+ (msg) => msg.name === `${Constants.LC_TRANSFER_TO_}agent_b`
179
+ );
180
+ expect(handoffToolMessage).toBeDefined();
181
+ expect(handoffToolMessage?.content).toContain('transferred to agent_b');
182
+ });
183
+
184
+ it('should not create handoff tool for agent without outgoing edges', async () => {
185
+ const agents: t.AgentInputs[] = [
186
+ createBasicAgent('agent_a', 'You are agent A'),
187
+ createBasicAgent('agent_b', 'You are agent B'),
188
+ ];
189
+
190
+ const edges: t.GraphEdge[] = [
191
+ {
192
+ from: 'agent_a',
193
+ to: 'agent_b',
194
+ edgeType: 'handoff',
195
+ },
196
+ ];
197
+
198
+ const run = await Run.create(createTestConfig(agents, edges));
199
+
200
+ const agentBContext = (run.Graph as StandardGraph).agentContexts.get(
201
+ 'agent_b'
202
+ );
203
+ expect(agentBContext).toBeDefined();
204
+
205
+ // Agent B should not have handoff tools (no outgoing edges)
206
+ const handoffTools = agentBContext?.tools?.filter((tool) => {
207
+ const name = getToolName(tool);
208
+ return name?.startsWith(Constants.LC_TRANSFER_TO_) ?? false;
209
+ });
210
+ expect(handoffTools?.length ?? 0).toBe(0);
211
+ });
212
+ });
213
+
214
+ describe('Bidirectional Handoffs', () => {
215
+ it('should create handoff tools for both agents in bidirectional setup', async () => {
216
+ const agents: t.AgentInputs[] = [
217
+ createBasicAgent('agent_a', 'You are agent A'),
218
+ createBasicAgent('agent_b', 'You are agent B'),
219
+ ];
220
+
221
+ const edges: t.GraphEdge[] = [
222
+ {
223
+ from: 'agent_a',
224
+ to: 'agent_b',
225
+ edgeType: 'handoff',
226
+ description: 'Transfer to agent B',
227
+ },
228
+ {
229
+ from: 'agent_b',
230
+ to: 'agent_a',
231
+ edgeType: 'handoff',
232
+ description: 'Transfer to agent A',
233
+ },
234
+ ];
235
+
236
+ const run = await Run.create(createTestConfig(agents, edges));
237
+
238
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
239
+ 'agent_a'
240
+ );
241
+ const agentBContext = (run.Graph as StandardGraph).agentContexts.get(
242
+ 'agent_b'
243
+ );
244
+
245
+ // Agent A should have tool to transfer to B
246
+ const agentAHandoffTool = findToolByName(
247
+ agentAContext?.tools,
248
+ `${Constants.LC_TRANSFER_TO_}agent_b`
249
+ );
250
+ expect(agentAHandoffTool).toBeDefined();
251
+
252
+ // Agent B should have tool to transfer to A
253
+ const agentBHandoffTool = findToolByName(
254
+ agentBContext?.tools,
255
+ `${Constants.LC_TRANSFER_TO_}agent_a`
256
+ );
257
+ expect(agentBHandoffTool).toBeDefined();
258
+ });
259
+
260
+ it('should handle handoff from A to B in bidirectional setup', async () => {
261
+ const agents: t.AgentInputs[] = [
262
+ createBasicAgent('agent_a', 'You are agent A'),
263
+ createBasicAgent('agent_b', 'You are agent B'),
264
+ ];
265
+
266
+ const edges: t.GraphEdge[] = [
267
+ {
268
+ from: 'agent_a',
269
+ to: 'agent_b',
270
+ edgeType: 'handoff',
271
+ },
272
+ {
273
+ from: 'agent_b',
274
+ to: 'agent_a',
275
+ edgeType: 'handoff',
276
+ },
277
+ ];
278
+
279
+ const run = await Run.create(createTestConfig(agents, edges));
280
+
281
+ // Simulate single handoff from A to B
282
+ run.Graph?.overrideTestModel(
283
+ ['Transferring to B', 'Response from B'],
284
+ 10,
285
+ [
286
+ {
287
+ id: 'tool_call_1',
288
+ name: `${Constants.LC_TRANSFER_TO_}agent_b`,
289
+ args: {},
290
+ } as ToolCall,
291
+ ]
292
+ );
293
+
294
+ const messages = [new HumanMessage('Start conversation')];
295
+
296
+ const config: Partial<RunnableConfig> & {
297
+ version: 'v1' | 'v2';
298
+ streamMode: string;
299
+ } = {
300
+ configurable: {
301
+ thread_id: 'test-bidirectional-thread',
302
+ },
303
+ streamMode: 'values',
304
+ version: 'v2' as const,
305
+ };
306
+
307
+ await run.processStream({ messages }, config);
308
+
309
+ const finalMessages = run.getRunMessages();
310
+ expect(finalMessages).toBeDefined();
311
+
312
+ // Should have a handoff tool message
313
+ const toolMessages = finalMessages!.filter(
314
+ (msg) => msg.getType() === 'tool'
315
+ ) as ToolMessage[];
316
+
317
+ const handoffMessage = toolMessages.find(
318
+ (msg) => msg.name === `${Constants.LC_TRANSFER_TO_}agent_b`
319
+ );
320
+ expect(handoffMessage).toBeDefined();
321
+ });
322
+ });
323
+
324
+ describe('Sequential Handoffs (Chain)', () => {
325
+ it('should create handoff tools for chain of agents A -> B -> C', async () => {
326
+ const agents: t.AgentInputs[] = [
327
+ createBasicAgent('agent_a', 'You are agent A'),
328
+ createBasicAgent('agent_b', 'You are agent B'),
329
+ createBasicAgent('agent_c', 'You are agent C'),
330
+ ];
331
+
332
+ const edges: t.GraphEdge[] = [
333
+ {
334
+ from: 'agent_a',
335
+ to: 'agent_b',
336
+ edgeType: 'handoff',
337
+ description: 'Transfer to agent B',
338
+ },
339
+ {
340
+ from: 'agent_b',
341
+ to: 'agent_c',
342
+ edgeType: 'handoff',
343
+ description: 'Transfer to agent C',
344
+ },
345
+ ];
346
+
347
+ const run = await Run.create(createTestConfig(agents, edges));
348
+
349
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
350
+ 'agent_a'
351
+ );
352
+ const agentBContext = (run.Graph as StandardGraph).agentContexts.get(
353
+ 'agent_b'
354
+ );
355
+ const agentCContext = (run.Graph as StandardGraph).agentContexts.get(
356
+ 'agent_c'
357
+ );
358
+
359
+ // Agent A should have tool to transfer to B
360
+ expect(
361
+ findToolByName(
362
+ agentAContext?.tools,
363
+ `${Constants.LC_TRANSFER_TO_}agent_b`
364
+ )
365
+ ).toBeDefined();
366
+
367
+ // Agent B should have tool to transfer to C
368
+ expect(
369
+ findToolByName(
370
+ agentBContext?.tools,
371
+ `${Constants.LC_TRANSFER_TO_}agent_c`
372
+ )
373
+ ).toBeDefined();
374
+
375
+ // Agent C should have no handoff tools
376
+ const agentCHandoffTools = agentCContext?.tools?.filter((tool) => {
377
+ const name = getToolName(tool);
378
+ return name?.startsWith(Constants.LC_TRANSFER_TO_) ?? false;
379
+ });
380
+ expect(agentCHandoffTools?.length ?? 0).toBe(0);
381
+ });
382
+ });
383
+
384
+ describe('Multiple Handoff Options', () => {
385
+ it('should create multiple handoff tools when agent has multiple outgoing edges', async () => {
386
+ const agents: t.AgentInputs[] = [
387
+ createBasicAgent('router', 'You are a router agent'),
388
+ createBasicAgent('agent_a', 'You are agent A'),
389
+ createBasicAgent('agent_b', 'You are agent B'),
390
+ createBasicAgent('agent_c', 'You are agent C'),
391
+ ];
392
+
393
+ const edges: t.GraphEdge[] = [
394
+ {
395
+ from: 'router',
396
+ to: 'agent_a',
397
+ edgeType: 'handoff',
398
+ description: 'Transfer to agent A for task A',
399
+ },
400
+ {
401
+ from: 'router',
402
+ to: 'agent_b',
403
+ edgeType: 'handoff',
404
+ description: 'Transfer to agent B for task B',
405
+ },
406
+ {
407
+ from: 'router',
408
+ to: 'agent_c',
409
+ edgeType: 'handoff',
410
+ description: 'Transfer to agent C for task C',
411
+ },
412
+ ];
413
+
414
+ const run = await Run.create(createTestConfig(agents, edges));
415
+
416
+ const routerContext = (run.Graph as StandardGraph).agentContexts.get(
417
+ 'router'
418
+ );
419
+ expect(routerContext).toBeDefined();
420
+
421
+ // Router should have 3 handoff tools
422
+ const handoffTools = routerContext?.tools?.filter((tool) => {
423
+ const name = getToolName(tool);
424
+ return name?.startsWith(Constants.LC_TRANSFER_TO_) ?? false;
425
+ });
426
+ expect(handoffTools?.length).toBe(3);
427
+
428
+ // Verify each tool exists
429
+ expect(
430
+ findToolByName(handoffTools, `${Constants.LC_TRANSFER_TO_}agent_a`)
431
+ ).toBeDefined();
432
+ expect(
433
+ findToolByName(handoffTools, `${Constants.LC_TRANSFER_TO_}agent_b`)
434
+ ).toBeDefined();
435
+ expect(
436
+ findToolByName(handoffTools, `${Constants.LC_TRANSFER_TO_}agent_c`)
437
+ ).toBeDefined();
438
+ });
439
+
440
+ it('should route to correct agent based on handoff tool used', async () => {
441
+ const agents: t.AgentInputs[] = [
442
+ createBasicAgent('router', 'You are a router'),
443
+ createBasicAgent('agent_a', 'You are agent A'),
444
+ createBasicAgent('agent_b', 'You are agent B'),
445
+ ];
446
+
447
+ const edges: t.GraphEdge[] = [
448
+ {
449
+ from: 'router',
450
+ to: 'agent_a',
451
+ edgeType: 'handoff',
452
+ description: 'Transfer to agent A',
453
+ },
454
+ {
455
+ from: 'router',
456
+ to: 'agent_b',
457
+ edgeType: 'handoff',
458
+ description: 'Transfer to agent B',
459
+ },
460
+ ];
461
+
462
+ const run = await Run.create(createTestConfig(agents, edges));
463
+
464
+ // Router chooses agent_b
465
+ run.Graph?.overrideTestModel(
466
+ ['Routing to agent B', 'Hello from agent B'],
467
+ 10,
468
+ [
469
+ {
470
+ id: 'tool_call_1',
471
+ name: `${Constants.LC_TRANSFER_TO_}agent_b`,
472
+ args: {},
473
+ } as ToolCall,
474
+ ]
475
+ );
476
+
477
+ const messages = [new HumanMessage('Route this message')];
478
+
479
+ const config: Partial<RunnableConfig> & {
480
+ version: 'v1' | 'v2';
481
+ streamMode: string;
482
+ } = {
483
+ configurable: {
484
+ thread_id: 'test-routing-thread',
485
+ },
486
+ streamMode: 'values',
487
+ version: 'v2' as const,
488
+ };
489
+
490
+ await run.processStream({ messages }, config);
491
+
492
+ const finalMessages = run.getRunMessages();
493
+ const toolMessages = finalMessages!.filter(
494
+ (msg) => msg.getType() === 'tool'
495
+ ) as ToolMessage[];
496
+
497
+ // Should have handoff to agent_b, not agent_a
498
+ const handoffToB = toolMessages.find(
499
+ (msg) => msg.name === `${Constants.LC_TRANSFER_TO_}agent_b`
500
+ );
501
+ expect(handoffToB).toBeDefined();
502
+
503
+ const handoffToA = toolMessages.find(
504
+ (msg) => msg.name === `${Constants.LC_TRANSFER_TO_}agent_a`
505
+ );
506
+ expect(handoffToA).toBeUndefined();
507
+ });
508
+ });
509
+
510
+ describe('Handoffs with Prompts', () => {
511
+ it('should create handoff tool with prompt parameter when prompt is specified', async () => {
512
+ const agents: t.AgentInputs[] = [
513
+ createBasicAgent('agent_a', 'You are agent A'),
514
+ createBasicAgent('agent_b', 'You are agent B'),
515
+ ];
516
+
517
+ const edges: t.GraphEdge[] = [
518
+ {
519
+ from: 'agent_a',
520
+ to: 'agent_b',
521
+ edgeType: 'handoff',
522
+ description: 'Transfer to agent B with instructions',
523
+ prompt: 'Provide specific instructions for agent B',
524
+ promptKey: 'instructions',
525
+ },
526
+ ];
527
+
528
+ const run = await Run.create(createTestConfig(agents, edges));
529
+
530
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
531
+ 'agent_a'
532
+ );
533
+ const handoffTool = findToolByName(
534
+ agentAContext?.tools,
535
+ `${Constants.LC_TRANSFER_TO_}agent_b`
536
+ );
537
+
538
+ expect(handoffTool).toBeDefined();
539
+ // Tool should accept parameters (schema should be defined)
540
+ expect(getToolSchema(handoffTool!)).toBeDefined();
541
+ });
542
+
543
+ it('should use default promptKey when not specified', async () => {
544
+ const agents: t.AgentInputs[] = [
545
+ createBasicAgent('agent_a', 'You are agent A'),
546
+ createBasicAgent('agent_b', 'You are agent B'),
547
+ ];
548
+
549
+ const edges: t.GraphEdge[] = [
550
+ {
551
+ from: 'agent_a',
552
+ to: 'agent_b',
553
+ edgeType: 'handoff',
554
+ prompt: 'Instructions for handoff',
555
+ // promptKey not specified, should default to 'instructions'
556
+ },
557
+ ];
558
+
559
+ const run = await Run.create(createTestConfig(agents, edges));
560
+
561
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
562
+ 'agent_a'
563
+ );
564
+ const handoffTool = findToolByName(
565
+ agentAContext?.tools,
566
+ `${Constants.LC_TRANSFER_TO_}agent_b`
567
+ );
568
+
569
+ expect(handoffTool).toBeDefined();
570
+ expect(getToolSchema(handoffTool!)).toBeDefined();
571
+ });
572
+
573
+ it('should include prompt content in handoff tool message', async () => {
574
+ const agents: t.AgentInputs[] = [
575
+ createBasicAgent('agent_a', 'You are agent A'),
576
+ createBasicAgent('agent_b', 'You are agent B'),
577
+ ];
578
+
579
+ const edges: t.GraphEdge[] = [
580
+ {
581
+ from: 'agent_a',
582
+ to: 'agent_b',
583
+ edgeType: 'handoff',
584
+ description: 'Transfer to agent B',
585
+ prompt: 'Additional context for agent B',
586
+ promptKey: 'context',
587
+ },
588
+ ];
589
+
590
+ const run = await Run.create(createTestConfig(agents, edges));
591
+
592
+ run.Graph?.overrideTestModel(['Transferring with context'], 10, [
593
+ {
594
+ id: 'tool_call_1',
595
+ name: `${Constants.LC_TRANSFER_TO_}agent_b`,
596
+ args: { context: 'User needs help with booking' },
597
+ } as ToolCall,
598
+ ]);
599
+
600
+ const messages = [new HumanMessage('Help me')];
601
+
602
+ const config: Partial<RunnableConfig> & {
603
+ version: 'v1' | 'v2';
604
+ streamMode: string;
605
+ } = {
606
+ configurable: {
607
+ thread_id: 'test-prompt-thread',
608
+ },
609
+ streamMode: 'values',
610
+ version: 'v2' as const,
611
+ };
612
+
613
+ await run.processStream({ messages }, config);
614
+
615
+ const finalMessages = run.getRunMessages();
616
+ const toolMessages = finalMessages!.filter(
617
+ (msg) => msg.getType() === 'tool'
618
+ ) as ToolMessage[];
619
+
620
+ const handoffMessage = toolMessages.find(
621
+ (msg) => msg.name === `${Constants.LC_TRANSFER_TO_}agent_b`
622
+ );
623
+
624
+ expect(handoffMessage).toBeDefined();
625
+ // Tool message should contain the prompt key and value
626
+ expect(handoffMessage?.content).toContain('Context:');
627
+ });
628
+ });
629
+
630
+ describe('Edge Cases and Error Handling', () => {
631
+ it('should handle self-referential edge gracefully', async () => {
632
+ const agents: t.AgentInputs[] = [
633
+ createBasicAgent('agent_a', 'You are agent A'),
634
+ ];
635
+
636
+ const edges: t.GraphEdge[] = [
637
+ {
638
+ from: 'agent_a',
639
+ to: 'agent_a',
640
+ edgeType: 'handoff',
641
+ description: 'Self-handoff (should be allowed but unusual)',
642
+ },
643
+ ];
644
+
645
+ // Should not throw during creation
646
+ expect(async () => {
647
+ await Run.create(createTestConfig(agents, edges));
648
+ }).not.toThrow();
649
+ });
650
+
651
+ it('should handle empty edges array', async () => {
652
+ const agents: t.AgentInputs[] = [
653
+ createBasicAgent('agent_a', 'You are agent A'),
654
+ createBasicAgent('agent_b', 'You are agent B'),
655
+ ];
656
+
657
+ const edges: t.GraphEdge[] = [];
658
+
659
+ const run = await Run.create(createTestConfig(agents, edges));
660
+
661
+ expect(run.Graph).toBeDefined();
662
+
663
+ // Agents should have no handoff tools
664
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
665
+ 'agent_a'
666
+ );
667
+ const handoffTools = agentAContext?.tools?.filter((tool) => {
668
+ const name = getToolName(tool);
669
+ return name?.startsWith(Constants.LC_TRANSFER_TO_) ?? false;
670
+ });
671
+ expect(handoffTools?.length ?? 0).toBe(0);
672
+ });
673
+
674
+ it('should start from first agent when no edges are defined', async () => {
675
+ const agents: t.AgentInputs[] = [
676
+ createBasicAgent('agent_a', 'You are agent A'),
677
+ createBasicAgent('agent_b', 'You are agent B'),
678
+ ];
679
+
680
+ const edges: t.GraphEdge[] = [];
681
+
682
+ const run = await Run.create(createTestConfig(agents, edges));
683
+
684
+ run.Graph?.overrideTestModel(['Response from first agent'], 10);
685
+
686
+ const messages = [new HumanMessage('Hello')];
687
+
688
+ const config: Partial<RunnableConfig> & {
689
+ version: 'v1' | 'v2';
690
+ streamMode: string;
691
+ } = {
692
+ configurable: {
693
+ thread_id: 'test-no-edges-thread',
694
+ },
695
+ streamMode: 'values',
696
+ version: 'v2' as const,
697
+ };
698
+
699
+ await run.processStream({ messages }, config);
700
+
701
+ const finalMessages = run.getRunMessages();
702
+ expect(finalMessages).toBeDefined();
703
+ expect(finalMessages!.length).toBeGreaterThan(0);
704
+ });
705
+
706
+ it('should handle agents with existing tools alongside handoff tools', async () => {
707
+ const customTool = new DynamicStructuredTool({
708
+ name: 'custom_tool',
709
+ description: 'A custom tool',
710
+ schema: { type: 'object', properties: {}, required: [] },
711
+ func: async (): Promise<string> => 'Tool result',
712
+ });
713
+
714
+ const agents: t.AgentInputs[] = [
715
+ {
716
+ ...createBasicAgent('agent_a', 'You are agent A'),
717
+ tools: [customTool],
718
+ },
719
+ createBasicAgent('agent_b', 'You are agent B'),
720
+ ];
721
+
722
+ const edges: t.GraphEdge[] = [
723
+ {
724
+ from: 'agent_a',
725
+ to: 'agent_b',
726
+ edgeType: 'handoff',
727
+ description: 'Transfer to agent B',
728
+ },
729
+ ];
730
+
731
+ const run = await Run.create(createTestConfig(agents, edges));
732
+
733
+ const agentAContext = (run.Graph as StandardGraph).agentContexts.get(
734
+ 'agent_a'
735
+ );
736
+
737
+ // Agent A should have both custom tool and handoff tool
738
+ expect(agentAContext?.tools?.length).toBeGreaterThanOrEqual(2);
739
+
740
+ expect(findToolByName(agentAContext?.tools, 'custom_tool')).toBeDefined();
741
+
742
+ expect(
743
+ findToolByName(
744
+ agentAContext?.tools,
745
+ `${Constants.LC_TRANSFER_TO_}agent_b`
746
+ )
747
+ ).toBeDefined();
748
+ });
749
+ });
750
+
751
+ describe('Graph Structure Analysis', () => {
752
+ it('should correctly identify starting nodes with no incoming edges', async () => {
753
+ const agents: t.AgentInputs[] = [
754
+ createBasicAgent('agent_a', 'Starting agent'),
755
+ createBasicAgent('agent_b', 'Middle agent'),
756
+ createBasicAgent('agent_c', 'End agent'),
757
+ ];
758
+
759
+ const edges: t.GraphEdge[] = [
760
+ {
761
+ from: 'agent_a',
762
+ to: 'agent_b',
763
+ edgeType: 'handoff',
764
+ },
765
+ {
766
+ from: 'agent_b',
767
+ to: 'agent_c',
768
+ edgeType: 'handoff',
769
+ },
770
+ ];
771
+
772
+ const run = await Run.create(createTestConfig(agents, edges));
773
+
774
+ // agent_a should be the starting node (no incoming edges)
775
+ expect(run.Graph).toBeDefined();
776
+ // This is internal behavior, but we can test via execution
777
+ run.Graph?.overrideTestModel(['Response from agent A'], 10);
778
+
779
+ const messages = [new HumanMessage('Start')];
780
+
781
+ const config: Partial<RunnableConfig> & {
782
+ version: 'v1' | 'v2';
783
+ streamMode: string;
784
+ } = {
785
+ configurable: {
786
+ thread_id: 'test-starting-node-thread',
787
+ },
788
+ streamMode: 'values',
789
+ version: 'v2' as const,
790
+ };
791
+
792
+ // Should start from agent_a
793
+ await run.processStream({ messages }, config);
794
+
795
+ const finalMessages = run.getRunMessages();
796
+ expect(finalMessages).toBeDefined();
797
+ });
798
+
799
+ it('should handle multiple starting nodes (parallel entry points)', async () => {
800
+ const agents: t.AgentInputs[] = [
801
+ createBasicAgent('agent_a', 'Starting agent A'),
802
+ createBasicAgent('agent_b', 'Starting agent B'),
803
+ createBasicAgent('agent_c', 'Shared destination'),
804
+ ];
805
+
806
+ const edges: t.GraphEdge[] = [
807
+ {
808
+ from: 'agent_a',
809
+ to: 'agent_c',
810
+ edgeType: 'handoff',
811
+ },
812
+ {
813
+ from: 'agent_b',
814
+ to: 'agent_c',
815
+ edgeType: 'handoff',
816
+ },
817
+ ];
818
+
819
+ // Both agent_a and agent_b have no incoming edges, so both are starting nodes
820
+ const run = await Run.create(createTestConfig(agents, edges));
821
+
822
+ expect(run.Graph).toBeDefined();
823
+ });
824
+ });
825
+
826
+ describe('Handoff Tool Naming', () => {
827
+ it('should use correct naming convention for handoff tools', async () => {
828
+ const agents: t.AgentInputs[] = [
829
+ createBasicAgent('flight_assistant', 'You handle flights'),
830
+ createBasicAgent('hotel_assistant', 'You handle hotels'),
831
+ ];
832
+
833
+ const edges: t.GraphEdge[] = [
834
+ {
835
+ from: 'flight_assistant',
836
+ to: 'hotel_assistant',
837
+ edgeType: 'handoff',
838
+ description: 'Transfer to hotel booking',
839
+ },
840
+ ];
841
+
842
+ const run = await Run.create(createTestConfig(agents, edges));
843
+
844
+ const flightContext = (run.Graph as StandardGraph).agentContexts.get(
845
+ 'flight_assistant'
846
+ );
847
+ const handoffTool = findToolByName(
848
+ flightContext?.tools,
849
+ `${Constants.LC_TRANSFER_TO_}hotel_assistant`
850
+ );
851
+
852
+ expect(handoffTool).toBeDefined();
853
+ expect(getToolName(handoffTool!)).toBe(
854
+ `${Constants.LC_TRANSFER_TO_}hotel_assistant`
855
+ );
856
+ });
857
+
858
+ it('should preserve agent ID format in tool names', async () => {
859
+ const agents: t.AgentInputs[] = [
860
+ createBasicAgent('agent_with_underscores', 'Agent with underscores'),
861
+ createBasicAgent('AgentWithCamelCase', 'Agent with camel case'),
862
+ ];
863
+
864
+ const edges: t.GraphEdge[] = [
865
+ {
866
+ from: 'agent_with_underscores',
867
+ to: 'AgentWithCamelCase',
868
+ edgeType: 'handoff',
869
+ },
870
+ ];
871
+
872
+ const run = await Run.create(createTestConfig(agents, edges));
873
+
874
+ const agentContext = (run.Graph as StandardGraph).agentContexts.get(
875
+ 'agent_with_underscores'
876
+ );
877
+ const handoffTool = findToolByName(
878
+ agentContext?.tools,
879
+ `${Constants.LC_TRANSFER_TO_}AgentWithCamelCase`
880
+ );
881
+
882
+ expect(handoffTool).toBeDefined();
883
+ expect(getToolName(handoffTool!)).toBe(
884
+ `${Constants.LC_TRANSFER_TO_}AgentWithCamelCase`
885
+ );
886
+ });
887
+ });
888
+ });