@athenaintel/react 0.22.4 → 0.23.1

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 (350) hide show
  1. package/README.md +394 -4
  2. package/dist/chat/AthenaChat.cjs +346 -244
  3. package/dist/chat/AthenaChat.cjs.map +1 -1
  4. package/dist/chat/AthenaChat.d.ts +19 -8
  5. package/dist/chat/AthenaChat.js +350 -248
  6. package/dist/chat/AthenaChat.js.map +1 -1
  7. package/dist/chat/StatewireApprovalCard.cjs +2 -1
  8. package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
  9. package/dist/chat/StatewireApprovalCard.js +2 -1
  10. package/dist/chat/StatewireApprovalCard.js.map +1 -1
  11. package/dist/chat/StatewireClientToolBridge.cjs +1 -0
  12. package/dist/chat/StatewireClientToolBridge.cjs.map +1 -1
  13. package/dist/chat/StatewireClientToolBridge.js +1 -0
  14. package/dist/chat/StatewireClientToolBridge.js.map +1 -1
  15. package/dist/chat/StatewireQueuedMessages.cjs +1 -0
  16. package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
  17. package/dist/chat/StatewireQueuedMessages.js +1 -0
  18. package/dist/chat/StatewireQueuedMessages.js.map +1 -1
  19. package/dist/chat/WaitingOnYouBanner.cjs +100 -0
  20. package/dist/chat/WaitingOnYouBanner.cjs.map +1 -0
  21. package/dist/chat/WaitingOnYouBanner.d.ts +29 -0
  22. package/dist/chat/WaitingOnYouBanner.js +100 -0
  23. package/dist/chat/WaitingOnYouBanner.js.map +1 -0
  24. package/dist/chat/athena-chat-welcome.cjs +148 -0
  25. package/dist/chat/athena-chat-welcome.cjs.map +1 -0
  26. package/dist/chat/athena-chat-welcome.d.ts +54 -0
  27. package/dist/chat/athena-chat-welcome.js +148 -0
  28. package/dist/chat/athena-chat-welcome.js.map +1 -0
  29. package/dist/chat/athena-composer-controls.cjs +76 -0
  30. package/dist/chat/athena-composer-controls.cjs.map +1 -0
  31. package/dist/chat/athena-composer-controls.d.ts +21 -0
  32. package/dist/chat/athena-composer-controls.js +76 -0
  33. package/dist/chat/athena-composer-controls.js.map +1 -0
  34. package/dist/chat/composer-keyboard-hint.cjs +61 -0
  35. package/dist/chat/composer-keyboard-hint.cjs.map +1 -0
  36. package/dist/chat/composer-keyboard-hint.d.ts +33 -0
  37. package/dist/chat/composer-keyboard-hint.js +61 -0
  38. package/dist/chat/composer-keyboard-hint.js.map +1 -0
  39. package/dist/chat/message-time.cjs +64 -0
  40. package/dist/chat/message-time.cjs.map +1 -0
  41. package/dist/chat/message-time.d.ts +45 -0
  42. package/dist/chat/message-time.js +64 -0
  43. package/dist/chat/message-time.js.map +1 -0
  44. package/dist/chat/run-activity.cjs +38 -7
  45. package/dist/chat/run-activity.cjs.map +1 -1
  46. package/dist/chat/run-activity.d.ts +14 -3
  47. package/dist/chat/run-activity.js +39 -8
  48. package/dist/chat/run-activity.js.map +1 -1
  49. package/dist/chat/statewire-client-tools.cjs +2 -1
  50. package/dist/chat/statewire-client-tools.cjs.map +1 -1
  51. package/dist/chat/statewire-client-tools.js +2 -1
  52. package/dist/chat/statewire-client-tools.js.map +1 -1
  53. package/dist/chat/super-grouping/activity-timeline.cjs +2 -1
  54. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  55. package/dist/chat/super-grouping/activity-timeline.js +2 -1
  56. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  57. package/dist/chat/thread-scroll-to-bottom.cjs +24 -0
  58. package/dist/chat/thread-scroll-to-bottom.cjs.map +1 -0
  59. package/dist/chat/thread-scroll-to-bottom.d.ts +11 -0
  60. package/dist/chat/thread-scroll-to-bottom.js +24 -0
  61. package/dist/chat/thread-scroll-to-bottom.js.map +1 -0
  62. package/dist/chat/tiptap-text.cjs +26 -95
  63. package/dist/chat/tiptap-text.cjs.map +1 -1
  64. package/dist/chat/tiptap-text.d.ts +13 -0
  65. package/dist/chat/tiptap-text.js +26 -95
  66. package/dist/chat/tiptap-text.js.map +1 -1
  67. package/dist/chat/use-athena-run-live.cjs +2 -1
  68. package/dist/chat/use-athena-run-live.cjs.map +1 -1
  69. package/dist/chat/use-athena-run-live.js +2 -1
  70. package/dist/chat/use-athena-run-live.js.map +1 -1
  71. package/dist/chat/use-statewire-approval-request.cjs +1 -0
  72. package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
  73. package/dist/chat/use-statewire-approval-request.js +1 -0
  74. package/dist/chat/use-statewire-approval-request.js.map +1 -1
  75. package/dist/chat-ui/composer/tiptap-composer.cjs +39 -4
  76. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  77. package/dist/chat-ui/composer/tiptap-composer.d.ts +21 -0
  78. package/dist/chat-ui/composer/tiptap-composer.js +39 -4
  79. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  80. package/dist/chat-ui/index.cjs +15 -1
  81. package/dist/chat-ui/index.cjs.map +1 -1
  82. package/dist/chat-ui/index.d.ts +6 -3
  83. package/dist/chat-ui/index.js +16 -2
  84. package/dist/chat-ui/index.js.map +1 -1
  85. package/dist/chat-ui/mentions/mention-chip.cjs +31 -4
  86. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  87. package/dist/chat-ui/mentions/mention-chip.js +31 -4
  88. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  89. package/dist/chat-ui/messages/message-components.cjs +19 -1
  90. package/dist/chat-ui/messages/message-components.cjs.map +1 -1
  91. package/dist/chat-ui/messages/message-components.d.ts +13 -0
  92. package/dist/chat-ui/messages/message-components.js +19 -1
  93. package/dist/chat-ui/messages/message-components.js.map +1 -1
  94. package/dist/chat-ui/messages/runtime-message.cjs +2 -1
  95. package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
  96. package/dist/chat-ui/messages/runtime-message.js +2 -1
  97. package/dist/chat-ui/messages/runtime-message.js.map +1 -1
  98. package/dist/chat-ui/messages/statewire-continue-run.cjs +1 -0
  99. package/dist/chat-ui/messages/statewire-continue-run.cjs.map +1 -1
  100. package/dist/chat-ui/messages/statewire-continue-run.js +1 -0
  101. package/dist/chat-ui/messages/statewire-continue-run.js.map +1 -1
  102. package/dist/chat-ui/messages/user-edit-composer.cjs +3 -1
  103. package/dist/chat-ui/messages/user-edit-composer.cjs.map +1 -1
  104. package/dist/chat-ui/messages/user-edit-composer.js +3 -1
  105. package/dist/chat-ui/messages/user-edit-composer.js.map +1 -1
  106. package/dist/chat-ui/messages/wake-marker.cjs +84 -0
  107. package/dist/chat-ui/messages/wake-marker.cjs.map +1 -0
  108. package/dist/chat-ui/messages/wake-marker.d.ts +16 -0
  109. package/dist/chat-ui/messages/wake-marker.js +84 -0
  110. package/dist/chat-ui/messages/wake-marker.js.map +1 -0
  111. package/dist/chat-ui/rich-text/chat-blocks.cjs +177 -0
  112. package/dist/chat-ui/rich-text/chat-blocks.cjs.map +1 -0
  113. package/dist/chat-ui/rich-text/chat-blocks.d.ts +58 -0
  114. package/dist/chat-ui/rich-text/chat-blocks.js +177 -0
  115. package/dist/chat-ui/rich-text/chat-blocks.js.map +1 -0
  116. package/dist/chat-ui/rich-text/chat-link.cjs +69 -0
  117. package/dist/chat-ui/rich-text/chat-link.cjs.map +1 -0
  118. package/dist/chat-ui/rich-text/chat-link.d.ts +24 -0
  119. package/dist/chat-ui/rich-text/chat-link.js +69 -0
  120. package/dist/chat-ui/rich-text/chat-link.js.map +1 -0
  121. package/dist/chat-ui/rich-text/chat-message-body.cjs +144 -18
  122. package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
  123. package/dist/chat-ui/rich-text/chat-message-body.d.ts +10 -1
  124. package/dist/chat-ui/rich-text/chat-message-body.js +149 -23
  125. package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
  126. package/dist/chat-ui/rich-text/chat-node-views.cjs +38 -5
  127. package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
  128. package/dist/chat-ui/rich-text/chat-node-views.d.ts +11 -0
  129. package/dist/chat-ui/rich-text/chat-node-views.js +39 -6
  130. package/dist/chat-ui/rich-text/chat-node-views.js.map +1 -1
  131. package/dist/chat-ui/rich-text/chat-text-schema.cjs +20 -3
  132. package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
  133. package/dist/chat-ui/rich-text/chat-text-schema.d.ts +15 -2
  134. package/dist/chat-ui/rich-text/chat-text-schema.js +20 -3
  135. package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
  136. package/dist/chat-ui/rich-text/citation-anchors.cjs +139 -0
  137. package/dist/chat-ui/rich-text/citation-anchors.cjs.map +1 -0
  138. package/dist/chat-ui/rich-text/citation-anchors.d.ts +74 -0
  139. package/dist/chat-ui/rich-text/citation-anchors.js +139 -0
  140. package/dist/chat-ui/rich-text/citation-anchors.js.map +1 -0
  141. package/dist/chat-ui/statewire.cjs +8 -1
  142. package/dist/chat-ui/statewire.cjs.map +1 -1
  143. package/dist/chat-ui/statewire.d.ts +2 -0
  144. package/dist/chat-ui/statewire.js +8 -1
  145. package/dist/chat-ui/statewire.js.map +1 -1
  146. package/dist/chat-ui/thread/chat-composer-dock.cjs +27 -6
  147. package/dist/chat-ui/thread/chat-composer-dock.cjs.map +1 -1
  148. package/dist/chat-ui/thread/chat-composer-dock.d.ts +21 -1
  149. package/dist/chat-ui/thread/chat-composer-dock.js +28 -7
  150. package/dist/chat-ui/thread/chat-composer-dock.js.map +1 -1
  151. package/dist/chat-ui/thread/statewire-history-edge.cjs +12 -13
  152. package/dist/chat-ui/thread/statewire-history-edge.cjs.map +1 -1
  153. package/dist/chat-ui/thread/statewire-history-edge.d.ts +11 -10
  154. package/dist/chat-ui/thread/statewire-history-edge.js +13 -14
  155. package/dist/chat-ui/thread/statewire-history-edge.js.map +1 -1
  156. package/dist/chat-ui/thread/thread-loading-overlay.cjs +31 -0
  157. package/dist/chat-ui/thread/thread-loading-overlay.cjs.map +1 -0
  158. package/dist/chat-ui/thread/thread-loading-overlay.d.ts +14 -0
  159. package/dist/chat-ui/thread/thread-loading-overlay.js +31 -0
  160. package/dist/chat-ui/thread/thread-loading-overlay.js.map +1 -0
  161. package/dist/composer/ComposerDropZone.cjs +8 -1
  162. package/dist/composer/ComposerDropZone.cjs.map +1 -1
  163. package/dist/composer/ComposerDropZone.d.ts +6 -0
  164. package/dist/composer/ComposerDropZone.js +9 -2
  165. package/dist/composer/ComposerDropZone.js.map +1 -1
  166. package/dist/diagnostics/errors.cjs +20 -0
  167. package/dist/diagnostics/errors.cjs.map +1 -1
  168. package/dist/diagnostics/errors.d.ts +20 -0
  169. package/dist/diagnostics/errors.js +20 -0
  170. package/dist/diagnostics/errors.js.map +1 -1
  171. package/dist/index.cjs +47 -1
  172. package/dist/index.cjs.map +1 -1
  173. package/dist/index.d.ts +26 -7
  174. package/dist/index.js +51 -5
  175. package/dist/index.js.map +1 -1
  176. package/dist/lib/use-prefers-reduced-motion.cjs +29 -0
  177. package/dist/lib/use-prefers-reduced-motion.cjs.map +1 -0
  178. package/dist/lib/use-prefers-reduced-motion.d.ts +6 -0
  179. package/dist/lib/use-prefers-reduced-motion.js +29 -0
  180. package/dist/lib/use-prefers-reduced-motion.js.map +1 -0
  181. package/dist/packages/agent-runtime/src/conversation-index.cjs.map +1 -1
  182. package/dist/packages/agent-runtime/src/conversation-index.js.map +1 -1
  183. package/dist/packages/agent-runtime/src/conversation-list.cjs +59 -0
  184. package/dist/packages/agent-runtime/src/conversation-list.cjs.map +1 -1
  185. package/dist/packages/agent-runtime/src/conversation-list.js +60 -1
  186. package/dist/packages/agent-runtime/src/conversation-list.js.map +1 -1
  187. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.cjs +5 -3
  188. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  189. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.js +5 -3
  190. package/dist/packages/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  191. package/dist/packages/agent-runtime/src/edit-command.cjs +21 -17
  192. package/dist/packages/agent-runtime/src/edit-command.cjs.map +1 -1
  193. package/dist/packages/agent-runtime/src/edit-command.js +22 -18
  194. package/dist/packages/agent-runtime/src/edit-command.js.map +1 -1
  195. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +9 -11
  196. package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  197. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +9 -11
  198. package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  199. package/dist/packages/agent-runtime/src/github-wake-event.cjs +86 -0
  200. package/dist/packages/agent-runtime/src/github-wake-event.cjs.map +1 -0
  201. package/dist/packages/agent-runtime/src/github-wake-event.js +86 -0
  202. package/dist/packages/agent-runtime/src/github-wake-event.js.map +1 -0
  203. package/dist/packages/agent-runtime/src/message-window.cjs +150 -42
  204. package/dist/packages/agent-runtime/src/message-window.cjs.map +1 -1
  205. package/dist/packages/agent-runtime/src/message-window.js +151 -43
  206. package/dist/packages/agent-runtime/src/message-window.js.map +1 -1
  207. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs +13 -9
  208. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  209. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js +13 -9
  210. package/dist/packages/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  211. package/dist/packages/agent-runtime/src/statewire-suspended.cjs +1 -3
  212. package/dist/packages/agent-runtime/src/statewire-suspended.cjs.map +1 -1
  213. package/dist/packages/agent-runtime/src/statewire-suspended.js +1 -3
  214. package/dist/packages/agent-runtime/src/statewire-suspended.js.map +1 -1
  215. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.cjs.map +1 -1
  216. package/dist/packages/agent-runtime/src/use-deep-agent-edit-submit.js.map +1 -1
  217. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs +61 -30
  218. package/dist/packages/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  219. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js +59 -28
  220. package/dist/packages/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  221. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs +56 -36
  222. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.cjs.map +1 -1
  223. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js +59 -39
  224. package/dist/packages/agent-runtime/src/use-deep-agent-window-sync.js.map +1 -1
  225. package/dist/packages/react/package.json.cjs +1 -1
  226. package/dist/packages/react/package.json.js +1 -1
  227. package/dist/provider/AthenaContext.cjs.map +1 -1
  228. package/dist/provider/AthenaContext.d.ts +3 -0
  229. package/dist/provider/AthenaContext.js.map +1 -1
  230. package/dist/provider/AthenaProvider.cjs +93 -45
  231. package/dist/provider/AthenaProvider.cjs.map +1 -1
  232. package/dist/provider/AthenaProvider.d.ts +6 -1
  233. package/dist/provider/AthenaProvider.js +97 -49
  234. package/dist/provider/AthenaProvider.js.map +1 -1
  235. package/dist/runtime/statewire-lifecycle.cjs +2 -1
  236. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  237. package/dist/runtime/statewire-lifecycle.js +2 -1
  238. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  239. package/dist/runtime/useAthenaStatewireRuntime.cjs +3 -2
  240. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  241. package/dist/runtime/useAthenaStatewireRuntime.d.ts +8 -12
  242. package/dist/runtime/useAthenaStatewireRuntime.js +3 -2
  243. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  244. package/dist/search/useAthenaRepoSearch.cjs +94 -0
  245. package/dist/search/useAthenaRepoSearch.cjs.map +1 -0
  246. package/dist/search/useAthenaRepoSearch.d.ts +95 -0
  247. package/dist/search/useAthenaRepoSearch.js +94 -0
  248. package/dist/search/useAthenaRepoSearch.js.map +1 -0
  249. package/dist/styles.css +1 -1
  250. package/dist/threads/SessionList.cjs +486 -0
  251. package/dist/threads/SessionList.cjs.map +1 -0
  252. package/dist/threads/SessionList.d.ts +60 -0
  253. package/dist/threads/SessionList.js +486 -0
  254. package/dist/threads/SessionList.js.map +1 -0
  255. package/dist/threads/api.cjs +112 -4
  256. package/dist/threads/api.cjs.map +1 -1
  257. package/dist/threads/api.d.ts +128 -1
  258. package/dist/threads/api.js +113 -5
  259. package/dist/threads/api.js.map +1 -1
  260. package/dist/threads/conversation-list-fetcher.cjs +27 -3
  261. package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
  262. package/dist/threads/conversation-list-fetcher.d.ts +16 -3
  263. package/dist/threads/conversation-list-fetcher.js +27 -3
  264. package/dist/threads/conversation-list-fetcher.js.map +1 -1
  265. package/dist/threads/index.d.ts +5 -1
  266. package/dist/threads/session-list-model.cjs +130 -0
  267. package/dist/threads/session-list-model.cjs.map +1 -0
  268. package/dist/threads/session-list-model.d.ts +62 -0
  269. package/dist/threads/session-list-model.js +130 -0
  270. package/dist/threads/session-list-model.js.map +1 -0
  271. package/dist/threads/statewire-thread-list.cjs +220 -38
  272. package/dist/threads/statewire-thread-list.cjs.map +1 -1
  273. package/dist/threads/statewire-thread-list.d.ts +152 -2
  274. package/dist/threads/statewire-thread-list.js +222 -40
  275. package/dist/threads/statewire-thread-list.js.map +1 -1
  276. package/dist/threads/thread-prefetcher.cjs +63 -0
  277. package/dist/threads/thread-prefetcher.cjs.map +1 -0
  278. package/dist/threads/thread-prefetcher.d.ts +54 -0
  279. package/dist/threads/thread-prefetcher.js +63 -0
  280. package/dist/threads/thread-prefetcher.js.map +1 -0
  281. package/dist/threads/use-athena-session-attention.cjs +22 -0
  282. package/dist/threads/use-athena-session-attention.cjs.map +1 -0
  283. package/dist/threads/use-athena-session-attention.d.ts +24 -0
  284. package/dist/threads/use-athena-session-attention.js +22 -0
  285. package/dist/threads/use-athena-session-attention.js.map +1 -0
  286. package/dist/threads/use-rest-conversation-history.cjs +25 -2
  287. package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
  288. package/dist/threads/use-rest-conversation-history.d.ts +8 -1
  289. package/dist/threads/use-rest-conversation-history.js +25 -2
  290. package/dist/threads/use-rest-conversation-history.js.map +1 -1
  291. package/dist/threads/use-statewire-conversation-history.cjs +40 -16
  292. package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
  293. package/dist/threads/use-statewire-conversation-history.d.ts +13 -0
  294. package/dist/threads/use-statewire-conversation-history.js +40 -16
  295. package/dist/threads/use-statewire-conversation-history.js.map +1 -1
  296. package/dist/threads/use-thread-archive.cjs +128 -0
  297. package/dist/threads/use-thread-archive.cjs.map +1 -0
  298. package/dist/threads/use-thread-archive.d.ts +26 -0
  299. package/dist/threads/use-thread-archive.js +128 -0
  300. package/dist/threads/use-thread-archive.js.map +1 -0
  301. package/dist/threads/use-thread-favorite.cjs +53 -0
  302. package/dist/threads/use-thread-favorite.cjs.map +1 -0
  303. package/dist/threads/use-thread-favorite.d.ts +49 -0
  304. package/dist/threads/use-thread-favorite.js +53 -0
  305. package/dist/threads/use-thread-favorite.js.map +1 -0
  306. package/dist/threads/use-thread-field-override.cjs +184 -0
  307. package/dist/threads/use-thread-field-override.cjs.map +1 -0
  308. package/dist/threads/use-thread-field-override.d.ts +55 -0
  309. package/dist/threads/use-thread-field-override.js +184 -0
  310. package/dist/threads/use-thread-field-override.js.map +1 -0
  311. package/dist/threads/use-thread-rename.cjs +53 -0
  312. package/dist/threads/use-thread-rename.cjs.map +1 -0
  313. package/dist/threads/use-thread-rename.d.ts +48 -0
  314. package/dist/threads/use-thread-rename.js +53 -0
  315. package/dist/threads/use-thread-rename.js.map +1 -0
  316. package/dist/tools/index.cjs +5 -1
  317. package/dist/tools/index.cjs.map +1 -1
  318. package/dist/tools/index.d.ts +1 -1
  319. package/dist/tools/index.js +7 -3
  320. package/dist/tools/index.js.map +1 -1
  321. package/dist/tools/misc-tool-uis.cjs +2 -1
  322. package/dist/tools/misc-tool-uis.cjs.map +1 -1
  323. package/dist/tools/misc-tool-uis.js +2 -1
  324. package/dist/tools/misc-tool-uis.js.map +1 -1
  325. package/dist/tools/primitives.cjs +25 -2
  326. package/dist/tools/primitives.cjs.map +1 -1
  327. package/dist/tools/primitives.d.ts +9 -2
  328. package/dist/tools/primitives.js +26 -3
  329. package/dist/tools/primitives.js.map +1 -1
  330. package/dist/tools/tool-appearance.cjs +11 -0
  331. package/dist/tools/tool-appearance.cjs.map +1 -0
  332. package/dist/tools/tool-appearance.d.ts +29 -0
  333. package/dist/tools/tool-appearance.js +11 -0
  334. package/dist/tools/tool-appearance.js.map +1 -0
  335. package/dist/tools/tool-fallback.cjs +211 -13
  336. package/dist/tools/tool-fallback.cjs.map +1 -1
  337. package/dist/tools/tool-fallback.d.ts +31 -4
  338. package/dist/tools/tool-fallback.js +214 -16
  339. package/dist/tools/tool-fallback.js.map +1 -1
  340. package/dist/tools/use-elapsed-seconds.cjs +24 -0
  341. package/dist/tools/use-elapsed-seconds.cjs.map +1 -0
  342. package/dist/tools/use-elapsed-seconds.d.ts +10 -0
  343. package/dist/tools/use-elapsed-seconds.js +24 -0
  344. package/dist/tools/use-elapsed-seconds.js.map +1 -0
  345. package/dist/tools/voice-update-tool-ui.cjs +2 -1
  346. package/dist/tools/voice-update-tool-ui.cjs.map +1 -1
  347. package/dist/tools/voice-update-tool-ui.js +2 -1
  348. package/dist/tools/voice-update-tool-ui.js.map +1 -1
  349. package/package.json +3 -3
  350. package/src/chat-ui/tailwind-preset.js +14 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-deep-agent-window-sync.cjs","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import { useStatewireSendCommand, useStatewireState } from '@assistant-ui/react-statewire';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY } from './generated/runconfig-contract';\nimport {\n buildHistoryLoadCommand,\n buildToolOutputCommand,\n type DeepAgentMessagesWindow,\n type HistoryLoadResult,\n readDeepAgentMessagesWindow,\n readHistoryLoadResult,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One `history/load` round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n beforeIndex: number;\n limit: number;\n /** The host's answer, or `null` when it was not a history-load result. */\n result: HistoryLoadResult | null;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** A `history/load` settled (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read command failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'history/load' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The lane, or `null` on a wire that is not windowed (both halves are inert). */\n window: DeepAgentMessagesWindow | null;\n /** Messages older than the loaded window the server still holds. */\n olderCount: number;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op on a wire that is not windowed or at the beginning. */\n loadOlder: () => void;\n}\n\n/** The raw lane, selected without derivation (selectors compare by identity). */\nfunction selectMessagesWindowLane(state: unknown): unknown {\n return typeof state === 'object' && state !== null\n ? (state as Record<string, unknown>)[DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY]\n : undefined;\n}\n\n/** The `messagesWindow` lane of the nearest statewire thread, or `null` when the wire is not windowed. */\nexport function useDeepAgentMessagesWindow(): DeepAgentMessagesWindow | null {\n const lane = useStatewireState(selectMessagesWindowLane);\n return useMemo(\n () => readDeepAgentMessagesWindow({ [DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY]: lane }),\n [lane]\n );\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\n\n/**\n * The client half of the windowed wire, shared by every surface that declares\n * a message window (`useDeepAgentThread({ messageWindow })`) — mounted once\n * per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the `messagesWindow` lane says older\n * messages exist, this sends `history/load` for the next page — the host\n * prepends it as ops for this client alone — chaining at most\n * `maxChainedLoads` pages per approach; `loadOlder` asks for one page on\n * demand (an edge row's button). Never two loads in flight.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n *\n * On a thread whose wire is not windowed (no lane) both halves are inert.\n */\nexport function useDeepAgentWindowSync({\n messages,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const sendCommand = useStatewireSendCommand();\n const window = useDeepAgentMessagesWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n // Bumped when a page settled AFTER its ops moved the lane (the host's\n // order: prepend, then answer), so the chain re-evaluates against the moved\n // window instead of waiting for another signal.\n const [settledLoads, setSettledLoads] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef<number | null>(null);\n const chainRef = useRef({ epoch: 0, loads: 0 });\n const aliveRef = useRef(true);\n const windowRef = useRef(window);\n windowRef.current = window;\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (window === null || window.start === 0 || inflightRef.current !== null) return;\n const requested = requests !== servedRequestsRef.current;\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1 };\n } else {\n if (!nearTop) return;\n if (chainRef.current.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0 };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n const command = buildHistoryLoadCommand({ window });\n if (command === null) return;\n inflightRef.current = command.beforeIndex;\n setLoading(true);\n const startedAt = nowRef.current();\n Promise.resolve(sendCommand(command))\n .then((payload) => {\n onHistoryLoadRef.current?.({\n beforeIndex: command.beforeIndex,\n limit: command.limit,\n result: readHistoryLoadResult(payload),\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'history/load');\n })\n .finally(() => {\n inflightRef.current = null;\n if (!aliveRef.current) return;\n setLoading(false);\n if (windowRef.current?.start !== command.beforeIndex) {\n setSettledLoads((count) => count + 1);\n }\n });\n }, [nearTop, nearTopEpoch, requests, settledLoads, window, sendCommand, maxChainedLoads]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n return { window, olderCount: window?.start ?? 0, loading, loadOlder };\n}\n"],"names":["DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY","useStatewireState","useMemo","readDeepAgentMessagesWindow","useStatewireSendCommand","useState","useRef","useEffect","buildHistoryLoadCommand","readHistoryLoadResult","readTruncatedToolOutputArtifact","buildToolOutputCommand","readToolOutputResult","_a","useCallback"],"mappings":"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"}
1
+ {"version":3,"file":"use-deep-agent-window-sync.cjs","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n interestsCovered,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'athena/interest' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * host's interest cap has room for them. `hasOlder && !canLoadOlder` is the\n * depth limit (`MAX_INTERESTS × MAX_MESSAGE_WINDOW` messages loaded in one\n * connection) — an edge row says so instead of offering a dead button.\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved or at the beginning. */\n loadOlder: () => void;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * re-states the interests with one more page (anchored at the window's\n * first message) — the host mounts its documents for this client alone —\n * chaining at most `maxChainedLoads` pages per approach; `loadOlder` asks\n * for one page on demand (an edge row's button). Never two loads in flight.\n * A reconnect whose hello does not carry the interests this mount last\n * stated (the host remembers a client id's view across its attaches; a new\n * host instance does not) re-states them.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n */\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0 });\n const aliveRef = useRef(true);\n // The interests this mount last stated, re-stated on the next connected\n // session (a hello resets the documents) so a reconnect keeps the loaded history.\n const statedRef = useRef<DeepAgentInterestRequest[] | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (connection.status !== 'connected' || restatedConnectionRef.current === connection) return;\n // Decided once per connected session, on the hello's interest document.\n if (window === null) return;\n restatedConnectionRef.current = connection;\n const stated = statedRef.current;\n if (stated === null || interestsCovered(window.requests, stated)) return;\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated]).catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n });\n }, [connection, invoke, window]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n const pageRequests = pageInterestRequests(window, pageSize);\n if (pageRequests === null) return;\n const requested = requests !== servedRequestsRef.current;\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1 };\n } else {\n if (!nearTop) return;\n if (chainRef.current.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0 };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n const page = window.pages + 1;\n const request = pageRequests[pageRequests.length - 1] as DeepAgentInterestRequest;\n inflightRef.current = true;\n setLoading(true);\n const startedAt = nowRef.current();\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [pageRequests])\n .then(() => {\n statedRef.current = pageRequests;\n onHistoryLoadRef.current?.({\n page,\n request,\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [nearTop, nearTopEpoch, requests, window, loading, invoke, maxChainedLoads, pageSize]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n const canLoadOlder = useMemo(\n () => window !== null && pageInterestRequests(window, pageSize) !== null,\n [window, pageSize]\n );\n\n return { window, hasOlder: window?.hasOlder ?? false, canLoadOlder, loading, loadOlder };\n}\n"],"names":["useAuiState","hasStatewireThreadExtras","useSyncExternalStore","useMemo","readDeepAgentMessageWindow","useState","useRef","useEffect","interestsCovered","DEEP_AGENT_INTEREST_PROTOCOL","pageInterestRequests","readTruncatedToolOutputArtifact","buildToolOutputCommand","readToolOutputResult","_a","useCallback"],"mappings":"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"}
@@ -1,22 +1,31 @@
1
- import { useStatewireSendCommand, useStatewireState } from "@assistant-ui/react-statewire";
2
- import { useState, useRef, useEffect, useCallback, useMemo } from "react";
3
- import { DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY } from "./generated/runconfig-contract.js";
4
- import { buildHistoryLoadCommand, readHistoryLoadResult, readTruncatedToolOutputArtifact, buildToolOutputCommand, readToolOutputResult, readDeepAgentMessagesWindow } from "./message-window.js";
1
+ import { useAuiState } from "@assistant-ui/store";
2
+ import { useState, useRef, useEffect, useCallback, useMemo, useSyncExternalStore } from "react";
3
+ import { DEEP_AGENT_INTEREST_PROTOCOL } from "./generated/runconfig-contract.js";
4
+ import { interestsCovered, pageInterestRequests, readTruncatedToolOutputArtifact, buildToolOutputCommand, readToolOutputResult, readDeepAgentMessageWindow } from "./message-window.js";
5
+ import { hasStatewireThreadExtras } from "./thread-extras.js";
5
6
  const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;
6
- function selectMessagesWindowLane(state) {
7
- return typeof state === "object" && state !== null ? state[DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY] : void 0;
8
- }
9
- function useDeepAgentMessagesWindow() {
10
- const lane = useStatewireState(selectMessagesWindowLane);
11
- return useMemo(
12
- () => readDeepAgentMessagesWindow({ [DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY]: lane }),
13
- [lane]
14
- );
15
- }
16
7
  const everyMessageMounted = () => true;
17
8
  const defaultNow = () => Date.now();
9
+ const noopSubscribe = () => () => {
10
+ };
11
+ const useStatewireExtras = () => useAuiState((s) => {
12
+ if (!hasStatewireThreadExtras(s.thread.extras)) {
13
+ throw new Error("useDeepAgentWindowSync requires a statewire thread");
14
+ }
15
+ return s.thread.extras;
16
+ });
17
+ function useDeepAgentMessageWindow() {
18
+ const documents = useStatewireExtras().documents;
19
+ const mounted = useSyncExternalStore(
20
+ (documents == null ? void 0 : documents.subscribe) ?? noopSubscribe,
21
+ () => documents == null ? void 0 : documents.list(),
22
+ () => documents == null ? void 0 : documents.list()
23
+ );
24
+ return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);
25
+ }
18
26
  function useDeepAgentWindowSync({
19
27
  messages,
28
+ pageSize,
20
29
  toolOutputs,
21
30
  nearTop = false,
22
31
  nearTopEpoch = 0,
@@ -26,17 +35,16 @@ function useDeepAgentWindowSync({
26
35
  onError,
27
36
  now = defaultNow
28
37
  }) {
29
- const sendCommand = useStatewireSendCommand();
30
- const window = useDeepAgentMessagesWindow();
38
+ const { sendCommand, invoke, connection } = useStatewireExtras();
39
+ const window = useDeepAgentMessageWindow();
31
40
  const [loading, setLoading] = useState(false);
32
41
  const [requests, setRequests] = useState(0);
33
- const [settledLoads, setSettledLoads] = useState(0);
34
42
  const servedRequestsRef = useRef(0);
35
- const inflightRef = useRef(null);
43
+ const inflightRef = useRef(false);
36
44
  const chainRef = useRef({ epoch: 0, loads: 0 });
37
45
  const aliveRef = useRef(true);
38
- const windowRef = useRef(window);
39
- windowRef.current = window;
46
+ const statedRef = useRef(null);
47
+ const restatedConnectionRef = useRef(null);
40
48
  const answeredRef = useRef(/* @__PURE__ */ new Map());
41
49
  const onHistoryLoadRef = useRef(onHistoryLoad);
42
50
  onHistoryLoadRef.current = onHistoryLoad;
@@ -51,7 +59,20 @@ function useDeepAgentWindowSync({
51
59
  };
52
60
  }, []);
53
61
  useEffect(() => {
54
- if (window === null || window.start === 0 || inflightRef.current !== null) return;
62
+ if (connection.status !== "connected" || restatedConnectionRef.current === connection) return;
63
+ if (window === null) return;
64
+ restatedConnectionRef.current = connection;
65
+ const stated = statedRef.current;
66
+ if (stated === null || interestsCovered(window.requests, stated)) return;
67
+ invoke(DEEP_AGENT_INTEREST_PROTOCOL, "set", [stated]).catch((error) => {
68
+ var _a;
69
+ (_a = onErrorRef.current) == null ? void 0 : _a.call(onErrorRef, error, "athena/interest");
70
+ });
71
+ }, [connection, invoke, window]);
72
+ useEffect(() => {
73
+ if (window === null || inflightRef.current) return;
74
+ const pageRequests = pageInterestRequests(window, pageSize);
75
+ if (pageRequests === null) return;
55
76
  const requested = requests !== servedRequestsRef.current;
56
77
  if (requested) {
57
78
  servedRequestsRef.current = requests;
@@ -64,32 +85,27 @@ function useDeepAgentWindowSync({
64
85
  if (chainRef.current.loads >= maxChainedLoads) return;
65
86
  chainRef.current.loads += 1;
66
87
  }
67
- const command = buildHistoryLoadCommand({ window });
68
- if (command === null) return;
69
- inflightRef.current = command.beforeIndex;
88
+ const page = window.pages + 1;
89
+ const request = pageRequests[pageRequests.length - 1];
90
+ inflightRef.current = true;
70
91
  setLoading(true);
71
92
  const startedAt = nowRef.current();
72
- Promise.resolve(sendCommand(command)).then((payload) => {
93
+ invoke(DEEP_AGENT_INTEREST_PROTOCOL, "set", [pageRequests]).then(() => {
73
94
  var _a;
95
+ statedRef.current = pageRequests;
74
96
  (_a = onHistoryLoadRef.current) == null ? void 0 : _a.call(onHistoryLoadRef, {
75
- beforeIndex: command.beforeIndex,
76
- limit: command.limit,
77
- result: readHistoryLoadResult(payload),
97
+ page,
98
+ request,
78
99
  durationMs: Math.max(0, Math.round(nowRef.current() - startedAt))
79
100
  });
80
101
  }).catch((error) => {
81
102
  var _a;
82
- (_a = onErrorRef.current) == null ? void 0 : _a.call(onErrorRef, error, "history/load");
103
+ (_a = onErrorRef.current) == null ? void 0 : _a.call(onErrorRef, error, "athena/interest");
83
104
  }).finally(() => {
84
- var _a;
85
- inflightRef.current = null;
86
- if (!aliveRef.current) return;
87
- setLoading(false);
88
- if (((_a = windowRef.current) == null ? void 0 : _a.start) !== command.beforeIndex) {
89
- setSettledLoads((count) => count + 1);
90
- }
105
+ inflightRef.current = false;
106
+ if (aliveRef.current) setLoading(false);
91
107
  });
92
- }, [nearTop, nearTopEpoch, requests, settledLoads, window, sendCommand, maxChainedLoads]);
108
+ }, [nearTop, nearTopEpoch, requests, window, loading, invoke, maxChainedLoads, pageSize]);
93
109
  useEffect(() => {
94
110
  var _a;
95
111
  if (window === null || toolOutputs === void 0) return;
@@ -123,11 +139,15 @@ function useDeepAgentWindowSync({
123
139
  const loadOlder = useCallback(() => {
124
140
  setRequests((count) => count + 1);
125
141
  }, []);
126
- return { window, olderCount: (window == null ? void 0 : window.start) ?? 0, loading, loadOlder };
142
+ const canLoadOlder = useMemo(
143
+ () => window !== null && pageInterestRequests(window, pageSize) !== null,
144
+ [window, pageSize]
145
+ );
146
+ return { window, hasOlder: (window == null ? void 0 : window.hasOlder) ?? false, canLoadOlder, loading, loadOlder };
127
147
  }
128
148
  export {
129
149
  DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,
130
- useDeepAgentMessagesWindow,
150
+ useDeepAgentMessageWindow,
131
151
  useDeepAgentWindowSync
132
152
  };
133
153
  //# sourceMappingURL=use-deep-agent-window-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-deep-agent-window-sync.js","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import { useStatewireSendCommand, useStatewireState } from '@assistant-ui/react-statewire';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY } from './generated/runconfig-contract';\nimport {\n buildHistoryLoadCommand,\n buildToolOutputCommand,\n type DeepAgentMessagesWindow,\n type HistoryLoadResult,\n readDeepAgentMessagesWindow,\n readHistoryLoadResult,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One `history/load` round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n beforeIndex: number;\n limit: number;\n /** The host's answer, or `null` when it was not a history-load result. */\n result: HistoryLoadResult | null;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** A `history/load` settled (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read command failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'history/load' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The lane, or `null` on a wire that is not windowed (both halves are inert). */\n window: DeepAgentMessagesWindow | null;\n /** Messages older than the loaded window the server still holds. */\n olderCount: number;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op on a wire that is not windowed or at the beginning. */\n loadOlder: () => void;\n}\n\n/** The raw lane, selected without derivation (selectors compare by identity). */\nfunction selectMessagesWindowLane(state: unknown): unknown {\n return typeof state === 'object' && state !== null\n ? (state as Record<string, unknown>)[DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY]\n : undefined;\n}\n\n/** The `messagesWindow` lane of the nearest statewire thread, or `null` when the wire is not windowed. */\nexport function useDeepAgentMessagesWindow(): DeepAgentMessagesWindow | null {\n const lane = useStatewireState(selectMessagesWindowLane);\n return useMemo(\n () => readDeepAgentMessagesWindow({ [DEEP_AGENT_MESSAGES_WINDOW_STATE_KEY]: lane }),\n [lane]\n );\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\n\n/**\n * The client half of the windowed wire, shared by every surface that declares\n * a message window (`useDeepAgentThread({ messageWindow })`) — mounted once\n * per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the `messagesWindow` lane says older\n * messages exist, this sends `history/load` for the next page — the host\n * prepends it as ops for this client alone — chaining at most\n * `maxChainedLoads` pages per approach; `loadOlder` asks for one page on\n * demand (an edge row's button). Never two loads in flight.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n *\n * On a thread whose wire is not windowed (no lane) both halves are inert.\n */\nexport function useDeepAgentWindowSync({\n messages,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const sendCommand = useStatewireSendCommand();\n const window = useDeepAgentMessagesWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n // Bumped when a page settled AFTER its ops moved the lane (the host's\n // order: prepend, then answer), so the chain re-evaluates against the moved\n // window instead of waiting for another signal.\n const [settledLoads, setSettledLoads] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef<number | null>(null);\n const chainRef = useRef({ epoch: 0, loads: 0 });\n const aliveRef = useRef(true);\n const windowRef = useRef(window);\n windowRef.current = window;\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (window === null || window.start === 0 || inflightRef.current !== null) return;\n const requested = requests !== servedRequestsRef.current;\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1 };\n } else {\n if (!nearTop) return;\n if (chainRef.current.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0 };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n const command = buildHistoryLoadCommand({ window });\n if (command === null) return;\n inflightRef.current = command.beforeIndex;\n setLoading(true);\n const startedAt = nowRef.current();\n Promise.resolve(sendCommand(command))\n .then((payload) => {\n onHistoryLoadRef.current?.({\n beforeIndex: command.beforeIndex,\n limit: command.limit,\n result: readHistoryLoadResult(payload),\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'history/load');\n })\n .finally(() => {\n inflightRef.current = null;\n if (!aliveRef.current) return;\n setLoading(false);\n if (windowRef.current?.start !== command.beforeIndex) {\n setSettledLoads((count) => count + 1);\n }\n });\n }, [nearTop, nearTopEpoch, requests, settledLoads, window, sendCommand, maxChainedLoads]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n return { window, olderCount: window?.start ?? 0, loading, loadOlder };\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"use-deep-agent-window-sync.js","sources":["../../../../../agent-runtime/src/use-deep-agent-window-sync.ts"],"sourcesContent":["import type { StatewireThread } from '@assistant-ui/react-statewire';\nimport { useAuiState } from '@assistant-ui/store';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { DEEP_AGENT_INTEREST_PROTOCOL } from './generated/runconfig-contract';\nimport {\n buildToolOutputCommand,\n type DeepAgentInterestRequest,\n type DeepAgentMessageWindow,\n interestsCovered,\n pageInterestRequests,\n readDeepAgentMessageWindow,\n readToolOutputResult,\n readTruncatedToolOutputArtifact,\n} from './message-window';\nimport { hasStatewireThreadExtras } from './thread-extras';\nimport type { DeepAgentToolOutputStore } from './tool-outputs';\n\n/**\n * Pages of older history chained per approach to the top. A renderer lowers\n * its near-top level once prepended content has pushed the first message out\n * of its band; this bounds the case where it cannot (no viewport to scroll,\n * a list too short to overflow) so a 2,000-message thread never streams whole.\n */\nexport const DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS = 3;\n\n/** The converted thread messages the tool-output half scans (web and native `ThreadMessage` both satisfy it). */\nexport interface DeepAgentWindowSyncMessage {\n readonly id: string;\n readonly content: readonly { readonly type: string; readonly artifact?: unknown }[];\n}\n\n/** One page interest round trip, for the host's telemetry. */\nexport interface DeepAgentHistoryLoadEvent {\n /** The page's ordinal (`1` extends the head). */\n page: number;\n request: DeepAgentInterestRequest;\n durationMs: number;\n}\n\nexport interface UseDeepAgentWindowSyncOptions {\n /**\n * The converted thread messages — read by the host through its platform\n * `useAuiState((s) => s.thread.messages)`, so this hook imports neither\n * `@assistant-ui/react` nor `@assistant-ui/react-native`.\n */\n messages: readonly DeepAgentWindowSyncMessage[];\n /** Messages per page; the thread's window size by default. */\n pageSize?: number;\n /**\n * Full tool outputs fetched back for cut tool messages; the same store the\n * thread converts with (`useDeepAgentThread({ toolOutputs })`). Omitted, the\n * tool-output half is inert (a surface that never shows a cut output whole).\n */\n toolOutputs?: DeepAgentToolOutputStore | undefined;\n /**\n * The renderer's report that the top of the LOADED history is near — a\n * level, not an edge: while it holds and older messages exist, pages load\n * one after another (bounded by `maxChainedLoads` per approach). Omitted for\n * hosts with only a manual affordance (`loadOlder`).\n */\n nearTop?: boolean;\n /** Bumped on every rise of `nearTop` (and every explicit request), so the chain bound is per approach. */\n nearTopEpoch?: number;\n /**\n * Whether a message's content is mounted right now, so lazy fetches (cut\n * tool outputs) target what the user can see rather than the whole loaded\n * history. Omitted: every message counts as mounted (the flat renderers).\n */\n isMessageMounted?: ((messageId: string) => boolean) | undefined;\n maxChainedLoads?: number;\n /** A page interest resolved (telemetry). */\n onHistoryLoad?: ((event: DeepAgentHistoryLoadEvent) => void) | undefined;\n /** A read failed; the sync itself recovers (the pending marks are released). */\n onError?: ((error: unknown, command: 'athena/interest' | 'history/tool_output') => void) | undefined;\n now?: () => number;\n}\n\nexport interface DeepAgentWindowSyncState {\n /** The joined window, or `null` while the head interest has not resolved (both halves are inert). */\n window: DeepAgentMessageWindow | null;\n /** Whether the host holds messages older than the loaded window. */\n hasOlder: boolean;\n /**\n * Whether the next page can be asked for: older messages exist and the\n * host's interest cap has room for them. `hasOlder && !canLoadOlder` is the\n * depth limit (`MAX_INTERESTS × MAX_MESSAGE_WINDOW` messages loaded in one\n * connection) — an edge row says so instead of offering a dead button.\n */\n canLoadOlder: boolean;\n /** A page of older history is in flight. */\n loading: boolean;\n /** Ask for the next page of older history now (an edge row's button, a keypress). A no-op before the head resolved or at the beginning. */\n loadOlder: () => void;\n}\n\nconst everyMessageMounted = (): boolean => true;\nconst defaultNow = (): number => Date.now();\nconst noopSubscribe = () => () => {};\n\n/** The statewire extras of the nearest aui thread; throws on a non-statewire thread like the library's own hooks. */\nconst useStatewireExtras = (): StatewireThread.Extras =>\n useAuiState((s) => {\n if (!hasStatewireThreadExtras(s.thread.extras)) {\n throw new Error('useDeepAgentWindowSync requires a statewire thread');\n }\n return s.thread.extras as StatewireThread.Extras;\n });\n\n/** The joined interest window of the nearest statewire thread. */\nexport function useDeepAgentMessageWindow(): DeepAgentMessageWindow | null {\n const documents = useStatewireExtras().documents;\n const mounted = useSyncExternalStore(\n documents?.subscribe ?? noopSubscribe,\n () => documents?.list(),\n () => documents?.list()\n );\n return useMemo(() => readDeepAgentMessageWindow(mounted), [mounted]);\n}\n\n/**\n * The client half of the interest window, shared by every surface — mounted\n * once per runtime, inside its aui provider.\n *\n * - **Older history.** While the host renderer reports the top of the loaded\n * history near (`nearTop`) and the window says older messages exist, this\n * re-states the interests with one more page (anchored at the window's\n * first message) — the host mounts its documents for this client alone —\n * chaining at most `maxChainedLoads` pages per approach; `loadOlder` asks\n * for one page on demand (an edge row's button). Never two loads in flight.\n * A reconnect whose hello does not carry the interests this mount last\n * stated (the host remembers a client id's view across its attaches; a new\n * host instance does not) re-states them.\n * - **Cut tool outputs.** Tool cards whose output the wire carried cut\n * (`artifact._athena_content_truncated`) get it fetched whole through\n * `history/tool_output` once their message is mounted; the converter puts\n * it back (`toolOutputs`), so the card re-renders complete. An output the\n * host replaced since (the marker's `chars` changed) is fetched again.\n */\nexport function useDeepAgentWindowSync({\n messages,\n pageSize,\n toolOutputs,\n nearTop = false,\n nearTopEpoch = 0,\n isMessageMounted = everyMessageMounted,\n maxChainedLoads = DEEP_AGENT_MAX_CHAINED_HISTORY_LOADS,\n onHistoryLoad,\n onError,\n now = defaultNow,\n}: UseDeepAgentWindowSyncOptions): DeepAgentWindowSyncState {\n const { sendCommand, invoke, connection } = useStatewireExtras();\n const window = useDeepAgentMessageWindow();\n const [loading, setLoading] = useState(false);\n const [requests, setRequests] = useState(0);\n const servedRequestsRef = useRef(0);\n const inflightRef = useRef(false);\n const chainRef = useRef({ epoch: 0, loads: 0 });\n const aliveRef = useRef(true);\n // The interests this mount last stated, re-stated on the next connected\n // session (a hello resets the documents) so a reconnect keeps the loaded history.\n const statedRef = useRef<DeepAgentInterestRequest[] | null>(null);\n const restatedConnectionRef = useRef<unknown>(null);\n // Outputs already asked for and answered by this mount — fetched, refused,\n // or failed — by the `chars` they were asked for. The converter re-runs on\n // every wire change, and the store is a bounded LRU: without this memory a\n // refused read would leave on every pass, and once a transcript holds more\n // cut outputs than the store retains, each fetch would evict a still-loaded\n // output and the next pass would fetch it again, forever. An evicted output\n // renders its cut text (the REST display limit) rather than re-entering the\n // loop; a marker whose `chars` moved (the host replaced the output) is asked\n // for again.\n const answeredRef = useRef(new Map<string, number>());\n const onHistoryLoadRef = useRef(onHistoryLoad);\n onHistoryLoadRef.current = onHistoryLoad;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const nowRef = useRef(now);\n nowRef.current = now;\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (connection.status !== 'connected' || restatedConnectionRef.current === connection) return;\n // Decided once per connected session, on the hello's interest document.\n if (window === null) return;\n restatedConnectionRef.current = connection;\n const stated = statedRef.current;\n if (stated === null || interestsCovered(window.requests, stated)) return;\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [stated]).catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n });\n }, [connection, invoke, window]);\n\n useEffect(() => {\n if (window === null || inflightRef.current) return;\n const pageRequests = pageInterestRequests(window, pageSize);\n if (pageRequests === null) return;\n const requested = requests !== servedRequestsRef.current;\n if (requested) {\n // An explicit ask re-arms the chain for this approach.\n servedRequestsRef.current = requests;\n chainRef.current = { epoch: nearTopEpoch, loads: 1 };\n } else {\n if (!nearTop) return;\n if (chainRef.current.epoch !== nearTopEpoch) {\n chainRef.current = { epoch: nearTopEpoch, loads: 0 };\n }\n if (chainRef.current.loads >= maxChainedLoads) return;\n chainRef.current.loads += 1;\n }\n const page = window.pages + 1;\n const request = pageRequests[pageRequests.length - 1] as DeepAgentInterestRequest;\n inflightRef.current = true;\n setLoading(true);\n const startedAt = nowRef.current();\n invoke(DEEP_AGENT_INTEREST_PROTOCOL, 'set', [pageRequests])\n .then(() => {\n statedRef.current = pageRequests;\n onHistoryLoadRef.current?.({\n page,\n request,\n durationMs: Math.max(0, Math.round(nowRef.current() - startedAt)),\n });\n })\n .catch((error: unknown) => {\n onErrorRef.current?.(error, 'athena/interest');\n })\n .finally(() => {\n inflightRef.current = false;\n if (aliveRef.current) setLoading(false);\n });\n // `loading` re-arms the chain once a page settled after its documents moved the window.\n }, [nearTop, nearTopEpoch, requests, window, loading, invoke, maxChainedLoads, pageSize]);\n\n useEffect(() => {\n if (window === null || toolOutputs === undefined) return;\n for (const message of messages) {\n if (!isMessageMounted(message.id)) continue;\n for (const part of message.content) {\n if (part.type !== 'tool-call') continue;\n const marker = readTruncatedToolOutputArtifact(part.artifact);\n if (marker === null || toolOutputs.isPending(marker.messageId)) continue;\n // Fetched for this very length already; a different length means the\n // host replaced the output under the same id since.\n if (toolOutputs.entry(marker.messageId)?.chars === marker.chars) continue;\n if (answeredRef.current.get(marker.messageId) === marker.chars) continue;\n const { messageId, chars } = marker;\n toolOutputs.markPending(messageId);\n Promise.resolve(sendCommand(buildToolOutputCommand({ messageId })))\n .then((payload) => {\n answeredRef.current.set(messageId, chars);\n const result = readToolOutputResult(payload);\n if (result === null) {\n toolOutputs.clearPending(messageId);\n return;\n }\n toolOutputs.set(result.messageId, { content: result.content, chars });\n })\n .catch((error: unknown) => {\n answeredRef.current.set(messageId, chars);\n toolOutputs.clearPending(messageId);\n onErrorRef.current?.(error, 'history/tool_output');\n });\n }\n }\n }, [messages, isMessageMounted, window, sendCommand, toolOutputs]);\n\n const loadOlder = useCallback(() => {\n setRequests((count) => count + 1);\n }, []);\n\n const canLoadOlder = useMemo(\n () => window !== null && pageInterestRequests(window, pageSize) !== null,\n [window, pageSize]\n );\n\n return { window, hasOlder: window?.hasOlder ?? false, canLoadOlder, loading, loadOlder };\n}\n"],"names":["_a"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const version = "0.22.4";
3
+ const version = "0.23.1";
4
4
  const packageJson = {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
- const version = "0.22.4";
1
+ const version = "0.23.1";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaContext.cjs","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAYO,MAAM,gBAAgBA,MAAAA,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAMC,MAAAA,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;;;"}
1
+ {"version":3,"file":"AthenaContext.cjs","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n /** The host's live token resolver, for SDK hooks that call agora's REST surface directly. */\n getToken?: AthenaStatewireTokenGetter;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAeO,MAAM,gBAAgBA,MAAAA,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAMC,MAAAA,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;;;"}
@@ -1,7 +1,10 @@
1
+ import type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';
1
2
  import type { AthenaProviderConfig } from './config';
2
3
  import type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';
3
4
  export interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {
4
5
  backendUrl: string;
6
+ /** The host's live token resolver, for SDK hooks that call agora's REST surface directly. */
7
+ getToken?: AthenaStatewireTokenGetter;
5
8
  appUrl: string;
6
9
  enabledToolkits: string[];
7
10
  linkClicks?: AthenaLinkClickOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaContext.js","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":[],"mappings":";AAYO,MAAM,gBAAgB,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAM,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;"}
1
+ {"version":3,"file":"AthenaContext.js","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n /** The host's live token resolver, for SDK hooks that call agora's REST surface directly. */\n getToken?: AthenaStatewireTokenGetter;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":[],"mappings":";AAeO,MAAM,gBAAgB,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAM,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;"}
@@ -7,16 +7,17 @@ require("../packages/agent-runtime/src/generated/runconfig-contract.cjs");
7
7
  require("@assistant-ui/tap");
8
8
  require("statewire");
9
9
  require("../packages/agent-runtime/src/statewire-suspended.cjs");
10
+ require("../packages/agent-runtime/src/conversation-list.cjs");
10
11
  require("@tanstack/react-query");
11
12
  require("../packages/agent-runtime/src/statewire-state.cjs");
12
13
  require("../packages/agent-runtime/src/messages.cjs");
13
- require("@assistant-ui/react-statewire");
14
14
  require("@assistant-ui/store");
15
15
  const toolOutputs = require("../packages/agent-runtime/src/tool-outputs.cjs");
16
16
  require("../packages/agent-runtime/src/quota-safe-local-storage-session.cjs");
17
17
  const threadSnapshotCache = require("../packages/agent-runtime/src/thread-snapshot-cache.cjs");
18
18
  require("../packages/agent-runtime/src/statewire-attach-observer.cjs");
19
19
  const threadStatus = require("../packages/agent-runtime/src/thread-status.cjs");
20
+ require("@assistant-ui/react-statewire");
20
21
  require("@assistant-ui/core");
21
22
  require("../packages/agent-runtime/src/thread-handoff.cjs");
22
23
  const athenaUrls = require("../lib/athena-urls.cjs");
@@ -53,6 +54,7 @@ const useAthenaConfigValue = ({
53
54
  appUrl,
54
55
  apiKey,
55
56
  token,
57
+ getToken,
56
58
  enabledToolkits,
57
59
  linkClicks,
58
60
  citationLinks
@@ -63,6 +65,8 @@ const useAthenaConfigValue = ({
63
65
  citationLinksRef.current = citationLinks;
64
66
  const tokenRef = react.useRef(token);
65
67
  tokenRef.current = token;
68
+ const getTokenRef = react.useRef(getToken);
69
+ getTokenRef.current = getToken;
66
70
  return react.useMemo(
67
71
  () => ({
68
72
  backendUrl,
@@ -72,6 +76,9 @@ const useAthenaConfigValue = ({
72
76
  get token() {
73
77
  return tokenRef.current;
74
78
  },
79
+ get getToken() {
80
+ return getTokenRef.current;
81
+ },
75
82
  get linkClicks() {
76
83
  return linkClicksRef.current;
77
84
  },
@@ -82,11 +89,11 @@ const useAthenaConfigValue = ({
82
89
  [backendUrl, appUrl, apiKey, enabledToolkits]
83
90
  );
84
91
  };
85
- function AthenaStatewireStandalone({
86
- children,
92
+ function AthenaStatewireRuntimeMount({
93
+ threadId,
94
+ isNewChat,
95
+ onPublish,
87
96
  syncUrl,
88
- backendUrl,
89
- appUrl,
90
97
  apiKey,
91
98
  token,
92
99
  getToken,
@@ -101,26 +108,17 @@ function AthenaStatewireStandalone({
101
108
  systemPrompt,
102
109
  appId,
103
110
  extraRunConfig,
104
- threadId: threadIdProp,
105
- isNewChatOverride,
106
111
  snapshotCache,
107
- toolOutputs: toolOutputs2,
108
- linkClicks,
109
- citationLinks
112
+ toolOutputs: toolOutputs2
110
113
  }) {
111
- const generatedIdRef = react.useRef(null);
112
- if (generatedIdRef.current === null) {
113
- generatedIdRef.current = mintThreadId.mintThreadId();
114
- }
115
- const threadId = threadIdProp ?? generatedIdRef.current;
116
114
  const [lifecycle, dispatchLifecycle] = react.useReducer(
117
115
  statewireLifecycle.statewireLifecycleReducer,
118
116
  statewireLifecycle.initialStatewireLifecycle
119
117
  );
120
- const aui = useAthenaStatewireRuntime.useAthenaStatewireRuntime({
118
+ const client = useAthenaStatewireRuntime.useAthenaStatewireRuntime({
121
119
  syncUrl,
122
120
  threadId,
123
- isNewChat: isNewChatOverride ?? !threadIdProp,
121
+ isNewChat,
124
122
  apiKey,
125
123
  token,
126
124
  getToken,
@@ -151,7 +149,6 @@ function AthenaStatewireStandalone({
151
149
  dispatchLifecycle({ type: "raw-connection", reconnect: connection.reconnect });
152
150
  }
153
151
  });
154
- const clientTools = useAthenaStatewireRuntime.useStatewireClientTools(frontendTools);
155
152
  const dismissError = react.useCallback(
156
153
  () => dispatchLifecycle({ type: "error", error: null }),
157
154
  []
@@ -165,19 +162,66 @@ function AthenaStatewireStandalone({
165
162
  }),
166
163
  [lifecycle, dismissError]
167
164
  );
165
+ const snapshot = react.useMemo(
166
+ () => ({ threadId, isNewChat, client, lifecycle: lifecycleValue }),
167
+ [threadId, isNewChat, client, lifecycleValue]
168
+ );
169
+ react.useLayoutEffect(() => {
170
+ onPublish(snapshot);
171
+ }, [onPublish, snapshot]);
172
+ return null;
173
+ }
174
+ function AthenaStatewireStandalone({
175
+ children,
176
+ backendUrl,
177
+ appUrl,
178
+ threadId: threadIdProp,
179
+ threadList,
180
+ linkClicks,
181
+ citationLinks,
182
+ ...runtimeProps
183
+ }) {
184
+ const generatedIdRef = react.useRef(null);
185
+ if (generatedIdRef.current === null) {
186
+ generatedIdRef.current = mintThreadId.mintThreadId();
187
+ }
188
+ const threadId = threadIdProp ?? generatedIdRef.current;
189
+ const isNewChat = (threadList == null ? void 0 : threadList.isNewChat) ?? !threadIdProp;
190
+ const [published, setPublished] = react.useState(null);
191
+ const clientTools = useAthenaStatewireRuntime.useStatewireClientTools(runtimeProps.frontendTools);
168
192
  const athenaConfig = useAthenaConfigValue({
169
193
  backendUrl,
170
194
  appUrl,
171
- apiKey,
172
- token,
173
- enabledToolkits: tools,
195
+ apiKey: runtimeProps.apiKey,
196
+ token: runtimeProps.token,
197
+ getToken: runtimeProps.getToken,
198
+ enabledToolkits: runtimeProps.tools,
174
199
  linkClicks,
175
200
  citationLinks
176
201
  });
177
- return /* @__PURE__ */ jsxRuntime.jsx(react$1.AuiProvider, { value: aui, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaContext.AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxRuntime.jsx(threadIdContext.AthenaStatewireThreadIdContext.Provider, { value: threadId, children: /* @__PURE__ */ jsxRuntime.jsx(statewireLifecycleContext.AthenaStatewireLifecycleContext.Provider, { value: lifecycleValue, children: /* @__PURE__ */ jsxRuntime.jsx(threadStatus.DeepAgentConnectionContext.Provider, { value: lifecycleValue.connection, children: /* @__PURE__ */ jsxRuntime.jsx(statewireWindowContext.StatewireToolOutputsContext.Provider, { value: toolOutputs2, children: /* @__PURE__ */ jsxRuntime.jsxs(tooltip.TooltipProvider, { children: [
178
- /* @__PURE__ */ jsxRuntime.jsx(StatewireClientToolBridge.StatewireClientToolBridge, { tools: clientTools, threadId }),
202
+ const scope = published && /* @__PURE__ */ jsxRuntime.jsx(react$1.AuiProvider, { value: published.client, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaContext.AthenaContext.Provider, { value: athenaConfig, children: /* @__PURE__ */ jsxRuntime.jsx(threadIdContext.AthenaStatewireThreadIdContext.Provider, { value: published.threadId, children: /* @__PURE__ */ jsxRuntime.jsx(statewireLifecycleContext.AthenaStatewireLifecycleContext.Provider, { value: published.lifecycle, children: /* @__PURE__ */ jsxRuntime.jsx(threadStatus.DeepAgentConnectionContext.Provider, { value: published.lifecycle.connection, children: /* @__PURE__ */ jsxRuntime.jsx(statewireWindowContext.StatewireToolOutputsContext.Provider, { value: runtimeProps.toolOutputs, children: /* @__PURE__ */ jsxRuntime.jsxs(tooltip.TooltipProvider, { children: [
203
+ /* @__PURE__ */ jsxRuntime.jsx(StatewireClientToolBridge.StatewireClientToolBridge, { tools: clientTools, threadId: published.threadId }),
179
204
  children
180
205
  ] }) }) }) }) }) }) });
206
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
207
+ /* @__PURE__ */ jsxRuntime.jsx(
208
+ AthenaStatewireRuntimeMount,
209
+ {
210
+ threadId,
211
+ isNewChat,
212
+ onPublish: setPublished,
213
+ ...runtimeProps
214
+ },
215
+ threadId
216
+ ),
217
+ threadList && published ? /* @__PURE__ */ jsxRuntime.jsx(
218
+ threadIdContext.AthenaThreadIdContext.Provider,
219
+ {
220
+ value: published.isNewChat ? void 0 : published.threadId,
221
+ children: scope
222
+ }
223
+ ) : scope
224
+ ] });
181
225
  }
182
226
  function AthenaStatewireWithThreadList({
183
227
  children,
@@ -188,6 +232,7 @@ function AthenaStatewireWithThreadList({
188
232
  token,
189
233
  getToken,
190
234
  initialThreadId,
235
+ includePullRequests,
191
236
  ...standaloneProps
192
237
  }) {
193
238
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -200,6 +245,8 @@ function AthenaStatewireWithThreadList({
200
245
  getToken,
201
246
  appId,
202
247
  initialThreadId,
248
+ includePullRequests,
249
+ snapshotCache: standaloneProps.snapshotCache,
203
250
  children: /* @__PURE__ */ jsxRuntime.jsx(
204
251
  AthenaStatewireActiveThreadHost,
205
252
  {
@@ -222,34 +269,26 @@ function AthenaStatewireActiveThreadHost({
222
269
  }) {
223
270
  const list = statewireThreadList.useAthenaStatewireThreadList();
224
271
  if (!list) return null;
225
- return /* @__PURE__ */ jsxRuntime.jsx(
226
- threadIdContext.AthenaThreadIdContext.Provider,
272
+ return /* @__PURE__ */ jsxRuntime.jsxs(
273
+ AthenaStatewireStandalone,
227
274
  {
228
- value: list.isNewChat ? void 0 : list.activeThreadId,
229
- children: /* @__PURE__ */ jsxRuntime.jsxs(
230
- AthenaStatewireStandalone,
231
- {
232
- threadId: list.activeThreadId,
233
- isNewChatOverride: list.isNewChat,
234
- ...standaloneProps,
235
- children: [
236
- /* @__PURE__ */ jsxRuntime.jsx(statewireThreadList.StatewireThreadTitlePoller, {}),
237
- /* @__PURE__ */ jsxRuntime.jsx(AssetPanelThreadSync, {}),
238
- children
239
- ]
240
- },
241
- list.activeThreadId
242
- )
275
+ threadId: list.activeThreadId,
276
+ threadList: { isNewChat: list.isNewChat },
277
+ ...standaloneProps,
278
+ children: [
279
+ /* @__PURE__ */ jsxRuntime.jsx(statewireThreadList.StatewireThreadTitlePoller, {}),
280
+ /* @__PURE__ */ jsxRuntime.jsx(AssetPanelThreadSync, {}),
281
+ children
282
+ ]
243
283
  }
244
284
  );
245
285
  }
246
286
  function AssetPanelThreadSync() {
247
- const list = statewireThreadList.useAthenaStatewireThreadList();
287
+ const threadId = threadIdContext.useAthenaStatewireThreadId();
248
288
  const setCurrentThread = assetPanelStore.useAssetPanelStore((s) => s.setCurrentThread);
249
- const activeThreadId = (list == null ? void 0 : list.activeThreadId) ?? null;
250
289
  react.useEffect(() => {
251
- setCurrentThread(activeThreadId);
252
- }, [activeThreadId, setCurrentThread]);
290
+ setCurrentThread(threadId);
291
+ }, [threadId, setCurrentThread]);
253
292
  return null;
254
293
  }
255
294
  function AthenaProvider({
@@ -276,6 +315,7 @@ function AthenaProvider({
276
315
  appId,
277
316
  threadId: threadIdProp,
278
317
  enableThreadList = false,
318
+ threadListIncludePullRequests = true,
279
319
  theme,
280
320
  linkClicks,
281
321
  citationLinks,
@@ -390,7 +430,15 @@ function AthenaProvider({
390
430
  linkClicks,
391
431
  citationLinks
392
432
  };
393
- const inner = enableThreadList ? /* @__PURE__ */ jsxRuntime.jsx(AthenaStatewireWithThreadList, { ...statewireProps, initialThreadId: threadIdProp, children }) : /* @__PURE__ */ jsxRuntime.jsx(AthenaStatewireStandalone, { ...statewireProps, threadId: threadIdProp, children });
433
+ const inner = enableThreadList ? /* @__PURE__ */ jsxRuntime.jsx(
434
+ AthenaStatewireWithThreadList,
435
+ {
436
+ ...statewireProps,
437
+ initialThreadId: threadIdProp,
438
+ includePullRequests: threadListIncludePullRequests,
439
+ children
440
+ }
441
+ ) : /* @__PURE__ */ jsxRuntime.jsx(AthenaStatewireStandalone, { ...statewireProps, threadId: threadIdProp, children });
394
442
  return /* @__PURE__ */ jsxRuntime.jsx(
395
443
  "div",
396
444
  {