@athenaintel/react 0.43.0 → 0.50.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 (746) hide show
  1. package/README.md +258 -8
  2. package/dist/agent-runtime/src/answer-label.cjs +137 -0
  3. package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
  4. package/dist/agent-runtime/src/answer-label.d.ts +104 -0
  5. package/dist/agent-runtime/src/answer-label.js +137 -0
  6. package/dist/agent-runtime/src/answer-label.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-rows.cjs +180 -0
  8. package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
  9. package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
  10. package/dist/agent-runtime/src/answer-rows.js +180 -0
  11. package/dist/agent-runtime/src/answer-rows.js.map +1 -0
  12. package/dist/agent-runtime/src/call-recap.cjs +319 -0
  13. package/dist/agent-runtime/src/call-recap.cjs.map +1 -0
  14. package/dist/agent-runtime/src/call-recap.d.ts +142 -0
  15. package/dist/agent-runtime/src/call-recap.js +319 -0
  16. package/dist/agent-runtime/src/call-recap.js.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-store.cjs +1 -0
  18. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -1
  19. package/dist/agent-runtime/src/chat-outbox-store.d.ts +7 -0
  20. package/dist/agent-runtime/src/chat-outbox-store.js +1 -0
  21. package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -1
  22. package/dist/agent-runtime/src/chat-outbox.cjs +46 -5
  23. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
  24. package/dist/agent-runtime/src/chat-outbox.d.ts +29 -0
  25. package/dist/agent-runtime/src/chat-outbox.js +46 -5
  26. package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
  27. package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
  28. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  29. package/dist/agent-runtime/src/conversation-index.cjs +8 -8
  30. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
  31. package/dist/agent-runtime/src/conversation-index.d.ts +7 -0
  32. package/dist/agent-runtime/src/conversation-index.js.map +1 -1
  33. package/dist/agent-runtime/src/conversation-list.cjs +2 -1
  34. package/dist/agent-runtime/src/conversation-list.cjs.map +1 -1
  35. package/dist/agent-runtime/src/conversation-list.d.ts +19 -3
  36. package/dist/agent-runtime/src/conversation-list.js +2 -1
  37. package/dist/agent-runtime/src/conversation-list.js.map +1 -1
  38. package/dist/agent-runtime/src/decision-checks.cjs +207 -0
  39. package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
  40. package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
  41. package/dist/agent-runtime/src/decision-checks.js +207 -0
  42. package/dist/agent-runtime/src/decision-checks.js.map +1 -0
  43. package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
  44. package/dist/agent-runtime/src/errors.cjs +18 -0
  45. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  46. package/dist/agent-runtime/src/errors.d.ts +7 -0
  47. package/dist/agent-runtime/src/errors.js +18 -0
  48. package/dist/agent-runtime/src/errors.js.map +1 -1
  49. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
  50. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  51. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
  52. package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
  53. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  54. package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
  55. package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
  56. package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
  57. package/dist/agent-runtime/src/handoff-arrival.js +60 -0
  58. package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
  59. package/dist/agent-runtime/src/index.d.ts +16 -9
  60. package/dist/agent-runtime/src/interrupts.cjs +71 -19
  61. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  62. package/dist/agent-runtime/src/interrupts.d.ts +40 -3
  63. package/dist/agent-runtime/src/interrupts.js +56 -4
  64. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  65. package/dist/agent-runtime/src/lane-history.cjs +8 -8
  66. package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
  67. package/dist/agent-runtime/src/messages.cjs +43 -8
  68. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  69. package/dist/agent-runtime/src/messages.d.ts +25 -3
  70. package/dist/agent-runtime/src/messages.js +43 -8
  71. package/dist/agent-runtime/src/messages.js.map +1 -1
  72. package/dist/agent-runtime/src/model-context.cjs +3 -2
  73. package/dist/agent-runtime/src/model-context.cjs.map +1 -1
  74. package/dist/agent-runtime/src/model-context.d.ts +6 -1
  75. package/dist/agent-runtime/src/model-context.js +3 -2
  76. package/dist/agent-runtime/src/model-context.js.map +1 -1
  77. package/dist/agent-runtime/src/offline-status.cjs +36 -0
  78. package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
  79. package/dist/agent-runtime/src/offline-status.d.ts +118 -3
  80. package/dist/agent-runtime/src/offline-status.js +36 -0
  81. package/dist/agent-runtime/src/offline-status.js.map +1 -0
  82. package/dist/agent-runtime/src/queue.cjs +0 -9
  83. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  84. package/dist/agent-runtime/src/queue.js +0 -9
  85. package/dist/agent-runtime/src/queue.js.map +1 -1
  86. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
  87. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  88. package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
  89. package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
  90. package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
  91. package/dist/agent-runtime/src/runtime-catalog.js +42 -0
  92. package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
  93. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
  94. package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
  95. package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
  96. package/dist/agent-runtime/src/runtime.d.ts +41 -0
  97. package/dist/agent-runtime/src/send-recovery.cjs +37 -3
  98. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  99. package/dist/agent-runtime/src/send-recovery.d.ts +19 -0
  100. package/dist/agent-runtime/src/send-recovery.js +37 -3
  101. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  102. package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
  103. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  104. package/dist/agent-runtime/src/subagents.cjs +32 -2
  105. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  106. package/dist/agent-runtime/src/subagents.d.ts +9 -0
  107. package/dist/agent-runtime/src/subagents.js +30 -0
  108. package/dist/agent-runtime/src/subagents.js.map +1 -1
  109. package/dist/agent-runtime/src/thread-driver.cjs +67 -0
  110. package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
  111. package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
  112. package/dist/agent-runtime/src/thread-driver.js +67 -0
  113. package/dist/agent-runtime/src/thread-driver.js.map +1 -0
  114. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
  115. package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +868 -0
  116. package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
  117. package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
  118. package/dist/agent-runtime/src/thread-status.cjs +3 -3
  119. package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
  120. package/dist/agent-runtime/src/tool-metadata.cjs +210 -25
  121. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  122. package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
  123. package/dist/agent-runtime/src/tool-metadata.js +210 -25
  124. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  125. package/dist/agent-runtime/src/tool-names.cjs +2 -0
  126. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  127. package/dist/agent-runtime/src/tool-names.d.ts +2 -0
  128. package/dist/agent-runtime/src/tool-names.js +2 -0
  129. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  130. package/dist/agent-runtime/src/types.d.ts +10 -2
  131. package/dist/agent-runtime/src/use-conversation-list.cjs +14 -13
  132. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  133. package/dist/agent-runtime/src/use-conversation-list.d.ts +6 -0
  134. package/dist/agent-runtime/src/use-conversation-list.js +3 -2
  135. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  136. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +45 -20
  137. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  138. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +10 -3
  139. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +27 -2
  140. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  141. package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
  142. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  143. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
  144. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  145. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +40 -22
  146. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  147. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +17 -0
  148. package/dist/agent-runtime/src/use-deep-agent-runtime.js +24 -6
  149. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  150. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
  151. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  152. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +588 -130
  153. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  154. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +162 -10
  155. package/dist/agent-runtime/src/use-deep-agent-voice.js +529 -71
  156. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  157. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
  158. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  159. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
  160. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
  161. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +34 -26
  162. package/dist/agent-runtime/src/voice-earcon.cjs +139 -0
  163. package/dist/agent-runtime/src/voice-earcon.cjs.map +1 -0
  164. package/dist/agent-runtime/src/voice-earcon.d.ts +38 -0
  165. package/dist/agent-runtime/src/voice-earcon.js +139 -0
  166. package/dist/agent-runtime/src/voice-earcon.js.map +1 -0
  167. package/dist/agent-runtime/src/voice-media.cjs +117 -0
  168. package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
  169. package/dist/agent-runtime/src/voice-media.d.ts +63 -0
  170. package/dist/agent-runtime/src/voice-media.js +117 -0
  171. package/dist/agent-runtime/src/voice-media.js.map +1 -0
  172. package/dist/agent-runtime/src/voice-presentation.cjs +2 -0
  173. package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
  174. package/dist/agent-runtime/src/voice-presentation.js +2 -0
  175. package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
  176. package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
  177. package/dist/assets/AssetPanel.cjs +11 -11
  178. package/dist/assets/AssetPanel.cjs.map +1 -1
  179. package/dist/assets/AthenaAssetEmbed.cjs +11 -9
  180. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  181. package/dist/assets/AthenaAssetEmbed.d.ts +18 -5
  182. package/dist/assets/AthenaAssetEmbed.js +4 -2
  183. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  184. package/dist/assets/AthenaLayout.cjs +16 -16
  185. package/dist/assets/AthenaLayout.cjs.map +1 -1
  186. package/dist/assets/use-asset-content.cjs +4 -4
  187. package/dist/assets/use-asset-content.cjs.map +1 -1
  188. package/dist/assets/use-asset-embed.cjs +14 -7
  189. package/dist/assets/use-asset-embed.cjs.map +1 -1
  190. package/dist/assets/use-asset-embed.d.ts +23 -6
  191. package/dist/assets/use-asset-embed.js +10 -3
  192. package/dist/assets/use-asset-embed.js.map +1 -1
  193. package/dist/auth/AthenaAuthContext.cjs +3 -3
  194. package/dist/auth/AthenaAuthContext.cjs.map +1 -1
  195. package/dist/auth/AthenaAuthProvider.cjs +8 -8
  196. package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
  197. package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
  198. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  199. package/dist/auth/AthenaSSOProvider.cjs +14 -14
  200. package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
  201. package/dist/auth/credential-source.cjs +26 -13
  202. package/dist/auth/credential-source.cjs.map +1 -1
  203. package/dist/auth/credential-source.d.ts +8 -0
  204. package/dist/auth/credential-source.js +26 -13
  205. package/dist/auth/credential-source.js.map +1 -1
  206. package/dist/catalog/agent-model-options.cjs +25 -17
  207. package/dist/catalog/agent-model-options.cjs.map +1 -1
  208. package/dist/catalog/agent-model-options.d.ts +38 -5
  209. package/dist/catalog/agent-model-options.js +25 -17
  210. package/dist/catalog/agent-model-options.js.map +1 -1
  211. package/dist/catalog/channel-refusal.cjs +36 -0
  212. package/dist/catalog/channel-refusal.cjs.map +1 -0
  213. package/dist/catalog/channel-refusal.d.ts +29 -0
  214. package/dist/catalog/channel-refusal.js +36 -0
  215. package/dist/catalog/channel-refusal.js.map +1 -0
  216. package/dist/catalog/chat-pickers.cjs +60 -24
  217. package/dist/catalog/chat-pickers.cjs.map +1 -1
  218. package/dist/catalog/chat-pickers.d.ts +12 -2
  219. package/dist/catalog/chat-pickers.js +56 -20
  220. package/dist/catalog/chat-pickers.js.map +1 -1
  221. package/dist/catalog/runtime-catalog.cjs +89 -23
  222. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  223. package/dist/catalog/runtime-catalog.d.ts +8 -2
  224. package/dist/catalog/runtime-catalog.js +83 -17
  225. package/dist/catalog/runtime-catalog.js.map +1 -1
  226. package/dist/catalog/use-athena-chat-mode.cjs +12 -12
  227. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
  228. package/dist/chat/AthenaChat.cjs +155 -67
  229. package/dist/chat/AthenaChat.cjs.map +1 -1
  230. package/dist/chat/AthenaChat.d.ts +42 -2
  231. package/dist/chat/AthenaChat.js +106 -18
  232. package/dist/chat/AthenaChat.js.map +1 -1
  233. package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
  234. package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
  235. package/dist/chat/DrivingOnChip.cjs +23 -0
  236. package/dist/chat/DrivingOnChip.cjs.map +1 -0
  237. package/dist/chat/DrivingOnChip.d.ts +17 -0
  238. package/dist/chat/DrivingOnChip.js +23 -0
  239. package/dist/chat/DrivingOnChip.js.map +1 -0
  240. package/dist/chat/StatewireApprovalCard.cjs +166 -37
  241. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  242. package/dist/chat/StatewireApprovalCard.d.ts +91 -2
  243. package/dist/chat/StatewireApprovalCard.js +156 -27
  244. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  245. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  246. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  247. package/dist/chat/StatewireQueuedMessages.cjs +81 -69
  248. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.d.ts +25 -13
  250. package/dist/chat/StatewireQueuedMessages.js +73 -61
  251. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  252. package/dist/chat/WaitingOnYouBanner.cjs +9 -5
  253. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  254. package/dist/chat/WaitingOnYouBanner.js +7 -3
  255. package/dist/chat/WaitingOnYouBanner.js.map +1 -1
  256. package/dist/chat/athena-chat-welcome.cjs +2 -2
  257. package/dist/chat/athena-chat-welcome.cjs.map +1 -1
  258. package/dist/chat/athena-citation-links.cjs +5 -5
  259. package/dist/chat/athena-citation-links.cjs.map +1 -1
  260. package/dist/chat/athena-composer-controls.cjs +26 -16
  261. package/dist/chat/athena-composer-controls.cjs.map +1 -1
  262. package/dist/chat/athena-composer-controls.d.ts +6 -0
  263. package/dist/chat/athena-composer-controls.js +26 -16
  264. package/dist/chat/athena-composer-controls.js.map +1 -1
  265. package/dist/chat/athena-turn-end-status.cjs +42 -0
  266. package/dist/chat/athena-turn-end-status.cjs.map +1 -0
  267. package/dist/chat/athena-turn-end-status.d.ts +24 -0
  268. package/dist/chat/athena-turn-end-status.js +42 -0
  269. package/dist/chat/athena-turn-end-status.js.map +1 -0
  270. package/dist/chat/browser-decision-check.cjs +131 -0
  271. package/dist/chat/browser-decision-check.cjs.map +1 -0
  272. package/dist/chat/browser-decision-check.d.ts +61 -0
  273. package/dist/chat/browser-decision-check.js +131 -0
  274. package/dist/chat/browser-decision-check.js.map +1 -0
  275. package/dist/chat/chat-outbox-rows.cjs +3 -3
  276. package/dist/chat/chat-outbox-rows.cjs.map +1 -1
  277. package/dist/chat/chat-voice-controls.cjs +96 -29
  278. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  279. package/dist/chat/chat-voice-controls.d.ts +42 -3
  280. package/dist/chat/chat-voice-controls.js +92 -25
  281. package/dist/chat/chat-voice-controls.js.map +1 -1
  282. package/dist/chat/composer-keyboard-hint.cjs +5 -5
  283. package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
  284. package/dist/chat/device-operation.cjs +29 -0
  285. package/dist/chat/device-operation.cjs.map +1 -0
  286. package/dist/chat/device-operation.d.ts +34 -0
  287. package/dist/chat/device-operation.js +29 -0
  288. package/dist/chat/device-operation.js.map +1 -0
  289. package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
  290. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  291. package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
  292. package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
  293. package/dist/chat/super-grouping/SuperGroupingCard.cjs +52 -36
  294. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  295. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
  296. package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
  297. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  298. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
  299. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  300. package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
  301. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  302. package/dist/chat/super-grouping/ToolTimeline.cjs +73 -40
  303. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  304. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
  305. package/dist/chat/super-grouping/ToolTimeline.js +69 -36
  306. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  307. package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
  308. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  309. package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
  310. package/dist/chat/super-grouping/activity-timeline.js +47 -12
  311. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  312. package/dist/chat/super-grouping/grouping-function.cjs +4 -0
  313. package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
  314. package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
  315. package/dist/chat/super-grouping/grouping-function.js +5 -1
  316. package/dist/chat/super-grouping/grouping-function.js.map +1 -1
  317. package/dist/chat/super-grouping/index.cjs +6 -0
  318. package/dist/chat/super-grouping/index.cjs.map +1 -1
  319. package/dist/chat/super-grouping/index.d.ts +5 -2
  320. package/dist/chat/super-grouping/index.js +7 -1
  321. package/dist/chat/super-grouping/index.js.map +1 -1
  322. package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
  323. package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
  324. package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
  325. package/dist/chat/super-grouping/tool-part-placement.js +17 -0
  326. package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
  327. package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
  328. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
  329. package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
  330. package/dist/chat/thread-scroll-to-bottom.js +2 -2
  331. package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
  332. package/dist/chat/tooltip-icon-button.cjs +2 -2
  333. package/dist/chat/tooltip-icon-button.cjs.map +1 -1
  334. package/dist/chat/use-athena-voice-live.cjs +11 -0
  335. package/dist/chat/use-athena-voice-live.cjs.map +1 -0
  336. package/dist/chat/use-athena-voice-live.d.ts +11 -0
  337. package/dist/chat/use-athena-voice-live.js +11 -0
  338. package/dist/chat/use-athena-voice-live.js.map +1 -0
  339. package/dist/chat/use-statewire-approval-request.cjs +56 -24
  340. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  341. package/dist/chat/use-statewire-approval-request.d.ts +33 -4
  342. package/dist/chat/use-statewire-approval-request.js +41 -9
  343. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  344. package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
  345. package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
  346. package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
  347. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  348. package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
  349. package/dist/chat-ui/composer/tiptap-composer.js +85 -54
  350. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  351. package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
  352. package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
  353. package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
  354. package/dist/chat-ui/header/conversation-history-panel.js +38 -12
  355. package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
  356. package/dist/chat-ui/index.cjs +21 -0
  357. package/dist/chat-ui/index.cjs.map +1 -1
  358. package/dist/chat-ui/index.d.ts +8 -1
  359. package/dist/chat-ui/index.js +21 -0
  360. package/dist/chat-ui/index.js.map +1 -1
  361. package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
  362. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  363. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
  364. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  365. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
  366. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  367. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
  368. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  369. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
  370. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  371. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
  372. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
  373. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  374. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
  375. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
  376. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
  377. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
  378. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
  379. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  380. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
  381. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
  382. package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
  383. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
  384. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
  385. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
  386. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  387. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
  388. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
  389. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
  391. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
  393. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
  394. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  395. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
  396. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
  397. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
  398. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
  399. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
  400. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
  401. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  402. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
  403. package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
  404. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  405. package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
  406. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
  407. package/dist/chat-ui/mentions/use-mention-asset.cjs +3 -3
  408. package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
  409. package/dist/chat-ui/messages/answer-label.cjs +42 -0
  410. package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
  411. package/dist/chat-ui/messages/answer-label.d.ts +33 -0
  412. package/dist/chat-ui/messages/answer-label.js +42 -0
  413. package/dist/chat-ui/messages/answer-label.js.map +1 -0
  414. package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
  415. package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
  416. package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
  417. package/dist/chat-ui/messages/arrival-animation.js +13 -0
  418. package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
  419. package/dist/chat-ui/messages/continue-pill.cjs +5 -5
  420. package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
  421. package/dist/chat-ui/messages/from-the-call-card.cjs +124 -0
  422. package/dist/chat-ui/messages/from-the-call-card.cjs.map +1 -0
  423. package/dist/chat-ui/messages/from-the-call-card.d.ts +17 -0
  424. package/dist/chat-ui/messages/from-the-call-card.js +124 -0
  425. package/dist/chat-ui/messages/from-the-call-card.js.map +1 -0
  426. package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
  427. package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
  428. package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
  429. package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
  430. package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
  431. package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
  432. package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
  433. package/dist/chat-ui/messages/message-components.cjs +8 -4
  434. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  435. package/dist/chat-ui/messages/message-components.js +5 -1
  436. package/dist/chat-ui/messages/message-components.js.map +1 -1
  437. package/dist/chat-ui/messages/message-images.cjs +66 -0
  438. package/dist/chat-ui/messages/message-images.cjs.map +1 -0
  439. package/dist/chat-ui/messages/message-images.d.ts +16 -0
  440. package/dist/chat-ui/messages/message-images.js +66 -0
  441. package/dist/chat-ui/messages/message-images.js.map +1 -0
  442. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
  443. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  444. package/dist/chat-ui/messages/wake-marker.cjs +3 -3
  445. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  446. package/dist/chat-ui/rich-text/chat-link.cjs +3 -2
  447. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
  448. package/dist/chat-ui/rich-text/chat-link.d.ts +4 -0
  449. package/dist/chat-ui/rich-text/chat-link.js +4 -3
  450. package/dist/chat-ui/rich-text/chat-link.js.map +1 -1
  451. package/dist/chat-ui/rich-text/chat-message-body.cjs +9 -8
  452. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  453. package/dist/chat-ui/rich-text/chat-message-body.d.ts +12 -0
  454. package/dist/chat-ui/rich-text/chat-message-body.js +2 -1
  455. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
  456. package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
  457. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  458. package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
  459. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
  460. package/dist/chat-ui/statewire.cjs +3 -0
  461. package/dist/chat-ui/statewire.cjs.map +1 -1
  462. package/dist/chat-ui/statewire.d.ts +2 -1
  463. package/dist/chat-ui/statewire.js +3 -0
  464. package/dist/chat-ui/statewire.js.map +1 -1
  465. package/dist/chat-ui/thread/chat-thread-shell.cjs +45 -14
  466. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  467. package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
  468. package/dist/chat-ui/thread/chat-thread-shell.js +37 -6
  469. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  470. package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
  471. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  472. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
  473. package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
  474. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  475. package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
  476. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  477. package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
  478. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  479. package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
  480. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
  481. package/dist/collab/client.cjs +52 -3
  482. package/dist/collab/client.cjs.map +1 -1
  483. package/dist/collab/client.d.ts +27 -0
  484. package/dist/collab/client.js +52 -3
  485. package/dist/collab/client.js.map +1 -1
  486. package/dist/collab/document-status.cjs +150 -0
  487. package/dist/collab/document-status.cjs.map +1 -0
  488. package/dist/collab/document-status.d.ts +68 -0
  489. package/dist/collab/document-status.js +150 -0
  490. package/dist/collab/document-status.js.map +1 -0
  491. package/dist/collab/index.cjs +7 -0
  492. package/dist/collab/index.cjs.map +1 -1
  493. package/dist/collab/index.d.ts +6 -1
  494. package/dist/collab/index.js +7 -0
  495. package/dist/collab/index.js.map +1 -1
  496. package/dist/collab/presence-react.cjs +11 -11
  497. package/dist/collab/presence-react.cjs.map +1 -1
  498. package/dist/collab/react.cjs +6 -6
  499. package/dist/collab/react.cjs.map +1 -1
  500. package/dist/composer/AttachmentContext.cjs +24 -11
  501. package/dist/composer/AttachmentContext.cjs.map +1 -1
  502. package/dist/composer/AttachmentContext.js +18 -5
  503. package/dist/composer/AttachmentContext.js.map +1 -1
  504. package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
  505. package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
  506. package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
  507. package/dist/composer/ComposerAttachmentPreview.js +79 -24
  508. package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
  509. package/dist/composer/ComposerDropZone.cjs +7 -7
  510. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  511. package/dist/composer/FileUploadButton.cjs +37 -22
  512. package/dist/composer/FileUploadButton.cjs.map +1 -1
  513. package/dist/composer/FileUploadButton.d.ts +6 -0
  514. package/dist/composer/FileUploadButton.js +34 -19
  515. package/dist/composer/FileUploadButton.js.map +1 -1
  516. package/dist/composer/QuoteContext.cjs +8 -8
  517. package/dist/composer/QuoteContext.cjs.map +1 -1
  518. package/dist/composer/composer-handoff.cjs +4 -4
  519. package/dist/composer/composer-handoff.cjs.map +1 -1
  520. package/dist/composer/index.d.ts +1 -1
  521. package/dist/composer/useAppendToComposer.cjs +4 -4
  522. package/dist/composer/useAppendToComposer.cjs.map +1 -1
  523. package/dist/composer/useAttachFiles.cjs +23 -6
  524. package/dist/composer/useAttachFiles.cjs.map +1 -1
  525. package/dist/composer/useAttachFiles.d.ts +15 -7
  526. package/dist/composer/useAttachFiles.js +22 -5
  527. package/dist/composer/useAttachFiles.js.map +1 -1
  528. package/dist/composer/useComposerAttachment.cjs +4 -4
  529. package/dist/composer/useComposerAttachment.cjs.map +1 -1
  530. package/dist/composer/useFileUpload.cjs +21 -16
  531. package/dist/composer/useFileUpload.cjs.map +1 -1
  532. package/dist/composer/useFileUpload.d.ts +12 -0
  533. package/dist/composer/useFileUpload.js +12 -7
  534. package/dist/composer/useFileUpload.js.map +1 -1
  535. package/dist/composer/useReadComposerDraft.cjs +27 -8
  536. package/dist/composer/useReadComposerDraft.cjs.map +1 -1
  537. package/dist/composer/useReadComposerDraft.d.ts +23 -1
  538. package/dist/composer/useReadComposerDraft.js +27 -8
  539. package/dist/composer/useReadComposerDraft.js.map +1 -1
  540. package/dist/composer/useSendMessage.cjs +4 -4
  541. package/dist/composer/useSendMessage.cjs.map +1 -1
  542. package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
  543. package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
  544. package/dist/dictation/audio-level-history.cjs +3 -3
  545. package/dist/dictation/audio-level-history.cjs.map +1 -1
  546. package/dist/dictation/dictation-controls.cjs +24 -20
  547. package/dist/dictation/dictation-controls.cjs.map +1 -1
  548. package/dist/dictation/dictation-controls.d.ts +6 -1
  549. package/dist/dictation/dictation-controls.js +24 -20
  550. package/dist/dictation/dictation-controls.js.map +1 -1
  551. package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
  552. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
  553. package/dist/dictation/use-dictation.cjs +22 -22
  554. package/dist/dictation/use-dictation.cjs.map +1 -1
  555. package/dist/index.cjs +29 -2
  556. package/dist/index.cjs.map +1 -1
  557. package/dist/index.d.ts +18 -4
  558. package/dist/index.js +30 -3
  559. package/dist/index.js.map +1 -1
  560. package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
  561. package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
  562. package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
  563. package/dist/keryx-http/src/receive-only-socket.js +40 -0
  564. package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
  565. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs +190 -0
  566. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs.map +1 -0
  567. package/dist/keryx-http/src/unconfirmed-update-attributions.d.ts +132 -0
  568. package/dist/keryx-http/src/unconfirmed-update-attributions.js +190 -0
  569. package/dist/keryx-http/src/unconfirmed-update-attributions.js.map +1 -0
  570. package/dist/keryx-http/src/update-attributions.cjs +141 -0
  571. package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
  572. package/dist/keryx-http/src/update-attributions.d.ts +107 -0
  573. package/dist/keryx-http/src/update-attributions.js +141 -0
  574. package/dist/keryx-http/src/update-attributions.js.map +1 -0
  575. package/dist/lib/owner-document.cjs +6 -6
  576. package/dist/lib/owner-document.cjs.map +1 -1
  577. package/dist/lib/use-athena-rest-query.cjs +4 -4
  578. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  579. package/dist/lib/use-document-active.cjs +4 -4
  580. package/dist/lib/use-document-active.cjs.map +1 -1
  581. package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
  582. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
  583. package/dist/offline/offline-history.cjs +7 -7
  584. package/dist/offline/offline-history.cjs.map +1 -1
  585. package/dist/provider/AthenaContext.cjs +3 -3
  586. package/dist/provider/AthenaContext.cjs.map +1 -1
  587. package/dist/provider/AthenaProvider.cjs +120 -79
  588. package/dist/provider/AthenaProvider.cjs.map +1 -1
  589. package/dist/provider/AthenaProvider.d.ts +11 -1
  590. package/dist/provider/AthenaProvider.js +44 -3
  591. package/dist/provider/AthenaProvider.js.map +1 -1
  592. package/dist/provider/PostHogProvider.cjs +2 -2
  593. package/dist/provider/PostHogProvider.cjs.map +1 -1
  594. package/dist/provider/agent-selection-context.cjs +2 -2
  595. package/dist/provider/agent-selection-context.cjs.map +1 -1
  596. package/dist/provider/chat-mode-context.cjs +2 -2
  597. package/dist/provider/chat-mode-context.cjs.map +1 -1
  598. package/dist/provider/session-persistence-context.cjs +10 -0
  599. package/dist/provider/session-persistence-context.cjs.map +1 -0
  600. package/dist/provider/session-persistence-context.d.ts +15 -0
  601. package/dist/provider/session-persistence-context.js +10 -0
  602. package/dist/provider/session-persistence-context.js.map +1 -0
  603. package/dist/provider/statewire-history-context.cjs +4 -4
  604. package/dist/provider/statewire-history-context.cjs.map +1 -1
  605. package/dist/provider/statewire-lifecycle-context.cjs +3 -3
  606. package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
  607. package/dist/provider/statewire-window-context.cjs +3 -3
  608. package/dist/provider/statewire-window-context.cjs.map +1 -1
  609. package/dist/provider/theme-style-context.cjs +3 -3
  610. package/dist/provider/theme-style-context.cjs.map +1 -1
  611. package/dist/react/package.json.cjs +1 -1
  612. package/dist/react/package.json.js +1 -1
  613. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
  614. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  615. package/dist/runtime/auth-refusal-restart.cjs +7 -7
  616. package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
  617. package/dist/runtime/auth.cjs +13 -13
  618. package/dist/runtime/auth.cjs.map +1 -1
  619. package/dist/runtime/statewire-lifecycle.cjs +1 -0
  620. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  621. package/dist/runtime/statewire-lifecycle.d.ts +3 -1
  622. package/dist/runtime/statewire-lifecycle.js +2 -1
  623. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  624. package/dist/runtime/statewire-server-lane-context.cjs +2 -2
  625. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  626. package/dist/runtime/statewire-session-lane.cjs +4 -4
  627. package/dist/runtime/statewire-session-lane.cjs.map +1 -1
  628. package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
  629. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  630. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  631. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  632. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  633. package/dist/styles.css +1 -1
  634. package/dist/threads/Inbox.cjs +8 -8
  635. package/dist/threads/Inbox.cjs.map +1 -1
  636. package/dist/threads/SessionList.cjs +9 -9
  637. package/dist/threads/SessionList.cjs.map +1 -1
  638. package/dist/threads/SessionsPage.cjs +11 -11
  639. package/dist/threads/SessionsPage.cjs.map +1 -1
  640. package/dist/threads/api.cjs.map +1 -1
  641. package/dist/threads/api.d.ts +15 -0
  642. package/dist/threads/api.js.map +1 -1
  643. package/dist/threads/conversation-list-fetcher.cjs +13 -5
  644. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  645. package/dist/threads/conversation-list-fetcher.d.ts +4 -1
  646. package/dist/threads/conversation-list-fetcher.js +13 -5
  647. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  648. package/dist/threads/index-triggered-refresh.cjs +10 -10
  649. package/dist/threads/index-triggered-refresh.cjs.map +1 -1
  650. package/dist/threads/mark-viewed-thread-read.cjs +12 -12
  651. package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
  652. package/dist/threads/offline-session-list.cjs +3 -3
  653. package/dist/threads/offline-session-list.cjs.map +1 -1
  654. package/dist/threads/session-list-tab-share.cjs +5 -5
  655. package/dist/threads/session-list-tab-share.cjs.map +1 -1
  656. package/dist/threads/statewire-thread-list.cjs +79 -57
  657. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  658. package/dist/threads/statewire-thread-list.d.ts +20 -8
  659. package/dist/threads/statewire-thread-list.js +28 -6
  660. package/dist/threads/statewire-thread-list.js.map +1 -1
  661. package/dist/threads/thread-id-context.cjs +5 -5
  662. package/dist/threads/thread-id-context.cjs.map +1 -1
  663. package/dist/threads/use-athena-session-attention.cjs +2 -2
  664. package/dist/threads/use-athena-session-attention.cjs.map +1 -1
  665. package/dist/threads/use-athena-sessions.cjs +37 -15
  666. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  667. package/dist/threads/use-athena-sessions.d.ts +10 -5
  668. package/dist/threads/use-athena-sessions.js +28 -6
  669. package/dist/threads/use-athena-sessions.js.map +1 -1
  670. package/dist/threads/use-athena-thread-model.cjs +3 -3
  671. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  672. package/dist/threads/use-rest-conversation-history.cjs +3 -3
  673. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  674. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  675. package/dist/threads/use-statewire-conversation-history.cjs +8 -8
  676. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  677. package/dist/threads/use-thread-archive.cjs +9 -9
  678. package/dist/threads/use-thread-archive.cjs.map +1 -1
  679. package/dist/threads/use-thread-favorite.cjs +2 -2
  680. package/dist/threads/use-thread-favorite.cjs.map +1 -1
  681. package/dist/threads/use-thread-field-override.cjs +20 -20
  682. package/dist/threads/use-thread-field-override.cjs.map +1 -1
  683. package/dist/threads/use-thread-read-state.cjs +4 -4
  684. package/dist/threads/use-thread-read-state.cjs.map +1 -1
  685. package/dist/threads/use-thread-rename.cjs +2 -2
  686. package/dist/threads/use-thread-rename.cjs.map +1 -1
  687. package/dist/threads/useAthenaThreadManager.cjs +2 -2
  688. package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
  689. package/dist/tools/NestedPtcMessages.cjs +6 -6
  690. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  691. package/dist/tools/append-document-tool-ui.cjs +7 -7
  692. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  693. package/dist/tools/file-tool-uis.cjs +2 -2
  694. package/dist/tools/file-tool-uis.cjs.map +1 -1
  695. package/dist/tools/misc-tool-uis.cjs +2 -2
  696. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  697. package/dist/tools/primitives.cjs +6 -6
  698. package/dist/tools/primitives.cjs.map +1 -1
  699. package/dist/tools/read-asset-tool-ui.cjs +6 -6
  700. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  701. package/dist/tools/subagent-task-tool-ui.cjs +21 -21
  702. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  703. package/dist/tools/test-recording-tool-uis.cjs +16 -16
  704. package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
  705. package/dist/tools/todo-plan-store.cjs +4 -4
  706. package/dist/tools/todo-plan-store.cjs.map +1 -1
  707. package/dist/tools/tool-appearance.cjs +3 -3
  708. package/dist/tools/tool-appearance.cjs.map +1 -1
  709. package/dist/tools/tool-fallback.cjs +14 -14
  710. package/dist/tools/tool-fallback.cjs.map +1 -1
  711. package/dist/tools/tool-uis.cjs +74 -74
  712. package/dist/tools/tool-uis.cjs.map +1 -1
  713. package/dist/tools/use-elapsed-seconds.cjs +3 -3
  714. package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
  715. package/dist/tools/write-todos-tool-ui.cjs +9 -9
  716. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  717. package/dist/ui/image-viewer.cjs +382 -0
  718. package/dist/ui/image-viewer.cjs.map +1 -0
  719. package/dist/ui/image-viewer.d.ts +50 -0
  720. package/dist/ui/image-viewer.js +382 -0
  721. package/dist/ui/image-viewer.js.map +1 -0
  722. package/dist/voice/chat.cjs +6 -0
  723. package/dist/voice/chat.cjs.map +1 -1
  724. package/dist/voice/chat.d.ts +1 -1
  725. package/dist/voice/chat.js +8 -2
  726. package/dist/voice/livekit-join.cjs +52 -101
  727. package/dist/voice/livekit-join.cjs.map +1 -1
  728. package/dist/voice/livekit-join.d.ts +1 -6
  729. package/dist/voice/livekit-join.js +52 -101
  730. package/dist/voice/livekit-join.js.map +1 -1
  731. package/dist/voice/livekit.cjs.map +1 -1
  732. package/dist/voice/livekit.d.ts +11 -1
  733. package/dist/voice/livekit.js.map +1 -1
  734. package/dist/voice/use-athena-voice-session.cjs +34 -34
  735. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  736. package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
  737. package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
  738. package/dist/workbench/SessionWorkbench.cjs +22 -22
  739. package/dist/workbench/SessionWorkbench.cjs.map +1 -1
  740. package/dist/workbench/session-workbench-context.cjs +3 -3
  741. package/dist/workbench/session-workbench-context.cjs.map +1 -1
  742. package/dist/workbench/session-workbench-panes.cjs +8 -8
  743. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  744. package/dist/workbench/workbench-layout-context.cjs +3 -3
  745. package/dist/workbench/workbench-layout-context.cjs.map +1 -1
  746. package/package.json +2 -1
