@athenaintel/react 0.43.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (746) hide show
  1. package/README.md +258 -8
  2. package/dist/agent-runtime/src/answer-label.cjs +137 -0
  3. package/dist/agent-runtime/src/answer-label.cjs.map +1 -0
  4. package/dist/agent-runtime/src/answer-label.d.ts +104 -0
  5. package/dist/agent-runtime/src/answer-label.js +137 -0
  6. package/dist/agent-runtime/src/answer-label.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-rows.cjs +180 -0
  8. package/dist/agent-runtime/src/answer-rows.cjs.map +1 -0
  9. package/dist/agent-runtime/src/answer-rows.d.ts +86 -0
  10. package/dist/agent-runtime/src/answer-rows.js +180 -0
  11. package/dist/agent-runtime/src/answer-rows.js.map +1 -0
  12. package/dist/agent-runtime/src/call-recap.cjs +319 -0
  13. package/dist/agent-runtime/src/call-recap.cjs.map +1 -0
  14. package/dist/agent-runtime/src/call-recap.d.ts +142 -0
  15. package/dist/agent-runtime/src/call-recap.js +319 -0
  16. package/dist/agent-runtime/src/call-recap.js.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-store.cjs +1 -0
  18. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +1 -1
  19. package/dist/agent-runtime/src/chat-outbox-store.d.ts +7 -0
  20. package/dist/agent-runtime/src/chat-outbox-store.js +1 -0
  21. package/dist/agent-runtime/src/chat-outbox-store.js.map +1 -1
  22. package/dist/agent-runtime/src/chat-outbox.cjs +46 -5
  23. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
  24. package/dist/agent-runtime/src/chat-outbox.d.ts +29 -0
  25. package/dist/agent-runtime/src/chat-outbox.js +46 -5
  26. package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
  27. package/dist/agent-runtime/src/client-tool-bridge.cjs +15 -15
  28. package/dist/agent-runtime/src/client-tool-bridge.cjs.map +1 -1
  29. package/dist/agent-runtime/src/conversation-index.cjs +8 -8
  30. package/dist/agent-runtime/src/conversation-index.cjs.map +1 -1
  31. package/dist/agent-runtime/src/conversation-index.d.ts +7 -0
  32. package/dist/agent-runtime/src/conversation-index.js.map +1 -1
  33. package/dist/agent-runtime/src/conversation-list.cjs +2 -1
  34. package/dist/agent-runtime/src/conversation-list.cjs.map +1 -1
  35. package/dist/agent-runtime/src/conversation-list.d.ts +19 -3
  36. package/dist/agent-runtime/src/conversation-list.js +2 -1
  37. package/dist/agent-runtime/src/conversation-list.js.map +1 -1
  38. package/dist/agent-runtime/src/decision-checks.cjs +207 -0
  39. package/dist/agent-runtime/src/decision-checks.cjs.map +1 -0
  40. package/dist/agent-runtime/src/decision-checks.d.ts +142 -0
  41. package/dist/agent-runtime/src/decision-checks.js +207 -0
  42. package/dist/agent-runtime/src/decision-checks.js.map +1 -0
  43. package/dist/agent-runtime/src/desktop-handoff.d.ts +12 -0
  44. package/dist/agent-runtime/src/errors.cjs +18 -0
  45. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  46. package/dist/agent-runtime/src/errors.d.ts +7 -0
  47. package/dist/agent-runtime/src/errors.js +18 -0
  48. package/dist/agent-runtime/src/errors.js.map +1 -1
  49. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +12 -0
  50. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  51. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +6 -6
  52. package/dist/agent-runtime/src/generated/runconfig-contract.js +12 -0
  53. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  54. package/dist/agent-runtime/src/handoff-arrival.cjs +60 -0
  55. package/dist/agent-runtime/src/handoff-arrival.cjs.map +1 -0
  56. package/dist/agent-runtime/src/handoff-arrival.d.ts +46 -0
  57. package/dist/agent-runtime/src/handoff-arrival.js +60 -0
  58. package/dist/agent-runtime/src/handoff-arrival.js.map +1 -0
  59. package/dist/agent-runtime/src/index.d.ts +16 -9
  60. package/dist/agent-runtime/src/interrupts.cjs +71 -19
  61. package/dist/agent-runtime/src/interrupts.cjs.map +1 -1
  62. package/dist/agent-runtime/src/interrupts.d.ts +40 -3
  63. package/dist/agent-runtime/src/interrupts.js +56 -4
  64. package/dist/agent-runtime/src/interrupts.js.map +1 -1
  65. package/dist/agent-runtime/src/lane-history.cjs +8 -8
  66. package/dist/agent-runtime/src/lane-history.cjs.map +1 -1
  67. package/dist/agent-runtime/src/messages.cjs +43 -8
  68. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  69. package/dist/agent-runtime/src/messages.d.ts +25 -3
  70. package/dist/agent-runtime/src/messages.js +43 -8
  71. package/dist/agent-runtime/src/messages.js.map +1 -1
  72. package/dist/agent-runtime/src/model-context.cjs +3 -2
  73. package/dist/agent-runtime/src/model-context.cjs.map +1 -1
  74. package/dist/agent-runtime/src/model-context.d.ts +6 -1
  75. package/dist/agent-runtime/src/model-context.js +3 -2
  76. package/dist/agent-runtime/src/model-context.js.map +1 -1
  77. package/dist/agent-runtime/src/offline-status.cjs +36 -0
  78. package/dist/agent-runtime/src/offline-status.cjs.map +1 -0
  79. package/dist/agent-runtime/src/offline-status.d.ts +118 -3
  80. package/dist/agent-runtime/src/offline-status.js +36 -0
  81. package/dist/agent-runtime/src/offline-status.js.map +1 -0
  82. package/dist/agent-runtime/src/queue.cjs +0 -9
  83. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  84. package/dist/agent-runtime/src/queue.js +0 -9
  85. package/dist/agent-runtime/src/queue.js.map +1 -1
  86. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +9 -9
  87. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  88. package/dist/agent-runtime/src/runtime-catalog.cjs +42 -0
  89. package/dist/agent-runtime/src/runtime-catalog.cjs.map +1 -0
  90. package/dist/agent-runtime/src/runtime-catalog.d.ts +35 -0
  91. package/dist/agent-runtime/src/runtime-catalog.js +42 -0
  92. package/dist/agent-runtime/src/runtime-catalog.js.map +1 -0
  93. package/dist/agent-runtime/src/runtime-messages.cjs.map +1 -1
  94. package/dist/agent-runtime/src/runtime-messages.d.ts +1 -1
  95. package/dist/agent-runtime/src/runtime-messages.js.map +1 -1
  96. package/dist/agent-runtime/src/runtime.d.ts +41 -0
  97. package/dist/agent-runtime/src/send-recovery.cjs +37 -3
  98. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  99. package/dist/agent-runtime/src/send-recovery.d.ts +19 -0
  100. package/dist/agent-runtime/src/send-recovery.js +37 -3
  101. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  102. package/dist/agent-runtime/src/statewire-suspended.cjs +3 -3
  103. package/dist/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  104. package/dist/agent-runtime/src/subagents.cjs +32 -2
  105. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  106. package/dist/agent-runtime/src/subagents.d.ts +9 -0
  107. package/dist/agent-runtime/src/subagents.js +30 -0
  108. package/dist/agent-runtime/src/subagents.js.map +1 -1
  109. package/dist/agent-runtime/src/thread-driver.cjs +67 -0
  110. package/dist/agent-runtime/src/thread-driver.cjs.map +1 -0
  111. package/dist/agent-runtime/src/thread-driver.d.ts +49 -0
  112. package/dist/agent-runtime/src/thread-driver.js +67 -0
  113. package/dist/agent-runtime/src/thread-driver.js.map +1 -0
  114. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +172 -0
  115. package/dist/agent-runtime/src/thread-handoff-protocol.d.ts +868 -0
  116. package/dist/agent-runtime/src/thread-handoff-qr.d.ts +11 -0
  117. package/dist/agent-runtime/src/thread-handoff.d.ts +3 -364
  118. package/dist/agent-runtime/src/thread-status.cjs +3 -3
  119. package/dist/agent-runtime/src/thread-status.cjs.map +1 -1
  120. package/dist/agent-runtime/src/tool-metadata.cjs +210 -25
  121. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  122. package/dist/agent-runtime/src/tool-metadata.d.ts +12 -0
  123. package/dist/agent-runtime/src/tool-metadata.js +210 -25
  124. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  125. package/dist/agent-runtime/src/tool-names.cjs +2 -0
  126. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  127. package/dist/agent-runtime/src/tool-names.d.ts +2 -0
  128. package/dist/agent-runtime/src/tool-names.js +2 -0
  129. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  130. package/dist/agent-runtime/src/types.d.ts +10 -2
  131. package/dist/agent-runtime/src/use-conversation-list.cjs +14 -13
  132. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  133. package/dist/agent-runtime/src/use-conversation-list.d.ts +6 -0
  134. package/dist/agent-runtime/src/use-conversation-list.js +3 -2
  135. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  136. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +45 -20
  137. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  138. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +10 -3
  139. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +27 -2
  140. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  141. package/dist/agent-runtime/src/use-deep-agent-config.cjs +14 -14
  142. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  143. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs +6 -6
  144. package/dist/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  145. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +40 -22
  146. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  147. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +17 -0
  148. package/dist/agent-runtime/src/use-deep-agent-runtime.js +24 -6
  149. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  150. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +45 -45
  151. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  152. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +588 -130
  153. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  154. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +162 -10
  155. package/dist/agent-runtime/src/use-deep-agent-voice.js +529 -71
  156. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  157. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs +26 -26
  158. package/dist/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  159. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs +4 -4
  160. package/dist/agent-runtime/src/use-historical-edit-attachments.cjs.map +1 -1
  161. package/dist/agent-runtime/src/use-thread-handoff-flow.d.ts +34 -26
  162. package/dist/agent-runtime/src/voice-earcon.cjs +139 -0
  163. package/dist/agent-runtime/src/voice-earcon.cjs.map +1 -0
  164. package/dist/agent-runtime/src/voice-earcon.d.ts +38 -0
  165. package/dist/agent-runtime/src/voice-earcon.js +139 -0
  166. package/dist/agent-runtime/src/voice-earcon.js.map +1 -0
  167. package/dist/agent-runtime/src/voice-media.cjs +117 -0
  168. package/dist/agent-runtime/src/voice-media.cjs.map +1 -0
  169. package/dist/agent-runtime/src/voice-media.d.ts +63 -0
  170. package/dist/agent-runtime/src/voice-media.js +117 -0
  171. package/dist/agent-runtime/src/voice-media.js.map +1 -0
  172. package/dist/agent-runtime/src/voice-presentation.cjs +2 -0
  173. package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
  174. package/dist/agent-runtime/src/voice-presentation.js +2 -0
  175. package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
  176. package/dist/agent-runtime/src/voice-wire-types.d.ts +32 -0
  177. package/dist/assets/AssetPanel.cjs +11 -11
  178. package/dist/assets/AssetPanel.cjs.map +1 -1
  179. package/dist/assets/AthenaAssetEmbed.cjs +11 -9
  180. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  181. package/dist/assets/AthenaAssetEmbed.d.ts +18 -5
  182. package/dist/assets/AthenaAssetEmbed.js +4 -2
  183. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  184. package/dist/assets/AthenaLayout.cjs +16 -16
  185. package/dist/assets/AthenaLayout.cjs.map +1 -1
  186. package/dist/assets/use-asset-content.cjs +4 -4
  187. package/dist/assets/use-asset-content.cjs.map +1 -1
  188. package/dist/assets/use-asset-embed.cjs +14 -7
  189. package/dist/assets/use-asset-embed.cjs.map +1 -1
  190. package/dist/assets/use-asset-embed.d.ts +23 -6
  191. package/dist/assets/use-asset-embed.js +10 -3
  192. package/dist/assets/use-asset-embed.js.map +1 -1
  193. package/dist/auth/AthenaAuthContext.cjs +3 -3
  194. package/dist/auth/AthenaAuthContext.cjs.map +1 -1
  195. package/dist/auth/AthenaAuthProvider.cjs +8 -8
  196. package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
  197. package/dist/auth/AthenaCredentialSourceContext.cjs +5 -5
  198. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  199. package/dist/auth/AthenaSSOProvider.cjs +14 -14
  200. package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
  201. package/dist/auth/credential-source.cjs +26 -13
  202. package/dist/auth/credential-source.cjs.map +1 -1
  203. package/dist/auth/credential-source.d.ts +8 -0
  204. package/dist/auth/credential-source.js +26 -13
  205. package/dist/auth/credential-source.js.map +1 -1
  206. package/dist/catalog/agent-model-options.cjs +25 -17
  207. package/dist/catalog/agent-model-options.cjs.map +1 -1
  208. package/dist/catalog/agent-model-options.d.ts +38 -5
  209. package/dist/catalog/agent-model-options.js +25 -17
  210. package/dist/catalog/agent-model-options.js.map +1 -1
  211. package/dist/catalog/channel-refusal.cjs +36 -0
  212. package/dist/catalog/channel-refusal.cjs.map +1 -0
  213. package/dist/catalog/channel-refusal.d.ts +29 -0
  214. package/dist/catalog/channel-refusal.js +36 -0
  215. package/dist/catalog/channel-refusal.js.map +1 -0
  216. package/dist/catalog/chat-pickers.cjs +60 -24
  217. package/dist/catalog/chat-pickers.cjs.map +1 -1
  218. package/dist/catalog/chat-pickers.d.ts +12 -2
  219. package/dist/catalog/chat-pickers.js +56 -20
  220. package/dist/catalog/chat-pickers.js.map +1 -1
  221. package/dist/catalog/runtime-catalog.cjs +89 -23
  222. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  223. package/dist/catalog/runtime-catalog.d.ts +8 -2
  224. package/dist/catalog/runtime-catalog.js +83 -17
  225. package/dist/catalog/runtime-catalog.js.map +1 -1
  226. package/dist/catalog/use-athena-chat-mode.cjs +12 -12
  227. package/dist/catalog/use-athena-chat-mode.cjs.map +1 -1
  228. package/dist/chat/AthenaChat.cjs +155 -67
  229. package/dist/chat/AthenaChat.cjs.map +1 -1
  230. package/dist/chat/AthenaChat.d.ts +42 -2
  231. package/dist/chat/AthenaChat.js +106 -18
  232. package/dist/chat/AthenaChat.js.map +1 -1
  233. package/dist/chat/AthenaChatErrorBoundary.cjs +3 -3
  234. package/dist/chat/AthenaChatErrorBoundary.cjs.map +1 -1
  235. package/dist/chat/DrivingOnChip.cjs +23 -0
  236. package/dist/chat/DrivingOnChip.cjs.map +1 -0
  237. package/dist/chat/DrivingOnChip.d.ts +17 -0
  238. package/dist/chat/DrivingOnChip.js +23 -0
  239. package/dist/chat/DrivingOnChip.js.map +1 -0
  240. package/dist/chat/StatewireApprovalCard.cjs +166 -37
  241. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  242. package/dist/chat/StatewireApprovalCard.d.ts +91 -2
  243. package/dist/chat/StatewireApprovalCard.js +156 -27
  244. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  245. package/dist/chat/StatewireClientToolBridge.cjs +2 -2
  246. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  247. package/dist/chat/StatewireQueuedMessages.cjs +81 -69
  248. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.d.ts +25 -13
  250. package/dist/chat/StatewireQueuedMessages.js +73 -61
  251. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  252. package/dist/chat/WaitingOnYouBanner.cjs +9 -5
  253. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -1
  254. package/dist/chat/WaitingOnYouBanner.js +7 -3
  255. package/dist/chat/WaitingOnYouBanner.js.map +1 -1
  256. package/dist/chat/athena-chat-welcome.cjs +2 -2
  257. package/dist/chat/athena-chat-welcome.cjs.map +1 -1
  258. package/dist/chat/athena-citation-links.cjs +5 -5
  259. package/dist/chat/athena-citation-links.cjs.map +1 -1
  260. package/dist/chat/athena-composer-controls.cjs +26 -16
  261. package/dist/chat/athena-composer-controls.cjs.map +1 -1
  262. package/dist/chat/athena-composer-controls.d.ts +6 -0
  263. package/dist/chat/athena-composer-controls.js +26 -16
  264. package/dist/chat/athena-composer-controls.js.map +1 -1
  265. package/dist/chat/athena-turn-end-status.cjs +42 -0
  266. package/dist/chat/athena-turn-end-status.cjs.map +1 -0
  267. package/dist/chat/athena-turn-end-status.d.ts +24 -0
  268. package/dist/chat/athena-turn-end-status.js +42 -0
  269. package/dist/chat/athena-turn-end-status.js.map +1 -0
  270. package/dist/chat/browser-decision-check.cjs +131 -0
  271. package/dist/chat/browser-decision-check.cjs.map +1 -0
  272. package/dist/chat/browser-decision-check.d.ts +61 -0
  273. package/dist/chat/browser-decision-check.js +131 -0
  274. package/dist/chat/browser-decision-check.js.map +1 -0
  275. package/dist/chat/chat-outbox-rows.cjs +3 -3
  276. package/dist/chat/chat-outbox-rows.cjs.map +1 -1
  277. package/dist/chat/chat-voice-controls.cjs +96 -29
  278. package/dist/chat/chat-voice-controls.cjs.map +1 -1
  279. package/dist/chat/chat-voice-controls.d.ts +42 -3
  280. package/dist/chat/chat-voice-controls.js +92 -25
  281. package/dist/chat/chat-voice-controls.js.map +1 -1
  282. package/dist/chat/composer-keyboard-hint.cjs +5 -5
  283. package/dist/chat/composer-keyboard-hint.cjs.map +1 -1
  284. package/dist/chat/device-operation.cjs +29 -0
  285. package/dist/chat/device-operation.cjs.map +1 -0
  286. package/dist/chat/device-operation.d.ts +34 -0
  287. package/dist/chat/device-operation.js +29 -0
  288. package/dist/chat/device-operation.js.map +1 -0
  289. package/dist/chat/super-grouping/CollapsibleGroup.cjs +14 -14
  290. package/dist/chat/super-grouping/CollapsibleGroup.cjs.map +1 -1
  291. package/dist/chat/super-grouping/GroupedMessageParts.cjs +4 -4
  292. package/dist/chat/super-grouping/GroupedMessageParts.cjs.map +1 -1
  293. package/dist/chat/super-grouping/SuperGroupingCard.cjs +52 -36
  294. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  295. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +19 -4
  296. package/dist/chat/super-grouping/SuperGroupingCard.js +29 -13
  297. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  298. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +32 -32
  299. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  300. package/dist/chat/super-grouping/SuperGroupingTranscript.js +3 -3
  301. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  302. package/dist/chat/super-grouping/ToolTimeline.cjs +73 -40
  303. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  304. package/dist/chat/super-grouping/ToolTimeline.d.ts +10 -2
  305. package/dist/chat/super-grouping/ToolTimeline.js +69 -36
  306. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  307. package/dist/chat/super-grouping/activity-timeline.cjs +47 -12
  308. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  309. package/dist/chat/super-grouping/activity-timeline.d.ts +21 -0
  310. package/dist/chat/super-grouping/activity-timeline.js +47 -12
  311. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  312. package/dist/chat/super-grouping/grouping-function.cjs +4 -0
  313. package/dist/chat/super-grouping/grouping-function.cjs.map +1 -1
  314. package/dist/chat/super-grouping/grouping-function.d.ts +7 -0
  315. package/dist/chat/super-grouping/grouping-function.js +5 -1
  316. package/dist/chat/super-grouping/grouping-function.js.map +1 -1
  317. package/dist/chat/super-grouping/index.cjs +6 -0
  318. package/dist/chat/super-grouping/index.cjs.map +1 -1
  319. package/dist/chat/super-grouping/index.d.ts +5 -2
  320. package/dist/chat/super-grouping/index.js +7 -1
  321. package/dist/chat/super-grouping/index.js.map +1 -1
  322. package/dist/chat/super-grouping/tool-part-placement.cjs +17 -0
  323. package/dist/chat/super-grouping/tool-part-placement.cjs.map +1 -0
  324. package/dist/chat/super-grouping/tool-part-placement.d.ts +22 -0
  325. package/dist/chat/super-grouping/tool-part-placement.js +17 -0
  326. package/dist/chat/super-grouping/tool-part-placement.js.map +1 -0
  327. package/dist/chat/thread-scroll-to-bottom.cjs +2 -2
  328. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -1
  329. package/dist/chat/thread-scroll-to-bottom.d.ts +10 -7
  330. package/dist/chat/thread-scroll-to-bottom.js +2 -2
  331. package/dist/chat/thread-scroll-to-bottom.js.map +1 -1
  332. package/dist/chat/tooltip-icon-button.cjs +2 -2
  333. package/dist/chat/tooltip-icon-button.cjs.map +1 -1
  334. package/dist/chat/use-athena-voice-live.cjs +11 -0
  335. package/dist/chat/use-athena-voice-live.cjs.map +1 -0
  336. package/dist/chat/use-athena-voice-live.d.ts +11 -0
  337. package/dist/chat/use-athena-voice-live.js +11 -0
  338. package/dist/chat/use-athena-voice-live.js.map +1 -0
  339. package/dist/chat/use-statewire-approval-request.cjs +56 -24
  340. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  341. package/dist/chat/use-statewire-approval-request.d.ts +33 -4
  342. package/dist/chat/use-statewire-approval-request.js +41 -9
  343. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  344. package/dist/chat-ui/auth/sign-in-card.cjs +2 -2
  345. package/dist/chat-ui/auth/sign-in-card.cjs.map +1 -1
  346. package/dist/chat-ui/composer/tiptap-composer.cjs +138 -107
  347. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  348. package/dist/chat-ui/composer/tiptap-composer.d.ts +20 -4
  349. package/dist/chat-ui/composer/tiptap-composer.js +85 -54
  350. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  351. package/dist/chat-ui/header/conversation-history-panel.cjs +49 -23
  352. package/dist/chat-ui/header/conversation-history-panel.cjs.map +1 -1
  353. package/dist/chat-ui/header/conversation-history-panel.d.ts +12 -1
  354. package/dist/chat-ui/header/conversation-history-panel.js +38 -12
  355. package/dist/chat-ui/header/conversation-history-panel.js.map +1 -1
  356. package/dist/chat-ui/index.cjs +21 -0
  357. package/dist/chat-ui/index.cjs.map +1 -1
  358. package/dist/chat-ui/index.d.ts +8 -1
  359. package/dist/chat-ui/index.js +21 -0
  360. package/dist/chat-ui/index.js.map +1 -1
  361. package/dist/chat-ui/mentions/mention-chip.cjs +4 -4
  362. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  363. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs +10 -9
  364. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.cjs.map +1 -1
  365. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js +3 -2
  366. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-list.js.map +1 -1
  367. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs +2 -2
  368. package/dist/chat-ui/mentions/suggestions/components/mention-suggestion-popup.cjs.map +1 -1
  369. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs +29 -6
  370. package/dist/chat-ui/mentions/suggestions/components/menu-list.cjs.map +1 -1
  371. package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +7 -1
  372. package/dist/chat-ui/mentions/suggestions/components/menu-list.js +25 -2
  373. package/dist/chat-ui/mentions/suggestions/components/menu-list.js.map +1 -1
  374. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs +2 -2
  375. package/dist/chat-ui/mentions/suggestions/components/use-keyboard-navigation.cjs.map +1 -1
  376. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs +2 -2
  377. package/dist/chat-ui/mentions/suggestions/components/use-menu-navigation.cjs.map +1 -1
  378. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +3 -3
  379. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  380. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs +56 -2
  381. package/dist/chat-ui/mentions/suggestions/data/orchestrator.cjs.map +1 -1
  382. package/dist/chat-ui/mentions/suggestions/data/orchestrator.d.ts +12 -0
  383. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js +56 -2
  384. package/dist/chat-ui/mentions/suggestions/data/orchestrator.js.map +1 -1
  385. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +24 -3
  386. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  387. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +7 -0
  388. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +24 -3
  389. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +35 -13
  391. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +15 -1
  393. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +28 -6
  394. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  395. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs +9 -6
  396. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.cjs.map +1 -1
  397. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.d.ts +3 -0
  398. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js +5 -2
  399. package/dist/chat-ui/mentions/suggestions/data/use-menu-items.js.map +1 -1
  400. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +45 -10
  401. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
  402. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +24 -1
  403. package/dist/chat-ui/mentions/use-account-workspace-id.js +46 -11
  404. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
  405. package/dist/chat-ui/mentions/use-member-avatar.cjs +4 -4
  406. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -1
  407. package/dist/chat-ui/mentions/use-mention-asset.cjs +3 -3
  408. package/dist/chat-ui/mentions/use-mention-asset.cjs.map +1 -1
  409. package/dist/chat-ui/messages/answer-label.cjs +42 -0
  410. package/dist/chat-ui/messages/answer-label.cjs.map +1 -0
  411. package/dist/chat-ui/messages/answer-label.d.ts +33 -0
  412. package/dist/chat-ui/messages/answer-label.js +42 -0
  413. package/dist/chat-ui/messages/answer-label.js.map +1 -0
  414. package/dist/chat-ui/messages/arrival-animation.cjs +13 -0
  415. package/dist/chat-ui/messages/arrival-animation.cjs.map +1 -0
  416. package/dist/chat-ui/messages/arrival-animation.d.ts +14 -0
  417. package/dist/chat-ui/messages/arrival-animation.js +13 -0
  418. package/dist/chat-ui/messages/arrival-animation.js.map +1 -0
  419. package/dist/chat-ui/messages/continue-pill.cjs +5 -5
  420. package/dist/chat-ui/messages/continue-pill.cjs.map +1 -1
  421. package/dist/chat-ui/messages/from-the-call-card.cjs +124 -0
  422. package/dist/chat-ui/messages/from-the-call-card.cjs.map +1 -0
  423. package/dist/chat-ui/messages/from-the-call-card.d.ts +17 -0
  424. package/dist/chat-ui/messages/from-the-call-card.js +124 -0
  425. package/dist/chat-ui/messages/from-the-call-card.js.map +1 -0
  426. package/dist/chat-ui/messages/handoff-arrival-divider.cjs +44 -0
  427. package/dist/chat-ui/messages/handoff-arrival-divider.cjs.map +1 -0
  428. package/dist/chat-ui/messages/handoff-arrival-divider.d.ts +17 -0
  429. package/dist/chat-ui/messages/handoff-arrival-divider.js +44 -0
  430. package/dist/chat-ui/messages/handoff-arrival-divider.js.map +1 -0
  431. package/dist/chat-ui/messages/message-actions-config.cjs +3 -3
  432. package/dist/chat-ui/messages/message-actions-config.cjs.map +1 -1
  433. package/dist/chat-ui/messages/message-components.cjs +8 -4
  434. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  435. package/dist/chat-ui/messages/message-components.js +5 -1
  436. package/dist/chat-ui/messages/message-components.js.map +1 -1
  437. package/dist/chat-ui/messages/message-images.cjs +66 -0
  438. package/dist/chat-ui/messages/message-images.cjs.map +1 -0
  439. package/dist/chat-ui/messages/message-images.d.ts +16 -0
  440. package/dist/chat-ui/messages/message-images.js +66 -0
  441. package/dist/chat-ui/messages/message-images.js.map +1 -0
  442. package/dist/chat-ui/messages/user-edit-composer.cjs +2 -2
  443. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  444. package/dist/chat-ui/messages/wake-marker.cjs +3 -3
  445. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
  446. package/dist/chat-ui/rich-text/chat-link.cjs +3 -2
  447. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -1
  448. package/dist/chat-ui/rich-text/chat-link.d.ts +4 -0
  449. package/dist/chat-ui/rich-text/chat-link.js +4 -3
  450. package/dist/chat-ui/rich-text/chat-link.js.map +1 -1
  451. package/dist/chat-ui/rich-text/chat-message-body.cjs +9 -8
  452. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  453. package/dist/chat-ui/rich-text/chat-message-body.d.ts +12 -0
  454. package/dist/chat-ui/rich-text/chat-message-body.js +2 -1
  455. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
  456. package/dist/chat-ui/rich-text/chat-node-views.cjs +6 -6
  457. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  458. package/dist/chat-ui/rich-text/dom-output-spec.cjs +2 -2
  459. package/dist/chat-ui/rich-text/dom-output-spec.cjs.map +1 -1
  460. package/dist/chat-ui/statewire.cjs +3 -0
  461. package/dist/chat-ui/statewire.cjs.map +1 -1
  462. package/dist/chat-ui/statewire.d.ts +2 -1
  463. package/dist/chat-ui/statewire.js +3 -0
  464. package/dist/chat-ui/statewire.js.map +1 -1
  465. package/dist/chat-ui/thread/chat-thread-shell.cjs +45 -14
  466. package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
  467. package/dist/chat-ui/thread/chat-thread-shell.d.ts +16 -2
  468. package/dist/chat-ui/thread/chat-thread-shell.js +37 -6
  469. package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
  470. package/dist/chat-ui/thread/composer-send-or-stop.cjs +30 -20
  471. package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
  472. package/dist/chat-ui/thread/composer-send-or-stop.d.ts +8 -0
  473. package/dist/chat-ui/thread/composer-send-or-stop.js +29 -19
  474. package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
  475. package/dist/chat-ui/thread/statewire-history-edge.cjs +20 -21
  476. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  477. package/dist/chat-ui/thread/statewire-history-edge.js +3 -4
  478. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  479. package/dist/chat-ui/thread/thread-loading-overlay.cjs +5 -5
  480. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -1
  481. package/dist/collab/client.cjs +52 -3
  482. package/dist/collab/client.cjs.map +1 -1
  483. package/dist/collab/client.d.ts +27 -0
  484. package/dist/collab/client.js +52 -3
  485. package/dist/collab/client.js.map +1 -1
  486. package/dist/collab/document-status.cjs +150 -0
  487. package/dist/collab/document-status.cjs.map +1 -0
  488. package/dist/collab/document-status.d.ts +68 -0
  489. package/dist/collab/document-status.js +150 -0
  490. package/dist/collab/document-status.js.map +1 -0
  491. package/dist/collab/index.cjs +7 -0
  492. package/dist/collab/index.cjs.map +1 -1
  493. package/dist/collab/index.d.ts +6 -1
  494. package/dist/collab/index.js +7 -0
  495. package/dist/collab/index.js.map +1 -1
  496. package/dist/collab/presence-react.cjs +11 -11
  497. package/dist/collab/presence-react.cjs.map +1 -1
  498. package/dist/collab/react.cjs +6 -6
  499. package/dist/collab/react.cjs.map +1 -1
  500. package/dist/composer/AttachmentContext.cjs +24 -11
  501. package/dist/composer/AttachmentContext.cjs.map +1 -1
  502. package/dist/composer/AttachmentContext.js +18 -5
  503. package/dist/composer/AttachmentContext.js.map +1 -1
  504. package/dist/composer/ComposerAttachmentPreview.cjs +78 -23
  505. package/dist/composer/ComposerAttachmentPreview.cjs.map +1 -1
  506. package/dist/composer/ComposerAttachmentPreview.d.ts +5 -3
  507. package/dist/composer/ComposerAttachmentPreview.js +79 -24
  508. package/dist/composer/ComposerAttachmentPreview.js.map +1 -1
  509. package/dist/composer/ComposerDropZone.cjs +7 -7
  510. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  511. package/dist/composer/FileUploadButton.cjs +37 -22
  512. package/dist/composer/FileUploadButton.cjs.map +1 -1
  513. package/dist/composer/FileUploadButton.d.ts +6 -0
  514. package/dist/composer/FileUploadButton.js +34 -19
  515. package/dist/composer/FileUploadButton.js.map +1 -1
  516. package/dist/composer/QuoteContext.cjs +8 -8
  517. package/dist/composer/QuoteContext.cjs.map +1 -1
  518. package/dist/composer/composer-handoff.cjs +4 -4
  519. package/dist/composer/composer-handoff.cjs.map +1 -1
  520. package/dist/composer/index.d.ts +1 -1
  521. package/dist/composer/useAppendToComposer.cjs +4 -4
  522. package/dist/composer/useAppendToComposer.cjs.map +1 -1
  523. package/dist/composer/useAttachFiles.cjs +23 -6
  524. package/dist/composer/useAttachFiles.cjs.map +1 -1
  525. package/dist/composer/useAttachFiles.d.ts +15 -7
  526. package/dist/composer/useAttachFiles.js +22 -5
  527. package/dist/composer/useAttachFiles.js.map +1 -1
  528. package/dist/composer/useComposerAttachment.cjs +4 -4
  529. package/dist/composer/useComposerAttachment.cjs.map +1 -1
  530. package/dist/composer/useFileUpload.cjs +21 -16
  531. package/dist/composer/useFileUpload.cjs.map +1 -1
  532. package/dist/composer/useFileUpload.d.ts +12 -0
  533. package/dist/composer/useFileUpload.js +12 -7
  534. package/dist/composer/useFileUpload.js.map +1 -1
  535. package/dist/composer/useReadComposerDraft.cjs +27 -8
  536. package/dist/composer/useReadComposerDraft.cjs.map +1 -1
  537. package/dist/composer/useReadComposerDraft.d.ts +23 -1
  538. package/dist/composer/useReadComposerDraft.js +27 -8
  539. package/dist/composer/useReadComposerDraft.js.map +1 -1
  540. package/dist/composer/useSendMessage.cjs +4 -4
  541. package/dist/composer/useSendMessage.cjs.map +1 -1
  542. package/dist/diagnostics/useAthenaDiagnostics.cjs +4 -4
  543. package/dist/diagnostics/useAthenaDiagnostics.cjs.map +1 -1
  544. package/dist/dictation/audio-level-history.cjs +3 -3
  545. package/dist/dictation/audio-level-history.cjs.map +1 -1
  546. package/dist/dictation/dictation-controls.cjs +24 -20
  547. package/dist/dictation/dictation-controls.cjs.map +1 -1
  548. package/dist/dictation/dictation-controls.d.ts +6 -1
  549. package/dist/dictation/dictation-controls.js +24 -20
  550. package/dist/dictation/dictation-controls.js.map +1 -1
  551. package/dist/dictation/use-athena-dictation-engine.cjs +3 -3
  552. package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
  553. package/dist/dictation/use-dictation.cjs +22 -22
  554. package/dist/dictation/use-dictation.cjs.map +1 -1
  555. package/dist/index.cjs +29 -2
  556. package/dist/index.cjs.map +1 -1
  557. package/dist/index.d.ts +18 -4
  558. package/dist/index.js +30 -3
  559. package/dist/index.js.map +1 -1
  560. package/dist/keryx-http/src/receive-only-socket.cjs +40 -0
  561. package/dist/keryx-http/src/receive-only-socket.cjs.map +1 -0
  562. package/dist/keryx-http/src/receive-only-socket.d.ts +27 -0
  563. package/dist/keryx-http/src/receive-only-socket.js +40 -0
  564. package/dist/keryx-http/src/receive-only-socket.js.map +1 -0
  565. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs +190 -0
  566. package/dist/keryx-http/src/unconfirmed-update-attributions.cjs.map +1 -0
  567. package/dist/keryx-http/src/unconfirmed-update-attributions.d.ts +132 -0
  568. package/dist/keryx-http/src/unconfirmed-update-attributions.js +190 -0
  569. package/dist/keryx-http/src/unconfirmed-update-attributions.js.map +1 -0
  570. package/dist/keryx-http/src/update-attributions.cjs +141 -0
  571. package/dist/keryx-http/src/update-attributions.cjs.map +1 -0
  572. package/dist/keryx-http/src/update-attributions.d.ts +107 -0
  573. package/dist/keryx-http/src/update-attributions.js +141 -0
  574. package/dist/keryx-http/src/update-attributions.js.map +1 -0
  575. package/dist/lib/owner-document.cjs +6 -6
  576. package/dist/lib/owner-document.cjs.map +1 -1
  577. package/dist/lib/use-athena-rest-query.cjs +4 -4
  578. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  579. package/dist/lib/use-document-active.cjs +4 -4
  580. package/dist/lib/use-document-active.cjs.map +1 -1
  581. package/dist/lib/use-prefers-reduced-motion.cjs +2 -2
  582. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -1
  583. package/dist/offline/offline-history.cjs +7 -7
  584. package/dist/offline/offline-history.cjs.map +1 -1
  585. package/dist/provider/AthenaContext.cjs +3 -3
  586. package/dist/provider/AthenaContext.cjs.map +1 -1
  587. package/dist/provider/AthenaProvider.cjs +120 -79
  588. package/dist/provider/AthenaProvider.cjs.map +1 -1
  589. package/dist/provider/AthenaProvider.d.ts +11 -1
  590. package/dist/provider/AthenaProvider.js +44 -3
  591. package/dist/provider/AthenaProvider.js.map +1 -1
  592. package/dist/provider/PostHogProvider.cjs +2 -2
  593. package/dist/provider/PostHogProvider.cjs.map +1 -1
  594. package/dist/provider/agent-selection-context.cjs +2 -2
  595. package/dist/provider/agent-selection-context.cjs.map +1 -1
  596. package/dist/provider/chat-mode-context.cjs +2 -2
  597. package/dist/provider/chat-mode-context.cjs.map +1 -1
  598. package/dist/provider/session-persistence-context.cjs +10 -0
  599. package/dist/provider/session-persistence-context.cjs.map +1 -0
  600. package/dist/provider/session-persistence-context.d.ts +15 -0
  601. package/dist/provider/session-persistence-context.js +10 -0
  602. package/dist/provider/session-persistence-context.js.map +1 -0
  603. package/dist/provider/statewire-history-context.cjs +4 -4
  604. package/dist/provider/statewire-history-context.cjs.map +1 -1
  605. package/dist/provider/statewire-lifecycle-context.cjs +3 -3
  606. package/dist/provider/statewire-lifecycle-context.cjs.map +1 -1
  607. package/dist/provider/statewire-window-context.cjs +3 -3
  608. package/dist/provider/statewire-window-context.cjs.map +1 -1
  609. package/dist/provider/theme-style-context.cjs +3 -3
  610. package/dist/provider/theme-style-context.cjs.map +1 -1
  611. package/dist/react/package.json.cjs +1 -1
  612. package/dist/react/package.json.js +1 -1
  613. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +10 -10
  614. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  615. package/dist/runtime/auth-refusal-restart.cjs +7 -7
  616. package/dist/runtime/auth-refusal-restart.cjs.map +1 -1
  617. package/dist/runtime/auth.cjs +13 -13
  618. package/dist/runtime/auth.cjs.map +1 -1
  619. package/dist/runtime/statewire-lifecycle.cjs +1 -0
  620. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  621. package/dist/runtime/statewire-lifecycle.d.ts +3 -1
  622. package/dist/runtime/statewire-lifecycle.js +2 -1
  623. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  624. package/dist/runtime/statewire-server-lane-context.cjs +2 -2
  625. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -1
  626. package/dist/runtime/statewire-session-lane.cjs +4 -4
  627. package/dist/runtime/statewire-session-lane.cjs.map +1 -1
  628. package/dist/runtime/useAthenaStatewireRuntime.cjs +10 -8
  629. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  630. package/dist/runtime/useAthenaStatewireRuntime.d.ts +2 -0
  631. package/dist/runtime/useAthenaStatewireRuntime.js +2 -0
  632. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  633. package/dist/styles.css +1 -1
  634. package/dist/threads/Inbox.cjs +8 -8
  635. package/dist/threads/Inbox.cjs.map +1 -1
  636. package/dist/threads/SessionList.cjs +9 -9
  637. package/dist/threads/SessionList.cjs.map +1 -1
  638. package/dist/threads/SessionsPage.cjs +11 -11
  639. package/dist/threads/SessionsPage.cjs.map +1 -1
  640. package/dist/threads/api.cjs.map +1 -1
  641. package/dist/threads/api.d.ts +15 -0
  642. package/dist/threads/api.js.map +1 -1
  643. package/dist/threads/conversation-list-fetcher.cjs +13 -5
  644. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  645. package/dist/threads/conversation-list-fetcher.d.ts +4 -1
  646. package/dist/threads/conversation-list-fetcher.js +13 -5
  647. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  648. package/dist/threads/index-triggered-refresh.cjs +10 -10
  649. package/dist/threads/index-triggered-refresh.cjs.map +1 -1
  650. package/dist/threads/mark-viewed-thread-read.cjs +12 -12
  651. package/dist/threads/mark-viewed-thread-read.cjs.map +1 -1
  652. package/dist/threads/offline-session-list.cjs +3 -3
  653. package/dist/threads/offline-session-list.cjs.map +1 -1
  654. package/dist/threads/session-list-tab-share.cjs +5 -5
  655. package/dist/threads/session-list-tab-share.cjs.map +1 -1
  656. package/dist/threads/statewire-thread-list.cjs +79 -57
  657. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  658. package/dist/threads/statewire-thread-list.d.ts +20 -8
  659. package/dist/threads/statewire-thread-list.js +28 -6
  660. package/dist/threads/statewire-thread-list.js.map +1 -1
  661. package/dist/threads/thread-id-context.cjs +5 -5
  662. package/dist/threads/thread-id-context.cjs.map +1 -1
  663. package/dist/threads/use-athena-session-attention.cjs +2 -2
  664. package/dist/threads/use-athena-session-attention.cjs.map +1 -1
  665. package/dist/threads/use-athena-sessions.cjs +37 -15
  666. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  667. package/dist/threads/use-athena-sessions.d.ts +10 -5
  668. package/dist/threads/use-athena-sessions.js +28 -6
  669. package/dist/threads/use-athena-sessions.js.map +1 -1
  670. package/dist/threads/use-athena-thread-model.cjs +3 -3
  671. package/dist/threads/use-athena-thread-model.cjs.map +1 -1
  672. package/dist/threads/use-rest-conversation-history.cjs +3 -3
  673. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  674. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  675. package/dist/threads/use-statewire-conversation-history.cjs +8 -8
  676. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  677. package/dist/threads/use-thread-archive.cjs +9 -9
  678. package/dist/threads/use-thread-archive.cjs.map +1 -1
  679. package/dist/threads/use-thread-favorite.cjs +2 -2
  680. package/dist/threads/use-thread-favorite.cjs.map +1 -1
  681. package/dist/threads/use-thread-field-override.cjs +20 -20
  682. package/dist/threads/use-thread-field-override.cjs.map +1 -1
  683. package/dist/threads/use-thread-read-state.cjs +4 -4
  684. package/dist/threads/use-thread-read-state.cjs.map +1 -1
  685. package/dist/threads/use-thread-rename.cjs +2 -2
  686. package/dist/threads/use-thread-rename.cjs.map +1 -1
  687. package/dist/threads/useAthenaThreadManager.cjs +2 -2
  688. package/dist/threads/useAthenaThreadManager.cjs.map +1 -1
  689. package/dist/tools/NestedPtcMessages.cjs +6 -6
  690. package/dist/tools/NestedPtcMessages.cjs.map +1 -1
  691. package/dist/tools/append-document-tool-ui.cjs +7 -7
  692. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  693. package/dist/tools/file-tool-uis.cjs +2 -2
  694. package/dist/tools/file-tool-uis.cjs.map +1 -1
  695. package/dist/tools/misc-tool-uis.cjs +2 -2
  696. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  697. package/dist/tools/primitives.cjs +6 -6
  698. package/dist/tools/primitives.cjs.map +1 -1
  699. package/dist/tools/read-asset-tool-ui.cjs +6 -6
  700. package/dist/tools/read-asset-tool-ui.cjs.map +1 -1
  701. package/dist/tools/subagent-task-tool-ui.cjs +21 -21
  702. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  703. package/dist/tools/test-recording-tool-uis.cjs +16 -16
  704. package/dist/tools/test-recording-tool-uis.cjs.map +1 -1
  705. package/dist/tools/todo-plan-store.cjs +4 -4
  706. package/dist/tools/todo-plan-store.cjs.map +1 -1
  707. package/dist/tools/tool-appearance.cjs +3 -3
  708. package/dist/tools/tool-appearance.cjs.map +1 -1
  709. package/dist/tools/tool-fallback.cjs +14 -14
  710. package/dist/tools/tool-fallback.cjs.map +1 -1
  711. package/dist/tools/tool-uis.cjs +74 -74
  712. package/dist/tools/tool-uis.cjs.map +1 -1
  713. package/dist/tools/use-elapsed-seconds.cjs +3 -3
  714. package/dist/tools/use-elapsed-seconds.cjs.map +1 -1
  715. package/dist/tools/write-todos-tool-ui.cjs +9 -9
  716. package/dist/tools/write-todos-tool-ui.cjs.map +1 -1
  717. package/dist/ui/image-viewer.cjs +382 -0
  718. package/dist/ui/image-viewer.cjs.map +1 -0
  719. package/dist/ui/image-viewer.d.ts +50 -0
  720. package/dist/ui/image-viewer.js +382 -0
  721. package/dist/ui/image-viewer.js.map +1 -0
  722. package/dist/voice/chat.cjs +6 -0
  723. package/dist/voice/chat.cjs.map +1 -1
  724. package/dist/voice/chat.d.ts +1 -1
  725. package/dist/voice/chat.js +8 -2
  726. package/dist/voice/livekit-join.cjs +52 -101
  727. package/dist/voice/livekit-join.cjs.map +1 -1
  728. package/dist/voice/livekit-join.d.ts +1 -6
  729. package/dist/voice/livekit-join.js +52 -101
  730. package/dist/voice/livekit-join.js.map +1 -1
  731. package/dist/voice/livekit.cjs.map +1 -1
  732. package/dist/voice/livekit.d.ts +11 -1
  733. package/dist/voice/livekit.js.map +1 -1
  734. package/dist/voice/use-athena-voice-session.cjs +34 -34
  735. package/dist/voice/use-athena-voice-session.cjs.map +1 -1
  736. package/dist/workbench/ComputerLiveDesktop.cjs +13 -13
  737. package/dist/workbench/ComputerLiveDesktop.cjs.map +1 -1
  738. package/dist/workbench/SessionWorkbench.cjs +22 -22
  739. package/dist/workbench/SessionWorkbench.cjs.map +1 -1
  740. package/dist/workbench/session-workbench-context.cjs +3 -3
  741. package/dist/workbench/session-workbench-context.cjs.map +1 -1
  742. package/dist/workbench/session-workbench-panes.cjs +8 -8
  743. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  744. package/dist/workbench/workbench-layout-context.cjs +3 -3
  745. package/dist/workbench/workbench-layout-context.cjs.map +1 -1
  746. package/package.json +2 -1
