@langchain/langgraph-sdk 1.8.10 → 1.9.0

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 (435) hide show
  1. package/README.md +90 -43
  2. package/dist/client/assistants/index.cjs +180 -0
  3. package/dist/client/assistants/index.cjs.map +1 -0
  4. package/dist/client/assistants/index.d.cts +155 -0
  5. package/dist/client/assistants/index.d.cts.map +1 -0
  6. package/dist/client/assistants/index.d.ts +155 -0
  7. package/dist/client/assistants/index.d.ts.map +1 -0
  8. package/dist/client/assistants/index.js +180 -0
  9. package/dist/client/assistants/index.js.map +1 -0
  10. package/dist/client/base.cjs +190 -0
  11. package/dist/client/base.cjs.map +1 -0
  12. package/dist/client/base.d.cts +84 -0
  13. package/dist/client/base.d.cts.map +1 -0
  14. package/dist/client/base.d.ts +84 -0
  15. package/dist/client/base.d.ts.map +1 -0
  16. package/dist/client/base.js +188 -0
  17. package/dist/client/base.js.map +1 -0
  18. package/dist/client/crons/index.cjs +159 -0
  19. package/dist/client/crons/index.cjs.map +1 -0
  20. package/dist/client/crons/index.d.cts +71 -0
  21. package/dist/client/crons/index.d.cts.map +1 -0
  22. package/dist/client/crons/index.d.ts +71 -0
  23. package/dist/client/crons/index.d.ts.map +1 -0
  24. package/dist/client/crons/index.js +159 -0
  25. package/dist/client/crons/index.js.map +1 -0
  26. package/dist/client/index.cjs +84 -0
  27. package/dist/client/index.cjs.map +1 -0
  28. package/dist/client/index.d.cts +63 -0
  29. package/dist/client/index.d.cts.map +1 -0
  30. package/dist/client/index.d.ts +63 -0
  31. package/dist/client/index.d.ts.map +1 -0
  32. package/dist/client/index.js +83 -0
  33. package/dist/client/index.js.map +1 -0
  34. package/dist/client/runs/index.cjs +275 -0
  35. package/dist/client/runs/index.cjs.map +1 -0
  36. package/dist/client/runs/index.d.cts +123 -0
  37. package/dist/client/runs/index.d.cts.map +1 -0
  38. package/dist/client/runs/index.d.ts +123 -0
  39. package/dist/client/runs/index.d.ts.map +1 -0
  40. package/dist/client/runs/index.js +275 -0
  41. package/dist/client/runs/index.js.map +1 -0
  42. package/dist/client/store/index.cjs +128 -0
  43. package/dist/client/store/index.cjs.map +1 -0
  44. package/dist/client/store/index.d.cts +75 -0
  45. package/dist/client/store/index.d.cts.map +1 -0
  46. package/dist/client/store/index.d.ts +75 -0
  47. package/dist/client/store/index.d.ts.map +1 -0
  48. package/dist/client/store/index.js +128 -0
  49. package/dist/client/store/index.js.map +1 -0
  50. package/dist/client/stream/error.cjs +18 -0
  51. package/dist/client/stream/error.cjs.map +1 -0
  52. package/dist/client/stream/error.d.cts +14 -0
  53. package/dist/client/stream/error.d.cts.map +1 -0
  54. package/dist/client/stream/error.d.ts +14 -0
  55. package/dist/client/stream/error.d.ts.map +1 -0
  56. package/dist/client/stream/error.js +18 -0
  57. package/dist/client/stream/error.js.map +1 -0
  58. package/dist/client/stream/handles/index.cjs +3 -0
  59. package/dist/client/stream/handles/index.d.ts +3 -0
  60. package/dist/client/stream/handles/index.js +4 -0
  61. package/dist/client/stream/handles/subagents.cjs +263 -0
  62. package/dist/client/stream/handles/subagents.cjs.map +1 -0
  63. package/dist/client/stream/handles/subagents.d.cts +45 -0
  64. package/dist/client/stream/handles/subagents.d.cts.map +1 -0
  65. package/dist/client/stream/handles/subagents.d.ts +45 -0
  66. package/dist/client/stream/handles/subagents.d.ts.map +1 -0
  67. package/dist/client/stream/handles/subagents.js +262 -0
  68. package/dist/client/stream/handles/subagents.js.map +1 -0
  69. package/dist/client/stream/handles/subgraphs.cjs +352 -0
  70. package/dist/client/stream/handles/subgraphs.cjs.map +1 -0
  71. package/dist/client/stream/handles/subgraphs.d.cts +82 -0
  72. package/dist/client/stream/handles/subgraphs.d.cts.map +1 -0
  73. package/dist/client/stream/handles/subgraphs.d.ts +82 -0
  74. package/dist/client/stream/handles/subgraphs.d.ts.map +1 -0
  75. package/dist/client/stream/handles/subgraphs.js +351 -0
  76. package/dist/client/stream/handles/subgraphs.js.map +1 -0
  77. package/dist/client/stream/handles/tools.cjs +92 -0
  78. package/dist/client/stream/handles/tools.cjs.map +1 -0
  79. package/dist/client/stream/handles/tools.d.cts +26 -0
  80. package/dist/client/stream/handles/tools.d.cts.map +1 -0
  81. package/dist/client/stream/handles/tools.d.ts +26 -0
  82. package/dist/client/stream/handles/tools.d.ts.map +1 -0
  83. package/dist/client/stream/handles/tools.js +92 -0
  84. package/dist/client/stream/handles/tools.js.map +1 -0
  85. package/dist/client/stream/index.cjs +1368 -0
  86. package/dist/client/stream/index.cjs.map +1 -0
  87. package/dist/client/stream/index.d.cts +238 -0
  88. package/dist/client/stream/index.d.cts.map +1 -0
  89. package/dist/client/stream/index.d.ts +238 -0
  90. package/dist/client/stream/index.d.ts.map +1 -0
  91. package/dist/client/stream/index.js +1367 -0
  92. package/dist/client/stream/index.js.map +1 -0
  93. package/dist/client/stream/media.cjs +506 -0
  94. package/dist/client/stream/media.cjs.map +1 -0
  95. package/dist/client/stream/media.d.cts +164 -0
  96. package/dist/client/stream/media.d.cts.map +1 -0
  97. package/dist/client/stream/media.d.ts +164 -0
  98. package/dist/client/stream/media.d.ts.map +1 -0
  99. package/dist/client/stream/media.js +505 -0
  100. package/dist/client/stream/media.js.map +1 -0
  101. package/dist/client/stream/messages.cjs +635 -0
  102. package/dist/client/stream/messages.cjs.map +1 -0
  103. package/dist/client/stream/messages.d.cts +139 -0
  104. package/dist/client/stream/messages.d.cts.map +1 -0
  105. package/dist/client/stream/messages.d.ts +139 -0
  106. package/dist/client/stream/messages.d.ts.map +1 -0
  107. package/dist/client/stream/messages.js +631 -0
  108. package/dist/client/stream/messages.js.map +1 -0
  109. package/dist/client/stream/multi-cursor-buffer.cjs +55 -0
  110. package/dist/client/stream/multi-cursor-buffer.cjs.map +1 -0
  111. package/dist/client/stream/multi-cursor-buffer.js +55 -0
  112. package/dist/client/stream/multi-cursor-buffer.js.map +1 -0
  113. package/dist/client/stream/subscription.cjs +85 -0
  114. package/dist/client/stream/subscription.cjs.map +1 -0
  115. package/dist/client/stream/subscription.d.cts +22 -0
  116. package/dist/client/stream/subscription.d.cts.map +1 -0
  117. package/dist/client/stream/subscription.d.ts +22 -0
  118. package/dist/client/stream/subscription.d.ts.map +1 -0
  119. package/dist/client/stream/subscription.js +84 -0
  120. package/dist/client/stream/subscription.js.map +1 -0
  121. package/dist/client/stream/transport/agent-server.cjs +45 -0
  122. package/dist/client/stream/transport/agent-server.cjs.map +1 -0
  123. package/dist/client/stream/transport/agent-server.d.cts +39 -0
  124. package/dist/client/stream/transport/agent-server.d.cts.map +1 -0
  125. package/dist/client/stream/transport/agent-server.d.ts +39 -0
  126. package/dist/client/stream/transport/agent-server.d.ts.map +1 -0
  127. package/dist/client/stream/transport/agent-server.js +45 -0
  128. package/dist/client/stream/transport/agent-server.js.map +1 -0
  129. package/dist/client/stream/transport/constants.cjs +10 -0
  130. package/dist/client/stream/transport/constants.cjs.map +1 -0
  131. package/dist/client/stream/transport/constants.js +10 -0
  132. package/dist/client/stream/transport/constants.js.map +1 -0
  133. package/dist/client/stream/transport/decoder.cjs +115 -0
  134. package/dist/client/stream/transport/decoder.cjs.map +1 -0
  135. package/dist/client/stream/transport/decoder.js +114 -0
  136. package/dist/client/stream/transport/decoder.js.map +1 -0
  137. package/dist/client/stream/transport/http.cjs +183 -0
  138. package/dist/client/stream/transport/http.cjs.map +1 -0
  139. package/dist/client/stream/transport/http.d.cts +45 -0
  140. package/dist/client/stream/transport/http.d.cts.map +1 -0
  141. package/dist/client/stream/transport/http.d.ts +45 -0
  142. package/dist/client/stream/transport/http.d.ts.map +1 -0
  143. package/dist/client/stream/transport/http.js +183 -0
  144. package/dist/client/stream/transport/http.js.map +1 -0
  145. package/dist/client/stream/transport/index.cjs +3 -0
  146. package/dist/client/stream/transport/index.js +4 -0
  147. package/dist/client/stream/transport/queue.cjs +55 -0
  148. package/dist/client/stream/transport/queue.cjs.map +1 -0
  149. package/dist/client/stream/transport/queue.js +55 -0
  150. package/dist/client/stream/transport/queue.js.map +1 -0
  151. package/dist/client/stream/transport/stream.cjs +79 -0
  152. package/dist/client/stream/transport/stream.cjs.map +1 -0
  153. package/dist/client/stream/transport/stream.js +79 -0
  154. package/dist/client/stream/transport/stream.js.map +1 -0
  155. package/dist/client/stream/transport/types.d.cts +29 -0
  156. package/dist/client/stream/transport/types.d.cts.map +1 -0
  157. package/dist/client/stream/transport/types.d.ts +29 -0
  158. package/dist/client/stream/transport/types.d.ts.map +1 -0
  159. package/dist/client/stream/transport/utils.cjs +45 -0
  160. package/dist/client/stream/transport/utils.cjs.map +1 -0
  161. package/dist/client/stream/transport/utils.js +39 -0
  162. package/dist/client/stream/transport/utils.js.map +1 -0
  163. package/dist/client/stream/transport/websocket.cjs +155 -0
  164. package/dist/client/stream/transport/websocket.cjs.map +1 -0
  165. package/dist/client/stream/transport/websocket.d.cts +36 -0
  166. package/dist/client/stream/transport/websocket.d.cts.map +1 -0
  167. package/dist/client/stream/transport/websocket.d.ts +36 -0
  168. package/dist/client/stream/transport/websocket.d.ts.map +1 -0
  169. package/dist/client/stream/transport/websocket.js +155 -0
  170. package/dist/client/stream/transport/websocket.js.map +1 -0
  171. package/dist/client/stream/transport.d.cts +104 -0
  172. package/dist/client/stream/transport.d.cts.map +1 -0
  173. package/dist/client/stream/transport.d.ts +104 -0
  174. package/dist/client/stream/transport.d.ts.map +1 -0
  175. package/dist/client/stream/types.d.cts +208 -0
  176. package/dist/client/stream/types.d.cts.map +1 -0
  177. package/dist/client/stream/types.d.ts +208 -0
  178. package/dist/client/stream/types.d.ts.map +1 -0
  179. package/dist/client/threads/index.cjs +271 -0
  180. package/dist/client/threads/index.cjs.map +1 -0
  181. package/dist/client/threads/index.d.cts +235 -0
  182. package/dist/client/threads/index.d.cts.map +1 -0
  183. package/dist/client/threads/index.d.ts +235 -0
  184. package/dist/client/threads/index.d.ts.map +1 -0
  185. package/dist/client/threads/index.js +270 -0
  186. package/dist/client/threads/index.js.map +1 -0
  187. package/dist/client/ui-internal/index.cjs +29 -0
  188. package/dist/client/ui-internal/index.cjs.map +1 -0
  189. package/dist/client/ui-internal/index.d.cts +11 -0
  190. package/dist/client/ui-internal/index.d.cts.map +1 -0
  191. package/dist/client/ui-internal/index.d.ts +11 -0
  192. package/dist/client/ui-internal/index.d.ts.map +1 -0
  193. package/dist/client/ui-internal/index.js +29 -0
  194. package/dist/client/ui-internal/index.js.map +1 -0
  195. package/dist/client.cjs +35 -1308
  196. package/dist/client.d.cts +19 -857
  197. package/dist/client.d.ts +19 -857
  198. package/dist/client.js +16 -1301
  199. package/dist/index.cjs +25 -4
  200. package/dist/index.d.cts +15 -3
  201. package/dist/index.d.ts +15 -3
  202. package/dist/index.js +14 -3
  203. package/dist/react/stream.cjs.map +1 -1
  204. package/dist/react/stream.custom.cjs +1 -1
  205. package/dist/react/stream.custom.js +1 -1
  206. package/dist/react/stream.d.cts +2 -1
  207. package/dist/react/stream.d.cts.map +1 -1
  208. package/dist/react/stream.d.ts +2 -1
  209. package/dist/react/stream.d.ts.map +1 -1
  210. package/dist/react/stream.js.map +1 -1
  211. package/dist/react/stream.lgp.cjs +6 -5
  212. package/dist/react/stream.lgp.cjs.map +1 -1
  213. package/dist/react/stream.lgp.js +4 -3
  214. package/dist/react/stream.lgp.js.map +1 -1
  215. package/dist/react/types.d.cts +1 -1
  216. package/dist/react/types.d.ts +1 -1
  217. package/dist/react/types.d.ts.map +1 -1
  218. package/dist/react-ui/server/server.cjs +1 -1
  219. package/dist/react-ui/server/server.cjs.map +1 -1
  220. package/dist/react-ui/server/server.js +1 -1
  221. package/dist/react-ui/server/server.js.map +1 -1
  222. package/dist/react-ui/types.cjs.map +1 -1
  223. package/dist/react-ui/types.d.cts +1 -1
  224. package/dist/react-ui/types.d.cts.map +1 -1
  225. package/dist/react-ui/types.d.ts +1 -1
  226. package/dist/react-ui/types.d.ts.map +1 -1
  227. package/dist/react-ui/types.js.map +1 -1
  228. package/dist/stream/assembled-to-message.cjs +121 -0
  229. package/dist/stream/assembled-to-message.cjs.map +1 -0
  230. package/dist/stream/assembled-to-message.d.cts +35 -0
  231. package/dist/stream/assembled-to-message.d.cts.map +1 -0
  232. package/dist/stream/assembled-to-message.d.ts +35 -0
  233. package/dist/stream/assembled-to-message.d.ts.map +1 -0
  234. package/dist/stream/assembled-to-message.js +119 -0
  235. package/dist/stream/assembled-to-message.js.map +1 -0
  236. package/dist/stream/channel-registry.cjs +224 -0
  237. package/dist/stream/channel-registry.cjs.map +1 -0
  238. package/dist/stream/channel-registry.d.cts +102 -0
  239. package/dist/stream/channel-registry.d.cts.map +1 -0
  240. package/dist/stream/channel-registry.d.ts +102 -0
  241. package/dist/stream/channel-registry.d.ts.map +1 -0
  242. package/dist/stream/channel-registry.js +224 -0
  243. package/dist/stream/channel-registry.js.map +1 -0
  244. package/dist/stream/constants.cjs +11 -0
  245. package/dist/stream/constants.cjs.map +1 -0
  246. package/dist/stream/constants.d.cts +10 -0
  247. package/dist/stream/constants.d.cts.map +1 -0
  248. package/dist/stream/constants.d.ts +10 -0
  249. package/dist/stream/constants.d.ts.map +1 -0
  250. package/dist/stream/constants.js +11 -0
  251. package/dist/stream/constants.js.map +1 -0
  252. package/dist/stream/controller.cjs +933 -0
  253. package/dist/stream/controller.cjs.map +1 -0
  254. package/dist/stream/controller.d.cts +135 -0
  255. package/dist/stream/controller.d.cts.map +1 -0
  256. package/dist/stream/controller.d.ts +135 -0
  257. package/dist/stream/controller.d.ts.map +1 -0
  258. package/dist/stream/controller.js +910 -0
  259. package/dist/stream/controller.js.map +1 -0
  260. package/dist/stream/discovery/index.d.ts +2 -0
  261. package/dist/stream/discovery/subagents.cjs +235 -0
  262. package/dist/stream/discovery/subagents.cjs.map +1 -0
  263. package/dist/stream/discovery/subagents.d.cts +18 -0
  264. package/dist/stream/discovery/subagents.d.cts.map +1 -0
  265. package/dist/stream/discovery/subagents.d.ts +18 -0
  266. package/dist/stream/discovery/subagents.d.ts.map +1 -0
  267. package/dist/stream/discovery/subagents.js +235 -0
  268. package/dist/stream/discovery/subagents.js.map +1 -0
  269. package/dist/stream/discovery/subgraphs.cjs +153 -0
  270. package/dist/stream/discovery/subgraphs.cjs.map +1 -0
  271. package/dist/stream/discovery/subgraphs.d.cts +19 -0
  272. package/dist/stream/discovery/subgraphs.d.cts.map +1 -0
  273. package/dist/stream/discovery/subgraphs.d.ts +19 -0
  274. package/dist/stream/discovery/subgraphs.d.ts.map +1 -0
  275. package/dist/stream/discovery/subgraphs.js +153 -0
  276. package/dist/stream/discovery/subgraphs.js.map +1 -0
  277. package/dist/stream/index.cjs +36 -0
  278. package/dist/stream/index.d.cts +25 -0
  279. package/dist/stream/index.d.ts +25 -0
  280. package/dist/stream/index.js +16 -0
  281. package/dist/stream/lifecycle-loading-tracker.cjs +83 -0
  282. package/dist/stream/lifecycle-loading-tracker.cjs.map +1 -0
  283. package/dist/stream/lifecycle-loading-tracker.js +83 -0
  284. package/dist/stream/lifecycle-loading-tracker.js.map +1 -0
  285. package/dist/stream/message-metadata-tracker.cjs +165 -0
  286. package/dist/stream/message-metadata-tracker.cjs.map +1 -0
  287. package/dist/stream/message-metadata-tracker.d.cts +24 -0
  288. package/dist/stream/message-metadata-tracker.d.cts.map +1 -0
  289. package/dist/stream/message-metadata-tracker.d.ts +24 -0
  290. package/dist/stream/message-metadata-tracker.d.ts.map +1 -0
  291. package/dist/stream/message-metadata-tracker.js +165 -0
  292. package/dist/stream/message-metadata-tracker.js.map +1 -0
  293. package/dist/stream/message-reconciliation.cjs +118 -0
  294. package/dist/stream/message-reconciliation.cjs.map +1 -0
  295. package/dist/stream/message-reconciliation.js +115 -0
  296. package/dist/stream/message-reconciliation.js.map +1 -0
  297. package/dist/stream/namespace.cjs +54 -0
  298. package/dist/stream/namespace.cjs.map +1 -0
  299. package/dist/stream/namespace.js +49 -0
  300. package/dist/stream/namespace.js.map +1 -0
  301. package/dist/stream/projections/channel.cjs +53 -0
  302. package/dist/stream/projections/channel.cjs.map +1 -0
  303. package/dist/stream/projections/channel.d.cts +22 -0
  304. package/dist/stream/projections/channel.d.cts.map +1 -0
  305. package/dist/stream/projections/channel.d.ts +22 -0
  306. package/dist/stream/projections/channel.d.ts.map +1 -0
  307. package/dist/stream/projections/channel.js +53 -0
  308. package/dist/stream/projections/channel.js.map +1 -0
  309. package/dist/stream/projections/extension.cjs +29 -0
  310. package/dist/stream/projections/extension.cjs.map +1 -0
  311. package/dist/stream/projections/extension.d.cts +7 -0
  312. package/dist/stream/projections/extension.d.cts.map +1 -0
  313. package/dist/stream/projections/extension.d.ts +7 -0
  314. package/dist/stream/projections/extension.d.ts.map +1 -0
  315. package/dist/stream/projections/extension.js +29 -0
  316. package/dist/stream/projections/extension.js.map +1 -0
  317. package/dist/stream/projections/index.cjs +6 -0
  318. package/dist/stream/projections/index.d.ts +6 -0
  319. package/dist/stream/projections/index.js +7 -0
  320. package/dist/stream/projections/media.cjs +81 -0
  321. package/dist/stream/projections/media.cjs.map +1 -0
  322. package/dist/stream/projections/media.d.cts +18 -0
  323. package/dist/stream/projections/media.d.cts.map +1 -0
  324. package/dist/stream/projections/media.d.ts +18 -0
  325. package/dist/stream/projections/media.d.ts.map +1 -0
  326. package/dist/stream/projections/media.js +78 -0
  327. package/dist/stream/projections/media.js.map +1 -0
  328. package/dist/stream/projections/messages.cjs +121 -0
  329. package/dist/stream/projections/messages.cjs.map +1 -0
  330. package/dist/stream/projections/messages.d.cts +8 -0
  331. package/dist/stream/projections/messages.d.cts.map +1 -0
  332. package/dist/stream/projections/messages.d.ts +8 -0
  333. package/dist/stream/projections/messages.d.ts.map +1 -0
  334. package/dist/stream/projections/messages.js +121 -0
  335. package/dist/stream/projections/messages.js.map +1 -0
  336. package/dist/stream/projections/runtime.cjs +44 -0
  337. package/dist/stream/projections/runtime.cjs.map +1 -0
  338. package/dist/stream/projections/runtime.js +44 -0
  339. package/dist/stream/projections/runtime.js.map +1 -0
  340. package/dist/stream/projections/tool-calls.cjs +50 -0
  341. package/dist/stream/projections/tool-calls.cjs.map +1 -0
  342. package/dist/stream/projections/tool-calls.d.cts +8 -0
  343. package/dist/stream/projections/tool-calls.d.cts.map +1 -0
  344. package/dist/stream/projections/tool-calls.d.ts +8 -0
  345. package/dist/stream/projections/tool-calls.d.ts.map +1 -0
  346. package/dist/stream/projections/tool-calls.js +50 -0
  347. package/dist/stream/projections/tool-calls.js.map +1 -0
  348. package/dist/stream/projections/values.cjs +52 -0
  349. package/dist/stream/projections/values.cjs.map +1 -0
  350. package/dist/stream/projections/values.d.cts +7 -0
  351. package/dist/stream/projections/values.d.cts.map +1 -0
  352. package/dist/stream/projections/values.d.ts +6 -0
  353. package/dist/stream/projections/values.d.ts.map +1 -0
  354. package/dist/stream/projections/values.js +52 -0
  355. package/dist/stream/projections/values.js.map +1 -0
  356. package/dist/stream/root-message-projection.cjs +256 -0
  357. package/dist/stream/root-message-projection.cjs.map +1 -0
  358. package/dist/stream/root-message-projection.js +256 -0
  359. package/dist/stream/root-message-projection.js.map +1 -0
  360. package/dist/stream/store.cjs +32 -0
  361. package/dist/stream/store.cjs.map +1 -0
  362. package/dist/stream/store.d.cts +37 -0
  363. package/dist/stream/store.d.cts.map +1 -0
  364. package/dist/stream/store.d.ts +37 -0
  365. package/dist/stream/store.d.ts.map +1 -0
  366. package/dist/stream/store.js +32 -0
  367. package/dist/stream/store.js.map +1 -0
  368. package/dist/stream/submit-coordinator.cjs +399 -0
  369. package/dist/stream/submit-coordinator.cjs.map +1 -0
  370. package/dist/stream/submit-coordinator.d.cts +27 -0
  371. package/dist/stream/submit-coordinator.d.cts.map +1 -0
  372. package/dist/stream/submit-coordinator.d.ts +27 -0
  373. package/dist/stream/submit-coordinator.d.ts.map +1 -0
  374. package/dist/stream/submit-coordinator.js +397 -0
  375. package/dist/stream/submit-coordinator.js.map +1 -0
  376. package/dist/stream/tool-calls.cjs +15 -0
  377. package/dist/stream/tool-calls.cjs.map +1 -0
  378. package/dist/stream/tool-calls.js +15 -0
  379. package/dist/stream/tool-calls.js.map +1 -0
  380. package/dist/stream/types-inference.d.cts +43 -0
  381. package/dist/stream/types-inference.d.cts.map +1 -0
  382. package/dist/stream/types-inference.d.ts +43 -0
  383. package/dist/stream/types-inference.d.ts.map +1 -0
  384. package/dist/stream/types.d.cts +354 -0
  385. package/dist/stream/types.d.cts.map +1 -0
  386. package/dist/stream/types.d.ts +354 -0
  387. package/dist/stream/types.d.ts.map +1 -0
  388. package/dist/types.d.cts +2 -1
  389. package/dist/types.d.cts.map +1 -1
  390. package/dist/types.d.ts +2 -1
  391. package/dist/types.d.ts.map +1 -1
  392. package/dist/ui/index.cjs +1 -1
  393. package/dist/ui/index.d.cts +3 -3
  394. package/dist/ui/index.d.ts +3 -3
  395. package/dist/ui/index.js +1 -1
  396. package/dist/ui/manager.cjs +1 -1
  397. package/dist/ui/manager.js +1 -1
  398. package/dist/ui/messages.cjs +50 -7
  399. package/dist/ui/messages.cjs.map +1 -1
  400. package/dist/ui/messages.d.cts.map +1 -1
  401. package/dist/ui/messages.d.ts.map +1 -1
  402. package/dist/ui/messages.js +51 -9
  403. package/dist/ui/messages.js.map +1 -1
  404. package/dist/ui/orchestrator-custom.cjs +1 -1
  405. package/dist/ui/orchestrator-custom.js +1 -1
  406. package/dist/ui/orchestrator.cjs +2 -2
  407. package/dist/ui/orchestrator.d.cts +1 -1
  408. package/dist/ui/orchestrator.d.ts +1 -1
  409. package/dist/ui/orchestrator.d.ts.map +1 -1
  410. package/dist/ui/orchestrator.js +2 -2
  411. package/dist/ui/stream/agent.d.cts +1 -1
  412. package/dist/ui/stream/agent.d.cts.map +1 -1
  413. package/dist/ui/stream/agent.d.ts +1 -1
  414. package/dist/ui/stream/agent.d.ts.map +1 -1
  415. package/dist/ui/stream/base.d.cts +7 -6
  416. package/dist/ui/stream/base.d.cts.map +1 -1
  417. package/dist/ui/stream/base.d.ts +7 -6
  418. package/dist/ui/stream/base.d.ts.map +1 -1
  419. package/dist/ui/stream/deep-agent.d.cts +1 -1
  420. package/dist/ui/stream/deep-agent.d.cts.map +1 -1
  421. package/dist/ui/stream/deep-agent.d.ts +1 -1
  422. package/dist/ui/stream/deep-agent.d.ts.map +1 -1
  423. package/dist/ui/stream/index.d.cts +4 -4
  424. package/dist/ui/stream/index.d.cts.map +1 -1
  425. package/dist/ui/stream/index.d.ts +4 -4
  426. package/dist/ui/stream/index.d.ts.map +1 -1
  427. package/dist/ui/types.d.cts +3 -2
  428. package/dist/ui/types.d.cts.map +1 -1
  429. package/dist/ui/types.d.ts +2 -1
  430. package/dist/ui/types.d.ts.map +1 -1
  431. package/package.json +18 -8
  432. package/dist/client.cjs.map +0 -1
  433. package/dist/client.d.cts.map +0 -1
  434. package/dist/client.d.ts.map +0 -1
  435. package/dist/client.js.map +0 -1
