@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
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaLayout.cjs","sources":["../../src/assets/AthenaLayout.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type FC,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../lib/utils\";\nimport {\n WorkbenchLayoutContext,\n type WorkbenchLayoutState,\n} from \"../workbench/workbench-layout-context\";\nimport { useAssetPanelStore } from \"./asset-panel-store\";\nimport { AssetPanel } from \"./AssetPanel\";\n\nexport interface AthenaLayoutProps {\n children: ReactNode;\n /** Default width (%) of the chat panel when assets are open. Defaults to 50. */\n defaultChatPercent?: number;\n /** Minimum width (%) of each panel. Defaults to 25. */\n minPercent?: number;\n /**\n * A right-hand workspace column beside the chat — typically\n * `<SessionWorkbench />`. It is always shown (collapsible to a rail,\n * maximizable over the chat, and resizable by its edge), and the assets the agent or the person opens\n * render inside it as its \"Open assets\" tab instead of in a column of their\n * own.\n */\n workbench?: ReactNode;\n /** Default width (%) of the workbench column. Defaults to 40. */\n defaultWorkbenchPercent?: number;\n /**\n * Whether a session's workbench starts collapsed to its rail. Each session\n * keeps its own open or collapsed workbench while the layout stays mounted,\n * as it keeps its own tabs, so this is how every session the person has not\n * opened it in shows it — a new one, or one switched to. Defaults to `false`.\n */\n defaultWorkbenchCollapsed?: boolean;\n}\n\n/** Drag-to-resize for a split: the pointer's x as a share of the container. */\nfunction useSplitDrag({\n onPercent,\n}: {\n /** Called with the pointer's x position as a percentage of the container width. */\n onPercent: (percentFromLeft: number) => void;\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n const dragging = useRef(false);\n const onPointerDown = useCallback((e: React.PointerEvent) => {\n e.preventDefault();\n dragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n }, []);\n const onPointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!dragging.current || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n onPercent(((e.clientX - rect.left) / rect.width) * 100);\n },\n [onPercent],\n );\n const onPointerUp = useCallback(() => {\n dragging.current = false;\n }, []);\n return { containerRef, handlers: { onPointerDown, onPointerMove, onPointerUp } };\n}\n\nconst RESIZE_HANDLE_CLASS =\n \"athena-sdk-chrome flex h-full w-1 shrink-0 cursor-col-resize items-center bg-border/40 transition-colors hover:bg-border active:bg-primary/30\";\n\n/**\n * Layout that places the chat on the left and the asset panel on the right.\n * When no assets are open, the chat takes full width. Includes a draggable resize handle.\n * With `workbench`, the right-hand column is the workbench instead (see the prop).\n */\nexport const AthenaLayout: FC<AthenaLayoutProps> = ({ workbench, ...props }) => {\n const registerAssetPanelHost = useAssetPanelStore((s) => s.registerAssetPanelHost);\n const unregisterAssetPanelHost = useAssetPanelStore((s) => s.unregisterAssetPanelHost);\n\n useEffect(() => {\n registerAssetPanelHost();\n return () => {\n unregisterAssetPanelHost();\n };\n }, [registerAssetPanelHost, unregisterAssetPanelHost]);\n\n return workbench === undefined || workbench === null ? (\n <AssetSplitLayout {...props} />\n ) : (\n <WorkbenchSplitLayout {...props} workbench={workbench} />\n );\n};\n\nconst AssetSplitLayout: FC<Omit<AthenaLayoutProps, \"workbench\">> = ({\n children,\n defaultChatPercent = 50,\n minPercent = 25,\n}) => {\n const isOpen = useAssetPanelStore((s) => s.isOpen);\n const [chatPercent, setChatPercent] = useState(defaultChatPercent);\n const { containerRef, handlers } = useSplitDrag({\n onPercent: useCallback(\n (pct: number) => setChatPercent(Math.max(minPercent, Math.min(100 - minPercent, pct))),\n [minPercent],\n ),\n });\n\n if (!isOpen) {\n return <div className=\"flex h-full w-full flex-col\">{children}</div>;\n }\n\n return (\n <div ref={containerRef} className=\"flex h-full w-full\">\n <div\n className=\"flex h-full flex-col overflow-hidden\"\n style={{ width: `${chatPercent}%` }}\n >\n {children}\n </div>\n <div className={RESIZE_HANDLE_CLASS} {...handlers} />\n <div className=\"athena-sdk-chrome flex h-full flex-1 flex-col overflow-hidden\">\n <AssetPanel manageAssetPanelHostRegistration={false} />\n </div>\n </div>\n );\n};\n\nconst WorkbenchSplitLayout: FC<\n Omit<AthenaLayoutProps, \"workbench\" | \"defaultChatPercent\"> & { workbench: ReactNode }\n> = ({\n children,\n workbench,\n minPercent = 25,\n defaultWorkbenchPercent = 40,\n defaultWorkbenchCollapsed = false,\n}) => {\n const [workbenchPercent, setWorkbenchPercent] = useState(defaultWorkbenchPercent);\n const [collapsed, setCollapsedState] = useState(defaultWorkbenchCollapsed);\n const [maximizedState, setMaximizedState] = useState(false);\n // A rail is never maximized: collapsing restores the chat beside it.\n const maximized = maximizedState && !collapsed;\n const setCollapsed = useCallback((next: boolean) => {\n setCollapsedState(next);\n if (next) setMaximizedState(false);\n }, []);\n const setMaximized = useCallback((next: boolean) => {\n setMaximizedState(next);\n if (next) setCollapsedState(false);\n }, []);\n const { containerRef, handlers } = useSplitDrag({\n onPercent: useCallback(\n (pct: number) =>\n setWorkbenchPercent(Math.max(minPercent, Math.min(100 - minPercent, 100 - pct))),\n [minPercent],\n ),\n });\n const layoutState = useMemo<WorkbenchLayoutState>(\n () => ({\n collapsed,\n setCollapsed,\n defaultCollapsed: defaultWorkbenchCollapsed,\n maximized,\n setMaximized,\n hostsAssetPanel: true,\n }),\n [collapsed, defaultWorkbenchCollapsed, maximized, setCollapsed, setMaximized],\n );\n\n return (\n <div ref={containerRef} className=\"flex h-full w-full\">\n {/* Hidden, not unmounted, while the workbench is maximized: the chat keeps its thread and draft. */}\n <div\n className={cn(\"flex h-full min-w-0 flex-1 flex-col overflow-hidden\", maximized && \"hidden\")}\n >\n {children}\n </div>\n {collapsed || maximized ? null : (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize workspace\"\n className={RESIZE_HANDLE_CLASS}\n {...handlers}\n />\n )}\n <div\n className={cn(\n \"flex h-full shrink-0 flex-col overflow-hidden\",\n collapsed && \"w-10\",\n maximized && \"min-w-0 flex-1\",\n )}\n // The dragged width is a runtime percentage — no static utility expresses it.\n style={collapsed || maximized ? undefined : { width: `${workbenchPercent}%` }}\n >\n <WorkbenchLayoutContext.Provider value={layoutState}>\n {workbench}\n </WorkbenchLayoutContext.Provider>\n </div>\n </div>\n );\n};\n"],"names":["useRef","useCallback","useAssetPanelStore","useEffect","jsx","useState","jsxs","AssetPanel","useMemo","cn","WorkbenchLayoutContext"],"mappings":"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"}
1
+ {"version":3,"file":"AthenaLayout.cjs","sources":["../../src/assets/AthenaLayout.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type FC,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../lib/utils\";\nimport {\n WorkbenchLayoutContext,\n type WorkbenchLayoutState,\n} from \"../workbench/workbench-layout-context\";\nimport { useAssetPanelStore } from \"./asset-panel-store\";\nimport { AssetPanel } from \"./AssetPanel\";\n\nexport interface AthenaLayoutProps {\n children: ReactNode;\n /** Default width (%) of the chat panel when assets are open. Defaults to 50. */\n defaultChatPercent?: number;\n /** Minimum width (%) of each panel. Defaults to 25. */\n minPercent?: number;\n /**\n * A right-hand workspace column beside the chat — typically\n * `<SessionWorkbench />`. It is always shown (collapsible to a rail,\n * maximizable over the chat, and resizable by its edge), and the assets the agent or the person opens\n * render inside it as its \"Open assets\" tab instead of in a column of their\n * own.\n */\n workbench?: ReactNode;\n /** Default width (%) of the workbench column. Defaults to 40. */\n defaultWorkbenchPercent?: number;\n /**\n * Whether a session's workbench starts collapsed to its rail. Each session\n * keeps its own open or collapsed workbench while the layout stays mounted,\n * as it keeps its own tabs, so this is how every session the person has not\n * opened it in shows it — a new one, or one switched to. Defaults to `false`.\n */\n defaultWorkbenchCollapsed?: boolean;\n}\n\n/** Drag-to-resize for a split: the pointer's x as a share of the container. */\nfunction useSplitDrag({\n onPercent,\n}: {\n /** Called with the pointer's x position as a percentage of the container width. */\n onPercent: (percentFromLeft: number) => void;\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n const dragging = useRef(false);\n const onPointerDown = useCallback((e: React.PointerEvent) => {\n e.preventDefault();\n dragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n }, []);\n const onPointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!dragging.current || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n onPercent(((e.clientX - rect.left) / rect.width) * 100);\n },\n [onPercent],\n );\n const onPointerUp = useCallback(() => {\n dragging.current = false;\n }, []);\n return { containerRef, handlers: { onPointerDown, onPointerMove, onPointerUp } };\n}\n\nconst RESIZE_HANDLE_CLASS =\n \"athena-sdk-chrome flex h-full w-1 shrink-0 cursor-col-resize items-center bg-border/40 transition-colors hover:bg-border active:bg-primary/30\";\n\n/**\n * Layout that places the chat on the left and the asset panel on the right.\n * When no assets are open, the chat takes full width. Includes a draggable resize handle.\n * With `workbench`, the right-hand column is the workbench instead (see the prop).\n */\nexport const AthenaLayout: FC<AthenaLayoutProps> = ({ workbench, ...props }) => {\n const registerAssetPanelHost = useAssetPanelStore((s) => s.registerAssetPanelHost);\n const unregisterAssetPanelHost = useAssetPanelStore((s) => s.unregisterAssetPanelHost);\n\n useEffect(() => {\n registerAssetPanelHost();\n return () => {\n unregisterAssetPanelHost();\n };\n }, [registerAssetPanelHost, unregisterAssetPanelHost]);\n\n return workbench === undefined || workbench === null ? (\n <AssetSplitLayout {...props} />\n ) : (\n <WorkbenchSplitLayout {...props} workbench={workbench} />\n );\n};\n\nconst AssetSplitLayout: FC<Omit<AthenaLayoutProps, \"workbench\">> = ({\n children,\n defaultChatPercent = 50,\n minPercent = 25,\n}) => {\n const isOpen = useAssetPanelStore((s) => s.isOpen);\n const [chatPercent, setChatPercent] = useState(defaultChatPercent);\n const { containerRef, handlers } = useSplitDrag({\n onPercent: useCallback(\n (pct: number) => setChatPercent(Math.max(minPercent, Math.min(100 - minPercent, pct))),\n [minPercent],\n ),\n });\n\n if (!isOpen) {\n return <div className=\"flex h-full w-full flex-col\">{children}</div>;\n }\n\n return (\n <div ref={containerRef} className=\"flex h-full w-full\">\n <div\n className=\"flex h-full flex-col overflow-hidden\"\n style={{ width: `${chatPercent}%` }}\n >\n {children}\n </div>\n <div className={RESIZE_HANDLE_CLASS} {...handlers} />\n <div className=\"athena-sdk-chrome flex h-full flex-1 flex-col overflow-hidden\">\n <AssetPanel manageAssetPanelHostRegistration={false} />\n </div>\n </div>\n );\n};\n\nconst WorkbenchSplitLayout: FC<\n Omit<AthenaLayoutProps, \"workbench\" | \"defaultChatPercent\"> & { workbench: ReactNode }\n> = ({\n children,\n workbench,\n minPercent = 25,\n defaultWorkbenchPercent = 40,\n defaultWorkbenchCollapsed = false,\n}) => {\n const [workbenchPercent, setWorkbenchPercent] = useState(defaultWorkbenchPercent);\n const [collapsed, setCollapsedState] = useState(defaultWorkbenchCollapsed);\n const [maximizedState, setMaximizedState] = useState(false);\n // A rail is never maximized: collapsing restores the chat beside it.\n const maximized = maximizedState && !collapsed;\n const setCollapsed = useCallback((next: boolean) => {\n setCollapsedState(next);\n if (next) setMaximizedState(false);\n }, []);\n const setMaximized = useCallback((next: boolean) => {\n setMaximizedState(next);\n if (next) setCollapsedState(false);\n }, []);\n const { containerRef, handlers } = useSplitDrag({\n onPercent: useCallback(\n (pct: number) =>\n setWorkbenchPercent(Math.max(minPercent, Math.min(100 - minPercent, 100 - pct))),\n [minPercent],\n ),\n });\n const layoutState = useMemo<WorkbenchLayoutState>(\n () => ({\n collapsed,\n setCollapsed,\n defaultCollapsed: defaultWorkbenchCollapsed,\n maximized,\n setMaximized,\n hostsAssetPanel: true,\n }),\n [collapsed, defaultWorkbenchCollapsed, maximized, setCollapsed, setMaximized],\n );\n\n return (\n <div ref={containerRef} className=\"flex h-full w-full\">\n {/* Hidden, not unmounted, while the workbench is maximized: the chat keeps its thread and draft. */}\n <div\n className={cn(\"flex h-full min-w-0 flex-1 flex-col overflow-hidden\", maximized && \"hidden\")}\n >\n {children}\n </div>\n {collapsed || maximized ? null : (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize workspace\"\n className={RESIZE_HANDLE_CLASS}\n {...handlers}\n />\n )}\n <div\n className={cn(\n \"flex h-full shrink-0 flex-col overflow-hidden\",\n collapsed && \"w-10\",\n maximized && \"min-w-0 flex-1\",\n )}\n // The dragged width is a runtime percentage — no static utility expresses it.\n style={collapsed || maximized ? undefined : { width: `${workbenchPercent}%` }}\n >\n <WorkbenchLayoutContext.Provider value={layoutState}>\n {workbench}\n </WorkbenchLayoutContext.Provider>\n </div>\n </div>\n );\n};\n"],"names":["useRef","useCallback","useAssetPanelStore","useEffect","jsx","useState","jsxs","AssetPanel","useMemo","cn","WorkbenchLayoutContext"],"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 reactQuery = require("@tanstack/react-query");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const mint = require("../collab/mint.cjs");
6
6
  const errors = require("../diagnostics/errors.cjs");
7
7
  const useAthenaRestQuery = require("../lib/use-athena-rest-query.cjs");
@@ -85,7 +85,7 @@ function useAthenaAssetContent({
85
85
  const { backendUrl, apiKey, getToken } = config;
86
86
  const identity = useAthenaRestQuery.useAthenaQueryIdentity({ apiKey, token: config.token, getToken });
87
87
  const queryClient = useAthenaRestQuery.useAthenaQueryClient();
88
- const reader = react.useId();
88
+ const reader = require$$0.useId();
89
89
  return reactQuery.useQuery(
90
90
  {
91
91
  queryKey: ["athena-sdk", "asset-content", backendUrl, ...identity, assetId, reader],
@@ -108,8 +108,8 @@ function useAthenaAssetContent({
108
108
  );
109
109
  }
110
110
  function useObjectUrl(blob) {
111
- const [url, setUrl] = react.useState(null);
112
- react.useEffect(() => {
111
+ const [url, setUrl] = require$$0.useState(null);
112
+ require$$0.useEffect(() => {
113
113
  if (!blob) {
114
114
  setUrl(null);
115
115
  return void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"use-asset-content.cjs","sources":["../../src/assets/use-asset-content.ts"],"sourcesContent":["/**\n * An asset's stored file, read with the signed-in user's own credential:\n * `GET /api/asset/content/{asset_id}` (agora `web/api/asset/views.py`\n * `serve_asset_content`), which passes the asset's permission check\n * (`get_asset_with_permission_check`) and streams the bytes through Agora.\n * No link is minted — no presigned storage URL, no embed token — so nothing\n * that could be opened without the credential ever exists: the bytes land in\n * a `Blob` that only this page holds, and a media element plays it through an\n * object URL (`useObjectUrl`).\n *\n * This is how the SDK plays an asset's video: a `<video src>` cannot carry\n * the `Authorization` / `X-API-KEY` header the SDK authenticates with, and the\n * alternatives (`/api/asset/fetch-presigned-url`, an `AthenaAssetEmbed` link)\n * each hand out a URL that works for whoever holds it. The whole file is read\n * before playback starts, so read it when the person asks to play, not on\n * mount.\n */\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport { useEffect, useId, useState } from 'react';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { AthenaSdkError, isAthenaSdkError } from '../diagnostics/errors';\nimport { useAthenaQueryClient, useAthenaQueryIdentity } from '../lib/use-athena-rest-query';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { sendWithCredentialRenewal } from '../runtime/credential-renewal';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/** `/api/asset/content/{asset_id}`: the asset's stored file, permission-checked. */\nexport function athenaAssetContentPath(assetId: string): string {\n return `/api/asset/content/${encodeURIComponent(assetId)}`;\n}\n\n/** A `fetch` the caller cancelled (unmount, a newer query): lifecycle, not failure. */\nfunction isAbortError(error: unknown): boolean {\n return (error instanceof DOMException || error instanceof Error) && error.name === 'AbortError';\n}\n\n/** `error` as an `asset_content_failed` SDK error; an abort or an SDK error passes through. */\nfunction assetContentError({\n error,\n assetId,\n message,\n hint,\n}: {\n error: unknown;\n assetId: string;\n message: string;\n hint: string;\n}): unknown {\n if (isAbortError(error) || isAthenaSdkError(error)) return error;\n return new AthenaSdkError({\n code: 'asset_content_failed',\n message,\n cause: error,\n hint,\n context: { assetId },\n });\n}\n\n/**\n * Read an asset's stored file as a `Blob`. The credential rides\n * `Authorization: Bearer` (resolved live through `getToken` when the host gave\n * one) or `X-API-KEY`; a refused bearer (`401`) is renewed once\n * (`sendWithCredentialRenewal`). Every failure is an `AthenaSdkError` —\n * `auth_rejected` for a 401 / 403, else `asset_content_failed` (with the HTTP\n * `status` when the server answered), a credential that could not be\n * resolved and a download cut off mid-body included; only an abort keeps its\n * own identity.\n */\nexport async function fetchAthenaAssetContent({\n backendUrl,\n auth,\n assetId,\n signal,\n}: {\n backendUrl: string;\n auth: StatewireAuthSource;\n assetId: string;\n signal?: AbortSignal;\n}): Promise<Blob> {\n const url = `${getAthenaApiBaseUrl(backendUrl)}${athenaAssetContentPath(assetId)}`;\n let response: Response;\n try {\n response = await sendWithCredentialRenewal(auth, (headers) =>\n fetch(url, { method: 'GET', headers, signal: signal ?? null }),\n );\n } catch (error) {\n throw assetContentError({\n error,\n assetId,\n message: 'Reading the asset could not reach the Agora API, or its credential could not be resolved.',\n hint: 'Check the network, that backendUrl points at the Agora API base, and that getToken resolves.',\n });\n }\n if (!response.ok) {\n const refused = response.status === 401 || response.status === 403;\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'asset_content_failed',\n message: `Reading the asset failed: ${response.status}`,\n status: response.status,\n detail: await response.json().catch(() => undefined),\n hint: refused\n ? 'The signed-in user cannot read this asset.'\n : response.status === 404\n ? 'The asset has no stored file, or it no longer exists.'\n : 'Check that backendUrl points at the Agora API base.',\n context: { assetId },\n });\n }\n try {\n return await response.blob();\n } catch (error) {\n throw assetContentError({\n error,\n assetId,\n message: 'Reading the asset failed while its file downloaded.',\n hint: 'Check the network and try again.',\n });\n }\n}\n\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([400, 401, 403, 404, 409]);\n\n/** Retry a transient failure once; a refusal or a missing file answers the same way again. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status = (error as { status?: unknown }).status;\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 1;\n}\n\nexport interface UseAthenaAssetContentOptions {\n /** The asset to read; `null` holds the query idle. */\n assetId: string | null;\n /** `false` holds the query idle (read on demand: the whole file is downloaded). Default `true`. */\n enabled?: boolean;\n}\n\n/**\n * An asset's stored file through TanStack Query, with the provider's\n * `backendUrl` and credentials. Each mounted hook reads its own copy: the key\n * carries the hook instance as well as the asset, the signed-in principal and\n * a fingerprint of the credential (`useAthenaQueryIdentity`, never the\n * credential itself), and the bytes are dropped as soon as it unmounts. So no\n * reader is ever handed bytes another mount read — not even behind a host\n * `getToken`, whose account the key cannot see — and every new reader passes\n * the permission check again. While mounted the file is read once (a stored\n * file does not change under its asset id); `refetch()` reads it again.\n */\nexport function useAthenaAssetContent({\n assetId,\n enabled = true,\n}: UseAthenaAssetContentOptions): UseQueryResult<Blob, Error> {\n const config = useAthenaConfig();\n const { backendUrl, apiKey, getToken } = config;\n const identity = useAthenaQueryIdentity({ apiKey, token: config.token, getToken });\n const queryClient = useAthenaQueryClient();\n const reader = useId();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'asset-content', backendUrl, ...identity, assetId, reader],\n // `config.token` is read at fetch time: the provider serves the latest\n // token through a getter, so rotations reach the request.\n queryFn: ({ signal }) =>\n fetchAthenaAssetContent({\n backendUrl,\n auth: { apiKey, token: config.token, getToken },\n assetId: assetId ?? '',\n signal,\n }),\n enabled: enabled && assetId !== null && assetId.length > 0 && backendUrl.length > 0,\n staleTime: Number.POSITIVE_INFINITY,\n gcTime: 0,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: retryTransient,\n },\n queryClient,\n );\n}\n\n/**\n * An object URL for `blob` while it is shown, revoked when the blob changes\n * or the component unmounts; `null` without a blob.\n */\nexport function useObjectUrl(blob: Blob | null | undefined): string | null {\n const [url, setUrl] = useState<string | null>(null);\n useEffect(() => {\n if (!blob) {\n setUrl(null);\n return undefined;\n }\n const objectUrl = URL.createObjectURL(blob);\n setUrl(objectUrl);\n return () => URL.revokeObjectURL(objectUrl);\n }, [blob]);\n return url;\n}\n"],"names":["isAthenaSdkError","AthenaSdkError","getAthenaApiBaseUrl","sendWithCredentialRenewal","useAthenaConfig","useAthenaQueryIdentity","useAthenaQueryClient","useId","useQuery","useState","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"use-asset-content.cjs","sources":["../../src/assets/use-asset-content.ts"],"sourcesContent":["/**\n * An asset's stored file, read with the signed-in user's own credential:\n * `GET /api/asset/content/{asset_id}` (agora `web/api/asset/views.py`\n * `serve_asset_content`), which passes the asset's permission check\n * (`get_asset_with_permission_check`) and streams the bytes through Agora.\n * No link is minted — no presigned storage URL, no embed token — so nothing\n * that could be opened without the credential ever exists: the bytes land in\n * a `Blob` that only this page holds, and a media element plays it through an\n * object URL (`useObjectUrl`).\n *\n * This is how the SDK plays an asset's video: a `<video src>` cannot carry\n * the `Authorization` / `X-API-KEY` header the SDK authenticates with, and the\n * alternatives (`/api/asset/fetch-presigned-url`, an `AthenaAssetEmbed` link)\n * each hand out a URL that works for whoever holds it. The whole file is read\n * before playback starts, so read it when the person asks to play, not on\n * mount.\n */\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport { useEffect, useId, useState } from 'react';\nimport { getAthenaApiBaseUrl } from '../collab/mint';\nimport { AthenaSdkError, isAthenaSdkError } from '../diagnostics/errors';\nimport { useAthenaQueryClient, useAthenaQueryIdentity } from '../lib/use-athena-rest-query';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { sendWithCredentialRenewal } from '../runtime/credential-renewal';\nimport type { StatewireAuthSource } from '../runtime/statewire-auth-headers';\n\n/** `/api/asset/content/{asset_id}`: the asset's stored file, permission-checked. */\nexport function athenaAssetContentPath(assetId: string): string {\n return `/api/asset/content/${encodeURIComponent(assetId)}`;\n}\n\n/** A `fetch` the caller cancelled (unmount, a newer query): lifecycle, not failure. */\nfunction isAbortError(error: unknown): boolean {\n return (error instanceof DOMException || error instanceof Error) && error.name === 'AbortError';\n}\n\n/** `error` as an `asset_content_failed` SDK error; an abort or an SDK error passes through. */\nfunction assetContentError({\n error,\n assetId,\n message,\n hint,\n}: {\n error: unknown;\n assetId: string;\n message: string;\n hint: string;\n}): unknown {\n if (isAbortError(error) || isAthenaSdkError(error)) return error;\n return new AthenaSdkError({\n code: 'asset_content_failed',\n message,\n cause: error,\n hint,\n context: { assetId },\n });\n}\n\n/**\n * Read an asset's stored file as a `Blob`. The credential rides\n * `Authorization: Bearer` (resolved live through `getToken` when the host gave\n * one) or `X-API-KEY`; a refused bearer (`401`) is renewed once\n * (`sendWithCredentialRenewal`). Every failure is an `AthenaSdkError` —\n * `auth_rejected` for a 401 / 403, else `asset_content_failed` (with the HTTP\n * `status` when the server answered), a credential that could not be\n * resolved and a download cut off mid-body included; only an abort keeps its\n * own identity.\n */\nexport async function fetchAthenaAssetContent({\n backendUrl,\n auth,\n assetId,\n signal,\n}: {\n backendUrl: string;\n auth: StatewireAuthSource;\n assetId: string;\n signal?: AbortSignal;\n}): Promise<Blob> {\n const url = `${getAthenaApiBaseUrl(backendUrl)}${athenaAssetContentPath(assetId)}`;\n let response: Response;\n try {\n response = await sendWithCredentialRenewal(auth, (headers) =>\n fetch(url, { method: 'GET', headers, signal: signal ?? null }),\n );\n } catch (error) {\n throw assetContentError({\n error,\n assetId,\n message: 'Reading the asset could not reach the Agora API, or its credential could not be resolved.',\n hint: 'Check the network, that backendUrl points at the Agora API base, and that getToken resolves.',\n });\n }\n if (!response.ok) {\n const refused = response.status === 401 || response.status === 403;\n throw new AthenaSdkError({\n code: refused ? 'auth_rejected' : 'asset_content_failed',\n message: `Reading the asset failed: ${response.status}`,\n status: response.status,\n detail: await response.json().catch(() => undefined),\n hint: refused\n ? 'The signed-in user cannot read this asset.'\n : response.status === 404\n ? 'The asset has no stored file, or it no longer exists.'\n : 'Check that backendUrl points at the Agora API base.',\n context: { assetId },\n });\n }\n try {\n return await response.blob();\n } catch (error) {\n throw assetContentError({\n error,\n assetId,\n message: 'Reading the asset failed while its file downloaded.',\n hint: 'Check the network and try again.',\n });\n }\n}\n\nconst NO_RETRY_STATUSES: ReadonlySet<number> = new Set([400, 401, 403, 404, 409]);\n\n/** Retry a transient failure once; a refusal or a missing file answers the same way again. */\nfunction retryTransient(failureCount: number, error: Error): boolean {\n const status = (error as { status?: unknown }).status;\n if (typeof status === 'number' && NO_RETRY_STATUSES.has(status)) return false;\n return failureCount < 1;\n}\n\nexport interface UseAthenaAssetContentOptions {\n /** The asset to read; `null` holds the query idle. */\n assetId: string | null;\n /** `false` holds the query idle (read on demand: the whole file is downloaded). Default `true`. */\n enabled?: boolean;\n}\n\n/**\n * An asset's stored file through TanStack Query, with the provider's\n * `backendUrl` and credentials. Each mounted hook reads its own copy: the key\n * carries the hook instance as well as the asset, the signed-in principal and\n * a fingerprint of the credential (`useAthenaQueryIdentity`, never the\n * credential itself), and the bytes are dropped as soon as it unmounts. So no\n * reader is ever handed bytes another mount read — not even behind a host\n * `getToken`, whose account the key cannot see — and every new reader passes\n * the permission check again. While mounted the file is read once (a stored\n * file does not change under its asset id); `refetch()` reads it again.\n */\nexport function useAthenaAssetContent({\n assetId,\n enabled = true,\n}: UseAthenaAssetContentOptions): UseQueryResult<Blob, Error> {\n const config = useAthenaConfig();\n const { backendUrl, apiKey, getToken } = config;\n const identity = useAthenaQueryIdentity({ apiKey, token: config.token, getToken });\n const queryClient = useAthenaQueryClient();\n const reader = useId();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'asset-content', backendUrl, ...identity, assetId, reader],\n // `config.token` is read at fetch time: the provider serves the latest\n // token through a getter, so rotations reach the request.\n queryFn: ({ signal }) =>\n fetchAthenaAssetContent({\n backendUrl,\n auth: { apiKey, token: config.token, getToken },\n assetId: assetId ?? '',\n signal,\n }),\n enabled: enabled && assetId !== null && assetId.length > 0 && backendUrl.length > 0,\n staleTime: Number.POSITIVE_INFINITY,\n gcTime: 0,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: retryTransient,\n },\n queryClient,\n );\n}\n\n/**\n * An object URL for `blob` while it is shown, revoked when the blob changes\n * or the component unmounts; `null` without a blob.\n */\nexport function useObjectUrl(blob: Blob | null | undefined): string | null {\n const [url, setUrl] = useState<string | null>(null);\n useEffect(() => {\n if (!blob) {\n setUrl(null);\n return undefined;\n }\n const objectUrl = URL.createObjectURL(blob);\n setUrl(objectUrl);\n return () => URL.revokeObjectURL(objectUrl);\n }, [blob]);\n return url;\n}\n"],"names":["isAthenaSdkError","AthenaSdkError","getAthenaApiBaseUrl","sendWithCredentialRenewal","useAthenaConfig","useAthenaQueryIdentity","useAthenaQueryClient","useId","useQuery","useState","useEffect"],"mappings":"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"}
@@ -1,19 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const reactQuery = require("@tanstack/react-query");
4
- const react = require("react");
4
+ const require$$0 = require("react");
5
5
  const athenaUrls = require("../lib/athena-urls.cjs");
6
6
  const useAthenaRestQuery = require("../lib/use-athena-rest-query.cjs");
7
7
  const credentialRenewal = require("../runtime/credential-renewal.cjs");
8
8
  const DEFAULT_ASSET_EMBED_READ_ONLY = false;
9
9
  const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;
10
+ const DEFAULT_ASSET_EMBED_ALLOW_COMMENTS = false;
10
11
  const DEFAULT_ASSET_EMBED_DISPLAY_MODE = "full";
11
12
  function buildAssetEmbedRequestBody({
12
13
  assetId,
13
14
  readOnly,
14
15
  expiresInSeconds,
15
16
  displayMode,
16
- allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT
17
+ allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
18
+ allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS
17
19
  }) {
18
20
  return {
19
21
  asset_id: assetId,
@@ -21,7 +23,8 @@ function buildAssetEmbedRequestBody({
21
23
  expires_in_seconds: expiresInSeconds,
22
24
  display_mode: displayMode,
23
25
  // Sent only when asked: an agora that predates it is never handed an unknown field.
24
- ...allowQuickEdit && { allow_quick_edit: true }
26
+ ...allowQuickEdit && { allow_quick_edit: true },
27
+ ...allowComments && { allow_comments: true }
25
28
  };
26
29
  }
27
30
  const embedQueryClient = new reactQuery.QueryClient();
@@ -306,15 +309,16 @@ function useAssetEmbed(assetId, options = {
306
309
  expiresInSeconds = 60 * 60 * 24 * 30,
307
310
  displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
308
311
  allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
312
+ allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS,
309
313
  backendUrl,
310
314
  appUrl,
311
315
  apiKey,
312
316
  token,
313
317
  getToken
314
318
  } = options;
315
- const tokenRef = react.useRef(token);
319
+ const tokenRef = require$$0.useRef(token);
316
320
  tokenRef.current = token;
317
- const getTokenRef = react.useRef(getToken);
321
+ const getTokenRef = require$$0.useRef(getToken);
318
322
  getTokenRef.current = getToken;
319
323
  const authContext = getAssetEmbedAuthContext({ token, apiKey });
320
324
  const enabled = Boolean(assetId && backendUrl);
@@ -327,6 +331,7 @@ function useAssetEmbed(assetId, options = {
327
331
  readOnly,
328
332
  displayMode,
329
333
  allowQuickEdit,
334
+ allowComments,
330
335
  // The identity, never the credential: an opaque token or a key is part of `authContext`.
331
336
  useAthenaRestQuery.keyPartFingerprint(authContext),
332
337
  backendUrl,
@@ -346,7 +351,8 @@ function useAssetEmbed(assetId, options = {
346
351
  readOnly,
347
352
  expiresInSeconds,
348
353
  displayMode,
349
- allowQuickEdit
354
+ allowQuickEdit,
355
+ allowComments
350
356
  })
351
357
  ),
352
358
  signal
@@ -370,7 +376,7 @@ function useAssetEmbed(assetId, options = {
370
376
  refetchOnReconnect: false,
371
377
  retry: false
372
378
  },
373
- react.useContext(reactQuery.QueryClientContext) ?? embedQueryClient
379
+ require$$0.useContext(reactQuery.QueryClientContext) ?? embedQueryClient
374
380
  );
375
381
  return {
376
382
  embedUrl: enabled ? ((_a = query.data) == null ? void 0 : _a.url) ?? null : null,
@@ -378,6 +384,7 @@ function useAssetEmbed(assetId, options = {
378
384
  error: enabled && query.error ? query.error.message : null
379
385
  };
380
386
  }
387
+ exports.DEFAULT_ASSET_EMBED_ALLOW_COMMENTS = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS;
381
388
  exports.DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT;
382
389
  exports.DEFAULT_ASSET_EMBED_DISPLAY_MODE = DEFAULT_ASSET_EMBED_DISPLAY_MODE;
383
390
  exports.DEFAULT_ASSET_EMBED_READ_ONLY = DEFAULT_ASSET_EMBED_READ_ONLY;
@@ -1 +1 @@
1
- {"version":3,"file":"use-asset-embed.cjs","sources":["../../src/assets/use-asset-embed.ts"],"sourcesContent":["import { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { deriveAthenaAppUrl } from '../lib/athena-urls';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { sendWithCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaAssetCitationReference } from './asset-embed-messages';\n\nexport interface UseAssetEmbedOptions {\n readOnly?: boolean;\n expiresInSeconds?: number;\n /** Native Olympus surface rendered by the iframe. Defaults to `full`. */\n displayMode?: 'minimal' | 'full';\n /**\n * Offer Quick Edit (⌘J, an AI rewrite of the selection) in a minimal embed, where the viewer\n * does not sign in: spreadsheets and Word documents, on an editable link (`readOnly: false`)\n * only. Its runs are billed to the asset's workspace under the link's creator, and each link has\n * its own hourly cap. The full mode's editors offer it to the signed-in person already. Defaults\n * to `false`.\n */\n allowQuickEdit?: boolean;\n}\n\nexport const DEFAULT_ASSET_EMBED_READ_ONLY = false;\nexport const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;\nexport const DEFAULT_ASSET_EMBED_DISPLAY_MODE = 'full' as const;\n\nexport interface UseAssetEmbedResult {\n embedUrl: string | null;\n isLoading: boolean;\n error: string | null;\n}\n\nexport function buildAssetEmbedRequestBody({\n assetId,\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n}: {\n assetId: string;\n readOnly: boolean;\n expiresInSeconds: number;\n displayMode: 'minimal' | 'full';\n allowQuickEdit?: boolean;\n}) {\n return {\n asset_id: assetId,\n read_only: readOnly,\n expires_in_seconds: expiresInSeconds,\n display_mode: displayMode,\n // Sent only when asked: an agora that predates it is never handed an unknown field.\n ...(allowQuickEdit && { allow_quick_edit: true }),\n };\n}\n\n/**\n * The embed links' query client when the host provides none: one for the page, so every embed of\n * one asset, mode and identity shares one minted link until it expires.\n */\nconst embedQueryClient = new QueryClient();\n\nconst ATHENA_APP_HOSTNAMES = new Set(['app.athenaintel.com', 'staging-app.athenaintel.com']);\nconst ATHENA_PREVIEW_HOSTNAME_SUFFIX = '.previews.athenaintel.com';\nconst ATHENA_WORKSPACE_HOSTNAME_PATTERN = /^.+--(\\d+)\\.(?:app\\.athenaintel\\.com|staging-app\\.athenaintel\\.com)$/;\nconst OLYMPUS_WORKSPACE_PORT = '8082';\n\nconst getUrl = (value?: string | null): URL | null => {\n if (!value) {\n return null;\n }\n\n try {\n return new URL(value);\n } catch {\n return null;\n }\n};\n\nconst getCurrentOrigin = (): string | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n return window.location.origin;\n};\n\nconst getOrigin = (value?: string | null): string | null => getUrl(value)?.origin ?? null;\n\nconst getAthenaWorkspacePort = (url: URL): string | null => {\n const match = url.hostname.toLowerCase().match(ATHENA_WORKSPACE_HOSTNAME_PATTERN);\n return match?.[1] ?? null;\n};\n\nconst isEmbedCapableAthenaHost = (url: URL): boolean => {\n const hostname = url.hostname.toLowerCase();\n\n if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX)) {\n return true;\n }\n\n return getAthenaWorkspacePort(url) === OLYMPUS_WORKSPACE_PORT;\n};\n\nconst shouldPreferDerivedEmbedAppUrl = ({\n appUrl,\n derivedAppUrl,\n currentOrigin,\n}: {\n appUrl: string;\n derivedAppUrl: string | null;\n currentOrigin?: string | null;\n}): boolean => {\n if (!derivedAppUrl) {\n return false;\n }\n\n const resolvedAppUrl = getUrl(appUrl);\n if (!resolvedAppUrl) {\n return true;\n }\n\n const workspacePort = getAthenaWorkspacePort(resolvedAppUrl);\n if (workspacePort && workspacePort !== OLYMPUS_WORKSPACE_PORT) {\n return true;\n }\n\n if (isEmbedCapableAthenaHost(resolvedAppUrl)) {\n return false;\n }\n\n const resolvedCurrentOrigin = getOrigin(currentOrigin ?? getCurrentOrigin());\n return !!resolvedCurrentOrigin && resolvedAppUrl.origin === resolvedCurrentOrigin;\n};\n\nconst resolveEmbedAppUrl = ({\n appUrl,\n backendUrl,\n currentOrigin,\n}: {\n appUrl?: string;\n backendUrl?: string | null;\n currentOrigin?: string | null;\n}): string | null => {\n const derivedAppUrl = deriveAthenaAppUrl({ backendUrl });\n\n if (!appUrl) {\n return derivedAppUrl;\n }\n\n if (shouldPreferDerivedEmbedAppUrl({ appUrl, derivedAppUrl, currentOrigin })) {\n return derivedAppUrl;\n }\n\n return appUrl;\n};\n\nexport function resolveAssetEmbedUrl({\n embedUrl,\n appUrl,\n backendUrl,\n currentOrigin,\n}: {\n embedUrl: string;\n appUrl?: string;\n backendUrl?: string | null;\n currentOrigin?: string | null;\n}): string {\n try {\n const resolvedEmbedUrl = new URL(embedUrl);\n if (!resolvedEmbedUrl.pathname.startsWith('/embed/')) {\n return embedUrl;\n }\n\n const embedAppUrl = resolveEmbedAppUrl({\n appUrl,\n backendUrl,\n currentOrigin,\n });\n if (!embedAppUrl) {\n return embedUrl;\n }\n\n const resolvedAppUrl = new URL(embedAppUrl);\n resolvedEmbedUrl.protocol = resolvedAppUrl.protocol;\n resolvedEmbedUrl.host = resolvedAppUrl.host;\n return resolvedEmbedUrl.toString();\n } catch {\n return embedUrl;\n }\n}\n\nfunction setFiniteNumberParam({ params, key, value }: { params: URLSearchParams; key: string; value: unknown }): void {\n if (typeof value === 'number' && Number.isFinite(value)) {\n params.set(key, String(value));\n }\n}\n\nfunction setNonEmptyStringParam({ params, key, value }: { params: URLSearchParams; key: string; value: unknown }): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\n/** The SDK's own embed parameter: it marks the bridge, never a place, so no anchor writes it. */\nconst SDK_BRIDGE_PARAM = 'athena_sdk_bridge';\n\n/**\n * The pairs of an anchor given as its raw query — the string an Athena link, citation or search\n * result carries (`anchor=slide&slide_index=3&slide_id=…`, `anchor=time&time=0:42`), alone or\n * after the `?` of an asset ref (`asset_x?anchor=…`) — read as URL parameters, or `null` when the\n * string holds none, or a parameter with no name. The SDK never interprets the anchor: the embed\n * page parses it with the references grammar, so every kind of place travels as written.\n */\nfunction rawAnchorQueryPairs(query: string): Array<[string, string]> | null {\n const queryIndex = query.indexOf('?');\n const search = queryIndex === -1 ? query : query.slice(queryIndex + 1);\n const pairs = [...new URLSearchParams(search)].filter(([key]) => key !== SDK_BRIDGE_PARAM);\n if (pairs.length === 0 || pairs.some(([key]) => key.length === 0)) return null;\n return pairs;\n}\n\nfunction appendRawAnchorQuery({ params, query }: { params: URLSearchParams; query: string }): void {\n const pairs = rawAnchorQueryPairs(query);\n if (!pairs) return;\n // Verbatim: a key the URL already has is replaced, and a repeated key keeps every value.\n for (const [key] of pairs) params.delete(key);\n for (const [key, value] of pairs) params.append(key, value);\n}\n\nfunction appendTypedAnchorParams({\n params,\n anchor,\n}: {\n params: URLSearchParams;\n anchor: object & { type: string };\n}): void {\n switch (anchor.type) {\n case 'page':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n break;\n case 'page_range':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'start_page',\n value: 'startPage' in anchor ? anchor.startPage : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'end_page',\n value: 'endPage' in anchor ? anchor.endPage : undefined,\n });\n break;\n case 'page_rect':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'x',\n value: 'x' in anchor ? anchor.x : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'y',\n value: 'y' in anchor ? anchor.y : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'width',\n value: 'width' in anchor ? anchor.width : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'height',\n value: 'height' in anchor ? anchor.height : undefined,\n });\n if (\n 'unit' in anchor &&\n (anchor.unit === 'percent' || anchor.unit === 'point')\n ) {\n params.set('unit', anchor.unit);\n }\n break;\n case 'page_text':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n if ('text' in anchor && typeof anchor.text === 'string') {\n params.set('text', anchor.text);\n }\n // Optional context that disambiguates a repeated phrase, and the hash of\n // the cited unit's normalized text; the embed parses both with the shared\n // `@athenaintel/references` parser.\n setNonEmptyStringParam({ params, key: 'prefix', value: 'prefix' in anchor ? anchor.prefix : undefined });\n setNonEmptyStringParam({ params, key: 'suffix', value: 'suffix' in anchor ? anchor.suffix : undefined });\n setNonEmptyStringParam({ params, key: 'hash', value: 'hash' in anchor ? anchor.hash : undefined });\n break;\n // Sheet anchors ride the same query contract the embed page parses with\n // the shared `@athenaintel/references` parser.\n case 'sheet_cell':\n case 'sheet_range':\n case 'sheet_tab':\n case 'sheet_table':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'sheet_id',\n value: 'sheetId' in anchor ? anchor.sheetId : undefined,\n });\n if ('cell' in anchor && typeof anchor.cell === 'string') {\n params.set('cell', anchor.cell);\n }\n if ('range' in anchor && typeof anchor.range === 'string') {\n params.set('range', anchor.range);\n }\n if ('tableName' in anchor && typeof anchor.tableName === 'string') {\n params.set('table_name', anchor.tableName);\n }\n if ('fallbackRange' in anchor && typeof anchor.fallbackRange === 'string') {\n params.set('fallback_range', anchor.fallbackRange);\n }\n break;\n }\n}\n\n/**\n * Writes a citation's place into an embed URL: its anchor and its excerpt (the passage the embed\n * finds by its words — alone, when the citation names no anchor). The anchor is either its raw\n * query string, forwarded as written whatever kind of place it names, or one of the typed page and\n * sheet anchors. Athena on the web's Spaces links read the same grammar, so a host that opens a\n * cited place there writes it the same way.\n */\nexport function appendCitationReferenceParams({\n params,\n reference,\n}: {\n params: URLSearchParams;\n reference?: AthenaAssetCitationReference;\n}): void {\n const anchor = reference?.anchor;\n if (typeof anchor === 'string') {\n appendRawAnchorQuery({ params, query: anchor });\n } else if (anchor && typeof anchor === 'object' && 'type' in anchor && typeof anchor.type === 'string') {\n appendTypedAnchorParams({ params, anchor: { ...anchor, type: anchor.type } });\n }\n\n const excerpt = reference?.meta?.excerpt;\n if (typeof excerpt === 'string' && excerpt) {\n params.set('excerpt', excerpt);\n }\n}\n\nexport function buildSdkAssetEmbedUrl(embedUrl: string, reference?: AthenaAssetCitationReference): string {\n try {\n const url = new URL(embedUrl);\n url.searchParams.set('athena_sdk_bridge', '1');\n appendCitationReferenceParams({ params: url.searchParams, reference });\n return url.toString();\n } catch {\n return embedUrl;\n }\n}\n\nconst getJwtPayload = (token: string): Record<string, unknown> | null => {\n try {\n const payloadSegment = token.split('.')[1];\n if (!payloadSegment || typeof atob !== 'function') return null;\n const normalized = payloadSegment.replace(/-/g, '+').replace(/_/g, '/');\n const payload: unknown = JSON.parse(\n atob(normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=')),\n );\n return payload && typeof payload === 'object' ? (payload as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n};\n\nexport function getAssetEmbedAuthContext({ token, apiKey }: { token?: string | null; apiKey?: string }): string {\n if (!token) return apiKey ? `api-key:${apiKey}` : 'anonymous';\n\n const payload = getJwtPayload(token);\n const userId = payload?.user_id ?? payload?.sub;\n if (typeof userId !== 'string' || !userId) return `opaque-token:${token}`;\n\n return `jwt:${JSON.stringify({\n issuer: payload?.iss ?? null,\n userId,\n activeOrgId: payload?.active_org_id ?? payload?.org_id ?? null,\n workspaceId: payload?.workspace_id ?? null,\n orgMemberships: payload?.org_id_to_org_member_info ?? null,\n })}`;\n}\n\n/**\n * Hook to generate an embed URL for rendering an asset in an iframe.\n * Calls the Athena embed token endpoint through TanStack Query (the host's\n * QueryClient when there is one, else the page's embed client), keyed on the\n * asset, the mode and the identity.\n *\n * Note: The auth token is read via a ref and is intentionally NOT part\n * of the query key. PropelAuth and similar providers refresh the token value\n * periodically (e.g. on window focus), but the underlying session is the\n * same — minting again on every token rotation would force the iframe to\n * reload unnecessarily. The link is minted again only when the identity\n * (user or tenant), the asset or the mode changes.\n */\nexport function useAssetEmbed(\n assetId: string | null,\n options: UseAssetEmbedOptions & {\n backendUrl: string;\n appUrl?: string;\n apiKey?: string;\n token?: string | null;\n /**\n * Live token resolver (the provider's `config.getToken`) that renews the\n * held `token`: read before the embed-token request, and asked for a\n * renewed token (`force: true`) when the backend refuses it. Ignored when\n * no token is held, so the request always authenticates as the identity\n * the embed cache is keyed on.\n */\n getToken?: AthenaStatewireTokenGetter;\n } = {\n backendUrl: '',\n },\n): UseAssetEmbedResult {\n const {\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n expiresInSeconds = 60 * 60 * 24 * 30,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n } = options;\n // Keep the latest token in a ref so the query can read it without being\n // keyed on it: PropelAuth and similar providers rotate the token value.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n // Stable across normal JWT rotations, but changes when the user or tenant\n // changes so a signed URL can never be reused across auth boundaries.\n const authContext = getAssetEmbedAuthContext({ token, apiKey });\n const enabled = Boolean(assetId && backendUrl);\n\n const query = useQuery(\n {\n queryKey: [\n 'athena-sdk',\n 'asset-embed',\n assetId,\n readOnly,\n displayMode,\n allowQuickEdit,\n // The identity, never the credential: an opaque token or a key is part of `authContext`.\n keyPartFingerprint(authContext),\n backendUrl,\n appUrl ?? '',\n ],\n queryFn: async ({ signal }): Promise<{ url: string; expiresAt: number }> => {\n // Derive the Athena API base from backendUrl before calling the embed endpoint.\n const apiBaseUrl = backendUrl.replace(/\\/api\\/assistant-ui\\/?$/, '');\n const heldToken = tokenRef.current;\n const res = await sendWithCredentialRenewal(\n { apiKey, token: heldToken, getToken: heldToken ? getTokenRef.current : undefined },\n (headers) =>\n fetch(`${apiBaseUrl}/api/embed/generate-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(\n buildAssetEmbedRequestBody({\n assetId: assetId ?? '',\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit,\n }),\n ),\n signal,\n }),\n );\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Failed to generate embed token (${res.status}): ${text}`);\n }\n const data: { embed_url: string; expires_at: number } = await res.json();\n return {\n url: resolveAssetEmbedUrl({ embedUrl: data.embed_url, appUrl, backendUrl }),\n expiresAt: data.expires_at,\n };\n },\n enabled,\n // A minted link is good until it expires; a new one would reload the frame, so it is never\n // minted again while the embed shows (no refetch on focus or reconnect) and never retried.\n staleTime: (cached) =>\n cached.state.data ? Math.max(0, cached.state.data.expiresAt * 1000 - Date.now()) : 0,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n },\n useContext(QueryClientContext) ?? embedQueryClient,\n );\n\n return {\n embedUrl: enabled ? (query.data?.url ?? null) : null,\n isLoading: enabled && query.isLoading,\n error: enabled && query.error ? query.error.message : null,\n };\n}\n"],"names":["QueryClient","deriveAthenaAppUrl","useRef","useQuery","keyPartFingerprint","sendWithCredentialRenewal","useContext","QueryClientContext"],"mappings":"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"}
1
+ {"version":3,"file":"use-asset-embed.cjs","sources":["../../src/assets/use-asset-embed.ts"],"sourcesContent":["import { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useContext, useRef } from 'react';\nimport { deriveAthenaAppUrl } from '../lib/athena-urls';\nimport { keyPartFingerprint } from '../lib/use-athena-rest-query';\nimport { sendWithCredentialRenewal } from '../runtime/credential-renewal';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaAssetCitationReference } from './asset-embed-messages';\n\nexport interface UseAssetEmbedOptions {\n /**\n * Mint a view-only link. A ceiling, not a grant: the link edits only what its creator may edit,\n * and a Word document, an Athena document, a spreadsheet, a user interface or a deck edits only\n * for a viewer who is signed in to Athena (the provider's `token`, which `AthenaAssetEmbed`\n * hands the frame). Anyone else views such a link read-only. Defaults to `false`.\n */\n readOnly?: boolean;\n expiresInSeconds?: number;\n /** Native Olympus surface rendered by the iframe. Defaults to `full`. */\n displayMode?: 'minimal' | 'full';\n /**\n * Offer Quick Edit (⌘J, an AI rewrite of the selection) in a minimal embed, which runs on the\n * link rather than an Athena sign-in: spreadsheets, Word documents and decks, on an editable\n * link (`readOnly: false`) only, and only to a viewer who is signed in to Athena (the provider's\n * `token`, which `AthenaAssetEmbed` hands the frame). Its runs are billed to the asset's\n * workspace under the link's creator, and each link has its own hourly cap. The full mode's\n * editors offer it to the signed-in person already. Defaults to `false`.\n */\n allowQuickEdit?: boolean;\n /**\n * Show the asset's comment threads, read-only, to everyone holding the link, a viewer who is not\n * signed in included. Without it, a minimal embed shows them only to a signed-in viewer who has\n * their own access to the asset (the bearer this component hands the iframe, or an Athena\n * session). No embed ever writes a comment. Defaults to `false`.\n */\n allowComments?: boolean;\n}\n\nexport const DEFAULT_ASSET_EMBED_READ_ONLY = false;\nexport const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;\nexport const DEFAULT_ASSET_EMBED_ALLOW_COMMENTS = false;\nexport const DEFAULT_ASSET_EMBED_DISPLAY_MODE = 'full' as const;\n\nexport interface UseAssetEmbedResult {\n embedUrl: string | null;\n isLoading: boolean;\n error: string | null;\n}\n\nexport function buildAssetEmbedRequestBody({\n assetId,\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS,\n}: {\n assetId: string;\n readOnly: boolean;\n expiresInSeconds: number;\n displayMode: 'minimal' | 'full';\n allowQuickEdit?: boolean;\n allowComments?: boolean;\n}) {\n return {\n asset_id: assetId,\n read_only: readOnly,\n expires_in_seconds: expiresInSeconds,\n display_mode: displayMode,\n // Sent only when asked: an agora that predates it is never handed an unknown field.\n ...(allowQuickEdit && { allow_quick_edit: true }),\n ...(allowComments && { allow_comments: true }),\n };\n}\n\n/**\n * The embed links' query client when the host provides none: one for the page, so every embed of\n * one asset, mode and identity shares one minted link until it expires.\n */\nconst embedQueryClient = new QueryClient();\n\nconst ATHENA_APP_HOSTNAMES = new Set(['app.athenaintel.com', 'staging-app.athenaintel.com']);\nconst ATHENA_PREVIEW_HOSTNAME_SUFFIX = '.previews.athenaintel.com';\nconst ATHENA_WORKSPACE_HOSTNAME_PATTERN = /^.+--(\\d+)\\.(?:app\\.athenaintel\\.com|staging-app\\.athenaintel\\.com)$/;\nconst OLYMPUS_WORKSPACE_PORT = '8082';\n\nconst getUrl = (value?: string | null): URL | null => {\n if (!value) {\n return null;\n }\n\n try {\n return new URL(value);\n } catch {\n return null;\n }\n};\n\nconst getCurrentOrigin = (): string | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n return window.location.origin;\n};\n\nconst getOrigin = (value?: string | null): string | null => getUrl(value)?.origin ?? null;\n\nconst getAthenaWorkspacePort = (url: URL): string | null => {\n const match = url.hostname.toLowerCase().match(ATHENA_WORKSPACE_HOSTNAME_PATTERN);\n return match?.[1] ?? null;\n};\n\nconst isEmbedCapableAthenaHost = (url: URL): boolean => {\n const hostname = url.hostname.toLowerCase();\n\n if (ATHENA_APP_HOSTNAMES.has(hostname) || hostname.endsWith(ATHENA_PREVIEW_HOSTNAME_SUFFIX)) {\n return true;\n }\n\n return getAthenaWorkspacePort(url) === OLYMPUS_WORKSPACE_PORT;\n};\n\nconst shouldPreferDerivedEmbedAppUrl = ({\n appUrl,\n derivedAppUrl,\n currentOrigin,\n}: {\n appUrl: string;\n derivedAppUrl: string | null;\n currentOrigin?: string | null;\n}): boolean => {\n if (!derivedAppUrl) {\n return false;\n }\n\n const resolvedAppUrl = getUrl(appUrl);\n if (!resolvedAppUrl) {\n return true;\n }\n\n const workspacePort = getAthenaWorkspacePort(resolvedAppUrl);\n if (workspacePort && workspacePort !== OLYMPUS_WORKSPACE_PORT) {\n return true;\n }\n\n if (isEmbedCapableAthenaHost(resolvedAppUrl)) {\n return false;\n }\n\n const resolvedCurrentOrigin = getOrigin(currentOrigin ?? getCurrentOrigin());\n return !!resolvedCurrentOrigin && resolvedAppUrl.origin === resolvedCurrentOrigin;\n};\n\nconst resolveEmbedAppUrl = ({\n appUrl,\n backendUrl,\n currentOrigin,\n}: {\n appUrl?: string;\n backendUrl?: string | null;\n currentOrigin?: string | null;\n}): string | null => {\n const derivedAppUrl = deriveAthenaAppUrl({ backendUrl });\n\n if (!appUrl) {\n return derivedAppUrl;\n }\n\n if (shouldPreferDerivedEmbedAppUrl({ appUrl, derivedAppUrl, currentOrigin })) {\n return derivedAppUrl;\n }\n\n return appUrl;\n};\n\nexport function resolveAssetEmbedUrl({\n embedUrl,\n appUrl,\n backendUrl,\n currentOrigin,\n}: {\n embedUrl: string;\n appUrl?: string;\n backendUrl?: string | null;\n currentOrigin?: string | null;\n}): string {\n try {\n const resolvedEmbedUrl = new URL(embedUrl);\n if (!resolvedEmbedUrl.pathname.startsWith('/embed/')) {\n return embedUrl;\n }\n\n const embedAppUrl = resolveEmbedAppUrl({\n appUrl,\n backendUrl,\n currentOrigin,\n });\n if (!embedAppUrl) {\n return embedUrl;\n }\n\n const resolvedAppUrl = new URL(embedAppUrl);\n resolvedEmbedUrl.protocol = resolvedAppUrl.protocol;\n resolvedEmbedUrl.host = resolvedAppUrl.host;\n return resolvedEmbedUrl.toString();\n } catch {\n return embedUrl;\n }\n}\n\nfunction setFiniteNumberParam({ params, key, value }: { params: URLSearchParams; key: string; value: unknown }): void {\n if (typeof value === 'number' && Number.isFinite(value)) {\n params.set(key, String(value));\n }\n}\n\nfunction setNonEmptyStringParam({ params, key, value }: { params: URLSearchParams; key: string; value: unknown }): void {\n if (typeof value === 'string' && value.length > 0) {\n params.set(key, value);\n }\n}\n\n/** The SDK's own embed parameter: it marks the bridge, never a place, so no anchor writes it. */\nconst SDK_BRIDGE_PARAM = 'athena_sdk_bridge';\n\n/**\n * The pairs of an anchor given as its raw query — the string an Athena link, citation or search\n * result carries (`anchor=slide&slide_index=3&slide_id=…`, `anchor=time&time=0:42`), alone or\n * after the `?` of an asset ref (`asset_x?anchor=…`) — read as URL parameters, or `null` when the\n * string holds none, or a parameter with no name. The SDK never interprets the anchor: the embed\n * page parses it with the references grammar, so every kind of place travels as written.\n */\nfunction rawAnchorQueryPairs(query: string): Array<[string, string]> | null {\n const queryIndex = query.indexOf('?');\n const search = queryIndex === -1 ? query : query.slice(queryIndex + 1);\n const pairs = [...new URLSearchParams(search)].filter(([key]) => key !== SDK_BRIDGE_PARAM);\n if (pairs.length === 0 || pairs.some(([key]) => key.length === 0)) return null;\n return pairs;\n}\n\nfunction appendRawAnchorQuery({ params, query }: { params: URLSearchParams; query: string }): void {\n const pairs = rawAnchorQueryPairs(query);\n if (!pairs) return;\n // Verbatim: a key the URL already has is replaced, and a repeated key keeps every value.\n for (const [key] of pairs) params.delete(key);\n for (const [key, value] of pairs) params.append(key, value);\n}\n\nfunction appendTypedAnchorParams({\n params,\n anchor,\n}: {\n params: URLSearchParams;\n anchor: object & { type: string };\n}): void {\n switch (anchor.type) {\n case 'page':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n break;\n case 'page_range':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'start_page',\n value: 'startPage' in anchor ? anchor.startPage : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'end_page',\n value: 'endPage' in anchor ? anchor.endPage : undefined,\n });\n break;\n case 'page_rect':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'x',\n value: 'x' in anchor ? anchor.x : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'y',\n value: 'y' in anchor ? anchor.y : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'width',\n value: 'width' in anchor ? anchor.width : undefined,\n });\n setFiniteNumberParam({\n params,\n key: 'height',\n value: 'height' in anchor ? anchor.height : undefined,\n });\n if (\n 'unit' in anchor &&\n (anchor.unit === 'percent' || anchor.unit === 'point')\n ) {\n params.set('unit', anchor.unit);\n }\n break;\n case 'page_text':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'page',\n value: 'page' in anchor ? anchor.page : undefined,\n });\n if ('text' in anchor && typeof anchor.text === 'string') {\n params.set('text', anchor.text);\n }\n // Optional context that disambiguates a repeated phrase, and the hash of\n // the cited unit's normalized text; the embed parses both with the shared\n // `@athenaintel/references` parser.\n setNonEmptyStringParam({ params, key: 'prefix', value: 'prefix' in anchor ? anchor.prefix : undefined });\n setNonEmptyStringParam({ params, key: 'suffix', value: 'suffix' in anchor ? anchor.suffix : undefined });\n setNonEmptyStringParam({ params, key: 'hash', value: 'hash' in anchor ? anchor.hash : undefined });\n break;\n // Sheet anchors ride the same query contract the embed page parses with\n // the shared `@athenaintel/references` parser.\n case 'sheet_cell':\n case 'sheet_range':\n case 'sheet_tab':\n case 'sheet_table':\n params.set('anchor', anchor.type);\n setFiniteNumberParam({\n params,\n key: 'sheet_id',\n value: 'sheetId' in anchor ? anchor.sheetId : undefined,\n });\n if ('cell' in anchor && typeof anchor.cell === 'string') {\n params.set('cell', anchor.cell);\n }\n if ('range' in anchor && typeof anchor.range === 'string') {\n params.set('range', anchor.range);\n }\n if ('tableName' in anchor && typeof anchor.tableName === 'string') {\n params.set('table_name', anchor.tableName);\n }\n if ('fallbackRange' in anchor && typeof anchor.fallbackRange === 'string') {\n params.set('fallback_range', anchor.fallbackRange);\n }\n break;\n }\n}\n\n/**\n * Writes a citation's place into an embed URL: its anchor and its excerpt (the passage the embed\n * finds by its words — alone, when the citation names no anchor). The anchor is either its raw\n * query string, forwarded as written whatever kind of place it names, or one of the typed page and\n * sheet anchors. Athena on the web's Spaces links read the same grammar, so a host that opens a\n * cited place there writes it the same way.\n */\nexport function appendCitationReferenceParams({\n params,\n reference,\n}: {\n params: URLSearchParams;\n reference?: AthenaAssetCitationReference;\n}): void {\n const anchor = reference?.anchor;\n if (typeof anchor === 'string') {\n appendRawAnchorQuery({ params, query: anchor });\n } else if (anchor && typeof anchor === 'object' && 'type' in anchor && typeof anchor.type === 'string') {\n appendTypedAnchorParams({ params, anchor: { ...anchor, type: anchor.type } });\n }\n\n const excerpt = reference?.meta?.excerpt;\n if (typeof excerpt === 'string' && excerpt) {\n params.set('excerpt', excerpt);\n }\n}\n\nexport function buildSdkAssetEmbedUrl(embedUrl: string, reference?: AthenaAssetCitationReference): string {\n try {\n const url = new URL(embedUrl);\n url.searchParams.set('athena_sdk_bridge', '1');\n appendCitationReferenceParams({ params: url.searchParams, reference });\n return url.toString();\n } catch {\n return embedUrl;\n }\n}\n\nconst getJwtPayload = (token: string): Record<string, unknown> | null => {\n try {\n const payloadSegment = token.split('.')[1];\n if (!payloadSegment || typeof atob !== 'function') return null;\n const normalized = payloadSegment.replace(/-/g, '+').replace(/_/g, '/');\n const payload: unknown = JSON.parse(\n atob(normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=')),\n );\n return payload && typeof payload === 'object' ? (payload as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n};\n\nexport function getAssetEmbedAuthContext({ token, apiKey }: { token?: string | null; apiKey?: string }): string {\n if (!token) return apiKey ? `api-key:${apiKey}` : 'anonymous';\n\n const payload = getJwtPayload(token);\n const userId = payload?.user_id ?? payload?.sub;\n if (typeof userId !== 'string' || !userId) return `opaque-token:${token}`;\n\n return `jwt:${JSON.stringify({\n issuer: payload?.iss ?? null,\n userId,\n activeOrgId: payload?.active_org_id ?? payload?.org_id ?? null,\n workspaceId: payload?.workspace_id ?? null,\n orgMemberships: payload?.org_id_to_org_member_info ?? null,\n })}`;\n}\n\n/**\n * Hook to generate an embed URL for rendering an asset in an iframe.\n * Calls the Athena embed token endpoint through TanStack Query (the host's\n * QueryClient when there is one, else the page's embed client), keyed on the\n * asset, the mode and the identity.\n *\n * Note: The auth token is read via a ref and is intentionally NOT part\n * of the query key. PropelAuth and similar providers refresh the token value\n * periodically (e.g. on window focus), but the underlying session is the\n * same — minting again on every token rotation would force the iframe to\n * reload unnecessarily. The link is minted again only when the identity\n * (user or tenant), the asset or the mode changes.\n */\nexport function useAssetEmbed(\n assetId: string | null,\n options: UseAssetEmbedOptions & {\n backendUrl: string;\n appUrl?: string;\n apiKey?: string;\n token?: string | null;\n /**\n * Live token resolver (the provider's `config.getToken`) that renews the\n * held `token`: read before the embed-token request, and asked for a\n * renewed token (`force: true`) when the backend refuses it. Ignored when\n * no token is held, so the request always authenticates as the identity\n * the embed cache is keyed on.\n */\n getToken?: AthenaStatewireTokenGetter;\n } = {\n backendUrl: '',\n },\n): UseAssetEmbedResult {\n const {\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n expiresInSeconds = 60 * 60 * 24 * 30,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS,\n backendUrl,\n appUrl,\n apiKey,\n token,\n getToken,\n } = options;\n // Keep the latest token in a ref so the query can read it without being\n // keyed on it: PropelAuth and similar providers rotate the token value.\n const tokenRef = useRef(token);\n tokenRef.current = token;\n const getTokenRef = useRef(getToken);\n getTokenRef.current = getToken;\n\n // Stable across normal JWT rotations, but changes when the user or tenant\n // changes so a signed URL can never be reused across auth boundaries.\n const authContext = getAssetEmbedAuthContext({ token, apiKey });\n const enabled = Boolean(assetId && backendUrl);\n\n const query = useQuery(\n {\n queryKey: [\n 'athena-sdk',\n 'asset-embed',\n assetId,\n readOnly,\n displayMode,\n allowQuickEdit,\n allowComments,\n // The identity, never the credential: an opaque token or a key is part of `authContext`.\n keyPartFingerprint(authContext),\n backendUrl,\n appUrl ?? '',\n ],\n queryFn: async ({ signal }): Promise<{ url: string; expiresAt: number }> => {\n // Derive the Athena API base from backendUrl before calling the embed endpoint.\n const apiBaseUrl = backendUrl.replace(/\\/api\\/assistant-ui\\/?$/, '');\n const heldToken = tokenRef.current;\n const res = await sendWithCredentialRenewal(\n { apiKey, token: heldToken, getToken: heldToken ? getTokenRef.current : undefined },\n (headers) =>\n fetch(`${apiBaseUrl}/api/embed/generate-token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify(\n buildAssetEmbedRequestBody({\n assetId: assetId ?? '',\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit,\n allowComments,\n }),\n ),\n signal,\n }),\n );\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`Failed to generate embed token (${res.status}): ${text}`);\n }\n const data: { embed_url: string; expires_at: number } = await res.json();\n return {\n url: resolveAssetEmbedUrl({ embedUrl: data.embed_url, appUrl, backendUrl }),\n expiresAt: data.expires_at,\n };\n },\n enabled,\n // A minted link is good until it expires; a new one would reload the frame, so it is never\n // minted again while the embed shows (no refetch on focus or reconnect) and never retried.\n staleTime: (cached) =>\n cached.state.data ? Math.max(0, cached.state.data.expiresAt * 1000 - Date.now()) : 0,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n },\n useContext(QueryClientContext) ?? embedQueryClient,\n );\n\n return {\n embedUrl: enabled ? (query.data?.url ?? null) : null,\n isLoading: enabled && query.isLoading,\n error: enabled && query.error ? query.error.message : null,\n };\n}\n"],"names":["QueryClient","deriveAthenaAppUrl","useRef","useQuery","keyPartFingerprint","sendWithCredentialRenewal","useContext","QueryClientContext"],"mappings":"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"}
@@ -1,39 +1,56 @@
1
1
  import type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';
2
2
  import type { AthenaAssetCitationReference } from './asset-embed-messages';
3
3
  export interface UseAssetEmbedOptions {
4
+ /**
5
+ * Mint a view-only link. A ceiling, not a grant: the link edits only what its creator may edit,
6
+ * and a Word document, an Athena document, a spreadsheet, a user interface or a deck edits only
7
+ * for a viewer who is signed in to Athena (the provider's `token`, which `AthenaAssetEmbed`
8
+ * hands the frame). Anyone else views such a link read-only. Defaults to `false`.
9
+ */
4
10
  readOnly?: boolean;
5
11
  expiresInSeconds?: number;
6
12
  /** Native Olympus surface rendered by the iframe. Defaults to `full`. */
7
13
  displayMode?: 'minimal' | 'full';
8
14
  /**
9
- * Offer Quick Edit (⌘J, an AI rewrite of the selection) in a minimal embed, where the viewer
10
- * does not sign in: spreadsheets and Word documents, on an editable link (`readOnly: false`)
11
- * only. Its runs are billed to the asset's workspace under the link's creator, and each link has
12
- * its own hourly cap. The full mode's editors offer it to the signed-in person already. Defaults
13
- * to `false`.
15
+ * Offer Quick Edit (⌘J, an AI rewrite of the selection) in a minimal embed, which runs on the
16
+ * link rather than an Athena sign-in: spreadsheets, Word documents and decks, on an editable
17
+ * link (`readOnly: false`) only, and only to a viewer who is signed in to Athena (the provider's
18
+ * `token`, which `AthenaAssetEmbed` hands the frame). Its runs are billed to the asset's
19
+ * workspace under the link's creator, and each link has its own hourly cap. The full mode's
20
+ * editors offer it to the signed-in person already. Defaults to `false`.
14
21
  */
15
22
  allowQuickEdit?: boolean;
23
+ /**
24
+ * Show the asset's comment threads, read-only, to everyone holding the link, a viewer who is not
25
+ * signed in included. Without it, a minimal embed shows them only to a signed-in viewer who has
26
+ * their own access to the asset (the bearer this component hands the iframe, or an Athena
27
+ * session). No embed ever writes a comment. Defaults to `false`.
28
+ */
29
+ allowComments?: boolean;
16
30
  }
17
31
  export declare const DEFAULT_ASSET_EMBED_READ_ONLY = false;
18
32
  export declare const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;
33
+ export declare const DEFAULT_ASSET_EMBED_ALLOW_COMMENTS = false;
19
34
  export declare const DEFAULT_ASSET_EMBED_DISPLAY_MODE: 'full';
20
35
  export interface UseAssetEmbedResult {
21
36
  embedUrl: string | null;
22
37
  isLoading: boolean;
23
38
  error: string | null;
24
39
  }
25
- export declare function buildAssetEmbedRequestBody({ assetId, readOnly, expiresInSeconds, displayMode, allowQuickEdit, }: {
40
+ export declare function buildAssetEmbedRequestBody({ assetId, readOnly, expiresInSeconds, displayMode, allowQuickEdit, allowComments, }: {
26
41
  assetId: string;
27
42
  readOnly: boolean;
28
43
  expiresInSeconds: number;
29
44
  displayMode: 'minimal' | 'full';
30
45
  allowQuickEdit?: boolean;
46
+ allowComments?: boolean;
31
47
  }): {
32
48
  asset_id: string;
33
49
  read_only: boolean;
34
50
  expires_in_seconds: number;
35
51
  display_mode: "full" | "minimal";
36
52
  allow_quick_edit?: boolean | undefined;
53
+ allow_comments?: boolean | undefined;
37
54
  };
38
55
  export declare function resolveAssetEmbedUrl({ embedUrl, appUrl, backendUrl, currentOrigin, }: {
39
56
  embedUrl: string;
@@ -5,13 +5,15 @@ import { keyPartFingerprint } from "../lib/use-athena-rest-query.js";
5
5
  import { sendWithCredentialRenewal } from "../runtime/credential-renewal.js";
6
6
  const DEFAULT_ASSET_EMBED_READ_ONLY = false;
7
7
  const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;
8
+ const DEFAULT_ASSET_EMBED_ALLOW_COMMENTS = false;
8
9
  const DEFAULT_ASSET_EMBED_DISPLAY_MODE = "full";
9
10
  function buildAssetEmbedRequestBody({
10
11
  assetId,
11
12
  readOnly,
12
13
  expiresInSeconds,
13
14
  displayMode,
14
- allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT
15
+ allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
16
+ allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS
15
17
  }) {
16
18
  return {
17
19
  asset_id: assetId,
@@ -19,7 +21,8 @@ function buildAssetEmbedRequestBody({
19
21
  expires_in_seconds: expiresInSeconds,
20
22
  display_mode: displayMode,
21
23
  // Sent only when asked: an agora that predates it is never handed an unknown field.
22
- ...allowQuickEdit && { allow_quick_edit: true }
24
+ ...allowQuickEdit && { allow_quick_edit: true },
25
+ ...allowComments && { allow_comments: true }
23
26
  };
24
27
  }
25
28
  const embedQueryClient = new QueryClient();
@@ -304,6 +307,7 @@ function useAssetEmbed(assetId, options = {
304
307
  expiresInSeconds = 60 * 60 * 24 * 30,
305
308
  displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
306
309
  allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
310
+ allowComments = DEFAULT_ASSET_EMBED_ALLOW_COMMENTS,
307
311
  backendUrl,
308
312
  appUrl,
309
313
  apiKey,
@@ -325,6 +329,7 @@ function useAssetEmbed(assetId, options = {
325
329
  readOnly,
326
330
  displayMode,
327
331
  allowQuickEdit,
332
+ allowComments,
328
333
  // The identity, never the credential: an opaque token or a key is part of `authContext`.
329
334
  keyPartFingerprint(authContext),
330
335
  backendUrl,
@@ -344,7 +349,8 @@ function useAssetEmbed(assetId, options = {
344
349
  readOnly,
345
350
  expiresInSeconds,
346
351
  displayMode,
347
- allowQuickEdit
352
+ allowQuickEdit,
353
+ allowComments
348
354
  })
349
355
  ),
350
356
  signal
@@ -377,6 +383,7 @@ function useAssetEmbed(assetId, options = {
377
383
  };
378
384
  }
379
385
  export {
386
+ DEFAULT_ASSET_EMBED_ALLOW_COMMENTS,
380
387
  DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
381
388
  DEFAULT_ASSET_EMBED_DISPLAY_MODE,
382
389
  DEFAULT_ASSET_EMBED_READ_ONLY,