@@ -3,22 +3,25 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const react = require("@assistant-ui/react");
5
5
  const lucideReact = require("lucide-react");
6
- const react$1 = require("react");
6
+ const require$$0 = require("react");
7
7
  const athenaDiagnostics = require("../diagnostics/athena-diagnostics.cjs");
8
8
  const voice_livekit = require("../voice/livekit.cjs");
9
9
  const useDeepAgentVoice = require("../agent-runtime/src/use-deep-agent-voice.cjs");
10
10
  const useChatVoiceEnabled = require("../voice/use-chat-voice-enabled.cjs");
11
+ const button = require("../ui/button.cjs");
11
12
  const tooltipIconButton = require("./tooltip-icon-button.cjs");
12
13
  const apiClient = require("../chat-ui/mentions/suggestions/data/api-client.cjs");
13
14
  const runtimeCatalog = require("../catalog/runtime-catalog.cjs");
15
+ const voiceEarcon = require("../agent-runtime/src/voice-earcon.cjs");
14
16
  const voicePresentation = require("../agent-runtime/src/voice-presentation.cjs");
17
+ const cnfast = require("cnfast");
15
18
  function useComposerChatVoice({ options }) {
16
19
  const aui = react.useAui();
17
20
  const auth = apiClient.useMentionAuth();
18
21
  const principal = runtimeCatalog.useCatalogPrincipal();
19
22
  const enabled = useChatVoiceEnabled.useChatVoiceEnabled({ enabled: options !== false });
20
- const audioRef = react$1.useRef(null);
21
- const media = react$1.useMemo(
23
+ const audioRef = require$$0.useRef(null);
24
+ const media = require$$0.useMemo(
22
25
  () => voice_livekit.createDeepAgentVoiceLiveKitAdapter({ audioElement: () => audioRef.current }),
23
26
  []
24
27
  );
@@ -27,7 +30,8 @@ function useComposerChatVoice({ options }) {
27
30
  transport: "livekit",
28
31
  livekit: (config == null ? void 0 : config.livekit) ?? media,
29
32
  model: config == null ? void 0 : config.model,
30
- onDiagnostic: (config == null ? void 0 : config.onDiagnostic) ?? ((entry) => athenaDiagnostics.athenaDiagnostics.emit("voice.chat", { data: { ...entry } }))
33
+ onDiagnostic: (config == null ? void 0 : config.onDiagnostic) ?? ((entry) => athenaDiagnostics.athenaDiagnostics.emit("voice.chat", { data: { ...entry } })),
34
+ onCallMoved: (config == null ? void 0 : config.onCallMoved) ?? voiceEarcon.playVoiceMoveEarcon
31
35
  });
32
36
  const active = voice.phase === "connecting" || voice.phase === "live";
33
37
  const { end, syncProfile } = voice;
@@ -36,8 +40,8 @@ function useComposerChatVoice({ options }) {
36
40
  principal,
37
41
  auth.apiKey ? runtimeCatalog.credentialFingerprint({ credential: auth.apiKey }) : null
38
42
  ]);
