@assistant-ui/react 0.15.29 → 0.15.31

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 (370) hide show
  1. package/dist/cloud-renderer/CloudRendererHost.d.ts.map +1 -1
  2. package/dist/cloud-renderer/CloudRendererHost.js +1 -2
  3. package/dist/cloud-renderer/CloudRendererHost.js.map +1 -1
  4. package/dist/context/providers/AttachmentByIndexProvider.js +1 -2
  5. package/dist/context/providers/ChainOfThoughtByIndicesProvider.js +1 -2
  6. package/dist/context/providers/MessageByIndexProvider.js +1 -2
  7. package/dist/context/providers/PartByIndexProvider.js +1 -2
  8. package/dist/context/providers/SuggestionByIndexProvider.js +1 -2
  9. package/dist/context/providers/TextMessagePartProvider.js +1 -2
  10. package/dist/context/providers/ThreadListItemProvider.js +1 -2
  11. package/dist/context/stores/ThreadViewport.d.ts +8 -0
  12. package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
  13. package/dist/context/stores/ThreadViewport.js +24 -8
  14. package/dist/context/stores/ThreadViewport.js.map +1 -1
  15. package/dist/index.d.ts +10 -9
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -9
  18. package/dist/internal.d.ts +1 -1
  19. package/dist/internal.d.ts.map +1 -1
  20. package/dist/internal.js +1 -1
  21. package/dist/internal.js.map +1 -1
  22. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts +1 -1
  23. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  24. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  25. package/dist/primitives/actionBar/ActionBarCopy.d.ts +1 -1
  26. package/dist/primitives/actionBar/ActionBarEdit.d.ts +1 -1
  27. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +1 -1
  28. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +1 -1
  29. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +1 -1
  30. package/dist/primitives/actionBar/ActionBarReload.d.ts +1 -1
  31. package/dist/primitives/actionBar/ActionBarRoot.d.ts +1 -1
  32. package/dist/primitives/actionBar/ActionBarSpeak.d.ts +1 -1
  33. package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts +1 -1
  34. package/dist/primitives/attachment/AttachmentRemove.d.ts +1 -1
  35. package/dist/primitives/attachment/AttachmentRoot.d.ts +1 -1
  36. package/dist/primitives/attachment/AttachmentThumb.d.ts +1 -1
  37. package/dist/primitives/branchPicker/BranchPickerNext.d.ts +1 -1
  38. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +1 -1
  39. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts +1 -1
  40. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +1 -1
  41. package/dist/primitives/chainOfThought/ChainOfThoughtParts.js +1 -2
  42. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +1 -1
  43. package/dist/primitives/composer/ComposerAddAttachment.d.ts +1 -1
  44. package/dist/primitives/composer/ComposerAttachments.js +1 -2
  45. package/dist/primitives/composer/ComposerCancel.d.ts +1 -1
  46. package/dist/primitives/composer/ComposerDictate.d.ts +1 -1
  47. package/dist/primitives/composer/ComposerDictationTranscript.d.ts +1 -1
  48. package/dist/primitives/composer/ComposerIf.js +1 -2
  49. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  50. package/dist/primitives/composer/ComposerInput.js +3 -3
  51. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  52. package/dist/primitives/composer/ComposerQueue.js +1 -2
  53. package/dist/primitives/composer/ComposerQuote.d.ts +3 -3
  54. package/dist/primitives/composer/ComposerResume.d.ts +23 -0
  55. package/dist/primitives/composer/ComposerResume.d.ts.map +1 -0
  56. package/dist/primitives/composer/ComposerResume.js +34 -0
  57. package/dist/primitives/composer/ComposerResume.js.map +1 -0
  58. package/dist/primitives/composer/ComposerRoot.d.ts +1 -1
  59. package/dist/primitives/composer/ComposerSend.d.ts +1 -1
  60. package/dist/primitives/composer/ComposerStopDictation.d.ts +1 -1
  61. package/dist/primitives/composer/trigger/TriggerPopover.d.ts +1 -1
  62. package/dist/primitives/composer/trigger/TriggerPopoverBack.d.ts +1 -1
  63. package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts +2 -2
  64. package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts +2 -2
  65. package/dist/primitives/composer/trigger/index.d.ts +1 -1
  66. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts +6 -2
  67. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
  68. package/dist/primitives/composer/trigger/triggerSelectionResource.js +6 -3
  69. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  70. package/dist/primitives/composer.d.ts +1 -0
  71. package/dist/primitives/composer.d.ts.map +1 -1
  72. package/dist/primitives/composer.js +3 -1
  73. package/dist/primitives/composer.js.map +1 -1
  74. package/dist/primitives/error/ErrorMessage.d.ts +1 -1
  75. package/dist/primitives/error/ErrorRoot.d.ts +1 -1
  76. package/dist/primitives/message/MessageAttachments.js +1 -2
  77. package/dist/primitives/message/MessageRoot.d.ts +1 -1
  78. package/dist/primitives/messagePart/MessagePartImage.d.ts +1 -1
  79. package/dist/primitives/messagePart/MessagePartInProgress.js +1 -2
  80. package/dist/primitives/messagePart/MessagePartText.d.ts +1 -1
  81. package/dist/primitives/queueItem/QueueItemRemove.d.ts +1 -1
  82. package/dist/primitives/queueItem/QueueItemSteer.d.ts +1 -1
  83. package/dist/primitives/queueItem/QueueItemText.d.ts +1 -1
  84. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts +1 -1
  85. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts +1 -1
  86. package/dist/primitives/suggestion/SuggestionDescription.d.ts +1 -1
  87. package/dist/primitives/suggestion/SuggestionTitle.d.ts +1 -1
  88. package/dist/primitives/suggestion/SuggestionTrigger.d.ts +1 -1
  89. package/dist/primitives/thread/ThreadLoadEarlier.d.ts +1 -1
  90. package/dist/primitives/thread/ThreadMessages.js +1 -2
  91. package/dist/primitives/thread/ThreadRoot.d.ts +1 -1
  92. package/dist/primitives/thread/ThreadScrollToBottom.d.ts +1 -1
  93. package/dist/primitives/thread/ThreadSuggestion.d.ts +1 -1
  94. package/dist/primitives/thread/ThreadSuggestions.js +1 -2
  95. package/dist/primitives/thread/ThreadViewport.d.ts +1 -1
  96. package/dist/primitives/thread/ThreadViewportFooter.d.ts +1 -1
  97. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  98. package/dist/primitives/thread/useThreadViewportAutoScroll.js +36 -293
  99. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  100. package/dist/primitives/threadList/ThreadListItems.js +1 -2
  101. package/dist/primitives/threadList/ThreadListLoadMore.d.ts +1 -1
  102. package/dist/primitives/threadList/ThreadListNew.d.ts +1 -1
  103. package/dist/primitives/threadList/ThreadListRoot.d.ts +1 -1
  104. package/dist/primitives/threadListFocusGroup.d.ts +1 -1
  105. package/dist/primitives/threadListFocusGroup.d.ts.map +1 -1
  106. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +1 -1
  107. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +1 -1
  108. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts +1 -1
  109. package/dist/primitives/threadListItem/ThreadListItemTitle.js +1 -2
  110. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +1 -1
  111. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +2 -2
  112. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
  113. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js +2 -2
  114. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  115. package/dist/unstable/useComposerInput.js +1 -1
  116. package/dist/unstable/useComposerInput.js.map +1 -1
  117. package/dist/unstable/useComposerInputHistory.d.ts.map +1 -1
  118. package/dist/unstable/useComposerInputHistory.js +2 -2
  119. package/dist/unstable/useComposerInputHistory.js.map +1 -1
  120. package/dist/unstable/useLiveCompletionAdapter.d.ts.map +1 -1
  121. package/dist/unstable/useLiveCompletionAdapter.js +3 -2
  122. package/dist/unstable/useLiveCompletionAdapter.js.map +1 -1
  123. package/dist/utils/Primitive.d.ts +17 -17
  124. package/dist/utils/createActionButton.d.ts +1 -1
  125. package/package.json +14 -14
  126. package/src/adapters/OpenAIRealtimeVoiceAdapter.test.ts +14 -1
  127. package/src/cloud-renderer/CloudRendererHost.tsx +4 -2
  128. package/src/context/stores/ThreadViewport.ts +36 -8
  129. package/src/index.ts +11 -8
  130. package/src/internal.ts +1 -1
  131. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +1 -1
  132. package/src/model-context/makeAssistantVisible.test.tsx +25 -37
  133. package/src/primitives/actionBar/ActionBarCopy.test.tsx +57 -0
  134. package/src/primitives/actionBar/ActionBarExportMarkdown.test.tsx +24 -5
  135. package/src/primitives/assistantModal/AssistantModalRoot.test.tsx +1 -1
  136. package/src/primitives/composer/ComposerInput.focus-on-run-start.test.tsx +1 -1
  137. package/src/primitives/composer/ComposerInput.test.tsx +1 -0
  138. package/src/primitives/composer/ComposerInput.text-change.test.tsx +68 -0
  139. package/src/primitives/composer/ComposerInput.thread-scope.test.tsx +82 -0
  140. package/src/primitives/composer/ComposerInput.tsx +5 -4
  141. package/src/primitives/composer/ComposerResume.ts +36 -0
  142. package/src/primitives/composer/trigger/triggerSelectionResource.test.ts +30 -4
  143. package/src/primitives/composer/trigger/triggerSelectionResource.ts +16 -3
  144. package/src/primitives/composer/useAuiState.composer.test.tsx +84 -0
  145. package/src/primitives/composer.ts +1 -0
  146. package/src/primitives/thread/ThreadRoot.test.tsx +1 -1
  147. package/src/primitives/thread/ThreadViewport.thread-scope.test.tsx +51 -0
  148. package/src/primitives/thread/useThreadViewportAutoScroll.test.tsx +90 -0
  149. package/src/primitives/thread/useThreadViewportAutoScroll.ts +56 -488
  150. package/src/primitives/threadListItem/ThreadListItemUnarchive.test.tsx +52 -0
  151. package/src/primitives/threadListItem/ThreadListItemUnarchive.ts +2 -2
  152. package/src/tests/DataRenderers.test.tsx +1 -1
  153. package/src/tests/MessageParts.loading.test.tsx +1 -1
  154. package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +1 -1
  155. package/src/tests/RemoteThreadListRuntime.deferredProvider.test.tsx +4 -2
  156. package/src/tests/RemoteThreadListRuntime.reloadMainThread.test.tsx +4 -2
  157. package/src/tests/generative-ui.primitive.test.tsx +1 -1
  158. package/src/tests/local-runtime-queue.test.tsx +2 -2
  159. package/src/tests/messagePartSwitchRace.test.tsx +2 -2
  160. package/src/tests/messagePartTypeMismatch.test.tsx +1 -1
  161. package/src/tests/threadListItemIsRunning.test.tsx +5 -3
  162. package/src/tests/toolCallTiming.test.tsx +1 -1
  163. package/src/unstable/useComposerInput.test.tsx +1 -1
  164. package/src/unstable/useComposerInput.ts +1 -1
  165. package/src/unstable/useComposerInputHistory.test.tsx +10 -7
  166. package/src/unstable/useComposerInputHistory.thread-scope.test.tsx +123 -0
  167. package/src/unstable/useComposerInputHistory.ts +3 -2
  168. package/src/unstable/useLiveCompletionAdapter.test.tsx +44 -0
  169. package/src/unstable/useLiveCompletionAdapter.ts +3 -2
  170. package/src/unstable/webmcp/convertTools.test.ts +11 -1
  171. package/src/utils/hooks/useMediaQuery.test.tsx +35 -0
  172. package/src/utils/smooth/useSmooth.test.tsx +37 -10
  173. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts +0 -2
  174. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +0 -1
  175. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.js +0 -3
  176. package/dist/legacy-runtime/RuntimeAdapter.d.ts +0 -2
  177. package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +0 -1
  178. package/dist/legacy-runtime/RuntimeAdapter.js +0 -2
  179. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts +0 -2
  180. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +0 -1
  181. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js +0 -3
  182. package/dist/legacy-runtime/runtime/AssistantRuntime.d.ts +0 -3
  183. package/dist/legacy-runtime/runtime/AssistantRuntime.d.ts.map +0 -1
  184. package/dist/legacy-runtime/runtime/AssistantRuntime.js +0 -2
  185. package/dist/legacy-runtime/runtime/AttachmentRuntime.d.ts +0 -3
  186. package/dist/legacy-runtime/runtime/AttachmentRuntime.d.ts.map +0 -1
  187. package/dist/legacy-runtime/runtime/AttachmentRuntime.js +0 -2
  188. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts +0 -4
  189. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts.map +0 -1
  190. package/dist/legacy-runtime/runtime/ComposerRuntime.js +0 -2
  191. package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts +0 -3
  192. package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts.map +0 -1
  193. package/dist/legacy-runtime/runtime/RuntimeBindings.js +0 -0
  194. package/dist/legacy-runtime/runtime/RuntimePathTypes.d.ts +0 -2
  195. package/dist/legacy-runtime/runtime/RuntimePathTypes.d.ts.map +0 -1
  196. package/dist/legacy-runtime/runtime/RuntimePathTypes.js +0 -0
  197. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.d.ts +0 -5
  198. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.d.ts.map +0 -1
  199. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.js +0 -2
  200. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts +0 -4
  201. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts.map +0 -1
  202. package/dist/legacy-runtime/runtime/ThreadRuntime.js +0 -2
  203. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts +0 -2
  204. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts.map +0 -1
  205. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js +0 -3
  206. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts +0 -2
  207. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts.map +0 -1
  208. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js +0 -3
  209. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts +0 -2
  210. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts.map +0 -1
  211. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.js +0 -2
  212. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts +0 -2
  213. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts.map +0 -1
  214. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.js +0 -2
  215. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts +0 -2
  216. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts.map +0 -1
  217. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.js +0 -2
  218. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +0 -2
  219. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +0 -1
  220. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.js +0 -0
  221. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +0 -2
  222. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +0 -1
  223. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +0 -2
  224. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts +0 -2
  225. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts.map +0 -1
  226. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.js +0 -2
  227. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts +0 -2
  228. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts.map +0 -1
  229. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.js +0 -0
  230. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.d.ts +0 -2
  231. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.d.ts.map +0 -1
  232. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.js +0 -0
  233. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts +0 -2
  234. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts.map +0 -1
  235. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.js +0 -0
  236. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts +0 -2
  237. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts.map +0 -1
  238. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.js +0 -0
  239. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.d.ts +0 -2
  240. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.d.ts.map +0 -1
  241. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.js +0 -2
  242. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +0 -3
  243. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +0 -1
  244. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +0 -2
  245. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts +0 -2
  246. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +0 -1
  247. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +0 -2
  248. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.d.ts +0 -3
  249. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.d.ts.map +0 -1
  250. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.js +0 -2
  251. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts +0 -3
  252. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts.map +0 -1
  253. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js +0 -2
  254. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +0 -2
  255. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +0 -1
  256. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +0 -2
  257. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts +0 -2
  258. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts.map +0 -1
  259. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js +0 -3
  260. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +0 -2
  261. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +0 -1
  262. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +0 -3
  263. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts +0 -2
  264. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts.map +0 -1
  265. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js +0 -3
  266. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.d.ts +0 -2
  267. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.d.ts.map +0 -1
  268. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.js +0 -0
  269. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.d.ts +0 -2
  270. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.d.ts.map +0 -1
  271. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.js +0 -2
  272. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts +0 -4
  273. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts.map +0 -1
  274. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js +0 -2
  275. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +0 -3
  276. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +0 -1
  277. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +0 -2
  278. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts +0 -2
  279. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts.map +0 -1
  280. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js +0 -2
  281. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.d.ts +0 -2
  282. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.d.ts.map +0 -1
  283. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.js +0 -2
  284. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts +0 -2
  285. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts.map +0 -1
  286. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js +0 -3
  287. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.d.ts +0 -2
  288. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.d.ts.map +0 -1
  289. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.js +0 -2
  290. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts +0 -2
  291. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts.map +0 -1
  292. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.js +0 -2
  293. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.d.ts +0 -2
  294. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.d.ts.map +0 -1
  295. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.js +0 -2
  296. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts +0 -2
  297. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +0 -1
  298. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js +0 -3
  299. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +0 -2
  300. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +0 -1
  301. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +0 -3
  302. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts +0 -2
  303. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +0 -1
  304. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +0 -3
  305. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts +0 -2
  306. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts.map +0 -1
  307. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.js +0 -2
  308. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts +0 -2
  309. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts.map +0 -1
  310. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.js +0 -0
  311. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts +0 -2
  312. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts.map +0 -1
  313. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js +0 -3
  314. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts +0 -4
  315. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts.map +0 -1
  316. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +0 -3
  317. package/dist/utils/hooks/useOnResizeContent.d.ts +0 -2
  318. package/dist/utils/hooks/useOnResizeContent.d.ts.map +0 -1
  319. package/dist/utils/hooks/useOnResizeContent.js +0 -21
  320. package/dist/utils/hooks/useOnResizeContent.js.map +0 -1
  321. package/src/context/providers/ChainOfThoughtPartByIndexProvider.tsx +0 -3
  322. package/src/legacy-runtime/RuntimeAdapter.ts +0 -1
  323. package/src/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.ts +0 -3
  324. package/src/legacy-runtime/runtime/AssistantRuntime.ts +0 -2
  325. package/src/legacy-runtime/runtime/AttachmentRuntime.ts +0 -7
  326. package/src/legacy-runtime/runtime/ComposerRuntime.ts +0 -20
  327. package/src/legacy-runtime/runtime/RuntimeBindings.ts +0 -12
  328. package/src/legacy-runtime/runtime/RuntimePathTypes.ts +0 -8
  329. package/src/legacy-runtime/runtime/ThreadListItemRuntime.ts +0 -10
  330. package/src/legacy-runtime/runtime/ThreadRuntime.ts +0 -14
  331. package/src/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.tsx +0 -7
  332. package/src/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.ts +0 -3
  333. package/src/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.ts +0 -1
  334. package/src/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.ts +0 -1
  335. package/src/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.ts +0 -1
  336. package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.ts +0 -1
  337. package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.ts +0 -1
  338. package/src/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.ts +0 -1
  339. package/src/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.ts +0 -6
  340. package/src/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.ts +0 -4
  341. package/src/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.ts +0 -13
  342. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.ts +0 -6
  343. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.ts +0 -1
  344. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.ts +0 -2
  345. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.ts +0 -4
  346. package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.ts +0 -2
  347. package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.ts +0 -2
  348. package/src/legacy-runtime/runtime-cores/external-store/auto-status.ts +0 -1
  349. package/src/legacy-runtime/runtime-cores/external-store/createMessageConverter.ts +0 -2
  350. package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.ts +0 -7
  351. package/src/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.ts +0 -3
  352. package/src/legacy-runtime/runtime-cores/local/ChatModelAdapter.ts +0 -7
  353. package/src/legacy-runtime/runtime-cores/local/LocalRuntimeCore.ts +0 -1
  354. package/src/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.ts +0 -3
  355. package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.ts +0 -2
  356. package/src/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.ts +0 -1
  357. package/src/legacy-runtime/runtime-cores/local/shouldContinue.ts +0 -1
  358. package/src/legacy-runtime/runtime-cores/local/useLocalRuntime.ts +0 -3
  359. package/src/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.ts +0 -1
  360. package/src/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.ts +0 -1
  361. package/src/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.ts +0 -1
  362. package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +0 -3
  363. package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +0 -3
  364. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +0 -3
  365. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.ts +0 -1
  366. package/src/legacy-runtime/runtime-cores/remote-thread-list/types.ts +0 -7
  367. package/src/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.ts +0 -3
  368. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.ts +0 -3
  369. package/src/model-context/frame/AssistantFrame.test.ts +0 -400
  370. package/src/utils/hooks/useOnResizeContent.ts +0 -15
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerInput.js","names":["useCallback","useAui","flushTapSync","useComposerSend","ComposerSendOptions","TriggerPopoverAriaProps","useComposerInputDisabled","useComposerInputValue","useTriggerPopoverAriaProps","Unstable_UseComposerInputOptions","disabled","Unstable_ComposerInput","value","setText","text","send","options","isDisabled","canSend","unstable_useComposerInput","aui","composer","getState","isEditing","rawSend","sendDisabled","sendOptions","Unstable_TriggerPopoverAriaProps","unstable_useTriggerPopoverAriaProps"],"sources":["../../src/unstable/useComposerInput.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport { useComposerSend } from \"@assistant-ui/core/react\";\nimport type { ComposerSendOptions } from \"@assistant-ui/core/store\";\nimport {\n type TriggerPopoverAriaProps,\n useComposerInputDisabled,\n useComposerInputValue,\n useTriggerPopoverAriaProps,\n} from \"../primitives/composer/useComposerInputState\";\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_UseComposerInputOptions = {\n /**\n * Disables the input in addition to the composer's own disabled sources\n * (thread disabled, active dictation). When disabled, `isDisabled` is `true`\n * and `canSend` is `false`.\n */\n disabled?: boolean | undefined;\n};\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_ComposerInput = {\n /** Current composer text, or `\"\"` when the composer is not editing. */\n value: string;\n /**\n * Writes `text` into the composer, mirroring `ComposerPrimitive.Input`:\n * a no-op unless the composer is editing; the controlled value stays in\n * sync within the same tick.\n */\n setText(text: string): void;\n /**\n * Sends the current message when `canSend` is `true`; otherwise a no-op.\n * Accepts the same options as the composer send action.\n */\n send(options?: ComposerSendOptions): void;\n /**\n * Whether the input is disabled, combining the `disabled` option with the\n * composer's own disabled sources (thread disabled, active dictation).\n */\n isDisabled: boolean;\n /**\n * Whether a send is currently available. Matches `ComposerPrimitive.Send`\n * gating (non-empty editing composer, not running without queue support) and\n * is additionally `false` while `isDisabled`.\n */\n canSend: boolean;\n};\n\n/**\n * Headless bridge to the composer's text value and send action, for building a\n * custom composer input without `ComposerPrimitive.Input`. It is a thin bridge,\n * not a second input: it does not own keyboard behavior, autosize, IME or\n * contentEditable sync, paste/drop attachments, focus management, or rich-text\n * state. Spread `unstable_useTriggerPopoverAriaProps()` onto your element for\n * trigger-popover combobox semantics.\n *\n * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const { value, setText, send, isDisabled, canSend } = unstable_useComposerInput();\n * <textarea\n * value={value}\n * disabled={isDisabled}\n * onChange={(e) => setText(e.target.value)}\n * onKeyDown={(e) => {\n * if (e.nativeEvent.isComposing || e.keyCode === 229) return;\n *\n * if (e.key === \"Enter\" && !e.shiftKey && canSend) {\n * e.preventDefault();\n * send();\n * }\n * }}\n * />\n * ```\n */\nexport function unstable_useComposerInput(\n options?: Unstable_UseComposerInputOptions,\n): Unstable_ComposerInput {\n const aui = useAui();\n const value = useComposerInputValue();\n const isDisabled = useComposerInputDisabled(options?.disabled);\n\n const setText = useCallback(\n (text: string) => {\n if (!aui.composer.getState().isEditing) return;\n flushTapSync(() => {\n aui.composer.setText(text);\n });\n },\n [aui],\n );\n\n const { send: rawSend, disabled: sendDisabled } = useComposerSend();\n const canSend = !sendDisabled && !isDisabled;\n const send = useCallback(\n (sendOptions?: ComposerSendOptions) => {\n if (!canSend) return;\n rawSend(sendOptions);\n },\n [canSend, rawSend],\n );\n\n return { value, setText, send, isDisabled, canSend };\n}\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_TriggerPopoverAriaProps = TriggerPopoverAriaProps;\n\n/**\n * ARIA combobox attributes for the focused element (typically the composer\n * input) describing the open trigger popover, per the WAI-ARIA editable\n * combobox pattern. Returns an empty object outside a `TriggerPopoverRoot` or\n * when no popover is open. Spread these last so they take precedence over any\n * matching ARIA props you set yourself, mirroring `ComposerPrimitive.Input`.\n *\n * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const aria = unstable_useTriggerPopoverAriaProps();\n * <textarea {...aria} />\n * ```\n */\nexport function unstable_useTriggerPopoverAriaProps(): Unstable_TriggerPopoverAriaProps {\n return useTriggerPopoverAriaProps();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,SAAgBmB,0BACdH,SACwB;CACxB,MAAMI,MAAMnB,OAAO;CACnB,MAAMW,QAAQL,sBAAsB;CACpC,MAAMU,aAAaX,yBAAyBU,SAASN,QAAQ;CAE7D,MAAMG,UAAUb,aACbc,SAAiB;EAChB,IAAI,CAACM,IAAIC,SAASC,SAAS,CAAC,CAACC,WAAW;EACxCrB,mBAAmB;GACjBkB,IAAIC,SAASR,QAAQC,IAAI;EAC3B,CAAC;CACH,GACA,CAACM,GAAG,CACN;CAEA,MAAM,EAAEL,MAAMS,SAASd,UAAUe,iBAAiBtB,gBAAgB;CAClE,MAAMe,UAAU,CAACO,gBAAgB,CAACR;CASlC,OAAO;EAAEL;EAAOC;EAASE,MARZf,aACV0B,gBAAsC;GACrC,IAAI,CAACR,SAAS;GACdM,QAAQE,WAAW;EACrB,GACA,CAACR,SAASM,OAAO,CAGMT;EAAME;EAAYC;CAAQ;AACrD;;;;;;;;;;;;;;;;AAoBA,SAAgBU,sCAAwE;CACtF,OAAOpB,2BAA2B;AACpC"}
1
+ {"version":3,"file":"useComposerInput.js","names":["useCallback","useAui","flushTapSync","useComposerSend","ComposerSendOptions","TriggerPopoverAriaProps","useComposerInputDisabled","useComposerInputValue","useTriggerPopoverAriaProps","Unstable_UseComposerInputOptions","disabled","Unstable_ComposerInput","value","setText","text","send","options","isDisabled","canSend","unstable_useComposerInput","aui","composer","getState","isEditing","origin","rawSend","sendDisabled","sendOptions","Unstable_TriggerPopoverAriaProps","unstable_useTriggerPopoverAriaProps"],"sources":["../../src/unstable/useComposerInput.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport { useComposerSend } from \"@assistant-ui/core/react\";\nimport type { ComposerSendOptions } from \"@assistant-ui/core/store\";\nimport {\n type TriggerPopoverAriaProps,\n useComposerInputDisabled,\n useComposerInputValue,\n useTriggerPopoverAriaProps,\n} from \"../primitives/composer/useComposerInputState\";\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_UseComposerInputOptions = {\n /**\n * Disables the input in addition to the composer's own disabled sources\n * (thread disabled, active dictation). When disabled, `isDisabled` is `true`\n * and `canSend` is `false`.\n */\n disabled?: boolean | undefined;\n};\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_ComposerInput = {\n /** Current composer text, or `\"\"` when the composer is not editing. */\n value: string;\n /**\n * Writes `text` into the composer, mirroring `ComposerPrimitive.Input`:\n * a no-op unless the composer is editing; the controlled value stays in\n * sync within the same tick.\n */\n setText(text: string): void;\n /**\n * Sends the current message when `canSend` is `true`; otherwise a no-op.\n * Accepts the same options as the composer send action.\n */\n send(options?: ComposerSendOptions): void;\n /**\n * Whether the input is disabled, combining the `disabled` option with the\n * composer's own disabled sources (thread disabled, active dictation).\n */\n isDisabled: boolean;\n /**\n * Whether a send is currently available. Matches `ComposerPrimitive.Send`\n * gating (non-empty editing composer, not running without queue support) and\n * is additionally `false` while `isDisabled`.\n */\n canSend: boolean;\n};\n\n/**\n * Headless bridge to the composer's text value and send action, for building a\n * custom composer input without `ComposerPrimitive.Input`. It is a thin bridge,\n * not a second input: it does not own keyboard behavior, autosize, IME or\n * contentEditable sync, paste/drop attachments, focus management, or rich-text\n * state. Spread `unstable_useTriggerPopoverAriaProps()` onto your element for\n * trigger-popover combobox semantics.\n *\n * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const { value, setText, send, isDisabled, canSend } = unstable_useComposerInput();\n * <textarea\n * value={value}\n * disabled={isDisabled}\n * onChange={(e) => setText(e.target.value)}\n * onKeyDown={(e) => {\n * if (e.nativeEvent.isComposing || e.keyCode === 229) return;\n *\n * if (e.key === \"Enter\" && !e.shiftKey && canSend) {\n * e.preventDefault();\n * send();\n * }\n * }}\n * />\n * ```\n */\nexport function unstable_useComposerInput(\n options?: Unstable_UseComposerInputOptions,\n): Unstable_ComposerInput {\n const aui = useAui();\n const value = useComposerInputValue();\n const isDisabled = useComposerInputDisabled(options?.disabled);\n\n const setText = useCallback(\n (text: string) => {\n if (!aui.composer.getState().isEditing) return;\n flushTapSync(() => {\n aui.composer.setText(text, { origin: \"user\" });\n });\n },\n [aui],\n );\n\n const { send: rawSend, disabled: sendDisabled } = useComposerSend();\n const canSend = !sendDisabled && !isDisabled;\n const send = useCallback(\n (sendOptions?: ComposerSendOptions) => {\n if (!canSend) return;\n rawSend(sendOptions);\n },\n [canSend, rawSend],\n );\n\n return { value, setText, send, isDisabled, canSend };\n}\n\n/** @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_TriggerPopoverAriaProps = TriggerPopoverAriaProps;\n\n/**\n * ARIA combobox attributes for the focused element (typically the composer\n * input) describing the open trigger popover, per the WAI-ARIA editable\n * combobox pattern. Returns an empty object outside a `TriggerPopoverRoot` or\n * when no popover is open. Spread these last so they take precedence over any\n * matching ARIA props you set yourself, mirroring `ComposerPrimitive.Input`.\n *\n * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const aria = unstable_useTriggerPopoverAriaProps();\n * <textarea {...aria} />\n * ```\n */\nexport function unstable_useTriggerPopoverAriaProps(): Unstable_TriggerPopoverAriaProps {\n return useTriggerPopoverAriaProps();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,SAAgBmB,0BACdH,SACwB;CACxB,MAAMI,MAAMnB,OAAO;CACnB,MAAMW,QAAQL,sBAAsB;CACpC,MAAMU,aAAaX,yBAAyBU,SAASN,QAAQ;CAE7D,MAAMG,UAAUb,aACbc,SAAiB;EAChB,IAAI,CAACM,IAAIC,SAASC,SAAS,CAAC,CAACC,WAAW;EACxCrB,mBAAmB;GACjBkB,IAAIC,SAASR,QAAQC,MAAM,EAAEU,QAAQ,OAAO,CAAC;EAC/C,CAAC;CACH,GACA,CAACJ,GAAG,CACN;CAEA,MAAM,EAAEL,MAAMU,SAASf,UAAUgB,iBAAiBvB,gBAAgB;CAClE,MAAMe,UAAU,CAACQ,gBAAgB,CAACT;CASlC,OAAO;EAAEL;EAAOC;EAASE,MARZf,aACV2B,gBAAsC;GACrC,IAAI,CAACT,SAAS;GACdO,QAAQE,WAAW;EACrB,GACA,CAACT,SAASO,OAAO,CAGMV;EAAME;EAAYC;CAAQ;AACrD;;;;;;;;;;;;;;;;AAoBA,SAAgBW,sCAAwE;CACtF,OAAOrB,2BAA2B;AACpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerInputHistory.d.ts","sourceRoot":"","sources":["../../src/unstable/useComposerInputHistory.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAOf,+GAA+G;AAC/G,MAAM,MAAM,6BAA6B,GAAG;IAC1C,gEAAgE;IAChE,SAAS,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;CACtD,CAAC;AA2BF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gCAAgC,IAAI,6BAA6B,CA6FhF"}
1
+ {"version":3,"file":"useComposerInputHistory.d.ts","sourceRoot":"","sources":["../../src/unstable/useComposerInputHistory.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAOf,+GAA+G;AAC/G,MAAM,MAAM,6BAA6B,GAAG;IAC1C,gEAAgE;IAChE,SAAS,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;CACtD,CAAC;AA2BF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gCAAgC,IAAI,6BAA6B,CA8FhF"}
@@ -44,7 +44,7 @@ function unstable_useComposerInputHistory() {
44
44
  const popoverCtx = useTriggerPopoverRootContextOptional();
45
45
  const browseRef = useRef(null);
46
46
  useEffect(() => {
47
- if (aui.composer.getState().type !== "thread") return void 0;
47
+ if (aui.composer.getState().type !== "thread" || !aui.optional.threads) return void 0;
48
48
  return aui.on("threads.selectionChanged", () => {
49
49
  browseRef.current = null;
50
50
  });
@@ -62,7 +62,7 @@ function unstable_useComposerInputHistory() {
62
62
  if (browseRef.current && value !== browseRef.current.lastRecalledText) browseRef.current = null;
63
63
  const browse = browseRef.current;
64
64
  const commitText = (text) => {
65
- flushTapSync(() => aui.composer.setText(text));
65
+ flushTapSync(() => aui.composer.setText(text, { origin: "recall" }));
66
66
  requestAnimationFrame(() => {
67
67
  textarea.setSelectionRange(text.length, text.length);
68
68
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerInputHistory.js","names":["useCallback","useEffect","useMemo","useRef","KeyboardEvent","KeyboardEventHandler","useAui","flushTapSync","ThreadMessage","getThreadMessageText","useTriggerPopoverRootContextOptional","Unstable_ComposerInputHistory","onKeyDown","HTMLTextAreaElement","BrowseState","cursor","draftSnapshot","lastRecalledText","deriveHistory","messages","entries","i","length","message","role","text","trim","push","isOnFirstLine","value","caret","slice","includes","isOnLastLine","unstable_useComposerInputHistory","aui","popoverCtx","browseRef","composer","getState","type","undefined","on","current","e","defaultPrevented","key","nativeEvent","isComposing","shiftKey","ctrlKey","metaKey","altKey","getActiveAria","textarea","currentTarget","selectionStart","selectionEnd","browse","commitText","setText","requestAnimationFrame","setSelectionRange","preventDefault","recall","history","entry","thread","next"],"sources":["../../src/unstable/useComposerInputHistory.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type KeyboardEvent,\n type KeyboardEventHandler,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport type { ThreadMessage } from \"@assistant-ui/core\";\nimport { getThreadMessageText } from \"@assistant-ui/core/internal\";\nimport { useTriggerPopoverRootContextOptional } from \"../primitives/composer/trigger/TriggerPopoverRootContext\";\n\n/** @deprecated Experimental since 2026-06-11. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_ComposerInputHistory = {\n /** Keydown handler to spread onto `ComposerPrimitive.Input`. */\n onKeyDown: KeyboardEventHandler<HTMLTextAreaElement>;\n};\n\ntype BrowseState = {\n cursor: number;\n draftSnapshot: string;\n lastRecalledText: string;\n};\n\nconst deriveHistory = (messages: readonly ThreadMessage[]): string[] => {\n const entries: string[] = [];\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]!;\n if (message.role !== \"user\") continue;\n const text = getThreadMessageText(message).trim();\n if (!text) continue;\n if (entries[entries.length - 1] === text) continue;\n entries.push(text);\n }\n return entries;\n};\n\nconst isOnFirstLine = (value: string, caret: number): boolean =>\n !value.slice(0, caret).includes(\"\\n\");\n\nconst isOnLastLine = (value: string, caret: number): boolean =>\n !value.slice(caret).includes(\"\\n\");\n\n/**\n * Terminal-style input history for the thread composer: ArrowUp on an\n * empty draft recalls previously sent user messages (newest first),\n * ArrowDown steps back toward the newest and finally restores the draft\n * that was being typed when browsing started.\n *\n * Recall only triggers when the caret is on the first/last line with no\n * selection, so multi-line editing keeps native arrow behavior. The\n * handler yields to an open mention/slash popover, to IME composition,\n * to modifier keys, and to consumer handlers that already called\n * `preventDefault`. It is inert on edit composers.\n *\n * @deprecated Experimental since 2026-06-11. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const history = unstable_useComposerInputHistory();\n * <ComposerPrimitive.Input {...history} />\n * ```\n */\nexport function unstable_useComposerInputHistory(): Unstable_ComposerInputHistory {\n const aui = useAui();\n const popoverCtx = useTriggerPopoverRootContextOptional();\n const browseRef = useRef<BrowseState | null>(null);\n\n useEffect(() => {\n if (aui.composer.getState().type !== \"thread\") return undefined;\n\n return aui.on(\"threads.selectionChanged\", () => {\n browseRef.current = null;\n });\n }, [aui]);\n\n const onKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.defaultPrevented) return;\n if (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\") return;\n if (e.nativeEvent.isComposing) return;\n if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;\n if (popoverCtx && popoverCtx.getActiveAria() !== null) return;\n if (aui.composer.getState().type !== \"thread\") return;\n\n const textarea = e.currentTarget;\n const { selectionStart, selectionEnd, value } = textarea;\n if (selectionStart !== selectionEnd) return;\n\n if (browseRef.current && value !== browseRef.current.lastRecalledText) {\n browseRef.current = null;\n }\n const browse = browseRef.current;\n\n const commitText = (text: string): void => {\n flushTapSync(() => aui.composer.setText(text));\n // React's controlled-value commit restores the pre-recall caret;\n // reposition after the commit, before paint.\n requestAnimationFrame(() => {\n textarea.setSelectionRange(text.length, text.length);\n });\n e.preventDefault();\n };\n\n const recall = (\n history: readonly string[],\n cursor: number,\n draftSnapshot: string,\n ): void => {\n const entry = history[cursor];\n if (entry === undefined) {\n e.preventDefault();\n return;\n }\n browseRef.current = { cursor, draftSnapshot, lastRecalledText: entry };\n commitText(entry);\n };\n\n if (e.key === \"ArrowUp\") {\n if (!isOnFirstLine(value, selectionStart)) return;\n\n if (!browse) {\n if (value.trim() !== \"\") return;\n const history = deriveHistory(aui.thread.getState().messages);\n if (history.length === 0) return;\n recall(history, 0, value);\n return;\n }\n\n const history = deriveHistory(aui.thread.getState().messages);\n const next = browse.cursor + 1;\n if (next >= history.length) {\n e.preventDefault();\n return;\n }\n recall(history, next, browse.draftSnapshot);\n return;\n }\n\n if (!browse) return;\n if (!isOnLastLine(value, selectionEnd)) return;\n\n const next = browse.cursor - 1;\n if (next < 0) {\n browseRef.current = null;\n commitText(browse.draftSnapshot);\n return;\n }\n\n const history = deriveHistory(aui.thread.getState().messages);\n recall(history, next, browse.draftSnapshot);\n },\n [aui, popoverCtx],\n );\n\n return useMemo(() => ({ onKeyDown }), [onKeyDown]);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useComposerInputHistory.js","names":["useCallback","useEffect","useMemo","useRef","KeyboardEvent","KeyboardEventHandler","useAui","flushTapSync","ThreadMessage","getThreadMessageText","useTriggerPopoverRootContextOptional","Unstable_ComposerInputHistory","onKeyDown","HTMLTextAreaElement","BrowseState","cursor","draftSnapshot","lastRecalledText","deriveHistory","messages","entries","i","length","message","role","text","trim","push","isOnFirstLine","value","caret","slice","includes","isOnLastLine","unstable_useComposerInputHistory","aui","popoverCtx","browseRef","composer","getState","type","optional","threads","undefined","on","current","e","defaultPrevented","key","nativeEvent","isComposing","shiftKey","ctrlKey","metaKey","altKey","getActiveAria","textarea","currentTarget","selectionStart","selectionEnd","browse","commitText","setText","origin","requestAnimationFrame","setSelectionRange","preventDefault","recall","history","entry","thread","next"],"sources":["../../src/unstable/useComposerInputHistory.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type KeyboardEvent,\n type KeyboardEventHandler,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { flushTapSync } from \"@assistant-ui/tap\";\nimport type { ThreadMessage } from \"@assistant-ui/core\";\nimport { getThreadMessageText } from \"@assistant-ui/core/internal\";\nimport { useTriggerPopoverRootContextOptional } from \"../primitives/composer/trigger/TriggerPopoverRootContext\";\n\n/** @deprecated Experimental since 2026-06-11. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_ComposerInputHistory = {\n /** Keydown handler to spread onto `ComposerPrimitive.Input`. */\n onKeyDown: KeyboardEventHandler<HTMLTextAreaElement>;\n};\n\ntype BrowseState = {\n cursor: number;\n draftSnapshot: string;\n lastRecalledText: string;\n};\n\nconst deriveHistory = (messages: readonly ThreadMessage[]): string[] => {\n const entries: string[] = [];\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]!;\n if (message.role !== \"user\") continue;\n const text = getThreadMessageText(message).trim();\n if (!text) continue;\n if (entries[entries.length - 1] === text) continue;\n entries.push(text);\n }\n return entries;\n};\n\nconst isOnFirstLine = (value: string, caret: number): boolean =>\n !value.slice(0, caret).includes(\"\\n\");\n\nconst isOnLastLine = (value: string, caret: number): boolean =>\n !value.slice(caret).includes(\"\\n\");\n\n/**\n * Terminal-style input history for the thread composer: ArrowUp on an\n * empty draft recalls previously sent user messages (newest first),\n * ArrowDown steps back toward the newest and finally restores the draft\n * that was being typed when browsing started.\n *\n * Recall only triggers when the caret is on the first/last line with no\n * selection, so multi-line editing keeps native arrow behavior. The\n * handler yields to an open mention/slash popover, to IME composition,\n * to modifier keys, and to consumer handlers that already called\n * `preventDefault`. It is inert on edit composers.\n *\n * @deprecated Experimental since 2026-06-11. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const history = unstable_useComposerInputHistory();\n * <ComposerPrimitive.Input {...history} />\n * ```\n */\nexport function unstable_useComposerInputHistory(): Unstable_ComposerInputHistory {\n const aui = useAui();\n const popoverCtx = useTriggerPopoverRootContextOptional();\n const browseRef = useRef<BrowseState | null>(null);\n\n useEffect(() => {\n if (aui.composer.getState().type !== \"thread\" || !aui.optional.threads)\n return undefined;\n\n return aui.on(\"threads.selectionChanged\", () => {\n browseRef.current = null;\n });\n }, [aui]);\n\n const onKeyDown = useCallback(\n (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.defaultPrevented) return;\n if (e.key !== \"ArrowUp\" && e.key !== \"ArrowDown\") return;\n if (e.nativeEvent.isComposing) return;\n if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;\n if (popoverCtx && popoverCtx.getActiveAria() !== null) return;\n if (aui.composer.getState().type !== \"thread\") return;\n\n const textarea = e.currentTarget;\n const { selectionStart, selectionEnd, value } = textarea;\n if (selectionStart !== selectionEnd) return;\n\n if (browseRef.current && value !== browseRef.current.lastRecalledText) {\n browseRef.current = null;\n }\n const browse = browseRef.current;\n\n const commitText = (text: string): void => {\n flushTapSync(() => aui.composer.setText(text, { origin: \"recall\" }));\n // React's controlled-value commit restores the pre-recall caret;\n // reposition after the commit, before paint.\n requestAnimationFrame(() => {\n textarea.setSelectionRange(text.length, text.length);\n });\n e.preventDefault();\n };\n\n const recall = (\n history: readonly string[],\n cursor: number,\n draftSnapshot: string,\n ): void => {\n const entry = history[cursor];\n if (entry === undefined) {\n e.preventDefault();\n return;\n }\n browseRef.current = { cursor, draftSnapshot, lastRecalledText: entry };\n commitText(entry);\n };\n\n if (e.key === \"ArrowUp\") {\n if (!isOnFirstLine(value, selectionStart)) return;\n\n if (!browse) {\n if (value.trim() !== \"\") return;\n const history = deriveHistory(aui.thread.getState().messages);\n if (history.length === 0) return;\n recall(history, 0, value);\n return;\n }\n\n const history = deriveHistory(aui.thread.getState().messages);\n const next = browse.cursor + 1;\n if (next >= history.length) {\n e.preventDefault();\n return;\n }\n recall(history, next, browse.draftSnapshot);\n return;\n }\n\n if (!browse) return;\n if (!isOnLastLine(value, selectionEnd)) return;\n\n const next = browse.cursor - 1;\n if (next < 0) {\n browseRef.current = null;\n commitText(browse.draftSnapshot);\n return;\n }\n\n const history = deriveHistory(aui.thread.getState().messages);\n recall(history, next, browse.draftSnapshot);\n },\n [aui, popoverCtx],\n );\n\n return useMemo(() => ({ onKeyDown }), [onKeyDown]);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useLiveCompletionAdapter.d.ts","sourceRoot":"","sources":["../../src/unstable/useLiveCompletionAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,+GAA+G;AAC/G,MAAM,MAAM,wCAAwC,GAAG;IACrD;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;IAC9E;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACxC,CAAC;AAKF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wCAAwC,GAChD;IAAE,OAAO,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAiK1D"}
1
+ {"version":3,"file":"useLiveCompletionAdapter.d.ts","sourceRoot":"","sources":["../../src/unstable/useLiveCompletionAdapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,+GAA+G;AAC/G,MAAM,MAAM,wCAAwC,GAAG;IACrD;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAC;IAC9E;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACxC,CAAC;AAKF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wCAAwC,GAChD;IAAE,OAAO,EAAE,uBAAuB,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAkK1D"}
@@ -158,7 +158,8 @@ function unstable_useLiveCompletionAdapter(options) {
158
158
  categories: () => [],
159
159
  categoryItems: () => [],
160
160
  search: (query) => {
161
- if (query !== state.query || retryableQueryRef.current === query) queueMicrotask(() => scheduleFetch(query));
161
+ if (!enabled) return [];
162
+ if (query !== state.query || retryableQueryRef.current === query) queueMicrotask(() => scheduleFetchRef.current(query));
162
163
  else queueMicrotask(() => {
163
164
  if (deferredQueryRef.current !== null && deferredQueryRef.current !== query) deferredQueryRef.current = null;
164
165
  if (pendingQueryRef.current !== null && pendingQueryRef.current !== query) invalidatePending();
@@ -166,8 +167,8 @@ function unstable_useLiveCompletionAdapter(options) {
166
167
  return state.items;
167
168
  }
168
169
  }), [
170
+ enabled,
169
171
  state,
170
- scheduleFetch,
171
172
  invalidatePending
172
173
  ]),
173
174
  isLoading
@@ -1 +1 @@
1
- {"version":3,"file":"useLiveCompletionAdapter.js","names":["useCallback","useEffect","useMemo","useRef","useState","useIsomorphicLayoutEffect","Unstable_TriggerAdapter","Unstable_TriggerItem","Unstable_UseLiveCompletionAdapterOptions","fetcher","query","Promise","cacheKey","debounceMs","enabled","NO_QUERY","unstable_useLiveCompletionAdapter","options","adapter","isLoading","state","setState","items","failed","setIsLoading","fetcherRef","current","timerRef","ReturnType","setTimeout","tokenRef","pendingQueryRef","retryableQueryRef","pendingRetryQueryRef","inactiveRef","deferredQueryRef","cancelTimer","clearTimeout","rearmPendingRetry","scheduleFetch","token","resolve","then","scheduleFetchRef","invalidatePending","cacheKeyRef","s","deferredQuery","categories","categoryItems","search","queueMicrotask"],"sources":["../../src/unstable/useLiveCompletionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\n\n/** @deprecated Experimental since 2026-06-15. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_UseLiveCompletionAdapterOptions = {\n /**\n * Fetches the items for a query from an async source. Called debounced; the\n * resolved items are cached and returned synchronously to the popover on the\n * next render.\n */\n readonly fetcher: (query: string) => Promise<readonly Unstable_TriggerItem[]>;\n /**\n * Identifies the fetcher's data source. Change this when switching accounts,\n * workspaces, or another boundary that should invalidate cached results.\n */\n readonly cacheKey?: string | number | undefined;\n /** Debounce applied before a fetch fires, in milliseconds. @default 60 */\n readonly debounceMs?: number | undefined;\n /** When `false`, no fetch is scheduled and the adapter stays empty. @default true */\n readonly enabled?: boolean | undefined;\n};\n\n/** Sentinel that no real query (including the empty string) equals, so the first query always fetches. */\nconst NO_QUERY = \"\\u0000\";\n\n/**\n * Bridges an async completion source (a server search, a gateway RPC) into the\n * synchronous `Unstable_TriggerAdapter` that `ComposerTriggerPopover` consumes.\n * `search(query)` returns the last fetched items synchronously and schedules a\n * debounced fetch when the query changes; when results arrive the returned\n * `adapter` identity changes, which re-runs the popover's lookup so the fresh\n * items render. This is a search-only adapter (`categories` are empty).\n *\n * `isLoading` is `true` while a fetch is in flight. Pass it to the popover's\n * `isLoading` prop to render a loading state.\n *\n * @deprecated Experimental since 2026-06-15. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const mentions = unstable_useLiveCompletionAdapter({\n * fetcher: (query) => searchUsers(query),\n * });\n *\n * <ComposerTriggerPopover\n * char=\"@\"\n * adapter={mentions.adapter}\n * isLoading={mentions.isLoading}\n * directive={{ onInserted }}\n * />\n * ```\n */\nexport function unstable_useLiveCompletionAdapter(\n options: Unstable_UseLiveCompletionAdapterOptions,\n): { adapter: Unstable_TriggerAdapter; isLoading: boolean } {\n const { fetcher, cacheKey, debounceMs = 60, enabled = true } = options;\n\n const [state, setState] = useState<{\n query: string;\n items: readonly Unstable_TriggerItem[];\n failed: boolean;\n }>({ query: NO_QUERY, items: [], failed: false });\n const [isLoading, setIsLoading] = useState(false);\n\n const fetcherRef = useRef(fetcher);\n // The debounce timer must only observe fetchers from committed renders.\n useIsomorphicLayoutEffect(() => {\n fetcherRef.current = fetcher;\n }, [fetcher]);\n\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const tokenRef = useRef(0);\n const pendingQueryRef = useRef<string | null>(null);\n const retryableQueryRef = useRef<string | null>(null);\n const pendingRetryQueryRef = useRef<string | null>(null);\n const inactiveRef = useRef(true);\n const deferredQueryRef = useRef<string | null>(null);\n\n const cancelTimer = useCallback(() => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const rearmPendingRetry = useCallback(() => {\n const query = pendingRetryQueryRef.current;\n if (query === null) return;\n retryableQueryRef.current = query;\n pendingRetryQueryRef.current = null;\n }, []);\n\n const scheduleFetch = useCallback(\n (query: string) => {\n if (!enabled) return;\n if (inactiveRef.current) {\n deferredQueryRef.current = query;\n return;\n }\n if (pendingQueryRef.current === query) return;\n rearmPendingRetry();\n if (retryableQueryRef.current === query) {\n retryableQueryRef.current = null;\n pendingRetryQueryRef.current = query;\n }\n pendingQueryRef.current = query;\n cancelTimer();\n const token = ++tokenRef.current;\n setIsLoading(true);\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n Promise.resolve()\n .then(() => fetcherRef.current(query))\n .then(\n (items) => {\n if (token !== tokenRef.current) return;\n pendingRetryQueryRef.current = null;\n setState({ query, items, failed: false });\n setIsLoading(false);\n },\n () => {\n if (token !== tokenRef.current) return;\n pendingQueryRef.current = null;\n pendingRetryQueryRef.current = null;\n setState({ query, items: [], failed: true });\n setIsLoading(false);\n },\n );\n }, debounceMs);\n },\n [enabled, debounceMs, cancelTimer, rearmPendingRetry],\n );\n\n const scheduleFetchRef = useRef(scheduleFetch);\n useIsomorphicLayoutEffect(() => {\n scheduleFetchRef.current = scheduleFetch;\n }, [scheduleFetch]);\n\n const invalidatePending = useCallback(() => {\n rearmPendingRetry();\n cancelTimer();\n pendingQueryRef.current = null;\n tokenRef.current += 1;\n setIsLoading(false);\n }, [cancelTimer, rearmPendingRetry]);\n\n const cacheKeyRef = useRef(cacheKey);\n useIsomorphicLayoutEffect(() => {\n if (cacheKeyRef.current === cacheKey) return;\n cacheKeyRef.current = cacheKey;\n invalidatePending();\n retryableQueryRef.current = null;\n pendingRetryQueryRef.current = null;\n setState({ query: NO_QUERY, items: [], failed: false });\n }, [cacheKey, invalidatePending]);\n\n useEffect(() => {\n if (enabled) return;\n invalidatePending();\n setState((s) =>\n s.query === NO_QUERY ? s : { query: NO_QUERY, items: [], failed: false },\n );\n }, [enabled, invalidatePending]);\n\n // Render-time searches can outlive an abandoned render, so they only arm\n // request work after this hook commits.\n useIsomorphicLayoutEffect(() => {\n inactiveRef.current = false;\n const deferredQuery = deferredQueryRef.current;\n deferredQueryRef.current = null;\n if (deferredQuery !== null) scheduleFetchRef.current(deferredQuery);\n return () => {\n inactiveRef.current = true;\n invalidatePending();\n };\n }, [invalidatePending]);\n\n // Arm retries only after the failed state commits. Arming during rejection\n // would let the failure render immediately schedule another request.\n useEffect(() => {\n retryableQueryRef.current = state.failed ? state.query : null;\n }, [state]);\n\n const adapter = useMemo<Unstable_TriggerAdapter>(\n () => ({\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n // search() runs inside the popover's render; defer state updates with\n // queueMicrotask so they are not dispatched while another component renders.\n if (query !== state.query || retryableQueryRef.current === query) {\n queueMicrotask(() => scheduleFetch(query));\n } else {\n queueMicrotask(() => {\n if (\n deferredQueryRef.current !== null &&\n deferredQueryRef.current !== query\n ) {\n deferredQueryRef.current = null;\n }\n if (\n pendingQueryRef.current !== null &&\n pendingQueryRef.current !== query\n ) {\n invalidatePending();\n }\n });\n }\n return state.items;\n },\n }),\n [state, scheduleFetch, invalidatePending],\n );\n\n return { adapter, isLoading };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useLiveCompletionAdapter.js","names":["useCallback","useEffect","useMemo","useRef","useState","useIsomorphicLayoutEffect","Unstable_TriggerAdapter","Unstable_TriggerItem","Unstable_UseLiveCompletionAdapterOptions","fetcher","query","Promise","cacheKey","debounceMs","enabled","NO_QUERY","unstable_useLiveCompletionAdapter","options","adapter","isLoading","state","setState","items","failed","setIsLoading","fetcherRef","current","timerRef","ReturnType","setTimeout","tokenRef","pendingQueryRef","retryableQueryRef","pendingRetryQueryRef","inactiveRef","deferredQueryRef","cancelTimer","clearTimeout","rearmPendingRetry","scheduleFetch","token","resolve","then","scheduleFetchRef","invalidatePending","cacheKeyRef","s","deferredQuery","categories","categoryItems","search","queueMicrotask"],"sources":["../../src/unstable/useLiveCompletionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\n\n/** @deprecated Experimental since 2026-06-15. Not scheduled for removal; the API may change in any release. */\nexport type Unstable_UseLiveCompletionAdapterOptions = {\n /**\n * Fetches the items for a query from an async source. Called debounced; the\n * resolved items are cached and returned synchronously to the popover on the\n * next render.\n */\n readonly fetcher: (query: string) => Promise<readonly Unstable_TriggerItem[]>;\n /**\n * Identifies the fetcher's data source. Change this when switching accounts,\n * workspaces, or another boundary that should invalidate cached results.\n */\n readonly cacheKey?: string | number | undefined;\n /** Debounce applied before a fetch fires, in milliseconds. @default 60 */\n readonly debounceMs?: number | undefined;\n /** When `false`, no fetch is scheduled and the adapter stays empty. @default true */\n readonly enabled?: boolean | undefined;\n};\n\n/** Sentinel that no real query (including the empty string) equals, so the first query always fetches. */\nconst NO_QUERY = \"\\u0000\";\n\n/**\n * Bridges an async completion source (a server search, a gateway RPC) into the\n * synchronous `Unstable_TriggerAdapter` that `ComposerTriggerPopover` consumes.\n * `search(query)` returns the last fetched items synchronously and schedules a\n * debounced fetch when the query changes; when results arrive the returned\n * `adapter` identity changes, which re-runs the popover's lookup so the fresh\n * items render. This is a search-only adapter (`categories` are empty).\n *\n * `isLoading` is `true` while a fetch is in flight. Pass it to the popover's\n * `isLoading` prop to render a loading state.\n *\n * @deprecated Experimental since 2026-06-15. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```tsx\n * const mentions = unstable_useLiveCompletionAdapter({\n * fetcher: (query) => searchUsers(query),\n * });\n *\n * <ComposerTriggerPopover\n * char=\"@\"\n * adapter={mentions.adapter}\n * isLoading={mentions.isLoading}\n * directive={{ onInserted }}\n * />\n * ```\n */\nexport function unstable_useLiveCompletionAdapter(\n options: Unstable_UseLiveCompletionAdapterOptions,\n): { adapter: Unstable_TriggerAdapter; isLoading: boolean } {\n const { fetcher, cacheKey, debounceMs = 60, enabled = true } = options;\n\n const [state, setState] = useState<{\n query: string;\n items: readonly Unstable_TriggerItem[];\n failed: boolean;\n }>({ query: NO_QUERY, items: [], failed: false });\n const [isLoading, setIsLoading] = useState(false);\n\n const fetcherRef = useRef(fetcher);\n // The debounce timer must only observe fetchers from committed renders.\n useIsomorphicLayoutEffect(() => {\n fetcherRef.current = fetcher;\n }, [fetcher]);\n\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const tokenRef = useRef(0);\n const pendingQueryRef = useRef<string | null>(null);\n const retryableQueryRef = useRef<string | null>(null);\n const pendingRetryQueryRef = useRef<string | null>(null);\n const inactiveRef = useRef(true);\n const deferredQueryRef = useRef<string | null>(null);\n\n const cancelTimer = useCallback(() => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const rearmPendingRetry = useCallback(() => {\n const query = pendingRetryQueryRef.current;\n if (query === null) return;\n retryableQueryRef.current = query;\n pendingRetryQueryRef.current = null;\n }, []);\n\n const scheduleFetch = useCallback(\n (query: string) => {\n if (!enabled) return;\n if (inactiveRef.current) {\n deferredQueryRef.current = query;\n return;\n }\n if (pendingQueryRef.current === query) return;\n rearmPendingRetry();\n if (retryableQueryRef.current === query) {\n retryableQueryRef.current = null;\n pendingRetryQueryRef.current = query;\n }\n pendingQueryRef.current = query;\n cancelTimer();\n const token = ++tokenRef.current;\n setIsLoading(true);\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n Promise.resolve()\n .then(() => fetcherRef.current(query))\n .then(\n (items) => {\n if (token !== tokenRef.current) return;\n pendingRetryQueryRef.current = null;\n setState({ query, items, failed: false });\n setIsLoading(false);\n },\n () => {\n if (token !== tokenRef.current) return;\n pendingQueryRef.current = null;\n pendingRetryQueryRef.current = null;\n setState({ query, items: [], failed: true });\n setIsLoading(false);\n },\n );\n }, debounceMs);\n },\n [enabled, debounceMs, cancelTimer, rearmPendingRetry],\n );\n\n const scheduleFetchRef = useRef(scheduleFetch);\n useIsomorphicLayoutEffect(() => {\n scheduleFetchRef.current = scheduleFetch;\n }, [scheduleFetch]);\n\n const invalidatePending = useCallback(() => {\n rearmPendingRetry();\n cancelTimer();\n pendingQueryRef.current = null;\n tokenRef.current += 1;\n setIsLoading(false);\n }, [cancelTimer, rearmPendingRetry]);\n\n const cacheKeyRef = useRef(cacheKey);\n useIsomorphicLayoutEffect(() => {\n if (cacheKeyRef.current === cacheKey) return;\n cacheKeyRef.current = cacheKey;\n invalidatePending();\n retryableQueryRef.current = null;\n pendingRetryQueryRef.current = null;\n setState({ query: NO_QUERY, items: [], failed: false });\n }, [cacheKey, invalidatePending]);\n\n useEffect(() => {\n if (enabled) return;\n invalidatePending();\n setState((s) =>\n s.query === NO_QUERY ? s : { query: NO_QUERY, items: [], failed: false },\n );\n }, [enabled, invalidatePending]);\n\n // Render-time searches can outlive an abandoned render, so they only arm\n // request work after this hook commits.\n useIsomorphicLayoutEffect(() => {\n inactiveRef.current = false;\n const deferredQuery = deferredQueryRef.current;\n deferredQueryRef.current = null;\n if (deferredQuery !== null) scheduleFetchRef.current(deferredQuery);\n return () => {\n inactiveRef.current = true;\n invalidatePending();\n };\n }, [invalidatePending]);\n\n // Arm retries only after the failed state commits. Arming during rejection\n // would let the failure render immediately schedule another request.\n useEffect(() => {\n retryableQueryRef.current = state.failed ? state.query : null;\n }, [state]);\n\n const adapter = useMemo<Unstable_TriggerAdapter>(\n () => ({\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n if (!enabled) return [];\n // search() runs inside the popover's render; defer state updates with\n // queueMicrotask so they are not dispatched while another component renders.\n if (query !== state.query || retryableQueryRef.current === query) {\n queueMicrotask(() => scheduleFetchRef.current(query));\n } else {\n queueMicrotask(() => {\n if (\n deferredQueryRef.current !== null &&\n deferredQueryRef.current !== query\n ) {\n deferredQueryRef.current = null;\n }\n if (\n pendingQueryRef.current !== null &&\n pendingQueryRef.current !== query\n ) {\n invalidatePending();\n }\n });\n }\n return state.items;\n },\n }),\n [enabled, state, invalidatePending],\n );\n\n return { adapter, isLoading };\n}\n"],"mappings":"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"}
@@ -26,87 +26,87 @@ declare function renderSlot(render: ReactElement, children: ReactNode, props: Co
26
26
  declare function withRenderProp<T extends ElementType>(Component: T): ForwardRefExoticComponent<WithRenderPropProps<T> & RefAttributes<ComponentRef<T>>>;
27
27
  declare const Primitive: {
28
28
  a: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLAnchorElement> & import("react").AnchorHTMLAttributes<HTMLAnchorElement> & {
29
- asChild?: boolean;
29
+ asChild?: boolean | undefined;
30
30
  }, "ref"> & {
31
31
  render?: ReactElement | undefined;
32
32
  } & RefAttributes<HTMLAnchorElement>>;
33
33
  button: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & {
34
- asChild?: boolean;
34
+ asChild?: boolean | undefined;
35
35
  }, "ref"> & {
36
36
  render?: ReactElement | undefined;
37
37
  } & RefAttributes<HTMLButtonElement>>;
38
38
  div: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
39
- asChild?: boolean;
39
+ asChild?: boolean | undefined;
40
40
  }, "ref"> & {
41
41
  render?: ReactElement | undefined;
42
42
  } & RefAttributes<HTMLDivElement>>;
43
43
  form: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLFormElement> & import("react").FormHTMLAttributes<HTMLFormElement> & {
44
- asChild?: boolean;
44
+ asChild?: boolean | undefined;
45
45
  }, "ref"> & {
46
46
  render?: ReactElement | undefined;
47
47
  } & RefAttributes<HTMLFormElement>>;
48
48
  h2: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLHeadingElement> & import("react").HTMLAttributes<HTMLHeadingElement> & {
49
- asChild?: boolean;
49
+ asChild?: boolean | undefined;
50
50
  }, "ref"> & {
51
51
  render?: ReactElement | undefined;
52
52
  } & RefAttributes<HTMLHeadingElement>>;
53
53
  h3: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLHeadingElement> & import("react").HTMLAttributes<HTMLHeadingElement> & {
54
- asChild?: boolean;
54
+ asChild?: boolean | undefined;
55
55
  }, "ref"> & {
56
56
  render?: ReactElement | undefined;
57
57
  } & RefAttributes<HTMLHeadingElement>>;
58
58
  img: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLImageElement> & import("react").ImgHTMLAttributes<HTMLImageElement> & {
59
- asChild?: boolean;
59
+ asChild?: boolean | undefined;
60
60
  }, "ref"> & {
61
61
  render?: ReactElement | undefined;
62
62
  } & RefAttributes<HTMLImageElement>>;
63
63
  input: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLInputElement> & import("react").InputHTMLAttributes<HTMLInputElement> & {
64
- asChild?: boolean;
64
+ asChild?: boolean | undefined;
65
65
  }, "ref"> & {
66
66
  render?: ReactElement | undefined;
67
67
  } & RefAttributes<HTMLInputElement>>;
68
68
  label: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLLabelElement> & import("react").LabelHTMLAttributes<HTMLLabelElement> & {
69
- asChild?: boolean;
69
+ asChild?: boolean | undefined;
70
70
  }, "ref"> & {
71
71
  render?: ReactElement | undefined;
72
72
  } & RefAttributes<HTMLLabelElement>>;
73
73
  li: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLLIElement> & import("react").LiHTMLAttributes<HTMLLIElement> & {
74
- asChild?: boolean;
74
+ asChild?: boolean | undefined;
75
75
  }, "ref"> & {
76
76
  render?: ReactElement | undefined;
77
77
  } & RefAttributes<HTMLLIElement>>;
78
78
  nav: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLElement> & import("react").HTMLAttributes<HTMLElement> & {
79
- asChild?: boolean;
79
+ asChild?: boolean | undefined;
80
80
  }, "ref"> & {
81
81
  render?: ReactElement | undefined;
82
82
  } & RefAttributes<HTMLElement>>;
83
83
  ol: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLOListElement> & import("react").OlHTMLAttributes<HTMLOListElement> & {
84
- asChild?: boolean;
84
+ asChild?: boolean | undefined;
85
85
  }, "ref"> & {
86
86
  render?: ReactElement | undefined;
87
87
  } & RefAttributes<HTMLOListElement>>;
88
88
  p: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLParagraphElement> & import("react").HTMLAttributes<HTMLParagraphElement> & {
89
- asChild?: boolean;
89
+ asChild?: boolean | undefined;
90
90
  }, "ref"> & {
91
91
  render?: ReactElement | undefined;
92
92
  } & RefAttributes<HTMLParagraphElement>>;
93
93
  select: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSelectElement> & import("react").SelectHTMLAttributes<HTMLSelectElement> & {
94
- asChild?: boolean;
94
+ asChild?: boolean | undefined;
95
95
  }, "ref"> & {
96
96
  render?: ReactElement | undefined;
97
97
  } & RefAttributes<HTMLSelectElement>>;
98
98
  span: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & {
99
- asChild?: boolean;
99
+ asChild?: boolean | undefined;
100
100
  }, "ref"> & {
101
101
  render?: ReactElement | undefined;
102
102
  } & RefAttributes<HTMLSpanElement>>;
103
103
  ul: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLUListElement> & import("react").HTMLAttributes<HTMLUListElement> & {
104
- asChild?: boolean;
104
+ asChild?: boolean | undefined;
105
105
  }, "ref"> & {
106
106
  render?: ReactElement | undefined;
107
107
  } & RefAttributes<HTMLUListElement>>;
108
108
  svg: ForwardRefExoticComponent<Omit<import("react").SVGProps<SVGSVGElement> & {
109
- asChild?: boolean;
109
+ asChild?: boolean | undefined;
110
110
  }, "ref"> & {
111
111
  render?: ReactElement | undefined;
112
112
  } & RefAttributes<SVGSVGElement>>;
@@ -5,7 +5,7 @@ type PrimitiveButtonProps = ComponentPropsWithoutRef<typeof Primitive.button>;
5
5
  export type ActionButtonProps<THook> = PrimitiveButtonProps & (THook extends (props: infer TProps) => unknown ? TProps : never);
6
6
  export type ActionButtonElement = ComponentRef<typeof Primitive.button>;
7
7
  export declare const createActionButton: <TProps>(displayName: string, useActionButton: ActionButtonCallback<TProps>, forwardProps?: (keyof NonNullable<TProps>)[]) => import("react").ForwardRefExoticComponent<import("react").PropsWithoutRef<Omit<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & {
8
- asChild?: boolean;
8
+ asChild?: boolean | undefined;
9
9
  }, "ref"> & {
10
10
  render?: import("react").ReactElement | undefined;
11
11
  } & import("react").RefAttributes<HTMLButtonElement>, "ref"> & TProps> & import("react").RefAttributes<HTMLButtonElement>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react",
3
- "version": "0.15.29",
3
+ "version": "0.15.31",
4
4
  "description": "Open-source TypeScript/React library for building production-grade AI chat experiences",
5
5
  "keywords": [
6
6
  "ai",
@@ -55,15 +55,15 @@
55
55
  ],
56
56
  "sideEffects": false,
57
57
  "dependencies": {
58
- "@assistant-ui/core": "^0.3.29",
59
- "@assistant-ui/store": "^0.3.21",
60
- "@assistant-ui/tap": "^0.9.23",
61
- "assistant-cloud": "^0.2.7",
62
- "assistant-stream": "^0.3.52",
63
- "radix-ui": "^1.7.0",
58
+ "@assistant-ui/core": "^0.3.31",
59
+ "@assistant-ui/store": "^0.3.22",
60
+ "@assistant-ui/tap": "^0.9.24",
61
+ "assistant-cloud": "^0.2.8",
62
+ "assistant-stream": "^0.3.54",
63
+ "radix-ui": "^1.8.1",
64
64
  "react-textarea-autosize": "^8.5.9",
65
65
  "safe-content-frame": "^0.0.34",
66
- "zod": "^4.6.5",
66
+ "zod": "^4.6.7",
67
67
  "zustand": "^5.0.15"
68
68
  },
69
69
  "peerDependencies": {
@@ -82,17 +82,17 @@
82
82
  },
83
83
  "devDependencies": {
84
84
  "@assistant-ui/vite": "0.0.21",
85
- "@assistant-ui/x-buildutils": "0.0.30",
85
+ "@assistant-ui/x-buildutils": "0.0.31",
86
86
  "@assistant-ui/x-react18": "0.0.0",
87
87
  "@testing-library/react": "^16.3.3",
88
88
  "@types/json-schema": "^7.0.15",
89
- "@types/node": "^26.6.4",
89
+ "@types/node": "^26.6.5",
90
90
  "@types/react": "^19.3.0",
91
91
  "@types/react-dom": "^19.3.0",
92
- "jsdom": "^30.1.2",
93
- "react": "^19.3.0",
94
- "react-dom": "^19.3.0",
95
- "vitest": "^5.0.3"
92
+ "jsdom": "^30.1.3",
93
+ "react": "^19.3.1",
94
+ "react-dom": "^19.3.1",
95
+ "vitest": "^5.0.5"
96
96
  },
97
97
  "publishConfig": {
98
98
  "access": "public",
@@ -435,6 +435,11 @@ describe("OpenAIRealtimeVoiceAdapter", () => {
435
435
  const accepted = vi.fn();
436
436
  session.onTranscript(onTranscript);
437
437
  channel.emit({ type: "response.created" });
438
+ channel.emit({
439
+ type: "response.output_audio_transcript.delta",
440
+ item_id: "old-reply",
441
+ delta: "Previous reply",
442
+ });
438
443
  channel.emit({ type: "output_audio_buffer.started" });
439
444
  const sent = Promise.resolve(session.sendText!("Change the topic"));
440
445
  void sent.then(accepted);
@@ -448,6 +453,11 @@ describe("OpenAIRealtimeVoiceAdapter", () => {
448
453
  role: "user",
449
454
  content: [{ type: "input_text", text: "Change the topic" }],
450
455
  });
456
+ channel.emit({ type: "response.done", response: { status: "cancelled" } });
457
+ expect(onTranscript.mock.calls.map(([item]) => item)).toEqual([
458
+ { role: "assistant", text: "Previous reply", isFinal: false },
459
+ { role: "assistant", text: "Previous reply", isFinal: true },
460
+ ]);
451
461
  expect(accepted).not.toHaveBeenCalled();
452
462
  channel.emit({
453
463
  type: "conversation.item.added",
@@ -475,7 +485,10 @@ describe("OpenAIRealtimeVoiceAdapter", () => {
475
485
  response: { metadata: response.response.metadata },
476
486
  });
477
487
  await sent;
478
- expect(onTranscript).not.toHaveBeenCalled();
488
+ expect(onTranscript.mock.calls.map(([item]) => item)).toEqual([
489
+ { role: "assistant", text: "Previous reply", isFinal: false },
490
+ { role: "assistant", text: "Previous reply", isFinal: true },
491
+ ]);
479
492
  });
480
493
 
481
494
  it("rejects a typed send whose response request fails after the item was accepted", async () => {
@@ -17,10 +17,12 @@ import {
17
17
  type AssistantClient,
18
18
  } from "@assistant-ui/store";
19
19
  import { resource } from "@assistant-ui/tap";
20
- import { ReadonlyThreadProvider } from "@assistant-ui/core/react";
20
+ import {
21
+ ReadonlyThreadProvider,
22
+ useExternalStoreRuntime,
23
+ } from "@assistant-ui/core/react";
21
24
  import type { ThreadMessage } from "@assistant-ui/core";
22
25
  import { AssistantRuntimeProvider } from "../legacy-runtime/AssistantRuntimeProvider";
23
- import { useExternalStoreRuntime } from "../legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime";
24
26
 
25
27
  const CHANNEL = "assistant-ui/cloud-renderer";
26
28
 
@@ -3,6 +3,12 @@
3
3
  import { create } from "zustand";
4
4
  import type { Unsubscribe } from "@assistant-ui/core";
5
5
  import { notifyEventListeners } from "@assistant-ui/core/internal";
6
+ import {
7
+ createThreadViewportAutoScroll,
8
+ type ThreadViewportAutoScroll,
9
+ type ThreadViewportAutoScrollOptions,
10
+ } from "@assistant-ui/store/client";
11
+ import type { ReadonlyStore } from "../ReadonlyStore";
6
12
 
7
13
  export type SizeHandle = {
8
14
  /** Update the height */
@@ -137,6 +143,20 @@ export type ThreadViewportStoreOptions = {
137
143
  | undefined;
138
144
  };
139
145
 
146
+ type ViewportAutoScroll = {
147
+ controller: ThreadViewportAutoScroll;
148
+ getOptions: () => ThreadViewportAutoScrollOptions;
149
+ };
150
+
151
+ const viewportAutoScroll = new WeakMap<
152
+ ReadonlyStore<ThreadViewportState>,
153
+ ViewportAutoScroll
154
+ >();
155
+
156
+ export const getThreadViewportAutoScroll = (
157
+ store: ReadonlyStore<ThreadViewportState>,
158
+ ) => viewportAutoScroll.get(store)!;
159
+
140
160
  export const makeThreadViewportStore = (
141
161
  options: ThreadViewportStoreOptions = {},
142
162
  ) => {
@@ -152,14 +172,21 @@ export const makeThreadViewportStore = (
152
172
  },
153
173
  });
154
174
  });
155
- const insetRegistry = createSizeRegistry((total) => {
156
- store.setState({
157
- height: {
158
- ...store.getState().height,
159
- inset: total,
175
+ const autoScroll: ViewportAutoScroll = {
176
+ getOptions: () => ({
177
+ autoScroll: options.turnAnchor !== "top",
178
+ scrollToBottomOnInitialize: true,
179
+ scrollToBottomOnRunStart: options.turnAnchor !== "top",
180
+ scrollToBottomOnThreadSwitch: true,
181
+ }),
182
+ controller: createThreadViewportAutoScroll({
183
+ getOptions: () => autoScroll.getOptions(),
184
+ onAtBottomChange: (isAtBottom) => store.setState({ isAtBottom }),
185
+ onContentInsetChange: (inset) => {
186
+ store.setState({ height: { ...store.getState().height, inset } });
160
187
  },
161
- });
162
- });
188
+ }),
189
+ };
163
190
  const registerElementSlot = (
164
191
  key: "viewport" | "anchor",
165
192
  element: HTMLElement | null,
@@ -217,7 +244,7 @@ export const makeThreadViewportStore = (
217
244
  topAnchorTurn: null,
218
245
 
219
246
  registerViewport: viewportRegistry.register,
220
- registerContentInset: insetRegistry.register,
247
+ registerContentInset: autoScroll.controller.registerContentInset,
221
248
  registerViewportElement: (element) =>
222
249
  registerElementSlot("viewport", element),
223
250
  registerAnchorElement: (element) => registerElementSlot("anchor", element),
@@ -246,5 +273,6 @@ export const makeThreadViewportStore = (
246
273
  },
247
274
  }));
248
275
 
276
+ viewportAutoScroll.set(store, autoScroll);
249
277
  return store;
250
278
  };
package/src/index.ts CHANGED
@@ -60,7 +60,7 @@ export {
60
60
  SimpleTextAttachmentAdapter,
61
61
  CompositeAttachmentAdapter,
62
62
  } from "@assistant-ui/core";
63
- export { CloudFileAttachmentAdapter } from "./legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter";
63
+ export { CloudFileAttachmentAdapter } from "@assistant-ui/core/react";
64
64
 
65
65
  // --- adapters/voice ---
66
66
  export type { RealtimeVoiceAdapter } from "@assistant-ui/core";
@@ -164,7 +164,7 @@ export {
164
164
  type ExternalThreadQueueAdapter,
165
165
  type ExternalThreadBranchAdapter,
166
166
  } from "@assistant-ui/core";
167
- export { useExternalStoreRuntime } from "./legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime";
167
+ export { useExternalStoreRuntime } from "@assistant-ui/core/react";
168
168
  export { useExternalStoreSharedOptions } from "@assistant-ui/core/react";
169
169
  export {
170
170
  useExternalMessageConverter,
@@ -174,11 +174,11 @@ export {
174
174
  createExternalMessageConversionCache as unstable_createExternalMessageConversionCache,
175
175
  /** @deprecated Experimental since 2026-09-15. Not scheduled for removal; the API may change in any release. */
176
176
  type ExternalMessageConversionCache as Unstable_ExternalMessageConversionCache,
177
- } from "./legacy-runtime/runtime-cores/external-store/external-message-converter";
177
+ } from "@assistant-ui/core/react";
178
178
  export {
179
179
  /** @deprecated Experimental since 2025-02-02. Not scheduled for removal; the API may change in any release. */
180
180
  createMessageConverter as unstable_createMessageConverter,
181
- } from "./legacy-runtime/runtime-cores/external-store/createMessageConverter";
181
+ } from "@assistant-ui/core/react";
182
182
 
183
183
  // --- local ---
184
184
  export type {
@@ -188,12 +188,12 @@ export type {
188
188
  ChatModelRunUpdate,
189
189
  LocalRuntimeOptionsBase,
190
190
  } from "@assistant-ui/core";
191
- export { useLocalRuntime } from "./legacy-runtime/runtime-cores/local/useLocalRuntime";
192
- export type { LocalRuntimeOptions } from "./legacy-runtime/runtime-cores/local/LocalRuntimeOptions";
191
+ export { useLocalRuntime } from "@assistant-ui/core/react";
192
+ export type { LocalRuntimeOptions } from "@assistant-ui/core/react";
193
193
 
194
194
  // --- remote-thread-list ---
195
- export { useRemoteThreadListRuntime } from "./legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime";
196
- export { useCloudThreadListAdapter } from "./legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud";
195
+ export { useRemoteThreadListRuntime } from "@assistant-ui/core/react";
196
+ export { useCloudThreadListAdapter } from "@assistant-ui/core/react";
197
197
  export type {
198
198
  RemoteThreadListAdapter,
199
199
  RemoteThreadListProviderComponent,
@@ -274,7 +274,9 @@ export {
274
274
 
275
275
  export type {
276
276
  ModelContext,
277
+ ModelContextOptions,
277
278
  ModelContextProvider,
279
+ SystemPart,
278
280
  LanguageModelConfig,
279
281
  LanguageModelV1CallSettings,
280
282
  } from "@assistant-ui/core";
@@ -301,6 +303,7 @@ export type {
301
303
  QueueItemMethods,
302
304
  } from "@assistant-ui/core/store";
303
305
  export type { ComposerSendOptions } from "@assistant-ui/core/store";
306
+ export type { ComposerTextOrigin } from "@assistant-ui/core";
304
307
 
305
308
  export { makeAssistantVisible } from "./model-context/makeAssistantVisible";
306
309
 
package/src/internal.ts CHANGED
@@ -20,7 +20,7 @@ export type {
20
20
  } from "@assistant-ui/core/internal";
21
21
 
22
22
  // React-specific (stay in react)
23
- export { splitLocalRuntimeOptions } from "./legacy-runtime/runtime-cores/local/LocalRuntimeOptions";
23
+ export { splitLocalRuntimeOptions } from "@assistant-ui/core/react";
24
24
  export type { ToolExecutionStatus } from "@assistant-ui/core";
25
25
 
26
26
  export { useSmooth } from "./utils/smooth/useSmooth";
@@ -6,7 +6,7 @@ import {
6
6
  type AuiConfig,
7
7
  useAui,
8
8
  } from "@assistant-ui/store";
9
- import type { AssistantRuntime } from "./runtime/AssistantRuntime";
9
+ import type { AssistantRuntime } from "@assistant-ui/core";
10
10
  import { AssistantProviderBase } from "@assistant-ui/core/react";
11
11
  import { ThreadPrimitiveViewportProvider } from "../context/providers/ThreadViewportProvider";
12
12
  import { DevToolsProviderApi } from "../devtools/DevToolsHooks";