@athenaintel/react 0.57.2 → 0.59.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 (799) hide show
  1. package/README.md +759 -9
  2. package/dist/agent-runtime/src/addressed-agents.cjs +16 -0
  3. package/dist/agent-runtime/src/addressed-agents.cjs.map +1 -0
  4. package/dist/agent-runtime/src/addressed-agents.d.ts +30 -0
  5. package/dist/agent-runtime/src/addressed-agents.js +16 -0
  6. package/dist/agent-runtime/src/addressed-agents.js.map +1 -0
  7. package/dist/agent-runtime/src/answer-label.cjs +4 -3
  8. package/dist/agent-runtime/src/answer-label.cjs.map +1 -1
  9. package/dist/agent-runtime/src/answer-label.d.ts +13 -6
  10. package/dist/agent-runtime/src/answer-label.js +4 -3
  11. package/dist/agent-runtime/src/answer-label.js.map +1 -1
  12. package/dist/agent-runtime/src/chat-outbox-attachments.cjs.map +1 -1
  13. package/dist/agent-runtime/src/chat-outbox-attachments.d.ts +1 -1
  14. package/dist/agent-runtime/src/chat-outbox-attachments.js.map +1 -1
  15. package/dist/agent-runtime/src/chat-outbox-entry.cjs +101 -0
  16. package/dist/agent-runtime/src/chat-outbox-entry.cjs.map +1 -0
  17. package/dist/agent-runtime/src/chat-outbox-entry.d.ts +99 -0
  18. package/dist/agent-runtime/src/chat-outbox-entry.js +101 -0
  19. package/dist/agent-runtime/src/chat-outbox-entry.js.map +1 -0
  20. package/dist/agent-runtime/src/chat-outbox-legacy.cjs +252 -0
  21. package/dist/agent-runtime/src/chat-outbox-legacy.cjs.map +1 -0
  22. package/dist/agent-runtime/src/chat-outbox-legacy.d.ts +96 -0
  23. package/dist/agent-runtime/src/chat-outbox-legacy.js +252 -0
  24. package/dist/agent-runtime/src/chat-outbox-legacy.js.map +1 -0
  25. package/dist/agent-runtime/src/chat-outbox-policy.cjs +30 -0
  26. package/dist/agent-runtime/src/chat-outbox-policy.cjs.map +1 -0
  27. package/dist/agent-runtime/src/chat-outbox-policy.d.ts +42 -0
  28. package/dist/agent-runtime/src/chat-outbox-policy.js +30 -0
  29. package/dist/agent-runtime/src/chat-outbox-policy.js.map +1 -0
  30. package/dist/agent-runtime/src/chat-outbox-storage.cjs +306 -0
  31. package/dist/agent-runtime/src/chat-outbox-storage.cjs.map +1 -0
  32. package/dist/agent-runtime/src/chat-outbox-storage.d.ts +194 -0
  33. package/dist/agent-runtime/src/chat-outbox-storage.js +306 -0
  34. package/dist/agent-runtime/src/chat-outbox-storage.js.map +1 -0
  35. package/dist/agent-runtime/src/chat-outbox-thread.cjs +21 -94
  36. package/dist/agent-runtime/src/chat-outbox-thread.cjs.map +1 -1
  37. package/dist/agent-runtime/src/chat-outbox-thread.d.ts +22 -18
  38. package/dist/agent-runtime/src/chat-outbox-thread.js +21 -94
  39. package/dist/agent-runtime/src/chat-outbox-thread.js.map +1 -1
  40. package/dist/agent-runtime/src/chat-outbox.cjs +492 -547
  41. package/dist/agent-runtime/src/chat-outbox.cjs.map +1 -1
  42. package/dist/agent-runtime/src/chat-outbox.d.ts +110 -142
  43. package/dist/agent-runtime/src/chat-outbox.js +492 -547
  44. package/dist/agent-runtime/src/chat-outbox.js.map +1 -1
  45. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  46. package/dist/agent-runtime/src/composer-markdown.d.ts +1 -1
  47. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  48. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +3 -1
  49. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  50. package/dist/agent-runtime/src/deep-agent-transport-recipe.d.ts +8 -1
  51. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -1
  52. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  53. package/dist/agent-runtime/src/dictation-preferences.d.ts +356 -0
  54. package/dist/agent-runtime/src/dictation-record.d.ts +279 -0
  55. package/dist/agent-runtime/src/dictation-session.d.ts +106 -7
  56. package/dist/agent-runtime/src/dictation-snippets.d.ts +9 -0
  57. package/dist/agent-runtime/src/dictation-transfer.d.ts +142 -0
  58. package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
  59. package/dist/agent-runtime/src/edit-command.d.ts +1 -1
  60. package/dist/agent-runtime/src/edit-command.js.map +1 -1
  61. package/dist/agent-runtime/src/errors.cjs +1 -0
  62. package/dist/agent-runtime/src/errors.cjs.map +1 -1
  63. package/dist/agent-runtime/src/errors.js +1 -0
  64. package/dist/agent-runtime/src/errors.js.map +1 -1
  65. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +24 -0
  66. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  67. package/dist/agent-runtime/src/generated/runconfig-contract.d.ts +3 -3
  68. package/dist/agent-runtime/src/generated/runconfig-contract.js +24 -0
  69. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  70. package/dist/agent-runtime/src/index.d.ts +14 -8
  71. package/dist/agent-runtime/src/lane-follow.cjs +289 -0
  72. package/dist/agent-runtime/src/lane-follow.cjs.map +1 -0
  73. package/dist/agent-runtime/src/lane-follow.js +289 -0
  74. package/dist/agent-runtime/src/lane-follow.js.map +1 -0
  75. package/dist/agent-runtime/src/lane-images.cjs +387 -0
  76. package/dist/agent-runtime/src/lane-images.cjs.map +1 -0
  77. package/dist/agent-runtime/src/lane-images.js +387 -0
  78. package/dist/agent-runtime/src/lane-images.js.map +1 -0
  79. package/dist/agent-runtime/src/message-window.js +1 -1
  80. package/dist/agent-runtime/src/messages.cjs +19 -1
  81. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  82. package/dist/agent-runtime/src/messages.d.ts +8 -0
  83. package/dist/agent-runtime/src/messages.js +21 -3
  84. package/dist/agent-runtime/src/messages.js.map +1 -1
  85. package/dist/agent-runtime/src/named-agents.cjs +301 -0
  86. package/dist/agent-runtime/src/named-agents.cjs.map +1 -0
  87. package/dist/agent-runtime/src/named-agents.d.ts +246 -0
  88. package/dist/agent-runtime/src/named-agents.js +301 -0
  89. package/dist/agent-runtime/src/named-agents.js.map +1 -0
  90. package/dist/agent-runtime/src/offline-status.cjs.map +1 -1
  91. package/dist/agent-runtime/src/offline-status.d.ts +66 -2
  92. package/dist/agent-runtime/src/offline-status.js.map +1 -1
  93. package/dist/agent-runtime/src/ptc-subcalls.cjs +41 -0
  94. package/dist/agent-runtime/src/ptc-subcalls.cjs.map +1 -0
  95. package/dist/agent-runtime/src/ptc-subcalls.js +41 -0
  96. package/dist/agent-runtime/src/ptc-subcalls.js.map +1 -0
  97. package/dist/agent-runtime/src/queue.cjs +2 -2
  98. package/dist/agent-runtime/src/queue.cjs.map +1 -1
  99. package/dist/agent-runtime/src/queue.d.ts +20 -25
  100. package/dist/agent-runtime/src/queue.js +2 -2
  101. package/dist/agent-runtime/src/queue.js.map +1 -1
  102. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +314 -84
  103. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  104. package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +137 -40
  105. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +318 -88
  106. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  107. package/dist/agent-runtime/src/run-send.cjs +54 -0
  108. package/dist/agent-runtime/src/run-send.cjs.map +1 -0
  109. package/dist/agent-runtime/src/run-send.d.ts +51 -0
  110. package/dist/agent-runtime/src/run-send.js +54 -0
  111. package/dist/agent-runtime/src/run-send.js.map +1 -0
  112. package/dist/agent-runtime/src/running-tool-placeholder.cjs +6 -0
  113. package/dist/agent-runtime/src/running-tool-placeholder.cjs.map +1 -1
  114. package/dist/agent-runtime/src/running-tool-placeholder.js +6 -0
  115. package/dist/agent-runtime/src/running-tool-placeholder.js.map +1 -1
  116. package/dist/agent-runtime/src/runtime.d.ts +9 -5
  117. package/dist/agent-runtime/src/sealed-idb.cjs +64 -0
  118. package/dist/agent-runtime/src/sealed-idb.cjs.map +1 -1
  119. package/dist/agent-runtime/src/sealed-idb.d.ts +16 -0
  120. package/dist/agent-runtime/src/sealed-idb.js +64 -0
  121. package/dist/agent-runtime/src/sealed-idb.js.map +1 -1
  122. package/dist/agent-runtime/src/send-recovery.cjs +90 -118
  123. package/dist/agent-runtime/src/send-recovery.cjs.map +1 -1
  124. package/dist/agent-runtime/src/send-recovery.d.ts +25 -29
  125. package/dist/agent-runtime/src/send-recovery.js +90 -118
  126. package/dist/agent-runtime/src/send-recovery.js.map +1 -1
  127. package/dist/agent-runtime/src/statewire-diagnostics.d.ts +4 -1
  128. package/dist/agent-runtime/src/statewire-held-sends.cjs +191 -0
  129. package/dist/agent-runtime/src/statewire-held-sends.cjs.map +1 -0
  130. package/dist/agent-runtime/src/statewire-held-sends.d.ts +119 -0
  131. package/dist/agent-runtime/src/statewire-held-sends.js +191 -0
  132. package/dist/agent-runtime/src/statewire-held-sends.js.map +1 -0
  133. package/dist/agent-runtime/src/statewire-state.cjs +4 -0
  134. package/dist/agent-runtime/src/statewire-state.cjs.map +1 -1
  135. package/dist/agent-runtime/src/statewire-state.js +4 -0
  136. package/dist/agent-runtime/src/statewire-state.js.map +1 -1
  137. package/dist/agent-runtime/src/statewire-transport.cjs +8 -2
  138. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
  139. package/dist/agent-runtime/src/statewire-transport.d.ts +14 -5
  140. package/dist/agent-runtime/src/statewire-transport.js +8 -2
  141. package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
  142. package/dist/agent-runtime/src/subagent-transcripts.cjs +1 -23
  143. package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -1
  144. package/dist/agent-runtime/src/subagent-transcripts.js +3 -25
  145. package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -1
  146. package/dist/agent-runtime/src/subagents.cjs +22 -29
  147. package/dist/agent-runtime/src/subagents.cjs.map +1 -1
  148. package/dist/agent-runtime/src/subagents.js +23 -30
  149. package/dist/agent-runtime/src/subagents.js.map +1 -1
  150. package/dist/agent-runtime/src/thread-extras.cjs +27 -19
  151. package/dist/agent-runtime/src/thread-extras.cjs.map +1 -1
  152. package/dist/agent-runtime/src/thread-extras.d.ts +19 -6
  153. package/dist/agent-runtime/src/thread-extras.js +27 -19
  154. package/dist/agent-runtime/src/thread-extras.js.map +1 -1
  155. package/dist/agent-runtime/src/thread-handoff-flow-machine.d.ts +8 -8
  156. package/dist/agent-runtime/src/tool-metadata.cjs +12 -0
  157. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  158. package/dist/agent-runtime/src/tool-metadata.js +12 -0
  159. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  160. package/dist/agent-runtime/src/tool-names.cjs +21 -0
  161. package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
  162. package/dist/agent-runtime/src/tool-names.d.ts +8 -0
  163. package/dist/agent-runtime/src/tool-names.js +21 -0
  164. package/dist/agent-runtime/src/tool-names.js.map +1 -1
  165. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs +247 -0
  166. package/dist/agent-runtime/src/typed-interrupt-kinds.cjs.map +1 -0
  167. package/dist/agent-runtime/src/typed-interrupt-kinds.d.ts +173 -0
  168. package/dist/agent-runtime/src/typed-interrupt-kinds.js +247 -0
  169. package/dist/agent-runtime/src/typed-interrupt-kinds.js.map +1 -0
  170. package/dist/agent-runtime/src/typed-interrupts.cjs +48 -0
  171. package/dist/agent-runtime/src/typed-interrupts.cjs.map +1 -0
  172. package/dist/agent-runtime/src/typed-interrupts.d.ts +75 -0
  173. package/dist/agent-runtime/src/typed-interrupts.js +48 -0
  174. package/dist/agent-runtime/src/typed-interrupts.js.map +1 -0
  175. package/dist/agent-runtime/src/types.d.ts +1 -1
  176. package/dist/agent-runtime/src/use-conversation-list.cjs +1 -0
  177. package/dist/agent-runtime/src/use-conversation-list.cjs.map +1 -1
  178. package/dist/agent-runtime/src/use-conversation-list.d.ts +7 -0
  179. package/dist/agent-runtime/src/use-conversation-list.js +1 -0
  180. package/dist/agent-runtime/src/use-conversation-list.js.map +1 -1
  181. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs +46 -29
  182. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.cjs.map +1 -1
  183. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.d.ts +14 -22
  184. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js +46 -29
  185. package/dist/agent-runtime/src/use-deep-agent-chat-outbox.js.map +1 -1
  186. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +78 -14
  187. package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
  188. package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +34 -7
  189. package/dist/agent-runtime/src/use-deep-agent-runtime.js +79 -15
  190. package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
  191. package/dist/agent-runtime/src/use-deep-agent-thread.cjs +16 -1
  192. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  193. package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +7 -2
  194. package/dist/agent-runtime/src/use-deep-agent-thread.js +16 -1
  195. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  196. package/dist/agent-runtime/src/use-deep-agent-voice.cjs +30 -4
  197. package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
  198. package/dist/agent-runtime/src/use-deep-agent-voice.d.ts +22 -4
  199. package/dist/agent-runtime/src/use-deep-agent-voice.js +30 -4
  200. package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
  201. package/dist/agent-runtime/src/withdrawn-turns.d.ts +5 -4
  202. package/dist/agent-runtime/src/word-device-fit.d.ts +174 -0
  203. package/dist/agent-runtime/src/work-in.d.ts +127 -0
  204. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  205. package/dist/assets/AthenaAssetEmbed.d.ts +6 -1
  206. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  207. package/dist/assets/asset-panel-store.cjs +13 -5
  208. package/dist/assets/asset-panel-store.cjs.map +1 -1
  209. package/dist/assets/asset-panel-store.d.ts +33 -2
  210. package/dist/assets/asset-panel-store.js +13 -5
  211. package/dist/assets/asset-panel-store.js.map +1 -1
  212. package/dist/auth/AthenaCredentialSourceContext.cjs +11 -0
  213. package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -1
  214. package/dist/auth/AthenaCredentialSourceContext.d.ts +6 -0
  215. package/dist/auth/AthenaCredentialSourceContext.js +11 -0
  216. package/dist/auth/AthenaCredentialSourceContext.js.map +1 -1
  217. package/dist/auth/account-identity.cjs +13 -2
  218. package/dist/auth/account-identity.cjs.map +1 -1
  219. package/dist/auth/account-identity.d.ts +9 -0
  220. package/dist/auth/account-identity.js +13 -2
  221. package/dist/auth/account-identity.js.map +1 -1
  222. package/dist/auth/credential-source.cjs +20 -4
  223. package/dist/auth/credential-source.cjs.map +1 -1
  224. package/dist/auth/credential-source.d.ts +9 -0
  225. package/dist/auth/credential-source.js +20 -4
  226. package/dist/auth/credential-source.js.map +1 -1
  227. package/dist/catalog/chat-pickers.cjs +31 -0
  228. package/dist/catalog/chat-pickers.cjs.map +1 -1
  229. package/dist/catalog/chat-pickers.d.ts +17 -0
  230. package/dist/catalog/chat-pickers.js +33 -2
  231. package/dist/catalog/chat-pickers.js.map +1 -1
  232. package/dist/catalog/runtime-catalog.cjs +63 -3
  233. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  234. package/dist/catalog/runtime-catalog.d.ts +63 -3
  235. package/dist/catalog/runtime-catalog.js +64 -4
  236. package/dist/catalog/runtime-catalog.js.map +1 -1
  237. package/dist/chat/AthenaChat.cjs +290 -97
  238. package/dist/chat/AthenaChat.cjs.map +1 -1
  239. package/dist/chat/AthenaChat.d.ts +80 -4
  240. package/dist/chat/AthenaChat.js +290 -97
  241. package/dist/chat/AthenaChat.js.map +1 -1
  242. package/dist/chat/StatewireApprovalCard.cjs +35 -5
  243. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  244. package/dist/chat/StatewireApprovalCard.d.ts +55 -2
  245. package/dist/chat/StatewireApprovalCard.js +37 -7
  246. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  247. package/dist/chat/StatewireQueuedMessages.cjs +17 -2
  248. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  249. package/dist/chat/StatewireQueuedMessages.d.ts +8 -45
  250. package/dist/chat/StatewireQueuedMessages.js +18 -3
  251. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  252. package/dist/chat/chat-agent-mentions.cjs +70 -0
  253. package/dist/chat/chat-agent-mentions.cjs.map +1 -0
  254. package/dist/chat/chat-agent-mentions.d.ts +13 -0
  255. package/dist/chat/chat-agent-mentions.js +70 -0
  256. package/dist/chat/chat-agent-mentions.js.map +1 -0
  257. package/dist/chat/composer-actions.cjs +12 -0
  258. package/dist/chat/composer-actions.cjs.map +1 -0
  259. package/dist/chat/composer-actions.d.ts +22 -0
  260. package/dist/chat/composer-actions.js +12 -0
  261. package/dist/chat/composer-actions.js.map +1 -0
  262. package/dist/chat/follow-up-suggestions.cjs +185 -0
  263. package/dist/chat/follow-up-suggestions.cjs.map +1 -0
  264. package/dist/chat/follow-up-suggestions.d.ts +64 -0
  265. package/dist/chat/follow-up-suggestions.js +185 -0
  266. package/dist/chat/follow-up-suggestions.js.map +1 -0
  267. package/dist/chat/super-grouping/ToolTimeline.cjs +4 -3
  268. package/dist/chat/super-grouping/ToolTimeline.cjs.map +1 -1
  269. package/dist/chat/super-grouping/ToolTimeline.d.ts +7 -3
  270. package/dist/chat/super-grouping/ToolTimeline.js +4 -3
  271. package/dist/chat/super-grouping/ToolTimeline.js.map +1 -1
  272. package/dist/chat/turn-changes.cjs +284 -0
  273. package/dist/chat/turn-changes.cjs.map +1 -0
  274. package/dist/chat/turn-changes.d.ts +130 -0
  275. package/dist/chat/turn-changes.js +284 -0
  276. package/dist/chat/turn-changes.js.map +1 -0
  277. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs +31 -0
  278. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.cjs.map +1 -0
  279. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.d.ts +31 -0
  280. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js +31 -0
  281. package/dist/chat/typed-interrupts/StatewireTypedInterruptCard.js.map +1 -0
  282. package/dist/chat/typed-interrupts/approval-cards.cjs +250 -0
  283. package/dist/chat/typed-interrupts/approval-cards.cjs.map +1 -0
  284. package/dist/chat/typed-interrupts/approval-cards.d.ts +22 -0
  285. package/dist/chat/typed-interrupts/approval-cards.js +250 -0
  286. package/dist/chat/typed-interrupts/approval-cards.js.map +1 -0
  287. package/dist/chat/typed-interrupts/form-cards.cjs +289 -0
  288. package/dist/chat/typed-interrupts/form-cards.cjs.map +1 -0
  289. package/dist/chat/typed-interrupts/form-cards.d.ts +6 -0
  290. package/dist/chat/typed-interrupts/form-cards.js +289 -0
  291. package/dist/chat/typed-interrupts/form-cards.js.map +1 -0
  292. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs +182 -0
  293. package/dist/chat/typed-interrupts/interrupt-card-shell.cjs.map +1 -0
  294. package/dist/chat/typed-interrupts/interrupt-card-shell.d.ts +47 -0
  295. package/dist/chat/typed-interrupts/interrupt-card-shell.js +182 -0
  296. package/dist/chat/typed-interrupts/interrupt-card-shell.js.map +1 -0
  297. package/dist/chat/typed-interrupts/json-schema-form.cjs +388 -0
  298. package/dist/chat/typed-interrupts/json-schema-form.cjs.map +1 -0
  299. package/dist/chat/typed-interrupts/json-schema-form.d.ts +33 -0
  300. package/dist/chat/typed-interrupts/json-schema-form.js +388 -0
  301. package/dist/chat/typed-interrupts/json-schema-form.js.map +1 -0
  302. package/dist/chat/typed-interrupts/questionnaire-card.cjs +449 -0
  303. package/dist/chat/typed-interrupts/questionnaire-card.cjs.map +1 -0
  304. package/dist/chat/typed-interrupts/questionnaire-card.d.ts +20 -0
  305. package/dist/chat/typed-interrupts/questionnaire-card.js +449 -0
  306. package/dist/chat/typed-interrupts/questionnaire-card.js.map +1 -0
  307. package/dist/chat/typed-interrupts/request-file-card.cjs +159 -0
  308. package/dist/chat/typed-interrupts/request-file-card.cjs.map +1 -0
  309. package/dist/chat/typed-interrupts/request-file-card.d.ts +2 -0
  310. package/dist/chat/typed-interrupts/request-file-card.js +159 -0
  311. package/dist/chat/typed-interrupts/request-file-card.js.map +1 -0
  312. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs +189 -0
  313. package/dist/chat/typed-interrupts/toolkit-selection-card.cjs.map +1 -0
  314. package/dist/chat/typed-interrupts/toolkit-selection-card.d.ts +23 -0
  315. package/dist/chat/typed-interrupts/toolkit-selection-card.js +189 -0
  316. package/dist/chat/typed-interrupts/toolkit-selection-card.js.map +1 -0
  317. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs +26 -0
  318. package/dist/chat/typed-interrupts/typed-interrupt-body.cjs.map +1 -0
  319. package/dist/chat/typed-interrupts/typed-interrupt-body.d.ts +3 -0
  320. package/dist/chat/typed-interrupts/typed-interrupt-body.js +26 -0
  321. package/dist/chat/typed-interrupts/typed-interrupt-body.js.map +1 -0
  322. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs +105 -0
  323. package/dist/chat/typed-interrupts/typed-interrupt-graphql.cjs.map +1 -0
  324. package/dist/chat/typed-interrupts/typed-interrupt-graphql.d.ts +29 -0
  325. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js +105 -0
  326. package/dist/chat/typed-interrupts/typed-interrupt-graphql.js.map +1 -0
  327. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs +70 -0
  328. package/dist/chat/typed-interrupts/typed-interrupt-notice.cjs.map +1 -0
  329. package/dist/chat/typed-interrupts/typed-interrupt-notice.d.ts +45 -0
  330. package/dist/chat/typed-interrupts/typed-interrupt-notice.js +70 -0
  331. package/dist/chat/typed-interrupts/typed-interrupt-notice.js.map +1 -0
  332. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs +76 -0
  333. package/dist/chat/typed-interrupts/typed-interrupt-panel.cjs.map +1 -0
  334. package/dist/chat/typed-interrupts/typed-interrupt-panel.d.ts +11 -0
  335. package/dist/chat/typed-interrupts/typed-interrupt-panel.js +76 -0
  336. package/dist/chat/typed-interrupts/typed-interrupt-panel.js.map +1 -0
  337. package/dist/chat/typed-interrupts/typed-interrupt-types.d.ts +46 -0
  338. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs +106 -0
  339. package/dist/chat/typed-interrupts/use-interrupt-draft.cjs.map +1 -0
  340. package/dist/chat/typed-interrupts/use-interrupt-draft.d.ts +29 -0
  341. package/dist/chat/typed-interrupts/use-interrupt-draft.js +106 -0
  342. package/dist/chat/typed-interrupts/use-interrupt-draft.js.map +1 -0
  343. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs +231 -0
  344. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.cjs.map +1 -0
  345. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.d.ts +66 -0
  346. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js +231 -0
  347. package/dist/chat/typed-interrupts/use-statewire-typed-interrupt.js.map +1 -0
  348. package/dist/chat-ui/composer/composer-named-agents.cjs +13 -0
  349. package/dist/chat-ui/composer/composer-named-agents.cjs.map +1 -0
  350. package/dist/chat-ui/composer/composer-named-agents.d.ts +20 -0
  351. package/dist/chat-ui/composer/composer-named-agents.js +13 -0
  352. package/dist/chat-ui/composer/composer-named-agents.js.map +1 -0
  353. package/dist/chat-ui/composer/slash-command-menu.cjs +143 -0
  354. package/dist/chat-ui/composer/slash-command-menu.cjs.map +1 -0
  355. package/dist/chat-ui/composer/slash-command-menu.d.ts +19 -0
  356. package/dist/chat-ui/composer/slash-command-menu.js +143 -0
  357. package/dist/chat-ui/composer/slash-command-menu.js.map +1 -0
  358. package/dist/chat-ui/composer/slash-commands-extension.cjs +51 -0
  359. package/dist/chat-ui/composer/slash-commands-extension.cjs.map +1 -0
  360. package/dist/chat-ui/composer/slash-commands-extension.d.ts +39 -0
  361. package/dist/chat-ui/composer/slash-commands-extension.js +51 -0
  362. package/dist/chat-ui/composer/slash-commands-extension.js.map +1 -0
  363. package/dist/chat-ui/composer/slash-commands.cjs +74 -0
  364. package/dist/chat-ui/composer/slash-commands.cjs.map +1 -0
  365. package/dist/chat-ui/composer/slash-commands.d.ts +82 -0
  366. package/dist/chat-ui/composer/slash-commands.js +74 -0
  367. package/dist/chat-ui/composer/slash-commands.js.map +1 -0
  368. package/dist/chat-ui/composer/tiptap-composer.cjs +135 -9
  369. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  370. package/dist/chat-ui/composer/tiptap-composer.d.ts +61 -2
  371. package/dist/chat-ui/composer/tiptap-composer.js +135 -9
  372. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  373. package/dist/chat-ui/index.cjs +3 -0
  374. package/dist/chat-ui/index.cjs.map +1 -1
  375. package/dist/chat-ui/index.d.ts +3 -2
  376. package/dist/chat-ui/index.js +3 -0
  377. package/dist/chat-ui/index.js.map +1 -1
  378. package/dist/chat-ui/mentions/mention-chip.cjs +1 -1
  379. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  380. package/dist/chat-ui/mentions/mention-chip.js +2 -2
  381. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  382. package/dist/chat-ui/mentions/mention-extension.cjs +8 -1
  383. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  384. package/dist/chat-ui/mentions/mention-extension.js +8 -1
  385. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  386. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs +1 -0
  387. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.cjs.map +1 -1
  388. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js +1 -0
  389. package/dist/chat-ui/mentions/suggestions/components/get-scope-name.js.map +1 -1
  390. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs +2 -0
  391. package/dist/chat-ui/mentions/suggestions/components/mention-icon.cjs.map +1 -1
  392. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js +3 -1
  393. package/dist/chat-ui/mentions/suggestions/components/mention-icon.js.map +1 -1
  394. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs +1 -1
  395. package/dist/chat-ui/mentions/suggestions/components/menu-item.cjs.map +1 -1
  396. package/dist/chat-ui/mentions/suggestions/components/menu-item.js +1 -1
  397. package/dist/chat-ui/mentions/suggestions/components/menu-item.js.map +1 -1
  398. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +36 -0
  399. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  400. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +42 -0
  401. package/dist/chat-ui/mentions/suggestions/data/api-client.js +36 -0
  402. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  403. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs +235 -19
  404. package/dist/chat-ui/mentions/suggestions/data/sources/index.cjs.map +1 -1
  405. package/dist/chat-ui/mentions/suggestions/data/sources/index.d.ts +88 -10
  406. package/dist/chat-ui/mentions/suggestions/data/sources/index.js +236 -20
  407. package/dist/chat-ui/mentions/suggestions/data/sources/index.js.map +1 -1
  408. package/dist/chat-ui/mentions/suggestions/data/types.cjs.map +1 -1
  409. package/dist/chat-ui/mentions/suggestions/data/types.d.ts +27 -1
  410. package/dist/chat-ui/mentions/suggestions/data/types.js.map +1 -1
  411. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs +56 -5
  412. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.cjs.map +1 -1
  413. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.d.ts +26 -6
  414. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js +57 -6
  415. package/dist/chat-ui/mentions/suggestions/data/use-mention-suggestions.js.map +1 -1
  416. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs +34 -17
  417. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.cjs.map +1 -1
  418. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.d.ts +19 -1
  419. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js +35 -18
  420. package/dist/chat-ui/mentions/suggestions/mention-suggestions.extension.js.map +1 -1
  421. package/dist/chat-ui/statewire.d.ts +1 -1
  422. package/dist/chat-ui/thread/statewire-history-edge.cjs +15 -0
  423. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  424. package/dist/chat-ui/thread/statewire-history-edge.d.ts +4 -1
  425. package/dist/chat-ui/thread/statewire-history-edge.js +15 -0
  426. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  427. package/dist/collab/client.cjs +17 -5
  428. package/dist/collab/client.cjs.map +1 -1
  429. package/dist/collab/client.d.ts +22 -7
  430. package/dist/collab/client.js +17 -5
  431. package/dist/collab/client.js.map +1 -1
  432. package/dist/composer/ComposerAttachedReferences.cjs +119 -0
  433. package/dist/composer/ComposerAttachedReferences.cjs.map +1 -0
  434. package/dist/composer/ComposerAttachedReferences.d.ts +26 -0
  435. package/dist/composer/ComposerAttachedReferences.js +119 -0
  436. package/dist/composer/ComposerAttachedReferences.js.map +1 -0
  437. package/dist/composer/ComposerNamedAgents.cjs +63 -0
  438. package/dist/composer/ComposerNamedAgents.cjs.map +1 -0
  439. package/dist/composer/ComposerNamedAgents.d.ts +16 -0
  440. package/dist/composer/ComposerNamedAgents.js +63 -0
  441. package/dist/composer/ComposerNamedAgents.js.map +1 -0
  442. package/dist/composer/attached-references.cjs +159 -0
  443. package/dist/composer/attached-references.cjs.map +1 -0
  444. package/dist/composer/attached-references.d.ts +86 -0
  445. package/dist/composer/attached-references.js +159 -0
  446. package/dist/composer/attached-references.js.map +1 -0
  447. package/dist/composer/build-composed-message.cjs +14 -7
  448. package/dist/composer/build-composed-message.cjs.map +1 -1
  449. package/dist/composer/build-composed-message.d.ts +6 -1
  450. package/dist/composer/build-composed-message.js +14 -7
  451. package/dist/composer/build-composed-message.js.map +1 -1
  452. package/dist/composer/composer-handoff.cjs +6 -2
  453. package/dist/composer/composer-handoff.cjs.map +1 -1
  454. package/dist/composer/composer-handoff.d.ts +7 -1
  455. package/dist/composer/composer-handoff.js +6 -2
  456. package/dist/composer/composer-handoff.js.map +1 -1
  457. package/dist/composer/folder-upload.cjs +149 -0
  458. package/dist/composer/folder-upload.cjs.map +1 -0
  459. package/dist/composer/folder-upload.d.ts +79 -0
  460. package/dist/composer/folder-upload.js +149 -0
  461. package/dist/composer/folder-upload.js.map +1 -0
  462. package/dist/composer/index.d.ts +1 -1
  463. package/dist/composer/useAttachToChat.cjs +35 -0
  464. package/dist/composer/useAttachToChat.cjs.map +1 -0
  465. package/dist/composer/useAttachToChat.d.ts +54 -0
  466. package/dist/composer/useAttachToChat.js +35 -0
  467. package/dist/composer/useAttachToChat.js.map +1 -0
  468. package/dist/composer/useAttachedReferencesComposerProps.cjs +19 -0
  469. package/dist/composer/useAttachedReferencesComposerProps.cjs.map +1 -0
  470. package/dist/composer/useAttachedReferencesComposerProps.d.ts +12 -0
  471. package/dist/composer/useAttachedReferencesComposerProps.js +19 -0
  472. package/dist/composer/useAttachedReferencesComposerProps.js.map +1 -0
  473. package/dist/composer/useFileUpload.cjs +95 -7
  474. package/dist/composer/useFileUpload.cjs.map +1 -1
  475. package/dist/composer/useFileUpload.d.ts +21 -2
  476. package/dist/composer/useFileUpload.js +95 -7
  477. package/dist/composer/useFileUpload.js.map +1 -1
  478. package/dist/data/athena-api-error.cjs +125 -0
  479. package/dist/data/athena-api-error.cjs.map +1 -0
  480. package/dist/data/athena-api-error.d.ts +96 -0
  481. package/dist/data/athena-api-error.js +125 -0
  482. package/dist/data/athena-api-error.js.map +1 -0
  483. package/dist/data/athena-data-client.cjs +106 -0
  484. package/dist/data/athena-data-client.cjs.map +1 -0
  485. package/dist/data/athena-data-client.d.ts +74 -0
  486. package/dist/data/athena-data-client.js +106 -0
  487. package/dist/data/athena-data-client.js.map +1 -0
  488. package/dist/data/athena-member.cjs +93 -0
  489. package/dist/data/athena-member.cjs.map +1 -0
  490. package/dist/data/athena-member.d.ts +125 -0
  491. package/dist/data/athena-member.js +93 -0
  492. package/dist/data/athena-member.js.map +1 -0
  493. package/dist/data/athena-request.cjs +458 -0
  494. package/dist/data/athena-request.cjs.map +1 -0
  495. package/dist/data/athena-request.d.ts +120 -0
  496. package/dist/data/athena-request.js +458 -0
  497. package/dist/data/athena-request.js.map +1 -0
  498. package/dist/data/use-athena-fetch.cjs +14 -0
  499. package/dist/data/use-athena-fetch.cjs.map +1 -0
  500. package/dist/data/use-athena-fetch.d.ts +19 -0
  501. package/dist/data/use-athena-fetch.js +14 -0
  502. package/dist/data/use-athena-fetch.js.map +1 -0
  503. package/dist/data/use-athena-graphql.cjs +66 -0
  504. package/dist/data/use-athena-graphql.cjs.map +1 -0
  505. package/dist/data/use-athena-graphql.d.ts +56 -0
  506. package/dist/data/use-athena-graphql.js +66 -0
  507. package/dist/data/use-athena-graphql.js.map +1 -0
  508. package/dist/data/use-athena-rest.cjs +33 -0
  509. package/dist/data/use-athena-rest.cjs.map +1 -0
  510. package/dist/data/use-athena-rest.d.ts +21 -0
  511. package/dist/data/use-athena-rest.js +33 -0
  512. package/dist/data/use-athena-rest.js.map +1 -0
  513. package/dist/data/use-semantic-query.cjs +44 -0
  514. package/dist/data/use-semantic-query.cjs.map +1 -0
  515. package/dist/data/use-semantic-query.d.ts +92 -0
  516. package/dist/data/use-semantic-query.js +44 -0
  517. package/dist/data/use-semantic-query.js.map +1 -0
  518. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  519. package/dist/diagnostics/athena-diagnostics.d.ts +5 -1
  520. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  521. package/dist/diagnostics/errors.cjs +7 -0
  522. package/dist/diagnostics/errors.cjs.map +1 -1
  523. package/dist/diagnostics/errors.d.ts +7 -0
  524. package/dist/diagnostics/errors.js +7 -0
  525. package/dist/diagnostics/errors.js.map +1 -1
  526. package/dist/index.cjs +155 -11
  527. package/dist/index.cjs.map +1 -1
  528. package/dist/index.d.ts +72 -13
  529. package/dist/index.js +148 -4
  530. package/dist/index.js.map +1 -1
  531. package/dist/keryx-http/src/initial-sync.cjs +64 -16
  532. package/dist/keryx-http/src/initial-sync.cjs.map +1 -1
  533. package/dist/keryx-http/src/initial-sync.d.ts +31 -1
  534. package/dist/keryx-http/src/initial-sync.js +64 -16
  535. package/dist/keryx-http/src/initial-sync.js.map +1 -1
  536. package/dist/keryx-http/src/own-awareness.cjs +20 -0
  537. package/dist/keryx-http/src/own-awareness.cjs.map +1 -0
  538. package/dist/keryx-http/src/own-awareness.d.ts +50 -0
  539. package/dist/keryx-http/src/own-awareness.js +20 -0
  540. package/dist/keryx-http/src/own-awareness.js.map +1 -0
  541. package/dist/keryx-http/src/update-attributions.cjs +26 -1
  542. package/dist/keryx-http/src/update-attributions.cjs.map +1 -1
  543. package/dist/keryx-http/src/update-attributions.d.ts +10 -1
  544. package/dist/keryx-http/src/update-attributions.js +26 -1
  545. package/dist/keryx-http/src/update-attributions.js.map +1 -1
  546. package/dist/offline/chat-outbox.cjs +262 -26
  547. package/dist/offline/chat-outbox.cjs.map +1 -1
  548. package/dist/offline/chat-outbox.d.ts +90 -12
  549. package/dist/offline/chat-outbox.js +263 -27
  550. package/dist/offline/chat-outbox.js.map +1 -1
  551. package/dist/provider/AthenaProvider.cjs +56 -19
  552. package/dist/provider/AthenaProvider.cjs.map +1 -1
  553. package/dist/provider/AthenaProvider.d.ts +24 -8
  554. package/dist/provider/AthenaProvider.js +57 -20
  555. package/dist/provider/AthenaProvider.js.map +1 -1
  556. package/dist/react/package.json.cjs +1 -1
  557. package/dist/react/package.json.js +1 -1
  558. package/dist/references/src/anchors/types.cjs +5 -0
  559. package/dist/references/src/anchors/types.cjs.map +1 -1
  560. package/dist/references/src/anchors/types.js +5 -0
  561. package/dist/references/src/anchors/types.js.map +1 -1
  562. package/dist/references/src/attachable.cjs +149 -0
  563. package/dist/references/src/attachable.cjs.map +1 -0
  564. package/dist/references/src/attachable.d.ts +87 -0
  565. package/dist/references/src/attachable.js +149 -0
  566. package/dist/references/src/attachable.js.map +1 -0
  567. package/dist/runtime/StatewirePlanModeLaneSync.cjs +93 -0
  568. package/dist/runtime/StatewirePlanModeLaneSync.cjs.map +1 -0
  569. package/dist/runtime/StatewirePlanModeLaneSync.d.ts +34 -0
  570. package/dist/runtime/StatewirePlanModeLaneSync.js +93 -0
  571. package/dist/runtime/StatewirePlanModeLaneSync.js.map +1 -0
  572. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +2 -0
  573. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -1
  574. package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +4 -0
  575. package/dist/runtime/StatewireThreadConfigLaneSync.js +2 -0
  576. package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -1
  577. package/dist/runtime/statewire-plan-mode.cjs +71 -0
  578. package/dist/runtime/statewire-plan-mode.cjs.map +1 -0
  579. package/dist/runtime/statewire-plan-mode.d.ts +88 -0
  580. package/dist/runtime/statewire-plan-mode.js +71 -0
  581. package/dist/runtime/statewire-plan-mode.js.map +1 -0
  582. package/dist/runtime/statewire-run-config.cjs +3 -1
  583. package/dist/runtime/statewire-run-config.cjs.map +1 -1
  584. package/dist/runtime/statewire-run-config.d.ts +7 -0
  585. package/dist/runtime/statewire-run-config.js +3 -1
  586. package/dist/runtime/statewire-run-config.js.map +1 -1
  587. package/dist/runtime/statewire-session-key.cjs +11 -5
  588. package/dist/runtime/statewire-session-key.cjs.map +1 -1
  589. package/dist/runtime/statewire-session-key.d.ts +22 -10
  590. package/dist/runtime/statewire-session-key.js +11 -5
  591. package/dist/runtime/statewire-session-key.js.map +1 -1
  592. package/dist/runtime/useAthenaStatewireRuntime.cjs +65 -8
  593. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  594. package/dist/runtime/useAthenaStatewireRuntime.d.ts +26 -10
  595. package/dist/runtime/useAthenaStatewireRuntime.js +67 -10
  596. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  597. package/dist/search/useAthenaAssets.cjs +394 -0
  598. package/dist/search/useAthenaAssets.cjs.map +1 -0
  599. package/dist/search/useAthenaAssets.d.ts +186 -0
  600. package/dist/search/useAthenaAssets.js +394 -0
  601. package/dist/search/useAthenaAssets.js.map +1 -0
  602. package/dist/sheet-range/index.cjs +4 -0
  603. package/dist/sheet-range/index.cjs.map +1 -1
  604. package/dist/sheet-range/index.d.ts +4 -2
  605. package/dist/sheet-range/index.js +4 -0
  606. package/dist/sheet-range/index.js.map +1 -1
  607. package/dist/sheet-range/query-range.cjs +102 -0
  608. package/dist/sheet-range/query-range.cjs.map +1 -0
  609. package/dist/sheet-range/query-range.d.ts +46 -0
  610. package/dist/sheet-range/query-range.js +102 -0
  611. package/dist/sheet-range/query-range.js.map +1 -0
  612. package/dist/styles.css +1 -1
  613. package/dist/subagents/index.cjs +49 -0
  614. package/dist/subagents/index.cjs.map +1 -0
  615. package/dist/subagents/index.d.ts +16 -0
  616. package/dist/subagents/index.js +49 -0
  617. package/dist/subagents/index.js.map +1 -0
  618. package/dist/subagents/lane-follow.cjs +19 -0
  619. package/dist/subagents/lane-follow.cjs.map +1 -0
  620. package/dist/subagents/lane-follow.d.ts +9 -0
  621. package/dist/subagents/lane-follow.js +19 -0
  622. package/dist/subagents/lane-follow.js.map +1 -0
  623. package/dist/subagents/lane-model.cjs +178 -0
  624. package/dist/subagents/lane-model.cjs.map +1 -0
  625. package/dist/subagents/lane-model.d.ts +140 -0
  626. package/dist/subagents/lane-model.js +178 -0
  627. package/dist/subagents/lane-model.js.map +1 -0
  628. package/dist/subagents/lane-parts.cjs +517 -0
  629. package/dist/subagents/lane-parts.cjs.map +1 -0
  630. package/dist/subagents/lane-parts.d.ts +130 -0
  631. package/dist/subagents/lane-parts.js +517 -0
  632. package/dist/subagents/lane-parts.js.map +1 -0
  633. package/dist/subagents/subagent-lane-group.cjs +215 -0
  634. package/dist/subagents/subagent-lane-group.cjs.map +1 -0
  635. package/dist/subagents/subagent-lane-group.d.ts +67 -0
  636. package/dist/subagents/subagent-lane-group.js +215 -0
  637. package/dist/subagents/subagent-lane-group.js.map +1 -0
  638. package/dist/subagents/subagent-transcript-drawer.cjs +431 -0
  639. package/dist/subagents/subagent-transcript-drawer.cjs.map +1 -0
  640. package/dist/subagents/subagent-transcript-drawer.d.ts +78 -0
  641. package/dist/subagents/subagent-transcript-drawer.js +431 -0
  642. package/dist/subagents/subagent-transcript-drawer.js.map +1 -0
  643. package/dist/subagents/task-subagent-group.cjs +115 -0
  644. package/dist/subagents/task-subagent-group.cjs.map +1 -0
  645. package/dist/subagents/task-subagent-group.d.ts +36 -0
  646. package/dist/subagents/task-subagent-group.js +115 -0
  647. package/dist/subagents/task-subagent-group.js.map +1 -0
  648. package/dist/subagents/use-omitted-images-in-view.cjs +68 -0
  649. package/dist/subagents/use-omitted-images-in-view.cjs.map +1 -0
  650. package/dist/subagents/use-omitted-images-in-view.d.ts +21 -0
  651. package/dist/subagents/use-omitted-images-in-view.js +68 -0
  652. package/dist/subagents/use-omitted-images-in-view.js.map +1 -0
  653. package/dist/threads/Inbox.cjs +2 -2
  654. package/dist/threads/Inbox.cjs.map +1 -1
  655. package/dist/threads/SessionList.cjs +6 -6
  656. package/dist/threads/SessionList.cjs.map +1 -1
  657. package/dist/threads/SessionsPage.cjs +13 -7
  658. package/dist/threads/SessionsPage.cjs.map +1 -1
  659. package/dist/threads/SessionsPage.d.ts +10 -1
  660. package/dist/threads/SessionsPage.js +9 -3
  661. package/dist/threads/SessionsPage.js.map +1 -1
  662. package/dist/threads/session-list-model.cjs.map +1 -1
  663. package/dist/threads/session-list-model.d.ts +2 -1
  664. package/dist/threads/session-list-model.js.map +1 -1
  665. package/dist/threads/session-row-parts.cjs +3 -3
  666. package/dist/threads/session-row-parts.cjs.map +1 -1
  667. package/dist/threads/sessions-page-model.cjs +13 -5
  668. package/dist/threads/sessions-page-model.cjs.map +1 -1
  669. package/dist/threads/sessions-page-model.d.ts +7 -0
  670. package/dist/threads/sessions-page-model.js +11 -3
  671. package/dist/threads/sessions-page-model.js.map +1 -1
  672. package/dist/threads/sessions-page-storage.cjs +8 -8
  673. package/dist/threads/sessions-page-storage.cjs.map +1 -1
  674. package/dist/threads/sessions-page-storage.d.ts +5 -1
  675. package/dist/threads/sessions-page-storage.js +8 -8
  676. package/dist/threads/sessions-page-storage.js.map +1 -1
  677. package/dist/threads/use-athena-sessions.cjs +1 -0
  678. package/dist/threads/use-athena-sessions.cjs.map +1 -1
  679. package/dist/threads/use-athena-sessions.d.ts +7 -0
  680. package/dist/threads/use-athena-sessions.js +1 -0
  681. package/dist/threads/use-athena-sessions.js.map +1 -1
  682. package/dist/threads/use-athena-thread-agent.cjs +31 -0
  683. package/dist/threads/use-athena-thread-agent.cjs.map +1 -0
  684. package/dist/threads/use-athena-thread-agent.d.ts +38 -0
  685. package/dist/threads/use-athena-thread-agent.js +31 -0
  686. package/dist/threads/use-athena-thread-agent.js.map +1 -0
  687. package/dist/threads/use-athena-thread-plan-mode.cjs +18 -0
  688. package/dist/threads/use-athena-thread-plan-mode.cjs.map +1 -0
  689. package/dist/threads/use-athena-thread-plan-mode.d.ts +18 -0
  690. package/dist/threads/use-athena-thread-plan-mode.js +18 -0
  691. package/dist/threads/use-athena-thread-plan-mode.js.map +1 -0
  692. package/dist/threads/use-rest-conversation-history.d.ts +1 -0
  693. package/dist/tools/agent-creations.cjs +97 -0
  694. package/dist/tools/agent-creations.cjs.map +1 -0
  695. package/dist/tools/agent-creations.d.ts +38 -0
  696. package/dist/tools/agent-creations.js +97 -0
  697. package/dist/tools/agent-creations.js.map +1 -0
  698. package/dist/tools/agent-highlights.cjs +100 -0
  699. package/dist/tools/agent-highlights.cjs.map +1 -0
  700. package/dist/tools/agent-highlights.d.ts +57 -0
  701. package/dist/tools/agent-highlights.js +100 -0
  702. package/dist/tools/agent-highlights.js.map +1 -0
  703. package/dist/tools/append-document-tool-ui.cjs +1 -0
  704. package/dist/tools/append-document-tool-ui.cjs.map +1 -1
  705. package/dist/tools/append-document-tool-ui.d.ts +7 -0
  706. package/dist/tools/append-document-tool-ui.js +2 -1
  707. package/dist/tools/append-document-tool-ui.js.map +1 -1
  708. package/dist/tools/auto-open-tools.cjs +144 -71
  709. package/dist/tools/auto-open-tools.cjs.map +1 -1
  710. package/dist/tools/auto-open-tools.d.ts +131 -1
  711. package/dist/tools/auto-open-tools.js +145 -72
  712. package/dist/tools/auto-open-tools.js.map +1 -1
  713. package/dist/tools/browser-tool-uis.cjs +594 -0
  714. package/dist/tools/browser-tool-uis.cjs.map +1 -0
  715. package/dist/tools/browser-tool-uis.d.ts +8 -0
  716. package/dist/tools/browser-tool-uis.js +594 -0
  717. package/dist/tools/browser-tool-uis.js.map +1 -0
  718. package/dist/tools/computer-asset-tool-uis.cjs +313 -0
  719. package/dist/tools/computer-asset-tool-uis.cjs.map +1 -0
  720. package/dist/tools/computer-asset-tool-uis.d.ts +5 -0
  721. package/dist/tools/computer-asset-tool-uis.js +313 -0
  722. package/dist/tools/computer-asset-tool-uis.js.map +1 -0
  723. package/dist/tools/document-edit-tool-uis.cjs +218 -0
  724. package/dist/tools/document-edit-tool-uis.cjs.map +1 -0
  725. package/dist/tools/document-edit-tool-uis.d.ts +40 -0
  726. package/dist/tools/document-edit-tool-uis.js +218 -0
  727. package/dist/tools/document-edit-tool-uis.js.map +1 -0
  728. package/dist/tools/drive-tool-uis.cjs +425 -0
  729. package/dist/tools/drive-tool-uis.cjs.map +1 -0
  730. package/dist/tools/drive-tool-uis.d.ts +120 -0
  731. package/dist/tools/drive-tool-uis.js +425 -0
  732. package/dist/tools/drive-tool-uis.js.map +1 -0
  733. package/dist/tools/email-calendar-tool-uis.cjs +789 -0
  734. package/dist/tools/email-calendar-tool-uis.cjs.map +1 -0
  735. package/dist/tools/email-calendar-tool-uis.d.ts +129 -0
  736. package/dist/tools/email-calendar-tool-uis.js +789 -0
  737. package/dist/tools/email-calendar-tool-uis.js.map +1 -0
  738. package/dist/tools/ontology-tool-uis.cjs +83 -0
  739. package/dist/tools/ontology-tool-uis.cjs.map +1 -0
  740. package/dist/tools/ontology-tool-uis.d.ts +9 -0
  741. package/dist/tools/ontology-tool-uis.js +83 -0
  742. package/dist/tools/ontology-tool-uis.js.map +1 -0
  743. package/dist/tools/orchestration-tool-uis.cjs +586 -0
  744. package/dist/tools/orchestration-tool-uis.cjs.map +1 -0
  745. package/dist/tools/orchestration-tool-uis.d.ts +141 -0
  746. package/dist/tools/orchestration-tool-uis.js +586 -0
  747. package/dist/tools/orchestration-tool-uis.js.map +1 -0
  748. package/dist/tools/presentation-edit-tool-uis.cjs +516 -0
  749. package/dist/tools/presentation-edit-tool-uis.cjs.map +1 -0
  750. package/dist/tools/presentation-edit-tool-uis.d.ts +73 -0
  751. package/dist/tools/presentation-edit-tool-uis.js +516 -0
  752. package/dist/tools/presentation-edit-tool-uis.js.map +1 -0
  753. package/dist/tools/project-tool-uis.cjs +213 -0
  754. package/dist/tools/project-tool-uis.cjs.map +1 -0
  755. package/dist/tools/project-tool-uis.d.ts +14 -0
  756. package/dist/tools/project-tool-uis.js +213 -0
  757. package/dist/tools/project-tool-uis.js.map +1 -0
  758. package/dist/tools/sandbox-tool-uis.cjs +491 -0
  759. package/dist/tools/sandbox-tool-uis.cjs.map +1 -0
  760. package/dist/tools/sandbox-tool-uis.d.ts +116 -0
  761. package/dist/tools/sandbox-tool-uis.js +491 -0
  762. package/dist/tools/sandbox-tool-uis.js.map +1 -0
  763. package/dist/tools/sheet-query-tool-ui.cjs +138 -0
  764. package/dist/tools/sheet-query-tool-ui.cjs.map +1 -0
  765. package/dist/tools/sheet-query-tool-ui.d.ts +15 -0
  766. package/dist/tools/sheet-query-tool-ui.js +138 -0
  767. package/dist/tools/sheet-query-tool-ui.js.map +1 -0
  768. package/dist/tools/studio-screenshot-tool-uis.cjs +262 -0
  769. package/dist/tools/studio-screenshot-tool-uis.cjs.map +1 -0
  770. package/dist/tools/studio-screenshot-tool-uis.d.ts +52 -0
  771. package/dist/tools/studio-screenshot-tool-uis.js +262 -0
  772. package/dist/tools/studio-screenshot-tool-uis.js.map +1 -0
  773. package/dist/tools/subagent-task-tool-ui.cjs +24 -475
  774. package/dist/tools/subagent-task-tool-ui.cjs.map +1 -1
  775. package/dist/tools/subagent-task-tool-ui.d.ts +19 -103
  776. package/dist/tools/subagent-task-tool-ui.js +28 -479
  777. package/dist/tools/subagent-task-tool-ui.js.map +1 -1
  778. package/dist/tools/tool-summary.cjs +36 -0
  779. package/dist/tools/tool-summary.cjs.map +1 -1
  780. package/dist/tools/tool-summary.js +36 -0
  781. package/dist/tools/tool-summary.js.map +1 -1
  782. package/dist/tools/tool-uis.cjs +181 -53
  783. package/dist/tools/tool-uis.cjs.map +1 -1
  784. package/dist/tools/tool-uis.d.ts +40 -0
  785. package/dist/tools/tool-uis.js +183 -55
  786. package/dist/tools/tool-uis.js.map +1 -1
  787. package/dist/typed-interrupts/index.cjs +15 -0
  788. package/dist/typed-interrupts/index.cjs.map +1 -0
  789. package/dist/typed-interrupts/index.d.ts +20 -0
  790. package/dist/typed-interrupts/index.js +15 -0
  791. package/dist/typed-interrupts/index.js.map +1 -0
  792. package/dist/workbench/session-workbench-panes.cjs +6 -6
  793. package/dist/workbench/session-workbench-panes.cjs.map +1 -1
  794. package/package.json +28 -6
  795. package/dist/agent-runtime/src/chat-outbox-store.cjs +0 -510
  796. package/dist/agent-runtime/src/chat-outbox-store.cjs.map +0 -1
  797. package/dist/agent-runtime/src/chat-outbox-store.d.ts +0 -210
  798. package/dist/agent-runtime/src/chat-outbox-store.js +0 -510
  799. package/dist/agent-runtime/src/chat-outbox-store.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-athena-sessions.cjs","sources":["../../src/threads/use-athena-sessions.ts"],"sourcesContent":["/**\n * `useAthenaSessions(query)` — one filtered, sorted, live session list under\n * `<AthenaProvider enableThreadList>`: the data layer of `SessionsPage` and\n * `Inbox`, for hosts drawing their own.\n *\n * - **Server-side.** The query travels to `POST /api/conversations/threads/list`\n * as filters of the server's one page statement (`planSessionsQuery`), over\n * the shared two-tier pager (`useConversationList`: a live first page and\n * frozen history pages) in the thread-list provider's query client.\n * - **Live.** Rows fold the same conversation-index pushes the sidebar folds\n * (titles, lifecycle, attention flip in place), carry the provider's\n * in-flight writes (pin, rename, read state, archive), and a thread the\n * index learns about that the list does not show yet refreshes the list\n * once.\n * - **Degraded, not wrong.** A server that cannot apply part of the query is\n * detected from its `supported_filters` echo (one `limit: 1` probe per\n * identity). Fields the loaded rows can be tested on are applied to them\n * (`degradedFields`: exact per page, a page can come back short); fields\n * they cannot are reported in `unavailableFields` and not applied, so a\n * control for them can be disabled rather than lie.\n */\nimport {\n type ConversationListFilter,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n useConversationList,\n} from '@athenaintel/agent-runtime';\nimport { useQuery } from '@tanstack/react-query';\nimport { useContext, useMemo, useRef } from 'react';\nimport { useAthenaQueryClient } from '../lib/use-athena-rest-query';\nimport { withCredentialRenewal } from '../runtime/credential-renewal';\nimport { listThreads } from './api';\nimport { createRestConversationListFetcher } from './conversation-list-fetcher';\nimport { useIndexTriggeredRefresh } from './index-triggered-refresh';\nimport { sessionListShareKey } from './session-list-tab-share';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n matchesSessionsQuery,\n planSessionsQuery,\n sessionsQueryFromKey,\n sessionsQueryKey,\n sortSessions,\n supportedFiltersFromResponse,\n unavailableSessionsQueryFields,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadSummary,\n foldConversationIndex,\n indexedThreadsToRefreshFor,\n threadSummaryFromConversation,\n} from './statewire-thread-list';\n\nexport interface UseAthenaSessionsOptions {\n /** What to list. A new object with the same content does not refetch. */\n query: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** `false` holds the list idle. Default `true`. */\n enabled?: boolean;\n}\n\nexport interface AthenaSessionsList {\n /** The rows, in the query's order, with live pushes and in-flight writes applied. */\n rows: AthenaStatewireThreadSummary[];\n /** `false` outside `enableThreadList` mode: nothing is fetched and `rows` stays empty. */\n isAvailable: boolean;\n /** True until the first page has answered (or while no credential has resolved). */\n isLoading: boolean;\n isFetching: boolean;\n hasResolvedFirstPage: boolean;\n /**\n * True while the rows are the previous query's (checked against this\n * query's local part) because this query's first page is still in flight.\n */\n isPlaceholderData: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n /** Refetch the first page; resolves once it has answered. */\n refresh: () => Promise<void>;\n /** True while the last \"load more\" request failed. */\n isFetchNextPageError: boolean;\n /**\n * The server fields this backend applies (`supported_filters`), `null`\n * while unknown or on a backend that predates the list.\n */\n supportedFilters: ReadonlySet<string> | null;\n /** Fields applied to the loaded rows because the backend cannot. */\n degradedFields: AthenaSessionsQueryField[];\n /** Fields of this query that cannot be applied on this backend at all (and are not). */\n unavailableFields: AthenaSessionsQueryField[];\n /**\n * Every field this backend cannot apply anywhere, selected or not — what a\n * filter UI disables. Empty until the capabilities probe has answered.\n */\n unsupportedFields: AthenaSessionsQueryField[];\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\n/** The capabilities probe's key prefix. */\nexport const THREAD_LIST_CAPABILITIES_QUERY_KEY = [\n 'athena-sdk',\n 'thread-list-capabilities',\n] as const;\n\nconst EMPTY_ROWS: AthenaStatewireThreadSummary[] = [];\nconst EMPTY_VERSIONS: ReadonlySet<string> = new Set();\nconst NOOP = () => undefined;\nconst NOOP_ASYNC = async () => undefined;\n\nexport function useAthenaSessions({\n query,\n pageSize = DEFAULT_PAGE_SIZE,\n enabled = true,\n}: UseAthenaSessionsOptions): AthenaSessionsList {\n const live = useContext(AthenaSessionsLiveContext);\n const isAvailable = live !== null;\n const backendUrl = live?.backendUrl ?? '';\n const principal = live?.principal ?? '';\n const hasAuth = live?.hasAuth ?? false;\n const includePullRequests = live?.includePullRequests ?? false;\n const getAuth = live?.getAuth;\n const active = isAvailable && enabled && hasAuth;\n // Every cache below is keyed by WHO reads (principal) and WITH WHAT (the\n // credential generation): a scoped credential for another workspace under\n // the same principal must never read this one's cached rows.\n const identityScope = `${live?.scopeKey ?? 'unavailable'}::credential-${\n live?.credentialGeneration ?? 0\n }`;\n\n // Outside thread-list mode there may be no `QueryClientProvider`; every\n // query below is disabled there, on a client of this hook's own.\n const queryClient = useAthenaQueryClient();\n\n // Which filters this backend applies: one tiny page per identity. The\n // answer is a property of the deployed agora, so it never goes stale.\n const capabilities = useQuery(\n {\n queryKey: [\n ...THREAD_LIST_CAPABILITIES_QUERY_KEY,\n backendUrl,\n principal,\n live?.credentialGeneration ?? 0,\n ],\n queryFn: async ({ signal }) => {\n if (!getAuth) return null;\n const response = await withCredentialRenewal(getAuth, (auth) =>\n listThreads(backendUrl, auth, { limit: 1, signal }),\n );\n return supportedFiltersFromResponse(response.supported_filters);\n },\n enabled: active,\n staleTime: Number.POSITIVE_INFINITY,\n retry: 1,\n },\n queryClient,\n );\n // A failed probe is treated as an older backend: the query degrades\n // instead of the list staying empty.\n const capabilitiesSettled = capabilities.isSuccess || capabilities.isError;\n const supportedFilters = capabilities.data ?? null;\n\n // `query` may be a fresh object every render; its normalized key is what\n // identifies it, so the plan is built from the key and recomputed only\n // when the content changes.\n const queryKey = sessionsQueryKey(query);\n const plan = useMemo(\n () =>\n planSessionsQuery(sessionsQueryFromKey(queryKey), {\n supportedFilters,\n includePullRequests,\n }),\n [queryKey, supportedFilters, includePullRequests],\n );\n const planRef = useRef(plan);\n planRef.current = plan;\n const unsupportedFields = useMemo(\n () =>\n capabilitiesSettled\n ? unavailableSessionsQueryFields({ supportedFilters, includePullRequests })\n : [],\n [capabilitiesSettled, supportedFilters, includePullRequests],\n );\n\n const fetchPage = useMemo(\n () =>\n getAuth\n ? createRestConversationListFetcher({\n backendUrl,\n getAuth,\n includePullRequests,\n extraFilters: plan.body,\n keepRow: (row) => matchesSessionsQuery(row, planRef.current.local),\n })\n : async () => ({ items: [], hasMore: false, totalCount: null }),\n [backendUrl, getAuth, includePullRequests, plan.body],\n );\n const baseFilter: ConversationListFilter = live?.baseFilter ?? {};\n const capabilityKey = supportedFilters ? [...supportedFilters].sort().join(',') : 'legacy';\n // The query's server filters are not part of the shared filter contract,\n // so they — and what this backend applies of them — key the cache here.\n const listScopeKey = `${identityScope}::sessions::${queryKey}::${capabilityKey}`;\n const list = useConversationList({\n fetchPage,\n filter: baseFilter,\n pageSize,\n scopeKey: listScopeKey,\n enabled: active && capabilitiesSettled,\n queryClient,\n });\n\n // While a changed query's first page is in flight, the previous query's\n // rows stand in, checked against the new query's local part — the list\n // narrows at once instead of blanking to skeletons. Only rows read as the\n // same identity and credential, over the same app scope, ever stand in: a\n // changed scope (another app, or the home agent's conversations turned off)\n // cannot be narrowed on the rows.\n const standInScope = `${identityScope}::${conversationListFilterKey(baseFilter)}`;\n const lastResolvedRef = useRef<{ scope: string; conversations: ConversationSummary[] }>({\n scope: '',\n conversations: [],\n });\n if (list.hasResolvedFirstPage) {\n lastResolvedRef.current = { scope: standInScope, conversations: list.conversations };\n }\n const standIn =\n !list.hasResolvedFirstPage && lastResolvedRef.current.scope === standInScope\n ? lastResolvedRef.current.conversations\n : null;\n const source = standIn ?? list.conversations;\n const isPlaceholderData = standIn !== null && standIn.length > 0;\n\n const indexByThread = live?.indexByThread;\n const applyOverrides = live?.applyOverrides;\n const rows = useMemo(() => {\n if (!indexByThread || !applyOverrides) return EMPTY_ROWS;\n const folded: ConversationSummary[] = applyOverrides(\n foldConversationIndex(source, indexByThread),\n ).filter((row) => matchesSessionsQuery(row, plan.local));\n return sortSessions(folded, plan.local).map(threadSummaryFromConversation);\n }, [source, indexByThread, applyOverrides, plan.local]);\n\n // A thread the index knows that this list does not show yet refreshes the\n // list — it may be new, or may have just come to match. Once per VERSION of\n // the entry (its id and `updated_at`): an unchanged entry the server keeps\n // leaving out never refreshes twice, and a later change to it (a PR opened,\n // a run now needing input) gets its own refresh. Coalesced, held while the\n // list is already being read, and a refused refresh is tried again\n // (`useIndexTriggeredRefresh`).\n const indexEntries = live?.indexEntries ?? null;\n const listRefresh = list.refresh;\n const baseAppId = baseFilter.appId;\n const baseAppIds = baseFilter.appIds;\n const baseHomeAgentId = baseFilter.homeAgentId;\n const homeAgentApplied = list.homeAgentApplied;\n const listedThreadIds = useMemo(\n () => new Set(list.conversations.map((conversation) => conversation.threadId)),\n [list.conversations],\n );\n const unlistedVersions = useMemo(\n () =>\n indexEntries === null\n ? []\n : indexEntryVersionsToRefresh({\n entries: indexEntries,\n listedThreadIds,\n refreshedVersions: EMPTY_VERSIONS,\n appId: baseAppId,\n additionalAppIds: baseAppIds ?? [],\n homeAgentId: baseHomeAgentId,\n homeAgentApplied,\n query: plan.local,\n }),\n [\n indexEntries,\n listedThreadIds,\n baseAppId,\n baseAppIds,\n baseHomeAgentId,\n homeAgentApplied,\n plan.local,\n ],\n );\n useIndexTriggeredRefresh({\n pending: unlistedVersions,\n refresh: listRefresh,\n // Held while the list is being read; a refused first page does not hold\n // it (the refresh is how the list recovers).\n enabled: active && capabilitiesSettled && indexEntries !== null && !list.isFetching,\n tabShare: live?.tabShare,\n shareKey: sessionListShareKey(\n conversationListQueryKeys.firstPage(\n listScopeKey,\n conversationListFilterKey(baseFilter),\n pageSize,\n ),\n ),\n });\n\n const listFetchNextPage = list.fetchNextPage;\n return {\n rows: isAvailable ? rows : EMPTY_ROWS,\n isAvailable,\n isLoading: active && (!capabilitiesSettled || list.isLoading),\n isFetching: list.isFetching || capabilities.isFetching,\n hasResolvedFirstPage: list.hasResolvedFirstPage,\n isPlaceholderData,\n hasNextPage: list.hasNextPage,\n isFetchingNextPage: list.isFetchingNextPage,\n fetchNextPage: isAvailable ? () => void listFetchNextPage() : NOOP,\n refresh: isAvailable ? async () => void (await listRefresh()) : NOOP_ASYNC,\n isFetchNextPageError: list.isFetchNextPageError,\n supportedFilters,\n degradedFields: plan.degraded,\n unavailableFields: plan.unavailable,\n unsupportedFields,\n };\n}\n\ntype IndexEntryLike = Parameters<typeof entryCouldMatch>[0] & {\n thread_id: string;\n updated_at: string;\n app_id: string | null;\n collab_agent_id?: string | null;\n start_channel?: string | null;\n};\n\n/**\n * The index entries that warrant one refresh of a filtered list, as\n * `<thread_id>@<updated_at>` versions: entries the list does not show, of\n * the apps it lists (and, while `homeAgentApplied`, of the conversations with\n * `homeAgentId`'s agent; see `indexedThreadsToRefreshFor`), that the query\n * could match on what the entry carries, and whose version has not prompted a\n * refresh before. An unchanged entry the server keeps leaving out refreshes\n * once; any later change to it refreshes again. Exported for tests.\n */\nexport function indexEntryVersionsToRefresh({\n entries,\n listedThreadIds,\n refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n query,\n}: {\n entries: readonly IndexEntryLike[];\n listedThreadIds: ReadonlySet<string>;\n refreshedVersions: ReadonlySet<string>;\n appId: string | undefined;\n additionalAppIds: readonly string[];\n homeAgentId?: string;\n homeAgentApplied?: boolean;\n query: AthenaSessionsQuery;\n}): string[] {\n const versionOf = (entry: IndexEntryLike) => `${entry.thread_id}@${entry.updated_at}`;\n const byVersion = new Map(entries.map((entry) => [versionOf(entry), entry]));\n return indexedThreadsToRefreshFor({\n entries: entries.map((entry) => ({\n thread_id: versionOf(entry),\n app_id: entry.app_id,\n collab_agent_id: entry.collab_agent_id,\n start_channel: entry.start_channel,\n })),\n listedThreadIds: new Set(\n entries.filter((entry) => listedThreadIds.has(entry.thread_id)).map(versionOf),\n ),\n refreshedThreadIds: refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n }).filter((version) => {\n const entry = byVersion.get(version);\n return entry === undefined || entryCouldMatch(entry, query);\n });\n}\n\n/**\n * Whether a pushed index entry could belong to a list with this local query:\n * the fields the entry carries are checked, the rest pass.\n */\nexport function entryCouldMatch(\n entry: {\n is_unread?: boolean | null;\n is_favorited?: boolean | null;\n run_status?: string | null;\n session_status?: string | null;\n },\n query: AthenaSessionsQuery,\n): boolean {\n if (query.unreadOnly && entry.is_unread === false) return false;\n if (query.favoritesOnly && entry.is_favorited === false) return false;\n if (\n query.runStatuses &&\n typeof entry.run_status === 'string' &&\n !(query.runStatuses as readonly string[]).includes(entry.run_status)\n ) {\n return false;\n }\n if (\n query.sessionStatuses &&\n typeof entry.session_status === 'string' &&\n !(query.sessionStatuses as readonly string[]).includes(entry.session_status)\n ) {\n return false;\n }\n return true;\n}\n"],"names":["useContext","AthenaSessionsLiveContext","useAthenaQueryClient","useQuery","withCredentialRenewal","listThreads","supportedFiltersFromResponse","sessionsQueryKey","useMemo","planSessionsQuery","sessionsQueryFromKey","useRef","unavailableSessionsQueryFields","createRestConversationListFetcher","matchesSessionsQuery","useConversationList","conversationListFilterKey","foldConversationIndex","sortSessions","threadSummaryFromConversation","useIndexTriggeredRefresh","sessionListShareKey","conversationListQueryKeys","indexedThreadsToRefreshFor"],"mappings":";;;;;;;;;;;;;;AAqGA,MAAM,oBAAoB;AAGnB,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AACF;AAEA,MAAM,aAA6C,CAAA;AACnD,MAAM,qCAA0C,IAAA;AAChD,MAAM,OAAO,MAAM;AACnB,MAAM,aAAa,YAAY;AAExB,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,WAAW;AAAA,EACX,UAAU;AACZ,GAAiD;AAC/C,QAAM,OAAOA,WAAAA,WAAWC,6CAAyB;AACjD,QAAM,cAAc,SAAS;AAC7B,QAAM,cAAa,6BAAM,eAAc;AACvC,QAAM,aAAY,6BAAM,cAAa;AACrC,QAAM,WAAU,6BAAM,YAAW;AACjC,QAAM,uBAAsB,6BAAM,wBAAuB;AACzD,QAAM,UAAU,6BAAM;AACtB,QAAM,SAAS,eAAe,WAAW;AAIzC,QAAM,gBAAgB,IAAG,6BAAM,aAAY,aAAa,iBACtD,6BAAM,yBAAwB,CAChC;AAIA,QAAM,cAAcC,mBAAAA,qBAAA;AAIpB,QAAM,eAAeC,WAAAA;AAAAA,IACnB;AAAA,MACE,UAAU;AAAA,QACR,GAAG;AAAA,QACH;AAAA,QACA;AAAA,SACA,6BAAM,yBAAwB;AAAA,MAAA;AAAA,MAEhC,SAAS,OAAO,EAAE,aAAa;AAC7B,YAAI,CAAC,QAAS,QAAO;AACrB,cAAM,WAAW,MAAMC,kBAAAA;AAAAA,UAAsB;AAAA,UAAS,CAAC,SACrDC,IAAAA,YAAY,YAAY,MAAM,EAAE,OAAO,GAAG,OAAA,CAAQ;AAAA,QAAA;AAEpD,eAAOC,cAAAA,6BAA6B,SAAS,iBAAiB;AAAA,MAChE;AAAA,MACA,SAAS;AAAA,MACT,WAAW,OAAO;AAAA,MAClB,OAAO;AAAA,IAAA;AAAA,IAET;AAAA,EAAA;AAIF,QAAM,sBAAsB,aAAa,aAAa,aAAa;AACnE,QAAM,mBAAmB,aAAa,QAAQ;AAK9C,QAAM,WAAWC,cAAAA,iBAAiB,KAAK;AACvC,QAAM,OAAOC,WAAAA;AAAAA,IACX,MACEC,cAAAA,kBAAkBC,mCAAqB,QAAQ,GAAG;AAAA,MAChD;AAAA,MACA;AAAA,IAAA,CACD;AAAA,IACH,CAAC,UAAU,kBAAkB,mBAAmB;AAAA,EAAA;AAElD,QAAM,UAAUC,WAAAA,OAAO,IAAI;AAC3B,UAAQ,UAAU;AAClB,QAAM,oBAAoBH,WAAAA;AAAAA,IACxB,MACE,sBACII,cAAAA,+BAA+B,EAAE,kBAAkB,oBAAA,CAAqB,IACxE,CAAA;AAAA,IACN,CAAC,qBAAqB,kBAAkB,mBAAmB;AAAA,EAAA;AAG7D,QAAM,YAAYJ,WAAAA;AAAAA,IAChB,MACE,UACIK,wBAAAA,kCAAkC;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,KAAK;AAAA,MACnB,SAAS,CAAC,QAAQC,cAAAA,qBAAqB,KAAK,QAAQ,QAAQ,KAAK;AAAA,IAAA,CAClE,IACD,aAAa,EAAE,OAAO,CAAA,GAAI,SAAS,OAAO,YAAY;IAC5D,CAAC,YAAY,SAAS,qBAAqB,KAAK,IAAI;AAAA,EAAA;AAEtD,QAAM,cAAqC,6BAAM,eAAc,CAAA;AAC/D,QAAM,gBAAgB,mBAAmB,CAAC,GAAG,gBAAgB,EAAE,OAAO,KAAK,GAAG,IAAI;AAGlF,QAAM,eAAe,GAAG,aAAa,eAAe,QAAQ,KAAK,aAAa;AAC9E,QAAM,OAAOC,oBAAAA,oBAAoB;AAAA,IAC/B;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,UAAU;AAAA,IACV,SAAS,UAAU;AAAA,IACnB;AAAA,EAAA,CACD;AAQD,QAAM,eAAe,GAAG,aAAa,KAAKC,iBAAAA,0BAA0B,UAAU,CAAC;AAC/E,QAAM,kBAAkBL,WAAAA,OAAgE;AAAA,IACtF,OAAO;AAAA,IACP,eAAe,CAAA;AAAA,EAAC,CACjB;AACD,MAAI,KAAK,sBAAsB;AAC7B,oBAAgB,UAAU,EAAE,OAAO,cAAc,eAAe,KAAK,cAAA;AAAA,EACvE;AACA,QAAM,UACJ,CAAC,KAAK,wBAAwB,gBAAgB,QAAQ,UAAU,eAC5D,gBAAgB,QAAQ,gBACxB;AACN,QAAM,SAAS,WAAW,KAAK;AAC/B,QAAM,oBAAoB,YAAY,QAAQ,QAAQ,SAAS;AAE/D,QAAM,gBAAgB,6BAAM;AAC5B,QAAM,iBAAiB,6BAAM;AAC7B,QAAM,OAAOH,WAAAA,QAAQ,MAAM;AACzB,QAAI,CAAC,iBAAiB,CAAC,eAAgB,QAAO;AAC9C,UAAM,SAAgC;AAAA,MACpCS,oBAAAA,sBAAsB,QAAQ,aAAa;AAAA,IAAA,EAC3C,OAAO,CAAC,QAAQH,cAAAA,qBAAqB,KAAK,KAAK,KAAK,CAAC;AACvD,WAAOI,cAAAA,aAAa,QAAQ,KAAK,KAAK,EAAE,IAAIC,iDAA6B;AAAA,EAC3E,GAAG,CAAC,QAAQ,eAAe,gBAAgB,KAAK,KAAK,CAAC;AAStD,QAAM,gBAAe,6BAAM,iBAAgB;AAC3C,QAAM,cAAc,KAAK;AACzB,QAAM,YAAY,WAAW;AAC7B,QAAM,aAAa,WAAW;AAC9B,QAAM,kBAAkB,WAAW;AACnC,QAAM,mBAAmB,KAAK;AAC9B,QAAM,kBAAkBX,WAAAA;AAAAA,IACtB,MAAM,IAAI,IAAI,KAAK,cAAc,IAAI,CAAC,iBAAiB,aAAa,QAAQ,CAAC;AAAA,IAC7E,CAAC,KAAK,aAAa;AAAA,EAAA;AAErB,QAAM,mBAAmBA,WAAAA;AAAAA,IACvB,MACE,iBAAiB,OACb,CAAA,IACA,4BAA4B;AAAA,MAC1B,SAAS;AAAA,MACT;AAAA,MACA,mBAAmB;AAAA,MACnB,OAAO;AAAA,MACP,kBAAkB,cAAc,CAAA;AAAA,MAChC,aAAa;AAAA,MACb;AAAA,MACA,OAAO,KAAK;AAAA,IAAA,CACb;AAAA,IACP;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IAAA;AAAA,EACP;AAEFY,iDAAyB;AAAA,IACvB,SAAS;AAAA,IACT,SAAS;AAAA;AAAA;AAAA,IAGT,SAAS,UAAU,uBAAuB,iBAAiB,QAAQ,CAAC,KAAK;AAAA,IACzE,UAAU,6BAAM;AAAA,IAChB,UAAUC,oBAAAA;AAAAA,MACRC,iBAAAA,0BAA0B;AAAA,QACxB;AAAA,QACAN,iBAAAA,0BAA0B,UAAU;AAAA,QACpC;AAAA,MAAA;AAAA,IACF;AAAA,EACF,CACD;AAED,QAAM,oBAAoB,KAAK;AAC/B,SAAO;AAAA,IACL,MAAM,cAAc,OAAO;AAAA,IAC3B;AAAA,IACA,WAAW,WAAW,CAAC,uBAAuB,KAAK;AAAA,IACnD,YAAY,KAAK,cAAc,aAAa;AAAA,IAC5C,sBAAsB,KAAK;AAAA,IAC3B;AAAA,IACA,aAAa,KAAK;AAAA,IAClB,oBAAoB,KAAK;AAAA,IACzB,eAAe,cAAc,MAAM,KAAK,sBAAsB;AAAA,IAC9D,SAAS,cAAc,YAAY,KAAM,MAAM,gBAAiB;AAAA,IAChE,sBAAsB,KAAK;AAAA,IAC3B;AAAA,IACA,gBAAgB,KAAK;AAAA,IACrB,mBAAmB,KAAK;AAAA,IACxB;AAAA,EAAA;AAEJ;AAmBO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASa;AACX,QAAM,YAAY,CAAC,UAA0B,GAAG,MAAM,SAAS,IAAI,MAAM,UAAU;AACnF,QAAM,YAAY,IAAI,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,GAAG,KAAK,CAAC,CAAC;AAC3E,SAAOO,+CAA2B;AAAA,IAChC,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,MAC/B,WAAW,UAAU,KAAK;AAAA,MAC1B,QAAQ,MAAM;AAAA,MACd,iBAAiB,MAAM;AAAA,MACvB,eAAe,MAAM;AAAA,IAAA,EACrB;AAAA,IACF,iBAAiB,IAAI;AAAA,MACnB,QAAQ,OAAO,CAAC,UAAU,gBAAgB,IAAI,MAAM,SAAS,CAAC,EAAE,IAAI,SAAS;AAAA,IAAA;AAAA,IAE/E,oBAAoB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD,EAAE,OAAO,CAAC,YAAY;AACrB,UAAM,QAAQ,UAAU,IAAI,OAAO;AACnC,WAAO,UAAU,UAAa,gBAAgB,OAAO,KAAK;AAAA,EAC5D,CAAC;AACH;AAMO,SAAS,gBACd,OAMA,OACS;AACT,MAAI,MAAM,cAAc,MAAM,cAAc,MAAO,QAAO;AAC1D,MAAI,MAAM,iBAAiB,MAAM,iBAAiB,MAAO,QAAO;AAChE,MACE,MAAM,eACN,OAAO,MAAM,eAAe,YAC5B,CAAE,MAAM,YAAkC,SAAS,MAAM,UAAU,GACnE;AACA,WAAO;AAAA,EACT;AACA,MACE,MAAM,mBACN,OAAO,MAAM,mBAAmB,YAChC,CAAE,MAAM,gBAAsC,SAAS,MAAM,cAAc,GAC3E;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;;;"}
1
+ {"version":3,"file":"use-athena-sessions.cjs","sources":["../../src/threads/use-athena-sessions.ts"],"sourcesContent":["/**\n * `useAthenaSessions(query)` — one filtered, sorted, live session list under\n * `<AthenaProvider enableThreadList>`: the data layer of `SessionsPage` and\n * `Inbox`, for hosts drawing their own.\n *\n * - **Server-side.** The query travels to `POST /api/conversations/threads/list`\n * as filters of the server's one page statement (`planSessionsQuery`), over\n * the shared two-tier pager (`useConversationList`: a live first page and\n * frozen history pages) in the thread-list provider's query client.\n * - **Live.** Rows fold the same conversation-index pushes the sidebar folds\n * (titles, lifecycle, attention flip in place), carry the provider's\n * in-flight writes (pin, rename, read state, archive), and a thread the\n * index learns about that the list does not show yet refreshes the list\n * once.\n * - **Degraded, not wrong.** A server that cannot apply part of the query is\n * detected from its `supported_filters` echo (one `limit: 1` probe per\n * identity). Fields the loaded rows can be tested on are applied to them\n * (`degradedFields`: exact per page, a page can come back short); fields\n * they cannot are reported in `unavailableFields` and not applied, so a\n * control for them can be disabled rather than lie.\n */\nimport {\n type ConversationListFilter,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n useConversationList,\n} from '@athenaintel/agent-runtime';\nimport { useQuery } from '@tanstack/react-query';\nimport { useContext, useMemo, useRef } from 'react';\nimport { useAthenaQueryClient } from '../lib/use-athena-rest-query';\nimport { withCredentialRenewal } from '../runtime/credential-renewal';\nimport { listThreads } from './api';\nimport { createRestConversationListFetcher } from './conversation-list-fetcher';\nimport { useIndexTriggeredRefresh } from './index-triggered-refresh';\nimport { sessionListShareKey } from './session-list-tab-share';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n matchesSessionsQuery,\n planSessionsQuery,\n sessionsQueryFromKey,\n sessionsQueryKey,\n sortSessions,\n supportedFiltersFromResponse,\n unavailableSessionsQueryFields,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadSummary,\n foldConversationIndex,\n indexedThreadsToRefreshFor,\n threadSummaryFromConversation,\n} from './statewire-thread-list';\n\nexport interface UseAthenaSessionsOptions {\n /** What to list. A new object with the same content does not refetch. */\n query: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** `false` holds the list idle. Default `true`. */\n enabled?: boolean;\n}\n\nexport interface AthenaSessionsList {\n /** The rows, in the query's order, with live pushes and in-flight writes applied. */\n rows: AthenaStatewireThreadSummary[];\n /** `false` outside `enableThreadList` mode: nothing is fetched and `rows` stays empty. */\n isAvailable: boolean;\n /** True until the first page has answered (or while no credential has resolved). */\n isLoading: boolean;\n isFetching: boolean;\n hasResolvedFirstPage: boolean;\n /**\n * When this query's first page was last written (ms since the epoch; 0 before it has any). A\n * first page restored from the copy kept on this device (`offlineList`) carries that copy's\n * old stamp until agora answers, and a refresh that fails leaves it as it was: compare it with\n * a mount time to act only on what agora said since.\n */\n firstPageUpdatedAt: number;\n /**\n * True while the rows are the previous query's (checked against this\n * query's local part) because this query's first page is still in flight.\n */\n isPlaceholderData: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n /** Refetch the first page; resolves once it has answered. */\n refresh: () => Promise<void>;\n /** True while the last \"load more\" request failed. */\n isFetchNextPageError: boolean;\n /**\n * The server fields this backend applies (`supported_filters`), `null`\n * while unknown or on a backend that predates the list.\n */\n supportedFilters: ReadonlySet<string> | null;\n /** Fields applied to the loaded rows because the backend cannot. */\n degradedFields: AthenaSessionsQueryField[];\n /** Fields of this query that cannot be applied on this backend at all (and are not). */\n unavailableFields: AthenaSessionsQueryField[];\n /**\n * Every field this backend cannot apply anywhere, selected or not — what a\n * filter UI disables. Empty until the capabilities probe has answered.\n */\n unsupportedFields: AthenaSessionsQueryField[];\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\n/** The capabilities probe's key prefix. */\nexport const THREAD_LIST_CAPABILITIES_QUERY_KEY = [\n 'athena-sdk',\n 'thread-list-capabilities',\n] as const;\n\nconst EMPTY_ROWS: AthenaStatewireThreadSummary[] = [];\nconst EMPTY_VERSIONS: ReadonlySet<string> = new Set();\nconst NOOP = () => undefined;\nconst NOOP_ASYNC = async () => undefined;\n\nexport function useAthenaSessions({\n query,\n pageSize = DEFAULT_PAGE_SIZE,\n enabled = true,\n}: UseAthenaSessionsOptions): AthenaSessionsList {\n const live = useContext(AthenaSessionsLiveContext);\n const isAvailable = live !== null;\n const backendUrl = live?.backendUrl ?? '';\n const principal = live?.principal ?? '';\n const hasAuth = live?.hasAuth ?? false;\n const includePullRequests = live?.includePullRequests ?? false;\n const getAuth = live?.getAuth;\n const active = isAvailable && enabled && hasAuth;\n // Every cache below is keyed by WHO reads (principal) and WITH WHAT (the\n // credential generation): a scoped credential for another workspace under\n // the same principal must never read this one's cached rows.\n const identityScope = `${live?.scopeKey ?? 'unavailable'}::credential-${\n live?.credentialGeneration ?? 0\n }`;\n\n // Outside thread-list mode there may be no `QueryClientProvider`; every\n // query below is disabled there, on a client of this hook's own.\n const queryClient = useAthenaQueryClient();\n\n // Which filters this backend applies: one tiny page per identity. The\n // answer is a property of the deployed agora, so it never goes stale.\n const capabilities = useQuery(\n {\n queryKey: [\n ...THREAD_LIST_CAPABILITIES_QUERY_KEY,\n backendUrl,\n principal,\n live?.credentialGeneration ?? 0,\n ],\n queryFn: async ({ signal }) => {\n if (!getAuth) return null;\n const response = await withCredentialRenewal(getAuth, (auth) =>\n listThreads(backendUrl, auth, { limit: 1, signal }),\n );\n return supportedFiltersFromResponse(response.supported_filters);\n },\n enabled: active,\n staleTime: Number.POSITIVE_INFINITY,\n retry: 1,\n },\n queryClient,\n );\n // A failed probe is treated as an older backend: the query degrades\n // instead of the list staying empty.\n const capabilitiesSettled = capabilities.isSuccess || capabilities.isError;\n const supportedFilters = capabilities.data ?? null;\n\n // `query` may be a fresh object every render; its normalized key is what\n // identifies it, so the plan is built from the key and recomputed only\n // when the content changes.\n const queryKey = sessionsQueryKey(query);\n const plan = useMemo(\n () =>\n planSessionsQuery(sessionsQueryFromKey(queryKey), {\n supportedFilters,\n includePullRequests,\n }),\n [queryKey, supportedFilters, includePullRequests],\n );\n const planRef = useRef(plan);\n planRef.current = plan;\n const unsupportedFields = useMemo(\n () =>\n capabilitiesSettled\n ? unavailableSessionsQueryFields({ supportedFilters, includePullRequests })\n : [],\n [capabilitiesSettled, supportedFilters, includePullRequests],\n );\n\n const fetchPage = useMemo(\n () =>\n getAuth\n ? createRestConversationListFetcher({\n backendUrl,\n getAuth,\n includePullRequests,\n extraFilters: plan.body,\n keepRow: (row) => matchesSessionsQuery(row, planRef.current.local),\n })\n : async () => ({ items: [], hasMore: false, totalCount: null }),\n [backendUrl, getAuth, includePullRequests, plan.body],\n );\n const baseFilter: ConversationListFilter = live?.baseFilter ?? {};\n const capabilityKey = supportedFilters ? [...supportedFilters].sort().join(',') : 'legacy';\n // The query's server filters are not part of the shared filter contract,\n // so they — and what this backend applies of them — key the cache here.\n const listScopeKey = `${identityScope}::sessions::${queryKey}::${capabilityKey}`;\n const list = useConversationList({\n fetchPage,\n filter: baseFilter,\n pageSize,\n scopeKey: listScopeKey,\n enabled: active && capabilitiesSettled,\n queryClient,\n });\n\n // While a changed query's first page is in flight, the previous query's\n // rows stand in, checked against the new query's local part — the list\n // narrows at once instead of blanking to skeletons. Only rows read as the\n // same identity and credential, over the same app scope, ever stand in: a\n // changed scope (another app, or the home agent's conversations turned off)\n // cannot be narrowed on the rows.\n const standInScope = `${identityScope}::${conversationListFilterKey(baseFilter)}`;\n const lastResolvedRef = useRef<{ scope: string; conversations: ConversationSummary[] }>({\n scope: '',\n conversations: [],\n });\n if (list.hasResolvedFirstPage) {\n lastResolvedRef.current = { scope: standInScope, conversations: list.conversations };\n }\n const standIn =\n !list.hasResolvedFirstPage && lastResolvedRef.current.scope === standInScope\n ? lastResolvedRef.current.conversations\n : null;\n const source = standIn ?? list.conversations;\n const isPlaceholderData = standIn !== null && standIn.length > 0;\n\n const indexByThread = live?.indexByThread;\n const applyOverrides = live?.applyOverrides;\n const rows = useMemo(() => {\n if (!indexByThread || !applyOverrides) return EMPTY_ROWS;\n const folded: ConversationSummary[] = applyOverrides(\n foldConversationIndex(source, indexByThread),\n ).filter((row) => matchesSessionsQuery(row, plan.local));\n return sortSessions(folded, plan.local).map(threadSummaryFromConversation);\n }, [source, indexByThread, applyOverrides, plan.local]);\n\n // A thread the index knows that this list does not show yet refreshes the\n // list — it may be new, or may have just come to match. Once per VERSION of\n // the entry (its id and `updated_at`): an unchanged entry the server keeps\n // leaving out never refreshes twice, and a later change to it (a PR opened,\n // a run now needing input) gets its own refresh. Coalesced, held while the\n // list is already being read, and a refused refresh is tried again\n // (`useIndexTriggeredRefresh`).\n const indexEntries = live?.indexEntries ?? null;\n const listRefresh = list.refresh;\n const baseAppId = baseFilter.appId;\n const baseAppIds = baseFilter.appIds;\n const baseHomeAgentId = baseFilter.homeAgentId;\n const homeAgentApplied = list.homeAgentApplied;\n const listedThreadIds = useMemo(\n () => new Set(list.conversations.map((conversation) => conversation.threadId)),\n [list.conversations],\n );\n const unlistedVersions = useMemo(\n () =>\n indexEntries === null\n ? []\n : indexEntryVersionsToRefresh({\n entries: indexEntries,\n listedThreadIds,\n refreshedVersions: EMPTY_VERSIONS,\n appId: baseAppId,\n additionalAppIds: baseAppIds ?? [],\n homeAgentId: baseHomeAgentId,\n homeAgentApplied,\n query: plan.local,\n }),\n [\n indexEntries,\n listedThreadIds,\n baseAppId,\n baseAppIds,\n baseHomeAgentId,\n homeAgentApplied,\n plan.local,\n ],\n );\n useIndexTriggeredRefresh({\n pending: unlistedVersions,\n refresh: listRefresh,\n // Held while the list is being read; a refused first page does not hold\n // it (the refresh is how the list recovers).\n enabled: active && capabilitiesSettled && indexEntries !== null && !list.isFetching,\n tabShare: live?.tabShare,\n shareKey: sessionListShareKey(\n conversationListQueryKeys.firstPage(\n listScopeKey,\n conversationListFilterKey(baseFilter),\n pageSize,\n ),\n ),\n });\n\n const listFetchNextPage = list.fetchNextPage;\n return {\n rows: isAvailable ? rows : EMPTY_ROWS,\n isAvailable,\n isLoading: active && (!capabilitiesSettled || list.isLoading),\n isFetching: list.isFetching || capabilities.isFetching,\n hasResolvedFirstPage: list.hasResolvedFirstPage,\n firstPageUpdatedAt: isAvailable ? list.firstPageUpdatedAt : 0,\n isPlaceholderData,\n hasNextPage: list.hasNextPage,\n isFetchingNextPage: list.isFetchingNextPage,\n fetchNextPage: isAvailable ? () => void listFetchNextPage() : NOOP,\n refresh: isAvailable ? async () => void (await listRefresh()) : NOOP_ASYNC,\n isFetchNextPageError: list.isFetchNextPageError,\n supportedFilters,\n degradedFields: plan.degraded,\n unavailableFields: plan.unavailable,\n unsupportedFields,\n };\n}\n\ntype IndexEntryLike = Parameters<typeof entryCouldMatch>[0] & {\n thread_id: string;\n updated_at: string;\n app_id: string | null;\n collab_agent_id?: string | null;\n start_channel?: string | null;\n};\n\n/**\n * The index entries that warrant one refresh of a filtered list, as\n * `<thread_id>@<updated_at>` versions: entries the list does not show, of\n * the apps it lists (and, while `homeAgentApplied`, of the conversations with\n * `homeAgentId`'s agent; see `indexedThreadsToRefreshFor`), that the query\n * could match on what the entry carries, and whose version has not prompted a\n * refresh before. An unchanged entry the server keeps leaving out refreshes\n * once; any later change to it refreshes again. Exported for tests.\n */\nexport function indexEntryVersionsToRefresh({\n entries,\n listedThreadIds,\n refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n query,\n}: {\n entries: readonly IndexEntryLike[];\n listedThreadIds: ReadonlySet<string>;\n refreshedVersions: ReadonlySet<string>;\n appId: string | undefined;\n additionalAppIds: readonly string[];\n homeAgentId?: string;\n homeAgentApplied?: boolean;\n query: AthenaSessionsQuery;\n}): string[] {\n const versionOf = (entry: IndexEntryLike) => `${entry.thread_id}@${entry.updated_at}`;\n const byVersion = new Map(entries.map((entry) => [versionOf(entry), entry]));\n return indexedThreadsToRefreshFor({\n entries: entries.map((entry) => ({\n thread_id: versionOf(entry),\n app_id: entry.app_id,\n collab_agent_id: entry.collab_agent_id,\n start_channel: entry.start_channel,\n })),\n listedThreadIds: new Set(\n entries.filter((entry) => listedThreadIds.has(entry.thread_id)).map(versionOf),\n ),\n refreshedThreadIds: refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n }).filter((version) => {\n const entry = byVersion.get(version);\n return entry === undefined || entryCouldMatch(entry, query);\n });\n}\n\n/**\n * Whether a pushed index entry could belong to a list with this local query:\n * the fields the entry carries are checked, the rest pass.\n */\nexport function entryCouldMatch(\n entry: {\n is_unread?: boolean | null;\n is_favorited?: boolean | null;\n run_status?: string | null;\n session_status?: string | null;\n },\n query: AthenaSessionsQuery,\n): boolean {\n if (query.unreadOnly && entry.is_unread === false) return false;\n if (query.favoritesOnly && entry.is_favorited === false) return false;\n if (\n query.runStatuses &&\n typeof entry.run_status === 'string' &&\n !(query.runStatuses as readonly string[]).includes(entry.run_status)\n ) {\n return false;\n }\n if (\n query.sessionStatuses &&\n typeof entry.session_status === 'string' &&\n !(query.sessionStatuses as readonly string[]).includes(entry.session_status)\n ) {\n return false;\n }\n return true;\n}\n"],"names":["useContext","AthenaSessionsLiveContext","useAthenaQueryClient","useQuery","withCredentialRenewal","listThreads","supportedFiltersFromResponse","sessionsQueryKey","useMemo","planSessionsQuery","sessionsQueryFromKey","useRef","unavailableSessionsQueryFields","createRestConversationListFetcher","matchesSessionsQuery","useConversationList","conversationListFilterKey","foldConversationIndex","sortSessions","threadSummaryFromConversation","useIndexTriggeredRefresh","sessionListShareKey","conversationListQueryKeys","indexedThreadsToRefreshFor"],"mappings":"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"}
@@ -17,6 +17,13 @@ export interface AthenaSessionsList {
17
17
  isLoading: boolean;
18
18
  isFetching: boolean;
19
19
  hasResolvedFirstPage: boolean;
20
+ /**
21
+ * When this query's first page was last written (ms since the epoch; 0 before it has any). A
22
+ * first page restored from the copy kept on this device (`offlineList`) carries that copy's
23
+ * old stamp until agora answers, and a refresh that fails leaves it as it was: compare it with
24
+ * a mount time to act only on what agora said since.
25
+ */
26
+ firstPageUpdatedAt: number;
20
27
  /**
21
28
  * True while the rows are the previous query's (checked against this
22
29
  * query's local part) because this query's first page is still in flight.
@@ -166,6 +166,7 @@ function useAthenaSessions({
166
166
  isLoading: active && (!capabilitiesSettled || list.isLoading),
167
167
  isFetching: list.isFetching || capabilities.isFetching,
168
168
  hasResolvedFirstPage: list.hasResolvedFirstPage,
169
+ firstPageUpdatedAt: isAvailable ? list.firstPageUpdatedAt : 0,
169
170
  isPlaceholderData,
170
171
  hasNextPage: list.hasNextPage,
171
172
  isFetchingNextPage: list.isFetchingNextPage,
@@ -1 +1 @@
1
- {"version":3,"file":"use-athena-sessions.js","sources":["../../src/threads/use-athena-sessions.ts"],"sourcesContent":["/**\n * `useAthenaSessions(query)` — one filtered, sorted, live session list under\n * `<AthenaProvider enableThreadList>`: the data layer of `SessionsPage` and\n * `Inbox`, for hosts drawing their own.\n *\n * - **Server-side.** The query travels to `POST /api/conversations/threads/list`\n * as filters of the server's one page statement (`planSessionsQuery`), over\n * the shared two-tier pager (`useConversationList`: a live first page and\n * frozen history pages) in the thread-list provider's query client.\n * - **Live.** Rows fold the same conversation-index pushes the sidebar folds\n * (titles, lifecycle, attention flip in place), carry the provider's\n * in-flight writes (pin, rename, read state, archive), and a thread the\n * index learns about that the list does not show yet refreshes the list\n * once.\n * - **Degraded, not wrong.** A server that cannot apply part of the query is\n * detected from its `supported_filters` echo (one `limit: 1` probe per\n * identity). Fields the loaded rows can be tested on are applied to them\n * (`degradedFields`: exact per page, a page can come back short); fields\n * they cannot are reported in `unavailableFields` and not applied, so a\n * control for them can be disabled rather than lie.\n */\nimport {\n type ConversationListFilter,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n useConversationList,\n} from '@athenaintel/agent-runtime';\nimport { useQuery } from '@tanstack/react-query';\nimport { useContext, useMemo, useRef } from 'react';\nimport { useAthenaQueryClient } from '../lib/use-athena-rest-query';\nimport { withCredentialRenewal } from '../runtime/credential-renewal';\nimport { listThreads } from './api';\nimport { createRestConversationListFetcher } from './conversation-list-fetcher';\nimport { useIndexTriggeredRefresh } from './index-triggered-refresh';\nimport { sessionListShareKey } from './session-list-tab-share';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n matchesSessionsQuery,\n planSessionsQuery,\n sessionsQueryFromKey,\n sessionsQueryKey,\n sortSessions,\n supportedFiltersFromResponse,\n unavailableSessionsQueryFields,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadSummary,\n foldConversationIndex,\n indexedThreadsToRefreshFor,\n threadSummaryFromConversation,\n} from './statewire-thread-list';\n\nexport interface UseAthenaSessionsOptions {\n /** What to list. A new object with the same content does not refetch. */\n query: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** `false` holds the list idle. Default `true`. */\n enabled?: boolean;\n}\n\nexport interface AthenaSessionsList {\n /** The rows, in the query's order, with live pushes and in-flight writes applied. */\n rows: AthenaStatewireThreadSummary[];\n /** `false` outside `enableThreadList` mode: nothing is fetched and `rows` stays empty. */\n isAvailable: boolean;\n /** True until the first page has answered (or while no credential has resolved). */\n isLoading: boolean;\n isFetching: boolean;\n hasResolvedFirstPage: boolean;\n /**\n * True while the rows are the previous query's (checked against this\n * query's local part) because this query's first page is still in flight.\n */\n isPlaceholderData: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n /** Refetch the first page; resolves once it has answered. */\n refresh: () => Promise<void>;\n /** True while the last \"load more\" request failed. */\n isFetchNextPageError: boolean;\n /**\n * The server fields this backend applies (`supported_filters`), `null`\n * while unknown or on a backend that predates the list.\n */\n supportedFilters: ReadonlySet<string> | null;\n /** Fields applied to the loaded rows because the backend cannot. */\n degradedFields: AthenaSessionsQueryField[];\n /** Fields of this query that cannot be applied on this backend at all (and are not). */\n unavailableFields: AthenaSessionsQueryField[];\n /**\n * Every field this backend cannot apply anywhere, selected or not — what a\n * filter UI disables. Empty until the capabilities probe has answered.\n */\n unsupportedFields: AthenaSessionsQueryField[];\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\n/** The capabilities probe's key prefix. */\nexport const THREAD_LIST_CAPABILITIES_QUERY_KEY = [\n 'athena-sdk',\n 'thread-list-capabilities',\n] as const;\n\nconst EMPTY_ROWS: AthenaStatewireThreadSummary[] = [];\nconst EMPTY_VERSIONS: ReadonlySet<string> = new Set();\nconst NOOP = () => undefined;\nconst NOOP_ASYNC = async () => undefined;\n\nexport function useAthenaSessions({\n query,\n pageSize = DEFAULT_PAGE_SIZE,\n enabled = true,\n}: UseAthenaSessionsOptions): AthenaSessionsList {\n const live = useContext(AthenaSessionsLiveContext);\n const isAvailable = live !== null;\n const backendUrl = live?.backendUrl ?? '';\n const principal = live?.principal ?? '';\n const hasAuth = live?.hasAuth ?? false;\n const includePullRequests = live?.includePullRequests ?? false;\n const getAuth = live?.getAuth;\n const active = isAvailable && enabled && hasAuth;\n // Every cache below is keyed by WHO reads (principal) and WITH WHAT (the\n // credential generation): a scoped credential for another workspace under\n // the same principal must never read this one's cached rows.\n const identityScope = `${live?.scopeKey ?? 'unavailable'}::credential-${\n live?.credentialGeneration ?? 0\n }`;\n\n // Outside thread-list mode there may be no `QueryClientProvider`; every\n // query below is disabled there, on a client of this hook's own.\n const queryClient = useAthenaQueryClient();\n\n // Which filters this backend applies: one tiny page per identity. The\n // answer is a property of the deployed agora, so it never goes stale.\n const capabilities = useQuery(\n {\n queryKey: [\n ...THREAD_LIST_CAPABILITIES_QUERY_KEY,\n backendUrl,\n principal,\n live?.credentialGeneration ?? 0,\n ],\n queryFn: async ({ signal }) => {\n if (!getAuth) return null;\n const response = await withCredentialRenewal(getAuth, (auth) =>\n listThreads(backendUrl, auth, { limit: 1, signal }),\n );\n return supportedFiltersFromResponse(response.supported_filters);\n },\n enabled: active,\n staleTime: Number.POSITIVE_INFINITY,\n retry: 1,\n },\n queryClient,\n );\n // A failed probe is treated as an older backend: the query degrades\n // instead of the list staying empty.\n const capabilitiesSettled = capabilities.isSuccess || capabilities.isError;\n const supportedFilters = capabilities.data ?? null;\n\n // `query` may be a fresh object every render; its normalized key is what\n // identifies it, so the plan is built from the key and recomputed only\n // when the content changes.\n const queryKey = sessionsQueryKey(query);\n const plan = useMemo(\n () =>\n planSessionsQuery(sessionsQueryFromKey(queryKey), {\n supportedFilters,\n includePullRequests,\n }),\n [queryKey, supportedFilters, includePullRequests],\n );\n const planRef = useRef(plan);\n planRef.current = plan;\n const unsupportedFields = useMemo(\n () =>\n capabilitiesSettled\n ? unavailableSessionsQueryFields({ supportedFilters, includePullRequests })\n : [],\n [capabilitiesSettled, supportedFilters, includePullRequests],\n );\n\n const fetchPage = useMemo(\n () =>\n getAuth\n ? createRestConversationListFetcher({\n backendUrl,\n getAuth,\n includePullRequests,\n extraFilters: plan.body,\n keepRow: (row) => matchesSessionsQuery(row, planRef.current.local),\n })\n : async () => ({ items: [], hasMore: false, totalCount: null }),\n [backendUrl, getAuth, includePullRequests, plan.body],\n );\n const baseFilter: ConversationListFilter = live?.baseFilter ?? {};\n const capabilityKey = supportedFilters ? [...supportedFilters].sort().join(',') : 'legacy';\n // The query's server filters are not part of the shared filter contract,\n // so they — and what this backend applies of them — key the cache here.\n const listScopeKey = `${identityScope}::sessions::${queryKey}::${capabilityKey}`;\n const list = useConversationList({\n fetchPage,\n filter: baseFilter,\n pageSize,\n scopeKey: listScopeKey,\n enabled: active && capabilitiesSettled,\n queryClient,\n });\n\n // While a changed query's first page is in flight, the previous query's\n // rows stand in, checked against the new query's local part — the list\n // narrows at once instead of blanking to skeletons. Only rows read as the\n // same identity and credential, over the same app scope, ever stand in: a\n // changed scope (another app, or the home agent's conversations turned off)\n // cannot be narrowed on the rows.\n const standInScope = `${identityScope}::${conversationListFilterKey(baseFilter)}`;\n const lastResolvedRef = useRef<{ scope: string; conversations: ConversationSummary[] }>({\n scope: '',\n conversations: [],\n });\n if (list.hasResolvedFirstPage) {\n lastResolvedRef.current = { scope: standInScope, conversations: list.conversations };\n }\n const standIn =\n !list.hasResolvedFirstPage && lastResolvedRef.current.scope === standInScope\n ? lastResolvedRef.current.conversations\n : null;\n const source = standIn ?? list.conversations;\n const isPlaceholderData = standIn !== null && standIn.length > 0;\n\n const indexByThread = live?.indexByThread;\n const applyOverrides = live?.applyOverrides;\n const rows = useMemo(() => {\n if (!indexByThread || !applyOverrides) return EMPTY_ROWS;\n const folded: ConversationSummary[] = applyOverrides(\n foldConversationIndex(source, indexByThread),\n ).filter((row) => matchesSessionsQuery(row, plan.local));\n return sortSessions(folded, plan.local).map(threadSummaryFromConversation);\n }, [source, indexByThread, applyOverrides, plan.local]);\n\n // A thread the index knows that this list does not show yet refreshes the\n // list — it may be new, or may have just come to match. Once per VERSION of\n // the entry (its id and `updated_at`): an unchanged entry the server keeps\n // leaving out never refreshes twice, and a later change to it (a PR opened,\n // a run now needing input) gets its own refresh. Coalesced, held while the\n // list is already being read, and a refused refresh is tried again\n // (`useIndexTriggeredRefresh`).\n const indexEntries = live?.indexEntries ?? null;\n const listRefresh = list.refresh;\n const baseAppId = baseFilter.appId;\n const baseAppIds = baseFilter.appIds;\n const baseHomeAgentId = baseFilter.homeAgentId;\n const homeAgentApplied = list.homeAgentApplied;\n const listedThreadIds = useMemo(\n () => new Set(list.conversations.map((conversation) => conversation.threadId)),\n [list.conversations],\n );\n const unlistedVersions = useMemo(\n () =>\n indexEntries === null\n ? []\n : indexEntryVersionsToRefresh({\n entries: indexEntries,\n listedThreadIds,\n refreshedVersions: EMPTY_VERSIONS,\n appId: baseAppId,\n additionalAppIds: baseAppIds ?? [],\n homeAgentId: baseHomeAgentId,\n homeAgentApplied,\n query: plan.local,\n }),\n [\n indexEntries,\n listedThreadIds,\n baseAppId,\n baseAppIds,\n baseHomeAgentId,\n homeAgentApplied,\n plan.local,\n ],\n );\n useIndexTriggeredRefresh({\n pending: unlistedVersions,\n refresh: listRefresh,\n // Held while the list is being read; a refused first page does not hold\n // it (the refresh is how the list recovers).\n enabled: active && capabilitiesSettled && indexEntries !== null && !list.isFetching,\n tabShare: live?.tabShare,\n shareKey: sessionListShareKey(\n conversationListQueryKeys.firstPage(\n listScopeKey,\n conversationListFilterKey(baseFilter),\n pageSize,\n ),\n ),\n });\n\n const listFetchNextPage = list.fetchNextPage;\n return {\n rows: isAvailable ? rows : EMPTY_ROWS,\n isAvailable,\n isLoading: active && (!capabilitiesSettled || list.isLoading),\n isFetching: list.isFetching || capabilities.isFetching,\n hasResolvedFirstPage: list.hasResolvedFirstPage,\n isPlaceholderData,\n hasNextPage: list.hasNextPage,\n isFetchingNextPage: list.isFetchingNextPage,\n fetchNextPage: isAvailable ? () => void listFetchNextPage() : NOOP,\n refresh: isAvailable ? async () => void (await listRefresh()) : NOOP_ASYNC,\n isFetchNextPageError: list.isFetchNextPageError,\n supportedFilters,\n degradedFields: plan.degraded,\n unavailableFields: plan.unavailable,\n unsupportedFields,\n };\n}\n\ntype IndexEntryLike = Parameters<typeof entryCouldMatch>[0] & {\n thread_id: string;\n updated_at: string;\n app_id: string | null;\n collab_agent_id?: string | null;\n start_channel?: string | null;\n};\n\n/**\n * The index entries that warrant one refresh of a filtered list, as\n * `<thread_id>@<updated_at>` versions: entries the list does not show, of\n * the apps it lists (and, while `homeAgentApplied`, of the conversations with\n * `homeAgentId`'s agent; see `indexedThreadsToRefreshFor`), that the query\n * could match on what the entry carries, and whose version has not prompted a\n * refresh before. An unchanged entry the server keeps leaving out refreshes\n * once; any later change to it refreshes again. Exported for tests.\n */\nexport function indexEntryVersionsToRefresh({\n entries,\n listedThreadIds,\n refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n query,\n}: {\n entries: readonly IndexEntryLike[];\n listedThreadIds: ReadonlySet<string>;\n refreshedVersions: ReadonlySet<string>;\n appId: string | undefined;\n additionalAppIds: readonly string[];\n homeAgentId?: string;\n homeAgentApplied?: boolean;\n query: AthenaSessionsQuery;\n}): string[] {\n const versionOf = (entry: IndexEntryLike) => `${entry.thread_id}@${entry.updated_at}`;\n const byVersion = new Map(entries.map((entry) => [versionOf(entry), entry]));\n return indexedThreadsToRefreshFor({\n entries: entries.map((entry) => ({\n thread_id: versionOf(entry),\n app_id: entry.app_id,\n collab_agent_id: entry.collab_agent_id,\n start_channel: entry.start_channel,\n })),\n listedThreadIds: new Set(\n entries.filter((entry) => listedThreadIds.has(entry.thread_id)).map(versionOf),\n ),\n refreshedThreadIds: refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n }).filter((version) => {\n const entry = byVersion.get(version);\n return entry === undefined || entryCouldMatch(entry, query);\n });\n}\n\n/**\n * Whether a pushed index entry could belong to a list with this local query:\n * the fields the entry carries are checked, the rest pass.\n */\nexport function entryCouldMatch(\n entry: {\n is_unread?: boolean | null;\n is_favorited?: boolean | null;\n run_status?: string | null;\n session_status?: string | null;\n },\n query: AthenaSessionsQuery,\n): boolean {\n if (query.unreadOnly && entry.is_unread === false) return false;\n if (query.favoritesOnly && entry.is_favorited === false) return false;\n if (\n query.runStatuses &&\n typeof entry.run_status === 'string' &&\n !(query.runStatuses as readonly string[]).includes(entry.run_status)\n ) {\n return false;\n }\n if (\n query.sessionStatuses &&\n typeof entry.session_status === 'string' &&\n !(query.sessionStatuses as readonly string[]).includes(entry.session_status)\n ) {\n return false;\n }\n return true;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-athena-sessions.js","sources":["../../src/threads/use-athena-sessions.ts"],"sourcesContent":["/**\n * `useAthenaSessions(query)` — one filtered, sorted, live session list under\n * `<AthenaProvider enableThreadList>`: the data layer of `SessionsPage` and\n * `Inbox`, for hosts drawing their own.\n *\n * - **Server-side.** The query travels to `POST /api/conversations/threads/list`\n * as filters of the server's one page statement (`planSessionsQuery`), over\n * the shared two-tier pager (`useConversationList`: a live first page and\n * frozen history pages) in the thread-list provider's query client.\n * - **Live.** Rows fold the same conversation-index pushes the sidebar folds\n * (titles, lifecycle, attention flip in place), carry the provider's\n * in-flight writes (pin, rename, read state, archive), and a thread the\n * index learns about that the list does not show yet refreshes the list\n * once.\n * - **Degraded, not wrong.** A server that cannot apply part of the query is\n * detected from its `supported_filters` echo (one `limit: 1` probe per\n * identity). Fields the loaded rows can be tested on are applied to them\n * (`degradedFields`: exact per page, a page can come back short); fields\n * they cannot are reported in `unavailableFields` and not applied, so a\n * control for them can be disabled rather than lie.\n */\nimport {\n type ConversationListFilter,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n useConversationList,\n} from '@athenaintel/agent-runtime';\nimport { useQuery } from '@tanstack/react-query';\nimport { useContext, useMemo, useRef } from 'react';\nimport { useAthenaQueryClient } from '../lib/use-athena-rest-query';\nimport { withCredentialRenewal } from '../runtime/credential-renewal';\nimport { listThreads } from './api';\nimport { createRestConversationListFetcher } from './conversation-list-fetcher';\nimport { useIndexTriggeredRefresh } from './index-triggered-refresh';\nimport { sessionListShareKey } from './session-list-tab-share';\nimport {\n type AthenaSessionsQuery,\n type AthenaSessionsQueryField,\n matchesSessionsQuery,\n planSessionsQuery,\n sessionsQueryFromKey,\n sessionsQueryKey,\n sortSessions,\n supportedFiltersFromResponse,\n unavailableSessionsQueryFields,\n} from './sessions-query';\nimport {\n AthenaSessionsLiveContext,\n type AthenaStatewireThreadSummary,\n foldConversationIndex,\n indexedThreadsToRefreshFor,\n threadSummaryFromConversation,\n} from './statewire-thread-list';\n\nexport interface UseAthenaSessionsOptions {\n /** What to list. A new object with the same content does not refetch. */\n query: AthenaSessionsQuery;\n /** Rows per page (default 50). */\n pageSize?: number;\n /** `false` holds the list idle. Default `true`. */\n enabled?: boolean;\n}\n\nexport interface AthenaSessionsList {\n /** The rows, in the query's order, with live pushes and in-flight writes applied. */\n rows: AthenaStatewireThreadSummary[];\n /** `false` outside `enableThreadList` mode: nothing is fetched and `rows` stays empty. */\n isAvailable: boolean;\n /** True until the first page has answered (or while no credential has resolved). */\n isLoading: boolean;\n isFetching: boolean;\n hasResolvedFirstPage: boolean;\n /**\n * When this query's first page was last written (ms since the epoch; 0 before it has any). A\n * first page restored from the copy kept on this device (`offlineList`) carries that copy's\n * old stamp until agora answers, and a refresh that fails leaves it as it was: compare it with\n * a mount time to act only on what agora said since.\n */\n firstPageUpdatedAt: number;\n /**\n * True while the rows are the previous query's (checked against this\n * query's local part) because this query's first page is still in flight.\n */\n isPlaceholderData: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n /** Refetch the first page; resolves once it has answered. */\n refresh: () => Promise<void>;\n /** True while the last \"load more\" request failed. */\n isFetchNextPageError: boolean;\n /**\n * The server fields this backend applies (`supported_filters`), `null`\n * while unknown or on a backend that predates the list.\n */\n supportedFilters: ReadonlySet<string> | null;\n /** Fields applied to the loaded rows because the backend cannot. */\n degradedFields: AthenaSessionsQueryField[];\n /** Fields of this query that cannot be applied on this backend at all (and are not). */\n unavailableFields: AthenaSessionsQueryField[];\n /**\n * Every field this backend cannot apply anywhere, selected or not — what a\n * filter UI disables. Empty until the capabilities probe has answered.\n */\n unsupportedFields: AthenaSessionsQueryField[];\n}\n\nconst DEFAULT_PAGE_SIZE = 50;\n\n/** The capabilities probe's key prefix. */\nexport const THREAD_LIST_CAPABILITIES_QUERY_KEY = [\n 'athena-sdk',\n 'thread-list-capabilities',\n] as const;\n\nconst EMPTY_ROWS: AthenaStatewireThreadSummary[] = [];\nconst EMPTY_VERSIONS: ReadonlySet<string> = new Set();\nconst NOOP = () => undefined;\nconst NOOP_ASYNC = async () => undefined;\n\nexport function useAthenaSessions({\n query,\n pageSize = DEFAULT_PAGE_SIZE,\n enabled = true,\n}: UseAthenaSessionsOptions): AthenaSessionsList {\n const live = useContext(AthenaSessionsLiveContext);\n const isAvailable = live !== null;\n const backendUrl = live?.backendUrl ?? '';\n const principal = live?.principal ?? '';\n const hasAuth = live?.hasAuth ?? false;\n const includePullRequests = live?.includePullRequests ?? false;\n const getAuth = live?.getAuth;\n const active = isAvailable && enabled && hasAuth;\n // Every cache below is keyed by WHO reads (principal) and WITH WHAT (the\n // credential generation): a scoped credential for another workspace under\n // the same principal must never read this one's cached rows.\n const identityScope = `${live?.scopeKey ?? 'unavailable'}::credential-${\n live?.credentialGeneration ?? 0\n }`;\n\n // Outside thread-list mode there may be no `QueryClientProvider`; every\n // query below is disabled there, on a client of this hook's own.\n const queryClient = useAthenaQueryClient();\n\n // Which filters this backend applies: one tiny page per identity. The\n // answer is a property of the deployed agora, so it never goes stale.\n const capabilities = useQuery(\n {\n queryKey: [\n ...THREAD_LIST_CAPABILITIES_QUERY_KEY,\n backendUrl,\n principal,\n live?.credentialGeneration ?? 0,\n ],\n queryFn: async ({ signal }) => {\n if (!getAuth) return null;\n const response = await withCredentialRenewal(getAuth, (auth) =>\n listThreads(backendUrl, auth, { limit: 1, signal }),\n );\n return supportedFiltersFromResponse(response.supported_filters);\n },\n enabled: active,\n staleTime: Number.POSITIVE_INFINITY,\n retry: 1,\n },\n queryClient,\n );\n // A failed probe is treated as an older backend: the query degrades\n // instead of the list staying empty.\n const capabilitiesSettled = capabilities.isSuccess || capabilities.isError;\n const supportedFilters = capabilities.data ?? null;\n\n // `query` may be a fresh object every render; its normalized key is what\n // identifies it, so the plan is built from the key and recomputed only\n // when the content changes.\n const queryKey = sessionsQueryKey(query);\n const plan = useMemo(\n () =>\n planSessionsQuery(sessionsQueryFromKey(queryKey), {\n supportedFilters,\n includePullRequests,\n }),\n [queryKey, supportedFilters, includePullRequests],\n );\n const planRef = useRef(plan);\n planRef.current = plan;\n const unsupportedFields = useMemo(\n () =>\n capabilitiesSettled\n ? unavailableSessionsQueryFields({ supportedFilters, includePullRequests })\n : [],\n [capabilitiesSettled, supportedFilters, includePullRequests],\n );\n\n const fetchPage = useMemo(\n () =>\n getAuth\n ? createRestConversationListFetcher({\n backendUrl,\n getAuth,\n includePullRequests,\n extraFilters: plan.body,\n keepRow: (row) => matchesSessionsQuery(row, planRef.current.local),\n })\n : async () => ({ items: [], hasMore: false, totalCount: null }),\n [backendUrl, getAuth, includePullRequests, plan.body],\n );\n const baseFilter: ConversationListFilter = live?.baseFilter ?? {};\n const capabilityKey = supportedFilters ? [...supportedFilters].sort().join(',') : 'legacy';\n // The query's server filters are not part of the shared filter contract,\n // so they — and what this backend applies of them — key the cache here.\n const listScopeKey = `${identityScope}::sessions::${queryKey}::${capabilityKey}`;\n const list = useConversationList({\n fetchPage,\n filter: baseFilter,\n pageSize,\n scopeKey: listScopeKey,\n enabled: active && capabilitiesSettled,\n queryClient,\n });\n\n // While a changed query's first page is in flight, the previous query's\n // rows stand in, checked against the new query's local part — the list\n // narrows at once instead of blanking to skeletons. Only rows read as the\n // same identity and credential, over the same app scope, ever stand in: a\n // changed scope (another app, or the home agent's conversations turned off)\n // cannot be narrowed on the rows.\n const standInScope = `${identityScope}::${conversationListFilterKey(baseFilter)}`;\n const lastResolvedRef = useRef<{ scope: string; conversations: ConversationSummary[] }>({\n scope: '',\n conversations: [],\n });\n if (list.hasResolvedFirstPage) {\n lastResolvedRef.current = { scope: standInScope, conversations: list.conversations };\n }\n const standIn =\n !list.hasResolvedFirstPage && lastResolvedRef.current.scope === standInScope\n ? lastResolvedRef.current.conversations\n : null;\n const source = standIn ?? list.conversations;\n const isPlaceholderData = standIn !== null && standIn.length > 0;\n\n const indexByThread = live?.indexByThread;\n const applyOverrides = live?.applyOverrides;\n const rows = useMemo(() => {\n if (!indexByThread || !applyOverrides) return EMPTY_ROWS;\n const folded: ConversationSummary[] = applyOverrides(\n foldConversationIndex(source, indexByThread),\n ).filter((row) => matchesSessionsQuery(row, plan.local));\n return sortSessions(folded, plan.local).map(threadSummaryFromConversation);\n }, [source, indexByThread, applyOverrides, plan.local]);\n\n // A thread the index knows that this list does not show yet refreshes the\n // list — it may be new, or may have just come to match. Once per VERSION of\n // the entry (its id and `updated_at`): an unchanged entry the server keeps\n // leaving out never refreshes twice, and a later change to it (a PR opened,\n // a run now needing input) gets its own refresh. Coalesced, held while the\n // list is already being read, and a refused refresh is tried again\n // (`useIndexTriggeredRefresh`).\n const indexEntries = live?.indexEntries ?? null;\n const listRefresh = list.refresh;\n const baseAppId = baseFilter.appId;\n const baseAppIds = baseFilter.appIds;\n const baseHomeAgentId = baseFilter.homeAgentId;\n const homeAgentApplied = list.homeAgentApplied;\n const listedThreadIds = useMemo(\n () => new Set(list.conversations.map((conversation) => conversation.threadId)),\n [list.conversations],\n );\n const unlistedVersions = useMemo(\n () =>\n indexEntries === null\n ? []\n : indexEntryVersionsToRefresh({\n entries: indexEntries,\n listedThreadIds,\n refreshedVersions: EMPTY_VERSIONS,\n appId: baseAppId,\n additionalAppIds: baseAppIds ?? [],\n homeAgentId: baseHomeAgentId,\n homeAgentApplied,\n query: plan.local,\n }),\n [\n indexEntries,\n listedThreadIds,\n baseAppId,\n baseAppIds,\n baseHomeAgentId,\n homeAgentApplied,\n plan.local,\n ],\n );\n useIndexTriggeredRefresh({\n pending: unlistedVersions,\n refresh: listRefresh,\n // Held while the list is being read; a refused first page does not hold\n // it (the refresh is how the list recovers).\n enabled: active && capabilitiesSettled && indexEntries !== null && !list.isFetching,\n tabShare: live?.tabShare,\n shareKey: sessionListShareKey(\n conversationListQueryKeys.firstPage(\n listScopeKey,\n conversationListFilterKey(baseFilter),\n pageSize,\n ),\n ),\n });\n\n const listFetchNextPage = list.fetchNextPage;\n return {\n rows: isAvailable ? rows : EMPTY_ROWS,\n isAvailable,\n isLoading: active && (!capabilitiesSettled || list.isLoading),\n isFetching: list.isFetching || capabilities.isFetching,\n hasResolvedFirstPage: list.hasResolvedFirstPage,\n firstPageUpdatedAt: isAvailable ? list.firstPageUpdatedAt : 0,\n isPlaceholderData,\n hasNextPage: list.hasNextPage,\n isFetchingNextPage: list.isFetchingNextPage,\n fetchNextPage: isAvailable ? () => void listFetchNextPage() : NOOP,\n refresh: isAvailable ? async () => void (await listRefresh()) : NOOP_ASYNC,\n isFetchNextPageError: list.isFetchNextPageError,\n supportedFilters,\n degradedFields: plan.degraded,\n unavailableFields: plan.unavailable,\n unsupportedFields,\n };\n}\n\ntype IndexEntryLike = Parameters<typeof entryCouldMatch>[0] & {\n thread_id: string;\n updated_at: string;\n app_id: string | null;\n collab_agent_id?: string | null;\n start_channel?: string | null;\n};\n\n/**\n * The index entries that warrant one refresh of a filtered list, as\n * `<thread_id>@<updated_at>` versions: entries the list does not show, of\n * the apps it lists (and, while `homeAgentApplied`, of the conversations with\n * `homeAgentId`'s agent; see `indexedThreadsToRefreshFor`), that the query\n * could match on what the entry carries, and whose version has not prompted a\n * refresh before. An unchanged entry the server keeps leaving out refreshes\n * once; any later change to it refreshes again. Exported for tests.\n */\nexport function indexEntryVersionsToRefresh({\n entries,\n listedThreadIds,\n refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n query,\n}: {\n entries: readonly IndexEntryLike[];\n listedThreadIds: ReadonlySet<string>;\n refreshedVersions: ReadonlySet<string>;\n appId: string | undefined;\n additionalAppIds: readonly string[];\n homeAgentId?: string;\n homeAgentApplied?: boolean;\n query: AthenaSessionsQuery;\n}): string[] {\n const versionOf = (entry: IndexEntryLike) => `${entry.thread_id}@${entry.updated_at}`;\n const byVersion = new Map(entries.map((entry) => [versionOf(entry), entry]));\n return indexedThreadsToRefreshFor({\n entries: entries.map((entry) => ({\n thread_id: versionOf(entry),\n app_id: entry.app_id,\n collab_agent_id: entry.collab_agent_id,\n start_channel: entry.start_channel,\n })),\n listedThreadIds: new Set(\n entries.filter((entry) => listedThreadIds.has(entry.thread_id)).map(versionOf),\n ),\n refreshedThreadIds: refreshedVersions,\n appId,\n additionalAppIds,\n homeAgentId,\n homeAgentApplied,\n }).filter((version) => {\n const entry = byVersion.get(version);\n return entry === undefined || entryCouldMatch(entry, query);\n });\n}\n\n/**\n * Whether a pushed index entry could belong to a list with this local query:\n * the fields the entry carries are checked, the rest pass.\n */\nexport function entryCouldMatch(\n entry: {\n is_unread?: boolean | null;\n is_favorited?: boolean | null;\n run_status?: string | null;\n session_status?: string | null;\n },\n query: AthenaSessionsQuery,\n): boolean {\n if (query.unreadOnly && entry.is_unread === false) return false;\n if (query.favoritesOnly && entry.is_favorited === false) return false;\n if (\n query.runStatuses &&\n typeof entry.run_status === 'string' &&\n !(query.runStatuses as readonly string[]).includes(entry.run_status)\n ) {\n return false;\n }\n if (\n query.sessionStatuses &&\n typeof entry.session_status === 'string' &&\n !(query.sessionStatuses as readonly string[]).includes(entry.session_status)\n ) {\n return false;\n }\n return true;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require$$0 = require("react");
4
+ const agentModelOptions = require("../catalog/agent-model-options.cjs");
5
+ const statewireServerLaneContext = require("../runtime/statewire-server-lane-context.cjs");
6
+ function threadAgentFromLane({
7
+ lane,
8
+ ready
9
+ }) {
10
+ if (!ready || lane === null) return { agentId: null, configured: false, ready };
11
+ const value = lane.custom.collab_agent_id;
12
+ return {
13
+ agentId: typeof value === "string" ? agentModelOptions.agentAssetIdOf(value) : null,
14
+ configured: true,
15
+ ready
16
+ };
17
+ }
18
+ function useAthenaThreadAgent() {
19
+ const lane = require$$0.useContext(statewireServerLaneContext.AthenaStatewireServerLaneContext);
20
+ const agent = require$$0.useMemo(
21
+ () => lane === null ? null : threadAgentFromLane({ lane: lane.config, ready: lane.landed }),
22
+ [lane]
23
+ );
24
+ if (agent === null) {
25
+ throw new Error("[AthenaSDK] useAthenaThreadAgent must be used within <AthenaProvider>");
26
+ }
27
+ return agent;
28
+ }
29
+ exports.threadAgentFromLane = threadAgentFromLane;
30
+ exports.useAthenaThreadAgent = useAthenaThreadAgent;
31
+ //# sourceMappingURL=use-athena-thread-agent.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-thread-agent.cjs","sources":["../../src/threads/use-athena-thread-agent.ts"],"sourcesContent":["import type { DeepAgentServerConfig } from '@athenaintel/agent-runtime';\nimport { useContext, useMemo } from 'react';\nimport { agentAssetIdOf } from '../catalog/agent-model-options';\nimport { AthenaStatewireServerLaneContext } from '../runtime/statewire-server-lane-context';\n\n/**\n * The collab agent a thread runs as, read from its server config lane\n * (`state.config.custom.collab_agent_id`), plus whether there is a lane at all.\n */\nexport interface AthenaThreadAgent {\n /**\n * The collab agent's asset id, or `null` when the lane names none: the thread is the person's\n * own Athena assistant's.\n */\n agentId: string | null;\n /** `true` once the thread has a server config lane (version > 0). */\n configured: boolean;\n /**\n * `true` once the statewire host's snapshot of this thread has arrived. Before that `agentId` is\n * `null` and `configured` is `false` whatever the thread holds, so wait for `ready` before\n * treating \"no agent\" as an answer.\n */\n ready: boolean;\n}\n\n/** {@link AthenaThreadAgent} from the lane and the landed flag. Pure. */\nexport function threadAgentFromLane({\n lane,\n ready,\n}: {\n lane: DeepAgentServerConfig | null;\n ready: boolean;\n}): AthenaThreadAgent {\n if (!ready || lane === null) return { agentId: null, configured: false, ready };\n const value = lane.custom.collab_agent_id;\n return {\n agentId: typeof value === 'string' ? agentAssetIdOf(value) : null,\n configured: true,\n ready,\n };\n}\n\n/**\n * The collab agent the active thread runs as, from the thread's config lane as the statewire host\n * sent it.\n *\n * `collab_agent_id` is a key the lane owns: once a thread has run, every turn runs as the agent\n * the lane names, whatever the provider's `agent` prop says (the prop seeds a new thread's lane on\n * its first send and is dropped from later sends). Read this hook to show an open thread's real\n * agent: `{ agentId: null, configured: true }` is a thread of the person's own assistant. Wait for\n * `ready`; a never-started chat stays not ready until its first send attaches it.\n *\n * Must be used within `<AthenaProvider>`.\n */\nexport function useAthenaThreadAgent(): AthenaThreadAgent {\n const lane = useContext(AthenaStatewireServerLaneContext);\n const agent = useMemo(\n () => (lane === null ? null : threadAgentFromLane({ lane: lane.config, ready: lane.landed })),\n [lane],\n );\n if (agent === null) {\n throw new Error('[AthenaSDK] useAthenaThreadAgent must be used within <AthenaProvider>');\n }\n return agent;\n}\n"],"names":["agentAssetIdOf","useContext","AthenaStatewireServerLaneContext","useMemo"],"mappings":";;;;;AA0BO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGsB;AACpB,MAAI,CAAC,SAAS,SAAS,KAAM,QAAO,EAAE,SAAS,MAAM,YAAY,OAAO,MAAA;AACxE,QAAM,QAAQ,KAAK,OAAO;AAC1B,SAAO;AAAA,IACL,SAAS,OAAO,UAAU,WAAWA,kBAAAA,eAAe,KAAK,IAAI;AAAA,IAC7D,YAAY;AAAA,IACZ;AAAA,EAAA;AAEJ;AAcO,SAAS,uBAA0C;AACxD,QAAM,OAAOC,WAAAA,WAAWC,2DAAgC;AACxD,QAAM,QAAQC,WAAAA;AAAAA,IACZ,MAAO,SAAS,OAAO,OAAO,oBAAoB,EAAE,MAAM,KAAK,QAAQ,OAAO,KAAK,OAAA,CAAQ;AAAA,IAC3F,CAAC,IAAI;AAAA,EAAA;AAEP,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AACA,SAAO;AACT;;;"}
@@ -0,0 +1,38 @@
1
+ import type { DeepAgentServerConfig } from '../agent-runtime/src/index';
2
+ /**
3
+ * The collab agent a thread runs as, read from its server config lane
4
+ * (`state.config.custom.collab_agent_id`), plus whether there is a lane at all.
5
+ */
6
+ export interface AthenaThreadAgent {
7
+ /**
8
+ * The collab agent's asset id, or `null` when the lane names none: the thread is the person's
9
+ * own Athena assistant's.
10
+ */
11
+ agentId: string | null;
12
+ /** `true` once the thread has a server config lane (version > 0). */
13
+ configured: boolean;
14
+ /**
15
+ * `true` once the statewire host's snapshot of this thread has arrived. Before that `agentId` is
16
+ * `null` and `configured` is `false` whatever the thread holds, so wait for `ready` before
17
+ * treating "no agent" as an answer.
18
+ */
19
+ ready: boolean;
20
+ }
21
+ /** {@link AthenaThreadAgent} from the lane and the landed flag. Pure. */
22
+ export declare function threadAgentFromLane({ lane, ready, }: {
23
+ lane: DeepAgentServerConfig | null;
24
+ ready: boolean;
25
+ }): AthenaThreadAgent;
26
+ /**
27
+ * The collab agent the active thread runs as, from the thread's config lane as the statewire host
28
+ * sent it.
29
+ *
30
+ * `collab_agent_id` is a key the lane owns: once a thread has run, every turn runs as the agent
31
+ * the lane names, whatever the provider's `agent` prop says (the prop seeds a new thread's lane on
32
+ * its first send and is dropped from later sends). Read this hook to show an open thread's real
33
+ * agent: `{ agentId: null, configured: true }` is a thread of the person's own assistant. Wait for
34
+ * `ready`; a never-started chat stays not ready until its first send attaches it.
35
+ *
36
+ * Must be used within `<AthenaProvider>`.
37
+ */
38
+ export declare function useAthenaThreadAgent(): AthenaThreadAgent;
@@ -0,0 +1,31 @@
1
+ import { useContext, useMemo } from "react";
2
+ import { agentAssetIdOf } from "../catalog/agent-model-options.js";
3
+ import { AthenaStatewireServerLaneContext } from "../runtime/statewire-server-lane-context.js";
4
+ function threadAgentFromLane({
5
+ lane,
6
+ ready
7
+ }) {
8
+ if (!ready || lane === null) return { agentId: null, configured: false, ready };
9
+ const value = lane.custom.collab_agent_id;
10
+ return {
11
+ agentId: typeof value === "string" ? agentAssetIdOf(value) : null,
12
+ configured: true,
13
+ ready
14
+ };
15
+ }
16
+ function useAthenaThreadAgent() {
17
+ const lane = useContext(AthenaStatewireServerLaneContext);
18
+ const agent = useMemo(
19
+ () => lane === null ? null : threadAgentFromLane({ lane: lane.config, ready: lane.landed }),
20
+ [lane]
21
+ );
22
+ if (agent === null) {
23
+ throw new Error("[AthenaSDK] useAthenaThreadAgent must be used within <AthenaProvider>");
24
+ }
25
+ return agent;
26
+ }
27
+ export {
28
+ threadAgentFromLane,
29
+ useAthenaThreadAgent
30
+ };
31
+ //# sourceMappingURL=use-athena-thread-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-thread-agent.js","sources":["../../src/threads/use-athena-thread-agent.ts"],"sourcesContent":["import type { DeepAgentServerConfig } from '@athenaintel/agent-runtime';\nimport { useContext, useMemo } from 'react';\nimport { agentAssetIdOf } from '../catalog/agent-model-options';\nimport { AthenaStatewireServerLaneContext } from '../runtime/statewire-server-lane-context';\n\n/**\n * The collab agent a thread runs as, read from its server config lane\n * (`state.config.custom.collab_agent_id`), plus whether there is a lane at all.\n */\nexport interface AthenaThreadAgent {\n /**\n * The collab agent's asset id, or `null` when the lane names none: the thread is the person's\n * own Athena assistant's.\n */\n agentId: string | null;\n /** `true` once the thread has a server config lane (version > 0). */\n configured: boolean;\n /**\n * `true` once the statewire host's snapshot of this thread has arrived. Before that `agentId` is\n * `null` and `configured` is `false` whatever the thread holds, so wait for `ready` before\n * treating \"no agent\" as an answer.\n */\n ready: boolean;\n}\n\n/** {@link AthenaThreadAgent} from the lane and the landed flag. Pure. */\nexport function threadAgentFromLane({\n lane,\n ready,\n}: {\n lane: DeepAgentServerConfig | null;\n ready: boolean;\n}): AthenaThreadAgent {\n if (!ready || lane === null) return { agentId: null, configured: false, ready };\n const value = lane.custom.collab_agent_id;\n return {\n agentId: typeof value === 'string' ? agentAssetIdOf(value) : null,\n configured: true,\n ready,\n };\n}\n\n/**\n * The collab agent the active thread runs as, from the thread's config lane as the statewire host\n * sent it.\n *\n * `collab_agent_id` is a key the lane owns: once a thread has run, every turn runs as the agent\n * the lane names, whatever the provider's `agent` prop says (the prop seeds a new thread's lane on\n * its first send and is dropped from later sends). Read this hook to show an open thread's real\n * agent: `{ agentId: null, configured: true }` is a thread of the person's own assistant. Wait for\n * `ready`; a never-started chat stays not ready until its first send attaches it.\n *\n * Must be used within `<AthenaProvider>`.\n */\nexport function useAthenaThreadAgent(): AthenaThreadAgent {\n const lane = useContext(AthenaStatewireServerLaneContext);\n const agent = useMemo(\n () => (lane === null ? null : threadAgentFromLane({ lane: lane.config, ready: lane.landed })),\n [lane],\n );\n if (agent === null) {\n throw new Error('[AthenaSDK] useAthenaThreadAgent must be used within <AthenaProvider>');\n }\n return agent;\n}\n"],"names":[],"mappings":";;;AA0BO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGsB;AACpB,MAAI,CAAC,SAAS,SAAS,KAAM,QAAO,EAAE,SAAS,MAAM,YAAY,OAAO,MAAA;AACxE,QAAM,QAAQ,KAAK,OAAO;AAC1B,SAAO;AAAA,IACL,SAAS,OAAO,UAAU,WAAW,eAAe,KAAK,IAAI;AAAA,IAC7D,YAAY;AAAA,IACZ;AAAA,EAAA;AAEJ;AAcO,SAAS,uBAA0C;AACxD,QAAM,OAAO,WAAW,gCAAgC;AACxD,QAAM,QAAQ;AAAA,IACZ,MAAO,SAAS,OAAO,OAAO,oBAAoB,EAAE,MAAM,KAAK,QAAQ,OAAO,KAAK,OAAA,CAAQ;AAAA,IAC3F,CAAC,IAAI;AAAA,EAAA;AAEP,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AACA,SAAO;AACT;"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require$$0 = require("react");
4
+ const statewirePlanMode = require("../runtime/statewire-plan-mode.cjs");
5
+ const statewireServerLaneContext = require("../runtime/statewire-server-lane-context.cjs");
6
+ function useAthenaThreadPlanMode() {
7
+ const lane = require$$0.useContext(statewireServerLaneContext.AthenaStatewireServerLaneContext);
8
+ const planMode = require$$0.useMemo(
9
+ () => lane === null ? null : statewirePlanMode.threadPlanModeFromLane({ lane: lane.config, ready: lane.landed }),
10
+ [lane]
11
+ );
12
+ if (planMode === null) {
13
+ throw new Error("[AthenaSDK] useAthenaThreadPlanMode must be used within <AthenaProvider>");
14
+ }
15
+ return planMode;
16
+ }
17
+ exports.useAthenaThreadPlanMode = useAthenaThreadPlanMode;
18
+ //# sourceMappingURL=use-athena-thread-plan-mode.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-thread-plan-mode.cjs","sources":["../../src/threads/use-athena-thread-plan-mode.ts"],"sourcesContent":["import { useContext, useMemo } from 'react';\nimport { type AthenaThreadPlanMode, threadPlanModeFromLane } from '../runtime/statewire-plan-mode';\nimport { AthenaStatewireServerLaneContext } from '../runtime/statewire-server-lane-context';\n\nexport type { AthenaThreadPlanMode };\n\n/**\n * Whether the active thread's server config plans: the agent's to-do plan\n * (`write_todos`) is on unless the thread's config lane excludes it, as the\n * statewire host sent the lane.\n *\n * Once a thread has run with server config, its lane (not the provider's\n * `planMode` prop) decides, and another client (Athena on the web, a second\n * app) can change it at any time. Read this hook when a thread opens to show\n * the thread's own plan mode in a switch: `{ planMode: null, configured: false }`\n * is a thread without server config, whose turns run with what the provider\n * sends. Wait for `ready`: until the host's snapshot of the thread has arrived\n * every thread reads as unconfigured.\n *\n * Must be used within `<AthenaProvider>`.\n */\nexport function useAthenaThreadPlanMode(): AthenaThreadPlanMode {\n const lane = useContext(AthenaStatewireServerLaneContext);\n const planMode = useMemo(\n () => (lane === null ? null : threadPlanModeFromLane({ lane: lane.config, ready: lane.landed })),\n [lane],\n );\n if (planMode === null) {\n throw new Error('[AthenaSDK] useAthenaThreadPlanMode must be used within <AthenaProvider>');\n }\n return planMode;\n}\n"],"names":["useContext","AthenaStatewireServerLaneContext","useMemo","threadPlanModeFromLane"],"mappings":";;;;;AAqBO,SAAS,0BAAgD;AAC9D,QAAM,OAAOA,WAAAA,WAAWC,2DAAgC;AACxD,QAAM,WAAWC,WAAAA;AAAAA,IACf,MAAO,SAAS,OAAO,OAAOC,kBAAAA,uBAAuB,EAAE,MAAM,KAAK,QAAQ,OAAO,KAAK,OAAA,CAAQ;AAAA,IAC9F,CAAC,IAAI;AAAA,EAAA;AAEP,MAAI,aAAa,MAAM;AACrB,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC5F;AACA,SAAO;AACT;;"}
@@ -0,0 +1,18 @@
1
+ import { type AthenaThreadPlanMode } from '../runtime/statewire-plan-mode';
2
+ export type { AthenaThreadPlanMode };
3
+ /**
4
+ * Whether the active thread's server config plans: the agent's to-do plan
5
+ * (`write_todos`) is on unless the thread's config lane excludes it, as the
6
+ * statewire host sent the lane.
7
+ *
8
+ * Once a thread has run with server config, its lane (not the provider's
9
+ * `planMode` prop) decides, and another client (Athena on the web, a second
10
+ * app) can change it at any time. Read this hook when a thread opens to show
11
+ * the thread's own plan mode in a switch: `{ planMode: null, configured: false }`
12
+ * is a thread without server config, whose turns run with what the provider
13
+ * sends. Wait for `ready`: until the host's snapshot of the thread has arrived
14
+ * every thread reads as unconfigured.
15
+ *
16
+ * Must be used within `<AthenaProvider>`.
17
+ */
18
+ export declare function useAthenaThreadPlanMode(): AthenaThreadPlanMode;
@@ -0,0 +1,18 @@
1
+ import { useContext, useMemo } from "react";
2
+ import { threadPlanModeFromLane } from "../runtime/statewire-plan-mode.js";
3
+ import { AthenaStatewireServerLaneContext } from "../runtime/statewire-server-lane-context.js";
4
+ function useAthenaThreadPlanMode() {
5
+ const lane = useContext(AthenaStatewireServerLaneContext);
6
+ const planMode = useMemo(
7
+ () => lane === null ? null : threadPlanModeFromLane({ lane: lane.config, ready: lane.landed }),
8
+ [lane]
9
+ );
10
+ if (planMode === null) {
11
+ throw new Error("[AthenaSDK] useAthenaThreadPlanMode must be used within <AthenaProvider>");
12
+ }
13
+ return planMode;
14
+ }
15
+ export {
16
+ useAthenaThreadPlanMode
17
+ };
18
+ //# sourceMappingURL=use-athena-thread-plan-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-athena-thread-plan-mode.js","sources":["../../src/threads/use-athena-thread-plan-mode.ts"],"sourcesContent":["import { useContext, useMemo } from 'react';\nimport { type AthenaThreadPlanMode, threadPlanModeFromLane } from '../runtime/statewire-plan-mode';\nimport { AthenaStatewireServerLaneContext } from '../runtime/statewire-server-lane-context';\n\nexport type { AthenaThreadPlanMode };\n\n/**\n * Whether the active thread's server config plans: the agent's to-do plan\n * (`write_todos`) is on unless the thread's config lane excludes it, as the\n * statewire host sent the lane.\n *\n * Once a thread has run with server config, its lane (not the provider's\n * `planMode` prop) decides, and another client (Athena on the web, a second\n * app) can change it at any time. Read this hook when a thread opens to show\n * the thread's own plan mode in a switch: `{ planMode: null, configured: false }`\n * is a thread without server config, whose turns run with what the provider\n * sends. Wait for `ready`: until the host's snapshot of the thread has arrived\n * every thread reads as unconfigured.\n *\n * Must be used within `<AthenaProvider>`.\n */\nexport function useAthenaThreadPlanMode(): AthenaThreadPlanMode {\n const lane = useContext(AthenaStatewireServerLaneContext);\n const planMode = useMemo(\n () => (lane === null ? null : threadPlanModeFromLane({ lane: lane.config, ready: lane.landed })),\n [lane],\n );\n if (planMode === null) {\n throw new Error('[AthenaSDK] useAthenaThreadPlanMode must be used within <AthenaProvider>');\n }\n return planMode;\n}\n"],"names":[],"mappings":";;;AAqBO,SAAS,0BAAgD;AAC9D,QAAM,OAAO,WAAW,gCAAgC;AACxD,QAAM,WAAW;AAAA,IACf,MAAO,SAAS,OAAO,OAAO,uBAAuB,EAAE,MAAM,KAAK,QAAQ,OAAO,KAAK,OAAA,CAAQ;AAAA,IAC9F,CAAC,IAAI;AAAA,EAAA;AAEP,MAAI,aAAa,MAAM;AACrB,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC5F;AACA,SAAO;AACT;"}
@@ -25,6 +25,7 @@ export declare function useRestConversationHistory({ backendUrl, principalId, ge
25
25
  isLoading: boolean;
26
26
  isFetching: boolean;
27
27
  hasResolvedFirstPage: boolean;
28
+ firstPageUpdatedAt: number;
28
29
  hasNextPage: boolean;
29
30
  isFetchingNextPage: boolean;
30
31
  isFetchNextPageError: boolean;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const reactStatewire = require("@assistant-ui/react-statewire");
4
+ const require$$0 = require("react");
5
+ const autoOpenTools = require("./auto-open-tools.cjs");
6
+ const statewireState = require("../agent-runtime/src/statewire-state.cjs");
7
+ const toolNames = require("../agent-runtime/src/tool-names.cjs");
8
+ const subagents = require("../agent-runtime/src/subagents.cjs");
9
+ const runningToolPlaceholder = require("../agent-runtime/src/running-tool-placeholder.cjs");
10
+ const messageText = require("../agent-runtime/src/message-text.cjs");
11
+ const creationsByMessage = /* @__PURE__ */ new WeakMap();
12
+ function argsByCallId(messages) {
13
+ const args = /* @__PURE__ */ new Map();
14
+ for (const message of messages) {
15
+ if (message.type !== "ai" || !message.tool_calls) continue;
16
+ for (const call of message.tool_calls) if (call.id) args.set(call.id, call.args);
17
+ }
18
+ return args;
19
+ }
20
+ function agentCreationsIn(messages) {
21
+ const args = argsByCallId(messages);
22
+ const made = [];
23
+ for (const message of messages) {
24
+ if (message.type !== "tool" || !message.tool_call_id || !message.name) continue;
25
+ if (message.name === toolNames.TASK_TOOL_NAME) {
26
+ made.push(...agentCreationsIn(subagents.nestedMessagesFromArtifact(message.artifact)));
27
+ continue;
28
+ }
29
+ if (runningToolPlaceholder.isRunningToolPlaceholder(message)) continue;
30
+ let creations = creationsByMessage.get(message);
31
+ if (creations === void 0) {
32
+ creations = autoOpenTools.creationsOfCall({
33
+ toolCallId: message.tool_call_id,
34
+ tool: message.name,
35
+ result: typeof message.content === "string" ? message.content : messageText.getMessageText(message),
36
+ isError: message.status === "error",
37
+ artifact: message.artifact,
38
+ args: args.get(message.tool_call_id)
39
+ });
40
+ creationsByMessage.set(message, creations);
41
+ }
42
+ made.push(...creations);
43
+ }
44
+ return made;
45
+ }
46
+ function latestTurn(messages) {
47
+ var _a;
48
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
49
+ if (((_a = messages[index]) == null ? void 0 : _a.type) === "human") return messages.slice(index + 1);
50
+ }
51
+ return messages;
52
+ }
53
+ function createAgentCreationsReporter() {
54
+ let seen = null;
55
+ return {
56
+ see: ({ thread, messages }) => {
57
+ if (seen === null || seen.thread !== thread) {
58
+ seen = { thread, reported: new Set(agentCreationsIn(messages).map(({ key }) => key)) };
59
+ return [];
60
+ }
61
+ const reported = seen.reported;
62
+ const fresh = agentCreationsIn(latestTurn(messages)).filter(({ key }) => !reported.has(key));
63
+ for (const { key } of fresh) reported.add(key);
64
+ return fresh;
65
+ }
66
+ };
67
+ }
68
+ const selectState = (state) => state;
69
+ function useAthenaAgentCreations({
70
+ onCreation,
71
+ enabled = true
72
+ }) {
73
+ const state = reactStatewire.useStatewireState(selectState);
74
+ const reporter = require$$0.useRef(null);
75
+ const latest = require$$0.useRef(onCreation);
76
+ require$$0.useEffect(() => {
77
+ latest.current = onCreation;
78
+ }, [onCreation]);
79
+ require$$0.useEffect(() => {
80
+ if (!enabled) {
81
+ reporter.current = null;
82
+ return;
83
+ }
84
+ if (!statewireState.isDeepAgentStateHydrated(state)) return;
85
+ reporter.current ?? (reporter.current = createAgentCreationsReporter());
86
+ const made = reporter.current.see({
87
+ thread: statewireState.readDeepAgentStateThreadId(state),
88
+ messages: statewireState.readDeepAgentStreamValues(state).messages ?? []
89
+ });
90
+ for (const creation of made) latest.current(creation);
91
+ }, [state, enabled]);
92
+ }
93
+ exports.agentCreationsIn = agentCreationsIn;
94
+ exports.createAgentCreationsReporter = createAgentCreationsReporter;
95
+ exports.latestTurn = latestTurn;
96
+ exports.useAthenaAgentCreations = useAthenaAgentCreations;
97
+ //# sourceMappingURL=agent-creations.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-creations.cjs","sources":["../../src/tools/agent-creations.ts"],"sourcesContent":["'use client';\n\nimport type { LangChainMessage } from '@assistant-ui/react-langgraph';\nimport { useStatewireState } from '@assistant-ui/react-statewire';\nimport {\n getMessageText,\n isDeepAgentStateHydrated,\n isRunningToolPlaceholder,\n nestedMessagesFromArtifact,\n readDeepAgentStateThreadId,\n readDeepAgentStreamValues,\n TASK_TOOL_NAME,\n} from '@athenaintel/agent-runtime';\nimport { useEffect, useRef } from 'react';\nimport { type AgentCreation, creationsOfCall } from './auto-open-tools';\n\n/*\n * What the agent makes, as it makes it, read off the conversation's own state: the deep agent's\n * runtime (statewire) runs no tool's `streamCall`, so the SDK's auto-open toolkit\n * (`DEFAULT_AUTO_OPEN_TOOLS`) never hears its calls answer. A host that follows the agent's work\n * (Athena's desktop app opens what it makes in a tab behind the person's) reads it here instead, as\n * Athena on the web's studio follow reads the transcript (`DeepAgentPtcStudioFollowObserver`).\n */\n\nexport type { AgentCreation } from './auto-open-tools';\n\n/** Each finished tool message's creations, kept with the message (a message never changes). */\nconst creationsByMessage = new WeakMap<object, AgentCreation[]>();\n\n/** The arguments of every tool call the AI messages in `messages` asked for, by call id. */\nfunction argsByCallId(messages: readonly LangChainMessage[]): Map<string, unknown> {\n const args = new Map<string, unknown>();\n for (const message of messages) {\n if (message.type !== 'ai' || !message.tool_calls) continue;\n for (const call of message.tool_calls) if (call.id) args.set(call.id, call.args);\n }\n return args;\n}\n\n/**\n * What the finished tool calls in `messages` made or showed the person (`creationsOfCall`), a\n * `task` subagent's own calls included (its transcript rides its card, running or done). A call\n * still running (its card is the backend's running placeholder) has made nothing yet.\n */\nexport function agentCreationsIn(messages: readonly LangChainMessage[]): AgentCreation[] {\n const args = argsByCallId(messages);\n const made: AgentCreation[] = [];\n for (const message of messages) {\n if (message.type !== 'tool' || !message.tool_call_id || !message.name) continue;\n if (message.name === TASK_TOOL_NAME) {\n made.push(...agentCreationsIn(nestedMessagesFromArtifact(message.artifact)));\n continue;\n }\n if (isRunningToolPlaceholder(message)) continue;\n let creations = creationsByMessage.get(message);\n if (creations === undefined) {\n creations = creationsOfCall({\n toolCallId: message.tool_call_id,\n tool: message.name,\n result: typeof message.content === 'string' ? message.content : getMessageText(message),\n isError: message.status === 'error',\n artifact: message.artifact,\n args: args.get(message.tool_call_id),\n });\n creationsByMessage.set(message, creations);\n }\n made.push(...creations);\n }\n return made;\n}\n\n/**\n * The messages of the conversation's latest turn: everything after the person's last message. What\n * the agent makes now is there; older history a page loads in never is.\n */\nexport function latestTurn(messages: readonly LangChainMessage[]): readonly LangChainMessage[] {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n if (messages[index]?.type === 'human') return messages.slice(index + 1);\n }\n return messages;\n}\n\n/** Tells a host what the agent makes, once each, from the states its conversation goes through. */\nexport interface AgentCreationsReporter {\n /**\n * A state of the conversation: what its latest turn made since the last one, never reported\n * before. Everything a thread's first state holds (its history, a run already under way when it\n * was opened) is history: nothing of it is reported. A state of another thread starts again.\n */\n see(params: { thread: string | null; messages: readonly LangChainMessage[] }): AgentCreation[];\n}\n\nexport function createAgentCreationsReporter(): AgentCreationsReporter {\n let seen: { thread: string | null; reported: Set<string> } | null = null;\n return {\n see: ({ thread, messages }) => {\n if (seen === null || seen.thread !== thread) {\n seen = { thread, reported: new Set(agentCreationsIn(messages).map(({ key }) => key)) };\n return [];\n }\n const reported = seen.reported;\n const fresh = agentCreationsIn(latestTurn(messages)).filter(({ key }) => !reported.has(key));\n for (const { key } of fresh) reported.add(key);\n return fresh;\n },\n };\n}\n\nconst selectState = (state: unknown): unknown => state;\n\n/**\n * Calls `onCreation` once for each asset the agent makes in this conversation (a create tool, a\n * studio script's `Create*`) or opens for the person to see (`open_asset_in_workspace`), as its\n * call finishes: never for history, a call that failed or was refused, or a call that only read or\n * changed an asset. Render it inside `AthenaChat` (a `composer` slot, a `components` override),\n * where the conversation's state is read. Nothing is read while `enabled` is false.\n */\nexport function useAthenaAgentCreations({\n onCreation,\n enabled = true,\n}: {\n onCreation: (creation: AgentCreation) => void;\n enabled?: boolean;\n}): void {\n const state = useStatewireState(selectState);\n const reporter = useRef<AgentCreationsReporter | null>(null);\n const latest = useRef(onCreation);\n useEffect(() => {\n latest.current = onCreation;\n }, [onCreation]);\n useEffect(() => {\n if (!enabled) {\n reporter.current = null;\n return;\n }\n if (!isDeepAgentStateHydrated(state)) return;\n reporter.current ??= createAgentCreationsReporter();\n const made = reporter.current.see({\n thread: readDeepAgentStateThreadId(state),\n messages: readDeepAgentStreamValues(state).messages ?? [],\n });\n for (const creation of made) latest.current(creation);\n }, [state, enabled]);\n}\n"],"names":["TASK_TOOL_NAME","nestedMessagesFromArtifact","isRunningToolPlaceholder","creationsOfCall","getMessageText","useStatewireState","useRef","useEffect","isDeepAgentStateHydrated","readDeepAgentStateThreadId","readDeepAgentStreamValues"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { LangChainMessage } from '@assistant-ui/react-langgraph';
2
+ import { type AgentCreation } from './auto-open-tools';
3
+ export type { AgentCreation } from './auto-open-tools';
4
+ /**
5
+ * What the finished tool calls in `messages` made or showed the person (`creationsOfCall`), a
6
+ * `task` subagent's own calls included (its transcript rides its card, running or done). A call
7
+ * still running (its card is the backend's running placeholder) has made nothing yet.
8
+ */
9
+ export declare function agentCreationsIn(messages: readonly LangChainMessage[]): AgentCreation[];
10
+ /**
11
+ * The messages of the conversation's latest turn: everything after the person's last message. What
12
+ * the agent makes now is there; older history a page loads in never is.
13
+ */
14
+ export declare function latestTurn(messages: readonly LangChainMessage[]): readonly LangChainMessage[];
15
+ /** Tells a host what the agent makes, once each, from the states its conversation goes through. */
16
+ export interface AgentCreationsReporter {
17
+ /**
18
+ * A state of the conversation: what its latest turn made since the last one, never reported
19
+ * before. Everything a thread's first state holds (its history, a run already under way when it
20
+ * was opened) is history: nothing of it is reported. A state of another thread starts again.
21
+ */
22
+ see(params: {
23
+ thread: string | null;
24
+ messages: readonly LangChainMessage[];
25
+ }): AgentCreation[];
26
+ }
27
+ export declare function createAgentCreationsReporter(): AgentCreationsReporter;
28
+ /**
29
+ * Calls `onCreation` once for each asset the agent makes in this conversation (a create tool, a
30
+ * studio script's `Create*`) or opens for the person to see (`open_asset_in_workspace`), as its
31
+ * call finishes: never for history, a call that failed or was refused, or a call that only read or
32
+ * changed an asset. Render it inside `AthenaChat` (a `composer` slot, a `components` override),
33
+ * where the conversation's state is read. Nothing is read while `enabled` is false.
34
+ */
35
+ export declare function useAthenaAgentCreations({ onCreation, enabled, }: {
36
+ onCreation: (creation: AgentCreation) => void;
37
+ enabled?: boolean;
38
+ }): void;