@athenaintel/react 0.43.0 → 0.48.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 (661) hide show
  1. package/README.md +215 -3
  2. package/dist/agent-runtime/src/answer-label.cjs +137 -0
  3. package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
  4. package/dist/agent-runtime/src/answer-label.d.ts +104 -0
  5. package/dist/agent-runtime/src/answer-label.js +137 -0
  6. package/dist/agent-runtime/src/answer-label.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-rows.cjs +180 -0
  8. package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
  9. package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
  10. package/dist/agent-runtime/src/answer-rows.js +180 -0
  11. package/dist/agent-runtime/src/answer-rows.js.map +1 -0
  12. package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
  13. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  14. package/dist/agent-runtime/src/conversation-index.cjs +8 -8
  15. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
  16. package/dist/agent-runtime/src/decision-checks.cjs +207 -0
  17. package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
  18. package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
  19. package/dist/agent-runtime/src/decision-checks.js +207 -0
  20. package/dist/agent-runtime/src/decision-checks.js.map +1 -0
  21. package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
  22. package/dist/agent-runtime/src/errors.cjs +18 -0
  23. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  24. package/dist/agent-runtime/src/errors.d.ts +7 -0
  25. package/dist/agent-runtime/src/errors.js +18 -0
  26. package/dist/agent-runtime/src/errors.js.map +1 -1
  27. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
  28. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  29. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
  30. package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
  31. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  32. package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
  33. package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
  34. package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
  35. package/dist/agent-runtime/src/handoff-arrival.js +60 -0
  36. package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
  37. package/dist/agent-runtime/src/index.d.ts +14 -8
  38. package/dist/agent-runtime/src/interrupts.cjs +43 -18
  39. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  40. package/dist/agent-runtime/src/interrupts.d.ts +19 -2
  41. package/dist/agent-runtime/src/interrupts.js +28 -3
  42. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  43. package/dist/agent-runtime/src/lane-history.cjs +8 -8
  44. package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
  45. package/dist/agent-runtime/src/messages.cjs +43 -8
  46. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  47. package/dist/agent-runtime/src/messages.d.ts +25 -3
  48. package/dist/agent-runtime/src/messages.js +43 -8
  49. package/dist/agent-runtime/src/messages.js.map +1 -1
  50. package/dist/agent-runtime/src/offline-status.cjs +36 -0
  51. package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
  52. package/dist/agent-runtime/src/offline-status.d.ts +118 -3
  53. package/dist/agent-runtime/src/offline-status.js +36 -0
  54. package/dist/agent-runtime/src/offline-status.js.map +1 -0
  55. package/dist/agent-runtime/src/queue.cjs +0 -9
  56. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  57. package/dist/agent-runtime/src/queue.js +0 -9
  58. package/dist/agent-runtime/src/queue.js.map +1 -1
  59. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
  60. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  61. package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
  62. package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
  63. package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
  64. package/dist/agent-runtime/src/runtime-catalog.js +42 -0
  65. package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
  66. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
  67. package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
  68. package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
  69. package/dist/agent-runtime/src/runtime.d.ts +40 -0
  70. package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
  71. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  72. package/dist/agent-runtime/src/subagents.cjs +32 -2
  73. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  74. package/dist/agent-runtime/src/subagents.d.ts +9 -0
  75. package/dist/agent-runtime/src/subagents.js +30 -0
  76. package/dist/agent-runtime/src/subagents.js.map +1 -1
  77. package/dist/agent-runtime/src/thread-driver.cjs +67 -0
  78. package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
  79. package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
  80. package/dist/agent-runtime/src/thread-driver.js +67 -0
  81. package/dist/agent-runtime/src/thread-driver.js.map +1 -0
  82. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
  83. package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +756 -0
  84. package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
  85. package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
  86. package/dist/agent-runtime/src/thread-status.cjs +3 -3
  87. package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
  88. package/dist/agent-runtime/src/tool-metadata.cjs +210 -25
  89. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  90. package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
  91. package/dist/agent-runtime/src/tool-metadata.js +210 -25
  92. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  93. package/dist/agent-runtime/src/tool-names.cjs +2 -0
  94. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  95. package/dist/agent-runtime/src/tool-names.d.ts +2 -0
  96. package/dist/agent-runtime/src/tool-names.js +2 -0
  97. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  98. package/dist/agent-runtime/src/types.d.ts +10 -2
  99. package/dist/agent-runtime/src/use-conversation-list.cjs +11 -11
  100. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  101. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +24 -19
  102. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  103. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +2 -1
  104. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +6 -1
  105. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  106. package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
  107. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  108. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
  109. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  110. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +16 -16
  111. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  112. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
  113. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  114. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +547 -124
  115. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  116. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +129 -10
  117. package/dist/agent-runtime/src/use-deep-agent-voice.js +487 -64
  118. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  119. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
  120. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  121. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
  122. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
  123. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +28 -26
  124. package/dist/agent-runtime/src/voice-media.cjs +117 -0
  125. package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
  126. package/dist/agent-runtime/src/voice-media.d.ts +49 -0
  127. package/dist/agent-runtime/src/voice-media.js +117 -0
  128. package/dist/agent-runtime/src/voice-media.js.map +1 -0
  129. package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
  130. package/dist/assets/AssetPanel.cjs +11 -11
  131. package/dist/assets/AssetPanel.cjs.map +1 -1
  132. package/dist/assets/AthenaAssetEmbed.cjs +11 -9
  133. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  134. package/dist/assets/AthenaAssetEmbed.d.ts +7 -0
  135. package/dist/assets/AthenaAssetEmbed.js +4 -2
  136. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  137. package/dist/assets/AthenaLayout.cjs +16 -16
  138. package/dist/assets/AthenaLayout.cjs.map +1 -1
  139. package/dist/assets/use-asset-content.cjs +4 -4
  140. package/dist/assets/use-asset-content.cjs.map +1 -1
  141. package/dist/assets/use-asset-embed.cjs +14 -7
  142. package/dist/assets/use-asset-embed.cjs.map +1 -1
  143. package/dist/assets/use-asset-embed.d.ts +11 -1
  144. package/dist/assets/use-asset-embed.js +10 -3
  145. package/dist/assets/use-asset-embed.js.map +1 -1
  146. package/dist/auth/AthenaAuthContext.cjs +3 -3
  147. package/dist/auth/AthenaAuthContext.cjs.map +1 -1
  148. package/dist/auth/AthenaAuthProvider.cjs +8 -8
  149. package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
  150. package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
  151. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  152. package/dist/auth/AthenaSSOProvider.cjs +14 -14
  153. package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
  154. package/dist/auth/credential-source.cjs +26 -13
  155. package/dist/auth/credential-source.cjs.map +1 -1
  156. package/dist/auth/credential-source.d.ts +8 -0
  157. package/dist/auth/credential-source.js +26 -13
  158. package/dist/auth/credential-source.js.map +1 -1
  159. package/dist/catalog/agent-model-options.cjs +25 -17
  160. package/dist/catalog/agent-model-options.cjs.map +1 -1
  161. package/dist/catalog/agent-model-options.d.ts +38 -5
  162. package/dist/catalog/agent-model-options.js +25 -17
  163. package/dist/catalog/agent-model-options.js.map +1 -1
  164. package/dist/catalog/channel-refusal.cjs +36 -0
  165. package/dist/catalog/channel-refusal.cjs.map +1 -0
  166. package/dist/catalog/channel-refusal.d.ts +29 -0
  167. package/dist/catalog/channel-refusal.js +36 -0
  168. package/dist/catalog/channel-refusal.js.map +1 -0
  169. package/dist/catalog/chat-pickers.cjs +60 -24
  170. package/dist/catalog/chat-pickers.cjs.map +1 -1
  171. package/dist/catalog/chat-pickers.d.ts +12 -2
  172. package/dist/catalog/chat-pickers.js +56 -20
  173. package/dist/catalog/chat-pickers.js.map +1 -1
  174. package/dist/catalog/runtime-catalog.cjs +89 -23
  175. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  176. package/dist/catalog/runtime-catalog.d.ts +8 -2
  177. package/dist/catalog/runtime-catalog.js +83 -17
  178. package/dist/catalog/runtime-catalog.js.map +1 -1
  179. package/dist/catalog/use-athena-chat-mode.cjs +12 -12
  180. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
  181. package/dist/chat/AthenaChat.cjs +155 -67
  182. package/dist/chat/AthenaChat.cjs.map +1 -1
  183. package/dist/chat/AthenaChat.d.ts +42 -2
  184. package/dist/chat/AthenaChat.js +106 -18
  185. package/dist/chat/AthenaChat.js.map +1 -1
  186. package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
  187. package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
  188. package/dist/chat/DrivingOnChip.cjs +23 -0
  189. package/dist/chat/DrivingOnChip.cjs.map +1 -0
  190. package/dist/chat/DrivingOnChip.d.ts +17 -0
  191. package/dist/chat/DrivingOnChip.js +23 -0
  192. package/dist/chat/DrivingOnChip.js.map +1 -0
  193. package/dist/chat/StatewireApprovalCard.cjs +125 -31
  194. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  195. package/dist/chat/StatewireApprovalCard.d.ts +73 -1
  196. package/dist/chat/StatewireApprovalCard.js +115 -21
  197. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  198. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  199. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  200. package/dist/chat/StatewireQueuedMessages.cjs +25 -63
  201. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  202. package/dist/chat/StatewireQueuedMessages.d.ts +11 -13
  203. package/dist/chat/StatewireQueuedMessages.js +16 -54
  204. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  205. package/dist/chat/WaitingOnYouBanner.cjs +3 -3
  206. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  207. package/dist/chat/athena-chat-welcome.cjs +2 -2
  208. package/dist/chat/athena-chat-welcome.cjs.map +1 -1
  209. package/dist/chat/athena-citation-links.cjs +5 -5
  210. package/dist/chat/athena-citation-links.cjs.map +1 -1
  211. package/dist/chat/athena-composer-controls.cjs +26 -16
  212. package/dist/chat/athena-composer-controls.cjs.map +1 -1
  213. package/dist/chat/athena-composer-controls.d.ts +6 -0
  214. package/dist/chat/athena-composer-controls.js +26 -16
  215. package/dist/chat/athena-composer-controls.js.map +1 -1
  216. package/dist/chat/athena-turn-end-status.cjs +42 -0
  217. package/dist/chat/athena-turn-end-status.cjs.map +1 -0
  218. package/dist/chat/athena-turn-end-status.d.ts +24 -0
  219. package/dist/chat/athena-turn-end-status.js +42 -0
  220. package/dist/chat/athena-turn-end-status.js.map +1 -0
  221. package/dist/chat/browser-decision-check.cjs +131 -0
  222. package/dist/chat/browser-decision-check.cjs.map +1 -0
  223. package/dist/chat/browser-decision-check.d.ts +61 -0
  224. package/dist/chat/browser-decision-check.js +131 -0
  225. package/dist/chat/browser-decision-check.js.map +1 -0
  226. package/dist/chat/chat-outbox-rows.cjs +3 -3
  227. package/dist/chat/chat-outbox-rows.cjs.map +1 -1
  228. package/dist/chat/chat-voice-controls.cjs +93 -28
  229. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  230. package/dist/chat/chat-voice-controls.d.ts +36 -2
  231. package/dist/chat/chat-voice-controls.js +89 -24
  232. package/dist/chat/chat-voice-controls.js.map +1 -1
  233. package/dist/chat/composer-keyboard-hint.cjs +5 -5
  234. package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
  235. package/dist/chat/device-operation.cjs +29 -0
  236. package/dist/chat/device-operation.cjs.map +1 -0
  237. package/dist/chat/device-operation.d.ts +34 -0
  238. package/dist/chat/device-operation.js +29 -0
  239. package/dist/chat/device-operation.js.map +1 -0
  240. package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
  241. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  242. package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
  243. package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
  244. package/dist/chat/super-grouping/SuperGroupingCard.cjs +52 -36
  245. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  246. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
  247. package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
  248. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  249. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
  250. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  251. package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
  252. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  253. package/dist/chat/super-grouping/ToolTimeline.cjs +73 -40
  254. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  255. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
  256. package/dist/chat/super-grouping/ToolTimeline.js +69 -36
  257. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  258. package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
  259. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  260. package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
  261. package/dist/chat/super-grouping/activity-timeline.js +47 -12
  262. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  263. package/dist/chat/super-grouping/grouping-function.cjs +4 -0
  264. package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
  265. package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
  266. package/dist/chat/super-grouping/grouping-function.js +5 -1
  267. package/dist/chat/super-grouping/grouping-function.js.map +1 -1
  268. package/dist/chat/super-grouping/index.cjs +6 -0
  269. package/dist/chat/super-grouping/index.cjs.map +1 -1
  270. package/dist/chat/super-grouping/index.d.ts +5 -2
  271. package/dist/chat/super-grouping/index.js +7 -1
  272. package/dist/chat/super-grouping/index.js.map +1 -1
  273. package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
  274. package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
  275. package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
  276. package/dist/chat/super-grouping/tool-part-placement.js +17 -0
  277. package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
  278. package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
  279. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
  280. package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
  281. package/dist/chat/thread-scroll-to-bottom.js +2 -2
  282. package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
  283. package/dist/chat/tooltip-icon-button.cjs +2 -2
  284. package/dist/chat/tooltip-icon-button.cjs.map +1 -1
  285. package/dist/chat/use-athena-voice-live.cjs +11 -0
  286. package/dist/chat/use-athena-voice-live.cjs.map +1 -0
  287. package/dist/chat/use-athena-voice-live.d.ts +11 -0
  288. package/dist/chat/use-athena-voice-live.js +11 -0
  289. package/dist/chat/use-athena-voice-live.js.map +1 -0
  290. package/dist/chat/use-statewire-approval-request.cjs +56 -24
  291. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  292. package/dist/chat/use-statewire-approval-request.d.ts +33 -4
  293. package/dist/chat/use-statewire-approval-request.js +41 -9
  294. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  295. package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
  296. package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
  297. package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
  298. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  299. package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
  300. package/dist/chat-ui/composer/tiptap-composer.js +85 -54
  301. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  302. package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
  303. package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
  304. package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
  305. package/dist/chat-ui/header/conversation-history-panel.js +38 -12
  306. package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
  307. package/dist/chat-ui/index.cjs +18 -0
  308. package/dist/chat-ui/index.cjs.map +1 -1
  309. package/dist/chat-ui/index.d.ts +7 -1
  310. package/dist/chat-ui/index.js +18 -0
  311. package/dist/chat-ui/index.js.map +1 -1
  312. package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
  313. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  314. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
  315. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  316. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
  317. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  318. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
  319. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  320. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
  321. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  322. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
  323. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
  324. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  325. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
  326. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
  327. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
  328. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
  329. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
  330. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  331. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
  332. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
  333. package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
  334. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
  335. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
  336. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
  337. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  338. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
  339. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
  340. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  341. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
  342. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  343. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
  344. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
  345. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  346. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
  347. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
  348. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
  349. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
  350. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
  351. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
  352. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  353. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
  354. package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
  355. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  356. package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
  357. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
  358. package/dist/chat-ui/mentions/use-mention-asset.cjs +3 -3
  359. package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
  360. package/dist/chat-ui/messages/answer-label.cjs +42 -0
  361. package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
  362. package/dist/chat-ui/messages/answer-label.d.ts +33 -0
  363. package/dist/chat-ui/messages/answer-label.js +42 -0
  364. package/dist/chat-ui/messages/answer-label.js.map +1 -0
  365. package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
  366. package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
  367. package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
  368. package/dist/chat-ui/messages/arrival-animation.js +13 -0
  369. package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
  370. package/dist/chat-ui/messages/continue-pill.cjs +5 -5
  371. package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
  372. package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
  373. package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
  374. package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
  375. package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
  376. package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
  377. package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
  378. package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
  379. package/dist/chat-ui/messages/message-components.cjs +8 -4
  380. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  381. package/dist/chat-ui/messages/message-components.js +5 -1
  382. package/dist/chat-ui/messages/message-components.js.map +1 -1
  383. package/dist/chat-ui/messages/message-images.cjs +66 -0
  384. package/dist/chat-ui/messages/message-images.cjs.map +1 -0
  385. package/dist/chat-ui/messages/message-images.d.ts +16 -0
  386. package/dist/chat-ui/messages/message-images.js +66 -0
  387. package/dist/chat-ui/messages/message-images.js.map +1 -0
  388. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
  389. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  390. package/dist/chat-ui/messages/wake-marker.cjs +3 -3
  391. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  392. package/dist/chat-ui/rich-text/chat-link.cjs +2 -2
  393. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
  394. package/dist/chat-ui/rich-text/chat-message-body.cjs +8 -8
  395. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  396. package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
  397. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  398. package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
  399. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
  400. package/dist/chat-ui/statewire.cjs +3 -0
  401. package/dist/chat-ui/statewire.cjs.map +1 -1
  402. package/dist/chat-ui/statewire.d.ts +2 -1
  403. package/dist/chat-ui/statewire.js +3 -0
  404. package/dist/chat-ui/statewire.js.map +1 -1
  405. package/dist/chat-ui/thread/chat-thread-shell.cjs +43 -14
  406. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  407. package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
  408. package/dist/chat-ui/thread/chat-thread-shell.js +35 -6
  409. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  410. package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
  411. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  412. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
  413. package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
  414. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  415. package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
  416. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  417. package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
  418. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  419. package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
  420. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
  421. package/dist/collab/client.cjs +40 -3
  422. package/dist/collab/client.cjs.map +1 -1
  423. package/dist/collab/client.d.ts +25 -0
  424. package/dist/collab/client.js +40 -3
  425. package/dist/collab/client.js.map +1 -1
  426. package/dist/collab/document-status.cjs +150 -0
  427. package/dist/collab/document-status.cjs.map +1 -0
  428. package/dist/collab/document-status.d.ts +68 -0
  429. package/dist/collab/document-status.js +150 -0
  430. package/dist/collab/document-status.js.map +1 -0
  431. package/dist/collab/index.cjs +7 -0
  432. package/dist/collab/index.cjs.map +1 -1
  433. package/dist/collab/index.d.ts +6 -1
  434. package/dist/collab/index.js +7 -0
  435. package/dist/collab/index.js.map +1 -1
  436. package/dist/collab/presence-react.cjs +11 -11
  437. package/dist/collab/presence-react.cjs.map +1 -1
  438. package/dist/collab/react.cjs +6 -6
  439. package/dist/collab/react.cjs.map +1 -1
  440. package/dist/composer/AttachmentContext.cjs +24 -11
  441. package/dist/composer/AttachmentContext.cjs.map +1 -1
  442. package/dist/composer/AttachmentContext.js +18 -5
  443. package/dist/composer/AttachmentContext.js.map +1 -1
  444. package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
  445. package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
  446. package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
  447. package/dist/composer/ComposerAttachmentPreview.js +79 -24
  448. package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
  449. package/dist/composer/ComposerDropZone.cjs +7 -7
  450. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  451. package/dist/composer/FileUploadButton.cjs +37 -22
  452. package/dist/composer/FileUploadButton.cjs.map +1 -1
  453. package/dist/composer/FileUploadButton.d.ts +6 -0
  454. package/dist/composer/FileUploadButton.js +34 -19
  455. package/dist/composer/FileUploadButton.js.map +1 -1
  456. package/dist/composer/QuoteContext.cjs +8 -8
  457. package/dist/composer/QuoteContext.cjs.map +1 -1
  458. package/dist/composer/composer-handoff.cjs +4 -4
  459. package/dist/composer/composer-handoff.cjs.map +1 -1
  460. package/dist/composer/useAppendToComposer.cjs +4 -4
  461. package/dist/composer/useAppendToComposer.cjs.map +1 -1
  462. package/dist/composer/useAttachFiles.cjs +23 -6
  463. package/dist/composer/useAttachFiles.cjs.map +1 -1
  464. package/dist/composer/useAttachFiles.d.ts +15 -7
  465. package/dist/composer/useAttachFiles.js +22 -5
  466. package/dist/composer/useAttachFiles.js.map +1 -1
  467. package/dist/composer/useComposerAttachment.cjs +4 -4
  468. package/dist/composer/useComposerAttachment.cjs.map +1 -1
  469. package/dist/composer/useFileUpload.cjs +21 -16
  470. package/dist/composer/useFileUpload.cjs.map +1 -1
  471. package/dist/composer/useFileUpload.d.ts +12 -0
  472. package/dist/composer/useFileUpload.js +12 -7
  473. package/dist/composer/useFileUpload.js.map +1 -1
  474. package/dist/composer/useReadComposerDraft.cjs +2 -2
  475. package/dist/composer/useReadComposerDraft.cjs.map +1 -1
  476. package/dist/composer/useSendMessage.cjs +4 -4
  477. package/dist/composer/useSendMessage.cjs.map +1 -1
  478. package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
  479. package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
  480. package/dist/dictation/audio-level-history.cjs +3 -3
  481. package/dist/dictation/audio-level-history.cjs.map +1 -1
  482. package/dist/dictation/dictation-controls.cjs +24 -20
  483. package/dist/dictation/dictation-controls.cjs.map +1 -1
  484. package/dist/dictation/dictation-controls.d.ts +6 -1
  485. package/dist/dictation/dictation-controls.js +24 -20
  486. package/dist/dictation/dictation-controls.js.map +1 -1
  487. package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
  488. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
  489. package/dist/dictation/use-dictation.cjs +22 -22
  490. package/dist/dictation/use-dictation.cjs.map +1 -1
  491. package/dist/index.cjs +26 -2
  492. package/dist/index.cjs.map +1 -1
  493. package/dist/index.d.ts +15 -3
  494. package/dist/index.js +26 -2
  495. package/dist/index.js.map +1 -1
  496. package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
  497. package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
  498. package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
  499. package/dist/keryx-http/src/receive-only-socket.js +40 -0
  500. package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
  501. package/dist/keryx-http/src/update-attributions.cjs +111 -0
  502. package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
  503. package/dist/keryx-http/src/update-attributions.d.ts +75 -0
  504. package/dist/keryx-http/src/update-attributions.js +111 -0
  505. package/dist/keryx-http/src/update-attributions.js.map +1 -0
  506. package/dist/lib/owner-document.cjs +6 -6
  507. package/dist/lib/owner-document.cjs.map +1 -1
  508. package/dist/lib/use-athena-rest-query.cjs +4 -4
  509. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  510. package/dist/lib/use-document-active.cjs +4 -4
  511. package/dist/lib/use-document-active.cjs.map +1 -1
  512. package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
  513. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
  514. package/dist/offline/offline-history.cjs +7 -7
  515. package/dist/offline/offline-history.cjs.map +1 -1
  516. package/dist/provider/AthenaContext.cjs +3 -3
  517. package/dist/provider/AthenaContext.cjs.map +1 -1
  518. package/dist/provider/AthenaProvider.cjs +116 -79
  519. package/dist/provider/AthenaProvider.cjs.map +1 -1
  520. package/dist/provider/AthenaProvider.js +40 -3
  521. package/dist/provider/AthenaProvider.js.map +1 -1
  522. package/dist/provider/PostHogProvider.cjs +2 -2
  523. package/dist/provider/PostHogProvider.cjs.map +1 -1
  524. package/dist/provider/agent-selection-context.cjs +2 -2
  525. package/dist/provider/agent-selection-context.cjs.map +1 -1
  526. package/dist/provider/chat-mode-context.cjs +2 -2
  527. package/dist/provider/chat-mode-context.cjs.map +1 -1
  528. package/dist/provider/session-persistence-context.cjs +10 -0
  529. package/dist/provider/session-persistence-context.cjs.map +1 -0
  530. package/dist/provider/session-persistence-context.d.ts +15 -0
  531. package/dist/provider/session-persistence-context.js +10 -0
  532. package/dist/provider/session-persistence-context.js.map +1 -0
  533. package/dist/provider/statewire-history-context.cjs +4 -4
  534. package/dist/provider/statewire-history-context.cjs.map +1 -1
  535. package/dist/provider/statewire-lifecycle-context.cjs +3 -3
  536. package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
  537. package/dist/provider/statewire-window-context.cjs +3 -3
  538. package/dist/provider/statewire-window-context.cjs.map +1 -1
  539. package/dist/provider/theme-style-context.cjs +3 -3
  540. package/dist/provider/theme-style-context.cjs.map +1 -1
  541. package/dist/react/package.json.cjs +1 -1
  542. package/dist/react/package.json.js +1 -1
  543. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
  544. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  545. package/dist/runtime/auth-refusal-restart.cjs +7 -7
  546. package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
  547. package/dist/runtime/auth.cjs +13 -13
  548. package/dist/runtime/auth.cjs.map +1 -1
  549. package/dist/runtime/statewire-lifecycle.cjs +1 -0
  550. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  551. package/dist/runtime/statewire-lifecycle.d.ts +3 -1
  552. package/dist/runtime/statewire-lifecycle.js +2 -1
  553. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  554. package/dist/runtime/statewire-server-lane-context.cjs +2 -2
  555. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  556. package/dist/runtime/statewire-session-lane.cjs +4 -4
  557. package/dist/runtime/statewire-session-lane.cjs.map +1 -1
  558. package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
  559. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  560. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  561. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  562. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  563. package/dist/styles.css +1 -1
  564. package/dist/threads/Inbox.cjs +8 -8
  565. package/dist/threads/Inbox.cjs.map +1 -1
  566. package/dist/threads/SessionList.cjs +9 -9
  567. package/dist/threads/SessionList.cjs.map +1 -1
  568. package/dist/threads/SessionsPage.cjs +11 -11
  569. package/dist/threads/SessionsPage.cjs.map +1 -1
  570. package/dist/threads/index-triggered-refresh.cjs +10 -10
  571. package/dist/threads/index-triggered-refresh.cjs.map +1 -1
  572. package/dist/threads/mark-viewed-thread-read.cjs +12 -12
  573. package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
  574. package/dist/threads/offline-session-list.cjs +3 -3
  575. package/dist/threads/offline-session-list.cjs.map +1 -1
  576. package/dist/threads/session-list-tab-share.cjs +5 -5
  577. package/dist/threads/session-list-tab-share.cjs.map +1 -1
  578. package/dist/threads/statewire-thread-list.cjs +51 -51
  579. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  580. package/dist/threads/thread-id-context.cjs +5 -5
  581. package/dist/threads/thread-id-context.cjs.map +1 -1
  582. package/dist/threads/use-athena-session-attention.cjs +2 -2
  583. package/dist/threads/use-athena-session-attention.cjs.map +1 -1
  584. package/dist/threads/use-athena-sessions.cjs +10 -10
  585. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  586. package/dist/threads/use-athena-thread-model.cjs +3 -3
  587. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  588. package/dist/threads/use-rest-conversation-history.cjs +3 -3
  589. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  590. package/dist/threads/use-statewire-conversation-history.cjs +8 -8
  591. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  592. package/dist/threads/use-thread-archive.cjs +9 -9
  593. package/dist/threads/use-thread-archive.cjs.map +1 -1
  594. package/dist/threads/use-thread-favorite.cjs +2 -2
  595. package/dist/threads/use-thread-favorite.cjs.map +1 -1
  596. package/dist/threads/use-thread-field-override.cjs +20 -20
  597. package/dist/threads/use-thread-field-override.cjs.map +1 -1
  598. package/dist/threads/use-thread-read-state.cjs +4 -4
  599. package/dist/threads/use-thread-read-state.cjs.map +1 -1
  600. package/dist/threads/use-thread-rename.cjs +2 -2
  601. package/dist/threads/use-thread-rename.cjs.map +1 -1
  602. package/dist/threads/useAthenaThreadManager.cjs +2 -2
  603. package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
  604. package/dist/tools/NestedPtcMessages.cjs +6 -6
  605. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  606. package/dist/tools/append-document-tool-ui.cjs +7 -7
  607. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  608. package/dist/tools/file-tool-uis.cjs +2 -2
  609. package/dist/tools/file-tool-uis.cjs.map +1 -1
  610. package/dist/tools/misc-tool-uis.cjs +2 -2
  611. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  612. package/dist/tools/primitives.cjs +6 -6
  613. package/dist/tools/primitives.cjs.map +1 -1
  614. package/dist/tools/read-asset-tool-ui.cjs +6 -6
  615. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  616. package/dist/tools/subagent-task-tool-ui.cjs +21 -21
  617. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  618. package/dist/tools/test-recording-tool-uis.cjs +16 -16
  619. package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
  620. package/dist/tools/todo-plan-store.cjs +4 -4
  621. package/dist/tools/todo-plan-store.cjs.map +1 -1
  622. package/dist/tools/tool-appearance.cjs +3 -3
  623. package/dist/tools/tool-appearance.cjs.map +1 -1
  624. package/dist/tools/tool-fallback.cjs +14 -14
  625. package/dist/tools/tool-fallback.cjs.map +1 -1
  626. package/dist/tools/tool-uis.cjs +74 -74
  627. package/dist/tools/tool-uis.cjs.map +1 -1
  628. package/dist/tools/use-elapsed-seconds.cjs +3 -3
  629. package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
  630. package/dist/tools/write-todos-tool-ui.cjs +9 -9
  631. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  632. package/dist/ui/image-viewer.cjs +382 -0
  633. package/dist/ui/image-viewer.cjs.map +1 -0
  634. package/dist/ui/image-viewer.d.ts +50 -0
  635. package/dist/ui/image-viewer.js +382 -0
  636. package/dist/ui/image-viewer.js.map +1 -0
  637. package/dist/voice/chat.cjs +6 -0
  638. package/dist/voice/chat.cjs.map +1 -1
  639. package/dist/voice/chat.d.ts +1 -1
  640. package/dist/voice/chat.js +8 -2
  641. package/dist/voice/livekit-join.cjs +52 -101
  642. package/dist/voice/livekit-join.cjs.map +1 -1
  643. package/dist/voice/livekit-join.d.ts +1 -6
  644. package/dist/voice/livekit-join.js +52 -101
  645. package/dist/voice/livekit-join.js.map +1 -1
  646. package/dist/voice/livekit.cjs.map +1 -1
  647. package/dist/voice/livekit.d.ts +11 -1
  648. package/dist/voice/livekit.js.map +1 -1
  649. package/dist/voice/use-athena-voice-session.cjs +34 -34
  650. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  651. package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
  652. package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
  653. package/dist/workbench/SessionWorkbench.cjs +22 -22
  654. package/dist/workbench/SessionWorkbench.cjs.map +1 -1
  655. package/dist/workbench/session-workbench-context.cjs +3 -3
  656. package/dist/workbench/session-workbench-context.cjs.map +1 -1
  657. package/dist/workbench/session-workbench-panes.cjs +8 -8
  658. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  659. package/dist/workbench/workbench-layout-context.cjs +3 -3
  660. package/dist/workbench/workbench-layout-context.cjs.map +1 -1
  661. package/package.json +2 -1
