@assistant-ui/react 0.14.16 → 0.14.19

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 (380) hide show
  1. package/dist/client/ExternalThread.d.ts +5 -3
  2. package/dist/client/ExternalThread.d.ts.map +1 -1
  3. package/dist/client/ExternalThread.js +745 -255
  4. package/dist/client/ExternalThread.js.map +1 -1
  5. package/dist/client/InMemoryThreadList.d.ts +1 -1
  6. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  7. package/dist/client/InMemoryThreadList.js +299 -113
  8. package/dist/client/InMemoryThreadList.js.map +1 -1
  9. package/dist/client/SingleThreadList.d.ts +1 -6
  10. package/dist/client/SingleThreadList.d.ts.map +1 -1
  11. package/dist/client/SingleThreadList.js +143 -55
  12. package/dist/client/SingleThreadList.js.map +1 -1
  13. package/dist/context/ReadonlyStore.js.map +1 -1
  14. package/dist/context/providers/MessageProvider.js +38 -5
  15. package/dist/context/providers/MessageProvider.js.map +1 -1
  16. package/dist/context/providers/ThreadViewportProvider.js +76 -20
  17. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  18. package/dist/context/react/ThreadViewportContext.js.map +1 -1
  19. package/dist/context/react/utils/createContextHook.js.map +1 -1
  20. package/dist/context/react/utils/createContextStoreHook.js +17 -2
  21. package/dist/context/react/utils/createContextStoreHook.js.map +1 -1
  22. package/dist/context/react/utils/createStateHookForRuntime.js.map +1 -1
  23. package/dist/context/react/utils/ensureBinding.js.map +1 -1
  24. package/dist/context/react/utils/useRuntimeState.js +18 -2
  25. package/dist/context/react/utils/useRuntimeState.js.map +1 -1
  26. package/dist/context/stores/ThreadViewport.js.map +1 -1
  27. package/dist/devtools/DevToolsHooks.js.map +1 -1
  28. package/dist/hooks/useMessageQuote.js.map +1 -1
  29. package/dist/hooks/useMessageTiming.js +4 -1
  30. package/dist/hooks/useMessageTiming.js.map +1 -1
  31. package/dist/hooks/useToolCallElapsed.d.ts +23 -0
  32. package/dist/hooks/useToolCallElapsed.d.ts.map +1 -0
  33. package/dist/hooks/useToolCallElapsed.js +72 -0
  34. package/dist/hooks/useToolCallElapsed.js.map +1 -0
  35. package/dist/index.d.ts +6 -2
  36. package/dist/index.js +5 -1
  37. package/dist/internal.js.map +1 -1
  38. package/dist/legacy-runtime/AssistantRuntimeProvider.js +46 -10
  39. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  40. package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
  41. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js +27 -6
  42. package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.js.map +1 -1
  43. package/dist/legacy-runtime/hooks/AssistantContext.js +13 -2
  44. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  45. package/dist/legacy-runtime/hooks/AttachmentContext.js +9 -1
  46. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  47. package/dist/legacy-runtime/hooks/ComposerContext.js +9 -1
  48. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  49. package/dist/legacy-runtime/hooks/MessageContext.js +12 -2
  50. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  51. package/dist/legacy-runtime/hooks/MessagePartContext.js +9 -1
  52. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  53. package/dist/legacy-runtime/hooks/ThreadContext.js +33 -5
  54. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  55. package/dist/legacy-runtime/hooks/ThreadListItemContext.js +9 -1
  56. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  57. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js +3 -3
  58. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js.map +1 -1
  59. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js +71 -31
  60. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js.map +1 -1
  61. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js.map +1 -1
  62. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +24 -16
  63. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  64. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js +17 -12
  65. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js.map +1 -1
  66. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js +17 -3
  67. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js.map +1 -1
  68. package/dist/mcp-apps/McpAppRenderer.d.ts +2 -10
  69. package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  70. package/dist/mcp-apps/McpAppRenderer.js +9 -8
  71. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  72. package/dist/mcp-apps/McpAppsRemoteHost.d.ts +1 -8
  73. package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
  74. package/dist/mcp-apps/McpAppsRemoteHost.js +6 -5
  75. package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
  76. package/dist/mcp-apps/app-frame.js +33 -14
  77. package/dist/mcp-apps/app-frame.js.map +1 -1
  78. package/dist/mcp-apps/bridge.js.map +1 -1
  79. package/dist/mcp-apps/types.js.map +1 -1
  80. package/dist/mcp-apps/utils.js.map +1 -1
  81. package/dist/model-context/frame/useAssistantFrameHost.js +32 -14
  82. package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
  83. package/dist/model-context/makeAssistantVisible.js +64 -26
  84. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  85. package/dist/primitives/actionBar/ActionBarCopy.js +94 -20
  86. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  87. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  88. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +105 -37
  89. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  90. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +60 -11
  91. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  92. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +60 -11
  93. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  94. package/dist/primitives/actionBar/ActionBarInteractionContext.js +3 -1
  95. package/dist/primitives/actionBar/ActionBarInteractionContext.js.map +1 -1
  96. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  97. package/dist/primitives/actionBar/ActionBarRoot.js +84 -25
  98. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  99. package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
  100. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +45 -14
  101. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  102. package/dist/primitives/actionBar/useActionBarFloatStatus.js +22 -10
  103. package/dist/primitives/actionBar/useActionBarFloatStatus.js.map +1 -1
  104. package/dist/primitives/actionBar.js.map +1 -1
  105. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +44 -7
  106. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
  107. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +28 -6
  108. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
  109. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +103 -36
  110. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
  111. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +28 -6
  112. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
  113. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +28 -6
  114. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
  115. package/dist/primitives/actionBarMore/scope.js.map +1 -1
  116. package/dist/primitives/actionBarMore.js.map +1 -1
  117. package/dist/primitives/assistantModal/AssistantModalAnchor.js +27 -6
  118. package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
  119. package/dist/primitives/assistantModal/AssistantModalContent.js +71 -10
  120. package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
  121. package/dist/primitives/assistantModal/AssistantModalRoot.js +93 -26
  122. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  123. package/dist/primitives/assistantModal/AssistantModalTrigger.js +27 -6
  124. package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
  125. package/dist/primitives/assistantModal/scope.js.map +1 -1
  126. package/dist/primitives/assistantModal.js.map +1 -1
  127. package/dist/primitives/attachment/AttachmentName.js +13 -1
  128. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  129. package/dist/primitives/attachment/AttachmentRemove.js +11 -4
  130. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  131. package/dist/primitives/attachment/AttachmentRoot.js +13 -4
  132. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  133. package/dist/primitives/attachment/AttachmentThumb.js +20 -9
  134. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  135. package/dist/primitives/attachment.js.map +1 -1
  136. package/dist/primitives/branchPicker/BranchPickerCount.js +14 -2
  137. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  138. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  139. package/dist/primitives/branchPicker/BranchPickerNumber.js +14 -2
  140. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  141. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  142. package/dist/primitives/branchPicker/BranchPickerRoot.js +34 -6
  143. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  144. package/dist/primitives/branchPicker.js.map +1 -1
  145. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +16 -5
  146. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  147. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +13 -4
  148. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  149. package/dist/primitives/chainOfThought.js.map +1 -1
  150. package/dist/primitives/composer/ComposerAddAttachment.js +37 -24
  151. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  152. package/dist/primitives/composer/ComposerAttachmentDropzone.js +124 -49
  153. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  154. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  155. package/dist/primitives/composer/ComposerDictate.js.map +1 -1
  156. package/dist/primitives/composer/ComposerDictationTranscript.js +32 -7
  157. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  158. package/dist/primitives/composer/ComposerInput.js +29 -29
  159. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  160. package/dist/primitives/composer/ComposerInputPluginContext.js +71 -25
  161. package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
  162. package/dist/primitives/composer/ComposerQuote.js +92 -23
  163. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  164. package/dist/primitives/composer/ComposerRoot.js +45 -11
  165. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  166. package/dist/primitives/composer/ComposerSend.js +9 -2
  167. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  168. package/dist/primitives/composer/ComposerStopDictation.js +15 -5
  169. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  170. package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
  171. package/dist/primitives/composer/trigger/TriggerPopover.js +215 -75
  172. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  173. package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
  174. package/dist/primitives/composer/trigger/TriggerPopoverBack.js +35 -7
  175. package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
  176. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +134 -28
  177. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
  178. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
  179. package/dist/primitives/composer/trigger/TriggerPopoverItems.js +132 -28
  180. package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
  181. package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts +2 -10
  182. package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -1
  183. package/dist/primitives/composer/trigger/TriggerPopoverResource.js +126 -53
  184. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  185. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +181 -78
  186. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
  187. package/dist/primitives/composer/trigger/detectTrigger.js.map +1 -1
  188. package/dist/primitives/composer/trigger/index.js.map +1 -1
  189. package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts +2 -6
  190. package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts.map +1 -1
  191. package/dist/primitives/composer/trigger/triggerDetectionResource.js +30 -15
  192. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  193. package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts +2 -17
  194. package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts.map +1 -1
  195. package/dist/primitives/composer/trigger/triggerKeyboardResource.js +117 -59
  196. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  197. package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts +2 -10
  198. package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts.map +1 -1
  199. package/dist/primitives/composer/trigger/triggerNavigationResource.js +204 -71
  200. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  201. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts +2 -10
  202. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
  203. package/dist/primitives/composer/trigger/triggerSelectionResource.js +51 -14
  204. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  205. package/dist/primitives/composer.js.map +1 -1
  206. package/dist/primitives/dropdownMenuRenderPrimitives.js.map +1 -1
  207. package/dist/primitives/error/ErrorMessage.js +28 -6
  208. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  209. package/dist/primitives/error/ErrorRoot.js +14 -5
  210. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  211. package/dist/primitives/error.js.map +1 -1
  212. package/dist/primitives/message/MessageError.js +2 -1
  213. package/dist/primitives/message/MessageError.js.map +1 -1
  214. package/dist/primitives/message/MessageIf.js +50 -20
  215. package/dist/primitives/message/MessageIf.js.map +1 -1
  216. package/dist/primitives/message/MessageParts.js +41 -7
  217. package/dist/primitives/message/MessageParts.js.map +1 -1
  218. package/dist/primitives/message/MessagePartsGrouped.js +399 -94
  219. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  220. package/dist/primitives/message/MessageRoot.js +197 -65
  221. package/dist/primitives/message/MessageRoot.js.map +1 -1
  222. package/dist/primitives/message.js.map +1 -1
  223. package/dist/primitives/messagePart/MessagePartImage.js +15 -5
  224. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  225. package/dist/primitives/messagePart/MessagePartText.d.ts +5 -2
  226. package/dist/primitives/messagePart/MessagePartText.d.ts.map +1 -1
  227. package/dist/primitives/messagePart/MessagePartText.js +35 -7
  228. package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
  229. package/dist/primitives/messagePart/useMessagePartData.js +5 -4
  230. package/dist/primitives/messagePart/useMessagePartData.js.map +1 -1
  231. package/dist/primitives/messagePart/useMessagePartFile.js +5 -4
  232. package/dist/primitives/messagePart/useMessagePartFile.js.map +1 -1
  233. package/dist/primitives/messagePart/useMessagePartImage.js +5 -4
  234. package/dist/primitives/messagePart/useMessagePartImage.js.map +1 -1
  235. package/dist/primitives/messagePart/useMessagePartReasoning.js +5 -4
  236. package/dist/primitives/messagePart/useMessagePartReasoning.js.map +1 -1
  237. package/dist/primitives/messagePart/useMessagePartSource.js +5 -4
  238. package/dist/primitives/messagePart/useMessagePartSource.js.map +1 -1
  239. package/dist/primitives/messagePart/useMessagePartText.js +5 -4
  240. package/dist/primitives/messagePart/useMessagePartText.js.map +1 -1
  241. package/dist/primitives/messagePart.js.map +1 -1
  242. package/dist/primitives/queueItem/QueueItemRemove.js +11 -4
  243. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  244. package/dist/primitives/queueItem/QueueItemSteer.js +11 -4
  245. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  246. package/dist/primitives/queueItem/QueueItemText.js +20 -6
  247. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  248. package/dist/primitives/queueItem.js.map +1 -1
  249. package/dist/primitives/reasoning/useScrollLock.js +61 -34
  250. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  251. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +56 -16
  252. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  253. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +120 -59
  254. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  255. package/dist/primitives/selectionToolbar.js.map +1 -1
  256. package/dist/primitives/suggestion/SuggestionDescription.js +20 -6
  257. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  258. package/dist/primitives/suggestion/SuggestionTitle.js +20 -6
  259. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  260. package/dist/primitives/suggestion/SuggestionTrigger.js +39 -26
  261. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  262. package/dist/primitives/suggestion.js.map +1 -1
  263. package/dist/primitives/thread/ThreadEmpty.js +6 -2
  264. package/dist/primitives/thread/ThreadEmpty.js.map +1 -1
  265. package/dist/primitives/thread/ThreadIf.js +32 -10
  266. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  267. package/dist/primitives/thread/ThreadRoot.js +13 -4
  268. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  269. package/dist/primitives/thread/ThreadScrollToBottom.js +24 -6
  270. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  271. package/dist/primitives/thread/ThreadSuggestion.js +18 -6
  272. package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
  273. package/dist/primitives/thread/ThreadViewport.js +185 -47
  274. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  275. package/dist/primitives/thread/ThreadViewportFooter.js +22 -9
  276. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  277. package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.js.map +1 -1
  278. package/dist/primitives/thread/topAnchor/createReserveObservers.js.map +1 -1
  279. package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.js.map +1 -1
  280. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -1
  281. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -1
  282. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +19 -4
  283. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  284. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  285. package/dist/primitives/thread/useThreadViewportAutoScroll.js +21 -16
  286. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  287. package/dist/primitives/thread.js.map +1 -1
  288. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -1
  289. package/dist/primitives/threadList/ThreadListNew.js +53 -11
  290. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  291. package/dist/primitives/threadList/ThreadListRoot.js +13 -4
  292. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  293. package/dist/primitives/threadList.js.map +1 -1
  294. package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
  295. package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
  296. package/dist/primitives/threadListItem/ThreadListItemRoot.js +26 -7
  297. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  298. package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
  299. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  300. package/dist/primitives/threadListItem.js.map +1 -1
  301. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +44 -7
  302. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
  303. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +28 -6
  304. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
  305. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +25 -5
  306. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
  307. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +28 -6
  308. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
  309. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +28 -6
  310. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
  311. package/dist/primitives/threadListItemMore/scope.js.map +1 -1
  312. package/dist/primitives/threadListItemMore.js.map +1 -1
  313. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  314. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  315. package/dist/tests/setup.js.map +1 -1
  316. package/dist/unstable/useComposerInputHistory.d.ts +30 -0
  317. package/dist/unstable/useComposerInputHistory.d.ts.map +1 -0
  318. package/dist/unstable/useComposerInputHistory.js +117 -0
  319. package/dist/unstable/useComposerInputHistory.js.map +1 -0
  320. package/dist/unstable/useMentionAdapter.js.map +1 -1
  321. package/dist/unstable/useMessageStallDetection.d.ts +29 -0
  322. package/dist/unstable/useMessageStallDetection.d.ts.map +1 -0
  323. package/dist/unstable/useMessageStallDetection.js +69 -0
  324. package/dist/unstable/useMessageStallDetection.js.map +1 -0
  325. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  326. package/dist/utils/Primitive.js +57 -12
  327. package/dist/utils/Primitive.js.map +1 -1
  328. package/dist/utils/createActionButton.js +23 -7
  329. package/dist/utils/createActionButton.js.map +1 -1
  330. package/dist/utils/getSelectionMessageId.js.map +1 -1
  331. package/dist/utils/hooks/useManagedRef.js +16 -8
  332. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  333. package/dist/utils/hooks/useMediaQuery.js +25 -10
  334. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  335. package/dist/utils/hooks/useOnResizeContent.js +29 -19
  336. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  337. package/dist/utils/hooks/useOnScrollToBottom.js +20 -4
  338. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  339. package/dist/utils/hooks/useSizeHandle.js +23 -15
  340. package/dist/utils/hooks/useSizeHandle.js.map +1 -1
  341. package/dist/utils/json/is-json-equal.js.map +1 -1
  342. package/dist/utils/json/is-json.js.map +1 -1
  343. package/dist/utils/smooth/SmoothContext.js +41 -11
  344. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  345. package/dist/utils/smooth/useSmooth.d.ts +40 -2
  346. package/dist/utils/smooth/useSmooth.d.ts.map +1 -1
  347. package/dist/utils/smooth/useSmooth.js +52 -13
  348. package/dist/utils/smooth/useSmooth.js.map +1 -1
  349. package/dist/utils/useToolArgsFieldStatus.d.ts +2 -2
  350. package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -1
  351. package/dist/utils/useToolArgsFieldStatus.js +13 -5
  352. package/dist/utils/useToolArgsFieldStatus.js.map +1 -1
  353. package/package.json +6 -6
  354. package/src/client/ExternalThread.ts +146 -74
  355. package/src/client/InMemoryThreadList.ts +23 -21
  356. package/src/client/SingleThreadList.ts +29 -27
  357. package/src/hooks/useToolCallElapsed.ts +52 -0
  358. package/src/index.ts +19 -0
  359. package/src/mcp-apps/McpAppRenderer.tsx +5 -3
  360. package/src/mcp-apps/McpAppsRemoteHost.ts +5 -3
  361. package/src/primitives/composer/ComposerInput.test.tsx +1 -1
  362. package/src/primitives/composer/ComposerInput.tsx +3 -3
  363. package/src/primitives/composer/trigger/TriggerPopover.tsx +4 -5
  364. package/src/primitives/composer/trigger/TriggerPopoverResource.ts +5 -3
  365. package/src/primitives/composer/trigger/triggerDetectionResource.ts +21 -21
  366. package/src/primitives/composer/trigger/triggerKeyboardResource.test.ts +5 -4
  367. package/src/primitives/composer/trigger/triggerKeyboardResource.ts +99 -101
  368. package/src/primitives/composer/trigger/triggerNavigationResource.ts +92 -98
  369. package/src/primitives/composer/trigger/triggerSelectionResource.ts +76 -76
  370. package/src/primitives/messagePart/MessagePartText.tsx +3 -2
  371. package/src/primitives/reasoning/useScrollLock.ts +25 -2
  372. package/src/primitives/thread/useThreadViewportAutoScroll.ts +8 -0
  373. package/src/tests/external-thread-branches.test.tsx +160 -0
  374. package/src/tests/shouldContinue.test.ts +33 -0
  375. package/src/tests/toolCallTiming.test.tsx +221 -0
  376. package/src/unstable/useComposerInputHistory.test.tsx +201 -0
  377. package/src/unstable/useComposerInputHistory.ts +160 -0
  378. package/src/unstable/useMessageStallDetection.ts +91 -0
  379. package/src/utils/smooth/useSmooth.test.tsx +95 -0
  380. package/src/utils/smooth/useSmooth.ts +82 -10