@@ -0,0 +1,910 @@
1
+ import { ensureMessageInstances } from "../ui/messages.js";
2
+ import { ToolCallAssembler } from "../client/stream/handles/tools.js";
3
+ import { StreamStore } from "./store.js";
4
+ import { ChannelRegistry } from "./channel-registry.js";
5
+ import { isInternalWorkNamespace, isLegacySubagentNamespace, isRootNamespace } from "./namespace.js";
6
+ import { SubagentDiscovery } from "./discovery/subagents.js";
7
+ import { SubgraphDiscovery } from "./discovery/subgraphs.js";
8
+ import { MessageMetadataTracker } from "./message-metadata-tracker.js";
9
+ import { LifecycleLoadingTracker } from "./lifecycle-loading-tracker.js";
10
+ import { RootMessageProjection } from "./root-message-projection.js";
11
+ import { EMPTY_QUEUE, SubmitCoordinator } from "./submit-coordinator.js";
12
+ import { upsertToolCall } from "./tool-calls.js";
13
+ import "@langchain/core/messages";
14
+ //#region src/stream/controller.ts
15
+ function isAbortLikeError(error) {
16
+ if (error == null || typeof error !== "object") return false;
17
+ const maybeError = error;
18
+ return maybeError.name === "AbortError" || typeof maybeError.message === "string" && maybeError.message.includes("aborted");
19
+ }
20
+ const ROOT_NAMESPACE = [];
21
+ /**
22
+ * Channel set covered by the always-on root subscription. Exported so
23
+ * projections (and transports) can reason about what the root pump
24
+ * already delivers before opening additional server subscriptions.
25
+ */
26
+ const ROOT_PUMP_CHANNELS = [
27
+ "values",
28
+ "checkpoints",
29
+ "lifecycle",
30
+ "input",
31
+ "messages",
32
+ "tools"
33
+ ];
34
+ /**
35
+ * Coordinates one thread's protocol-v2 stream and exposes stable
36
+ * observable projections for framework bindings.
37
+ *
38
+ * The controller owns the root subscription, lazily binds scoped
39
+ * projections through {@link ChannelRegistry}, and normalizes protocol
40
+ * events into class-message, tool-call, discovery, interrupt, and queue
41
+ * stores.
42
+ *
43
+ * @typeParam StateType - Shape of the graph state exposed on `values`.
44
+ * @typeParam InterruptType - Shape of protocol interrupt payloads.
45
+ * @typeParam ConfigurableType - Shape of `config.configurable` accepted by submit.
46
+ */
47
+ var StreamController = class {
48
+ rootStore;
49
+ subagentStore;
50
+ subgraphStore;
51
+ subgraphByNodeStore;
52
+ messageMetadataStore;
53
+ queueStore;
54
+ registry;
55
+ #options;
56
+ #messagesKey;
57
+ #subagents = new SubagentDiscovery();
58
+ #subgraphs = new SubgraphDiscovery();
59
+ #messageMetadata = new MessageMetadataTracker();
60
+ #thread;
61
+ #currentThreadId;
62
+ #rootSubscription;
63
+ #rootPump;
64
+ #rootPumpReady;
65
+ #threadEventUnsubscribe;
66
+ #disposed = false;
67
+ #pendingDisposeTimer = null;
68
+ #resolvedInterrupts = /* @__PURE__ */ new Set();
69
+ /**
70
+ * Thread ids we minted client-side on first `submit()`. Keeping them
71
+ * here lets `hydrate()` skip the `threads.getState()` round-trip —
72
+ * we know there is nothing checkpointed server-side yet (and the
73
+ * request would 404 and surface a spurious error to the UI).
74
+ */
75
+ #selfCreatedThreadIds = /* @__PURE__ */ new Set();
76
+ #rootEventListeners = /* @__PURE__ */ new Set();
77
+ #rootBus;
78
+ /**
79
+ * Single-shot hydration promise. Exposed via `hydrationPromise`
80
+ * so Suspense wrappers can throw it until the first hydrate
81
+ * completes (resolve) or fails (reject). Reset whenever a new
82
+ * hydrate cycle begins so `<Suspense>` boundaries re-suspend on
83
+ * thread switch.
84
+ */
85
+ #hydrationPromise;
86
+ #resolveHydration;
87
+ #rejectHydration;
88
+ /**
89
+ * Tool assembler lives for the lifetime of a thread; reset on
90
+ * rebind so a fresh thread starts with a clean slate.
91
+ */
92
+ #rootToolAssembler = new ToolCallAssembler();
93
+ #rootMessages;
94
+ #lifecycleLoading;
95
+ #submitter;
96
+ #threadListeners = /* @__PURE__ */ new Set();
97
+ /**
98
+ * Create a controller around a LangGraph client and optional initial thread.
99
+ *
100
+ * @param options - Runtime configuration, client, thread id, and initial state.
101
+ */
102
+ constructor(options) {
103
+ this.#options = options;
104
+ this.#messagesKey = options.messagesKey ?? "messages";
105
+ this.#currentThreadId = options.threadId ?? null;
106
+ this.#rootBus = {
107
+ channels: ROOT_PUMP_CHANNELS,
108
+ subscribe: (listener) => {
109
+ this.#rootEventListeners.add(listener);
110
+ return () => {
111
+ this.#rootEventListeners.delete(listener);
112
+ };
113
+ }
114
+ };
115
+ this.registry = new ChannelRegistry(this.#rootBus);
116
+ this.subagentStore = this.#subagents.store;
117
+ this.subgraphStore = this.#subgraphs.store;
118
+ this.subgraphByNodeStore = this.#subgraphs.byNodeStore;
119
+ this.rootStore = new StreamStore(this.#createInitialSnapshot());
120
+ this.#rootMessages = new RootMessageProjection({
121
+ messagesKey: this.#messagesKey,
122
+ store: this.rootStore,
123
+ subagents: this.#subagents
124
+ });
125
+ this.#lifecycleLoading = new LifecycleLoadingTracker({
126
+ store: this.rootStore,
127
+ isDisposed: () => this.#disposed
128
+ });
129
+ this.messageMetadataStore = this.#messageMetadata.store;
130
+ this.queueStore = new StreamStore(EMPTY_QUEUE);
131
+ this.#submitter = new SubmitCoordinator({
132
+ options: this.#options,
133
+ rootStore: this.rootStore,
134
+ queueStore: this.queueStore,
135
+ getDisposed: () => this.#disposed,
136
+ getCurrentThreadId: () => this.#currentThreadId,
137
+ setCurrentThreadId: (threadId) => {
138
+ this.#currentThreadId = threadId;
139
+ },
140
+ rememberSelfCreatedThreadId: (threadId) => {
141
+ this.#selfCreatedThreadIds.add(threadId);
142
+ },
143
+ hydrate: (threadId) => this.hydrate(threadId),
144
+ ensureThread: (threadId) => this.#ensureThread(threadId),
145
+ waitForRootPumpReady: () => this.#rootPumpReady,
146
+ awaitNextTerminal: (signal) => this.#awaitNextTerminal(signal),
147
+ latestUnresolvedInterrupt: () => this.#latestUnresolvedInterrupt(),
148
+ markInterruptResolved: (interruptId) => {
149
+ this.#resolvedInterrupts.add(interruptId);
150
+ }
151
+ });
152
+ this.#hydrationPromise = this.#createHydrationPromise();
153
+ /**
154
+ * Attach a default no-op catch so orphaned hydrationPromise
155
+ * rejections (e.g. controllers spawned during Suspense retries
156
+ * whose promise never gets subscribed to because the suspense
157
+ * cache already holds an earlier one) don't surface as unhandled
158
+ * rejections. Callers that attach their own handlers via .then()
159
+ * still receive the rejection on their derived promise.
160
+ */
161
+ this.#hydrationPromise.catch(() => void 0);
162
+ /**
163
+ * Kick off the initial hydrate eagerly when a caller-supplied
164
+ * thread id is present. Suspense consumers throw
165
+ * `hydrationPromise` on the very first render, which unmounts the
166
+ * subtree before any `useEffect` can run — so if we waited for an
167
+ * effect to drive the hydrate we'd deadlock. Firing here makes
168
+ * the promise settle independently of the component lifecycle.
169
+ */
170
+ if (this.#currentThreadId != null) this.hydrate(this.#currentThreadId);
171
+ else this.#resolveHydration();
172
+ }
173
+ /**
174
+ * Promise that settles the first time {@link hydrate} finishes on
175
+ * the current thread. Resolves on a clean hydration, rejects when
176
+ * the thread-state fetch errors. A fresh promise is installed on
177
+ * every thread swap so `<Suspense>` wrappers re-suspend on
178
+ * `switchThread`.
179
+ */
180
+ get hydrationPromise() {
181
+ return this.#hydrationPromise;
182
+ }
183
+ /**
184
+ * Create the deferred promise backing the current hydration cycle.
185
+ */
186
+ #createHydrationPromise() {
187
+ return new Promise((resolve, reject) => {
188
+ this.#resolveHydration = resolve;
189
+ this.#rejectHydration = reject;
190
+ });
191
+ }
192
+ /**
193
+ * Replace the current hydration promise before a thread swap.
194
+ */
195
+ #resetHydrationPromise() {
196
+ /**
197
+ * Swallow rejection on the orphaned promise so Node doesn't
198
+ * flag it as unhandled; Suspense callers that still hold a
199
+ * reference see the rejection they subscribed to.
200
+ */
201
+ this.#hydrationPromise.catch(() => void 0);
202
+ this.#hydrationPromise = this.#createHydrationPromise();
203
+ }
204
+ /**
205
+ * Fetch the checkpointed thread state and seed the root snapshot.
206
+ * Re-calling with a different `threadId` swaps the underlying
207
+ * {@link ThreadStream}, rewires the registry to the new thread, and
208
+ * resets assemblers.
209
+ *
210
+ * @param threadId - Optional replacement thread id; `null` clears the active thread.
211
+ */
212
+ async hydrate(threadId) {
213
+ if (this.#disposed) return;
214
+ const target = threadId === void 0 ? this.#currentThreadId : threadId;
215
+ const changed = target !== this.#currentThreadId;
216
+ this.#currentThreadId = target ?? null;
217
+ this.rootStore.setState((s) => ({
218
+ ...s,
219
+ threadId: this.#currentThreadId
220
+ }));
221
+ if (changed) {
222
+ /**
223
+ * Swap to a new thread: re-arm the hydration promise so any
224
+ * Suspense boundary remounted against the new id suspends again.
225
+ */
226
+ this.#resetHydrationPromise();
227
+ await this.#teardownThread();
228
+ /**
229
+ * Reset UI-facing snapshot so stale messages/values/tool-calls
230
+ * from the previous thread don't bleed into the new one. The
231
+ * new thread's state (if any) is then populated below via
232
+ * `#applyValues`.
233
+ */
234
+ this.rootStore.setState(() => ({
235
+ ...this.#createInitialSnapshot(),
236
+ threadId: this.#currentThreadId
237
+ }));
238
+ /**
239
+ * Drop queued submissions — they were targeted at the previous
240
+ * thread so dispatching them against the new thread would be
241
+ * surprising. Mirrors the legacy `StreamOrchestrator` behaviour.
242
+ */
243
+ this.queueStore.setState(() => EMPTY_QUEUE);
244
+ }
245
+ if (this.#currentThreadId == null) {
246
+ this.rootStore.setState((s) => ({
247
+ ...s,
248
+ isThreadLoading: false
249
+ }));
250
+ this.#resolveHydration();
251
+ return;
252
+ }
253
+ /**
254
+ * Self-generated thread ids have nothing to fetch server-side yet
255
+ * — the thread is created lazily by the first `run.start`. Calling
256
+ * `threads.getState()` here would return a 404 and surface a
257
+ * spurious error to the UI.
258
+ */
259
+ if (this.#selfCreatedThreadIds.has(this.#currentThreadId)) {
260
+ this.rootStore.setState((s) => ({
261
+ ...s,
262
+ isThreadLoading: false
263
+ }));
264
+ this.#resolveHydration();
265
+ return;
266
+ }
267
+ this.rootStore.setState((s) => ({
268
+ ...s,
269
+ isThreadLoading: true
270
+ }));
271
+ let hydrationError;
272
+ try {
273
+ const state = await this.#options.client.threads.getState(this.#currentThreadId);
274
+ if (state?.values != null) {
275
+ /**
276
+ * `threads.getState()` returns the legacy `ThreadState` shape
277
+ * where `parent_checkpoint` is an object (`{ thread_id,
278
+ * checkpoint_id, checkpoint_ns }`). Synthesize the v2
279
+ * `Checkpoint` envelope (matching the `checkpoints` channel
280
+ * payload) so hydrated messages also get their
281
+ * `parentCheckpointId` populated for fork / edit flows.
282
+ */
283
+ const checkpointId = state.checkpoint?.checkpoint_id;
284
+ const parentCheckpointId = state.parent_checkpoint?.checkpoint_id ?? void 0;
285
+ const syntheticCheckpoint = typeof checkpointId === "string" ? {
286
+ id: checkpointId,
287
+ ...parentCheckpointId != null ? { parent_id: parentCheckpointId } : {}
288
+ } : void 0;
289
+ this.#applyValues(state.values, syntheticCheckpoint);
290
+ }
291
+ } catch (error) {
292
+ if (error?.status !== 404) {
293
+ hydrationError = error;
294
+ this.rootStore.setState((s) => ({
295
+ ...s,
296
+ error
297
+ }));
298
+ }
299
+ } finally {
300
+ this.rootStore.setState((s) => ({
301
+ ...s,
302
+ isThreadLoading: false
303
+ }));
304
+ if (hydrationError != null) this.#rejectHydration(hydrationError);
305
+ else this.#resolveHydration();
306
+ }
307
+ /**
308
+ * P0 fix: open the shared subscription on mount so in-flight
309
+ * server-side runs are observed even when no local `submit()` is
310
+ * active. The transport replays the run from `seq=0` on a rotating
311
+ * subscribe, so late-joining is free once the subscription exists.
312
+ * `isLoading` transitions are driven by the persistent root
313
+ * lifecycle listener registered in `#startRootPump`.
314
+ */
315
+ this.#ensureThread(this.#currentThreadId);
316
+ }
317
+ /**
318
+ * Submit input or a resume command to the active thread.
319
+ *
320
+ * @param input - Input payload for a new run; `null`/`undefined` submits no input.
321
+ * @param options - Per-run config, metadata, multitask behavior, and callbacks.
322
+ */
323
+ async submit(input, options) {
324
+ await this.#submitter.submit(input, options);
325
+ }
326
+ /**
327
+ * Abort the currently tracked run and mark the controller idle.
328
+ */
329
+ async stop() {
330
+ await this.#submitter.stop();
331
+ }
332
+ /**
333
+ * Cancel a queued submission by id. Returns `true` when the entry
334
+ * was found and removed, `false` otherwise.
335
+ *
336
+ * Today this only removes the entry from the client-side mirror —
337
+ * once the server exposes queue cancel (roadmap A0.3) the
338
+ * controller will additionally issue a cancel call against the
339
+ * active transport.
340
+ *
341
+ * @param id - Client-side queue entry id to remove.
342
+ */
343
+ async cancelQueued(id) {
344
+ return this.#submitter.cancelQueued(id);
345
+ }
346
+ /**
347
+ * Drop every queued submission. Server-side cancel arrives with A0.3.
348
+ */
349
+ async clearQueue() {
350
+ await this.#submitter.clearQueue();
351
+ }
352
+ /**
353
+ * Respond to a pending protocol interrupt.
354
+ *
355
+ * @param response - Payload to send back to the interrupted namespace.
356
+ * @param target - Optional explicit interrupt id and namespace; defaults to the latest unresolved interrupt.
357
+ */
358
+ async respond(response, target) {
359
+ if (this.#disposed || this.#thread == null) throw new Error("No active thread to respond to.");
360
+ const resolved = target != null ? {
361
+ interruptId: target.interruptId,
362
+ namespace: target.namespace ?? [...ROOT_NAMESPACE]
363
+ } : this.#latestUnresolvedInterrupt();
364
+ if (resolved == null) throw new Error("No pending interrupt to respond to.");
365
+ try {
366
+ await this.#thread.respondInput({
367
+ namespace: resolved.namespace,
368
+ interrupt_id: resolved.interruptId,
369
+ response
370
+ });
371
+ this.#resolvedInterrupts.add(resolved.interruptId);
372
+ } catch (error) {
373
+ if (this.#disposed && isAbortLikeError(error)) return;
374
+ throw error;
375
+ }
376
+ }
377
+ /**
378
+ * Dispose the active thread, subscriptions, registry entries, and listeners.
379
+ */
380
+ async dispose() {
381
+ if (this.#disposed) return;
382
+ this.#cancelPendingDispose();
383
+ this.#disposed = true;
384
+ this.#submitter.abortActiveRun();
385
+ await this.#teardownThread();
386
+ await this.registry.dispose();
387
+ this.#threadListeners.clear();
388
+ }
389
+ /**
390
+ * StrictMode-safe lifecycle hook for framework bindings.
391
+ *
392
+ * React 18+ `StrictMode` intentionally mounts → unmounts → remounts
393
+ * components in dev to surface effect-cleanup bugs. A naive
394
+ * `useEffect(() => () => controller.dispose())` would permanently
395
+ * tear the controller down on that first synthetic unmount, leaving
396
+ * every subsequent `submit()` a silent no-op.
397
+ *
398
+ * Call {@link activate} from the bind site's effect and return the
399
+ * result as the effect's cleanup. The controller uses deferred
400
+ * disposal: a `release()` only schedules a dispose on the next
401
+ * microtask, which is cancelled if another `activate()` arrives
402
+ * before it fires (the normal StrictMode remount path).
403
+ */
404
+ activate() {
405
+ this.#cancelPendingDispose();
406
+ return () => {
407
+ if (this.#disposed) return;
408
+ this.#pendingDisposeTimer = setTimeout(() => {
409
+ this.#pendingDisposeTimer = null;
410
+ this.dispose().catch(() => void 0);
411
+ }, 0);
412
+ };
413
+ }
414
+ /**
415
+ * Cancel a deferred dispose scheduled by {@link activate}.
416
+ */
417
+ #cancelPendingDispose() {
418
+ if (this.#pendingDisposeTimer != null) {
419
+ clearTimeout(this.#pendingDisposeTimer);
420
+ this.#pendingDisposeTimer = null;
421
+ }
422
+ }
423
+ /**
424
+ * Current underlying {@link ThreadStream} (v2 escape hatch).
425
+ */
426
+ getThread() {
427
+ return this.#thread;
428
+ }
429
+ /**
430
+ * Listen for `ThreadStream` lifecycle (swap on thread-id change,
431
+ * detach on dispose). The listener fires immediately with the
432
+ * current thread (may be `undefined`).
433
+ *
434
+ * @param listener - Callback invoked immediately and on every thread swap.
435
+ */
436
+ subscribeThread(listener) {
437
+ this.#threadListeners.add(listener);
438
+ listener(this.#thread);
439
+ return () => {
440
+ this.#threadListeners.delete(listener);
441
+ };
442
+ }
443
+ /**
444
+ * Build the initial root snapshot from configured initial values.
445
+ */
446
+ #createInitialSnapshot() {
447
+ const values = this.#options.initialValues ?? {};
448
+ return {
449
+ values,
450
+ messages: extractAndCoerceMessages(values, this.#messagesKey),
451
+ toolCalls: [],
452
+ interrupts: [],
453
+ interrupt: void 0,
454
+ isLoading: false,
455
+ isThreadLoading: this.#currentThreadId != null && !this.#selfCreatedThreadIds.has(this.#currentThreadId),
456
+ error: void 0,
457
+ threadId: this.#currentThreadId
458
+ };
459
+ }
460
+ /**
461
+ * Return the active thread stream, creating and binding one when needed.
462
+ *
463
+ * @param threadId - Thread id used when constructing the stream.
464
+ */
465
+ #ensureThread(threadId) {
466
+ if (this.#thread != null) return this.#thread;
467
+ this.#thread = this.#options.client.threads.stream(threadId, {
468
+ assistantId: this.#options.assistantId,
469
+ transport: this.#options.transport,
470
+ fetch: this.#options.fetch,
471
+ webSocketFactory: this.#options.webSocketFactory
472
+ });
473
+ this.registry.bind(this.#thread);
474
+ this.#startRootPump(this.#thread);
475
+ this.#notifyThreadListeners();
476
+ return this.#thread;
477
+ }
478
+ /**
479
+ * Close the current thread stream and reset per-thread assembly state.
480
+ */
481
+ async #teardownThread() {
482
+ const thread = this.#thread;
483
+ this.#thread = void 0;
484
+ this.registry.bind(void 0);
485
+ this.#threadEventUnsubscribe?.();
486
+ this.#threadEventUnsubscribe = void 0;
487
+ /**
488
+ * Persistent lifecycle driver is scoped to the current thread
489
+ * stream. Remove it so a swap to a new thread starts with a clean
490
+ * listener set (a new one is installed in `#startRootPump`).
491
+ */
492
+ this.#rootEventListeners.delete(this.#lifecycleLoading.listener);
493
+ try {
494
+ await this.#rootSubscription?.unsubscribe();
495
+ } catch {}
496
+ this.#rootSubscription = void 0;
497
+ this.#rootPumpReady = void 0;
498
+ try {
499
+ await this.#rootPump;
500
+ } catch {}
501
+ this.#rootPump = void 0;
502
+ this.#rootMessages.reset();
503
+ this.#rootToolAssembler = new ToolCallAssembler();
504
+ this.#lifecycleLoading.reset();
505
+ this.#messageMetadata.reset();
506
+ this.queueStore.setState(() => EMPTY_QUEUE);
507
+ if (thread != null) {
508
+ try {
509
+ await thread.close();
510
+ } catch {}
511
+ this.#notifyThreadListeners();
512
+ }
513
+ }
514
+ /**
515
+ * Determine whether the configured transport uses the resumable event-stream path.
516
+ */
517
+ #usesEventStreamTransport() {
518
+ const transport = this.#options.transport;
519
+ if (transport === "websocket") return false;
520
+ if (transport == null || transport === "sse") return true;
521
+ return typeof transport.openEventStream === "function";
522
+ }
523
+ /**
524
+ * Start the always-on root subscription pump for the provided thread.
525
+ *
526
+ * @param thread - Thread stream to subscribe to and fan out from.
527
+ */
528
+ #startRootPump(thread) {
529
+ if (this.#rootPump != null) return;
530
+ let resolveReady;
531
+ this.#rootPumpReady = new Promise((resolve) => {
532
+ resolveReady = resolve;
533
+ });
534
+ /**
535
+ * Wildcard discovery + interrupt tracking is delivered via the
536
+ * thread's dedicated lifecycle watcher (see `ThreadStream.onEvent`).
537
+ * This callback fires once per globally-unique event across both
538
+ * the content pump AND the watcher, so we can drive discovery
539
+ * runners and nested HITL capture without widening the content
540
+ * pump's narrow filter.
541
+ */
542
+ this.#threadEventUnsubscribe = thread.onEvent((event) => this.#onWildcardEvent(event));
543
+ /**
544
+ * Persistent isLoading driver. Drives `isLoading` from
545
+ * root-namespace lifecycle events so that in-flight runs observed
546
+ * via `hydrate()` (not initiated by a local `submit()`) still flip
547
+ * the UI to loading. `running` → true; terminals → false. The
548
+ * optimistic `isLoading = true` inside `submit()` stays because
549
+ * that fires before any subscription event arrives.
550
+ */
551
+ this.#rootEventListeners.add(this.#lifecycleLoading.listener);
552
+ this.#rootPump = (async () => {
553
+ try {
554
+ /**
555
+ * Narrow the content pump to the root namespace, depth 1:
556
+ * this is enough to observe root LLM deltas and first-level
557
+ * discovery hints (tool-started for task:* / subgraph
558
+ * boundaries) without downloading content from every nested
559
+ * subagent / subgraph. Deeper content is pulled in lazily by
560
+ * per-namespace selector projections (e.g. `useMessages(sub)`),
561
+ * which expand `#computeUnionFilter` progressively.
562
+ */
563
+ const subscriptionPromise = thread.subscribe({
564
+ channels: [...ROOT_PUMP_CHANNELS],
565
+ namespaces: [[]],
566
+ depth: 1
567
+ });
568
+ if (this.#usesEventStreamTransport())
569
+ /**
570
+ * SSE streams can legitimately withhold response headers until
571
+ * the first event is available. Waiting for `subscribe()` here
572
+ * would deadlock new-thread submits: the run is not dispatched
573
+ * until the root pump is "ready", but the pump does not become
574
+ * ready until the run emits. `thread.subscribe()` has already
575
+ * registered the local subscription and scheduled the stream
576
+ * rotation by this point; waiting one microtask lets the fetch
577
+ * get kicked off without requiring headers to arrive.
578
+ */
579
+ queueMicrotask(() => {
580
+ resolveReady?.();
581
+ resolveReady = void 0;
582
+ });
583
+ const subscription = await subscriptionPromise;
584
+ resolveReady?.();
585
+ resolveReady = void 0;
586
+ this.#rootSubscription = subscription;
587
+ /**
588
+ * The SSE transport pauses the underlying subscription when
589
+ * a terminal root lifecycle event arrives (so `for await`
590
+ * loops observing a single run exit cleanly) and re-opens
591
+ * the next run's server stream on `#prepareForNextRun`,
592
+ * resuming the subscription handle. The root pump needs to
593
+ * survive that hand-off: we re-enter the inner `for await`
594
+ * for every resumed iteration until the subscription is
595
+ * permanently closed or the controller is disposed.
596
+ */
597
+ while (!this.#disposed) {
598
+ for await (const event of subscription) {
599
+ if (this.#disposed) break;
600
+ /**
601
+ * Resilience: isolate per-event dispatch from the pump loop.
602
+ *
603
+ * `#onRootEvent` runs synchronously and, transitively,
604
+ * invokes every root-bus listener (selector projections that
605
+ * opted into the shared stream) plus every `rootStore`
606
+ * subscriber. Some of those subscribers live in a React
607
+ * render tree — `useStream` drives
608
+ * `useSyncExternalStore`, so a misbehaving component can
609
+ * surface a render-phase error ("Maximum update depth
610
+ * exceeded", "The result of getSnapshot should be cached",
611
+ * etc.) that propagates out here.
612
+ *
613
+ * Without this guard, a single throw bubbles through the
614
+ * `for await` loop and terminates the root pump permanently.
615
+ * That is catastrophic: no more root events get processed —
616
+ * the terminal `lifecycle: completed` never lands, so
617
+ * `#awaitNextTerminal` never resolves, `isLoading` stays
618
+ * `true`, composers stay disabled, and the final assistant
619
+ * turn never commits to `stream.messages`. The UI looks
620
+ * hung even though the server is still emitting events
621
+ * (and `ThreadStream.onEvent` keeps firing).
622
+ *
623
+ * We therefore swallow the error and keep pumping. The
624
+ * the pump's correctness guarantees do not depend on any
625
+ * consumer behaving well.
626
+ */
627
+ try {
628
+ this.#onRootEvent(event);
629
+ } catch {}
630
+ }
631
+ if (this.#disposed) break;
632
+ if (!subscription.isPaused) break;
633
+ await subscription.waitForResume();
634
+ }
635
+ } catch {
636
+ resolveReady?.();
637
+ resolveReady = void 0;
638
+ }
639
+ })();
640
+ }
641
+ /**
642
+ * Handle an event delivered via {@link ThreadStream.onEvent}.
643
+ *
644
+ * `onEvent` fires once per globally-unique event across the content
645
+ * pump and the wildcard lifecycle watcher, so this is the single
646
+ * entry point for wildcard discovery / interrupt tracking. It does
647
+ * NOT fan events out to the root bus (that's driven by the content
648
+ * pump iterator so root-bus short-circuits stay depth-1 scoped) and
649
+ * it does NOT process root content — messages/tools/values at root
650
+ * are handled by `#onRootEvent` off the content pump.
651
+ *
652
+ * @param event - Raw protocol event observed by the thread-wide listener.
653
+ */
654
+ #onWildcardEvent(event) {
655
+ try {
656
+ this.#subagents.push(event);
657
+ } catch {}
658
+ this.#subgraphs.push(event);
659
+ this.#lifecycleLoading.handle(event);
660
+ /**
661
+ * Nested `input.requested` events (HITL inside a subagent /
662
+ * subgraph) are not observable via the narrow content pump. The
663
+ * `ThreadStream` itself already records them into
664
+ * `thread.interrupts`, which `#latestUnresolvedInterrupt()`
665
+ * consults — so HITL respond() works for any depth. Root-level
666
+ * interrupts are also mirrored into `rootStore.interrupts` here so
667
+ * UI state does not depend on the narrower content pump being the
668
+ * first consumer to see the event.
669
+ */
670
+ this.#recordRootInterrupt(event);
671
+ }
672
+ /**
673
+ * Process one root-pump event and update all root projections.
674
+ *
675
+ * @param event - Event yielded by the root subscription.
676
+ */
677
+ #onRootEvent(event) {
678
+ try {
679
+ this.#subagents.push(event);
680
+ } catch {}
681
+ /**
682
+ * Fan root-pump events out to every root-bus listener (selector
683
+ * projections that opted into the shared stream,
684
+ * `#awaitTerminal`, etc.). The root bus mirrors the content
685
+ * pump's narrow scope (depth 1 at root) so projections that
686
+ * short-circuit via the bus stay bounded.
687
+ */
688
+ if (this.#rootEventListeners.size > 0) for (const listener of this.#rootEventListeners) try {
689
+ listener(event);
690
+ } catch {}
691
+ /**
692
+ * `messages` and `tools` events are emitted under a node's
693
+ * namespace — for a typical StateGraph the LLM's token deltas
694
+ * land on `["model:<uuid>"]`, tool executions on
695
+ * `["tools:<uuid>"]`, etc. The orchestrator's own turns (root
696
+ * agent, or an orchestrator-scoped subgraph like `model:*` /
697
+ * `model_request:*`) belong in `root.messages` and
698
+ * `root.toolCalls`.
699
+ *
700
+ * Subagent / tool-internal branches do NOT:
701
+ * - `task:*` segment — legacy subagent convention.
702
+ * - `tools:*` segment — every tool execution is wrapped in a
703
+ * `tools` subgraph. For simple tools its only content is
704
+ * the eventual tool result (also echoed verbatim by
705
+ * `values.messages` so we don't lose anything). For the
706
+ * deep-agent `task` tool its content IS the spawned
707
+ * subagent's full message + tool stream, which is surfaced
708
+ * separately via `useMessages(stream, subagent)` /
709
+ * `useToolCalls(stream, subagent)`.
710
+ *
711
+ * We therefore drop `messages` events from any namespace that
712
+ * contains a `task:*` or `tools:*` segment; the authoritative
713
+ * tool-result text lands in `root.messages` via the root
714
+ * `values.messages` snapshot merge in `#applyValues`.
715
+ */
716
+ const isInternalNamespace = isInternalWorkNamespace(event.params.namespace);
717
+ const hasLegacySubagentNamespace = isLegacySubagentNamespace(event.params.namespace);
718
+ if (event.method === "messages") {
719
+ if (!isInternalNamespace) this.#rootMessages.handleMessage(event);
720
+ return;
721
+ }
722
+ if (event.method === "tools") {
723
+ if (event.params.namespace.length <= 1 && !hasLegacySubagentNamespace) {
724
+ /**
725
+ * Record the `namespace → tool_call_id` association so that
726
+ * the ensuing `message-start` (role: "tool") at the same
727
+ * namespace can recover the `tool_call_id` (the `messages`
728
+ * channel's start event doesn't carry it directly).
729
+ */
730
+ const toolData = event.params.data;
731
+ if (toolData.event === "tool-started" && typeof toolData.tool_call_id === "string") this.#rootMessages.recordToolCallNamespace(event.params.namespace, toolData.tool_call_id);
732
+ const tc = this.#rootToolAssembler.consume(event);
733
+ if (tc != null) this.rootStore.setState((s) => ({
734
+ ...s,
735
+ toolCalls: upsertToolCall(s.toolCalls, tc)
736
+ }));
737
+ }
738
+ return;
739
+ }
740
+ /**
741
+ * The `checkpoints` channel carries the lightweight envelope
742
+ * (`id`, `parent_id`, `step`, `source`) emitted immediately
743
+ * before its companion `values` event on the same superstep.
744
+ * Buffer the envelope per-namespace so the ensuing `values`
745
+ * event at the same namespace can pair with it in `#applyValues`.
746
+ * The buffer is read-and-cleared on consumption so a subsequent
747
+ * `values` event without a new checkpoint doesn't reuse stale
748
+ * metadata.
749
+ */
750
+ if (event.method === "checkpoints") {
751
+ const data = event.params.data;
752
+ this.#messageMetadata.bufferCheckpoint(event.params.namespace, data);
753
+ return;
754
+ }
755
+ if (!isRootNamespace(event.params.namespace)) return;
756
+ if (event.method === "values") {
757
+ const valuesEvent = event;
758
+ const bufferedCheckpoint = this.#messageMetadata.consumeCheckpoint(event.params.namespace);
759
+ this.#applyValues(valuesEvent.params.data, bufferedCheckpoint);
760
+ return;
761
+ }
762
+ if (event.method === "input.requested") {
763
+ this.#recordRootInterrupt(event);
764
+ return;
765
+ }
766
+ if (event.method === "lifecycle") event.params.data;
767
+ }
768
+ /**
769
+ * Merge a `values` payload into root values and root messages.
770
+ *
771
+ * @param raw - Raw `values` channel payload.
772
+ * @param checkpoint - Optional checkpoint envelope paired with the values event.
773
+ */
774
+ #applyValues(raw, checkpoint) {
775
+ if (raw == null || typeof raw !== "object" || Array.isArray(raw)) return;
776
+ const state = raw;
777
+ /**
778
+ * Surface parent_checkpoint per-message when the values event
779
+ * carries the lightweight checkpoint envelope (populated by
780
+ * `@langchain/langgraph-core`'s `_emitValuesWithCheckpointMeta` and
781
+ * forwarded through `convertToProtocolEvent`). Consumers surface
782
+ * this as `useMessageMetadata(stream, msg.id).parentCheckpointId`
783
+ * for fork / edit flows.
784
+ */
785
+ const parentCheckpointId = checkpoint?.parent_id;
786
+ if (parentCheckpointId != null && Array.isArray(state[this.#messagesKey])) this.#messageMetadata.recordMessages(state[this.#messagesKey], { parentCheckpointId });
787
+ const maybeMessages = state[this.#messagesKey];
788
+ let nextValues;
789
+ let nextMessages;
790
+ if (Array.isArray(maybeMessages)) {
791
+ const coerced = ensureMessageInstances(maybeMessages);
792
+ nextValues = {
793
+ ...state,
794
+ [this.#messagesKey]: coerced
795
+ };
796
+ nextMessages = coerced;
797
+ } else {
798
+ nextValues = state;
799
+ nextMessages = [];
800
+ }
801
+ this.#rootMessages.applyValues(nextValues, nextMessages);
802
+ }
803
+ /**
804
+ * Mirror root protocol interrupts into the root snapshot.
805
+ *
806
+ * This can be called from both the wildcard lifecycle/input watcher and the
807
+ * root content pump. Store-level dedup keeps the user-facing list stable.
808
+ */
809
+ #recordRootInterrupt(event) {
810
+ if (event.method !== "input.requested") return;
811
+ if (!isRootNamespace(event.params.namespace)) return;
812
+ const data = event.params.data;
813
+ const interruptId = data?.interrupt_id;
814
+ if (typeof interruptId !== "string" || this.#resolvedInterrupts.has(interruptId)) return;
815
+ const interrupt = {
816
+ id: interruptId,
817
+ value: data.payload
818
+ };
819
+ this.rootStore.setState((s) => {
820
+ if (s.interrupts.some((entry) => entry.id === interruptId)) return s;
821
+ const interrupts = [...s.interrupts, interrupt];
822
+ return {
823
+ ...s,
824
+ interrupts,
825
+ interrupt: interrupts[0]
826
+ };
827
+ });
828
+ }
829
+ /**
830
+ * Resolve on the next root-namespace terminal lifecycle event
831
+ * (`completed` / `failed` / `interrupted`) or on abort.
832
+ *
833
+ * Attaches to the controller's root event bus instead of opening
834
+ * a second server subscription. Callers should register the
835
+ * returned promise **before** dispatching the command that
836
+ * triggers the run (`thread.run.start` / `thread.input.respond`)
837
+ * — the root pump fans events out synchronously on arrival, so a
838
+ * late registration would miss the terminal for fast runs.
839
+ *
840
+ * @param signal - Abort signal for the local submit lifecycle.
841
+ */
842
+ #awaitNextTerminal(signal) {
843
+ return new Promise((resolve) => {
844
+ let settled = false;
845
+ function finish(result) {
846
+ if (settled) return;
847
+ settled = true;
848
+ unsubscribeRoot?.();
849
+ unsubscribeThread?.();
850
+ signal.removeEventListener("abort", finishAborted);
851
+ resolve(result);
852
+ }
853
+ const finishAborted = () => finish({ event: "aborted" });
854
+ const onEvent = (event) => {
855
+ if (settled) return;
856
+ if (event.method !== "lifecycle") return;
857
+ if (!isRootNamespace(event.params.namespace)) return;
858
+ const lifecycle = event.params.data;
859
+ if (lifecycle?.event === "completed") setTimeout(() => finish({ event: "completed" }), 0);
860
+ else if (lifecycle?.event === "failed") setTimeout(() => finish({
861
+ event: "failed",
862
+ error: lifecycle.error
863
+ }), 0);
864
+ else if (lifecycle?.event === "interrupted") setTimeout(() => finish({ event: "interrupted" }), 0);
865
+ };
866
+ const unsubscribeRoot = this.#rootBus.subscribe(onEvent);
867
+ const unsubscribeThread = this.#thread?.onEvent(onEvent);
868
+ if (signal.aborted) finishAborted();
869
+ else signal.addEventListener("abort", finishAborted, { once: true });
870
+ });
871
+ }
872
+ /**
873
+ * Find the newest unresolved interrupt recorded on the active thread.
874
+ */
875
+ #latestUnresolvedInterrupt() {
876
+ const thread = this.#thread;
877
+ if (thread == null) return null;
878
+ for (let i = thread.interrupts.length - 1; i >= 0; i -= 1) {
879
+ const entry = thread.interrupts[i];
880
+ if (entry == null) continue;
881
+ if (this.#resolvedInterrupts.has(entry.interruptId)) continue;
882
+ return {
883
+ interruptId: entry.interruptId,
884
+ namespace: entry.namespace
885
+ };
886
+ }
887
+ return null;
888
+ }
889
+ /**
890
+ * Notify listeners that the underlying thread stream changed.
891
+ */
892
+ #notifyThreadListeners() {
893
+ for (const listener of this.#threadListeners) listener(this.#thread);
894
+ }
895
+ };
896
+ /**
897
+ * Extract and coerce the configured messages key from a values object.
898
+ *
899
+ * @param values - State values object to read from.
900
+ * @param messagesKey - Key that contains the message array.
901
+ */
902
+ function extractAndCoerceMessages(values, messagesKey) {
903
+ const raw = values[messagesKey];
904
+ if (!Array.isArray(raw)) return [];
905
+ return ensureMessageInstances(raw);
906
+ }
907
+ //#endregion
908
+ export { ROOT_PUMP_CHANNELS, StreamController };
909
+
910
+ //# sourceMappingURL=controller.js.map