@@ -0,0 +1,41 @@
1
+ /** Shared chat runtime exports, without initializing optional handoff controllers. */
2
+ export { answerLabelText, type DeepAgentAnsweredBy, readMessageAnswers, showsAnswerLabel, threadShowsAnswerLabels, } from "./answer-label";
3
+ export { type ChatAssetUploadResponse, uploadChatAsset, uploadedChatAsset, } from "./asset-attachment";
4
+ export { CHAT_EDIT_UNREACHABLE_LABEL, CHAT_OUTBOX_ASK_AFTER_MS, CHAT_OUTBOX_CLAIM_LEASE_MS, type ChatOutbox, type ChatOutboxEvent, type ChatOutboxRow, } from "./chat-outbox";
5
+ export { type ChatOutboxAttachmentCheck, chatOutboxAttachmentPath, createChatOutboxAttachmentCheck, } from "./chat-outbox-attachments";
6
+ export { type ChatOutboxRecord, createMemoryChatOutboxStore, parseChatOutboxEntry, readChatOutboxClaim, readChatOutboxFailure, withChatOutboxMemoryFallback, } from "./chat-outbox-store";
7
+ export { type ClientToolBridgeTool, useStatewireClientToolBridge, } from "./client-tool-bridge";
8
+ export { createClientToolRequestTracker } from "./client-tools";
9
+ export { pickThreadConfigCustom, type ThreadConfigPatch, } from "./config-mutations";
10
+ export { type ConversationIndexEntry, conversationIndexFingerprint, useConversationIndex, } from "./conversation-index";
11
+ export { type ConversationListPage, type ConversationSummary, mergeConversationIndexIntoPage, } from "./conversation-list";
12
+ export { isLegacyThreadReadOnlyRejection, isStatewireChannelTeardown, isStatewireRewindAnchorRejection, statewireRejectionDetailMessage, statewireRejectionPayload, } from "./errors";
13
+ export { asHitlApproval, findAbandonedInterrupt, HITL_PENDING_RESUME_GRACE_MS, type HitlApprovalPayload, hitlResumeApprove, hitlResumeReject, interruptResumeDecline, isApprovalCardInterrupt, pendingActionRequests, readAbandonedInputRequests, readInterruptMessage, toolCallIdsAwaitingApproval, useApprovalResumeLock, } from "./interrupts";
14
+ export { type DeepAgentMessageWindowDeclaration } from "./message-window";
15
+ export { ATHENA_RUN_MARKER_KEY, isQueuedLaneMessage, } from "./messages";
16
+ export { isDeepAgentHostState } from "./protocol";
17
+ export { parkIncompatibleSessionCommands } from "./quota-safe-local-storage-session";
18
+ export { type AthenaRuntimeMessageKind, readRuntimeMessageFromSourceMessages, readSoleRuntimeMessageKind, runtimeMessageMarkerText, } from "./runtime-messages";
19
+ export { createStatewireDiagnosticsRecorder } from "./statewire-diagnostics";
20
+ export { isDeepAgentStateHydrated } from "./statewire-state";
21
+ export { DEEP_AGENT_STATEWIRE_PROTOCOL } from "./statewire-transport";
22
+ export { hideUnterminatedMarkdownLink } from "./streaming-markdown";
23
+ export { nestedMessagesFromArtifact } from "./subagents";
24
+ export { hasStatewireThreadExtras } from "./thread-extras";
25
+ export { createDeepAgentThreadSnapshotCache, type DeepAgentThreadSnapshotCache, } from "./thread-snapshot-cache";
26
+ export { useDeepAgentThreadStatus } from "./thread-status";
27
+ export { describeToolArgs, formatToolName, getCategoryEmoji, getToolDisplayMeta, knownToolNames, } from "./tool-metadata";
28
+ export { createDeepAgentToolOutputStore, type DeepAgentToolOutputStore, } from "./tool-outputs";
29
+ export { classifyToolResult } from "./tool-result";
30
+ export { type DeepAgentConnectionState, type DeepAgentStreamValues, } from "./types";
31
+ export { DeepAgentChatOutboxContext, useChatOutboxReachable, useChatOutboxSnapshot, useDeepAgentChatOutbox, useDeepAgentChatOutboxContext, } from "./use-deep-agent-chat-outbox";
32
+ export { type DeepAgentConfigWriteResult, isConfigWriteForbiddenRejection, useDeepAgentConfig, } from "./use-deep-agent-config";
33
+ export { useDeepAgentMessageEditSubmit } from "./use-deep-agent-edit-submit";
34
+ export { type DeepAgentThreadElement, logUnhandledStatewireError, useDeepAgentRuntime, } from "./use-deep-agent-runtime";
35
+ export { describeVoiceFailure, describeVoiceLiveElsewhere, type DeepAgentVoiceCallMove, type DeepAgentVoiceSurface, playVoiceMoveEarcon, useDeepAgentVoice, type UseDeepAgentVoiceReturn, useVoiceElapsed, useVoiceMovedNotice, VOICE_CONTINUE_BY_VOICE_LABEL, VOICE_MOVE_CALL_HERE_LABEL, VOICE_MOVE_EARCON_MS, VOICE_MOVE_HERE_ACTION, voiceMoveEarconDataUri, } from "./use-deep-agent-voice";
36
+ export { useDeepAgentWindowSync } from "./use-deep-agent-window-sync";
37
+ export { describeVoiceUpdateToolCall, isVoiceDelegationMessage, VOICE_LIVE_TYPED_HINT, VOICE_UPDATE_TOOL_NAME, voiceProvenanceLabel, voiceUpdateStatusLabel, } from "./voice-presentation";
38
+ export { CALL_RECAP_APPROVAL_LABEL, CALL_RECAP_TITLE, type CallRecap, type CallRecapApproval, type CallRecapAsset, type CallRecapItem, type CallRecapLink, type CallRecapMessage, type CallRecapOpenToolCall, type CallRecapPart, callRecapAfter, callRecapHasItems, callRecapItems, isCallUserMessage, mayHaveLiveCall, VOICE_TYPED_ID_PREFIX, } from "./call-recap";
39
+ export { type ResumeExtras } from "./interrupts";
40
+ export { resumeValueApproves } from "./interrupts";
41
+ export { statewireAnswerDescriptors } from "./decision-checks";
@@ -4,12 +4,16 @@ const statewireState = require("./statewire-state.cjs");
4
4
  const AUTO_RETRY_FATES = /* @__PURE__ */ new Set(["lost", "aborted"]);
