@athenaintel/react 0.28.0 → 0.30.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 (761) hide show
  1. package/README.md +418 -10
  2. package/dist/agent-runtime/src/asset-attachment.cjs.map +1 -0
  3. package/dist/agent-runtime/src/asset-attachment.js.map +1 -0
  4. package/dist/agent-runtime/src/auth-denial.cjs.map +1 -0
  5. package/dist/agent-runtime/src/auth-denial.js.map +1 -0
  6. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -0
  7. package/dist/agent-runtime/src/client-tool-bridge.js.map +1 -0
  8. package/dist/agent-runtime/src/client-tools.cjs.map +1 -0
  9. package/dist/agent-runtime/src/client-tools.js.map +1 -0
  10. package/dist/agent-runtime/src/composer-markdown.cjs +124 -0
  11. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -0
  12. package/dist/agent-runtime/src/composer-markdown.js +124 -0
  13. package/dist/agent-runtime/src/composer-markdown.js.map +1 -0
  14. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -0
  15. package/dist/agent-runtime/src/conversation-index.js.map +1 -0
  16. package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-list.cjs +36 -0
  17. package/dist/agent-runtime/src/conversation-list.cjs.map +1 -0
  18. package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-list.js +36 -0
  19. package/dist/agent-runtime/src/conversation-list.js.map +1 -0
  20. package/dist/{packages/agent-runtime → agent-runtime}/src/deep-agent-transport-recipe.cjs +5 -3
  21. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -0
  22. package/dist/{packages/agent-runtime → agent-runtime}/src/deep-agent-transport-recipe.js +6 -4
  23. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -0
  24. package/dist/agent-runtime/src/edit-command.cjs.map +1 -0
  25. package/dist/agent-runtime/src/edit-command.js.map +1 -0
  26. package/dist/{packages/agent-runtime → agent-runtime}/src/errors.cjs +23 -0
  27. package/dist/agent-runtime/src/errors.cjs.map +1 -0
  28. package/dist/{packages/agent-runtime → agent-runtime}/src/errors.js +23 -0
  29. package/dist/agent-runtime/src/errors.js.map +1 -0
  30. package/dist/agent-runtime/src/execute-output.cjs +41 -0
  31. package/dist/agent-runtime/src/execute-output.cjs.map +1 -0
  32. package/dist/agent-runtime/src/execute-output.js +41 -0
  33. package/dist/agent-runtime/src/execute-output.js.map +1 -0
  34. package/dist/{packages/agent-runtime → agent-runtime}/src/generated/runconfig-contract.cjs +12 -2
  35. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -0
  36. package/dist/{packages/agent-runtime → agent-runtime}/src/generated/runconfig-contract.js +12 -2
  37. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -0
  38. package/dist/agent-runtime/src/github-wake-event.cjs.map +1 -0
  39. package/dist/agent-runtime/src/github-wake-event.js.map +1 -0
  40. package/dist/{packages/agent-runtime → agent-runtime}/src/interrupts.cjs +24 -1
  41. package/dist/agent-runtime/src/interrupts.cjs.map +1 -0
  42. package/dist/{packages/agent-runtime → agent-runtime}/src/interrupts.js +24 -1
  43. package/dist/agent-runtime/src/interrupts.js.map +1 -0
  44. package/dist/agent-runtime/src/message-author.cjs.map +1 -0
  45. package/dist/agent-runtime/src/message-author.js.map +1 -0
  46. package/dist/agent-runtime/src/message-window.cjs.map +1 -0
  47. package/dist/agent-runtime/src/message-window.js.map +1 -0
  48. package/dist/{packages/agent-runtime → agent-runtime}/src/messages.cjs +8 -4
  49. package/dist/agent-runtime/src/messages.cjs.map +1 -0
  50. package/dist/{packages/agent-runtime → agent-runtime}/src/messages.js +6 -2
  51. package/dist/agent-runtime/src/messages.js.map +1 -0
  52. package/dist/agent-runtime/src/model-context.cjs.map +1 -0
  53. package/dist/agent-runtime/src/model-context.js.map +1 -0
  54. package/dist/agent-runtime/src/optimistic-content.cjs.map +1 -0
  55. package/dist/agent-runtime/src/optimistic-content.js.map +1 -0
  56. package/dist/agent-runtime/src/protocol.cjs.map +1 -0
  57. package/dist/agent-runtime/src/protocol.js.map +1 -0
  58. package/dist/{packages/agent-runtime → agent-runtime}/src/queue.cjs +23 -2
  59. package/dist/agent-runtime/src/queue.cjs.map +1 -0
  60. package/dist/{packages/agent-runtime → agent-runtime}/src/queue.js +23 -2
  61. package/dist/agent-runtime/src/queue.js.map +1 -0
  62. package/dist/{packages/agent-runtime → agent-runtime}/src/quota-safe-local-storage-session.cjs +23 -13
  63. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -0
  64. package/dist/{packages/agent-runtime → agent-runtime}/src/quota-safe-local-storage-session.js +24 -14
  65. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -0
  66. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -0
  67. package/dist/agent-runtime/src/runtime-messages.js.map +1 -0
  68. package/dist/agent-runtime/src/screen-point.cjs.map +1 -0
  69. package/dist/agent-runtime/src/screen-point.js.map +1 -0
  70. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -0
  71. package/dist/agent-runtime/src/send-recovery.js.map +1 -0
  72. package/dist/agent-runtime/src/statewire-attach-observer.cjs.map +1 -0
  73. package/dist/agent-runtime/src/statewire-attach-observer.js.map +1 -0
  74. package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-state.cjs +8 -0
  75. package/dist/agent-runtime/src/statewire-state.cjs.map +1 -0
  76. package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-state.js +8 -0
  77. package/dist/agent-runtime/src/statewire-state.js.map +1 -0
  78. package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-suspended.cjs +4 -0
  79. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -0
  80. package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-suspended.js +4 -0
  81. package/dist/agent-runtime/src/statewire-suspended.js.map +1 -0
  82. package/dist/agent-runtime/src/statewire-transport.cjs +43 -0
  83. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -0
  84. package/dist/agent-runtime/src/statewire-transport.js +43 -0
  85. package/dist/agent-runtime/src/statewire-transport.js.map +1 -0
  86. package/dist/agent-runtime/src/streaming-markdown.cjs.map +1 -0
  87. package/dist/agent-runtime/src/streaming-markdown.js.map +1 -0
  88. package/dist/agent-runtime/src/subscription-wake-event.cjs +252 -0
  89. package/dist/agent-runtime/src/subscription-wake-event.cjs.map +1 -0
  90. package/dist/agent-runtime/src/subscription-wake-event.js +252 -0
  91. package/dist/agent-runtime/src/subscription-wake-event.js.map +1 -0
  92. package/dist/agent-runtime/src/thread-extras.cjs.map +1 -0
  93. package/dist/agent-runtime/src/thread-extras.js.map +1 -0
  94. package/dist/agent-runtime/src/thread-snapshot-cache.cjs.map +1 -0
  95. package/dist/agent-runtime/src/thread-snapshot-cache.js.map +1 -0
  96. package/dist/agent-runtime/src/thread-status.cjs.map +1 -0
  97. package/dist/agent-runtime/src/thread-status.js.map +1 -0
  98. package/dist/{packages/agent-runtime → agent-runtime}/src/tool-metadata.cjs +365 -3
  99. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -0
  100. package/dist/{packages/agent-runtime → agent-runtime}/src/tool-metadata.js +365 -3
  101. package/dist/agent-runtime/src/tool-metadata.js.map +1 -0
  102. package/dist/agent-runtime/src/tool-names.cjs +5 -0
  103. package/dist/agent-runtime/src/tool-names.cjs.map +1 -0
  104. package/dist/agent-runtime/src/tool-names.js +5 -0
  105. package/dist/agent-runtime/src/tool-names.js.map +1 -0
  106. package/dist/agent-runtime/src/tool-outputs.cjs.map +1 -0
  107. package/dist/agent-runtime/src/tool-outputs.js.map +1 -0
  108. package/dist/agent-runtime/src/tool-result.cjs.map +1 -0
  109. package/dist/agent-runtime/src/tool-result.js.map +1 -0
  110. package/dist/{packages/agent-runtime → agent-runtime}/src/use-conversation-list.cjs +33 -22
  111. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -0
  112. package/dist/{packages/agent-runtime → agent-runtime}/src/use-conversation-list.js +34 -23
  113. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -0
  114. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -0
  115. package/dist/agent-runtime/src/use-deep-agent-config.js.map +1 -0
  116. package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-edit-submit.cjs +2 -0
  117. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -0
  118. package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-edit-submit.js +2 -0
  119. package/dist/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -0
  120. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -0
  121. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -0
  122. package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-thread.cjs +1 -0
  123. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -0
  124. package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-thread.js +2 -1
  125. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -0
  126. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -0
  127. package/dist/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -0
  128. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +52 -0
  129. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -0
  130. package/dist/agent-runtime/src/use-historical-edit-attachments.js +52 -0
  131. package/dist/agent-runtime/src/use-historical-edit-attachments.js.map +1 -0
  132. package/dist/{packages/agent-runtime → agent-runtime}/src/voice-presentation.cjs +14 -0
  133. package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -0
  134. package/dist/{packages/agent-runtime → agent-runtime}/src/voice-presentation.js +14 -0
  135. package/dist/agent-runtime/src/voice-presentation.js.map +1 -0
  136. package/dist/agent-runtime/src/voice-turn-grouping.cjs.map +1 -0
  137. package/dist/agent-runtime/src/voice-turn-grouping.js.map +1 -0
  138. package/dist/assets/AthenaAssetEmbed.cjs +8 -2
  139. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  140. package/dist/assets/AthenaAssetEmbed.d.ts +8 -0
  141. package/dist/assets/AthenaAssetEmbed.js +8 -2
  142. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  143. package/dist/assets/AthenaLayout.cjs +97 -31
  144. package/dist/assets/AthenaLayout.cjs.map +1 -1
  145. package/dist/assets/AthenaLayout.d.ts +13 -0
  146. package/dist/assets/AthenaLayout.js +98 -32
  147. package/dist/assets/AthenaLayout.js.map +1 -1
  148. package/dist/assets/asset-embed-messages.cjs.map +1 -1
  149. package/dist/assets/asset-embed-messages.d.ts +6 -0
  150. package/dist/assets/asset-embed-messages.js.map +1 -1
  151. package/dist/assets/asset-panel-store.cjs +68 -32
  152. package/dist/assets/asset-panel-store.cjs.map +1 -1
  153. package/dist/assets/asset-panel-store.d.ts +47 -1
  154. package/dist/assets/asset-panel-store.js +68 -32
  155. package/dist/assets/asset-panel-store.js.map +1 -1
  156. package/dist/assets/use-asset-embed.cjs +29 -8
  157. package/dist/assets/use-asset-embed.cjs.map +1 -1
  158. package/dist/assets/use-asset-embed.d.ts +7 -0
  159. package/dist/assets/use-asset-embed.js +29 -8
  160. package/dist/assets/use-asset-embed.js.map +1 -1
  161. package/dist/catalog/chat-pickers.cjs +152 -0
  162. package/dist/catalog/chat-pickers.cjs.map +1 -0
  163. package/dist/catalog/chat-pickers.d.ts +22 -0
  164. package/dist/catalog/chat-pickers.js +152 -0
  165. package/dist/catalog/chat-pickers.js.map +1 -0
  166. package/dist/catalog/runtime-catalog.cjs +181 -0
  167. package/dist/catalog/runtime-catalog.cjs.map +1 -0
  168. package/dist/catalog/runtime-catalog.d.ts +100 -0
  169. package/dist/catalog/runtime-catalog.js +181 -0
  170. package/dist/catalog/runtime-catalog.js.map +1 -0
  171. package/dist/chat/AthenaChat.cjs +86 -46
  172. package/dist/chat/AthenaChat.cjs.map +1 -1
  173. package/dist/chat/AthenaChat.d.ts +21 -4
  174. package/dist/chat/AthenaChat.js +88 -48
  175. package/dist/chat/AthenaChat.js.map +1 -1
  176. package/dist/chat/StatewireApprovalCard.cjs +38 -37
  177. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  178. package/dist/chat/StatewireApprovalCard.d.ts +2 -0
  179. package/dist/chat/StatewireApprovalCard.js +39 -38
  180. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  181. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  182. package/dist/chat/StatewireClientToolBridge.js +2 -2
  183. package/dist/chat/StatewireQueuedMessages.cjs +15 -12
  184. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  185. package/dist/chat/StatewireQueuedMessages.d.ts +22 -2
  186. package/dist/chat/StatewireQueuedMessages.js +15 -12
  187. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  188. package/dist/chat/StatewireRunRefusalNotice.cjs +48 -0
  189. package/dist/chat/StatewireRunRefusalNotice.cjs.map +1 -0
  190. package/dist/chat/StatewireRunRefusalNotice.d.ts +25 -0
  191. package/dist/chat/StatewireRunRefusalNotice.js +48 -0
  192. package/dist/chat/StatewireRunRefusalNotice.js.map +1 -0
  193. package/dist/chat/WaitingOnYouBanner.cjs +2 -2
  194. package/dist/chat/WaitingOnYouBanner.js +2 -2
  195. package/dist/chat/athena-citation-links.cjs +19 -15
  196. package/dist/chat/athena-citation-links.cjs.map +1 -1
  197. package/dist/chat/athena-citation-links.js +19 -15
  198. package/dist/chat/athena-citation-links.js.map +1 -1
  199. package/dist/chat/run-activity.cjs +9 -1
  200. package/dist/chat/run-activity.cjs.map +1 -1
  201. package/dist/chat/run-activity.d.ts +6 -0
  202. package/dist/chat/run-activity.js +10 -2
  203. package/dist/chat/run-activity.js.map +1 -1
  204. package/dist/chat/statewire-banners.cjs +30 -1
  205. package/dist/chat/statewire-banners.cjs.map +1 -1
  206. package/dist/chat/statewire-banners.d.ts +20 -1
  207. package/dist/chat/statewire-banners.js +32 -3
  208. package/dist/chat/statewire-banners.js.map +1 -1
  209. package/dist/chat/statewire-client-tools.cjs +1 -1
  210. package/dist/chat/statewire-client-tools.js +1 -1
  211. package/dist/chat/super-grouping/CollapsibleGroup.cjs +1 -1
  212. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  213. package/dist/chat/super-grouping/CollapsibleGroup.js +1 -1
  214. package/dist/chat/super-grouping/CollapsibleGroup.js.map +1 -1
  215. package/dist/chat/super-grouping/SuperGroupingCard.cjs +7 -5
  216. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  217. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +8 -2
  218. package/dist/chat/super-grouping/SuperGroupingCard.js +7 -5
  219. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  220. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +350 -0
  221. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -0
  222. package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +31 -0
  223. package/dist/chat/super-grouping/SuperGroupingTranscript.js +350 -0
  224. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -0
  225. package/dist/chat/super-grouping/ToolTimeline.cjs +13 -2
  226. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  227. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -3
  228. package/dist/chat/super-grouping/ToolTimeline.js +13 -2
  229. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  230. package/dist/chat/super-grouping/activity-timeline.cjs +51 -26
  231. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  232. package/dist/chat/super-grouping/activity-timeline.d.ts +40 -8
  233. package/dist/chat/super-grouping/activity-timeline.js +52 -27
  234. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  235. package/dist/chat/super-grouping/index.cjs +12 -0
  236. package/dist/chat/super-grouping/index.cjs.map +1 -1
  237. package/dist/chat/super-grouping/index.d.ts +7 -2
  238. package/dist/chat/super-grouping/index.js +14 -2
  239. package/dist/chat/super-grouping/index.js.map +1 -1
  240. package/dist/chat/super-grouping/timeline-step.cjs +14 -5
  241. package/dist/chat/super-grouping/timeline-step.cjs.map +1 -1
  242. package/dist/chat/super-grouping/timeline-step.d.ts +10 -1
  243. package/dist/chat/super-grouping/timeline-step.js +15 -6
  244. package/dist/chat/super-grouping/timeline-step.js.map +1 -1
  245. package/dist/chat/super-grouping/turn-segments.cjs +82 -0
  246. package/dist/chat/super-grouping/turn-segments.cjs.map +1 -0
  247. package/dist/chat/super-grouping/turn-segments.d.ts +69 -0
  248. package/dist/chat/super-grouping/turn-segments.js +82 -0
  249. package/dist/chat/super-grouping/turn-segments.js.map +1 -0
  250. package/dist/chat/super-grouping/turn-timing.cjs +110 -0
  251. package/dist/chat/super-grouping/turn-timing.cjs.map +1 -0
  252. package/dist/chat/super-grouping/turn-timing.d.ts +52 -0
  253. package/dist/chat/super-grouping/turn-timing.js +110 -0
  254. package/dist/chat/super-grouping/turn-timing.js.map +1 -0
  255. package/dist/chat/tiptap-text.cjs +1 -1
  256. package/dist/chat/tiptap-text.js +1 -1
  257. package/dist/chat/use-athena-run-live.cjs +1 -1
  258. package/dist/chat/use-athena-run-live.js +1 -1
  259. package/dist/chat/use-statewire-approval-request.cjs +73 -4
  260. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  261. package/dist/chat/use-statewire-approval-request.js +74 -5
  262. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  263. package/dist/chat-ui/composer/composer-message.cjs +284 -0
  264. package/dist/chat-ui/composer/composer-message.cjs.map +1 -0
  265. package/dist/chat-ui/composer/composer-message.d.ts +152 -0
  266. package/dist/chat-ui/composer/composer-message.js +284 -0
  267. package/dist/chat-ui/composer/composer-message.js.map +1 -0
  268. package/dist/chat-ui/composer/tiptap-composer.cjs +57 -11
  269. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  270. package/dist/chat-ui/composer/tiptap-composer.d.ts +34 -6
  271. package/dist/chat-ui/composer/tiptap-composer.js +57 -11
  272. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  273. package/dist/chat-ui/index.cjs +4 -1
  274. package/dist/chat-ui/index.cjs.map +1 -1
  275. package/dist/chat-ui/index.d.ts +3 -2
  276. package/dist/chat-ui/index.js +5 -2
  277. package/dist/chat-ui/index.js.map +1 -1
  278. package/dist/chat-ui/mentions/mention-chip.cjs +3 -2
  279. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  280. package/dist/chat-ui/mentions/mention-chip.js +4 -3
  281. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  282. package/dist/chat-ui/mentions/mention-extension.cjs +8 -2
  283. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  284. package/dist/chat-ui/mentions/mention-extension.js +8 -2
  285. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  286. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +3 -1
  287. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  288. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.js +3 -1
  289. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.js.map +1 -1
  290. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +65 -19
  291. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  292. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +15 -0
  293. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +67 -21
  294. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  295. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +4 -2
  296. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  297. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +2 -1
  298. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +5 -3
  299. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  300. package/dist/chat-ui/messages/message-components.cjs +30 -10
  301. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  302. package/dist/chat-ui/messages/message-components.d.ts +21 -1
  303. package/dist/chat-ui/messages/message-components.js +30 -10
  304. package/dist/chat-ui/messages/message-components.js.map +1 -1
  305. package/dist/chat-ui/messages/runtime-message.cjs +1 -1
  306. package/dist/chat-ui/messages/runtime-message.js +1 -1
  307. package/dist/chat-ui/messages/statewire-continue-run.cjs +5 -5
  308. package/dist/chat-ui/messages/statewire-continue-run.js +5 -5
  309. package/dist/chat-ui/messages/user-edit-composer.cjs +1 -1
  310. package/dist/chat-ui/messages/user-edit-composer.js +1 -1
  311. package/dist/chat-ui/messages/wake-marker.cjs +39 -4
  312. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  313. package/dist/chat-ui/messages/wake-marker.d.ts +16 -5
  314. package/dist/chat-ui/messages/wake-marker.js +40 -5
  315. package/dist/chat-ui/messages/wake-marker.js.map +1 -1
  316. package/dist/chat-ui/rich-text/chat-message-body.cjs +12 -8
  317. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  318. package/dist/chat-ui/rich-text/chat-message-body.d.ts +6 -1
  319. package/dist/chat-ui/rich-text/chat-message-body.js +13 -9
  320. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
  321. package/dist/chat-ui/rich-text/chat-text-schema.cjs +64 -6
  322. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
  323. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +5 -0
  324. package/dist/chat-ui/rich-text/chat-text-schema.js +66 -8
  325. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
  326. package/dist/chat-ui/statewire.cjs +1 -1
  327. package/dist/chat-ui/statewire.d.ts +1 -1
  328. package/dist/chat-ui/statewire.js +1 -1
  329. package/dist/chat-ui/thread/statewire-history-edge.cjs +2 -2
  330. package/dist/chat-ui/thread/statewire-history-edge.js +2 -2
  331. package/dist/collab/client.cjs +218 -13
  332. package/dist/collab/client.cjs.map +1 -1
  333. package/dist/collab/client.d.ts +105 -2
  334. package/dist/collab/client.js +221 -17
  335. package/dist/collab/client.js.map +1 -1
  336. package/dist/collab/index.cjs +2 -0
  337. package/dist/collab/index.cjs.map +1 -1
  338. package/dist/collab/index.d.ts +1 -1
  339. package/dist/collab/index.js +3 -1
  340. package/dist/composer/AttachmentContext.cjs +38 -12
  341. package/dist/composer/AttachmentContext.cjs.map +1 -1
  342. package/dist/composer/AttachmentContext.d.ts +22 -1
  343. package/dist/composer/AttachmentContext.js +40 -14
  344. package/dist/composer/AttachmentContext.js.map +1 -1
  345. package/dist/composer/QuoteContext.cjs +80 -28
  346. package/dist/composer/QuoteContext.cjs.map +1 -1
  347. package/dist/composer/QuoteContext.d.ts +35 -6
  348. package/dist/composer/QuoteContext.js +82 -30
  349. package/dist/composer/QuoteContext.js.map +1 -1
  350. package/dist/composer/build-composed-message.cjs +27 -0
  351. package/dist/composer/build-composed-message.cjs.map +1 -1
  352. package/dist/composer/build-composed-message.d.ts +21 -0
  353. package/dist/composer/build-composed-message.js +28 -1
  354. package/dist/composer/build-composed-message.js.map +1 -1
  355. package/dist/composer/composer-handoff.cjs +13 -1
  356. package/dist/composer/composer-handoff.cjs.map +1 -1
  357. package/dist/composer/composer-handoff.d.ts +12 -0
  358. package/dist/composer/composer-handoff.js +15 -3
  359. package/dist/composer/composer-handoff.js.map +1 -1
  360. package/dist/composer/index.d.ts +6 -3
  361. package/dist/composer/useReadComposerDraft.cjs +16 -0
  362. package/dist/composer/useReadComposerDraft.cjs.map +1 -0
  363. package/dist/composer/useReadComposerDraft.d.ts +6 -0
  364. package/dist/composer/useReadComposerDraft.js +16 -0
  365. package/dist/composer/useReadComposerDraft.js.map +1 -0
  366. package/dist/diagnostics/errors.cjs +6 -0
  367. package/dist/diagnostics/errors.cjs.map +1 -1
  368. package/dist/diagnostics/errors.d.ts +6 -0
  369. package/dist/diagnostics/errors.js +6 -0
  370. package/dist/diagnostics/errors.js.map +1 -1
  371. package/dist/index.cjs +159 -7
  372. package/dist/index.cjs.map +1 -1
  373. package/dist/index.d.ts +53 -12
  374. package/dist/index.js +166 -14
  375. package/dist/index.js.map +1 -1
  376. package/dist/lib/owner-document.cjs +32 -0
  377. package/dist/lib/owner-document.cjs.map +1 -0
  378. package/dist/lib/owner-document.d.ts +17 -0
  379. package/dist/lib/owner-document.js +32 -0
  380. package/dist/lib/owner-document.js.map +1 -0
  381. package/dist/lib/portal-surface.cjs +55 -0
  382. package/dist/lib/portal-surface.cjs.map +1 -0
  383. package/dist/lib/portal-surface.d.ts +37 -0
  384. package/dist/lib/portal-surface.js +55 -0
  385. package/dist/lib/portal-surface.js.map +1 -0
  386. package/dist/lib/use-athena-rest-query.cjs +34 -0
  387. package/dist/lib/use-athena-rest-query.cjs.map +1 -0
  388. package/dist/lib/use-athena-rest-query.d.ts +31 -0
  389. package/dist/lib/use-athena-rest-query.js +34 -0
  390. package/dist/lib/use-athena-rest-query.js.map +1 -0
  391. package/dist/provider/AthenaProvider.cjs +36 -6
  392. package/dist/provider/AthenaProvider.cjs.map +1 -1
  393. package/dist/provider/AthenaProvider.d.ts +20 -1
  394. package/dist/provider/AthenaProvider.js +38 -8
  395. package/dist/provider/AthenaProvider.js.map +1 -1
  396. package/dist/provider/citation-links.d.ts +10 -2
  397. package/dist/{packages/react → react}/package.json.cjs +1 -1
  398. package/dist/{packages/react → react}/package.json.js +1 -1
  399. package/dist/runtime/statewire-lifecycle.cjs +15 -3
  400. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  401. package/dist/runtime/statewire-lifecycle.d.ts +6 -0
  402. package/dist/runtime/statewire-lifecycle.js +15 -3
  403. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  404. package/dist/runtime/useAthenaStatewireRuntime.cjs +11 -7
  405. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  406. package/dist/runtime/useAthenaStatewireRuntime.js +11 -7
  407. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  408. package/dist/search/useAthenaRepoSearch.cjs +5 -13
  409. package/dist/search/useAthenaRepoSearch.cjs.map +1 -1
  410. package/dist/search/useAthenaRepoSearch.d.ts +3 -3
  411. package/dist/search/useAthenaRepoSearch.js +6 -14
  412. package/dist/search/useAthenaRepoSearch.js.map +1 -1
  413. package/dist/sheet-range/a1.cjs +162 -0
  414. package/dist/sheet-range/a1.cjs.map +1 -0
  415. package/dist/sheet-range/a1.d.ts +91 -0
  416. package/dist/sheet-range/a1.js +162 -0
  417. package/dist/sheet-range/a1.js.map +1 -0
  418. package/dist/sheet-range/index.cjs +22 -0
  419. package/dist/sheet-range/index.cjs.map +1 -0
  420. package/dist/sheet-range/index.d.ts +12 -0
  421. package/dist/sheet-range/index.js +22 -0
  422. package/dist/sheet-range/index.js.map +1 -0
  423. package/dist/sheet-range/range-preview-table.cjs +75 -0
  424. package/dist/sheet-range/range-preview-table.cjs.map +1 -0
  425. package/dist/sheet-range/range-preview-table.d.ts +20 -0
  426. package/dist/sheet-range/range-preview-table.js +75 -0
  427. package/dist/sheet-range/range-preview-table.js.map +1 -0
  428. package/dist/sheet-range/range-preview.cjs +116 -0
  429. package/dist/sheet-range/range-preview.cjs.map +1 -0
  430. package/dist/sheet-range/range-preview.d.ts +67 -0
  431. package/dist/sheet-range/range-preview.js +116 -0
  432. package/dist/sheet-range/range-preview.js.map +1 -0
  433. package/dist/styles.css +1 -1
  434. package/dist/threads/Inbox.cjs +289 -0
  435. package/dist/threads/Inbox.cjs.map +1 -0
  436. package/dist/threads/Inbox.d.ts +46 -0
  437. package/dist/threads/Inbox.js +289 -0
  438. package/dist/threads/Inbox.js.map +1 -0
  439. package/dist/threads/SessionList.cjs +51 -126
  440. package/dist/threads/SessionList.cjs.map +1 -1
  441. package/dist/threads/SessionList.d.ts +26 -1
  442. package/dist/threads/SessionList.js +45 -120
  443. package/dist/threads/SessionList.js.map +1 -1
  444. package/dist/threads/SessionsPage.cjs +753 -0
  445. package/dist/threads/SessionsPage.cjs.map +1 -0
  446. package/dist/threads/SessionsPage.d.ts +35 -0
  447. package/dist/threads/SessionsPage.js +753 -0
  448. package/dist/threads/SessionsPage.js.map +1 -0
  449. package/dist/threads/api.cjs +21 -1
  450. package/dist/threads/api.cjs.map +1 -1
  451. package/dist/threads/api.d.ts +59 -0
  452. package/dist/threads/api.js +21 -1
  453. package/dist/threads/api.js.map +1 -1
  454. package/dist/threads/conversation-list-fetcher.cjs +9 -2
  455. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  456. package/dist/threads/conversation-list-fetcher.d.ts +14 -1
  457. package/dist/threads/conversation-list-fetcher.js +9 -2
  458. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  459. package/dist/threads/index.d.ts +2 -1
  460. package/dist/threads/pull-request-display.cjs +25 -0
  461. package/dist/threads/pull-request-display.cjs.map +1 -0
  462. package/dist/threads/pull-request-display.d.ts +15 -0
  463. package/dist/threads/pull-request-display.js +25 -0
  464. package/dist/threads/pull-request-display.js.map +1 -0
  465. package/dist/threads/session-list-model.cjs +16 -2
  466. package/dist/threads/session-list-model.cjs.map +1 -1
  467. package/dist/threads/session-list-model.d.ts +10 -0
  468. package/dist/threads/session-list-model.js +16 -2
  469. package/dist/threads/session-list-model.js.map +1 -1
  470. package/dist/threads/session-row-parts.cjs +152 -0
  471. package/dist/threads/session-row-parts.cjs.map +1 -0
  472. package/dist/threads/session-row-parts.d.ts +50 -0
  473. package/dist/threads/session-row-parts.js +152 -0
  474. package/dist/threads/session-row-parts.js.map +1 -0
  475. package/dist/threads/sessions-page-model.cjs +305 -0
  476. package/dist/threads/sessions-page-model.cjs.map +1 -0
  477. package/dist/threads/sessions-page-model.d.ts +86 -0
  478. package/dist/threads/sessions-page-model.js +305 -0
  479. package/dist/threads/sessions-page-model.js.map +1 -0
  480. package/dist/threads/sessions-page-storage.cjs +93 -0
  481. package/dist/threads/sessions-page-storage.cjs.map +1 -0
  482. package/dist/threads/sessions-page-storage.d.ts +23 -0
  483. package/dist/threads/sessions-page-storage.js +93 -0
  484. package/dist/threads/sessions-page-storage.js.map +1 -0
  485. package/dist/threads/sessions-query.cjs +235 -0
  486. package/dist/threads/sessions-query.cjs.map +1 -0
  487. package/dist/threads/sessions-query.d.ts +119 -0
  488. package/dist/threads/sessions-query.js +235 -0
  489. package/dist/threads/sessions-query.js.map +1 -0
  490. package/dist/threads/statewire-thread-list.cjs +133 -40
  491. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  492. package/dist/threads/statewire-thread-list.d.ts +83 -2
  493. package/dist/threads/statewire-thread-list.js +134 -41
  494. package/dist/threads/statewire-thread-list.js.map +1 -1
  495. package/dist/threads/use-athena-sessions.cjs +198 -0
  496. package/dist/threads/use-athena-sessions.cjs.map +1 -0
  497. package/dist/threads/use-athena-sessions.d.ts +81 -0
  498. package/dist/threads/use-athena-sessions.js +198 -0
  499. package/dist/threads/use-athena-sessions.js.map +1 -0
  500. package/dist/threads/use-rest-conversation-history.cjs +1 -1
  501. package/dist/threads/use-rest-conversation-history.js +1 -1
  502. package/dist/threads/use-statewire-conversation-history.cjs +1 -1
  503. package/dist/threads/use-statewire-conversation-history.d.ts +3 -0
  504. package/dist/threads/use-statewire-conversation-history.js +1 -1
  505. package/dist/threads/use-thread-read-state.cjs +73 -0
  506. package/dist/threads/use-thread-read-state.cjs.map +1 -0
  507. package/dist/threads/use-thread-read-state.d.ts +51 -0
  508. package/dist/threads/use-thread-read-state.js +73 -0
  509. package/dist/threads/use-thread-read-state.js.map +1 -0
  510. package/dist/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +1 -0
  511. package/dist/tiptap-markdown-table/src/markdown-table-serializer.js.map +1 -0
  512. package/dist/tools/auto-open-tools.cjs +2 -0
  513. package/dist/tools/auto-open-tools.cjs.map +1 -1
  514. package/dist/tools/auto-open-tools.js +2 -0
  515. package/dist/tools/auto-open-tools.js.map +1 -1
  516. package/dist/tools/file-tool-uis.cjs +18 -43
  517. package/dist/tools/file-tool-uis.cjs.map +1 -1
  518. package/dist/tools/file-tool-uis.d.ts +1 -2
  519. package/dist/tools/file-tool-uis.js +18 -42
  520. package/dist/tools/file-tool-uis.js.map +1 -1
  521. package/dist/tools/index.cjs +6 -2
  522. package/dist/tools/index.cjs.map +1 -1
  523. package/dist/tools/index.d.ts +1 -0
  524. package/dist/tools/index.js +6 -2
  525. package/dist/tools/index.js.map +1 -1
  526. package/dist/tools/misc-tool-uis.cjs +2 -2
  527. package/dist/tools/misc-tool-uis.js +2 -2
  528. package/dist/tools/primitives.cjs +1 -1
  529. package/dist/tools/primitives.js +1 -1
  530. package/dist/tools/read-asset-tool-ui.cjs +21 -70
  531. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  532. package/dist/tools/read-asset-tool-ui.js +21 -70
  533. package/dist/tools/read-asset-tool-ui.js.map +1 -1
  534. package/dist/tools/step-text.cjs +21 -0
  535. package/dist/tools/step-text.cjs.map +1 -0
  536. package/dist/tools/step-text.d.ts +10 -0
  537. package/dist/tools/step-text.js +21 -0
  538. package/dist/tools/step-text.js.map +1 -0
  539. package/dist/tools/tool-fallback.cjs +24 -5
  540. package/dist/tools/tool-fallback.cjs.map +1 -1
  541. package/dist/tools/tool-fallback.d.ts +3 -1
  542. package/dist/tools/tool-fallback.js +24 -5
  543. package/dist/tools/tool-fallback.js.map +1 -1
  544. package/dist/tools/tool-summary.cjs +661 -0
  545. package/dist/tools/tool-summary.cjs.map +1 -0
  546. package/dist/tools/tool-summary.d.ts +99 -0
  547. package/dist/tools/tool-summary.js +661 -0
  548. package/dist/tools/tool-summary.js.map +1 -0
  549. package/dist/tools/tool-uis.cjs +39 -97
  550. package/dist/tools/tool-uis.cjs.map +1 -1
  551. package/dist/tools/tool-uis.js +39 -97
  552. package/dist/tools/tool-uis.js.map +1 -1
  553. package/dist/tools/voice-update-tool-ui.cjs +1 -1
  554. package/dist/tools/voice-update-tool-ui.js +1 -1
  555. package/dist/tools/write-todos-tool-ui.cjs +3 -2
  556. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  557. package/dist/tools/write-todos-tool-ui.d.ts +5 -0
  558. package/dist/tools/write-todos-tool-ui.js +5 -4
  559. package/dist/tools/write-todos-tool-ui.js.map +1 -1
  560. package/dist/ui/popover.cjs +6 -6
  561. package/dist/ui/popover.cjs.map +1 -1
  562. package/dist/ui/popover.js +6 -6
  563. package/dist/ui/popover.js.map +1 -1
  564. package/dist/ui/tooltip.cjs +16 -2
  565. package/dist/ui/tooltip.cjs.map +1 -1
  566. package/dist/ui/tooltip.d.ts +1 -1
  567. package/dist/ui/tooltip.js +16 -2
  568. package/dist/ui/tooltip.js.map +1 -1
  569. package/dist/version.cjs +1 -1
  570. package/dist/version.js +1 -1
  571. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  572. package/dist/voice/use-athena-voice-session.d.ts +3 -3
  573. package/dist/voice/use-athena-voice-session.js.map +1 -1
  574. package/dist/workbench/SessionWorkbench.cjs +378 -0
  575. package/dist/workbench/SessionWorkbench.cjs.map +1 -0
  576. package/dist/workbench/SessionWorkbench.d.ts +30 -0
  577. package/dist/workbench/SessionWorkbench.js +378 -0
  578. package/dist/workbench/SessionWorkbench.js.map +1 -0
  579. package/dist/workbench/session-workbench-context.cjs +26 -0
  580. package/dist/workbench/session-workbench-context.cjs.map +1 -0
  581. package/dist/workbench/session-workbench-context.d.ts +55 -0
  582. package/dist/workbench/session-workbench-context.js +26 -0
  583. package/dist/workbench/session-workbench-context.js.map +1 -0
  584. package/dist/workbench/session-workbench-model.cjs +288 -0
  585. package/dist/workbench/session-workbench-model.cjs.map +1 -0
  586. package/dist/workbench/session-workbench-model.d.ts +168 -0
  587. package/dist/workbench/session-workbench-model.js +288 -0
  588. package/dist/workbench/session-workbench-model.js.map +1 -0
  589. package/dist/workbench/session-workbench-panes.cjs +580 -0
  590. package/dist/workbench/session-workbench-panes.cjs.map +1 -0
  591. package/dist/workbench/session-workbench-panes.d.ts +16 -0
  592. package/dist/workbench/session-workbench-panes.js +580 -0
  593. package/dist/workbench/session-workbench-panes.js.map +1 -0
  594. package/dist/workbench/session-workspace-api.cjs +157 -0
  595. package/dist/workbench/session-workspace-api.cjs.map +1 -0
  596. package/dist/workbench/session-workspace-api.d.ts +70 -0
  597. package/dist/workbench/session-workspace-api.js +157 -0
  598. package/dist/workbench/session-workspace-api.js.map +1 -0
  599. package/dist/workbench/use-session-workspace.cjs +100 -0
  600. package/dist/workbench/use-session-workspace.cjs.map +1 -0
  601. package/dist/workbench/use-session-workspace.d.ts +45 -0
  602. package/dist/workbench/use-session-workspace.js +100 -0
  603. package/dist/workbench/use-session-workspace.js.map +1 -0
  604. package/dist/workbench/workbench-layout-context.cjs +10 -0
  605. package/dist/workbench/workbench-layout-context.cjs.map +1 -0
  606. package/dist/workbench/workbench-layout-context.d.ts +17 -0
  607. package/dist/workbench/workbench-layout-context.js +10 -0
  608. package/dist/workbench/workbench-layout-context.js.map +1 -0
  609. package/package.json +20 -9
  610. package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.cjs +0 -77
  611. package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.cjs.map +0 -1
  612. package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.js +0 -77
  613. package/dist/node_modules/@assistant-ui/react-langchain/dist/converter.js.map +0 -1
  614. package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.cjs +0 -181
  615. package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.cjs.map +0 -1
  616. package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.js +0 -181
  617. package/dist/node_modules/@assistant-ui/react-langgraph/dist/convertLangChainMessages.js.map +0 -1
  618. package/dist/packages/agent-runtime/src/asset-attachment.cjs.map +0 -1
  619. package/dist/packages/agent-runtime/src/asset-attachment.js.map +0 -1
  620. package/dist/packages/agent-runtime/src/auth-denial.cjs.map +0 -1
  621. package/dist/packages/agent-runtime/src/auth-denial.js.map +0 -1
  622. package/dist/packages/agent-runtime/src/client-tool-bridge.cjs.map +0 -1
  623. package/dist/packages/agent-runtime/src/client-tool-bridge.js.map +0 -1
  624. package/dist/packages/agent-runtime/src/client-tools.cjs.map +0 -1
  625. package/dist/packages/agent-runtime/src/client-tools.js.map +0 -1
  626. package/dist/packages/agent-runtime/src/conversation-index.cjs.map +0 -1
  627. package/dist/packages/agent-runtime/src/conversation-index.js.map +0 -1
  628. package/dist/packages/agent-runtime/src/conversation-list.cjs.map +0 -1
  629. package/dist/packages/agent-runtime/src/conversation-list.js.map +0 -1
  630. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.cjs.map +0 -1
  631. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.js.map +0 -1
  632. package/dist/packages/agent-runtime/src/edit-command.cjs.map +0 -1
  633. package/dist/packages/agent-runtime/src/edit-command.js.map +0 -1
  634. package/dist/packages/agent-runtime/src/errors.cjs.map +0 -1
  635. package/dist/packages/agent-runtime/src/errors.js.map +0 -1
  636. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +0 -1
  637. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +0 -1
  638. package/dist/packages/agent-runtime/src/github-wake-event.cjs.map +0 -1
  639. package/dist/packages/agent-runtime/src/github-wake-event.js.map +0 -1
  640. package/dist/packages/agent-runtime/src/interrupts.cjs.map +0 -1
  641. package/dist/packages/agent-runtime/src/interrupts.js.map +0 -1
  642. package/dist/packages/agent-runtime/src/message-author.cjs.map +0 -1
  643. package/dist/packages/agent-runtime/src/message-author.js.map +0 -1
  644. package/dist/packages/agent-runtime/src/message-window.cjs.map +0 -1
  645. package/dist/packages/agent-runtime/src/message-window.js.map +0 -1
  646. package/dist/packages/agent-runtime/src/messages.cjs.map +0 -1
  647. package/dist/packages/agent-runtime/src/messages.js.map +0 -1
  648. package/dist/packages/agent-runtime/src/model-context.cjs.map +0 -1
  649. package/dist/packages/agent-runtime/src/model-context.js.map +0 -1
  650. package/dist/packages/agent-runtime/src/optimistic-content.cjs.map +0 -1
  651. package/dist/packages/agent-runtime/src/optimistic-content.js.map +0 -1
  652. package/dist/packages/agent-runtime/src/protocol.cjs.map +0 -1
  653. package/dist/packages/agent-runtime/src/protocol.js.map +0 -1
  654. package/dist/packages/agent-runtime/src/queue.cjs.map +0 -1
  655. package/dist/packages/agent-runtime/src/queue.js.map +0 -1
  656. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +0 -1
  657. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +0 -1
  658. package/dist/packages/agent-runtime/src/runtime-messages.cjs.map +0 -1
  659. package/dist/packages/agent-runtime/src/runtime-messages.js.map +0 -1
  660. package/dist/packages/agent-runtime/src/screen-point.cjs.map +0 -1
  661. package/dist/packages/agent-runtime/src/screen-point.js.map +0 -1
  662. package/dist/packages/agent-runtime/src/send-recovery.cjs.map +0 -1
  663. package/dist/packages/agent-runtime/src/send-recovery.js.map +0 -1
  664. package/dist/packages/agent-runtime/src/statewire-attach-observer.cjs.map +0 -1
  665. package/dist/packages/agent-runtime/src/statewire-attach-observer.js.map +0 -1
  666. package/dist/packages/agent-runtime/src/statewire-state.cjs.map +0 -1
  667. package/dist/packages/agent-runtime/src/statewire-state.js.map +0 -1
  668. package/dist/packages/agent-runtime/src/statewire-suspended.cjs.map +0 -1
  669. package/dist/packages/agent-runtime/src/statewire-suspended.js.map +0 -1
  670. package/dist/packages/agent-runtime/src/statewire-transport.cjs +0 -11
  671. package/dist/packages/agent-runtime/src/statewire-transport.cjs.map +0 -1
  672. package/dist/packages/agent-runtime/src/statewire-transport.js +0 -11
  673. package/dist/packages/agent-runtime/src/statewire-transport.js.map +0 -1
  674. package/dist/packages/agent-runtime/src/streaming-markdown.cjs.map +0 -1
  675. package/dist/packages/agent-runtime/src/streaming-markdown.js.map +0 -1
  676. package/dist/packages/agent-runtime/src/thread-extras.cjs.map +0 -1
  677. package/dist/packages/agent-runtime/src/thread-extras.js.map +0 -1
  678. package/dist/packages/agent-runtime/src/thread-snapshot-cache.cjs.map +0 -1
  679. package/dist/packages/agent-runtime/src/thread-snapshot-cache.js.map +0 -1
  680. package/dist/packages/agent-runtime/src/thread-status.cjs.map +0 -1
  681. package/dist/packages/agent-runtime/src/thread-status.js.map +0 -1
  682. package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +0 -1
  683. package/dist/packages/agent-runtime/src/tool-metadata.js.map +0 -1
  684. package/dist/packages/agent-runtime/src/tool-outputs.cjs.map +0 -1
  685. package/dist/packages/agent-runtime/src/tool-outputs.js.map +0 -1
  686. package/dist/packages/agent-runtime/src/tool-result.cjs.map +0 -1
  687. package/dist/packages/agent-runtime/src/tool-result.js.map +0 -1
  688. package/dist/packages/agent-runtime/src/use-conversation-list.cjs.map +0 -1
  689. package/dist/packages/agent-runtime/src/use-conversation-list.js.map +0 -1
  690. package/dist/packages/agent-runtime/src/use-deep-agent-config.cjs.map +0 -1
  691. package/dist/packages/agent-runtime/src/use-deep-agent-config.js.map +0 -1
  692. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +0 -1
  693. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js.map +0 -1
  694. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.cjs.map +0 -1
  695. package/dist/packages/agent-runtime/src/use-deep-agent-runtime.js.map +0 -1
  696. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +0 -1
  697. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +0 -1
  698. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs.map +0 -1
  699. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js.map +0 -1
  700. package/dist/packages/agent-runtime/src/voice-presentation.cjs.map +0 -1
  701. package/dist/packages/agent-runtime/src/voice-presentation.js.map +0 -1
  702. package/dist/packages/agent-runtime/src/voice-turn-grouping.cjs.map +0 -1
  703. package/dist/packages/agent-runtime/src/voice-turn-grouping.js.map +0 -1
  704. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +0 -1
  705. package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js.map +0 -1
  706. /package/dist/{packages/agent-runtime → agent-runtime}/src/asset-attachment.cjs +0 -0
  707. /package/dist/{packages/agent-runtime → agent-runtime}/src/asset-attachment.js +0 -0
  708. /package/dist/{packages/agent-runtime → agent-runtime}/src/auth-denial.cjs +0 -0
  709. /package/dist/{packages/agent-runtime → agent-runtime}/src/auth-denial.js +0 -0
  710. /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tool-bridge.cjs +0 -0
  711. /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tool-bridge.js +0 -0
  712. /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tools.cjs +0 -0
  713. /package/dist/{packages/agent-runtime → agent-runtime}/src/client-tools.js +0 -0
  714. /package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-index.cjs +0 -0
  715. /package/dist/{packages/agent-runtime → agent-runtime}/src/conversation-index.js +0 -0
  716. /package/dist/{packages/agent-runtime → agent-runtime}/src/edit-command.cjs +0 -0
  717. /package/dist/{packages/agent-runtime → agent-runtime}/src/edit-command.js +0 -0
  718. /package/dist/{packages/agent-runtime → agent-runtime}/src/github-wake-event.cjs +0 -0
  719. /package/dist/{packages/agent-runtime → agent-runtime}/src/github-wake-event.js +0 -0
  720. /package/dist/{packages/agent-runtime → agent-runtime}/src/message-author.cjs +0 -0
  721. /package/dist/{packages/agent-runtime → agent-runtime}/src/message-author.js +0 -0
  722. /package/dist/{packages/agent-runtime → agent-runtime}/src/message-window.cjs +0 -0
  723. /package/dist/{packages/agent-runtime → agent-runtime}/src/message-window.js +0 -0
  724. /package/dist/{packages/agent-runtime → agent-runtime}/src/model-context.cjs +0 -0
  725. /package/dist/{packages/agent-runtime → agent-runtime}/src/model-context.js +0 -0
  726. /package/dist/{packages/agent-runtime → agent-runtime}/src/optimistic-content.cjs +0 -0
  727. /package/dist/{packages/agent-runtime → agent-runtime}/src/optimistic-content.js +0 -0
  728. /package/dist/{packages/agent-runtime → agent-runtime}/src/protocol.cjs +0 -0
  729. /package/dist/{packages/agent-runtime → agent-runtime}/src/protocol.js +0 -0
  730. /package/dist/{packages/agent-runtime → agent-runtime}/src/runtime-messages.cjs +0 -0
  731. /package/dist/{packages/agent-runtime → agent-runtime}/src/runtime-messages.js +0 -0
  732. /package/dist/{packages/agent-runtime → agent-runtime}/src/screen-point.cjs +0 -0
  733. /package/dist/{packages/agent-runtime → agent-runtime}/src/screen-point.js +0 -0
  734. /package/dist/{packages/agent-runtime → agent-runtime}/src/send-recovery.cjs +0 -0
  735. /package/dist/{packages/agent-runtime → agent-runtime}/src/send-recovery.js +0 -0
  736. /package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-attach-observer.cjs +0 -0
  737. /package/dist/{packages/agent-runtime → agent-runtime}/src/statewire-attach-observer.js +0 -0
  738. /package/dist/{packages/agent-runtime → agent-runtime}/src/streaming-markdown.cjs +0 -0
  739. /package/dist/{packages/agent-runtime → agent-runtime}/src/streaming-markdown.js +0 -0
  740. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-extras.cjs +0 -0
  741. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-extras.js +0 -0
  742. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-snapshot-cache.cjs +0 -0
  743. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-snapshot-cache.js +0 -0
  744. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-status.cjs +0 -0
  745. /package/dist/{packages/agent-runtime → agent-runtime}/src/thread-status.js +0 -0
  746. /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-outputs.cjs +0 -0
  747. /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-outputs.js +0 -0
  748. /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-result.cjs +0 -0
  749. /package/dist/{packages/agent-runtime → agent-runtime}/src/tool-result.js +0 -0
  750. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-config.cjs +0 -0
  751. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-config.js +0 -0
  752. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-runtime.cjs +0 -0
  753. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-runtime.js +0 -0
  754. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-window-sync.cjs +0 -0
  755. /package/dist/{packages/agent-runtime → agent-runtime}/src/use-deep-agent-window-sync.js +0 -0
  756. /package/dist/{packages/agent-runtime → agent-runtime}/src/voice-turn-grouping.cjs +0 -0
  757. /package/dist/{packages/agent-runtime → agent-runtime}/src/voice-turn-grouping.js +0 -0
  758. /package/dist/{packages/react → react}/package.json.cjs.map +0 -0
  759. /package/dist/{packages/react → react}/package.json.js.map +0 -0
  760. /package/dist/{packages/tiptap-markdown-table → tiptap-markdown-table}/src/markdown-table-serializer.cjs +0 -0
  761. /package/dist/{packages/tiptap-markdown-table → tiptap-markdown-table}/src/markdown-table-serializer.js +0 -0
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const messageTime = require("../message-time.cjs");
4
+ const messages = require("../../agent-runtime/src/messages.cjs");
5
+ function record(value) {
6
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
7
+ }
8
+ function readInstantMs(value) {
9
+ var _a;
10
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
11
+ return value > 1e12 ? value : value * 1e3;
12
+ }
13
+ return ((_a = messageTime.parseMessageTime(value)) == null ? void 0 : _a.getTime()) ?? null;
14
+ }
15
+ function sourceMetadata(message) {
16
+ var _a;
17
+ const kwargs = record((_a = record(message)) == null ? void 0 : _a.additional_kwargs);
18
+ return record(kwargs == null ? void 0 : kwargs.metadata) ?? kwargs;
19
+ }
20
+ function isRunMarker(message) {
21
+ var _a, _b;
22
+ return typeof ((_b = record((_a = record(message)) == null ? void 0 : _a.additional_kwargs)) == null ? void 0 : _b[messages.ATHENA_RUN_MARKER_KEY]) === "string";
23
+ }
24
+ function readTurnTiming({ promptCreatedAt, custom, sourceMessages }) {
25
+ let endMs = null;
26
+ let firstStampMs = null;
27
+ let serverStartMs = null;
28
+ let serverDurationMs = null;
29
+ let afterMarker = false;
30
+ let continuedAtMs = null;
31
+ for (const message of sourceMessages) {
32
+ if (isRunMarker(message)) {
33
+ afterMarker = true;
34
+ continuedAtMs = null;
35
+ serverDurationMs = null;
36
+ continue;
37
+ }
38
+ const metadata = sourceMetadata(message);
39
+ const stamp = readInstantMs(metadata == null ? void 0 : metadata[messageTime.MESSAGE_CREATED_AT_KEY]);
40
+ if (stamp !== null) {
41
+ firstStampMs ?? (firstStampMs = stamp);
42
+ if (afterMarker) continuedAtMs ?? (continuedAtMs = stamp);
43
+ endMs = endMs === null ? stamp : Math.max(endMs, stamp);
44
+ }
45
+ const duration = metadata == null ? void 0 : metadata.agent_duration_seconds;
46
+ if (typeof duration === "number" && Number.isFinite(duration) && duration > 0) {
47
+ serverDurationMs = duration * 1e3;
48
+ serverStartMs = readInstantMs(metadata == null ? void 0 : metadata.agent_start_time) ?? serverStartMs;
49
+ }
50
+ }
51
+ if (serverStartMs !== null && serverDurationMs !== null) {
52
+ const serverEnd = serverStartMs + serverDurationMs;
53
+ endMs = endMs === null ? serverEnd : Math.max(endMs, serverEnd);
54
+ }
55
+ const startMs = continuedAtMs ?? readInstantMs(promptCreatedAt) ?? serverStartMs ?? readInstantMs(custom == null ? void 0 : custom.agent_start_time) ?? readInstantMs(custom == null ? void 0 : custom.run_started_at) ?? readInstantMs(custom == null ? void 0 : custom[messageTime.MESSAGE_CREATED_AT_KEY]) ?? firstStampMs;
56
+ return { startMs, endMs, serverDurationMs };
57
+ }
58
+ function workedDurationMs({ startMs, endMs, serverDurationMs }, observedEndMs = null) {
59
+ const observed = observedEndMs !== null && (endMs === null || observedEndMs - endMs <= MAX_OBSERVED_END_LAG_MS) ? observedEndMs : null;
60
+ const end = serverDurationMs !== null || observed === null ? endMs : endMs === null ? observed : Math.max(endMs, observed);
61
+ if (startMs !== null && end !== null && end >= startMs) {
62
+ return Math.max(end - startMs, serverDurationMs ?? 0);
63
+ }
64
+ return serverDurationMs;
65
+ }
66
+ const MAX_OBSERVED_END_LAG_MS = 10 * 60 * 1e3;
67
+ function formatWorkDuration(ms) {
68
+ const totalSeconds = Math.max(0, Math.floor(ms / 1e3));
69
+ if (totalSeconds < 60) return `${totalSeconds}s`;
70
+ const totalMinutes = Math.floor(totalSeconds / 60);
71
+ if (totalMinutes < 60) return `${totalMinutes}m ${String(totalSeconds % 60).padStart(2, "0")}s`;
72
+ const hours = Math.floor(totalMinutes / 60);
73
+ return `${hours}h ${String(totalMinutes % 60).padStart(2, "0")}m`;
74
+ }
75
+ function workingLabel(elapsedMs) {
76
+ return elapsedMs < 1e3 ? "Working" : `Working for ${formatWorkDuration(elapsedMs)}`;
77
+ }
78
+ const MAX_FIRST_SEEN = 200;
79
+ const firstSeen = /* @__PURE__ */ new Map();
80
+ function firstSeenMs(key, now = Date.now()) {
81
+ const seen = firstSeen.get(key);
82
+ if (seen !== void 0) return seen;
83
+ firstSeen.set(key, now);
84
+ if (firstSeen.size > MAX_FIRST_SEEN) {
85
+ const oldest = firstSeen.keys().next().value;
86
+ if (oldest !== void 0) firstSeen.delete(oldest);
87
+ }
88
+ return now;
89
+ }
90
+ const observedEnds = /* @__PURE__ */ new Map();
91
+ function recordObservedTurnEnd(key, now = Date.now()) {
92
+ observedEnds.set(key, now);
93
+ if (observedEnds.size > MAX_FIRST_SEEN) {
94
+ const oldest = observedEnds.keys().next().value;
95
+ if (oldest !== void 0) observedEnds.delete(oldest);
96
+ }
97
+ return now;
98
+ }
99
+ function observedTurnEndMs(key) {
100
+ return observedEnds.get(key) ?? null;
101
+ }
102
+ exports.firstSeenMs = firstSeenMs;
103
+ exports.formatWorkDuration = formatWorkDuration;
104
+ exports.observedTurnEndMs = observedTurnEndMs;
105
+ exports.readInstantMs = readInstantMs;
106
+ exports.readTurnTiming = readTurnTiming;
107
+ exports.recordObservedTurnEnd = recordObservedTurnEnd;
108
+ exports.workedDurationMs = workedDurationMs;
109
+ exports.workingLabel = workingLabel;
110
+ //# sourceMappingURL=turn-timing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-timing.cjs","sources":["../../../src/chat/super-grouping/turn-timing.ts"],"sourcesContent":["/**\n * How long an assistant turn has been working, or worked — the grouped\n * transcript's \"Working for 1m 12s\" / \"Worked for 2m 30s\" header.\n *\n * Every clock here is a server stamp the runtime already writes: `_created_at`\n * on each message (`additional_kwargs.metadata`, surfaced as\n * `metadata.custom`), and on the turn's final assistant message the\n * turn-timing middleware's `agent_start_time` / `agent_duration_seconds`\n * (epoch seconds). The converter joins only the first assistant message's\n * metadata into the turn, so the end of the turn is read off the raw messages\n * bound to it. assistant-ui's own `createdAt` is when this client first saw the\n * message, so it is never used.\n */\nimport { ATHENA_RUN_MARKER_KEY } from '@athenaintel/agent-runtime';\nimport { MESSAGE_CREATED_AT_KEY, parseMessageTime } from '../message-time';\n\nexport interface TurnTiming {\n /**\n * When the turn started: the prompt's stamp, else the run's own start\n * stamps. A turn that was stopped and then continued starts at its\n * continuation, so the clock never counts the time it sat stopped.\n */\n startMs: number | null;\n /** When the turn's last message was written, from the server's stamps. */\n endMs: number | null;\n /** The turn-timing middleware's duration, when the final message carries it. */\n serverDurationMs: number | null;\n}\n\nexport interface TurnTimingSources {\n /** `_created_at` of the user message this turn answers. */\n promptCreatedAt: string | null | undefined;\n /** The turn's joined `metadata.custom` (its first assistant message's). */\n custom: Record<string, unknown> | undefined;\n /** The raw messages bound to the turn (`getExternalStoreMessages`), oldest first. */\n sourceMessages: readonly unknown[];\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** An instant from an ISO stamp or epoch seconds (milliseconds past 1e12), else `null`. */\nexport function readInstantMs(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\n return value > 1e12 ? value : value * 1000;\n }\n return parseMessageTime(value)?.getTime() ?? null;\n}\n\nfunction sourceMetadata(message: unknown): Record<string, unknown> | undefined {\n const kwargs = record(record(message)?.additional_kwargs);\n return record(kwargs?.metadata) ?? kwargs;\n}\n\nfunction isRunMarker(message: unknown): boolean {\n return typeof record(record(message)?.additional_kwargs)?.[ATHENA_RUN_MARKER_KEY] === 'string';\n}\n\n/** The turn's start, end and server-measured duration from the stamps it carries. */\nexport function readTurnTiming({ promptCreatedAt, custom, sourceMessages }: TurnTimingSources): TurnTiming {\n let endMs: number | null = null;\n let firstStampMs: number | null = null;\n let serverStartMs: number | null = null;\n let serverDurationMs: number | null = null;\n let afterMarker = false;\n let continuedAtMs: number | null = null;\n for (const message of sourceMessages) {\n if (isRunMarker(message)) {\n afterMarker = true;\n continuedAtMs = null;\n serverDurationMs = null;\n continue;\n }\n const metadata = sourceMetadata(message);\n const stamp = readInstantMs(metadata?.[MESSAGE_CREATED_AT_KEY]);\n if (stamp !== null) {\n firstStampMs ??= stamp;\n if (afterMarker) continuedAtMs ??= stamp;\n endMs = endMs === null ? stamp : Math.max(endMs, stamp);\n }\n const duration = metadata?.agent_duration_seconds;\n if (typeof duration === 'number' && Number.isFinite(duration) && duration > 0) {\n serverDurationMs = duration * 1000;\n serverStartMs = readInstantMs(metadata?.agent_start_time) ?? serverStartMs;\n }\n }\n if (serverStartMs !== null && serverDurationMs !== null) {\n const serverEnd = serverStartMs + serverDurationMs;\n endMs = endMs === null ? serverEnd : Math.max(endMs, serverEnd);\n }\n // Without a prompt stamp the run's own server clock comes before any\n // assistant stamp: the first assistant message is written after the turn\n // has already been working (thinking, the first tool), so starting there\n // would drop that time.\n const startMs =\n continuedAtMs ??\n readInstantMs(promptCreatedAt) ??\n serverStartMs ??\n readInstantMs(custom?.agent_start_time) ??\n readInstantMs(custom?.run_started_at) ??\n readInstantMs(custom?.[MESSAGE_CREATED_AT_KEY]) ??\n firstStampMs;\n return { startMs, endMs, serverDurationMs };\n}\n\n/**\n * How long a finished turn worked: from its start to its end, else the\n * server-measured duration, else `null` (nothing truthful to show).\n *\n * The end is the server's own turn clock when the final message carries it.\n * The turn-timing stamp lands on that message only after it has streamed, so a\n * turn watched live can settle before the stamp reaches this client; the last\n * message's `_created_at` is then the start of the final answer, not its end,\n * and `observedEndMs` (when this client saw the turn settle) stands in for it.\n */\nexport function workedDurationMs(\n { startMs, endMs, serverDurationMs }: TurnTiming,\n observedEndMs: number | null = null,\n): number | null {\n // A settle seen long after the last stamp is not this turn's end (a thread\n // opened while its status was still catching up), so it is ignored.\n const observed =\n observedEndMs !== null && (endMs === null || observedEndMs - endMs <= MAX_OBSERVED_END_LAG_MS)\n ? observedEndMs\n : null;\n const end =\n serverDurationMs !== null || observed === null\n ? endMs\n : endMs === null\n ? observed\n : Math.max(endMs, observed);\n // The server's own duration is a floor: a start read off a later stamp\n // never shortens the turn below what the server measured.\n if (startMs !== null && end !== null && end >= startMs) {\n return Math.max(end - startMs, serverDurationMs ?? 0);\n }\n return serverDurationMs;\n}\n\n/** How far past its last stamp a turn may be seen to settle and still count as its end. */\nconst MAX_OBSERVED_END_LAG_MS = 10 * 60 * 1000;\n\n/** \"45s\", \"1m 12s\", \"1h 03m\". */\nexport function formatWorkDuration(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / 1000));\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const totalMinutes = Math.floor(totalSeconds / 60);\n if (totalMinutes < 60) return `${totalMinutes}m ${String(totalSeconds % 60).padStart(2, '0')}s`;\n const hours = Math.floor(totalMinutes / 60);\n return `${hours}h ${String(totalMinutes % 60).padStart(2, '0')}m`;\n}\n\n/** The live header: \"Working\" for the first second, then \"Working for 1m 12s\". */\nexport function workingLabel(elapsedMs: number): string {\n return elapsedMs < 1000 ? 'Working' : `Working for ${formatWorkDuration(elapsedMs)}`;\n}\n\n/** The settled header: \"Worked for 2m 30s\", or `null` when the turn carries no usable stamps. */\nexport function workedLabel(timing: TurnTiming): string | null {\n const worked = workedDurationMs(timing);\n return worked === null ? null : `Worked for ${formatWorkDuration(worked)}`;\n}\n\nconst MAX_FIRST_SEEN = 200;\nconst firstSeen = new Map<string, number>();\n\n/**\n * The first time this client saw a turn, for a live clock with no server stamp\n * to anchor on yet (an optimistic prompt before the server echoes it). Keyed\n * per turn, so a later turn never inherits an earlier one's start; bounded.\n */\nexport function firstSeenMs(key: string, now = Date.now()): number {\n const seen = firstSeen.get(key);\n if (seen !== undefined) return seen;\n firstSeen.set(key, now);\n if (firstSeen.size > MAX_FIRST_SEEN) {\n const oldest = firstSeen.keys().next().value;\n if (oldest !== undefined) firstSeen.delete(oldest);\n }\n return now;\n}\n\nconst observedEnds = new Map<string, number>();\n\n/** Record that this client saw the turn `key` settle at `now`; returns the recorded instant. */\nexport function recordObservedTurnEnd(key: string, now = Date.now()): number {\n observedEnds.set(key, now);\n if (observedEnds.size > MAX_FIRST_SEEN) {\n const oldest = observedEnds.keys().next().value;\n if (oldest !== undefined) observedEnds.delete(oldest);\n }\n return now;\n}\n\n/** When this client saw the turn `key` settle, if it watched it do so. */\nexport function observedTurnEndMs(key: string): number | null {\n return observedEnds.get(key) ?? null;\n}\n\nexport function resetFirstSeenForTests(): void {\n firstSeen.clear();\n observedEnds.clear();\n}\n"],"names":["parseMessageTime","ATHENA_RUN_MARKER_KEY","MESSAGE_CREATED_AT_KEY"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ export interface TurnTiming {
2
+ /**
3
+ * When the turn started: the prompt's stamp, else the run's own start
4
+ * stamps. A turn that was stopped and then continued starts at its
5
+ * continuation, so the clock never counts the time it sat stopped.
6
+ */
7
+ startMs: number | null;
8
+ /** When the turn's last message was written, from the server's stamps. */
9
+ endMs: number | null;
10
+ /** The turn-timing middleware's duration, when the final message carries it. */
11
+ serverDurationMs: number | null;
12
+ }
13
+ export interface TurnTimingSources {
14
+ /** `_created_at` of the user message this turn answers. */
15
+ promptCreatedAt: string | null | undefined;
16
+ /** The turn's joined `metadata.custom` (its first assistant message's). */
17
+ custom: Record<string, unknown> | undefined;
18
+ /** The raw messages bound to the turn (`getExternalStoreMessages`), oldest first. */
19
+ sourceMessages: readonly unknown[];
20
+ }
21
+ /** An instant from an ISO stamp or epoch seconds (milliseconds past 1e12), else `null`. */
22
+ export declare function readInstantMs(value: unknown): number | null;
23
+ /** The turn's start, end and server-measured duration from the stamps it carries. */
24
+ export declare function readTurnTiming({ promptCreatedAt, custom, sourceMessages }: TurnTimingSources): TurnTiming;
25
+ /**
26
+ * How long a finished turn worked: from its start to its end, else the
27
+ * server-measured duration, else `null` (nothing truthful to show).
28
+ *
29
+ * The end is the server's own turn clock when the final message carries it.
30
+ * The turn-timing stamp lands on that message only after it has streamed, so a
31
+ * turn watched live can settle before the stamp reaches this client; the last
32
+ * message's `_created_at` is then the start of the final answer, not its end,
33
+ * and `observedEndMs` (when this client saw the turn settle) stands in for it.
34
+ */
35
+ export declare function workedDurationMs({ startMs, endMs, serverDurationMs }: TurnTiming, observedEndMs?: number | null): number | null;
36
+ /** "45s", "1m 12s", "1h 03m". */
37
+ export declare function formatWorkDuration(ms: number): string;
38
+ /** The live header: "Working" for the first second, then "Working for 1m 12s". */
39
+ export declare function workingLabel(elapsedMs: number): string;
40
+ /** The settled header: "Worked for 2m 30s", or `null` when the turn carries no usable stamps. */
41
+ export declare function workedLabel(timing: TurnTiming): string | null;
42
+ /**
43
+ * The first time this client saw a turn, for a live clock with no server stamp
44
+ * to anchor on yet (an optimistic prompt before the server echoes it). Keyed
45
+ * per turn, so a later turn never inherits an earlier one's start; bounded.
46
+ */
47
+ export declare function firstSeenMs(key: string, now?: number): number;
48
+ /** Record that this client saw the turn `key` settle at `now`; returns the recorded instant. */
49
+ export declare function recordObservedTurnEnd(key: string, now?: number): number;
50
+ /** When this client saw the turn `key` settle, if it watched it do so. */
51
+ export declare function observedTurnEndMs(key: string): number | null;
52
+ export declare function resetFirstSeenForTests(): void;
@@ -0,0 +1,110 @@
1
+ import { MESSAGE_CREATED_AT_KEY, parseMessageTime } from "../message-time.js";
2
+ import { ATHENA_RUN_MARKER_KEY } from "../../agent-runtime/src/messages.js";
3
+ function record(value) {
4
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5
+ }
6
+ function readInstantMs(value) {
7
+ var _a;
8
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
9
+ return value > 1e12 ? value : value * 1e3;
10
+ }
11
+ return ((_a = parseMessageTime(value)) == null ? void 0 : _a.getTime()) ?? null;
12
+ }
13
+ function sourceMetadata(message) {
14
+ var _a;
15
+ const kwargs = record((_a = record(message)) == null ? void 0 : _a.additional_kwargs);
16
+ return record(kwargs == null ? void 0 : kwargs.metadata) ?? kwargs;
17
+ }
18
+ function isRunMarker(message) {
19
+ var _a, _b;
20
+ return typeof ((_b = record((_a = record(message)) == null ? void 0 : _a.additional_kwargs)) == null ? void 0 : _b[ATHENA_RUN_MARKER_KEY]) === "string";
21
+ }
22
+ function readTurnTiming({ promptCreatedAt, custom, sourceMessages }) {
23
+ let endMs = null;
24
+ let firstStampMs = null;
25
+ let serverStartMs = null;
26
+ let serverDurationMs = null;
27
+ let afterMarker = false;
28
+ let continuedAtMs = null;
29
+ for (const message of sourceMessages) {
30
+ if (isRunMarker(message)) {
31
+ afterMarker = true;
32
+ continuedAtMs = null;
33
+ serverDurationMs = null;
34
+ continue;
35
+ }
36
+ const metadata = sourceMetadata(message);
37
+ const stamp = readInstantMs(metadata == null ? void 0 : metadata[MESSAGE_CREATED_AT_KEY]);
38
+ if (stamp !== null) {
39
+ firstStampMs ?? (firstStampMs = stamp);
40
+ if (afterMarker) continuedAtMs ?? (continuedAtMs = stamp);
41
+ endMs = endMs === null ? stamp : Math.max(endMs, stamp);
42
+ }
43
+ const duration = metadata == null ? void 0 : metadata.agent_duration_seconds;
44
+ if (typeof duration === "number" && Number.isFinite(duration) && duration > 0) {
45
+ serverDurationMs = duration * 1e3;
46
+ serverStartMs = readInstantMs(metadata == null ? void 0 : metadata.agent_start_time) ?? serverStartMs;
47
+ }
48
+ }
49
+ if (serverStartMs !== null && serverDurationMs !== null) {
50
+ const serverEnd = serverStartMs + serverDurationMs;
51
+ endMs = endMs === null ? serverEnd : Math.max(endMs, serverEnd);
52
+ }
53
+ const startMs = continuedAtMs ?? readInstantMs(promptCreatedAt) ?? serverStartMs ?? readInstantMs(custom == null ? void 0 : custom.agent_start_time) ?? readInstantMs(custom == null ? void 0 : custom.run_started_at) ?? readInstantMs(custom == null ? void 0 : custom[MESSAGE_CREATED_AT_KEY]) ?? firstStampMs;
54
+ return { startMs, endMs, serverDurationMs };
55
+ }
56
+ function workedDurationMs({ startMs, endMs, serverDurationMs }, observedEndMs = null) {
57
+ const observed = observedEndMs !== null && (endMs === null || observedEndMs - endMs <= MAX_OBSERVED_END_LAG_MS) ? observedEndMs : null;
58
+ const end = serverDurationMs !== null || observed === null ? endMs : endMs === null ? observed : Math.max(endMs, observed);
59
+ if (startMs !== null && end !== null && end >= startMs) {
60
+ return Math.max(end - startMs, serverDurationMs ?? 0);
61
+ }
62
+ return serverDurationMs;
63
+ }
64
+ const MAX_OBSERVED_END_LAG_MS = 10 * 60 * 1e3;
65
+ function formatWorkDuration(ms) {
66
+ const totalSeconds = Math.max(0, Math.floor(ms / 1e3));
67
+ if (totalSeconds < 60) return `${totalSeconds}s`;
68
+ const totalMinutes = Math.floor(totalSeconds / 60);
69
+ if (totalMinutes < 60) return `${totalMinutes}m ${String(totalSeconds % 60).padStart(2, "0")}s`;
70
+ const hours = Math.floor(totalMinutes / 60);
71
+ return `${hours}h ${String(totalMinutes % 60).padStart(2, "0")}m`;
72
+ }
73
+ function workingLabel(elapsedMs) {
74
+ return elapsedMs < 1e3 ? "Working" : `Working for ${formatWorkDuration(elapsedMs)}`;
75
+ }
76
+ const MAX_FIRST_SEEN = 200;
77
+ const firstSeen = /* @__PURE__ */ new Map();
78
+ function firstSeenMs(key, now = Date.now()) {
79
+ const seen = firstSeen.get(key);
80
+ if (seen !== void 0) return seen;
81
+ firstSeen.set(key, now);
82
+ if (firstSeen.size > MAX_FIRST_SEEN) {
83
+ const oldest = firstSeen.keys().next().value;
84
+ if (oldest !== void 0) firstSeen.delete(oldest);
85
+ }
86
+ return now;
87
+ }
88
+ const observedEnds = /* @__PURE__ */ new Map();
89
+ function recordObservedTurnEnd(key, now = Date.now()) {
90
+ observedEnds.set(key, now);
91
+ if (observedEnds.size > MAX_FIRST_SEEN) {
92
+ const oldest = observedEnds.keys().next().value;
93
+ if (oldest !== void 0) observedEnds.delete(oldest);
94
+ }
95
+ return now;
96
+ }
97
+ function observedTurnEndMs(key) {
98
+ return observedEnds.get(key) ?? null;
99
+ }
100
+ export {
101
+ firstSeenMs,
102
+ formatWorkDuration,
103
+ observedTurnEndMs,
104
+ readInstantMs,
105
+ readTurnTiming,
106
+ recordObservedTurnEnd,
107
+ workedDurationMs,
108
+ workingLabel
109
+ };
110
+ //# sourceMappingURL=turn-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-timing.js","sources":["../../../src/chat/super-grouping/turn-timing.ts"],"sourcesContent":["/**\n * How long an assistant turn has been working, or worked — the grouped\n * transcript's \"Working for 1m 12s\" / \"Worked for 2m 30s\" header.\n *\n * Every clock here is a server stamp the runtime already writes: `_created_at`\n * on each message (`additional_kwargs.metadata`, surfaced as\n * `metadata.custom`), and on the turn's final assistant message the\n * turn-timing middleware's `agent_start_time` / `agent_duration_seconds`\n * (epoch seconds). The converter joins only the first assistant message's\n * metadata into the turn, so the end of the turn is read off the raw messages\n * bound to it. assistant-ui's own `createdAt` is when this client first saw the\n * message, so it is never used.\n */\nimport { ATHENA_RUN_MARKER_KEY } from '@athenaintel/agent-runtime';\nimport { MESSAGE_CREATED_AT_KEY, parseMessageTime } from '../message-time';\n\nexport interface TurnTiming {\n /**\n * When the turn started: the prompt's stamp, else the run's own start\n * stamps. A turn that was stopped and then continued starts at its\n * continuation, so the clock never counts the time it sat stopped.\n */\n startMs: number | null;\n /** When the turn's last message was written, from the server's stamps. */\n endMs: number | null;\n /** The turn-timing middleware's duration, when the final message carries it. */\n serverDurationMs: number | null;\n}\n\nexport interface TurnTimingSources {\n /** `_created_at` of the user message this turn answers. */\n promptCreatedAt: string | null | undefined;\n /** The turn's joined `metadata.custom` (its first assistant message's). */\n custom: Record<string, unknown> | undefined;\n /** The raw messages bound to the turn (`getExternalStoreMessages`), oldest first. */\n sourceMessages: readonly unknown[];\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** An instant from an ISO stamp or epoch seconds (milliseconds past 1e12), else `null`. */\nexport function readInstantMs(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\n return value > 1e12 ? value : value * 1000;\n }\n return parseMessageTime(value)?.getTime() ?? null;\n}\n\nfunction sourceMetadata(message: unknown): Record<string, unknown> | undefined {\n const kwargs = record(record(message)?.additional_kwargs);\n return record(kwargs?.metadata) ?? kwargs;\n}\n\nfunction isRunMarker(message: unknown): boolean {\n return typeof record(record(message)?.additional_kwargs)?.[ATHENA_RUN_MARKER_KEY] === 'string';\n}\n\n/** The turn's start, end and server-measured duration from the stamps it carries. */\nexport function readTurnTiming({ promptCreatedAt, custom, sourceMessages }: TurnTimingSources): TurnTiming {\n let endMs: number | null = null;\n let firstStampMs: number | null = null;\n let serverStartMs: number | null = null;\n let serverDurationMs: number | null = null;\n let afterMarker = false;\n let continuedAtMs: number | null = null;\n for (const message of sourceMessages) {\n if (isRunMarker(message)) {\n afterMarker = true;\n continuedAtMs = null;\n serverDurationMs = null;\n continue;\n }\n const metadata = sourceMetadata(message);\n const stamp = readInstantMs(metadata?.[MESSAGE_CREATED_AT_KEY]);\n if (stamp !== null) {\n firstStampMs ??= stamp;\n if (afterMarker) continuedAtMs ??= stamp;\n endMs = endMs === null ? stamp : Math.max(endMs, stamp);\n }\n const duration = metadata?.agent_duration_seconds;\n if (typeof duration === 'number' && Number.isFinite(duration) && duration > 0) {\n serverDurationMs = duration * 1000;\n serverStartMs = readInstantMs(metadata?.agent_start_time) ?? serverStartMs;\n }\n }\n if (serverStartMs !== null && serverDurationMs !== null) {\n const serverEnd = serverStartMs + serverDurationMs;\n endMs = endMs === null ? serverEnd : Math.max(endMs, serverEnd);\n }\n // Without a prompt stamp the run's own server clock comes before any\n // assistant stamp: the first assistant message is written after the turn\n // has already been working (thinking, the first tool), so starting there\n // would drop that time.\n const startMs =\n continuedAtMs ??\n readInstantMs(promptCreatedAt) ??\n serverStartMs ??\n readInstantMs(custom?.agent_start_time) ??\n readInstantMs(custom?.run_started_at) ??\n readInstantMs(custom?.[MESSAGE_CREATED_AT_KEY]) ??\n firstStampMs;\n return { startMs, endMs, serverDurationMs };\n}\n\n/**\n * How long a finished turn worked: from its start to its end, else the\n * server-measured duration, else `null` (nothing truthful to show).\n *\n * The end is the server's own turn clock when the final message carries it.\n * The turn-timing stamp lands on that message only after it has streamed, so a\n * turn watched live can settle before the stamp reaches this client; the last\n * message's `_created_at` is then the start of the final answer, not its end,\n * and `observedEndMs` (when this client saw the turn settle) stands in for it.\n */\nexport function workedDurationMs(\n { startMs, endMs, serverDurationMs }: TurnTiming,\n observedEndMs: number | null = null,\n): number | null {\n // A settle seen long after the last stamp is not this turn's end (a thread\n // opened while its status was still catching up), so it is ignored.\n const observed =\n observedEndMs !== null && (endMs === null || observedEndMs - endMs <= MAX_OBSERVED_END_LAG_MS)\n ? observedEndMs\n : null;\n const end =\n serverDurationMs !== null || observed === null\n ? endMs\n : endMs === null\n ? observed\n : Math.max(endMs, observed);\n // The server's own duration is a floor: a start read off a later stamp\n // never shortens the turn below what the server measured.\n if (startMs !== null && end !== null && end >= startMs) {\n return Math.max(end - startMs, serverDurationMs ?? 0);\n }\n return serverDurationMs;\n}\n\n/** How far past its last stamp a turn may be seen to settle and still count as its end. */\nconst MAX_OBSERVED_END_LAG_MS = 10 * 60 * 1000;\n\n/** \"45s\", \"1m 12s\", \"1h 03m\". */\nexport function formatWorkDuration(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / 1000));\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const totalMinutes = Math.floor(totalSeconds / 60);\n if (totalMinutes < 60) return `${totalMinutes}m ${String(totalSeconds % 60).padStart(2, '0')}s`;\n const hours = Math.floor(totalMinutes / 60);\n return `${hours}h ${String(totalMinutes % 60).padStart(2, '0')}m`;\n}\n\n/** The live header: \"Working\" for the first second, then \"Working for 1m 12s\". */\nexport function workingLabel(elapsedMs: number): string {\n return elapsedMs < 1000 ? 'Working' : `Working for ${formatWorkDuration(elapsedMs)}`;\n}\n\n/** The settled header: \"Worked for 2m 30s\", or `null` when the turn carries no usable stamps. */\nexport function workedLabel(timing: TurnTiming): string | null {\n const worked = workedDurationMs(timing);\n return worked === null ? null : `Worked for ${formatWorkDuration(worked)}`;\n}\n\nconst MAX_FIRST_SEEN = 200;\nconst firstSeen = new Map<string, number>();\n\n/**\n * The first time this client saw a turn, for a live clock with no server stamp\n * to anchor on yet (an optimistic prompt before the server echoes it). Keyed\n * per turn, so a later turn never inherits an earlier one's start; bounded.\n */\nexport function firstSeenMs(key: string, now = Date.now()): number {\n const seen = firstSeen.get(key);\n if (seen !== undefined) return seen;\n firstSeen.set(key, now);\n if (firstSeen.size > MAX_FIRST_SEEN) {\n const oldest = firstSeen.keys().next().value;\n if (oldest !== undefined) firstSeen.delete(oldest);\n }\n return now;\n}\n\nconst observedEnds = new Map<string, number>();\n\n/** Record that this client saw the turn `key` settle at `now`; returns the recorded instant. */\nexport function recordObservedTurnEnd(key: string, now = Date.now()): number {\n observedEnds.set(key, now);\n if (observedEnds.size > MAX_FIRST_SEEN) {\n const oldest = observedEnds.keys().next().value;\n if (oldest !== undefined) observedEnds.delete(oldest);\n }\n return now;\n}\n\n/** When this client saw the turn `key` settle, if it watched it do so. */\nexport function observedTurnEndMs(key: string): number | null {\n return observedEnds.get(key) ?? null;\n}\n\nexport function resetFirstSeenForTests(): void {\n firstSeen.clear();\n observedEnds.clear();\n}\n"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const chatMessageBody = require("../chat-ui/rich-text/chat-message-body.cjs");
5
- const streamingMarkdown = require("../packages/agent-runtime/src/streaming-markdown.cjs");
5
+ const streamingMarkdown = require("../agent-runtime/src/streaming-markdown.cjs");
6
6
  const TiptapText = ({ text, status }) => {
7
7
  const isRunning = (status == null ? void 0 : status.type) === "running";
8
8
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { ChatMessageBody } from "../chat-ui/rich-text/chat-message-body.js";
3
- import { hideUnterminatedMarkdownLink } from "../packages/agent-runtime/src/streaming-markdown.js";
3
+ import { hideUnterminatedMarkdownLink } from "../agent-runtime/src/streaming-markdown.js";
4
4
  const TiptapText = ({ text, status }) => {
5
5
  const isRunning = (status == null ? void 0 : status.type) === "running";
6
6
  return /* @__PURE__ */ jsx(
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const react = require("@assistant-ui/react");
4
- const threadStatus = require("../packages/agent-runtime/src/thread-status.cjs");
4
+ const threadStatus = require("../agent-runtime/src/thread-status.cjs");
5
5
  function useAthenaRunLive() {
6
6
  const connection = threadStatus.useDeepAgentConnection();
7
7
  return react.useAuiState((s) => threadStatus.readRunLive(s.thread, connection));
@@ -1,5 +1,5 @@
1
1
  import { useAuiState } from "@assistant-ui/react";
2
- import { useDeepAgentConnection, readRunLive } from "../packages/agent-runtime/src/thread-status.js";
2
+ import { useDeepAgentConnection, readRunLive } from "../agent-runtime/src/thread-status.js";
3
3
  function useAthenaRunLive() {
4
4
  const connection = useDeepAgentConnection();
5
5
  return useAuiState((s) => readRunLive(s.thread, connection));
@@ -3,8 +3,46 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const reactStatewire = require("@assistant-ui/react-statewire");
4
4
  const react = require("react");
5
5
  const useAthenaRunLive = require("./use-athena-run-live.cjs");
6
- const interrupts = require("../packages/agent-runtime/src/interrupts.cjs");
6
+ const interrupts = require("../agent-runtime/src/interrupts.cjs");
7
7
  const NO_QUEUED_LANE_DECISIONS = Object.freeze({});
8
+ const NO_ACTION_REQUESTS = [];
9
+ const answeredRequests = /* @__PURE__ */ new Map();
10
+ const answeredListeners = /* @__PURE__ */ new Set();
11
+ let answeredVersion = 0;
12
+ function notifyAnswered() {
13
+ answeredVersion += 1;
14
+ for (const listener of answeredListeners) listener();
15
+ }
16
+ function recordAnswered(requestId, laneIds) {
17
+ answeredRequests.set(requestId, laneIds);
18
+ notifyAnswered();
19
+ }
20
+ function forgetAnswered(requestId) {
21
+ if (answeredRequests.delete(requestId)) notifyAnswered();
22
+ }
23
+ function subscribeAnswered(listener) {
24
+ answeredListeners.add(listener);
25
+ return () => {
26
+ answeredListeners.delete(listener);
27
+ };
28
+ }
29
+ const readAnsweredVersion = () => answeredVersion;
30
+ function answeredLaneIds(value, actionRequests) {
31
+ const ids = interrupts.laneInterruptIds(actionRequests) ?? [];
32
+ if (typeof value === "object" && value !== null && "lane_decisions" in value) {
33
+ const lanes = value.lane_decisions;
34
+ if (typeof lanes === "object" && lanes !== null) {
35
+ for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);
36
+ }
37
+ }
38
+ return ids;
39
+ }
40
+ function mirrorAlreadyAnswered(answeredLanes, liveActionRequests) {
41
+ if (answeredLanes === void 0) return false;
42
+ const ids = interrupts.laneInterruptIds(liveActionRequests);
43
+ if (ids === null) return false;
44
+ return ids.every((id) => answeredLanes.includes(id));
45
+ }
8
46
  function useStatewireApprovalRequest(options = {}) {
9
47
  var _a;
10
48
  const {
@@ -22,10 +60,32 @@ function useStatewireApprovalRequest(options = {}) {
22
60
  const actionRequests = react.useMemo(() => interrupts.pendingActionRequests(hitl), [hitl]);
23
61
  const isRunning = useAthenaRunLive.useAthenaRunLive();
24
62
  const mirror = reactStatewire.useStatewireState(interrupts.readInterruptMirror);
25
- const liveHitl = request === void 0 && isRunning ? interrupts.asHitlApproval(interrupts.interruptMirrorPayload(mirror)) : null;
26
- const liveActionRequests = react.useMemo(() => interrupts.pendingActionRequests(liveHitl), [liveHitl]);
63
+ const mirrorHitl = request === void 0 && isRunning ? interrupts.asHitlApproval(interrupts.interruptMirrorPayload(mirror)) : null;
64
+ const mirrorActionRequests = react.useMemo(() => interrupts.pendingActionRequests(mirrorHitl), [mirrorHitl]);
65
+ const lastRequestIdRef = react.useRef(void 0);
66
+ if (requestId !== void 0) lastRequestIdRef.current = requestId;
67
+ react.useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);
68
+ const answeredLanes = lastRequestIdRef.current === void 0 ? void 0 : answeredRequests.get(lastRequestIdRef.current);
69
+ const mirrorCleared = interrupts.interruptMirrorPayload(mirror) === void 0;
70
+ react.useEffect(() => {
71
+ if (requestId === void 0) return;
72
+ return () => {
73
+ if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);
74
+ };
75
+ }, [requestId]);
76
+ react.useEffect(() => {
77
+ if (mirrorCleared && lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
78
+ }, [mirrorCleared]);
79
+ react.useEffect(
80
+ () => () => {
81
+ if (lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
82
+ },
83
+ []
84
+ );
85
+ const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;
86
+ const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;
27
87
  const queuedLaneDecisions = reactStatewire.useStatewireState(interrupts.readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;
28
- const { pending, resume } = interrupts.useApprovalResumeLock({
88
+ const { pending, resume: resumeLocked } = interrupts.useApprovalResumeLock({
29
89
  requestId,
30
90
  isRunning,
31
91
  pendingResumeGraceMs,
@@ -39,6 +99,15 @@ function useStatewireApprovalRequest(options = {}) {
39
99
  response: { type: "resume", value }
40
100
  })
41
101
  });
102
+ const resume = react.useCallback(
103
+ (value) => {
104
+ if (requestId !== void 0) {
105
+ recordAnswered(requestId, answeredLaneIds(value, actionRequests));
106
+ }
107
+ return resumeLocked(value);
108
+ },
109
+ [requestId, actionRequests, resumeLocked]
110
+ );
42
111
  const sendLaneDecisions = react.useCallback(
43
112
  (lanes) => requestId !== void 0 ? resume({ lane_decisions: lanes }) : sendCommand({ type: "run/lane-input", laneDecisions: lanes }),
44
113
  [requestId, resume, sendCommand]
@@ -1 +1 @@
1
- {"version":3,"file":"use-statewire-approval-request.cjs","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useMemo } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const liveHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const liveActionRequests = useMemo(() => pendingActionRequests(liveHitl), [liveHitl]);\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":["isApprovalCardInterrupt","HITL_PENDING_RESUME_GRACE_MS","useStatewireSendCommand","useStatewireRuns","useStatewireState","readAbandonedInputRequests","findAbandonedInterrupt","asHitlApproval","useMemo","pendingActionRequests","useAthenaRunLive","readInterruptMirror","interruptMirrorPayload","readQueuedLaneDecisions","useApprovalResumeLock","useCallback"],"mappings":";;;;;;AAuDA,MAAM,2BAA8D,OAAO,OAAO,EAAE;AA6F7E,SAAS,4BAEd,UAA8C,IAAsC;;AACpF,QAAM;AAAA,IACJ,qBAAqBA,WAAAA;AAAAA,IACrB,uBAAuBC,WAAAA;AAAAA,IACvB;AAAA,IACA;AAAA,EAAA,IACE;AACJ,QAAM,cAAcC,eAAAA,wBAAA;AAGpB,QAAM,WAAUC,oBAAAA,iBAAA,EAAmB,kBAAnBA,mBAAkC,KAAK;AACvD,QAAM,YAAY,mCAAS;AAK3B,QAAM,YAAYC,eAAAA,kBAAkBC,qCAA0B;AAC9D,QAAM,qBAAqBC,WAAAA,uBAAuB,SAAS;AAE3D,QAAM,OAAOC,WAAAA,eAAe,mCAAS,OAAO;AAC5C,QAAM,iBAAiBC,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;AAExE,QAAM,YAAYC,iBAAAA,iBAAA;AAIlB,QAAM,SAASN,eAAAA,kBAAkBO,8BAAmB;AACpD,QAAM,WACJ,YAAY,UAAa,YAAYJ,WAAAA,eAAeK,WAAAA,uBAAuB,MAAM,CAAC,IAAI;AACxF,QAAM,qBAAqBJ,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACpF,QAAM,sBACJL,eAAAA,kBAAkBS,WAAAA,uBAAuB,KAAK;AAEhD,QAAM,EAAE,SAAS,OAAA,IAAWC,iCAA8B;AAAA,IACxD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,CAAC,IAAI,UACf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU,EAAE,MAAM,UAAU,MAAA;AAAA,IAAM,CACnC;AAAA,EAAA,CACJ;AAED,QAAM,oBAAoBC,MAAAA;AAAAA,IACxB,CAAC,UACC,cAAc,SACV,OAAO,EAAE,gBAAgB,MAAA,CAA4B,IACrD,YAAY,EAAE,MAAM,kBAAkB,eAAe,OAAO;AAAA,IAClE,CAAC,WAAW,QAAQ,WAAW;AAAA,EAAA;AAGjC,QAAM,oBAAoBA,MAAAA;AAAAA,IACxB,CAAC,OAAe,YAAY,EAAE,MAAM,mBAAmB,WAAW,IAAI;AAAA,IACtE,CAAC,WAAW;AAAA,EAAA;AAGd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;"}
1
+ {"version":3,"file":"use-statewire-approval-request.cjs","sources":["../../src/chat/use-statewire-approval-request.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport {\n useStatewireRuns,\n useStatewireSendCommand,\n useStatewireState,\n} from '@assistant-ui/react-statewire';\nimport {\n type AbandonedInputRequest,\n asHitlApproval,\n findAbandonedInterrupt,\n HITL_PENDING_RESUME_GRACE_MS,\n type HitlApprovalPayload,\n interruptMirrorPayload,\n isApprovalCardInterrupt,\n laneInterruptIds,\n type PendingActionRequest,\n pendingActionRequests,\n readAbandonedInputRequests,\n readInterruptMirror,\n readQueuedLaneDecisions,\n useApprovalResumeLock,\n} from '@athenaintel/agent-runtime';\nimport { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useAthenaRunLive } from './use-athena-run-live';\n\ndeclare module '@assistant-ui/core' {\n namespace Assistant {\n interface Commands {\n /**\n * Decide per-dispatch subagent lanes while the parent run is still\n * streaming (`DeepAgentThread.run_lane_input`). Keys are the lanes'\n * langgraph interrupt ids; the host matches them against the lanes its\n * mirrored interrupt currently parks, answers at once when the run is\n * already parked, and otherwise holds them until it parks — stale or\n * unknown ids are ignored, never carried to a later interrupt.\n */\n runLaneInput: {\n readonly type: 'run/lane-input';\n readonly laneDecisions: Readonly<Record<string, StatewireThread.InputResponse>>;\n };\n /**\n * Re-send the lane decisions the host still holds queued as their\n * approver's resume of the parked request (`DeepAgentThread.run_lane_replay`).\n * The host resumes under the meta the approver's `run/lane-input`\n * recorded and refuses any other caller — every attached client reads\n * the same queue, and only the one that queued it may turn it into a\n * resume. Carries no decisions: the host replays what it recorded.\n */\n runLaneReplay: {\n readonly type: 'run/lane-replay';\n readonly requestId: string;\n };\n }\n }\n}\n\nconst NO_QUEUED_LANE_DECISIONS: Readonly<Record<string, unknown>> = Object.freeze({});\nconst NO_ACTION_REQUESTS: PendingActionRequest[] = [];\n\n/**\n * Lane ids of the parked requests this client resumed, keyed by request id\n * and shared by every hook instance on the page (approval card,\n * waiting-on-you banner, host editors) so all of them treat a lingering\n * mirror the same way. Request ids are unique per parked interrupt, so an\n * instance only ever consults the record of the request it saw parked: two\n * chats mounted side by side cannot suppress or clear each other's. A record\n * is retired once the host drops that request's mirror (the resume run\n * started), the surface sees a different request park, or it unmounts.\n */\nconst answeredRequests = new Map<string, readonly string[]>();\nconst answeredListeners = new Set<() => void>();\nlet answeredVersion = 0;\nfunction notifyAnswered(): void {\n answeredVersion += 1;\n for (const listener of answeredListeners) listener();\n}\nfunction recordAnswered(requestId: string, laneIds: readonly string[]): void {\n answeredRequests.set(requestId, laneIds);\n notifyAnswered();\n}\nfunction forgetAnswered(requestId: string): void {\n if (answeredRequests.delete(requestId)) notifyAnswered();\n}\nfunction subscribeAnswered(listener: () => void): () => void {\n answeredListeners.add(listener);\n return () => {\n answeredListeners.delete(listener);\n };\n}\nconst readAnsweredVersion = (): number => answeredVersion;\n\n/**\n * The lanes a resume of the parked request settles: every lane of the request\n * (a resume answers the whole park — lanes already queued through\n * `run/lane-input` ride along) plus any lane named in the `lane_decisions` map.\n */\nfunction answeredLaneIds(value: unknown, actionRequests: readonly PendingActionRequest[]): string[] {\n const ids = laneInterruptIds(actionRequests) ?? [];\n if (typeof value === 'object' && value !== null && 'lane_decisions' in value) {\n const lanes = (value as { lane_decisions: unknown }).lane_decisions;\n if (typeof lanes === 'object' && lanes !== null) {\n for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);\n }\n }\n return ids;\n}\n\n/**\n * Whether the host's mirror still shows an interrupt this client already\n * answered. After `run/input` the host drops the parked request at once but\n * keeps `__interrupt__` until the resume run starts and clears it (seconds on\n * a cold checkpoint); without this check the card would re-offer the SAME\n * approval from the mirror, buttons live, and then fold it away again.\n */\nfunction mirrorAlreadyAnswered(\n answeredLanes: readonly string[] | undefined,\n liveActionRequests: readonly PendingActionRequest[],\n): boolean {\n if (answeredLanes === undefined) return false;\n const ids = laneInterruptIds(liveActionRequests);\n if (ids === null) return false;\n return ids.every((id) => answeredLanes.includes(id));\n}\n\n/** Selects which pending interrupt an approval surface answers. */\nexport type StatewireInterruptPredicate = (\n request: StatewireThread.InputRequestState,\n) => request is StatewireThread.CustomInputRequest;\n\nexport interface UseStatewireApprovalRequestOptions {\n /**\n * Which pending interrupt to answer. Defaults to `isApprovalCardInterrupt`\n * (client-tool parks excluded — the client-tool bridge owns those, and a\n * generic resume would corrupt the parked tool call).\n */\n interruptPredicate?: StatewireInterruptPredicate;\n /**\n * How long a sent decision keeps the actions locked when no resume run ever\n * starts. Defaults to {@link HITL_PENDING_RESUME_GRACE_MS}.\n */\n pendingResumeGraceMs?: number;\n /**\n * The host refused the `run/input` (or the transport lost it): the\n * optimistic fold rolls back, the request is on screen again with its\n * actions re-enabled, and this is the surface's one chance to say why.\n */\n onResumeRejected?: (error: unknown, requestId: string) => void;\n /** See {@link UseApprovalResumeLockOptions.onResumeRetry}. */\n onResumeRetry?: (error: unknown, requestId: string, attempt: number) => void;\n}\n\nexport interface StatewireApprovalRequest<TValue> {\n /** The pending interrupt this surface answers, if any. */\n request: StatewireThread.CustomInputRequest | undefined;\n requestId: string | undefined;\n /** The payload narrowed to the Athena HITL approval shape, or `null`. */\n hitl: HitlApprovalPayload | null;\n /** Every gated call the approval covers, in decision order (empty for non-HITL parks). */\n actionRequests: PendingActionRequest[];\n /** An interrupt a non-resume dispatch dropped — the \"approval was cancelled\" notice. */\n abandonedInterrupt: AbandonedInputRequest | undefined;\n /**\n * The mirrored interrupt's HITL payload while the run is still live and no\n * input request is answerable: per-dispatch `task` lanes parked on their\n * gates while sibling lanes stream. `null` once the run parks (the same\n * lanes are then `hitl` / `actionRequests`) and when nothing is parked.\n */\n liveHitl: HitlApprovalPayload | null;\n /** Every gated call `liveHitl` covers (empty when it is `null`). */\n liveActionRequests: PendingActionRequest[];\n /**\n * The decisions the host already holds from a `run/lane-input`, keyed by\n * langgraph interrupt id, to be answered when the run parks — a queued lane\n * reads as decided on every attached client, not just the one that sent it.\n */\n queuedLaneDecisions: Readonly<Record<string, unknown>>;\n /** True after a resume until the request identity changes (or recovery fires). */\n pending: boolean;\n /**\n * Answer the request with `{ type: 'run/input', requestId, response: { type: 'resume', value } }`.\n * Returns the dispatch promise (settles when the host accepts, rejects when\n * it refuses), or `undefined` when the lock dropped the send.\n */\n resume: (value: TValue) => Promise<unknown> | undefined;\n /**\n * Decide per-dispatch lanes by langgraph interrupt id. With a pending\n * request this is the native `lane_decisions` resume through the lock;\n * without one (the run is still streaming siblings) it is `run/lane-input`,\n * which the host queues and answers on the park. Returns the dispatch\n * promise, or `undefined` when the lock dropped a resume.\n */\n sendLaneDecisions: (\n lanes: Readonly<Record<string, StatewireThread.InputResponse>>,\n ) => Promise<unknown> | undefined;\n /**\n * Ask the host to resume the parked `requestId` with the lane decisions it\n * still holds queued, as their approver (`run/lane-replay`). For the card\n * that queued them, after the host's own answerer has stayed silent past\n * its budget; the host refuses every other caller. Settles when the host\n * accepts, rejects when it refuses.\n */\n replayQueuedLanes: (requestId: string) => Promise<unknown>;\n}\n\n/**\n * The headless half of every statewire approval surface: selects the pending\n * interrupt from the runs projection, narrows its payload, reads the\n * host-published abandoned interrupts, and wires the shared optimistic resume\n * lock to the thread's `run/input` command. `StatewireApprovalCard` renders\n * over it; hosts with their own decision UI (per-lane subagent cards) build\n * on it directly so the selection and lock semantics cannot drift.\n *\n * Requires a statewire aui scope (throws outside one, like every\n * `useStatewire*` hook) — gate the mount with `hasStatewireThreadExtras`.\n */\nexport function useStatewireApprovalRequest<\n TValue extends StatewireThread.InputResponse = Record<string, string>,\n>(options: UseStatewireApprovalRequestOptions = {}): StatewireApprovalRequest<TValue> {\n const {\n interruptPredicate = isApprovalCardInterrupt,\n pendingResumeGraceMs = HITL_PENDING_RESUME_GRACE_MS,\n onResumeRejected,\n onResumeRetry,\n } = options;\n const sendCommand = useStatewireSendCommand();\n // The runs projection is memoized by the lib, so this derivation is\n // reference-stable between state updates.\n const request = useStatewireRuns().inputRequests?.find(interruptPredicate);\n const requestId = request?.id;\n\n // The host publishes the interrupts a non-resume dispatch dropped. Select\n // the raw array reference (pre-stream-safe) and derive inline; a `.find`\n // selector would return a fresh object every update.\n const abandoned = useStatewireState(readAbandonedInputRequests);\n const abandonedInterrupt = findAbandonedInterrupt(abandoned);\n\n const hitl = asHitlApproval(request?.payload);\n const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);\n\n const isRunning = useAthenaRunLive();\n // The host mirrors the interrupt into state as soon as a lane parks — while\n // the run manager still reports `running` (siblings streaming) and has no\n // request to answer. Raw reference selectors; derive inline.\n const mirror = useStatewireState(readInterruptMirror);\n const mirrorHitl =\n request === undefined && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;\n const mirrorActionRequests = useMemo(() => pendingActionRequests(mirrorHitl), [mirrorHitl]);\n\n // The request this surface last saw parked: the only record it may read\n // or retire (the mirror it watches is the one that request's resume clears).\n const lastRequestIdRef = useRef<string>(undefined);\n if (requestId !== undefined) lastRequestIdRef.current = requestId;\n useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);\n const answeredLanes =\n lastRequestIdRef.current === undefined ? undefined : answeredRequests.get(lastRequestIdRef.current);\n const mirrorCleared = interruptMirrorPayload(mirror) === undefined;\n useEffect(() => {\n if (requestId === undefined) return;\n return () => {\n // A different request parks next (or this one unparks for good): the\n // record of this one is stale once it is not the one on screen.\n if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);\n };\n }, [requestId]);\n useEffect(() => {\n if (mirrorCleared && lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n }, [mirrorCleared]);\n useEffect(\n () => () => {\n if (lastRequestIdRef.current !== undefined) forgetAnswered(lastRequestIdRef.current);\n },\n [],\n );\n const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;\n const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;\n const queuedLaneDecisions =\n useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;\n\n const { pending, resume: resumeLocked } = useApprovalResumeLock<TValue>({\n requestId,\n isRunning,\n pendingResumeGraceMs,\n onResumeRejected,\n onResumeRetry,\n // The dispatch promise is handed to the lock: a refusal releases it and\n // reaches `onResumeRejected`.\n sendResume: (id, value) =>\n sendCommand({\n type: 'run/input',\n requestId: id,\n response: { type: 'resume', value },\n }),\n });\n\n const resume = useCallback(\n (value: TValue) => {\n if (requestId !== undefined) {\n recordAnswered(requestId, answeredLaneIds(value, actionRequests));\n }\n return resumeLocked(value);\n },\n [requestId, actionRequests, resumeLocked],\n );\n\n const sendLaneDecisions = useCallback(\n (lanes: Readonly<Record<string, StatewireThread.InputResponse>>) =>\n requestId !== undefined\n ? resume({ lane_decisions: lanes } as unknown as TValue)\n : sendCommand({ type: 'run/lane-input', laneDecisions: lanes }),\n [requestId, resume, sendCommand],\n );\n\n const replayQueuedLanes = useCallback(\n (id: string) => sendCommand({ type: 'run/lane-replay', requestId: id }),\n [sendCommand],\n );\n\n return {\n request,\n requestId,\n hitl,\n actionRequests,\n liveHitl,\n liveActionRequests,\n queuedLaneDecisions,\n abandonedInterrupt,\n pending,\n resume,\n sendLaneDecisions,\n replayQueuedLanes,\n };\n}\n"],"names":["laneInterruptIds","isApprovalCardInterrupt","HITL_PENDING_RESUME_GRACE_MS","useStatewireSendCommand","useStatewireRuns","useStatewireState","readAbandonedInputRequests","findAbandonedInterrupt","asHitlApproval","useMemo","pendingActionRequests","useAthenaRunLive","readInterruptMirror","interruptMirrorPayload","useRef","useSyncExternalStore","useEffect","readQueuedLaneDecisions","useApprovalResumeLock","useCallback"],"mappings":";;;;;;AAwDA,MAAM,2BAA8D,OAAO,OAAO,EAAE;AACpF,MAAM,qBAA6C,CAAA;AAYnD,MAAM,uCAAuB,IAAA;AAC7B,MAAM,wCAAwB,IAAA;AAC9B,IAAI,kBAAkB;AACtB,SAAS,iBAAuB;AAC9B,qBAAmB;AACnB,aAAW,YAAY,kBAAmB,UAAA;AAC5C;AACA,SAAS,eAAe,WAAmB,SAAkC;AAC3E,mBAAiB,IAAI,WAAW,OAAO;AACvC,iBAAA;AACF;AACA,SAAS,eAAe,WAAyB;AAC/C,MAAI,iBAAiB,OAAO,SAAS,EAAG,gBAAA;AAC1C;AACA,SAAS,kBAAkB,UAAkC;AAC3D,oBAAkB,IAAI,QAAQ;AAC9B,SAAO,MAAM;AACX,sBAAkB,OAAO,QAAQ;AAAA,EACnC;AACF;AACA,MAAM,sBAAsB,MAAc;AAO1C,SAAS,gBAAgB,OAAgB,gBAA2D;AAClG,QAAM,MAAMA,WAAAA,iBAAiB,cAAc,KAAK,CAAA;AAChD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,oBAAoB,OAAO;AAC5E,UAAM,QAAS,MAAsC;AACrD,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,iBAAW,MAAM,OAAO,KAAK,KAAK,EAAG,KAAI,CAAC,IAAI,SAAS,EAAE,EAAG,KAAI,KAAK,EAAE;AAAA,IACzE;AAAA,EACF;AACA,SAAO;AACT;AASA,SAAS,sBACP,eACA,oBACS;AACT,MAAI,kBAAkB,OAAW,QAAO;AACxC,QAAM,MAAMA,WAAAA,iBAAiB,kBAAkB;AAC/C,MAAI,QAAQ,KAAM,QAAO;AACzB,SAAO,IAAI,MAAM,CAAC,OAAO,cAAc,SAAS,EAAE,CAAC;AACrD;AA6FO,SAAS,4BAEd,UAA8C,IAAsC;;AACpF,QAAM;AAAA,IACJ,qBAAqBC,WAAAA;AAAAA,IACrB,uBAAuBC,WAAAA;AAAAA,IACvB;AAAA,IACA;AAAA,EAAA,IACE;AACJ,QAAM,cAAcC,eAAAA,wBAAA;AAGpB,QAAM,WAAUC,oBAAAA,iBAAA,EAAmB,kBAAnBA,mBAAkC,KAAK;AACvD,QAAM,YAAY,mCAAS;AAK3B,QAAM,YAAYC,eAAAA,kBAAkBC,qCAA0B;AAC9D,QAAM,qBAAqBC,WAAAA,uBAAuB,SAAS;AAE3D,QAAM,OAAOC,WAAAA,eAAe,mCAAS,OAAO;AAC5C,QAAM,iBAAiBC,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,IAAI,GAAG,CAAC,IAAI,CAAC;AAExE,QAAM,YAAYC,iBAAAA,iBAAA;AAIlB,QAAM,SAASN,eAAAA,kBAAkBO,8BAAmB;AACpD,QAAM,aACJ,YAAY,UAAa,YAAYJ,WAAAA,eAAeK,WAAAA,uBAAuB,MAAM,CAAC,IAAI;AACxF,QAAM,uBAAuBJ,MAAAA,QAAQ,MAAMC,WAAAA,sBAAsB,UAAU,GAAG,CAAC,UAAU,CAAC;AAI1F,QAAM,mBAAmBI,MAAAA,OAAe,MAAS;AACjD,MAAI,cAAc,OAAW,kBAAiB,UAAU;AACxDC,6BAAqB,mBAAmB,qBAAqB,mBAAmB;AAChF,QAAM,gBACJ,iBAAiB,YAAY,SAAY,SAAY,iBAAiB,IAAI,iBAAiB,OAAO;AACpG,QAAM,gBAAgBF,WAAAA,uBAAuB,MAAM,MAAM;AACzDG,QAAAA,UAAU,MAAM;AACd,QAAI,cAAc,OAAW;AAC7B,WAAO,MAAM;AAGX,UAAI,iBAAiB,YAAY,UAAW,gBAAe,SAAS;AAAA,IACtE;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AACdA,QAAAA,UAAU,MAAM;AACd,QAAI,iBAAiB,iBAAiB,YAAY,OAAW,gBAAe,iBAAiB,OAAO;AAAA,EACtG,GAAG,CAAC,aAAa,CAAC;AAClBA,QAAAA;AAAAA,IACE,MAAM,MAAM;AACV,UAAI,iBAAiB,YAAY,OAAW,gBAAe,iBAAiB,OAAO;AAAA,IACrF;AAAA,IACA,CAAA;AAAA,EAAC;AAEH,QAAM,WAAW,sBAAsB,eAAe,oBAAoB,IAAI,OAAO;AACrF,QAAM,qBAAqB,aAAa,aAAa,uBAAuB;AAC5E,QAAM,sBACJX,eAAAA,kBAAkBY,WAAAA,uBAAuB,KAAK;AAEhD,QAAM,EAAE,SAAS,QAAQ,aAAA,IAAiBC,WAAAA,sBAA8B;AAAA,IACtE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,CAAC,IAAI,UACf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU,EAAE,MAAM,UAAU,MAAA;AAAA,IAAM,CACnC;AAAA,EAAA,CACJ;AAED,QAAM,SAASC,MAAAA;AAAAA,IACb,CAAC,UAAkB;AACjB,UAAI,cAAc,QAAW;AAC3B,uBAAe,WAAW,gBAAgB,OAAO,cAAc,CAAC;AAAA,MAClE;AACA,aAAO,aAAa,KAAK;AAAA,IAC3B;AAAA,IACA,CAAC,WAAW,gBAAgB,YAAY;AAAA,EAAA;AAG1C,QAAM,oBAAoBA,MAAAA;AAAAA,IACxB,CAAC,UACC,cAAc,SACV,OAAO,EAAE,gBAAgB,MAAA,CAA4B,IACrD,YAAY,EAAE,MAAM,kBAAkB,eAAe,OAAO;AAAA,IAClE,CAAC,WAAW,QAAQ,WAAW;AAAA,EAAA;AAGjC,QAAM,oBAAoBA,MAAAA;AAAAA,IACxB,CAAC,OAAe,YAAY,EAAE,MAAM,mBAAmB,WAAW,IAAI;AAAA,IACtE,CAAC,WAAW;AAAA,EAAA;AAGd,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;"}
@@ -1,8 +1,46 @@
1
1
  import { useStatewireSendCommand, useStatewireRuns, useStatewireState } from "@assistant-ui/react-statewire";
2
- import { useMemo, useCallback } from "react";
2
+ import { useMemo, useRef, useSyncExternalStore, useEffect, useCallback } from "react";
3
3
  import { useAthenaRunLive } from "./use-athena-run-live.js";
4
- import { isApprovalCardInterrupt, HITL_PENDING_RESUME_GRACE_MS, readAbandonedInputRequests, findAbandonedInterrupt, asHitlApproval, pendingActionRequests, readInterruptMirror, interruptMirrorPayload, readQueuedLaneDecisions, useApprovalResumeLock } from "../packages/agent-runtime/src/interrupts.js";
4
+ import { isApprovalCardInterrupt, HITL_PENDING_RESUME_GRACE_MS, readAbandonedInputRequests, findAbandonedInterrupt, asHitlApproval, pendingActionRequests, readInterruptMirror, interruptMirrorPayload, readQueuedLaneDecisions, useApprovalResumeLock, laneInterruptIds } from "../agent-runtime/src/interrupts.js";
5
5
  const NO_QUEUED_LANE_DECISIONS = Object.freeze({});
6
+ const NO_ACTION_REQUESTS = [];
7
+ const answeredRequests = /* @__PURE__ */ new Map();
8
+ const answeredListeners = /* @__PURE__ */ new Set();
9
+ let answeredVersion = 0;
10
+ function notifyAnswered() {
11
+ answeredVersion += 1;
12
+ for (const listener of answeredListeners) listener();
13
+ }
14
+ function recordAnswered(requestId, laneIds) {
15
+ answeredRequests.set(requestId, laneIds);
16
+ notifyAnswered();
17
+ }
18
+ function forgetAnswered(requestId) {
19
+ if (answeredRequests.delete(requestId)) notifyAnswered();
20
+ }
21
+ function subscribeAnswered(listener) {
22
+ answeredListeners.add(listener);
23
+ return () => {
24
+ answeredListeners.delete(listener);
25
+ };
26
+ }
27
+ const readAnsweredVersion = () => answeredVersion;
28
+ function answeredLaneIds(value, actionRequests) {
29
+ const ids = laneInterruptIds(actionRequests) ?? [];
30
+ if (typeof value === "object" && value !== null && "lane_decisions" in value) {
31
+ const lanes = value.lane_decisions;
32
+ if (typeof lanes === "object" && lanes !== null) {
33
+ for (const id of Object.keys(lanes)) if (!ids.includes(id)) ids.push(id);
34
+ }
35
+ }
36
+ return ids;
37
+ }
38
+ function mirrorAlreadyAnswered(answeredLanes, liveActionRequests) {
39
+ if (answeredLanes === void 0) return false;
40
+ const ids = laneInterruptIds(liveActionRequests);
41
+ if (ids === null) return false;
42
+ return ids.every((id) => answeredLanes.includes(id));
43
+ }
6
44
  function useStatewireApprovalRequest(options = {}) {
7
45
  var _a;
8
46
  const {
@@ -20,10 +58,32 @@ function useStatewireApprovalRequest(options = {}) {
20
58
  const actionRequests = useMemo(() => pendingActionRequests(hitl), [hitl]);
21
59
  const isRunning = useAthenaRunLive();
22
60
  const mirror = useStatewireState(readInterruptMirror);
23
- const liveHitl = request === void 0 && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;
24
- const liveActionRequests = useMemo(() => pendingActionRequests(liveHitl), [liveHitl]);
61
+ const mirrorHitl = request === void 0 && isRunning ? asHitlApproval(interruptMirrorPayload(mirror)) : null;
62
+ const mirrorActionRequests = useMemo(() => pendingActionRequests(mirrorHitl), [mirrorHitl]);
63
+ const lastRequestIdRef = useRef(void 0);
64
+ if (requestId !== void 0) lastRequestIdRef.current = requestId;
65
+ useSyncExternalStore(subscribeAnswered, readAnsweredVersion, readAnsweredVersion);
66
+ const answeredLanes = lastRequestIdRef.current === void 0 ? void 0 : answeredRequests.get(lastRequestIdRef.current);
67
+ const mirrorCleared = interruptMirrorPayload(mirror) === void 0;
68
+ useEffect(() => {
69
+ if (requestId === void 0) return;
70
+ return () => {
71
+ if (lastRequestIdRef.current !== requestId) forgetAnswered(requestId);
72
+ };
73
+ }, [requestId]);
74
+ useEffect(() => {
75
+ if (mirrorCleared && lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
76
+ }, [mirrorCleared]);
77
+ useEffect(
78
+ () => () => {
79
+ if (lastRequestIdRef.current !== void 0) forgetAnswered(lastRequestIdRef.current);
80
+ },
81
+ []
82
+ );
83
+ const liveHitl = mirrorAlreadyAnswered(answeredLanes, mirrorActionRequests) ? null : mirrorHitl;
84
+ const liveActionRequests = liveHitl === mirrorHitl ? mirrorActionRequests : NO_ACTION_REQUESTS;
25
85
  const queuedLaneDecisions = useStatewireState(readQueuedLaneDecisions) ?? NO_QUEUED_LANE_DECISIONS;
26
- const { pending, resume } = useApprovalResumeLock({
86
+ const { pending, resume: resumeLocked } = useApprovalResumeLock({
27
87
  requestId,
28
88
  isRunning,
29
89
  pendingResumeGraceMs,
@@ -37,6 +97,15 @@ function useStatewireApprovalRequest(options = {}) {
37
97
  response: { type: "resume", value }
38
98
  })
39
99
  });
100
+ const resume = useCallback(
101
+ (value) => {
102
+ if (requestId !== void 0) {
103
+ recordAnswered(requestId, answeredLaneIds(value, actionRequests));
104
+ }
105
+ return resumeLocked(value);
106
+ },
107
+ [requestId, actionRequests, resumeLocked]
108
+ );
40
109
  const sendLaneDecisions = useCallback(
41
110
  (lanes) => requestId !== void 0 ? resume({ lane_decisions: lanes }) : sendCommand({ type: "run/lane-input", laneDecisions: lanes }),
42
111
  [requestId, resume, sendCommand]