@assistant-ui/react 0.15.30 → 0.15.32

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 (550) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +1 -2
  2. package/dist/adapters/OpenAIRealtimeVoiceAdapter.js +1 -2
  3. package/dist/assistant-transport.js +1 -2
  4. package/dist/cloud-renderer/CloudRendererHost.d.ts.map +1 -1
  5. package/dist/cloud-renderer/CloudRendererHost.js +2 -4
  6. package/dist/cloud-renderer/CloudRendererHost.js.map +1 -1
  7. package/dist/context/ReadonlyStore.js +1 -2
  8. package/dist/context/providers/AttachmentByIndexProvider.js +1 -2
  9. package/dist/context/providers/ChainOfThoughtByIndicesProvider.js +1 -2
  10. package/dist/context/providers/MessageByIndexProvider.js +1 -2
  11. package/dist/context/providers/MessageProvider.js +1 -2
  12. package/dist/context/providers/PartByIndexProvider.js +1 -2
  13. package/dist/context/providers/SuggestionByIndexProvider.js +1 -2
  14. package/dist/context/providers/TextMessagePartProvider.js +1 -2
  15. package/dist/context/providers/ThreadListItemProvider.js +1 -2
  16. package/dist/context/providers/ThreadViewportProvider.js +1 -2
  17. package/dist/context/react/ThreadViewportContext.js +1 -2
  18. package/dist/context/react/utils/createContextHook.js +1 -2
  19. package/dist/context/react/utils/createContextStoreHook.js +1 -2
  20. package/dist/context/stores/ThreadViewport.js +1 -2
  21. package/dist/devtools/DevToolsHooks.js +1 -2
  22. package/dist/hooks/useMessageQuote.js +1 -2
  23. package/dist/hooks/useMessageTiming.js +1 -2
  24. package/dist/hooks/useToolCallElapsed.js +1 -2
  25. package/dist/index.d.ts +9 -8
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -9
  28. package/dist/internal.d.ts +1 -1
  29. package/dist/internal.d.ts.map +1 -1
  30. package/dist/internal.js +2 -3
  31. package/dist/internal.js.map +1 -1
  32. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts +1 -1
  33. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  34. package/dist/legacy-runtime/AssistantRuntimeProvider.js +1 -2
  35. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  36. package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  37. package/dist/mcp-apps/McpAppRenderer.js +3 -3
  38. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  39. package/dist/mcp-apps/McpAppsRemoteHost.js +1 -2
  40. package/dist/mcp-apps/app-frame.js +1 -2
  41. package/dist/mcp-apps/bridge.js +1 -2
  42. package/dist/mcp-apps/csp.js +1 -2
  43. package/dist/mcp-apps/types.js +1 -2
  44. package/dist/mcp-apps/utils.js +1 -2
  45. package/dist/model-context/frame/useAssistantFrameHost.js +1 -2
  46. package/dist/model-context/makeAssistantVisible.js +1 -2
  47. package/dist/primitives/actionBar/ActionBarCopy.d.ts +1 -1
  48. package/dist/primitives/actionBar/ActionBarCopy.js +1 -2
  49. package/dist/primitives/actionBar/ActionBarEdit.d.ts +1 -1
  50. package/dist/primitives/actionBar/ActionBarEdit.js +1 -2
  51. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +1 -1
  52. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +1 -2
  53. package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +1 -1
  54. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +1 -2
  55. package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +1 -1
  56. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +1 -2
  57. package/dist/primitives/actionBar/ActionBarInteractionContext.js +1 -2
  58. package/dist/primitives/actionBar/ActionBarReload.d.ts +1 -1
  59. package/dist/primitives/actionBar/ActionBarReload.js +1 -2
  60. package/dist/primitives/actionBar/ActionBarRoot.d.ts +1 -1
  61. package/dist/primitives/actionBar/ActionBarRoot.js +1 -2
  62. package/dist/primitives/actionBar/ActionBarSpeak.d.ts +1 -1
  63. package/dist/primitives/actionBar/ActionBarSpeak.js +1 -2
  64. package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts +1 -1
  65. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +1 -2
  66. package/dist/primitives/actionBar/useActionBarFloatStatus.js +1 -2
  67. package/dist/primitives/actionBar.js +1 -2
  68. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +1 -2
  69. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +1 -2
  70. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +1 -2
  71. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +1 -2
  72. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +1 -2
  73. package/dist/primitives/actionBarMore/scope.js +1 -2
  74. package/dist/primitives/actionBarMore.js +1 -2
  75. package/dist/primitives/assistantModal/AssistantModalAnchor.js +1 -2
  76. package/dist/primitives/assistantModal/AssistantModalContent.js +1 -2
  77. package/dist/primitives/assistantModal/AssistantModalRoot.js +1 -2
  78. package/dist/primitives/assistantModal/AssistantModalTrigger.js +1 -2
  79. package/dist/primitives/assistantModal/popoverRenderPrimitives.js +1 -2
  80. package/dist/primitives/assistantModal/scope.js +1 -2
  81. package/dist/primitives/assistantModal.js +1 -2
  82. package/dist/primitives/attachment/AttachmentName.js +1 -2
  83. package/dist/primitives/attachment/AttachmentRemove.d.ts +1 -1
  84. package/dist/primitives/attachment/AttachmentRemove.js +1 -2
  85. package/dist/primitives/attachment/AttachmentRoot.d.ts +1 -1
  86. package/dist/primitives/attachment/AttachmentRoot.js +1 -2
  87. package/dist/primitives/attachment/AttachmentThumb.d.ts +1 -1
  88. package/dist/primitives/attachment/AttachmentThumb.js +1 -2
  89. package/dist/primitives/attachment.js +1 -2
  90. package/dist/primitives/branchPicker/BranchPickerCount.js +1 -2
  91. package/dist/primitives/branchPicker/BranchPickerNext.d.ts +1 -1
  92. package/dist/primitives/branchPicker/BranchPickerNext.js +1 -2
  93. package/dist/primitives/branchPicker/BranchPickerNumber.js +1 -2
  94. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +1 -1
  95. package/dist/primitives/branchPicker/BranchPickerPrevious.js +1 -2
  96. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts +1 -1
  97. package/dist/primitives/branchPicker/BranchPickerRoot.js +1 -2
  98. package/dist/primitives/branchPicker.js +1 -2
  99. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +6 -5
  100. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -1
  101. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +57 -20
  102. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  103. package/dist/primitives/chainOfThought/ChainOfThoughtParts.js +1 -2
  104. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +1 -1
  105. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +1 -2
  106. package/dist/primitives/chainOfThought.js +1 -2
  107. package/dist/primitives/composer/ComposerAddAttachment.d.ts +1 -1
  108. package/dist/primitives/composer/ComposerAddAttachment.js +1 -2
  109. package/dist/primitives/composer/ComposerAttachmentDropzone.js +1 -2
  110. package/dist/primitives/composer/ComposerAttachments.js +1 -2
  111. package/dist/primitives/composer/ComposerCancel.d.ts +1 -1
  112. package/dist/primitives/composer/ComposerCancel.js +1 -2
  113. package/dist/primitives/composer/ComposerCompactContext.js +1 -2
  114. package/dist/primitives/composer/ComposerDictate.d.ts +1 -1
  115. package/dist/primitives/composer/ComposerDictate.js +1 -2
  116. package/dist/primitives/composer/ComposerDictationTranscript.d.ts +1 -1
  117. package/dist/primitives/composer/ComposerDictationTranscript.js +1 -2
  118. package/dist/primitives/composer/ComposerIf.js +1 -2
  119. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  120. package/dist/primitives/composer/ComposerInput.js +4 -5
  121. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  122. package/dist/primitives/composer/ComposerInputPluginContext.js +1 -2
  123. package/dist/primitives/composer/ComposerQueue.js +1 -2
  124. package/dist/primitives/composer/ComposerQuote.d.ts +3 -3
  125. package/dist/primitives/composer/ComposerQuote.js +1 -2
  126. package/dist/primitives/composer/ComposerResume.d.ts +1 -1
  127. package/dist/primitives/composer/ComposerResume.js +1 -2
  128. package/dist/primitives/composer/ComposerRoot.d.ts +1 -1
  129. package/dist/primitives/composer/ComposerRoot.js +1 -2
  130. package/dist/primitives/composer/ComposerSend.d.ts +1 -1
  131. package/dist/primitives/composer/ComposerSend.js +1 -2
  132. package/dist/primitives/composer/ComposerStopDictation.d.ts +1 -1
  133. package/dist/primitives/composer/ComposerStopDictation.js +1 -2
  134. package/dist/primitives/composer/composerInputSelector.js +1 -2
  135. package/dist/primitives/composer/trigger/TriggerPopover.d.ts +1 -1
  136. package/dist/primitives/composer/trigger/TriggerPopover.js +1 -2
  137. package/dist/primitives/composer/trigger/TriggerPopoverAction.js +1 -2
  138. package/dist/primitives/composer/trigger/TriggerPopoverBack.d.ts +1 -1
  139. package/dist/primitives/composer/trigger/TriggerPopoverBack.js +1 -2
  140. package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts +2 -2
  141. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +1 -2
  142. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js +1 -2
  143. package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts +2 -2
  144. package/dist/primitives/composer/trigger/TriggerPopoverItems.js +1 -2
  145. package/dist/primitives/composer/trigger/TriggerPopoverResource.js +1 -2
  146. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +1 -2
  147. package/dist/primitives/composer/trigger/detectTrigger.js +1 -2
  148. package/dist/primitives/composer/trigger/index.d.ts +1 -1
  149. package/dist/primitives/composer/trigger/index.js +1 -2
  150. package/dist/primitives/composer/trigger/matchesTriggerItemQuery.js +1 -2
  151. package/dist/primitives/composer/trigger/triggerDetectionResource.js +1 -2
  152. package/dist/primitives/composer/trigger/triggerKeyboardResource.js +1 -2
  153. package/dist/primitives/composer/trigger/triggerNavigationResource.js +1 -2
  154. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
  155. package/dist/primitives/composer/trigger/triggerSelectionResource.js +3 -4
  156. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  157. package/dist/primitives/composer/useComposerCancelWithFocus.js +1 -2
  158. package/dist/primitives/composer/useComposerInputState.js +1 -2
  159. package/dist/primitives/composer.js +1 -2
  160. package/dist/primitives/dropdownMenuRenderPrimitives.js +1 -2
  161. package/dist/primitives/error/ErrorMessage.d.ts +1 -1
  162. package/dist/primitives/error/ErrorMessage.js +1 -2
  163. package/dist/primitives/error/ErrorRoot.d.ts +1 -1
  164. package/dist/primitives/error/ErrorRoot.js +1 -2
  165. package/dist/primitives/error.js +1 -2
  166. package/dist/primitives/message/MessageAttachments.js +1 -2
  167. package/dist/primitives/message/MessageError.js +1 -2
  168. package/dist/primitives/message/MessageIf.js +1 -2
  169. package/dist/primitives/message/MessageParts.js +1 -2
  170. package/dist/primitives/message/MessagePartsGrouped.js +1 -2
  171. package/dist/primitives/message/MessageRoot.d.ts +1 -1
  172. package/dist/primitives/message/MessageRoot.js +1 -2
  173. package/dist/primitives/message.js +1 -2
  174. package/dist/primitives/messagePart/MessagePartImage.d.ts +1 -1
  175. package/dist/primitives/messagePart/MessagePartImage.js +1 -2
  176. package/dist/primitives/messagePart/MessagePartInProgress.js +1 -2
  177. package/dist/primitives/messagePart/MessagePartText.d.ts +1 -1
  178. package/dist/primitives/messagePart/MessagePartText.js +1 -2
  179. package/dist/primitives/messagePart/useMessagePartData.js +1 -2
  180. package/dist/primitives/messagePart/useMessagePartFile.js +1 -2
  181. package/dist/primitives/messagePart/useMessagePartImage.js +1 -2
  182. package/dist/primitives/messagePart/useMessagePartReasoning.js +1 -2
  183. package/dist/primitives/messagePart/useMessagePartSource.js +1 -2
  184. package/dist/primitives/messagePart/useMessagePartText.js +1 -2
  185. package/dist/primitives/messagePart.js +1 -2
  186. package/dist/primitives/queueItem/QueueItemRemove.d.ts +1 -1
  187. package/dist/primitives/queueItem/QueueItemRemove.js +1 -2
  188. package/dist/primitives/queueItem/QueueItemSteer.d.ts +1 -1
  189. package/dist/primitives/queueItem/QueueItemSteer.js +1 -2
  190. package/dist/primitives/queueItem/QueueItemText.d.ts +1 -1
  191. package/dist/primitives/queueItem/QueueItemText.js +1 -2
  192. package/dist/primitives/queueItem.js +1 -2
  193. package/dist/primitives/reasoning/useScrollLock.d.ts.map +1 -1
  194. package/dist/primitives/reasoning/useScrollLock.js +41 -25
  195. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  196. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts +1 -1
  197. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +1 -2
  198. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts +1 -1
  199. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +1 -2
  200. package/dist/primitives/selectionToolbar.js +1 -2
  201. package/dist/primitives/suggestion/SuggestionDescription.d.ts +1 -1
  202. package/dist/primitives/suggestion/SuggestionDescription.js +1 -2
  203. package/dist/primitives/suggestion/SuggestionTitle.d.ts +1 -1
  204. package/dist/primitives/suggestion/SuggestionTitle.js +1 -2
  205. package/dist/primitives/suggestion/SuggestionTrigger.d.ts +1 -1
  206. package/dist/primitives/suggestion/SuggestionTrigger.js +1 -2
  207. package/dist/primitives/suggestion.js +1 -2
  208. package/dist/primitives/thread/ThreadEmpty.js +1 -2
  209. package/dist/primitives/thread/ThreadIf.js +1 -2
  210. package/dist/primitives/thread/ThreadLoadEarlier.d.ts +1 -1
  211. package/dist/primitives/thread/ThreadLoadEarlier.js +1 -2
  212. package/dist/primitives/thread/ThreadMessages.js +1 -2
  213. package/dist/primitives/thread/ThreadRoot.d.ts +1 -1
  214. package/dist/primitives/thread/ThreadRoot.js +1 -2
  215. package/dist/primitives/thread/ThreadRootElementContext.js +1 -2
  216. package/dist/primitives/thread/ThreadScrollToBottom.d.ts +1 -1
  217. package/dist/primitives/thread/ThreadScrollToBottom.js +1 -2
  218. package/dist/primitives/thread/ThreadSuggestion.d.ts +1 -1
  219. package/dist/primitives/thread/ThreadSuggestion.js +1 -2
  220. package/dist/primitives/thread/ThreadSuggestions.js +1 -2
  221. package/dist/primitives/thread/ThreadViewport.d.ts +1 -1
  222. package/dist/primitives/thread/ThreadViewport.js +1 -2
  223. package/dist/primitives/thread/ThreadViewportFooter.d.ts +1 -1
  224. package/dist/primitives/thread/ThreadViewportFooter.js +1 -2
  225. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js +1 -2
  226. package/dist/primitives/thread/topAnchor/createReserveObservers.js +1 -2
  227. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js +1 -2
  228. package/dist/primitives/thread/topAnchor/topAnchorTurn.js +1 -2
  229. package/dist/primitives/thread/topAnchor/topAnchorUtils.js +1 -2
  230. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +1 -2
  231. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  232. package/dist/primitives/thread/useThreadViewportAutoScroll.js +7 -5
  233. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  234. package/dist/primitives/thread.js +1 -2
  235. package/dist/primitives/threadList/ThreadListItems.js +1 -2
  236. package/dist/primitives/threadList/ThreadListLoadMore.d.ts +1 -1
  237. package/dist/primitives/threadList/ThreadListLoadMore.js +1 -2
  238. package/dist/primitives/threadList/ThreadListNew.d.ts +1 -1
  239. package/dist/primitives/threadList/ThreadListNew.js +1 -2
  240. package/dist/primitives/threadList/ThreadListRoot.d.ts +1 -1
  241. package/dist/primitives/threadList/ThreadListRoot.js +1 -2
  242. package/dist/primitives/threadList.js +1 -2
  243. package/dist/primitives/threadListFocusGroup.d.ts +1 -1
  244. package/dist/primitives/threadListFocusGroup.d.ts.map +1 -1
  245. package/dist/primitives/threadListFocusGroup.js +1 -2
  246. package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +1 -1
  247. package/dist/primitives/threadListItem/ThreadListItemArchive.js +1 -2
  248. package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +1 -1
  249. package/dist/primitives/threadListItem/ThreadListItemDelete.js +1 -2
  250. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts +1 -1
  251. package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts.map +1 -1
  252. package/dist/primitives/threadListItem/ThreadListItemRoot.js +2 -3
  253. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  254. package/dist/primitives/threadListItem/ThreadListItemTitle.js +1 -2
  255. package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +1 -1
  256. package/dist/primitives/threadListItem/ThreadListItemTrigger.js +1 -2
  257. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +2 -2
  258. package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
  259. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js +3 -4
  260. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  261. package/dist/primitives/threadListItem.js +1 -2
  262. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +1 -2
  263. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +1 -2
  264. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +1 -2
  265. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +1 -2
  266. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +1 -2
  267. package/dist/primitives/threadListItemMore/scope.js +1 -2
  268. package/dist/primitives/threadListItemMore.js +1 -2
  269. package/dist/sandbox-host/SandboxHost.js +1 -2
  270. package/dist/unstable/useComposerInput.js +2 -3
  271. package/dist/unstable/useComposerInput.js.map +1 -1
  272. package/dist/unstable/useComposerInputHistory.d.ts.map +1 -1
  273. package/dist/unstable/useComposerInputHistory.js +3 -4
  274. package/dist/unstable/useComposerInputHistory.js.map +1 -1
  275. package/dist/unstable/useLiveCompletionAdapter.d.ts.map +1 -1
  276. package/dist/unstable/useLiveCompletionAdapter.js +4 -4
  277. package/dist/unstable/useLiveCompletionAdapter.js.map +1 -1
  278. package/dist/unstable/useMentionAdapter.js +1 -2
  279. package/dist/unstable/useMessageStallDetection.js +1 -2
  280. package/dist/unstable/useModelContextSnapshot.js +1 -2
  281. package/dist/unstable/useSlashCommandAdapter.js +1 -2
  282. package/dist/unstable/webmcp/WebMcpRegistrationResource.js +1 -2
  283. package/dist/unstable/webmcp/convertTools.js +1 -2
  284. package/dist/unstable/webmcp/useWebMcpProvider.js +1 -2
  285. package/dist/unstable/webmcp/webmcp-host.js +1 -2
  286. package/dist/utils/Primitive.d.ts +17 -17
  287. package/dist/utils/Primitive.js +1 -2
  288. package/dist/utils/createActionButton.d.ts +1 -1
  289. package/dist/utils/createActionButton.js +1 -2
  290. package/dist/utils/getSelectionMessageId.js +1 -2
  291. package/dist/utils/hooks/useManagedRef.js +1 -2
  292. package/dist/utils/hooks/useMediaQuery.js +1 -2
  293. package/dist/utils/hooks/useOnScrollToBottom.js +1 -2
  294. package/dist/utils/hooks/useSizeHandle.js +1 -2
  295. package/dist/utils/isCompositionKey.js +1 -2
  296. package/dist/utils/smooth/SmoothContext.js +1 -2
  297. package/dist/utils/smooth/useSmooth.d.ts.map +1 -1
  298. package/dist/utils/smooth/useSmooth.js +11 -4
  299. package/dist/utils/smooth/useSmooth.js.map +1 -1
  300. package/dist/utils/useIsomorphicLayoutEffect.js +0 -1
  301. package/package.json +13 -13
  302. package/src/adapters/OpenAIRealtimeVoiceAdapter.test.ts +14 -1
  303. package/src/cloud-renderer/CloudRendererHost.tsx +4 -2
  304. package/src/index.ts +9 -8
  305. package/src/internal.ts +1 -1
  306. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +1 -1
  307. package/src/mcp-apps/McpAppRenderer.composer.test.tsx +111 -0
  308. package/src/mcp-apps/McpAppRenderer.test.tsx +24 -23
  309. package/src/mcp-apps/McpAppRenderer.tsx +9 -1
  310. package/src/primitives/actionBar/ActionBarCopy.test.tsx +57 -0
  311. package/src/primitives/actionBar/ActionBarExportMarkdown.test.tsx +24 -5
  312. package/src/primitives/assistantModal/AssistantModalRoot.test.tsx +1 -1
  313. package/src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.test.tsx +91 -0
  314. package/src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.tsx +54 -0
  315. package/src/primitives/composer/ComposerInput.focus-on-run-start.test.tsx +1 -1
  316. package/src/primitives/composer/ComposerInput.test.tsx +1 -0
  317. package/src/primitives/composer/ComposerInput.text-change.test.tsx +68 -0
  318. package/src/primitives/composer/ComposerInput.thread-scope.test.tsx +82 -0
  319. package/src/primitives/composer/ComposerInput.tsx +4 -3
  320. package/src/primitives/composer/trigger/triggerSelectionResource.test.ts +6 -4
  321. package/src/primitives/composer/trigger/triggerSelectionResource.ts +2 -0
  322. package/src/primitives/reasoning/useScrollLock.test.tsx +71 -2
  323. package/src/primitives/reasoning/useScrollLock.ts +78 -51
  324. package/src/primitives/thread/ThreadRoot.test.tsx +1 -1
  325. package/src/primitives/thread/ThreadViewport.thread-scope.test.tsx +51 -0
  326. package/src/primitives/thread/useThreadViewportAutoScroll.ts +8 -2
  327. package/src/primitives/threadListItem/ThreadListItemRoot.tsx +4 -1
  328. package/src/primitives/threadListItem/ThreadListItemUnarchive.test.tsx +52 -0
  329. package/src/primitives/threadListItem/ThreadListItemUnarchive.ts +2 -2
  330. package/src/primitives/threadListItem/ThreadListKeyboardNav.test.tsx +25 -0
  331. package/src/tests/DataRenderers.test.tsx +1 -1
  332. package/src/tests/MessageParts.loading.test.tsx +1 -1
  333. package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +1 -1
  334. package/src/tests/RemoteThreadListRuntime.deferredProvider.test.tsx +4 -2
  335. package/src/tests/RemoteThreadListRuntime.reloadMainThread.test.tsx +4 -2
  336. package/src/tests/generative-ui.primitive.test.tsx +1 -1
  337. package/src/tests/local-runtime-queue.test.tsx +2 -2
  338. package/src/tests/messagePartSwitchRace.test.tsx +2 -2
  339. package/src/tests/messagePartTypeMismatch.test.tsx +1 -1
  340. package/src/tests/threadListItemIsRunning.test.tsx +5 -3
  341. package/src/tests/toolCallTiming.test.tsx +1 -1
  342. package/src/unstable/useComposerInput.test.tsx +1 -1
  343. package/src/unstable/useComposerInput.ts +1 -1
  344. package/src/unstable/useComposerInputHistory.test.tsx +10 -7
  345. package/src/unstable/useComposerInputHistory.thread-scope.test.tsx +123 -0
  346. package/src/unstable/useComposerInputHistory.ts +3 -2
  347. package/src/unstable/useLiveCompletionAdapter.test.tsx +44 -0
  348. package/src/unstable/useLiveCompletionAdapter.ts +3 -2
  349. package/src/unstable/webmcp/convertTools.test.ts +11 -1
  350. package/src/utils/hooks/useMediaQuery.test.tsx +35 -0
  351. package/src/utils/smooth/useSmooth.test.tsx +150 -14
  352. package/src/utils/smooth/useSmooth.ts +16 -2
  353. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts +0 -2
  354. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +0 -1
  355. package/dist/context/providers/ChainOfThoughtPartByIndexProvider.js +0 -3
  356. package/dist/legacy-runtime/RuntimeAdapter.d.ts +0 -2
  357. package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +0 -1
  358. package/dist/legacy-runtime/RuntimeAdapter.js +0 -2
  359. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts +0 -2
  360. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +0 -1
  361. package/dist/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.js +0 -3
  362. package/dist/legacy-runtime/runtime/AssistantRuntime.d.ts +0 -3
  363. package/dist/legacy-runtime/runtime/AssistantRuntime.d.ts.map +0 -1
  364. package/dist/legacy-runtime/runtime/AssistantRuntime.js +0 -2
  365. package/dist/legacy-runtime/runtime/AttachmentRuntime.d.ts +0 -3
  366. package/dist/legacy-runtime/runtime/AttachmentRuntime.d.ts.map +0 -1
  367. package/dist/legacy-runtime/runtime/AttachmentRuntime.js +0 -2
  368. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts +0 -4
  369. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts.map +0 -1
  370. package/dist/legacy-runtime/runtime/ComposerRuntime.js +0 -2
  371. package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts +0 -3
  372. package/dist/legacy-runtime/runtime/RuntimeBindings.d.ts.map +0 -1
  373. package/dist/legacy-runtime/runtime/RuntimeBindings.js +0 -0
  374. package/dist/legacy-runtime/runtime/RuntimePathTypes.d.ts +0 -2
  375. package/dist/legacy-runtime/runtime/RuntimePathTypes.d.ts.map +0 -1
  376. package/dist/legacy-runtime/runtime/RuntimePathTypes.js +0 -0
  377. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.d.ts +0 -5
  378. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.d.ts.map +0 -1
  379. package/dist/legacy-runtime/runtime/ThreadListItemRuntime.js +0 -2
  380. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts +0 -4
  381. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts.map +0 -1
  382. package/dist/legacy-runtime/runtime/ThreadRuntime.js +0 -2
  383. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts +0 -2
  384. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.d.ts.map +0 -1
  385. package/dist/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.js +0 -3
  386. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts +0 -2
  387. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.d.ts.map +0 -1
  388. package/dist/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.js +0 -3
  389. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts +0 -2
  390. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts.map +0 -1
  391. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.js +0 -2
  392. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts +0 -2
  393. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts.map +0 -1
  394. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.js +0 -2
  395. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts +0 -2
  396. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts.map +0 -1
  397. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.js +0 -2
  398. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +0 -2
  399. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +0 -1
  400. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.js +0 -0
  401. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +0 -2
  402. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +0 -1
  403. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +0 -2
  404. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts +0 -2
  405. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.d.ts.map +0 -1
  406. package/dist/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.js +0 -2
  407. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts +0 -2
  408. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts.map +0 -1
  409. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.js +0 -0
  410. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.d.ts +0 -2
  411. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.d.ts.map +0 -1
  412. package/dist/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.js +0 -0
  413. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts +0 -2
  414. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts.map +0 -1
  415. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.js +0 -0
  416. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts +0 -2
  417. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts.map +0 -1
  418. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.js +0 -0
  419. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.d.ts +0 -2
  420. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.d.ts.map +0 -1
  421. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.js +0 -2
  422. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +0 -3
  423. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +0 -1
  424. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +0 -2
  425. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts +0 -2
  426. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +0 -1
  427. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +0 -2
  428. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.d.ts +0 -3
  429. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.d.ts.map +0 -1
  430. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.js +0 -2
  431. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts +0 -3
  432. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts.map +0 -1
  433. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js +0 -2
  434. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +0 -2
  435. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +0 -1
  436. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +0 -2
  437. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts +0 -2
  438. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.d.ts.map +0 -1
  439. package/dist/legacy-runtime/runtime-cores/external-store/createMessageConverter.js +0 -3
  440. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +0 -2
  441. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +0 -1
  442. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +0 -3
  443. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts +0 -2
  444. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.d.ts.map +0 -1
  445. package/dist/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.js +0 -3
  446. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.d.ts +0 -2
  447. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.d.ts.map +0 -1
  448. package/dist/legacy-runtime/runtime-cores/local/ChatModelAdapter.js +0 -0
  449. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.d.ts +0 -2
  450. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.d.ts.map +0 -1
  451. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeCore.js +0 -2
  452. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts +0 -4
  453. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts.map +0 -1
  454. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js +0 -2
  455. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +0 -3
  456. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +0 -1
  457. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +0 -2
  458. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts +0 -2
  459. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts.map +0 -1
  460. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js +0 -2
  461. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.d.ts +0 -2
  462. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.d.ts.map +0 -1
  463. package/dist/legacy-runtime/runtime-cores/local/shouldContinue.js +0 -2
  464. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts +0 -2
  465. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.d.ts.map +0 -1
  466. package/dist/legacy-runtime/runtime-cores/local/useLocalRuntime.js +0 -3
  467. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.d.ts +0 -2
  468. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.d.ts.map +0 -1
  469. package/dist/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.js +0 -2
  470. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts +0 -2
  471. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts.map +0 -1
  472. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.js +0 -2
  473. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.d.ts +0 -2
  474. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.d.ts.map +0 -1
  475. package/dist/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.js +0 -2
  476. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts +0 -2
  477. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +0 -1
  478. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.js +0 -3
  479. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +0 -2
  480. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +0 -1
  481. package/dist/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +0 -3
  482. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts +0 -2
  483. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +0 -1
  484. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +0 -3
  485. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts +0 -2
  486. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.d.ts.map +0 -1
  487. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.js +0 -2
  488. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts +0 -2
  489. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.d.ts.map +0 -1
  490. package/dist/legacy-runtime/runtime-cores/remote-thread-list/types.js +0 -0
  491. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts +0 -2
  492. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.d.ts.map +0 -1
  493. package/dist/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.js +0 -3
  494. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts +0 -4
  495. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts.map +0 -1
  496. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +0 -3
  497. package/dist/utils/hooks/useOnResizeContent.d.ts +0 -2
  498. package/dist/utils/hooks/useOnResizeContent.d.ts.map +0 -1
  499. package/dist/utils/hooks/useOnResizeContent.js +0 -21
  500. package/dist/utils/hooks/useOnResizeContent.js.map +0 -1
  501. package/src/context/providers/ChainOfThoughtPartByIndexProvider.tsx +0 -3
  502. package/src/legacy-runtime/RuntimeAdapter.ts +0 -1
  503. package/src/legacy-runtime/cloud/AssistantCloudThreadHistoryAdapter.ts +0 -3
  504. package/src/legacy-runtime/runtime/AssistantRuntime.ts +0 -2
  505. package/src/legacy-runtime/runtime/AttachmentRuntime.ts +0 -7
  506. package/src/legacy-runtime/runtime/ComposerRuntime.ts +0 -20
  507. package/src/legacy-runtime/runtime/RuntimeBindings.ts +0 -12
  508. package/src/legacy-runtime/runtime/RuntimePathTypes.ts +0 -8
  509. package/src/legacy-runtime/runtime/ThreadListItemRuntime.ts +0 -10
  510. package/src/legacy-runtime/runtime/ThreadRuntime.ts +0 -14
  511. package/src/legacy-runtime/runtime-cores/adapters/RuntimeAdapterProvider.tsx +0 -7
  512. package/src/legacy-runtime/runtime-cores/adapters/attachment/CloudFileAttachmentAdapter.ts +0 -3
  513. package/src/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.ts +0 -1
  514. package/src/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.ts +0 -1
  515. package/src/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.ts +0 -1
  516. package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.ts +0 -1
  517. package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.ts +0 -1
  518. package/src/legacy-runtime/runtime-cores/core/BaseThreadRuntimeCore.ts +0 -1
  519. package/src/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.ts +0 -6
  520. package/src/legacy-runtime/runtime-cores/core/ThreadListRuntimeCore.ts +0 -4
  521. package/src/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.ts +0 -13
  522. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.ts +0 -6
  523. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreRuntimeCore.ts +0 -1
  524. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.ts +0 -2
  525. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.ts +0 -4
  526. package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageConverter.ts +0 -2
  527. package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.ts +0 -2
  528. package/src/legacy-runtime/runtime-cores/external-store/auto-status.ts +0 -1
  529. package/src/legacy-runtime/runtime-cores/external-store/createMessageConverter.ts +0 -2
  530. package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.ts +0 -7
  531. package/src/legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime.ts +0 -3
  532. package/src/legacy-runtime/runtime-cores/local/ChatModelAdapter.ts +0 -7
  533. package/src/legacy-runtime/runtime-cores/local/LocalRuntimeCore.ts +0 -1
  534. package/src/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.ts +0 -3
  535. package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.ts +0 -2
  536. package/src/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.ts +0 -1
  537. package/src/legacy-runtime/runtime-cores/local/shouldContinue.ts +0 -1
  538. package/src/legacy-runtime/runtime-cores/local/useLocalRuntime.ts +0 -3
  539. package/src/legacy-runtime/runtime-cores/remote-thread-list/BaseSubscribable.ts +0 -1
  540. package/src/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.ts +0 -1
  541. package/src/legacy-runtime/runtime-cores/remote-thread-list/OptimisticState.ts +0 -1
  542. package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +0 -3
  543. package/src/legacy-runtime/runtime-cores/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +0 -3
  544. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +0 -3
  545. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/in-memory.ts +0 -1
  546. package/src/legacy-runtime/runtime-cores/remote-thread-list/types.ts +0 -7
  547. package/src/legacy-runtime/runtime-cores/remote-thread-list/useRemoteThreadListRuntime.ts +0 -3
  548. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.ts +0 -3
  549. package/src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.ts +0 -49
  550. package/src/utils/hooks/useOnResizeContent.ts +0 -15