39
- const previousScope = react$1.useRef({ identity, workspaceId: auth.workspaceId });
40
- react$1.useEffect(() => {
43
+ const previousScope = require$$0.useRef({ identity, workspaceId: auth.workspaceId });
44
+ require$$0.useEffect(() => {
41
45
  const previous = previousScope.current;
42
46
  const changed = previous.identity !== identity || Boolean(
43
47
  previous.workspaceId && auth.workspaceId && previous.workspaceId !== auth.workspaceId
@@ -49,7 +53,7 @@ function useComposerChatVoice({ options }) {
49
53
  if (active && (changed || !enabled)) end();
50
54
  }, [identity, auth.workspaceId, active, enabled, end]);
51
55
  const live = voice.phase === "live";
52
- react$1.useEffect(() => {
56
+ require$$0.useEffect(() => {
53
57
  var _a, _b;
54
58
  if (!live) return;
55
59
  let timer;
@@ -68,47 +72,93 @@ function useComposerChatVoice({ options }) {
68
72
  }
69
73
  function ChatVoiceButton({
70
74
  voice,
71
- disabled
75
+ disabled,
76
+ disabledReason = null
72
77
  }) {
73
78
  const live = voice.phase === "live";
74
79
  const connecting = voice.phase === "connecting";
75
- const label = connecting ? "Cancel voice connection" : live ? voice.micMuted ? "Unmute microphone" : "Mute microphone" : "Start voice session";
80
+ const unavailable = Boolean(disabledReason) && !live && !connecting;
81
+ const moveHere = !live && !connecting && voice.liveElsewhere !== null;
82
+ const label = connecting ? "Cancel voice connection" : live ? voice.micMuted ? "Unmute microphone" : "Mute microphone" : moveHere ? useDeepAgentVoice.VOICE_MOVE_CALL_HERE_LABEL : "Start voice session";
76
83
  return /* @__PURE__ */ jsxRuntime.jsx(
77
84
  tooltipIconButton.TooltipIconButton,
78
85
  {
79
86
  type: "button",
80
- tooltip: label,
87
+ tooltip: unavailable && disabledReason ? disabledReason : label,
81
88
  "aria-label": label,
82
89
  "aria-pressed": live && !voice.micMuted,
83
- className: "aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30",
84
- disabled: !live && !connecting && disabled,
90
+ "aria-disabled": unavailable || void 0,
91
+ "data-unavailable": unavailable || void 0,
92
+ className: cnfast.cn(
93
+ "aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30",
94
+ unavailable && "cursor-not-allowed opacity-30 hover:bg-transparent"
95
+ ),
96
+ disabled: !unavailable && !live && !connecting && disabled,
85
97
  onClick: () => {
98
+ if (unavailable) return;
86
99
  if (connecting) voice.end();
87
100
  else if (live) voice.setMicMuted(!voice.micMuted);
101
+ else if (moveHere) void voice.transferHere();
88
102
  else void voice.start();
89
103
  },
90
- children: connecting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "size-4 animate-spin" }) : live ? voice.micMuted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicOffIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HeadphonesIcon, { className: "size-4" })
104
+ children: connecting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "size-4 animate-spin" }) : live ? voice.micMuted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicOffIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicIcon, { className: "size-4" }) : moveHere ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PhoneIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HeadphonesIcon, { className: "size-4" })
91
105
  }
92
106
  );
93
107
  }
94
- function ChatVoiceStatus({ voice }) {
108
+ function ChatVoiceContinueOffer({
109
+ voice,
110
+ offer,
111
+ disabled = false,
112
+ disabledReason = null
113
+ }) {
114
+ if (!offer || voice.phase !== "idle" || voice.liveElsewhere !== null) return null;
115
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-chat-voice-continue flex items-center gap-1 px-2 pb-2", children: [
116
+ /* @__PURE__ */ jsxRuntime.jsxs(
117
+ button.Button,
118
+ {
119
+ type: "button",
120
+ variant: "outline",
121
+ size: "xs",
122
+ title: disabledReason ?? void 0,
123
+ disabled: disabled || Boolean(disabledReason),
124
+ onClick: () => {
125
+ offer.onDone();
126
+ void voice.start({ opening: "recap" });
127
+ },
128
+ children: [
129
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicIcon, { "aria-hidden": "true" }),
130
+ useDeepAgentVoice.VOICE_CONTINUE_BY_VOICE_LABEL
131
+ ]
132
+ }
133
+ ),
134
+ /* @__PURE__ */ jsxRuntime.jsx(
135
+ tooltipIconButton.TooltipIconButton,
136
+ {
137
+ type: "button",
138
+ tooltip: "Not now",
139
+ "aria-label": "Not now",
140
+ className: "size-6 rounded-md p-0",
141
+ onClick: offer.onDone,
142
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-3" })
143
+ }
144
+ )
145
+ ] });
146
+ }
147
+ function ChatVoiceStatus({
148
+ voice,
149
+ offerMove = false,
150
+ moveDisabled = false,
151
+ moveDisabledReason = null
152
+ }) {
95
153
  const elapsed = useDeepAgentVoice.useVoiceElapsed(voice.liveSince);
154
+ const movedNotice = useDeepAgentVoice.useVoiceMovedNotice(voice.movedTo);
96
155
  const active = voice.phase === "connecting" || voice.phase === "live";
97
- if (!active && !voice.error && !voice.handoffTask) return null;
156
+ const elsewhere = offerMove && !active && movedNotice === null ? voice.liveElsewhere : null;
157
+ if (!active && !voice.error && !voice.handoffTask && movedNotice === null && elsewhere === null)
158
+ return null;
159
+ const moveUnavailable = moveDisabled || Boolean(moveDisabledReason);
98
160
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground", children: [
99
- active && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", role: "status", children: [
100
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: voice.phase === "connecting" ? "Connecting voice…" : `Voice ${voice.micMuted ? "muted" : "live"}${elapsed ? ` · ${elapsed}` : ""}` }),
101
- /* @__PURE__ */ jsxRuntime.jsx(
102
- tooltipIconButton.TooltipIconButton,
103
- {
104
- type: "button",
105
- tooltip: "End voice session",
106
- "aria-label": "End voice session",
107
- onClick: voice.end,
108
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PhoneOffIcon, { className: "size-3.5" })
109
- }
110
- )
111
- ] }),
161
+ active && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", children: voice.phase === "connecting" ? "Connecting voice…" : `Voice ${voice.micMuted ? "muted" : "live"}${elapsed ? ` · ${elapsed}` : ""}` }),
112
162
  voice.phase === "live" && /* @__PURE__ */ jsxRuntime.jsx("span", { children: voicePresentation.VOICE_LIVE_TYPED_HINT }),