5
5
  const MAX_AUTO_RETRIES_PER_MESSAGE = 3;
6
6
  const MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1e3;
7
+ const MAX_BEFORE_RETRY_HOLDS = 10;
7
8
  function shouldAutoRetryFailedSend(failure) {
8
9
  return failure !== void 0 && AUTO_RETRY_FATES.has(failure.fate);
9
10
  }
10
11
  function awaitsLostPredecessor(entry) {
11
12
  return entry.sendFailure.fate === "aborted" && entry.sendFailure.predecessorLost === true;
12
13
  }
14
+ function isThenable(value) {
15
+ return typeof value === "object" && value !== null && typeof value.then === "function";
16
+ }
13
17
  function commandMessageId(update) {
14
18
  var _a, _b;
15
19
  const first = (_a = update.params) == null ? void 0 : _a[0];
@@ -28,14 +32,16 @@ function createDeepAgentSendRecovery(options) {
28
32
  const surfacedDeferrals = /* @__PURE__ */ new Set();
29
33
  const inFlight = /* @__PURE__ */ new Set();
30
34
  const deferred = /* @__PURE__ */ new Set();
35
+ const holds = /* @__PURE__ */ new Map();
36
+ let holding = false;
31
37
  const record = (event, data) => {
32
38
  var _a, _b;
33
39
  (_b = (_a = options.diagnostics) == null ? void 0 : _a.call(options)) == null ? void 0 : _b.record(event, data);
34
40
  };
35
41
  const sweep = () => {
36
- var _a;
42
+ var _a, _b;
37
43
  sweepScheduled = false;
38
- if (disposed || !hydrated || !armed) return;
44
+ if (disposed || holding || !hydrated || !armed) return;
39
45
  const lane = options.lane();
40
46
  if (lane === null) return;
41
47
  armed = false;
@@ -75,6 +81,29 @@ function createDeepAgentSendRecovery(options) {
75
81
  if (isLost) lostPredecessorPending = true;
76
82
  continue;
77
83
  }
84
+ let before;
85
+ try {
86
+ before = (_b = options.beforeRetry) == null ? void 0 : _b.call(options, entry.id);
87
+ } catch {
88
+ record("send-recovery/before-retry-failed", { messageId: entry.id });
89
+ }
90
+ if (isThenable(before)) {
91
+ const held = (holds.get(entry.id) ?? 0) + 1;
92
+ if (held <= MAX_BEFORE_RETRY_HOLDS) {
93
+ holds.set(entry.id, held);
94
+ holding = true;
95
+ armed = true;
96
+ record("send-recovery/held", { messageId: entry.id, holds: held });
97
+ const resume = () => {
98
+ holding = false;
99
+ armed = true;
100
+ scheduleSweep();
101
+ };
102
+ before.then(resume, resume);
103
+ return;
104
+ }
105
+ record("send-recovery/held-too-long", { messageId: entry.id });
106
+ }
78
107
  try {
79
108
  lane.retryFailed(entry.id);
80
109
  attempts.set(entry.id, attempt);
@@ -87,12 +116,16 @@ function createDeepAgentSendRecovery(options) {
87
116
  });
88
117
  } catch {
89
118
  record("send-recovery/raced", { messageId: entry.id });
119
+ try {
120
+ if (typeof before === "function") before();
121
+ } catch {
122
+ }
90
123
  }
91
124
  }
92
125
  if (deferred.size > 0) armed = true;
93
126
  };
94
127
  const scheduleSweep = () => {
95
- if (disposed || sweepScheduled || !hydrated || !armed) return;
128
+ if (disposed || sweepScheduled || holding || !hydrated || !armed) return;
96
129
  sweepScheduled = true;
97
130
  schedule(sweep);
98
131
  };
@@ -123,6 +156,7 @@ function createDeepAgentSendRecovery(options) {
123
156
  }
124
157
  };
125
158
  }
159
+ exports.MAX_BEFORE_RETRY_HOLDS = MAX_BEFORE_RETRY_HOLDS;
126
160
  exports.createDeepAgentSendRecovery = createDeepAgentSendRecovery;
127
161
  exports.shouldAutoRetryFailedSend = shouldAutoRetryFailedSend;