@@ -1,18 +1,47 @@
1
1
  import { useQuery } from "@tanstack/react-query";
2
- import { useId } from "react";
3
- import { useCatalogQueryClient, credentialFingerprint } from "../../catalog/runtime-catalog.js";
2
+ import { useAthenaCredentialIdentityEpoch } from "../../auth/AthenaCredentialSourceContext.js";
3
+ import { jwtSubject, jwtScope } from "../../auth/credential-source.js";
4
+ import { useCatalogQueryClient } from "../../catalog/runtime-catalog.js";
5
+ import { keyPartFingerprint } from "../../lib/use-athena-rest-query.js";
4
6
  import { withCredentialRenewal } from "../../runtime/credential-renewal.js";
5
7
  import { fetchAccountIdentity } from "../../threads/api.js";
6
- function useAccountWorkspaceId(auth) {
8
+ const tokenGetterIds = /* @__PURE__ */ new WeakMap();
9
+ let lastTokenGetterId = 0;
10
+ function tokenGetterId(getToken) {
11
+ if (getToken === void 0) return "";
12
+ let id = tokenGetterIds.get(getToken);
13
+ if (id === void 0) {
14
+ lastTokenGetterId += 1;
15
+ id = lastTokenGetterId;
16
+ tokenGetterIds.set(getToken, id);
17
+ }
18
+ return `getter:${id}`;
19
+ }
20
+ function heldTokenIdentity(token) {
21
+ if (!token) return "";
22
+ const subject = jwtSubject(token);
23
+ if (subject === null) return `token:${keyPartFingerprint(token)}`;
24
+ const scope = jwtScope(token);
25
+ return scope === null ? `sub:${keyPartFingerprint(subject)}` : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;
26
+ }
27
+ function useAccountIdentityRead(auth, { enabled, tokenGetter }) {
7
28
  const queryClient = useCatalogQueryClient();
8
- const anonymousScope = useId();
9
- const principal = (auth == null ? void 0 : auth.apiKey) ? `key:${credentialFingerprint({ credential: auth.apiKey })}` : (auth == null ? void 0 : auth.userId) ?? ((auth == null ? void 0 : auth.accessToken) ? `token:${credentialFingerprint({ credential: auth.accessToken })}` : anonymousScope);
29
+ const identityEpoch = useAthenaCredentialIdentityEpoch();
10
30
  const query = useQuery(
11
31
  {
12
- queryKey: ["athena-sdk", "account-workspace", auth == null ? void 0 : auth.backendUrl, auth == null ? void 0 : auth.userId, principal],
32
+ queryKey: [
33
+ "athena-sdk",
34
+ "account",
35
+ (auth == null ? void 0 : auth.backendUrl) ?? "",
36
+ (auth == null ? void 0 : auth.userId) ?? "",
37
+ (auth == null ? void 0 : auth.apiKey) ? keyPartFingerprint(auth.apiKey) : "",
38
+ tokenGetterId(tokenGetter),
39
+ heldTokenIdentity(auth == null ? void 0 : auth.accessToken),
40
+ identityEpoch
41
+ ],
13
42
  queryFn: async ({ signal }) => {
14
43
  if (!auth) return null;
15
- const identity = await withCredentialRenewal(
44
+ return withCredentialRenewal(
16
45
  async ({ force } = {}) => {
17
46
  var _a, _b;
18
47
  return {
@@ -23,17 +52,23 @@ function useAccountWorkspaceId(auth) {
23
52
  },
24
53
  (resolved) => fetchAccountIdentity(auth.backendUrl, resolved, { signal })
25
54
  );
26
- return identity.workspaceId ?? null;
27
55
  },
28
- enabled: auth !== null && !auth.workspaceId,
56
+ enabled: auth !== null && enabled,
29
57
  retry: false,
30
58
  staleTime: 6e4
31
59
  },
32
60
  queryClient
33
61
  );
34
- return (auth == null ? void 0 : auth.workspaceId) ?? query.data ?? void 0;
62
+ return query.data;
63
+ }
64
+ function useAccountIdentity(auth, options = {}) {
65
+ const identity = useAccountIdentityRead(auth, { enabled: true, ...options });
66
+ return {
67
+ userId: identity == null ? void 0 : identity.userId,
68
+ workspaceId: (auth == null ? void 0 : auth.workspaceId) ?? (identity == null ? void 0 : identity.workspaceId) ?? void 0
69
+ };
35
70
  }
36
71
  export {
37
- useAccountWorkspaceId
72
+ useAccountIdentity
38
73
  };
39
74
  //# sourceMappingURL=use-account-workspace-id.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-account-workspace-id.js","sources":["../../../src/chat-ui/mentions/use-account-workspace-id.ts"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { useId } from 'react';\nimport { credentialFingerprint, useCatalogQueryClient } from '../../catalog/runtime-catalog';\nimport { withCredentialRenewal } from '../../runtime/credential-renewal';\nimport { fetchAccountIdentity } from '../../threads/api';\nimport type { MentionAuthContext } from './suggestions/data/api-client';\n\n/** Account identity uses the host's query cache and never a process-wide user-id map. */\nexport function useAccountWorkspaceId(auth: MentionAuthContext | null): string | undefined {\n const queryClient = useCatalogQueryClient();\n const anonymousScope = useId();\n // A workspace API key wins even when the person is known; a bearer can\n // rotate without changing that person's cache identity.\n const principal = auth?.apiKey\n ? `key:${credentialFingerprint({ credential: auth.apiKey })}`\n : auth?.userId ??\n (auth?.accessToken\n ? `token:${credentialFingerprint({ credential: auth.accessToken })}`\n : anonymousScope);\n const query = useQuery(\n {\n queryKey: ['athena-sdk', 'account-workspace', auth?.backendUrl, auth?.userId, principal],\n queryFn: async ({ signal }) => {\n if (!auth) return null;\n const identity = await withCredentialRenewal(\n async ({ force }: { force?: boolean } = {}) => ({\n token:\n (force ? await auth.renewAccessToken?.() : await auth.getAccessToken?.()) ??\n auth.accessToken ??\n null,\n apiKey: auth.apiKey,\n credentials: auth.credentials,\n }),\n (resolved) => fetchAccountIdentity(auth.backendUrl, resolved, { signal })\n );\n return identity.workspaceId ?? null;\n },\n enabled: auth !== null && !auth.workspaceId,\n retry: false,\n staleTime: 60_000,\n },\n queryClient\n );\n return auth?.workspaceId ?? query.data ?? undefined;\n}\n"],"names":[],"mappings":";;;;;AAQO,SAAS,sBAAsB,MAAqD;AACzF,QAAM,cAAc,sBAAA;AACpB,QAAM,iBAAiB,MAAA;AAGvB,QAAM,aAAY,6BAAM,UACpB,OAAO,sBAAsB,EAAE,YAAY,KAAK,OAAA,CAAQ,CAAC,MACzD,6BAAM,aACL,6BAAM,eACH,SAAS,sBAAsB,EAAE,YAAY,KAAK,YAAA,CAAa,CAAC,KAChE;AACR,QAAM,QAAQ;AAAA,IACZ;AAAA,MACE,UAAU,CAAC,cAAc,qBAAqB,6BAAM,YAAY,6BAAM,QAAQ,SAAS;AAAA,MACvF,SAAS,OAAO,EAAE,aAAa;AAC7B,YAAI,CAAC,KAAM,QAAO;AAClB,cAAM,WAAW,MAAM;AAAA,UACrB,OAAO,EAAE,MAAA,IAA+B,OAAC;;AAAO;AAAA,cAC9C,QACG,QAAQ,QAAM,UAAK,qBAAL,iCAA4B,QAAM,UAAK,mBAAL,mCACjD,KAAK,eACL;AAAA,cACF,QAAQ,KAAK;AAAA,cACb,aAAa,KAAK;AAAA,YAAA;AAAA;AAAA,UAEpB,CAAC,aAAa,qBAAqB,KAAK,YAAY,UAAU,EAAE,QAAQ;AAAA,QAAA;AAE1E,eAAO,SAAS,eAAe;AAAA,MACjC;AAAA,MACA,SAAS,SAAS,QAAQ,CAAC,KAAK;AAAA,MAChC,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEF,UAAO,6BAAM,gBAAe,MAAM,QAAQ;AAC5C;"}
1
+ {"version":3,"file":"use-account-workspace-id.js","sources":["../../../src/chat-ui/mentions/use-account-workspace-id.ts"],"sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { useAthenaCredentialIdentityEpoch } from '../../auth/AthenaCredentialSourceContext';\nimport { jwtScope, jwtSubject } from '../../auth/credential-source';\nimport { useCatalogQueryClient } from '../../catalog/runtime-catalog';\nimport { keyPartFingerprint } from '../../lib/use-athena-rest-query';\nimport { withCredentialRenewal } from '../../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../../runtime/statewire-auth-headers';\nimport { type AccountIdentity, fetchAccountIdentity } from '../../threads/api';\nimport type { MentionAuthContext } from './suggestions/data/api-client';\n\n/** The credential's agora identity, as far as it is known yet. */\nexport interface AccountIdentityState {\n /** Agora's user id (`user_…`) for the credential; unknown until `/me` answers. */\n userId: string | undefined;\n /** The host's workspace when it names one, else the credential's current workspace. */\n workspaceId: string | undefined;\n}\n\nexport interface AccountIdentityOptions {\n /**\n * The provider's token getter, which `auth.getAccessToken` wraps (`AthenaChat`\n * passes `useAthenaConfig().getToken`). Its identity keeps two providers\n * apart when only their getters know who they sign in.\n */\n tokenGetter?: AthenaStatewireTokenGetter;\n}\n\n/** One id per token getter, so the key can name a getter without holding it. */\nconst tokenGetterIds = new WeakMap<AthenaStatewireTokenGetter, number>();\nlet lastTokenGetterId = 0;\n\nfunction tokenGetterId(getToken: AthenaStatewireTokenGetter | undefined): string {\n if (getToken === undefined) return '';\n let id = tokenGetterIds.get(getToken);\n if (id === undefined) {\n lastTokenGetterId += 1;\n id = lastTokenGetterId;\n tokenGetterIds.set(getToken, id);\n }\n return `getter:${id}`;\n}\n\n/**\n * Who a held token acts as, and where, without the token: its JWT subject and\n * the claims scoping it to a workspace or org (`jwtScope`), or the token\n * itself when it is opaque, fingerprinted. A renewal for the same person and\n * scope keeps it, so a rotation is not a new identity; the same person's token\n * scoped to another workspace is.\n */\nfunction heldTokenIdentity(token: string | null | undefined): string {\n if (!token) return '';\n const subject = jwtSubject(token);\n if (subject === null) return `token:${keyPartFingerprint(token)}`;\n const scope = jwtScope(token);\n return scope === null\n ? `sub:${keyPartFingerprint(subject)}`\n : `sub:${keyPartFingerprint(subject)}|scope:${keyPartFingerprint(scope)}`;\n}\n\n/**\n * One `/me` read per credential, through the host's query cache (never a\n * process-wide user-id map), keyed by the credential the read is sent with and\n * never by the secret: the backend, the signed-in person, the API key's\n * fingerprint, the provider's token getter, who the held token acts as and\n * which workspace it is scoped to, and the provider's credential identity\n * epoch (`useAthenaCredentialIdentityEpoch`), which moves once the getter has\n * handed out a token that acts as someone else. A renewal for the same person\n * and scope keeps the key, so the answer stays put; an API-key switch, a held\n * token scoped to another workspace, or a getter now signing in someone else,\n * reads `/me` again under a new key, never a cached answer for the previous\n * credential. The epoch follows the person, not the scope: a host getter that\n * alone hands out the same person's token for another workspace is read again\n * once the answer goes stale. `enabled` is the caller's: a reader that only\n * needs the workspace skips the read when the host names one.\n */\nfunction useAccountIdentityRead(\n auth: MentionAuthContext | null,\n { enabled, tokenGetter }: { enabled: boolean } & AccountIdentityOptions\n): AccountIdentity | null | undefined {\n const queryClient = useCatalogQueryClient();\n const identityEpoch = useAthenaCredentialIdentityEpoch();\n const query = useQuery(\n {\n queryKey: [\n 'athena-sdk',\n 'account',\n auth?.backendUrl ?? '',\n auth?.userId ?? '',\n auth?.apiKey ? keyPartFingerprint(auth.apiKey) : '',\n tokenGetterId(tokenGetter),\n heldTokenIdentity(auth?.accessToken),\n identityEpoch,\n ],\n queryFn: async ({ signal }) => {\n if (!auth) return null;\n return withCredentialRenewal(\n async ({ force }: { force?: boolean } = {}) => ({\n token:\n (force ? await auth.renewAccessToken?.() : await auth.getAccessToken?.()) ??\n auth.accessToken ??\n null,\n apiKey: auth.apiKey,\n credentials: auth.credentials,\n }),\n (resolved) => fetchAccountIdentity(auth.backendUrl, resolved, { signal })\n );\n },\n enabled: auth !== null && enabled,\n retry: false,\n staleTime: 60_000,\n },\n queryClient\n );\n return query.data;\n}\n\n/** The workspace mentions search: the host's when it names one, else the credential's own. */\nexport function useAccountWorkspaceId(auth: MentionAuthContext | null): string | undefined {\n const identity = useAccountIdentityRead(auth, { enabled: !auth?.workspaceId });\n return auth?.workspaceId ?? identity?.workspaceId ?? undefined;\n}\n\n/**\n * The credential's agora user id and workspace from the same read. The auth\n * context carries the identity provider's user id, not agora's, so \"who is\n * the viewer\" (an answer label's \"for you\") needs this one, and it reads\n * `/me` even when the host names a workspace.\n */\nexport function useAccountIdentity(\n auth: MentionAuthContext | null,\n options: AccountIdentityOptions = {}\n): AccountIdentityState {\n const identity = useAccountIdentityRead(auth, { enabled: true, ...options });\n return {\n userId: identity?.userId,\n workspaceId: auth?.workspaceId ?? identity?.workspaceId ?? undefined,\n };\n}\n"],"names":[],"mappings":";;;;;;;AA4BA,MAAM,qCAAqB,QAAA;AAC3B,IAAI,oBAAoB;AAExB,SAAS,cAAc,UAA0D;AAC/E,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,KAAK,eAAe,IAAI,QAAQ;AACpC,MAAI,OAAO,QAAW;AACpB,yBAAqB;AACrB,SAAK;AACL,mBAAe,IAAI,UAAU,EAAE;AAAA,EACjC;AACA,SAAO,UAAU,EAAE;AACrB;AASA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,YAAY,KAAM,QAAO,SAAS,mBAAmB,KAAK,CAAC;AAC/D,QAAM,QAAQ,SAAS,KAAK;AAC5B,SAAO,UAAU,OACb,OAAO,mBAAmB,OAAO,CAAC,KAClC,OAAO,mBAAmB,OAAO,CAAC,UAAU,mBAAmB,KAAK,CAAC;AAC3E;AAkBA,SAAS,uBACP,MACA,EAAE,SAAS,eACyB;AACpC,QAAM,cAAc,sBAAA;AACpB,QAAM,gBAAgB,iCAAA;AACtB,QAAM,QAAQ;AAAA,IACZ;AAAA,MACE,UAAU;AAAA,QACR;AAAA,QACA;AAAA,SACA,6BAAM,eAAc;AAAA,SACpB,6BAAM,WAAU;AAAA,SAChB,6BAAM,UAAS,mBAAmB,KAAK,MAAM,IAAI;AAAA,QACjD,cAAc,WAAW;AAAA,QACzB,kBAAkB,6BAAM,WAAW;AAAA,QACnC;AAAA,MAAA;AAAA,MAEF,SAAS,OAAO,EAAE,aAAa;AAC7B,YAAI,CAAC,KAAM,QAAO;AAClB,eAAO;AAAA,UACL,OAAO,EAAE,MAAA,IAA+B,OAAC;;AAAO;AAAA,cAC9C,QACG,QAAQ,QAAM,UAAK,qBAAL,iCAA4B,QAAM,UAAK,mBAAL,mCACjD,KAAK,eACL;AAAA,cACF,QAAQ,KAAK;AAAA,cACb,aAAa,KAAK;AAAA,YAAA;AAAA;AAAA,UAEpB,CAAC,aAAa,qBAAqB,KAAK,YAAY,UAAU,EAAE,QAAQ;AAAA,QAAA;AAAA,MAE5E;AAAA,MACA,SAAS,SAAS,QAAQ;AAAA,MAC1B,OAAO;AAAA,MACP,WAAW;AAAA,IAAA;AAAA,IAEb;AAAA,EAAA;AAEF,SAAO,MAAM;AACf;AAcO,SAAS,mBACd,MACA,UAAkC,IACZ;AACtB,QAAM,WAAW,uBAAuB,MAAM,EAAE,SAAS,MAAM,GAAG,SAAS;AAC3E,SAAO;AAAA,IACL,QAAQ,qCAAU;AAAA,IAClB,cAAa,6BAAM,iBAAe,qCAAU,gBAAe;AAAA,EAAA;AAE/D;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react = require("react");
3
+ const require$$0 = require("react");
4
4
  const apiClient = require("./suggestions/data/api-client.cjs");
5
5
  const MEMBER_AVATAR_TTL_MS = 5 * 60 * 1e3;
6
6
  const memberAvatarRequests = /* @__PURE__ */ new Map();
@@ -42,11 +42,11 @@ function loadMemberAvatars(auth) {
42
42
  return request;
43
43
  }
44
44
  function useMemberAvatarUrl(email) {
45
- const auth = react.useContext(apiClient.MentionAuthCtx);
45
+ const auth = require$$0.useContext(apiClient.MentionAuthCtx);
46
46
  const normalizedEmail = email == null ? void 0 : email.trim().toLowerCase();
47
47
  const cacheKey = (auth == null ? void 0 : auth.workspaceId) && `${auth.backendUrl}|${auth.workspaceId}`;
48
- const [resolvedAvatar, setResolvedAvatar] = react.useState();
49
- react.useEffect(() => {
48
+ const [resolvedAvatar, setResolvedAvatar] = require$$0.useState();
49
+ require$$0.useEffect(() => {
50
50
  if (!auth || !cacheKey || !normalizedEmail) {
51
51
  setResolvedAvatar(void 0);
52
52
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-member-avatar.cjs","sources":["../../../src/chat-ui/mentions/use-member-avatar.ts"],"sourcesContent":["import { useContext, useEffect, useState } from \"react\";\nimport {\n fetchGraphQL,\n MentionAuthCtx,\n WORKSPACE_MEMBERS_QUERY,\n} from \"./suggestions/data/api-client\";\nimport type { MentionAuthContext } from \"./suggestions/data/api-client\";\n\ntype WorkspaceMemberAvatar = {\n email?: string | null;\n avatarUrl?: string | null;\n};\n\ntype WorkspaceMembersResponse = {\n getUsersInWorkspace?: WorkspaceMemberAvatar[] | null;\n};\n\nconst MEMBER_AVATAR_TTL_MS = 5 * 60 * 1000;\n\ntype MemberAvatarCacheEntry = {\n request: Promise<Map<string, string>>;\n fetchedAt: number | null;\n};\n\nconst memberAvatarRequests = new Map<string, MemberAvatarCacheEntry>();\n\nfunction loadMemberAvatars(\n auth: MentionAuthContext,\n): Promise<Map<string, string>> {\n const workspaceId = auth.workspaceId;\n if (!workspaceId) return Promise.resolve(new Map());\n\n const cacheKey = `${auth.backendUrl}|${workspaceId}`;\n const cached = memberAvatarRequests.get(cacheKey);\n if (cached && (cached.fetchedAt === null || Date.now() - cached.fetchedAt < MEMBER_AVATAR_TTL_MS)) {\n return cached.request;\n }\n\n const entry: MemberAvatarCacheEntry = {\n request: Promise.resolve(new Map<string, string>()),\n fetchedAt: null,\n };\n const request = fetchGraphQL<WorkspaceMembersResponse>(\n auth,\n WORKSPACE_MEMBERS_QUERY,\n { workspaceId },\n )\n .then((data) => {\n const avatars = new Map<string, string>();\n for (const member of data.getUsersInWorkspace ?? []) {\n const email = member.email?.trim().toLowerCase();\n if (email && member.avatarUrl != null) {\n avatars.set(email, member.avatarUrl);\n }\n }\n entry.fetchedAt = Date.now();\n return avatars;\n })\n .catch((error: unknown) => {\n if (memberAvatarRequests.get(cacheKey) === entry) {\n memberAvatarRequests.delete(cacheKey);\n }\n throw error;\n });\n\n entry.request = request;\n memberAvatarRequests.set(cacheKey, entry);\n return request;\n}\n\nexport function useMemberAvatarUrl(\n email: string | undefined,\n): string | undefined {\n const auth = useContext(MentionAuthCtx);\n const normalizedEmail = email?.trim().toLowerCase();\n const cacheKey =\n auth?.workspaceId && `${auth.backendUrl}|${auth.workspaceId}`;\n const [resolvedAvatar, setResolvedAvatar] = useState<{\n cacheKey: string;\n url: string | undefined;\n }>();\n\n useEffect(() => {\n if (!auth || !cacheKey || !normalizedEmail) {\n setResolvedAvatar(undefined);\n return;\n }\n\n let cancelled = false;\n loadMemberAvatars(auth).then(\n (avatars) => {\n if (!cancelled) {\n setResolvedAvatar({ cacheKey, url: avatars.get(normalizedEmail) });\n }\n },\n () => {\n if (!cancelled) setResolvedAvatar({ cacheKey, url: undefined });\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [auth, cacheKey, normalizedEmail]);\n\n if (!cacheKey || !resolvedAvatar || resolvedAvatar.cacheKey !== cacheKey) {\n return undefined;\n }\n return resolvedAvatar.url;\n}\n\nexport function resetMemberAvatarsForTests(): void {\n memberAvatarRequests.clear();\n}\n"],"names":["fetchGraphQL","WORKSPACE_MEMBERS_QUERY","useContext","MentionAuthCtx","useState","useEffect"],"mappings":";;;;AAiBA,MAAM,uBAAuB,IAAI,KAAK;AAOtC,MAAM,2CAA2B,IAAA;AAEjC,SAAS,kBACP,MAC8B;AAC9B,QAAM,cAAc,KAAK;AACzB,MAAI,CAAC,YAAa,QAAO,QAAQ,QAAQ,oBAAI,KAAK;AAElD,QAAM,WAAW,GAAG,KAAK,UAAU,IAAI,WAAW;AAClD,QAAM,SAAS,qBAAqB,IAAI,QAAQ;AAChD,MAAI,WAAW,OAAO,cAAc,QAAQ,KAAK,IAAA,IAAQ,OAAO,YAAY,uBAAuB;AACjG,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,QAAgC;AAAA,IACpC,SAAS,QAAQ,QAAQ,oBAAI,KAAqB;AAAA,IAClD,WAAW;AAAA,EAAA;AAEb,QAAM,UAAUA,UAAAA;AAAAA,IACd;AAAA,IACAC,UAAAA;AAAAA,IACA,EAAE,YAAA;AAAA,EAAY,EAEb,KAAK,CAAC,SAAS;;AACd,UAAM,8BAAc,IAAA;AACpB,eAAW,UAAU,KAAK,uBAAuB,CAAA,GAAI;AACnD,YAAM,SAAQ,YAAO,UAAP,mBAAc,OAAO;AACnC,UAAI,SAAS,OAAO,aAAa,MAAM;AACrC,gBAAQ,IAAI,OAAO,OAAO,SAAS;AAAA,MACrC;AAAA,IACF;AACA,UAAM,YAAY,KAAK,IAAA;AACvB,WAAO;AAAA,EACT,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,QAAI,qBAAqB,IAAI,QAAQ,MAAM,OAAO;AAChD,2BAAqB,OAAO,QAAQ;AAAA,IACtC;AACA,UAAM;AAAA,EACR,CAAC;AAEH,QAAM,UAAU;AAChB,uBAAqB,IAAI,UAAU,KAAK;AACxC,SAAO;AACT;AAEO,SAAS,mBACd,OACoB;AACpB,QAAM,OAAOC,MAAAA,WAAWC,wBAAc;AACtC,QAAM,kBAAkB,+BAAO,OAAO;AACtC,QAAM,YACJ,6BAAM,gBAAe,GAAG,KAAK,UAAU,IAAI,KAAK,WAAW;AAC7D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,eAAA;AAK5CC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB;AAC1C,wBAAkB,MAAS;AAC3B;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,sBAAkB,IAAI,EAAE;AAAA,MACtB,CAAC,YAAY;AACX,YAAI,CAAC,WAAW;AACd,4BAAkB,EAAE,UAAU,KAAK,QAAQ,IAAI,eAAe,GAAG;AAAA,QACnE;AAAA,MACF;AAAA,MACA,MAAM;AACJ,YAAI,CAAC,UAAW,mBAAkB,EAAE,UAAU,KAAK,QAAW;AAAA,MAChE;AAAA,IAAA;AAGF,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,eAAe,CAAC;AAEpC,MAAI,CAAC,YAAY,CAAC,kBAAkB,eAAe,aAAa,UAAU;AACxE,WAAO;AAAA,EACT;AACA,SAAO,eAAe;AACxB;;"}
1
+ {"version":3,"file":"use-member-avatar.cjs","sources":["../../../src/chat-ui/mentions/use-member-avatar.ts"],"sourcesContent":["import { useContext, useEffect, useState } from \"react\";\nimport {\n fetchGraphQL,\n MentionAuthCtx,\n WORKSPACE_MEMBERS_QUERY,\n} from \"./suggestions/data/api-client\";\nimport type { MentionAuthContext } from \"./suggestions/data/api-client\";\n\ntype WorkspaceMemberAvatar = {\n email?: string | null;\n avatarUrl?: string | null;\n};\n\ntype WorkspaceMembersResponse = {\n getUsersInWorkspace?: WorkspaceMemberAvatar[] | null;\n};\n\nconst MEMBER_AVATAR_TTL_MS = 5 * 60 * 1000;\n\ntype MemberAvatarCacheEntry = {\n request: Promise<Map<string, string>>;\n fetchedAt: number | null;\n};\n\nconst memberAvatarRequests = new Map<string, MemberAvatarCacheEntry>();\n\nfunction loadMemberAvatars(\n auth: MentionAuthContext,\n): Promise<Map<string, string>> {\n const workspaceId = auth.workspaceId;\n if (!workspaceId) return Promise.resolve(new Map());\n\n const cacheKey = `${auth.backendUrl}|${workspaceId}`;\n const cached = memberAvatarRequests.get(cacheKey);\n if (cached && (cached.fetchedAt === null || Date.now() - cached.fetchedAt < MEMBER_AVATAR_TTL_MS)) {\n return cached.request;\n }\n\n const entry: MemberAvatarCacheEntry = {\n request: Promise.resolve(new Map<string, string>()),\n fetchedAt: null,\n };\n const request = fetchGraphQL<WorkspaceMembersResponse>(\n auth,\n WORKSPACE_MEMBERS_QUERY,\n { workspaceId },\n )\n .then((data) => {\n const avatars = new Map<string, string>();\n for (const member of data.getUsersInWorkspace ?? []) {\n const email = member.email?.trim().toLowerCase();\n if (email && member.avatarUrl != null) {\n avatars.set(email, member.avatarUrl);\n }\n }\n entry.fetchedAt = Date.now();\n return avatars;\n })\n .catch((error: unknown) => {\n if (memberAvatarRequests.get(cacheKey) === entry) {\n memberAvatarRequests.delete(cacheKey);\n }\n throw error;\n });\n\n entry.request = request;\n memberAvatarRequests.set(cacheKey, entry);\n return request;\n}\n\nexport function useMemberAvatarUrl(\n email: string | undefined,\n): string | undefined {\n const auth = useContext(MentionAuthCtx);\n const normalizedEmail = email?.trim().toLowerCase();\n const cacheKey =\n auth?.workspaceId && `${auth.backendUrl}|${auth.workspaceId}`;\n const [resolvedAvatar, setResolvedAvatar] = useState<{\n cacheKey: string;\n url: string | undefined;\n }>();\n\n useEffect(() => {\n if (!auth || !cacheKey || !normalizedEmail) {\n setResolvedAvatar(undefined);\n return;\n }\n\n let cancelled = false;\n loadMemberAvatars(auth).then(\n (avatars) => {\n if (!cancelled) {\n setResolvedAvatar({ cacheKey, url: avatars.get(normalizedEmail) });\n }\n },\n () => {\n if (!cancelled) setResolvedAvatar({ cacheKey, url: undefined });\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [auth, cacheKey, normalizedEmail]);\n\n if (!cacheKey || !resolvedAvatar || resolvedAvatar.cacheKey !== cacheKey) {\n return undefined;\n }\n return resolvedAvatar.url;\n}\n\nexport function resetMemberAvatarsForTests(): void {\n memberAvatarRequests.clear();\n}\n"],"names":["fetchGraphQL","WORKSPACE_MEMBERS_QUERY","useContext","MentionAuthCtx","useState","useEffect"],"mappings":";;;;AAiBA,MAAM,uBAAuB,IAAI,KAAK;AAOtC,MAAM,2CAA2B,IAAA;AAEjC,SAAS,kBACP,MAC8B;AAC9B,QAAM,cAAc,KAAK;AACzB,MAAI,CAAC,YAAa,QAAO,QAAQ,QAAQ,oBAAI,KAAK;AAElD,QAAM,WAAW,GAAG,KAAK,UAAU,IAAI,WAAW;AAClD,QAAM,SAAS,qBAAqB,IAAI,QAAQ;AAChD,MAAI,WAAW,OAAO,cAAc,QAAQ,KAAK,IAAA,IAAQ,OAAO,YAAY,uBAAuB;AACjG,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,QAAgC;AAAA,IACpC,SAAS,QAAQ,QAAQ,oBAAI,KAAqB;AAAA,IAClD,WAAW;AAAA,EAAA;AAEb,QAAM,UAAUA,UAAAA;AAAAA,IACd;AAAA,IACAC,UAAAA;AAAAA,IACA,EAAE,YAAA;AAAA,EAAY,EAEb,KAAK,CAAC,SAAS;;AACd,UAAM,8BAAc,IAAA;AACpB,eAAW,UAAU,KAAK,uBAAuB,CAAA,GAAI;AACnD,YAAM,SAAQ,YAAO,UAAP,mBAAc,OAAO;AACnC,UAAI,SAAS,OAAO,aAAa,MAAM;AACrC,gBAAQ,IAAI,OAAO,OAAO,SAAS;AAAA,MACrC;AAAA,IACF;AACA,UAAM,YAAY,KAAK,IAAA;AACvB,WAAO;AAAA,EACT,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,QAAI,qBAAqB,IAAI,QAAQ,MAAM,OAAO;AAChD,2BAAqB,OAAO,QAAQ;AAAA,IACtC;AACA,UAAM;AAAA,EACR,CAAC;AAEH,QAAM,UAAU;AAChB,uBAAqB,IAAI,UAAU,KAAK;AACxC,SAAO;AACT;AAEO,SAAS,mBACd,OACoB;AACpB,QAAM,OAAOC,WAAAA,WAAWC,wBAAc;AACtC,QAAM,kBAAkB,+BAAO,OAAO;AACtC,QAAM,YACJ,6BAAM,gBAAe,GAAG,KAAK,UAAU,IAAI,KAAK,WAAW;AAC7D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,oBAAA;AAK5CC,aAAAA,UAAU,MAAM;AACd,QAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB;AAC1C,wBAAkB,MAAS;AAC3B;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,sBAAkB,IAAI,EAAE;AAAA,MACtB,CAAC,YAAY;AACX,YAAI,CAAC,WAAW;AACd,4BAAkB,EAAE,UAAU,KAAK,QAAQ,IAAI,eAAe,GAAG;AAAA,QACnE;AAAA,MACF;AAAA,MACA,MAAM;AACJ,YAAI,CAAC,UAAW,mBAAkB,EAAE,UAAU,KAAK,QAAW;AAAA,MAChE;AAAA,IAAA;AAGF,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,eAAe,CAAC;AAEpC,MAAI,CAAC,YAAY,CAAC,kBAAkB,eAAe,aAAa,UAAU;AACxE,WAAO;AAAA,EACT;AACA,SAAO,eAAe;AACxB;;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const reactQuery = require("@tanstack/react-query");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const apiClient = require("./suggestions/data/api-client.cjs");
6
6
  const MENTION_ASSET_BATCH_SIZE = 50;
7
7
  const MENTION_ASSET_BATCH_WINDOW_MS = 16;
@@ -104,8 +104,8 @@ function loadMentionAsset({
104
104
  }
105
105
  const chipQueryClient = new reactQuery.QueryClient();
106
106
  function useMentionAsset(assetId) {
107
- const auth = react.useContext(apiClient.MentionAuthCtx);
108
- const hostQueryClient = react.useContext(reactQuery.QueryClientContext);
107
+ const auth = require$$0.useContext(apiClient.MentionAuthCtx);
108
+ const hostQueryClient = require$$0.useContext(reactQuery.QueryClientContext);
109
109
  const lookupId = mentionAssetLookupId(assetId);
110
110
  const enabled = Boolean(auth && lookupId && canAuthenticate(auth));
111
111
  const backendUrl = (auth == null ? void 0 : auth.backendUrl) ?? "";
@@ -1 +1 @@
1
- {"version":3,"file":"use-mention-asset.cjs","sources":["../../../src/chat-ui/mentions/use-mention-asset.ts"],"sourcesContent":["/**\n * The asset an asset chip names, read the way Olympus's chips read it: its\n * title and type from agora's `getAssetsByIds`, which returns only the assets\n * the caller may read (an id they cannot read is left out of the answer, as is\n * another workspace's). A chip then shows the asset's own name and icon\n * instead of whatever label and `type=` its link carried.\n *\n * Chips that mount together ask together: one GraphQL request per batch of up\n * to {@link MENTION_ASSET_BATCH_SIZE} ids, gathered over\n * {@link MENTION_ASSET_BATCH_WINDOW_MS}. Each answer is a TanStack query keyed\n * by backend, the person asking and the id, fresh for a minute, so a\n * transcript full of citations to one repository asks for it once.\n */\nimport { QueryClient, QueryClientContext, useQuery } from \"@tanstack/react-query\";\nimport { useContext } from \"react\";\nimport {\n fetchGraphQL,\n type MentionAuthContext,\n MentionAuthCtx,\n} from \"./suggestions/data/api-client\";\n\n/** What a chip draws from the asset: its current title and its type. */\nexport interface MentionAsset {\n id: string;\n title: string;\n assetType: string;\n}\n\nexport const MENTION_ASSET_BATCH_SIZE = 50;\nexport const MENTION_ASSET_BATCH_WINDOW_MS = 16;\nconst MENTION_ASSET_STALE_TIME_MS = 60_000;\n\n/** No metadata: a session's carries its token ledgers, and a chip needs a name and a type. */\nconst MENTION_ASSETS_QUERY = `\n query MentionChipAssets($assetIds: [String!]!) {\n getAssetsByIds(assetIds: $assetIds) {\n id\n title\n athenaOriginalType\n }\n }\n`;\n\ninterface MentionAssetsResponse {\n getAssetsByIds?: Array<{\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n }> | null;\n}\n\n/**\n * The ids a lookup asks about: a stored asset. A versioned id (`asset_x@3`)\n * asks about its asset. A live provider file (`asset_<catalog>_<file>`) is not\n * a row `getAssetsByIds` holds, and a session (`asset_thread_<uuid>`) is never\n * asked about: agora reads the whole row, and a session's metadata carries\n * its transcript's ledgers (megabytes on a long session) — too much for a name.\n */\nconst LOOKUP_ID = /^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function mentionAssetLookupId(assetId: string | undefined): string | null {\n const baseId = assetId?.trim().split(\"@\")[0] ?? \"\";\n return LOOKUP_ID.test(baseId) ? baseId : null;\n}\n\n/** Whether a request can carry a credential (`mentionRequestInit` refuses one that cannot). */\nfunction canAuthenticate(auth: MentionAuthContext): boolean {\n return Boolean(auth.accessToken || auth.apiKey || auth.credentials || auth.getAccessToken);\n}\n\n/** A short, stable stand-in for a credential in a cache key; never the credential itself. */\nfunction fingerprint(credential: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\n/** The scope each credential with no stable identity of its own gets: its own auth object. */\nconst authScopes = new WeakMap<MentionAuthContext, string>();\nlet authScopeCount = 0;\n\n/**\n * Who is asking, as narrowly as the credential says: what `getAssetsByIds`\n * answers differs per person and per API key, and an answer (or a batch's\n * request) is only ever shared within one scope. A person's id and an API key\n * scope the cache across token rotations. A credential that names neither (a\n * session cookie, a token callback) shares nothing beyond its own auth object\n * and its current token, so a token swapped on the same object asks again.\n */\nfunction principalOf(auth: MentionAuthContext): string {\n const scope: string[] = [];\n if (auth.userId) scope.push(`user:${auth.userId}`);\n if (auth.apiKey) scope.push(`key:${fingerprint(auth.apiKey)}`);\n if (scope.length) return scope.join(\"|\");\n let own = authScopes.get(auth);\n if (!own) {\n authScopeCount += 1;\n own = `auth:${authScopeCount}`;\n authScopes.set(auth, own);\n }\n const token = auth.accessToken;\n return token ? `${own}|token:${fingerprint(token)}` : own;\n}\n\ninterface Waiter {\n resolve: (asset: MentionAsset | null) => void;\n reject: (error: unknown) => void;\n}\n\ninterface PendingBatch {\n auth: MentionAuthContext;\n waiters: Map<string, Waiter[]>;\n}\n\n/** The batch each backend and principal is gathering, until its window closes. */\nconst pendingBatches = new Map<string, PendingBatch>();\n\nfunction settle(waiters: Waiter[] | undefined, asset: MentionAsset | null): void {\n for (const waiter of waiters ?? []) waiter.resolve(asset);\n}\n\nfunction fail(waiters: Waiter[] | undefined, error: unknown): void {\n for (const waiter of waiters ?? []) waiter.reject(error);\n}\n\nfunction sendBatch(batchKey: string): void {\n const batch = pendingBatches.get(batchKey);\n if (!batch) return;\n pendingBatches.delete(batchKey);\n const ids = [...batch.waiters.keys()];\n for (let start = 0; start < ids.length; start += MENTION_ASSET_BATCH_SIZE) {\n const chunk = ids.slice(start, start + MENTION_ASSET_BATCH_SIZE);\n fetchGraphQL<MentionAssetsResponse>(batch.auth, MENTION_ASSETS_QUERY, {\n assetIds: chunk,\n }).then(\n (data) => {\n const found = new Map((data.getAssetsByIds ?? []).map((asset) => [asset.id, asset]));\n for (const id of chunk) {\n const asset = found.get(id);\n settle(\n batch.waiters.get(id),\n asset\n ? {\n id,\n title: asset.title?.trim() ?? \"\",\n assetType: asset.athenaOriginalType?.trim() ?? \"\",\n }\n : null,\n );\n }\n },\n (error: unknown) => {\n for (const id of chunk) fail(batch.waiters.get(id), error);\n },\n );\n }\n}\n\nfunction loadMentionAsset({\n auth,\n batchKey,\n assetId,\n}: {\n auth: MentionAuthContext;\n batchKey: string;\n assetId: string;\n}): Promise<MentionAsset | null> {\n return new Promise((resolve, reject) => {\n let batch = pendingBatches.get(batchKey);\n if (!batch) {\n batch = { auth, waiters: new Map() };\n pendingBatches.set(batchKey, batch);\n setTimeout(() => sendBatch(batchKey), MENTION_ASSET_BATCH_WINDOW_MS);\n }\n const waiters = batch.waiters.get(assetId) ?? [];\n waiters.push({ resolve, reject });\n batch.waiters.set(assetId, waiters);\n });\n}\n\n/** Chips rendered outside any query client (a host's own tray) still share one cache. */\nconst chipQueryClient = new QueryClient();\n\n/**\n * The asset an asset chip names: `undefined` while unknown (no lookup, still\n * loading, or the lookup failed), `null` when agora returned no asset the\n * viewer may read under that id, else its title and type.\n */\nexport function useMentionAsset(assetId: string | undefined): MentionAsset | null | undefined {\n const auth = useContext(MentionAuthCtx);\n const hostQueryClient = useContext(QueryClientContext);\n const lookupId = mentionAssetLookupId(assetId);\n const enabled = Boolean(auth && lookupId && canAuthenticate(auth));\n const backendUrl = auth?.backendUrl ?? \"\";\n const principal = auth ? principalOf(auth) : \"\";\n const { data } = useQuery(\n {\n queryKey: [\"athena-sdk\", \"mention-asset\", backendUrl, principal, lookupId ?? \"\"],\n queryFn: () => {\n if (!auth || !lookupId) return null;\n return loadMentionAsset({\n auth,\n batchKey: `${backendUrl}|${principal}`,\n assetId: lookupId,\n });\n },\n enabled,\n staleTime: MENTION_ASSET_STALE_TIME_MS,\n // Kept no longer than it is fresh: a title is shown again only after\n // agora answers again, never from a cache a minute past its check.\n gcTime: MENTION_ASSET_STALE_TIME_MS,\n retry: false,\n refetchOnWindowFocus: false,\n },\n hostQueryClient ?? chipQueryClient,\n );\n return enabled ? data : undefined;\n}\n\nexport function resetMentionAssetsForTests(): void {\n pendingBatches.clear();\n chipQueryClient.clear();\n}\n"],"names":["fetchGraphQL","QueryClient","useContext","MentionAuthCtx","QueryClientContext","useQuery"],"mappings":"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"}
1
+ {"version":3,"file":"use-mention-asset.cjs","sources":["../../../src/chat-ui/mentions/use-mention-asset.ts"],"sourcesContent":["/**\n * The asset an asset chip names, read the way Olympus's chips read it: its\n * title and type from agora's `getAssetsByIds`, which returns only the assets\n * the caller may read (an id they cannot read is left out of the answer, as is\n * another workspace's). A chip then shows the asset's own name and icon\n * instead of whatever label and `type=` its link carried.\n *\n * Chips that mount together ask together: one GraphQL request per batch of up\n * to {@link MENTION_ASSET_BATCH_SIZE} ids, gathered over\n * {@link MENTION_ASSET_BATCH_WINDOW_MS}. Each answer is a TanStack query keyed\n * by backend, the person asking and the id, fresh for a minute, so a\n * transcript full of citations to one repository asks for it once.\n */\nimport { QueryClient, QueryClientContext, useQuery } from \"@tanstack/react-query\";\nimport { useContext } from \"react\";\nimport {\n fetchGraphQL,\n type MentionAuthContext,\n MentionAuthCtx,\n} from \"./suggestions/data/api-client\";\n\n/** What a chip draws from the asset: its current title and its type. */\nexport interface MentionAsset {\n id: string;\n title: string;\n assetType: string;\n}\n\nexport const MENTION_ASSET_BATCH_SIZE = 50;\nexport const MENTION_ASSET_BATCH_WINDOW_MS = 16;\nconst MENTION_ASSET_STALE_TIME_MS = 60_000;\n\n/** No metadata: a session's carries its token ledgers, and a chip needs a name and a type. */\nconst MENTION_ASSETS_QUERY = `\n query MentionChipAssets($assetIds: [String!]!) {\n getAssetsByIds(assetIds: $assetIds) {\n id\n title\n athenaOriginalType\n }\n }\n`;\n\ninterface MentionAssetsResponse {\n getAssetsByIds?: Array<{\n id: string;\n title: string | null;\n athenaOriginalType: string | null;\n }> | null;\n}\n\n/**\n * The ids a lookup asks about: a stored asset. A versioned id (`asset_x@3`)\n * asks about its asset. A live provider file (`asset_<catalog>_<file>`) is not\n * a row `getAssetsByIds` holds, and a session (`asset_thread_<uuid>`) is never\n * asked about: agora reads the whole row, and a session's metadata carries\n * its transcript's ledgers (megabytes on a long session) — too much for a name.\n */\nconst LOOKUP_ID = /^asset_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function mentionAssetLookupId(assetId: string | undefined): string | null {\n const baseId = assetId?.trim().split(\"@\")[0] ?? \"\";\n return LOOKUP_ID.test(baseId) ? baseId : null;\n}\n\n/** Whether a request can carry a credential (`mentionRequestInit` refuses one that cannot). */\nfunction canAuthenticate(auth: MentionAuthContext): boolean {\n return Boolean(auth.accessToken || auth.apiKey || auth.credentials || auth.getAccessToken);\n}\n\n/** A short, stable stand-in for a credential in a cache key; never the credential itself. */\nfunction fingerprint(credential: string): string {\n let hash = 0x811c9dc5;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\n/** The scope each credential with no stable identity of its own gets: its own auth object. */\nconst authScopes = new WeakMap<MentionAuthContext, string>();\nlet authScopeCount = 0;\n\n/**\n * Who is asking, as narrowly as the credential says: what `getAssetsByIds`\n * answers differs per person and per API key, and an answer (or a batch's\n * request) is only ever shared within one scope. A person's id and an API key\n * scope the cache across token rotations. A credential that names neither (a\n * session cookie, a token callback) shares nothing beyond its own auth object\n * and its current token, so a token swapped on the same object asks again.\n */\nfunction principalOf(auth: MentionAuthContext): string {\n const scope: string[] = [];\n if (auth.userId) scope.push(`user:${auth.userId}`);\n if (auth.apiKey) scope.push(`key:${fingerprint(auth.apiKey)}`);\n if (scope.length) return scope.join(\"|\");\n let own = authScopes.get(auth);\n if (!own) {\n authScopeCount += 1;\n own = `auth:${authScopeCount}`;\n authScopes.set(auth, own);\n }\n const token = auth.accessToken;\n return token ? `${own}|token:${fingerprint(token)}` : own;\n}\n\ninterface Waiter {\n resolve: (asset: MentionAsset | null) => void;\n reject: (error: unknown) => void;\n}\n\ninterface PendingBatch {\n auth: MentionAuthContext;\n waiters: Map<string, Waiter[]>;\n}\n\n/** The batch each backend and principal is gathering, until its window closes. */\nconst pendingBatches = new Map<string, PendingBatch>();\n\nfunction settle(waiters: Waiter[] | undefined, asset: MentionAsset | null): void {\n for (const waiter of waiters ?? []) waiter.resolve(asset);\n}\n\nfunction fail(waiters: Waiter[] | undefined, error: unknown): void {\n for (const waiter of waiters ?? []) waiter.reject(error);\n}\n\nfunction sendBatch(batchKey: string): void {\n const batch = pendingBatches.get(batchKey);\n if (!batch) return;\n pendingBatches.delete(batchKey);\n const ids = [...batch.waiters.keys()];\n for (let start = 0; start < ids.length; start += MENTION_ASSET_BATCH_SIZE) {\n const chunk = ids.slice(start, start + MENTION_ASSET_BATCH_SIZE);\n fetchGraphQL<MentionAssetsResponse>(batch.auth, MENTION_ASSETS_QUERY, {\n assetIds: chunk,\n }).then(\n (data) => {\n const found = new Map((data.getAssetsByIds ?? []).map((asset) => [asset.id, asset]));\n for (const id of chunk) {\n const asset = found.get(id);\n settle(\n batch.waiters.get(id),\n asset\n ? {\n id,\n title: asset.title?.trim() ?? \"\",\n assetType: asset.athenaOriginalType?.trim() ?? \"\",\n }\n : null,\n );\n }\n },\n (error: unknown) => {\n for (const id of chunk) fail(batch.waiters.get(id), error);\n },\n );\n }\n}\n\nfunction loadMentionAsset({\n auth,\n batchKey,\n assetId,\n}: {\n auth: MentionAuthContext;\n batchKey: string;\n assetId: string;\n}): Promise<MentionAsset | null> {\n return new Promise((resolve, reject) => {\n let batch = pendingBatches.get(batchKey);\n if (!batch) {\n batch = { auth, waiters: new Map() };\n pendingBatches.set(batchKey, batch);\n setTimeout(() => sendBatch(batchKey), MENTION_ASSET_BATCH_WINDOW_MS);\n }\n const waiters = batch.waiters.get(assetId) ?? [];\n waiters.push({ resolve, reject });\n batch.waiters.set(assetId, waiters);\n });\n}\n\n/** Chips rendered outside any query client (a host's own tray) still share one cache. */\nconst chipQueryClient = new QueryClient();\n\n/**\n * The asset an asset chip names: `undefined` while unknown (no lookup, still\n * loading, or the lookup failed), `null` when agora returned no asset the\n * viewer may read under that id, else its title and type.\n */\nexport function useMentionAsset(assetId: string | undefined): MentionAsset | null | undefined {\n const auth = useContext(MentionAuthCtx);\n const hostQueryClient = useContext(QueryClientContext);\n const lookupId = mentionAssetLookupId(assetId);\n const enabled = Boolean(auth && lookupId && canAuthenticate(auth));\n const backendUrl = auth?.backendUrl ?? \"\";\n const principal = auth ? principalOf(auth) : \"\";\n const { data } = useQuery(\n {\n queryKey: [\"athena-sdk\", \"mention-asset\", backendUrl, principal, lookupId ?? \"\"],\n queryFn: () => {\n if (!auth || !lookupId) return null;\n return loadMentionAsset({\n auth,\n batchKey: `${backendUrl}|${principal}`,\n assetId: lookupId,\n });\n },\n enabled,\n staleTime: MENTION_ASSET_STALE_TIME_MS,\n // Kept no longer than it is fresh: a title is shown again only after\n // agora answers again, never from a cache a minute past its check.\n gcTime: MENTION_ASSET_STALE_TIME_MS,\n retry: false,\n refetchOnWindowFocus: false,\n },\n hostQueryClient ?? chipQueryClient,\n );\n return enabled ? data : undefined;\n}\n\nexport function resetMentionAssetsForTests(): void {\n pendingBatches.clear();\n chipQueryClient.clear();\n}\n"],"names":["fetchGraphQL","QueryClient","useContext","MentionAuthCtx","QueryClientContext","useQuery"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("@assistant-ui/react");
5
+ const require$$0 = require("react");
6
+ const answerLabel = require("../../agent-runtime/src/answer-label.cjs");
7
+ const cnfast = require("cnfast");
8
+ const NO_ANSWER_LABELS = { threadShowsLabels: false, viewerUserId: null };
9
+ const AnswerLabelsContext = require$$0.createContext(NO_ANSWER_LABELS);
10
+ const AnswerLabelScope = ({ viewerUserId = null, children }) => {
11
+ const threadShowsLabels = react.useAuiState(
12
+ (state) => answerLabel.threadShowsAnswerLabels(state.thread.messages)
13
+ );
14
+ const labels = require$$0.useMemo(
15
+ () => ({ threadShowsLabels, viewerUserId }),
16
+ [threadShowsLabels, viewerUserId]
17
+ );
18
+ return /* @__PURE__ */ jsxRuntime.jsx(AnswerLabelsContext.Provider, { value: labels, children });
19
+ };
20
+ const AnswerLabel = ({ className }) => {
21
+ const message = react.useAuiState((state) => state.message);
22
+ const { threadShowsLabels, viewerUserId } = require$$0.useContext(AnswerLabelsContext);
23
+ const label = require$$0.useMemo(() => {
24
+ const answers = answerLabel.readMessageAnswers(message);
25
+ return answerLabel.showsAnswerLabel({ answers, threadShowsLabels, viewerId: viewerUserId }) ? answerLabel.answerLabelText({ answers, viewerId: viewerUserId }) : null;
26
+ }, [message, threadShowsLabels, viewerUserId]);
27
+ if (!label) return null;
28
+ return /* @__PURE__ */ jsxRuntime.jsxs(
29
+ "p",
30
+ {
31
+ "data-slot": "answer-label",
32
+ className: cnfast.cn("aui-answer-label text-muted-foreground text-xs", className),
33
+ children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Answered by " }),
35
+ label
36
+ ]
37
+ }
38
+ );
39
+ };
40
+ exports.AnswerLabel = AnswerLabel;
41
+ exports.AnswerLabelScope = AnswerLabelScope;
42
+ //# sourceMappingURL=answer-label.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer-label.cjs","sources":["../../../src/chat-ui/messages/answer-label.tsx"],"sourcesContent":["/**\n * Which agent answered and whom it worked for, above an answer (identity v7\n * D13): \"Finance · for you\". The backend stamps every answer a deep-agent\n * run's model produces (`metadata.custom.answered_by`); the reader and the\n * decision are `@athenaintel/agent-runtime`'s, shared with Olympus, so every\n * surface labels the same answers with the same words.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n answerLabelText,\n readMessageAnswers,\n showsAnswerLabel,\n threadShowsAnswerLabels,\n} from \"@athenaintel/agent-runtime\";\nimport { createContext, type FC, type ReactNode, useContext, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\ninterface AnswerLabels {\n /** The transcript's answers name several agents, or several principals they worked for. */\n threadShowsLabels: boolean;\n viewerUserId: string | null;\n}\n\nconst NO_ANSWER_LABELS: AnswerLabels = { threadShowsLabels: false, viewerUserId: null };\n\nconst AnswerLabelsContext = createContext<AnswerLabels>(NO_ANSWER_LABELS);\n\nexport interface AnswerLabelScopeProps {\n /**\n * The signed-in viewer's Athena user id (`user_…`): their own answers read\n * \"for you\", and an answer for another person is labelled even in a 1:1\n * chat. Unknown (`null`, the default), answers read \"for <their name>\" and\n * only the thread-wide rule labels them.\n */\n viewerUserId?: string | null;\n children: ReactNode;\n}\n\n/**\n * The thread-wide half of the decision, derived once per thread: once the\n * transcript's answers name two or more agents, or two or more principals,\n * every answer is labelled. It decides over the history loaded so far\n * (`threadShowsAnswerLabels`): an older page can turn the labels on, never\n * change what an answer is attributed to. Selected as a boolean (the answers\n * are cached per message object, so a streamed token rescans only its own\n * row) and published keyed on primitives, so the answers below never\n * re-render per token. `ChatThreadShell` mounts it around the messages.\n */\nexport const AnswerLabelScope: FC<AnswerLabelScopeProps> = ({ viewerUserId = null, children }) => {\n const threadShowsLabels = useAuiState((state) =>\n threadShowsAnswerLabels(state.thread.messages),\n );\n const labels = useMemo(\n (): AnswerLabels => ({ threadShowsLabels, viewerUserId }),\n [threadShowsLabels, viewerUserId],\n );\n return <AnswerLabelsContext.Provider value={labels}>{children}</AnswerLabelsContext.Provider>;\n};\n\nexport interface AnswerLabelProps {\n className?: string;\n}\n\n/**\n * Inside an assistant message: the agent that answered and whom it worked for,\n * as a small muted line. Nothing in a 1:1 chat with one's own assistant, and\n * nothing for an answer written before the backend stamped it. Reads only its\n * own message (its bound sources, where every agent that answered in a joined\n * turn is found), never the thread's list.\n */\nexport const AnswerLabel: FC<AnswerLabelProps> = ({ className }) => {\n const message = useAuiState((state) => state.message);\n const { threadShowsLabels, viewerUserId } = useContext(AnswerLabelsContext);\n const label = useMemo(() => {\n const answers = readMessageAnswers(message);\n return showsAnswerLabel({ answers, threadShowsLabels, viewerId: viewerUserId })\n ? answerLabelText({ answers, viewerId: viewerUserId })\n : null;\n }, [message, threadShowsLabels, viewerUserId]);\n if (!label) return null;\n return (\n <p\n data-slot=\"answer-label\"\n className={cn(\"aui-answer-label text-muted-foreground text-xs\", className)}\n >\n <span className=\"sr-only\">Answered by </span>\n {label}\n </p>\n );\n};\n"],"names":["createContext","useAuiState","threadShowsAnswerLabels","useMemo","useContext","readMessageAnswers","showsAnswerLabel","answerLabelText","jsxs","cn","jsx"],"mappings":";;;;;;;AAuBA,MAAM,mBAAiC,EAAE,mBAAmB,OAAO,cAAc,KAAA;AAEjF,MAAM,sBAAsBA,WAAAA,cAA4B,gBAAgB;AAuBjE,MAAM,mBAA8C,CAAC,EAAE,eAAe,MAAM,eAAe;AAChG,QAAM,oBAAoBC,MAAAA;AAAAA,IAAY,CAAC,UACrCC,YAAAA,wBAAwB,MAAM,OAAO,QAAQ;AAAA,EAAA;AAE/C,QAAM,SAASC,WAAAA;AAAAA,IACb,OAAqB,EAAE,mBAAmB;IAC1C,CAAC,mBAAmB,YAAY;AAAA,EAAA;AAElC,wCAAQ,oBAAoB,UAApB,EAA6B,OAAO,QAAS,UAAS;AAChE;AAaO,MAAM,cAAoC,CAAC,EAAE,gBAAgB;AAClE,QAAM,UAAUF,MAAAA,YAAY,CAAC,UAAU,MAAM,OAAO;AACpD,QAAM,EAAE,mBAAmB,iBAAiBG,WAAAA,WAAW,mBAAmB;AAC1E,QAAM,QAAQD,WAAAA,QAAQ,MAAM;AAC1B,UAAM,UAAUE,YAAAA,mBAAmB,OAAO;AAC1C,WAAOC,YAAAA,iBAAiB,EAAE,SAAS,mBAAmB,UAAU,aAAA,CAAc,IAC1EC,YAAAA,gBAAgB,EAAE,SAAS,UAAU,aAAA,CAAc,IACnD;AAAA,EACN,GAAG,CAAC,SAAS,mBAAmB,YAAY,CAAC;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAWC,OAAAA,GAAG,kDAAkD,SAAS;AAAA,MAEzE,UAAA;AAAA,QAAAC,2BAAAA,IAAC,QAAA,EAAK,WAAU,WAAU,UAAA,gBAAY;AAAA,QACrC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;;;"}
@@ -0,0 +1,33 @@
1
+ import { type FC, type ReactNode } from "react";
2
+ export interface AnswerLabelScopeProps {
3
+ /**
4
+ * The signed-in viewer's Athena user id (`user_…`): their own answers read
5
+ * "for you", and an answer for another person is labelled even in a 1:1
6
+ * chat. Unknown (`null`, the default), answers read "for <their name>" and
7
+ * only the thread-wide rule labels them.
8
+ */
9
+ viewerUserId?: string | null;
10
+ children: ReactNode;
11
+ }
12
+ /**
13
+ * The thread-wide half of the decision, derived once per thread: once the
14
+ * transcript's answers name two or more agents, or two or more principals,
15
+ * every answer is labelled. It decides over the history loaded so far
16
+ * (`threadShowsAnswerLabels`): an older page can turn the labels on, never
17
+ * change what an answer is attributed to. Selected as a boolean (the answers
18
+ * are cached per message object, so a streamed token rescans only its own
19
+ * row) and published keyed on primitives, so the answers below never
20
+ * re-render per token. `ChatThreadShell` mounts it around the messages.
21
+ */
22
+ export declare const AnswerLabelScope: FC<AnswerLabelScopeProps>;
23
+ export interface AnswerLabelProps {
24
+ className?: string;
25
+ }
26
+ /**
27
+ * Inside an assistant message: the agent that answered and whom it worked for,
28
+ * as a small muted line. Nothing in a 1:1 chat with one's own assistant, and
29
+ * nothing for an answer written before the backend stamped it. Reads only its
30
+ * own message (its bound sources, where every agent that answered in a joined
31
+ * turn is found), never the thread's list.
32
+ */
33
+ export declare const AnswerLabel: FC<AnswerLabelProps>;
@@ -0,0 +1,42 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useAuiState } from "@assistant-ui/react";
3
+ import { useContext, useMemo, createContext } from "react";
4
+ import { readMessageAnswers, showsAnswerLabel, answerLabelText, threadShowsAnswerLabels } from "../../agent-runtime/src/answer-label.js";
5
+ import { cn } from "cnfast";
6
+ const NO_ANSWER_LABELS = { threadShowsLabels: false, viewerUserId: null };
7
+ const AnswerLabelsContext = createContext(NO_ANSWER_LABELS);
8
+ const AnswerLabelScope = ({ viewerUserId = null, children }) => {
9
+ const threadShowsLabels = useAuiState(
10
+ (state) => threadShowsAnswerLabels(state.thread.messages)
11
+ );
12
+ const labels = useMemo(
13
+ () => ({ threadShowsLabels, viewerUserId }),
14
+ [threadShowsLabels, viewerUserId]
15
+ );
16
+ return /* @__PURE__ */ jsx(AnswerLabelsContext.Provider, { value: labels, children });
17
+ };
18
+ const AnswerLabel = ({ className }) => {
19
+ const message = useAuiState((state) => state.message);
20
+ const { threadShowsLabels, viewerUserId } = useContext(AnswerLabelsContext);
21
+ const label = useMemo(() => {
22
+ const answers = readMessageAnswers(message);
23
+ return showsAnswerLabel({ answers, threadShowsLabels, viewerId: viewerUserId }) ? answerLabelText({ answers, viewerId: viewerUserId }) : null;
24
+ }, [message, threadShowsLabels, viewerUserId]);
25
+ if (!label) return null;
26
+ return /* @__PURE__ */ jsxs(
27
+ "p",
28
+ {
29
+ "data-slot": "answer-label",
30
+ className: cn("aui-answer-label text-muted-foreground text-xs", className),
31
+ children: [
32
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Answered by " }),
33
+ label
34
+ ]
35
+ }
36
+ );
37
+ };
38
+ export {
39
+ AnswerLabel,
40
+ AnswerLabelScope
41
+ };
42
+ //# sourceMappingURL=answer-label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer-label.js","sources":["../../../src/chat-ui/messages/answer-label.tsx"],"sourcesContent":["/**\n * Which agent answered and whom it worked for, above an answer (identity v7\n * D13): \"Finance · for you\". The backend stamps every answer a deep-agent\n * run's model produces (`metadata.custom.answered_by`); the reader and the\n * decision are `@athenaintel/agent-runtime`'s, shared with Olympus, so every\n * surface labels the same answers with the same words.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n answerLabelText,\n readMessageAnswers,\n showsAnswerLabel,\n threadShowsAnswerLabels,\n} from \"@athenaintel/agent-runtime\";\nimport { createContext, type FC, type ReactNode, useContext, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\ninterface AnswerLabels {\n /** The transcript's answers name several agents, or several principals they worked for. */\n threadShowsLabels: boolean;\n viewerUserId: string | null;\n}\n\nconst NO_ANSWER_LABELS: AnswerLabels = { threadShowsLabels: false, viewerUserId: null };\n\nconst AnswerLabelsContext = createContext<AnswerLabels>(NO_ANSWER_LABELS);\n\nexport interface AnswerLabelScopeProps {\n /**\n * The signed-in viewer's Athena user id (`user_…`): their own answers read\n * \"for you\", and an answer for another person is labelled even in a 1:1\n * chat. Unknown (`null`, the default), answers read \"for <their name>\" and\n * only the thread-wide rule labels them.\n */\n viewerUserId?: string | null;\n children: ReactNode;\n}\n\n/**\n * The thread-wide half of the decision, derived once per thread: once the\n * transcript's answers name two or more agents, or two or more principals,\n * every answer is labelled. It decides over the history loaded so far\n * (`threadShowsAnswerLabels`): an older page can turn the labels on, never\n * change what an answer is attributed to. Selected as a boolean (the answers\n * are cached per message object, so a streamed token rescans only its own\n * row) and published keyed on primitives, so the answers below never\n * re-render per token. `ChatThreadShell` mounts it around the messages.\n */\nexport const AnswerLabelScope: FC<AnswerLabelScopeProps> = ({ viewerUserId = null, children }) => {\n const threadShowsLabels = useAuiState((state) =>\n threadShowsAnswerLabels(state.thread.messages),\n );\n const labels = useMemo(\n (): AnswerLabels => ({ threadShowsLabels, viewerUserId }),\n [threadShowsLabels, viewerUserId],\n );\n return <AnswerLabelsContext.Provider value={labels}>{children}</AnswerLabelsContext.Provider>;\n};\n\nexport interface AnswerLabelProps {\n className?: string;\n}\n\n/**\n * Inside an assistant message: the agent that answered and whom it worked for,\n * as a small muted line. Nothing in a 1:1 chat with one's own assistant, and\n * nothing for an answer written before the backend stamped it. Reads only its\n * own message (its bound sources, where every agent that answered in a joined\n * turn is found), never the thread's list.\n */\nexport const AnswerLabel: FC<AnswerLabelProps> = ({ className }) => {\n const message = useAuiState((state) => state.message);\n const { threadShowsLabels, viewerUserId } = useContext(AnswerLabelsContext);\n const label = useMemo(() => {\n const answers = readMessageAnswers(message);\n return showsAnswerLabel({ answers, threadShowsLabels, viewerId: viewerUserId })\n ? answerLabelText({ answers, viewerId: viewerUserId })\n : null;\n }, [message, threadShowsLabels, viewerUserId]);\n if (!label) return null;\n return (\n <p\n data-slot=\"answer-label\"\n className={cn(\"aui-answer-label text-muted-foreground text-xs\", className)}\n >\n <span className=\"sr-only\">Answered by </span>\n {label}\n </p>\n );\n};\n"],"names":[],"mappings":";;;;;AAuBA,MAAM,mBAAiC,EAAE,mBAAmB,OAAO,cAAc,KAAA;AAEjF,MAAM,sBAAsB,cAA4B,gBAAgB;AAuBjE,MAAM,mBAA8C,CAAC,EAAE,eAAe,MAAM,eAAe;AAChG,QAAM,oBAAoB;AAAA,IAAY,CAAC,UACrC,wBAAwB,MAAM,OAAO,QAAQ;AAAA,EAAA;AAE/C,QAAM,SAAS;AAAA,IACb,OAAqB,EAAE,mBAAmB;IAC1C,CAAC,mBAAmB,YAAY;AAAA,EAAA;AAElC,6BAAQ,oBAAoB,UAApB,EAA6B,OAAO,QAAS,UAAS;AAChE;AAaO,MAAM,cAAoC,CAAC,EAAE,gBAAgB;AAClE,QAAM,UAAU,YAAY,CAAC,UAAU,MAAM,OAAO;AACpD,QAAM,EAAE,mBAAmB,iBAAiB,WAAW,mBAAmB;AAC1E,QAAM,QAAQ,QAAQ,MAAM;AAC1B,UAAM,UAAU,mBAAmB,OAAO;AAC1C,WAAO,iBAAiB,EAAE,SAAS,mBAAmB,UAAU,aAAA,CAAc,IAC1E,gBAAgB,EAAE,SAAS,UAAU,aAAA,CAAc,IACnD;AAAA,EACN,GAAG,CAAC,SAAS,mBAAmB,YAAY,CAAC;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,kDAAkD,SAAS;AAAA,MAEzE,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,WAAU,UAAA,gBAAY;AAAA,QACrC;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react = require("@assistant-ui/react");
4
+ const require$$0 = require("react");
5
+ const MESSAGE_ARRIVAL_ANIMATION_CLASS = "animate-in fade-in slide-in-from-bottom-1 duration-150 motion-reduce:animate-none";
6
+ function useMessageArrivalAnimation() {
7
+ const arrivingLive = react.useAuiState((s) => s.message.isLast && s.thread.isRunning);
8
+ const [arrivedLive] = require$$0.useState(arrivingLive);
9
+ return arrivedLive;
10
+ }
11
+ exports.MESSAGE_ARRIVAL_ANIMATION_CLASS = MESSAGE_ARRIVAL_ANIMATION_CLASS;
12
+ exports.useMessageArrivalAnimation = useMessageArrivalAnimation;
13
+ //# sourceMappingURL=arrival-animation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrival-animation.cjs","sources":["../../../src/chat-ui/messages/arrival-animation.ts"],"sourcesContent":["import { useAuiState } from \"@assistant-ui/react\";\nimport { useState } from \"react\";\n\n/** A message row's entrance: a short fade with a 4px rise. */\nexport const MESSAGE_ARRIVAL_ANIMATION_CLASS =\n \"animate-in fade-in slide-in-from-bottom-1 duration-150 motion-reduce:animate-none\";\n\n/**\n * Whether a message row plays its entrance animation: only a row that mounted\n * as the thread's newest message while a run was live, which is how a message\n * the person is watching arrives (their own send, the turn that answers it).\n *\n * Everything else renders still: the rows of a thread as it opens, and every\n * row a page of older history mounts above the newest one, so scrolling back\n * through a long session never flashes. Decided once, when the row mounts\n * (as Olympus's `useEntranceOnMount` does for its cards): a row neither\n * starts animating when a later run begins nor loses the entrance it had.\n */\nexport function useMessageArrivalAnimation(): boolean {\n const arrivingLive = useAuiState((s) => s.message.isLast && s.thread.isRunning);\n const [arrivedLive] = useState(arrivingLive);\n return arrivedLive;\n}\n"],"names":["useAuiState","useState"],"mappings":";;;;AAIO,MAAM,kCACX;AAaK,SAAS,6BAAsC;AACpD,QAAM,eAAeA,kBAAY,CAAC,MAAM,EAAE,QAAQ,UAAU,EAAE,OAAO,SAAS;AAC9E,QAAM,CAAC,WAAW,IAAIC,WAAAA,SAAS,YAAY;AAC3C,SAAO;AACT;;;"}
@@ -0,0 +1,14 @@
1
+ /** A message row's entrance: a short fade with a 4px rise. */
2
+ export declare const MESSAGE_ARRIVAL_ANIMATION_CLASS = "animate-in fade-in slide-in-from-bottom-1 duration-150 motion-reduce:animate-none";
3
+ /**
4
+ * Whether a message row plays its entrance animation: only a row that mounted
5
+ * as the thread's newest message while a run was live, which is how a message
6
+ * the person is watching arrives (their own send, the turn that answers it).
7
+ *
8
+ * Everything else renders still: the rows of a thread as it opens, and every
9
+ * row a page of older history mounts above the newest one, so scrolling back
10
+ * through a long session never flashes. Decided once, when the row mounts
11
+ * (as Olympus's `useEntranceOnMount` does for its cards): a row neither
12
+ * starts animating when a later run begins nor loses the entrance it had.
13
+ */
14
+ export declare function useMessageArrivalAnimation(): boolean;
@@ -0,0 +1,13 @@
1
+ import { useAuiState } from "@assistant-ui/react";
2
+ import { useState } from "react";
3
+ const MESSAGE_ARRIVAL_ANIMATION_CLASS = "animate-in fade-in slide-in-from-bottom-1 duration-150 motion-reduce:animate-none";
4
+ function useMessageArrivalAnimation() {
5
+ const arrivingLive = useAuiState((s) => s.message.isLast && s.thread.isRunning);
6
+ const [arrivedLive] = useState(arrivingLive);
7
+ return arrivedLive;
8
+ }
9
+ export {
10
+ MESSAGE_ARRIVAL_ANIMATION_CLASS,
11
+ useMessageArrivalAnimation
12
+ };
13
+ //# sourceMappingURL=arrival-animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrival-animation.js","sources":["../../../src/chat-ui/messages/arrival-animation.ts"],"sourcesContent":["import { useAuiState } from \"@assistant-ui/react\";\nimport { useState } from \"react\";\n\n/** A message row's entrance: a short fade with a 4px rise. */\nexport const MESSAGE_ARRIVAL_ANIMATION_CLASS =\n \"animate-in fade-in slide-in-from-bottom-1 duration-150 motion-reduce:animate-none\";\n\n/**\n * Whether a message row plays its entrance animation: only a row that mounted\n * as the thread's newest message while a run was live, which is how a message\n * the person is watching arrives (their own send, the turn that answers it).\n *\n * Everything else renders still: the rows of a thread as it opens, and every\n * row a page of older history mounts above the newest one, so scrolling back\n * through a long session never flashes. Decided once, when the row mounts\n * (as Olympus's `useEntranceOnMount` does for its cards): a row neither\n * starts animating when a later run begins nor loses the entrance it had.\n */\nexport function useMessageArrivalAnimation(): boolean {\n const arrivingLive = useAuiState((s) => s.message.isLast && s.thread.isRunning);\n const [arrivedLive] = useState(arrivingLive);\n return arrivedLive;\n}\n"],"names":[],"mappings":";;AAIO,MAAM,kCACX;AAaK,SAAS,6BAAsC;AACpD,QAAM,eAAe,YAAY,CAAC,MAAM,EAAE,QAAQ,UAAU,EAAE,OAAO,SAAS;AAC9E,QAAM,CAAC,WAAW,IAAI,SAAS,YAAY;AAC3C,SAAO;AACT;"}
@@ -2,16 +2,16 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const lucideReact = require("lucide-react");
5
- const react = require("react");
5
+ const require$$0 = require("react");
6
6
  const cnfast = require("cnfast");
7
7
  const EXIT_ANIMATION_MS = 200;
8
8
  const EXIT_RESET_MS = 2500;
9
9
  const ContinuePill = ({ onClick, ariaLabel, dataTestId }) => {
10
- const [isExiting, setIsExiting] = react.useState(false);
11
- const onClickRef = react.useRef(onClick);
12
- const pendingOnClickRef = react.useRef(onClick);
10
+ const [isExiting, setIsExiting] = require$$0.useState(false);
11
+ const onClickRef = require$$0.useRef(onClick);
12
+ const pendingOnClickRef = require$$0.useRef(onClick);
13
13
  onClickRef.current = onClick;
14
- react.useEffect(() => {
14
+ require$$0.useEffect(() => {
15
15
  if (!isExiting) return;
16
16
  const dispatchTimer = setTimeout(
17
17
  () => pendingOnClickRef.current(),
@@ -1 +1 @@
1
- {"version":3,"file":"continue-pill.cjs","sources":["../../../src/chat-ui/messages/continue-pill.tsx"],"sourcesContent":["import { Play } from \"lucide-react\";\nimport { type FC, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nconst EXIT_ANIMATION_MS = 200;\nconst EXIT_RESET_MS = 2500;\n\n/**\n * Shared Continue action for recoverable chat states.\n *\n * The dispatch waits for the exit animation to paint. If the owning runtime\n * does not leave the recoverable state (for example, the command is rejected),\n * the control resets so the user can try again.\n */\nexport const ContinuePill: FC<{\n onClick: () => void;\n ariaLabel: string;\n dataTestId?: string;\n}> = ({ onClick, ariaLabel, dataTestId }) => {\n const [isExiting, setIsExiting] = useState(false);\n const onClickRef = useRef(onClick);\n const pendingOnClickRef = useRef(onClick);\n onClickRef.current = onClick;\n\n useEffect(() => {\n if (!isExiting) return;\n const dispatchTimer = setTimeout(\n () => pendingOnClickRef.current(),\n EXIT_ANIMATION_MS,\n );\n const resetTimer = setTimeout(() => setIsExiting(false), EXIT_RESET_MS);\n return () => {\n clearTimeout(dispatchTimer);\n clearTimeout(resetTimer);\n };\n }, [isExiting]);\n\n const handleClick = (): void => {\n if (isExiting) return;\n pendingOnClickRef.current = onClickRef.current;\n setIsExiting(true);\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isExiting}\n className={cn(\n \"group inline-flex items-center gap-1.5 rounded-full bg-primary px-3.5 py-1 text-xs font-medium text-primary-foreground shadow-sm\",\n \"transition-all duration-200 ease-out\",\n \"hover:bg-primary/90 hover:shadow-md active:scale-95\",\n \"animate-in fade-in slide-in-from-bottom-1\",\n isExiting && \"pointer-events-none scale-90 opacity-0\",\n )}\n aria-label={ariaLabel}\n data-testid={dataTestId}\n >\n <Play className=\"size-3 fill-current transition-transform duration-200 ease-out group-hover:translate-x-0.5\" />\n <span>Continue</span>\n </button>\n );\n};\n"],"names":["useState","useRef","useEffect","jsxs","cn","jsx","Play"],"mappings":";;;;;;AAIA,MAAM,oBAAoB;AAC1B,MAAM,gBAAgB;AASf,MAAM,eAIR,CAAC,EAAE,SAAS,WAAW,iBAAiB;AAC3C,QAAM,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,KAAK;AAChD,QAAM,aAAaC,MAAAA,OAAO,OAAO;AACjC,QAAM,oBAAoBA,MAAAA,OAAO,OAAO;AACxC,aAAW,UAAU;AAErBC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAChB,UAAM,gBAAgB;AAAA,MACpB,MAAM,kBAAkB,QAAA;AAAA,MACxB;AAAA,IAAA;AAEF,UAAM,aAAa,WAAW,MAAM,aAAa,KAAK,GAAG,aAAa;AACtE,WAAO,MAAM;AACX,mBAAa,aAAa;AAC1B,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,cAAc,MAAY;AAC9B,QAAI,UAAW;AACf,sBAAkB,UAAU,WAAW;AACvC,iBAAa,IAAI;AAAA,EACnB;AAEA,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAWC,OAAAA;AAAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MAAA;AAAA,MAEf,cAAY;AAAA,MACZ,eAAa;AAAA,MAEb,UAAA;AAAA,QAAAC,2BAAAA,IAACC,YAAAA,MAAA,EAAK,WAAU,6FAAA,CAA6F;AAAA,QAC7GD,2BAAAA,IAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpB;;"}
1
+ {"version":3,"file":"continue-pill.cjs","sources":["../../../src/chat-ui/messages/continue-pill.tsx"],"sourcesContent":["import { Play } from \"lucide-react\";\nimport { type FC, useEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nconst EXIT_ANIMATION_MS = 200;\nconst EXIT_RESET_MS = 2500;\n\n/**\n * Shared Continue action for recoverable chat states.\n *\n * The dispatch waits for the exit animation to paint. If the owning runtime\n * does not leave the recoverable state (for example, the command is rejected),\n * the control resets so the user can try again.\n */\nexport const ContinuePill: FC<{\n onClick: () => void;\n ariaLabel: string;\n dataTestId?: string;\n}> = ({ onClick, ariaLabel, dataTestId }) => {\n const [isExiting, setIsExiting] = useState(false);\n const onClickRef = useRef(onClick);\n const pendingOnClickRef = useRef(onClick);\n onClickRef.current = onClick;\n\n useEffect(() => {\n if (!isExiting) return;\n const dispatchTimer = setTimeout(\n () => pendingOnClickRef.current(),\n EXIT_ANIMATION_MS,\n );\n const resetTimer = setTimeout(() => setIsExiting(false), EXIT_RESET_MS);\n return () => {\n clearTimeout(dispatchTimer);\n clearTimeout(resetTimer);\n };\n }, [isExiting]);\n\n const handleClick = (): void => {\n if (isExiting) return;\n pendingOnClickRef.current = onClickRef.current;\n setIsExiting(true);\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isExiting}\n className={cn(\n \"group inline-flex items-center gap-1.5 rounded-full bg-primary px-3.5 py-1 text-xs font-medium text-primary-foreground shadow-sm\",\n \"transition-all duration-200 ease-out\",\n \"hover:bg-primary/90 hover:shadow-md active:scale-95\",\n \"animate-in fade-in slide-in-from-bottom-1\",\n isExiting && \"pointer-events-none scale-90 opacity-0\",\n )}\n aria-label={ariaLabel}\n data-testid={dataTestId}\n >\n <Play className=\"size-3 fill-current transition-transform duration-200 ease-out group-hover:translate-x-0.5\" />\n <span>Continue</span>\n </button>\n );\n};\n"],"names":["useState","useRef","useEffect","jsxs","cn","jsx","Play"],"mappings":";;;;;;AAIA,MAAM,oBAAoB;AAC1B,MAAM,gBAAgB;AASf,MAAM,eAIR,CAAC,EAAE,SAAS,WAAW,iBAAiB;AAC3C,QAAM,CAAC,WAAW,YAAY,IAAIA,WAAAA,SAAS,KAAK;AAChD,QAAM,aAAaC,WAAAA,OAAO,OAAO;AACjC,QAAM,oBAAoBA,WAAAA,OAAO,OAAO;AACxC,aAAW,UAAU;AAErBC,aAAAA,UAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAChB,UAAM,gBAAgB;AAAA,MACpB,MAAM,kBAAkB,QAAA;AAAA,MACxB;AAAA,IAAA;AAEF,UAAM,aAAa,WAAW,MAAM,aAAa,KAAK,GAAG,aAAa;AACtE,WAAO,MAAM;AACX,mBAAa,aAAa;AAC1B,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,cAAc,MAAY;AAC9B,QAAI,UAAW;AACf,sBAAkB,UAAU,WAAW;AACvC,iBAAa,IAAI;AAAA,EACnB;AAEA,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAWC,OAAAA;AAAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MAAA;AAAA,MAEf,cAAY;AAAA,MACZ,eAAa;AAAA,MAEb,UAAA;AAAA,QAAAC,2BAAAA,IAACC,YAAAA,MAAA,EAAK,WAAU,6FAAA,CAA6F;AAAA,QAC7GD,2BAAAA,IAAC,UAAK,UAAA,WAAA,CAAQ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpB;;"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("@assistant-ui/react");
5
+ const handoffArrival = require("../../agent-runtime/src/handoff-arrival.cjs");
6
+ const cnfast = require("cnfast");
7
+ const HandoffArrivalDivider = ({
8
+ label,
9
+ className,
10
+ ...rest
11
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
12
+ "div",
13
+ {
14
+ ...rest,
15
+ "data-testid": "handoff-arrival-divider",
16
+ className: cnfast.cn(
17
+ "my-3 flex w-full items-center gap-3 text-muted-foreground text-xs",
18
+ className
19
+ ),
20
+ children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "h-px flex-1 bg-border" }),
22
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: label }),
23
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "h-px flex-1 bg-border" })
24
+ ]
25
+ }
26
+ );
27
+ const HandoffArrivalScope = ({ threadId, children }) => {
28
+ const lastMessageId = react.useAuiState((state) => {
29
+ var _a;
30
+ return ((_a = state.thread.messages.at(-1)) == null ? void 0 : _a.id) ?? null;
31
+ });
32
+ const loading = react.useAuiState((state) => state.thread.isLoading);
33
+ const arrival = handoffArrival.useHandoffArrival({ threadId, lastMessageId, loading });
34
+ return /* @__PURE__ */ jsxRuntime.jsx(handoffArrival.HandoffArrivalContext.Provider, { value: arrival, children });
35
+ };
36
+ const HandoffArrivalAfterMessage = () => {
37
+ const messageId = react.useAuiState((state) => state.message.id);
38
+ const label = handoffArrival.useHandoffArrivalAfter(messageId);
39
+ return label ? /* @__PURE__ */ jsxRuntime.jsx(HandoffArrivalDivider, { label }) : null;
40
+ };
41
+ exports.HandoffArrivalAfterMessage = HandoffArrivalAfterMessage;
42
+ exports.HandoffArrivalDivider = HandoffArrivalDivider;
43
+ exports.HandoffArrivalScope = HandoffArrivalScope;
44
+ //# sourceMappingURL=handoff-arrival-divider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff-arrival-divider.cjs","sources":["../../../src/chat-ui/messages/handoff-arrival-divider.tsx"],"sourcesContent":["/**\n * The transcript divider a surface shows where a handed-off conversation\n * arrived (\"Continued from your phone\"), after the last message that was\n * already there. The arrival itself is `@athenaintel/agent-runtime`'s\n * `handoff-arrival`: ephemeral, client-side, recorded when a pick-up lands.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n HandoffArrivalContext,\n useHandoffArrival,\n useHandoffArrivalAfter,\n} from \"@athenaintel/agent-runtime\";\nimport type { ComponentPropsWithoutRef, FC, ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface HandoffArrivalDividerProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** \"Continued from your phone\". */\n label: string;\n}\n\n/** A hairline either side of the label, which reads as plain text: pure presenter. */\nexport const HandoffArrivalDivider: FC<HandoffArrivalDividerProps> = ({\n label,\n className,\n ...rest\n}) => (\n <div\n {...rest}\n data-testid=\"handoff-arrival-divider\"\n className={cn(\n \"my-3 flex w-full items-center gap-3 text-muted-foreground text-xs\",\n className,\n )}\n >\n <span aria-hidden=\"true\" className=\"h-px flex-1 bg-border\" />\n <span className=\"shrink-0\">{label}</span>\n <span aria-hidden=\"true\" className=\"h-px flex-1 bg-border\" />\n </div>\n);\n\n/**\n * Anchors the arrival of `threadId` (if any) to the thread's last message once\n * its history has loaded, and gives the messages below it that anchor.\n */\nexport const HandoffArrivalScope: FC<{\n threadId: string | null | undefined;\n children: ReactNode;\n}> = ({ threadId, children }) => {\n const lastMessageId = useAuiState((state) => state.thread.messages.at(-1)?.id ?? null);\n const loading = useAuiState((state) => state.thread.isLoading);\n const arrival = useHandoffArrival({ threadId, lastMessageId, loading });\n return (\n <HandoffArrivalContext.Provider value={arrival}>{children}</HandoffArrivalContext.Provider>\n );\n};\n\n/** Inside a message: the divider when the conversation arrived right after it. */\nexport const HandoffArrivalAfterMessage: FC = () => {\n const messageId = useAuiState((state) => state.message.id);\n const label = useHandoffArrivalAfter(messageId);\n return label ? <HandoffArrivalDivider label={label} /> : null;\n};\n"],"names":["jsxs","cn","jsx","useAuiState","useHandoffArrival","HandoffArrivalContext","useHandoffArrivalAfter"],"mappings":";;;;;;AAsBO,MAAM,wBAAwD,CAAC;AAAA,EACpE;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACEA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACE,GAAG;AAAA,IACJ,eAAY;AAAA,IACZ,WAAWC,OAAAA;AAAAA,MACT;AAAA,MACA;AAAA,IAAA;AAAA,IAGF,UAAA;AAAA,MAAAC,2BAAAA,IAAC,QAAA,EAAK,eAAY,QAAO,WAAU,yBAAwB;AAAA,MAC3DA,2BAAAA,IAAC,QAAA,EAAK,WAAU,YAAY,UAAA,OAAM;AAAA,MAClCA,2BAAAA,IAAC,QAAA,EAAK,eAAY,QAAO,WAAU,wBAAA,CAAwB;AAAA,IAAA;AAAA,EAAA;AAC7D;AAOK,MAAM,sBAGR,CAAC,EAAE,UAAU,eAAe;AAC/B,QAAM,gBAAgBC,MAAAA,YAAY,CAAC,UAAA;;AAAU,wBAAM,OAAO,SAAS,GAAG,EAAE,MAA3B,mBAA8B,OAAM;AAAA,GAAI;AACrF,QAAM,UAAUA,MAAAA,YAAY,CAAC,UAAU,MAAM,OAAO,SAAS;AAC7D,QAAM,UAAUC,eAAAA,kBAAkB,EAAE,UAAU,eAAe,SAAS;AACtE,wCACGC,eAAAA,sBAAsB,UAAtB,EAA+B,OAAO,SAAU,UAAS;AAE9D;AAGO,MAAM,6BAAiC,MAAM;AAClD,QAAM,YAAYF,MAAAA,YAAY,CAAC,UAAU,MAAM,QAAQ,EAAE;AACzD,QAAM,QAAQG,eAAAA,uBAAuB,SAAS;AAC9C,SAAO,QAAQJ,2BAAAA,IAAC,uBAAA,EAAsB,MAAA,CAAc,IAAK;AAC3D;;;;"}
@@ -0,0 +1,17 @@
1
+ import type { ComponentPropsWithoutRef, FC, ReactNode } from "react";
2
+ export interface HandoffArrivalDividerProps extends Omit<ComponentPropsWithoutRef<"div">, "children"> {
3
+ /** "Continued from your phone". */
4
+ label: string;
5
+ }
6
+ /** A hairline either side of the label, which reads as plain text: pure presenter. */
7
+ export declare const HandoffArrivalDivider: FC<HandoffArrivalDividerProps>;
8
+ /**
9
+ * Anchors the arrival of `threadId` (if any) to the thread's last message once
10
+ * its history has loaded, and gives the messages below it that anchor.
11
+ */
12
+ export declare const HandoffArrivalScope: FC<{
13
+ threadId: string | null | undefined;
14
+ children: ReactNode;
15
+ }>;
16
+ /** Inside a message: the divider when the conversation arrived right after it. */
17
+ export declare const HandoffArrivalAfterMessage: FC;
@@ -0,0 +1,44 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useAuiState } from "@assistant-ui/react";
3
+ import { useHandoffArrivalAfter, useHandoffArrival, HandoffArrivalContext } from "../../agent-runtime/src/handoff-arrival.js";
4
+ import { cn } from "cnfast";
5
+ const HandoffArrivalDivider = ({
6
+ label,
7
+ className,
8
+ ...rest
9
+ }) => /* @__PURE__ */ jsxs(
10
+ "div",
11
+ {
12
+ ...rest,
13
+ "data-testid": "handoff-arrival-divider",
14
+ className: cn(
15
+ "my-3 flex w-full items-center gap-3 text-muted-foreground text-xs",
16
+ className
17
+ ),
18
+ children: [
19
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-px flex-1 bg-border" }),
20
+ /* @__PURE__ */ jsx("span", { className: "shrink-0", children: label }),
21
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-px flex-1 bg-border" })
22
+ ]
23
+ }
24
+ );
25
+ const HandoffArrivalScope = ({ threadId, children }) => {
26
+ const lastMessageId = useAuiState((state) => {
27
+ var _a;
28
+ return ((_a = state.thread.messages.at(-1)) == null ? void 0 : _a.id) ?? null;
29
+ });
30
+ const loading = useAuiState((state) => state.thread.isLoading);
31
+ const arrival = useHandoffArrival({ threadId, lastMessageId, loading });
32
+ return /* @__PURE__ */ jsx(HandoffArrivalContext.Provider, { value: arrival, children });
33
+ };
34
+ const HandoffArrivalAfterMessage = () => {
35
+ const messageId = useAuiState((state) => state.message.id);
36
+ const label = useHandoffArrivalAfter(messageId);
37
+ return label ? /* @__PURE__ */ jsx(HandoffArrivalDivider, { label }) : null;
38
+ };
39
+ export {
40
+ HandoffArrivalAfterMessage,
41
+ HandoffArrivalDivider,
42
+ HandoffArrivalScope
43
+ };
44
+ //# sourceMappingURL=handoff-arrival-divider.js.map