@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":"runtime-catalog.cjs","sources":["../../src/catalog/runtime-catalog.ts"],"sourcesContent":["import { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useMemo, useState } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n AthenaGraphQLError,\n fetchGraphQL,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { useOptionalAthenaThreadModel } from '../threads/use-athena-thread-model';\nimport {\n type AgentModelSource,\n type AthenaAgentModelOption,\n agentAssetIdOf,\n buildAgentModelOptions,\n publishedAgentModelSource,\n} from './agent-model-options';\n\n/**\n * The workspace's runtime catalog for a chat's model and agent pickers: the models the signed-in\n * person may run (the workspace's allow or deny list, admin-only models for admins), and the\n * published collab agents they can see. The rules are the Chrome extension's, which every host now\n * reads from here.\n */\n\nexport type AthenaModelStatus = 'ACTIVE' | 'LEGACY' | 'RECOMMENDED';\n\nexport interface AthenaModelOption {\n id: string;\n label: string;\n description: string | null;\n /** Upper-case provider key, e.g. `ANTHROPIC`, `OPENAI`. */\n provider: string;\n status: AthenaModelStatus;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n}\n\nexport interface AthenaAgentOption {\n /** The collab agent's asset id; pass `collab_agent:<id>` as the provider's `agent`. */\n id: string;\n name: string;\n}\n\n/** The provider labels a model picker groups by. */\nexport const MODEL_PROVIDER_LABELS: Readonly<Record<string, string>> = {\n ANTHROPIC: 'Anthropic',\n OPENAI: 'OpenAI',\n GOOGLE: 'Google',\n XAI: 'xAI',\n META: 'Meta',\n MISTRAL: 'Mistral',\n DEEPSEEK: 'DeepSeek',\n QWEN: 'Qwen',\n MOONSHOT: 'Moonshot',\n MINIMAX: 'MiniMax',\n ZAI: 'Z.ai',\n};\n\nexport const ATHENA_MODEL_CATALOG_QUERY = `\n query AthenaModelCatalog {\n getCurrentUserWithWorkspace { user { isAdmin } }\n settings { workspace { approvedLargeLlms blacklistedLlms } }\n availableModels {\n id name provider status description adminOnly sortOrder\n familyId familyName isFamilyDefault isFeatured variantOrder\n }\n }\n`;\n\nexport const ATHENA_AGENT_CATALOG_QUERY = `\n query AthenaAgentCatalog {\n getAllAssets(filterByAthenaOriginalType: [\"collab_agent\"]) { id title }\n }\n`;\n\nexport interface AthenaModelCatalogResponse {\n getCurrentUserWithWorkspace: { user: { isAdmin: boolean } };\n settings: { workspace: { approvedLargeLlms: string[]; blacklistedLlms: string[] } };\n availableModels: Array<{\n id: string;\n name: string;\n provider: string;\n status: AthenaModelStatus;\n description: string | null;\n adminOnly: boolean;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n }>;\n}\n\n/**\n * The models the person may pick, in catalog order. A workspace with an allow list offers only\n * those; otherwise everything except its deny list. Admin-only models are offered to admins only.\n */\nexport function normalizeModelCatalog({\n response,\n}: {\n response: AthenaModelCatalogResponse;\n}): AthenaModelOption[] {\n const isAdmin = response.getCurrentUserWithWorkspace.user.isAdmin;\n const approved = new Set(response.settings.workspace.approvedLargeLlms);\n const denied = new Set(response.settings.workspace.blacklistedLlms);\n const hasAllowlist = approved.size > 0;\n return response.availableModels\n .filter(\n (model) =>\n (!model.adminOnly || isAdmin) && (hasAllowlist ? approved.has(model.id) : !denied.has(model.id)),\n )\n .map(\n (model): AthenaModelOption => ({\n id: model.id,\n label: model.name,\n description: model.description,\n provider: model.provider,\n status: model.status,\n sortOrder: model.sortOrder,\n familyId: model.familyId,\n familyName: model.familyName,\n isFamilyDefault: model.isFamilyDefault,\n isFeatured: model.isFeatured,\n variantOrder: model.variantOrder,\n }),\n )\n .sort(\n (left, right) =>\n left.sortOrder - right.sortOrder ||\n left.variantOrder - right.variantOrder ||\n left.label.localeCompare(right.label),\n );\n}\n\n/** The published collab agents, named and sorted; assets with a blank id are dropped. */\nexport function normalizeAgentCatalog({\n assets,\n}: {\n assets: ReadonlyArray<{ id: string; title: string | null }>;\n}): AthenaAgentOption[] {\n return assets\n .filter((asset) => asset.id.trim().length > 0)\n .map((asset) => ({ id: asset.id, name: asset.title?.trim() || 'Untitled agent' }))\n .sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/**\n * The model a picker shows as chosen: the stored choice while the catalog offers it, else the\n * default (unless retired), else a recommended family default, else any live model. While the\n * catalog is empty (loading, or unreachable) the stored choice or the default stands.\n */\nexport function resolveCatalogModelId({\n stored,\n defaultModelId,\n models,\n}: {\n stored: string | null;\n defaultModelId: string;\n models: readonly AthenaModelOption[];\n}): string {\n if (stored && models.some((model) => model.id === stored)) return stored;\n return (\n (\n models.find((model) => model.id === defaultModelId && model.status !== 'LEGACY') ??\n models.find((model) => model.status === 'RECOMMENDED' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY') ??\n models[0]\n )?.id ?? (stored || defaultModelId)\n );\n}\n\n/** Models grouped under their provider's label, in catalog order. */\nexport function groupModelsByProvider({\n models,\n}: {\n models: readonly AthenaModelOption[];\n}): Array<{ provider: string; models: AthenaModelOption[] }> {\n const groups = new Map<string, AthenaModelOption[]>();\n for (const model of models) {\n const label = MODEL_PROVIDER_LABELS[model.provider] ?? model.provider;\n groups.set(label, [...(groups.get(label) ?? []), model]);\n }\n return Array.from(groups, ([provider, grouped]) => ({ provider, models: grouped }));\n}\n\n/** The provider's credentials as the SDK's GraphQL client takes them. Internal. */\nexport function useCatalogAuth(): MentionAuthContext {\n const config = useAthenaConfig();\n return useMemo<MentionAuthContext>(\n () => ({\n backendUrl: config.backendUrl,\n appUrl: config.appUrl,\n apiKey: config.apiKey,\n credentials: 'include',\n get accessToken() {\n return config.token ?? undefined;\n },\n getAccessToken: async () => (await config.getToken?.()) ?? undefined,\n renewAccessToken: async () => (await config.getToken?.({ force: true })) ?? undefined,\n }),\n [config],\n );\n}\n\n/**\n * A short fingerprint (two FNV-1a rounds, 64 bits) of a credential: it tells accounts apart in an\n * in-memory cache key without the credential itself, or anything it could be recovered from,\n * entering the key.\n */\nexport function credentialFingerprint({ credential }: { credential: string }): string {\n const round = (seed: number) => {\n let hash = seed;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, '0');\n };\n return `${round(0x811c9dc5)}${round(0x01000193)}`;\n}\n\n/**\n * Who is asking, for the cache key: the catalog differs per account (admin-only models, the\n * workspace's lists, the agents shared with them), and a host can switch accounts while keeping its\n * query client. The signed-in user's id when the SDK knows it, else a fingerprint of the credential\n * in use. Never the credential itself.\n */\nexport function useCatalogPrincipal(): string {\n const config = useAthenaConfig();\n const userId = useContext(AthenaAuthContext)?.user?.userId;\n if (userId) return `user:${userId}`;\n if (config.apiKey) return `key:${credentialFingerprint({ credential: config.apiKey })}`;\n if (config.token) return `token:${credentialFingerprint({ credential: config.token })}`;\n return 'session';\n}\n\n/**\n * The host's QueryClient when there is one (the thread list provides one), else one of the\n * pickers' own, so the catalog hooks work with or without the thread list.\n */\nexport function useCatalogQueryClient(): QueryClient {\n const host = useContext(QueryClientContext);\n const [own] = useState(() => new QueryClient());\n return host ?? own;\n}\n\n/** The models the signed-in person may pick (`normalizeModelCatalog`). */\nexport function useAthenaModelCatalog() {\n return useModelCatalogQuery({\n auth: useCatalogAuth(),\n principal: useCatalogPrincipal(),\n queryClient: useCatalogQueryClient(),\n });\n}\n\n/** The model catalog's query on a given client (one client for every read a hook makes). */\nfunction useModelCatalogQuery({\n auth,\n principal,\n queryClient,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n}) {\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'models', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeModelCatalog({\n response: await fetchGraphQL<AthenaModelCatalogResponse>(auth, ATHENA_MODEL_CATALOG_QUERY),\n }),\n staleTime: 5 * 60 * 1000,\n },\n queryClient,\n );\n}\n\n/** The published collab agents the signed-in person can see (`normalizeAgentCatalog`). */\nexport function useAthenaAgentCatalog() {\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agents', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeAgentCatalog({\n assets:\n (\n await fetchGraphQL<{ getAllAssets: Array<{ id: string; title: string | null }> }>(\n auth,\n ATHENA_AGENT_CATALOG_QUERY,\n )\n ).getAllAssets ?? [],\n }),\n staleTime: 60 * 1000,\n },\n queryClient,\n );\n}\n\nexport const ATHENA_AGENT_MODELS_QUERY = `\n query AthenaAgentModels($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The `getAssetById` error codes that mean \"this person may not read the\n * agent\": no VIEW on it (`UNAUTHORIZED`, `FORBIDDEN`), or it lives in another\n * workspace (`WORKSPACE_MISMATCH`). Asking again answers the same.\n */\nconst AGENT_READ_DENIAL_CODES: ReadonlySet<string> = new Set([\n 'UNAUTHORIZED',\n 'FORBIDDEN',\n 'WORKSPACE_MISMATCH',\n]);\n\n/** What reading the agent's published models found: its models, or that this person cannot know them. */\nexport type AgentModelRead = { readable: true; source: AgentModelSource | null } | { readable: false };\n\n/**\n * Where `useAthenaAgentModelOptions` stands:\n *\n * - `idle`: no agent given;\n * - `loading`: the agent (or the model catalog that names its models) is being read;\n * - `ready`: the agent's published models are known;\n * - `unavailable`: this person cannot know them: no VIEW on the agent, no such\n * agent, or one never published (or whose published definition names no\n * model). Not an error: `allowAnyModel` stays `true`, so a picker keeps the\n * workspace's models;\n * - `error`: the read failed (network, server); `allowAnyModel` stays `true`.\n */\nexport type AthenaAgentModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'unavailable' | 'error';\n\nexport interface AthenaAgentModelOptions {\n status: AthenaAgentModelOptionsStatus;\n /** The agent's model choices (see {@link AthenaAgentModelOption}); empty unless `ready`. */\n options: readonly AthenaAgentModelOption[];\n /**\n * The model the thread runs while it pins none: the channel's override, else\n * the agent's own model. `null` unless `ready`.\n */\n defaultModel: string | null;\n /**\n * Whether people may pick any workspace model with this agent: the agent's\n * \"Allow any workspace model\" switch (`allowAnyModel` in its published\n * definition). Only an explicit `false` restricts a picker to `options`;\n * absent, `null` or `true` (every agent saved before the switch) allow any,\n * and so does an agent this person cannot read. `true` unless `ready`.\n */\n allowAnyModel: boolean;\n}\n\nconst NO_AGENT_MODEL_OPTIONS: Readonly<\n Record<Exclude<AthenaAgentModelOptionsStatus, 'ready'>, AthenaAgentModelOptions>\n> = {\n idle: { status: 'idle', options: [], defaultModel: null, allowAnyModel: true },\n loading: { status: 'loading', options: [], defaultModel: null, allowAnyModel: true },\n unavailable: { status: 'unavailable', options: [], defaultModel: null, allowAnyModel: true },\n error: { status: 'error', options: [], defaultModel: null, allowAnyModel: true },\n};\n\n/** Whether a failed read is a denial: an answer, not a failure (nothing to retry or report). */\nexport function isAgentReadDenial(error: unknown): boolean {\n return (\n error instanceof AthenaGraphQLError &&\n error.code !== null &&\n AGENT_READ_DENIAL_CODES.has(error.code)\n );\n}\n\n/**\n * A selected collab agent's own model choices, and whether the agent restricts\n * a picker to them (`allowAnyModel: false`, the agent's \"Allow any workspace\n * model\" switch turned off). Restriction is opt-in per agent: with\n * `allowAnyModel` true (the default) a picker keeps the workspace's models and\n * can still show `defaultModel` as the agent's own; `ChatModelPicker` does\n * both.\n *\n * `agent` is the agent's asset id or its `collab_agent:<id>` ref (`null`:\n * none, `idle`). `channel` is the collab channel the chat runs on: its model\n * override is the default there. The rules are in `agent-model-options.ts`.\n *\n * The agent is read through `getAssetById(withMetadata: true)`, the\n * permission-checked asset read (VIEW on the agent), with the provider's\n * credentials: a person without VIEW gets `unavailable` with no options. The\n * model the thread pins comes from `useAthenaThreadModel()` (inside\n * `<AthenaProvider>`; none outside one): a pinned model outside the agent's\n * list is an option with `pinnedOutside`.\n *\n * Picking the `isDefault` option means \"no model\": hand the provider\n * `model={undefined}` so the agent's (or channel's) default runs, and a session\n * pinning another model is unpinned.\n *\n * While shown, the agent is read again every\n * {@link AGENT_MODELS_REFRESH_MS}: an author publishing new models elsewhere\n * invalidates nothing here.\n */\nexport function useAthenaAgentModelOptions({\n agent,\n channel = null,\n}: {\n agent: string | null | undefined;\n channel?: string | null;\n}): AthenaAgentModelOptions {\n return useAgentModelChoices({ agent, channel }).choices;\n}\n\n/** How often an agent's published models are read again while a hook shows them. */\nexport const AGENT_MODELS_REFRESH_MS = 60 * 1000;\n\n/**\n * The re-read cadence of an agent model read: every\n * {@link AGENT_MODELS_REFRESH_MS} while it answers, never for a denial (asking\n * again answers the same).\n */\nexport function agentModelsRefetchInterval({\n data,\n}: {\n data: AgentModelRead | undefined;\n}): number | false {\n return data !== undefined && !data.readable ? false : AGENT_MODELS_REFRESH_MS;\n}\n\n/**\n * {@link useAthenaAgentModelOptions} plus the catalog label of any model id,\n * from the same query client and catalog read (a picker needs both; reading\n * the catalog again through its own client would fetch it twice). Internal.\n */\nexport function useAgentModelChoices({\n agent,\n channel,\n}: {\n agent: string | null | undefined;\n channel: string | null;\n}): {\n choices: AthenaAgentModelOptions;\n modelLabel: (model: string) => string;\n /** The workspace model catalog, read through the same client as the agent. */\n catalog: ReturnType<typeof useModelCatalogQuery>;\n} {\n const assetId = agentAssetIdOf(agent);\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-models', auth.backendUrl, principal, assetId],\n queryFn: async (): Promise<AgentModelRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModelSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled: assetId !== null,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) => agentModelsRefetchInterval({ data: query.state.data }),\n },\n queryClient,\n );\n const catalog = useModelCatalogQuery({ auth, principal, queryClient });\n const threadModel = useOptionalAthenaThreadModel();\n const pinnedModel =\n threadModel !== null && threadModel.ready && threadModel.configured ? threadModel.model : null;\n const trimmedChannel = channel?.trim() || null;\n const models = catalog.data;\n const catalogPending = catalog.isPending;\n const { isPending: readPending, data: readData } = read;\n const modelLabel = useCallback(\n (model: string) => models?.find((option) => option.id === model)?.label ?? model,\n [models],\n );\n const choices = useMemo((): AthenaAgentModelOptions => {\n if (assetId === null) return NO_AGENT_MODEL_OPTIONS.idle;\n // A failed re-read keeps the last answer; only a first read that failed is an error.\n if (readData === undefined) {\n return readPending ? NO_AGENT_MODEL_OPTIONS.loading : NO_AGENT_MODEL_OPTIONS.error;\n }\n if (!readData.readable || readData.source === null) return NO_AGENT_MODEL_OPTIONS.unavailable;\n // The catalog names the models: wait for it, unless it failed (ids then name them).\n if (catalogPending) return NO_AGENT_MODEL_OPTIONS.loading;\n return {\n status: 'ready',\n ...buildAgentModelOptions({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }, [assetId, readPending, readData, catalogPending, modelLabel, trimmedChannel, pinnedModel]);\n return useMemo(() => ({ choices, modelLabel, catalog }), [choices, modelLabel, catalog]);\n}\n"],"names":["useAthenaConfig","useMemo","useContext","AthenaAuthContext","QueryClientContext","useState","QueryClient","useQuery","fetchGraphQL","AthenaGraphQLError","agentAssetIdOf","publishedAgentModelSource","useOptionalAthenaThreadModel","useCallback","buildAgentModelOptions"],"mappings":"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"}
1
+ {"version":3,"file":"runtime-catalog.cjs","sources":["../../src/catalog/runtime-catalog.ts"],"sourcesContent":["import {\n filterAndSortCatalogModels,\n normalizeCatalogAgentOptions,\n} from '@athenaintel/agent-runtime/runtime-catalog';\nimport { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n AthenaGraphQLError,\n fetchGraphQL,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { useOptionalAthenaThreadModel } from '../threads/use-athena-thread-model';\nimport {\n type AgentModelSource,\n type AthenaAgentModelOption,\n agentAssetIdOf,\n agentModelOptionsWithoutDefault,\n buildAgentModelOptions,\n publishedAgentModelSource,\n} from './agent-model-options';\nimport {\n ATHENA_CHANNEL_REFUSAL_QUERY,\n answersWithoutRefusalDay,\n channelReplacementsRefusalStartsAt,\n channelReplacementsRefusedOn,\n refusalDayOf,\n} from './channel-refusal';\n\n/**\n * The workspace's runtime catalog for a chat's model and agent pickers: the models the signed-in\n * person may run (the workspace's allow or deny list, admin-only models for admins), and the\n * published collab agents they can see. The rules are the Chrome extension's, which every host now\n * reads from here.\n */\n\nexport type AthenaModelStatus = 'ACTIVE' | 'LEGACY' | 'RECOMMENDED';\n\nexport interface AthenaModelOption {\n id: string;\n label: string;\n description: string | null;\n /** Upper-case provider key, e.g. `ANTHROPIC`, `OPENAI`. */\n provider: string;\n status: AthenaModelStatus;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n}\n\nexport interface AthenaAgentOption {\n /** The collab agent's asset id; pass `collab_agent:<id>` as the provider's `agent`. */\n id: string;\n name: string;\n}\n\n/** The provider labels a model picker groups by. */\nexport const MODEL_PROVIDER_LABELS: Readonly<Record<string, string>> = {\n ANTHROPIC: 'Anthropic',\n OPENAI: 'OpenAI',\n GOOGLE: 'Google',\n XAI: 'xAI',\n META: 'Meta',\n MISTRAL: 'Mistral',\n DEEPSEEK: 'DeepSeek',\n QWEN: 'Qwen',\n MOONSHOT: 'Moonshot',\n MINIMAX: 'MiniMax',\n ZAI: 'Z.ai',\n};\n\nexport const ATHENA_MODEL_CATALOG_QUERY = `\n query AthenaModelCatalog {\n getCurrentUserWithWorkspace { user { isAdmin } }\n settings { workspace { approvedLargeLlms blacklistedLlms } }\n availableModels {\n id name provider status description adminOnly sortOrder\n familyId familyName isFamilyDefault isFeatured variantOrder\n }\n }\n`;\n\nexport const ATHENA_AGENT_CATALOG_QUERY = `\n query AthenaAgentCatalog {\n getAllAssets(filterByAthenaOriginalType: [\"collab_agent\"]) { id title }\n }\n`;\n\nexport interface AthenaModelCatalogResponse {\n getCurrentUserWithWorkspace: { user: { isAdmin: boolean } };\n settings: { workspace: { approvedLargeLlms: string[]; blacklistedLlms: string[] } };\n availableModels: Array<{\n id: string;\n name: string;\n provider: string;\n status: AthenaModelStatus;\n description: string | null;\n adminOnly: boolean;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n }>;\n}\n\n/**\n * The models the person may pick, in catalog order. A workspace with an allow list offers only\n * those; otherwise everything except its deny list. Admin-only models are offered to admins only.\n */\nexport function normalizeModelCatalog({\n response,\n}: {\n response: AthenaModelCatalogResponse;\n}): AthenaModelOption[] {\n return filterAndSortCatalogModels({\n models: response.availableModels,\n isAdmin: response.getCurrentUserWithWorkspace.user.isAdmin,\n approvedModelIds: response.settings.workspace.approvedLargeLlms,\n deniedModelIds: response.settings.workspace.blacklistedLlms,\n }).map(\n (model): AthenaModelOption => ({\n id: model.id,\n label: model.name,\n description: model.description,\n provider: model.provider,\n status: model.status,\n sortOrder: model.sortOrder,\n familyId: model.familyId,\n familyName: model.familyName,\n isFamilyDefault: model.isFamilyDefault,\n isFeatured: model.isFeatured,\n variantOrder: model.variantOrder,\n }),\n );\n}\n\n/** The published collab agents, named and sorted; assets with a blank id are dropped. */\nexport function normalizeAgentCatalog({\n assets,\n}: {\n assets: ReadonlyArray<{ id: string; title: string | null }>;\n}): AthenaAgentOption[] {\n return normalizeCatalogAgentOptions({ assets });\n}\n\n/**\n * The model a picker shows as chosen: the stored choice while the catalog offers it, else the\n * default (unless retired), else a recommended family default, else any live model. While the\n * catalog is empty (loading, or unreachable) the stored choice or the default stands.\n */\nexport function resolveCatalogModelId({\n stored,\n defaultModelId,\n models,\n}: {\n stored: string | null;\n defaultModelId: string;\n models: readonly AthenaModelOption[];\n}): string {\n if (stored && models.some((model) => model.id === stored)) return stored;\n return (\n (\n models.find((model) => model.id === defaultModelId && model.status !== 'LEGACY') ??\n models.find((model) => model.status === 'RECOMMENDED' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY') ??\n models[0]\n )?.id ?? (stored || defaultModelId)\n );\n}\n\n/** Models grouped under their provider's label, in catalog order. */\nexport function groupModelsByProvider({\n models,\n}: {\n models: readonly AthenaModelOption[];\n}): Array<{ provider: string; models: AthenaModelOption[] }> {\n const groups = new Map<string, AthenaModelOption[]>();\n for (const model of models) {\n const label = MODEL_PROVIDER_LABELS[model.provider] ?? model.provider;\n groups.set(label, [...(groups.get(label) ?? []), model]);\n }\n return Array.from(groups, ([provider, grouped]) => ({ provider, models: grouped }));\n}\n\n/** The provider's credentials as the SDK's GraphQL client takes them. Internal. */\nexport function useCatalogAuth(): MentionAuthContext {\n const config = useAthenaConfig();\n return useMemo<MentionAuthContext>(\n () => ({\n backendUrl: config.backendUrl,\n appUrl: config.appUrl,\n apiKey: config.apiKey,\n credentials: 'include',\n get accessToken() {\n return config.token ?? undefined;\n },\n getAccessToken: async () => (await config.getToken?.()) ?? undefined,\n renewAccessToken: async () => (await config.getToken?.({ force: true })) ?? undefined,\n }),\n [config],\n );\n}\n\n/**\n * A short fingerprint (two FNV-1a rounds, 64 bits) of a credential: it tells accounts apart in an\n * in-memory cache key without the credential itself, or anything it could be recovered from,\n * entering the key.\n */\nexport function credentialFingerprint({ credential }: { credential: string }): string {\n const round = (seed: number) => {\n let hash = seed;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, '0');\n };\n return `${round(0x811c9dc5)}${round(0x01000193)}`;\n}\n\n/**\n * Who is asking, for the cache key: the catalog differs per account (admin-only models, the\n * workspace's lists, the agents shared with them), and a host can switch accounts while keeping its\n * query client. The signed-in user's id when the SDK knows it, else a fingerprint of the credential\n * in use. Never the credential itself.\n */\nexport function useCatalogPrincipal(): string {\n const config = useAthenaConfig();\n const userId = useContext(AthenaAuthContext)?.user?.userId;\n if (userId) return `user:${userId}`;\n if (config.apiKey) return `key:${credentialFingerprint({ credential: config.apiKey })}`;\n if (config.token) return `token:${credentialFingerprint({ credential: config.token })}`;\n return 'session';\n}\n\n/**\n * The host's QueryClient when there is one (the thread list provides one), else one of the\n * pickers' own, so the catalog hooks work with or without the thread list.\n */\nexport function useCatalogQueryClient(): QueryClient {\n const host = useContext(QueryClientContext);\n const [own] = useState(() => new QueryClient());\n return host ?? own;\n}\n\n/** The models the signed-in person may pick (`normalizeModelCatalog`). */\nexport function useAthenaModelCatalog() {\n return useModelCatalogQuery({\n auth: useCatalogAuth(),\n principal: useCatalogPrincipal(),\n queryClient: useCatalogQueryClient(),\n });\n}\n\n/** The model catalog's query on a given client (one client for every read a hook makes). */\nfunction useModelCatalogQuery({\n auth,\n principal,\n queryClient,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n}) {\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'models', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeModelCatalog({\n response: await fetchGraphQL<AthenaModelCatalogResponse>(auth, ATHENA_MODEL_CATALOG_QUERY),\n }),\n staleTime: 5 * 60 * 1000,\n },\n queryClient,\n );\n}\n\n/** The published collab agents the signed-in person can see (`normalizeAgentCatalog`). */\nexport function useAthenaAgentCatalog() {\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agents', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeAgentCatalog({\n assets:\n (\n await fetchGraphQL<{ getAllAssets: Array<{ id: string; title: string | null }> }>(\n auth,\n ATHENA_AGENT_CATALOG_QUERY,\n )\n ).getAllAssets ?? [],\n }),\n staleTime: 60 * 1000,\n },\n queryClient,\n );\n}\n\nexport const ATHENA_AGENT_MODELS_QUERY = `\n query AthenaAgentModels($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The `getAssetById` error codes that mean \"this person may not read the\n * agent\": no VIEW on it (`UNAUTHORIZED`, `FORBIDDEN`), or it lives in another\n * workspace (`WORKSPACE_MISMATCH`). Asking again answers the same.\n */\nconst AGENT_READ_DENIAL_CODES: ReadonlySet<string> = new Set([\n 'UNAUTHORIZED',\n 'FORBIDDEN',\n 'WORKSPACE_MISMATCH',\n]);\n\n/** What reading the agent's published models found: its models, or that this person cannot know them. */\nexport type AgentModelRead = { readable: true; source: AgentModelSource | null } | { readable: false };\n\n/**\n * Where `useAthenaAgentModelOptions` stands:\n *\n * - `idle`: no agent given;\n * - `loading`: the agent (or the model catalog that names its models) is being read;\n * - `ready`: the agent's published models are known;\n * - `unavailable`: this person cannot know them: no VIEW on the agent, no such\n * agent, or one never published (or whose published definition names no\n * model). Not an error: `allowAnyModel` stays `true`, so a picker keeps the\n * workspace's models;\n * - `error`: the read failed (network, server); `allowAnyModel` stays `true`.\n */\nexport type AthenaAgentModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'unavailable' | 'error';\n\nexport interface AthenaAgentModelOptions {\n status: AthenaAgentModelOptionsStatus;\n /** The agent's model choices (see {@link AthenaAgentModelOption}); empty unless `ready`. */\n options: readonly AthenaAgentModelOption[];\n /**\n * The model the thread runs while it pins none: the channel's override, else\n * the agent's own model. From the deployment's refusal day (identity v7 D12,\n * `FeatureGateEnv.channelReplacementsRefusedFrom`) Athena no longer applies a\n * channel's model, so this is the agent's own on every channel. `null` unless\n * `ready`, and also `null` on a channel until the day's first read answers:\n * meanwhile `options` are the agent's own models, none marked default.\n */\n defaultModel: string | null;\n /**\n * Whether people may pick any workspace model with this agent: the agent's\n * \"Allow any workspace model\" switch (`allowAnyModel` in its published\n * definition). Only an explicit `false` restricts a picker to `options`;\n * absent, `null` or `true` (every agent saved before the switch) allow any,\n * and so does an agent this person cannot read. `true` unless `ready`.\n */\n allowAnyModel: boolean;\n}\n\nconst NO_AGENT_MODEL_OPTIONS: Readonly<\n Record<Exclude<AthenaAgentModelOptionsStatus, 'ready'>, AthenaAgentModelOptions>\n> = {\n idle: { status: 'idle', options: [], defaultModel: null, allowAnyModel: true },\n loading: { status: 'loading', options: [], defaultModel: null, allowAnyModel: true },\n unavailable: { status: 'unavailable', options: [], defaultModel: null, allowAnyModel: true },\n error: { status: 'error', options: [], defaultModel: null, allowAnyModel: true },\n};\n\n/** Whether a failed read is a denial: an answer, not a failure (nothing to retry or report). */\nexport function isAgentReadDenial(error: unknown): boolean {\n return (\n error instanceof AthenaGraphQLError &&\n error.code !== null &&\n AGENT_READ_DENIAL_CODES.has(error.code)\n );\n}\n\n/**\n * A selected collab agent's own model choices, and whether the agent restricts\n * a picker to them (`allowAnyModel: false`, the agent's \"Allow any workspace\n * model\" switch turned off). Restriction is opt-in per agent: with\n * `allowAnyModel` true (the default) a picker keeps the workspace's models and\n * can still show `defaultModel` as the agent's own; `ChatModelPicker` does\n * both.\n *\n * `agent` is the agent's asset id or its `collab_agent:<id>` ref (`null`:\n * none, `idle`). `channel` is the collab channel the chat runs on: its model\n * override is the default there, until the deployment's refusal day (identity\n * v7 D12), which a chat with a channel reads from `featureGateEnv` and follows\n * across UTC midnight. The rules are in `agent-model-options.ts`.\n *\n * The agent is read through `getAssetById(withMetadata: true)`, the\n * permission-checked asset read (VIEW on the agent), with the provider's\n * credentials: a person without VIEW gets `unavailable` with no options. The\n * model the thread pins comes from `useAthenaThreadModel()` (inside\n * `<AthenaProvider>`; none outside one): a pinned model outside the agent's\n * list is an option with `pinnedOutside`.\n *\n * Picking the `isDefault` option means \"no model\": hand the provider\n * `model={undefined}` so the agent's (or channel's) default runs, and a session\n * pinning another model is unpinned.\n *\n * While shown, the agent is read again every\n * {@link AGENT_MODELS_REFRESH_MS}: an author publishing new models elsewhere\n * invalidates nothing here.\n */\nexport function useAthenaAgentModelOptions({\n agent,\n channel = null,\n}: {\n agent: string | null | undefined;\n channel?: string | null;\n}): AthenaAgentModelOptions {\n return useAgentModelChoices({ agent, channel }).choices;\n}\n\n/** How often an agent's published models are read again while a hook shows them. */\nexport const AGENT_MODELS_REFRESH_MS = 60 * 1000;\n\n/**\n * The re-read cadence of an agent model read: every\n * {@link AGENT_MODELS_REFRESH_MS} while it answers, never for a denial (asking\n * again answers the same).\n */\nexport function agentModelsRefetchInterval({\n data,\n}: {\n data: AgentModelRead | undefined;\n}): number | false {\n return data !== undefined && !data.readable ? false : AGENT_MODELS_REFRESH_MS;\n}\n\n/** `setTimeout` holds at most 2^31 - 1 ms (about 24.8 days); a later day is waited for in steps. */\nconst MAX_TIMER_MS = 2 ** 31 - 1;\n\n/** Where a picker stands on the deployment's refusal day. */\ninterface ChannelRefusal {\n /** The day's first read is still out: a picker names no default until it answers. */\n pending: boolean;\n /** The day has come: a channel's model no longer applies. */\n refused: boolean;\n}\n\n/**\n * Whether the deployment's refusal day has come (identity v7 D12, `channel-refusal.ts`), rendering\n * again at UTC midnight of the day, so a picker open across it turns without a reload. The day is\n * read only while `enabled` (an agent and a channel: no channel, no channel model to refuse) and\n * again every {@link AGENT_MODELS_REFRESH_MS}, as the agent is. Only an agora whose schema lacks\n * the field (one from before D12's date, which refuses nothing) answers \"no day\"; any other failure\n * is a failed read, which keeps the day last read (TanStack keeps a query's data across a failed\n * re-read). Display only: agora decides at every compile from its own setting.\n */\nfunction useChannelReplacementsRefused({\n auth,\n principal,\n queryClient,\n enabled,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n enabled: boolean;\n}): ChannelRefusal {\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'channel-refusal-day', auth.backendUrl, principal],\n queryFn: async (): Promise<string | null> => {\n try {\n return refusalDayOf(await fetchGraphQL<unknown>(auth, ATHENA_CHANNEL_REFUSAL_QUERY));\n } catch (error) {\n if (\n error instanceof AthenaGraphQLError &&\n error.status === null &&\n answersWithoutRefusalDay(error.message)\n ) {\n return null;\n }\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: AGENT_MODELS_REFRESH_MS,\n // A picker waits on the first answer: one retry, not TanStack's three.\n retry: 1,\n },\n queryClient,\n );\n const refusedFrom = enabled ? (read.data ?? null) : null;\n const [tick, setTick] = useState(0);\n const refused = channelReplacementsRefusedOn({ refusedFrom, now: Date.now() });\n const startsAt = refused ? null : channelReplacementsRefusalStartsAt(refusedFrom);\n useEffect(() => {\n // `tick` is read so that a step short of a far day waits again.\n if (startsAt === null || tick < 0) return;\n const delay = Math.min(Math.max(startsAt - Date.now(), 0), MAX_TIMER_MS);\n const timer = setTimeout(() => setTick((value) => value + 1), delay);\n return () => clearTimeout(timer);\n }, [startsAt, tick]);\n // A first read that failed leaves the day unknown: the picker shows what it showed before D12.\n return { pending: enabled && read.isPending, refused };\n}\n\n/**\n * {@link useAthenaAgentModelOptions} plus the catalog label of any model id,\n * from the same query client and catalog read (a picker needs both; reading\n * the catalog again through its own client would fetch it twice). Internal.\n */\nexport function useAgentModelChoices({\n agent,\n channel,\n}: {\n agent: string | null | undefined;\n channel: string | null;\n}): {\n choices: AthenaAgentModelOptions;\n modelLabel: (model: string) => string;\n /** The workspace model catalog, read through the same client as the agent. */\n catalog: ReturnType<typeof useModelCatalogQuery>;\n} {\n const assetId = agentAssetIdOf(agent);\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-models', auth.backendUrl, principal, assetId],\n queryFn: async (): Promise<AgentModelRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModelSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled: assetId !== null,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) => agentModelsRefetchInterval({ data: query.state.data }),\n },\n queryClient,\n );\n const catalog = useModelCatalogQuery({ auth, principal, queryClient });\n const threadModel = useOptionalAthenaThreadModel();\n const pinnedModel =\n threadModel !== null && threadModel.ready && threadModel.configured ? threadModel.model : null;\n const trimmedChannel = channel?.trim() || null;\n const refusal = useChannelReplacementsRefused({\n auth,\n principal,\n queryClient,\n enabled: assetId !== null && trimmedChannel !== null,\n });\n const { pending: refusalPending, refused: refuseReplacements } = refusal;\n const models = catalog.data;\n const catalogPending = catalog.isPending;\n const { isPending: readPending, data: readData } = read;\n const modelLabel = useCallback(\n (model: string) => models?.find((option) => option.id === model)?.label ?? model,\n [models],\n );\n const choices = useMemo((): AthenaAgentModelOptions => {\n if (assetId === null) return NO_AGENT_MODEL_OPTIONS.idle;\n // A failed re-read keeps the last answer; only a first read that failed is an error.\n if (readData === undefined) {\n return readPending ? NO_AGENT_MODEL_OPTIONS.loading : NO_AGENT_MODEL_OPTIONS.error;\n }\n if (!readData.readable || readData.source === null) return NO_AGENT_MODEL_OPTIONS.unavailable;\n // The catalog names the models: wait for it, unless it failed (ids then name them).\n if (catalogPending) return NO_AGENT_MODEL_OPTIONS.loading;\n // On a channel the default turns on the refusal day. Until its first answer, offer the agent's\n // own models with their restriction kept, and name no default: never the refused channel's.\n if (refusalPending) {\n return {\n status: 'ready',\n ...agentModelOptionsWithoutDefault({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }\n return {\n status: 'ready',\n ...buildAgentModelOptions({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n refuseReplacements,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }, [\n assetId,\n readPending,\n readData,\n catalogPending,\n modelLabel,\n trimmedChannel,\n pinnedModel,\n refusalPending,\n refuseReplacements,\n ]);\n return useMemo(() => ({ choices, modelLabel, catalog }), [choices, modelLabel, catalog]);\n}\n"],"names":["filterAndSortCatalogModels","normalizeCatalogAgentOptions","useAthenaConfig","useMemo","useContext","AthenaAuthContext","QueryClientContext","useState","QueryClient","useQuery","fetchGraphQL","AthenaGraphQLError","refusalDayOf","ATHENA_CHANNEL_REFUSAL_QUERY","answersWithoutRefusalDay","channelReplacementsRefusedOn","channelReplacementsRefusalStartsAt","useEffect","agentAssetIdOf","publishedAgentModelSource","useOptionalAthenaThreadModel","useCallback","agentModelOptionsWithoutDefault","buildAgentModelOptions"],"mappings":";;;;;;;;;;;AA6DO,MAAM,wBAA0D;AAAA,EACrE,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,KAAK;AACP;AAEO,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWnC,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AA6BnC,SAAS,sBAAsB;AAAA,EACpC;AACF,GAEwB;AACtB,SAAOA,0CAA2B;AAAA,IAChC,QAAQ,SAAS;AAAA,IACjB,SAAS,SAAS,4BAA4B,KAAK;AAAA,IACnD,kBAAkB,SAAS,SAAS,UAAU;AAAA,IAC9C,gBAAgB,SAAS,SAAS,UAAU;AAAA,EAAA,CAC7C,EAAE;AAAA,IACD,CAAC,WAA8B;AAAA,MAC7B,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb,aAAa,MAAM;AAAA,MACnB,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,iBAAiB,MAAM;AAAA,MACvB,YAAY,MAAM;AAAA,MAClB,cAAc,MAAM;AAAA,IAAA;AAAA,EACtB;AAEJ;AAGO,SAAS,sBAAsB;AAAA,EACpC;AACF,GAEwB;AACtB,SAAOC,eAAAA,6BAA6B,EAAE,QAAQ;AAChD;AAOO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAIW;;AACT,MAAI,UAAU,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,EAAG,QAAO;AAClE,WAEI,YAAO,KAAK,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM,WAAW,QAAQ,KAC/E,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,iBAAiB,MAAM,eAAe,KAC9E,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,YAAY,MAAM,eAAe,KACzE,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,QAAQ,KAChD,OAAO,CAAC,MAJR,mBAKC,QAAO,UAAU;AAExB;AAGO,SAAS,sBAAsB;AAAA,EACpC;AACF,GAE6D;AAC3D,QAAM,6BAAa,IAAA;AACnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,sBAAsB,MAAM,QAAQ,KAAK,MAAM;AAC7D,WAAO,IAAI,OAAO,CAAC,GAAI,OAAO,IAAI,KAAK,KAAK,IAAK,KAAK,CAAC;AAAA,EACzD;AACA,SAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,UAAU,OAAO,OAAO,EAAE,UAAU,QAAQ,QAAA,EAAU;AACpF;AAGO,SAAS,iBAAqC;AACnD,QAAM,SAASC,cAAAA,gBAAA;AACf,SAAOC,WAAAA;AAAAA,IACL,OAAO;AAAA,MACL,YAAY,OAAO;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf,aAAa;AAAA,MACb,IAAI,cAAc;AAChB,eAAO,OAAO,SAAS;AAAA,MACzB;AAAA,MACA,gBAAgB,YAAA;;AAAa,uBAAM,YAAO,aAAP,oCAAwB;AAAA;AAAA,MAC3D,kBAAkB,YAAA;;AAAa,uBAAM,YAAO,aAAP,gCAAkB,EAAE,OAAO,KAAA,OAAY;AAAA;AAAA,IAAA;AAAA,IAE9E,CAAC,MAAM;AAAA,EAAA;AAEX;AAOO,SAAS,sBAAsB,EAAE,cAA8C;AACpF,QAAM,QAAQ,CAAC,SAAiB;AAC9B,QAAI,OAAO;AACX,aAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS,GAAG;AACzD,cAAQ,WAAW,WAAW,KAAK;AACnC,aAAO,KAAK,KAAK,MAAM,QAAU,MAAM;AAAA,IACzC;AACA,WAAO,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,EAC1C;AACA,SAAO,GAAG,MAAM,UAAU,CAAC,GAAG,MAAM,QAAU,CAAC;AACjD;AAQO,SAAS,sBAA8B;;AAC5C,QAAM,SAASD,cAAAA,gBAAA;AACf,QAAM,UAASE,sBAAAA,WAAWC,mCAAiB,MAA5BD,mBAA+B,SAA/BA,mBAAqC;AACpD,MAAI,OAAQ,QAAO,QAAQ,MAAM;AACjC,MAAI,OAAO,OAAQ,QAAO,OAAO,sBAAsB,EAAE,YAAY,OAAO,OAAA,CAAQ,CAAC;AACrF,MAAI,OAAO,MAAO,QAAO,SAAS,sBAAsB,EAAE,YAAY,OAAO,MAAA,CAAO,CAAC;AACrF,SAAO;AACT;AAMO,SAAS,wBAAqC;AACnD,QAAM,OAAOA,WAAAA,WAAWE,6BAAkB;AAC1C,QAAM,CAAC,GAAG,IAAIC,WAAAA,SAAS,MAAM,IAAIC,WAAAA,aAAa;AAC9C,SAAO,QAAQ;AACjB;AAGO,SAAS,wBAAwB;AACtC,SAAO,qBAAqB;AAAA,IAC1B,MAAM,eAAA;AAAA,IACN,WAAW,oBAAA;AAAA,IACX,aAAa,sBAAA;AAAA,EAAsB,CACpC;AACH;AAGA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SAAOC,WAAAA;AAAAA,IACL;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,UAAU,KAAK,YAAY,SAAS;AAAA,MACxE,SAAS,YACP,sBAAsB;AAAA,QACpB,UAAU,MAAMC,uBAAyC,MAAM,0BAA0B;AAAA,MAAA,CAC1F;AAAA,MACH,WAAW,IAAI,KAAK;AAAA,IAAA;AAAA,IAEtB;AAAA,EAAA;AAEJ;AAGO,SAAS,wBAAwB;AACtC,QAAM,OAAO,eAAA;AACb,QAAM,YAAY,oBAAA;AAClB,QAAM,cAAc,sBAAA;AACpB,SAAOD,WAAAA;AAAAA,IACL;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,UAAU,KAAK,YAAY,SAAS;AAAA,MACxE,SAAS,YACP,sBAAsB;AAAA,QACpB,SAEI,MAAMC,UAAAA;AAAAA,UACJ;AAAA,UACA;AAAA,QAAA,GAEF,gBAAgB,CAAA;AAAA,MAAC,CACtB;AAAA,MACH,WAAW,KAAK;AAAA,IAAA;AAAA,IAElB;AAAA,EAAA;AAEJ;AAEO,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAWzC,MAAM,8CAAmD,IAAI;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA0CD,MAAM,yBAEF;AAAA,EACF,MAAM,EAAE,QAAQ,QAAQ,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EACxE,SAAS,EAAE,QAAQ,WAAW,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EAC9E,aAAa,EAAE,QAAQ,eAAe,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EACtF,OAAO,EAAE,QAAQ,SAAS,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAC5E;AAGO,SAAS,kBAAkB,OAAyB;AACzD,SACE,iBAAiBC,gCACjB,MAAM,SAAS,QACf,wBAAwB,IAAI,MAAM,IAAI;AAE1C;AA+BO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA,UAAU;AACZ,GAG4B;AAC1B,SAAO,qBAAqB,EAAE,OAAO,QAAA,CAAS,EAAE;AAClD;AAGO,MAAM,0BAA0B,KAAK;AAOrC,SAAS,2BAA2B;AAAA,EACzC;AACF,GAEmB;AACjB,SAAO,SAAS,UAAa,CAAC,KAAK,WAAW,QAAQ;AACxD;AAGA,MAAM,eAAe,KAAK,KAAK;AAmB/B,SAAS,8BAA8B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKmB;AACjB,QAAM,OAAOF,WAAAA;AAAAA,IACX;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,uBAAuB,KAAK,YAAY,SAAS;AAAA,MACrF,SAAS,YAAoC;AAC3C,YAAI;AACF,iBAAOG,eAAAA,aAAa,MAAMF,UAAAA,aAAsB,MAAMG,eAAAA,4BAA4B,CAAC;AAAA,QACrF,SAAS,OAAO;AACd,cACE,iBAAiBF,UAAAA,sBACjB,MAAM,WAAW,QACjBG,eAAAA,yBAAyB,MAAM,OAAO,GACtC;AACA,mBAAO;AAAA,UACT;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,iBAAiB;AAAA;AAAA,MAEjB,OAAO;AAAA,IAAA;AAAA,IAET;AAAA,EAAA;AAEF,QAAM,cAAc,UAAW,KAAK,QAAQ,OAAQ;AACpD,QAAM,CAAC,MAAM,OAAO,IAAIP,WAAAA,SAAS,CAAC;AAClC,QAAM,UAAUQ,eAAAA,6BAA6B,EAAE,aAAa,KAAK,KAAK,IAAA,GAAO;AAC7E,QAAM,WAAW,UAAU,OAAOC,eAAAA,mCAAmC,WAAW;AAChFC,aAAAA,UAAU,MAAM;AAEd,QAAI,aAAa,QAAQ,OAAO,EAAG;AACnC,UAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,WAAW,KAAK,IAAA,GAAO,CAAC,GAAG,YAAY;AACvE,UAAM,QAAQ,WAAW,MAAM,QAAQ,CAAC,UAAU,QAAQ,CAAC,GAAG,KAAK;AACnE,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,UAAU,IAAI,CAAC;AAEnB,SAAO,EAAE,SAAS,WAAW,KAAK,WAAW,QAAA;AAC/C;AAOO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAQE;AACA,QAAM,UAAUC,kBAAAA,eAAe,KAAK;AACpC,QAAM,OAAO,eAAA;AACb,QAAM,YAAY,oBAAA;AAClB,QAAM,cAAc,sBAAA;AACpB,QAAM,OAAOT,WAAAA;AAAAA,IACX;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,gBAAgB,KAAK,YAAY,WAAW,OAAO;AAAA,MACvF,SAAS,YAAqC;AAC5C,YAAI;AACF,gBAAM,OAAO,MAAMC,UAAAA;AAAAA,YACjB;AAAA,YACA;AAAA,YACA,EAAE,QAAA;AAAA,UAAQ;AAEZ,cAAI,KAAK,iBAAiB,KAAM,QAAO,EAAE,UAAU,MAAA;AACnD,iBAAO;AAAA,YACL,UAAU;AAAA,YACV,QAAQS,kBAAAA,0BAA0B,KAAK,aAAa,cAAc;AAAA,UAAA;AAAA,QAEtE,SAAS,OAAO;AACd,cAAI,kBAAkB,KAAK,EAAG,QAAO,EAAE,UAAU,MAAA;AACjD,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,SAAS,YAAY;AAAA,MACrB,WAAW;AAAA,MACX,iBAAiB,CAAC,UAAU,2BAA2B,EAAE,MAAM,MAAM,MAAM,KAAA,CAAM;AAAA,IAAA;AAAA,IAEnF;AAAA,EAAA;AAEF,QAAM,UAAU,qBAAqB,EAAE,MAAM,WAAW,aAAa;AACrE,QAAM,cAAcC,qBAAAA,6BAAA;AACpB,QAAM,cACJ,gBAAgB,QAAQ,YAAY,SAAS,YAAY,aAAa,YAAY,QAAQ;AAC5F,QAAM,kBAAiB,mCAAS,WAAU;AAC1C,QAAM,UAAU,8BAA8B;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,YAAY,QAAQ,mBAAmB;AAAA,EAAA,CACjD;AACD,QAAM,EAAE,SAAS,gBAAgB,SAAS,uBAAuB;AACjE,QAAM,SAAS,QAAQ;AACvB,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,EAAE,WAAW,aAAa,MAAM,aAAa;AACnD,QAAM,aAAaC,WAAAA;AAAAA,IACjB,CAAC,UAAA;;AAAkB,qDAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,WAAvC,mBAA+C,UAAS;AAAA;AAAA,IAC3E,CAAC,MAAM;AAAA,EAAA;AAET,QAAM,UAAUlB,WAAAA,QAAQ,MAA+B;AACrD,QAAI,YAAY,KAAM,QAAO,uBAAuB;AAEpD,QAAI,aAAa,QAAW;AAC1B,aAAO,cAAc,uBAAuB,UAAU,uBAAuB;AAAA,IAC/E;AACA,QAAI,CAAC,SAAS,YAAY,SAAS,WAAW,aAAa,uBAAuB;AAElF,QAAI,uBAAuB,uBAAuB;AAGlD,QAAI,gBAAgB;AAClB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,GAAGmB,kDAAgC;AAAA,UACjC,QAAQ,SAAS;AAAA,UACjB,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QAAA,CACD;AAAA,QACD,eAAe,SAAS,OAAO;AAAA,MAAA;AAAA,IAEnC;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,GAAGC,yCAAuB;AAAA,QACxB,QAAQ,SAAS;AAAA,QACjB,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,MACD,eAAe,SAAS,OAAO;AAAA,IAAA;AAAA,EAEnC,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AACD,SAAOpB,mBAAQ,OAAO,EAAE,SAAS,YAAY,YAAY,CAAC,SAAS,YAAY,OAAO,CAAC;AACzF;;;;;;;;;;;;;;;;;;;;"}
@@ -148,7 +148,11 @@ export interface AthenaAgentModelOptions {
148
148
  options: readonly AthenaAgentModelOption[];
149
149
  /**
150
150
  * The model the thread runs while it pins none: the channel's override, else
151
- * the agent's own model. `null` unless `ready`.
151
+ * the agent's own model. From the deployment's refusal day (identity v7 D12,
152
+ * `FeatureGateEnv.channelReplacementsRefusedFrom`) Athena no longer applies a
153
+ * channel's model, so this is the agent's own on every channel. `null` unless
154
+ * `ready`, and also `null` on a channel until the day's first read answers:
155
+ * meanwhile `options` are the agent's own models, none marked default.
152
156
  */
153
157
  defaultModel: string | null;
154
158
  /**
@@ -172,7 +176,9 @@ export declare function isAgentReadDenial(error: unknown): boolean;
172
176
  *
173
177
  * `agent` is the agent's asset id or its `collab_agent:<id>` ref (`null`:
174
178
  * none, `idle`). `channel` is the collab channel the chat runs on: its model
175
- * override is the default there. The rules are in `agent-model-options.ts`.
179
+ * override is the default there, until the deployment's refusal day (identity
180
+ * v7 D12), which a chat with a channel reads from `featureGateEnv` and follows
181
+ * across UTC midnight. The rules are in `agent-model-options.ts`.
176
182
  *
177
183
  * The agent is read through `getAssetById(withMetadata: true)`, the
178
184
  * permission-checked asset read (VIEW on the agent), with the provider's
@@ -1,10 +1,12 @@
1
+ import { normalizeCatalogAgentOptions, filterAndSortCatalogModels } from "../agent-runtime/src/runtime-catalog.js";
1
2
  import { useQuery, QueryClientContext, QueryClient } from "@tanstack/react-query";
2
- import { useContext, useState, useMemo, useCallback } from "react";
3
+ import { useContext, useState, useMemo, useCallback, useEffect } from "react";
3
4
  import { AthenaAuthContext } from "../auth/AthenaAuthContext.js";
4
5
  import { fetchGraphQL, AthenaGraphQLError } from "../chat-ui/mentions/suggestions/data/api-client.js";
5
6
  import { useAthenaConfig } from "../provider/AthenaContext.js";
6
7
  import { useOptionalAthenaThreadModel } from "../threads/use-athena-thread-model.js";
7
- import { agentAssetIdOf, publishedAgentModelSource, buildAgentModelOptions } from "./agent-model-options.js";
8
+ import { agentAssetIdOf, publishedAgentModelSource, agentModelOptionsWithoutDefault, buildAgentModelOptions } from "./agent-model-options.js";
9
+ import { refusalDayOf, ATHENA_CHANNEL_REFUSAL_QUERY, answersWithoutRefusalDay, channelReplacementsRefusalStartsAt, channelReplacementsRefusedOn } from "./channel-refusal.js";
8
10
  const MODEL_PROVIDER_LABELS = {
9
11
  ANTHROPIC: "Anthropic",
10
12
  OPENAI: "OpenAI",
@@ -36,13 +38,12 @@ const ATHENA_AGENT_CATALOG_QUERY = `
36
38
  function normalizeModelCatalog({
37
39
  response
38
40
  }) {
39
- const isAdmin = response.getCurrentUserWithWorkspace.user.isAdmin;
40
- const approved = new Set(response.settings.workspace.approvedLargeLlms);
41
- const denied = new Set(response.settings.workspace.blacklistedLlms);
42
- const hasAllowlist = approved.size > 0;
43
- return response.availableModels.filter(
44
- (model) => (!model.adminOnly || isAdmin) && (hasAllowlist ? approved.has(model.id) : !denied.has(model.id))
45
- ).map(
41
+ return filterAndSortCatalogModels({
42
+ models: response.availableModels,
43
+ isAdmin: response.getCurrentUserWithWorkspace.user.isAdmin,
44
+ approvedModelIds: response.settings.workspace.approvedLargeLlms,
45
+ deniedModelIds: response.settings.workspace.blacklistedLlms
46
+ }).map(
46
47
  (model) => ({
47
48
  id: model.id,
48
49
  label: model.name,
@@ -56,17 +57,12 @@ function normalizeModelCatalog({
56
57
  isFeatured: model.isFeatured,
57
58
  variantOrder: model.variantOrder
58
59
  })
59
- ).sort(
60
- (left, right) => left.sortOrder - right.sortOrder || left.variantOrder - right.variantOrder || left.label.localeCompare(right.label)
61
60
  );
62
61
  }
63
62
  function normalizeAgentCatalog({
64
63
  assets
65
64
  }) {
66
- return assets.filter((asset) => asset.id.trim().length > 0).map((asset) => {
67
- var _a;
68
- return { id: asset.id, name: ((_a = asset.title) == null ? void 0 : _a.trim()) || "Untitled agent" };
69
- }).sort((left, right) => left.name.localeCompare(right.name));
65
+ return normalizeCatalogAgentOptions({ assets });
70
66
  }
71
67
  function resolveCatalogModelId({
72
68
  stored,
@@ -207,6 +203,46 @@ function agentModelsRefetchInterval({
207
203
  }) {
208
204
  return data !== void 0 && !data.readable ? false : AGENT_MODELS_REFRESH_MS;
209
205
  }
206
+ const MAX_TIMER_MS = 2 ** 31 - 1;
207
+ function useChannelReplacementsRefused({
208
+ auth,
209
+ principal,
210
+ queryClient,
211
+ enabled
212
+ }) {
213
+ const read = useQuery(
214
+ {
215
+ queryKey: ["athena-sdk", "catalog", "channel-refusal-day", auth.backendUrl, principal],
216
+ queryFn: async () => {
217
+ try {
218
+ return refusalDayOf(await fetchGraphQL(auth, ATHENA_CHANNEL_REFUSAL_QUERY));
219
+ } catch (error) {
220
+ if (error instanceof AthenaGraphQLError && error.status === null && answersWithoutRefusalDay(error.message)) {
221
+ return null;
222
+ }
223
+ throw error;
224
+ }
225
+ },
226
+ enabled,
227
+ staleTime: AGENT_MODELS_REFRESH_MS,
228
+ refetchInterval: AGENT_MODELS_REFRESH_MS,
229
+ // A picker waits on the first answer: one retry, not TanStack's three.
230
+ retry: 1
231
+ },
232
+ queryClient
233
+ );
234
+ const refusedFrom = enabled ? read.data ?? null : null;
235
+ const [tick, setTick] = useState(0);
236
+ const refused = channelReplacementsRefusedOn({ refusedFrom, now: Date.now() });
237
+ const startsAt = refused ? null : channelReplacementsRefusalStartsAt(refusedFrom);
238
+ useEffect(() => {
239
+ if (startsAt === null || tick < 0) return;
240
+ const delay = Math.min(Math.max(startsAt - Date.now(), 0), MAX_TIMER_MS);
241
+ const timer = setTimeout(() => setTick((value) => value + 1), delay);
242
+ return () => clearTimeout(timer);
243
+ }, [startsAt, tick]);
244
+ return { pending: enabled && read.isPending, refused };
245
+ }
210
246
  function useAgentModelChoices({
211
247
  agent,
212
248
  channel
@@ -245,6 +281,13 @@ function useAgentModelChoices({
245
281
  const threadModel = useOptionalAthenaThreadModel();
246
282
  const pinnedModel = threadModel !== null && threadModel.ready && threadModel.configured ? threadModel.model : null;
247
283
  const trimmedChannel = (channel == null ? void 0 : channel.trim()) || null;
284
+ const refusal = useChannelReplacementsRefused({
285
+ auth,
286
+ principal,
287
+ queryClient,
288
+ enabled: assetId !== null && trimmedChannel !== null
289
+ });
290
+ const { pending: refusalPending, refused: refuseReplacements } = refusal;
248
291
  const models = catalog.data;
249
292
  const catalogPending = catalog.isPending;
250
293
  const { isPending: readPending, data: readData } = read;
@@ -262,17 +305,40 @@ function useAgentModelChoices({
262
305
  }
263
306
  if (!readData.readable || readData.source === null) return NO_AGENT_MODEL_OPTIONS.unavailable;
264
307
  if (catalogPending) return NO_AGENT_MODEL_OPTIONS.loading;
308
+ if (refusalPending) {
309
+ return {
310
+ status: "ready",
311
+ ...agentModelOptionsWithoutDefault({
312
+ source: readData.source,
313
+ channel: trimmedChannel,
314
+ pinnedModel,
315
+ modelLabel
316
+ }),
317
+ allowAnyModel: readData.source.allowAnyModel
318
+ };
319
+ }
265
320
  return {
266
321
  status: "ready",
267
322
  ...buildAgentModelOptions({
268
323
  source: readData.source,
269
324
  channel: trimmedChannel,
270
325
  pinnedModel,
271
- modelLabel
326
+ modelLabel,
327
+ refuseReplacements
272
328
  }),
273
329
  allowAnyModel: readData.source.allowAnyModel
274
330
  };
275
- }, [assetId, readPending, readData, catalogPending, modelLabel, trimmedChannel, pinnedModel]);
331
+ }, [
332
+ assetId,
333
+ readPending,
334
+ readData,
335
+ catalogPending,
336
+ modelLabel,
337
+ trimmedChannel,
338
+ pinnedModel,
339
+ refusalPending,
340
+ refuseReplacements
341
+ ]);
276
342
  return useMemo(() => ({ choices, modelLabel, catalog }), [choices, modelLabel, catalog]);
277
343
  }
278
344
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-catalog.js","sources":["../../src/catalog/runtime-catalog.ts"],"sourcesContent":["import { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useMemo, useState } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n AthenaGraphQLError,\n fetchGraphQL,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { useOptionalAthenaThreadModel } from '../threads/use-athena-thread-model';\nimport {\n type AgentModelSource,\n type AthenaAgentModelOption,\n agentAssetIdOf,\n buildAgentModelOptions,\n publishedAgentModelSource,\n} from './agent-model-options';\n\n/**\n * The workspace's runtime catalog for a chat's model and agent pickers: the models the signed-in\n * person may run (the workspace's allow or deny list, admin-only models for admins), and the\n * published collab agents they can see. The rules are the Chrome extension's, which every host now\n * reads from here.\n */\n\nexport type AthenaModelStatus = 'ACTIVE' | 'LEGACY' | 'RECOMMENDED';\n\nexport interface AthenaModelOption {\n id: string;\n label: string;\n description: string | null;\n /** Upper-case provider key, e.g. `ANTHROPIC`, `OPENAI`. */\n provider: string;\n status: AthenaModelStatus;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n}\n\nexport interface AthenaAgentOption {\n /** The collab agent's asset id; pass `collab_agent:<id>` as the provider's `agent`. */\n id: string;\n name: string;\n}\n\n/** The provider labels a model picker groups by. */\nexport const MODEL_PROVIDER_LABELS: Readonly<Record<string, string>> = {\n ANTHROPIC: 'Anthropic',\n OPENAI: 'OpenAI',\n GOOGLE: 'Google',\n XAI: 'xAI',\n META: 'Meta',\n MISTRAL: 'Mistral',\n DEEPSEEK: 'DeepSeek',\n QWEN: 'Qwen',\n MOONSHOT: 'Moonshot',\n MINIMAX: 'MiniMax',\n ZAI: 'Z.ai',\n};\n\nexport const ATHENA_MODEL_CATALOG_QUERY = `\n query AthenaModelCatalog {\n getCurrentUserWithWorkspace { user { isAdmin } }\n settings { workspace { approvedLargeLlms blacklistedLlms } }\n availableModels {\n id name provider status description adminOnly sortOrder\n familyId familyName isFamilyDefault isFeatured variantOrder\n }\n }\n`;\n\nexport const ATHENA_AGENT_CATALOG_QUERY = `\n query AthenaAgentCatalog {\n getAllAssets(filterByAthenaOriginalType: [\"collab_agent\"]) { id title }\n }\n`;\n\nexport interface AthenaModelCatalogResponse {\n getCurrentUserWithWorkspace: { user: { isAdmin: boolean } };\n settings: { workspace: { approvedLargeLlms: string[]; blacklistedLlms: string[] } };\n availableModels: Array<{\n id: string;\n name: string;\n provider: string;\n status: AthenaModelStatus;\n description: string | null;\n adminOnly: boolean;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n }>;\n}\n\n/**\n * The models the person may pick, in catalog order. A workspace with an allow list offers only\n * those; otherwise everything except its deny list. Admin-only models are offered to admins only.\n */\nexport function normalizeModelCatalog({\n response,\n}: {\n response: AthenaModelCatalogResponse;\n}): AthenaModelOption[] {\n const isAdmin = response.getCurrentUserWithWorkspace.user.isAdmin;\n const approved = new Set(response.settings.workspace.approvedLargeLlms);\n const denied = new Set(response.settings.workspace.blacklistedLlms);\n const hasAllowlist = approved.size > 0;\n return response.availableModels\n .filter(\n (model) =>\n (!model.adminOnly || isAdmin) && (hasAllowlist ? approved.has(model.id) : !denied.has(model.id)),\n )\n .map(\n (model): AthenaModelOption => ({\n id: model.id,\n label: model.name,\n description: model.description,\n provider: model.provider,\n status: model.status,\n sortOrder: model.sortOrder,\n familyId: model.familyId,\n familyName: model.familyName,\n isFamilyDefault: model.isFamilyDefault,\n isFeatured: model.isFeatured,\n variantOrder: model.variantOrder,\n }),\n )\n .sort(\n (left, right) =>\n left.sortOrder - right.sortOrder ||\n left.variantOrder - right.variantOrder ||\n left.label.localeCompare(right.label),\n );\n}\n\n/** The published collab agents, named and sorted; assets with a blank id are dropped. */\nexport function normalizeAgentCatalog({\n assets,\n}: {\n assets: ReadonlyArray<{ id: string; title: string | null }>;\n}): AthenaAgentOption[] {\n return assets\n .filter((asset) => asset.id.trim().length > 0)\n .map((asset) => ({ id: asset.id, name: asset.title?.trim() || 'Untitled agent' }))\n .sort((left, right) => left.name.localeCompare(right.name));\n}\n\n/**\n * The model a picker shows as chosen: the stored choice while the catalog offers it, else the\n * default (unless retired), else a recommended family default, else any live model. While the\n * catalog is empty (loading, or unreachable) the stored choice or the default stands.\n */\nexport function resolveCatalogModelId({\n stored,\n defaultModelId,\n models,\n}: {\n stored: string | null;\n defaultModelId: string;\n models: readonly AthenaModelOption[];\n}): string {\n if (stored && models.some((model) => model.id === stored)) return stored;\n return (\n (\n models.find((model) => model.id === defaultModelId && model.status !== 'LEGACY') ??\n models.find((model) => model.status === 'RECOMMENDED' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY') ??\n models[0]\n )?.id ?? (stored || defaultModelId)\n );\n}\n\n/** Models grouped under their provider's label, in catalog order. */\nexport function groupModelsByProvider({\n models,\n}: {\n models: readonly AthenaModelOption[];\n}): Array<{ provider: string; models: AthenaModelOption[] }> {\n const groups = new Map<string, AthenaModelOption[]>();\n for (const model of models) {\n const label = MODEL_PROVIDER_LABELS[model.provider] ?? model.provider;\n groups.set(label, [...(groups.get(label) ?? []), model]);\n }\n return Array.from(groups, ([provider, grouped]) => ({ provider, models: grouped }));\n}\n\n/** The provider's credentials as the SDK's GraphQL client takes them. Internal. */\nexport function useCatalogAuth(): MentionAuthContext {\n const config = useAthenaConfig();\n return useMemo<MentionAuthContext>(\n () => ({\n backendUrl: config.backendUrl,\n appUrl: config.appUrl,\n apiKey: config.apiKey,\n credentials: 'include',\n get accessToken() {\n return config.token ?? undefined;\n },\n getAccessToken: async () => (await config.getToken?.()) ?? undefined,\n renewAccessToken: async () => (await config.getToken?.({ force: true })) ?? undefined,\n }),\n [config],\n );\n}\n\n/**\n * A short fingerprint (two FNV-1a rounds, 64 bits) of a credential: it tells accounts apart in an\n * in-memory cache key without the credential itself, or anything it could be recovered from,\n * entering the key.\n */\nexport function credentialFingerprint({ credential }: { credential: string }): string {\n const round = (seed: number) => {\n let hash = seed;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, '0');\n };\n return `${round(0x811c9dc5)}${round(0x01000193)}`;\n}\n\n/**\n * Who is asking, for the cache key: the catalog differs per account (admin-only models, the\n * workspace's lists, the agents shared with them), and a host can switch accounts while keeping its\n * query client. The signed-in user's id when the SDK knows it, else a fingerprint of the credential\n * in use. Never the credential itself.\n */\nexport function useCatalogPrincipal(): string {\n const config = useAthenaConfig();\n const userId = useContext(AthenaAuthContext)?.user?.userId;\n if (userId) return `user:${userId}`;\n if (config.apiKey) return `key:${credentialFingerprint({ credential: config.apiKey })}`;\n if (config.token) return `token:${credentialFingerprint({ credential: config.token })}`;\n return 'session';\n}\n\n/**\n * The host's QueryClient when there is one (the thread list provides one), else one of the\n * pickers' own, so the catalog hooks work with or without the thread list.\n */\nexport function useCatalogQueryClient(): QueryClient {\n const host = useContext(QueryClientContext);\n const [own] = useState(() => new QueryClient());\n return host ?? own;\n}\n\n/** The models the signed-in person may pick (`normalizeModelCatalog`). */\nexport function useAthenaModelCatalog() {\n return useModelCatalogQuery({\n auth: useCatalogAuth(),\n principal: useCatalogPrincipal(),\n queryClient: useCatalogQueryClient(),\n });\n}\n\n/** The model catalog's query on a given client (one client for every read a hook makes). */\nfunction useModelCatalogQuery({\n auth,\n principal,\n queryClient,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n}) {\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'models', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeModelCatalog({\n response: await fetchGraphQL<AthenaModelCatalogResponse>(auth, ATHENA_MODEL_CATALOG_QUERY),\n }),\n staleTime: 5 * 60 * 1000,\n },\n queryClient,\n );\n}\n\n/** The published collab agents the signed-in person can see (`normalizeAgentCatalog`). */\nexport function useAthenaAgentCatalog() {\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agents', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeAgentCatalog({\n assets:\n (\n await fetchGraphQL<{ getAllAssets: Array<{ id: string; title: string | null }> }>(\n auth,\n ATHENA_AGENT_CATALOG_QUERY,\n )\n ).getAllAssets ?? [],\n }),\n staleTime: 60 * 1000,\n },\n queryClient,\n );\n}\n\nexport const ATHENA_AGENT_MODELS_QUERY = `\n query AthenaAgentModels($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The `getAssetById` error codes that mean \"this person may not read the\n * agent\": no VIEW on it (`UNAUTHORIZED`, `FORBIDDEN`), or it lives in another\n * workspace (`WORKSPACE_MISMATCH`). Asking again answers the same.\n */\nconst AGENT_READ_DENIAL_CODES: ReadonlySet<string> = new Set([\n 'UNAUTHORIZED',\n 'FORBIDDEN',\n 'WORKSPACE_MISMATCH',\n]);\n\n/** What reading the agent's published models found: its models, or that this person cannot know them. */\nexport type AgentModelRead = { readable: true; source: AgentModelSource | null } | { readable: false };\n\n/**\n * Where `useAthenaAgentModelOptions` stands:\n *\n * - `idle`: no agent given;\n * - `loading`: the agent (or the model catalog that names its models) is being read;\n * - `ready`: the agent's published models are known;\n * - `unavailable`: this person cannot know them: no VIEW on the agent, no such\n * agent, or one never published (or whose published definition names no\n * model). Not an error: `allowAnyModel` stays `true`, so a picker keeps the\n * workspace's models;\n * - `error`: the read failed (network, server); `allowAnyModel` stays `true`.\n */\nexport type AthenaAgentModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'unavailable' | 'error';\n\nexport interface AthenaAgentModelOptions {\n status: AthenaAgentModelOptionsStatus;\n /** The agent's model choices (see {@link AthenaAgentModelOption}); empty unless `ready`. */\n options: readonly AthenaAgentModelOption[];\n /**\n * The model the thread runs while it pins none: the channel's override, else\n * the agent's own model. `null` unless `ready`.\n */\n defaultModel: string | null;\n /**\n * Whether people may pick any workspace model with this agent: the agent's\n * \"Allow any workspace model\" switch (`allowAnyModel` in its published\n * definition). Only an explicit `false` restricts a picker to `options`;\n * absent, `null` or `true` (every agent saved before the switch) allow any,\n * and so does an agent this person cannot read. `true` unless `ready`.\n */\n allowAnyModel: boolean;\n}\n\nconst NO_AGENT_MODEL_OPTIONS: Readonly<\n Record<Exclude<AthenaAgentModelOptionsStatus, 'ready'>, AthenaAgentModelOptions>\n> = {\n idle: { status: 'idle', options: [], defaultModel: null, allowAnyModel: true },\n loading: { status: 'loading', options: [], defaultModel: null, allowAnyModel: true },\n unavailable: { status: 'unavailable', options: [], defaultModel: null, allowAnyModel: true },\n error: { status: 'error', options: [], defaultModel: null, allowAnyModel: true },\n};\n\n/** Whether a failed read is a denial: an answer, not a failure (nothing to retry or report). */\nexport function isAgentReadDenial(error: unknown): boolean {\n return (\n error instanceof AthenaGraphQLError &&\n error.code !== null &&\n AGENT_READ_DENIAL_CODES.has(error.code)\n );\n}\n\n/**\n * A selected collab agent's own model choices, and whether the agent restricts\n * a picker to them (`allowAnyModel: false`, the agent's \"Allow any workspace\n * model\" switch turned off). Restriction is opt-in per agent: with\n * `allowAnyModel` true (the default) a picker keeps the workspace's models and\n * can still show `defaultModel` as the agent's own; `ChatModelPicker` does\n * both.\n *\n * `agent` is the agent's asset id or its `collab_agent:<id>` ref (`null`:\n * none, `idle`). `channel` is the collab channel the chat runs on: its model\n * override is the default there. The rules are in `agent-model-options.ts`.\n *\n * The agent is read through `getAssetById(withMetadata: true)`, the\n * permission-checked asset read (VIEW on the agent), with the provider's\n * credentials: a person without VIEW gets `unavailable` with no options. The\n * model the thread pins comes from `useAthenaThreadModel()` (inside\n * `<AthenaProvider>`; none outside one): a pinned model outside the agent's\n * list is an option with `pinnedOutside`.\n *\n * Picking the `isDefault` option means \"no model\": hand the provider\n * `model={undefined}` so the agent's (or channel's) default runs, and a session\n * pinning another model is unpinned.\n *\n * While shown, the agent is read again every\n * {@link AGENT_MODELS_REFRESH_MS}: an author publishing new models elsewhere\n * invalidates nothing here.\n */\nexport function useAthenaAgentModelOptions({\n agent,\n channel = null,\n}: {\n agent: string | null | undefined;\n channel?: string | null;\n}): AthenaAgentModelOptions {\n return useAgentModelChoices({ agent, channel }).choices;\n}\n\n/** How often an agent's published models are read again while a hook shows them. */\nexport const AGENT_MODELS_REFRESH_MS = 60 * 1000;\n\n/**\n * The re-read cadence of an agent model read: every\n * {@link AGENT_MODELS_REFRESH_MS} while it answers, never for a denial (asking\n * again answers the same).\n */\nexport function agentModelsRefetchInterval({\n data,\n}: {\n data: AgentModelRead | undefined;\n}): number | false {\n return data !== undefined && !data.readable ? false : AGENT_MODELS_REFRESH_MS;\n}\n\n/**\n * {@link useAthenaAgentModelOptions} plus the catalog label of any model id,\n * from the same query client and catalog read (a picker needs both; reading\n * the catalog again through its own client would fetch it twice). Internal.\n */\nexport function useAgentModelChoices({\n agent,\n channel,\n}: {\n agent: string | null | undefined;\n channel: string | null;\n}): {\n choices: AthenaAgentModelOptions;\n modelLabel: (model: string) => string;\n /** The workspace model catalog, read through the same client as the agent. */\n catalog: ReturnType<typeof useModelCatalogQuery>;\n} {\n const assetId = agentAssetIdOf(agent);\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-models', auth.backendUrl, principal, assetId],\n queryFn: async (): Promise<AgentModelRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModelSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled: assetId !== null,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) => agentModelsRefetchInterval({ data: query.state.data }),\n },\n queryClient,\n );\n const catalog = useModelCatalogQuery({ auth, principal, queryClient });\n const threadModel = useOptionalAthenaThreadModel();\n const pinnedModel =\n threadModel !== null && threadModel.ready && threadModel.configured ? threadModel.model : null;\n const trimmedChannel = channel?.trim() || null;\n const models = catalog.data;\n const catalogPending = catalog.isPending;\n const { isPending: readPending, data: readData } = read;\n const modelLabel = useCallback(\n (model: string) => models?.find((option) => option.id === model)?.label ?? model,\n [models],\n );\n const choices = useMemo((): AthenaAgentModelOptions => {\n if (assetId === null) return NO_AGENT_MODEL_OPTIONS.idle;\n // A failed re-read keeps the last answer; only a first read that failed is an error.\n if (readData === undefined) {\n return readPending ? NO_AGENT_MODEL_OPTIONS.loading : NO_AGENT_MODEL_OPTIONS.error;\n }\n if (!readData.readable || readData.source === null) return NO_AGENT_MODEL_OPTIONS.unavailable;\n // The catalog names the models: wait for it, unless it failed (ids then name them).\n if (catalogPending) return NO_AGENT_MODEL_OPTIONS.loading;\n return {\n status: 'ready',\n ...buildAgentModelOptions({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }, [assetId, readPending, readData, catalogPending, modelLabel, trimmedChannel, pinnedModel]);\n return useMemo(() => ({ choices, modelLabel, catalog }), [choices, modelLabel, catalog]);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-catalog.js","sources":["../../src/catalog/runtime-catalog.ts"],"sourcesContent":["import {\n filterAndSortCatalogModels,\n normalizeCatalogAgentOptions,\n} from '@athenaintel/agent-runtime/runtime-catalog';\nimport { QueryClient, QueryClientContext, useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useState } from 'react';\nimport { AthenaAuthContext } from '../auth/AthenaAuthContext';\nimport {\n AthenaGraphQLError,\n fetchGraphQL,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { useOptionalAthenaThreadModel } from '../threads/use-athena-thread-model';\nimport {\n type AgentModelSource,\n type AthenaAgentModelOption,\n agentAssetIdOf,\n agentModelOptionsWithoutDefault,\n buildAgentModelOptions,\n publishedAgentModelSource,\n} from './agent-model-options';\nimport {\n ATHENA_CHANNEL_REFUSAL_QUERY,\n answersWithoutRefusalDay,\n channelReplacementsRefusalStartsAt,\n channelReplacementsRefusedOn,\n refusalDayOf,\n} from './channel-refusal';\n\n/**\n * The workspace's runtime catalog for a chat's model and agent pickers: the models the signed-in\n * person may run (the workspace's allow or deny list, admin-only models for admins), and the\n * published collab agents they can see. The rules are the Chrome extension's, which every host now\n * reads from here.\n */\n\nexport type AthenaModelStatus = 'ACTIVE' | 'LEGACY' | 'RECOMMENDED';\n\nexport interface AthenaModelOption {\n id: string;\n label: string;\n description: string | null;\n /** Upper-case provider key, e.g. `ANTHROPIC`, `OPENAI`. */\n provider: string;\n status: AthenaModelStatus;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n}\n\nexport interface AthenaAgentOption {\n /** The collab agent's asset id; pass `collab_agent:<id>` as the provider's `agent`. */\n id: string;\n name: string;\n}\n\n/** The provider labels a model picker groups by. */\nexport const MODEL_PROVIDER_LABELS: Readonly<Record<string, string>> = {\n ANTHROPIC: 'Anthropic',\n OPENAI: 'OpenAI',\n GOOGLE: 'Google',\n XAI: 'xAI',\n META: 'Meta',\n MISTRAL: 'Mistral',\n DEEPSEEK: 'DeepSeek',\n QWEN: 'Qwen',\n MOONSHOT: 'Moonshot',\n MINIMAX: 'MiniMax',\n ZAI: 'Z.ai',\n};\n\nexport const ATHENA_MODEL_CATALOG_QUERY = `\n query AthenaModelCatalog {\n getCurrentUserWithWorkspace { user { isAdmin } }\n settings { workspace { approvedLargeLlms blacklistedLlms } }\n availableModels {\n id name provider status description adminOnly sortOrder\n familyId familyName isFamilyDefault isFeatured variantOrder\n }\n }\n`;\n\nexport const ATHENA_AGENT_CATALOG_QUERY = `\n query AthenaAgentCatalog {\n getAllAssets(filterByAthenaOriginalType: [\"collab_agent\"]) { id title }\n }\n`;\n\nexport interface AthenaModelCatalogResponse {\n getCurrentUserWithWorkspace: { user: { isAdmin: boolean } };\n settings: { workspace: { approvedLargeLlms: string[]; blacklistedLlms: string[] } };\n availableModels: Array<{\n id: string;\n name: string;\n provider: string;\n status: AthenaModelStatus;\n description: string | null;\n adminOnly: boolean;\n sortOrder: number;\n familyId: string;\n familyName: string;\n isFamilyDefault: boolean;\n isFeatured: boolean;\n variantOrder: number;\n }>;\n}\n\n/**\n * The models the person may pick, in catalog order. A workspace with an allow list offers only\n * those; otherwise everything except its deny list. Admin-only models are offered to admins only.\n */\nexport function normalizeModelCatalog({\n response,\n}: {\n response: AthenaModelCatalogResponse;\n}): AthenaModelOption[] {\n return filterAndSortCatalogModels({\n models: response.availableModels,\n isAdmin: response.getCurrentUserWithWorkspace.user.isAdmin,\n approvedModelIds: response.settings.workspace.approvedLargeLlms,\n deniedModelIds: response.settings.workspace.blacklistedLlms,\n }).map(\n (model): AthenaModelOption => ({\n id: model.id,\n label: model.name,\n description: model.description,\n provider: model.provider,\n status: model.status,\n sortOrder: model.sortOrder,\n familyId: model.familyId,\n familyName: model.familyName,\n isFamilyDefault: model.isFamilyDefault,\n isFeatured: model.isFeatured,\n variantOrder: model.variantOrder,\n }),\n );\n}\n\n/** The published collab agents, named and sorted; assets with a blank id are dropped. */\nexport function normalizeAgentCatalog({\n assets,\n}: {\n assets: ReadonlyArray<{ id: string; title: string | null }>;\n}): AthenaAgentOption[] {\n return normalizeCatalogAgentOptions({ assets });\n}\n\n/**\n * The model a picker shows as chosen: the stored choice while the catalog offers it, else the\n * default (unless retired), else a recommended family default, else any live model. While the\n * catalog is empty (loading, or unreachable) the stored choice or the default stands.\n */\nexport function resolveCatalogModelId({\n stored,\n defaultModelId,\n models,\n}: {\n stored: string | null;\n defaultModelId: string;\n models: readonly AthenaModelOption[];\n}): string {\n if (stored && models.some((model) => model.id === stored)) return stored;\n return (\n (\n models.find((model) => model.id === defaultModelId && model.status !== 'LEGACY') ??\n models.find((model) => model.status === 'RECOMMENDED' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY' && model.isFamilyDefault) ??\n models.find((model) => model.status !== 'LEGACY') ??\n models[0]\n )?.id ?? (stored || defaultModelId)\n );\n}\n\n/** Models grouped under their provider's label, in catalog order. */\nexport function groupModelsByProvider({\n models,\n}: {\n models: readonly AthenaModelOption[];\n}): Array<{ provider: string; models: AthenaModelOption[] }> {\n const groups = new Map<string, AthenaModelOption[]>();\n for (const model of models) {\n const label = MODEL_PROVIDER_LABELS[model.provider] ?? model.provider;\n groups.set(label, [...(groups.get(label) ?? []), model]);\n }\n return Array.from(groups, ([provider, grouped]) => ({ provider, models: grouped }));\n}\n\n/** The provider's credentials as the SDK's GraphQL client takes them. Internal. */\nexport function useCatalogAuth(): MentionAuthContext {\n const config = useAthenaConfig();\n return useMemo<MentionAuthContext>(\n () => ({\n backendUrl: config.backendUrl,\n appUrl: config.appUrl,\n apiKey: config.apiKey,\n credentials: 'include',\n get accessToken() {\n return config.token ?? undefined;\n },\n getAccessToken: async () => (await config.getToken?.()) ?? undefined,\n renewAccessToken: async () => (await config.getToken?.({ force: true })) ?? undefined,\n }),\n [config],\n );\n}\n\n/**\n * A short fingerprint (two FNV-1a rounds, 64 bits) of a credential: it tells accounts apart in an\n * in-memory cache key without the credential itself, or anything it could be recovered from,\n * entering the key.\n */\nexport function credentialFingerprint({ credential }: { credential: string }): string {\n const round = (seed: number) => {\n let hash = seed;\n for (let index = 0; index < credential.length; index += 1) {\n hash ^= credential.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, '0');\n };\n return `${round(0x811c9dc5)}${round(0x01000193)}`;\n}\n\n/**\n * Who is asking, for the cache key: the catalog differs per account (admin-only models, the\n * workspace's lists, the agents shared with them), and a host can switch accounts while keeping its\n * query client. The signed-in user's id when the SDK knows it, else a fingerprint of the credential\n * in use. Never the credential itself.\n */\nexport function useCatalogPrincipal(): string {\n const config = useAthenaConfig();\n const userId = useContext(AthenaAuthContext)?.user?.userId;\n if (userId) return `user:${userId}`;\n if (config.apiKey) return `key:${credentialFingerprint({ credential: config.apiKey })}`;\n if (config.token) return `token:${credentialFingerprint({ credential: config.token })}`;\n return 'session';\n}\n\n/**\n * The host's QueryClient when there is one (the thread list provides one), else one of the\n * pickers' own, so the catalog hooks work with or without the thread list.\n */\nexport function useCatalogQueryClient(): QueryClient {\n const host = useContext(QueryClientContext);\n const [own] = useState(() => new QueryClient());\n return host ?? own;\n}\n\n/** The models the signed-in person may pick (`normalizeModelCatalog`). */\nexport function useAthenaModelCatalog() {\n return useModelCatalogQuery({\n auth: useCatalogAuth(),\n principal: useCatalogPrincipal(),\n queryClient: useCatalogQueryClient(),\n });\n}\n\n/** The model catalog's query on a given client (one client for every read a hook makes). */\nfunction useModelCatalogQuery({\n auth,\n principal,\n queryClient,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n}) {\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'models', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeModelCatalog({\n response: await fetchGraphQL<AthenaModelCatalogResponse>(auth, ATHENA_MODEL_CATALOG_QUERY),\n }),\n staleTime: 5 * 60 * 1000,\n },\n queryClient,\n );\n}\n\n/** The published collab agents the signed-in person can see (`normalizeAgentCatalog`). */\nexport function useAthenaAgentCatalog() {\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n return useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agents', auth.backendUrl, principal],\n queryFn: async () =>\n normalizeAgentCatalog({\n assets:\n (\n await fetchGraphQL<{ getAllAssets: Array<{ id: string; title: string | null }> }>(\n auth,\n ATHENA_AGENT_CATALOG_QUERY,\n )\n ).getAllAssets ?? [],\n }),\n staleTime: 60 * 1000,\n },\n queryClient,\n );\n}\n\nexport const ATHENA_AGENT_MODELS_QUERY = `\n query AthenaAgentModels($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The `getAssetById` error codes that mean \"this person may not read the\n * agent\": no VIEW on it (`UNAUTHORIZED`, `FORBIDDEN`), or it lives in another\n * workspace (`WORKSPACE_MISMATCH`). Asking again answers the same.\n */\nconst AGENT_READ_DENIAL_CODES: ReadonlySet<string> = new Set([\n 'UNAUTHORIZED',\n 'FORBIDDEN',\n 'WORKSPACE_MISMATCH',\n]);\n\n/** What reading the agent's published models found: its models, or that this person cannot know them. */\nexport type AgentModelRead = { readable: true; source: AgentModelSource | null } | { readable: false };\n\n/**\n * Where `useAthenaAgentModelOptions` stands:\n *\n * - `idle`: no agent given;\n * - `loading`: the agent (or the model catalog that names its models) is being read;\n * - `ready`: the agent's published models are known;\n * - `unavailable`: this person cannot know them: no VIEW on the agent, no such\n * agent, or one never published (or whose published definition names no\n * model). Not an error: `allowAnyModel` stays `true`, so a picker keeps the\n * workspace's models;\n * - `error`: the read failed (network, server); `allowAnyModel` stays `true`.\n */\nexport type AthenaAgentModelOptionsStatus = 'idle' | 'loading' | 'ready' | 'unavailable' | 'error';\n\nexport interface AthenaAgentModelOptions {\n status: AthenaAgentModelOptionsStatus;\n /** The agent's model choices (see {@link AthenaAgentModelOption}); empty unless `ready`. */\n options: readonly AthenaAgentModelOption[];\n /**\n * The model the thread runs while it pins none: the channel's override, else\n * the agent's own model. From the deployment's refusal day (identity v7 D12,\n * `FeatureGateEnv.channelReplacementsRefusedFrom`) Athena no longer applies a\n * channel's model, so this is the agent's own on every channel. `null` unless\n * `ready`, and also `null` on a channel until the day's first read answers:\n * meanwhile `options` are the agent's own models, none marked default.\n */\n defaultModel: string | null;\n /**\n * Whether people may pick any workspace model with this agent: the agent's\n * \"Allow any workspace model\" switch (`allowAnyModel` in its published\n * definition). Only an explicit `false` restricts a picker to `options`;\n * absent, `null` or `true` (every agent saved before the switch) allow any,\n * and so does an agent this person cannot read. `true` unless `ready`.\n */\n allowAnyModel: boolean;\n}\n\nconst NO_AGENT_MODEL_OPTIONS: Readonly<\n Record<Exclude<AthenaAgentModelOptionsStatus, 'ready'>, AthenaAgentModelOptions>\n> = {\n idle: { status: 'idle', options: [], defaultModel: null, allowAnyModel: true },\n loading: { status: 'loading', options: [], defaultModel: null, allowAnyModel: true },\n unavailable: { status: 'unavailable', options: [], defaultModel: null, allowAnyModel: true },\n error: { status: 'error', options: [], defaultModel: null, allowAnyModel: true },\n};\n\n/** Whether a failed read is a denial: an answer, not a failure (nothing to retry or report). */\nexport function isAgentReadDenial(error: unknown): boolean {\n return (\n error instanceof AthenaGraphQLError &&\n error.code !== null &&\n AGENT_READ_DENIAL_CODES.has(error.code)\n );\n}\n\n/**\n * A selected collab agent's own model choices, and whether the agent restricts\n * a picker to them (`allowAnyModel: false`, the agent's \"Allow any workspace\n * model\" switch turned off). Restriction is opt-in per agent: with\n * `allowAnyModel` true (the default) a picker keeps the workspace's models and\n * can still show `defaultModel` as the agent's own; `ChatModelPicker` does\n * both.\n *\n * `agent` is the agent's asset id or its `collab_agent:<id>` ref (`null`:\n * none, `idle`). `channel` is the collab channel the chat runs on: its model\n * override is the default there, until the deployment's refusal day (identity\n * v7 D12), which a chat with a channel reads from `featureGateEnv` and follows\n * across UTC midnight. The rules are in `agent-model-options.ts`.\n *\n * The agent is read through `getAssetById(withMetadata: true)`, the\n * permission-checked asset read (VIEW on the agent), with the provider's\n * credentials: a person without VIEW gets `unavailable` with no options. The\n * model the thread pins comes from `useAthenaThreadModel()` (inside\n * `<AthenaProvider>`; none outside one): a pinned model outside the agent's\n * list is an option with `pinnedOutside`.\n *\n * Picking the `isDefault` option means \"no model\": hand the provider\n * `model={undefined}` so the agent's (or channel's) default runs, and a session\n * pinning another model is unpinned.\n *\n * While shown, the agent is read again every\n * {@link AGENT_MODELS_REFRESH_MS}: an author publishing new models elsewhere\n * invalidates nothing here.\n */\nexport function useAthenaAgentModelOptions({\n agent,\n channel = null,\n}: {\n agent: string | null | undefined;\n channel?: string | null;\n}): AthenaAgentModelOptions {\n return useAgentModelChoices({ agent, channel }).choices;\n}\n\n/** How often an agent's published models are read again while a hook shows them. */\nexport const AGENT_MODELS_REFRESH_MS = 60 * 1000;\n\n/**\n * The re-read cadence of an agent model read: every\n * {@link AGENT_MODELS_REFRESH_MS} while it answers, never for a denial (asking\n * again answers the same).\n */\nexport function agentModelsRefetchInterval({\n data,\n}: {\n data: AgentModelRead | undefined;\n}): number | false {\n return data !== undefined && !data.readable ? false : AGENT_MODELS_REFRESH_MS;\n}\n\n/** `setTimeout` holds at most 2^31 - 1 ms (about 24.8 days); a later day is waited for in steps. */\nconst MAX_TIMER_MS = 2 ** 31 - 1;\n\n/** Where a picker stands on the deployment's refusal day. */\ninterface ChannelRefusal {\n /** The day's first read is still out: a picker names no default until it answers. */\n pending: boolean;\n /** The day has come: a channel's model no longer applies. */\n refused: boolean;\n}\n\n/**\n * Whether the deployment's refusal day has come (identity v7 D12, `channel-refusal.ts`), rendering\n * again at UTC midnight of the day, so a picker open across it turns without a reload. The day is\n * read only while `enabled` (an agent and a channel: no channel, no channel model to refuse) and\n * again every {@link AGENT_MODELS_REFRESH_MS}, as the agent is. Only an agora whose schema lacks\n * the field (one from before D12's date, which refuses nothing) answers \"no day\"; any other failure\n * is a failed read, which keeps the day last read (TanStack keeps a query's data across a failed\n * re-read). Display only: agora decides at every compile from its own setting.\n */\nfunction useChannelReplacementsRefused({\n auth,\n principal,\n queryClient,\n enabled,\n}: {\n auth: MentionAuthContext;\n principal: string;\n queryClient: QueryClient;\n enabled: boolean;\n}): ChannelRefusal {\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'channel-refusal-day', auth.backendUrl, principal],\n queryFn: async (): Promise<string | null> => {\n try {\n return refusalDayOf(await fetchGraphQL<unknown>(auth, ATHENA_CHANNEL_REFUSAL_QUERY));\n } catch (error) {\n if (\n error instanceof AthenaGraphQLError &&\n error.status === null &&\n answersWithoutRefusalDay(error.message)\n ) {\n return null;\n }\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: AGENT_MODELS_REFRESH_MS,\n // A picker waits on the first answer: one retry, not TanStack's three.\n retry: 1,\n },\n queryClient,\n );\n const refusedFrom = enabled ? (read.data ?? null) : null;\n const [tick, setTick] = useState(0);\n const refused = channelReplacementsRefusedOn({ refusedFrom, now: Date.now() });\n const startsAt = refused ? null : channelReplacementsRefusalStartsAt(refusedFrom);\n useEffect(() => {\n // `tick` is read so that a step short of a far day waits again.\n if (startsAt === null || tick < 0) return;\n const delay = Math.min(Math.max(startsAt - Date.now(), 0), MAX_TIMER_MS);\n const timer = setTimeout(() => setTick((value) => value + 1), delay);\n return () => clearTimeout(timer);\n }, [startsAt, tick]);\n // A first read that failed leaves the day unknown: the picker shows what it showed before D12.\n return { pending: enabled && read.isPending, refused };\n}\n\n/**\n * {@link useAthenaAgentModelOptions} plus the catalog label of any model id,\n * from the same query client and catalog read (a picker needs both; reading\n * the catalog again through its own client would fetch it twice). Internal.\n */\nexport function useAgentModelChoices({\n agent,\n channel,\n}: {\n agent: string | null | undefined;\n channel: string | null;\n}): {\n choices: AthenaAgentModelOptions;\n modelLabel: (model: string) => string;\n /** The workspace model catalog, read through the same client as the agent. */\n catalog: ReturnType<typeof useModelCatalogQuery>;\n} {\n const assetId = agentAssetIdOf(agent);\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n const read = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-models', auth.backendUrl, principal, assetId],\n queryFn: async (): Promise<AgentModelRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModelSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled: assetId !== null,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) => agentModelsRefetchInterval({ data: query.state.data }),\n },\n queryClient,\n );\n const catalog = useModelCatalogQuery({ auth, principal, queryClient });\n const threadModel = useOptionalAthenaThreadModel();\n const pinnedModel =\n threadModel !== null && threadModel.ready && threadModel.configured ? threadModel.model : null;\n const trimmedChannel = channel?.trim() || null;\n const refusal = useChannelReplacementsRefused({\n auth,\n principal,\n queryClient,\n enabled: assetId !== null && trimmedChannel !== null,\n });\n const { pending: refusalPending, refused: refuseReplacements } = refusal;\n const models = catalog.data;\n const catalogPending = catalog.isPending;\n const { isPending: readPending, data: readData } = read;\n const modelLabel = useCallback(\n (model: string) => models?.find((option) => option.id === model)?.label ?? model,\n [models],\n );\n const choices = useMemo((): AthenaAgentModelOptions => {\n if (assetId === null) return NO_AGENT_MODEL_OPTIONS.idle;\n // A failed re-read keeps the last answer; only a first read that failed is an error.\n if (readData === undefined) {\n return readPending ? NO_AGENT_MODEL_OPTIONS.loading : NO_AGENT_MODEL_OPTIONS.error;\n }\n if (!readData.readable || readData.source === null) return NO_AGENT_MODEL_OPTIONS.unavailable;\n // The catalog names the models: wait for it, unless it failed (ids then name them).\n if (catalogPending) return NO_AGENT_MODEL_OPTIONS.loading;\n // On a channel the default turns on the refusal day. Until its first answer, offer the agent's\n // own models with their restriction kept, and name no default: never the refused channel's.\n if (refusalPending) {\n return {\n status: 'ready',\n ...agentModelOptionsWithoutDefault({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }\n return {\n status: 'ready',\n ...buildAgentModelOptions({\n source: readData.source,\n channel: trimmedChannel,\n pinnedModel,\n modelLabel,\n refuseReplacements,\n }),\n allowAnyModel: readData.source.allowAnyModel,\n };\n }, [\n assetId,\n readPending,\n readData,\n catalogPending,\n modelLabel,\n trimmedChannel,\n pinnedModel,\n refusalPending,\n refuseReplacements,\n ]);\n return useMemo(() => ({ choices, modelLabel, catalog }), [choices, modelLabel, catalog]);\n}\n"],"names":[],"mappings":";;;;;;;;;AA6DO,MAAM,wBAA0D;AAAA,EACrE,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,KAAK;AACP;AAEO,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWnC,MAAM,6BAA6B;AAAA;AAAA;AAAA;AAAA;AA6BnC,SAAS,sBAAsB;AAAA,EACpC;AACF,GAEwB;AACtB,SAAO,2BAA2B;AAAA,IAChC,QAAQ,SAAS;AAAA,IACjB,SAAS,SAAS,4BAA4B,KAAK;AAAA,IACnD,kBAAkB,SAAS,SAAS,UAAU;AAAA,IAC9C,gBAAgB,SAAS,SAAS,UAAU;AAAA,EAAA,CAC7C,EAAE;AAAA,IACD,CAAC,WAA8B;AAAA,MAC7B,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb,aAAa,MAAM;AAAA,MACnB,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,iBAAiB,MAAM;AAAA,MACvB,YAAY,MAAM;AAAA,MAClB,cAAc,MAAM;AAAA,IAAA;AAAA,EACtB;AAEJ;AAGO,SAAS,sBAAsB;AAAA,EACpC;AACF,GAEwB;AACtB,SAAO,6BAA6B,EAAE,QAAQ;AAChD;AAOO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAIW;;AACT,MAAI,UAAU,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,EAAG,QAAO;AAClE,WAEI,YAAO,KAAK,CAAC,UAAU,MAAM,OAAO,kBAAkB,MAAM,WAAW,QAAQ,KAC/E,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,iBAAiB,MAAM,eAAe,KAC9E,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,YAAY,MAAM,eAAe,KACzE,OAAO,KAAK,CAAC,UAAU,MAAM,WAAW,QAAQ,KAChD,OAAO,CAAC,MAJR,mBAKC,QAAO,UAAU;AAExB;AAGO,SAAS,sBAAsB;AAAA,EACpC;AACF,GAE6D;AAC3D,QAAM,6BAAa,IAAA;AACnB,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,sBAAsB,MAAM,QAAQ,KAAK,MAAM;AAC7D,WAAO,IAAI,OAAO,CAAC,GAAI,OAAO,IAAI,KAAK,KAAK,IAAK,KAAK,CAAC;AAAA,EACzD;AACA,SAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,UAAU,OAAO,OAAO,EAAE,UAAU,QAAQ,QAAA,EAAU;AACpF;AAGO,SAAS,iBAAqC;AACnD,QAAM,SAAS,gBAAA;AACf,SAAO;AAAA,IACL,OAAO;AAAA,MACL,YAAY,OAAO;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf,aAAa;AAAA,MACb,IAAI,cAAc;AAChB,eAAO,OAAO,SAAS;AAAA,MACzB;AAAA,MACA,gBAAgB,YAAA;;AAAa,uBAAM,YAAO,aAAP,oCAAwB;AAAA;AAAA,MAC3D,kBAAkB,YAAA;;AAAa,uBAAM,YAAO,aAAP,gCAAkB,EAAE,OAAO,KAAA,OAAY;AAAA;AAAA,IAAA;AAAA,IAE9E,CAAC,MAAM;AAAA,EAAA;AAEX;AAOO,SAAS,sBAAsB,EAAE,cAA8C;AACpF,QAAM,QAAQ,CAAC,SAAiB;AAC9B,QAAI,OAAO;AACX,aAAS,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS,GAAG;AACzD,cAAQ,WAAW,WAAW,KAAK;AACnC,aAAO,KAAK,KAAK,MAAM,QAAU,MAAM;AAAA,IACzC;AACA,WAAO,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,EAC1C;AACA,SAAO,GAAG,MAAM,UAAU,CAAC,GAAG,MAAM,QAAU,CAAC;AACjD;AAQO,SAAS,sBAA8B;;AAC5C,QAAM,SAAS,gBAAA;AACf,QAAM,UAAS,sBAAW,iBAAiB,MAA5B,mBAA+B,SAA/B,mBAAqC;AACpD,MAAI,OAAQ,QAAO,QAAQ,MAAM;AACjC,MAAI,OAAO,OAAQ,QAAO,OAAO,sBAAsB,EAAE,YAAY,OAAO,OAAA,CAAQ,CAAC;AACrF,MAAI,OAAO,MAAO,QAAO,SAAS,sBAAsB,EAAE,YAAY,OAAO,MAAA,CAAO,CAAC;AACrF,SAAO;AACT;AAMO,SAAS,wBAAqC;AACnD,QAAM,OAAO,WAAW,kBAAkB;AAC1C,QAAM,CAAC,GAAG,IAAI,SAAS,MAAM,IAAI,aAAa;AAC9C,SAAO,QAAQ;AACjB;AAGO,SAAS,wBAAwB;AACtC,SAAO,qBAAqB;AAAA,IAC1B,MAAM,eAAA;AAAA,IACN,WAAW,oBAAA;AAAA,IACX,aAAa,sBAAA;AAAA,EAAsB,CACpC;AACH;AAGA,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SAAO;AAAA,IACL;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,UAAU,KAAK,YAAY,SAAS;AAAA,MACxE,SAAS,YACP,sBAAsB;AAAA,QACpB,UAAU,MAAM,aAAyC,MAAM,0BAA0B;AAAA,MAAA,CAC1F;AAAA,MACH,WAAW,IAAI,KAAK;AAAA,IAAA;AAAA,IAEtB;AAAA,EAAA;AAEJ;AAGO,SAAS,wBAAwB;AACtC,QAAM,OAAO,eAAA;AACb,QAAM,YAAY,oBAAA;AAClB,QAAM,cAAc,sBAAA;AACpB,SAAO;AAAA,IACL;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,UAAU,KAAK,YAAY,SAAS;AAAA,MACxE,SAAS,YACP,sBAAsB;AAAA,QACpB,SAEI,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,QAAA,GAEF,gBAAgB,CAAA;AAAA,MAAC,CACtB;AAAA,MACH,WAAW,KAAK;AAAA,IAAA;AAAA,IAElB;AAAA,EAAA;AAEJ;AAEO,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAWzC,MAAM,8CAAmD,IAAI;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA0CD,MAAM,yBAEF;AAAA,EACF,MAAM,EAAE,QAAQ,QAAQ,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EACxE,SAAS,EAAE,QAAQ,WAAW,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EAC9E,aAAa,EAAE,QAAQ,eAAe,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAAA,EACtF,OAAO,EAAE,QAAQ,SAAS,SAAS,CAAA,GAAI,cAAc,MAAM,eAAe,KAAA;AAC5E;AAGO,SAAS,kBAAkB,OAAyB;AACzD,SACE,iBAAiB,sBACjB,MAAM,SAAS,QACf,wBAAwB,IAAI,MAAM,IAAI;AAE1C;AA+BO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA,UAAU;AACZ,GAG4B;AAC1B,SAAO,qBAAqB,EAAE,OAAO,QAAA,CAAS,EAAE;AAClD;AAGO,MAAM,0BAA0B,KAAK;AAOrC,SAAS,2BAA2B;AAAA,EACzC;AACF,GAEmB;AACjB,SAAO,SAAS,UAAa,CAAC,KAAK,WAAW,QAAQ;AACxD;AAGA,MAAM,eAAe,KAAK,KAAK;AAmB/B,SAAS,8BAA8B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKmB;AACjB,QAAM,OAAO;AAAA,IACX;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,uBAAuB,KAAK,YAAY,SAAS;AAAA,MACrF,SAAS,YAAoC;AAC3C,YAAI;AACF,iBAAO,aAAa,MAAM,aAAsB,MAAM,4BAA4B,CAAC;AAAA,QACrF,SAAS,OAAO;AACd,cACE,iBAAiB,sBACjB,MAAM,WAAW,QACjB,yBAAyB,MAAM,OAAO,GACtC;AACA,mBAAO;AAAA,UACT;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,iBAAiB;AAAA;AAAA,MAEjB,OAAO;AAAA,IAAA;AAAA,IAET;AAAA,EAAA;AAEF,QAAM,cAAc,UAAW,KAAK,QAAQ,OAAQ;AACpD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,CAAC;AAClC,QAAM,UAAU,6BAA6B,EAAE,aAAa,KAAK,KAAK,IAAA,GAAO;AAC7E,QAAM,WAAW,UAAU,OAAO,mCAAmC,WAAW;AAChF,YAAU,MAAM;AAEd,QAAI,aAAa,QAAQ,OAAO,EAAG;AACnC,UAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,WAAW,KAAK,IAAA,GAAO,CAAC,GAAG,YAAY;AACvE,UAAM,QAAQ,WAAW,MAAM,QAAQ,CAAC,UAAU,QAAQ,CAAC,GAAG,KAAK;AACnE,WAAO,MAAM,aAAa,KAAK;AAAA,EACjC,GAAG,CAAC,UAAU,IAAI,CAAC;AAEnB,SAAO,EAAE,SAAS,WAAW,KAAK,WAAW,QAAA;AAC/C;AAOO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAQE;AACA,QAAM,UAAU,eAAe,KAAK;AACpC,QAAM,OAAO,eAAA;AACb,QAAM,YAAY,oBAAA;AAClB,QAAM,cAAc,sBAAA;AACpB,QAAM,OAAO;AAAA,IACX;AAAA,MACE,UAAU,CAAC,cAAc,WAAW,gBAAgB,KAAK,YAAY,WAAW,OAAO;AAAA,MACvF,SAAS,YAAqC;AAC5C,YAAI;AACF,gBAAM,OAAO,MAAM;AAAA,YACjB;AAAA,YACA;AAAA,YACA,EAAE,QAAA;AAAA,UAAQ;AAEZ,cAAI,KAAK,iBAAiB,KAAM,QAAO,EAAE,UAAU,MAAA;AACnD,iBAAO;AAAA,YACL,UAAU;AAAA,YACV,QAAQ,0BAA0B,KAAK,aAAa,cAAc;AAAA,UAAA;AAAA,QAEtE,SAAS,OAAO;AACd,cAAI,kBAAkB,KAAK,EAAG,QAAO,EAAE,UAAU,MAAA;AACjD,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,SAAS,YAAY;AAAA,MACrB,WAAW;AAAA,MACX,iBAAiB,CAAC,UAAU,2BAA2B,EAAE,MAAM,MAAM,MAAM,KAAA,CAAM;AAAA,IAAA;AAAA,IAEnF;AAAA,EAAA;AAEF,QAAM,UAAU,qBAAqB,EAAE,MAAM,WAAW,aAAa;AACrE,QAAM,cAAc,6BAAA;AACpB,QAAM,cACJ,gBAAgB,QAAQ,YAAY,SAAS,YAAY,aAAa,YAAY,QAAQ;AAC5F,QAAM,kBAAiB,mCAAS,WAAU;AAC1C,QAAM,UAAU,8BAA8B;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,YAAY,QAAQ,mBAAmB;AAAA,EAAA,CACjD;AACD,QAAM,EAAE,SAAS,gBAAgB,SAAS,uBAAuB;AACjE,QAAM,SAAS,QAAQ;AACvB,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,EAAE,WAAW,aAAa,MAAM,aAAa;AACnD,QAAM,aAAa;AAAA,IACjB,CAAC,UAAA;;AAAkB,qDAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,WAAvC,mBAA+C,UAAS;AAAA;AAAA,IAC3E,CAAC,MAAM;AAAA,EAAA;AAET,QAAM,UAAU,QAAQ,MAA+B;AACrD,QAAI,YAAY,KAAM,QAAO,uBAAuB;AAEpD,QAAI,aAAa,QAAW;AAC1B,aAAO,cAAc,uBAAuB,UAAU,uBAAuB;AAAA,IAC/E;AACA,QAAI,CAAC,SAAS,YAAY,SAAS,WAAW,aAAa,uBAAuB;AAElF,QAAI,uBAAuB,uBAAuB;AAGlD,QAAI,gBAAgB;AAClB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,GAAG,gCAAgC;AAAA,UACjC,QAAQ,SAAS;AAAA,UACjB,SAAS;AAAA,UACT;AAAA,UACA;AAAA,QAAA,CACD;AAAA,QACD,eAAe,SAAS,OAAO;AAAA,MAAA;AAAA,IAEnC;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,GAAG,uBAAuB;AAAA,QACxB,QAAQ,SAAS;AAAA,QACjB,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,MACD,eAAe,SAAS,OAAO;AAAA,IAAA;AAAA,EAEnC,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AACD,SAAO,QAAQ,OAAO,EAAE,SAAS,YAAY,YAAY,CAAC,SAAS,YAAY,OAAO,CAAC;AACzF;"}
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react$1 = require("@assistant-ui/react");
3
+ const react = require("@assistant-ui/react");
4
4
  const reactQuery = require("@tanstack/react-query");
5
- const react = require("react");
5
+ const require$$0 = require("react");
6
6
  const apiClient = require("../chat-ui/mentions/suggestions/data/api-client.cjs");
7
7
  const agentSelectionContext = require("../provider/agent-selection-context.cjs");
8
8
  const chatModeContext = require("../provider/chat-mode-context.cjs");
@@ -18,8 +18,8 @@ const ATHENA_SESSION_MODE_QUERY = `
18
18
  `;
19
19
  function useAthenaChatMode() {
20
20
  var _a, _b, _c;
21
- const selection = react.useContext(chatModeContext.AthenaChatModeSelectionContext);
22
- const agentSelection = react.useContext(agentSelectionContext.AthenaAgentSelectionContext);
21
+ const selection = require$$0.useContext(chatModeContext.AthenaChatModeSelectionContext);
22
+ const agentSelection = require$$0.useContext(agentSelectionContext.AthenaAgentSelectionContext);
23
23
  const agentAssetId = (agentSelection == null ? void 0 : agentSelection.agentAssetId) ?? null;
24
24
  const channel = (agentSelection == null ? void 0 : agentSelection.channel) ?? null;
25
25
  const hostModes = (selection == null ? void 0 : selection.hostModes) ?? NO_MODES;
@@ -53,11 +53,11 @@ function useAthenaChatMode() {
53
53
  },
54
54
  queryClient
55
55
  );
56
- const threadEmpty = react$1.useAuiState((state) => {
56
+ const threadEmpty = react.useAuiState((state) => {
57
57
  var _a2;
58
58
  return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isEmpty) ?? true;
59
59
  });
60
- const threadRunning = react$1.useAuiState((state) => {
60
+ const threadRunning = react.useAuiState((state) => {
61
61
  var _a2;
62
62
  return ((_a2 = state.optional.thread) == null ? void 0 : _a2.isRunning) ?? false;
63
63
  });
@@ -84,14 +84,14 @@ function useAthenaChatMode() {
84
84
  queryClient
85
85
  );
86
86
  const refetchSession = sessionRead.refetch;
87
- const wasRunning = react.useRef(threadRunning);
88
- react.useEffect(() => {
87
+ const wasRunning = require$$0.useRef(threadRunning);
88
+ require$$0.useEffect(() => {
89
89
  const ended = wasRunning.current && !threadRunning;
90
90
  wasRunning.current = threadRunning;
91
91
  if (ended && readSession) void refetchSession();
92
92
  }, [threadRunning, readSession, refetchSession]);
93
93
  const source = ((_a = agentRead.data) == null ? void 0 : _a.readable) ? agentRead.data.source : null;
94
- const menu = react.useMemo(
94
+ const menu = require$$0.useMemo(
95
95
  () => source ? agentModeMenu.agentModeMenu({ source, channel, hostModes }) : null,
96
96
  [source, channel, hostModes]
97
97
  );
@@ -100,11 +100,11 @@ function useAthenaChatMode() {
100
100
  const sessionChannel = (session == null ? void 0 : session.exists) ? session.channel : null;
101
101
  const setPick = selection == null ? void 0 : selection.setPick;
102
102
  const setSessionChannel = selection == null ? void 0 : selection.setSessionChannel;
103
- react.useEffect(() => {
103
+ require$$0.useEffect(() => {
104
104
  if (!threadId || !setSessionChannel || session === void 0) return;
105
105
  setSessionChannel({ threadId, channel: sessionChannel });
106
106
  }, [threadId, setSessionChannel, session, sessionChannel]);
107
- react.useEffect(() => {
107
+ require$$0.useEffect(() => {
108
108
  if (!threadId || !setPick || pick === null) return;
109
109
  const applied = sessionChannel !== null && (sessionChannel === pick || source !== null && agentModeMenu.agentModeOfChannel({ source, channel: sessionChannel }) === pick);
110
110
  const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);
@@ -112,7 +112,7 @@ function useAthenaChatMode() {
112
112
  }, [threadId, setPick, pick, sessionChannel, source, menu]);
113
113
  const canSwitch = !((menu == null ? void 0 : menu.locked) && sessionStarted);
114
114
  const options = menu == null ? void 0 : menu.options;
115
- const select = react.useCallback(
115
+ const select = require$$0.useCallback(
116
116
  (modeId) => {
117
117
  if (!threadId || !setPick || !canSwitch) return;
118
118
  if (!(options == null ? void 0 : options.some((option) => option.id === modeId))) return;
@@ -1 +1 @@
1
- {"version":3,"file":"use-athena-chat-mode.cjs","sources":["../../src/catalog/use-athena-chat-mode.ts"],"sourcesContent":["import { useAuiState } from '@assistant-ui/react';\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport { fetchGraphQL } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { AthenaAgentSelectionContext } from '../provider/agent-selection-context';\nimport { AthenaChatModeSelectionContext } from '../provider/chat-mode-context';\nimport {\n type AgentModeSource,\n type AthenaChatModeOption,\n agentModeMenu,\n agentModeOfChannel,\n publishedAgentModeSource,\n sessionChannelFromMetadata,\n} from './agent-mode-menu';\nimport {\n AGENT_MODELS_REFRESH_MS,\n ATHENA_AGENT_MODELS_QUERY,\n isAgentReadDenial,\n useCatalogAuth,\n useCatalogPrincipal,\n useCatalogQueryClient,\n} from './runtime-catalog';\n\n/**\n * The open chat's mode menu (`AthenaProvider` `modes`):\n *\n * - `off`: no menu: the host listed no modes, no collab agent is selected, the\n * agent cannot be read or was never published, or it offers fewer than two\n * of the listed modes on the provider's `channel`;\n * - `loading`: the agent is being read;\n * - `ready`: the modes to offer, the one the open session runs in (or a new\n * one starts in), and `select` to switch. `canSwitch` is false on a session\n * of a channel its author locks: there, people pick the mode before a\n * session's first message.\n */\nexport type AthenaChatMode =\n | { status: 'off' }\n | { status: 'loading' }\n | {\n status: 'ready';\n options: readonly AthenaChatModeOption[];\n /** The mode the open session runs in, or a new session starts in. */\n current: string;\n /** The current mode's name, also when it is none of `options`. */\n currentLabel: string;\n /** Whether a pick applies now. */\n canSwitch: boolean;\n /** The channel keeps each session in the mode it starts in. */\n locked: boolean;\n /** Run the open session's next sends in `modeId` (one of `options`). */\n select: (modeId: string) => void;\n };\n\ntype AgentModeRead = { readable: true; source: AgentModeSource | null } | { readable: false };\n\n/** The open thread's session asset: absent until its first send mints it. */\ntype SessionRead = { exists: false } | { exists: true; channel: string | null };\n\nconst OFF: AthenaChatMode = { status: 'off' };\nconst LOADING: AthenaChatMode = { status: 'loading' };\nconst NO_MODES: readonly string[] = [];\n\nconst ATHENA_SESSION_MODE_QUERY = `\n query AthenaSessionMode($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The mode menu of the chat inside the nearest `AthenaProvider`, from the\n * agent's published definition, the open session's own mode, and the\n * provider's `modes`, `agent` and `channel`. `AthenaChat` renders it in its\n * composer; use it to build a menu of your own.\n *\n * The open session's mode is read again when the chat regains focus and after\n * every run, and its sends name it, so a session switched in another browser\n * continues where it is. A pick holds until the session runs in it (or the\n * menu stops offering it); only a pick not yet sent overrides the session.\n */\nexport function useAthenaChatMode(): AthenaChatMode {\n const selection = useContext(AthenaChatModeSelectionContext);\n const agentSelection = useContext(AthenaAgentSelectionContext);\n const agentAssetId = agentSelection?.agentAssetId ?? null;\n const channel = agentSelection?.channel ?? null;\n const hostModes = selection?.hostModes ?? NO_MODES;\n const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n\n const agentRead = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-modes', auth.backendUrl, principal, agentAssetId],\n queryFn: async (): Promise<AgentModeRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId: agentAssetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModeSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) =>\n query.state.data !== undefined && !query.state.data.readable\n ? false\n : AGENT_MODELS_REFRESH_MS,\n },\n queryClient,\n );\n\n // The open thread as this chat holds it: its first send ends a new chat's\n // pick-before-start window even where the provider cannot tell (a\n // standalone chat on a thread id it minted), and the end of each run, which\n // may have switched the session (here or in another browser), reads it again.\n const threadEmpty = useAuiState((state) => state.optional.thread?.isEmpty ?? true);\n const threadRunning = useAuiState((state) => state.optional.thread?.isRunning ?? false);\n\n const threadId = selection?.threadId ?? null;\n const sessionStarted = selection?.isNewChat === false || !threadEmpty;\n const readSession = enabled && threadId !== null && sessionStarted;\n const sessionRead = useQuery(\n {\n queryKey: ['athena-sdk', 'chat-mode', 'session', auth.backendUrl, principal, threadId],\n queryFn: async (): Promise<SessionRead> => {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_SESSION_MODE_QUERY,\n { assetId: `asset_${threadId}` },\n );\n const asset = data.getAssetById;\n return asset\n ? { exists: true, channel: sessionChannelFromMetadata(asset.athenaMetadata) }\n : { exists: false };\n },\n enabled: readSession,\n staleTime: 0,\n refetchOnWindowFocus: true,\n retry: false,\n },\n queryClient,\n );\n const refetchSession = sessionRead.refetch;\n const wasRunning = useRef(threadRunning);\n useEffect(() => {\n const ended = wasRunning.current && !threadRunning;\n wasRunning.current = threadRunning;\n if (ended && readSession) void refetchSession();\n }, [threadRunning, readSession, refetchSession]);\n\n const source = agentRead.data?.readable ? agentRead.data.source : null;\n const menu = useMemo(\n () => (source ? agentModeMenu({ source, channel, hostModes }) : null),\n [source, channel, hostModes],\n );\n const pick = selection?.pick ?? null;\n const session = readSession ? sessionRead.data : undefined;\n const sessionChannel = session?.exists ? session.channel : null;\n const setPick = selection?.setPick;\n const setSessionChannel = selection?.setSessionChannel;\n\n useEffect(() => {\n if (!threadId || !setSessionChannel || session === undefined) return;\n setSessionChannel({ threadId, channel: sessionChannel });\n }, [threadId, setSessionChannel, session, sessionChannel]);\n\n useEffect(() => {\n if (!threadId || !setPick || pick === null) return;\n const applied =\n sessionChannel !== null &&\n (sessionChannel === pick ||\n (source !== null && agentModeOfChannel({ source, channel: sessionChannel }) === pick));\n const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);\n if (applied || withdrawn) setPick({ threadId, modeId: null });\n }, [threadId, setPick, pick, sessionChannel, source, menu]);\n\n const canSwitch = !(menu?.locked && sessionStarted);\n const options = menu?.options;\n const select = useCallback(\n (modeId: string) => {\n if (!threadId || !setPick || !canSwitch) return;\n if (!options?.some((option) => option.id === modeId)) return;\n setPick({ threadId, modeId });\n },\n [threadId, setPick, canSwitch, options],\n );\n\n if (!enabled) return OFF;\n if (agentRead.isPending) return LOADING;\n if (!menu || menu.options.length < 2) return OFF;\n const current =\n pick ??\n (source && sessionChannel !== null\n ? agentModeOfChannel({ source, channel: sessionChannel })\n : menu.firstSendModeId);\n const currentLabel =\n menu.options.find((option) => option.id === current)?.label ??\n (current === 'base' ? 'Default' : (source?.channels[current]?.label ?? current));\n return {\n status: 'ready',\n options: menu.options,\n current,\n currentLabel,\n canSwitch,\n locked: menu.locked,\n select,\n };\n}\n"],"names":["useContext","AthenaChatModeSelectionContext","AthenaAgentSelectionContext","useCatalogAuth","useCatalogPrincipal","useCatalogQueryClient","useQuery","fetchGraphQL","ATHENA_AGENT_MODELS_QUERY","publishedAgentModeSource","isAgentReadDenial","AGENT_MODELS_REFRESH_MS","useAuiState","_a","sessionChannelFromMetadata","useRef","useEffect","useMemo","agentModeMenu","agentModeOfChannel","useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"use-athena-chat-mode.cjs","sources":["../../src/catalog/use-athena-chat-mode.ts"],"sourcesContent":["import { useAuiState } from '@assistant-ui/react';\nimport { useQuery } from '@tanstack/react-query';\nimport { useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport { fetchGraphQL } from '../chat-ui/mentions/suggestions/data/api-client';\nimport { AthenaAgentSelectionContext } from '../provider/agent-selection-context';\nimport { AthenaChatModeSelectionContext } from '../provider/chat-mode-context';\nimport {\n type AgentModeSource,\n type AthenaChatModeOption,\n agentModeMenu,\n agentModeOfChannel,\n publishedAgentModeSource,\n sessionChannelFromMetadata,\n} from './agent-mode-menu';\nimport {\n AGENT_MODELS_REFRESH_MS,\n ATHENA_AGENT_MODELS_QUERY,\n isAgentReadDenial,\n useCatalogAuth,\n useCatalogPrincipal,\n useCatalogQueryClient,\n} from './runtime-catalog';\n\n/**\n * The open chat's mode menu (`AthenaProvider` `modes`):\n *\n * - `off`: no menu: the host listed no modes, no collab agent is selected, the\n * agent cannot be read or was never published, or it offers fewer than two\n * of the listed modes on the provider's `channel`;\n * - `loading`: the agent is being read;\n * - `ready`: the modes to offer, the one the open session runs in (or a new\n * one starts in), and `select` to switch. `canSwitch` is false on a session\n * of a channel its author locks: there, people pick the mode before a\n * session's first message.\n */\nexport type AthenaChatMode =\n | { status: 'off' }\n | { status: 'loading' }\n | {\n status: 'ready';\n options: readonly AthenaChatModeOption[];\n /** The mode the open session runs in, or a new session starts in. */\n current: string;\n /** The current mode's name, also when it is none of `options`. */\n currentLabel: string;\n /** Whether a pick applies now. */\n canSwitch: boolean;\n /** The channel keeps each session in the mode it starts in. */\n locked: boolean;\n /** Run the open session's next sends in `modeId` (one of `options`). */\n select: (modeId: string) => void;\n };\n\ntype AgentModeRead = { readable: true; source: AgentModeSource | null } | { readable: false };\n\n/** The open thread's session asset: absent until its first send mints it. */\ntype SessionRead = { exists: false } | { exists: true; channel: string | null };\n\nconst OFF: AthenaChatMode = { status: 'off' };\nconst LOADING: AthenaChatMode = { status: 'loading' };\nconst NO_MODES: readonly string[] = [];\n\nconst ATHENA_SESSION_MODE_QUERY = `\n query AthenaSessionMode($assetId: String!) {\n getAssetById(assetId: $assetId, withMetadata: true) { athenaMetadata }\n }\n`;\n\n/**\n * The mode menu of the chat inside the nearest `AthenaProvider`, from the\n * agent's published definition, the open session's own mode, and the\n * provider's `modes`, `agent` and `channel`. `AthenaChat` renders it in its\n * composer; use it to build a menu of your own.\n *\n * The open session's mode is read again when the chat regains focus and after\n * every run, and its sends name it, so a session switched in another browser\n * continues where it is. A pick holds until the session runs in it (or the\n * menu stops offering it); only a pick not yet sent overrides the session.\n */\nexport function useAthenaChatMode(): AthenaChatMode {\n const selection = useContext(AthenaChatModeSelectionContext);\n const agentSelection = useContext(AthenaAgentSelectionContext);\n const agentAssetId = agentSelection?.agentAssetId ?? null;\n const channel = agentSelection?.channel ?? null;\n const hostModes = selection?.hostModes ?? NO_MODES;\n const enabled = selection !== null && hostModes.length > 0 && agentAssetId !== null;\n const auth = useCatalogAuth();\n const principal = useCatalogPrincipal();\n const queryClient = useCatalogQueryClient();\n\n const agentRead = useQuery(\n {\n queryKey: ['athena-sdk', 'catalog', 'agent-modes', auth.backendUrl, principal, agentAssetId],\n queryFn: async (): Promise<AgentModeRead> => {\n try {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_AGENT_MODELS_QUERY,\n { assetId: agentAssetId },\n );\n if (data.getAssetById === null) return { readable: false };\n return {\n readable: true,\n source: publishedAgentModeSource(data.getAssetById.athenaMetadata),\n };\n } catch (error) {\n if (isAgentReadDenial(error)) return { readable: false };\n throw error;\n }\n },\n enabled,\n staleTime: AGENT_MODELS_REFRESH_MS,\n refetchInterval: (query) =>\n query.state.data !== undefined && !query.state.data.readable\n ? false\n : AGENT_MODELS_REFRESH_MS,\n },\n queryClient,\n );\n\n // The open thread as this chat holds it: its first send ends a new chat's\n // pick-before-start window even where the provider cannot tell (a\n // standalone chat on a thread id it minted), and the end of each run, which\n // may have switched the session (here or in another browser), reads it again.\n const threadEmpty = useAuiState((state) => state.optional.thread?.isEmpty ?? true);\n const threadRunning = useAuiState((state) => state.optional.thread?.isRunning ?? false);\n\n const threadId = selection?.threadId ?? null;\n const sessionStarted = selection?.isNewChat === false || !threadEmpty;\n const readSession = enabled && threadId !== null && sessionStarted;\n const sessionRead = useQuery(\n {\n queryKey: ['athena-sdk', 'chat-mode', 'session', auth.backendUrl, principal, threadId],\n queryFn: async (): Promise<SessionRead> => {\n const data = await fetchGraphQL<{ getAssetById: { athenaMetadata: unknown } | null }>(\n auth,\n ATHENA_SESSION_MODE_QUERY,\n { assetId: `asset_${threadId}` },\n );\n const asset = data.getAssetById;\n return asset\n ? { exists: true, channel: sessionChannelFromMetadata(asset.athenaMetadata) }\n : { exists: false };\n },\n enabled: readSession,\n staleTime: 0,\n refetchOnWindowFocus: true,\n retry: false,\n },\n queryClient,\n );\n const refetchSession = sessionRead.refetch;\n const wasRunning = useRef(threadRunning);\n useEffect(() => {\n const ended = wasRunning.current && !threadRunning;\n wasRunning.current = threadRunning;\n if (ended && readSession) void refetchSession();\n }, [threadRunning, readSession, refetchSession]);\n\n const source = agentRead.data?.readable ? agentRead.data.source : null;\n const menu = useMemo(\n () => (source ? agentModeMenu({ source, channel, hostModes }) : null),\n [source, channel, hostModes],\n );\n const pick = selection?.pick ?? null;\n const session = readSession ? sessionRead.data : undefined;\n const sessionChannel = session?.exists ? session.channel : null;\n const setPick = selection?.setPick;\n const setSessionChannel = selection?.setSessionChannel;\n\n useEffect(() => {\n if (!threadId || !setSessionChannel || session === undefined) return;\n setSessionChannel({ threadId, channel: sessionChannel });\n }, [threadId, setSessionChannel, session, sessionChannel]);\n\n useEffect(() => {\n if (!threadId || !setPick || pick === null) return;\n const applied =\n sessionChannel !== null &&\n (sessionChannel === pick ||\n (source !== null && agentModeOfChannel({ source, channel: sessionChannel }) === pick));\n const withdrawn = menu !== null && !menu.options.some((option) => option.id === pick);\n if (applied || withdrawn) setPick({ threadId, modeId: null });\n }, [threadId, setPick, pick, sessionChannel, source, menu]);\n\n const canSwitch = !(menu?.locked && sessionStarted);\n const options = menu?.options;\n const select = useCallback(\n (modeId: string) => {\n if (!threadId || !setPick || !canSwitch) return;\n if (!options?.some((option) => option.id === modeId)) return;\n setPick({ threadId, modeId });\n },\n [threadId, setPick, canSwitch, options],\n );\n\n if (!enabled) return OFF;\n if (agentRead.isPending) return LOADING;\n if (!menu || menu.options.length < 2) return OFF;\n const current =\n pick ??\n (source && sessionChannel !== null\n ? agentModeOfChannel({ source, channel: sessionChannel })\n : menu.firstSendModeId);\n const currentLabel =\n menu.options.find((option) => option.id === current)?.label ??\n (current === 'base' ? 'Default' : (source?.channels[current]?.label ?? current));\n return {\n status: 'ready',\n options: menu.options,\n current,\n currentLabel,\n canSwitch,\n locked: menu.locked,\n select,\n };\n}\n"],"names":["useContext","AthenaChatModeSelectionContext","AthenaAgentSelectionContext","useCatalogAuth","useCatalogPrincipal","useCatalogQueryClient","useQuery","fetchGraphQL","ATHENA_AGENT_MODELS_QUERY","publishedAgentModeSource","isAgentReadDenial","AGENT_MODELS_REFRESH_MS","useAuiState","_a","sessionChannelFromMetadata","useRef","useEffect","useMemo","agentModeMenu","agentModeOfChannel","useCallback"],"mappings":"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"}