128
162
  //# sourceMappingURL=send-recovery.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"send-recovery.cjs","sources":["../../../../agent-runtime/src/send-recovery.ts"],"sourcesContent":["import type {\n StatewireDiagnosticsCommandUpdate,\n StatewireDiagnosticsRecorder,\n} from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated } from './statewire-state';\nimport type { StatewireFailedSendEntry, StatewireFailedSendLane } from './thread-extras';\n\n/**\n * Transport-level send durability for the deep-agent thread (the successor to\n * Olympus' localStorage outbox, #29368 → #31504).\n *\n * The durable journal itself is the statewire session record: every command is\n * persisted through the mounted session storage from `send()` until the server\n * durably admits or judges it, and a reload resends survivors on the SAME lane\n * seq (exactly-once — the server absorbs replayed seqs at or below its\n * watermark). What the record cannot recover on its own is a send the client\n * had to settle without a server verdict — a proven session loss or a record\n * reset settles it `lost`/`aborted` and RETAINS it in the record's failed lane\n * (message-carrying sends only), where the vendor drops it as soon as a\n * canonical snapshot shows the message landed (`failureCovered`).\n *\n * This controller turns that persisted failed lane back into live sends: once\n * the thread snapshot has hydrated (so covered entries are already gone), every\n * failed send the server NEVER judged is re-dispatched through the thread's own\n * `retryFailed` — same client-minted message id, re-anchored against the\n * current thread — which the host dedupes by id (a still-queued id re-places,\n * a durable one rejects `duplicate-id`). Server-judged fates (`rejected`,\n * `failed`, `crashed`, `expired`) are the user's decision and stay in the\n * manual retry/discard affordance.\n *\n * Ordering: an `aborted` send stamped `predecessorLost` was never attempted\n * because an earlier send of the same batch WAS attempted and settled `lost`\n * — it may or may not have run. Re-dispatching the successor first could land\n * it ahead of a predecessor that later turns out to have landed too, so the\n * successor is held until every preceding `lost` predecessor has settled: it\n * was covered by a snapshot, its retry was judged by the server, or the user\n * discarded it.\n */\n\n/** Fates the server never saw: the send died client-side (unmount, stream\n * gone, session lost) and is safe to re-dispatch under its original message\n * id. The complement — rejected/failed/crashed/expired — is server-judged. */\nconst AUTO_RETRY_FATES: ReadonlySet<string> = new Set(['lost', 'aborted']);\n\n/** A failed send is re-dispatched at most this many times per attach; a\n * persistent failure (repeated session losses) stays in the manual lane. */\nconst MAX_AUTO_RETRIES_PER_MESSAGE = 3;\n\n/** Persisted failures older than this stay manual: auto-sending a message the\n * user abandoned a day ago is worse than surfacing it for a decision. Mirrors\n * the retired outbox's retention window. */\nconst MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport interface DeepAgentSendRecoveryOptions {\n /**\n * Reads the thread's failed-send lane. `null` while it is unavailable (the\n * client has not mounted yet, or its extras are not a statewire thread) —\n * the controller stays armed and retries on the next state change.\n */\n lane: () => StatewireFailedSendLane | null;\n /**\n * Persisted failure stamps (message id → epoch ms of the original send) for\n * the freshness gate. `null`/absent means no persistence is readable — every\n * lane entry then counts as fresh (an in-memory failed lane can only hold\n * failures from this page session).\n */\n failureStamps?: (() => ReadonlyMap<string, number> | null) | undefined;\n /** Transport lifecycle recorder; read per event so a late-mounted recorder still sees retries. */\n diagnostics?: (() => StatewireDiagnosticsRecorder | undefined) | undefined;\n /** Injectable clock (tests). */\n now?: () => number;\n /** Sweep scheduler; defaults to `queueMicrotask` so a sweep never dispatches\n * from inside a statewire flush or a React render. */\n schedule?: (task: () => void) => void;\n}\n\nexport interface DeepAgentSendRecovery {\n /** Feed every (normalized) statewire state change; hydration arms the mount sweep. */\n observeStateChange(state: unknown): void;\n /** Feed every command-lifecycle update; a never-server-judged settle arms a sweep. */\n observeCommand(update: StatewireDiagnosticsCommandUpdate): void;\n /** Feed client notifications too: failed history can publish after the\n * command settles, without any change to the canonical thread snapshot. */\n observeFailedLaneChange(): void;\n dispose(): void;\n}\n\n/** Whether a settle failure is a client-side death the recovery re-dispatches\n * (the server never judged the command). Exported for host-side telemetry. */\nexport function shouldAutoRetryFailedSend(failure: { fate: string } | undefined): boolean {\n return failure !== undefined && AUTO_RETRY_FATES.has(failure.fate);\n}\n\n/** Whether a failed entry must wait for a lost predecessor to settle first. */\nfunction awaitsLostPredecessor(entry: StatewireFailedSendEntry): boolean {\n return entry.sendFailure.fate === 'aborted' && entry.sendFailure.predecessorLost === true;\n}\n\n/** The client-minted message id a run send carries, off a command update's params. */\nfunction commandMessageId(update: StatewireDiagnosticsCommandUpdate): string | null {\n const first = update.params?.[0] as { message?: { id?: unknown } } | undefined;\n const id = first?.message?.id;\n return typeof id === 'string' ? id : null;\n}\n\nexport function createDeepAgentSendRecovery(\n options: DeepAgentSendRecoveryOptions\n): DeepAgentSendRecovery {\n const now = options.now ?? Date.now;\n const schedule = options.schedule ?? ((task: () => void) => queueMicrotask(task));\n\n let disposed = false;\n let hydrated = false;\n /** Work may exist: set at hydration and on retryable settles, cleared by a\n * sweep that could actually read the lane. */\n let armed = false;\n let sweepScheduled = false;\n /** Retry budget per message id, for this controller's attach lifetime. */\n const attempts = new Map<string, number>();\n /** Message ids already diagnosed as stale/exhausted, so the lane re-scan\n * stays quiet about them. */\n const surfacedSkips = new Set<string>();\n /** Message ids whose deferral behind a lost predecessor was diagnosed once. */\n const surfacedDeferrals = new Set<string>();\n /** Re-dispatched sends still awaiting the server's verdict: a successor\n * stamped `predecessorLost` waits while any of these is pending. */\n const inFlight = new Set<string>();\n /** Successors held back by the last sweep; a non-empty set keeps the\n * controller armed so the next settle or state change re-sweeps. */\n const deferred = new Set<string>();\n\n const record = (event: string, data?: Record<string, unknown>): void => {\n options.diagnostics?.()?.record(event, data);\n };\n\n const sweep = (): void => {\n sweepScheduled = false;\n if (disposed || !hydrated || !armed) return;\n const lane = options.lane();\n // No readable lane yet: stay armed so the next state change re-sweeps.\n if (lane === null) return;\n armed = false;\n deferred.clear();\n const stamps = options.failureStamps?.() ?? null;\n // A `lost` entry earlier in lane order that this sweep leaves unsettled\n // (skipped as stale/exhausted, or re-dispatched and now in flight).\n let lostPredecessorPending = false;\n for (const entry of lane.failed) {\n if (!shouldAutoRetryFailedSend(entry.sendFailure)) continue;\n // Shared retry/discard may still be waiting for the storage lock. The\n // visible lane can keep this entry until then; do not spend another\n // attempt on a send whose previous retry is still awaiting a verdict.\n if (inFlight.has(entry.id)) {\n if (entry.sendFailure.fate === 'lost') lostPredecessorPending = true;\n continue;\n }\n if (awaitsLostPredecessor(entry) && (lostPredecessorPending || inFlight.size > 0)) {\n deferred.add(entry.id);\n if (!surfacedDeferrals.has(entry.id)) {\n surfacedDeferrals.add(entry.id);\n record('send-recovery/deferred', { messageId: entry.id });\n }\n continue;\n }\n const isLost = entry.sendFailure.fate === 'lost';\n const stamp = stamps?.get(entry.id);\n if (stamp !== undefined && now() - stamp > MAX_AUTO_RETRY_AGE_MS) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/stale', { messageId: entry.id, ageMs: Math.round(now() - stamp) });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n const attempt = (attempts.get(entry.id) ?? 0) + 1;\n if (attempt > MAX_AUTO_RETRIES_PER_MESSAGE) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/exhausted', { messageId: entry.id });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n try {\n lane.retryFailed(entry.id);\n attempts.set(entry.id, attempt);\n inFlight.add(entry.id);\n if (isLost) lostPredecessorPending = true;\n record('send-recovery/retry', {\n messageId: entry.id,\n fate: entry.sendFailure.fate,\n attempt,\n });\n } catch {\n // The entry settled or was covered between the lane read and the\n // retry (the vendor drops covered failures against every snapshot);\n // nothing was dispatched.\n record('send-recovery/raced', { messageId: entry.id });\n }\n }\n // Held successors must be revisited once their predecessors settle.\n if (deferred.size > 0) armed = true;\n };\n\n const scheduleSweep = (): void => {\n if (disposed || sweepScheduled || !hydrated || !armed) return;\n sweepScheduled = true;\n schedule(sweep);\n };\n\n return {\n observeStateChange(state) {\n if (disposed) return;\n if (!hydrated && isDeepAgentStateHydrated(state)) {\n // First real snapshot: the vendor's failureCovered pass has had its\n // chance to drop entries whose message actually landed, so whatever\n // remains provably never reached the thread.\n hydrated = true;\n armed = true;\n }\n scheduleSweep();\n },\n observeCommand(update) {\n if (disposed || update.status !== 'settled') return;\n const messageId = commandMessageId(update);\n if (messageId !== null) inFlight.delete(messageId);\n // A never-server-judged settle means new work; any settle while\n // successors are held may be the predecessor they wait on.\n if (!shouldAutoRetryFailedSend(update.failure) && deferred.size === 0) return;\n armed = true;\n scheduleSweep();\n },\n observeFailedLaneChange() {\n if (disposed) return;\n armed = true;\n scheduleSweep();\n },\n dispose() {\n disposed = true;\n },\n };\n}\n"],"names":["isDeepAgentStateHydrated"],"mappings":";;;AA0CA,MAAM,mBAAwC,oBAAI,IAAI,CAAC,QAAQ,SAAS,CAAC;AAIzE,MAAM,+BAA+B;AAKrC,MAAM,wBAAwB,KAAK,KAAK,KAAK;AAsCtC,SAAS,0BAA0B,SAAgD;AACxF,SAAO,YAAY,UAAa,iBAAiB,IAAI,QAAQ,IAAI;AACnE;AAGA,SAAS,sBAAsB,OAA0C;AACvE,SAAO,MAAM,YAAY,SAAS,aAAa,MAAM,YAAY,oBAAoB;AACvF;AAGA,SAAS,iBAAiB,QAA0D;;AAClF,QAAM,SAAQ,YAAO,WAAP,mBAAgB;AAC9B,QAAM,MAAK,oCAAO,YAAP,mBAAgB;AAC3B,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEO,SAAS,4BACd,SACuB;AACvB,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,WAAW,QAAQ,aAAa,CAAC,SAAqB,eAAe,IAAI;AAE/E,MAAI,WAAW;AACf,MAAI,WAAW;AAGf,MAAI,QAAQ;AACZ,MAAI,iBAAiB;AAErB,QAAM,+BAAe,IAAA;AAGrB,QAAM,oCAAoB,IAAA;AAE1B,QAAM,wCAAwB,IAAA;AAG9B,QAAM,+BAAe,IAAA;AAGrB,QAAM,+BAAe,IAAA;AAErB,QAAM,SAAS,CAAC,OAAe,SAAyC;;AACtE,wBAAQ,gBAAR,wDAAyB,OAAO,OAAO;AAAA,EACzC;AAEA,QAAM,QAAQ,MAAY;;AACxB,qBAAiB;AACjB,QAAI,YAAY,CAAC,YAAY,CAAC,MAAO;AACrC,UAAM,OAAO,QAAQ,KAAA;AAErB,QAAI,SAAS,KAAM;AACnB,YAAQ;AACR,aAAS,MAAA;AACT,UAAM,WAAS,aAAQ,kBAAR,qCAA6B;AAG5C,QAAI,yBAAyB;AAC7B,eAAW,SAAS,KAAK,QAAQ;AAC/B,UAAI,CAAC,0BAA0B,MAAM,WAAW,EAAG;AAInD,UAAI,SAAS,IAAI,MAAM,EAAE,GAAG;AAC1B,YAAI,MAAM,YAAY,SAAS,OAAQ,0BAAyB;AAChE;AAAA,MACF;AACA,UAAI,sBAAsB,KAAK,MAAM,0BAA0B,SAAS,OAAO,IAAI;AACjF,iBAAS,IAAI,MAAM,EAAE;AACrB,YAAI,CAAC,kBAAkB,IAAI,MAAM,EAAE,GAAG;AACpC,4BAAkB,IAAI,MAAM,EAAE;AAC9B,iBAAO,0BAA0B,EAAE,WAAW,MAAM,IAAI;AAAA,QAC1D;AACA;AAAA,MACF;AACA,YAAM,SAAS,MAAM,YAAY,SAAS;AAC1C,YAAM,QAAQ,iCAAQ,IAAI,MAAM;AAChC,UAAI,UAAU,UAAa,IAAA,IAAQ,QAAQ,uBAAuB;AAChE,YAAI,CAAC,cAAc,IAAI,MAAM,EAAE,GAAG;AAChC,wBAAc,IAAI,MAAM,EAAE;AAC1B,iBAAO,uBAAuB,EAAE,WAAW,MAAM,IAAI,OAAO,KAAK,MAAM,QAAQ,KAAK,EAAA,CAAG;AAAA,QACzF;AACA,YAAI,OAAQ,0BAAyB;AACrC;AAAA,MACF;AACA,YAAM,WAAW,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK;AAChD,UAAI,UAAU,8BAA8B;AAC1C,YAAI,CAAC,cAAc,IAAI,MAAM,EAAE,GAAG;AAChC,wBAAc,IAAI,MAAM,EAAE;AAC1B,iBAAO,2BAA2B,EAAE,WAAW,MAAM,IAAI;AAAA,QAC3D;AACA,YAAI,OAAQ,0BAAyB;AACrC;AAAA,MACF;AACA,UAAI;AACF,aAAK,YAAY,MAAM,EAAE;AACzB,iBAAS,IAAI,MAAM,IAAI,OAAO;AAC9B,iBAAS,IAAI,MAAM,EAAE;AACrB,YAAI,OAAQ,0BAAyB;AACrC,eAAO,uBAAuB;AAAA,UAC5B,WAAW,MAAM;AAAA,UACjB,MAAM,MAAM,YAAY;AAAA,UACxB;AAAA,QAAA,CACD;AAAA,MACH,QAAQ;AAIN,eAAO,uBAAuB,EAAE,WAAW,MAAM,IAAI;AAAA,MACvD;AAAA,IACF;AAEA,QAAI,SAAS,OAAO,EAAG,SAAQ;AAAA,EACjC;AAEA,QAAM,gBAAgB,MAAY;AAChC,QAAI,YAAY,kBAAkB,CAAC,YAAY,CAAC,MAAO;AACvD,qBAAiB;AACjB,aAAS,KAAK;AAAA,EAChB;AAEA,SAAO;AAAA,IACL,mBAAmB,OAAO;AACxB,UAAI,SAAU;AACd,UAAI,CAAC,YAAYA,wCAAyB,KAAK,GAAG;AAIhD,mBAAW;AACX,gBAAQ;AAAA,MACV;AACA,oBAAA;AAAA,IACF;AAAA,IACA,eAAe,QAAQ;AACrB,UAAI,YAAY,OAAO,WAAW,UAAW;AAC7C,YAAM,YAAY,iBAAiB,MAAM;AACzC,UAAI,cAAc,KAAM,UAAS,OAAO,SAAS;AAGjD,UAAI,CAAC,0BAA0B,OAAO,OAAO,KAAK,SAAS,SAAS,EAAG;AACvE,cAAQ;AACR,oBAAA;AAAA,IACF;AAAA,IACA,0BAA0B;AACxB,UAAI,SAAU;AACd,cAAQ;AACR,oBAAA;AAAA,IACF;AAAA,IACA,UAAU;AACR,iBAAW;AAAA,IACb;AAAA,EAAA;AAEJ;;;"}