@@ -25,16 +25,17 @@ async function postToHost(options, method, params) {
25
25
  * params }`, using the method names expected by the assistant-ui MCP Apps
26
26
  * guide.
27
27
  */
28
- const McpAppsRemoteHost = resource(function McpAppsRemoteHost(options) {
28
+ const useMcpAppsRemoteHost = (options) => {
29
29
  const optionsRef = useRef(options);
30
30
  optionsRef.current = options;
31
31
  return useMemo(() => ({
32
32
  loadResource: (params) => postToHost(optionsRef.current, "mcp-apps/read-resource", params),
33
- callTool: (params) => postToHost(optionsRef.current, "tools/call", params),
34
- readResource: (params) => postToHost(optionsRef.current, "resources/read", params),
35
- listResources: (params) => postToHost(optionsRef.current, "resources/list", params)
33
+ callTool: (params_0) => postToHost(optionsRef.current, "tools/call", params_0),
34
+ readResource: (params_1) => postToHost(optionsRef.current, "resources/read", params_1),
35
+ listResources: (params_2) => postToHost(optionsRef.current, "resources/list", params_2)
36
36
  }), []);
37
- });
37
+ };
38
+ const McpAppsRemoteHost = resource(useMcpAppsRemoteHost);
38
39
  //#endregion
39
40
  export { McpAppsRemoteHost };
40
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"McpAppsRemoteHost.js","names":[],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"sourcesContent":["import { useMemo, useRef } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type {\n McpAppResource,\n McpAppsHost,\n McpAppsRemoteHostOptions,\n} from \"./types\";\n\nasync function postToHost(\n options: McpAppsRemoteHostOptions,\n method: string,\n params: unknown,\n): Promise<unknown> {\n const doFetch = options.fetch ?? fetch;\n const extraHeaders =\n typeof options.headers === \"function\"\n ? await options.headers()\n : (options.headers ?? {});\n const res = await doFetch(options.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...extraHeaders },\n body: JSON.stringify({ method, params }),\n });\n if (!res.ok) {\n throw new Error(`MCP App host request failed: ${res.status}`);\n }\n return res.json();\n}\n\n/**\n * Creates the default HTTP host for MCP App widgets.\n *\n * The host POSTs widget requests to the configured route as `{ method,\n * params }`, using the method names expected by the assistant-ui MCP Apps\n * guide.\n */\nexport const McpAppsRemoteHost = resource(function McpAppsRemoteHost(\n options: McpAppsRemoteHostOptions,\n): McpAppsHost {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n return useMemo(\n (): McpAppsHost => ({\n loadResource: (params) =>\n postToHost(\n optionsRef.current,\n \"mcp-apps/read-resource\",\n params,\n ) as Promise<McpAppResource>,\n callTool: (params) =>\n postToHost(optionsRef.current, \"tools/call\", params),\n readResource: (params) =>\n postToHost(optionsRef.current, \"resources/read\", params),\n listResources: (params) =>\n postToHost(optionsRef.current, \"resources/list\", params),\n }),\n [],\n );\n});\n"],"mappings":";;;AAQA,eAAe,WACb,SACA,QACA,QACkB;CAClB,MAAM,UAAU,QAAQ,SAAS;CACjC,MAAM,eACJ,OAAO,QAAQ,YAAY,aACvB,MAAM,QAAQ,QAAQ,IACrB,QAAQ,WAAW,CAAC;CAC3B,MAAM,MAAM,MAAM,QAAQ,QAAQ,KAAK;EACrC,QAAQ;EACR,SAAS;GAAE,gBAAgB;GAAoB,GAAG;EAAa;EAC/D,MAAM,KAAK,UAAU;GAAE;GAAQ;EAAO,CAAC;CACzC,CAAC;CACD,IAAI,CAAC,IAAI,IACP,MAAM,IAAI,MAAM,gCAAgC,IAAI,QAAQ;CAE9D,OAAO,IAAI,KAAK;AAClB;;;;;;;;AASA,MAAa,oBAAoB,SAAS,SAAS,kBACjD,SACa;CACb,MAAM,aAAa,OAAO,OAAO;CACjC,WAAW,UAAU;CAErB,OAAO,eACe;EAClB,eAAe,WACb,WACE,WAAW,SACX,0BACA,MACF;EACF,WAAW,WACT,WAAW,WAAW,SAAS,cAAc,MAAM;EACrD,eAAe,WACb,WAAW,WAAW,SAAS,kBAAkB,MAAM;EACzD,gBAAgB,WACd,WAAW,WAAW,SAAS,kBAAkB,MAAM;CAC3D,IACA,CAAC,CACH;AACF,CAAC"}
1
+ {"version":3,"file":"McpAppsRemoteHost.js","names":["useMemo","useRef","resource","McpAppResource","McpAppsHost","McpAppsRemoteHostOptions","postToHost","options","method","params","Promise","doFetch","fetch","extraHeaders","headers","res","url","body","JSON","stringify","ok","Error","status","json","useMcpAppsRemoteHost","optionsRef","current","loadResource","callTool","readResource","listResources","McpAppsRemoteHost"],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"sourcesContent":["import { useMemo, useRef } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type {\n McpAppResource,\n McpAppsHost,\n McpAppsRemoteHostOptions,\n} from \"./types\";\n\nasync function postToHost(\n options: McpAppsRemoteHostOptions,\n method: string,\n params: unknown,\n): Promise<unknown> {\n const doFetch = options.fetch ?? fetch;\n const extraHeaders =\n typeof options.headers === \"function\"\n ? await options.headers()\n : (options.headers ?? {});\n const res = await doFetch(options.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...extraHeaders },\n body: JSON.stringify({ method, params }),\n });\n if (!res.ok) {\n throw new Error(`MCP App host request failed: ${res.status}`);\n }\n return res.json();\n}\n\n/**\n * Creates the default HTTP host for MCP App widgets.\n *\n * The host POSTs widget requests to the configured route as `{ method,\n * params }`, using the method names expected by the assistant-ui MCP Apps\n * guide.\n */\nconst useMcpAppsRemoteHost = (\n options: McpAppsRemoteHostOptions,\n): McpAppsHost => {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n return useMemo(\n (): McpAppsHost => ({\n loadResource: (params) =>\n postToHost(\n optionsRef.current,\n \"mcp-apps/read-resource\",\n params,\n ) as Promise<McpAppResource>,\n callTool: (params) =>\n postToHost(optionsRef.current, \"tools/call\", params),\n readResource: (params) =>\n postToHost(optionsRef.current, \"resources/read\", params),\n listResources: (params) =>\n postToHost(optionsRef.current, \"resources/list\", params),\n }),\n [],\n );\n};\n\nexport const McpAppsRemoteHost = resource(useMcpAppsRemoteHost);\n"],"mappings":";;;AAQA,eAAeM,WACbC,SACAC,QACAC,QACkB;CAClB,MAAME,UAAUJ,QAAQK,SAASA;CACjC,MAAMC,eACJ,OAAON,QAAQO,YAAY,aACvB,MAAMP,QAAQO,QAAQ,IACrBP,QAAQO,WAAW,CAAC;CAC3B,MAAMC,MAAM,MAAMJ,QAAQJ,QAAQS,KAAK;EACrCR,QAAQ;EACRM,SAAS;GAAE,gBAAgB;GAAoB,GAAGD;EAAa;EAC/DI,MAAMC,KAAKC,UAAU;GAAEX;GAAQC;EAAO,CAAC;CACzC,CAAC;CACD,IAAI,CAACM,IAAIK,IACP,MAAM,IAAIC,MAAM,gCAAgCN,IAAIO,QAAQ;CAE9D,OAAOP,IAAIQ,KAAK;AAClB;;;;;;;;AASA,MAAMC,wBACJjB,YACgB;CAChB,MAAMkB,aAAaxB,OAAOM,OAAO;CACjCkB,WAAWC,UAAUnB;CAErB,OAAOP,eACe;EAClB2B,eAAelB,WACbH,WACEmB,WAAWC,SACX,0BACAjB,MACF;EACFmB,WAAWnB,aACTH,WAAWmB,WAAWC,SAAS,cAAcjB,QAAM;EACrDoB,eAAepB,aACbH,WAAWmB,WAAWC,SAAS,kBAAkBjB,QAAM;EACzDqB,gBAAgBrB,aACdH,WAAWmB,WAAWC,SAAS,kBAAkBjB,QAAM;CAC3D,IACA,CAAA,CACF;AACF;AAEA,MAAasB,oBAAoB7B,SAASsB,oBAAoB"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { createMcpAppBridge } from "./bridge.js";
3
3
  import { SandboxHost } from "../sandbox-host/SandboxHost.js";
4
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
5
  import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  //#region src/mcp-apps/app-frame.tsx
@@ -8,17 +9,35 @@ const DEFAULT_PRODUCT = "assistant-ui-mcp-app";
8
9
  const INIT_TIMEOUT_MS = 5e3;
9
10
  const DEFAULT_MAX_HEIGHT = 800;
10
11
  function useBridgeNotify(value, bridgeRef, widgetReadyRef, pendingRef, lastSentRef, notify) {
11
- useEffect(() => {
12
- if (!bridgeRef.current) return;
13
- if (value === void 0) return;
14
- if (lastSentRef.current === value) return;
15
- if (!widgetReadyRef.current) {
16
- pendingRef.current = value;
17
- return;
18
- }
19
- notify(bridgeRef.current, value);
20
- lastSentRef.current = value;
21
- }, [value]);
12
+ const $ = c(9);
13
+ let t0;
14
+ if ($[0] !== bridgeRef || $[1] !== lastSentRef || $[2] !== notify || $[3] !== pendingRef || $[4] !== value || $[5] !== widgetReadyRef) {
15
+ t0 = () => {
16
+ if (!bridgeRef.current) return;
17
+ if (value === void 0) return;
18
+ if (lastSentRef.current === value) return;
19
+ if (!widgetReadyRef.current) {
20
+ pendingRef.current = value;
21
+ return;
22
+ }
23
+ notify(bridgeRef.current, value);
24
+ lastSentRef.current = value;
25
+ };
26
+ $[0] = bridgeRef;
27
+ $[1] = lastSentRef;
28
+ $[2] = notify;
29
+ $[3] = pendingRef;
30
+ $[4] = value;
31
+ $[5] = widgetReadyRef;
32
+ $[6] = t0;
33
+ } else t0 = $[6];
34
+ let t1;
35
+ if ($[7] !== value) {
36
+ t1 = [value];
37
+ $[7] = value;
38
+ $[8] = t1;
39
+ } else t1 = $[8];
40
+ useEffect(t0, t1);
22
41
  }
23
42
  function buildLiveHandlers(initial, liveRef) {
24
43
  const live = () => liveRef.current.handlers;
@@ -138,9 +157,9 @@ function McpAppFrame({ app, resource, input, output, sandbox, handlers, hostInfo
138
157
  }
139
158
  };
140
159
  };
141
- useBridgeNotify(input, bridgeRef, widgetReadyRef, pendingInputRef, lastSentInputRef, (b, v) => b.notifyToolInput(v));
142
- useBridgeNotify(output, bridgeRef, widgetReadyRef, pendingOutputRef, lastSentOutputRef, (b, v) => b.notifyToolResult(v));
143
- useBridgeNotify(hostContext, bridgeRef, widgetReadyRef, pendingHostContextRef, lastSentHostContextRef, (b, v) => b.notifyHostContextChanged(v));
160
+ useBridgeNotify(input, bridgeRef, widgetReadyRef, pendingInputRef, lastSentInputRef, (b_0, v) => b_0.notifyToolInput(v));
161
+ useBridgeNotify(output, bridgeRef, widgetReadyRef, pendingOutputRef, lastSentOutputRef, (b_1, v_0) => b_1.notifyToolResult(v_0));
162
+ useBridgeNotify(hostContext, bridgeRef, widgetReadyRef, pendingHostContextRef, lastSentHostContextRef, (b_2, v_1) => b_2.notifyHostContextChanged(v_1));
144
163
  return /* @__PURE__ */ jsx(SandboxHost, {
145
164
  content: { html: resource.html },
146
165
  contentKey: resource.uri,
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame.js","names":[],"sources":["../../src/mcp-apps/app-frame.tsx"],"sourcesContent":["\"use client\";\n\nimport { type MutableRefObject, useEffect, useRef } from \"react\";\nimport { type McpAppBridge, createMcpAppBridge } from \"./bridge\";\nimport {\n SandboxHost,\n type SandboxBridge,\n type SandboxHostApi,\n type SandboxHostFrame,\n} from \"../sandbox-host/SandboxHost\";\nimport type {\n McpAppBridgeHandlers,\n McpAppFrameProps,\n McpAppHostContext,\n} from \"./types\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-mcp-app\";\nconst INIT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_HEIGHT = 800;\n\nfunction useBridgeNotify<T>(\n value: T | undefined,\n bridgeRef: MutableRefObject<McpAppBridge | null>,\n widgetReadyRef: MutableRefObject<boolean>,\n pendingRef: MutableRefObject<T | undefined>,\n lastSentRef: MutableRefObject<T | undefined>,\n notify: (bridge: McpAppBridge, v: T) => void,\n) {\n useEffect(() => {\n if (!bridgeRef.current) return;\n if (value === undefined) return;\n if (lastSentRef.current === value) return;\n if (!widgetReadyRef.current) {\n pendingRef.current = value;\n return;\n }\n notify(bridgeRef.current, value);\n lastSentRef.current = value;\n // oxlint-disable-next-line react/exhaustive-deps -- refs are stable; notify is assumed stable; re-run only when value changes\n }, [value]);\n}\n\ntype LiveSnapshot = {\n handlers: McpAppBridgeHandlers | undefined;\n hostInfo: McpAppFrameProps[\"hostInfo\"];\n hostContext: McpAppFrameProps[\"hostContext\"];\n input: unknown;\n output: unknown;\n};\n\n// Proxy each per-call handler through liveRef so the bridge always dispatches\n// to the latest handler reference (e.g. inline callbacks closing over state).\n// Capability presence is snapshot at mount: a handler added later requires a\n// remount (keyed on resource URI) to expose the capability to the widget.\nfunction buildLiveHandlers(\n initial: McpAppBridgeHandlers | undefined,\n liveRef: { readonly current: LiveSnapshot },\n): McpAppBridgeHandlers {\n const live = () => liveRef.current.handlers;\n const has = <K extends keyof McpAppBridgeHandlers>(key: K) =>\n initial?.[key] !== undefined;\n const out: McpAppBridgeHandlers = {};\n if (has(\"allowedTools\")) {\n Object.defineProperty(out, \"allowedTools\", {\n get: () => live()?.allowedTools,\n enumerable: true,\n configurable: true,\n });\n }\n const liveCall = <K extends keyof McpAppBridgeHandlers>(\n key: K,\n ): NonNullable<McpAppBridgeHandlers[K]> =>\n ((p: unknown) => {\n const fn = live()?.[key] as ((p: unknown) => unknown) | undefined;\n if (!fn) {\n throw new Error(`${key} handler is no longer available`);\n }\n return fn(p);\n }) as NonNullable<McpAppBridgeHandlers[K]>;\n if (has(\"callTool\")) out.callTool = liveCall(\"callTool\");\n if (has(\"readResource\")) out.readResource = liveCall(\"readResource\");\n if (has(\"listResources\")) out.listResources = liveCall(\"listResources\");\n if (has(\"openLink\")) out.openLink = liveCall(\"openLink\");\n if (has(\"sendMessage\")) out.sendMessage = liveCall(\"sendMessage\");\n if (has(\"updateModelContext\"))\n out.updateModelContext = liveCall(\"updateModelContext\");\n if (has(\"requestDisplayMode\"))\n out.requestDisplayMode = liveCall(\"requestDisplayMode\");\n out.onSizeChange = (p) => live()?.onSizeChange?.(p);\n out.onInitialized = () => live()?.onInitialized?.();\n out.onRequestTeardown = (p) => live()?.onRequestTeardown?.(p);\n out.onLog = (p) => live()?.onLog?.(p);\n out.onError = (e) => live()?.onError?.(e);\n return out;\n}\n\nexport function McpAppFrame({\n app,\n resource,\n input,\n output,\n sandbox,\n handlers,\n hostInfo,\n hostContext,\n maxHeight = DEFAULT_MAX_HEIGHT,\n}: McpAppFrameProps) {\n const bridgeRef = useRef<McpAppBridge | null>(null);\n const lastSentInputRef = useRef<unknown>(undefined);\n const lastSentOutputRef = useRef<unknown>(undefined);\n const lastSentHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n // Per MCP Apps spec, the host should defer notifications until the widget\n // signals readiness via `notifications/initialized`. Until then, we record\n // pending values and flush them on init.\n const widgetReadyRef = useRef(false);\n const pendingInputRef = useRef<unknown>(undefined);\n const pendingOutputRef = useRef<unknown>(undefined);\n const pendingHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>(null!);\n liveRef.current = {\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n };\n\n const createBridge = (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ): SandboxBridge => {\n const current = liveRef.current;\n let initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const flushPending = () => {\n if (widgetReadyRef.current) return;\n widgetReadyRef.current = true;\n const b = bridgeRef.current;\n if (!b) return;\n if (pendingInputRef.current !== undefined) {\n b.notifyToolInput(pendingInputRef.current);\n lastSentInputRef.current = pendingInputRef.current;\n pendingInputRef.current = undefined;\n }\n if (pendingOutputRef.current !== undefined) {\n b.notifyToolResult(pendingOutputRef.current);\n lastSentOutputRef.current = pendingOutputRef.current;\n pendingOutputRef.current = undefined;\n }\n if (pendingHostContextRef.current !== undefined) {\n b.notifyHostContextChanged(pendingHostContextRef.current);\n lastSentHostContextRef.current = pendingHostContextRef.current;\n pendingHostContextRef.current = undefined;\n }\n };\n\n const liveHandlers = buildLiveHandlers(current.handlers, liveRef);\n const liveOnInitialized = liveHandlers.onInitialized;\n const wrappedHandlers: McpAppBridgeHandlers = {\n ...liveHandlers,\n onInitialized: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n flushPending();\n liveOnInitialized?.();\n },\n onSizeChange: (p) => {\n if (p.height != null) host.setHeight(p.height);\n liveHandlers.onSizeChange?.(p);\n },\n };\n\n // Safety net: if the widget never sends notifications/initialized (broken\n // or non-spec-compliant), flush the queue anyway so the host doesn't\n // appear hung.\n initTimeoutId = setTimeout(() => {\n initTimeoutId = null;\n flushPending();\n }, INIT_TIMEOUT_MS);\n\n const bridge = createMcpAppBridge({\n frame,\n handlers: wrappedHandlers,\n hostInfo: current.hostInfo,\n hostContext: current.hostContext,\n });\n bridgeRef.current = bridge;\n\n if (current.input !== undefined) pendingInputRef.current = current.input;\n if (current.output !== undefined) pendingOutputRef.current = current.output;\n // hostContext is delivered inside the ui/initialize response; subsequent\n // changes flow through useBridgeNotify's pending path.\n\n return {\n onMessage: bridge.onMessage,\n dispose: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n bridge.dispose();\n bridgeRef.current = null;\n lastSentInputRef.current = undefined;\n lastSentOutputRef.current = undefined;\n lastSentHostContextRef.current = undefined;\n widgetReadyRef.current = false;\n pendingInputRef.current = undefined;\n pendingOutputRef.current = undefined;\n pendingHostContextRef.current = undefined;\n },\n };\n };\n\n useBridgeNotify(\n input,\n bridgeRef,\n widgetReadyRef,\n pendingInputRef,\n lastSentInputRef,\n (b, v) => b.notifyToolInput(v),\n );\n useBridgeNotify(\n output,\n bridgeRef,\n widgetReadyRef,\n pendingOutputRef,\n lastSentOutputRef,\n (b, v) => b.notifyToolResult(v),\n );\n useBridgeNotify(\n hostContext,\n bridgeRef,\n widgetReadyRef,\n pendingHostContextRef,\n lastSentHostContextRef,\n (b, v) => b.notifyHostContextChanged(v),\n );\n\n return (\n <SandboxHost\n content={{ html: resource.html }}\n contentKey={resource.uri}\n sandbox={{ ...sandbox, product: sandbox?.product ?? DEFAULT_PRODUCT }}\n maxHeight={maxHeight}\n createBridge={createBridge}\n onError={(err) => liveRef.current.handlers?.onError?.(err)}\n containerProps={{\n \"data-mcp-app-resource\": app.resourceUri,\n \"data-mcp-app-prefers-border\": resource.meta?.prefersBorder\n ? \"\"\n : undefined,\n }}\n />\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-frame.js","names":["c","_c","MutableRefObject","useEffect","useRef","McpAppBridge","createMcpAppBridge","SandboxHost","SandboxBridge","SandboxHostApi","SandboxHostFrame","McpAppBridgeHandlers","McpAppFrameProps","McpAppHostContext","DEFAULT_PRODUCT","INIT_TIMEOUT_MS","DEFAULT_MAX_HEIGHT","useBridgeNotify","value","bridgeRef","widgetReadyRef","pendingRef","lastSentRef","notify","$","t0","current","undefined","t1","LiveSnapshot","handlers","hostInfo","hostContext","input","output","buildLiveHandlers","initial","liveRef","live","has","key","K","out","Object","defineProperty","get","allowedTools","enumerable","configurable","liveCall","NonNullable","p","fn","Error","callTool","readResource","listResources","openLink","sendMessage","updateModelContext","requestDisplayMode","onSizeChange","onInitialized","onRequestTeardown","onLog","onError","e","McpAppFrame","app","resource","sandbox","maxHeight","lastSentInputRef","lastSentOutputRef","lastSentHostContextRef","pendingInputRef","pendingOutputRef","pendingHostContextRef","createBridge","frame","host","initTimeoutId","ReturnType","setTimeout","flushPending","b","notifyToolInput","notifyToolResult","notifyHostContextChanged","liveHandlers","liveOnInitialized","wrappedHandlers","clearTimeout","height","setHeight","bridge","onMessage","dispose","v","html","uri","product","err","resourceUri","meta","prefersBorder"],"sources":["../../src/mcp-apps/app-frame.tsx"],"sourcesContent":["\"use client\";\n\nimport { type MutableRefObject, useEffect, useRef } from \"react\";\nimport { type McpAppBridge, createMcpAppBridge } from \"./bridge\";\nimport {\n SandboxHost,\n type SandboxBridge,\n type SandboxHostApi,\n type SandboxHostFrame,\n} from \"../sandbox-host/SandboxHost\";\nimport type {\n McpAppBridgeHandlers,\n McpAppFrameProps,\n McpAppHostContext,\n} from \"./types\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-mcp-app\";\nconst INIT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_HEIGHT = 800;\n\nfunction useBridgeNotify<T>(\n value: T | undefined,\n bridgeRef: MutableRefObject<McpAppBridge | null>,\n widgetReadyRef: MutableRefObject<boolean>,\n pendingRef: MutableRefObject<T | undefined>,\n lastSentRef: MutableRefObject<T | undefined>,\n notify: (bridge: McpAppBridge, v: T) => void,\n) {\n useEffect(() => {\n if (!bridgeRef.current) return;\n if (value === undefined) return;\n if (lastSentRef.current === value) return;\n if (!widgetReadyRef.current) {\n pendingRef.current = value;\n return;\n }\n notify(bridgeRef.current, value);\n lastSentRef.current = value;\n // oxlint-disable-next-line react/exhaustive-deps -- refs are stable; notify is assumed stable; re-run only when value changes\n }, [value]);\n}\n\ntype LiveSnapshot = {\n handlers: McpAppBridgeHandlers | undefined;\n hostInfo: McpAppFrameProps[\"hostInfo\"];\n hostContext: McpAppFrameProps[\"hostContext\"];\n input: unknown;\n output: unknown;\n};\n\n// Proxy each per-call handler through liveRef so the bridge always dispatches\n// to the latest handler reference (e.g. inline callbacks closing over state).\n// Capability presence is snapshot at mount: a handler added later requires a\n// remount (keyed on resource URI) to expose the capability to the widget.\nfunction buildLiveHandlers(\n initial: McpAppBridgeHandlers | undefined,\n liveRef: { readonly current: LiveSnapshot },\n): McpAppBridgeHandlers {\n const live = () => liveRef.current.handlers;\n const has = <K extends keyof McpAppBridgeHandlers>(key: K) =>\n initial?.[key] !== undefined;\n const out: McpAppBridgeHandlers = {};\n if (has(\"allowedTools\")) {\n Object.defineProperty(out, \"allowedTools\", {\n get: () => live()?.allowedTools,\n enumerable: true,\n configurable: true,\n });\n }\n const liveCall = <K extends keyof McpAppBridgeHandlers>(\n key: K,\n ): NonNullable<McpAppBridgeHandlers[K]> =>\n ((p: unknown) => {\n const fn = live()?.[key] as ((p: unknown) => unknown) | undefined;\n if (!fn) {\n throw new Error(`${key} handler is no longer available`);\n }\n return fn(p);\n }) as NonNullable<McpAppBridgeHandlers[K]>;\n if (has(\"callTool\")) out.callTool = liveCall(\"callTool\");\n if (has(\"readResource\")) out.readResource = liveCall(\"readResource\");\n if (has(\"listResources\")) out.listResources = liveCall(\"listResources\");\n if (has(\"openLink\")) out.openLink = liveCall(\"openLink\");\n if (has(\"sendMessage\")) out.sendMessage = liveCall(\"sendMessage\");\n if (has(\"updateModelContext\"))\n out.updateModelContext = liveCall(\"updateModelContext\");\n if (has(\"requestDisplayMode\"))\n out.requestDisplayMode = liveCall(\"requestDisplayMode\");\n out.onSizeChange = (p) => live()?.onSizeChange?.(p);\n out.onInitialized = () => live()?.onInitialized?.();\n out.onRequestTeardown = (p) => live()?.onRequestTeardown?.(p);\n out.onLog = (p) => live()?.onLog?.(p);\n out.onError = (e) => live()?.onError?.(e);\n return out;\n}\n\nexport function McpAppFrame({\n app,\n resource,\n input,\n output,\n sandbox,\n handlers,\n hostInfo,\n hostContext,\n maxHeight = DEFAULT_MAX_HEIGHT,\n}: McpAppFrameProps) {\n const bridgeRef = useRef<McpAppBridge | null>(null);\n const lastSentInputRef = useRef<unknown>(undefined);\n const lastSentOutputRef = useRef<unknown>(undefined);\n const lastSentHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n // Per MCP Apps spec, the host should defer notifications until the widget\n // signals readiness via `notifications/initialized`. Until then, we record\n // pending values and flush them on init.\n const widgetReadyRef = useRef(false);\n const pendingInputRef = useRef<unknown>(undefined);\n const pendingOutputRef = useRef<unknown>(undefined);\n const pendingHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>(null!);\n liveRef.current = {\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n };\n\n const createBridge = (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ): SandboxBridge => {\n const current = liveRef.current;\n let initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const flushPending = () => {\n if (widgetReadyRef.current) return;\n widgetReadyRef.current = true;\n const b = bridgeRef.current;\n if (!b) return;\n if (pendingInputRef.current !== undefined) {\n b.notifyToolInput(pendingInputRef.current);\n lastSentInputRef.current = pendingInputRef.current;\n pendingInputRef.current = undefined;\n }\n if (pendingOutputRef.current !== undefined) {\n b.notifyToolResult(pendingOutputRef.current);\n lastSentOutputRef.current = pendingOutputRef.current;\n pendingOutputRef.current = undefined;\n }\n if (pendingHostContextRef.current !== undefined) {\n b.notifyHostContextChanged(pendingHostContextRef.current);\n lastSentHostContextRef.current = pendingHostContextRef.current;\n pendingHostContextRef.current = undefined;\n }\n };\n\n const liveHandlers = buildLiveHandlers(current.handlers, liveRef);\n const liveOnInitialized = liveHandlers.onInitialized;\n const wrappedHandlers: McpAppBridgeHandlers = {\n ...liveHandlers,\n onInitialized: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n flushPending();\n liveOnInitialized?.();\n },\n onSizeChange: (p) => {\n if (p.height != null) host.setHeight(p.height);\n liveHandlers.onSizeChange?.(p);\n },\n };\n\n // Safety net: if the widget never sends notifications/initialized (broken\n // or non-spec-compliant), flush the queue anyway so the host doesn't\n // appear hung.\n initTimeoutId = setTimeout(() => {\n initTimeoutId = null;\n flushPending();\n }, INIT_TIMEOUT_MS);\n\n const bridge = createMcpAppBridge({\n frame,\n handlers: wrappedHandlers,\n hostInfo: current.hostInfo,\n hostContext: current.hostContext,\n });\n bridgeRef.current = bridge;\n\n if (current.input !== undefined) pendingInputRef.current = current.input;\n if (current.output !== undefined) pendingOutputRef.current = current.output;\n // hostContext is delivered inside the ui/initialize response; subsequent\n // changes flow through useBridgeNotify's pending path.\n\n return {\n onMessage: bridge.onMessage,\n dispose: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n bridge.dispose();\n bridgeRef.current = null;\n lastSentInputRef.current = undefined;\n lastSentOutputRef.current = undefined;\n lastSentHostContextRef.current = undefined;\n widgetReadyRef.current = false;\n pendingInputRef.current = undefined;\n pendingOutputRef.current = undefined;\n pendingHostContextRef.current = undefined;\n },\n };\n };\n\n useBridgeNotify(\n input,\n bridgeRef,\n widgetReadyRef,\n pendingInputRef,\n lastSentInputRef,\n (b, v) => b.notifyToolInput(v),\n );\n useBridgeNotify(\n output,\n bridgeRef,\n widgetReadyRef,\n pendingOutputRef,\n lastSentOutputRef,\n (b, v) => b.notifyToolResult(v),\n );\n useBridgeNotify(\n hostContext,\n bridgeRef,\n widgetReadyRef,\n pendingHostContextRef,\n lastSentHostContextRef,\n (b, v) => b.notifyHostContextChanged(v),\n );\n\n return (\n <SandboxHost\n content={{ html: resource.html }}\n contentKey={resource.uri}\n sandbox={{ ...sandbox, product: sandbox?.product ?? DEFAULT_PRODUCT }}\n maxHeight={maxHeight}\n createBridge={createBridge}\n onError={(err) => liveRef.current.handlers?.onError?.(err)}\n containerProps={{\n \"data-mcp-app-resource\": app.resourceUri,\n \"data-mcp-app-prefers-border\": resource.meta?.prefersBorder\n ? \"\"\n : undefined,\n }}\n />\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"sourcesContent":["import type { SandboxHostFrame } from \"../sandbox-host/SandboxHost\";\nimport {\n MCP_APP_PROTOCOL_VERSION,\n type McpAppBridgeHandlers,\n type McpAppDisplayMode,\n type McpAppHostContext,\n type McpAppHostInfo,\n type McpAppJsonRpcMessage,\n type McpAppJsonRpcNotification,\n type McpAppJsonRpcRequest,\n type McpAppJsonRpcResponse,\n} from \"./types\";\nimport { isRecord } from \"../utils/json/is-json\";\n\nconst VALID_DISPLAY_MODES = [\n \"inline\",\n \"fullscreen\",\n \"pip\",\n] as const satisfies readonly McpAppDisplayMode[];\n\nexport type McpAppBridgeFrame = SandboxHostFrame;\n\nexport type CreateMcpAppBridgeOptions = {\n frame: McpAppBridgeFrame;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n};\n\nexport type McpAppBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n notifyToolInput: (input: unknown) => void;\n notifyToolResult: (result: unknown) => void;\n notifyHostContextChanged: (hostContext: McpAppHostContext) => void;\n};\n\nconst DEFAULT_HOST_INFO: McpAppHostInfo = {\n name: \"assistant-ui\",\n version: \"0.1\",\n};\n\n// Accept both the legacy method names and the MCP-UI 2026-01-26 names that\n// `ui/*` capable widgets (e.g. xmcp's host-bridge) emit. Normalize on input\n// so downstream switch statements only need to know the legacy names.\nconst METHOD_ALIASES: Record<string, string> = {\n \"ui/notifications/initialized\": \"notifications/initialized\",\n \"ui/notifications/size-changed\": \"notifications/size_changed\",\n \"ui/request-display-mode\": \"requestDisplayMode\",\n \"ui/open-link\": \"openLink\",\n \"ui/update-model-context\": \"updateModelContext\",\n \"ui/message\": \"sendMessage\",\n \"notifications/message\": \"notifications/log\",\n};\n\nconst normalizeMethod = (method: string): string =>\n METHOD_ALIASES[method] ?? method;\n\nconst JSONRPC_ERROR = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n} as const;\n\nfunction isJsonRpcMessage(value: unknown): value is McpAppJsonRpcMessage {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return v.jsonrpc === \"2.0\" && typeof v.method === \"string\";\n}\n\nfunction isRequest(msg: McpAppJsonRpcMessage): msg is McpAppJsonRpcRequest {\n return \"id\" in msg;\n}\n\nfunction isNotification(\n msg: McpAppJsonRpcMessage,\n): msg is McpAppJsonRpcNotification {\n return !(\"id\" in msg);\n}\n\nexport function createMcpAppBridge(\n opts: CreateMcpAppBridgeOptions,\n): McpAppBridge {\n const {\n frame,\n handlers = {},\n hostInfo = DEFAULT_HOST_INFO,\n hostContext = {},\n } = opts;\n\n const post = (msg: McpAppJsonRpcMessage) => {\n frame.sendMessage(msg);\n };\n\n const respond = (\n id: McpAppJsonRpcRequest[\"id\"],\n payload:\n | { result: unknown }\n | { error: { code: number; message: string; data?: unknown } },\n ) => {\n const res: McpAppJsonRpcResponse = {\n jsonrpc: \"2.0\",\n id,\n ...payload,\n };\n post(res);\n };\n\n const errorResponse = (\n id: McpAppJsonRpcRequest[\"id\"],\n code: number,\n message: string,\n data?: unknown,\n ) => {\n respond(id, {\n error: {\n code,\n message,\n ...(data !== undefined ? { data } : {}),\n },\n });\n };\n\n const handleRequest = async (req: McpAppJsonRpcRequest) => {\n try {\n const params = req.params;\n\n switch (normalizeMethod(req.method)) {\n case \"ui/initialize\": {\n const requestedProtocolVersion =\n isRecord(params) && typeof params.protocolVersion === \"string\"\n ? params.protocolVersion\n : MCP_APP_PROTOCOL_VERSION;\n respond(req.id, {\n result: {\n protocolVersion: requestedProtocolVersion,\n host: hostInfo,\n hostInfo,\n hostContext,\n capabilities: {\n tools: handlers.callTool ? {} : undefined,\n resources:\n handlers.readResource || handlers.listResources\n ? {}\n : undefined,\n ui: {\n sendMessage: !!handlers.sendMessage,\n openLink: !!handlers.openLink,\n requestDisplayMode: !!handlers.requestDisplayMode,\n updateModelContext: !!handlers.updateModelContext,\n },\n },\n hostCapabilities: {\n ...(handlers.openLink ? { openLinks: {} } : {}),\n ...(handlers.callTool ? { serverTools: {} } : {}),\n ...(handlers.readResource || handlers.listResources\n ? { serverResources: {} }\n : {}),\n ...(handlers.updateModelContext\n ? { updateModelContext: { text: {} } }\n : {}),\n ...(handlers.sendMessage ? { message: { text: {} } } : {}),\n ...(handlers.onLog ? { logging: {} } : {}),\n },\n },\n });\n return;\n }\n\n case \"tools/call\": {\n if (!handlers.callTool) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"tools/call is not supported by this host\",\n );\n return;\n }\n const callParams = (params ?? {}) as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof callParams.name !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call requires a string 'name'\",\n );\n return;\n }\n if (\n handlers.allowedTools &&\n !handlers.allowedTools.includes(callParams.name)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n `tool '${callParams.name}' is not allowed for this app`,\n );\n return;\n }\n let callArgs: Record<string, unknown> | undefined;\n if (callParams.arguments !== undefined) {\n if (\n callParams.arguments === null ||\n typeof callParams.arguments !== \"object\" ||\n Array.isArray(callParams.arguments)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call 'arguments' must be an object\",\n );\n return;\n }\n callArgs = callParams.arguments as Record<string, unknown>;\n }\n const result = await handlers.callTool({\n name: callParams.name,\n ...(callArgs !== undefined ? { arguments: callArgs } : {}),\n });\n respond(req.id, { result });\n return;\n }\n\n case \"resources/read\": {\n if (!handlers.readResource) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/read is not supported by this host\",\n );\n return;\n }\n const readParams = (params ?? {}) as { uri?: unknown };\n if (typeof readParams.uri !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"resources/read requires a string 'uri'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.readResource({ uri: readParams.uri }),\n });\n return;\n }\n\n case \"resources/list\": {\n if (!handlers.listResources) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/list is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.listResources(params)) ?? null,\n });\n return;\n }\n\n case \"openLink\": {\n if (!handlers.openLink) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"openLink is not supported by this host\",\n );\n return;\n }\n const linkParams = (params ?? {}) as { url?: unknown };\n if (typeof linkParams.url !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a string 'url'\",\n );\n return;\n }\n let linkProtocol: string;\n try {\n linkProtocol = new URL(linkParams.url).protocol;\n } catch {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a valid URL\",\n );\n return;\n }\n if (linkProtocol !== \"https:\" && linkProtocol !== \"http:\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink only accepts http(s) URLs\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.openLink({ url: linkParams.url }),\n });\n return;\n }\n\n case \"sendMessage\": {\n if (!handlers.sendMessage) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"sendMessage is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.sendMessage(params)) ?? null,\n });\n return;\n }\n\n case \"updateModelContext\": {\n if (!handlers.updateModelContext) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"updateModelContext is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.updateModelContext(params)) ?? null,\n });\n return;\n }\n\n case \"requestDisplayMode\": {\n if (!handlers.requestDisplayMode) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"requestDisplayMode is not supported by this host\",\n );\n return;\n }\n const modeParams = (params ?? {}) as { mode?: unknown };\n if (\n typeof modeParams.mode !== \"string\" ||\n !VALID_DISPLAY_MODES.includes(modeParams.mode as McpAppDisplayMode)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"requestDisplayMode requires a valid 'mode'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.requestDisplayMode({\n mode: modeParams.mode as McpAppDisplayMode,\n }),\n });\n return;\n }\n\n default: {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n `Unknown method: ${req.method}`,\n );\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n handlers.onError?.(error);\n errorResponse(req.id, JSONRPC_ERROR.internalError, error.message);\n }\n };\n\n const handleNotification = (note: McpAppJsonRpcNotification) => {\n switch (normalizeMethod(note.method)) {\n case \"notifications/initialized\": {\n handlers.onInitialized?.();\n return;\n }\n case \"notifications/size_changed\": {\n const p = (note.params ?? {}) as { width?: number; height?: number };\n handlers.onSizeChange?.({\n ...(typeof p.width === \"number\" ? { width: p.width } : {}),\n ...(typeof p.height === \"number\" ? { height: p.height } : {}),\n });\n return;\n }\n case \"notifications/log\": {\n handlers.onLog?.(note.params);\n return;\n }\n case \"notifications/request_teardown\": {\n handlers.onRequestTeardown?.(note.params);\n return;\n }\n case \"notifications/error\": {\n const p = (note.params ?? {}) as { message?: string };\n handlers.onError?.(\n new Error(typeof p.message === \"string\" ? p.message : \"Widget error\"),\n );\n return;\n }\n default:\n return;\n }\n };\n\n // The host applies the cross-origin guard before delegating; this only\n // validates the JSON-RPC envelope.\n const onMessage = (event: MessageEvent) => {\n if (!isJsonRpcMessage(event.data)) return;\n\n const msg = event.data;\n if (isRequest(msg)) {\n void handleRequest(msg);\n } else if (isNotification(msg)) {\n handleNotification(msg);\n }\n };\n\n return {\n onMessage,\n dispose: () => {},\n notifyToolInput: (input: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/input\",\n params: { input },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-input\",\n params: isRecord(input) ? { arguments: input } : {},\n });\n },\n notifyToolResult: (result: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/result\",\n params: { result },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-result\",\n params: isRecord(result)\n ? result\n : { content: [{ type: \"text\", text: String(result) }] },\n });\n },\n notifyHostContextChanged: (ctx: McpAppHostContext) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/host_context/changed\",\n params: ctx,\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/host-context-changed\",\n params: ctx,\n });\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bridge.js","names":["SandboxHostFrame","MCP_APP_PROTOCOL_VERSION","McpAppBridgeHandlers","McpAppDisplayMode","McpAppHostContext","McpAppHostInfo","McpAppJsonRpcMessage","McpAppJsonRpcNotification","McpAppJsonRpcRequest","McpAppJsonRpcResponse","isRecord","VALID_DISPLAY_MODES","const","McpAppBridgeFrame","CreateMcpAppBridgeOptions","frame","handlers","hostInfo","hostContext","McpAppBridge","onMessage","event","MessageEvent","dispose","notifyToolInput","input","notifyToolResult","result","notifyHostContextChanged","DEFAULT_HOST_INFO","name","version","METHOD_ALIASES","Record","normalizeMethod","method","JSONRPC_ERROR","parseError","invalidRequest","methodNotFound","invalidParams","internalError","isJsonRpcMessage","value","v","jsonrpc","isRequest","msg","isNotification","createMcpAppBridge","opts","post","sendMessage","respond","id","payload","error","code","message","data","res","errorResponse","undefined","handleRequest","req","params","requestedProtocolVersion","protocolVersion","host","capabilities","tools","callTool","resources","readResource","listResources","ui","openLink","requestDisplayMode","updateModelContext","hostCapabilities","openLinks","serverTools","serverResources","text","onLog","logging","callParams","arguments","allowedTools","includes","callArgs","Array","isArray","readParams","uri","linkParams","url","linkProtocol","URL","protocol","modeParams","mode","err","Error","String","onError","handleNotification","note","onInitialized","p","width","height","onSizeChange","onRequestTeardown","content","type","ctx"],"sources":["../../src/mcp-apps/bridge.ts"],"sourcesContent":["import type { SandboxHostFrame } from \"../sandbox-host/SandboxHost\";\nimport {\n MCP_APP_PROTOCOL_VERSION,\n type McpAppBridgeHandlers,\n type McpAppDisplayMode,\n type McpAppHostContext,\n type McpAppHostInfo,\n type McpAppJsonRpcMessage,\n type McpAppJsonRpcNotification,\n type McpAppJsonRpcRequest,\n type McpAppJsonRpcResponse,\n} from \"./types\";\nimport { isRecord } from \"../utils/json/is-json\";\n\nconst VALID_DISPLAY_MODES = [\n \"inline\",\n \"fullscreen\",\n \"pip\",\n] as const satisfies readonly McpAppDisplayMode[];\n\nexport type McpAppBridgeFrame = SandboxHostFrame;\n\nexport type CreateMcpAppBridgeOptions = {\n frame: McpAppBridgeFrame;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n};\n\nexport type McpAppBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n notifyToolInput: (input: unknown) => void;\n notifyToolResult: (result: unknown) => void;\n notifyHostContextChanged: (hostContext: McpAppHostContext) => void;\n};\n\nconst DEFAULT_HOST_INFO: McpAppHostInfo = {\n name: \"assistant-ui\",\n version: \"0.1\",\n};\n\n// Accept both the legacy method names and the MCP-UI 2026-01-26 names that\n// `ui/*` capable widgets (e.g. xmcp's host-bridge) emit. Normalize on input\n// so downstream switch statements only need to know the legacy names.\nconst METHOD_ALIASES: Record<string, string> = {\n \"ui/notifications/initialized\": \"notifications/initialized\",\n \"ui/notifications/size-changed\": \"notifications/size_changed\",\n \"ui/request-display-mode\": \"requestDisplayMode\",\n \"ui/open-link\": \"openLink\",\n \"ui/update-model-context\": \"updateModelContext\",\n \"ui/message\": \"sendMessage\",\n \"notifications/message\": \"notifications/log\",\n};\n\nconst normalizeMethod = (method: string): string =>\n METHOD_ALIASES[method] ?? method;\n\nconst JSONRPC_ERROR = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n} as const;\n\nfunction isJsonRpcMessage(value: unknown): value is McpAppJsonRpcMessage {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return v.jsonrpc === \"2.0\" && typeof v.method === \"string\";\n}\n\nfunction isRequest(msg: McpAppJsonRpcMessage): msg is McpAppJsonRpcRequest {\n return \"id\" in msg;\n}\n\nfunction isNotification(\n msg: McpAppJsonRpcMessage,\n): msg is McpAppJsonRpcNotification {\n return !(\"id\" in msg);\n}\n\nexport function createMcpAppBridge(\n opts: CreateMcpAppBridgeOptions,\n): McpAppBridge {\n const {\n frame,\n handlers = {},\n hostInfo = DEFAULT_HOST_INFO,\n hostContext = {},\n } = opts;\n\n const post = (msg: McpAppJsonRpcMessage) => {\n frame.sendMessage(msg);\n };\n\n const respond = (\n id: McpAppJsonRpcRequest[\"id\"],\n payload:\n | { result: unknown }\n | { error: { code: number; message: string; data?: unknown } },\n ) => {\n const res: McpAppJsonRpcResponse = {\n jsonrpc: \"2.0\",\n id,\n ...payload,\n };\n post(res);\n };\n\n const errorResponse = (\n id: McpAppJsonRpcRequest[\"id\"],\n code: number,\n message: string,\n data?: unknown,\n ) => {\n respond(id, {\n error: {\n code,\n message,\n ...(data !== undefined ? { data } : {}),\n },\n });\n };\n\n const handleRequest = async (req: McpAppJsonRpcRequest) => {\n try {\n const params = req.params;\n\n switch (normalizeMethod(req.method)) {\n case \"ui/initialize\": {\n const requestedProtocolVersion =\n isRecord(params) && typeof params.protocolVersion === \"string\"\n ? params.protocolVersion\n : MCP_APP_PROTOCOL_VERSION;\n respond(req.id, {\n result: {\n protocolVersion: requestedProtocolVersion,\n host: hostInfo,\n hostInfo,\n hostContext,\n capabilities: {\n tools: handlers.callTool ? {} : undefined,\n resources:\n handlers.readResource || handlers.listResources\n ? {}\n : undefined,\n ui: {\n sendMessage: !!handlers.sendMessage,\n openLink: !!handlers.openLink,\n requestDisplayMode: !!handlers.requestDisplayMode,\n updateModelContext: !!handlers.updateModelContext,\n },\n },\n hostCapabilities: {\n ...(handlers.openLink ? { openLinks: {} } : {}),\n ...(handlers.callTool ? { serverTools: {} } : {}),\n ...(handlers.readResource || handlers.listResources\n ? { serverResources: {} }\n : {}),\n ...(handlers.updateModelContext\n ? { updateModelContext: { text: {} } }\n : {}),\n ...(handlers.sendMessage ? { message: { text: {} } } : {}),\n ...(handlers.onLog ? { logging: {} } : {}),\n },\n },\n });\n return;\n }\n\n case \"tools/call\": {\n if (!handlers.callTool) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"tools/call is not supported by this host\",\n );\n return;\n }\n const callParams = (params ?? {}) as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof callParams.name !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call requires a string 'name'\",\n );\n return;\n }\n if (\n handlers.allowedTools &&\n !handlers.allowedTools.includes(callParams.name)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n `tool '${callParams.name}' is not allowed for this app`,\n );\n return;\n }\n let callArgs: Record<string, unknown> | undefined;\n if (callParams.arguments !== undefined) {\n if (\n callParams.arguments === null ||\n typeof callParams.arguments !== \"object\" ||\n Array.isArray(callParams.arguments)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call 'arguments' must be an object\",\n );\n return;\n }\n callArgs = callParams.arguments as Record<string, unknown>;\n }\n const result = await handlers.callTool({\n name: callParams.name,\n ...(callArgs !== undefined ? { arguments: callArgs } : {}),\n });\n respond(req.id, { result });\n return;\n }\n\n case \"resources/read\": {\n if (!handlers.readResource) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/read is not supported by this host\",\n );\n return;\n }\n const readParams = (params ?? {}) as { uri?: unknown };\n if (typeof readParams.uri !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"resources/read requires a string 'uri'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.readResource({ uri: readParams.uri }),\n });\n return;\n }\n\n case \"resources/list\": {\n if (!handlers.listResources) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/list is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.listResources(params)) ?? null,\n });\n return;\n }\n\n case \"openLink\": {\n if (!handlers.openLink) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"openLink is not supported by this host\",\n );\n return;\n }\n const linkParams = (params ?? {}) as { url?: unknown };\n if (typeof linkParams.url !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a string 'url'\",\n );\n return;\n }\n let linkProtocol: string;\n try {\n linkProtocol = new URL(linkParams.url).protocol;\n } catch {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a valid URL\",\n );\n return;\n }\n if (linkProtocol !== \"https:\" && linkProtocol !== \"http:\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink only accepts http(s) URLs\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.openLink({ url: linkParams.url }),\n });\n return;\n }\n\n case \"sendMessage\": {\n if (!handlers.sendMessage) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"sendMessage is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.sendMessage(params)) ?? null,\n });\n return;\n }\n\n case \"updateModelContext\": {\n if (!handlers.updateModelContext) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"updateModelContext is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.updateModelContext(params)) ?? null,\n });\n return;\n }\n\n case \"requestDisplayMode\": {\n if (!handlers.requestDisplayMode) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"requestDisplayMode is not supported by this host\",\n );\n return;\n }\n const modeParams = (params ?? {}) as { mode?: unknown };\n if (\n typeof modeParams.mode !== \"string\" ||\n !VALID_DISPLAY_MODES.includes(modeParams.mode as McpAppDisplayMode)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"requestDisplayMode requires a valid 'mode'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.requestDisplayMode({\n mode: modeParams.mode as McpAppDisplayMode,\n }),\n });\n return;\n }\n\n default: {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n `Unknown method: ${req.method}`,\n );\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n handlers.onError?.(error);\n errorResponse(req.id, JSONRPC_ERROR.internalError, error.message);\n }\n };\n\n const handleNotification = (note: McpAppJsonRpcNotification) => {\n switch (normalizeMethod(note.method)) {\n case \"notifications/initialized\": {\n handlers.onInitialized?.();\n return;\n }\n case \"notifications/size_changed\": {\n const p = (note.params ?? {}) as { width?: number; height?: number };\n handlers.onSizeChange?.({\n ...(typeof p.width === \"number\" ? { width: p.width } : {}),\n ...(typeof p.height === \"number\" ? { height: p.height } : {}),\n });\n return;\n }\n case \"notifications/log\": {\n handlers.onLog?.(note.params);\n return;\n }\n case \"notifications/request_teardown\": {\n handlers.onRequestTeardown?.(note.params);\n return;\n }\n case \"notifications/error\": {\n const p = (note.params ?? {}) as { message?: string };\n handlers.onError?.(\n new Error(typeof p.message === \"string\" ? p.message : \"Widget error\"),\n );\n return;\n }\n default:\n return;\n }\n };\n\n // The host applies the cross-origin guard before delegating; this only\n // validates the JSON-RPC envelope.\n const onMessage = (event: MessageEvent) => {\n if (!isJsonRpcMessage(event.data)) return;\n\n const msg = event.data;\n if (isRequest(msg)) {\n void handleRequest(msg);\n } else if (isNotification(msg)) {\n handleNotification(msg);\n }\n };\n\n return {\n onMessage,\n dispose: () => {},\n notifyToolInput: (input: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/input\",\n params: { input },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-input\",\n params: isRecord(input) ? { arguments: input } : {},\n });\n },\n notifyToolResult: (result: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/result\",\n params: { result },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-result\",\n params: isRecord(result)\n ? result\n : { content: [{ type: \"text\", text: String(result) }] },\n });\n },\n notifyHostContextChanged: (ctx: McpAppHostContext) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/host_context/changed\",\n params: ctx,\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/host-context-changed\",\n params: ctx,\n });\n },\n };\n}\n"],"mappings":";;;AAcA,MAAMW,sBAAsB;CAC1B;CACA;CACA;AAAK;AAoBP,MAAMkB,oBAAoC;CACxCC,MAAM;CACNC,SAAS;AACX;AAKA,MAAMC,iBAAyC;CAC7C,gCAAgC;CAChC,iCAAiC;CACjC,2BAA2B;CAC3B,gBAAgB;CAChB,2BAA2B;CAC3B,cAAc;CACd,yBAAyB;AAC3B;AAEA,MAAME,mBAAmBC,WACvBH,eAAeG,WAAWA;AAE5B,MAAMC,gBAAgB;CACpBC,YAAY;CACZC,gBAAgB;CAChBC,gBAAgB;CAChBC,eAAe;CACfC,eAAe;AACjB;AAEA,SAASC,iBAAiBC,OAA+C;CACvE,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU,OAAO;CAChD,MAAMC,IAAID;CACV,OAAOC,EAAEC,YAAY,SAAS,OAAOD,EAAET,WAAW;AACpD;AAEA,SAASW,UAAUC,KAAwD;CACzE,OAAO,QAAQA;AACjB;AAEA,SAASC,eACPD,KACkC;CAClC,OAAO,EAAE,QAAQA;AACnB;AAEA,SAAgBE,mBACdC,MACc;CACd,MAAM,EACJnC,OACAC,WAAW,CAAC,GACZC,WAAWY,mBACXX,cAAc,CAAC,MACbgC;CAEJ,MAAMC,QAAQJ,QAA8B;EAC1ChC,MAAMqC,YAAYL,GAAG;CACvB;CAEA,MAAMM,WACJC,IACAC,YAGG;EAMHJ,KAAKS;GAJHf,SAAS;GACTS;GACA,GAAGC;EAEAK,CAAG;CACV;CAEA,MAAMC,iBACJP,IACAG,MACAC,SACAC,SACG;EACHN,QAAQC,IAAI,EACVE,OAAO;GACLC;GACAC;GACA,GAAIC,SAASG,KAAAA,IAAY,EAAEH,KAAK,IAAI,CAAC;EACvC,EACF,CAAC;CACH;CAEA,MAAMI,gBAAgB,OAAOC,QAA8B;EACzD,IAAI;GACF,MAAMC,SAASD,IAAIC;GAEnB,QAAQ/B,gBAAgB8B,IAAI7B,MAAM,GAAlC;IACE,KAAK,iBAAiB;KACpB,MAAM+B,2BACJxD,SAASuD,MAAM,KAAK,OAAOA,OAAOE,oBAAoB,WAClDF,OAAOE,kBAAAA;KAEbd,QAAQW,IAAIV,IAAI,EACd3B,QAAQ;MACNwC,iBAAiBD;MACjBE,MAAMnD;MACNA;MACAC;MACAmD,cAAc;OACZC,OAAOtD,SAASuD,WAAW,CAAC,IAAIT,KAAAA;OAChCU,WACExD,SAASyD,gBAAgBzD,SAAS0D,gBAC9B,CAAC,IACDZ,KAAAA;OACNa,IAAI;QACFvB,aAAa,CAAC,CAACpC,SAASoC;QACxBwB,UAAU,CAAC,CAAC5D,SAAS4D;QACrBC,oBAAoB,CAAC,CAAC7D,SAAS6D;QAC/BC,oBAAoB,CAAC,CAAC9D,SAAS8D;OACjC;MACF;MACAC,kBAAkB;OAChB,GAAI/D,SAAS4D,WAAW,EAAEI,WAAW,CAAC,EAAE,IAAI,CAAC;OAC7C,GAAIhE,SAASuD,WAAW,EAAEU,aAAa,CAAC,EAAE,IAAI,CAAC;OAC/C,GAAIjE,SAASyD,gBAAgBzD,SAAS0D,gBAClC,EAAEQ,iBAAiB,CAAC,EAAE,IACtB,CAAC;OACL,GAAIlE,SAAS8D,qBACT,EAAEA,oBAAoB,EAAEK,MAAM,CAAC,EAAE,EAAE,IACnC,CAAC;OACL,GAAInE,SAASoC,cAAc,EAAEM,SAAS,EAAEyB,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC;OACxD,GAAInE,SAASoE,QAAQ,EAAEC,SAAS,CAAC,EAAE,IAAI,CAAC;MAC1C;KACF,EACF,CAAC;KACD;IACF;IAEA,KAAK,cAAc;KACjB,IAAI,CAACrE,SAASuD,UAAU;MACtBV,cACEG,IAAIV,IACJlB,cAAcG,gBACd,0CACF;MACA;KACF;KACA,MAAM+C,aAAcrB,UAAU,CAAC;KAI/B,IAAI,OAAOqB,WAAWxD,SAAS,UAAU;MACvC+B,cACEG,IAAIV,IACJlB,cAAcI,eACd,qCACF;MACA;KACF;KACA,IACExB,SAASwE,gBACT,CAACxE,SAASwE,aAAaC,SAASH,WAAWxD,IAAI,GAC/C;MACA+B,cACEG,IAAIV,IACJlB,cAAcI,eACd,SAAS8C,WAAWxD,KAAI,8BAC1B;MACA;KACF;KACA,IAAI4D;KACJ,IAAIJ,WAAWC,cAAczB,KAAAA,GAAW;MACtC,IACEwB,WAAWC,cAAc,QACzB,OAAOD,WAAWC,cAAc,YAChCI,MAAMC,QAAQN,WAAWC,SAAS,GAClC;OACA1B,cACEG,IAAIV,IACJlB,cAAcI,eACd,0CACF;OACA;MACF;MACAkD,WAAWJ,WAAWC;KACxB;KACA,MAAM5D,SAAS,MAAMX,SAASuD,SAAS;MACrCzC,MAAMwD,WAAWxD;MACjB,GAAI4D,aAAa5B,KAAAA,IAAY,EAAEyB,WAAWG,SAAS,IAAI,CAAC;KAC1D,CAAC;KACDrC,QAAQW,IAAIV,IAAI,EAAE3B,OAAO,CAAC;KAC1B;IACF;IAEA,KAAK,kBAAkB;KACrB,IAAI,CAACX,SAASyD,cAAc;MAC1BZ,cACEG,IAAIV,IACJlB,cAAcG,gBACd,8CACF;MACA;KACF;KACA,MAAMsD,aAAc5B,UAAU,CAAC;KAC/B,IAAI,OAAO4B,WAAWC,QAAQ,UAAU;MACtCjC,cACEG,IAAIV,IACJlB,cAAcI,eACd,wCACF;MACA;KACF;KACAa,QAAQW,IAAIV,IAAI,EACd3B,QAAQ,MAAMX,SAASyD,aAAa,EAAEqB,KAAKD,WAAWC,IAAI,CAAC,EAC7D,CAAC;KACD;IACF;IAEA,KAAK;KACH,IAAI,CAAC9E,SAAS0D,eAAe;MAC3Bb,cACEG,IAAIV,IACJlB,cAAcG,gBACd,8CACF;MACA;KACF;KACAc,QAAQW,IAAIV,IAAI,EACd3B,QAAS,MAAMX,SAAS0D,cAAcT,MAAM,KAAM,KACpD,CAAC;KACD;IAGF,KAAK,YAAY;KACf,IAAI,CAACjD,SAAS4D,UAAU;MACtBf,cACEG,IAAIV,IACJlB,cAAcG,gBACd,wCACF;MACA;KACF;KACA,MAAMwD,aAAc9B,UAAU,CAAC;KAC/B,IAAI,OAAO8B,WAAWC,QAAQ,UAAU;MACtCnC,cACEG,IAAIV,IACJlB,cAAcI,eACd,kCACF;MACA;KACF;KACA,IAAIyD;KACJ,IAAI;MACFA,eAAe,IAAIC,IAAIH,WAAWC,GAAG,CAAC,CAACG;KACzC,QAAQ;MACNtC,cACEG,IAAIV,IACJlB,cAAcI,eACd,+BACF;MACA;KACF;KACA,IAAIyD,iBAAiB,YAAYA,iBAAiB,SAAS;MACzDpC,cACEG,IAAIV,IACJlB,cAAcI,eACd,oCACF;MACA;KACF;KACAa,QAAQW,IAAIV,IAAI,EACd3B,QAAQ,MAAMX,SAAS4D,SAAS,EAAEoB,KAAKD,WAAWC,IAAI,CAAC,EACzD,CAAC;KACD;IACF;IAEA,KAAK;KACH,IAAI,CAAChF,SAASoC,aAAa;MACzBS,cACEG,IAAIV,IACJlB,cAAcG,gBACd,2CACF;MACA;KACF;KACAc,QAAQW,IAAIV,IAAI,EACd3B,QAAS,MAAMX,SAASoC,YAAYa,MAAM,KAAM,KAClD,CAAC;KACD;IAGF,KAAK;KACH,IAAI,CAACjD,SAAS8D,oBAAoB;MAChCjB,cACEG,IAAIV,IACJlB,cAAcG,gBACd,kDACF;MACA;KACF;KACAc,QAAQW,IAAIV,IAAI,EACd3B,QAAS,MAAMX,SAAS8D,mBAAmBb,MAAM,KAAM,KACzD,CAAC;KACD;IAGF,KAAK,sBAAsB;KACzB,IAAI,CAACjD,SAAS6D,oBAAoB;MAChChB,cACEG,IAAIV,IACJlB,cAAcG,gBACd,kDACF;MACA;KACF;KACA,MAAM6D,aAAcnC,UAAU,CAAC;KAC/B,IACE,OAAOmC,WAAWC,SAAS,YAC3B,CAAC1F,oBAAoB8E,SAASW,WAAWC,IAAyB,GAClE;MACAxC,cACEG,IAAIV,IACJlB,cAAcI,eACd,4CACF;MACA;KACF;KACAa,QAAQW,IAAIV,IAAI,EACd3B,QAAQ,MAAMX,SAAS6D,mBAAmB,EACxCwB,MAAMD,WAAWC,KACnB,CAAC,EACH,CAAC;KACD;IACF;IAEA,SACExC,cACEG,IAAIV,IACJlB,cAAcG,gBACd,mBAAmByB,IAAI7B,QACzB;GAEJ;EACF,SAASmE,KAAK;GACZ,MAAM9C,QAAQ8C,eAAeC,QAAQD,MAAM,IAAIC,MAAMC,OAAOF,GAAG,CAAC;GAChEtF,SAASyF,UAAUjD,KAAK;GACxBK,cAAcG,IAAIV,IAAIlB,cAAcK,eAAee,MAAME,OAAO;EAClE;CACF;CAEA,MAAMgD,sBAAsBC,SAAoC;EAC9D,QAAQzE,gBAAgByE,KAAKxE,MAAM,GAAnC;GACE,KAAK;IACHnB,SAAS4F,gBAAgB;IACzB;GAEF,KAAK,8BAA8B;IACjC,MAAMC,IAAKF,KAAK1C,UAAU,CAAC;IAC3BjD,SAASgG,eAAe;KACtB,GAAI,OAAOH,EAAEC,UAAU,WAAW,EAAEA,OAAOD,EAAEC,MAAM,IAAI,CAAC;KACxD,GAAI,OAAOD,EAAEE,WAAW,WAAW,EAAEA,QAAQF,EAAEE,OAAO,IAAI,CAAC;IAC7D,CAAC;IACD;GACF;GACA,KAAK;IACH/F,SAASoE,QAAQuB,KAAK1C,MAAM;IAC5B;GAEF,KAAK;IACHjD,SAASiG,oBAAoBN,KAAK1C,MAAM;IACxC;GAEF,KAAK,uBAAuB;IAC1B,MAAM4C,IAAKF,KAAK1C,UAAU,CAAC;IAC3BjD,SAASyF,UACP,IAAIF,MAAM,OAAOM,EAAEnD,YAAY,WAAWmD,EAAEnD,UAAU,cAAc,CACtE;IACA;GACF;GACA,SACE;EACJ;CACF;CAIA,MAAMtC,aAAaC,UAAwB;EACzC,IAAI,CAACqB,iBAAiBrB,MAAMsC,IAAI,GAAG;EAEnC,MAAMZ,MAAM1B,MAAMsC;EAClB,IAAIb,UAAUC,GAAG,GACf,cAAmBA,GAAG;OACjB,IAAIC,eAAeD,GAAG,GAC3B2D,mBAAmB3D,GAAG;CAE1B;CAEA,OAAO;EACL3B;EACAG,eAAe,CAAC;EAChBC,kBAAkBC,UAAmB;GACnC0B,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQ,EAAExC,MAAM;GAClB,CAAC;GACD0B,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQvD,SAASe,KAAK,IAAI,EAAE8D,WAAW9D,MAAM,IAAI,CAAC;GACpD,CAAC;EACH;EACAC,mBAAmBC,WAAoB;GACrCwB,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQ,EAAEtC,OAAO;GACnB,CAAC;GACDwB,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQvD,SAASiB,MAAM,IACnBA,SACA,EAAEuF,SAAS,CAAC;KAAEC,MAAM;KAAQhC,MAAMqB,OAAO7E,MAAM;IAAE,CAAC,EAAE;GAC1D,CAAC;EACH;EACAC,2BAA2BwF,QAA2B;GACpDjE,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQmD;GACV,CAAC;GACDjE,KAAK;IACHN,SAAS;IACTV,QAAQ;IACR8B,QAAQmD;GACV,CAAC;EACH;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/mcp-apps/types.ts"],"sourcesContent":["import type {\n McpAppMetadata,\n ToolCallMessagePartMcpMetadata,\n} from \"@assistant-ui/core\";\nimport type { SandboxHostConfig } from \"../sandbox-host/SandboxHost\";\n\nexport type { McpAppMetadata, ToolCallMessagePartMcpMetadata };\n\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\n\nexport const MCP_APP_PROTOCOL_VERSION = \"0.1\" as const;\n\nexport type McpAppResourceCSP = {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n [k: string]: unknown;\n};\n\nexport type McpAppResourceMeta = {\n prefersBorder?: boolean;\n csp?: McpAppResourceCSP;\n permissions?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\nexport type McpAppResource = {\n uri: string;\n mimeType: typeof MCP_APP_MIME_TYPE;\n html: string;\n meta?: McpAppResourceMeta;\n};\n\nexport type McpAppDisplayMode = \"inline\" | \"fullscreen\" | \"pip\";\n\nexport type McpAppHostContext = {\n theme?: \"light\" | \"dark\";\n displayMode?: McpAppDisplayMode;\n availableDisplayModes?: McpAppDisplayMode[];\n [k: string]: unknown;\n};\n\nexport type McpAppHostInfo = {\n name: string;\n version: string;\n};\n\n/**\n * What `McpAppRenderer` needs from its host — the data-plane operations\n * the widget can request. Provided by a host resource like\n * `McpAppsRemoteHost`.\n */\nexport type McpAppsHost = {\n loadResource: (params: { uri: string }) => Promise<McpAppResource>;\n callTool: (params: McpAppToolCallParams) => Promise<unknown>;\n readResource: (params: { uri: string }) => Promise<unknown>;\n listResources: (params?: unknown) => Promise<unknown>;\n};\n\n/**\n * Options for `McpAppsRemoteHost`. The host POSTs `{ method, params }` to\n * `url` and expects JSON responses. Method names sent:\n * - `mcp-apps/read-resource` (`{ uri }`) → `McpAppResource`\n * - `tools/call` (`{ name, arguments? }`) → tool result\n * - `resources/read` (`{ uri }`) → resource read result\n * - `resources/list` (`params?`) → list result\n */\nexport type McpAppsRemoteHostOptions = {\n url: string;\n fetch?: typeof fetch;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n};\n\nexport type McpAppToolCallParams = {\n name: string;\n arguments?: Record<string, unknown>;\n};\n\nexport type McpAppBridgeHandlers = {\n allowedTools?: readonly string[];\n callTool?: (params: McpAppToolCallParams) => Promise<unknown> | unknown;\n readResource?: (params: { uri: string }) => Promise<unknown> | unknown;\n listResources?: (params?: unknown) => Promise<unknown> | unknown;\n openLink?: (params: { url: string }) => Promise<unknown> | unknown;\n sendMessage?: (params: unknown) => Promise<unknown> | unknown;\n updateModelContext?: (params: unknown) => Promise<unknown> | unknown;\n requestDisplayMode?: (params: {\n mode: McpAppDisplayMode;\n }) => Promise<{ mode: McpAppDisplayMode }> | { mode: McpAppDisplayMode };\n onSizeChange?: (params: { width?: number; height?: number }) => void;\n onInitialized?: () => void;\n onRequestTeardown?: (params: unknown) => void;\n onLog?: (params: unknown) => void;\n onError?: (error: Error) => void;\n};\n\nexport type McpAppSandboxConfig = SandboxHostConfig;\n\nexport type McpAppFrameProps = {\n app: McpAppMetadata;\n resource: McpAppResource;\n input?: unknown;\n output?: unknown;\n sandbox?: McpAppSandboxConfig | undefined;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n /**\n * Upper bound (in pixels) for the auto-resize height driven by the widget's\n * `notifications/size_changed`. Defaults to 800.\n */\n maxHeight?: number | undefined;\n};\n\nexport type McpAppJsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcError = {\n code: number;\n message: string;\n data?: unknown;\n};\n\nexport type McpAppJsonRpcResponse =\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result: unknown;\n error?: never;\n }\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: never;\n error: McpAppJsonRpcError;\n };\n\nexport type McpAppJsonRpcMessage =\n | McpAppJsonRpcRequest\n | McpAppJsonRpcNotification\n | McpAppJsonRpcResponse;\n"],"mappings":";AAQA,MAAa,oBAAoB;AAEjC,MAAa,2BAA2B"}
1
+ {"version":3,"file":"types.js","names":["McpAppMetadata","ToolCallMessagePartMcpMetadata","SandboxHostConfig","MCP_APP_MIME_TYPE","const","MCP_APP_PROTOCOL_VERSION","McpAppResourceCSP","connectDomains","resourceDomains","frameDomains","k","McpAppResourceMeta","prefersBorder","csp","permissions","Record","McpAppResource","uri","mimeType","html","meta","McpAppDisplayMode","McpAppHostContext","theme","displayMode","availableDisplayModes","McpAppHostInfo","name","version","McpAppsHost","loadResource","params","Promise","callTool","McpAppToolCallParams","readResource","listResources","McpAppsRemoteHostOptions","url","fetch","headers","arguments","McpAppBridgeHandlers","allowedTools","openLink","sendMessage","updateModelContext","requestDisplayMode","mode","onSizeChange","width","height","onInitialized","onRequestTeardown","onLog","onError","error","Error","McpAppSandboxConfig","McpAppFrameProps","app","resource","input","output","sandbox","handlers","hostInfo","hostContext","maxHeight","McpAppJsonRpcRequest","jsonrpc","id","method","McpAppJsonRpcNotification","McpAppJsonRpcError","code","message","data","McpAppJsonRpcResponse","result","McpAppJsonRpcMessage"],"sources":["../../src/mcp-apps/types.ts"],"sourcesContent":["import type {\n McpAppMetadata,\n ToolCallMessagePartMcpMetadata,\n} from \"@assistant-ui/core\";\nimport type { SandboxHostConfig } from \"../sandbox-host/SandboxHost\";\n\nexport type { McpAppMetadata, ToolCallMessagePartMcpMetadata };\n\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\n\nexport const MCP_APP_PROTOCOL_VERSION = \"0.1\" as const;\n\nexport type McpAppResourceCSP = {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n [k: string]: unknown;\n};\n\nexport type McpAppResourceMeta = {\n prefersBorder?: boolean;\n csp?: McpAppResourceCSP;\n permissions?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\nexport type McpAppResource = {\n uri: string;\n mimeType: typeof MCP_APP_MIME_TYPE;\n html: string;\n meta?: McpAppResourceMeta;\n};\n\nexport type McpAppDisplayMode = \"inline\" | \"fullscreen\" | \"pip\";\n\nexport type McpAppHostContext = {\n theme?: \"light\" | \"dark\";\n displayMode?: McpAppDisplayMode;\n availableDisplayModes?: McpAppDisplayMode[];\n [k: string]: unknown;\n};\n\nexport type McpAppHostInfo = {\n name: string;\n version: string;\n};\n\n/**\n * What `McpAppRenderer` needs from its host — the data-plane operations\n * the widget can request. Provided by a host resource like\n * `McpAppsRemoteHost`.\n */\nexport type McpAppsHost = {\n loadResource: (params: { uri: string }) => Promise<McpAppResource>;\n callTool: (params: McpAppToolCallParams) => Promise<unknown>;\n readResource: (params: { uri: string }) => Promise<unknown>;\n listResources: (params?: unknown) => Promise<unknown>;\n};\n\n/**\n * Options for `McpAppsRemoteHost`. The host POSTs `{ method, params }` to\n * `url` and expects JSON responses. Method names sent:\n * - `mcp-apps/read-resource` (`{ uri }`) → `McpAppResource`\n * - `tools/call` (`{ name, arguments? }`) → tool result\n * - `resources/read` (`{ uri }`) → resource read result\n * - `resources/list` (`params?`) → list result\n */\nexport type McpAppsRemoteHostOptions = {\n url: string;\n fetch?: typeof fetch;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n};\n\nexport type McpAppToolCallParams = {\n name: string;\n arguments?: Record<string, unknown>;\n};\n\nexport type McpAppBridgeHandlers = {\n allowedTools?: readonly string[];\n callTool?: (params: McpAppToolCallParams) => Promise<unknown> | unknown;\n readResource?: (params: { uri: string }) => Promise<unknown> | unknown;\n listResources?: (params?: unknown) => Promise<unknown> | unknown;\n openLink?: (params: { url: string }) => Promise<unknown> | unknown;\n sendMessage?: (params: unknown) => Promise<unknown> | unknown;\n updateModelContext?: (params: unknown) => Promise<unknown> | unknown;\n requestDisplayMode?: (params: {\n mode: McpAppDisplayMode;\n }) => Promise<{ mode: McpAppDisplayMode }> | { mode: McpAppDisplayMode };\n onSizeChange?: (params: { width?: number; height?: number }) => void;\n onInitialized?: () => void;\n onRequestTeardown?: (params: unknown) => void;\n onLog?: (params: unknown) => void;\n onError?: (error: Error) => void;\n};\n\nexport type McpAppSandboxConfig = SandboxHostConfig;\n\nexport type McpAppFrameProps = {\n app: McpAppMetadata;\n resource: McpAppResource;\n input?: unknown;\n output?: unknown;\n sandbox?: McpAppSandboxConfig | undefined;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n /**\n * Upper bound (in pixels) for the auto-resize height driven by the widget's\n * `notifications/size_changed`. Defaults to 800.\n */\n maxHeight?: number | undefined;\n};\n\nexport type McpAppJsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcError = {\n code: number;\n message: string;\n data?: unknown;\n};\n\nexport type McpAppJsonRpcResponse =\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result: unknown;\n error?: never;\n }\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: never;\n error: McpAppJsonRpcError;\n };\n\nexport type McpAppJsonRpcMessage =\n | McpAppJsonRpcRequest\n | McpAppJsonRpcNotification\n | McpAppJsonRpcResponse;\n"],"mappings":";AAQA,MAAaG,oBAAoB;AAEjC,MAAaE,2BAA2B"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../src/mcp-apps/utils.ts"],"sourcesContent":["import {\n isMcpAppUri,\n type McpAppMetadata,\n type ToolCallMessagePart,\n} from \"@assistant-ui/core\";\n\ntype ToolPartLike = Pick<ToolCallMessagePart, \"mcp\">;\n\n/**\n * Returns MCP app metadata for a tool-call part that points at a `ui://`\n * resource.\n *\n * Returns `undefined` when the part has no MCP app metadata or the metadata\n * does not reference an assistant-ui MCP app resource.\n */\nexport function getMcpAppFromToolPart(\n part: ToolPartLike,\n): McpAppMetadata | undefined {\n const app = part.mcp?.app;\n if (!app) return undefined;\n if (!isMcpAppUri(app.resourceUri)) return undefined;\n return app;\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgB,sBACd,MAC4B;CAC5B,MAAM,MAAM,KAAK,KAAK;CACtB,IAAI,CAAC,KAAK,OAAO,KAAA;CACjB,IAAI,CAAC,YAAY,IAAI,WAAW,GAAG,OAAO,KAAA;CAC1C,OAAO;AACT"}
1
+ {"version":3,"file":"utils.js","names":["isMcpAppUri","McpAppMetadata","ToolCallMessagePart","ToolPartLike","Pick","getMcpAppFromToolPart","part","app","mcp","undefined","resourceUri"],"sources":["../../src/mcp-apps/utils.ts"],"sourcesContent":["import {\n isMcpAppUri,\n type McpAppMetadata,\n type ToolCallMessagePart,\n} from \"@assistant-ui/core\";\n\ntype ToolPartLike = Pick<ToolCallMessagePart, \"mcp\">;\n\n/**\n * Returns MCP app metadata for a tool-call part that points at a `ui://`\n * resource.\n *\n * Returns `undefined` when the part has no MCP app metadata or the metadata\n * does not reference an assistant-ui MCP app resource.\n */\nexport function getMcpAppFromToolPart(\n part: ToolPartLike,\n): McpAppMetadata | undefined {\n const app = part.mcp?.app;\n if (!app) return undefined;\n if (!isMcpAppUri(app.resourceUri)) return undefined;\n return app;\n}\n"],"mappings":";;;;;;;;;AAeA,SAAgBK,sBACdC,MAC4B;CAC5B,MAAMC,MAAMD,KAAKE,KAAKD;CACtB,IAAI,CAACA,KAAK,OAAOE,KAAAA;CACjB,IAAI,CAACT,YAAYO,IAAIG,WAAW,GAAG,OAAOD,KAAAA;CAC1C,OAAOF;AACT"}
@@ -1,4 +1,5 @@
1
1
  "use client";
