@assistant-ui/react 0.14.18 → 0.14.20

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 (334) hide show
  1. package/dist/client/ExternalThread.d.ts +3 -2
  2. package/dist/client/ExternalThread.d.ts.map +1 -1
  3. package/dist/client/ExternalThread.js +721 -256
  4. package/dist/client/ExternalThread.js.map +1 -1
  5. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  6. package/dist/client/InMemoryThreadList.js +292 -108
  7. package/dist/client/InMemoryThreadList.js.map +1 -1
  8. package/dist/client/SingleThreadList.js +139 -53
  9. package/dist/client/SingleThreadList.js.map +1 -1
  10. package/dist/context/ReadonlyStore.js.map +1 -1
  11. package/dist/context/providers/MessageProvider.js +38 -5
  12. package/dist/context/providers/MessageProvider.js.map +1 -1
  13. package/dist/context/providers/ThreadViewportProvider.js +76 -20
  14. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  15. package/dist/context/react/ThreadViewportContext.js.map +1 -1
  16. package/dist/context/react/utils/createContextHook.js.map +1 -1
  17. package/dist/context/react/utils/createContextStoreHook.js +17 -2
  18. package/dist/context/react/utils/createContextStoreHook.js.map +1 -1
  19. package/dist/context/react/utils/createStateHookForRuntime.js.map +1 -1
  20. package/dist/context/react/utils/ensureBinding.js.map +1 -1
  21. package/dist/context/react/utils/useRuntimeState.js +18 -2
  22. package/dist/context/react/utils/useRuntimeState.js.map +1 -1
  23. package/dist/context/stores/ThreadViewport.js.map +1 -1
  24. package/dist/devtools/DevToolsHooks.js.map +1 -1
  25. package/dist/hooks/useMessageQuote.js.map +1 -1
  26. package/dist/hooks/useMessageTiming.js +4 -1
  27. package/dist/hooks/useMessageTiming.js.map +1 -1
  28. package/dist/hooks/useToolCallElapsed.d.ts +23 -0
  29. package/dist/hooks/useToolCallElapsed.d.ts.map +1 -0
  30. package/dist/hooks/useToolCallElapsed.js +72 -0
  31. package/dist/hooks/useToolCallElapsed.js.map +1 -0
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.js +3 -1
  34. package/dist/internal.js.map +1 -1
  35. package/dist/legacy-runtime/AssistantRuntimeProvider.js +46 -10
  36. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  37. package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
  38. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js +27 -6
  39. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js.map +1 -1
  40. package/dist/legacy-runtime/hooks/AssistantContext.js +13 -2
  41. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  42. package/dist/legacy-runtime/hooks/AttachmentContext.js +9 -1
  43. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  44. package/dist/legacy-runtime/hooks/ComposerContext.js +9 -1
  45. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  46. package/dist/legacy-runtime/hooks/MessageContext.js +12 -2
  47. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  48. package/dist/legacy-runtime/hooks/MessagePartContext.js +9 -1
  49. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  50. package/dist/legacy-runtime/hooks/ThreadContext.js +33 -5
  51. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  52. package/dist/legacy-runtime/hooks/ThreadListItemContext.js +9 -1
  53. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  54. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js +3 -3
  55. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js.map +1 -1
  56. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js +71 -31
  57. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js.map +1 -1
  58. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js.map +1 -1
  59. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +24 -16
  60. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  61. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js +17 -12
  62. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js.map +1 -1
  63. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js +17 -3
  64. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js.map +1 -1
  65. package/dist/mcp-apps/McpAppRenderer.js +6 -6
  66. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  67. package/dist/mcp-apps/McpAppsRemoteHost.js +3 -3
  68. package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
  69. package/dist/mcp-apps/app-frame.js +33 -14
  70. package/dist/mcp-apps/app-frame.js.map +1 -1
  71. package/dist/mcp-apps/bridge.js.map +1 -1
  72. package/dist/mcp-apps/types.js.map +1 -1
  73. package/dist/mcp-apps/utils.js.map +1 -1
  74. package/dist/model-context/frame/useAssistantFrameHost.js +32 -14
  75. package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
  76. package/dist/model-context/makeAssistantVisible.js +64 -26
  77. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  78. package/dist/primitives/actionBar/ActionBarCopy.js +94 -20
  79. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  80. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  81. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +105 -37
  82. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  83. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +60 -11
  84. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  85. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +60 -11
  86. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  87. package/dist/primitives/actionBar/ActionBarInteractionContext.js +3 -1
  88. package/dist/primitives/actionBar/ActionBarInteractionContext.js.map +1 -1
  89. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  90. package/dist/primitives/actionBar/ActionBarRoot.js +84 -25
  91. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  92. package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
  93. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +45 -14
  94. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  95. package/dist/primitives/actionBar/useActionBarFloatStatus.js +22 -10
  96. package/dist/primitives/actionBar/useActionBarFloatStatus.js.map +1 -1
  97. package/dist/primitives/actionBar.js.map +1 -1
  98. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +44 -7
  99. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
  100. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +28 -6
  101. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
  102. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +103 -36
  103. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
  104. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +28 -6
  105. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
  106. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +28 -6
  107. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
  108. package/dist/primitives/actionBarMore/scope.js.map +1 -1
  109. package/dist/primitives/actionBarMore.js.map +1 -1
  110. package/dist/primitives/assistantModal/AssistantModalAnchor.js +27 -6
  111. package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
  112. package/dist/primitives/assistantModal/AssistantModalContent.js +71 -10
  113. package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
  114. package/dist/primitives/assistantModal/AssistantModalRoot.js +93 -26
  115. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  116. package/dist/primitives/assistantModal/AssistantModalTrigger.js +27 -6
  117. package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
  118. package/dist/primitives/assistantModal/scope.js.map +1 -1
  119. package/dist/primitives/assistantModal.js.map +1 -1
  120. package/dist/primitives/attachment/AttachmentName.js +13 -1
  121. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  122. package/dist/primitives/attachment/AttachmentRemove.js +11 -4
  123. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  124. package/dist/primitives/attachment/AttachmentRoot.js +13 -4
  125. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  126. package/dist/primitives/attachment/AttachmentThumb.js +20 -9
  127. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  128. package/dist/primitives/attachment.js.map +1 -1
  129. package/dist/primitives/branchPicker/BranchPickerCount.js +14 -2
  130. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  131. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  132. package/dist/primitives/branchPicker/BranchPickerNumber.js +14 -2
  133. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  134. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  135. package/dist/primitives/branchPicker/BranchPickerRoot.js +34 -6
  136. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  137. package/dist/primitives/branchPicker.js.map +1 -1
  138. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +16 -5
  139. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  140. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +13 -4
  141. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  142. package/dist/primitives/chainOfThought.js.map +1 -1
  143. package/dist/primitives/composer/ComposerAddAttachment.js +37 -24
  144. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  145. package/dist/primitives/composer/ComposerAttachmentDropzone.js +124 -49
  146. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  147. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  148. package/dist/primitives/composer/ComposerDictate.js.map +1 -1
  149. package/dist/primitives/composer/ComposerDictationTranscript.js +32 -7
  150. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  151. package/dist/primitives/composer/ComposerInput.js +26 -26
  152. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  153. package/dist/primitives/composer/ComposerInputPluginContext.js +71 -25
  154. package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
  155. package/dist/primitives/composer/ComposerQuote.js +92 -23
  156. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  157. package/dist/primitives/composer/ComposerRoot.js +45 -11
  158. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  159. package/dist/primitives/composer/ComposerSend.js +9 -2
  160. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  161. package/dist/primitives/composer/ComposerStopDictation.js +15 -5
  162. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  163. package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
  164. package/dist/primitives/composer/trigger/TriggerPopover.js +215 -75
  165. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  166. package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
  167. package/dist/primitives/composer/trigger/TriggerPopoverBack.js +35 -7
  168. package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
  169. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +134 -28
  170. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
  171. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
  172. package/dist/primitives/composer/trigger/TriggerPopoverItems.js +132 -28
  173. package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
  174. package/dist/primitives/composer/trigger/TriggerPopoverResource.js +124 -52
  175. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  176. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +181 -78
  177. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
  178. package/dist/primitives/composer/trigger/detectTrigger.js.map +1 -1
  179. package/dist/primitives/composer/trigger/index.js.map +1 -1
  180. package/dist/primitives/composer/trigger/triggerDetectionResource.js +28 -14
  181. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  182. package/dist/primitives/composer/trigger/triggerKeyboardResource.js +115 -58
  183. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  184. package/dist/primitives/composer/trigger/triggerNavigationResource.js +202 -70
  185. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  186. package/dist/primitives/composer/trigger/triggerSelectionResource.js +49 -13
  187. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  188. package/dist/primitives/composer.js.map +1 -1
  189. package/dist/primitives/dropdownMenuRenderPrimitives.js.map +1 -1
  190. package/dist/primitives/error/ErrorMessage.js +28 -6
  191. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  192. package/dist/primitives/error/ErrorRoot.js +14 -5
  193. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  194. package/dist/primitives/error.js.map +1 -1
  195. package/dist/primitives/message/MessageError.js +2 -1
  196. package/dist/primitives/message/MessageError.js.map +1 -1
  197. package/dist/primitives/message/MessageIf.js +50 -20
  198. package/dist/primitives/message/MessageIf.js.map +1 -1
  199. package/dist/primitives/message/MessageParts.js +41 -7
  200. package/dist/primitives/message/MessageParts.js.map +1 -1
  201. package/dist/primitives/message/MessagePartsGrouped.js +399 -94
  202. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  203. package/dist/primitives/message/MessageRoot.js +197 -65
  204. package/dist/primitives/message/MessageRoot.js.map +1 -1
  205. package/dist/primitives/message.js.map +1 -1
  206. package/dist/primitives/messagePart/MessagePartImage.js +15 -5
  207. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  208. package/dist/primitives/messagePart/MessagePartText.js +35 -7
  209. package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
  210. package/dist/primitives/messagePart/useMessagePartData.js +5 -4
  211. package/dist/primitives/messagePart/useMessagePartData.js.map +1 -1
  212. package/dist/primitives/messagePart/useMessagePartFile.js +5 -4
  213. package/dist/primitives/messagePart/useMessagePartFile.js.map +1 -1
  214. package/dist/primitives/messagePart/useMessagePartImage.js +5 -4
  215. package/dist/primitives/messagePart/useMessagePartImage.js.map +1 -1
  216. package/dist/primitives/messagePart/useMessagePartReasoning.js +5 -4
  217. package/dist/primitives/messagePart/useMessagePartReasoning.js.map +1 -1
  218. package/dist/primitives/messagePart/useMessagePartSource.js +5 -4
  219. package/dist/primitives/messagePart/useMessagePartSource.js.map +1 -1
  220. package/dist/primitives/messagePart/useMessagePartText.js +5 -4
  221. package/dist/primitives/messagePart/useMessagePartText.js.map +1 -1
  222. package/dist/primitives/messagePart.js.map +1 -1
  223. package/dist/primitives/queueItem/QueueItemRemove.js +11 -4
  224. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  225. package/dist/primitives/queueItem/QueueItemSteer.js +11 -4
  226. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  227. package/dist/primitives/queueItem/QueueItemText.js +20 -6
  228. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  229. package/dist/primitives/queueItem.js.map +1 -1
  230. package/dist/primitives/reasoning/useScrollLock.js +61 -43
  231. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  232. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +56 -16
  233. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  234. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +120 -59
  235. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  236. package/dist/primitives/selectionToolbar.js.map +1 -1
  237. package/dist/primitives/suggestion/SuggestionDescription.js +20 -6
  238. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  239. package/dist/primitives/suggestion/SuggestionTitle.js +20 -6
  240. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  241. package/dist/primitives/suggestion/SuggestionTrigger.js +39 -26
  242. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  243. package/dist/primitives/suggestion.js.map +1 -1
  244. package/dist/primitives/thread/ThreadEmpty.js +6 -2
  245. package/dist/primitives/thread/ThreadEmpty.js.map +1 -1
  246. package/dist/primitives/thread/ThreadIf.js +32 -10
  247. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  248. package/dist/primitives/thread/ThreadRoot.js +13 -4
  249. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  250. package/dist/primitives/thread/ThreadScrollToBottom.js +24 -6
  251. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  252. package/dist/primitives/thread/ThreadSuggestion.js +18 -6
  253. package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
  254. package/dist/primitives/thread/ThreadViewport.js +185 -47
  255. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  256. package/dist/primitives/thread/ThreadViewportFooter.js +22 -9
  257. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  258. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -1
  259. package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -1
  260. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -1
  261. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -1
  262. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -1
  263. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +19 -4
  264. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  265. package/dist/primitives/thread/useThreadViewportAutoScroll.js +16 -16
  266. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  267. package/dist/primitives/thread.js.map +1 -1
  268. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -1
  269. package/dist/primitives/threadList/ThreadListNew.js +53 -11
  270. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  271. package/dist/primitives/threadList/ThreadListRoot.js +13 -4
  272. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  273. package/dist/primitives/threadList.js.map +1 -1
  274. package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
  275. package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
  276. package/dist/primitives/threadListItem/ThreadListItemRoot.js +26 -7
  277. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  278. package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
  279. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  280. package/dist/primitives/threadListItem.js.map +1 -1
  281. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +44 -7
  282. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
  283. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +28 -6
  284. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
  285. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +25 -5
  286. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
  287. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +28 -6
  288. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
  289. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +28 -6
  290. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
  291. package/dist/primitives/threadListItemMore/scope.js.map +1 -1
  292. package/dist/primitives/threadListItemMore.js.map +1 -1
  293. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  294. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  295. package/dist/tests/setup.js.map +1 -1
  296. package/dist/unstable/useComposerInputHistory.js.map +1 -1
  297. package/dist/unstable/useMentionAdapter.js.map +1 -1
  298. package/dist/unstable/useMessageStallDetection.d.ts +29 -0
  299. package/dist/unstable/useMessageStallDetection.d.ts.map +1 -0
  300. package/dist/unstable/useMessageStallDetection.js +69 -0
  301. package/dist/unstable/useMessageStallDetection.js.map +1 -0
  302. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  303. package/dist/utils/Primitive.js +57 -12
  304. package/dist/utils/Primitive.js.map +1 -1
  305. package/dist/utils/createActionButton.js +23 -7
  306. package/dist/utils/createActionButton.js.map +1 -1
  307. package/dist/utils/getSelectionMessageId.js.map +1 -1
  308. package/dist/utils/hooks/useManagedRef.js +16 -8
  309. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  310. package/dist/utils/hooks/useMediaQuery.js +25 -10
  311. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  312. package/dist/utils/hooks/useOnResizeContent.js +29 -19
  313. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  314. package/dist/utils/hooks/useOnScrollToBottom.js +20 -4
  315. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  316. package/dist/utils/hooks/useSizeHandle.js +23 -15
  317. package/dist/utils/hooks/useSizeHandle.js.map +1 -1
  318. package/dist/utils/json/is-json-equal.js.map +1 -1
  319. package/dist/utils/json/is-json.js.map +1 -1
  320. package/dist/utils/smooth/SmoothContext.js +41 -11
  321. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  322. package/dist/utils/smooth/useSmooth.js +5 -5
  323. package/dist/utils/smooth/useSmooth.js.map +1 -1
  324. package/dist/utils/useToolArgsFieldStatus.js +13 -5
  325. package/dist/utils/useToolArgsFieldStatus.js.map +1 -1
  326. package/package.json +9 -9
  327. package/src/client/ExternalThread.ts +81 -52
  328. package/src/client/InMemoryThreadList.ts +12 -14
  329. package/src/hooks/useToolCallElapsed.ts +52 -0
  330. package/src/index.ts +11 -0
  331. package/src/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.test.ts +10 -6
  332. package/src/primitives/composer/trigger/TriggerPopover.tsx +4 -5
  333. package/src/tests/toolCallTiming.test.tsx +221 -0
  334. package/src/unstable/useMessageStallDetection.ts +91 -0