113
163
  voice.activeTask && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
114
164
  "Athena is working: ",
@@ -119,10 +169,27 @@ function ChatVoiceStatus({ voice }) {
119
169
  voice.handoffTask.text
120
170
  ] }),
121
171
  voice.notice && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", children: voice.notice }),
122
- voice.error && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "alert", className: "text-destructive", children: voice.error })
172
+ voice.error && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "alert", className: "text-destructive", children: voice.error }),
173
+ movedNotice !== null && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", children: movedNotice }),
174
+ elsewhere !== null && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "aui-chat-voice-elsewhere flex items-center gap-1", children: [
175
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: useDeepAgentVoice.describeVoiceLiveElsewhere(elsewhere.surface) }),
176
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "·" }),
177
+ /* @__PURE__ */ jsxRuntime.jsx(
178
+ "button",
179
+ {
180
+ type: "button",
181
+ title: moveDisabledReason ?? void 0,
182
+ disabled: moveUnavailable,
183
+ onClick: () => void voice.transferHere(),
184
+ className: "shrink-0 font-medium text-foreground underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50",
185
+ children: useDeepAgentVoice.VOICE_MOVE_HERE_ACTION
186
+ }
187
+ )
188
+ ] })
123
189
  ] });
124
190
  }
125
191
  exports.ChatVoiceButton = ChatVoiceButton;
192
+ exports.ChatVoiceContinueOffer = ChatVoiceContinueOffer;
126
193
  exports.ChatVoiceStatus = ChatVoiceStatus;
127
194
  exports.useComposerChatVoice = useComposerChatVoice;