2
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
2
3
  import { AssistantFrameHost } from "@assistant-ui/core";
3
4
  import { useEffect } from "@assistant-ui/tap/react-shim";
4
5
  //#region src/model-context/frame/useAssistantFrameHost.ts
@@ -19,21 +20,38 @@ import { useEffect } from "@assistant-ui/tap/react-shim";
19
20
  * }
20
21
  * ```
21
22
  */
22
- const useAssistantFrameHost = ({ iframeRef, targetOrigin = "*", register }) => {
23
- useEffect(() => {
24
- const iframeWindow = iframeRef.current?.contentWindow;
25
- if (!iframeWindow) return;
26
- const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);
27
- const unsubscribe = register(frameHost);
28
- return () => {
29
- frameHost.dispose();
30
- unsubscribe();
23
+ const useAssistantFrameHost = (t0) => {
24
+ const $ = c(5);
25
+ const { iframeRef, targetOrigin: t1, register } = t0;
26
+ const targetOrigin = t1 === void 0 ? "*" : t1;
27
+ let t2;
28
+ let t3;
29
+ if ($[0] !== iframeRef || $[1] !== register || $[2] !== targetOrigin) {
30
+ t2 = () => {
31
+ const iframeWindow = iframeRef.current?.contentWindow;
32
+ if (!iframeWindow) return;
33
+ const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);
34
+ const unsubscribe = register(frameHost);
35
+ return () => {
36
+ frameHost.dispose();
37
+ unsubscribe();
38
+ };
31
39
  };
32
- }, [
33
- iframeRef,
34
- targetOrigin,
35
- register
36
- ]);
40
+ t3 = [
41
+ iframeRef,
42
+ targetOrigin,
43
+ register
44
+ ];
45
+ $[0] = iframeRef;
46
+ $[1] = register;
47
+ $[2] = targetOrigin;
48
+ $[3] = t2;
49
+ $[4] = t3;
50
+ } else {
51
+ t2 = $[3];
52
+ t3 = $[4];
53
+ }
54
+ useEffect(t2, t3);
37
55
  };
38
56
  //#endregion
39
57
  export { useAssistantFrameHost };
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantFrameHost.js","names":[],"sources":["../../../src/model-context/frame/useAssistantFrameHost.ts"],"sourcesContent":["\"use client\";\n\nimport type { Unsubscribe } from \"@assistant-ui/core\";\nimport { useEffect, type RefObject } from \"react\";\nimport { AssistantFrameHost } from \"@assistant-ui/core\";\n\ntype UseAssistantFrameHostOptions = {\n iframeRef: Readonly<RefObject<HTMLIFrameElement | null | undefined>>;\n targetOrigin?: string;\n register: (frameHost: AssistantFrameHost) => Unsubscribe;\n};\n\n/**\n * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime.\n *\n * Usage example:\n * ```typescript\n * function MyComponent() {\n * const iframeRef = useRef<HTMLIFrameElement>(null);\n *\n * useAssistantFrameHost({\n * iframeRef,\n * targetOrigin: \"https://trusted-domain.com\", // optional\n * });\n *\n * return <iframe ref={iframeRef} src=\"...\" />;\n * }\n * ```\n */\nexport const useAssistantFrameHost = ({\n iframeRef,\n targetOrigin = \"*\",\n register,\n}: UseAssistantFrameHostOptions): void => {\n useEffect(() => {\n const iframeWindow = iframeRef.current?.contentWindow;\n if (!iframeWindow) return;\n\n const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);\n\n const unsubscribe = register(frameHost);\n\n return () => {\n frameHost.dispose();\n unsubscribe();\n };\n }, [iframeRef, targetOrigin, register]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,yBAAyB,EACpC,WACA,eAAe,KACf,eACwC;CACxC,gBAAgB;EACd,MAAM,eAAe,UAAU,SAAS;EACxC,IAAI,CAAC,cAAc;EAEnB,MAAM,YAAY,IAAI,mBAAmB,cAAc,YAAY;EAEnE,MAAM,cAAc,SAAS,SAAS;EAEtC,aAAa;GACX,UAAU,QAAQ;GAClB,YAAY;EACd;CACF,GAAG;EAAC;EAAW;EAAc;CAAQ,CAAC;AACxC"}
1
+ {"version":3,"file":"useAssistantFrameHost.js","names":["c","_c","Unsubscribe","useEffect","RefObject","AssistantFrameHost","UseAssistantFrameHostOptions","iframeRef","Readonly","HTMLIFrameElement","targetOrigin","register","frameHost","useAssistantFrameHost","t0","$","t1","undefined","t2","t3","iframeWindow","current","contentWindow","unsubscribe","dispose"],"sources":["../../../src/model-context/frame/useAssistantFrameHost.ts"],"sourcesContent":["\"use client\";\n\nimport type { Unsubscribe } from \"@assistant-ui/core\";\nimport { useEffect, type RefObject } from \"react\";\nimport { AssistantFrameHost } from \"@assistant-ui/core\";\n\ntype UseAssistantFrameHostOptions = {\n iframeRef: Readonly<RefObject<HTMLIFrameElement | null | undefined>>;\n targetOrigin?: string;\n register: (frameHost: AssistantFrameHost) => Unsubscribe;\n};\n\n/**\n * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime.\n *\n * Usage example:\n * ```typescript\n * function MyComponent() {\n * const iframeRef = useRef<HTMLIFrameElement>(null);\n *\n * useAssistantFrameHost({\n * iframeRef,\n * targetOrigin: \"https://trusted-domain.com\", // optional\n * });\n *\n * return <iframe ref={iframeRef} src=\"...\" />;\n * }\n * ```\n */\nexport const useAssistantFrameHost = ({\n iframeRef,\n targetOrigin = \"*\",\n register,\n}: UseAssistantFrameHostOptions): void => {\n useEffect(() => {\n const iframeWindow = iframeRef.current?.contentWindow;\n if (!iframeWindow) return;\n\n const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);\n\n const unsubscribe = register(frameHost);\n\n return () => {\n frameHost.dispose();\n unsubscribe();\n };\n }, [iframeRef, targetOrigin, register]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAaa,yBAAwBC,OAAA;CAAA,MAAAC,IAAAd,EAAA,CAAA;CAAC,MAAA,EAAAM,WAAAG,cAAAM,IAAAL,aAAAG;CAEpC,MAAAJ,eAAAM,OAAAC,KAAAA,IAAA,MAAAD;CAAkB,IAAAE;CAAA,IAAAC;CAAA,IAAAJ,EAAA,OAAAR,aAAAQ,EAAA,OAAAJ,YAAAI,EAAA,OAAAL,cAAA;EAGRQ,WAAA;GACR,MAAAE,eAAqBb,UAASc,SAAuBC;GACrD,IAAI,CAACF,cAAY;GAEjB,MAAAR,YAAkB,IAAIP,mBAAmBe,cAAcV,YAAY;GAEnE,MAAAa,cAAoBZ,SAASC,SAAS;GAAE,aAEjC;IACLA,UAASY,QAAS;IAClBD,YAAY;GAAC;EACd;EACAJ,KAAA;GAACZ;GAAWG;GAAcC;EAAQ;EAACI,EAAA,KAAAR;EAAAQ,EAAA,KAAAJ;EAAAI,EAAA,KAAAL;EAAAK,EAAA,KAAAG;EAAAH,EAAA,KAAAI;CAAA,OAAA;EAAAD,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;CAAA;CAZtCZ,UAAUe,IAYPC,EAAmC;AAAC"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { useAui } from "@assistant-ui/store";
3
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
3
4
  import { tool } from "@assistant-ui/core";
4
5
  import { createContext, forwardRef, useContext, useEffect, useId, useRef } from "@assistant-ui/tap/react-shim";
5
6
  import { jsx } from "react/jsx-runtime";
@@ -45,37 +46,74 @@ const edit = tool({
45
46
  const ReadableContext = createContext(false);
46
47
  const makeAssistantVisible = (Component, config) => {
47
48
  const ReadableComponent = forwardRef((props, outerRef) => {
49
+ const $ = c(13);
48
50
  const isNestedReadable = useContext(ReadableContext);
49
51
  const clickId = useId();
50
52
  const componentRef = useRef(null);
51
53
  const aui = useAui();
52
- const { clickable, editable } = config ?? {};
53
- useEffect(() => {
54
- return aui.modelContext().register({ getModelContext: () => {
55
- return {
56
- tools: {
57
- ...clickable ? { click } : {},
58
- ...editable ? { edit } : {}
59
- },
60
- system: !isNestedReadable ? componentRef.current?.outerHTML : void 0
61
- };
62
- } });
63
- }, [
64
- isNestedReadable,
65
- aui,
66
- clickable,
67
- editable
68
- ]);
54
+ let t0;
55
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
56
+ t0 = config ?? {};
57
+ $[0] = t0;
58
+ } else t0 = $[0];
59
+ const { clickable, editable } = t0;
60
+ let t1;
61
+ let t2;
62
+ if ($[1] !== aui || $[2] !== isNestedReadable) {
63
+ t1 = () => aui.modelContext().register({ getModelContext: () => ({
64
+ tools: {
65
+ ...clickable ? { click } : {},
66
+ ...editable ? { edit } : {}
67
+ },
68
+ system: !isNestedReadable ? componentRef.current?.outerHTML : void 0
69
+ }) });
70
+ t2 = [
71
+ isNestedReadable,
72
+ aui,
73
+ clickable,
74
+ editable
75
+ ];
76
+ $[1] = aui;
77
+ $[2] = isNestedReadable;
78
+ $[3] = t1;
79
+ $[4] = t2;
80
+ } else {
81
+ t1 = $[3];
82
+ t2 = $[4];
83
+ }
84
+ useEffect(t1, t2);
69
85
  const ref = useComposedRefs(componentRef, outerRef);
70
- return /* @__PURE__ */ jsx(ReadableContext.Provider, {
71
- value: true,
72
- children: /* @__PURE__ */ jsx(Component, {
73
- ...props,
74
- ...config?.clickable ? { "data-click-id": clickId } : {},
75
- ...config?.editable ? { "data-edit-id": clickId } : {},
76
- ref
77
- })
78
- });
86
+ const t3 = props;
87
+ let t4;
88
+ let t5;
89
+ if ($[5] !== clickId) {
90
+ t4 = config?.clickable ? { "data-click-id": clickId } : {};
91
+ t5 = config?.editable ? { "data-edit-id": clickId } : {};
92
+ $[5] = clickId;
93
+ $[6] = t4;
94
+ $[7] = t5;
95
+ } else {
96
+ t4 = $[6];
97
+ t5 = $[7];
98
+ }
99
+ let t6;
100
+ if ($[8] !== ref || $[9] !== t3 || $[10] !== t4 || $[11] !== t5) {
101
+ t6 = /* @__PURE__ */ jsx(ReadableContext.Provider, {
102
+ value: true,
103
+ children: /* @__PURE__ */ jsx(Component, {
104
+ ...t3,
105
+ ...t4,
106
+ ...t5,
107
+ ref
108
+ })
109
+ });
110
+ $[8] = ref;
111
+ $[9] = t3;
112
+ $[10] = t4;
113
+ $[11] = t5;
114
+ $[12] = t6;
115
+ } else t6 = $[12];
116
+ return t6;
79
117
  });
80
118
  ReadableComponent.displayName = Component.displayName;
81
119
  return ReadableComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"makeAssistantVisible.js","names":[],"sources":["../../src/model-context/makeAssistantVisible.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useRef,\n forwardRef,\n type ComponentType,\n type ForwardedRef,\n type PropsWithoutRef,\n useId,\n createContext,\n useContext,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { tool } from \"@assistant-ui/core\";\n\nconst click = tool({\n parameters: {\n type: \"object\",\n properties: {\n clickId: {\n type: \"string\",\n },\n },\n required: [\"clickId\"],\n },\n execute: async ({ clickId }: { clickId: string }) => {\n const escapedClickId = CSS.escape(clickId);\n const el = document.querySelector(`[data-click-id='${escapedClickId}']`);\n if (el instanceof HTMLElement) {\n el.click();\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst edit = tool({\n parameters: {\n type: \"object\",\n properties: {\n editId: {\n type: \"string\",\n },\n value: {\n type: \"string\",\n },\n },\n required: [\"editId\", \"value\"],\n },\n execute: async ({ editId, value }: { editId: string; value: string }) => {\n const escapedEditId = CSS.escape(editId);\n const el = document.querySelector(`[data-edit-id='${escapedEditId}']`);\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {\n el.value = value;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst ReadableContext = createContext<boolean>(false);\n\nexport const makeAssistantVisible = <T extends ComponentType<any>>(\n Component: T,\n config?: { clickable?: boolean | undefined; editable?: boolean | undefined },\n) => {\n const ReadableComponent = forwardRef(\n (props: PropsWithoutRef<T>, outerRef: ForwardedRef<any>) => {\n const isNestedReadable = useContext(ReadableContext);\n\n const clickId = useId();\n const componentRef = useRef<HTMLElement>(null);\n\n const aui = useAui();\n\n const { clickable, editable } = config ?? {};\n useEffect(() => {\n return aui.modelContext().register({\n getModelContext: () => {\n return {\n tools: {\n ...(clickable ? { click } : {}),\n ...(editable ? { edit } : {}),\n },\n system: !isNestedReadable // only pass content if this readable isn't nested in another readable\n ? componentRef.current?.outerHTML\n : undefined,\n };\n },\n });\n }, [isNestedReadable, aui, clickable, editable]);\n\n const ref = useComposedRefs(componentRef, outerRef);\n\n return (\n <ReadableContext.Provider value={true}>\n <Component\n {...(props as any)}\n {...(config?.clickable ? { \"data-click-id\": clickId } : {})}\n {...(config?.editable ? { \"data-edit-id\": clickId } : {})}\n ref={ref}\n />\n </ReadableContext.Provider>\n );\n },\n );\n\n ReadableComponent.displayName = Component.displayName;\n\n return ReadableComponent as unknown as T;\n};\n\nexport default makeAssistantVisible;\n"],"mappings":";;;;;;;AAiBA,MAAM,QAAQ,KAAK;CACjB,YAAY;EACV,MAAM;EACN,YAAY,EACV,SAAS,EACP,MAAM,SACR,EACF;EACA,UAAU,CAAC,SAAS;CACtB;CACA,SAAS,OAAO,EAAE,cAAmC;EACnD,MAAM,iBAAiB,IAAI,OAAO,OAAO;EACzC,MAAM,KAAK,SAAS,cAAc,mBAAmB,eAAe,GAAG;EACvE,IAAI,cAAc,aAAa;GAC7B,GAAG,MAAM;GAGT,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,OAAO,KAAK;CAChB,YAAY;EACV,MAAM;EACN,YAAY;GACV,QAAQ,EACN,MAAM,SACR;GACA,OAAO,EACL,MAAM,SACR;EACF;EACA,UAAU,CAAC,UAAU,OAAO;CAC9B;CACA,SAAS,OAAO,EAAE,QAAQ,YAA+C;EACvE,MAAM,gBAAgB,IAAI,OAAO,MAAM;EACvC,MAAM,KAAK,SAAS,cAAc,kBAAkB,cAAc,GAAG;EACrE,IAAI,cAAc,oBAAoB,cAAc,qBAAqB;GACvE,GAAG,QAAQ;GACX,GAAG,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;GACtD,GAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;GAGvD,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,kBAAkB,cAAuB,KAAK;AAEpD,MAAa,wBACX,WACA,WACG;CACH,MAAM,oBAAoB,YACvB,OAA2B,aAAgC;EAC1D,MAAM,mBAAmB,WAAW,eAAe;EAEnD,MAAM,UAAU,MAAM;EACtB,MAAM,eAAe,OAAoB,IAAI;EAE7C,MAAM,MAAM,OAAO;EAEnB,MAAM,EAAE,WAAW,aAAa,UAAU,CAAC;EAC3C,gBAAgB;GACd,OAAO,IAAI,aAAa,CAAC,CAAC,SAAS,EACjC,uBAAuB;IACrB,OAAO;KACL,OAAO;MACL,GAAI,YAAY,EAAE,MAAM,IAAI,CAAC;MAC7B,GAAI,WAAW,EAAE,KAAK,IAAI,CAAC;KAC7B;KACA,QAAQ,CAAC,mBACL,aAAa,SAAS,YACtB,KAAA;IACN;GACF,EACF,CAAC;EACH,GAAG;GAAC;GAAkB;GAAK;GAAW;EAAQ,CAAC;EAE/C,MAAM,MAAM,gBAAgB,cAAc,QAAQ;EAElD,OACE,oBAAC,gBAAgB,UAAjB;GAA0B,OAAO;aAC/B,oBAAC,WAAD;IACE,GAAK;IACL,GAAK,QAAQ,YAAY,EAAE,iBAAiB,QAAQ,IAAI,CAAC;IACzD,GAAK,QAAQ,WAAW,EAAE,gBAAgB,QAAQ,IAAI,CAAC;IAClD;GACN,CAAA;EACuB,CAAA;CAE9B,CACF;CAEA,kBAAkB,cAAc,UAAU;CAE1C,OAAO;AACT"}
1
+ {"version":3,"file":"makeAssistantVisible.js","names":["c","_c","useEffect","useRef","forwardRef","ComponentType","ForwardedRef","PropsWithoutRef","useId","createContext","useContext","useAui","useComposedRefs","tool","click","parameters","type","properties","clickId","required","execute","escapedClickId","CSS","escape","el","document","querySelector","HTMLElement","Promise","resolve","setTimeout","edit","editId","value","escapedEditId","HTMLInputElement","HTMLTextAreaElement","dispatchEvent","Event","bubbles","ReadableContext","makeAssistantVisible","Component","T","config","clickable","editable","ReadableComponent","props","outerRef","$","isNestedReadable","componentRef","aui","t0","Symbol","for","t1","t2","modelContext","register","getModelContext","tools","system","current","outerHTML","undefined","ref","t3","t4","t5","t6","displayName"],"sources":["../../src/model-context/makeAssistantVisible.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useRef,\n forwardRef,\n type ComponentType,\n type ForwardedRef,\n type PropsWithoutRef,\n useId,\n createContext,\n useContext,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { tool } from \"@assistant-ui/core\";\n\nconst click = tool({\n parameters: {\n type: \"object\",\n properties: {\n clickId: {\n type: \"string\",\n },\n },\n required: [\"clickId\"],\n },\n execute: async ({ clickId }: { clickId: string }) => {\n const escapedClickId = CSS.escape(clickId);\n const el = document.querySelector(`[data-click-id='${escapedClickId}']`);\n if (el instanceof HTMLElement) {\n el.click();\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst edit = tool({\n parameters: {\n type: \"object\",\n properties: {\n editId: {\n type: \"string\",\n },\n value: {\n type: \"string\",\n },\n },\n required: [\"editId\", \"value\"],\n },\n execute: async ({ editId, value }: { editId: string; value: string }) => {\n const escapedEditId = CSS.escape(editId);\n const el = document.querySelector(`[data-edit-id='${escapedEditId}']`);\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {\n el.value = value;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst ReadableContext = createContext<boolean>(false);\n\nexport const makeAssistantVisible = <T extends ComponentType<any>>(\n Component: T,\n config?: { clickable?: boolean | undefined; editable?: boolean | undefined },\n) => {\n const ReadableComponent = forwardRef(\n (props: PropsWithoutRef<T>, outerRef: ForwardedRef<any>) => {\n const isNestedReadable = useContext(ReadableContext);\n\n const clickId = useId();\n const componentRef = useRef<HTMLElement>(null);\n\n const aui = useAui();\n\n const { clickable, editable } = config ?? {};\n useEffect(() => {\n return aui.modelContext().register({\n getModelContext: () => {\n return {\n tools: {\n ...(clickable ? { click } : {}),\n ...(editable ? { edit } : {}),\n },\n system: !isNestedReadable // only pass content if this readable isn't nested in another readable\n ? componentRef.current?.outerHTML\n : undefined,\n };\n },\n });\n }, [isNestedReadable, aui, clickable, editable]);\n\n const ref = useComposedRefs(componentRef, outerRef);\n\n return (\n <ReadableContext.Provider value={true}>\n <Component\n {...(props as any)}\n {...(config?.clickable ? { \"data-click-id\": clickId } : {})}\n {...(config?.editable ? { \"data-edit-id\": clickId } : {})}\n ref={ref}\n />\n </ReadableContext.Provider>\n );\n },\n );\n\n ReadableComponent.displayName = Component.displayName;\n\n return ReadableComponent as unknown as T;\n};\n\nexport default makeAssistantVisible;\n"],"mappings":";;;;;;;;AAiBA,MAAMc,QAAQD,KAAK;CACjBE,YAAY;EACVC,MAAM;EACNC,YAAY,EACVC,SAAS,EACPF,MAAM,SACR,EACF;EACAG,UAAU,CAAC,SAAS;CACtB;CACAC,SAAS,OAAO,EAAEF,cAAmC;EACnD,MAAMG,iBAAiBC,IAAIC,OAAOL,OAAO;EACzC,MAAMM,KAAKC,SAASC,cAAc,mBAAmBL,eAAc,GAAI;EACvE,IAAIG,cAAcG,aAAa;GAC7BH,GAAGV,MAAM;GAGT,MAAM,IAAIc,SAASC,YAAYC,WAAWD,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAME,OAAOlB,KAAK;CAChBE,YAAY;EACVC,MAAM;EACNC,YAAY;GACVe,QAAQ,EACNhB,MAAM,SACR;GACAiB,OAAO,EACLjB,MAAM,SACR;EACF;EACAG,UAAU,CAAC,UAAU,OAAO;CAC9B;CACAC,SAAS,OAAO,EAAEY,QAAQC,YAA+C;EACvE,MAAMC,gBAAgBZ,IAAIC,OAAOS,MAAM;EACvC,MAAMR,KAAKC,SAASC,cAAc,kBAAkBQ,cAAa,GAAI;EACrE,IAAIV,cAAcW,oBAAoBX,cAAcY,qBAAqB;GACvEZ,GAAGS,QAAQA;GACXT,GAAGa,cAAc,IAAIC,MAAM,SAAS,EAAEC,SAAS,KAAK,CAAC,CAAC;GACtDf,GAAGa,cAAc,IAAIC,MAAM,UAAU,EAAEC,SAAS,KAAK,CAAC,CAAC;GAGvD,MAAM,IAAIX,SAASC,YAAYC,WAAWD,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAMW,kBAAkB/B,cAAuB,KAAK;AAEpD,MAAagC,wBACXC,WACAE,WACG;CACH,MAAMG,oBAAoB3C,YACxB4C,OAAAC,aAAA;EAAA,MAAAC,IAAAjD,EAAA,EAAA;EACE,MAAAkD,mBAAyBzC,WAAW8B,eAAe;EAEnD,MAAAtB,UAAgBV,MAAM;EACtB,MAAA4C,eAAqBjD,OAAoB,IAAI;EAE7C,MAAAkD,MAAY1C,OAAO;EAAE,IAAA2C;EAAA,IAAAJ,EAAA,OAAAK,OAAAC,IAAA,2BAAA,GAAA;GAEWF,KAAAV,UAAA,CAAW;GAACM,EAAA,KAAAI;EAAA,OAAAA,KAAAJ,EAAA;EAA5C,MAAA,EAAAL,WAAAC,aAAgCQ;EAAa,IAAAG;EAAA,IAAAC;EAAA,IAAAR,EAAA,OAAAG,OAAAH,EAAA,OAAAC,kBAAA;GACnCM,WACDJ,IAAGM,aAAc,CAAC,CAAAC,SAAU,EAAAC,wBAExB;IAAAC,OACE;KAAA,GACDjB,YAAA,EAAA/B,MAAyB,IAAzB,CAAyB;KAAC,GAC1BgC,WAAA,EAAAf,KAAuB,IAAvB,CAAuB;IAC7B;IAACgC,QACO,CAACZ,mBACLC,aAAYY,SAAmBC,YAD3BC,KAAAA;GAGV,GAEJ,CAAC;GACAR,KAAA;IAACP;IAAkBE;IAAKR;IAAWC;GAAQ;GAACI,EAAA,KAAAG;GAAAH,EAAA,KAAAC;GAAAD,EAAA,KAAAO;GAAAP,EAAA,KAAAQ;EAAA,OAAA;GAAAD,KAAAP,EAAA;GAAAQ,KAAAR,EAAA;EAAA;EAd/ChD,UAAUuD,IAcPC,EAA4C;EAE/C,MAAAS,MAAYvD,gBAAgBwC,cAAcH,QAAQ;EAKvC,MAAAmB,KAAApB;EAAY,IAAAqB;EAAA,IAAAC;EAAA,IAAApB,EAAA,OAAAhC,SAAA;GACZmD,KAAAzB,QAAMC,YAAN,EAAA,iBAAuC3B,QAAa,IAApD,CAAoD;GACpDoD,KAAA1B,QAAME,WAAN,EAAA,gBAAqC5B,QAAa,IAAlD,CAAkD;GAACgC,EAAA,KAAAhC;GAAAgC,EAAA,KAAAmB;GAAAnB,EAAA,KAAAoB;EAAA,OAAA;GAAAD,KAAAnB,EAAA;GAAAoB,KAAApB,EAAA;EAAA;EAAA,IAAAqB;EAAA,IAAArB,EAAA,OAAAiB,OAAAjB,EAAA,OAAAkB,MAAAlB,EAAA,QAAAmB,MAAAnB,EAAA,QAAAoB,IAAA;GAJ5DC,KAAA,oBAAA,gBAAA,UAAA;IAAiC,OAAA;cAC/B,oBAAC,WAAD;KAAU,GACHH;KAAY,GACZC;KAAqD,GACrDC;KACAH;IAAG,CAAA;GAEZ,CAAA;GAA2BjB,EAAA,KAAAiB;GAAAjB,EAAA,KAAAkB;GAAAlB,EAAA,MAAAmB;GAAAnB,EAAA,MAAAoB;GAAApB,EAAA,MAAAqB;EAAA,OAAAA,KAAArB,EAAA;EAAA,OAP3BqB;CAO2B,CAGjC;CAEAxB,kBAAkByB,cAAc9B,UAAU8B;CAE1C,OAAOzB;AACT"}