@@ -1,14 +1,34 @@
1
1
  "use client";
2
2
  import { useDropdownMenuScope } from "./scope.js";
3
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  import { DropdownMenu } from "radix-ui";
5
6
  //#region src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx
6
- const ThreadListItemMorePrimitiveRoot = ({ __scopeThreadListItemMore, ...rest }) => {
7
+ const ThreadListItemMorePrimitiveRoot = (t0) => {
8
+ const $ = c(6);
9
+ let __scopeThreadListItemMore;
10
+ let rest;
11
+ if ($[0] !== t0) {
12
+ ({__scopeThreadListItemMore, ...rest} = t0);
13
+ $[0] = t0;
14
+ $[1] = __scopeThreadListItemMore;
15
+ $[2] = rest;
16
+ } else {
17
+ __scopeThreadListItemMore = $[1];
18
+ rest = $[2];
19
+ }
7
20
  const scope = useDropdownMenuScope(__scopeThreadListItemMore);
8
- return /* @__PURE__ */ jsx(DropdownMenu.Root, {
9
- ...scope,
10
- ...rest
11
- });
21
+ let t1;
22
+ if ($[3] !== rest || $[4] !== scope) {
23
+ t1 = /* @__PURE__ */ jsx(DropdownMenu.Root, {
24
+ ...scope,
25
+ ...rest
26
+ });
27
+ $[3] = rest;
28
+ $[4] = scope;
29
+ $[5] = t1;
30
+ } else t1 = $[5];
31
+ return t1;
12
32
  };
13
33
  ThreadListItemMorePrimitiveRoot.displayName = "ThreadListItemMorePrimitive.Root";
14
34
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadListItemMoreRoot.js","names":["DropdownMenuPrimitive"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC } from \"react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveRoot {\n export type Props = DropdownMenuPrimitive.DropdownMenuProps;\n}\n\nexport const ThreadListItemMorePrimitiveRoot: FC<\n ThreadListItemMorePrimitiveRoot.Props\n> = ({\n __scopeThreadListItemMore,\n ...rest\n}: ScopedProps<ThreadListItemMorePrimitiveRoot.Props>) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuPrimitive.Root {...scope} {...rest} />;\n};\n\nThreadListItemMorePrimitiveRoot.displayName =\n \"ThreadListItemMorePrimitive.Root\";\n"],"mappings":";;;;;AAUA,MAAa,mCAER,EACH,2BACA,GAAG,WACqD;CACxD,MAAM,QAAQ,qBAAqB,yBAAyB;CAE5D,OAAO,oBAACA,aAAsB,MAAvB;EAA4B,GAAI;EAAO,GAAI;CAAO,CAAA;AAC3D;AAEA,gCAAgC,cAC9B"}
1
+ {"version":3,"file":"ThreadListItemMoreRoot.js","names":["c","_c","FC","DropdownMenu","DropdownMenuPrimitive","ScopedProps","useDropdownMenuScope","ThreadListItemMorePrimitiveRoot","Props","DropdownMenuProps","t0","$","__scopeThreadListItemMore","rest","scope","t1","displayName"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC } from \"react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveRoot {\n export type Props = DropdownMenuPrimitive.DropdownMenuProps;\n}\n\nexport const ThreadListItemMorePrimitiveRoot: FC<\n ThreadListItemMorePrimitiveRoot.Props\n> = ({\n __scopeThreadListItemMore,\n ...rest\n}: ScopedProps<ThreadListItemMorePrimitiveRoot.Props>) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuPrimitive.Root {...scope} {...rest} />;\n};\n\nThreadListItemMorePrimitiveRoot.displayName =\n \"ThreadListItemMorePrimitive.Root\";\n"],"mappings":";;;;;;AAUA,MAAaO,mCAETG,OAAA;CAAA,MAAAC,IAAAV,EAAA,CAAA;CAAA,IAAAW;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAC,CAAA,CAAAE,8BAAAC,QAAAH;EAGgDC,EAAA,KAAAD;EAAAC,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,4BAAAD,EAAA;EAAAE,OAAAF,EAAA;CAAA;CACnD,MAAAG,QAAcR,qBAAqBM,yBAAyB;CAAE,IAAAG;CAAA,IAAAJ,EAAA,OAAAE,QAAAF,EAAA,OAAAG,OAAA;EAEvDC,KAAA,oBAAA,aAAA,MAAA;GAAA,GAAgCD;GAAK,GAAMD;EAAI,CAAA;EAAIF,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAA,OAAnDI;AAAmD;AAG5DR,gCAAgCS,cAC9B"}
@@ -1,15 +1,37 @@
1
1
  "use client";
2
2
  import { DropdownMenuRenderSeparator } from "../dropdownMenuRenderPrimitives.js";
3
3
  import { useDropdownMenuScope } from "./scope.js";