1
+ {"version":3,"file":"send-recovery.cjs","sources":["../../../../agent-runtime/src/send-recovery.ts"],"sourcesContent":["import type {\n StatewireDiagnosticsCommandUpdate,\n StatewireDiagnosticsRecorder,\n} from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated } from './statewire-state';\nimport type { StatewireFailedSendEntry, StatewireFailedSendLane } from './thread-extras';\n\n/**\n * Transport-level send durability for the deep-agent thread (the successor to\n * Olympus' localStorage outbox, #29368 → #31504).\n *\n * The durable journal itself is the statewire session record: every command is\n * persisted through the mounted session storage from `send()` until the server\n * durably admits or judges it, and a reload resends survivors on the SAME lane\n * seq (exactly-once — the server absorbs replayed seqs at or below its\n * watermark). What the record cannot recover on its own is a send the client\n * had to settle without a server verdict — a proven session loss or a record\n * reset settles it `lost`/`aborted` and RETAINS it in the record's failed lane\n * (message-carrying sends only), where the vendor drops it as soon as a\n * canonical snapshot shows the message landed (`failureCovered`).\n *\n * This controller turns that persisted failed lane back into live sends: once\n * the thread snapshot has hydrated (so covered entries are already gone), every\n * failed send the server NEVER judged is re-dispatched through the thread's own\n * `retryFailed` — same client-minted message id, re-anchored against the\n * current thread — which the host dedupes by id (a still-queued id re-places,\n * a durable one rejects `duplicate-id`). Server-judged fates (`rejected`,\n * `failed`, `crashed`, `expired`) are the user's decision and stay in the\n * manual retry/discard affordance.\n *\n * Ordering: an `aborted` send stamped `predecessorLost` was never attempted\n * because an earlier send of the same batch WAS attempted and settled `lost`\n * — it may or may not have run. Re-dispatching the successor first could land\n * it ahead of a predecessor that later turns out to have landed too, so the\n * successor is held until every preceding `lost` predecessor has settled: it\n * was covered by a snapshot, its retry was judged by the server, or the user\n * discarded it.\n */\n\n/** Fates the server never saw: the send died client-side (unmount, stream\n * gone, session lost) and is safe to re-dispatch under its original message\n * id. The complement — rejected/failed/crashed/expired — is server-judged. */\nconst AUTO_RETRY_FATES: ReadonlySet<string> = new Set(['lost', 'aborted']);\n\n/** A failed send is re-dispatched at most this many times per attach; a\n * persistent failure (repeated session losses) stays in the manual lane. */\nconst MAX_AUTO_RETRIES_PER_MESSAGE = 3;\n\n/** Persisted failures older than this stay manual: auto-sending a message the\n * user abandoned a day ago is worse than surfacing it for a decision. Mirrors\n * the retired outbox's retention window. */\nconst MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** How many times a host may hold one message's retry (`beforeRetry`\n * returning a promise) before the sweep sends it regardless: a hold is the\n * host's own bounded wait, never a reason to keep a message back for good. */\nexport const MAX_BEFORE_RETRY_HOLDS = 10;\n\nexport interface DeepAgentSendRecoveryOptions {\n /**\n * Reads the thread's failed-send lane. `null` while it is unavailable (the\n * client has not mounted yet, or its extras are not a statewire thread) —\n * the controller stays armed and retries on the next state change.\n */\n lane: () => StatewireFailedSendLane | null;\n /**\n * Persisted failure stamps (message id → epoch ms of the original send) for\n * the freshness gate. `null`/absent means no persistence is readable — every\n * lane entry then counts as fresh (an in-memory failed lane can only hold\n * failures from this page session).\n */\n failureStamps?: (() => ReadonlyMap<string, number> | null) | undefined;\n /** Transport lifecycle recorder; read per event so a late-mounted recorder still sees retries. */\n diagnostics?: (() => StatewireDiagnosticsRecorder | undefined) | undefined;\n /** Injectable clock (tests). */\n now?: () => number;\n /** Sweep scheduler; defaults to `queueMicrotask` so a sweep never dispatches\n * from inside a statewire flush or a React render. */\n schedule?: (task: () => void) => void;\n /**\n * Called right before a failed send is dispatched again, with its message\n * id, so a host can put back the per-send context that message was sent\n * with (Olympus stages the agents it named) before its command leaves.\n *\n * Returning a promise holds the retry: the host can't put that context back\n * yet (every send of the conversation rides one ambient context, and a send\n * with another context is still on its way). The sweep then stops at this\n * message, so nothing behind it overtakes it, and asks again once the\n * promise settles; past {@link MAX_BEFORE_RETRY_HOLDS} holds it sends the\n * message regardless. A hook that throws never holds a retry back. A\n * function returned is called when the message does not go after all (the\n * retry raced its leaving the lane), so the host lets go of what it put back.\n */\n beforeRetry?: ((messageId: string) => void | PromiseLike<void> | (() => void)) | undefined;\n}\n\nexport interface DeepAgentSendRecovery {\n /** Feed every (normalized) statewire state change; hydration arms the mount sweep. */\n observeStateChange(state: unknown): void;\n /** Feed every command-lifecycle update; a never-server-judged settle arms a sweep. */\n observeCommand(update: StatewireDiagnosticsCommandUpdate): void;\n /** Feed client notifications too: failed history can publish after the\n * command settles, without any change to the canonical thread snapshot. */\n observeFailedLaneChange(): void;\n dispose(): void;\n}\n\n/** Whether a settle failure is a client-side death the recovery re-dispatches\n * (the server never judged the command). Exported for host-side telemetry. */\nexport function shouldAutoRetryFailedSend(failure: { fate: string } | undefined): boolean {\n return failure !== undefined && AUTO_RETRY_FATES.has(failure.fate);\n}\n\n/** Whether a failed entry must wait for a lost predecessor to settle first. */\nfunction awaitsLostPredecessor(entry: StatewireFailedSendEntry): boolean {\n return entry.sendFailure.fate === 'aborted' && entry.sendFailure.predecessorLost === true;\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/** The client-minted message id a run send carries, off a command update's params. */\nfunction commandMessageId(update: StatewireDiagnosticsCommandUpdate): string | null {\n const first = update.params?.[0] as { message?: { id?: unknown } } | undefined;\n const id = first?.message?.id;\n return typeof id === 'string' ? id : null;\n}\n\nexport function createDeepAgentSendRecovery(\n options: DeepAgentSendRecoveryOptions\n): DeepAgentSendRecovery {\n const now = options.now ?? Date.now;\n const schedule = options.schedule ?? ((task: () => void) => queueMicrotask(task));\n\n let disposed = false;\n let hydrated = false;\n /** Work may exist: set at hydration and on retryable settles, cleared by a\n * sweep that could actually read the lane. */\n let armed = false;\n let sweepScheduled = false;\n /** Retry budget per message id, for this controller's attach lifetime. */\n const attempts = new Map<string, number>();\n /** Message ids already diagnosed as stale/exhausted, so the lane re-scan\n * stays quiet about them. */\n const surfacedSkips = new Set<string>();\n /** Message ids whose deferral behind a lost predecessor was diagnosed once. */\n const surfacedDeferrals = new Set<string>();\n /** Re-dispatched sends still awaiting the server's verdict: a successor\n * stamped `predecessorLost` waits while any of these is pending. */\n const inFlight = new Set<string>();\n /** Successors held back by the last sweep; a non-empty set keeps the\n * controller armed so the next settle or state change re-sweeps. */\n const deferred = new Set<string>();\n /** How many times the host held each message's retry (`beforeRetry`'s promise). */\n const holds = new Map<string, number>();\n /** A host's hold in progress: no sweep runs until it settles. */\n let holding = false;\n\n const record = (event: string, data?: Record<string, unknown>): void => {\n options.diagnostics?.()?.record(event, data);\n };\n\n const sweep = (): void => {\n sweepScheduled = false;\n // A host's hold re-sweeps once it settles; until then nothing is retried.\n if (disposed || holding || !hydrated || !armed) return;\n const lane = options.lane();\n // No readable lane yet: stay armed so the next state change re-sweeps.\n if (lane === null) return;\n armed = false;\n deferred.clear();\n const stamps = options.failureStamps?.() ?? null;\n // A `lost` entry earlier in lane order that this sweep leaves unsettled\n // (skipped as stale/exhausted, or re-dispatched and now in flight).\n let lostPredecessorPending = false;\n for (const entry of lane.failed) {\n if (!shouldAutoRetryFailedSend(entry.sendFailure)) continue;\n // Shared retry/discard may still be waiting for the storage lock. The\n // visible lane can keep this entry until then; do not spend another\n // attempt on a send whose previous retry is still awaiting a verdict.\n if (inFlight.has(entry.id)) {\n if (entry.sendFailure.fate === 'lost') lostPredecessorPending = true;\n continue;\n }\n if (awaitsLostPredecessor(entry) && (lostPredecessorPending || inFlight.size > 0)) {\n deferred.add(entry.id);\n if (!surfacedDeferrals.has(entry.id)) {\n surfacedDeferrals.add(entry.id);\n record('send-recovery/deferred', { messageId: entry.id });\n }\n continue;\n }\n const isLost = entry.sendFailure.fate === 'lost';\n const stamp = stamps?.get(entry.id);\n if (stamp !== undefined && now() - stamp > MAX_AUTO_RETRY_AGE_MS) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/stale', { messageId: entry.id, ageMs: Math.round(now() - stamp) });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n const attempt = (attempts.get(entry.id) ?? 0) + 1;\n if (attempt > MAX_AUTO_RETRIES_PER_MESSAGE) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/exhausted', { messageId: entry.id });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n let before: ReturnType<NonNullable<DeepAgentSendRecoveryOptions['beforeRetry']>> | undefined;\n try {\n before = options.beforeRetry?.(entry.id);\n } catch {\n // A host's own context step failing never holds the retry back.\n record('send-recovery/before-retry-failed', { messageId: entry.id });\n }\n if (isThenable(before)) {\n const held = (holds.get(entry.id) ?? 0) + 1;\n if (held <= MAX_BEFORE_RETRY_HOLDS) {\n // The host can't put this message's context back yet: it waits, and\n // so does everything behind it (nothing overtakes it); the sweep asks\n // again once the hold settles.\n holds.set(entry.id, held);\n holding = true;\n armed = true;\n record('send-recovery/held', { messageId: entry.id, holds: held });\n const resume = (): void => {\n holding = false;\n armed = true;\n scheduleSweep();\n };\n before.then(resume, resume);\n return;\n }\n record('send-recovery/held-too-long', { messageId: entry.id });\n }\n try {\n lane.retryFailed(entry.id);\n attempts.set(entry.id, attempt);\n inFlight.add(entry.id);\n if (isLost) lostPredecessorPending = true;\n record('send-recovery/retry', {\n messageId: entry.id,\n fate: entry.sendFailure.fate,\n attempt,\n });\n } catch {\n // The entry settled or was covered between the lane read and the\n // retry (the vendor drops covered failures against every snapshot);\n // nothing was dispatched, so the host lets go of what it put back.\n record('send-recovery/raced', { messageId: entry.id });\n try {\n if (typeof before === 'function') before();\n } catch {\n // The host's own step failing never stops the sweep.\n }\n }\n }\n // Held successors must be revisited once their predecessors settle.\n if (deferred.size > 0) armed = true;\n };\n\n const scheduleSweep = (): void => {\n if (disposed || sweepScheduled || holding || !hydrated || !armed) return;\n sweepScheduled = true;\n schedule(sweep);\n };\n\n return {\n observeStateChange(state) {\n if (disposed) return;\n if (!hydrated && isDeepAgentStateHydrated(state)) {\n // First real snapshot: the vendor's failureCovered pass has had its\n // chance to drop entries whose message actually landed, so whatever\n // remains provably never reached the thread.\n hydrated = true;\n armed = true;\n }\n scheduleSweep();\n },\n observeCommand(update) {\n if (disposed || update.status !== 'settled') return;\n const messageId = commandMessageId(update);\n if (messageId !== null) inFlight.delete(messageId);\n // A never-server-judged settle means new work; any settle while\n // successors are held may be the predecessor they wait on.\n if (!shouldAutoRetryFailedSend(update.failure) && deferred.size === 0) return;\n armed = true;\n scheduleSweep();\n },\n observeFailedLaneChange() {\n if (disposed) return;\n armed = true;\n scheduleSweep();\n },\n dispose() {\n disposed = true;\n },\n };\n}\n"],"names":["isDeepAgentStateHydrated"],"mappings":"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"}
@@ -1,5 +1,9 @@
1
1
  import type { StatewireDiagnosticsCommandUpdate, StatewireDiagnosticsRecorder } from './statewire-diagnostics';
2
2
  import type { StatewireFailedSendLane } from './thread-extras';
3
+ /** How many times a host may hold one message's retry (`beforeRetry`
4
+ * returning a promise) before the sweep sends it regardless: a hold is the
5
+ * host's own bounded wait, never a reason to keep a message back for good. */
6
+ export declare const MAX_BEFORE_RETRY_HOLDS = 10;
3
7
  export interface DeepAgentSendRecoveryOptions {
4
8
  /**
5
9
  * Reads the thread's failed-send lane. `null` while it is unavailable (the
@@ -21,6 +25,21 @@ export interface DeepAgentSendRecoveryOptions {
21
25
  /** Sweep scheduler; defaults to `queueMicrotask` so a sweep never dispatches
22
26
  * from inside a statewire flush or a React render. */
23
27
  schedule?: (task: () => void) => void;
28
+ /**
29
+ * Called right before a failed send is dispatched again, with its message
30
+ * id, so a host can put back the per-send context that message was sent
31
+ * with (Olympus stages the agents it named) before its command leaves.
32
+ *
33
+ * Returning a promise holds the retry: the host can't put that context back
34
+ * yet (every send of the conversation rides one ambient context, and a send
35
+ * with another context is still on its way). The sweep then stops at this
36
+ * message, so nothing behind it overtakes it, and asks again once the
37
+ * promise settles; past {@link MAX_BEFORE_RETRY_HOLDS} holds it sends the
38
+ * message regardless. A hook that throws never holds a retry back. A
39
+ * function returned is called when the message does not go after all (the
40
+ * retry raced its leaving the lane), so the host lets go of what it put back.
41
+ */
42
+ beforeRetry?: ((messageId: string) => void | PromiseLike<void> | (() => void)) | undefined;
24
43
  }
