langchain 1.5.3 → 1.5.5

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 (363) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/agents/ReactAgent.cjs +6 -6
  3. package/dist/agents/ReactAgent.cjs.map +1 -1
  4. package/dist/agents/ReactAgent.d.cts +1 -1
  5. package/dist/agents/ReactAgent.d.cts.map +1 -1
  6. package/dist/agents/ReactAgent.d.ts +1 -1
  7. package/dist/agents/ReactAgent.d.ts.map +1 -1
  8. package/dist/agents/ReactAgent.js +6 -5
  9. package/dist/agents/ReactAgent.js.map +1 -1
  10. package/dist/agents/RunnableCallable.cjs +0 -1
  11. package/dist/agents/RunnableCallable.cjs.map +1 -1
  12. package/dist/agents/RunnableCallable.js.map +1 -1
  13. package/dist/agents/annotation.cjs +0 -1
  14. package/dist/agents/annotation.cjs.map +1 -1
  15. package/dist/agents/annotation.js.map +1 -1
  16. package/dist/agents/constants.d.cts +1 -1
  17. package/dist/agents/constants.d.cts.map +1 -1
  18. package/dist/agents/constants.d.ts +1 -1
  19. package/dist/agents/constants.d.ts.map +1 -1
  20. package/dist/agents/errors.cjs +0 -1
  21. package/dist/agents/errors.cjs.map +1 -1
  22. package/dist/agents/errors.d.cts +0 -1
  23. package/dist/agents/errors.d.cts.map +1 -1
  24. package/dist/agents/errors.d.ts +0 -1
  25. package/dist/agents/errors.d.ts.map +1 -1
  26. package/dist/agents/errors.js.map +1 -1
  27. package/dist/agents/index.cjs +21 -7
  28. package/dist/agents/index.cjs.map +1 -1
  29. package/dist/agents/index.d.cts +2 -2
  30. package/dist/agents/index.d.cts.map +1 -1
  31. package/dist/agents/index.d.ts +2 -2
  32. package/dist/agents/index.d.ts.map +1 -1
  33. package/dist/agents/index.js +8 -8
  34. package/dist/agents/index.js.map +1 -1
  35. package/dist/agents/middleware/constants.cjs +0 -1
  36. package/dist/agents/middleware/constants.cjs.map +1 -1
  37. package/dist/agents/middleware/constants.js.map +1 -1
  38. package/dist/agents/middleware/contextEditing.cjs +0 -1
  39. package/dist/agents/middleware/contextEditing.cjs.map +1 -1
  40. package/dist/agents/middleware/contextEditing.d.cts +1 -3
  41. package/dist/agents/middleware/contextEditing.d.cts.map +1 -1
  42. package/dist/agents/middleware/contextEditing.d.ts +1 -3
  43. package/dist/agents/middleware/contextEditing.d.ts.map +1 -1
  44. package/dist/agents/middleware/contextEditing.js.map +1 -1
  45. package/dist/agents/middleware/dynamicSystemPrompt.cjs +0 -1
  46. package/dist/agents/middleware/dynamicSystemPrompt.cjs.map +1 -1
  47. package/dist/agents/middleware/dynamicSystemPrompt.d.cts +1 -3
  48. package/dist/agents/middleware/dynamicSystemPrompt.d.cts.map +1 -1
  49. package/dist/agents/middleware/dynamicSystemPrompt.d.ts +1 -3
  50. package/dist/agents/middleware/dynamicSystemPrompt.d.ts.map +1 -1
  51. package/dist/agents/middleware/dynamicSystemPrompt.js.map +1 -1
  52. package/dist/agents/middleware/error.cjs +0 -1
  53. package/dist/agents/middleware/error.cjs.map +1 -1
  54. package/dist/agents/middleware/error.js.map +1 -1
  55. package/dist/agents/middleware/hitl.cjs +0 -1
  56. package/dist/agents/middleware/hitl.cjs.map +1 -1
  57. package/dist/agents/middleware/hitl.d.cts +1 -3
  58. package/dist/agents/middleware/hitl.d.cts.map +1 -1
  59. package/dist/agents/middleware/hitl.d.ts +1 -3
  60. package/dist/agents/middleware/hitl.d.ts.map +1 -1
  61. package/dist/agents/middleware/hitl.js.map +1 -1
  62. package/dist/agents/middleware/index.cjs +51 -19
  63. package/dist/agents/middleware/index.d.cts +3 -1
  64. package/dist/agents/middleware/index.d.ts +3 -1
  65. package/dist/agents/middleware/index.js +21 -20
  66. package/dist/agents/middleware/llmToolSelector.cjs +1 -1
  67. package/dist/agents/middleware/llmToolSelector.cjs.map +1 -1
  68. package/dist/agents/middleware/llmToolSelector.d.cts +9 -12
  69. package/dist/agents/middleware/llmToolSelector.d.cts.map +1 -1
  70. package/dist/agents/middleware/llmToolSelector.d.ts +9 -12
  71. package/dist/agents/middleware/llmToolSelector.d.ts.map +1 -1
  72. package/dist/agents/middleware/llmToolSelector.js +1 -1
  73. package/dist/agents/middleware/llmToolSelector.js.map +1 -1
  74. package/dist/agents/middleware/modelCallLimit.cjs +0 -1
  75. package/dist/agents/middleware/modelCallLimit.cjs.map +1 -1
  76. package/dist/agents/middleware/modelCallLimit.d.cts +1 -3
  77. package/dist/agents/middleware/modelCallLimit.d.cts.map +1 -1
  78. package/dist/agents/middleware/modelCallLimit.d.ts +1 -3
  79. package/dist/agents/middleware/modelCallLimit.d.ts.map +1 -1
  80. package/dist/agents/middleware/modelCallLimit.js.map +1 -1
  81. package/dist/agents/middleware/modelFallback.cjs.map +1 -1
  82. package/dist/agents/middleware/modelFallback.d.cts +1 -3
  83. package/dist/agents/middleware/modelFallback.d.cts.map +1 -1
  84. package/dist/agents/middleware/modelFallback.d.ts +1 -3
  85. package/dist/agents/middleware/modelFallback.d.ts.map +1 -1
  86. package/dist/agents/middleware/modelFallback.js.map +1 -1
  87. package/dist/agents/middleware/modelRetry.cjs +1 -1
  88. package/dist/agents/middleware/modelRetry.cjs.map +1 -1
  89. package/dist/agents/middleware/modelRetry.d.cts +2 -4
  90. package/dist/agents/middleware/modelRetry.d.cts.map +1 -1
  91. package/dist/agents/middleware/modelRetry.d.ts +2 -4
  92. package/dist/agents/middleware/modelRetry.d.ts.map +1 -1
  93. package/dist/agents/middleware/modelRetry.js +1 -1
  94. package/dist/agents/middleware/modelRetry.js.map +1 -1
  95. package/dist/agents/middleware/pii.cjs +2 -1
  96. package/dist/agents/middleware/pii.cjs.map +1 -1
  97. package/dist/agents/middleware/pii.d.cts +2 -4
  98. package/dist/agents/middleware/pii.d.cts.map +1 -1
  99. package/dist/agents/middleware/pii.d.ts +2 -4
  100. package/dist/agents/middleware/pii.d.ts.map +1 -1
  101. package/dist/agents/middleware/pii.js +2 -0
  102. package/dist/agents/middleware/pii.js.map +1 -1
  103. package/dist/agents/middleware/piiRedaction.cjs +0 -1
  104. package/dist/agents/middleware/piiRedaction.cjs.map +1 -1
  105. package/dist/agents/middleware/piiRedaction.d.cts +1 -3
  106. package/dist/agents/middleware/piiRedaction.d.cts.map +1 -1
  107. package/dist/agents/middleware/piiRedaction.d.ts +1 -3
  108. package/dist/agents/middleware/piiRedaction.d.ts.map +1 -1
  109. package/dist/agents/middleware/piiRedaction.js.map +1 -1
  110. package/dist/agents/middleware/provider/anthropic/promptCaching.cjs +0 -1
  111. package/dist/agents/middleware/provider/anthropic/promptCaching.cjs.map +1 -1
  112. package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts +1 -3
  113. package/dist/agents/middleware/provider/anthropic/promptCaching.d.cts.map +1 -1
  114. package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts +1 -3
  115. package/dist/agents/middleware/provider/anthropic/promptCaching.d.ts.map +1 -1
  116. package/dist/agents/middleware/provider/anthropic/promptCaching.js.map +1 -1
  117. package/dist/agents/middleware/provider/aws/promptCaching.cjs +0 -1
  118. package/dist/agents/middleware/provider/aws/promptCaching.cjs.map +1 -1
  119. package/dist/agents/middleware/provider/aws/promptCaching.d.cts +1 -3
  120. package/dist/agents/middleware/provider/aws/promptCaching.d.cts.map +1 -1
  121. package/dist/agents/middleware/provider/aws/promptCaching.d.ts +1 -3
  122. package/dist/agents/middleware/provider/aws/promptCaching.d.ts.map +1 -1
  123. package/dist/agents/middleware/provider/aws/promptCaching.js.map +1 -1
  124. package/dist/agents/middleware/provider/openai/moderation.cjs +1 -1
  125. package/dist/agents/middleware/provider/openai/moderation.cjs.map +1 -1
  126. package/dist/agents/middleware/provider/openai/moderation.d.cts +0 -4
  127. package/dist/agents/middleware/provider/openai/moderation.d.cts.map +1 -1
  128. package/dist/agents/middleware/provider/openai/moderation.d.ts +0 -4
  129. package/dist/agents/middleware/provider/openai/moderation.d.ts.map +1 -1
  130. package/dist/agents/middleware/provider/openai/moderation.js +1 -1
  131. package/dist/agents/middleware/provider/openai/moderation.js.map +1 -1
  132. package/dist/agents/middleware/providerToolSearch.cjs +0 -1
  133. package/dist/agents/middleware/providerToolSearch.cjs.map +1 -1
  134. package/dist/agents/middleware/providerToolSearch.d.cts +1 -2
  135. package/dist/agents/middleware/providerToolSearch.d.cts.map +1 -1
  136. package/dist/agents/middleware/providerToolSearch.d.ts +1 -2
  137. package/dist/agents/middleware/providerToolSearch.d.ts.map +1 -1
  138. package/dist/agents/middleware/providerToolSearch.js.map +1 -1
  139. package/dist/agents/middleware/summarization.cjs +2 -3
  140. package/dist/agents/middleware/summarization.cjs.map +1 -1
  141. package/dist/agents/middleware/summarization.d.cts +16 -20
  142. package/dist/agents/middleware/summarization.d.cts.map +1 -1
  143. package/dist/agents/middleware/summarization.d.ts +16 -20
  144. package/dist/agents/middleware/summarization.d.ts.map +1 -1
  145. package/dist/agents/middleware/summarization.js +2 -3
  146. package/dist/agents/middleware/summarization.js.map +1 -1
  147. package/dist/agents/middleware/todoListMiddleware.cjs +0 -1
  148. package/dist/agents/middleware/todoListMiddleware.cjs.map +1 -1
  149. package/dist/agents/middleware/todoListMiddleware.d.cts +2 -5
  150. package/dist/agents/middleware/todoListMiddleware.d.cts.map +1 -1
  151. package/dist/agents/middleware/todoListMiddleware.d.ts +2 -5
  152. package/dist/agents/middleware/todoListMiddleware.d.ts.map +1 -1
  153. package/dist/agents/middleware/todoListMiddleware.js.map +1 -1
  154. package/dist/agents/middleware/toolCallLimit.cjs +0 -1
  155. package/dist/agents/middleware/toolCallLimit.cjs.map +1 -1
  156. package/dist/agents/middleware/toolCallLimit.d.cts +2 -4
  157. package/dist/agents/middleware/toolCallLimit.d.cts.map +1 -1
  158. package/dist/agents/middleware/toolCallLimit.d.ts +2 -4
  159. package/dist/agents/middleware/toolCallLimit.d.ts.map +1 -1
  160. package/dist/agents/middleware/toolCallLimit.js.map +1 -1
  161. package/dist/agents/middleware/toolEmulator.cjs +0 -1
  162. package/dist/agents/middleware/toolEmulator.cjs.map +1 -1
  163. package/dist/agents/middleware/toolEmulator.d.cts +0 -1
  164. package/dist/agents/middleware/toolEmulator.d.cts.map +1 -1
  165. package/dist/agents/middleware/toolEmulator.d.ts +0 -1
  166. package/dist/agents/middleware/toolEmulator.d.ts.map +1 -1
  167. package/dist/agents/middleware/toolEmulator.js.map +1 -1
  168. package/dist/agents/middleware/toolError.cjs +67 -0
  169. package/dist/agents/middleware/toolError.cjs.map +1 -0
  170. package/dist/agents/middleware/toolError.d.cts +63 -0
  171. package/dist/agents/middleware/toolError.d.cts.map +1 -0
  172. package/dist/agents/middleware/toolError.d.ts +63 -0
  173. package/dist/agents/middleware/toolError.d.ts.map +1 -0
  174. package/dist/agents/middleware/toolError.js +67 -0
  175. package/dist/agents/middleware/toolError.js.map +1 -0
  176. package/dist/agents/middleware/toolRetry.cjs +1 -1
  177. package/dist/agents/middleware/toolRetry.cjs.map +1 -1
  178. package/dist/agents/middleware/toolRetry.d.cts +1 -2
  179. package/dist/agents/middleware/toolRetry.d.cts.map +1 -1
  180. package/dist/agents/middleware/toolRetry.d.ts +1 -2
  181. package/dist/agents/middleware/toolRetry.d.ts.map +1 -1
  182. package/dist/agents/middleware/toolRetry.js +1 -1
  183. package/dist/agents/middleware/toolRetry.js.map +1 -1
  184. package/dist/agents/middleware/types.cjs.map +1 -1
  185. package/dist/agents/middleware/types.d.cts +1 -2
  186. package/dist/agents/middleware/types.d.cts.map +1 -1
  187. package/dist/agents/middleware/types.d.ts +1 -2
  188. package/dist/agents/middleware/types.d.ts.map +1 -1
  189. package/dist/agents/middleware/types.js.map +1 -1
  190. package/dist/agents/middleware/utils.cjs +0 -1
  191. package/dist/agents/middleware/utils.cjs.map +1 -1
  192. package/dist/agents/middleware/utils.d.cts +2 -1
  193. package/dist/agents/middleware/utils.d.cts.map +1 -1
  194. package/dist/agents/middleware/utils.d.ts +2 -1
  195. package/dist/agents/middleware/utils.d.ts.map +1 -1
  196. package/dist/agents/middleware/utils.js.map +1 -1
  197. package/dist/agents/middleware.cjs.map +1 -1
  198. package/dist/agents/middleware.d.cts +0 -1
  199. package/dist/agents/middleware.d.cts.map +1 -1
  200. package/dist/agents/middleware.d.ts +0 -1
  201. package/dist/agents/middleware.d.ts.map +1 -1
  202. package/dist/agents/middleware.js.map +1 -1
  203. package/dist/agents/model.cjs.map +1 -1
  204. package/dist/agents/model.d.cts +0 -1
  205. package/dist/agents/model.d.cts.map +1 -1
  206. package/dist/agents/model.d.ts +0 -1
  207. package/dist/agents/model.d.ts.map +1 -1
  208. package/dist/agents/model.js.map +1 -1
  209. package/dist/agents/nodes/AfterAgentNode.cjs +1 -0
  210. package/dist/agents/nodes/AfterAgentNode.cjs.map +1 -1
  211. package/dist/agents/nodes/AfterAgentNode.js +1 -0
  212. package/dist/agents/nodes/AfterAgentNode.js.map +1 -1
  213. package/dist/agents/nodes/AfterModelNode.cjs +1 -0
  214. package/dist/agents/nodes/AfterModelNode.cjs.map +1 -1
  215. package/dist/agents/nodes/AfterModelNode.js +1 -0
  216. package/dist/agents/nodes/AfterModelNode.js.map +1 -1
  217. package/dist/agents/nodes/AgentNode.cjs +0 -1
  218. package/dist/agents/nodes/AgentNode.cjs.map +1 -1
  219. package/dist/agents/nodes/AgentNode.js.map +1 -1
  220. package/dist/agents/nodes/BeforeAgentNode.cjs +1 -0
  221. package/dist/agents/nodes/BeforeAgentNode.cjs.map +1 -1
  222. package/dist/agents/nodes/BeforeAgentNode.js +1 -0
  223. package/dist/agents/nodes/BeforeAgentNode.js.map +1 -1
  224. package/dist/agents/nodes/BeforeModelNode.cjs +1 -0
  225. package/dist/agents/nodes/BeforeModelNode.cjs.map +1 -1
  226. package/dist/agents/nodes/BeforeModelNode.js +1 -0
  227. package/dist/agents/nodes/BeforeModelNode.js.map +1 -1
  228. package/dist/agents/nodes/ToolNode.cjs +2 -1
  229. package/dist/agents/nodes/ToolNode.cjs.map +1 -1
  230. package/dist/agents/nodes/ToolNode.js +2 -1
  231. package/dist/agents/nodes/ToolNode.js.map +1 -1
  232. package/dist/agents/nodes/middleware.cjs +0 -1
  233. package/dist/agents/nodes/middleware.cjs.map +1 -1
  234. package/dist/agents/nodes/middleware.js.map +1 -1
  235. package/dist/agents/nodes/types.d.cts +0 -1
  236. package/dist/agents/nodes/types.d.cts.map +1 -1
  237. package/dist/agents/nodes/types.d.ts +0 -1
  238. package/dist/agents/nodes/types.d.ts.map +1 -1
  239. package/dist/agents/nodes/utils.cjs +0 -1
  240. package/dist/agents/nodes/utils.cjs.map +1 -1
  241. package/dist/agents/nodes/utils.js.map +1 -1
  242. package/dist/agents/responses.cjs +11 -5
  243. package/dist/agents/responses.cjs.map +1 -1
  244. package/dist/agents/responses.d.cts +3 -3
  245. package/dist/agents/responses.d.cts.map +1 -1
  246. package/dist/agents/responses.d.ts +3 -3
  247. package/dist/agents/responses.d.ts.map +1 -1
  248. package/dist/agents/responses.js +11 -5
  249. package/dist/agents/responses.js.map +1 -1
  250. package/dist/agents/runtime.d.cts +2 -2
  251. package/dist/agents/runtime.d.cts.map +1 -1
  252. package/dist/agents/runtime.d.ts +2 -2
  253. package/dist/agents/runtime.d.ts.map +1 -1
  254. package/dist/agents/tests/utils.cjs +0 -1
  255. package/dist/agents/tests/utils.cjs.map +1 -1
  256. package/dist/agents/tests/utils.d.cts +2 -9
  257. package/dist/agents/tests/utils.d.cts.map +1 -1
  258. package/dist/agents/tests/utils.d.ts +2 -9
  259. package/dist/agents/tests/utils.d.ts.map +1 -1
  260. package/dist/agents/tests/utils.js.map +1 -1
  261. package/dist/agents/transformers/index.cjs +4 -2
  262. package/dist/agents/transformers/index.d.cts +2 -1
  263. package/dist/agents/transformers/index.d.ts +2 -1
  264. package/dist/agents/transformers/index.js +3 -3
  265. package/dist/agents/transformers/subagent.cjs +0 -1
  266. package/dist/agents/transformers/subagent.cjs.map +1 -1
  267. package/dist/agents/transformers/subagent.d.cts +0 -1
  268. package/dist/agents/transformers/subagent.d.cts.map +1 -1
  269. package/dist/agents/transformers/subagent.d.ts +0 -1
  270. package/dist/agents/transformers/subagent.d.ts.map +1 -1
  271. package/dist/agents/transformers/subagent.js.map +1 -1
  272. package/dist/agents/transformers/tool-call.cjs +0 -1
  273. package/dist/agents/transformers/tool-call.cjs.map +1 -1
  274. package/dist/agents/transformers/tool-call.d.cts +0 -1
  275. package/dist/agents/transformers/tool-call.d.cts.map +1 -1
  276. package/dist/agents/transformers/tool-call.d.ts +0 -1
  277. package/dist/agents/transformers/tool-call.d.ts.map +1 -1
  278. package/dist/agents/transformers/tool-call.js.map +1 -1
  279. package/dist/agents/transformers/types.d.cts +3 -3
  280. package/dist/agents/transformers/types.d.cts.map +1 -1
  281. package/dist/agents/transformers/types.d.ts +3 -3
  282. package/dist/agents/transformers/types.d.ts.map +1 -1
  283. package/dist/agents/types.d.cts +1 -2
  284. package/dist/agents/types.d.cts.map +1 -1
  285. package/dist/agents/types.d.ts +1 -2
  286. package/dist/agents/types.d.ts.map +1 -1
  287. package/dist/agents/utils.cjs +11 -5
  288. package/dist/agents/utils.cjs.map +1 -1
  289. package/dist/agents/utils.js +11 -4
  290. package/dist/agents/utils.js.map +1 -1
  291. package/dist/agents/withAgentName.cjs +0 -1
  292. package/dist/agents/withAgentName.cjs.map +1 -1
  293. package/dist/agents/withAgentName.js.map +1 -1
  294. package/dist/browser.cjs +3 -0
  295. package/dist/browser.d.cts +3 -1
  296. package/dist/browser.d.ts +3 -1
  297. package/dist/browser.js +3 -1
  298. package/dist/chat_models/universal.cjs.map +1 -1
  299. package/dist/chat_models/universal.d.cts +0 -1
  300. package/dist/chat_models/universal.d.cts.map +1 -1
  301. package/dist/chat_models/universal.d.ts +0 -1
  302. package/dist/chat_models/universal.d.ts.map +1 -1
  303. package/dist/chat_models/universal.js.map +1 -1
  304. package/dist/hub/base.cjs +0 -1
  305. package/dist/hub/base.cjs.map +1 -1
  306. package/dist/hub/base.d.cts +1 -0
  307. package/dist/hub/base.d.cts.map +1 -1
  308. package/dist/hub/base.d.ts +1 -0
  309. package/dist/hub/base.d.ts.map +1 -1
  310. package/dist/hub/base.js.map +1 -1
  311. package/dist/hub/index.cjs.map +1 -1
  312. package/dist/hub/index.d.cts +0 -1
  313. package/dist/hub/index.d.cts.map +1 -1
  314. package/dist/hub/index.d.ts +0 -1
  315. package/dist/hub/index.d.ts.map +1 -1
  316. package/dist/hub/index.js.map +1 -1
  317. package/dist/hub/node.cjs.map +1 -1
  318. package/dist/hub/node.d.cts +0 -1
  319. package/dist/hub/node.d.cts.map +1 -1
  320. package/dist/hub/node.d.ts +0 -1
  321. package/dist/hub/node.d.ts.map +1 -1
  322. package/dist/hub/node.js.map +1 -1
  323. package/dist/index.cjs +3 -0
  324. package/dist/index.d.cts +3 -1
  325. package/dist/index.d.ts +3 -1
  326. package/dist/index.js +3 -1
  327. package/dist/load/import_constants.cjs.map +1 -1
  328. package/dist/load/import_constants.js.map +1 -1
  329. package/dist/load/import_map.cjs +56 -0
  330. package/dist/load/import_map.cjs.map +1 -1
  331. package/dist/load/import_map.js +1 -1
  332. package/dist/load/import_map.js.map +1 -1
  333. package/dist/load/import_type.d.cts.map +1 -1
  334. package/dist/load/import_type.d.ts.map +1 -1
  335. package/dist/load/index.cjs +0 -1
  336. package/dist/load/index.cjs.map +1 -1
  337. package/dist/load/index.d.cts +0 -1
  338. package/dist/load/index.d.cts.map +1 -1
  339. package/dist/load/index.d.ts +0 -1
  340. package/dist/load/index.d.ts.map +1 -1
  341. package/dist/load/index.js.map +1 -1
  342. package/dist/storage/encoder_backed.cjs.map +1 -1
  343. package/dist/storage/encoder_backed.d.cts +0 -1
  344. package/dist/storage/encoder_backed.d.cts.map +1 -1
  345. package/dist/storage/encoder_backed.d.ts +0 -1
  346. package/dist/storage/encoder_backed.d.ts.map +1 -1
  347. package/dist/storage/encoder_backed.js.map +1 -1
  348. package/dist/storage/file_system.cjs +4 -3
  349. package/dist/storage/file_system.cjs.map +1 -1
  350. package/dist/storage/file_system.d.cts +20 -1
  351. package/dist/storage/file_system.d.cts.map +1 -1
  352. package/dist/storage/file_system.d.ts +20 -1
  353. package/dist/storage/file_system.d.ts.map +1 -1
  354. package/dist/storage/file_system.js +4 -3
  355. package/dist/storage/file_system.js.map +1 -1
  356. package/dist/tools/headless.cjs +0 -1
  357. package/dist/tools/headless.cjs.map +1 -1
  358. package/dist/tools/headless.d.cts +5 -3
  359. package/dist/tools/headless.d.cts.map +1 -1
  360. package/dist/tools/headless.d.ts +5 -3
  361. package/dist/tools/headless.d.ts.map +1 -1
  362. package/dist/tools/headless.js.map +1 -1
  363. package/package.json +16 -16