4
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
5
  import { forwardRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  //#region src/primitives/threadListItemMore/ThreadListItemMoreSeparator.tsx
7
- const ThreadListItemMorePrimitiveSeparator = forwardRef(({ __scopeThreadListItemMore, ...rest }, ref) => {
8
- return /* @__PURE__ */ jsx(DropdownMenuRenderSeparator, {
9
- ...useDropdownMenuScope(__scopeThreadListItemMore),
10
- ...rest,
11
- ref
12
- });
8
+ const ThreadListItemMorePrimitiveSeparator = forwardRef((t0, ref) => {
9
+ const $ = c(7);
10
+ let __scopeThreadListItemMore;
11
+ let rest;
12
+ if ($[0] !== t0) {
13
+ ({__scopeThreadListItemMore, ...rest} = t0);
14
+ $[0] = t0;
15
+ $[1] = __scopeThreadListItemMore;
16
+ $[2] = rest;
17
+ } else {
18
+ __scopeThreadListItemMore = $[1];
19
+ rest = $[2];
20
+ }
21
+ const scope = useDropdownMenuScope(__scopeThreadListItemMore);
22
+ let t1;
23
+ if ($[3] !== ref || $[4] !== rest || $[5] !== scope) {
24
+ t1 = /* @__PURE__ */ jsx(DropdownMenuRenderSeparator, {
25
+ ...scope,
26
+ ...rest,
27
+ ref
28
+ });
29
+ $[3] = ref;
30
+ $[4] = rest;
31
+ $[5] = scope;
32
+ $[6] = t1;
33
+ } else t1 = $[6];
34
+ return t1;
13
35
  });
14
36
  ThreadListItemMorePrimitiveSeparator.displayName = "ThreadListItemMorePrimitive.Separator";
15
37
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadListItemMoreSeparator.js","names":[],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreSeparator.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport type { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderSeparator } from \"../dropdownMenuRenderPrimitives\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveSeparator {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Separator>;\n export type Props = WithRenderPropProps<\n typeof DropdownMenuPrimitive.Separator\n >;\n}\n\nexport const ThreadListItemMorePrimitiveSeparator = forwardRef<\n ThreadListItemMorePrimitiveSeparator.Element,\n ThreadListItemMorePrimitiveSeparator.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveSeparator.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuRenderSeparator {...scope} {...rest} ref={ref} />;\n },\n);\n\nThreadListItemMorePrimitiveSeparator.displayName =\n \"ThreadListItemMorePrimitive.Separator\";\n"],"mappings":";;;;;;AAeA,MAAa,uCAAuC,YAKhD,EACE,2BACA,GAAG,QAEL,QACG;CAGH,OAAO,oBAAC,6BAAD;EAA6B,GAFtB,qBAAqB,yBAES;EAAG,GAAI;EAAW;CAAM,CAAA;AACtE,CACF;AAEA,qCAAqC,cACnC"}
1
+ {"version":3,"file":"ThreadListItemMoreSeparator.js","names":["c","_c","ComponentRef","forwardRef","DropdownMenu","DropdownMenuPrimitive","WithRenderPropProps","DropdownMenuRenderSeparator","ScopedProps","useDropdownMenuScope","ThreadListItemMorePrimitiveSeparator","Element","Separator","Props","t0","ref","$","__scopeThreadListItemMore","rest","scope","t1","displayName"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreSeparator.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport type { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderSeparator } from \"../dropdownMenuRenderPrimitives\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveSeparator {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Separator>;\n export type Props = WithRenderPropProps<\n typeof DropdownMenuPrimitive.Separator\n >;\n}\n\nexport const ThreadListItemMorePrimitiveSeparator = forwardRef<\n ThreadListItemMorePrimitiveSeparator.Element,\n ThreadListItemMorePrimitiveSeparator.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveSeparator.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuRenderSeparator {...scope} {...rest} ref={ref} />;\n },\n);\n\nThreadListItemMorePrimitiveSeparator.displayName =\n \"ThreadListItemMorePrimitive.Separator\";\n"],"mappings":";;;;;;;AAeA,MAAaU,uCAAuCP,YAIlDW,IAAAC,QAAA;CAAA,MAAAC,IAAAf,EAAA,CAAA;CAAA,IAAAgB;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAF,IAAA;EACE,CAAA,CAAAG,8BAAAC,QAAAJ;EAG0DE,EAAA,KAAAF;EAAAE,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,4BAAAD,EAAA;EAAAE,OAAAF,EAAA;CAAA;CAG1D,MAAAG,QAAcV,qBAAqBQ,yBAAyB;CAAE,IAAAG;CAAA,IAAAJ,EAAA,OAAAD,OAAAC,EAAA,OAAAE,QAAAF,EAAA,OAAAG,OAAA;EAEvDC,KAAA,oBAAC,6BAAD;GAA4B,GAAKD;GAAK,GAAMD;GAAWH;EAAG,CAAA;EAAIC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAA,OAA9DI;AAA8D,CAEzE;AAEAV,qCAAqCW,cACnC"}
@@ -1,15 +1,37 @@
1
1
  "use client";
2
2
  import { DropdownMenuRenderTrigger } from "../dropdownMenuRenderPrimitives.js";
3
3
  import { useDropdownMenuScope } from "./scope.js";
4
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
5
  import { forwardRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  //#region src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx
7
- const ThreadListItemMorePrimitiveTrigger = forwardRef(({ __scopeThreadListItemMore, ...rest }, ref) => {
8
- return /* @__PURE__ */ jsx(DropdownMenuRenderTrigger, {
9
- ...useDropdownMenuScope(__scopeThreadListItemMore),
10
- ...rest,
11
- ref
12
- });
8
+ const ThreadListItemMorePrimitiveTrigger = forwardRef((t0, ref) => {
9
+ const $ = c(7);
10
+ let __scopeThreadListItemMore;
11
+ let rest;
12
+ if ($[0] !== t0) {
13
+ ({__scopeThreadListItemMore, ...rest} = t0);
14
+ $[0] = t0;
15
+ $[1] = __scopeThreadListItemMore;
16
+ $[2] = rest;
17
+ } else {
18
+ __scopeThreadListItemMore = $[1];
19
+ rest = $[2];
20
+ }
21
+ const scope = useDropdownMenuScope(__scopeThreadListItemMore);
22
+ let t1;
23
+ if ($[3] !== ref || $[4] !== rest || $[5] !== scope) {
24
+ t1 = /* @__PURE__ */ jsx(DropdownMenuRenderTrigger, {
25
+ ...scope,
26
+ ...rest,
27
+ ref
28
+ });
29
+ $[3] = ref;
30
+ $[4] = rest;
31
+ $[5] = scope;
32
+ $[6] = t1;
33
+ } else t1 = $[6];
34
+ return t1;
13
35
  });
14
36
  ThreadListItemMorePrimitiveTrigger.displayName = "ThreadListItemMorePrimitive.Trigger";
15
37
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadListItemMoreTrigger.js","names":[],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport type { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderTrigger } from \"../dropdownMenuRenderPrimitives\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveTrigger {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Trigger>;\n export type Props = WithRenderPropProps<typeof DropdownMenuPrimitive.Trigger>;\n}\n\nexport const ThreadListItemMorePrimitiveTrigger = forwardRef<\n ThreadListItemMorePrimitiveTrigger.Element,\n ThreadListItemMorePrimitiveTrigger.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveTrigger.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuRenderTrigger {...scope} {...rest} ref={ref} />;\n },\n);\n\nThreadListItemMorePrimitiveTrigger.displayName =\n \"ThreadListItemMorePrimitive.Trigger\";\n"],"mappings":";;;;;;AAaA,MAAa,qCAAqC,YAK9C,EACE,2BACA,GAAG,QAEL,QACG;CAGH,OAAO,oBAAC,2BAAD;EAA2B,GAFpB,qBAAqB,yBAEO;EAAG,GAAI;EAAW;CAAM,CAAA;AACpE,CACF;AAEA,mCAAmC,cACjC"}
1
+ {"version":3,"file":"ThreadListItemMoreTrigger.js","names":["c","_c","ComponentRef","forwardRef","DropdownMenu","DropdownMenuPrimitive","WithRenderPropProps","DropdownMenuRenderTrigger","ScopedProps","useDropdownMenuScope","ThreadListItemMorePrimitiveTrigger","Element","Trigger","Props","t0","ref","$","__scopeThreadListItemMore","rest","scope","t1","displayName"],"sources":["../../../src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentRef, forwardRef } from \"react\";\nimport type { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { WithRenderPropProps } from \"../../utils/Primitive\";\nimport { DropdownMenuRenderTrigger } from \"../dropdownMenuRenderPrimitives\";\nimport { type ScopedProps, useDropdownMenuScope } from \"./scope\";\n\nexport namespace ThreadListItemMorePrimitiveTrigger {\n export type Element = ComponentRef<typeof DropdownMenuPrimitive.Trigger>;\n export type Props = WithRenderPropProps<typeof DropdownMenuPrimitive.Trigger>;\n}\n\nexport const ThreadListItemMorePrimitiveTrigger = forwardRef<\n ThreadListItemMorePrimitiveTrigger.Element,\n ThreadListItemMorePrimitiveTrigger.Props\n>(\n (\n {\n __scopeThreadListItemMore,\n ...rest\n }: ScopedProps<ThreadListItemMorePrimitiveTrigger.Props>,\n ref,\n ) => {\n const scope = useDropdownMenuScope(__scopeThreadListItemMore);\n\n return <DropdownMenuRenderTrigger {...scope} {...rest} ref={ref} />;\n },\n);\n\nThreadListItemMorePrimitiveTrigger.displayName =\n \"ThreadListItemMorePrimitive.Trigger\";\n"],"mappings":";;;;;;;AAaA,MAAaU,qCAAqCP,YAIhDW,IAAAC,QAAA;CAAA,MAAAC,IAAAf,EAAA,CAAA;CAAA,IAAAgB;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAF,IAAA;EACE,CAAA,CAAAG,8BAAAC,QAAAJ;EAGwDE,EAAA,KAAAF;EAAAE,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,4BAAAD,EAAA;EAAAE,OAAAF,EAAA;CAAA;CAGxD,MAAAG,QAAcV,qBAAqBQ,yBAAyB;CAAE,IAAAG;CAAA,IAAAJ,EAAA,OAAAD,OAAAC,EAAA,OAAAE,QAAAF,EAAA,OAAAG,OAAA;EAEvDC,KAAA,oBAAC,2BAAD;GAA0B,GAAKD;GAAK,GAAMD;GAAWH;EAAG,CAAA;EAAIC,EAAA,KAAAD;EAAAC,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAA,OAA5DI;AAA4D,CAEvE;AAEAV,mCAAmCW,cACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","names":["DropdownMenuPrimitive"],"sources":["../../../src/primitives/threadListItemMore/scope.ts"],"sourcesContent":["import { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { Scope } from \"@radix-ui/react-context\";\n\nexport const useDropdownMenuScope: ReturnType<\n typeof DropdownMenuPrimitive.createDropdownMenuScope\n> = DropdownMenuPrimitive.createDropdownMenuScope();\n\nexport type ScopedProps<P> = P & { __scopeThreadListItemMore?: Scope };\n"],"mappings":";;AAGA,MAAa,uBAETA,aAAsB,wBAAwB"}
1
+ {"version":3,"file":"scope.js","names":["DropdownMenu","DropdownMenuPrimitive","Scope","useDropdownMenuScope","ReturnType","createDropdownMenuScope","ScopedProps","P","__scopeThreadListItemMore"],"sources":["../../../src/primitives/threadListItemMore/scope.ts"],"sourcesContent":["import { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport type { Scope } from \"@radix-ui/react-context\";\n\nexport const useDropdownMenuScope: ReturnType<\n typeof DropdownMenuPrimitive.createDropdownMenuScope\n> = DropdownMenuPrimitive.createDropdownMenuScope();\n\nexport type ScopedProps<P> = P & { __scopeThreadListItemMore?: Scope };\n"],"mappings":";;AAGA,MAAaG,uBAETF,aAAsBI,wBAAwB"}
@@ -1 +1 @@
1
- {"version":3,"file":"threadListItemMore.js","names":[],"sources":["../../src/primitives/threadListItemMore.ts"],"sourcesContent":["export { ThreadListItemMorePrimitiveRoot as Root } from \"./threadListItemMore/ThreadListItemMoreRoot\";\nexport { ThreadListItemMorePrimitiveTrigger as Trigger } from \"./threadListItemMore/ThreadListItemMoreTrigger\";\nexport { ThreadListItemMorePrimitiveContent as Content } from \"./threadListItemMore/ThreadListItemMoreContent\";\nexport { ThreadListItemMorePrimitiveItem as Item } from \"./threadListItemMore/ThreadListItemMoreItem\";\nexport { ThreadListItemMorePrimitiveSeparator as Separator } from \"./threadListItemMore/ThreadListItemMoreSeparator\";\n"],"mappings":""}
1
+ {"version":3,"file":"threadListItemMore.js","names":["ThreadListItemMorePrimitiveRoot","Root","ThreadListItemMorePrimitiveTrigger","Trigger","ThreadListItemMorePrimitiveContent","Content","ThreadListItemMorePrimitiveItem","Item","ThreadListItemMorePrimitiveSeparator","Separator"],"sources":["../../src/primitives/threadListItemMore.ts"],"sourcesContent":["export { ThreadListItemMorePrimitiveRoot as Root } from \"./threadListItemMore/ThreadListItemMoreRoot\";\nexport { ThreadListItemMorePrimitiveTrigger as Trigger } from \"./threadListItemMore/ThreadListItemMoreTrigger\";\nexport { ThreadListItemMorePrimitiveContent as Content } from \"./threadListItemMore/ThreadListItemMoreContent\";\nexport { ThreadListItemMorePrimitiveItem as Item } from \"./threadListItemMore/ThreadListItemMoreItem\";\nexport { ThreadListItemMorePrimitiveSeparator as Separator } from \"./threadListItemMore/ThreadListItemMoreSeparator\";\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"SandboxHost.js","names":[],"sources":["../../src/sandbox-host/SandboxHost.tsx"],"sourcesContent":["\"use client\";\n\nimport { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport {\n type RenderedFrame,\n SafeContentFrame,\n type SandboxOption,\n} from \"safe-content-frame\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-sandbox\";\nconst DEFAULT_MAX_HEIGHT = 800;\n\nexport type SandboxHostConfig = {\n sandbox?: SandboxOption[];\n useShadowDom?: boolean;\n enableBrowserCaching?: boolean;\n salt?: string;\n product?: string;\n className?: string;\n style?: CSSProperties;\n unsafeDocumentWrite?: boolean;\n};\n\nexport type SandboxHostFrame = Pick<\n RenderedFrame,\n \"iframe\" | \"origin\" | \"sendMessage\"\n>;\n\nexport type SandboxHostApi = {\n setHeight: (height: number) => void;\n};\n\nexport type SandboxBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n};\n\nexport type SandboxContent = { html: string };\n\nexport type SandboxHostProps = {\n content: SandboxContent;\n contentKey: string;\n sandbox?: SandboxHostConfig | undefined;\n maxHeight?: number | undefined;\n createBridge: (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ) => SandboxBridge;\n onError?: ((error: Error) => void) | undefined;\n containerProps?: Record<string, string | undefined> | undefined;\n};\n\nexport function isSandboxFrameMessage(\n event: MessageEvent,\n frame: { iframe: HTMLIFrameElement; origin: string },\n): boolean {\n return (\n event.source === frame.iframe.contentWindow && event.origin === frame.origin\n );\n}\n\ntype LiveSnapshot = {\n content: SandboxContent;\n sandbox: SandboxHostConfig | undefined;\n createBridge: SandboxHostProps[\"createBridge\"];\n onError: SandboxHostProps[\"onError\"];\n};\n\nexport function SandboxHost({\n content,\n contentKey,\n sandbox,\n maxHeight = DEFAULT_MAX_HEIGHT,\n createBridge,\n onError,\n containerProps,\n}: SandboxHostProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [contentHeight, setContentHeight] = useState<number | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>(null!);\n liveRef.current = { content, sandbox, createBridge, onError };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n let frame: RenderedFrame | null = null;\n let bridge: SandboxBridge | null = null;\n let onMessage: ((event: MessageEvent) => void) | null = null;\n\n const { content: liveContent, sandbox: sb } = liveRef.current;\n\n const scf = new SafeContentFrame(sb?.product ?? DEFAULT_PRODUCT, {\n ...(sb?.sandbox !== undefined && { sandbox: sb.sandbox }),\n ...(sb?.useShadowDom !== undefined && { useShadowDom: sb.useShadowDom }),\n ...(sb?.enableBrowserCaching !== undefined && {\n enableBrowserCaching: sb.enableBrowserCaching,\n }),\n ...(sb?.salt !== undefined && { salt: sb.salt }),\n });\n\n const renderOpts =\n sb?.unsafeDocumentWrite !== undefined\n ? { unsafeDocumentWrite: sb.unsafeDocumentWrite }\n : undefined;\n\n scf\n .renderHtml(liveContent.html, container, renderOpts)\n .then((rendered) => {\n if (cancelled) {\n rendered.dispose();\n return;\n }\n frame = rendered;\n\n const hostApi: SandboxHostApi = {\n setHeight: (height) => {\n if (\n typeof height === \"number\" &&\n Number.isFinite(height) &&\n height > 0\n ) {\n setContentHeight(height);\n }\n },\n };\n\n bridge = liveRef.current.createBridge(\n {\n iframe: rendered.iframe,\n origin: rendered.origin,\n sendMessage: rendered.sendMessage,\n },\n hostApi,\n );\n\n // Single owner of the window listener; the cross-origin guard runs\n // here so the bridge only sees frame-validated messages.\n onMessage = (event) => {\n if (!isSandboxFrameMessage(event, rendered)) return;\n bridge?.onMessage(event);\n };\n window.addEventListener(\"message\", onMessage);\n })\n .catch((err) => {\n liveRef.current.onError?.(\n err instanceof Error ? err : new Error(String(err)),\n );\n });\n\n return () => {\n cancelled = true;\n if (onMessage) {\n window.removeEventListener(\"message\", onMessage);\n onMessage = null;\n }\n bridge?.dispose();\n bridge = null;\n frame?.dispose();\n frame = null;\n setContentHeight(undefined);\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-init only on contentKey change; live values flow through liveRef\n }, [contentKey]);\n\n const resolvedHeight =\n contentHeight != null ? Math.min(contentHeight, maxHeight) : undefined;\n const mergedStyle =\n resolvedHeight != null\n ? { ...sandbox?.style, height: resolvedHeight }\n : sandbox?.style;\n\n return (\n <div\n {...containerProps}\n ref={containerRef}\n className={sandbox?.className}\n style={mergedStyle}\n />\n );\n}\n"],"mappings":";;;;;AASA,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AA0C3B,SAAgB,sBACd,OACA,OACS;CACT,OACE,MAAM,WAAW,MAAM,OAAO,iBAAiB,MAAM,WAAW,MAAM;AAE1E;AASA,SAAgB,YAAY,EAC1B,SACA,YACA,SACA,YAAY,oBACZ,cACA,SACA,kBACmB;CACnB,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,CAAC,eAAe,oBAAoB,SACxC,KAAA,CACF;CAEA,MAAM,UAAU,OAAqB,IAAK;CAC1C,QAAQ,UAAU;EAAE;EAAS;EAAS;EAAc;CAAQ;CAE5D,gBAAgB;EACd,MAAM,YAAY,aAAa;EAC/B,IAAI,CAAC,WAAW;EAEhB,IAAI,YAAY;EAChB,IAAI,QAA8B;EAClC,IAAI,SAA+B;EACnC,IAAI,YAAoD;EAExD,MAAM,EAAE,SAAS,aAAa,SAAS,OAAO,QAAQ;EAEtD,MAAM,MAAM,IAAI,iBAAiB,IAAI,WAAW,iBAAiB;GAC/D,GAAI,IAAI,YAAY,KAAA,KAAa,EAAE,SAAS,GAAG,QAAQ;GACvD,GAAI,IAAI,iBAAiB,KAAA,KAAa,EAAE,cAAc,GAAG,aAAa;GACtE,GAAI,IAAI,yBAAyB,KAAA,KAAa,EAC5C,sBAAsB,GAAG,qBAC3B;GACA,GAAI,IAAI,SAAS,KAAA,KAAa,EAAE,MAAM,GAAG,KAAK;EAChD,CAAC;EAED,MAAM,aACJ,IAAI,wBAAwB,KAAA,IACxB,EAAE,qBAAqB,GAAG,oBAAoB,IAC9C,KAAA;EAEN,IACG,WAAW,YAAY,MAAM,WAAW,UAAU,CAAC,CACnD,MAAM,aAAa;GAClB,IAAI,WAAW;IACb,SAAS,QAAQ;IACjB;GACF;GACA,QAAQ;GAcR,SAAS,QAAQ,QAAQ,aACvB;IACE,QAAQ,SAAS;IACjB,QAAQ,SAAS;IACjB,aAAa,SAAS;GACxB,GACA,EAjBA,YAAY,WAAW;IACrB,IACE,OAAO,WAAW,YAClB,OAAO,SAAS,MAAM,KACtB,SAAS,GAET,iBAAiB,MAAM;GAE3B,EASM,CACR;GAIA,aAAa,UAAU;IACrB,IAAI,CAAC,sBAAsB,OAAO,QAAQ,GAAG;IAC7C,QAAQ,UAAU,KAAK;GACzB;GACA,OAAO,iBAAiB,WAAW,SAAS;EAC9C,CAAC,CAAC,CACD,OAAO,QAAQ;GACd,QAAQ,QAAQ,UACd,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CACpD;EACF,CAAC;EAEH,aAAa;GACX,YAAY;GACZ,IAAI,WAAW;IACb,OAAO,oBAAoB,WAAW,SAAS;IAC/C,YAAY;GACd;GACA,QAAQ,QAAQ;GAChB,SAAS;GACT,OAAO,QAAQ;GACf,QAAQ;GACR,iBAAiB,KAAA,CAAS;EAC5B;CAEF,GAAG,CAAC,UAAU,CAAC;CAEf,MAAM,iBACJ,iBAAiB,OAAO,KAAK,IAAI,eAAe,SAAS,IAAI,KAAA;CAC/D,MAAM,cACJ,kBAAkB,OACd;EAAE,GAAG,SAAS;EAAO,QAAQ;CAAe,IAC5C,SAAS;CAEf,OACE,oBAAC,OAAD;EACE,GAAI;EACJ,KAAK;EACL,WAAW,SAAS;EACpB,OAAO;CACR,CAAA;AAEL"}
1
+ {"version":3,"file":"SandboxHost.js","names":["CSSProperties","useEffect","useRef","useState","RenderedFrame","SafeContentFrame","SandboxOption","DEFAULT_PRODUCT","DEFAULT_MAX_HEIGHT","SandboxHostConfig","sandbox","useShadowDom","enableBrowserCaching","salt","product","className","style","unsafeDocumentWrite","SandboxHostFrame","Pick","SandboxHostApi","setHeight","height","SandboxBridge","onMessage","event","MessageEvent","dispose","SandboxContent","html","SandboxHostProps","content","contentKey","maxHeight","createBridge","frame","host","onError","error","Error","containerProps","Record","isSandboxFrameMessage","iframe","HTMLIFrameElement","origin","source","contentWindow","LiveSnapshot","SandboxHost","containerRef","HTMLDivElement","contentHeight","setContentHeight","undefined","liveRef","current","container","cancelled","bridge","liveContent","sb","scf","renderOpts","renderHtml","then","rendered","hostApi","Number","isFinite","sendMessage","window","addEventListener","catch","err","String","removeEventListener","resolvedHeight","Math","min","mergedStyle"],"sources":["../../src/sandbox-host/SandboxHost.tsx"],"sourcesContent":["\"use client\";\n\nimport { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport {\n type RenderedFrame,\n SafeContentFrame,\n type SandboxOption,\n} from \"safe-content-frame\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-sandbox\";\nconst DEFAULT_MAX_HEIGHT = 800;\n\nexport type SandboxHostConfig = {\n sandbox?: SandboxOption[];\n useShadowDom?: boolean;\n enableBrowserCaching?: boolean;\n salt?: string;\n product?: string;\n className?: string;\n style?: CSSProperties;\n unsafeDocumentWrite?: boolean;\n};\n\nexport type SandboxHostFrame = Pick<\n RenderedFrame,\n \"iframe\" | \"origin\" | \"sendMessage\"\n>;\n\nexport type SandboxHostApi = {\n setHeight: (height: number) => void;\n};\n\nexport type SandboxBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n};\n\nexport type SandboxContent = { html: string };\n\nexport type SandboxHostProps = {\n content: SandboxContent;\n contentKey: string;\n sandbox?: SandboxHostConfig | undefined;\n maxHeight?: number | undefined;\n createBridge: (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ) => SandboxBridge;\n onError?: ((error: Error) => void) | undefined;\n containerProps?: Record<string, string | undefined> | undefined;\n};\n\nexport function isSandboxFrameMessage(\n event: MessageEvent,\n frame: { iframe: HTMLIFrameElement; origin: string },\n): boolean {\n return (\n event.source === frame.iframe.contentWindow && event.origin === frame.origin\n );\n}\n\ntype LiveSnapshot = {\n content: SandboxContent;\n sandbox: SandboxHostConfig | undefined;\n createBridge: SandboxHostProps[\"createBridge\"];\n onError: SandboxHostProps[\"onError\"];\n};\n\nexport function SandboxHost({\n content,\n contentKey,\n sandbox,\n maxHeight = DEFAULT_MAX_HEIGHT,\n createBridge,\n onError,\n containerProps,\n}: SandboxHostProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [contentHeight, setContentHeight] = useState<number | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>(null!);\n liveRef.current = { content, sandbox, createBridge, onError };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n let frame: RenderedFrame | null = null;\n let bridge: SandboxBridge | null = null;\n let onMessage: ((event: MessageEvent) => void) | null = null;\n\n const { content: liveContent, sandbox: sb } = liveRef.current;\n\n const scf = new SafeContentFrame(sb?.product ?? DEFAULT_PRODUCT, {\n ...(sb?.sandbox !== undefined && { sandbox: sb.sandbox }),\n ...(sb?.useShadowDom !== undefined && { useShadowDom: sb.useShadowDom }),\n ...(sb?.enableBrowserCaching !== undefined && {\n enableBrowserCaching: sb.enableBrowserCaching,\n }),\n ...(sb?.salt !== undefined && { salt: sb.salt }),\n });\n\n const renderOpts =\n sb?.unsafeDocumentWrite !== undefined\n ? { unsafeDocumentWrite: sb.unsafeDocumentWrite }\n : undefined;\n\n scf\n .renderHtml(liveContent.html, container, renderOpts)\n .then((rendered) => {\n if (cancelled) {\n rendered.dispose();\n return;\n }\n frame = rendered;\n\n const hostApi: SandboxHostApi = {\n setHeight: (height) => {\n if (\n typeof height === \"number\" &&\n Number.isFinite(height) &&\n height > 0\n ) {\n setContentHeight(height);\n }\n },\n };\n\n bridge = liveRef.current.createBridge(\n {\n iframe: rendered.iframe,\n origin: rendered.origin,\n sendMessage: rendered.sendMessage,\n },\n hostApi,\n );\n\n // Single owner of the window listener; the cross-origin guard runs\n // here so the bridge only sees frame-validated messages.\n onMessage = (event) => {\n if (!isSandboxFrameMessage(event, rendered)) return;\n bridge?.onMessage(event);\n };\n window.addEventListener(\"message\", onMessage);\n })\n .catch((err) => {\n liveRef.current.onError?.(\n err instanceof Error ? err : new Error(String(err)),\n );\n });\n\n return () => {\n cancelled = true;\n if (onMessage) {\n window.removeEventListener(\"message\", onMessage);\n onMessage = null;\n }\n bridge?.dispose();\n bridge = null;\n frame?.dispose();\n frame = null;\n setContentHeight(undefined);\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-init only on contentKey change; live values flow through liveRef\n }, [contentKey]);\n\n const resolvedHeight =\n contentHeight != null ? Math.min(contentHeight, maxHeight) : undefined;\n const mergedStyle =\n resolvedHeight != null\n ? { ...sandbox?.style, height: resolvedHeight }\n : sandbox?.style;\n\n return (\n <div\n {...containerProps}\n ref={containerRef}\n className={sandbox?.className}\n style={mergedStyle}\n />\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"remote-thread-list-test-helpers.js","names":[],"sources":["../../src/tests/remote-thread-list-test-helpers.ts"],"sourcesContent":["import { vi } from \"vitest\";\nimport type { RemoteThreadListAdapter } from \"../index\";\n\nexport function makeAdapter(\n overrides: Partial<RemoteThreadListAdapter> = {},\n): RemoteThreadListAdapter {\n return {\n list: vi.fn(async () => ({ threads: [] })),\n initialize: vi.fn(async (threadId: string) => ({\n remoteId: threadId,\n externalId: threadId,\n })),\n rename: vi.fn(async () => {}),\n archive: vi.fn(async () => {}),\n unarchive: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n generateTitle: vi.fn(\n async () =>\n new ReadableStream({\n start(c) {\n c.close();\n },\n }) as never,\n ),\n fetch: vi.fn(async (id: string) => ({\n status: \"regular\" as const,\n remoteId: id,\n externalId: id,\n title: \"Test\",\n })),\n ...overrides,\n };\n}\n"],"mappings":";;AAGA,SAAgB,YACd,YAA8C,CAAC,GACtB;CACzB,OAAO;EACL,MAAM,GAAG,GAAG,aAAa,EAAE,SAAS,CAAC,EAAE,EAAE;EACzC,YAAY,GAAG,GAAG,OAAO,cAAsB;GAC7C,UAAU;GACV,YAAY;EACd,EAAE;EACF,QAAQ,GAAG,GAAG,YAAY,CAAC,CAAC;EAC5B,SAAS,GAAG,GAAG,YAAY,CAAC,CAAC;EAC7B,WAAW,GAAG,GAAG,YAAY,CAAC,CAAC;EAC/B,QAAQ,GAAG,GAAG,YAAY,CAAC,CAAC;EAC5B,eAAe,GAAG,GAChB,YACE,IAAI,eAAe,EACjB,MAAM,GAAG;GACP,EAAE,MAAM;EACV,EACF,CAAC,CACL;EACA,OAAO,GAAG,GAAG,OAAO,QAAgB;GAClC,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,OAAO;EACT,EAAE;EACF,GAAG;CACL;AACF"}
1
+ {"version":3,"file":"remote-thread-list-test-helpers.js","names":["vi","RemoteThreadListAdapter","makeAdapter","overrides","Partial","list","fn","threads","initialize","threadId","remoteId","externalId","rename","archive","unarchive","delete","generateTitle","ReadableStream","start","c","close","fetch","id","status","const","title"],"sources":["../../src/tests/remote-thread-list-test-helpers.ts"],"sourcesContent":["import { vi } from \"vitest\";\nimport type { RemoteThreadListAdapter } from \"../index\";\n\nexport function makeAdapter(\n overrides: Partial<RemoteThreadListAdapter> = {},\n): RemoteThreadListAdapter {\n return {\n list: vi.fn(async () => ({ threads: [] })),\n initialize: vi.fn(async (threadId: string) => ({\n remoteId: threadId,\n externalId: threadId,\n })),\n rename: vi.fn(async () => {}),\n archive: vi.fn(async () => {}),\n unarchive: vi.fn(async () => {}),\n delete: vi.fn(async () => {}),\n generateTitle: vi.fn(\n async () =>\n new ReadableStream({\n start(c) {\n c.close();\n },\n }) as never,\n ),\n fetch: vi.fn(async (id: string) => ({\n status: \"regular\" as const,\n remoteId: id,\n externalId: id,\n title: \"Test\",\n })),\n ...overrides,\n };\n}\n"],"mappings":";;AAGA,SAAgBE,YACdC,YAA8C,CAAC,GACtB;CACzB,OAAO;EACLE,MAAML,GAAGM,GAAG,aAAa,EAAEC,SAAS,CAAA,EAAG,EAAE;EACzCC,YAAYR,GAAGM,GAAG,OAAOG,cAAsB;GAC7CC,UAAUD;GACVE,YAAYF;EACd,EAAE;EACFG,QAAQZ,GAAGM,GAAG,YAAY,CAAC,CAAC;EAC5BO,SAASb,GAAGM,GAAG,YAAY,CAAC,CAAC;EAC7BQ,WAAWd,GAAGM,GAAG,YAAY,CAAC,CAAC;EAC/BS,QAAQf,GAAGM,GAAG,YAAY,CAAC,CAAC;EAC5BU,eAAehB,GAAGM,GAChB,YACE,IAAIW,eAAe,EACjBC,MAAMC,GAAG;GACPA,EAAEC,MAAM;EACV,EACF,CAAC,CACL;EACAC,OAAOrB,GAAGM,GAAG,OAAOgB,QAAgB;GAClCC,QAAQ;GACRb,UAAUY;GACVX,YAAYW;GACZG,OAAO;EACT,EAAE;EACF,GAAGtB;CACL;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","names":[],"sources":["../../src/tests/setup.ts"],"sourcesContent":["// This file contains setup code for tests\nimport { vi } from \"vitest\";\n\n// Use Vitest's built-in to mock Date\nvi.setSystemTime(new Date(\"2023-01-01\"));\n"],"mappings":";;AAIA,GAAG,8BAAc,IAAI,KAAK,YAAY,CAAC"}
1
+ {"version":3,"file":"setup.js","names":["vi","setSystemTime","Date"],"sources":["../../src/tests/setup.ts"],"sourcesContent":["// This file contains setup code for tests\nimport { vi } from \"vitest\";\n\n// Use Vitest's built-in to mock Date\nvi.setSystemTime(new Date(\"2023-01-01\"));\n"],"mappings":";;AAIAA,GAAGC,8BAAc,IAAIC,KAAK,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useComposerInputHistory.js","names":[],"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\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 * @deprecated Under active development and might change without notice.\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 * @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(\"threadListItem.switchedTo\", () => {\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","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\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 * @deprecated Under active development and might change without notice.\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 * @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(\"threadListItem.switchedTo\", () => {\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 +1 @@
1
- {"version":3,"file":"useMentionAdapter.js","names":[],"sources":["../../src/unstable/useMentionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, type FC } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type {\n Unstable_DirectiveFormatter,\n Unstable_TriggerAdapter,\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport { unstable_defaultDirectiveFormatter } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n/** Icon component shape consumed by `ComposerTriggerPopover`'s `iconMap`. */\nexport type Unstable_IconComponent = FC<{ className?: string }>;\n\nexport type Unstable_Mention = {\n readonly id: string;\n readonly type: string;\n readonly label: string;\n readonly description?: string | undefined;\n /** Shortcut for `metadata.icon`; merged with `metadata` if both are given. */\n readonly icon?: string | undefined;\n readonly metadata?: ReadonlyJSONObject | undefined;\n};\n\nexport type Unstable_MentionCategory = {\n readonly id: string;\n readonly label: string;\n readonly items: readonly Unstable_Mention[];\n};\n\nexport type Unstable_ModelContextToolsOptions = {\n /** Wrap tools in a dedicated category (drill-down mode). */\n readonly category?: { readonly id: string; readonly label: string };\n /** Format tool name for display. */\n readonly formatLabel?: (toolName: string) => string;\n /** Default icon key for each tool. */\n readonly icon?: string;\n};\n\nexport type Unstable_UseMentionAdapterOptions = {\n /** Flat mention list. Ignored when `categories` is set. */\n readonly items?: readonly Unstable_Mention[];\n /** Categorized mentions for drill-down navigation. */\n readonly categories?: readonly Unstable_MentionCategory[];\n /**\n * How tools registered in model context integrate.\n * - `false`: exclude.\n * - `true`: include (default when no `items`/`categories`; as a category\n * if `categories` is set, flat otherwise).\n * - object: explicit config.\n *\n * Omitted → defaults to `true` iff neither `items` nor `categories`.\n */\n readonly includeModelContextTools?:\n | boolean\n | Unstable_ModelContextToolsOptions;\n /** Directive formatter. @default unstable_defaultDirectiveFormatter */\n readonly formatter?: Unstable_DirectiveFormatter;\n /** Fires after an item is inserted into the composer. */\n readonly onInserted?: (item: Unstable_TriggerItem) => void;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_MentionDirective = {\n readonly formatter: Unstable_DirectiveFormatter;\n readonly onInserted?: ((item: Unstable_TriggerItem) => void) | undefined;\n};\n\n/**\n * @deprecated Under active development and might change without notice.\n *\n * Creates a spreadable `{ adapter, directive }` bundle for `@` mentions.\n * Supports tools registered in model context, explicit items, or both —\n * flat or categorized.\n *\n * @example\n * ```tsx\n * const mention = unstable_useMentionAdapter();\n * <ComposerTriggerPopover char=\"@\" {...mention} />\n * ```\n */\nexport function unstable_useMentionAdapter(\n options?: Unstable_UseMentionAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n directive: Unstable_MentionDirective;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const aui = useAui();\n\n const items = options?.items;\n const categories = options?.categories;\n const includeTools =\n options?.includeModelContextTools ?? (!items && !categories);\n const toolsConfig =\n typeof includeTools === \"object\" ? includeTools : undefined;\n const wantsTools = includeTools !== false;\n const formatter = options?.formatter;\n const onInserted = options?.onInserted;\n\n const adapter = useMemo<Unstable_TriggerAdapter>(() => {\n const getModelContextTools = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return [];\n const ctx = aui.thread().getModelContext();\n const tools = ctx.tools;\n if (!tools) return [];\n const formatLabel = toolsConfig?.formatLabel;\n const defaultIcon = toolsConfig?.icon;\n return Object.entries(tools).map(([name, tool]) =>\n toTriggerItem({\n id: name,\n type: \"tool\",\n label: formatLabel ? formatLabel(name) : name,\n description: tool.description ?? undefined,\n icon: defaultIcon,\n }),\n );\n };\n\n // Categorized: drill-down mode\n if (categories && categories.length > 0) {\n const groups = categories.map((cat) => ({\n id: cat.id,\n label: cat.label,\n items: cat.items.map(toTriggerItem),\n }));\n\n let toolCategory: {\n id: string;\n label: string;\n items: Unstable_TriggerItem[];\n } | null = null;\n if (wantsTools) {\n const toolItems = getModelContextTools();\n if (toolItems.length > 0) {\n toolCategory = {\n id: toolsConfig?.category?.id ?? \"tools\",\n label: toolsConfig?.category?.label ?? \"Tools\",\n items: toolItems,\n };\n }\n }\n const allGroups = toolCategory ? [...groups, toolCategory] : groups;\n\n return {\n categories: () => allGroups.map(({ id, label }) => ({ id, label })),\n categoryItems: (id) => allGroups.find((g) => g.id === id)?.items ?? [],\n search: (query) => {\n const lower = query.toLowerCase();\n return allGroups\n .flatMap((g) => g.items)\n .filter((item) => matchesQuery(item, lower));\n },\n };\n }\n\n // Flat: items + (optionally) tools, all in one search pool\n const flatItems = (items ?? []).map(toTriggerItem);\n const getFlatPool = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return flatItems;\n const toolItems = getModelContextTools();\n // Dedupe by id — explicit items win.\n const seen = new Set(flatItems.map((i) => i.id));\n return [...flatItems, ...toolItems.filter((t) => !seen.has(t.id))];\n };\n\n return {\n categories: (): readonly Unstable_TriggerCategory[] => [],\n categoryItems: () => [],\n search: (query) => {\n const lower = query.toLowerCase();\n return getFlatPool().filter((item) => matchesQuery(item, lower));\n },\n };\n }, [aui, items, categories, wantsTools, toolsConfig]);\n\n const directive = useMemo<Unstable_MentionDirective>(\n () => ({\n formatter: formatter ?? unstable_defaultDirectiveFormatter,\n ...(onInserted ? { onInserted } : {}),\n }),\n [formatter, onInserted],\n );\n\n return {\n adapter,\n directive,\n ...(options?.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options?.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n}\n\nfunction toTriggerItem(m: Unstable_Mention): Unstable_TriggerItem {\n const metadata =\n m.icon !== undefined ? { ...(m.metadata ?? {}), icon: m.icon } : m.metadata;\n return {\n id: m.id,\n type: m.type,\n label: m.label,\n ...(m.description !== undefined ? { description: m.description } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nfunction matchesQuery(item: Unstable_TriggerItem, lower: string): boolean {\n if (!lower) return true;\n if (item.id.toLowerCase().includes(lower)) return true;\n if (item.label.toLowerCase().includes(lower)) return true;\n if (item.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useMentionAdapter.js","names":["useMemo","FC","useAui","Unstable_DirectiveFormatter","Unstable_TriggerAdapter","Unstable_TriggerCategory","Unstable_TriggerItem","unstable_defaultDirectiveFormatter","ReadonlyJSONObject","Unstable_IconComponent","className","Unstable_Mention","id","type","label","description","icon","metadata","Unstable_MentionCategory","items","Unstable_ModelContextToolsOptions","category","formatLabel","toolName","Unstable_UseMentionAdapterOptions","categories","includeModelContextTools","formatter","onInserted","item","iconMap","Record","fallbackIcon","Unstable_MentionDirective","unstable_useMentionAdapter","options","adapter","directive","aui","includeTools","toolsConfig","undefined","wantsTools","getModelContextTools","ctx","thread","getModelContext","tools","defaultIcon","Object","entries","map","name","tool","toTriggerItem","length","groups","cat","toolCategory","toolItems","allGroups","categoryItems","find","g","search","query","lower","toLowerCase","flatMap","filter","matchesQuery","flatItems","getFlatPool","seen","Set","i","t","has","m","includes"],"sources":["../../src/unstable/useMentionAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, type FC } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type {\n Unstable_DirectiveFormatter,\n Unstable_TriggerAdapter,\n Unstable_TriggerCategory,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport { unstable_defaultDirectiveFormatter } from \"@assistant-ui/core\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\n\n/** Icon component shape consumed by `ComposerTriggerPopover`'s `iconMap`. */\nexport type Unstable_IconComponent = FC<{ className?: string }>;\n\nexport type Unstable_Mention = {\n readonly id: string;\n readonly type: string;\n readonly label: string;\n readonly description?: string | undefined;\n /** Shortcut for `metadata.icon`; merged with `metadata` if both are given. */\n readonly icon?: string | undefined;\n readonly metadata?: ReadonlyJSONObject | undefined;\n};\n\nexport type Unstable_MentionCategory = {\n readonly id: string;\n readonly label: string;\n readonly items: readonly Unstable_Mention[];\n};\n\nexport type Unstable_ModelContextToolsOptions = {\n /** Wrap tools in a dedicated category (drill-down mode). */\n readonly category?: { readonly id: string; readonly label: string };\n /** Format tool name for display. */\n readonly formatLabel?: (toolName: string) => string;\n /** Default icon key for each tool. */\n readonly icon?: string;\n};\n\nexport type Unstable_UseMentionAdapterOptions = {\n /** Flat mention list. Ignored when `categories` is set. */\n readonly items?: readonly Unstable_Mention[];\n /** Categorized mentions for drill-down navigation. */\n readonly categories?: readonly Unstable_MentionCategory[];\n /**\n * How tools registered in model context integrate.\n * - `false`: exclude.\n * - `true`: include (default when no `items`/`categories`; as a category\n * if `categories` is set, flat otherwise).\n * - object: explicit config.\n *\n * Omitted → defaults to `true` iff neither `items` nor `categories`.\n */\n readonly includeModelContextTools?:\n | boolean\n | Unstable_ModelContextToolsOptions;\n /** Directive formatter. @default unstable_defaultDirectiveFormatter */\n readonly formatter?: Unstable_DirectiveFormatter;\n /** Fires after an item is inserted into the composer. */\n readonly onInserted?: (item: Unstable_TriggerItem) => void;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_MentionDirective = {\n readonly formatter: Unstable_DirectiveFormatter;\n readonly onInserted?: ((item: Unstable_TriggerItem) => void) | undefined;\n};\n\n/**\n * @deprecated Under active development and might change without notice.\n *\n * Creates a spreadable `{ adapter, directive }` bundle for `@` mentions.\n * Supports tools registered in model context, explicit items, or both —\n * flat or categorized.\n *\n * @example\n * ```tsx\n * const mention = unstable_useMentionAdapter();\n * <ComposerTriggerPopover char=\"@\" {...mention} />\n * ```\n */\nexport function unstable_useMentionAdapter(\n options?: Unstable_UseMentionAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n directive: Unstable_MentionDirective;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const aui = useAui();\n\n const items = options?.items;\n const categories = options?.categories;\n const includeTools =\n options?.includeModelContextTools ?? (!items && !categories);\n const toolsConfig =\n typeof includeTools === \"object\" ? includeTools : undefined;\n const wantsTools = includeTools !== false;\n const formatter = options?.formatter;\n const onInserted = options?.onInserted;\n\n const adapter = useMemo<Unstable_TriggerAdapter>(() => {\n const getModelContextTools = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return [];\n const ctx = aui.thread().getModelContext();\n const tools = ctx.tools;\n if (!tools) return [];\n const formatLabel = toolsConfig?.formatLabel;\n const defaultIcon = toolsConfig?.icon;\n return Object.entries(tools).map(([name, tool]) =>\n toTriggerItem({\n id: name,\n type: \"tool\",\n label: formatLabel ? formatLabel(name) : name,\n description: tool.description ?? undefined,\n icon: defaultIcon,\n }),\n );\n };\n\n // Categorized: drill-down mode\n if (categories && categories.length > 0) {\n const groups = categories.map((cat) => ({\n id: cat.id,\n label: cat.label,\n items: cat.items.map(toTriggerItem),\n }));\n\n let toolCategory: {\n id: string;\n label: string;\n items: Unstable_TriggerItem[];\n } | null = null;\n if (wantsTools) {\n const toolItems = getModelContextTools();\n if (toolItems.length > 0) {\n toolCategory = {\n id: toolsConfig?.category?.id ?? \"tools\",\n label: toolsConfig?.category?.label ?? \"Tools\",\n items: toolItems,\n };\n }\n }\n const allGroups = toolCategory ? [...groups, toolCategory] : groups;\n\n return {\n categories: () => allGroups.map(({ id, label }) => ({ id, label })),\n categoryItems: (id) => allGroups.find((g) => g.id === id)?.items ?? [],\n search: (query) => {\n const lower = query.toLowerCase();\n return allGroups\n .flatMap((g) => g.items)\n .filter((item) => matchesQuery(item, lower));\n },\n };\n }\n\n // Flat: items + (optionally) tools, all in one search pool\n const flatItems = (items ?? []).map(toTriggerItem);\n const getFlatPool = (): Unstable_TriggerItem[] => {\n if (!wantsTools) return flatItems;\n const toolItems = getModelContextTools();\n // Dedupe by id — explicit items win.\n const seen = new Set(flatItems.map((i) => i.id));\n return [...flatItems, ...toolItems.filter((t) => !seen.has(t.id))];\n };\n\n return {\n categories: (): readonly Unstable_TriggerCategory[] => [],\n categoryItems: () => [],\n search: (query) => {\n const lower = query.toLowerCase();\n return getFlatPool().filter((item) => matchesQuery(item, lower));\n },\n };\n }, [aui, items, categories, wantsTools, toolsConfig]);\n\n const directive = useMemo<Unstable_MentionDirective>(\n () => ({\n formatter: formatter ?? unstable_defaultDirectiveFormatter,\n ...(onInserted ? { onInserted } : {}),\n }),\n [formatter, onInserted],\n );\n\n return {\n adapter,\n directive,\n ...(options?.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options?.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n}\n\nfunction toTriggerItem(m: Unstable_Mention): Unstable_TriggerItem {\n const metadata =\n m.icon !== undefined ? { ...(m.metadata ?? {}), icon: m.icon } : m.metadata;\n return {\n id: m.id,\n type: m.type,\n label: m.label,\n ...(m.description !== undefined ? { description: m.description } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nfunction matchesQuery(item: Unstable_TriggerItem, lower: string): boolean {\n if (!lower) return true;\n if (item.id.toLowerCase().includes(lower)) return true;\n if (item.label.toLowerCase().includes(lower)) return true;\n if (item.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ //#region src/unstable/useMessageStallDetection.d.ts
2
+ type Unstable_MessageStallDetectionOptions = {
3
+ /**
4
+ * Milliseconds of unchanged message content before the message counts as
5
+ * stalled.
6
+ * @default 2000
7
+ */
8
+ thresholdMs?: number | undefined;
9
+ };
10
+ type Unstable_MessageStallDetection = {
11
+ /** True while the message is running and its content has not changed for at least `thresholdMs`. */stalled: boolean; /** Milliseconds since the last observed content change. `0` while not stalled. */
12
+ stalledForMs: number;
13
+ };
14
+ /**
15
+ * @deprecated Under active development and might change without notice.
16
+ *
17
+ * Detects mid-run output stalls on the current message: while the message is
18
+ * running, watches a fingerprint of its content (part count plus text,
19
+ * argument, and result sizes) and reports a stall once the fingerprint stops
20
+ * changing for `thresholdMs`. Useful for re-surfacing a "still working"
21
+ * indicator during tool think-time or provider stalls, after the first
22
+ * tokens have already streamed.
23
+ *
24
+ * Must be used inside a message scope.
25
+ */
26
+ declare function unstable_useMessageStallDetection(options?: Unstable_MessageStallDetectionOptions): Unstable_MessageStallDetection;
27
+ //#endregion
28
+ export { Unstable_MessageStallDetection, Unstable_MessageStallDetectionOptions, unstable_useMessageStallDetection };
29
+ //# sourceMappingURL=useMessageStallDetection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMessageStallDetection.d.ts","names":[],"sources":["../../src/unstable/useMessageStallDetection.ts"],"mappings":";KAKY,qCAAA;EAAA;;;;AAMC;EAAX,WAAW;AAAA;AAAA,KAGD,8BAAA;EAEV,oGAAA,OAAA,WAiBc;EAfd,YAAY;AAAA;;;;;;AAiBmB;;;;;;;iBAFjB,iCAAA,CACd,OAAA,GAAU,qCAAA,GACT,8BAA8B"}
@@ -0,0 +1,69 @@
1
+ "use client";
2
+ import { useAuiState } from "@assistant-ui/store";
3
+ import { useEffect, useRef, useState } from "@assistant-ui/tap/react-shim";
4
+ //#region src/unstable/useMessageStallDetection.ts
5
+ /**
6
+ * @deprecated Under active development and might change without notice.
7
+ *
8
+ * Detects mid-run output stalls on the current message: while the message is
9
+ * running, watches a fingerprint of its content (part count plus text,
10
+ * argument, and result sizes) and reports a stall once the fingerprint stops
11
+ * changing for `thresholdMs`. Useful for re-surfacing a "still working"
12
+ * indicator during tool think-time or provider stalls, after the first
13
+ * tokens have already streamed.
14
+ *
15
+ * Must be used inside a message scope.
16
+ */
17
+ function unstable_useMessageStallDetection(options) {
18
+ const thresholdMs = options?.thresholdMs ?? 2e3;
19
+ const fingerprint = useAuiState((s) => {
20
+ if (s.message.status?.type !== "running") return void 0;
21
+ let size = 0;
22
+ for (const part of s.message.content) if (part.type === "text" || part.type === "reasoning") size += part.text.length;
23
+ else if (part.type === "tool-call") size += part.argsText.length + (part.result !== void 0 ? 1 : 0);
24
+ return `${s.message.content.length}:${size}`;
25
+ });
26
+ const running = fingerprint !== void 0;
27
+ const lastActivityRef = useRef(Date.now());
28
+ const [stalled, setStalled] = useState(false);
29
+ const [, setTick] = useState(0);
30
+ useEffect(() => {
31
+ if (!running) return void 0;
32
+ lastActivityRef.current = Date.now();
33
+ }, [running, fingerprint]);
34
+ useEffect(() => {
35
+ if (!running) {
36
+ setStalled(false);
37
+ return;
38
+ }
39
+ const sinceActivity = Date.now() - lastActivityRef.current;
40
+ if (sinceActivity >= thresholdMs) {
41
+ setStalled(true);
42
+ return;
43
+ }
44
+ setStalled(false);
45
+ const id = setTimeout(() => setStalled(true), thresholdMs - sinceActivity);
46
+ return () => clearTimeout(id);
47
+ }, [
48
+ running,
49
+ fingerprint,
50
+ thresholdMs
51
+ ]);
52
+ useEffect(() => {
53
+ if (!stalled) return void 0;
54
+ const id = setInterval(() => setTick((t) => t + 1), 1e3);
55
+ return () => clearInterval(id);
56
+ }, [stalled]);
57
+ if (!stalled) return {
58
+ stalled: false,
59
+ stalledForMs: 0
60
+ };
61
+ return {
62
+ stalled: true,
63
+ stalledForMs: Math.max(0, Date.now() - lastActivityRef.current)
64
+ };
65
+ }
66
+ //#endregion
67
+ export { unstable_useMessageStallDetection };
68
+
69
+ //# sourceMappingURL=useMessageStallDetection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMessageStallDetection.js","names":["useEffect","useRef","useState","useAuiState","Unstable_MessageStallDetectionOptions","thresholdMs","Unstable_MessageStallDetection","stalled","stalledForMs","unstable_useMessageStallDetection","options","fingerprint","s","message","status","type","undefined","size","part","content","text","length","argsText","result","running","lastActivityRef","Date","now","setStalled","setTick","current","sinceActivity","id","setTimeout","clearTimeout","setInterval","t","clearInterval","Math","max"],"sources":["../../src/unstable/useMessageStallDetection.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport type Unstable_MessageStallDetectionOptions = {\n /**\n * Milliseconds of unchanged message content before the message counts as\n * stalled.\n * @default 2000\n */\n thresholdMs?: number | undefined;\n};\n\nexport type Unstable_MessageStallDetection = {\n /** True while the message is running and its content has not changed for at least `thresholdMs`. */\n stalled: boolean;\n /** Milliseconds since the last observed content change. `0` while not stalled. */\n stalledForMs: number;\n};\n\n/**\n * @deprecated Under active development and might change without notice.\n *\n * Detects mid-run output stalls on the current message: while the message is\n * running, watches a fingerprint of its content (part count plus text,\n * argument, and result sizes) and reports a stall once the fingerprint stops\n * changing for `thresholdMs`. Useful for re-surfacing a \"still working\"\n * indicator during tool think-time or provider stalls, after the first\n * tokens have already streamed.\n *\n * Must be used inside a message scope.\n */\nexport function unstable_useMessageStallDetection(\n options?: Unstable_MessageStallDetectionOptions,\n): Unstable_MessageStallDetection {\n const thresholdMs = options?.thresholdMs ?? 2000;\n\n const fingerprint = useAuiState((s) => {\n if (s.message.status?.type !== \"running\") return undefined;\n let size = 0;\n for (const part of s.message.content) {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n size += part.text.length;\n } else if (part.type === \"tool-call\") {\n size += part.argsText.length + (part.result !== undefined ? 1 : 0);\n }\n }\n return `${s.message.content.length}:${size}`;\n });\n\n const running = fingerprint !== undefined;\n const lastActivityRef = useRef(Date.now());\n const [stalled, setStalled] = useState(false);\n const [, setTick] = useState(0);\n\n useEffect(() => {\n if (!running) return undefined;\n lastActivityRef.current = Date.now();\n return undefined;\n }, [running, fingerprint]);\n\n useEffect(() => {\n if (!running) {\n setStalled(false);\n return undefined;\n }\n\n const sinceActivity = Date.now() - lastActivityRef.current;\n if (sinceActivity >= thresholdMs) {\n setStalled(true);\n return undefined;\n }\n\n setStalled(false);\n const id = setTimeout(() => setStalled(true), thresholdMs - sinceActivity);\n return () => clearTimeout(id);\n }, [running, fingerprint, thresholdMs]);\n\n useEffect(() => {\n if (!stalled) return undefined;\n const id = setInterval(() => setTick((t) => t + 1), 1000);\n return () => clearInterval(id);\n }, [stalled]);\n\n if (!stalled) return { stalled: false, stalledForMs: 0 };\n return {\n stalled: true,\n stalledForMs: Math.max(0, Date.now() - lastActivityRef.current),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiCA,SAAgBS,kCACdC,SACgC;CAChC,MAAML,cAAcK,SAASL,eAAe;CAE5C,MAAMM,cAAcR,aAAaS,MAAM;EACrC,IAAIA,EAAEC,QAAQC,QAAQC,SAAS,WAAW,OAAOC,KAAAA;EACjD,IAAIC,OAAO;EACX,KAAK,MAAMC,QAAQN,EAAEC,QAAQM,SAC3B,IAAID,KAAKH,SAAS,UAAUG,KAAKH,SAAS,aACxCE,QAAQC,KAAKE,KAAKC;OACb,IAAIH,KAAKH,SAAS,aACvBE,QAAQC,KAAKI,SAASD,UAAUH,KAAKK,WAAWP,KAAAA,IAAY,IAAI;EAGpE,OAAO,GAAGJ,EAAEC,QAAQM,QAAQE,OAAM,GAAIJ;CACxC,CAAC;CAED,MAAMO,UAAUb,gBAAgBK,KAAAA;CAChC,MAAMS,kBAAkBxB,OAAOyB,KAAKC,IAAI,CAAC;CACzC,MAAM,CAACpB,SAASqB,cAAc1B,SAAS,KAAK;CAC5C,MAAM,GAAG2B,WAAW3B,SAAS,CAAC;CAE9BF,gBAAgB;EACd,IAAI,CAACwB,SAAS,OAAOR,KAAAA;EACrBS,gBAAgBK,UAAUJ,KAAKC,IAAI;CAErC,GAAG,CAACH,SAASb,WAAW,CAAC;CAEzBX,gBAAgB;EACd,IAAI,CAACwB,SAAS;GACZI,WAAW,KAAK;GAChB;EACF;EAEA,MAAMG,gBAAgBL,KAAKC,IAAI,IAAIF,gBAAgBK;EACnD,IAAIC,iBAAiB1B,aAAa;GAChCuB,WAAW,IAAI;GACf;EACF;EAEAA,WAAW,KAAK;EAChB,MAAMI,KAAKC,iBAAiBL,WAAW,IAAI,GAAGvB,cAAc0B,aAAa;EACzE,aAAaG,aAAaF,EAAE;CAC9B,GAAG;EAACR;EAASb;EAAaN;CAAW,CAAC;CAEtCL,gBAAgB;EACd,IAAI,CAACO,SAAS,OAAOS,KAAAA;EACrB,MAAMgB,KAAKG,kBAAkBN,SAASO,MAAMA,IAAI,CAAC,GAAG,GAAI;EACxD,aAAaC,cAAcL,EAAE;CAC/B,GAAG,CAACzB,OAAO,CAAC;CAEZ,IAAI,CAACA,SAAS,OAAO;EAAEA,SAAS;EAAOC,cAAc;CAAE;CACvD,OAAO;EACLD,SAAS;EACTC,cAAc8B,KAAKC,IAAI,GAAGb,KAAKC,IAAI,IAAIF,gBAAgBK,OAAO;CAChE;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSlashCommandAdapter.js","names":[],"sources":["../../src/unstable/useSlashCommandAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport type { Unstable_IconComponent } from \"./useMentionAdapter\";\n\nexport type Unstable_SlashCommand = {\n readonly id: string;\n readonly label?: string | undefined;\n readonly description?: string | undefined;\n readonly icon?: string | undefined;\n readonly execute: () => void;\n};\n\nexport type Unstable_UseSlashCommandAdapterOptions = {\n readonly commands: readonly Unstable_SlashCommand[];\n /** Strip the trigger text from the composer after executing. @default false */\n readonly removeOnExecute?: boolean | undefined;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_SlashCommandAction = {\n readonly onExecute: (item: Unstable_TriggerItem) => void;\n readonly removeOnExecute?: boolean | undefined;\n};\n\n/**\n * @deprecated Under active development and may change without notice.\n *\n * Bundles slash command definitions (with inline `execute` callbacks) into\n * `{adapter, action}` that plug directly into `ComposerTriggerPopover`.\n * `execute` stays in the hook closure and is never attached to the returned\n * `TriggerItem`, keeping items serializable.\n *\n * @example\n * ```tsx\n * const slash = unstable_useSlashCommandAdapter({\n * commands: [\n * { id: \"summarize\", execute: () => runSummarize(), icon: \"FileText\" },\n * { id: \"translate\", execute: () => runTranslate(), icon: \"Languages\" },\n * ],\n * });\n *\n * <ComposerTriggerPopover char=\"/\" {...slash} />\n * ```\n */\nexport function unstable_useSlashCommandAdapter(\n options: Unstable_UseSlashCommandAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n action: Unstable_SlashCommandAction;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const { commands, removeOnExecute } = options;\n\n const commandsRef = useRef(commands);\n commandsRef.current = commands;\n\n return useMemo(() => {\n const adapter: Unstable_TriggerAdapter = {\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n const lower = query.toLowerCase();\n return commandsRef.current\n .filter((c) => matchesQuery(c, lower))\n .map(toItem);\n },\n };\n\n const action: Unstable_SlashCommandAction = {\n onExecute: (item) => {\n commandsRef.current.find((c) => c.id === item.id)?.execute();\n },\n ...(removeOnExecute !== undefined ? { removeOnExecute } : {}),\n };\n\n return {\n adapter,\n action,\n ...(options.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n }, [removeOnExecute, options.iconMap, options.fallbackIcon]);\n}\n\nfunction toItem(cmd: Unstable_SlashCommand): Unstable_TriggerItem {\n return {\n id: cmd.id,\n type: \"command\",\n label: cmd.label ?? `/${cmd.id}`,\n ...(cmd.description !== undefined ? { description: cmd.description } : {}),\n ...(cmd.icon !== undefined ? { metadata: { icon: cmd.icon } } : {}),\n };\n}\n\nfunction matchesQuery(cmd: Unstable_SlashCommand, lower: string): boolean {\n if (!lower) return true;\n if (cmd.id.toLowerCase().includes(lower)) return true;\n if (cmd.label?.toLowerCase().includes(lower)) return true;\n if (cmd.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,gCACd,SAMA;CACA,MAAM,EAAE,UAAU,oBAAoB;CAEtC,MAAM,cAAc,OAAO,QAAQ;CACnC,YAAY,UAAU;CAEtB,OAAO,cAAc;EAmBnB,OAAO;GACL,SAAA;IAlBA,kBAAkB,CAAC;IACnB,qBAAqB,CAAC;IACtB,SAAS,UAAkB;KACzB,MAAM,QAAQ,MAAM,YAAY;KAChC,OAAO,YAAY,QAChB,QAAQ,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CACrC,IAAI,MAAM;IACf;GAWM;GACN,QAAA;IARA,YAAY,SAAS;KACnB,YAAY,QAAQ,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,CAAC,EAAE,QAAQ;IAC7D;IACA,GAAI,oBAAoB,KAAA,IAAY,EAAE,gBAAgB,IAAI,CAAC;GAKtD;GACL,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;GACtD,GAAI,QAAQ,eAAe,EAAE,cAAc,QAAQ,aAAa,IAAI,CAAC;EACvE;CACF,GAAG;EAAC;EAAiB,QAAQ;EAAS,QAAQ;CAAY,CAAC;AAC7D;AAEA,SAAS,OAAO,KAAkD;CAChE,OAAO;EACL,IAAI,IAAI;EACR,MAAM;EACN,OAAO,IAAI,SAAS,IAAI,IAAI;EAC5B,GAAI,IAAI,gBAAgB,KAAA,IAAY,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;EACxE,GAAI,IAAI,SAAS,KAAA,IAAY,EAAE,UAAU,EAAE,MAAM,IAAI,KAAK,EAAE,IAAI,CAAC;CACnE;AACF;AAEA,SAAS,aAAa,KAA4B,OAAwB;CACxE,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,IAAI,GAAG,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,OAAO;CACjD,IAAI,IAAI,OAAO,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,OAAO;CACrD,IAAI,IAAI,aAAa,YAAY,CAAC,CAAC,SAAS,KAAK,GAAG,OAAO;CAC3D,OAAO;AACT"}
1
+ {"version":3,"file":"useSlashCommandAdapter.js","names":["useMemo","useRef","Unstable_TriggerAdapter","Unstable_TriggerItem","Unstable_IconComponent","Unstable_SlashCommand","id","label","description","icon","execute","Unstable_UseSlashCommandAdapterOptions","commands","removeOnExecute","iconMap","Record","fallbackIcon","Unstable_SlashCommandAction","onExecute","item","unstable_useSlashCommandAdapter","options","adapter","action","commandsRef","current","categories","categoryItems","search","query","lower","toLowerCase","filter","c","matchesQuery","map","toItem","find","undefined","cmd","type","metadata","includes"],"sources":["../../src/unstable/useSlashCommandAdapter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useRef } from \"react\";\nimport type {\n Unstable_TriggerAdapter,\n Unstable_TriggerItem,\n} from \"@assistant-ui/core\";\nimport type { Unstable_IconComponent } from \"./useMentionAdapter\";\n\nexport type Unstable_SlashCommand = {\n readonly id: string;\n readonly label?: string | undefined;\n readonly description?: string | undefined;\n readonly icon?: string | undefined;\n readonly execute: () => void;\n};\n\nexport type Unstable_UseSlashCommandAdapterOptions = {\n readonly commands: readonly Unstable_SlashCommand[];\n /** Strip the trigger text from the composer after executing. @default false */\n readonly removeOnExecute?: boolean | undefined;\n /** Maps `metadata.icon` / `category.id` string keys to React components. */\n readonly iconMap?: Record<string, Unstable_IconComponent>;\n /** Fallback icon when no entry in `iconMap` matches. */\n readonly fallbackIcon?: Unstable_IconComponent;\n};\n\nexport type Unstable_SlashCommandAction = {\n readonly onExecute: (item: Unstable_TriggerItem) => void;\n readonly removeOnExecute?: boolean | undefined;\n};\n\n/**\n * @deprecated Under active development and may change without notice.\n *\n * Bundles slash command definitions (with inline `execute` callbacks) into\n * `{adapter, action}` that plug directly into `ComposerTriggerPopover`.\n * `execute` stays in the hook closure and is never attached to the returned\n * `TriggerItem`, keeping items serializable.\n *\n * @example\n * ```tsx\n * const slash = unstable_useSlashCommandAdapter({\n * commands: [\n * { id: \"summarize\", execute: () => runSummarize(), icon: \"FileText\" },\n * { id: \"translate\", execute: () => runTranslate(), icon: \"Languages\" },\n * ],\n * });\n *\n * <ComposerTriggerPopover char=\"/\" {...slash} />\n * ```\n */\nexport function unstable_useSlashCommandAdapter(\n options: Unstable_UseSlashCommandAdapterOptions,\n): {\n adapter: Unstable_TriggerAdapter;\n action: Unstable_SlashCommandAction;\n iconMap?: Record<string, Unstable_IconComponent>;\n fallbackIcon?: Unstable_IconComponent;\n} {\n const { commands, removeOnExecute } = options;\n\n const commandsRef = useRef(commands);\n commandsRef.current = commands;\n\n return useMemo(() => {\n const adapter: Unstable_TriggerAdapter = {\n categories: () => [],\n categoryItems: () => [],\n search: (query: string) => {\n const lower = query.toLowerCase();\n return commandsRef.current\n .filter((c) => matchesQuery(c, lower))\n .map(toItem);\n },\n };\n\n const action: Unstable_SlashCommandAction = {\n onExecute: (item) => {\n commandsRef.current.find((c) => c.id === item.id)?.execute();\n },\n ...(removeOnExecute !== undefined ? { removeOnExecute } : {}),\n };\n\n return {\n adapter,\n action,\n ...(options.iconMap ? { iconMap: options.iconMap } : {}),\n ...(options.fallbackIcon ? { fallbackIcon: options.fallbackIcon } : {}),\n };\n }, [removeOnExecute, options.iconMap, options.fallbackIcon]);\n}\n\nfunction toItem(cmd: Unstable_SlashCommand): Unstable_TriggerItem {\n return {\n id: cmd.id,\n type: \"command\",\n label: cmd.label ?? `/${cmd.id}`,\n ...(cmd.description !== undefined ? { description: cmd.description } : {}),\n ...(cmd.icon !== undefined ? { metadata: { icon: cmd.icon } } : {}),\n };\n}\n\nfunction matchesQuery(cmd: Unstable_SlashCommand, lower: string): boolean {\n if (!lower) return true;\n if (cmd.id.toLowerCase().includes(lower)) return true;\n if (cmd.label?.toLowerCase().includes(lower)) return true;\n if (cmd.description?.toLowerCase().includes(lower)) return true;\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgBoB,gCACdC,SAMA;CACA,MAAM,EAAET,UAAUC,oBAAoBQ;CAEtC,MAAMG,cAAcvB,OAAOW,QAAQ;CACnCY,YAAYC,UAAUb;CAEtB,OAAOZ,cAAc;EAmBnB,OAAO;GACLsB,SAAAA;IAlBAI,kBAAkB,CAAA;IAClBC,qBAAqB,CAAA;IACrBC,SAASC,UAAkB;KACzB,MAAMC,QAAQD,MAAME,YAAY;KAChC,OAAOP,YAAYC,QAChBO,QAAQC,MAAMC,aAAaD,GAAGH,KAAK,CAAC,CAAC,CACrCK,IAAIC,MAAM;IACf;GAWAd;GACAC,QAAAA;IARAL,YAAYC,SAAS;KACnBK,YAAYC,QAAQY,MAAMJ,MAAMA,EAAE3B,OAAOa,KAAKb,EAAE,CAAC,EAAEI,QAAQ;IAC7D;IACA,GAAIG,oBAAoByB,KAAAA,IAAY,EAAEzB,gBAAgB,IAAI,CAAC;GAK3DU;GACA,GAAIF,QAAQP,UAAU,EAAEA,SAASO,QAAQP,QAAQ,IAAI,CAAC;GACtD,GAAIO,QAAQL,eAAe,EAAEA,cAAcK,QAAQL,aAAa,IAAI,CAAC;EACvE;CACF,GAAG;EAACH;EAAiBQ,QAAQP;EAASO,QAAQL;CAAY,CAAC;AAC7D;AAEA,SAASoB,OAAOG,KAAkD;CAChE,OAAO;EACLjC,IAAIiC,IAAIjC;EACRkC,MAAM;EACNjC,OAAOgC,IAAIhC,SAAS,IAAIgC,IAAIjC;EAC5B,GAAIiC,IAAI/B,gBAAgB8B,KAAAA,IAAY,EAAE9B,aAAa+B,IAAI/B,YAAY,IAAI,CAAC;EACxE,GAAI+B,IAAI9B,SAAS6B,KAAAA,IAAY,EAAEG,UAAU,EAAEhC,MAAM8B,IAAI9B,KAAK,EAAE,IAAI,CAAC;CACnE;AACF;AAEA,SAASyB,aAAaK,KAA4BT,OAAwB;CACxE,IAAI,CAACA,OAAO,OAAO;CACnB,IAAIS,IAAIjC,GAAGyB,YAAY,CAAC,CAACW,SAASZ,KAAK,GAAG,OAAO;CACjD,IAAIS,IAAIhC,OAAOwB,YAAY,CAAC,CAACW,SAASZ,KAAK,GAAG,OAAO;CACrD,IAAIS,IAAI/B,aAAauB,YAAY,CAAC,CAACW,SAASZ,KAAK,GAAG,OAAO;CAC3D,OAAO;AACT"}
@@ -1,3 +1,4 @@
1
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
1
2
  import { cloneElement, forwardRef, isValidElement } from "@assistant-ui/tap/react-shim";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  import { Primitive as Primitive$1 } from "@radix-ui/react-primitive";
@@ -31,23 +32,67 @@ const NODES = [
31
32
  "ul"
32
33
  ];
33
34
  function withRenderProp(Component) {
34
- const Wrapped = forwardRef(({ render, asChild, children, ...rest }, ref) => {
35
+ const Wrapped = forwardRef((t0, ref) => {
36
+ const $ = c(17);
37
+ let asChild;
38
+ let children;
39
+ let render;
40
+ let rest;
41
+ if ($[0] !== t0) {
42
+ ({render, asChild, children, ...rest} = t0);
43
+ $[0] = t0;
44
+ $[1] = asChild;
45
+ $[2] = children;
46
+ $[3] = render;
47
+ $[4] = rest;
48
+ } else {
49
+ asChild = $[1];
50
+ children = $[2];
51
+ render = $[3];
52
+ rest = $[4];
53
+ }
35
54
  const Comp = Component;
36
55
  if (render && isValidElement(render)) {
37
56
  const renderChildren = children !== void 0 ? children : render.props.children;
38
- return /* @__PURE__ */ jsx(Comp, {
39
- ...rest,
40
- asChild: true,
57
+ const t1 = rest;
58
+ let t2;
59
+ if ($[5] !== render || $[6] !== renderChildren) {
60
+ t2 = cloneElement(render, void 0, renderChildren);
61
+ $[5] = render;
62
+ $[6] = renderChildren;
63
+ $[7] = t2;
64
+ } else t2 = $[7];
65
+ let t3;
66
+ if ($[8] !== ref || $[9] !== t1 || $[10] !== t2) {
67
+ t3 = /* @__PURE__ */ jsx(Comp, {
68
+ ...t1,
69
+ asChild: true,
70
+ ref,
71
+ children: t2
72
+ });
73
+ $[8] = ref;
74
+ $[9] = t1;
75
+ $[10] = t2;
76
+ $[11] = t3;
77
+ } else t3 = $[11];
78
+ return t3;
79
+ }
80
+ const t1 = rest;
81
+ let t2;
82
+ if ($[12] !== asChild || $[13] !== children || $[14] !== ref || $[15] !== t1) {
83
+ t2 = /* @__PURE__ */ jsx(Comp, {
84
+ ...t1,
85
+ asChild,
41
86
  ref,
42
- children: cloneElement(render, void 0, renderChildren)
87
+ children
43
88
  });
44
- }
45
- return /* @__PURE__ */ jsx(Comp, {
46
- ...rest,
47
- asChild,
48
- ref,
49
- children
50
- });
89
+ $[12] = asChild;
90
+ $[13] = children;
91
+ $[14] = ref;
92
+ $[15] = t1;
93
+ $[16] = t2;
94
+ } else t2 = $[16];
95
+ return t2;
51
96
  });
52
97
  Wrapped.displayName = typeof Component === "string" ? Component : Component.displayName ?? Component.name ?? "Component";
53
98
  return Wrapped;