25
44
  export interface DeepAgentSendRecovery {
26
45
  /** Feed every (normalized) statewire state change; hydration arms the mount sweep. */
@@ -2,12 +2,16 @@ import { isDeepAgentStateHydrated } from "./statewire-state.js";
2
2
  const AUTO_RETRY_FATES = /* @__PURE__ */ new Set(["lost", "aborted"]);
3
3
  const MAX_AUTO_RETRIES_PER_MESSAGE = 3;
4
4
  const MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1e3;
5
+ const MAX_BEFORE_RETRY_HOLDS = 10;
5
6
  function shouldAutoRetryFailedSend(failure) {
6
7
  return failure !== void 0 && AUTO_RETRY_FATES.has(failure.fate);
7
8
  }
8
9
  function awaitsLostPredecessor(entry) {
9
10
  return entry.sendFailure.fate === "aborted" && entry.sendFailure.predecessorLost === true;
10
11
  }
12
+ function isThenable(value) {
13
+ return typeof value === "object" && value !== null && typeof value.then === "function";
14
+ }
11
15
  function commandMessageId(update) {
12
16
  var _a, _b;
13
17
  const first = (_a = update.params) == null ? void 0 : _a[0];
@@ -26,14 +30,16 @@ function createDeepAgentSendRecovery(options) {
26
30
  const surfacedDeferrals = /* @__PURE__ */ new Set();
27
31
  const inFlight = /* @__PURE__ */ new Set();
28
32
  const deferred = /* @__PURE__ */ new Set();
33
+ const holds = /* @__PURE__ */ new Map();
34
+ let holding = false;
29
35
  const record = (event, data) => {
30
36
  var _a, _b;
31
37
  (_b = (_a = options.diagnostics) == null ? void 0 : _a.call(options)) == null ? void 0 : _b.record(event, data);
32
38
  };
33
39
  const sweep = () => {
34
- var _a;
40
+ var _a, _b;
35
41
  sweepScheduled = false;
36
- if (disposed || !hydrated || !armed) return;
42
+ if (disposed || holding || !hydrated || !armed) return;
37
43
  const lane = options.lane();
38
44
  if (lane === null) return;
39
45
  armed = false;
@@ -73,6 +79,29 @@ function createDeepAgentSendRecovery(options) {
73
79
  if (isLost) lostPredecessorPending = true;
74
80
  continue;
75
81
  }
82
+ let before;
83
+ try {
84
+ before = (_b = options.beforeRetry) == null ? void 0 : _b.call(options, entry.id);
85
+ } catch {
86
+ record("send-recovery/before-retry-failed", { messageId: entry.id });
87
+ }
88
+ if (isThenable(before)) {
89
+ const held = (holds.get(entry.id) ?? 0) + 1;
90
+ if (held <= MAX_BEFORE_RETRY_HOLDS) {
91
+ holds.set(entry.id, held);
92
+ holding = true;
93
+ armed = true;
94
+ record("send-recovery/held", { messageId: entry.id, holds: held });
95
+ const resume = () => {
96
+ holding = false;
97
+ armed = true;
98
+ scheduleSweep();
99
+ };
100
+ before.then(resume, resume);
101
+ return;
102
+ }
103
+ record("send-recovery/held-too-long", { messageId: entry.id });
104
+ }
76
105
  try {
77
106
  lane.retryFailed(entry.id);
78
107
  attempts.set(entry.id, attempt);
@@ -85,12 +114,16 @@ function createDeepAgentSendRecovery(options) {
85
114
  });
86
115
  } catch {
87
116
  record("send-recovery/raced", { messageId: entry.id });
117
+ try {
118
+ if (typeof before === "function") before();
119
+ } catch {
120
+ }
88
121
  }
89
122
  }
90
123
  if (deferred.size > 0) armed = true;
91
124
  };
92
125
  const scheduleSweep = () => {
93
- if (disposed || sweepScheduled || !hydrated || !armed) return;
126
+ if (disposed || sweepScheduled || holding || !hydrated || !armed) return;
94
127
  sweepScheduled = true;
95
128
  schedule(sweep);
96
129
  };
@@ -122,6 +155,7 @@ function createDeepAgentSendRecovery(options) {
122
155
  };
123
156
  }
124
157
  export {
158
+ MAX_BEFORE_RETRY_HOLDS,
125
159
  createDeepAgentSendRecovery,
126
160
  shouldAutoRetryFailedSend
127
161
  };