@@ -0,0 +1,68 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import {
4
+ act,
5
+ cleanup,
6
+ fireEvent,
7
+ render,
8
+ screen,
9
+ } from "@testing-library/react";
10
+ import type { FC } from "react";
11
+ import { afterEach, expect, it } from "vitest";
12
+ import { useAui } from "@assistant-ui/store";
13
+ import { useLocalRuntime } from "@assistant-ui/core/react";
14
+ import type { ChatModelAdapter } from "@assistant-ui/core";
15
+ import { AssistantRuntimeProvider } from "../../context";
16
+ import { ThreadPrimitiveViewportProvider } from "../../context/providers/ThreadViewportProvider";
17
+ import { ComposerPrimitiveInput } from "./ComposerInput";
18
+
19
+ const adapter: ChatModelAdapter = {
20
+ async *run() {
21
+ yield { content: [{ type: "text", text: "done" }] };
22
+ },
23
+ };
24
+
25
+ afterEach(cleanup);
26
+
27
+ it("emits composer.textChange with the user origin for typing and the send origin for the clear", async () => {
28
+ let aui!: ReturnType<typeof useAui>;
29
+ const Capture: FC = () => {
30
+ aui = useAui();
31
+ return null;
32
+ };
33
+ const App: FC = () => (
34
+ <AssistantRuntimeProvider runtime={useLocalRuntime(adapter)}>
35
+ <Capture />
36
+ <ThreadPrimitiveViewportProvider>
37
+ <ComposerPrimitiveInput aria-label="Composer" />
38
+ </ThreadPrimitiveViewportProvider>
39
+ </AssistantRuntimeProvider>
40
+ );
41
+ render(<App />);
42
+ const changes: unknown[] = [];
43
+ aui.on({ scope: "*", event: "composer.textChange" }, (change) =>
44
+ changes.push(change),
45
+ );
46
+ const input = screen.getByRole("textbox", { name: "Composer" });
47
+
48
+ await act(async () => {
49
+ fireEvent.change(input, { target: { value: "hi" } });
50
+ });
51
+ await act(async () => {
52
+ fireEvent.change(input, { target: { value: "" } });
53
+ });
54
+ await act(async () => {
55
+ fireEvent.change(input, { target: { value: "hello" } });
56
+ });
57
+ await act(async () => {
58
+ aui.composer().send();
59
+ });
60
+
61
+ const threadId = aui.threads().getState().mainThreadId;
62
+ expect(changes).toEqual([
63
+ { threadId, text: "hi", origin: "user" },
64
+ { threadId, text: "", origin: "user" },
65
+ { threadId, text: "hello", origin: "user" },
66
+ { threadId, text: "", origin: "send" },
67
+ ]);
68
+ });
@@ -0,0 +1,82 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import {
4
+ act,
5
+ cleanup,
6
+ fireEvent,
7
+ render,
8
+ screen,
9
+ waitFor,
10
+ } from "@testing-library/react";
11
+ import { afterEach, expect, it } from "vitest";
12
+ import { AuiConfig, AuiProvider, Derived, useAui } from "@assistant-ui/store";
13
+ import { ExternalThread, InMemoryThreadList } from "@assistant-ui/core/store";
14
+ import { resource, useResource } from "@assistant-ui/tap";
15
+ import { ThreadPrimitiveViewportProvider } from "../../context/providers/ThreadViewportProvider";
16
+ import { ComposerPrimitiveInput } from "./ComposerInput";
17
+
18
+ const StandaloneThread = resource(function useStandaloneThread() {
19
+ return useResource(ExternalThread({ messages: [] }));
20
+ });
21
+ const StandaloneApp = () => {
22
+ const config = AuiConfig({
23
+ thread: StandaloneThread(),
24
+ composer: Derived({
25
+ source: "thread",
26
+ query: {},
27
+ get: (aui) => aui.thread.composer(),
28
+ }),
29
+ });
30
+ return (
31
+ <AuiProvider config={config}>
32
+ <ThreadPrimitiveViewportProvider>
33
+ <ComposerPrimitiveInput aria-label="Composer" />
34
+ </ThreadPrimitiveViewportProvider>
35
+ </AuiProvider>
36
+ );
37
+ };
38
+
39
+ afterEach(cleanup);
40
+
41
+ it("edits a draft without a thread-list scope", async () => {
42
+ render(<StandaloneApp />);
43
+ const input = screen.getByRole("textbox", {
44
+ name: "Composer",
45
+ }) as HTMLTextAreaElement;
46
+ await act(async () => {
47
+ fireEvent.change(input, { target: { value: "New question" } });
48
+ });
49
+ expect(input.value).toBe("New question");
50
+ });
51
+
52
+ it("restores composer focus when the thread switches", async () => {
53
+ let captured!: ReturnType<typeof useAui>;
54
+ const App = () => {
55
+ const aui = useAui({
56
+ threads: InMemoryThreadList({
57
+ thread: () => ExternalThread({ messages: [] }),
58
+ }),
59
+ });
60
+ captured = aui;
61
+ return (
62
+ <AuiProvider value={aui}>
63
+ <ThreadPrimitiveViewportProvider>
64
+ <button>Outside</button>
65
+ <ComposerPrimitiveInput aria-label="Composer" autoFocus />
66
+ </ThreadPrimitiveViewportProvider>
67
+ </AuiProvider>
68
+ );
69
+ };
70
+ render(<App />);
71
+ const input = screen.getByRole("textbox", { name: "Composer" });
72
+ expect(document.activeElement).toBe(input);
73
+ act(() => screen.getByRole("button", { name: "Outside" }).focus());
74
+ const oldId = captured.threads.getState().mainThreadId;
75
+ await act(async () => {
76
+ captured.threads.switchToNewThread();
77
+ });
78
+ await waitFor(() =>
79
+ expect(captured.threads.getState().mainThreadId).not.toBe(oldId),
80
+ );
81
+ expect(document.activeElement).toBe(input);
82
+ });
@@ -393,7 +393,8 @@ export const ComposerPrimitiveInput = forwardRef<
393
393
  useEffect(() => {
394
394
  if (
395
395
  aui.composer.getState().type !== "thread" ||
396
- !unstable_focusOnThreadSwitched
396
+ !unstable_focusOnThreadSwitched ||
397
+ !aui.optional.threads
397
398
  )
398
399
  return undefined;
399
400
 
@@ -426,7 +427,7 @@ export const ComposerPrimitiveInput = forwardRef<
426
427
  const isComposing = nativeIsComposing || compositionRef.current;
427
428
  // Standalone tap roots need a synchronous flush while the input is composing.
428
429
  flushTapSync(() => {
429
- aui.composer.setText(e.target.value);
430
+ aui.composer.setText(e.target.value, { origin: "user" });
430
431
  });
431
432
  if (isComposing) return;
432
433
  const pos = e.target.selectionStart ?? e.target.value.length;
@@ -453,7 +454,7 @@ export const ComposerPrimitiveInput = forwardRef<
453
454
  if (!aui.composer.getState().isEditing) return;
454
455
  const target = e.target as HTMLTextAreaElement;
455
456
  flushTapSync(() => {
456
- aui.composer.setText(target.value);
457
+ aui.composer.setText(target.value, { origin: "user" });
457
458
  });
458
459
  const pos = target.selectionStart ?? target.value.length;
459
460
  if (pluginRegistry) {
@@ -77,7 +77,7 @@ describe("TriggerSelectionResource", () => {
77
77
 
78
78
  root.getValue().selectItem(item);
79
79
 
80
- expect(setText).toHaveBeenCalledWith("@file.txt tail");
80
+ expect(setText).toHaveBeenCalledWith("@file.txt tail", { origin: "user" });
81
81
  expect(setCursorPosition).toHaveBeenCalledWith("@file.txt".length + 1);
82
82
  expect(onSelected).toHaveBeenCalledOnce();
83
83
  });
@@ -120,7 +120,7 @@ describe("TriggerSelectionResource", () => {
120
120
 
121
121
  root.getValue().selectItem(item);
122
122
 
123
- expect(setText).toHaveBeenCalledWith("before tail");
123
+ expect(setText).toHaveBeenCalledWith("before tail", { origin: "user" });
124
124
  expect(setCursorPosition).toHaveBeenCalledWith(7);
125
125
  });
126
126
 
@@ -153,7 +153,7 @@ describe("TriggerSelectionResource", () => {
153
153
  root.getValue().selectItem(item);
154
154
 
155
155
  expect(setText).toHaveBeenCalledOnce();
156
- expect(setText).toHaveBeenCalledWith("@file.txt ");
156
+ expect(setText).toHaveBeenCalledWith("@file.txt ", { origin: "user" });
157
157
  expect(textRef.value).toBe("@file.txt ");
158
158
  });
159
159
 
@@ -166,6 +166,8 @@ describe("TriggerSelectionResource", () => {
166
166
 
167
167
  root.getValue().selectItem(item);
168
168
 
169
- expect(setText).toHaveBeenCalledWith("hello @file.txt tail");
169
+ expect(setText).toHaveBeenCalledWith("hello @file.txt tail", {
170
+ origin: "user",
171
+ });
170
172
  });
171
173
  });
@@ -90,6 +90,7 @@ const useTriggerSelectionResource = ({
90
90
  const directive = behavior.formatter.serialize(item);
91
91
  aui.composer.setText(
92
92
  before + directive + (after.startsWith(" ") ? after : ` ${after}`),
93
+ { origin: "user" },
93
94
  );
94
95
  setCursorPosition(before.length + directive.length + 1);
95
96
  };
@@ -101,6 +102,7 @@ const useTriggerSelectionResource = ({
101
102
  if (behavior.removeOnExecute) {
102
103
  aui.composer.setText(
103
104
  before + (after.startsWith(" ") ? after.slice(1) : after),
105
+ { origin: "user" },
104
106
  );
105
107
  setCursorPosition(before.length);
106
108
  } else {
@@ -31,9 +31,29 @@ function stubWidths(
31
31
  function lockWithin(container: HTMLElement) {
32
32
  const animated = document.createElement("div");
33
33
  container.appendChild(animated);
34
+ return createLock(animated).lock;
35
+ }
36
+
37
+ function createLock(animated: HTMLElement) {
34
38
  const ref = { current: animated };
35
- const { result } = renderHook(() => useScrollLock(ref, 200));
36
- return result.current;
39
+ const { result, unmount } = renderHook(() => useScrollLock(ref, 200));
40
+ return { lock: result.current, dispose: unmount };
41
+ }
42
+
43
+ function createSharedScroller() {
44
+ const scroller = document.createElement("div");
45
+ scroller.style.overflowY = "auto";
46
+ scroller.style.borderWidth = "0px";
47
+ scroller.style.paddingRight = "4px";
48
+ document.body.appendChild(scroller);
49
+ Object.defineProperty(scroller, "offsetWidth", { value: 306 });
50
+ Object.defineProperty(scroller, "clientWidth", {
51
+ get: () => (scroller.style.scrollbarWidth === "none" ? 306 : 300),
52
+ });
53
+ const first = document.createElement("div");
54
+ const second = document.createElement("div");
55
+ scroller.append(first, second);
56
+ return { scroller, first: createLock(first), second: createLock(second) };
37
57
  }
38
58
 
39
59
  describe("useScrollLock", () => {
@@ -115,6 +135,55 @@ describe("useScrollLock", () => {
115
135
  expect(scroller.style.scrollbarWidth).toBe("");
116
136
  });
117
137
 
138
+ it("keeps overlapping animations locked until the last one finishes", () => {
139
+ vi.useFakeTimers();
140
+ const { scroller, first, second } = createSharedScroller();
141
+ scroller.scrollTop = 120;
142
+
143
+ first.lock();
144
+ vi.advanceTimersByTime(100);
145
+ second.lock();
146
+ expect(scroller.style.paddingRight).toBe("10px");
147
+
148
+ vi.advanceTimersByTime(100);
149
+ expect(scroller.style.scrollbarWidth).toBe("none");
150
+ expect(scroller.style.paddingRight).toBe("10px");
151
+ scroller.scrollTop = 90;
152
+ scroller.dispatchEvent(new Event("scroll"));
153
+ expect(scroller.scrollTop).toBe(120);
154
+
155
+ vi.advanceTimersByTime(100);
156
+ expect(scroller.style.scrollbarWidth).toBe("");
157
+ expect(scroller.style.paddingRight).toBe("4px");
158
+ scroller.scrollTop = 90;
159
+ scroller.dispatchEvent(new Event("scroll"));
160
+ expect(scroller.scrollTop).toBe(90);
161
+ });
162
+
163
+ it.each(["first", "second"] as const)(
164
+ "preserves a restarted shared lock when the %s owner is disposed first",
165
+ (disposedFirst) => {
166
+ vi.useFakeTimers();
167
+ const shared = createSharedScroller();
168
+ const { scroller, first, second } = shared;
169
+ first.lock();
170
+ second.lock();
171
+ vi.advanceTimersByTime(100);
172
+ first.lock();
173
+
174
+ shared[disposedFirst].dispose();
175
+ expect(scroller.style.scrollbarWidth).toBe("none");
176
+ expect(scroller.style.paddingRight).toBe("10px");
177
+
178
+ shared[disposedFirst === "first" ? "second" : "first"].dispose();
179
+ expect(scroller.style.scrollbarWidth).toBe("");
180
+ expect(scroller.style.paddingRight).toBe("4px");
181
+ scroller.style.scrollbarWidth = "thin";
182
+ vi.advanceTimersByTime(200);
183
+ expect(scroller.style.scrollbarWidth).toBe("thin");
184
+ },
185
+ );
186
+
118
187
  it("leaves the padding alone when no scrollbar takes space", () => {
119
188
  const scroller = document.createElement("div");
120
189
  scroller.style.overflowY = "auto";
@@ -12,6 +12,74 @@ const findScrollableAncestor = (element: HTMLElement | null) => {
12
12
  return null;
13
13
  };
14
14
 
15
+ const scrollLocks = new WeakMap<
16
+ HTMLElement,
17
+ { count: number; restore: () => void }
18
+ >();
19
+
20
+ const acquireScrollLock = (scrollContainer: HTMLElement) => {
21
+ const existing = scrollLocks.get(scrollContainer);
22
+ if (existing) {
23
+ existing.count++;
24
+ return existing;
25
+ }
26
+
27
+ const scrollPosition = scrollContainer.scrollTop;
28
+ const scrollbarWidth = scrollContainer.style.scrollbarWidth;
29
+
30
+ // Hiding the scrollbar collapses its gutter on classic scrollbars, which
31
+ // shifts centered content horizontally; compensate with padding on the
32
+ // side the scrollbar occupies (the left side in RTL).
33
+ const computed = getComputedStyle(scrollContainer);
34
+ const paddingSide =
35
+ computed.direction === "rtl" ? "paddingLeft" : "paddingRight";
36
+ const previousPadding = scrollContainer.style[paddingSide];
37
+ const elementScrollbarSize =
38
+ scrollContainer.offsetWidth -
39
+ scrollContainer.clientWidth -
40
+ parseFloat(computed.borderLeftWidth) -
41
+ parseFloat(computed.borderRightWidth);
42
+ // A root element's offsetWidth already excludes the viewport scrollbar, so
43
+ // the element formula reports zero once the scroll propagates to the
44
+ // viewport, and only then does the viewport measure apply. A body that
45
+ // scrolls in its own right is measured by the element formula like any
46
+ // other scroller, whether or not the viewport is scrolling too.
47
+ const ownerDocument = scrollContainer.ownerDocument;
48
+ const isRootScroller =
49
+ scrollContainer === ownerDocument.documentElement ||
50
+ scrollContainer === ownerDocument.body;
51
+ const scrollbarSize =
52
+ isRootScroller && elementScrollbarSize <= 0
53
+ ? (ownerDocument.defaultView?.innerWidth ?? 0) -
54
+ ownerDocument.documentElement.clientWidth
55
+ : elementScrollbarSize;
56
+
57
+ scrollContainer.style.scrollbarWidth = "none";
58
+ if (scrollbarSize > 0) {
59
+ scrollContainer.style[paddingSide] = `${
60
+ parseFloat(computed[paddingSide]) + scrollbarSize
61
+ }px`;
62
+ }
63
+
64
+ const restoreStyles = () => {
65
+ scrollContainer.style.scrollbarWidth = scrollbarWidth;
66
+ scrollContainer.style[paddingSide] = previousPadding;
67
+ };
68
+
69
+ const resetPosition = () => (scrollContainer.scrollTop = scrollPosition);
70
+ scrollContainer.addEventListener("scroll", resetPosition);
71
+
72
+ const lock = {
73
+ count: 1,
74
+ restore: () => {
75
+ scrollContainer.removeEventListener("scroll", resetPosition);
76
+ restoreStyles();
77
+ },
78
+ };
79
+ scrollLocks.set(scrollContainer, lock);
80
+ return lock;
81
+ };
82
+
15
83
  /**
16
84
  * Locks scroll position during collapsible/height animations and hides scrollbar.
17
85
  *
@@ -59,61 +127,20 @@ export const useScrollLock = <T extends HTMLElement = HTMLElement>(
59
127
  return;
60
128
  }
61
129
 
62
- const scrollPosition = scrollContainer.scrollTop;
63
- const scrollbarWidth = scrollContainer.style.scrollbarWidth;
64
-
65
- // Hiding the scrollbar collapses its gutter on classic scrollbars, which
66
- // shifts centered content horizontally; compensate with padding on the
67
- // side the scrollbar occupies (the left side in RTL).
68
- const computed = getComputedStyle(scrollContainer);
69
- const paddingSide =
70
- computed.direction === "rtl" ? "paddingLeft" : "paddingRight";
71
- const previousPadding = scrollContainer.style[paddingSide];
72
- const elementScrollbarSize =
73
- scrollContainer.offsetWidth -
74
- scrollContainer.clientWidth -
75
- parseFloat(computed.borderLeftWidth) -
76
- parseFloat(computed.borderRightWidth);
77
- // A root element's offsetWidth already excludes the viewport scrollbar, so
78
- // the element formula reports zero once the scroll propagates to the
79
- // viewport, and only then does the viewport measure apply. A body that
80
- // scrolls in its own right is measured by the element formula like any
81
- // other scroller, whether or not the viewport is scrolling too.
82
- const ownerDocument = scrollContainer.ownerDocument;
83
- const isRootScroller =
84
- scrollContainer === ownerDocument.documentElement ||
85
- scrollContainer === ownerDocument.body;
86
- const scrollbarSize =
87
- isRootScroller && elementScrollbarSize <= 0
88
- ? (ownerDocument.defaultView?.innerWidth ?? 0) -
89
- ownerDocument.documentElement.clientWidth
90
- : elementScrollbarSize;
91
-
92
- scrollContainer.style.scrollbarWidth = "none";
93
- if (scrollbarSize > 0) {
94
- scrollContainer.style[paddingSide] = `${
95
- parseFloat(computed[paddingSide]) + scrollbarSize
96
- }px`;
97
- }
98
-
99
- const restoreStyles = () => {
100
- scrollContainer.style.scrollbarWidth = scrollbarWidth;
101
- scrollContainer.style[paddingSide] = previousPadding;
102
- };
130
+ const lock = acquireScrollLock(scrollContainer);
103
131
 
104
- const resetPosition = () => (scrollContainer.scrollTop = scrollPosition);
105
- scrollContainer.addEventListener("scroll", resetPosition);
106
-
107
- const timeoutId = setTimeout(() => {
108
- scrollContainer.removeEventListener("scroll", resetPosition);
109
- restoreStyles();
110
- cleanupRef.current = null;
111
- }, animationDuration);
132
+ const timeoutId = setTimeout(
133
+ () => cleanupRef.current?.(),
134
+ animationDuration,
135
+ );
112
136
 
113
137
  cleanupRef.current = () => {
114
138
  clearTimeout(timeoutId);
115
- scrollContainer.removeEventListener("scroll", resetPosition);
116
- restoreStyles();
139
+ if (--lock.count === 0) {
140
+ lock.restore();
141
+ scrollLocks.delete(scrollContainer);
142
+ }
143
+ cleanupRef.current = null;
117
144
  };
118
145
  }, [animationDuration, animatedElementRef]);
119
146
 
@@ -4,7 +4,7 @@ import { act, render, screen, waitFor } from "@testing-library/react";
4
4
  import type { FC, PropsWithChildren } from "react";
5
5
  import { describe, expect, it, vi } from "vitest";
6
6
  import { AssistantRuntimeProvider } from "../../context";
7
- import { useLocalRuntime } from "../../legacy-runtime/runtime-cores/local/useLocalRuntime";
7
+ import { useLocalRuntime } from "@assistant-ui/core/react";
8
8
  import type {
9
9
  ChatModelAdapter,
10
10
  SpeechSynthesisAdapter,
@@ -0,0 +1,51 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { cleanup, render } from "@testing-library/react";
4
+ import { afterEach, beforeEach, expect, it, vi } from "vitest";
5
+ import { AuiConfig, AuiProvider } from "@assistant-ui/store";
6
+ import { resource, useResource } from "@assistant-ui/tap";
7
+ import { ExternalThread } from "@assistant-ui/core/store";
8
+ import { ThreadPrimitiveViewport } from "./ThreadViewport";
9
+
10
+ const StandaloneThread = resource(function useStandaloneThread() {
11
+ return useResource(ExternalThread({ messages: [] }));
12
+ });
13
+
14
+ const Harness = ({ standalone }: { standalone: boolean }) => {
15
+ const config = AuiConfig({
16
+ thread: standalone ? StandaloneThread() : ExternalThread({ messages: [] }),
17
+ });
18
+ return (
19
+ <AuiProvider config={config}>
20
+ <ThreadPrimitiveViewport role="region" aria-label="Conversation">
21
+ Conversation content
22
+ </ThreadPrimitiveViewport>
23
+ </AuiProvider>
24
+ );
25
+ };
26
+
27
+ beforeEach(() => {
28
+ vi.stubGlobal(
29
+ "ResizeObserver",
30
+ class {
31
+ observe() {}
32
+ unobserve() {}
33
+ disconnect() {}
34
+ },
35
+ );
36
+ });
37
+
38
+ afterEach(() => {
39
+ cleanup();
40
+ vi.unstubAllGlobals();
41
+ });
42
+
43
+ it.each([true, false])(
44
+ "renders a thread viewport with standalone=%s",
45
+ (standalone) => {
46
+ const view = render(<Harness standalone={standalone} />);
47
+ expect(view.getByRole("region", { name: "Conversation" }).textContent).toBe(
48
+ "Conversation content",
49
+ );
50
+ },
51
+ );
@@ -2,6 +2,7 @@
2
2
 
3
3
  import {
4
4
  useCallback,
5
+ useEffect,
5
6
  useInsertionEffect,
6
7
  useRef,
7
8
  type RefCallback,
@@ -56,7 +57,7 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
56
57
  const divRef = useRef<TElement>(null);
57
58
  const hasMessages = useAuiState((s) => s.thread.messages.length > 0);
58
59
  const firstMessageId = useAuiState((s) => s.thread.messages[0]?.id);
59
- const threadId = useAuiState((s) => s.threadListItem.id);
60
+ const threadId = useAuiState((s) => s.optional.threadListItem?.id);
60
61
  const isRunning = useAuiState((s) => s.thread.isRunning);
61
62
  const threadViewportStore = useThreadViewportStore();
62
63
  const binding = getThreadViewportAutoScroll(threadViewportStore);
@@ -105,7 +106,12 @@ export const useThreadViewportAutoScroll = <TElement extends HTMLElement>({
105
106
 
106
107
  useOnScrollToBottom(({ behavior }) => controller.scrollToBottom(behavior));
107
108
  useAuiEvent("thread.runStart", () => controller.runStarted());
108
- useAuiEvent("threads.selectionChanged", () => controller.threadSwitched());
109
+ useEffect(() => {
110
+ if (!aui.optional.threads) return;
111
+ return aui.on("threads.selectionChanged", () =>
112
+ controller.threadSwitched(),
113
+ );
114
+ }, [aui, controller]);
109
115
 
110
116
  return useManagedRef(
111
117
  useCallback(
@@ -51,7 +51,10 @@ export const ThreadListItemPrimitiveRoot = forwardRef<
51
51
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
52
52
  const triggers = getItems()
53
53
  .map((item) => item.ref.current)
54
- .filter((node): node is HTMLButtonElement => node !== null);
54
+ .filter(
55
+ (node): node is HTMLButtonElement =>
56
+ node !== null && !node.disabled,
57
+ );
55
58
  const next =
56
59
  triggers[
57
60
  triggers.indexOf(trigger) + (event.key === "ArrowDown" ? 1 : -1)
@@ -0,0 +1,52 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { cleanup, fireEvent, render } from "@testing-library/react";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
+ import {
6
+ AssistantRuntimeProvider,
7
+ ThreadListItemByIndexProvider,
8
+ } from "@assistant-ui/core/react";
9
+ import {
10
+ AssistantRuntimeImpl,
11
+ ExternalStoreRuntimeCore,
12
+ } from "@assistant-ui/core/internal";
13
+ import { ThreadListItemPrimitiveUnarchive } from "./ThreadListItemUnarchive";
14
+
15
+ afterEach(cleanup);
16
+
17
+ describe("ThreadListItemPrimitive.Unarchive", () => {
18
+ it.each([true, false])(
19
+ "renders an actionable button only when unarchive is supported (%s)",
20
+ (supported) => {
21
+ const onUnarchive = vi.fn();
22
+ const runtime = new AssistantRuntimeImpl(
23
+ new ExternalStoreRuntimeCore({
24
+ messages: [],
25
+ onNew: async () => {},
26
+ adapters: {
27
+ threadList: {
28
+ archivedThreads: [{ id: "archived", status: "archived" }],
29
+ onUnarchive: supported ? onUnarchive : undefined,
30
+ },
31
+ },
32
+ }),
33
+ );
34
+ const { getByRole } = render(
35
+ <AssistantRuntimeProvider runtime={runtime}>
36
+ <ThreadListItemByIndexProvider index={0} archived>
37
+ <ThreadListItemPrimitiveUnarchive disabled={false}>
38
+ Restore
39
+ </ThreadListItemPrimitiveUnarchive>
40
+ </ThreadListItemByIndexProvider>
41
+ </AssistantRuntimeProvider>,
42
+ );
43
+ const button = getByRole("button", {
44
+ name: "Restore",
45
+ }) as HTMLButtonElement;
46
+ expect(button.disabled).toBe(!supported);
47
+ fireEvent.click(button);
48
+ if (supported) expect(onUnarchive).toHaveBeenCalledWith("archived");
49
+ else expect(onUnarchive).not.toHaveBeenCalled();
50
+ },
51
+ );
52
+ });
@@ -8,8 +8,8 @@ import {
8
8
  import { useThreadListItemUnarchive as useThreadListItemUnarchiveBehavior } from "@assistant-ui/core/react";
9
9
 
10
10
  const useThreadListItemUnarchive = () => {
11
- const { unarchive } = useThreadListItemUnarchiveBehavior();
12
- return unarchive;
11
+ const { unarchive, disabled } = useThreadListItemUnarchiveBehavior();
12
+ return disabled ? null : unarchive;
13
13
  };
14
14
 
15
15
  export namespace ThreadListItemPrimitiveUnarchive {
@@ -112,6 +112,31 @@ describe("thread list keyboard navigation", () => {
112
112
  expect(document.activeElement).toBe(first);
113
113
  });
114
114
 
115
+ it("skips disabled triggers in both directions without wrapping", () => {
116
+ const { container } = render(
117
+ <ThreadListPrimitiveRoot>
118
+ {[0, 1, 2].map((i) => (
119
+ <ThreadListItemPrimitiveRoot key={i}>
120
+ <ThreadListItemPrimitiveTrigger disabled={i === 1}>
121
+ item {i}
122
+ </ThreadListItemPrimitiveTrigger>
123
+ </ThreadListItemPrimitiveRoot>
124
+ ))}
125
+ </ThreadListPrimitiveRoot>,
126
+ );
127
+ const [first, , third] = triggers(container);
128
+
129
+ first!.focus();
130
+ expect(fireEvent.keyDown(first!, { key: "ArrowDown" })).toBe(false);
131
+ expect(document.activeElement).toBe(third);
132
+ expect(fireEvent.keyDown(third!, { key: "ArrowDown" })).toBe(true);
133
+ expect(document.activeElement).toBe(third);
134
+ expect(fireEvent.keyDown(third!, { key: "ArrowUp" })).toBe(false);
135
+ expect(document.activeElement).toBe(first);
136
+ expect(fireEvent.keyDown(first!, { key: "ArrowUp" })).toBe(true);
137
+ expect(document.activeElement).toBe(first);
138
+ });
139
+
115
140
  it("moves between an item and its More button with right/left arrows", () => {
116
141
  const { trigger, more } = renderItem();
117
142
 
@@ -15,7 +15,7 @@ import { useAui } from "@assistant-ui/store";
15
15
  import { AssistantRuntimeProvider } from "../context";
16
16
  import * as MessagePrimitive from "../primitives/message";
17
17
  import * as ThreadPrimitive from "../primitives/thread";
18
- import { useLocalRuntime } from "../legacy-runtime/runtime-cores/local/useLocalRuntime";
18
+ import { useLocalRuntime } from "@assistant-ui/core/react";
19
19
  import {
20
20
  useAssistantDataUI,
21
21
  type ChatModelAdapter,