@@ -1,4 +1,5 @@
1
1
  import { AIMessage, BaseMessage, ToolMessage } from "@langchain/core/messages";
2
+ import "@langchain/core/language_models/base";
2
3
  import { BaseChatModel, BaseChatModelParams, BindToolsInput, ToolChoice } from "@langchain/core/language_models/chat_models";
3
4
  import { Runnable, RunnableBinding, RunnableConfig, RunnableLambda } from "@langchain/core/runnables";
4
5
  import { StructuredTool } from "@langchain/core/tools";
@@ -7,7 +8,6 @@ import { ChatResult } from "@langchain/core/outputs";
7
8
  import { ModelProfile } from "@langchain/core/language_models/profile";
8
9
  import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
9
10
  import { z } from "zod/v3";
10
-
11
11
  //#region src/agents/tests/utils.d.ts
12
12
  interface ToolCall$1 {
13
13
  name: string;
@@ -30,14 +30,7 @@ declare class FakeToolCallingModel extends BaseChatModel {
30
30
  private indexRef;
31
31
  structuredResponse?: any;
32
32
  private tools;
33
- constructor({
34
- toolCalls,
35
- toolStyle,
36
- index,
37
- structuredResponse,
38
- indexRef,
39
- ...rest
40
- }?: FakeToolCallingModelFields & {
33
+ constructor({ toolCalls, toolStyle, index, structuredResponse, indexRef, ...rest }?: FakeToolCallingModelFields & {
41
34
  indexRef?: {
42
35
  current: number;
43
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.cts","names":[],"sources":["../../../src/agents/tests/utils.ts"],"mappings":";;;;;;;;;;;UA2UU,UAAA;EACR,IAAA;EACA,IAAA,EAAM,MAAA;EACN,EAAA;EACA,IAAA;AAAA;AAAA,UAGQ,0BAAA;EACR,SAAA,GAAY,UAAA;EACZ,SAAA;EACA,KAAA;EACA,kBAAA;AAAA;;;;cAWW,oBAAA,SAA6B,aAAA;EACxC,SAAA,EAAW,UAAA;EAEX,SAAA;EAAA,QAGQ,QAAA;EAER,kBAAA;EAAA,QAEQ,KAAA;EAER,WAAA,CAAA;IACE,SAAA;IACA,SAAA;IACA,KAAA;IACA,kBAAA;IACA,QAAA;IAAA,GACG;EAAA,IACF,0BAAA;IAA+B,QAAA;MAAa,OAAA;IAAA;EAAA;EAAA,IAU3C,KAAA,CAAA;EAAA,IAIA,KAAA,CAAM,KAAA;EAIV,QAAA,CAAA;EAIA,iBAAA,CAAA;EAIA,SAAA,CACE,KAAA,EAAO,cAAA,KAEL,oBAAA,GACA,eAAA;IAGU,WAAA,GAAc,UAAA;EAAA;EAa5B,oBAAA,CAAqB,OAAA,QAAY,cAAA,eAAA,cAAA,CAAA,MAAA;EAQ3B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,QAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA"}
1
+ {"version":3,"file":"utils.d.cts","names":[],"sources":["../../../src/agents/tests/utils.ts"],"mappings":";;;;;;;;;;;UA2UU;EACR;EACA,MAAM;EACN;EACA;;UAGQ;EACR,YAAY;EACZ;EACA;EACA;;;;;cAWW,6BAA6B;EACxC,WAAW;EAEX;UAGQ;EAER;UAEQ;EAER,cACE,WACA,WACA,OACA,oBACA,aACG,SACF;IAA+B;MAAa;;;MAU3C;MAIA,MAAM;EAIV;EAIA;EAIA,UACE,OAAO,mBAEL,uBACA;IAGU,cAAc;;EAa5B,qBAAqB,eAAY,6BAAA,eAAA;EAQ3B,UACJ,UAAU,eACV,sCACA,cAAc,2BACb,QAAQ"}
@@ -4,10 +4,10 @@ import { Runnable, RunnableBinding, RunnableConfig, RunnableLambda } from "@lang
4
4
  import { StructuredTool } from "@langchain/core/tools";
5
5
  import { BaseCheckpointSaver } from "@langchain/langgraph-checkpoint";
6
6
  import { z } from "zod/v3";
7
+ import "@langchain/core/language_models/base";
7
8
  import { ChatResult } from "@langchain/core/outputs";
8
9
  import { CallbackManagerForLLMRun } from "@langchain/core/callbacks/manager";
9
10
  import { ModelProfile } from "@langchain/core/language_models/profile";
10
-
11
11
  //#region src/agents/tests/utils.d.ts
12
12
  interface ToolCall$1 {
13
13
  name: string;
@@ -30,14 +30,7 @@ declare class FakeToolCallingModel extends BaseChatModel {
30
30
  private indexRef;
31
31
  structuredResponse?: any;
32
32
  private tools;
33
- constructor({
34
- toolCalls,
35
- toolStyle,
36
- index,
37
- structuredResponse,
38
- indexRef,
39
- ...rest
40
- }?: FakeToolCallingModelFields & {
33
+ constructor({ toolCalls, toolStyle, index, structuredResponse, indexRef, ...rest }?: FakeToolCallingModelFields & {
41
34
  indexRef?: {
42
35
  current: number;
43
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/agents/tests/utils.ts"],"mappings":";;;;;;;;;;;UA2UU,UAAA;EACR,IAAA;EACA,IAAA,EAAM,MAAA;EACN,EAAA;EACA,IAAA;AAAA;AAAA,UAGQ,0BAAA;EACR,SAAA,GAAY,UAAA;EACZ,SAAA;EACA,KAAA;EACA,kBAAA;AAAA;;;;cAWW,oBAAA,SAA6B,aAAA;EACxC,SAAA,EAAW,UAAA;EAEX,SAAA;EAAA,QAGQ,QAAA;EAER,kBAAA;EAAA,QAEQ,KAAA;EAER,WAAA,CAAA;IACE,SAAA;IACA,SAAA;IACA,KAAA;IACA,kBAAA;IACA,QAAA;IAAA,GACG;EAAA,IACF,0BAAA;IAA+B,QAAA;MAAa,OAAA;IAAA;EAAA;EAAA,IAU3C,KAAA,CAAA;EAAA,IAIA,KAAA,CAAM,KAAA;EAIV,QAAA,CAAA;EAIA,iBAAA,CAAA;EAIA,SAAA,CACE,KAAA,EAAO,cAAA,KAEL,oBAAA,GACA,eAAA;IAGU,WAAA,GAAc,UAAA;EAAA;EAa5B,oBAAA,CAAqB,OAAA,QAAY,cAAA,eAAA,cAAA,CAAA,MAAA;EAQ3B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,QAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA"}
1
+ {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/agents/tests/utils.ts"],"mappings":";;;;;;;;;;;UA2UU;EACR;EACA,MAAM;EACN;EACA;;UAGQ;EACR,YAAY;EACZ;EACA;EACA;;;;;cAWW,6BAA6B;EACxC,WAAW;EAEX;UAGQ;EAER;UAEQ;EAER,cACE,WACA,WACA,OACA,oBACA,aACG,SACF;IAA+B;MAAa;;;MAU3C;MAIA,MAAM;EAIV;EAIA;EAIA,UACE,OAAO,mBAEL,uBACA;IAGU,cAAc;;EAa5B,qBAAqB,eAAY,6BAAA,eAAA;EAQ3B,UACJ,UAAU,eACV,sCACA,cAAc,2BACb,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6B,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,EAAE;CAEpC,YAAY,EACV,YAAY,EAAE,EACd,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,EAAE,EAAE;AACvE,QAAM,KAAK;AACX,OAAK,YAAY;AACjB,OAAK,YAAY;AAEjB,OAAK,WAAW,YAAY,EAAE,SAAS,OAAO;AAC9C,OAAK,qBAAqB;;CAI5B,IAAI,QAAgB;AAClB,SAAO,KAAK,SAAS;;CAGvB,IAAI,MAAM,OAAe;AACvB,OAAK,SAAS,UAAU;;CAG1B,WAAmB;AACjB,SAAO;;CAGT,oBAAoB;AAClB,SAAO,EAAE;;CAGX,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;GAChB,CAAC;AACF,cAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,MAAM;AAC7C,SAAO;;CAGT,qBAAqB,SAAc;AACjC,SAAO,IAAI,eAAe,EACxB,MAAM,YAAY;AAChB,UAAO,KAAK;KAEf,CAAC;;CAGJ,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,GACrB;AAG1B,MAAI,SAAS,SAAS,EAEpB,WADc,SAAS,KAAK,MAAM,EAAE,QAAQ,CAAC,OAAO,QACrC,CACZ,KAAK,SAAS;AACb,OAAI,OAAO,SAAS,SAClB,QAAO;YACE,OAAO,SAAS,YAAY,UAAU,KAC/C,QAAO,KAAK;YACH,MAAM,QAAQ,KAAK,CAC5B,QAAO,KACJ,KAAK,MAAM;AACV,QAAI,OAAO,MAAM,SACf,QAAO;aACE,OAAO,MAAM,YAAY,UAAU,EAC5C,QAAO,EAAE;AAEX,WAAO;KACP,CACD,KAAK,IAAI;OAEZ,QAAO,KAAK,UAAU,KAAK;IAE7B,CACD,KAAK,IAAI;AAQd,OAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAM,aAAa,WAAW,KACtC,KAAK,UAAU,EAC1C,MAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,EAAE;EACzD,MAAM,YAAY,KAAK,MAAM,UAAU;AAGvC,OAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,OAAO;EAElE,MAAM,UAAU,IAAI,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;IACP,EAAE,GACH,KAAA;GACP,CAAC;AAEF,SAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;IACD,CACF;GACD,WAAW,EAAE;GACd"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/agents/tests/utils.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport {\n BaseChatModel,\n BaseChatModelParams,\n BaseChatModelCallOptions,\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport { StructuredTool } from \"@langchain/core/tools\";\nimport {\n BaseMessage,\n AIMessage,\n HumanMessage,\n BaseMessageFields,\n AIMessageFields,\n ToolMessage,\n ToolMessageFields,\n} from \"@langchain/core/messages\";\nimport { ChatResult } from \"@langchain/core/outputs\";\nimport {\n Runnable,\n RunnableConfig,\n RunnableLambda,\n RunnableBinding,\n} from \"@langchain/core/runnables\";\nimport {\n MemorySaver,\n Checkpoint,\n CheckpointMetadata,\n type BaseCheckpointSaver,\n} from \"@langchain/langgraph-checkpoint\";\nimport { LanguageModelLike } from \"@langchain/core/language_models/base\";\nimport { z } from \"zod/v3\";\n\n/**\n * Custom asymmetric matcher that matches any string value.\n * Works with both Jest and Vitest's toEqual() assertions.\n */\nclass AnyString {\n asymmetricMatch(other: unknown): boolean {\n return typeof other === \"string\";\n }\n\n toString(): string {\n return \"Any<String>\";\n }\n\n toAsymmetricMatcher(): string {\n return \"Any<String>\";\n }\n}\n\nexport class _AnyIdAIMessage extends AIMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"AIMessage\"];\n }\n\n constructor(fields: AIMessageFields | string) {\n let fieldsWithJestMatcher: Partial<AIMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as AIMessageFields);\n }\n}\n\nexport class _AnyIdHumanMessage extends HumanMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"HumanMessage\"];\n }\n\n constructor(fields: BaseMessageFields | string) {\n let fieldsWithJestMatcher: Partial<BaseMessageFields> = {\n id: new AnyString() as unknown as string,\n };\n if (typeof fields === \"string\") {\n fieldsWithJestMatcher = {\n content: fields,\n ...fieldsWithJestMatcher,\n };\n } else {\n fieldsWithJestMatcher = {\n ...fields,\n ...fieldsWithJestMatcher,\n };\n }\n super(fieldsWithJestMatcher as BaseMessageFields);\n }\n}\n\nexport class _AnyIdToolMessage extends ToolMessage {\n get lc_id() {\n return [\"langchain_core\", \"messages\", \"ToolMessage\"];\n }\n\n constructor(fields: ToolMessageFields) {\n const fieldsWithJestMatcher: Partial<ToolMessageFields> = {\n id: new AnyString() as unknown as string,\n ...fields,\n };\n super(fieldsWithJestMatcher as ToolMessageFields);\n }\n}\n\nexport class FakeConfigurableModel extends BaseChatModel {\n _queuedMethodOperations: Record<string, any> = {};\n\n _chatModel: LanguageModelLike;\n\n constructor(\n fields: {\n model: LanguageModelLike;\n } & BaseChatModelParams\n ) {\n super(fields);\n this._chatModel = fields.model;\n }\n\n _llmType() {\n return \"fake_configurable\";\n }\n\n async _generate(\n _messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n throw new Error(\"Not implemented\");\n }\n\n async _model() {\n return this._chatModel;\n }\n\n bindTools(tools: BindToolsInput[]) {\n const modelWithTools = new FakeConfigurableModel({\n model: (this._chatModel as FakeToolCallingChatModel).bindTools(tools),\n });\n modelWithTools._queuedMethodOperations.bindTools = tools;\n return modelWithTools;\n }\n}\n\nexport class FakeToolCallingChatModel extends BaseChatModel {\n sleep?: number = 50;\n\n responses?: BaseMessage[];\n\n thrownErrorString?: string;\n\n idx: number;\n\n toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n structuredResponse?: Record<string, unknown>;\n\n // Track messages passed to structured output calls\n structuredOutputMessages: BaseMessage[][] = [];\n\n constructor(\n fields: {\n sleep?: number;\n responses?: BaseMessage[];\n thrownErrorString?: string;\n toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n structuredResponse?: Record<string, unknown>;\n } & BaseChatModelParams\n ) {\n super(fields);\n this.sleep = fields.sleep ?? this.sleep;\n this.responses = fields.responses;\n this.thrownErrorString = fields.thrownErrorString;\n this.idx = 0;\n this.toolStyle = fields.toolStyle ?? this.toolStyle;\n this.structuredResponse = fields.structuredResponse;\n this.structuredOutputMessages = [];\n }\n\n _llmType() {\n return \"fake\";\n }\n\n get profile(): ModelProfile {\n return {\n toolCalling: true,\n structuredOutput: true,\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n _options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.thrownErrorString) {\n throw new Error(this.thrownErrorString);\n }\n if (this.sleep !== undefined) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n const responses = this.responses?.length ? this.responses : messages;\n const msg = responses[this.idx % responses.length];\n const generation: ChatResult = {\n generations: [\n {\n text: \"\",\n message: msg,\n },\n ],\n };\n this.idx += 1;\n\n if (typeof msg.content === \"string\") {\n await runManager?.handleLLMNewToken(msg.content);\n }\n return generation;\n }\n\n bindTools(tools: BindToolsInput[]): Runnable<any> {\n const toolDicts = [];\n const serverTools = [];\n for (const tool of tools) {\n if (!(\"name\" in tool)) {\n serverTools.push(tool);\n continue;\n }\n\n // NOTE: this is a simplified tool spec for testing purposes only\n if (this.toolStyle === \"openai\") {\n toolDicts.push({\n type: \"function\",\n function: {\n name: tool.name,\n },\n });\n } else if ([\"anthropic\", \"google\"].includes(this.toolStyle)) {\n toolDicts.push({\n name: tool.name,\n });\n } else if (this.toolStyle === \"bedrock\") {\n toolDicts.push({\n toolSpec: {\n name: tool.name,\n },\n });\n }\n }\n let toolsToBind: BindToolsInput[] = toolDicts;\n if (this.toolStyle === \"google\") {\n toolsToBind = [{ functionDeclarations: toolDicts }];\n }\n return this.withConfig({\n tools: [...toolsToBind, ...serverTools],\n } as BaseChatModelCallOptions);\n }\n\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(_: unknown): Runnable<any> {\n if (!this.structuredResponse) {\n throw new Error(\"No structured response provided\");\n }\n // Create a runnable that returns the proper structured format\n return RunnableLambda.from(async (messages: BaseMessage[]) => {\n if (this.sleep) {\n await new Promise((resolve) => setTimeout(resolve, this.sleep));\n }\n\n // Store the messages that were sent to generate structured output\n this.structuredOutputMessages.push([...messages]);\n\n // Return in the format expected: { raw: BaseMessage, parsed: RunOutput }\n return this.structuredResponse as RunOutput;\n });\n }\n}\n\nexport class MemorySaverAssertImmutable extends MemorySaver {\n storageForCopies: Record<string, Record<string, Uint8Array>> = {};\n\n constructor() {\n super();\n this.storageForCopies = {};\n }\n\n async put(\n config: RunnableConfig,\n checkpoint: Checkpoint,\n metadata: CheckpointMetadata\n ): Promise<RunnableConfig> {\n const thread_id = config.configurable?.thread_id;\n this.storageForCopies[thread_id] ??= {};\n\n // assert checkpoint hasn't been modified since last written\n const saved = await this.get(config);\n if (saved) {\n const savedId = saved.id;\n if (this.storageForCopies[thread_id][savedId]) {\n const [, serializedSaved] = await this.serde.dumpsTyped(saved);\n const serializedCopy = this.storageForCopies[thread_id][savedId];\n\n // Compare Uint8Array contents by converting to string\n const savedStr = new TextDecoder().decode(serializedSaved);\n const copyStr = new TextDecoder().decode(serializedCopy);\n if (savedStr !== copyStr) {\n throw new Error(\n `Checkpoint [${savedId}] has been modified since last written`\n );\n }\n }\n }\n const [, serializedCheckpoint] = await this.serde.dumpsTyped(checkpoint);\n // save a copy of the checkpoint\n this.storageForCopies[thread_id][checkpoint.id] = serializedCheckpoint;\n\n return super.put(config, checkpoint, metadata);\n }\n}\n\ninterface ToolCall {\n name: string;\n args: Record<string, any>;\n id: string;\n type?: \"tool_call\";\n}\n\ninterface FakeToolCallingModelFields {\n toolCalls?: ToolCall[][];\n toolStyle?: \"openai\" | \"anthropic\";\n index?: number;\n structuredResponse?: any;\n}\n\n// Helper function to create checkpointer\nexport function createCheckpointer(): BaseCheckpointSaver {\n return new MemorySaver();\n}\n\n/**\n * Fake chat model for testing tool calling functionality\n */\nexport class FakeToolCallingModel extends BaseChatModel {\n toolCalls: ToolCall[][];\n\n toolStyle: \"openai\" | \"anthropic\";\n\n // Use a shared reference object so the index persists across bindTools calls\n private indexRef: { current: number };\n\n structuredResponse?: any;\n\n private tools: StructuredTool[] = [];\n\n constructor({\n toolCalls = [],\n toolStyle = \"openai\",\n index = 0,\n structuredResponse,\n indexRef,\n ...rest\n }: FakeToolCallingModelFields & { indexRef?: { current: number } } = {}) {\n super(rest);\n this.toolCalls = toolCalls;\n this.toolStyle = toolStyle;\n // Share the same index reference across instances\n this.indexRef = indexRef ?? { current: index };\n this.structuredResponse = structuredResponse;\n }\n\n // Getter/setter for backwards compatibility\n get index(): number {\n return this.indexRef.current;\n }\n\n set index(value: number) {\n this.indexRef.current = value;\n }\n\n _llmType(): string {\n return \"fake-tool-calling\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n bindTools(\n tools: StructuredTool[]\n ):\n | FakeToolCallingModel\n | RunnableBinding<\n any,\n any,\n any & { tool_choice?: ToolChoice | undefined }\n > {\n const newInstance = new FakeToolCallingModel({\n toolCalls: this.toolCalls,\n toolStyle: this.toolStyle,\n structuredResponse: this.structuredResponse,\n // Pass the same indexRef so all instances share the same index state\n indexRef: this.indexRef,\n });\n newInstance.tools = [...this.tools, ...tools];\n return newInstance;\n }\n\n withStructuredOutput(_schema: any) {\n return new RunnableLambda({\n func: async () => {\n return this.structuredResponse;\n },\n });\n }\n\n async _generate(\n messages: BaseMessage[],\n _options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const lastMessage = messages[messages.length - 1];\n let content = lastMessage.content as string;\n\n // Handle prompt concatenation\n if (messages.length > 1) {\n const parts = messages.map((m) => m.content).filter(Boolean);\n content = parts\n .map((part) => {\n if (typeof part === \"string\") {\n return part;\n } else if (typeof part === \"object\" && \"text\" in part) {\n return part.text;\n } else if (Array.isArray(part)) {\n return part\n .map((p) => {\n if (typeof p === \"string\") {\n return p;\n } else if (typeof p === \"object\" && \"text\" in p) {\n return p.text;\n }\n return \"\";\n })\n .join(\"-\");\n } else {\n return JSON.stringify(part);\n }\n })\n .join(\"-\");\n }\n\n // Reset index at the start of a new conversation (only human message)\n // This allows the model to be reused across multiple agent.invoke() calls\n const isStartOfConversation =\n messages.length === 1 ||\n (messages.length === 2 && messages.every(HumanMessage.isInstance));\n if (isStartOfConversation && this.index !== 0) {\n this.index = 0;\n }\n\n const currentToolCalls = this.toolCalls[this.index] || [];\n const messageId = this.index.toString();\n\n // Move to next set of tool calls for subsequent invocations\n this.index = (this.index + 1) % Math.max(1, this.toolCalls.length);\n\n const message = new AIMessage({\n content,\n id: messageId,\n tool_calls:\n currentToolCalls.length > 0\n ? currentToolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [\n {\n text: content,\n message,\n },\n ],\n llmOutput: {},\n };\n }\n}\n\nexport class SearchAPI extends StructuredTool {\n name = \"search_api\";\n\n description = \"A simple API that returns the input string.\";\n\n schema = z.object({\n query: z.string().describe(\"The query to search for.\"),\n });\n\n async _call(input: z.infer<typeof this.schema>) {\n if (input?.query === \"error\") {\n throw new Error(\"Error\");\n }\n return `result for ${input?.query}`;\n }\n}\n"],"mappings":";;;;;;;;;;AAiWA,IAAa,uBAAb,MAAa,6BAA6B,cAAc;CACtD;CAEA;CAGA;CAEA;CAEA,QAAkC,CAAC;CAEnC,YAAY,EACV,YAAY,CAAC,GACb,YAAY,UACZ,QAAQ,GACR,oBACA,UACA,GAAG,SACgE,CAAC,GAAG;EACvE,MAAM,IAAI;EACV,KAAK,YAAY;EACjB,KAAK,YAAY;EAEjB,KAAK,WAAW,YAAY,EAAE,SAAS,MAAM;EAC7C,KAAK,qBAAqB;CAC5B;CAGA,IAAI,QAAgB;EAClB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,MAAM,OAAe;EACvB,KAAK,SAAS,UAAU;CAC1B;CAEA,WAAmB;EACjB,OAAO;CACT;CAEA,oBAAoB;EAClB,OAAO,CAAC;CACV;CAEA,UACE,OAOI;EACJ,MAAM,cAAc,IAAI,qBAAqB;GAC3C,WAAW,KAAK;GAChB,WAAW,KAAK;GAChB,oBAAoB,KAAK;GAEzB,UAAU,KAAK;EACjB,CAAC;EACD,YAAY,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,KAAK;EAC5C,OAAO;CACT;CAEA,qBAAqB,SAAc;EACjC,OAAO,IAAI,eAAe,EACxB,MAAM,YAAY;GAChB,OAAO,KAAK;EACd,EACF,CAAC;CACH;CAEA,MAAM,UACJ,UACA,UACA,aACqB;EAErB,IAAI,UADgB,SAAS,SAAS,SAAS,EACtB,CAAC;EAG1B,IAAI,SAAS,SAAS,GAEpB,UADc,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,OACtC,CAAC,CACZ,KAAK,SAAS;GACb,IAAI,OAAO,SAAS,UAClB,OAAO;QACF,IAAI,OAAO,SAAS,YAAY,UAAU,MAC/C,OAAO,KAAK;QACP,IAAI,MAAM,QAAQ,IAAI,GAC3B,OAAO,KACJ,KAAK,MAAM;IACV,IAAI,OAAO,MAAM,UACf,OAAO;SACF,IAAI,OAAO,MAAM,YAAY,UAAU,GAC5C,OAAO,EAAE;IAEX,OAAO;GACT,CAAC,CAAC,CACD,KAAK,GAAG;QAEX,OAAO,KAAK,UAAU,IAAI;EAE9B,CAAC,CAAC,CACD,KAAK,GAAG;EAQb,KAFE,SAAS,WAAW,KACnB,SAAS,WAAW,KAAK,SAAS,MAAM,aAAa,UAAU,MACrC,KAAK,UAAU,GAC1C,KAAK,QAAQ;EAGf,MAAM,mBAAmB,KAAK,UAAU,KAAK,UAAU,CAAC;EACxD,MAAM,YAAY,KAAK,MAAM,SAAS;EAGtC,KAAK,SAAS,KAAK,QAAQ,KAAK,KAAK,IAAI,GAAG,KAAK,UAAU,MAAM;EAEjE,MAAM,UAAU,IAAI,UAAU;GAC5B;GACA,IAAI;GACJ,YACE,iBAAiB,SAAS,IACtB,iBAAiB,KAAK,QAAQ;IAC5B,GAAG;IACH,MAAM;GACR,EAAE,IACF,KAAA;EACR,CAAC;EAED,OAAO;GACL,aAAa,CACX;IACE,MAAM;IACN;GACF,CACF;GACA,WAAW,CAAC;EACd;CACF;AACF"}
@@ -1,2 +1,4 @@
1
- require("./tool-call.cjs");
2
- require("./subagent.cjs");
1
+ const require_tool_call = require("./tool-call.cjs");
2
+ const require_subagent = require("./subagent.cjs");
3
+ exports.createSubagentTransformer = require_subagent.createSubagentTransformer;
4
+ exports.createToolCallTransformer = require_tool_call.createToolCallTransformer;
@@ -1,3 +1,4 @@
1
1
  import { createToolCallTransformer } from "./tool-call.cjs";
2
2
  import { AgentRunStream, InferStreamExtensions, SubagentRunStream, ToolCallStreamUnion } from "./types.cjs";
3
- import { createSubagentTransformer } from "./subagent.cjs";
3
+ import { createSubagentTransformer } from "./subagent.cjs";
4
+ export { type AgentRunStream, type InferStreamExtensions, type SubagentRunStream, type ToolCallStreamUnion, createSubagentTransformer, createToolCallTransformer };
@@ -1,3 +1,4 @@
1
1
  import { createToolCallTransformer } from "./tool-call.js";
2
2
  import { AgentRunStream, InferStreamExtensions, SubagentRunStream, ToolCallStreamUnion } from "./types.js";
3
- import { createSubagentTransformer } from "./subagent.js";
3
+ import { createSubagentTransformer } from "./subagent.js";
4
+ export { type AgentRunStream, type InferStreamExtensions, type SubagentRunStream, type ToolCallStreamUnion, createSubagentTransformer, createToolCallTransformer };
@@ -1,3 +1,3 @@
1
- import "./tool-call.js";
2
- import "./subagent.js";
3
- export {};
1
+ import { createToolCallTransformer } from "./tool-call.js";
2
+ import { createSubagentTransformer } from "./subagent.js";
3
+ export { createSubagentTransformer, createToolCallTransformer };
@@ -1,4 +1,3 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");
2
1
  const require_tool_call = require("./tool-call.cjs");
3
2
  let _langchain_langgraph = require("@langchain/langgraph");
4
3
  //#region src/agents/transformers/subagent.ts
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.cjs","names":["StreamChannel","createToolCallTransformer"],"sources":["../../../src/agents/transformers/subagent.ts"],"sourcesContent":["import {\n StreamChannel,\n createMessagesTransformer,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type Namespace,\n type LifecycleCause,\n} from \"@langchain/langgraph\";\n\nimport { createToolCallTransformer } from \"./tool-call.js\";\nimport type { SubagentRunStream } from \"./types.js\";\n\ninterface SubagentProjection {\n subagents: AsyncIterable<SubagentRunStream>;\n}\n\n/** Per-subagent transformer instances, driven manually by the parent. */\ntype MessagesTransformer = ReturnType<typeof createMessagesTransformer>;\ntype ToolCallTransformer = ReturnType<\n ReturnType<typeof createToolCallTransformer>\n>;\ntype NestedSubagentTransformer = ReturnType<\n ReturnType<typeof createSubagentTransformer>\n>;\n\ninterface SubagentHandle {\n readonly key: string;\n readonly path: Namespace;\n readonly name: string;\n readonly messages: MessagesTransformer;\n readonly toolCall: ToolCallTransformer;\n readonly nested: NestedSubagentTransformer;\n readonly resolveOutput: (value: unknown) => void;\n readonly rejectOutput: (error: unknown) => void;\n latestValues: Record<string, unknown> | undefined;\n done: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Stable string key for a namespace. */\nfunction nsKey(ns: Namespace): string {\n return ns.join(\"\\u0000\");\n}\n\n/** Tests whether `ns` starts with every segment in `prefix`. */\nfunction hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n\n/**\n * Creates a native transformer that surfaces nested named agents on\n * `run.subagents`.\n *\n * It watches `tasks` events to record each namespace's `lc_agent_name` (set by\n * `createAgent({ name })`) and the triggering tool call, then — for any nested\n * run one level below {@link scope} that carries an `lc_agent_name` — emits a\n * typed {@link SubagentRunStream} handle.\n *\n * Each handle is backed by its own per-subagent transformer instances\n * ({@link createMessagesTransformer}, {@link createToolCallTransformer}, and a\n * nested {@link createSubagentTransformer}) scoped to the subagent's namespace.\n * Every event in the subtree is fed straight into those transformers, which\n * self-filter by namespace; the subagent's final `output` is resolved from its\n * last `values` snapshot when its `lifecycle` completes.\n *\n * Marked `__native: true` — the `subagents` projection lands directly on the\n * `GraphRunStream` instance as `run.subagents`.\n *\n * @param scope - Namespace prefix this transformer is scoped to. The root agent\n * uses `[]`; nested handles use their subagent's namespace, so grandchild\n * subagents are discovered recursively.\n */\nexport function createSubagentTransformer(\n scope: Namespace = []\n): () => NativeStreamTransformer<SubagentProjection> {\n return () => {\n const subagentsLog = StreamChannel.local<SubagentRunStream>();\n /** `lc_agent_name` observed per namespace (first task event wins). */\n const lcByNs = new Map<string, string | undefined>();\n /** Triggering task id -> originating LLM `tool_call_id`. */\n const pendingToolCalls = new Map<string, string>();\n /**\n * Namespace key -> the `tool_call_id` of the most recent tool to start\n * executing there. A tool that invokes a subagent emits its `tool-started`\n * at the tools-node namespace (`tools:<task_id>`) where the subagent then\n * roots, so this is the tool call that caused the subagent.\n */\n const activeToolCallByNs = new Map<string, string>();\n const handles = new Map<string, SubagentHandle>();\n const depth = scope.length;\n\n function recordIdentity(ns: Namespace, data: unknown): void {\n const key = nsKey(ns);\n if (lcByNs.has(key)) return;\n const metadata =\n isRecord(data) && isRecord(data.metadata) ? data.metadata : undefined;\n const lc = metadata?.lc_agent_name;\n lcByNs.set(key, typeof lc === \"string\" ? lc : undefined);\n }\n\n function recordPendingToolCalls(data: unknown): void {\n if (!isRecord(data)) return;\n const taskId = data.id;\n if (typeof taskId !== \"string\") return;\n const input = data.input;\n let toolCallId: string | undefined;\n if (isRecord(input) && isRecord(input.tool_call)) {\n const candidate = input.tool_call.id;\n if (typeof candidate === \"string\") toolCallId = candidate;\n } else if (Array.isArray(input)) {\n for (const toolCall of input) {\n if (isRecord(toolCall) && typeof toolCall.id === \"string\") {\n toolCallId = toolCall.id;\n break;\n }\n }\n }\n if (toolCallId != null) pendingToolCalls.set(taskId, toolCallId);\n }\n\n /**\n * Derive the `toolCall` cause for a named-subagent namespace.\n *\n * Primary signal: the tool whose `tool-started` event fired at the\n * subagent's own namespace (the tools node it roots under). Fallback: the\n * namespace segment's task id (`node:<task_id>`) joined to a tool call\n * harvested from a `tool_call_with_context`-shaped task input, so the\n * derivation stays correct if that shape reaches the stream in the future.\n */\n function deriveCause(ns: Namespace): LifecycleCause | undefined {\n const active = activeToolCallByNs.get(nsKey(ns));\n if (typeof active === \"string\" && active.length > 0) {\n return { type: \"toolCall\", tool_call_id: active } as LifecycleCause;\n }\n const segment = ns[ns.length - 1];\n const colon = segment.indexOf(\":\");\n if (colon === -1) return undefined;\n const triggerCallId = segment.slice(colon + 1);\n if (triggerCallId.length === 0) return undefined;\n const toolCallId = pendingToolCalls.get(triggerCallId);\n if (typeof toolCallId !== \"string\" || toolCallId.length === 0) {\n return undefined;\n }\n return { type: \"toolCall\", tool_call_id: toolCallId } as LifecycleCause;\n }\n\n function maybeStartSubagent(ns: Namespace): void {\n if (ns.length !== depth + 1 || !hasPrefix(ns, scope)) return;\n const key = nsKey(ns);\n if (handles.has(key)) return;\n const lc = lcByNs.get(key);\n // Only surface nested runs carrying an `lc_agent_name`; plain subgraphs\n // (no name) are excluded so `run.subagents` stays agent-only.\n if (typeof lc !== \"string\" || lc.length === 0) return;\n\n // Per-subagent transformers, each scoped to the subagent's namespace so\n // they pick out only the subagent's own model node / tools / nested\n // agents when fed the full event stream.\n const messages = createMessagesTransformer(ns);\n const messagesProjection = messages.init();\n const toolCall = createToolCallTransformer(ns)();\n const toolCallProjection = toolCall.init();\n const nested = createSubagentTransformer(ns)();\n const nestedProjection = nested.init();\n\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (error: unknown) => void;\n const output = new Promise<Record<string, unknown>>((resolve, reject) => {\n resolveOutput = resolve as (value: unknown) => void;\n rejectOutput = reject;\n });\n\n handles.set(key, {\n key,\n path: ns,\n name: lc,\n messages,\n toolCall,\n nested,\n resolveOutput,\n rejectOutput,\n latestValues: undefined,\n done: false,\n });\n\n subagentsLog.push({\n name: lc,\n cause: deriveCause(ns),\n output,\n messages: messagesProjection.messages,\n toolCalls: toolCallProjection.toolCalls,\n subagents: nestedProjection.subagents,\n });\n }\n\n function finishHandle(\n handle: SubagentHandle,\n outcome: { type: \"resolve\" } | { type: \"reject\"; error: unknown }\n ): void {\n if (handle.done) return;\n handle.done = true;\n if (outcome.type === \"resolve\") {\n handle.resolveOutput(handle.latestValues);\n } else {\n handle.rejectOutput(outcome.error);\n }\n handle.messages.finalize?.();\n handle.toolCall.finalize?.();\n handle.nested.finalize?.();\n }\n\n return {\n __native: true as const,\n\n init: () => ({ subagents: subagentsLog }),\n\n process(event: ProtocolEvent): boolean {\n const ns = event.params.namespace;\n const data = event.params.data;\n const isTaskResult =\n event.method === \"tasks\" && isRecord(data) && \"result\" in data;\n\n // Track the tool currently executing at each namespace. A subagent's\n // dispatching tool starts at the same namespace the subagent roots\n // under, so this records the cause before the subagent is discovered.\n if (\n event.method === \"tools\" &&\n isRecord(data) &&\n data.event === \"tool-started\" &&\n typeof data.tool_call_id === \"string\" &&\n data.tool_call_id.length > 0\n ) {\n activeToolCallByNs.set(nsKey(ns), data.tool_call_id);\n }\n\n // A task start: record identity / tool call, then discover a subagent\n // boundary *before* fanning out so the new handle receives its own\n // subtree events (which Pregel emits after the parent-namespace task).\n if (event.method === \"tasks\" && !isTaskResult) {\n recordIdentity(ns, data);\n recordPendingToolCalls(data);\n maybeStartSubagent(ns);\n }\n\n // Fan the event out to every active subagent whose subtree contains it.\n // The per-subagent transformers self-filter by namespace depth.\n for (const handle of handles.values()) {\n if (handle.done) continue;\n if (!hasPrefix(ns, handle.path)) continue;\n\n handle.messages.process(event);\n handle.toolCall.process(event);\n handle.nested.process(event);\n\n // Track the subagent's own (root-level) state and resolve its\n // `output` from the last snapshot when its lifecycle completes.\n if (nsKey(ns) === handle.key) {\n if (event.method === \"values\" && isRecord(data)) {\n handle.latestValues = data;\n } else if (event.method === \"lifecycle\" && isRecord(data)) {\n const status = data.event;\n if (status === \"completed\" || status === \"interrupted\") {\n finishHandle(handle, { type: \"resolve\" });\n } else if (status === \"failed\") {\n finishHandle(handle, {\n type: \"reject\",\n error: new Error(`Subagent ${handle.name} failed`),\n });\n }\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"resolve\" });\n }\n subagentsLog.close();\n },\n\n fail(err: unknown): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"reject\", error: err });\n }\n subagentsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"subagent.cjs","names":["StreamChannel","createToolCallTransformer"],"sources":["../../../src/agents/transformers/subagent.ts"],"sourcesContent":["import {\n StreamChannel,\n createMessagesTransformer,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type Namespace,\n type LifecycleCause,\n} from \"@langchain/langgraph\";\n\nimport { createToolCallTransformer } from \"./tool-call.js\";\nimport type { SubagentRunStream } from \"./types.js\";\n\ninterface SubagentProjection {\n subagents: AsyncIterable<SubagentRunStream>;\n}\n\n/** Per-subagent transformer instances, driven manually by the parent. */\ntype MessagesTransformer = ReturnType<typeof createMessagesTransformer>;\ntype ToolCallTransformer = ReturnType<\n ReturnType<typeof createToolCallTransformer>\n>;\ntype NestedSubagentTransformer = ReturnType<\n ReturnType<typeof createSubagentTransformer>\n>;\n\ninterface SubagentHandle {\n readonly key: string;\n readonly path: Namespace;\n readonly name: string;\n readonly messages: MessagesTransformer;\n readonly toolCall: ToolCallTransformer;\n readonly nested: NestedSubagentTransformer;\n readonly resolveOutput: (value: unknown) => void;\n readonly rejectOutput: (error: unknown) => void;\n latestValues: Record<string, unknown> | undefined;\n done: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Stable string key for a namespace. */\nfunction nsKey(ns: Namespace): string {\n return ns.join(\"\\u0000\");\n}\n\n/** Tests whether `ns` starts with every segment in `prefix`. */\nfunction hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n\n/**\n * Creates a native transformer that surfaces nested named agents on\n * `run.subagents`.\n *\n * It watches `tasks` events to record each namespace's `lc_agent_name` (set by\n * `createAgent({ name })`) and the triggering tool call, then — for any nested\n * run one level below {@link scope} that carries an `lc_agent_name` — emits a\n * typed {@link SubagentRunStream} handle.\n *\n * Each handle is backed by its own per-subagent transformer instances\n * ({@link createMessagesTransformer}, {@link createToolCallTransformer}, and a\n * nested {@link createSubagentTransformer}) scoped to the subagent's namespace.\n * Every event in the subtree is fed straight into those transformers, which\n * self-filter by namespace; the subagent's final `output` is resolved from its\n * last `values` snapshot when its `lifecycle` completes.\n *\n * Marked `__native: true` — the `subagents` projection lands directly on the\n * `GraphRunStream` instance as `run.subagents`.\n *\n * @param scope - Namespace prefix this transformer is scoped to. The root agent\n * uses `[]`; nested handles use their subagent's namespace, so grandchild\n * subagents are discovered recursively.\n */\nexport function createSubagentTransformer(\n scope: Namespace = []\n): () => NativeStreamTransformer<SubagentProjection> {\n return () => {\n const subagentsLog = StreamChannel.local<SubagentRunStream>();\n /** `lc_agent_name` observed per namespace (first task event wins). */\n const lcByNs = new Map<string, string | undefined>();\n /** Triggering task id -> originating LLM `tool_call_id`. */\n const pendingToolCalls = new Map<string, string>();\n /**\n * Namespace key -> the `tool_call_id` of the most recent tool to start\n * executing there. A tool that invokes a subagent emits its `tool-started`\n * at the tools-node namespace (`tools:<task_id>`) where the subagent then\n * roots, so this is the tool call that caused the subagent.\n */\n const activeToolCallByNs = new Map<string, string>();\n const handles = new Map<string, SubagentHandle>();\n const depth = scope.length;\n\n function recordIdentity(ns: Namespace, data: unknown): void {\n const key = nsKey(ns);\n if (lcByNs.has(key)) return;\n const metadata =\n isRecord(data) && isRecord(data.metadata) ? data.metadata : undefined;\n const lc = metadata?.lc_agent_name;\n lcByNs.set(key, typeof lc === \"string\" ? lc : undefined);\n }\n\n function recordPendingToolCalls(data: unknown): void {\n if (!isRecord(data)) return;\n const taskId = data.id;\n if (typeof taskId !== \"string\") return;\n const input = data.input;\n let toolCallId: string | undefined;\n if (isRecord(input) && isRecord(input.tool_call)) {\n const candidate = input.tool_call.id;\n if (typeof candidate === \"string\") toolCallId = candidate;\n } else if (Array.isArray(input)) {\n for (const toolCall of input) {\n if (isRecord(toolCall) && typeof toolCall.id === \"string\") {\n toolCallId = toolCall.id;\n break;\n }\n }\n }\n if (toolCallId != null) pendingToolCalls.set(taskId, toolCallId);\n }\n\n /**\n * Derive the `toolCall` cause for a named-subagent namespace.\n *\n * Primary signal: the tool whose `tool-started` event fired at the\n * subagent's own namespace (the tools node it roots under). Fallback: the\n * namespace segment's task id (`node:<task_id>`) joined to a tool call\n * harvested from a `tool_call_with_context`-shaped task input, so the\n * derivation stays correct if that shape reaches the stream in the future.\n */\n function deriveCause(ns: Namespace): LifecycleCause | undefined {\n const active = activeToolCallByNs.get(nsKey(ns));\n if (typeof active === \"string\" && active.length > 0) {\n return { type: \"toolCall\", tool_call_id: active } as LifecycleCause;\n }\n const segment = ns[ns.length - 1];\n const colon = segment.indexOf(\":\");\n if (colon === -1) return undefined;\n const triggerCallId = segment.slice(colon + 1);\n if (triggerCallId.length === 0) return undefined;\n const toolCallId = pendingToolCalls.get(triggerCallId);\n if (typeof toolCallId !== \"string\" || toolCallId.length === 0) {\n return undefined;\n }\n return { type: \"toolCall\", tool_call_id: toolCallId } as LifecycleCause;\n }\n\n function maybeStartSubagent(ns: Namespace): void {\n if (ns.length !== depth + 1 || !hasPrefix(ns, scope)) return;\n const key = nsKey(ns);\n if (handles.has(key)) return;\n const lc = lcByNs.get(key);\n // Only surface nested runs carrying an `lc_agent_name`; plain subgraphs\n // (no name) are excluded so `run.subagents` stays agent-only.\n if (typeof lc !== \"string\" || lc.length === 0) return;\n\n // Per-subagent transformers, each scoped to the subagent's namespace so\n // they pick out only the subagent's own model node / tools / nested\n // agents when fed the full event stream.\n const messages = createMessagesTransformer(ns);\n const messagesProjection = messages.init();\n const toolCall = createToolCallTransformer(ns)();\n const toolCallProjection = toolCall.init();\n const nested = createSubagentTransformer(ns)();\n const nestedProjection = nested.init();\n\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (error: unknown) => void;\n const output = new Promise<Record<string, unknown>>((resolve, reject) => {\n resolveOutput = resolve as (value: unknown) => void;\n rejectOutput = reject;\n });\n\n handles.set(key, {\n key,\n path: ns,\n name: lc,\n messages,\n toolCall,\n nested,\n resolveOutput,\n rejectOutput,\n latestValues: undefined,\n done: false,\n });\n\n subagentsLog.push({\n name: lc,\n cause: deriveCause(ns),\n output,\n messages: messagesProjection.messages,\n toolCalls: toolCallProjection.toolCalls,\n subagents: nestedProjection.subagents,\n });\n }\n\n function finishHandle(\n handle: SubagentHandle,\n outcome: { type: \"resolve\" } | { type: \"reject\"; error: unknown }\n ): void {\n if (handle.done) return;\n handle.done = true;\n if (outcome.type === \"resolve\") {\n handle.resolveOutput(handle.latestValues);\n } else {\n handle.rejectOutput(outcome.error);\n }\n handle.messages.finalize?.();\n handle.toolCall.finalize?.();\n handle.nested.finalize?.();\n }\n\n return {\n __native: true as const,\n\n init: () => ({ subagents: subagentsLog }),\n\n process(event: ProtocolEvent): boolean {\n const ns = event.params.namespace;\n const data = event.params.data;\n const isTaskResult =\n event.method === \"tasks\" && isRecord(data) && \"result\" in data;\n\n // Track the tool currently executing at each namespace. A subagent's\n // dispatching tool starts at the same namespace the subagent roots\n // under, so this records the cause before the subagent is discovered.\n if (\n event.method === \"tools\" &&\n isRecord(data) &&\n data.event === \"tool-started\" &&\n typeof data.tool_call_id === \"string\" &&\n data.tool_call_id.length > 0\n ) {\n activeToolCallByNs.set(nsKey(ns), data.tool_call_id);\n }\n\n // A task start: record identity / tool call, then discover a subagent\n // boundary *before* fanning out so the new handle receives its own\n // subtree events (which Pregel emits after the parent-namespace task).\n if (event.method === \"tasks\" && !isTaskResult) {\n recordIdentity(ns, data);\n recordPendingToolCalls(data);\n maybeStartSubagent(ns);\n }\n\n // Fan the event out to every active subagent whose subtree contains it.\n // The per-subagent transformers self-filter by namespace depth.\n for (const handle of handles.values()) {\n if (handle.done) continue;\n if (!hasPrefix(ns, handle.path)) continue;\n\n handle.messages.process(event);\n handle.toolCall.process(event);\n handle.nested.process(event);\n\n // Track the subagent's own (root-level) state and resolve its\n // `output` from the last snapshot when its lifecycle completes.\n if (nsKey(ns) === handle.key) {\n if (event.method === \"values\" && isRecord(data)) {\n handle.latestValues = data;\n } else if (event.method === \"lifecycle\" && isRecord(data)) {\n const status = data.event;\n if (status === \"completed\" || status === \"interrupted\") {\n finishHandle(handle, { type: \"resolve\" });\n } else if (status === \"failed\") {\n finishHandle(handle, {\n type: \"reject\",\n error: new Error(`Subagent ${handle.name} failed`),\n });\n }\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"resolve\" });\n }\n subagentsLog.close();\n },\n\n fail(err: unknown): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"reject\", error: err });\n }\n subagentsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { SubagentRunStream } from "./types.cjs";
2
2
  import { Namespace, NativeStreamTransformer } from "@langchain/langgraph";
3
-
4
3
  //#region src/agents/transformers/subagent.d.ts
5
4
  interface SubagentProjection {
6
5
  subagents: AsyncIterable<SubagentRunStream>;
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.d.cts","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"mappings":";;;;UAYU,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,iBAAA;AAAA;;;;;;;;;AAkE3B;;;;;;;;;;;;;;;iBAAgB,yBAAA,CACd,KAAA,GAAO,SAAA,SACA,uBAAA,CAAwB,kBAAA"}
1
+ {"version":3,"file":"subagent.d.cts","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"mappings":";;;UAYU;EACR,WAAW,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;iBAkEX,0BACd,QAAO,kBACA,wBAAwB"}
@@ -1,6 +1,5 @@
1
1
  import { SubagentRunStream } from "./types.js";
2
2
  import { Namespace, NativeStreamTransformer } from "@langchain/langgraph";
3
-
4
3
  //#region src/agents/transformers/subagent.d.ts
5
4
  interface SubagentProjection {
6
5
  subagents: AsyncIterable<SubagentRunStream>;
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.d.ts","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"mappings":";;;;UAYU,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,iBAAA;AAAA;;;;;;;;;AAkE3B;;;;;;;;;;;;;;;iBAAgB,yBAAA,CACd,KAAA,GAAO,SAAA,SACA,uBAAA,CAAwB,kBAAA"}
1
+ {"version":3,"file":"subagent.d.ts","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"mappings":";;;UAYU;EACR,WAAW,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;iBAkEX,0BACd,QAAO,kBACA,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"subagent.js","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"sourcesContent":["import {\n StreamChannel,\n createMessagesTransformer,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type Namespace,\n type LifecycleCause,\n} from \"@langchain/langgraph\";\n\nimport { createToolCallTransformer } from \"./tool-call.js\";\nimport type { SubagentRunStream } from \"./types.js\";\n\ninterface SubagentProjection {\n subagents: AsyncIterable<SubagentRunStream>;\n}\n\n/** Per-subagent transformer instances, driven manually by the parent. */\ntype MessagesTransformer = ReturnType<typeof createMessagesTransformer>;\ntype ToolCallTransformer = ReturnType<\n ReturnType<typeof createToolCallTransformer>\n>;\ntype NestedSubagentTransformer = ReturnType<\n ReturnType<typeof createSubagentTransformer>\n>;\n\ninterface SubagentHandle {\n readonly key: string;\n readonly path: Namespace;\n readonly name: string;\n readonly messages: MessagesTransformer;\n readonly toolCall: ToolCallTransformer;\n readonly nested: NestedSubagentTransformer;\n readonly resolveOutput: (value: unknown) => void;\n readonly rejectOutput: (error: unknown) => void;\n latestValues: Record<string, unknown> | undefined;\n done: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Stable string key for a namespace. */\nfunction nsKey(ns: Namespace): string {\n return ns.join(\"\\u0000\");\n}\n\n/** Tests whether `ns` starts with every segment in `prefix`. */\nfunction hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n\n/**\n * Creates a native transformer that surfaces nested named agents on\n * `run.subagents`.\n *\n * It watches `tasks` events to record each namespace's `lc_agent_name` (set by\n * `createAgent({ name })`) and the triggering tool call, then — for any nested\n * run one level below {@link scope} that carries an `lc_agent_name` — emits a\n * typed {@link SubagentRunStream} handle.\n *\n * Each handle is backed by its own per-subagent transformer instances\n * ({@link createMessagesTransformer}, {@link createToolCallTransformer}, and a\n * nested {@link createSubagentTransformer}) scoped to the subagent's namespace.\n * Every event in the subtree is fed straight into those transformers, which\n * self-filter by namespace; the subagent's final `output` is resolved from its\n * last `values` snapshot when its `lifecycle` completes.\n *\n * Marked `__native: true` — the `subagents` projection lands directly on the\n * `GraphRunStream` instance as `run.subagents`.\n *\n * @param scope - Namespace prefix this transformer is scoped to. The root agent\n * uses `[]`; nested handles use their subagent's namespace, so grandchild\n * subagents are discovered recursively.\n */\nexport function createSubagentTransformer(\n scope: Namespace = []\n): () => NativeStreamTransformer<SubagentProjection> {\n return () => {\n const subagentsLog = StreamChannel.local<SubagentRunStream>();\n /** `lc_agent_name` observed per namespace (first task event wins). */\n const lcByNs = new Map<string, string | undefined>();\n /** Triggering task id -> originating LLM `tool_call_id`. */\n const pendingToolCalls = new Map<string, string>();\n /**\n * Namespace key -> the `tool_call_id` of the most recent tool to start\n * executing there. A tool that invokes a subagent emits its `tool-started`\n * at the tools-node namespace (`tools:<task_id>`) where the subagent then\n * roots, so this is the tool call that caused the subagent.\n */\n const activeToolCallByNs = new Map<string, string>();\n const handles = new Map<string, SubagentHandle>();\n const depth = scope.length;\n\n function recordIdentity(ns: Namespace, data: unknown): void {\n const key = nsKey(ns);\n if (lcByNs.has(key)) return;\n const metadata =\n isRecord(data) && isRecord(data.metadata) ? data.metadata : undefined;\n const lc = metadata?.lc_agent_name;\n lcByNs.set(key, typeof lc === \"string\" ? lc : undefined);\n }\n\n function recordPendingToolCalls(data: unknown): void {\n if (!isRecord(data)) return;\n const taskId = data.id;\n if (typeof taskId !== \"string\") return;\n const input = data.input;\n let toolCallId: string | undefined;\n if (isRecord(input) && isRecord(input.tool_call)) {\n const candidate = input.tool_call.id;\n if (typeof candidate === \"string\") toolCallId = candidate;\n } else if (Array.isArray(input)) {\n for (const toolCall of input) {\n if (isRecord(toolCall) && typeof toolCall.id === \"string\") {\n toolCallId = toolCall.id;\n break;\n }\n }\n }\n if (toolCallId != null) pendingToolCalls.set(taskId, toolCallId);\n }\n\n /**\n * Derive the `toolCall` cause for a named-subagent namespace.\n *\n * Primary signal: the tool whose `tool-started` event fired at the\n * subagent's own namespace (the tools node it roots under). Fallback: the\n * namespace segment's task id (`node:<task_id>`) joined to a tool call\n * harvested from a `tool_call_with_context`-shaped task input, so the\n * derivation stays correct if that shape reaches the stream in the future.\n */\n function deriveCause(ns: Namespace): LifecycleCause | undefined {\n const active = activeToolCallByNs.get(nsKey(ns));\n if (typeof active === \"string\" && active.length > 0) {\n return { type: \"toolCall\", tool_call_id: active } as LifecycleCause;\n }\n const segment = ns[ns.length - 1];\n const colon = segment.indexOf(\":\");\n if (colon === -1) return undefined;\n const triggerCallId = segment.slice(colon + 1);\n if (triggerCallId.length === 0) return undefined;\n const toolCallId = pendingToolCalls.get(triggerCallId);\n if (typeof toolCallId !== \"string\" || toolCallId.length === 0) {\n return undefined;\n }\n return { type: \"toolCall\", tool_call_id: toolCallId } as LifecycleCause;\n }\n\n function maybeStartSubagent(ns: Namespace): void {\n if (ns.length !== depth + 1 || !hasPrefix(ns, scope)) return;\n const key = nsKey(ns);\n if (handles.has(key)) return;\n const lc = lcByNs.get(key);\n // Only surface nested runs carrying an `lc_agent_name`; plain subgraphs\n // (no name) are excluded so `run.subagents` stays agent-only.\n if (typeof lc !== \"string\" || lc.length === 0) return;\n\n // Per-subagent transformers, each scoped to the subagent's namespace so\n // they pick out only the subagent's own model node / tools / nested\n // agents when fed the full event stream.\n const messages = createMessagesTransformer(ns);\n const messagesProjection = messages.init();\n const toolCall = createToolCallTransformer(ns)();\n const toolCallProjection = toolCall.init();\n const nested = createSubagentTransformer(ns)();\n const nestedProjection = nested.init();\n\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (error: unknown) => void;\n const output = new Promise<Record<string, unknown>>((resolve, reject) => {\n resolveOutput = resolve as (value: unknown) => void;\n rejectOutput = reject;\n });\n\n handles.set(key, {\n key,\n path: ns,\n name: lc,\n messages,\n toolCall,\n nested,\n resolveOutput,\n rejectOutput,\n latestValues: undefined,\n done: false,\n });\n\n subagentsLog.push({\n name: lc,\n cause: deriveCause(ns),\n output,\n messages: messagesProjection.messages,\n toolCalls: toolCallProjection.toolCalls,\n subagents: nestedProjection.subagents,\n });\n }\n\n function finishHandle(\n handle: SubagentHandle,\n outcome: { type: \"resolve\" } | { type: \"reject\"; error: unknown }\n ): void {\n if (handle.done) return;\n handle.done = true;\n if (outcome.type === \"resolve\") {\n handle.resolveOutput(handle.latestValues);\n } else {\n handle.rejectOutput(outcome.error);\n }\n handle.messages.finalize?.();\n handle.toolCall.finalize?.();\n handle.nested.finalize?.();\n }\n\n return {\n __native: true as const,\n\n init: () => ({ subagents: subagentsLog }),\n\n process(event: ProtocolEvent): boolean {\n const ns = event.params.namespace;\n const data = event.params.data;\n const isTaskResult =\n event.method === \"tasks\" && isRecord(data) && \"result\" in data;\n\n // Track the tool currently executing at each namespace. A subagent's\n // dispatching tool starts at the same namespace the subagent roots\n // under, so this records the cause before the subagent is discovered.\n if (\n event.method === \"tools\" &&\n isRecord(data) &&\n data.event === \"tool-started\" &&\n typeof data.tool_call_id === \"string\" &&\n data.tool_call_id.length > 0\n ) {\n activeToolCallByNs.set(nsKey(ns), data.tool_call_id);\n }\n\n // A task start: record identity / tool call, then discover a subagent\n // boundary *before* fanning out so the new handle receives its own\n // subtree events (which Pregel emits after the parent-namespace task).\n if (event.method === \"tasks\" && !isTaskResult) {\n recordIdentity(ns, data);\n recordPendingToolCalls(data);\n maybeStartSubagent(ns);\n }\n\n // Fan the event out to every active subagent whose subtree contains it.\n // The per-subagent transformers self-filter by namespace depth.\n for (const handle of handles.values()) {\n if (handle.done) continue;\n if (!hasPrefix(ns, handle.path)) continue;\n\n handle.messages.process(event);\n handle.toolCall.process(event);\n handle.nested.process(event);\n\n // Track the subagent's own (root-level) state and resolve its\n // `output` from the last snapshot when its lifecycle completes.\n if (nsKey(ns) === handle.key) {\n if (event.method === \"values\" && isRecord(data)) {\n handle.latestValues = data;\n } else if (event.method === \"lifecycle\" && isRecord(data)) {\n const status = data.event;\n if (status === \"completed\" || status === \"interrupted\") {\n finishHandle(handle, { type: \"resolve\" });\n } else if (status === \"failed\") {\n finishHandle(handle, {\n type: \"reject\",\n error: new Error(`Subagent ${handle.name} failed`),\n });\n }\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"resolve\" });\n }\n subagentsLog.close();\n },\n\n fail(err: unknown): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"reject\", error: err });\n }\n subagentsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"subagent.js","names":[],"sources":["../../../src/agents/transformers/subagent.ts"],"sourcesContent":["import {\n StreamChannel,\n createMessagesTransformer,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type Namespace,\n type LifecycleCause,\n} from \"@langchain/langgraph\";\n\nimport { createToolCallTransformer } from \"./tool-call.js\";\nimport type { SubagentRunStream } from \"./types.js\";\n\ninterface SubagentProjection {\n subagents: AsyncIterable<SubagentRunStream>;\n}\n\n/** Per-subagent transformer instances, driven manually by the parent. */\ntype MessagesTransformer = ReturnType<typeof createMessagesTransformer>;\ntype ToolCallTransformer = ReturnType<\n ReturnType<typeof createToolCallTransformer>\n>;\ntype NestedSubagentTransformer = ReturnType<\n ReturnType<typeof createSubagentTransformer>\n>;\n\ninterface SubagentHandle {\n readonly key: string;\n readonly path: Namespace;\n readonly name: string;\n readonly messages: MessagesTransformer;\n readonly toolCall: ToolCallTransformer;\n readonly nested: NestedSubagentTransformer;\n readonly resolveOutput: (value: unknown) => void;\n readonly rejectOutput: (error: unknown) => void;\n latestValues: Record<string, unknown> | undefined;\n done: boolean;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Stable string key for a namespace. */\nfunction nsKey(ns: Namespace): string {\n return ns.join(\"\\u0000\");\n}\n\n/** Tests whether `ns` starts with every segment in `prefix`. */\nfunction hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n if (prefix.length > ns.length) return false;\n for (let i = 0; i < prefix.length; i += 1) {\n if (ns[i] !== prefix[i]) return false;\n }\n return true;\n}\n\n/**\n * Creates a native transformer that surfaces nested named agents on\n * `run.subagents`.\n *\n * It watches `tasks` events to record each namespace's `lc_agent_name` (set by\n * `createAgent({ name })`) and the triggering tool call, then — for any nested\n * run one level below {@link scope} that carries an `lc_agent_name` — emits a\n * typed {@link SubagentRunStream} handle.\n *\n * Each handle is backed by its own per-subagent transformer instances\n * ({@link createMessagesTransformer}, {@link createToolCallTransformer}, and a\n * nested {@link createSubagentTransformer}) scoped to the subagent's namespace.\n * Every event in the subtree is fed straight into those transformers, which\n * self-filter by namespace; the subagent's final `output` is resolved from its\n * last `values` snapshot when its `lifecycle` completes.\n *\n * Marked `__native: true` — the `subagents` projection lands directly on the\n * `GraphRunStream` instance as `run.subagents`.\n *\n * @param scope - Namespace prefix this transformer is scoped to. The root agent\n * uses `[]`; nested handles use their subagent's namespace, so grandchild\n * subagents are discovered recursively.\n */\nexport function createSubagentTransformer(\n scope: Namespace = []\n): () => NativeStreamTransformer<SubagentProjection> {\n return () => {\n const subagentsLog = StreamChannel.local<SubagentRunStream>();\n /** `lc_agent_name` observed per namespace (first task event wins). */\n const lcByNs = new Map<string, string | undefined>();\n /** Triggering task id -> originating LLM `tool_call_id`. */\n const pendingToolCalls = new Map<string, string>();\n /**\n * Namespace key -> the `tool_call_id` of the most recent tool to start\n * executing there. A tool that invokes a subagent emits its `tool-started`\n * at the tools-node namespace (`tools:<task_id>`) where the subagent then\n * roots, so this is the tool call that caused the subagent.\n */\n const activeToolCallByNs = new Map<string, string>();\n const handles = new Map<string, SubagentHandle>();\n const depth = scope.length;\n\n function recordIdentity(ns: Namespace, data: unknown): void {\n const key = nsKey(ns);\n if (lcByNs.has(key)) return;\n const metadata =\n isRecord(data) && isRecord(data.metadata) ? data.metadata : undefined;\n const lc = metadata?.lc_agent_name;\n lcByNs.set(key, typeof lc === \"string\" ? lc : undefined);\n }\n\n function recordPendingToolCalls(data: unknown): void {\n if (!isRecord(data)) return;\n const taskId = data.id;\n if (typeof taskId !== \"string\") return;\n const input = data.input;\n let toolCallId: string | undefined;\n if (isRecord(input) && isRecord(input.tool_call)) {\n const candidate = input.tool_call.id;\n if (typeof candidate === \"string\") toolCallId = candidate;\n } else if (Array.isArray(input)) {\n for (const toolCall of input) {\n if (isRecord(toolCall) && typeof toolCall.id === \"string\") {\n toolCallId = toolCall.id;\n break;\n }\n }\n }\n if (toolCallId != null) pendingToolCalls.set(taskId, toolCallId);\n }\n\n /**\n * Derive the `toolCall` cause for a named-subagent namespace.\n *\n * Primary signal: the tool whose `tool-started` event fired at the\n * subagent's own namespace (the tools node it roots under). Fallback: the\n * namespace segment's task id (`node:<task_id>`) joined to a tool call\n * harvested from a `tool_call_with_context`-shaped task input, so the\n * derivation stays correct if that shape reaches the stream in the future.\n */\n function deriveCause(ns: Namespace): LifecycleCause | undefined {\n const active = activeToolCallByNs.get(nsKey(ns));\n if (typeof active === \"string\" && active.length > 0) {\n return { type: \"toolCall\", tool_call_id: active } as LifecycleCause;\n }\n const segment = ns[ns.length - 1];\n const colon = segment.indexOf(\":\");\n if (colon === -1) return undefined;\n const triggerCallId = segment.slice(colon + 1);\n if (triggerCallId.length === 0) return undefined;\n const toolCallId = pendingToolCalls.get(triggerCallId);\n if (typeof toolCallId !== \"string\" || toolCallId.length === 0) {\n return undefined;\n }\n return { type: \"toolCall\", tool_call_id: toolCallId } as LifecycleCause;\n }\n\n function maybeStartSubagent(ns: Namespace): void {\n if (ns.length !== depth + 1 || !hasPrefix(ns, scope)) return;\n const key = nsKey(ns);\n if (handles.has(key)) return;\n const lc = lcByNs.get(key);\n // Only surface nested runs carrying an `lc_agent_name`; plain subgraphs\n // (no name) are excluded so `run.subagents` stays agent-only.\n if (typeof lc !== \"string\" || lc.length === 0) return;\n\n // Per-subagent transformers, each scoped to the subagent's namespace so\n // they pick out only the subagent's own model node / tools / nested\n // agents when fed the full event stream.\n const messages = createMessagesTransformer(ns);\n const messagesProjection = messages.init();\n const toolCall = createToolCallTransformer(ns)();\n const toolCallProjection = toolCall.init();\n const nested = createSubagentTransformer(ns)();\n const nestedProjection = nested.init();\n\n let resolveOutput!: (value: unknown) => void;\n let rejectOutput!: (error: unknown) => void;\n const output = new Promise<Record<string, unknown>>((resolve, reject) => {\n resolveOutput = resolve as (value: unknown) => void;\n rejectOutput = reject;\n });\n\n handles.set(key, {\n key,\n path: ns,\n name: lc,\n messages,\n toolCall,\n nested,\n resolveOutput,\n rejectOutput,\n latestValues: undefined,\n done: false,\n });\n\n subagentsLog.push({\n name: lc,\n cause: deriveCause(ns),\n output,\n messages: messagesProjection.messages,\n toolCalls: toolCallProjection.toolCalls,\n subagents: nestedProjection.subagents,\n });\n }\n\n function finishHandle(\n handle: SubagentHandle,\n outcome: { type: \"resolve\" } | { type: \"reject\"; error: unknown }\n ): void {\n if (handle.done) return;\n handle.done = true;\n if (outcome.type === \"resolve\") {\n handle.resolveOutput(handle.latestValues);\n } else {\n handle.rejectOutput(outcome.error);\n }\n handle.messages.finalize?.();\n handle.toolCall.finalize?.();\n handle.nested.finalize?.();\n }\n\n return {\n __native: true as const,\n\n init: () => ({ subagents: subagentsLog }),\n\n process(event: ProtocolEvent): boolean {\n const ns = event.params.namespace;\n const data = event.params.data;\n const isTaskResult =\n event.method === \"tasks\" && isRecord(data) && \"result\" in data;\n\n // Track the tool currently executing at each namespace. A subagent's\n // dispatching tool starts at the same namespace the subagent roots\n // under, so this records the cause before the subagent is discovered.\n if (\n event.method === \"tools\" &&\n isRecord(data) &&\n data.event === \"tool-started\" &&\n typeof data.tool_call_id === \"string\" &&\n data.tool_call_id.length > 0\n ) {\n activeToolCallByNs.set(nsKey(ns), data.tool_call_id);\n }\n\n // A task start: record identity / tool call, then discover a subagent\n // boundary *before* fanning out so the new handle receives its own\n // subtree events (which Pregel emits after the parent-namespace task).\n if (event.method === \"tasks\" && !isTaskResult) {\n recordIdentity(ns, data);\n recordPendingToolCalls(data);\n maybeStartSubagent(ns);\n }\n\n // Fan the event out to every active subagent whose subtree contains it.\n // The per-subagent transformers self-filter by namespace depth.\n for (const handle of handles.values()) {\n if (handle.done) continue;\n if (!hasPrefix(ns, handle.path)) continue;\n\n handle.messages.process(event);\n handle.toolCall.process(event);\n handle.nested.process(event);\n\n // Track the subagent's own (root-level) state and resolve its\n // `output` from the last snapshot when its lifecycle completes.\n if (nsKey(ns) === handle.key) {\n if (event.method === \"values\" && isRecord(data)) {\n handle.latestValues = data;\n } else if (event.method === \"lifecycle\" && isRecord(data)) {\n const status = data.event;\n if (status === \"completed\" || status === \"interrupted\") {\n finishHandle(handle, { type: \"resolve\" });\n } else if (status === \"failed\") {\n finishHandle(handle, {\n type: \"reject\",\n error: new Error(`Subagent ${handle.name} failed`),\n });\n }\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"resolve\" });\n }\n subagentsLog.close();\n },\n\n fail(err: unknown): void {\n for (const handle of handles.values()) {\n finishHandle(handle, { type: \"reject\", error: err });\n }\n subagentsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- require("../../_virtual/_rolldown/runtime.cjs");
2
1
  let _langchain_core_messages = require("@langchain/core/messages");
3
2
  let _langchain_langgraph = require("@langchain/langgraph");
4
3
  //#region src/agents/transformers/tool-call.ts
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call.cjs","names":["ToolMessage","StreamChannel"],"sources":["../../../src/agents/transformers/tool-call.ts"],"sourcesContent":["import {\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\n/**\n * Detects when a `tool-error` payload is actually a graph interrupt rather\n * than a genuine tool failure.\n *\n * A tool that calls `interrupt()` throws a `GraphInterrupt`, whose message is\n * the JSON-serialized `Interrupt[]` array. Each entry has the LangGraph\n * `Interrupt` shape `{ id, value }`: a stable `id` (a hash of the checkpoint\n * namespace, generated by `interrupt()` and always present during graph\n * execution) plus the `value` passed to `interrupt(...)`. We require BOTH a\n * string `id` and a `value` on every entry — a bare `value` is not a reliable\n * discriminator, since a genuine tool error message can also be a JSON array\n * of `{ value }` records (e.g. a validator emitting\n * `[{ \"value\": \"bad input\", \"message\": \"invalid\" }]`). Keying off the\n * interrupt `id` keeps real tool failures on the error path.\n *\n * An interrupt is control flow that *suspends* the run (the tool re-runs on\n * resume); it is not an error, so the tool call must stay pending rather than\n * have its `output` promise rejected. Any interrupt qualifies regardless of\n * its `value` shape: HITL middleware interrupts (`value.type === \"tool\"`) and\n * raw `interrupt(...)` calls from inside a tool are treated identically —\n * raising an interrupt in a tool must work whether or not\n * `humanInTheLoopMiddleware` is involved.\n */\nfunction isToolInterrupt(message: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return false;\n }\n if (!Array.isArray(parsed) || parsed.length === 0) return false;\n return parsed.every((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const record = entry as Record<string, unknown>;\n return typeof record.id === \"string\" && \"value\" in record;\n });\n}\n\n/**\n * Detects serialized LangChain `ToolMessage` values that can appear on\n * `tool-finished.output` after crossing a protocol or serialization boundary.\n *\n * @example\n * ```ts\n * {\n * lc: 1,\n * type: \"constructor\",\n * id: [\"langchain_core\", \"messages\", \"ToolMessage\"],\n * kwargs: { content: \"raw tool result\", tool_call_id: \"call_1\" }\n * }\n * ```\n */\nfunction isSerializedToolMessage(\n value: unknown\n): value is { kwargs?: { content?: unknown } } {\n if (value == null || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type !== \"constructor\" || !Array.isArray(record.id)) return false;\n return record.id[record.id.length - 1] === \"ToolMessage\";\n}\n\nfunction normalizeToolOutput(output: unknown): unknown {\n if (ToolMessage.isInstance(output)) {\n return output.content;\n }\n if (isSerializedToolMessage(output)) {\n return output.kwargs?.content;\n }\n return output;\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput(\n normalizeToolOutput((data as Record<string, unknown>).output)\n );\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n // An interrupt raised inside a tool (HITL middleware *or* a\n // raw `interrupt()`) surfaces here as a `tool-error` whose\n // message is the serialized interrupt. It is control flow,\n // not a failure: keep the call pending (it re-runs on resume)\n // and never reject `output`, which would otherwise become an\n // unhandled rejection and crash the run.\n if (isToolInterrupt(message)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool-call.cjs","names":["ToolMessage","StreamChannel"],"sources":["../../../src/agents/transformers/tool-call.ts"],"sourcesContent":["import {\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\n/**\n * Detects when a `tool-error` payload is actually a graph interrupt rather\n * than a genuine tool failure.\n *\n * A tool that calls `interrupt()` throws a `GraphInterrupt`, whose message is\n * the JSON-serialized `Interrupt[]` array. Each entry has the LangGraph\n * `Interrupt` shape `{ id, value }`: a stable `id` (a hash of the checkpoint\n * namespace, generated by `interrupt()` and always present during graph\n * execution) plus the `value` passed to `interrupt(...)`. We require BOTH a\n * string `id` and a `value` on every entry — a bare `value` is not a reliable\n * discriminator, since a genuine tool error message can also be a JSON array\n * of `{ value }` records (e.g. a validator emitting\n * `[{ \"value\": \"bad input\", \"message\": \"invalid\" }]`). Keying off the\n * interrupt `id` keeps real tool failures on the error path.\n *\n * An interrupt is control flow that *suspends* the run (the tool re-runs on\n * resume); it is not an error, so the tool call must stay pending rather than\n * have its `output` promise rejected. Any interrupt qualifies regardless of\n * its `value` shape: HITL middleware interrupts (`value.type === \"tool\"`) and\n * raw `interrupt(...)` calls from inside a tool are treated identically —\n * raising an interrupt in a tool must work whether or not\n * `humanInTheLoopMiddleware` is involved.\n */\nfunction isToolInterrupt(message: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return false;\n }\n if (!Array.isArray(parsed) || parsed.length === 0) return false;\n return parsed.every((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const record = entry as Record<string, unknown>;\n return typeof record.id === \"string\" && \"value\" in record;\n });\n}\n\n/**\n * Detects serialized LangChain `ToolMessage` values that can appear on\n * `tool-finished.output` after crossing a protocol or serialization boundary.\n *\n * @example\n * ```ts\n * {\n * lc: 1,\n * type: \"constructor\",\n * id: [\"langchain_core\", \"messages\", \"ToolMessage\"],\n * kwargs: { content: \"raw tool result\", tool_call_id: \"call_1\" }\n * }\n * ```\n */\nfunction isSerializedToolMessage(\n value: unknown\n): value is { kwargs?: { content?: unknown } } {\n if (value == null || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type !== \"constructor\" || !Array.isArray(record.id)) return false;\n return record.id[record.id.length - 1] === \"ToolMessage\";\n}\n\nfunction normalizeToolOutput(output: unknown): unknown {\n if (ToolMessage.isInstance(output)) {\n return output.content;\n }\n if (isSerializedToolMessage(output)) {\n return output.kwargs?.content;\n }\n return output;\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput(\n normalizeToolOutput((data as Record<string, unknown>).output)\n );\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n // An interrupt raised inside a tool (HITL middleware *or* a\n // raw `interrupt()`) surfaces here as a `tool-error` whose\n // message is the serialized interrupt. It is control flow,\n // not a failure: keep the call pending (it re-runs on resume)\n // and never reject `output`, which would otherwise become an\n // unhandled rejection and crash the run.\n if (isToolInterrupt(message)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Namespace, NativeStreamTransformer, ToolCallStream } from "@langchain/langgraph";
2
-
3
2
  //#region src/agents/transformers/tool-call.d.ts
4
3
  interface ToolCallProjection {
5
4
  toolCalls: AsyncIterable<ToolCallStream>;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call.d.cts","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"mappings":";;;UAWU,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,cAAA;AAAA;;;;;;;;iBAkGX,yBAAA,CACd,IAAA,EAAM,SAAA,SACC,uBAAA,CAAwB,kBAAA"}
1
+ {"version":3,"file":"tool-call.d.cts","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"mappings":";;UAWU;EACR,WAAW,cAAc;;;;;;;;;iBAkGX,0BACd,MAAM,kBACC,wBAAwB"}
@@ -1,5 +1,4 @@
1
1
  import { Namespace, NativeStreamTransformer, ToolCallStream } from "@langchain/langgraph";
2
-
3
2
  //#region src/agents/transformers/tool-call.d.ts
4
3
  interface ToolCallProjection {
5
4
  toolCalls: AsyncIterable<ToolCallStream>;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call.d.ts","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"mappings":";;;UAWU,kBAAA;EACR,SAAA,EAAW,aAAA,CAAc,cAAA;AAAA;;;;;;;;iBAkGX,yBAAA,CACd,IAAA,EAAM,SAAA,SACC,uBAAA,CAAwB,kBAAA"}
1
+ {"version":3,"file":"tool-call.d.ts","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"mappings":";;UAWU;EACR,WAAW,cAAc;;;;;;;;;iBAkGX,0BACd,MAAM,kBACC,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call.js","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"sourcesContent":["import {\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\n/**\n * Detects when a `tool-error` payload is actually a graph interrupt rather\n * than a genuine tool failure.\n *\n * A tool that calls `interrupt()` throws a `GraphInterrupt`, whose message is\n * the JSON-serialized `Interrupt[]` array. Each entry has the LangGraph\n * `Interrupt` shape `{ id, value }`: a stable `id` (a hash of the checkpoint\n * namespace, generated by `interrupt()` and always present during graph\n * execution) plus the `value` passed to `interrupt(...)`. We require BOTH a\n * string `id` and a `value` on every entry — a bare `value` is not a reliable\n * discriminator, since a genuine tool error message can also be a JSON array\n * of `{ value }` records (e.g. a validator emitting\n * `[{ \"value\": \"bad input\", \"message\": \"invalid\" }]`). Keying off the\n * interrupt `id` keeps real tool failures on the error path.\n *\n * An interrupt is control flow that *suspends* the run (the tool re-runs on\n * resume); it is not an error, so the tool call must stay pending rather than\n * have its `output` promise rejected. Any interrupt qualifies regardless of\n * its `value` shape: HITL middleware interrupts (`value.type === \"tool\"`) and\n * raw `interrupt(...)` calls from inside a tool are treated identically —\n * raising an interrupt in a tool must work whether or not\n * `humanInTheLoopMiddleware` is involved.\n */\nfunction isToolInterrupt(message: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return false;\n }\n if (!Array.isArray(parsed) || parsed.length === 0) return false;\n return parsed.every((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const record = entry as Record<string, unknown>;\n return typeof record.id === \"string\" && \"value\" in record;\n });\n}\n\n/**\n * Detects serialized LangChain `ToolMessage` values that can appear on\n * `tool-finished.output` after crossing a protocol or serialization boundary.\n *\n * @example\n * ```ts\n * {\n * lc: 1,\n * type: \"constructor\",\n * id: [\"langchain_core\", \"messages\", \"ToolMessage\"],\n * kwargs: { content: \"raw tool result\", tool_call_id: \"call_1\" }\n * }\n * ```\n */\nfunction isSerializedToolMessage(\n value: unknown\n): value is { kwargs?: { content?: unknown } } {\n if (value == null || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type !== \"constructor\" || !Array.isArray(record.id)) return false;\n return record.id[record.id.length - 1] === \"ToolMessage\";\n}\n\nfunction normalizeToolOutput(output: unknown): unknown {\n if (ToolMessage.isInstance(output)) {\n return output.content;\n }\n if (isSerializedToolMessage(output)) {\n return output.kwargs?.content;\n }\n return output;\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput(\n normalizeToolOutput((data as Record<string, unknown>).output)\n );\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n // An interrupt raised inside a tool (HITL middleware *or* a\n // raw `interrupt()`) surfaces here as a `tool-error` whose\n // message is the serialized interrupt. It is control flow,\n // not a failure: keep the call pending (it re-runs on resume)\n // and never reject `output`, which would otherwise become an\n // unhandled rejection and crash the run.\n if (isToolInterrupt(message)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool-call.js","names":[],"sources":["../../../src/agents/transformers/tool-call.ts"],"sourcesContent":["import {\n StreamChannel,\n type NativeStreamTransformer,\n type ProtocolEvent,\n type ToolCallStream,\n type ToolCallStatus,\n type ToolsEventData,\n type Namespace,\n} from \"@langchain/langgraph\";\nimport { ToolMessage } from \"@langchain/core/messages\";\n\ninterface ToolCallProjection {\n toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n if (ns.length < path.length || ns.length > path.length + 1) return false;\n for (let i = 0; i < path.length; i += 1) {\n if (ns[i] !== path[i]) return false;\n }\n return true;\n}\n\n/**\n * Detects when a `tool-error` payload is actually a graph interrupt rather\n * than a genuine tool failure.\n *\n * A tool that calls `interrupt()` throws a `GraphInterrupt`, whose message is\n * the JSON-serialized `Interrupt[]` array. Each entry has the LangGraph\n * `Interrupt` shape `{ id, value }`: a stable `id` (a hash of the checkpoint\n * namespace, generated by `interrupt()` and always present during graph\n * execution) plus the `value` passed to `interrupt(...)`. We require BOTH a\n * string `id` and a `value` on every entry — a bare `value` is not a reliable\n * discriminator, since a genuine tool error message can also be a JSON array\n * of `{ value }` records (e.g. a validator emitting\n * `[{ \"value\": \"bad input\", \"message\": \"invalid\" }]`). Keying off the\n * interrupt `id` keeps real tool failures on the error path.\n *\n * An interrupt is control flow that *suspends* the run (the tool re-runs on\n * resume); it is not an error, so the tool call must stay pending rather than\n * have its `output` promise rejected. Any interrupt qualifies regardless of\n * its `value` shape: HITL middleware interrupts (`value.type === \"tool\"`) and\n * raw `interrupt(...)` calls from inside a tool are treated identically —\n * raising an interrupt in a tool must work whether or not\n * `humanInTheLoopMiddleware` is involved.\n */\nfunction isToolInterrupt(message: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(message);\n } catch {\n return false;\n }\n if (!Array.isArray(parsed) || parsed.length === 0) return false;\n return parsed.every((entry) => {\n if (entry == null || typeof entry !== \"object\") return false;\n const record = entry as Record<string, unknown>;\n return typeof record.id === \"string\" && \"value\" in record;\n });\n}\n\n/**\n * Detects serialized LangChain `ToolMessage` values that can appear on\n * `tool-finished.output` after crossing a protocol or serialization boundary.\n *\n * @example\n * ```ts\n * {\n * lc: 1,\n * type: \"constructor\",\n * id: [\"langchain_core\", \"messages\", \"ToolMessage\"],\n * kwargs: { content: \"raw tool result\", tool_call_id: \"call_1\" }\n * }\n * ```\n */\nfunction isSerializedToolMessage(\n value: unknown\n): value is { kwargs?: { content?: unknown } } {\n if (value == null || typeof value !== \"object\") return false;\n const record = value as Record<string, unknown>;\n if (record.type !== \"constructor\" || !Array.isArray(record.id)) return false;\n return record.id[record.id.length - 1] === \"ToolMessage\";\n}\n\nfunction normalizeToolOutput(output: unknown): unknown {\n if (ToolMessage.isInstance(output)) {\n return output.content;\n }\n if (isSerializedToolMessage(output)) {\n return output.kwargs?.content;\n }\n return output;\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n return () => {\n const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n const pendingCalls = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n resolveStatus: (v: ToolCallStatus) => void;\n resolveError: (v: string | undefined) => void;\n }\n >();\n\n function createToolCallEntry(\n callId: string,\n name: string,\n rawInput: unknown\n ): void {\n if (pendingCalls.has(callId)) return;\n const input =\n typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n let resolveStatus!: (v: ToolCallStatus) => void;\n let resolveError!: (v: string | undefined) => void;\n\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n const status = new Promise<ToolCallStatus>((res) => {\n resolveStatus = res;\n });\n const error = new Promise<string | undefined>((res) => {\n resolveError = res;\n });\n\n pendingCalls.set(callId, {\n resolveOutput,\n rejectOutput,\n resolveStatus,\n resolveError,\n });\n\n toolCallsLog.push({\n name,\n callId,\n input,\n output,\n status,\n error,\n } as ToolCallStream);\n }\n\n return {\n __native: true as const,\n\n init: () => ({\n toolCalls: toolCallsLog,\n }),\n\n process(event: ProtocolEvent): boolean {\n /**\n * Only process events that are at the same depth as the agent's graph.\n */\n if (!isOwnEvent(event.params.namespace, path)) return true;\n\n if (event.method === \"messages\") {\n const data = event.params.data as Record<string, unknown>;\n if (data.event === \"content-block-finish\") {\n const cb = (data.contentBlock ?? data.content_block) as\n | Record<string, unknown>\n | undefined;\n if (cb?.type === \"tool_call\") {\n createToolCallEntry(\n String(cb.id ?? \"\"),\n String(cb.name ?? \"\"),\n cb.args ?? cb.input\n );\n }\n }\n }\n\n if (event.method === \"tools\") {\n const data = event.params.data as ToolsEventData;\n const toolCallId = (data as Record<string, unknown>)\n .tool_call_id as string;\n\n if (data.event === \"tool-started\") {\n createToolCallEntry(\n toolCallId,\n ((data as Record<string, unknown>).tool_name as string) ??\n \"unknown\",\n (data as Record<string, unknown>).input\n );\n }\n\n const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput(\n normalizeToolOutput((data as Record<string, unknown>).output)\n );\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pendingCalls.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n // An interrupt raised inside a tool (HITL middleware *or* a\n // raw `interrupt()`) surfaces here as a `tool-error` whose\n // message is the serialized interrupt. It is control flow,\n // not a failure: keep the call pending (it re-runs on resume)\n // and never reject `output`, which would otherwise become an\n // unhandled rejection and crash the run.\n if (isToolInterrupt(message)) {\n return true;\n }\n pending.rejectOutput(new Error(message));\n pending.resolveStatus(\"error\");\n pending.resolveError(message);\n pendingCalls.delete(toolCallId);\n }\n }\n }\n\n return true;\n },\n\n finalize(): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"finished\");\n pending.resolveError(undefined);\n pending.resolveOutput(undefined);\n }\n pendingCalls.clear();\n toolCallsLog.close();\n },\n\n fail(err: unknown): void {\n for (const pending of pendingCalls.values()) {\n pending.resolveStatus(\"error\");\n pending.resolveError(\n err instanceof Error ? err.message : String(err)\n );\n pending.rejectOutput(err);\n }\n pendingCalls.clear();\n toolCallsLog.fail(err);\n },\n };\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { ClientTool, DynamicStructuredTool, ServerTool, StructuredToolInterface } from "@langchain/core/tools";
2
2
  import { ChatModelStream, GraphRunStream, LifecycleCause, StreamTransformer, ToolCallStream } from "@langchain/langgraph";
3
-
4
3
  //#region src/agents/transformers/types.d.ts
5
4
  /**
6
5
  * Infers the merged extensions shape from a tuple of stream transformer
@@ -26,7 +25,7 @@ type ToolOutputOf<T> = T extends DynamicStructuredTool<any, any, any, infer Tool
26
25
  * Falls back to `ToolCallStream` (untyped) when the tools tuple is a
27
26
  * plain `(ClientTool | ServerTool)[]` without literal name types.
28
27
  */
29
- type ToolCallStreamUnion<TTools extends readonly (ClientTool | ServerTool)[]> = { [K in keyof TTools]: ToolCallStream<ToolNameOf<TTools[K]>, ToolInputOf<TTools[K]>, ToolOutputOf<TTools[K]>> }[number];
28
+ type ToolCallStreamUnion<TTools extends readonly (ClientTool | ServerTool)[]> = { [K in keyof TTools]: ToolCallStream<ToolNameOf<TTools[K]>, ToolInputOf<TTools[K]>, ToolOutputOf<TTools[K]>>; }[number];
30
29
  /**
31
30
  * A nested named-agent execution surfaced on `run.subagents`.
32
31
  *
@@ -79,7 +78,8 @@ interface SubagentRunStream<TValues = Record<string, unknown>, TTools extends re
79
78
  * `InferStreamExtensions<TStreamTransformers>`.
80
79
  */
81
80
  type AgentRunStream<TValues = Record<string, unknown>, TTools extends readonly (ClientTool | ServerTool)[] = readonly (ClientTool | ServerTool)[], TExtensions extends Record<string, unknown> = Record<string, unknown>> = GraphRunStream<TValues, TExtensions> & {
82
- /** Tool call streams from the native ToolCallTransformer. */toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
81
+ /** Tool call streams from the native ToolCallTransformer. */
82
+ toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;
83
83
  /**
84
84
  * Named subagent runs dispatched from tools, surfaced by the native
85
85
  * {@link createSubagentTransformer}. Each yielded {@link SubagentRunStream}
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/agents/transformers/types.ts"],"mappings":";;;;;;AAuBA;;;;;KAAY,qBAAA,WACA,aAAA,OAAoB,iBAAA,UAC5B,CAAA,uBACA,MAAA,kBACA,CAAA,yBACU,iBAAA,iCACgB,aAAA,OAAoB,iBAAA,UAE5C,CAAA,GAAI,qBAAA,CAAsB,IAAA,IAC1B,MAAA;;KAGD,UAAA,MAAgB,CAAA;EAAY,IAAA;AAAA,IAAiC,CAAA;;KAG7D,WAAA,MACH,CAAA,SAAU,qBAAA,gDACN,YAAA,GACA,CAAA,SAAU,uBAAA,iCACR,YAAA;;KAIH,YAAA,MACH,CAAA,SAAU,qBAAA,+CACN,WAAA,GACA,CAAA,SAAU,uBAAA,gCACR,WAAA;;;;;;;;;KAWI,mBAAA,0BACe,UAAA,GAAa,UAAA,qBAE1B,MAAA,GAAS,cAAA,CACnB,UAAA,CAAW,MAAA,CAAO,CAAA,IAClB,WAAA,CAAY,MAAA,CAAO,CAAA,IACnB,YAAA,CAAa,MAAA,CAAO,CAAA;;;;;;;AAnCM;;;;;;;;;;;UAwDb,iBAAA,WACL,MAAA,4CACe,UAAA,GAAa,UAAA,gBAClC,UAAA,GACA,UAAA;EAtDU;EAAA,SA0DL,IAAA;EAzDT;;;;;EAAA,SAgES,KAAA,EAAO,cAAA;EAjED;EAAA,SAoEN,MAAA,EAAQ,OAAA,CAAQ,OAAA;EAnEf;EAAA,SAsED,QAAA,EAAU,aAAA,CAAc,IAAA,CAAK,eAAA;EArElC;EAAA,SAwEK,SAAA,EAAW,aAAA,CAAc,mBAAA,CAAoB,MAAA;EAvExC;EAAA,SA0EL,SAAA,EAAW,aAAA,CAAc,iBAAA;AAAA;;;AAzEhB;;;;;;;;;;;;;;KA4FR,cAAA,WACA,MAAA,4CACe,UAAA,GAAa,UAAA,gBAClC,UAAA,GACA,UAAA,yBAEgB,MAAA,oBAA0B,MAAA,qBAC5C,cAAA,CAAe,OAAA,EAAS,WAAA;EA5FZ,6DA8Fd,SAAA,EAAW,aAAA,CAAc,mBAAA,CAAoB,MAAA;EA7FvC;;;AAWR;;;;;EA4FE,SAAA,EAAW,aAAA,CAAc,iBAAA,CAAkB,OAAA;AAAA"}
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/agents/transformers/types.ts"],"mappings":";;;;;;;;;;KAuBY,sBACV,UAAU,oBAAoB,2BAC5B,wBACA,wBACA,0BACU,wBAAwB,aACrB,aAAa,oBAAoB,2BAE5C,IAAI,sBAAsB,QAC1B;;KAGD,WAAW,KAAK;EAAY,YAAY;IAAqB;;KAG7D,YAAY,KACf,UAAU,sCAAsC,+BAC5C,eACA,UAAU,mCAAmC,qBAC3C;;KAIH,aAAa,KAChB,UAAU,2CAA2C,yBACjD,cACA,UAAU,wCAAwC,eAChD;;;;;;;;;KAWI,oBACV,yBAAyB,aAAa,oBAErC,WAAW,SAAS,eACnB,WAAW,OAAO,KAClB,YAAY,OAAO,KACnB,aAAa,OAAO;;;;;;;;;;;;;;;;;;UAqBP,kBACf,UAAU,yBACV,yBAAyB,aAAa,0BAClC,aACA;;WAIK;;;;;;WAOA,OAAO;;WAGP,QAAQ,QAAQ;;WAGhB,UAAU,cAAc,KAAK;;WAG7B,WAAW,cAAc,oBAAoB;;WAG7C,WAAW,cAAc;;;;;;;;;;;;;;;;;;KAmBxB,eACV,UAAU,yBACV,yBAAyB,aAAa,0BAClC,aACA,eAEJ,oBAAoB,0BAA0B,2BAC5C,eAAe,SAAS;;EAE1B,WAAW,cAAc,oBAAoB;;;;;;;;;EAU7C,WAAW,cAAc,kBAAkB"}