@@ -1 +1 @@
1
- {"version":3,"file":"send-recovery.js","sources":["../../../../agent-runtime/src/send-recovery.ts"],"sourcesContent":["import type {\n StatewireDiagnosticsCommandUpdate,\n StatewireDiagnosticsRecorder,\n} from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated } from './statewire-state';\nimport type { StatewireFailedSendEntry, StatewireFailedSendLane } from './thread-extras';\n\n/**\n * Transport-level send durability for the deep-agent thread (the successor to\n * Olympus' localStorage outbox, #29368 → #31504).\n *\n * The durable journal itself is the statewire session record: every command is\n * persisted through the mounted session storage from `send()` until the server\n * durably admits or judges it, and a reload resends survivors on the SAME lane\n * seq (exactly-once — the server absorbs replayed seqs at or below its\n * watermark). What the record cannot recover on its own is a send the client\n * had to settle without a server verdict — a proven session loss or a record\n * reset settles it `lost`/`aborted` and RETAINS it in the record's failed lane\n * (message-carrying sends only), where the vendor drops it as soon as a\n * canonical snapshot shows the message landed (`failureCovered`).\n *\n * This controller turns that persisted failed lane back into live sends: once\n * the thread snapshot has hydrated (so covered entries are already gone), every\n * failed send the server NEVER judged is re-dispatched through the thread's own\n * `retryFailed` — same client-minted message id, re-anchored against the\n * current thread — which the host dedupes by id (a still-queued id re-places,\n * a durable one rejects `duplicate-id`). Server-judged fates (`rejected`,\n * `failed`, `crashed`, `expired`) are the user's decision and stay in the\n * manual retry/discard affordance.\n *\n * Ordering: an `aborted` send stamped `predecessorLost` was never attempted\n * because an earlier send of the same batch WAS attempted and settled `lost`\n * — it may or may not have run. Re-dispatching the successor first could land\n * it ahead of a predecessor that later turns out to have landed too, so the\n * successor is held until every preceding `lost` predecessor has settled: it\n * was covered by a snapshot, its retry was judged by the server, or the user\n * discarded it.\n */\n\n/** Fates the server never saw: the send died client-side (unmount, stream\n * gone, session lost) and is safe to re-dispatch under its original message\n * id. The complement — rejected/failed/crashed/expired — is server-judged. */\nconst AUTO_RETRY_FATES: ReadonlySet<string> = new Set(['lost', 'aborted']);\n\n/** A failed send is re-dispatched at most this many times per attach; a\n * persistent failure (repeated session losses) stays in the manual lane. */\nconst MAX_AUTO_RETRIES_PER_MESSAGE = 3;\n\n/** Persisted failures older than this stay manual: auto-sending a message the\n * user abandoned a day ago is worse than surfacing it for a decision. Mirrors\n * the retired outbox's retention window. */\nconst MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1000;\n\nexport interface DeepAgentSendRecoveryOptions {\n /**\n * Reads the thread's failed-send lane. `null` while it is unavailable (the\n * client has not mounted yet, or its extras are not a statewire thread) —\n * the controller stays armed and retries on the next state change.\n */\n lane: () => StatewireFailedSendLane | null;\n /**\n * Persisted failure stamps (message id → epoch ms of the original send) for\n * the freshness gate. `null`/absent means no persistence is readable — every\n * lane entry then counts as fresh (an in-memory failed lane can only hold\n * failures from this page session).\n */\n failureStamps?: (() => ReadonlyMap<string, number> | null) | undefined;\n /** Transport lifecycle recorder; read per event so a late-mounted recorder still sees retries. */\n diagnostics?: (() => StatewireDiagnosticsRecorder | undefined) | undefined;\n /** Injectable clock (tests). */\n now?: () => number;\n /** Sweep scheduler; defaults to `queueMicrotask` so a sweep never dispatches\n * from inside a statewire flush or a React render. */\n schedule?: (task: () => void) => void;\n}\n\nexport interface DeepAgentSendRecovery {\n /** Feed every (normalized) statewire state change; hydration arms the mount sweep. */\n observeStateChange(state: unknown): void;\n /** Feed every command-lifecycle update; a never-server-judged settle arms a sweep. */\n observeCommand(update: StatewireDiagnosticsCommandUpdate): void;\n /** Feed client notifications too: failed history can publish after the\n * command settles, without any change to the canonical thread snapshot. */\n observeFailedLaneChange(): void;\n dispose(): void;\n}\n\n/** Whether a settle failure is a client-side death the recovery re-dispatches\n * (the server never judged the command). Exported for host-side telemetry. */\nexport function shouldAutoRetryFailedSend(failure: { fate: string } | undefined): boolean {\n return failure !== undefined && AUTO_RETRY_FATES.has(failure.fate);\n}\n\n/** Whether a failed entry must wait for a lost predecessor to settle first. */\nfunction awaitsLostPredecessor(entry: StatewireFailedSendEntry): boolean {\n return entry.sendFailure.fate === 'aborted' && entry.sendFailure.predecessorLost === true;\n}\n\n/** The client-minted message id a run send carries, off a command update's params. */\nfunction commandMessageId(update: StatewireDiagnosticsCommandUpdate): string | null {\n const first = update.params?.[0] as { message?: { id?: unknown } } | undefined;\n const id = first?.message?.id;\n return typeof id === 'string' ? id : null;\n}\n\nexport function createDeepAgentSendRecovery(\n options: DeepAgentSendRecoveryOptions\n): DeepAgentSendRecovery {\n const now = options.now ?? Date.now;\n const schedule = options.schedule ?? ((task: () => void) => queueMicrotask(task));\n\n let disposed = false;\n let hydrated = false;\n /** Work may exist: set at hydration and on retryable settles, cleared by a\n * sweep that could actually read the lane. */\n let armed = false;\n let sweepScheduled = false;\n /** Retry budget per message id, for this controller's attach lifetime. */\n const attempts = new Map<string, number>();\n /** Message ids already diagnosed as stale/exhausted, so the lane re-scan\n * stays quiet about them. */\n const surfacedSkips = new Set<string>();\n /** Message ids whose deferral behind a lost predecessor was diagnosed once. */\n const surfacedDeferrals = new Set<string>();\n /** Re-dispatched sends still awaiting the server's verdict: a successor\n * stamped `predecessorLost` waits while any of these is pending. */\n const inFlight = new Set<string>();\n /** Successors held back by the last sweep; a non-empty set keeps the\n * controller armed so the next settle or state change re-sweeps. */\n const deferred = new Set<string>();\n\n const record = (event: string, data?: Record<string, unknown>): void => {\n options.diagnostics?.()?.record(event, data);\n };\n\n const sweep = (): void => {\n sweepScheduled = false;\n if (disposed || !hydrated || !armed) return;\n const lane = options.lane();\n // No readable lane yet: stay armed so the next state change re-sweeps.\n if (lane === null) return;\n armed = false;\n deferred.clear();\n const stamps = options.failureStamps?.() ?? null;\n // A `lost` entry earlier in lane order that this sweep leaves unsettled\n // (skipped as stale/exhausted, or re-dispatched and now in flight).\n let lostPredecessorPending = false;\n for (const entry of lane.failed) {\n if (!shouldAutoRetryFailedSend(entry.sendFailure)) continue;\n // Shared retry/discard may still be waiting for the storage lock. The\n // visible lane can keep this entry until then; do not spend another\n // attempt on a send whose previous retry is still awaiting a verdict.\n if (inFlight.has(entry.id)) {\n if (entry.sendFailure.fate === 'lost') lostPredecessorPending = true;\n continue;\n }\n if (awaitsLostPredecessor(entry) && (lostPredecessorPending || inFlight.size > 0)) {\n deferred.add(entry.id);\n if (!surfacedDeferrals.has(entry.id)) {\n surfacedDeferrals.add(entry.id);\n record('send-recovery/deferred', { messageId: entry.id });\n }\n continue;\n }\n const isLost = entry.sendFailure.fate === 'lost';\n const stamp = stamps?.get(entry.id);\n if (stamp !== undefined && now() - stamp > MAX_AUTO_RETRY_AGE_MS) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/stale', { messageId: entry.id, ageMs: Math.round(now() - stamp) });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n const attempt = (attempts.get(entry.id) ?? 0) + 1;\n if (attempt > MAX_AUTO_RETRIES_PER_MESSAGE) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/exhausted', { messageId: entry.id });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n try {\n lane.retryFailed(entry.id);\n attempts.set(entry.id, attempt);\n inFlight.add(entry.id);\n if (isLost) lostPredecessorPending = true;\n record('send-recovery/retry', {\n messageId: entry.id,\n fate: entry.sendFailure.fate,\n attempt,\n });\n } catch {\n // The entry settled or was covered between the lane read and the\n // retry (the vendor drops covered failures against every snapshot);\n // nothing was dispatched.\n record('send-recovery/raced', { messageId: entry.id });\n }\n }\n // Held successors must be revisited once their predecessors settle.\n if (deferred.size > 0) armed = true;\n };\n\n const scheduleSweep = (): void => {\n if (disposed || sweepScheduled || !hydrated || !armed) return;\n sweepScheduled = true;\n schedule(sweep);\n };\n\n return {\n observeStateChange(state) {\n if (disposed) return;\n if (!hydrated && isDeepAgentStateHydrated(state)) {\n // First real snapshot: the vendor's failureCovered pass has had its\n // chance to drop entries whose message actually landed, so whatever\n // remains provably never reached the thread.\n hydrated = true;\n armed = true;\n }\n scheduleSweep();\n },\n observeCommand(update) {\n if (disposed || update.status !== 'settled') return;\n const messageId = commandMessageId(update);\n if (messageId !== null) inFlight.delete(messageId);\n // A never-server-judged settle means new work; any settle while\n // successors are held may be the predecessor they wait on.\n if (!shouldAutoRetryFailedSend(update.failure) && deferred.size === 0) return;\n armed = true;\n scheduleSweep();\n },\n observeFailedLaneChange() {\n if (disposed) return;\n armed = true;\n scheduleSweep();\n },\n dispose() {\n disposed = true;\n },\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send-recovery.js","sources":["../../../../agent-runtime/src/send-recovery.ts"],"sourcesContent":["import type {\n StatewireDiagnosticsCommandUpdate,\n StatewireDiagnosticsRecorder,\n} from './statewire-diagnostics';\nimport { isDeepAgentStateHydrated } from './statewire-state';\nimport type { StatewireFailedSendEntry, StatewireFailedSendLane } from './thread-extras';\n\n/**\n * Transport-level send durability for the deep-agent thread (the successor to\n * Olympus' localStorage outbox, #29368 → #31504).\n *\n * The durable journal itself is the statewire session record: every command is\n * persisted through the mounted session storage from `send()` until the server\n * durably admits or judges it, and a reload resends survivors on the SAME lane\n * seq (exactly-once — the server absorbs replayed seqs at or below its\n * watermark). What the record cannot recover on its own is a send the client\n * had to settle without a server verdict — a proven session loss or a record\n * reset settles it `lost`/`aborted` and RETAINS it in the record's failed lane\n * (message-carrying sends only), where the vendor drops it as soon as a\n * canonical snapshot shows the message landed (`failureCovered`).\n *\n * This controller turns that persisted failed lane back into live sends: once\n * the thread snapshot has hydrated (so covered entries are already gone), every\n * failed send the server NEVER judged is re-dispatched through the thread's own\n * `retryFailed` — same client-minted message id, re-anchored against the\n * current thread — which the host dedupes by id (a still-queued id re-places,\n * a durable one rejects `duplicate-id`). Server-judged fates (`rejected`,\n * `failed`, `crashed`, `expired`) are the user's decision and stay in the\n * manual retry/discard affordance.\n *\n * Ordering: an `aborted` send stamped `predecessorLost` was never attempted\n * because an earlier send of the same batch WAS attempted and settled `lost`\n * — it may or may not have run. Re-dispatching the successor first could land\n * it ahead of a predecessor that later turns out to have landed too, so the\n * successor is held until every preceding `lost` predecessor has settled: it\n * was covered by a snapshot, its retry was judged by the server, or the user\n * discarded it.\n */\n\n/** Fates the server never saw: the send died client-side (unmount, stream\n * gone, session lost) and is safe to re-dispatch under its original message\n * id. The complement — rejected/failed/crashed/expired — is server-judged. */\nconst AUTO_RETRY_FATES: ReadonlySet<string> = new Set(['lost', 'aborted']);\n\n/** A failed send is re-dispatched at most this many times per attach; a\n * persistent failure (repeated session losses) stays in the manual lane. */\nconst MAX_AUTO_RETRIES_PER_MESSAGE = 3;\n\n/** Persisted failures older than this stay manual: auto-sending a message the\n * user abandoned a day ago is worse than surfacing it for a decision. Mirrors\n * the retired outbox's retention window. */\nconst MAX_AUTO_RETRY_AGE_MS = 24 * 60 * 60 * 1000;\n\n/** How many times a host may hold one message's retry (`beforeRetry`\n * returning a promise) before the sweep sends it regardless: a hold is the\n * host's own bounded wait, never a reason to keep a message back for good. */\nexport const MAX_BEFORE_RETRY_HOLDS = 10;\n\nexport interface DeepAgentSendRecoveryOptions {\n /**\n * Reads the thread's failed-send lane. `null` while it is unavailable (the\n * client has not mounted yet, or its extras are not a statewire thread) —\n * the controller stays armed and retries on the next state change.\n */\n lane: () => StatewireFailedSendLane | null;\n /**\n * Persisted failure stamps (message id → epoch ms of the original send) for\n * the freshness gate. `null`/absent means no persistence is readable — every\n * lane entry then counts as fresh (an in-memory failed lane can only hold\n * failures from this page session).\n */\n failureStamps?: (() => ReadonlyMap<string, number> | null) | undefined;\n /** Transport lifecycle recorder; read per event so a late-mounted recorder still sees retries. */\n diagnostics?: (() => StatewireDiagnosticsRecorder | undefined) | undefined;\n /** Injectable clock (tests). */\n now?: () => number;\n /** Sweep scheduler; defaults to `queueMicrotask` so a sweep never dispatches\n * from inside a statewire flush or a React render. */\n schedule?: (task: () => void) => void;\n /**\n * Called right before a failed send is dispatched again, with its message\n * id, so a host can put back the per-send context that message was sent\n * with (Olympus stages the agents it named) before its command leaves.\n *\n * Returning a promise holds the retry: the host can't put that context back\n * yet (every send of the conversation rides one ambient context, and a send\n * with another context is still on its way). The sweep then stops at this\n * message, so nothing behind it overtakes it, and asks again once the\n * promise settles; past {@link MAX_BEFORE_RETRY_HOLDS} holds it sends the\n * message regardless. A hook that throws never holds a retry back. A\n * function returned is called when the message does not go after all (the\n * retry raced its leaving the lane), so the host lets go of what it put back.\n */\n beforeRetry?: ((messageId: string) => void | PromiseLike<void> | (() => void)) | undefined;\n}\n\nexport interface DeepAgentSendRecovery {\n /** Feed every (normalized) statewire state change; hydration arms the mount sweep. */\n observeStateChange(state: unknown): void;\n /** Feed every command-lifecycle update; a never-server-judged settle arms a sweep. */\n observeCommand(update: StatewireDiagnosticsCommandUpdate): void;\n /** Feed client notifications too: failed history can publish after the\n * command settles, without any change to the canonical thread snapshot. */\n observeFailedLaneChange(): void;\n dispose(): void;\n}\n\n/** Whether a settle failure is a client-side death the recovery re-dispatches\n * (the server never judged the command). Exported for host-side telemetry. */\nexport function shouldAutoRetryFailedSend(failure: { fate: string } | undefined): boolean {\n return failure !== undefined && AUTO_RETRY_FATES.has(failure.fate);\n}\n\n/** Whether a failed entry must wait for a lost predecessor to settle first. */\nfunction awaitsLostPredecessor(entry: StatewireFailedSendEntry): boolean {\n return entry.sendFailure.fate === 'aborted' && entry.sendFailure.predecessorLost === true;\n}\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\n/** The client-minted message id a run send carries, off a command update's params. */\nfunction commandMessageId(update: StatewireDiagnosticsCommandUpdate): string | null {\n const first = update.params?.[0] as { message?: { id?: unknown } } | undefined;\n const id = first?.message?.id;\n return typeof id === 'string' ? id : null;\n}\n\nexport function createDeepAgentSendRecovery(\n options: DeepAgentSendRecoveryOptions\n): DeepAgentSendRecovery {\n const now = options.now ?? Date.now;\n const schedule = options.schedule ?? ((task: () => void) => queueMicrotask(task));\n\n let disposed = false;\n let hydrated = false;\n /** Work may exist: set at hydration and on retryable settles, cleared by a\n * sweep that could actually read the lane. */\n let armed = false;\n let sweepScheduled = false;\n /** Retry budget per message id, for this controller's attach lifetime. */\n const attempts = new Map<string, number>();\n /** Message ids already diagnosed as stale/exhausted, so the lane re-scan\n * stays quiet about them. */\n const surfacedSkips = new Set<string>();\n /** Message ids whose deferral behind a lost predecessor was diagnosed once. */\n const surfacedDeferrals = new Set<string>();\n /** Re-dispatched sends still awaiting the server's verdict: a successor\n * stamped `predecessorLost` waits while any of these is pending. */\n const inFlight = new Set<string>();\n /** Successors held back by the last sweep; a non-empty set keeps the\n * controller armed so the next settle or state change re-sweeps. */\n const deferred = new Set<string>();\n /** How many times the host held each message's retry (`beforeRetry`'s promise). */\n const holds = new Map<string, number>();\n /** A host's hold in progress: no sweep runs until it settles. */\n let holding = false;\n\n const record = (event: string, data?: Record<string, unknown>): void => {\n options.diagnostics?.()?.record(event, data);\n };\n\n const sweep = (): void => {\n sweepScheduled = false;\n // A host's hold re-sweeps once it settles; until then nothing is retried.\n if (disposed || holding || !hydrated || !armed) return;\n const lane = options.lane();\n // No readable lane yet: stay armed so the next state change re-sweeps.\n if (lane === null) return;\n armed = false;\n deferred.clear();\n const stamps = options.failureStamps?.() ?? null;\n // A `lost` entry earlier in lane order that this sweep leaves unsettled\n // (skipped as stale/exhausted, or re-dispatched and now in flight).\n let lostPredecessorPending = false;\n for (const entry of lane.failed) {\n if (!shouldAutoRetryFailedSend(entry.sendFailure)) continue;\n // Shared retry/discard may still be waiting for the storage lock. The\n // visible lane can keep this entry until then; do not spend another\n // attempt on a send whose previous retry is still awaiting a verdict.\n if (inFlight.has(entry.id)) {\n if (entry.sendFailure.fate === 'lost') lostPredecessorPending = true;\n continue;\n }\n if (awaitsLostPredecessor(entry) && (lostPredecessorPending || inFlight.size > 0)) {\n deferred.add(entry.id);\n if (!surfacedDeferrals.has(entry.id)) {\n surfacedDeferrals.add(entry.id);\n record('send-recovery/deferred', { messageId: entry.id });\n }\n continue;\n }\n const isLost = entry.sendFailure.fate === 'lost';\n const stamp = stamps?.get(entry.id);\n if (stamp !== undefined && now() - stamp > MAX_AUTO_RETRY_AGE_MS) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/stale', { messageId: entry.id, ageMs: Math.round(now() - stamp) });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n const attempt = (attempts.get(entry.id) ?? 0) + 1;\n if (attempt > MAX_AUTO_RETRIES_PER_MESSAGE) {\n if (!surfacedSkips.has(entry.id)) {\n surfacedSkips.add(entry.id);\n record('send-recovery/exhausted', { messageId: entry.id });\n }\n if (isLost) lostPredecessorPending = true;\n continue;\n }\n let before: ReturnType<NonNullable<DeepAgentSendRecoveryOptions['beforeRetry']>> | undefined;\n try {\n before = options.beforeRetry?.(entry.id);\n } catch {\n // A host's own context step failing never holds the retry back.\n record('send-recovery/before-retry-failed', { messageId: entry.id });\n }\n if (isThenable(before)) {\n const held = (holds.get(entry.id) ?? 0) + 1;\n if (held <= MAX_BEFORE_RETRY_HOLDS) {\n // The host can't put this message's context back yet: it waits, and\n // so does everything behind it (nothing overtakes it); the sweep asks\n // again once the hold settles.\n holds.set(entry.id, held);\n holding = true;\n armed = true;\n record('send-recovery/held', { messageId: entry.id, holds: held });\n const resume = (): void => {\n holding = false;\n armed = true;\n scheduleSweep();\n };\n before.then(resume, resume);\n return;\n }\n record('send-recovery/held-too-long', { messageId: entry.id });\n }\n try {\n lane.retryFailed(entry.id);\n attempts.set(entry.id, attempt);\n inFlight.add(entry.id);\n if (isLost) lostPredecessorPending = true;\n record('send-recovery/retry', {\n messageId: entry.id,\n fate: entry.sendFailure.fate,\n attempt,\n });\n } catch {\n // The entry settled or was covered between the lane read and the\n // retry (the vendor drops covered failures against every snapshot);\n // nothing was dispatched, so the host lets go of what it put back.\n record('send-recovery/raced', { messageId: entry.id });\n try {\n if (typeof before === 'function') before();\n } catch {\n // The host's own step failing never stops the sweep.\n }\n }\n }\n // Held successors must be revisited once their predecessors settle.\n if (deferred.size > 0) armed = true;\n };\n\n const scheduleSweep = (): void => {\n if (disposed || sweepScheduled || holding || !hydrated || !armed) return;\n sweepScheduled = true;\n schedule(sweep);\n };\n\n return {\n observeStateChange(state) {\n if (disposed) return;\n if (!hydrated && isDeepAgentStateHydrated(state)) {\n // First real snapshot: the vendor's failureCovered pass has had its\n // chance to drop entries whose message actually landed, so whatever\n // remains provably never reached the thread.\n hydrated = true;\n armed = true;\n }\n scheduleSweep();\n },\n observeCommand(update) {\n if (disposed || update.status !== 'settled') return;\n const messageId = commandMessageId(update);\n if (messageId !== null) inFlight.delete(messageId);\n // A never-server-judged settle means new work; any settle while\n // successors are held may be the predecessor they wait on.\n if (!shouldAutoRetryFailedSend(update.failure) && deferred.size === 0) return;\n armed = true;\n scheduleSweep();\n },\n observeFailedLaneChange() {\n if (disposed) return;\n armed = true;\n scheduleSweep();\n },\n dispose() {\n disposed = true;\n },\n };\n}\n"],"names":[],"mappings":";AA0CA,MAAM,mBAAwC,oBAAI,IAAI,CAAC,QAAQ,SAAS,CAAC;AAIzE,MAAM,+BAA+B;AAKrC,MAAM,wBAAwB,KAAK,KAAK,KAAK;AAKtC,MAAM,yBAAyB;AAqD/B,SAAS,0BAA0B,SAAgD;AACxF,SAAO,YAAY,UAAa,iBAAiB,IAAI,QAAQ,IAAI;AACnE;AAGA,SAAS,sBAAsB,OAA0C;AACvE,SAAO,MAAM,YAAY,SAAS,aAAa,MAAM,YAAY,oBAAoB;AACvF;AAEA,SAAS,WAAW,OAA+C;AACjE,SACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA6B,SAAS;AAElD;AAGA,SAAS,iBAAiB,QAA0D;;AAClF,QAAM,SAAQ,YAAO,WAAP,mBAAgB;AAC9B,QAAM,MAAK,oCAAO,YAAP,mBAAgB;AAC3B,SAAO,OAAO,OAAO,WAAW,KAAK;AACvC;AAEO,SAAS,4BACd,SACuB;AACvB,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,WAAW,QAAQ,aAAa,CAAC,SAAqB,eAAe,IAAI;AAE/E,MAAI,WAAW;AACf,MAAI,WAAW;AAGf,MAAI,QAAQ;AACZ,MAAI,iBAAiB;AAErB,QAAM,+BAAe,IAAA;AAGrB,QAAM,oCAAoB,IAAA;AAE1B,QAAM,wCAAwB,IAAA;AAG9B,QAAM,+BAAe,IAAA;AAGrB,QAAM,+BAAe,IAAA;AAErB,QAAM,4BAAY,IAAA;AAElB,MAAI,UAAU;AAEd,QAAM,SAAS,CAAC,OAAe,SAAyC;;AACtE,wBAAQ,gBAAR,wDAAyB,OAAO,OAAO;AAAA,EACzC;AAEA,QAAM,QAAQ,MAAY;;AACxB,qBAAiB;AAEjB,QAAI,YAAY,WAAW,CAAC,YAAY,CAAC,MAAO;AAChD,UAAM,OAAO,QAAQ,KAAA;AAErB,QAAI,SAAS,KAAM;AACnB,YAAQ;AACR,aAAS,MAAA;AACT,UAAM,WAAS,aAAQ,kBAAR,qCAA6B;AAG5C,QAAI,yBAAyB;AAC7B,eAAW,SAAS,KAAK,QAAQ;AAC/B,UAAI,CAAC,0BAA0B,MAAM,WAAW,EAAG;AAInD,UAAI,SAAS,IAAI,MAAM,EAAE,GAAG;AAC1B,YAAI,MAAM,YAAY,SAAS,OAAQ,0BAAyB;AAChE;AAAA,MACF;AACA,UAAI,sBAAsB,KAAK,MAAM,0BAA0B,SAAS,OAAO,IAAI;AACjF,iBAAS,IAAI,MAAM,EAAE;AACrB,YAAI,CAAC,kBAAkB,IAAI,MAAM,EAAE,GAAG;AACpC,4BAAkB,IAAI,MAAM,EAAE;AAC9B,iBAAO,0BAA0B,EAAE,WAAW,MAAM,IAAI;AAAA,QAC1D;AACA;AAAA,MACF;AACA,YAAM,SAAS,MAAM,YAAY,SAAS;AAC1C,YAAM,QAAQ,iCAAQ,IAAI,MAAM;AAChC,UAAI,UAAU,UAAa,IAAA,IAAQ,QAAQ,uBAAuB;AAChE,YAAI,CAAC,cAAc,IAAI,MAAM,EAAE,GAAG;AAChC,wBAAc,IAAI,MAAM,EAAE;AAC1B,iBAAO,uBAAuB,EAAE,WAAW,MAAM,IAAI,OAAO,KAAK,MAAM,QAAQ,KAAK,EAAA,CAAG;AAAA,QACzF;AACA,YAAI,OAAQ,0BAAyB;AACrC;AAAA,MACF;AACA,YAAM,WAAW,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK;AAChD,UAAI,UAAU,8BAA8B;AAC1C,YAAI,CAAC,cAAc,IAAI,MAAM,EAAE,GAAG;AAChC,wBAAc,IAAI,MAAM,EAAE;AAC1B,iBAAO,2BAA2B,EAAE,WAAW,MAAM,IAAI;AAAA,QAC3D;AACA,YAAI,OAAQ,0BAAyB;AACrC;AAAA,MACF;AACA,UAAI;AACJ,UAAI;AACF,kBAAS,aAAQ,gBAAR,iCAAsB,MAAM;AAAA,MACvC,QAAQ;AAEN,eAAO,qCAAqC,EAAE,WAAW,MAAM,IAAI;AAAA,MACrE;AACA,UAAI,WAAW,MAAM,GAAG;AACtB,cAAM,QAAQ,MAAM,IAAI,MAAM,EAAE,KAAK,KAAK;AAC1C,YAAI,QAAQ,wBAAwB;AAIlC,gBAAM,IAAI,MAAM,IAAI,IAAI;AACxB,oBAAU;AACV,kBAAQ;AACR,iBAAO,sBAAsB,EAAE,WAAW,MAAM,IAAI,OAAO,MAAM;AACjE,gBAAM,SAAS,MAAY;AACzB,sBAAU;AACV,oBAAQ;AACR,0BAAA;AAAA,UACF;AACA,iBAAO,KAAK,QAAQ,MAAM;AAC1B;AAAA,QACF;AACA,eAAO,+BAA+B,EAAE,WAAW,MAAM,IAAI;AAAA,MAC/D;AACA,UAAI;AACF,aAAK,YAAY,MAAM,EAAE;AACzB,iBAAS,IAAI,MAAM,IAAI,OAAO;AAC9B,iBAAS,IAAI,MAAM,EAAE;AACrB,YAAI,OAAQ,0BAAyB;AACrC,eAAO,uBAAuB;AAAA,UAC5B,WAAW,MAAM;AAAA,UACjB,MAAM,MAAM,YAAY;AAAA,UACxB;AAAA,QAAA,CACD;AAAA,MACH,QAAQ;AAIN,eAAO,uBAAuB,EAAE,WAAW,MAAM,IAAI;AACrD,YAAI;AACF,cAAI,OAAO,WAAW,WAAY,QAAA;AAAA,QACpC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS,OAAO,EAAG,SAAQ;AAAA,EACjC;AAEA,QAAM,gBAAgB,MAAY;AAChC,QAAI,YAAY,kBAAkB,WAAW,CAAC,YAAY,CAAC,MAAO;AAClE,qBAAiB;AACjB,aAAS,KAAK;AAAA,EAChB;AAEA,SAAO;AAAA,IACL,mBAAmB,OAAO;AACxB,UAAI,SAAU;AACd,UAAI,CAAC,YAAY,yBAAyB,KAAK,GAAG;AAIhD,mBAAW;AACX,gBAAQ;AAAA,MACV;AACA,oBAAA;AAAA,IACF;AAAA,IACA,eAAe,QAAQ;AACrB,UAAI,YAAY,OAAO,WAAW,UAAW;AAC7C,YAAM,YAAY,iBAAiB,MAAM;AACzC,UAAI,cAAc,KAAM,UAAS,OAAO,SAAS;AAGjD,UAAI,CAAC,0BAA0B,OAAO,OAAO,KAAK,SAAS,SAAS,EAAG;AACvE,cAAQ;AACR,oBAAA;AAAA,IACF;AAAA,IACA,0BAA0B;AACxB,UAAI,SAAU;AACd,cAAQ;AACR,oBAAA;AAAA,IACF;AAAA,IACA,UAAU;AACR,iBAAW;AAAA,IACb;AAAA,EAAA;AAEJ;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const tap = require("@assistant-ui/tap");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const statewire = require("statewire");
6
6
  const suspendedCommands = () => new Proxy({}, {
7
7
  get: (_target, method) => {
@@ -10,9 +10,9 @@ const suspendedCommands = () => new Proxy({}, {
10
10
  }
11
11
  });
12
12
  const useSuspendedStatewire = (options) => {
13
- const latest = react.useRef(options);
13
+ const latest = require$$0.useRef(options);
14
14
  latest.current = options;
15
- const [value] = react.useState(() => {
15
+ const [value] = require$$0.useState(() => {
16
16
  const connection = {
17
17
  status: "standby",
18
18
  reason: "deferred",
@@ -1 +1 @@
1
- {"version":3,"file":"statewire-suspended.cjs","sources":["../../../../agent-runtime/src/statewire-suspended.ts"],"sourcesContent":["import { resource } from '@assistant-ui/tap';\nimport type { ResourceElement } from '@assistant-ui/tap';\nimport { useRef, useState } from 'react';\nimport type { Statewire, StatewireClient } from 'statewire';\nimport { StatewireSendError } from 'statewire';\n\nexport interface SuspendedStatewireOptions {\n /**\n * Why the transport is parked; surfaced as the connection message. Omitted\n * for a park that is part of normal startup rather than a refusal (a\n * `pending` session lane, whose principal is still loading): the connection\n * then carries no message and reads like a never-started chat, which hosts\n * render as ready rather than paused.\n */\n message?: string | undefined;\n /**\n * Invoked when a surface asks the parked connection to `reconnect()` (the\n * connection indicator's retry affordance). Hosts that park for a reason\n * only they can clear (e.g. the user has no workspace) omit it.\n */\n onReconnectRequested?: (() => void) | undefined;\n}\n\nconst suspendedCommands = <\n TCommands extends Statewire.Commands,\n>(): Statewire.CommandsProxy<TCommands> =>\n new Proxy({} as Statewire.CommandsProxy<TCommands>, {\n get: (_target, method) => {\n if (typeof method !== 'string') return undefined;\n // Settle like a locally-dead channel: hosts already classify\n // non-\"server\" causes as channel teardown (quiet log, no user error).\n return () =>\n Promise.reject(new StatewireSendError({ fate: 'aborted', cause: 'stream-gone' }));\n },\n });\n\nconst useSuspendedStatewire = <TCommands extends Statewire.Commands = Statewire.Commands>(\n options: SuspendedStatewireOptions\n): Statewire<undefined, TCommands> => {\n const latest = useRef(options);\n latest.current = options;\n // `state` stays undefined so the thread keeps serving its `initialState`\n // (the same contract a live transport has before its attach snapshot).\n const [value] = useState((): Statewire<undefined, TCommands> => {\n const connection: StatewireClient.Connection & { readonly message: string | undefined } = {\n status: 'standby',\n reason: 'deferred',\n get message() {\n return latest.current.message;\n },\n reconnect: () => latest.current.onReconnectRequested?.(),\n degraded: false,\n };\n return {\n state: undefined,\n commands: suspendedCommands<TCommands>(),\n connection,\n // Context updates while parked are local and must never start a dial.\n // The live transport receives the current snapshot when it replaces us.\n setContext: () => {},\n isBusy: false,\n };\n });\n return value;\n};\n\n/**\n * A statewire transport that never dials.\n *\n * Swapped in for the live WS/SSE transport when attaching is known to be\n * pointless — the host gates it (no workspace) or repeated `unauthorized`\n * denials parked it — so the thread element stays mounted for assistant-ui\n * consumers while the reconnect loop stops entirely.\n */\nexport const StatewireSuspended = resource(useSuspendedStatewire) as <\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: SuspendedStatewireOptions\n) => ResourceElement<Statewire<undefined, TCommands>>;\n"],"names":["StatewireSendError","useRef","useState","resource"],"mappings":";;;;;AAuBA,MAAM,oBAAoB,MAGxB,IAAI,MAAM,IAA0C;AAAA,EAClD,KAAK,CAAC,SAAS,WAAW;AACxB,QAAI,OAAO,WAAW,SAAU,QAAO;AAGvC,WAAO,MACL,QAAQ,OAAO,IAAIA,UAAAA,mBAAmB,EAAE,MAAM,WAAW,OAAO,cAAA,CAAe,CAAC;AAAA,EACpF;AACF,CAAC;AAEH,MAAM,wBAAwB,CAC5B,YACoC;AACpC,QAAM,SAASC,MAAAA,OAAO,OAAO;AAC7B,SAAO,UAAU;AAGjB,QAAM,CAAC,KAAK,IAAIC,MAAAA,SAAS,MAAuC;AAC9D,UAAM,aAAoF;AAAA,MACxF,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,IAAI,UAAU;AACZ,eAAO,OAAO,QAAQ;AAAA,MACxB;AAAA,MACA,WAAW,MAAA;;AAAM,kCAAO,SAAQ,yBAAf;AAAA;AAAA,MACjB,UAAU;AAAA,IAAA;AAEZ,WAAO;AAAA,MACL,OAAO;AAAA,MACP,UAAU,kBAAA;AAAA,MACV;AAAA;AAAA;AAAA,MAGA,YAAY,MAAM;AAAA,MAAC;AAAA,MACnB,QAAQ;AAAA,IAAA;AAAA,EAEZ,CAAC;AACD,SAAO;AACT;AAUO,MAAM,qBAAqBC,IAAAA,SAAS,qBAAqB;;"}
1
+ {"version":3,"file":"statewire-suspended.cjs","sources":["../../../../agent-runtime/src/statewire-suspended.ts"],"sourcesContent":["import { resource } from '@assistant-ui/tap';\nimport type { ResourceElement } from '@assistant-ui/tap';\nimport { useRef, useState } from 'react';\nimport type { Statewire, StatewireClient } from 'statewire';\nimport { StatewireSendError } from 'statewire';\n\nexport interface SuspendedStatewireOptions {\n /**\n * Why the transport is parked; surfaced as the connection message. Omitted\n * for a park that is part of normal startup rather than a refusal (a\n * `pending` session lane, whose principal is still loading): the connection\n * then carries no message and reads like a never-started chat, which hosts\n * render as ready rather than paused.\n */\n message?: string | undefined;\n /**\n * Invoked when a surface asks the parked connection to `reconnect()` (the\n * connection indicator's retry affordance). Hosts that park for a reason\n * only they can clear (e.g. the user has no workspace) omit it.\n */\n onReconnectRequested?: (() => void) | undefined;\n}\n\nconst suspendedCommands = <\n TCommands extends Statewire.Commands,\n>(): Statewire.CommandsProxy<TCommands> =>\n new Proxy({} as Statewire.CommandsProxy<TCommands>, {\n get: (_target, method) => {\n if (typeof method !== 'string') return undefined;\n // Settle like a locally-dead channel: hosts already classify\n // non-\"server\" causes as channel teardown (quiet log, no user error).\n return () =>\n Promise.reject(new StatewireSendError({ fate: 'aborted', cause: 'stream-gone' }));\n },\n });\n\nconst useSuspendedStatewire = <TCommands extends Statewire.Commands = Statewire.Commands>(\n options: SuspendedStatewireOptions\n): Statewire<undefined, TCommands> => {\n const latest = useRef(options);\n latest.current = options;\n // `state` stays undefined so the thread keeps serving its `initialState`\n // (the same contract a live transport has before its attach snapshot).\n const [value] = useState((): Statewire<undefined, TCommands> => {\n const connection: StatewireClient.Connection & { readonly message: string | undefined } = {\n status: 'standby',\n reason: 'deferred',\n get message() {\n return latest.current.message;\n },\n reconnect: () => latest.current.onReconnectRequested?.(),\n degraded: false,\n };\n return {\n state: undefined,\n commands: suspendedCommands<TCommands>(),\n connection,\n // Context updates while parked are local and must never start a dial.\n // The live transport receives the current snapshot when it replaces us.\n setContext: () => {},\n isBusy: false,\n };\n });\n return value;\n};\n\n/**\n * A statewire transport that never dials.\n *\n * Swapped in for the live WS/SSE transport when attaching is known to be\n * pointless — the host gates it (no workspace) or repeated `unauthorized`\n * denials parked it — so the thread element stays mounted for assistant-ui\n * consumers while the reconnect loop stops entirely.\n */\nexport const StatewireSuspended = resource(useSuspendedStatewire) as <\n TCommands extends Statewire.Commands = Statewire.Commands,\n>(\n options: SuspendedStatewireOptions\n) => ResourceElement<Statewire<undefined, TCommands>>;\n"],"names":["StatewireSendError","useRef","useState","resource"],"mappings":";;;;;AAuBA,MAAM,oBAAoB,MAGxB,IAAI,MAAM,IAA0C;AAAA,EAClD,KAAK,CAAC,SAAS,WAAW;AACxB,QAAI,OAAO,WAAW,SAAU,QAAO;AAGvC,WAAO,MACL,QAAQ,OAAO,IAAIA,UAAAA,mBAAmB,EAAE,MAAM,WAAW,OAAO,cAAA,CAAe,CAAC;AAAA,EACpF;AACF,CAAC;AAEH,MAAM,wBAAwB,CAC5B,YACoC;AACpC,QAAM,SAASC,WAAAA,OAAO,OAAO;AAC7B,SAAO,UAAU;AAGjB,QAAM,CAAC,KAAK,IAAIC,WAAAA,SAAS,MAAuC;AAC9D,UAAM,aAAoF;AAAA,MACxF,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,IAAI,UAAU;AACZ,eAAO,OAAO,QAAQ;AAAA,MACxB;AAAA,MACA,WAAW,MAAA;;AAAM,kCAAO,SAAQ,yBAAf;AAAA;AAAA,MACjB,UAAU;AAAA,IAAA;AAEZ,WAAO;AAAA,MACL,OAAO;AAAA,MACP,UAAU,kBAAA;AAAA,MACV;AAAA;AAAA;AAAA,MAGA,YAAY,MAAM;AAAA,MAAC;AAAA,MACnB,QAAQ;AAAA,IAAA;AAAA,EAEZ,CAAC;AACD,SAAO;AACT;AAUO,MAAM,qBAAqBC,IAAAA,SAAS,qBAAqB;;"}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const core = require("@assistant-ui/core");
4
4
  const store = require("@assistant-ui/store");
5
- const react = require("react");
5
+ const require$$0 = require("react");
6
6
  const runconfigContract = require("./generated/runconfig-contract.cjs");
7
7
  const messageText = require("./message-text.cjs");
8
8
  const subagentTranscripts = require("./subagent-transcripts.cjs");
@@ -65,6 +65,34 @@ function nestedTodosFromArtifact(artifact) {
65
65
  const todos = (_a = a == null ? void 0 : a.subgraph_state) == null ? void 0 : _a.todos;
66
66
  return Array.isArray(todos) ? todos : void 0;
67
67
  }
68
+ function ptcSubagentsFromArtifact(artifact) {
69
+ const a = artifact;
70
+ const entries = a == null ? void 0 : a.ptc_subagents;
71
+ if (!Array.isArray(entries)) return [];
72
+ return entries.filter(
73
+ (entry) => !!entry && typeof entry === "object" && typeof entry.id === "string" && !!entry.id
74
+ );
75
+ }
76
+ const inEvalDispatchCounts = /* @__PURE__ */ new WeakMap();
77
+ function countInEvalDispatches(artifact) {
78
+ if (typeof artifact !== "object" || artifact === null) return 0;
79
+ const cached = inEvalDispatchCounts.get(artifact);
80
+ if (cached !== void 0) return cached;
81
+ const summaries = new Set(ptcSubagentsFromArtifact(artifact).map((entry) => entry.id));
82
+ let count = summaries.size;
83
+ if (count === 0) {
84
+ const dispatches = /* @__PURE__ */ new Set();
85
+ for (const message of nestedMessagesFromArtifact(artifact)) {
86
+ if (message.type !== "ai" || !message.tool_calls) continue;
87
+ for (const call of message.tool_calls) {
88
+ if (call.name === toolNames.TASK_TOOL_NAME && call.id) dispatches.add(call.id);
89
+ }
90
+ }
91
+ count = dispatches.size;
92
+ }
93
+ inEvalDispatchCounts.set(artifact, count);
94
+ return count;
95
+ }
68
96
  const EMPTY_TRANSCRIPT_DERIVATION = {
69
97
  currentText: "",
70
98
  model: void 0,
@@ -234,14 +262,16 @@ function useTurnToolCallsAwaitingApproval(toolCallIds) {
234
262
  TOOL_CALL_ID_SEPARATOR
235
263
  )
236
264
  );
237
- return react.useMemo(
265
+ return require$$0.useMemo(
238
266
  () => key === "" ? NO_WAITING_TOOL_CALLS : new Set(key.split(TOOL_CALL_ID_SEPARATOR)),
239
267
  [key]
240
268
  );
241
269
  }
270
+ exports.countInEvalDispatches = countInEvalDispatches;
242
271
  exports.isTerminalSubagentStatus = isTerminalSubagentStatus;
243
272
  exports.nestedMessagesFromArtifact = nestedMessagesFromArtifact;
244
273
  exports.nestedTodosFromArtifact = nestedTodosFromArtifact;
274
+ exports.ptcSubagentsFromArtifact = ptcSubagentsFromArtifact;
245
275
  exports.readLaneUsage = readLaneUsage;
246
276
  exports.readTruncatedLane = readTruncatedLane;
247
277
  exports.subagentAwaitingApproval = subagentAwaitingApproval;