128
195
  //# sourceMappingURL=chat-voice-controls.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-voice-controls.cjs","sources":["../../src/chat/chat-voice-controls.tsx"],"sourcesContent":["import { useAui } from '@assistant-ui/react';\nimport { useVoiceElapsed, VOICE_LIVE_TYPED_HINT } from '@athenaintel/agent-runtime';\nimport { HeadphonesIcon, Loader2Icon, MicIcon, MicOffIcon, PhoneOffIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { createDeepAgentVoiceLiveKitAdapter } from '../voice/livekit';\nimport {\n useAthenaChatVoice,\n type UseAthenaChatVoiceOptions,\n type UseAthenaChatVoiceReturn,\n} from '../voice/chat';\nimport { useChatVoiceEnabled } from '../voice/use-chat-voice-enabled';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { useMentionAuth } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { credentialFingerprint, useCatalogPrincipal } from '../catalog/runtime-catalog';\n\nexport interface AthenaChatVoiceOptions\n extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic'> {}\n\n/** One controller for this composer's controls, text sends and audio sink. */\nexport function useComposerChatVoice({ options }: { options: boolean | AthenaChatVoiceOptions }) {\n const aui = useAui();\n const auth = useMentionAuth();\n const principal = useCatalogPrincipal();\n const enabled = useChatVoiceEnabled({ enabled: options !== false });\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const media = useMemo(\n () => createDeepAgentVoiceLiveKitAdapter({ audioElement: () => audioRef.current }),\n []\n );\n const config = typeof options === 'object' ? options : undefined;\n const voice = useAthenaChatVoice({\n transport: 'livekit',\n livekit: config?.livekit ?? media,\n model: config?.model,\n onDiagnostic:\n config?.onDiagnostic ??\n ((entry) => athenaDiagnostics.emit('voice.chat', { data: { ...entry } })),\n });\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n const { end, syncProfile } = voice;\n const identity = JSON.stringify([\n auth.backendUrl,\n principal,\n auth.apiKey ? credentialFingerprint({ credential: auth.apiKey }) : null,\n ]);\n const previousScope = useRef({ identity, workspaceId: auth.workspaceId });\n useEffect(() => {\n const previous = previousScope.current;\n const changed =\n previous.identity !== identity ||\n Boolean(\n previous.workspaceId && auth.workspaceId && previous.workspaceId !== auth.workspaceId\n );\n previousScope.current = {\n identity,\n workspaceId:\n previous.identity === identity\n ? auth.workspaceId ?? previous.workspaceId\n : auth.workspaceId,\n };\n if (active && (changed || !enabled)) end();\n }, [identity, auth.workspaceId, active, enabled, end]);\n\n // Model/agent/toolkit/mode picks live in the ambient model context. Read it\n // through the controller at send time, with the same debounce as other hosts.\n const live = voice.phase === 'live';\n useEffect(() => {\n if (!live) return;\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(syncProfile, 800);\n };\n schedule();\n const unsubscribe = aui.modelContext.subscribe?.(schedule);\n return () => {\n clearTimeout(timer);\n unsubscribe?.();\n };\n }, [aui, live, syncProfile]);\n return { voice, enabled, active, audioRef };\n}\n\nexport function ChatVoiceButton({\n voice,\n disabled,\n}: {\n voice: UseAthenaChatVoiceReturn;\n disabled: boolean;\n}) {\n const live = voice.phase === 'live';\n const connecting = voice.phase === 'connecting';\n const label = connecting\n ? 'Cancel voice connection'\n : live\n ? voice.micMuted\n ? 'Unmute microphone'\n : 'Mute microphone'\n : 'Start voice session';\n return (\n <TooltipIconButton\n type=\"button\"\n tooltip={label}\n aria-label={label}\n aria-pressed={live && !voice.micMuted}\n className=\"aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30\"\n disabled={!live && !connecting && disabled}\n onClick={() => {\n if (connecting) voice.end();\n else if (live) voice.setMicMuted(!voice.micMuted);\n else void voice.start();\n }}\n >\n {connecting ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : live ? (\n voice.micMuted ? (\n <MicOffIcon className=\"size-4\" />\n ) : (\n <MicIcon className=\"size-4\" />\n )\n ) : (\n <HeadphonesIcon className=\"size-4\" />\n )}\n </TooltipIconButton>\n );\n}\n\nexport function ChatVoiceStatus({ voice }: { voice: UseAthenaChatVoiceReturn }) {\n const elapsed = useVoiceElapsed(voice.liveSince);\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n if (!active && !voice.error && !voice.handoffTask) return null;\n return (\n <div className=\"aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground\">\n {active && (\n <div className=\"flex items-center justify-between gap-2\" role=\"status\">\n <span>\n {voice.phase === 'connecting'\n ? 'Connecting voice…'\n : `Voice ${voice.micMuted ? 'muted' : 'live'}${elapsed ? ` · ${elapsed}` : ''}`}\n </span>\n <TooltipIconButton\n type=\"button\"\n tooltip=\"End voice session\"\n aria-label=\"End voice session\"\n onClick={voice.end}\n >\n <PhoneOffIcon className=\"size-3.5\" />\n </TooltipIconButton>\n </div>\n )}\n {voice.phase === 'live' && <span>{VOICE_LIVE_TYPED_HINT}</span>}\n {voice.activeTask && <span>Athena is working: {voice.activeTask.text}</span>}\n {voice.handoffTask && (\n <span>Voice ended. Athena is still working: {voice.handoffTask.text}</span>\n )}\n {voice.notice && <span role=\"status\">{voice.notice}</span>}\n {voice.error && (\n <span role=\"alert\" className=\"text-destructive\">\n {voice.error}\n </span>\n )}\n </div>\n );\n}\n"],"names":["useAui","useMentionAuth","useCatalogPrincipal","useChatVoiceEnabled","useRef","useMemo","createDeepAgentVoiceLiveKitAdapter","useAthenaChatVoice","athenaDiagnostics","credentialFingerprint","useEffect","jsx","TooltipIconButton","Loader2Icon","MicOffIcon","MicIcon","HeadphonesIcon","useVoiceElapsed","jsxs","PhoneOffIcon","VOICE_LIVE_TYPED_HINT"],"mappings":"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"}
1
+ {"version":3,"file":"chat-voice-controls.cjs","sources":["../../src/chat/chat-voice-controls.tsx"],"sourcesContent":["import { useAui } from '@assistant-ui/react';\nimport {\n describeVoiceLiveElsewhere,\n playVoiceMoveEarcon,\n useVoiceElapsed,\n useVoiceMovedNotice,\n VOICE_CONTINUE_BY_VOICE_LABEL,\n VOICE_LIVE_TYPED_HINT,\n VOICE_MOVE_CALL_HERE_LABEL,\n VOICE_MOVE_HERE_ACTION,\n} from '@athenaintel/agent-runtime';\nimport { HeadphonesIcon, Loader2Icon, MicIcon, MicOffIcon, PhoneIcon, XIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { createDeepAgentVoiceLiveKitAdapter } from '../voice/livekit';\nimport {\n useAthenaChatVoice,\n type UseAthenaChatVoiceOptions,\n type UseAthenaChatVoiceReturn,\n} from '../voice/chat';\nimport { useChatVoiceEnabled } from '../voice/use-chat-voice-enabled';\nimport { cn } from '../lib/utils';\nimport { Button } from '../ui/button';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { useMentionAuth } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { credentialFingerprint, useCatalogPrincipal } from '../catalog/runtime-catalog';\n\n/**\n * `onCallMoved` replaces the move earcon a call plays when it moves to or\n * from this device (pass a no-op to keep it silent); by default the shared\n * one plays.\n */\nexport interface AthenaChatVoiceOptions\n extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic' | 'onCallMoved'> {}\n\n/** One controller for this composer's controls, text sends and audio sink. */\nexport function useComposerChatVoice({ options }: { options: boolean | AthenaChatVoiceOptions }) {\n const aui = useAui();\n const auth = useMentionAuth();\n const principal = useCatalogPrincipal();\n const enabled = useChatVoiceEnabled({ enabled: options !== false });\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const media = useMemo(\n () => createDeepAgentVoiceLiveKitAdapter({ audioElement: () => audioRef.current }),\n []\n );\n const config = typeof options === 'object' ? options : undefined;\n const voice = useAthenaChatVoice({\n transport: 'livekit',\n livekit: config?.livekit ?? media,\n model: config?.model,\n onDiagnostic:\n config?.onDiagnostic ??\n ((entry) => athenaDiagnostics.emit('voice.chat', { data: { ...entry } })),\n onCallMoved: config?.onCallMoved ?? playVoiceMoveEarcon,\n });\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n const { end, syncProfile } = voice;\n const identity = JSON.stringify([\n auth.backendUrl,\n principal,\n auth.apiKey ? credentialFingerprint({ credential: auth.apiKey }) : null,\n ]);\n const previousScope = useRef({ identity, workspaceId: auth.workspaceId });\n useEffect(() => {\n const previous = previousScope.current;\n const changed =\n previous.identity !== identity ||\n Boolean(\n previous.workspaceId && auth.workspaceId && previous.workspaceId !== auth.workspaceId\n );\n previousScope.current = {\n identity,\n workspaceId:\n previous.identity === identity\n ? auth.workspaceId ?? previous.workspaceId\n : auth.workspaceId,\n };\n if (active && (changed || !enabled)) end();\n }, [identity, auth.workspaceId, active, enabled, end]);\n\n // Model/agent/toolkit/mode picks live in the ambient model context. Read it\n // through the controller at send time, with the same debounce as other hosts.\n const live = voice.phase === 'live';\n useEffect(() => {\n if (!live) return;\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(syncProfile, 800);\n };\n schedule();\n const unsubscribe = aui.modelContext.subscribe?.(schedule);\n return () => {\n clearTimeout(timer);\n unsubscribe?.();\n };\n }, [aui, live, syncProfile]);\n return { voice, enabled, active, audioRef };\n}\n\nexport function ChatVoiceButton({\n voice,\n disabled,\n disabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n disabled: boolean;\n /**\n * Why a voice session can't start now (Athena can't be reached): shown as the tooltip of a\n * control that stays focusable and starts nothing. A session already connecting or live keeps its\n * Cancel and Mute.\n */\n disabledReason?: string | null;\n}) {\n const live = voice.phase === 'live';\n const connecting = voice.phase === 'connecting';\n const unavailable = Boolean(disabledReason) && !live && !connecting;\n // The conversation's call is live on another of the person's devices.\n const moveHere = !live && !connecting && voice.liveElsewhere !== null;\n const label = connecting\n ? 'Cancel voice connection'\n : live\n ? voice.micMuted\n ? 'Unmute microphone'\n : 'Mute microphone'\n : moveHere\n ? VOICE_MOVE_CALL_HERE_LABEL\n : 'Start voice session';\n return (\n <TooltipIconButton\n type=\"button\"\n tooltip={unavailable && disabledReason ? disabledReason : label}\n aria-label={label}\n aria-pressed={live && !voice.micMuted}\n aria-disabled={unavailable || undefined}\n data-unavailable={unavailable || undefined}\n className={cn(\n 'aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30',\n unavailable && 'cursor-not-allowed opacity-30 hover:bg-transparent',\n )}\n disabled={!unavailable && !live && !connecting && disabled}\n onClick={() => {\n if (unavailable) return;\n if (connecting) voice.end();\n else if (live) voice.setMicMuted(!voice.micMuted);\n else if (moveHere) void voice.transferHere();\n else void voice.start();\n }}\n >\n {connecting ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : live ? (\n voice.micMuted ? (\n <MicOffIcon className=\"size-4\" />\n ) : (\n <MicIcon className=\"size-4\" />\n )\n ) : moveHere ? (\n <PhoneIcon className=\"size-4\" />\n ) : (\n <HeadphonesIcon className=\"size-4\" />\n )}\n </TooltipIconButton>\n );\n}\n\n/**\n * A host's \"Continue by voice\" offer for the open conversation: a handover the\n * person sent in voice mode landed here. `onDone` runs once they answer it —\n * took it, dismissed it, or typed instead — so the host clears the offer.\n */\nexport interface AthenaChatContinueByVoice {\n onDone: () => void;\n}\n\n/**\n * The one-tap \"Continue by voice\" above the composer: it starts a call whose\n * model opens by saying where things stand. Shown while voice is idle here and\n * no call is live on another of the person's devices (\"Move here\" covers that).\n * Nothing starts the microphone without the tap.\n */\nexport function ChatVoiceContinueOffer({\n voice,\n offer,\n disabled = false,\n disabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n offer: AthenaChatContinueByVoice | null;\n /** Starting would capture the microphone now (dictation, an upload, no channel). */\n disabled?: boolean;\n /** Why voice can't start now (Athena can't be reached), as the action's tooltip. */\n disabledReason?: string | null;\n}) {\n if (!offer || voice.phase !== 'idle' || voice.liveElsewhere !== null) return null;\n return (\n <div className=\"aui-chat-voice-continue flex items-center gap-1 px-2 pb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"xs\"\n title={disabledReason ?? undefined}\n disabled={disabled || Boolean(disabledReason)}\n onClick={() => {\n offer.onDone();\n void voice.start({ opening: 'recap' });\n }}\n >\n <MicIcon aria-hidden=\"true\" />\n {VOICE_CONTINUE_BY_VOICE_LABEL}\n </Button>\n <TooltipIconButton\n type=\"button\"\n tooltip=\"Not now\"\n aria-label=\"Not now\"\n className=\"size-6 rounded-md p-0\"\n onClick={offer.onDone}\n >\n <XIcon className=\"size-3\" />\n </TooltipIconButton>\n </div>\n );\n}\n\nexport function ChatVoiceStatus({\n voice,\n offerMove = false,\n moveDisabled = false,\n moveDisabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n /** Whether this composer may take a call from another device (its voice is enabled). */\n offerMove?: boolean;\n /** Moving the call here would capture the microphone now (dictation, an upload, no channel). */\n moveDisabled?: boolean;\n /** Why the call can't move here now (Athena can't be reached), as the action's tooltip. */\n moveDisabledReason?: string | null;\n}) {\n const elapsed = useVoiceElapsed(voice.liveSince);\n const movedNotice = useVoiceMovedNotice(voice.movedTo);\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n // \"Live call on your phone · Move here\", or briefly after this composer's call moved away,\n // \"Call moved to your phone\".\n const elsewhere = offerMove && !active && movedNotice === null ? voice.liveElsewhere : null;\n if (!active && !voice.error && !voice.handoffTask && movedNotice === null && elsewhere === null)\n return null;\n const moveUnavailable = moveDisabled || Boolean(moveDisabledReason);\n return (\n <div className=\"aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground\">\n {/* No end control of its own: the composer's Stop ends the session\n (and any run), so there is one way to stop everything. */}\n {active && (\n <span role=\"status\">\n {voice.phase === 'connecting'\n ? 'Connecting voice…'\n : `Voice ${voice.micMuted ? 'muted' : 'live'}${elapsed ? ` · ${elapsed}` : ''}`}\n </span>\n )}\n {voice.phase === 'live' && <span>{VOICE_LIVE_TYPED_HINT}</span>}\n {voice.activeTask && <span>Athena is working: {voice.activeTask.text}</span>}\n {voice.handoffTask && (\n <span>Voice ended. Athena is still working: {voice.handoffTask.text}</span>\n )}\n {voice.notice && <span role=\"status\">{voice.notice}</span>}\n {voice.error && (\n <span role=\"alert\" className=\"text-destructive\">\n {voice.error}\n </span>\n )}\n {movedNotice !== null && <span role=\"status\">{movedNotice}</span>}\n {elsewhere !== null && (\n <span className=\"aui-chat-voice-elsewhere flex items-center gap-1\">\n <span className=\"min-w-0 truncate\">{describeVoiceLiveElsewhere(elsewhere.surface)}</span>\n <span aria-hidden=\"true\">·</span>\n <button\n type=\"button\"\n title={moveDisabledReason ?? undefined}\n disabled={moveUnavailable}\n onClick={() => void voice.transferHere()}\n className=\"shrink-0 font-medium text-foreground underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {VOICE_MOVE_HERE_ACTION}\n </button>\n </span>\n )}\n </div>\n );\n}\n"],"names":["useAui","useMentionAuth","useCatalogPrincipal","useChatVoiceEnabled","useRef","useMemo","createDeepAgentVoiceLiveKitAdapter","useAthenaChatVoice","athenaDiagnostics","playVoiceMoveEarcon","credentialFingerprint","useEffect","VOICE_MOVE_CALL_HERE_LABEL","jsx","TooltipIconButton","cn","Loader2Icon","MicOffIcon","MicIcon","PhoneIcon","HeadphonesIcon","jsxs","Button","VOICE_CONTINUE_BY_VOICE_LABEL","XIcon","useVoiceElapsed","useVoiceMovedNotice","VOICE_LIVE_TYPED_HINT","describeVoiceLiveElsewhere","VOICE_MOVE_HERE_ACTION"],"mappings":"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"}
@@ -1,5 +1,10 @@
1
1
  import { type UseAthenaChatVoiceOptions, type UseAthenaChatVoiceReturn } from '../voice/chat';
