@assistant-ui/react 0.14.24 → 0.14.27
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.
- package/README.md +1 -1
- package/dist/augmentations.d.ts.map +1 -1
- package/dist/client/ExternalThread.d.ts +6 -4
- package/dist/client/ExternalThread.d.ts.map +1 -1
- package/dist/client/ExternalThread.js +2 -1
- package/dist/client/ExternalThread.js.map +1 -1
- package/dist/client/InMemoryThreadList.d.ts +0 -1
- package/dist/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/client/InMemoryThreadList.js +4 -1
- package/dist/client/InMemoryThreadList.js.map +1 -1
- package/dist/client/SingleThreadList.d.ts +0 -1
- package/dist/client/SingleThreadList.d.ts.map +1 -1
- package/dist/context/ReadonlyStore.d.ts +0 -1
- package/dist/context/ReadonlyStore.d.ts.map +1 -1
- package/dist/context/providers/MessageProvider.d.ts +0 -1
- package/dist/context/providers/MessageProvider.d.ts.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.d.ts +0 -1
- package/dist/context/providers/ThreadViewportProvider.d.ts.map +1 -1
- package/dist/context/react/ThreadViewportContext.d.ts +15 -16
- package/dist/context/react/ThreadViewportContext.d.ts.map +1 -1
- package/dist/context/react/utils/createContextHook.d.ts +0 -1
- package/dist/context/react/utils/createContextHook.d.ts.map +1 -1
- package/dist/context/react/utils/createContextStoreHook.d.ts +2 -3
- package/dist/context/react/utils/createContextStoreHook.d.ts.map +1 -1
- package/dist/context/react/utils/createStateHookForRuntime.d.ts +0 -1
- package/dist/context/react/utils/createStateHookForRuntime.d.ts.map +1 -1
- package/dist/context/react/utils/ensureBinding.d.ts.map +1 -1
- package/dist/context/react/utils/useRuntimeState.d.ts +0 -1
- package/dist/context/react/utils/useRuntimeState.d.ts.map +1 -1
- package/dist/context/stores/ThreadViewport.d.ts +25 -15
- package/dist/context/stores/ThreadViewport.d.ts.map +1 -1
- package/dist/devtools/DevToolsHooks.d.ts +0 -1
- package/dist/devtools/DevToolsHooks.d.ts.map +1 -1
- package/dist/hooks/useMessageQuote.d.ts +0 -1
- package/dist/hooks/useMessageQuote.d.ts.map +1 -1
- package/dist/hooks/useMessageTiming.d.ts +0 -1
- package/dist/hooks/useMessageTiming.d.ts.map +1 -1
- package/dist/hooks/useToolCallElapsed.d.ts.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/internal.d.ts +0 -2
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts +0 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.d.ts +11 -2
- package/dist/legacy-runtime/cloud/auiV0.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js +31 -2
- package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
- package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.d.ts +1 -5
- package/dist/legacy-runtime/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +0 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.d.ts +0 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.d.ts +1 -4
- package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +0 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts +0 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.d.ts +0 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.d.ts +12 -7
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.js +29 -7
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts +0 -1
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.js +32 -1
- package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
- package/dist/mcp-apps/app-frame.d.ts +1 -12
- package/dist/mcp-apps/app-frame.d.ts.map +1 -1
- package/dist/mcp-apps/app-frame.js +1 -1
- package/dist/mcp-apps/app-frame.js.map +1 -1
- package/dist/mcp-apps/bridge.d.ts +0 -1
- package/dist/mcp-apps/bridge.d.ts.map +1 -1
- package/dist/mcp-apps/bridge.js +4 -3
- package/dist/mcp-apps/bridge.js.map +1 -1
- package/dist/mcp-apps/types.d.ts +10 -7
- package/dist/mcp-apps/types.d.ts.map +1 -1
- package/dist/mcp-apps/types.js.map +1 -1
- package/dist/mcp-apps/utils.d.ts +0 -1
- package/dist/mcp-apps/utils.d.ts.map +1 -1
- package/dist/model-context/frame/useAssistantFrameHost.d.ts +1 -6
- package/dist/model-context/frame/useAssistantFrameHost.d.ts.map +1 -1
- package/dist/model-context/makeAssistantVisible.d.ts +0 -1
- package/dist/model-context/makeAssistantVisible.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.d.ts +1 -4
- package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarEdit.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +1 -5
- package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarInteractionContext.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarReload.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarRoot.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarRoot.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarSpeak.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarSpeak.d.ts.map +1 -1
- package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts +0 -1
- package/dist/primitives/actionBar/ActionBarStopSpeaking.d.ts.map +1 -1
- package/dist/primitives/actionBar/useActionBarFloatStatus.d.ts +1 -6
- package/dist/primitives/actionBar/useActionBarFloatStatus.d.ts.map +1 -1
- package/dist/primitives/actionBar.d.ts +0 -2
- package/dist/primitives/actionBarMore/ActionBarMoreContent.d.ts +0 -1
- package/dist/primitives/actionBarMore/ActionBarMoreContent.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreItem.d.ts +0 -1
- package/dist/primitives/actionBarMore/ActionBarMoreItem.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreRoot.d.ts +0 -1
- package/dist/primitives/actionBarMore/ActionBarMoreRoot.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreSeparator.d.ts +0 -1
- package/dist/primitives/actionBarMore/ActionBarMoreSeparator.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreTrigger.d.ts +0 -1
- package/dist/primitives/actionBarMore/ActionBarMoreTrigger.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/scope.d.ts +0 -1
- package/dist/primitives/actionBarMore/scope.d.ts.map +1 -1
- package/dist/primitives/actionBarMore.d.ts +0 -2
- package/dist/primitives/assistantModal/AssistantModalAnchor.d.ts +6 -4
- package/dist/primitives/assistantModal/AssistantModalAnchor.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalAnchor.js +2 -2
- package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalContent.d.ts +4 -2
- package/dist/primitives/assistantModal/AssistantModalContent.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalContent.js +2 -1
- package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.d.ts +0 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalTrigger.d.ts +6 -4
- package/dist/primitives/assistantModal/AssistantModalTrigger.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalTrigger.js +2 -2
- package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
- package/dist/primitives/assistantModal/popoverRenderPrimitives.d.ts +14 -0
- package/dist/primitives/assistantModal/popoverRenderPrimitives.d.ts.map +1 -0
- package/dist/primitives/assistantModal/popoverRenderPrimitives.js +10 -0
- package/dist/primitives/assistantModal/popoverRenderPrimitives.js.map +1 -0
- package/dist/primitives/assistantModal/scope.d.ts +0 -1
- package/dist/primitives/assistantModal/scope.d.ts.map +1 -1
- package/dist/primitives/assistantModal.d.ts +0 -2
- package/dist/primitives/attachment/AttachmentName.d.ts +0 -1
- package/dist/primitives/attachment/AttachmentName.d.ts.map +1 -1
- package/dist/primitives/attachment/AttachmentRemove.d.ts +0 -1
- package/dist/primitives/attachment/AttachmentRemove.d.ts.map +1 -1
- package/dist/primitives/attachment/AttachmentRoot.d.ts +0 -1
- package/dist/primitives/attachment/AttachmentRoot.d.ts.map +1 -1
- package/dist/primitives/attachment/AttachmentThumb.d.ts +0 -1
- package/dist/primitives/attachment/AttachmentThumb.d.ts.map +1 -1
- package/dist/primitives/attachment.d.ts +0 -2
- package/dist/primitives/branchPicker/BranchPickerCount.d.ts +0 -1
- package/dist/primitives/branchPicker/BranchPickerCount.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNext.d.ts +0 -1
- package/dist/primitives/branchPicker/BranchPickerNext.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerNumber.d.ts +0 -1
- package/dist/primitives/branchPicker/BranchPickerNumber.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +0 -1
- package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerRoot.d.ts +0 -1
- package/dist/primitives/branchPicker/BranchPickerRoot.d.ts.map +1 -1
- package/dist/primitives/branchPicker.d.ts +0 -2
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts +0 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.d.ts.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts +0 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.d.ts.map +1 -1
- package/dist/primitives/chainOfThought.d.ts +0 -2
- package/dist/primitives/composer/ComposerAddAttachment.d.ts +5 -6
- package/dist/primitives/composer/ComposerAddAttachment.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts +0 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCancel.d.ts +0 -1
- package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCompactContext.d.ts +9 -0
- package/dist/primitives/composer/ComposerCompactContext.d.ts.map +1 -0
- package/dist/primitives/composer/ComposerCompactContext.js +11 -0
- package/dist/primitives/composer/ComposerCompactContext.js.map +1 -0
- package/dist/primitives/composer/ComposerDictate.d.ts +0 -1
- package/dist/primitives/composer/ComposerDictate.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerDictationTranscript.d.ts +0 -1
- package/dist/primitives/composer/ComposerDictationTranscript.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts +0 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +17 -2
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts +4 -3
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerQuote.d.ts +0 -1
- package/dist/primitives/composer/ComposerQuote.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerRoot.d.ts +22 -3
- package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerRoot.js +63 -30
- package/dist/primitives/composer/ComposerRoot.js.map +1 -1
- package/dist/primitives/composer/ComposerSend.d.ts +0 -1
- package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerStopDictation.d.ts +0 -1
- package/dist/primitives/composer/ComposerStopDictation.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts +10 -5
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.d.ts +5 -3
- package/dist/primitives/composer/trigger/TriggerPopoverAction.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js +3 -2
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverBack.d.ts +0 -1
- package/dist/primitives/composer/trigger/TriggerPopoverBack.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts +0 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.d.ts +3 -2
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts +0 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts +10 -6
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts +8 -5
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/index.d.ts +0 -1
- package/dist/primitives/composer/trigger/index.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts +5 -2
- package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts +7 -4
- package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts +13 -7
- package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts +7 -4
- package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/useComposerInputState.d.ts.map +1 -1
- package/dist/primitives/composer.d.ts +0 -2
- package/dist/primitives/dropdownMenuRenderPrimitives.d.ts +0 -1
- package/dist/primitives/dropdownMenuRenderPrimitives.d.ts.map +1 -1
- package/dist/primitives/error/ErrorMessage.d.ts +0 -1
- package/dist/primitives/error/ErrorMessage.d.ts.map +1 -1
- package/dist/primitives/error/ErrorRoot.d.ts +0 -1
- package/dist/primitives/error/ErrorRoot.d.ts.map +1 -1
- package/dist/primitives/error.d.ts +0 -2
- package/dist/primitives/message/MessageError.d.ts +0 -1
- package/dist/primitives/message/MessageError.d.ts.map +1 -1
- package/dist/primitives/message/MessageIf.d.ts +0 -1
- package/dist/primitives/message/MessageIf.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts +0 -1
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts +25 -12
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
- package/dist/primitives/message/MessageRoot.d.ts +0 -1
- package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
- package/dist/primitives/message.d.ts +0 -2
- package/dist/primitives/messagePart/MessagePartImage.d.ts +0 -1
- package/dist/primitives/messagePart/MessagePartImage.d.ts.map +1 -1
- package/dist/primitives/messagePart/MessagePartText.d.ts +2 -1
- package/dist/primitives/messagePart/MessagePartText.d.ts.map +1 -1
- package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
- package/dist/primitives/messagePart/useMessagePartData.d.ts +0 -1
- package/dist/primitives/messagePart/useMessagePartData.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartFile.d.ts +0 -1
- package/dist/primitives/messagePart/useMessagePartFile.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartImage.d.ts +0 -1
- package/dist/primitives/messagePart/useMessagePartImage.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartReasoning.d.ts +0 -1
- package/dist/primitives/messagePart/useMessagePartReasoning.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartSource.d.ts.map +1 -1
- package/dist/primitives/messagePart/useMessagePartText.d.ts +0 -1
- package/dist/primitives/messagePart/useMessagePartText.d.ts.map +1 -1
- package/dist/primitives/messagePart.d.ts +0 -2
- package/dist/primitives/queueItem/QueueItemRemove.d.ts +0 -1
- package/dist/primitives/queueItem/QueueItemRemove.d.ts.map +1 -1
- package/dist/primitives/queueItem/QueueItemSteer.d.ts +0 -1
- package/dist/primitives/queueItem/QueueItemSteer.d.ts.map +1 -1
- package/dist/primitives/queueItem/QueueItemText.d.ts +0 -1
- package/dist/primitives/queueItem/QueueItemText.d.ts.map +1 -1
- package/dist/primitives/queueItem.d.ts +0 -2
- package/dist/primitives/reasoning/useScrollLock.d.ts +0 -1
- package/dist/primitives/reasoning/useScrollLock.d.ts.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts +0 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.d.ts.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts +0 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +2 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
- package/dist/primitives/selectionToolbar.d.ts +0 -2
- package/dist/primitives/suggestion/SuggestionDescription.d.ts +0 -1
- package/dist/primitives/suggestion/SuggestionDescription.d.ts.map +1 -1
- package/dist/primitives/suggestion/SuggestionTitle.d.ts +0 -1
- package/dist/primitives/suggestion/SuggestionTitle.d.ts.map +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts +1 -5
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts.map +1 -1
- package/dist/primitives/suggestion.d.ts +0 -2
- package/dist/primitives/thread/ThreadEmpty.d.ts +0 -1
- package/dist/primitives/thread/ThreadEmpty.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadIf.d.ts +0 -1
- package/dist/primitives/thread/ThreadIf.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadRoot.d.ts +0 -1
- package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadScrollToBottom.d.ts +1 -4
- package/dist/primitives/thread/ThreadScrollToBottom.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.d.ts +13 -14
- package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewport.d.ts +0 -1
- package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.d.ts +0 -1
- package/dist/primitives/thread/ThreadViewportFooter.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts +2 -11
- package/dist/primitives/thread/topAnchor/computeTopAnchorSlack.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/createReserveObservers.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/mountTopAnchorReserve.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts +1 -4
- package/dist/primitives/thread/topAnchor/topAnchorTurn.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/topAnchorUtils.d.ts.map +1 -1
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.d.ts.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts +1 -7
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
- package/dist/primitives/thread.d.ts +0 -2
- package/dist/primitives/threadList/ThreadListLoadMore.d.ts +0 -1
- package/dist/primitives/threadList/ThreadListLoadMore.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.d.ts +0 -1
- package/dist/primitives/threadList/ThreadListNew.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListRoot.d.ts +0 -1
- package/dist/primitives/threadList/ThreadListRoot.d.ts.map +1 -1
- package/dist/primitives/threadList/ThreadListRoot.js +10 -3
- package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
- package/dist/primitives/threadList.d.ts +0 -2
- package/dist/primitives/threadListFocusGroup.d.ts +25 -0
- package/dist/primitives/threadListFocusGroup.d.ts.map +1 -0
- package/dist/primitives/threadListFocusGroup.js +15 -0
- package/dist/primitives/threadListFocusGroup.js.map +1 -0
- package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts +0 -1
- package/dist/primitives/threadListItem/ThreadListItemArchive.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts +0 -1
- package/dist/primitives/threadListItem/ThreadListItemDelete.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts +0 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.js +45 -27
- package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts +0 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.d.ts.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js +26 -2
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts +0 -1
- package/dist/primitives/threadListItem/ThreadListItemUnarchive.d.ts.map +1 -1
- package/dist/primitives/threadListItem.d.ts +0 -2
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.d.ts +0 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +63 -38
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.d.ts +0 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.d.ts +20 -4
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +95 -14
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.d.ts +0 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.d.ts +0 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +38 -21
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
- package/dist/primitives/threadListItemMore/scope.d.ts +0 -1
- package/dist/primitives/threadListItemMore/scope.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore.d.ts +0 -2
- package/dist/sandbox-host/SandboxHost.d.ts +1 -10
- package/dist/sandbox-host/SandboxHost.d.ts.map +1 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts +0 -1
- package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
- package/dist/unstable/useComposerInput.d.ts +2 -2
- package/dist/unstable/useComposerInput.d.ts.map +1 -1
- package/dist/unstable/useComposerInputHistory.d.ts +2 -2
- package/dist/unstable/useComposerInputHistory.d.ts.map +1 -1
- package/dist/unstable/useLiveCompletionAdapter.d.ts +4 -3
- package/dist/unstable/useLiveCompletionAdapter.d.ts.map +1 -1
- package/dist/unstable/useMentionAdapter.d.ts +19 -10
- package/dist/unstable/useMentionAdapter.d.ts.map +1 -1
- package/dist/unstable/useMessageStallDetection.d.ts +3 -1
- package/dist/unstable/useMessageStallDetection.d.ts.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.d.ts +6 -4
- package/dist/unstable/useSlashCommandAdapter.d.ts.map +1 -1
- package/dist/utils/Primitive.d.ts +0 -1
- package/dist/utils/Primitive.d.ts.map +1 -1
- package/dist/utils/RequireAtLeastOne.d.ts +1 -1
- package/dist/utils/RequireAtLeastOne.d.ts.map +1 -1
- package/dist/utils/createActionButton.d.ts +0 -1
- package/dist/utils/createActionButton.d.ts.map +1 -1
- package/dist/utils/getSelectionMessageId.d.ts.map +1 -1
- package/dist/utils/getSelectionMessageId.js +32 -7
- package/dist/utils/getSelectionMessageId.js.map +1 -1
- package/dist/utils/hooks/useManagedRef.d.ts.map +1 -1
- package/dist/utils/hooks/useMediaQuery.d.ts.map +1 -1
- package/dist/utils/hooks/useMediaQuery.js +2 -2
- package/dist/utils/hooks/useMediaQuery.js.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.d.ts.map +1 -1
- package/dist/utils/hooks/useSizeHandle.d.ts +0 -1
- package/dist/utils/hooks/useSizeHandle.d.ts.map +1 -1
- package/dist/utils/smooth/SmoothContext.d.ts +71 -72
- package/dist/utils/smooth/SmoothContext.d.ts.map +1 -1
- package/dist/utils/smooth/useSmooth.d.ts +4 -1
- package/dist/utils/smooth/useSmooth.d.ts.map +1 -1
- package/dist/utils/smooth/useSmooth.js +7 -1
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -1
- package/package.json +19 -17
- package/src/index.ts +3 -0
- package/src/legacy-runtime/cloud/auiV0.ts +72 -3
- package/src/mcp-apps/McpAppRenderer.test.tsx +141 -0
- package/src/mcp-apps/McpAppRenderer.tsx +48 -10
- package/src/mcp-apps/McpAppsRemoteHost.test.ts +126 -0
- package/src/mcp-apps/McpAppsRemoteHost.ts +40 -1
- package/src/mcp-apps/app-frame.tsx +3 -1
- package/src/mcp-apps/bridge.ts +1 -1
- package/src/mcp-apps/types.ts +16 -8
- package/src/primitives/assistantModal/AssistantModalAnchor.tsx +6 -8
- package/src/primitives/assistantModal/AssistantModalContent.tsx +5 -5
- package/src/primitives/assistantModal/AssistantModalTrigger.test.tsx +80 -0
- package/src/primitives/assistantModal/AssistantModalTrigger.tsx +6 -8
- package/src/primitives/assistantModal/popoverRenderPrimitives.ts +6 -0
- package/src/primitives/composer/ComposerCompactContext.tsx +13 -0
- package/src/primitives/composer/ComposerInput.tsx +35 -0
- package/src/primitives/composer/ComposerRoot.test.tsx +161 -0
- package/src/primitives/composer/ComposerRoot.tsx +37 -7
- package/src/primitives/messagePart/MessagePartText.tsx +1 -0
- package/src/primitives/threadList/ThreadListRoot.tsx +8 -1
- package/src/primitives/threadListFocusGroup.ts +24 -0
- package/src/primitives/threadListItem/ThreadListItemRoot.tsx +53 -5
- package/src/primitives/threadListItem/ThreadListItemTrigger.tsx +45 -0
- package/src/primitives/threadListItem/ThreadListKeyboardNav.test.tsx +141 -0
- package/src/primitives/threadListItemMore/ThreadListItemMoreContent.tsx +22 -1
- package/src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx +64 -3
- package/src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx +29 -2
- package/src/tests/LocalThreadRuntimeCore.test.ts +4 -1
- package/src/tests/auiV0Encode.test.ts +134 -1
- package/src/tests/generative-ui.test.tsx +21 -1
- package/src/utils/getSelectionMessageId.test.ts +175 -0
- package/src/utils/getSelectionMessageId.ts +57 -6
- package/src/utils/hooks/useMediaQuery.ts +3 -2
- package/src/utils/smooth/useSmooth.test.tsx +26 -0
- package/src/utils/smooth/useSmooth.ts +7 -1
- package/dist/utils/json/is-json-equal.d.ts +0 -5
- package/dist/utils/json/is-json-equal.d.ts.map +0 -1
- package/dist/utils/json/is-json-equal.js +0 -26
- package/dist/utils/json/is-json-equal.js.map +0 -1
- package/dist/utils/json/is-json.d.ts +0 -10
- package/dist/utils/json/is-json.d.ts.map +0 -1
- package/dist/utils/json/is-json.js +0 -22
- package/dist/utils/json/is-json.js.map +0 -1
- package/src/primitives/threadListItem/ThreadListItemTrigger.ts +0 -23
- package/src/utils/json/is-json-equal.ts +0 -48
- package/src/utils/json/is-json.ts +0 -58
package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":";;;;cA8Fa,yCAGH,SAAS;iBAOH,8BAA8B;iBAC9B,2BAA2B,GACzC,WAAW,OAAO,sBAAsB,IACvC;;;;cA6QU,+BAAgC,GAC3C,SAAS,0BAA0B,OAClC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AssistantTransportCommand, AssistantTransportState, AssistantTransportStateConverter } from "./types.js";
|
|
2
2
|
import { ToolExecutionStatus } from "@assistant-ui/core";
|
|
3
|
-
|
|
4
3
|
//#region src/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.d.ts
|
|
5
4
|
declare function useConvertedState<T>(converter: AssistantTransportStateConverter<T>, agentState: T, pendingCommands: AssistantTransportCommand[], isSending: boolean, toolStatuses: Record<string, ToolExecutionStatus>): AssistantTransportState;
|
|
6
5
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConvertedState.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useConvertedState.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.ts"],"mappings":";;;iBAQgB,kBAAkB,GAChC,WAAW,iCAAiC,IAC5C,YAAY,GACZ,iBAAiB,6BACjB,oBACA,cAAc,eAAe,uBAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLatestRef.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.ts"],"mappings":";iBAEgB,
|
|
1
|
+
{"version":3,"file":"useLatestRef.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.ts"],"mappings":";iBAEgB,aAAa,GAAG,OAAO;EAKrB,SAAS"}
|
|
@@ -2,7 +2,6 @@ import { McpAppHostContext, McpAppHostInfo, McpAppSandboxConfig, McpAppsHost } f
|
|
|
2
2
|
import { ToolCallMessagePartComponent } from "@assistant-ui/core/react";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
import { ResourceElement } from "@assistant-ui/tap";
|
|
5
|
-
|
|
6
5
|
//#region src/mcp-apps/McpAppRenderer.d.ts
|
|
7
6
|
type McpAppRendererOptions = {
|
|
8
7
|
/**
|
|
@@ -10,17 +9,23 @@ type McpAppRendererOptions = {
|
|
|
10
9
|
* (`loadResource`, `callTool`, `readResource`, `listResources`). Use
|
|
11
10
|
* `McpAppsRemoteHost({ url })` for the default HTTP-route convention.
|
|
12
11
|
*/
|
|
13
|
-
host: ResourceElement<McpAppsHost>;
|
|
12
|
+
host: ResourceElement<McpAppsHost>;
|
|
13
|
+
/** Sandbox + container styling. Passes through to SafeContentFrame. */
|
|
14
14
|
sandbox?: McpAppSandboxConfig;
|
|
15
15
|
/**
|
|
16
16
|
* Upper bound (in pixels) applied to the widget-driven auto-resize height.
|
|
17
17
|
* Defaults to 800.
|
|
18
18
|
*/
|
|
19
|
-
maxHeight?: number;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
maxHeight?: number;
|
|
20
|
+
/** Identifies the host to the widget in the `ui/initialize` response. */
|
|
21
|
+
hostInfo?: McpAppHostInfo;
|
|
22
|
+
/** Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change. */
|
|
23
|
+
hostContext?: McpAppHostContext;
|
|
24
|
+
/** Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden). */
|
|
25
|
+
fallback?: ReactNode;
|
|
26
|
+
/** Rendered while the resource is loading. Defaults to `fallback`. */
|
|
27
|
+
loadingFallback?: ReactNode;
|
|
28
|
+
/** Rendered when the resource load rejects. Defaults to `fallback`. */
|
|
24
29
|
errorFallback?: ReactNode | ((error: Error) => ReactNode);
|
|
25
30
|
};
|
|
26
31
|
declare const McpAppRenderer: import("@assistant-ui/tap").Resource<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppRenderer.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"McpAppRenderer.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"mappings":";;;;;KA8BY;;;;;;EAMV,MAAM,gBAAgB;;EAEtB,UAAU;;;;;EAKV;;EAEA,WAAW;;EAEX,cAAc;;EAEd,WAAW;;EAEX,kBAAkB;;EAElB,gBAAgB,cAAc,OAAO,UAAU;;cAgNpC,4CAAc;mBAxBL;aAAA"}
|
|
@@ -5,6 +5,7 @@ import { useAui } from "@assistant-ui/store";
|
|
|
5
5
|
import { useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
6
6
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
7
7
|
import { resource, useResource } from "@assistant-ui/tap";
|
|
8
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
8
9
|
//#region src/mcp-apps/McpAppRenderer.tsx
|
|
9
10
|
function getInput(part) {
|
|
10
11
|
if (part.status.type === "running" && (part.argsText === "" || part.argsText === "{}")) return;
|
|
@@ -26,29 +27,38 @@ function InlineRenderer({ part, internalsRef, optionsRef }) {
|
|
|
26
27
|
const aui = useAui();
|
|
27
28
|
const app = getMcpAppFromToolPart(part);
|
|
28
29
|
const cachedAppRef = useRef(void 0);
|
|
29
|
-
if (app != null && cachedAppRef.current?.resourceUri !== app.resourceUri) cachedAppRef.current = app;
|
|
30
|
+
if (app != null && (cachedAppRef.current?.resourceUri !== app.resourceUri || cachedAppRef.current?.serverId !== app.serverId)) cachedAppRef.current = app;
|
|
30
31
|
const appForRender = app ?? cachedAppRef.current;
|
|
31
32
|
const [loadedResource, setLoadedResource] = useState();
|
|
32
33
|
const resourceUri = appForRender?.resourceUri;
|
|
34
|
+
const serverId = appForRender?.serverId;
|
|
35
|
+
const serverIdRef = useRef(void 0);
|
|
36
|
+
serverIdRef.current = serverId;
|
|
33
37
|
useEffect(() => {
|
|
34
38
|
if (appForRender == null || resourceUri == null) return;
|
|
35
39
|
let cancelled = false;
|
|
36
40
|
const targetUri = resourceUri;
|
|
37
|
-
|
|
41
|
+
const targetServerId = serverId;
|
|
42
|
+
internalsRef.current.host.loadResource({
|
|
43
|
+
uri: targetUri,
|
|
44
|
+
...targetServerId ? { serverId: targetServerId } : {}
|
|
45
|
+
}).then((res) => {
|
|
38
46
|
if (!cancelled) setLoadedResource({
|
|
39
47
|
resourceUri: targetUri,
|
|
48
|
+
...targetServerId !== void 0 ? { serverId: targetServerId } : {},
|
|
40
49
|
resource: res
|
|
41
50
|
});
|
|
42
51
|
}).catch((error) => {
|
|
43
52
|
if (!cancelled) setLoadedResource({
|
|
44
53
|
resourceUri: targetUri,
|
|
54
|
+
...targetServerId !== void 0 ? { serverId: targetServerId } : {},
|
|
45
55
|
error: error instanceof Error ? error : new Error(String(error))
|
|
46
56
|
});
|
|
47
57
|
});
|
|
48
58
|
return () => {
|
|
49
59
|
cancelled = true;
|
|
50
60
|
};
|
|
51
|
-
}, [resourceUri]);
|
|
61
|
+
}, [resourceUri, serverId]);
|
|
52
62
|
const bridgeHandlers = useMemo(() => ({
|
|
53
63
|
openLink: defaultOpenLink,
|
|
54
64
|
sendMessage: (params) => {
|
|
@@ -63,11 +73,23 @@ function InlineRenderer({ part, internalsRef, optionsRef }) {
|
|
|
63
73
|
}] });
|
|
64
74
|
return { ok: true };
|
|
65
75
|
},
|
|
66
|
-
callTool: (params_0) => internalsRef.current.host.callTool(
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
callTool: (params_0) => internalsRef.current.host.callTool({
|
|
77
|
+
...params_0,
|
|
78
|
+
...serverIdRef.current ? { serverId: serverIdRef.current } : {}
|
|
79
|
+
}),
|
|
80
|
+
readResource: (params_1) => internalsRef.current.host.readResource({
|
|
81
|
+
...params_1,
|
|
82
|
+
...serverIdRef.current ? { serverId: serverIdRef.current } : {}
|
|
83
|
+
}),
|
|
84
|
+
listResources: (params_2) => {
|
|
85
|
+
if (!serverIdRef.current) return internalsRef.current.host.listResources(params_2);
|
|
86
|
+
return internalsRef.current.host.listResources({
|
|
87
|
+
...isRecord(params_2) ? params_2 : {},
|
|
88
|
+
serverId: serverIdRef.current
|
|
89
|
+
});
|
|
90
|
+
}
|
|
69
91
|
}), [aui, internalsRef]);
|
|
70
|
-
const loadedResourceForApp = loadedResource?.resourceUri === appForRender?.resourceUri ? loadedResource : void 0;
|
|
92
|
+
const loadedResourceForApp = loadedResource?.resourceUri === appForRender?.resourceUri && loadedResource?.serverId === appForRender?.serverId ? loadedResource : void 0;
|
|
71
93
|
const appResource = loadedResourceForApp?.resource;
|
|
72
94
|
const error_0 = loadedResourceForApp?.error;
|
|
73
95
|
const fallback = opts.fallback ?? null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppRenderer.js","names":["useEffect","useMemo","useRef","useState","MutableRefObject","ReactNode","McpAppMetadata","ToolCallMessagePartComponent","ToolCallMessagePartProps","useAui","useResource","resource","ResourceElement","McpAppFrame","McpAppBridgeHandlers","McpAppHostContext","McpAppHostInfo","McpAppResource","McpAppSandboxConfig","McpAppsHost","getMcpAppFromToolPart","McpAppRendererOptions","host","sandbox","maxHeight","hostInfo","hostContext","fallback","loadingFallback","errorFallback","error","Error","LoadedResourceState","resourceUri","getInput","part","status","type","argsText","args","undefined","defaultOpenLink","url","window","open","extractSendMessageText","params","obj","Record","InlineRenderer","internalsRef","optionsRef","opts","current","aui","app","cachedAppRef","appForRender","loadedResource","setLoadedResource","cancelled","targetUri","loadResource","uri","then","res","catch","String","bridgeHandlers","openLink","sendMessage","text","ok","reason","thread","append","content","callTool","readResource","listResources","loadedResourceForApp","appResource","result","useMcpAppRenderer","options","render","Render","props","displayName","McpAppRenderer"],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type ReactNode,\n} from \"react\";\nimport type { McpAppMetadata } from \"@assistant-ui/core\";\nimport type {\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\n\nimport { useResource, resource, type ResourceElement } from \"@assistant-ui/tap\";\nimport { McpAppFrame } from \"./app-frame\";\nimport type {\n McpAppBridgeHandlers,\n McpAppHostContext,\n McpAppHostInfo,\n McpAppResource,\n McpAppSandboxConfig,\n McpAppsHost,\n} from \"./types\";\nimport { getMcpAppFromToolPart } from \"./utils\";\n\nexport type McpAppRendererOptions = {\n /**\n * Provides the data-plane operations the widget can request\n * (`loadResource`, `callTool`, `readResource`, `listResources`). Use\n * `McpAppsRemoteHost({ url })` for the default HTTP-route convention.\n */\n host: ResourceElement<McpAppsHost>;\n /** Sandbox + container styling. Passes through to SafeContentFrame. */\n sandbox?: McpAppSandboxConfig;\n /**\n * Upper bound (in pixels) applied to the widget-driven auto-resize height.\n * Defaults to 800.\n */\n maxHeight?: number;\n /** Identifies the host to the widget in the `ui/initialize` response. */\n hostInfo?: McpAppHostInfo;\n /** Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change. */\n hostContext?: McpAppHostContext;\n /** Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden). */\n fallback?: ReactNode;\n /** Rendered while the resource is loading. Defaults to `fallback`. */\n loadingFallback?: ReactNode;\n /** Rendered when the resource load rejects. Defaults to `fallback`. */\n errorFallback?: ReactNode | ((error: Error) => ReactNode);\n};\n\ntype LoadedResourceState = {\n resourceUri: string;\n resource?: McpAppResource;\n error?: Error;\n};\n\nfunction getInput(part: {\n status: { type: string };\n argsText: string;\n args: unknown;\n}): unknown {\n if (\n part.status.type === \"running\" &&\n (part.argsText === \"\" || part.argsText === \"{}\")\n ) {\n return undefined;\n }\n return part.args;\n}\n\nconst defaultOpenLink = ({ url }: { url: string }) => {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n};\n\nfunction extractSendMessageText(params: unknown): string | undefined {\n if (typeof params === \"string\") return params;\n if (!params || typeof params !== \"object\") return undefined;\n const obj = params as Record<string, unknown>;\n if (typeof obj[\"prompt\"] === \"string\") return obj[\"prompt\"];\n if (typeof obj[\"text\"] === \"string\") return obj[\"text\"];\n if (typeof obj[\"message\"] === \"string\") return obj[\"message\"];\n return undefined;\n}\n\nfunction InlineRenderer({\n part,\n internalsRef,\n optionsRef,\n}: {\n part: ToolCallMessagePartProps;\n internalsRef: MutableRefObject<{ host: McpAppsHost }>;\n optionsRef: MutableRefObject<McpAppRendererOptions>;\n}) {\n const opts = optionsRef.current;\n const aui = useAui();\n const app = getMcpAppFromToolPart(part);\n const cachedAppRef = useRef<McpAppMetadata | undefined>(undefined);\n if (app != null && cachedAppRef.current?.resourceUri !== app.resourceUri) {\n cachedAppRef.current = app;\n }\n const appForRender = app ?? cachedAppRef.current;\n\n const [loadedResource, setLoadedResource] = useState<LoadedResourceState>();\n\n const resourceUri = appForRender?.resourceUri;\n useEffect(() => {\n if (appForRender == null || resourceUri == null) return;\n let cancelled = false;\n const targetUri = resourceUri;\n\n internalsRef.current.host\n .loadResource({ uri: targetUri })\n .then((res) => {\n if (!cancelled)\n setLoadedResource({ resourceUri: targetUri, resource: res });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setLoadedResource({\n resourceUri: targetUri,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-fetch only when URI changes; appForRender identity is unstable and internalsRef is a stable ref\n }, [resourceUri]);\n\n const bridgeHandlers = useMemo<McpAppBridgeHandlers>(\n () => ({\n openLink: defaultOpenLink,\n sendMessage: (params) => {\n const text = extractSendMessageText(params);\n if (!text) return { ok: false, reason: \"unrecognised params shape\" };\n aui.thread().append({ content: [{ type: \"text\", text }] });\n return { ok: true };\n },\n callTool: (params) => internalsRef.current.host.callTool(params),\n readResource: (params) => internalsRef.current.host.readResource(params),\n listResources: (params) =>\n internalsRef.current.host.listResources(params),\n }),\n [aui, internalsRef],\n );\n\n const loadedResourceForApp =\n loadedResource?.resourceUri === appForRender?.resourceUri\n ? loadedResource\n : undefined;\n const appResource = loadedResourceForApp?.resource;\n const error = loadedResourceForApp?.error;\n\n const fallback = opts.fallback ?? null;\n if (appForRender == null) {\n return <>{fallback}</>;\n }\n if (error != null) {\n const errorFallback = opts.errorFallback;\n if (errorFallback === undefined) return <>{fallback}</>;\n if (typeof errorFallback === \"function\") return <>{errorFallback(error)}</>;\n return <>{errorFallback}</>;\n }\n if (appResource == null) {\n return <>{opts.loadingFallback ?? fallback}</>;\n }\n\n return (\n <McpAppFrame\n app={appForRender}\n resource={appResource}\n input={getInput(part)}\n output={part.result}\n sandbox={opts.sandbox}\n handlers={bridgeHandlers}\n hostInfo={opts.hostInfo}\n hostContext={opts.hostContext}\n maxHeight={opts.maxHeight}\n />\n );\n}\n\n/**\n * Creates a tool-call renderer for MCP Apps embedded in assistant messages.\n *\n * Compose this into the `Tools` resource through its `mcpApp` option. When a\n * tool-call part carries `mcp.app` metadata for a `ui://` resource, the\n * renderer loads that resource from the configured host and displays it in a\n * sandboxed frame.\n */\nconst useMcpAppRenderer = (\n options: McpAppRendererOptions,\n): { readonly render: ToolCallMessagePartComponent } => {\n const host = useResource(options.host);\n\n const optionsRef = useRef<McpAppRendererOptions>(options);\n optionsRef.current = options;\n\n const internalsRef = useRef<{ host: McpAppsHost }>({ host });\n internalsRef.current = { host };\n\n const render = useMemo((): ToolCallMessagePartComponent => {\n const Render: ToolCallMessagePartComponent = (props) => (\n <InlineRenderer\n part={props}\n internalsRef={internalsRef}\n optionsRef={optionsRef}\n />\n );\n Render.displayName = \"McpAppRenderer\";\n return Render;\n }, []);\n\n return { render };\n};\n\nexport const McpAppRenderer = resource(useMcpAppRenderer);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpAppRenderer.js","names":["useEffect","useMemo","useRef","useState","MutableRefObject","ReactNode","McpAppMetadata","ToolCallMessagePartComponent","ToolCallMessagePartProps","useAui","useResource","resource","ResourceElement","McpAppFrame","McpAppBridgeHandlers","McpAppHostContext","McpAppHostInfo","McpAppResource","McpAppSandboxConfig","McpAppsHost","getMcpAppFromToolPart","isRecord","McpAppRendererOptions","host","sandbox","maxHeight","hostInfo","hostContext","fallback","loadingFallback","errorFallback","error","Error","LoadedResourceState","resourceUri","serverId","getInput","part","status","type","argsText","args","undefined","defaultOpenLink","url","window","open","extractSendMessageText","params","obj","Record","InlineRenderer","internalsRef","optionsRef","opts","current","aui","app","cachedAppRef","appForRender","loadedResource","setLoadedResource","serverIdRef","cancelled","targetUri","targetServerId","loadResource","uri","then","res","catch","String","bridgeHandlers","openLink","sendMessage","text","ok","reason","thread","append","content","callTool","readResource","listResources","loadedResourceForApp","appResource","result","useMcpAppRenderer","options","render","Render","props","displayName","McpAppRenderer"],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type ReactNode,\n} from \"react\";\nimport type { McpAppMetadata } from \"@assistant-ui/core\";\nimport type {\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\n\nimport { useResource, resource, type ResourceElement } from \"@assistant-ui/tap\";\nimport { McpAppFrame } from \"./app-frame\";\nimport type {\n McpAppBridgeHandlers,\n McpAppHostContext,\n McpAppHostInfo,\n McpAppResource,\n McpAppSandboxConfig,\n McpAppsHost,\n} from \"./types\";\nimport { getMcpAppFromToolPart } from \"./utils\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nexport type McpAppRendererOptions = {\n /**\n * Provides the data-plane operations the widget can request\n * (`loadResource`, `callTool`, `readResource`, `listResources`). Use\n * `McpAppsRemoteHost({ url })` for the default HTTP-route convention.\n */\n host: ResourceElement<McpAppsHost>;\n /** Sandbox + container styling. Passes through to SafeContentFrame. */\n sandbox?: McpAppSandboxConfig;\n /**\n * Upper bound (in pixels) applied to the widget-driven auto-resize height.\n * Defaults to 800.\n */\n maxHeight?: number;\n /** Identifies the host to the widget in the `ui/initialize` response. */\n hostInfo?: McpAppHostInfo;\n /** Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change. */\n hostContext?: McpAppHostContext;\n /** Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden). */\n fallback?: ReactNode;\n /** Rendered while the resource is loading. Defaults to `fallback`. */\n loadingFallback?: ReactNode;\n /** Rendered when the resource load rejects. Defaults to `fallback`. */\n errorFallback?: ReactNode | ((error: Error) => ReactNode);\n};\n\ntype LoadedResourceState = {\n resourceUri: string;\n serverId?: string;\n resource?: McpAppResource;\n error?: Error;\n};\n\nfunction getInput(part: {\n status: { type: string };\n argsText: string;\n args: unknown;\n}): unknown {\n if (\n part.status.type === \"running\" &&\n (part.argsText === \"\" || part.argsText === \"{}\")\n ) {\n return undefined;\n }\n return part.args;\n}\n\nconst defaultOpenLink = ({ url }: { url: string }) => {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n};\n\nfunction extractSendMessageText(params: unknown): string | undefined {\n if (typeof params === \"string\") return params;\n if (!params || typeof params !== \"object\") return undefined;\n const obj = params as Record<string, unknown>;\n if (typeof obj[\"prompt\"] === \"string\") return obj[\"prompt\"];\n if (typeof obj[\"text\"] === \"string\") return obj[\"text\"];\n if (typeof obj[\"message\"] === \"string\") return obj[\"message\"];\n return undefined;\n}\n\nfunction InlineRenderer({\n part,\n internalsRef,\n optionsRef,\n}: {\n part: ToolCallMessagePartProps;\n internalsRef: MutableRefObject<{ host: McpAppsHost }>;\n optionsRef: MutableRefObject<McpAppRendererOptions>;\n}) {\n const opts = optionsRef.current;\n const aui = useAui();\n const app = getMcpAppFromToolPart(part);\n const cachedAppRef = useRef<McpAppMetadata | undefined>(undefined);\n if (\n app != null &&\n (cachedAppRef.current?.resourceUri !== app.resourceUri ||\n cachedAppRef.current?.serverId !== app.serverId)\n ) {\n cachedAppRef.current = app;\n }\n const appForRender = app ?? cachedAppRef.current;\n\n const [loadedResource, setLoadedResource] = useState<LoadedResourceState>();\n\n const resourceUri = appForRender?.resourceUri;\n const serverId = appForRender?.serverId;\n const serverIdRef = useRef<string | undefined>(undefined);\n serverIdRef.current = serverId;\n useEffect(() => {\n if (appForRender == null || resourceUri == null) return;\n let cancelled = false;\n const targetUri = resourceUri;\n const targetServerId = serverId;\n\n internalsRef.current.host\n .loadResource({\n uri: targetUri,\n ...(targetServerId ? { serverId: targetServerId } : {}),\n })\n .then((res) => {\n if (!cancelled)\n setLoadedResource({\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n resource: res,\n });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setLoadedResource({\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-fetch only when URI or server identity changes; appForRender identity is unstable and internalsRef is a stable ref\n }, [resourceUri, serverId]);\n\n const bridgeHandlers = useMemo<McpAppBridgeHandlers>(\n () => ({\n openLink: defaultOpenLink,\n sendMessage: (params) => {\n const text = extractSendMessageText(params);\n if (!text) return { ok: false, reason: \"unrecognised params shape\" };\n aui.thread().append({ content: [{ type: \"text\", text }] });\n return { ok: true };\n },\n callTool: (params) =>\n internalsRef.current.host.callTool({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n readResource: (params) =>\n internalsRef.current.host.readResource({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n listResources: (params) => {\n if (!serverIdRef.current) {\n return internalsRef.current.host.listResources(params);\n }\n return internalsRef.current.host.listResources({\n ...(isRecord(params) ? params : {}),\n serverId: serverIdRef.current,\n });\n },\n }),\n [aui, internalsRef],\n );\n\n const loadedResourceForApp =\n loadedResource?.resourceUri === appForRender?.resourceUri &&\n loadedResource?.serverId === appForRender?.serverId\n ? loadedResource\n : undefined;\n const appResource = loadedResourceForApp?.resource;\n const error = loadedResourceForApp?.error;\n\n const fallback = opts.fallback ?? null;\n if (appForRender == null) {\n return <>{fallback}</>;\n }\n if (error != null) {\n const errorFallback = opts.errorFallback;\n if (errorFallback === undefined) return <>{fallback}</>;\n if (typeof errorFallback === \"function\") return <>{errorFallback(error)}</>;\n return <>{errorFallback}</>;\n }\n if (appResource == null) {\n return <>{opts.loadingFallback ?? fallback}</>;\n }\n\n return (\n <McpAppFrame\n app={appForRender}\n resource={appResource}\n input={getInput(part)}\n output={part.result}\n sandbox={opts.sandbox}\n handlers={bridgeHandlers}\n hostInfo={opts.hostInfo}\n hostContext={opts.hostContext}\n maxHeight={opts.maxHeight}\n />\n );\n}\n\n/**\n * Creates a tool-call renderer for MCP Apps embedded in assistant messages.\n *\n * Compose this into the `Tools` resource through its `mcpApp` option. When a\n * tool-call part carries `mcp.app` metadata for a `ui://` resource, the\n * renderer loads that resource from the configured host and displays it in a\n * sandboxed frame.\n */\nconst useMcpAppRenderer = (\n options: McpAppRendererOptions,\n): { readonly render: ToolCallMessagePartComponent } => {\n const host = useResource(options.host);\n\n const optionsRef = useRef<McpAppRendererOptions>(options);\n optionsRef.current = options;\n\n const internalsRef = useRef<{ host: McpAppsHost }>({ host });\n internalsRef.current = { host };\n\n const render = useMemo((): ToolCallMessagePartComponent => {\n const Render: ToolCallMessagePartComponent = (props) => (\n <InlineRenderer\n part={props}\n internalsRef={internalsRef}\n optionsRef={optionsRef}\n />\n );\n Render.displayName = \"McpAppRenderer\";\n return Render;\n }, []);\n\n return { render };\n};\n\nexport const McpAppRenderer = resource(useMcpAppRenderer);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppsRemoteHost.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"McpAppsRemoteHost.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"mappings":";;cAoGa,+CAAiB,SAAA,cAAA,SAAA"}
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import { useMemo, useRef } from "@assistant-ui/tap/react-shim";
|
|
2
2
|
import { resource } from "@assistant-ui/tap";
|
|
3
3
|
//#region src/mcp-apps/McpAppsRemoteHost.ts
|
|
4
|
+
const truncateBody = (body) => body.length > 500 ? `${body.slice(0, 500)}...` : body;
|
|
5
|
+
const extractErrorBody = (body) => {
|
|
6
|
+
const trimmed = body.trim();
|
|
7
|
+
if (!trimmed) return void 0;
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(trimmed);
|
|
10
|
+
if (parsed && typeof parsed === "object") {
|
|
11
|
+
const record = parsed;
|
|
12
|
+
if (typeof record.message === "string") return record.message;
|
|
13
|
+
if (typeof record.error === "string") return record.error;
|
|
14
|
+
if (record.error && typeof record.error === "object") {
|
|
15
|
+
const error = record.error;
|
|
16
|
+
if (typeof error.message === "string") return error.message;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
return truncateBody(trimmed);
|
|
21
|
+
}
|
|
22
|
+
return truncateBody(trimmed);
|
|
23
|
+
};
|
|
24
|
+
const readErrorBody = async (res) => {
|
|
25
|
+
try {
|
|
26
|
+
return extractErrorBody(await res.text());
|
|
27
|
+
} catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
4
31
|
async function postToHost(options, method, params) {
|
|
5
32
|
const doFetch = options.fetch ?? fetch;
|
|
6
33
|
const extraHeaders = typeof options.headers === "function" ? await options.headers() : options.headers ?? {};
|
|
@@ -15,7 +42,11 @@ async function postToHost(options, method, params) {
|
|
|
15
42
|
params
|
|
16
43
|
})
|
|
17
44
|
});
|
|
18
|
-
if (!res.ok)
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const status = res.statusText ? `${res.status} ${res.statusText}` : `${res.status}`;
|
|
47
|
+
const body = await readErrorBody(res);
|
|
48
|
+
throw new Error(`MCP App host request "${method}" to "${options.url}" failed with ${status}${body ? `: ${body}` : ""}`);
|
|
49
|
+
}
|
|
19
50
|
return res.json();
|
|
20
51
|
}
|
|
21
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppsRemoteHost.js","names":["useMemo","useRef","resource","McpAppResource","McpAppsHost","McpAppsRemoteHostOptions","
|
|
1
|
+
{"version":3,"file":"McpAppsRemoteHost.js","names":["useMemo","useRef","resource","McpAppResource","McpAppsHost","McpAppsRemoteHostOptions","truncateBody","body","length","slice","extractErrorBody","trimmed","trim","undefined","parsed","JSON","parse","record","Record","message","error","readErrorBody","res","Response","Promise","text","postToHost","options","method","params","doFetch","fetch","extraHeaders","headers","url","stringify","ok","status","statusText","Error","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\nconst truncateBody = (body: string) =>\n body.length > 500 ? `${body.slice(0, 500)}...` : body;\n\nconst extractErrorBody = (body: string): string | undefined => {\n const trimmed = body.trim();\n if (!trimmed) return undefined;\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (parsed && typeof parsed === \"object\") {\n const record = parsed as Record<string, unknown>;\n if (typeof record.message === \"string\") return record.message;\n if (typeof record.error === \"string\") return record.error;\n if (record.error && typeof record.error === \"object\") {\n const error = record.error as Record<string, unknown>;\n if (typeof error.message === \"string\") return error.message;\n }\n }\n } catch {\n return truncateBody(trimmed);\n }\n\n return truncateBody(trimmed);\n};\n\nconst readErrorBody = async (res: Response): Promise<string | undefined> => {\n try {\n return extractErrorBody(await res.text());\n } catch {\n return undefined;\n }\n};\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 const status = res.statusText\n ? `${res.status} ${res.statusText}`\n : `${res.status}`;\n const body = await readErrorBody(res);\n throw new Error(\n `MCP App host request \"${method}\" to \"${options.url}\" failed with ${status}${body ? `: ${body}` : \"\"}`,\n );\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,MAAMM,gBAAgBC,SACpBA,KAAKC,SAAS,MAAM,GAAGD,KAAKE,MAAM,GAAG,GAAG,EAAC,OAAQF;AAEnD,MAAMG,oBAAoBH,SAAqC;CAC7D,MAAMI,UAAUJ,KAAKK,KAAK;CAC1B,IAAI,CAACD,SAAS,OAAOE,KAAAA;CAErB,IAAI;EACF,MAAMC,SAASC,KAAKC,MAAML,OAAO;EACjC,IAAIG,UAAU,OAAOA,WAAW,UAAU;GACxC,MAAMG,SAASH;GACf,IAAI,OAAOG,OAAOE,YAAY,UAAU,OAAOF,OAAOE;GACtD,IAAI,OAAOF,OAAOG,UAAU,UAAU,OAAOH,OAAOG;GACpD,IAAIH,OAAOG,SAAS,OAAOH,OAAOG,UAAU,UAAU;IACpD,MAAMA,QAAQH,OAAOG;IACrB,IAAI,OAAOA,MAAMD,YAAY,UAAU,OAAOC,MAAMD;GACtD;EACF;CACF,QAAQ;EACN,OAAOb,aAAaK,OAAO;CAC7B;CAEA,OAAOL,aAAaK,OAAO;AAC7B;AAEA,MAAMU,gBAAgB,OAAOC,QAA+C;CAC1E,IAAI;EACF,OAAOZ,iBAAiB,MAAMY,IAAIG,KAAK,CAAC;CAC1C,QAAQ;EACN;CACF;AACF;AAEA,eAAeC,WACbC,SACAC,QACAC,QACkB;CAClB,MAAMC,UAAUH,QAAQI,SAASA;CACjC,MAAMC,eACJ,OAAOL,QAAQM,YAAY,aACvB,MAAMN,QAAQM,QAAQ,IACrBN,QAAQM,WAAW,CAAC;CAC3B,MAAMX,MAAM,MAAMQ,QAAQH,QAAQO,KAAK;EACrCN,QAAQ;EACRK,SAAS;GAAE,gBAAgB;GAAoB,GAAGD;EAAa;EAC/DzB,MAAMQ,KAAKoB,UAAU;GAAEP;GAAQC;EAAO,CAAC;CACzC,CAAC;CACD,IAAI,CAACP,IAAIc,IAAI;EACX,MAAMC,SAASf,IAAIgB,aACf,GAAGhB,IAAIe,OAAM,GAAIf,IAAIgB,eACrB,GAAGhB,IAAIe;EACX,MAAM9B,OAAO,MAAMc,cAAcC,GAAG;EACpC,MAAM,IAAIiB,MACR,yBAAyBX,OAAM,QAASD,QAAQO,IAAG,gBAAiBG,SAAS9B,OAAO,KAAKA,SAAS,IACpG;CACF;CACA,OAAOe,IAAIkB,KAAK;AAClB;;;;;;;;AASA,MAAMC,wBACJd,YACgB;CAChB,MAAMe,aAAazC,OAAO0B,OAAO;CACjCe,WAAWC,UAAUhB;CAErB,OAAO3B,eACe;EAClB4C,eAAef,WACbH,WACEgB,WAAWC,SACX,0BACAd,MACF;EACFgB,WAAWhB,aACTH,WAAWgB,WAAWC,SAAS,cAAcd,QAAM;EACrDiB,eAAejB,aACbH,WAAWgB,WAAWC,SAAS,kBAAkBd,QAAM;EACzDkB,gBAAgBlB,aACdH,WAAWgB,WAAWC,SAAS,kBAAkBd,QAAM;CAC3D,IACA,CAAA,CACF;AACF;AAEA,MAAamB,oBAAoB9C,SAASuC,oBAAoB"}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
import { McpAppFrameProps } from "./types.js";
|
|
2
|
-
|
|
3
2
|
//#region src/mcp-apps/app-frame.d.ts
|
|
4
|
-
declare function McpAppFrame({
|
|
5
|
-
app,
|
|
6
|
-
resource,
|
|
7
|
-
input,
|
|
8
|
-
output,
|
|
9
|
-
sandbox,
|
|
10
|
-
handlers,
|
|
11
|
-
hostInfo,
|
|
12
|
-
hostContext,
|
|
13
|
-
maxHeight
|
|
14
|
-
}: McpAppFrameProps): import("react").JSX.Element;
|
|
3
|
+
declare function McpAppFrame({ app, resource, input, output, sandbox, handlers, hostInfo, hostContext, maxHeight }: McpAppFrameProps): import("react").JSX.Element;
|
|
15
4
|
//#endregion
|
|
16
5
|
export { McpAppFrame };
|
|
17
6
|
//# sourceMappingURL=app-frame.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame.d.ts","names":[],"sources":["../../src/mcp-apps/app-frame.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-frame.d.ts","names":[],"sources":["../../src/mcp-apps/app-frame.tsx"],"mappings":";;iBAgGgB,cACd,KACA,UACA,OACA,QACA,SACA,UACA,UACA,aACA,aACC,mCAAgB,IAAA"}
|
|
@@ -162,7 +162,7 @@ function McpAppFrame({ app, resource, input, output, sandbox, handlers, hostInfo
|
|
|
162
162
|
useBridgeNotify(hostContext, bridgeRef, widgetReadyRef, pendingHostContextRef, lastSentHostContextRef, (b_2, v_1) => b_2.notifyHostContextChanged(v_1));
|
|
163
163
|
return /* @__PURE__ */ jsx(SandboxHost, {
|
|
164
164
|
content: { html: resource.html },
|
|
165
|
-
contentKey: resource.uri,
|
|
165
|
+
contentKey: app.serverId ? `${app.serverId} ${resource.uri}` : resource.uri,
|
|
166
166
|
sandbox: {
|
|
167
167
|
...sandbox,
|
|
168
168
|
product: sandbox?.product ?? DEFAULT_PRODUCT
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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","serverId","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={\n app.serverId ? `${app.serverId} ${resource.uri}` : resource.uri\n }\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,6 +1,5 @@
|
|
|
1
1
|
import { SandboxHostFrame } from "../sandbox-host/SandboxHost.js";
|
|
2
2
|
import { McpAppBridgeHandlers, McpAppHostContext, McpAppHostInfo } from "./types.js";
|
|
3
|
-
|
|
4
3
|
//#region src/mcp-apps/bridge.d.ts
|
|
5
4
|
type McpAppBridgeFrame = SandboxHostFrame;
|
|
6
5
|
type CreateMcpAppBridgeOptions = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"mappings":";;;KAoBY,oBAAoB;KAEpB;EACV,OAAO;EACP,WAAW;EACX,WAAW;EACX,cAAc;;KAGJ;EACV,YAAY,OAAO;EACnB;EACA,kBAAkB;EAClB,mBAAmB;EACnB,2BAA2B,aAAa;;iBAgD1B,mBACd,MAAM,4BACL"}
|
package/dist/mcp-apps/bridge.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./types.js";
|
|
2
|
-
import { isRecord } from "
|
|
2
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
3
3
|
//#region src/mcp-apps/bridge.ts
|
|
4
4
|
const VALID_DISPLAY_MODES = [
|
|
5
5
|
"inline",
|
|
@@ -44,11 +44,12 @@ function createMcpAppBridge(opts) {
|
|
|
44
44
|
frame.sendMessage(msg);
|
|
45
45
|
};
|
|
46
46
|
const respond = (id, payload) => {
|
|
47
|
-
|
|
47
|
+
const res = {
|
|
48
48
|
jsonrpc: "2.0",
|
|
49
49
|
id,
|
|
50
50
|
...payload
|
|
51
|
-
}
|
|
51
|
+
};
|
|
52
|
+
post(res);
|
|
52
53
|
};
|
|
53
54
|
const errorResponse = (id, code, message, data) => {
|
|
54
55
|
respond(id, { error: {
|
|
@@ -1 +1 @@
|
|
|
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":"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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 \"@assistant-ui/core/internal\";\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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"}
|