2
- export interface AthenaChatVoiceOptions extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic'> {
2
+ /**
3
+ * `onCallMoved` replaces the move earcon a call plays when it moves to or
4
+ * from this device (pass a no-op to keep it silent); by default the shared
5
+ * one plays.
6
+ */
7
+ export interface AthenaChatVoiceOptions extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic' | 'onCallMoved'> {
3
8
  }
4
9
  /** One controller for this composer's controls, text sends and audio sink. */
5
10
  export declare function useComposerChatVoice({ options }: {
@@ -10,10 +15,44 @@ export declare function useComposerChatVoice({ options }: {
10
15
  active: boolean;
11
16
  audioRef: import("react").RefObject<HTMLAudioElement | null>;
12
17
  };
13
- export declare function ChatVoiceButton({ voice, disabled, }: {
18
+ export declare function ChatVoiceButton({ voice, disabled, disabledReason, }: {
14
19
  voice: UseAthenaChatVoiceReturn;
15
20
  disabled: boolean;
21
+ /**
22
+ * Why a voice session can't start now (Athena can't be reached): shown as the tooltip of a
23
+ * control that stays focusable and starts nothing. A session already connecting or live keeps its
24
+ * Cancel and Mute.
25
+ */
26
+ disabledReason?: string | null;
16
27
  }): import("react").JSX.Element;
17
- export declare function ChatVoiceStatus({ voice }: {
28
+ /**
29
+ * A host's "Continue by voice" offer for the open conversation: a handover the
30
+ * person sent in voice mode landed here. `onDone` runs once they answer it —
31
+ * took it, dismissed it, or typed instead — so the host clears the offer.
32
+ */
33
+ export interface AthenaChatContinueByVoice {
34
+ onDone: () => void;
35
+ }
36
+ /**
37
+ * The one-tap "Continue by voice" above the composer: it starts a call whose
38
+ * model opens by saying where things stand. Shown while voice is idle here and
39
+ * no call is live on another of the person's devices ("Move here" covers that).
40
+ * Nothing starts the microphone without the tap.
41
+ */
42
+ export declare function ChatVoiceContinueOffer({ voice, offer, disabled, disabledReason, }: {
43
+ voice: UseAthenaChatVoiceReturn;
44
+ offer: AthenaChatContinueByVoice | null;
45
+ /** Starting would capture the microphone now (dictation, an upload, no channel). */
46
+ disabled?: boolean;
47
+ /** Why voice can't start now (Athena can't be reached), as the action's tooltip. */
48
+ disabledReason?: string | null;
49
+ }): import("react").JSX.Element | null;
50
+ export declare function ChatVoiceStatus({ voice, offerMove, moveDisabled, moveDisabledReason, }: {
18
51
  voice: UseAthenaChatVoiceReturn;
52
+ /** Whether this composer may take a call from another device (its voice is enabled). */
53
+ offerMove?: boolean;
54
+ /** Moving the call here would capture the microphone now (dictation, an upload, no channel). */
55
+ moveDisabled?: boolean;
56
+ /** Why the call can't move here now (Athena can't be reached), as the action's tooltip. */
57
+ moveDisabledReason?: string | null;
19
58
  }): import("react").JSX.Element | null;
@@ -1,15 +1,18 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useAui } from "@assistant-ui/react";
3
- import { Loader2Icon, MicOffIcon, MicIcon, HeadphonesIcon, PhoneOffIcon } from "lucide-react";
3
+ import { Loader2Icon, MicOffIcon, MicIcon, PhoneIcon, HeadphonesIcon, XIcon } from "lucide-react";
4
4
  import { useRef, useMemo, useEffect } from "react";
5
5
  import { athenaDiagnostics } from "../diagnostics/athena-diagnostics.js";
6
6
  import { createDeepAgentVoiceLiveKitAdapter } from "../voice/livekit.js";
7
- import { useDeepAgentVoice, useVoiceElapsed } from "../agent-runtime/src/use-deep-agent-voice.js";
7
+ import { useDeepAgentVoice, VOICE_MOVE_CALL_HERE_LABEL, useVoiceElapsed, useVoiceMovedNotice, describeVoiceLiveElsewhere, VOICE_MOVE_HERE_ACTION, VOICE_CONTINUE_BY_VOICE_LABEL } from "../agent-runtime/src/use-deep-agent-voice.js";
8
8
  import { useChatVoiceEnabled } from "../voice/use-chat-voice-enabled.js";
9
+ import { Button } from "../ui/button.js";
9
10
  import { TooltipIconButton } from "./tooltip-icon-button.js";
10
11
  import { useMentionAuth } from "../chat-ui/mentions/suggestions/data/api-client.js";
11
12
  import { useCatalogPrincipal, credentialFingerprint } from "../catalog/runtime-catalog.js";
13
+ import { playVoiceMoveEarcon } from "../agent-runtime/src/voice-earcon.js";
12
14
  import { VOICE_LIVE_TYPED_HINT } from "../agent-runtime/src/voice-presentation.js";
15
+ import { cn } from "cnfast";
13
16
  function useComposerChatVoice({ options }) {
14
17
  const aui = useAui();
15
18
  const auth = useMentionAuth();
@@ -25,7 +28,8 @@ function useComposerChatVoice({ options }) {
25
28
  transport: "livekit",
26
29
  livekit: (config == null ? void 0 : config.livekit) ?? media,
27
30
  model: config == null ? void 0 : config.model,
28
- onDiagnostic: (config == null ? void 0 : config.onDiagnostic) ?? ((entry) => athenaDiagnostics.emit("voice.chat", { data: { ...entry } }))
31
+ onDiagnostic: (config == null ? void 0 : config.onDiagnostic) ?? ((entry) => athenaDiagnostics.emit("voice.chat", { data: { ...entry } })),
32
+ onCallMoved: (config == null ? void 0 : config.onCallMoved) ?? playVoiceMoveEarcon
29
33
  });
30
34
  const active = voice.phase === "connecting" || voice.phase === "live";
31
35
  const { end, syncProfile } = voice;
@@ -66,47 +70,93 @@ function useComposerChatVoice({ options }) {
66
70
  }
67
71
  function ChatVoiceButton({
68
72
  voice,
69
- disabled
73
+ disabled,
74
+ disabledReason = null
70
75
  }) {
71
76
  const live = voice.phase === "live";
72
77
  const connecting = voice.phase === "connecting";
73
- const label = connecting ? "Cancel voice connection" : live ? voice.micMuted ? "Unmute microphone" : "Mute microphone" : "Start voice session";
78
+ const unavailable = Boolean(disabledReason) && !live && !connecting;
79
+ const moveHere = !live && !connecting && voice.liveElsewhere !== null;
80
+ const label = connecting ? "Cancel voice connection" : live ? voice.micMuted ? "Unmute microphone" : "Mute microphone" : moveHere ? VOICE_MOVE_CALL_HERE_LABEL : "Start voice session";
74
81
  return /* @__PURE__ */ jsx(
75
82
  TooltipIconButton,
76
83
  {
77
84
  type: "button",
78
- tooltip: label,
85
+ tooltip: unavailable && disabledReason ? disabledReason : label,
79
86
  "aria-label": label,
80
87
  "aria-pressed": live && !voice.micMuted,
81
- className: "aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30",
82
- disabled: !live && !connecting && disabled,
88
+ "aria-disabled": unavailable || void 0,
89
+ "data-unavailable": unavailable || void 0,
90
+ className: cn(
91
+ "aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30",
92
+ unavailable && "cursor-not-allowed opacity-30 hover:bg-transparent"
93
+ ),
94
+ disabled: !unavailable && !live && !connecting && disabled,
83
95
  onClick: () => {
96
+ if (unavailable) return;
84
97
  if (connecting) voice.end();
85
98
  else if (live) voice.setMicMuted(!voice.micMuted);
99
+ else if (moveHere) void voice.transferHere();
86
100
  else void voice.start();
87
101
  },
88
- children: connecting ? /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin" }) : live ? voice.micMuted ? /* @__PURE__ */ jsx(MicOffIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(MicIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(HeadphonesIcon, { className: "size-4" })
102
+ children: connecting ? /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin" }) : live ? voice.micMuted ? /* @__PURE__ */ jsx(MicOffIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(MicIcon, { className: "size-4" }) : moveHere ? /* @__PURE__ */ jsx(PhoneIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(HeadphonesIcon, { className: "size-4" })
89
103
  }
90
104
  );
91
105
  }
92
- function ChatVoiceStatus({ voice }) {
106
+ function ChatVoiceContinueOffer({
107
+ voice,
108
+ offer,
109
+ disabled = false,
110
+ disabledReason = null
111
+ }) {
112
+ if (!offer || voice.phase !== "idle" || voice.liveElsewhere !== null) return null;
113
+ return /* @__PURE__ */ jsxs("div", { className: "aui-chat-voice-continue flex items-center gap-1 px-2 pb-2", children: [
114
+ /* @__PURE__ */ jsxs(
115
+ Button,
116
+ {
117
+ type: "button",
118
+ variant: "outline",
119
+ size: "xs",
120
+ title: disabledReason ?? void 0,
121
+ disabled: disabled || Boolean(disabledReason),
122
+ onClick: () => {
123
+ offer.onDone();
124
+ void voice.start({ opening: "recap" });
125
+ },
126
+ children: [
127
+ /* @__PURE__ */ jsx(MicIcon, { "aria-hidden": "true" }),
128
+ VOICE_CONTINUE_BY_VOICE_LABEL
129
+ ]
130
+ }
131
+ ),
132
+ /* @__PURE__ */ jsx(
133
+ TooltipIconButton,
134
+ {
135
+ type: "button",
136
+ tooltip: "Not now",
137
+ "aria-label": "Not now",
138
+ className: "size-6 rounded-md p-0",
139
+ onClick: offer.onDone,
140
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-3" })
141
+ }
142
+ )
143
+ ] });
144
+ }
145
+ function ChatVoiceStatus({
146
+ voice,
147
+ offerMove = false,
148
+ moveDisabled = false,
149
+ moveDisabledReason = null
150
+ }) {
93
151
  const elapsed = useVoiceElapsed(voice.liveSince);
152
+ const movedNotice = useVoiceMovedNotice(voice.movedTo);
94
153
  const active = voice.phase === "connecting" || voice.phase === "live";
95
- if (!active && !voice.error && !voice.handoffTask) return null;
154
+ const elsewhere = offerMove && !active && movedNotice === null ? voice.liveElsewhere : null;
155
+ if (!active && !voice.error && !voice.handoffTask && movedNotice === null && elsewhere === null)
156
+ return null;
157
+ const moveUnavailable = moveDisabled || Boolean(moveDisabledReason);
96
158
  return /* @__PURE__ */ jsxs("div", { className: "aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground", children: [
97
- active && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", role: "status", children: [
98
- /* @__PURE__ */ jsx("span", { children: voice.phase === "connecting" ? "Connecting voice…" : `Voice ${voice.micMuted ? "muted" : "live"}${elapsed ? ` · ${elapsed}` : ""}` }),
99
- /* @__PURE__ */ jsx(
100
- TooltipIconButton,
101
- {
102
- type: "button",
103
- tooltip: "End voice session",
104
- "aria-label": "End voice session",
105
- onClick: voice.end,
106
- children: /* @__PURE__ */ jsx(PhoneOffIcon, { className: "size-3.5" })
107
- }
108
- )
109
- ] }),
159
+ active && /* @__PURE__ */ jsx("span", { role: "status", children: voice.phase === "connecting" ? "Connecting voice…" : `Voice ${voice.micMuted ? "muted" : "live"}${elapsed ? ` · ${elapsed}` : ""}` }),
110
160
  voice.phase === "live" && /* @__PURE__ */ jsx("span", { children: VOICE_LIVE_TYPED_HINT }),
111
161
  voice.activeTask && /* @__PURE__ */ jsxs("span", { children: [
112
162
  "Athena is working: ",
@@ -117,11 +167,28 @@ function ChatVoiceStatus({ voice }) {
117
167
  voice.handoffTask.text
118
168
  ] }),
119
169
  voice.notice && /* @__PURE__ */ jsx("span", { role: "status", children: voice.notice }),
120
- voice.error && /* @__PURE__ */ jsx("span", { role: "alert", className: "text-destructive", children: voice.error })
170
+ voice.error && /* @__PURE__ */ jsx("span", { role: "alert", className: "text-destructive", children: voice.error }),
171
+ movedNotice !== null && /* @__PURE__ */ jsx("span", { role: "status", children: movedNotice }),
172
+ elsewhere !== null && /* @__PURE__ */ jsxs("span", { className: "aui-chat-voice-elsewhere flex items-center gap-1", children: [
173
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: describeVoiceLiveElsewhere(elsewhere.surface) }),
174
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "·" }),
175
+ /* @__PURE__ */ jsx(
176
+ "button",
177
+ {
178
+ type: "button",
179
+ title: moveDisabledReason ?? void 0,
180
+ disabled: moveUnavailable,
181
+ onClick: () => void voice.transferHere(),
182
+ className: "shrink-0 font-medium text-foreground underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50",
183
+ children: VOICE_MOVE_HERE_ACTION
184
+ }
185
+ )
186
+ ] })
121
187
  ] });
122
188
  }
123
189
  export {
124
190
  ChatVoiceButton,
191
+ ChatVoiceContinueOffer,
125
192
  ChatVoiceStatus,
126
193
  useComposerChatVoice
127
194
  };
@@ -1 +1 @@
1
- {"version":3,"file":"chat-voice-controls.js","sources":["../../src/chat/chat-voice-controls.tsx"],"sourcesContent":["import { useAui } from '@assistant-ui/react';\nimport { useVoiceElapsed, VOICE_LIVE_TYPED_HINT } from '@athenaintel/agent-runtime';\nimport { HeadphonesIcon, Loader2Icon, MicIcon, MicOffIcon, PhoneOffIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { createDeepAgentVoiceLiveKitAdapter } from '../voice/livekit';\nimport {\n useAthenaChatVoice,\n type UseAthenaChatVoiceOptions,\n type UseAthenaChatVoiceReturn,\n} from '../voice/chat';\nimport { useChatVoiceEnabled } from '../voice/use-chat-voice-enabled';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { useMentionAuth } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { credentialFingerprint, useCatalogPrincipal } from '../catalog/runtime-catalog';\n\nexport interface AthenaChatVoiceOptions\n extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic'> {}\n\n/** One controller for this composer's controls, text sends and audio sink. */\nexport function useComposerChatVoice({ options }: { options: boolean | AthenaChatVoiceOptions }) {\n const aui = useAui();\n const auth = useMentionAuth();\n const principal = useCatalogPrincipal();\n const enabled = useChatVoiceEnabled({ enabled: options !== false });\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const media = useMemo(\n () => createDeepAgentVoiceLiveKitAdapter({ audioElement: () => audioRef.current }),\n []\n );\n const config = typeof options === 'object' ? options : undefined;\n const voice = useAthenaChatVoice({\n transport: 'livekit',\n livekit: config?.livekit ?? media,\n model: config?.model,\n onDiagnostic:\n config?.onDiagnostic ??\n ((entry) => athenaDiagnostics.emit('voice.chat', { data: { ...entry } })),\n });\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n const { end, syncProfile } = voice;\n const identity = JSON.stringify([\n auth.backendUrl,\n principal,\n auth.apiKey ? credentialFingerprint({ credential: auth.apiKey }) : null,\n ]);\n const previousScope = useRef({ identity, workspaceId: auth.workspaceId });\n useEffect(() => {\n const previous = previousScope.current;\n const changed =\n previous.identity !== identity ||\n Boolean(\n previous.workspaceId && auth.workspaceId && previous.workspaceId !== auth.workspaceId\n );\n previousScope.current = {\n identity,\n workspaceId:\n previous.identity === identity\n ? auth.workspaceId ?? previous.workspaceId\n : auth.workspaceId,\n };\n if (active && (changed || !enabled)) end();\n }, [identity, auth.workspaceId, active, enabled, end]);\n\n // Model/agent/toolkit/mode picks live in the ambient model context. Read it\n // through the controller at send time, with the same debounce as other hosts.\n const live = voice.phase === 'live';\n useEffect(() => {\n if (!live) return;\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(syncProfile, 800);\n };\n schedule();\n const unsubscribe = aui.modelContext.subscribe?.(schedule);\n return () => {\n clearTimeout(timer);\n unsubscribe?.();\n };\n }, [aui, live, syncProfile]);\n return { voice, enabled, active, audioRef };\n}\n\nexport function ChatVoiceButton({\n voice,\n disabled,\n}: {\n voice: UseAthenaChatVoiceReturn;\n disabled: boolean;\n}) {\n const live = voice.phase === 'live';\n const connecting = voice.phase === 'connecting';\n const label = connecting\n ? 'Cancel voice connection'\n : live\n ? voice.micMuted\n ? 'Unmute microphone'\n : 'Mute microphone'\n : 'Start voice session';\n return (\n <TooltipIconButton\n type=\"button\"\n tooltip={label}\n aria-label={label}\n aria-pressed={live && !voice.micMuted}\n className=\"aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30\"\n disabled={!live && !connecting && disabled}\n onClick={() => {\n if (connecting) voice.end();\n else if (live) voice.setMicMuted(!voice.micMuted);\n else void voice.start();\n }}\n >\n {connecting ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : live ? (\n voice.micMuted ? (\n <MicOffIcon className=\"size-4\" />\n ) : (\n <MicIcon className=\"size-4\" />\n )\n ) : (\n <HeadphonesIcon className=\"size-4\" />\n )}\n </TooltipIconButton>\n );\n}\n\nexport function ChatVoiceStatus({ voice }: { voice: UseAthenaChatVoiceReturn }) {\n const elapsed = useVoiceElapsed(voice.liveSince);\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n if (!active && !voice.error && !voice.handoffTask) return null;\n return (\n <div className=\"aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground\">\n {active && (\n <div className=\"flex items-center justify-between gap-2\" role=\"status\">\n <span>\n {voice.phase === 'connecting'\n ? 'Connecting voice…'\n : `Voice ${voice.micMuted ? 'muted' : 'live'}${elapsed ? ` · ${elapsed}` : ''}`}\n </span>\n <TooltipIconButton\n type=\"button\"\n tooltip=\"End voice session\"\n aria-label=\"End voice session\"\n onClick={voice.end}\n >\n <PhoneOffIcon className=\"size-3.5\" />\n </TooltipIconButton>\n </div>\n )}\n {voice.phase === 'live' && <span>{VOICE_LIVE_TYPED_HINT}</span>}\n {voice.activeTask && <span>Athena is working: {voice.activeTask.text}</span>}\n {voice.handoffTask && (\n <span>Voice ended. Athena is still working: {voice.handoffTask.text}</span>\n )}\n {voice.notice && <span role=\"status\">{voice.notice}</span>}\n {voice.error && (\n <span role=\"alert\" className=\"text-destructive\">\n {voice.error}\n </span>\n )}\n </div>\n );\n}\n"],"names":["useAthenaChatVoice"],"mappings":"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"}
1
+ {"version":3,"file":"chat-voice-controls.js","sources":["../../src/chat/chat-voice-controls.tsx"],"sourcesContent":["import { useAui } from '@assistant-ui/react';\nimport {\n describeVoiceLiveElsewhere,\n playVoiceMoveEarcon,\n useVoiceElapsed,\n useVoiceMovedNotice,\n VOICE_CONTINUE_BY_VOICE_LABEL,\n VOICE_LIVE_TYPED_HINT,\n VOICE_MOVE_CALL_HERE_LABEL,\n VOICE_MOVE_HERE_ACTION,\n} from '@athenaintel/agent-runtime';\nimport { HeadphonesIcon, Loader2Icon, MicIcon, MicOffIcon, PhoneIcon, XIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { athenaDiagnostics } from '../diagnostics/athena-diagnostics';\nimport { createDeepAgentVoiceLiveKitAdapter } from '../voice/livekit';\nimport {\n useAthenaChatVoice,\n type UseAthenaChatVoiceOptions,\n type UseAthenaChatVoiceReturn,\n} from '../voice/chat';\nimport { useChatVoiceEnabled } from '../voice/use-chat-voice-enabled';\nimport { cn } from '../lib/utils';\nimport { Button } from '../ui/button';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { useMentionAuth } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { credentialFingerprint, useCatalogPrincipal } from '../catalog/runtime-catalog';\n\n/**\n * `onCallMoved` replaces the move earcon a call plays when it moves to or\n * from this device (pass a no-op to keep it silent); by default the shared\n * one plays.\n */\nexport interface AthenaChatVoiceOptions\n extends Pick<UseAthenaChatVoiceOptions, 'model' | 'livekit' | 'onDiagnostic' | 'onCallMoved'> {}\n\n/** One controller for this composer's controls, text sends and audio sink. */\nexport function useComposerChatVoice({ options }: { options: boolean | AthenaChatVoiceOptions }) {\n const aui = useAui();\n const auth = useMentionAuth();\n const principal = useCatalogPrincipal();\n const enabled = useChatVoiceEnabled({ enabled: options !== false });\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const media = useMemo(\n () => createDeepAgentVoiceLiveKitAdapter({ audioElement: () => audioRef.current }),\n []\n );\n const config = typeof options === 'object' ? options : undefined;\n const voice = useAthenaChatVoice({\n transport: 'livekit',\n livekit: config?.livekit ?? media,\n model: config?.model,\n onDiagnostic:\n config?.onDiagnostic ??\n ((entry) => athenaDiagnostics.emit('voice.chat', { data: { ...entry } })),\n onCallMoved: config?.onCallMoved ?? playVoiceMoveEarcon,\n });\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n const { end, syncProfile } = voice;\n const identity = JSON.stringify([\n auth.backendUrl,\n principal,\n auth.apiKey ? credentialFingerprint({ credential: auth.apiKey }) : null,\n ]);\n const previousScope = useRef({ identity, workspaceId: auth.workspaceId });\n useEffect(() => {\n const previous = previousScope.current;\n const changed =\n previous.identity !== identity ||\n Boolean(\n previous.workspaceId && auth.workspaceId && previous.workspaceId !== auth.workspaceId\n );\n previousScope.current = {\n identity,\n workspaceId:\n previous.identity === identity\n ? auth.workspaceId ?? previous.workspaceId\n : auth.workspaceId,\n };\n if (active && (changed || !enabled)) end();\n }, [identity, auth.workspaceId, active, enabled, end]);\n\n // Model/agent/toolkit/mode picks live in the ambient model context. Read it\n // through the controller at send time, with the same debounce as other hosts.\n const live = voice.phase === 'live';\n useEffect(() => {\n if (!live) return;\n let timer: ReturnType<typeof setTimeout>;\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(syncProfile, 800);\n };\n schedule();\n const unsubscribe = aui.modelContext.subscribe?.(schedule);\n return () => {\n clearTimeout(timer);\n unsubscribe?.();\n };\n }, [aui, live, syncProfile]);\n return { voice, enabled, active, audioRef };\n}\n\nexport function ChatVoiceButton({\n voice,\n disabled,\n disabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n disabled: boolean;\n /**\n * Why a voice session can't start now (Athena can't be reached): shown as the tooltip of a\n * control that stays focusable and starts nothing. A session already connecting or live keeps its\n * Cancel and Mute.\n */\n disabledReason?: string | null;\n}) {\n const live = voice.phase === 'live';\n const connecting = voice.phase === 'connecting';\n const unavailable = Boolean(disabledReason) && !live && !connecting;\n // The conversation's call is live on another of the person's devices.\n const moveHere = !live && !connecting && voice.liveElsewhere !== null;\n const label = connecting\n ? 'Cancel voice connection'\n : live\n ? voice.micMuted\n ? 'Unmute microphone'\n : 'Mute microphone'\n : moveHere\n ? VOICE_MOVE_CALL_HERE_LABEL\n : 'Start voice session';\n return (\n <TooltipIconButton\n type=\"button\"\n tooltip={unavailable && disabledReason ? disabledReason : label}\n aria-label={label}\n aria-pressed={live && !voice.micMuted}\n aria-disabled={unavailable || undefined}\n data-unavailable={unavailable || undefined}\n className={cn(\n 'aui-composer-voice size-8 rounded-full p-0 disabled:opacity-30',\n unavailable && 'cursor-not-allowed opacity-30 hover:bg-transparent',\n )}\n disabled={!unavailable && !live && !connecting && disabled}\n onClick={() => {\n if (unavailable) return;\n if (connecting) voice.end();\n else if (live) voice.setMicMuted(!voice.micMuted);\n else if (moveHere) void voice.transferHere();\n else void voice.start();\n }}\n >\n {connecting ? (\n <Loader2Icon className=\"size-4 animate-spin\" />\n ) : live ? (\n voice.micMuted ? (\n <MicOffIcon className=\"size-4\" />\n ) : (\n <MicIcon className=\"size-4\" />\n )\n ) : moveHere ? (\n <PhoneIcon className=\"size-4\" />\n ) : (\n <HeadphonesIcon className=\"size-4\" />\n )}\n </TooltipIconButton>\n );\n}\n\n/**\n * A host's \"Continue by voice\" offer for the open conversation: a handover the\n * person sent in voice mode landed here. `onDone` runs once they answer it —\n * took it, dismissed it, or typed instead — so the host clears the offer.\n */\nexport interface AthenaChatContinueByVoice {\n onDone: () => void;\n}\n\n/**\n * The one-tap \"Continue by voice\" above the composer: it starts a call whose\n * model opens by saying where things stand. Shown while voice is idle here and\n * no call is live on another of the person's devices (\"Move here\" covers that).\n * Nothing starts the microphone without the tap.\n */\nexport function ChatVoiceContinueOffer({\n voice,\n offer,\n disabled = false,\n disabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n offer: AthenaChatContinueByVoice | null;\n /** Starting would capture the microphone now (dictation, an upload, no channel). */\n disabled?: boolean;\n /** Why voice can't start now (Athena can't be reached), as the action's tooltip. */\n disabledReason?: string | null;\n}) {\n if (!offer || voice.phase !== 'idle' || voice.liveElsewhere !== null) return null;\n return (\n <div className=\"aui-chat-voice-continue flex items-center gap-1 px-2 pb-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"xs\"\n title={disabledReason ?? undefined}\n disabled={disabled || Boolean(disabledReason)}\n onClick={() => {\n offer.onDone();\n void voice.start({ opening: 'recap' });\n }}\n >\n <MicIcon aria-hidden=\"true\" />\n {VOICE_CONTINUE_BY_VOICE_LABEL}\n </Button>\n <TooltipIconButton\n type=\"button\"\n tooltip=\"Not now\"\n aria-label=\"Not now\"\n className=\"size-6 rounded-md p-0\"\n onClick={offer.onDone}\n >\n <XIcon className=\"size-3\" />\n </TooltipIconButton>\n </div>\n );\n}\n\nexport function ChatVoiceStatus({\n voice,\n offerMove = false,\n moveDisabled = false,\n moveDisabledReason = null,\n}: {\n voice: UseAthenaChatVoiceReturn;\n /** Whether this composer may take a call from another device (its voice is enabled). */\n offerMove?: boolean;\n /** Moving the call here would capture the microphone now (dictation, an upload, no channel). */\n moveDisabled?: boolean;\n /** Why the call can't move here now (Athena can't be reached), as the action's tooltip. */\n moveDisabledReason?: string | null;\n}) {\n const elapsed = useVoiceElapsed(voice.liveSince);\n const movedNotice = useVoiceMovedNotice(voice.movedTo);\n const active = voice.phase === 'connecting' || voice.phase === 'live';\n // \"Live call on your phone · Move here\", or briefly after this composer's call moved away,\n // \"Call moved to your phone\".\n const elsewhere = offerMove && !active && movedNotice === null ? voice.liveElsewhere : null;\n if (!active && !voice.error && !voice.handoffTask && movedNotice === null && elsewhere === null)\n return null;\n const moveUnavailable = moveDisabled || Boolean(moveDisabledReason);\n return (\n <div className=\"aui-chat-voice-status flex flex-col gap-1 px-2 pb-2 text-xs text-muted-foreground\">\n {/* No end control of its own: the composer's Stop ends the session\n (and any run), so there is one way to stop everything. */}\n {active && (\n <span role=\"status\">\n {voice.phase === 'connecting'\n ? 'Connecting voice…'\n : `Voice ${voice.micMuted ? 'muted' : 'live'}${elapsed ? ` · ${elapsed}` : ''}`}\n </span>\n )}\n {voice.phase === 'live' && <span>{VOICE_LIVE_TYPED_HINT}</span>}\n {voice.activeTask && <span>Athena is working: {voice.activeTask.text}</span>}\n {voice.handoffTask && (\n <span>Voice ended. Athena is still working: {voice.handoffTask.text}</span>\n )}\n {voice.notice && <span role=\"status\">{voice.notice}</span>}\n {voice.error && (\n <span role=\"alert\" className=\"text-destructive\">\n {voice.error}\n </span>\n )}\n {movedNotice !== null && <span role=\"status\">{movedNotice}</span>}\n {elsewhere !== null && (\n <span className=\"aui-chat-voice-elsewhere flex items-center gap-1\">\n <span className=\"min-w-0 truncate\">{describeVoiceLiveElsewhere(elsewhere.surface)}</span>\n <span aria-hidden=\"true\">·</span>\n <button\n type=\"button\"\n title={moveDisabledReason ?? undefined}\n disabled={moveUnavailable}\n onClick={() => void voice.transferHere()}\n className=\"shrink-0 font-medium text-foreground underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {VOICE_MOVE_HERE_ACTION}\n </button>\n </span>\n )}\n </div>\n );\n}\n"],"names":["useAthenaChatVoice"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const cnfast = require("cnfast");
6
6
  const COMPOSER_HINT_SEEN_STORAGE_KEY = "athena-sdk:composer-hint-seen";
7
7
  function readHintSeen() {
@@ -18,14 +18,14 @@ function writeHintSeen() {
18
18
  }
19
19
  }
20
20
  function useComposerKeyboardHint() {
21
- const [visible, setVisible] = react.useState(false);
22
- const visibleRef = react.useRef(false);
23
- const onFocus = react.useCallback(() => {
21
+ const [visible, setVisible] = require$$0.useState(false);
22
+ const visibleRef = require$$0.useRef(false);
23
+ const onFocus = require$$0.useCallback(() => {
24
24
  if (visibleRef.current || readHintSeen()) return;
25
25
  visibleRef.current = true;
26
26
  setVisible(true);
27
27
  }, []);
28
- const onSubmitted = react.useCallback(() => {
28
+ const onSubmitted = require$$0.useCallback(() => {
29
29
  if (!visibleRef.current) return;
30
30
  writeHintSeen();
31
31
  visibleRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"composer-keyboard-hint.cjs","sources":["../../src/chat/composer-keyboard-hint.tsx"],"sourcesContent":["import { useCallback, useRef, useState, type FC } from 'react';\nimport { cn } from '../lib/utils';\n\n/**\n * Browser-local marker that the viewer has seen the Enter / Shift+Enter hint.\n * Namespaced so a host page's own storage keys cannot collide with it.\n */\nexport const COMPOSER_HINT_SEEN_STORAGE_KEY = 'athena-sdk:composer-hint-seen';\n\nexport const COMPOSER_KEYBOARD_HINT_TEXT = 'Enter to send · Shift+Enter for a new line';\n\nfunction readHintSeen(): boolean {\n try {\n return window.localStorage.getItem(COMPOSER_HINT_SEEN_STORAGE_KEY) === '1';\n } catch {\n // Storage can be denied (sandboxed iframes, privacy modes); treat as\n // unseen — the hint shows once more, which costs nothing.\n return false;\n }\n}\n\nfunction writeHintSeen(): void {\n try {\n window.localStorage.setItem(COMPOSER_HINT_SEEN_STORAGE_KEY, '1');\n } catch {\n // Same denial as above: the hint simply shows again next time.\n }\n}\n\nexport interface ComposerKeyboardHintController {\n /** Whether the hint is showing right now. */\n visible: boolean;\n /**\n * Attach to the composer's focus (React `onFocus` on a wrapper receives\n * the editor's focus, since it is delivered as `focusin`). Shows the hint\n * the first time the composer is focused in a browser that has not seen it.\n */\n onFocus: () => void;\n /** Call once a draft was sent: hides the hint and records it as seen. */\n onSubmitted: () => void;\n}\n\n/**\n * The one-time \"Enter to send · Shift+Enter for a new line\" hint: appears\n * under the composer on its first focus in this browser and stays until the\n * first send, which records it as seen (`localStorage`) so it never returns.\n * A send made before the composer was ever focused (a suggestion card) leaves\n * the hint unshown and unrecorded, so typing later still gets the hint.\n */\nexport function useComposerKeyboardHint(): ComposerKeyboardHintController {\n const [visible, setVisible] = useState(false);\n // Mirrors `visible` for the handlers, which run outside render.\n const visibleRef = useRef(false);\n\n const onFocus = useCallback(() => {\n if (visibleRef.current || readHintSeen()) return;\n visibleRef.current = true;\n setVisible(true);\n }, []);\n\n const onSubmitted = useCallback(() => {\n if (!visibleRef.current) return;\n writeHintSeen();\n visibleRef.current = false;\n setVisible(false);\n }, []);\n\n return { visible, onFocus, onSubmitted };\n}\n\nconst KEY_CLASS =\n 'rounded border border-border/70 bg-muted/60 px-1 py-px font-sans text-[10px] text-foreground/70';\n\nexport interface ComposerKeyboardHintProps {\n visible: boolean;\n className?: string;\n}\n\n/** The hint row under the composer surface; renders nothing while hidden. */\nexport const ComposerKeyboardHint: FC<ComposerKeyboardHintProps> = ({ visible, className }) => {\n if (!visible) return null;\n return (\n <p\n className={cn(\n 'aui-composer-hint animate-in fade-in fill-mode-both px-3 pt-1.5 text-[11px] leading-4 text-muted-foreground motion-reduce:animate-none',\n className,\n )}\n data-testid=\"athena-composer-keyboard-hint\"\n >\n <kbd className={KEY_CLASS}>Enter</kbd> to send · <kbd className={KEY_CLASS}>Shift</kbd>+\n <kbd className={KEY_CLASS}>Enter</kbd> for a new line\n </p>\n );\n};\n"],"names":["useState","useRef","useCallback","jsxs","cn","jsx"],"mappings":";;;;;AAOO,MAAM,iCAAiC;AAI9C,SAAS,eAAwB;AAC/B,MAAI;AACF,WAAO,OAAO,aAAa,QAAQ,8BAA8B,MAAM;AAAA,EACzE,QAAQ;AAGN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAsB;AAC7B,MAAI;AACF,WAAO,aAAa,QAAQ,gCAAgC,GAAG;AAAA,EACjE,QAAQ;AAAA,EAER;AACF;AAsBO,SAAS,0BAA0D;AACxE,QAAM,CAAC,SAAS,UAAU,IAAIA,MAAAA,SAAS,KAAK;AAE5C,QAAM,aAAaC,MAAAA,OAAO,KAAK;AAE/B,QAAM,UAAUC,MAAAA,YAAY,MAAM;AAChC,QAAI,WAAW,WAAW,eAAgB;AAC1C,eAAW,UAAU;AACrB,eAAW,IAAI;AAAA,EACjB,GAAG,CAAA,CAAE;AAEL,QAAM,cAAcA,MAAAA,YAAY,MAAM;AACpC,QAAI,CAAC,WAAW,QAAS;AACzB,kBAAA;AACA,eAAW,UAAU;AACrB,eAAW,KAAK;AAAA,EAClB,GAAG,CAAA,CAAE;AAEL,SAAO,EAAE,SAAS,SAAS,YAAA;AAC7B;AAEA,MAAM,YACJ;AAQK,MAAM,uBAAsD,CAAC,EAAE,SAAS,gBAAgB;AAC7F,MAAI,CAAC,QAAS,QAAO;AACrB,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,OAAAA;AAAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,eAAY;AAAA,MAEZ,UAAA;AAAA,QAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,QAAWA,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,QACvFA,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG5C;;;;"}
1
+ {"version":3,"file":"composer-keyboard-hint.cjs","sources":["../../src/chat/composer-keyboard-hint.tsx"],"sourcesContent":["import { useCallback, useRef, useState, type FC } from 'react';\nimport { cn } from '../lib/utils';\n\n/**\n * Browser-local marker that the viewer has seen the Enter / Shift+Enter hint.\n * Namespaced so a host page's own storage keys cannot collide with it.\n */\nexport const COMPOSER_HINT_SEEN_STORAGE_KEY = 'athena-sdk:composer-hint-seen';\n\nexport const COMPOSER_KEYBOARD_HINT_TEXT = 'Enter to send · Shift+Enter for a new line';\n\nfunction readHintSeen(): boolean {\n try {\n return window.localStorage.getItem(COMPOSER_HINT_SEEN_STORAGE_KEY) === '1';\n } catch {\n // Storage can be denied (sandboxed iframes, privacy modes); treat as\n // unseen — the hint shows once more, which costs nothing.\n return false;\n }\n}\n\nfunction writeHintSeen(): void {\n try {\n window.localStorage.setItem(COMPOSER_HINT_SEEN_STORAGE_KEY, '1');\n } catch {\n // Same denial as above: the hint simply shows again next time.\n }\n}\n\nexport interface ComposerKeyboardHintController {\n /** Whether the hint is showing right now. */\n visible: boolean;\n /**\n * Attach to the composer's focus (React `onFocus` on a wrapper receives\n * the editor's focus, since it is delivered as `focusin`). Shows the hint\n * the first time the composer is focused in a browser that has not seen it.\n */\n onFocus: () => void;\n /** Call once a draft was sent: hides the hint and records it as seen. */\n onSubmitted: () => void;\n}\n\n/**\n * The one-time \"Enter to send · Shift+Enter for a new line\" hint: appears\n * under the composer on its first focus in this browser and stays until the\n * first send, which records it as seen (`localStorage`) so it never returns.\n * A send made before the composer was ever focused (a suggestion card) leaves\n * the hint unshown and unrecorded, so typing later still gets the hint.\n */\nexport function useComposerKeyboardHint(): ComposerKeyboardHintController {\n const [visible, setVisible] = useState(false);\n // Mirrors `visible` for the handlers, which run outside render.\n const visibleRef = useRef(false);\n\n const onFocus = useCallback(() => {\n if (visibleRef.current || readHintSeen()) return;\n visibleRef.current = true;\n setVisible(true);\n }, []);\n\n const onSubmitted = useCallback(() => {\n if (!visibleRef.current) return;\n writeHintSeen();\n visibleRef.current = false;\n setVisible(false);\n }, []);\n\n return { visible, onFocus, onSubmitted };\n}\n\nconst KEY_CLASS =\n 'rounded border border-border/70 bg-muted/60 px-1 py-px font-sans text-[10px] text-foreground/70';\n\nexport interface ComposerKeyboardHintProps {\n visible: boolean;\n className?: string;\n}\n\n/** The hint row under the composer surface; renders nothing while hidden. */\nexport const ComposerKeyboardHint: FC<ComposerKeyboardHintProps> = ({ visible, className }) => {\n if (!visible) return null;\n return (\n <p\n className={cn(\n 'aui-composer-hint animate-in fade-in fill-mode-both px-3 pt-1.5 text-[11px] leading-4 text-muted-foreground motion-reduce:animate-none',\n className,\n )}\n data-testid=\"athena-composer-keyboard-hint\"\n >\n <kbd className={KEY_CLASS}>Enter</kbd> to send · <kbd className={KEY_CLASS}>Shift</kbd>+\n <kbd className={KEY_CLASS}>Enter</kbd> for a new line\n </p>\n );\n};\n"],"names":["useState","useRef","useCallback","jsxs","cn","jsx"],"mappings":";;;;;AAOO,MAAM,iCAAiC;AAI9C,SAAS,eAAwB;AAC/B,MAAI;AACF,WAAO,OAAO,aAAa,QAAQ,8BAA8B,MAAM;AAAA,EACzE,QAAQ;AAGN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAsB;AAC7B,MAAI;AACF,WAAO,aAAa,QAAQ,gCAAgC,GAAG;AAAA,EACjE,QAAQ;AAAA,EAER;AACF;AAsBO,SAAS,0BAA0D;AACxE,QAAM,CAAC,SAAS,UAAU,IAAIA,WAAAA,SAAS,KAAK;AAE5C,QAAM,aAAaC,WAAAA,OAAO,KAAK;AAE/B,QAAM,UAAUC,WAAAA,YAAY,MAAM;AAChC,QAAI,WAAW,WAAW,eAAgB;AAC1C,eAAW,UAAU;AACrB,eAAW,IAAI;AAAA,EACjB,GAAG,CAAA,CAAE;AAEL,QAAM,cAAcA,WAAAA,YAAY,MAAM;AACpC,QAAI,CAAC,WAAW,QAAS;AACzB,kBAAA;AACA,eAAW,UAAU;AACrB,eAAW,KAAK;AAAA,EAClB,GAAG,CAAA,CAAE;AAEL,SAAO,EAAE,SAAS,SAAS,YAAA;AAC7B;AAEA,MAAM,YACJ;AAQK,MAAM,uBAAsD,CAAC,EAAE,SAAS,gBAAgB;AAC7F,MAAI,CAAC,QAAS,QAAO;AACrB,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,OAAAA;AAAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAEF,eAAY;AAAA,MAEZ,UAAA;AAAA,QAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,QAAWA,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,QACvFA,2BAAAA,IAAC,OAAA,EAAI,WAAW,WAAW,UAAA,SAAK;AAAA,QAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG5C;;;;"}