@assistant-ui/react 0.15.16 → 0.15.18
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 +4 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +4 -2
- package/dist/mcp-apps/McpAppRenderer.d.ts +36 -9
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.js +108 -57
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.js +20 -17
- package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
- package/dist/mcp-apps/app-frame.d.ts.map +1 -1
- package/dist/mcp-apps/app-frame.js +229 -115
- package/dist/mcp-apps/app-frame.js.map +1 -1
- package/dist/mcp-apps/bridge.js +2 -3
- package/dist/mcp-apps/bridge.js.map +1 -1
- package/dist/mcp-apps/index.d.ts +3 -3
- package/dist/model-context/frame/useAssistantFrameHost.d.ts +1 -1
- package/dist/model-context/frame/useAssistantFrameHost.js +10 -11
- package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
- package/dist/model-context/makeAssistantVisible.js +1 -1
- package/dist/model-context/makeAssistantVisible.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +3 -3
- package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js +3 -3
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +3 -3
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +3 -3
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarStopSpeaking.js +3 -3
- package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
- package/dist/primitives/actionBarMore/scope.d.ts +2 -2
- package/dist/primitives/actionBarMore/scope.d.ts.map +1 -1
- package/dist/primitives/actionBarMore/scope.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalContent.js +1 -1
- package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
- package/dist/primitives/assistantModal/scope.d.ts +2 -2
- package/dist/primitives/assistantModal/scope.d.ts.map +1 -1
- package/dist/primitives/assistantModal/scope.js.map +1 -1
- package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.js +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
- package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +1 -3
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts +1 -2
- package/dist/primitives/composer/ComposerInputPluginContext.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInputPluginContext.js +1 -6
- package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
- package/dist/primitives/composer/ComposerQuote.js +5 -5
- package/dist/primitives/composer/ComposerQuote.js.map +1 -1
- package/dist/primitives/composer/ComposerRoot.js +3 -3
- package/dist/primitives/composer/ComposerRoot.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts +5 -0
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.js +157 -130
- package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js +46 -15
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverBack.js +3 -3
- package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +4 -4
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.js +40 -10
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js +4 -4
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts +2 -0
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverResource.js +63 -61
- package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts +2 -0
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
- package/dist/primitives/composer/trigger/detectTrigger.d.ts +21 -1
- package/dist/primitives/composer/trigger/detectTrigger.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/detectTrigger.js +17 -3
- package/dist/primitives/composer/trigger/detectTrigger.js.map +1 -1
- package/dist/primitives/composer/trigger/index.d.ts +3 -1
- package/dist/primitives/composer/trigger/index.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/index.js.map +1 -1
- package/dist/primitives/composer/trigger/matchesTriggerItemQuery.d.ts +6 -0
- package/dist/primitives/composer/trigger/matchesTriggerItemQuery.d.ts.map +1 -0
- package/dist/primitives/composer/trigger/matchesTriggerItemQuery.js +9 -0
- package/dist/primitives/composer/trigger/matchesTriggerItemQuery.js.map +1 -0
- package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts +3 -4
- package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerDetectionResource.js +15 -14
- package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerNavigationResource.js +3 -5
- package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerSelectionResource.js +18 -19
- package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
- package/dist/primitives/composer.d.ts +3 -2
- package/dist/primitives/composer.js.map +1 -1
- package/dist/primitives/error/ErrorMessage.js.map +1 -1
- package/dist/primitives/message/MessageIf.js.map +1 -1
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/message/MessageRoot.js +4 -4
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/messagePart/MessagePartText.d.ts +1 -1
- package/dist/primitives/messagePart/MessagePartText.js.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +3 -3
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +3 -3
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
- package/dist/primitives/thread/ThreadIf.js.map +1 -1
- package/dist/primitives/thread/ThreadViewport.js +3 -3
- package/dist/primitives/thread/ThreadViewport.js.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.js +3 -3
- package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js +4 -4
- package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.js +3 -3
- package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
- package/dist/primitives/threadListFocusGroup.d.ts +2 -1
- package/dist/primitives/threadListFocusGroup.d.ts.map +1 -1
- package/dist/primitives/threadListFocusGroup.js +2 -2
- package/dist/primitives/threadListFocusGroup.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.js +3 -3
- package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js +1 -1
- package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +1 -2
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
- package/dist/primitives/threadListItemMore/scope.d.ts +2 -2
- package/dist/primitives/threadListItemMore/scope.d.ts.map +1 -1
- package/dist/primitives/threadListItemMore/scope.js.map +1 -1
- package/dist/sandbox-host/SandboxHost.d.ts.map +1 -1
- package/dist/sandbox-host/SandboxHost.js +148 -72
- package/dist/sandbox-host/SandboxHost.js.map +1 -1
- package/dist/unstable/useLiveCompletionAdapter.js +3 -1
- package/dist/unstable/useLiveCompletionAdapter.js.map +1 -1
- package/dist/unstable/useMentionAdapter.d.ts +9 -3
- package/dist/unstable/useMentionAdapter.d.ts.map +1 -1
- package/dist/unstable/useMentionAdapter.js +50 -43
- package/dist/unstable/useMentionAdapter.js.map +1 -1
- package/dist/unstable/useModelContextSnapshot.d.ts +34 -0
- package/dist/unstable/useModelContextSnapshot.d.ts.map +1 -0
- package/dist/unstable/useModelContextSnapshot.js +61 -0
- package/dist/unstable/useModelContextSnapshot.js.map +1 -0
- package/dist/unstable/useSlashCommandAdapter.d.ts.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.js +37 -29
- package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
- package/dist/unstable/webmcp/WebMcpRegistrationResource.d.ts +14 -0
- package/dist/unstable/webmcp/WebMcpRegistrationResource.d.ts.map +1 -0
- package/dist/unstable/webmcp/WebMcpRegistrationResource.js +85 -0
- package/dist/unstable/webmcp/WebMcpRegistrationResource.js.map +1 -0
- package/dist/unstable/webmcp/convertTools.d.ts +21 -0
- package/dist/unstable/webmcp/convertTools.d.ts.map +1 -0
- package/dist/unstable/webmcp/convertTools.js +110 -0
- package/dist/unstable/webmcp/convertTools.js.map +1 -0
- package/dist/unstable/webmcp/useWebMcpProvider.d.ts +21 -0
- package/dist/unstable/webmcp/useWebMcpProvider.d.ts.map +1 -0
- package/dist/unstable/webmcp/useWebMcpProvider.js +105 -0
- package/dist/unstable/webmcp/useWebMcpProvider.js.map +1 -0
- package/dist/unstable/webmcp/webmcp-host.d.ts +39 -0
- package/dist/unstable/webmcp/webmcp-host.d.ts.map +1 -0
- package/dist/unstable/webmcp/webmcp-host.js +29 -0
- package/dist/unstable/webmcp/webmcp-host.js.map +1 -0
- package/dist/utils/Primitive.d.ts +6 -6
- package/dist/utils/Primitive.js +2 -2
- package/dist/utils/Primitive.js.map +1 -1
- package/dist/utils/createActionButton.js +3 -3
- package/dist/utils/createActionButton.js.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.js +1 -1
- package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.js +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
- package/dist/utils/smooth/SmoothContext.d.ts +24 -0
- package/dist/utils/smooth/SmoothContext.d.ts.map +1 -1
- package/dist/utils/smooth/useSmooth.js +1 -1
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/package.json +14 -22
- package/src/index.ts +22 -1
- package/src/mcp-apps/McpAppRenderer.test.tsx +386 -9
- package/src/mcp-apps/McpAppRenderer.tsx +171 -69
- package/src/mcp-apps/McpAppsRemoteHost.concurrent.test.tsx +215 -0
- package/src/mcp-apps/McpAppsRemoteHost.ts +28 -12
- package/src/mcp-apps/app-frame.test.tsx +349 -0
- package/src/mcp-apps/app-frame.tsx +68 -9
- package/src/mcp-apps/bridge.ts +7 -2
- package/src/mcp-apps/index.ts +6 -1
- package/src/model-context/frame/AssistantFrame.test.ts +3 -3
- package/src/model-context/frame/SPEC_AssistantFrame.md +1 -1
- package/src/model-context/frame/useAssistantFrameHost.ts +2 -2
- package/src/model-context/makeAssistantVisible.tsx +1 -1
- package/src/primitives/actionBar/ActionBarCopy.tsx +1 -1
- package/src/primitives/actionBar/ActionBarExportMarkdown.tsx +1 -1
- package/src/primitives/actionBar/ActionBarFeedbackNegative.tsx +1 -1
- package/src/primitives/actionBar/ActionBarFeedbackPositive.tsx +1 -1
- package/src/primitives/actionBar/ActionBarStopSpeaking.tsx +1 -1
- package/src/primitives/actionBarMore/scope.ts +2 -2
- package/src/primitives/assistantModal/AssistantModalContent.tsx +1 -1
- package/src/primitives/assistantModal/scope.ts +2 -2
- package/src/primitives/composer/ComposerAttachmentDropzone.tsx +1 -1
- package/src/primitives/composer/ComposerInput.test.tsx +2 -1
- package/src/primitives/composer/ComposerInput.tsx +3 -3
- package/src/primitives/composer/ComposerInputPluginContext.tsx +0 -10
- package/src/primitives/composer/ComposerQuote.tsx +1 -1
- package/src/primitives/composer/ComposerRoot.tsx +1 -1
- package/src/primitives/composer/trigger/TriggerPopover.tsx +16 -1
- package/src/primitives/composer/trigger/TriggerPopoverAction.tsx +4 -2
- package/src/primitives/composer/trigger/TriggerPopoverBack.tsx +1 -1
- package/src/primitives/composer/trigger/TriggerPopoverBehavior.test.tsx +109 -0
- package/src/primitives/composer/trigger/TriggerPopoverCategories.tsx +1 -1
- package/src/primitives/composer/trigger/TriggerPopoverDirective.tsx +4 -2
- package/src/primitives/composer/trigger/TriggerPopoverItems.tsx +1 -1
- package/src/primitives/composer/trigger/TriggerPopoverResource.ts +4 -1
- package/src/primitives/composer/trigger/TriggerPopoverRootContext.tsx +2 -0
- package/src/primitives/composer/trigger/detectTrigger.test.ts +88 -5
- package/src/primitives/composer/trigger/detectTrigger.ts +50 -9
- package/src/primitives/composer/trigger/index.ts +1 -0
- package/src/primitives/composer/trigger/matchesTriggerItemQuery.test.ts +52 -0
- package/src/primitives/composer/trigger/matchesTriggerItemQuery.ts +13 -0
- package/src/primitives/composer/trigger/triggerDetectionResource.ts +10 -7
- package/src/primitives/composer/trigger/triggerNavigationResource.ts +3 -10
- package/src/primitives/composer/trigger/triggerSelectionResource.test.ts +15 -3
- package/src/primitives/composer/trigger/triggerSelectionResource.ts +1 -4
- package/src/primitives/composer.ts +1 -0
- package/src/primitives/message/MessageRoot.tsx +1 -1
- package/src/primitives/selectionToolbar/SelectionToolbarQuote.tsx +1 -1
- package/src/primitives/selectionToolbar/SelectionToolbarRoot.tsx +1 -1
- package/src/primitives/thread/ThreadViewport.tsx +1 -1
- package/src/primitives/thread/ThreadViewportFooter.tsx +1 -1
- package/src/primitives/thread/useThreadViewportAutoScroll.ts +8 -7
- package/src/primitives/threadList/ThreadListNew.tsx +1 -1
- package/src/primitives/threadListFocusGroup.ts +2 -2
- package/src/primitives/threadListItem/ThreadListItemRoot.tsx +1 -1
- package/src/primitives/threadListItem/ThreadListItemTrigger.tsx +1 -1
- package/src/primitives/threadListItemMore/ThreadListItemMoreContent.tsx +1 -1
- package/src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx +1 -1
- package/src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx +2 -2
- package/src/primitives/threadListItemMore/scope.ts +2 -2
- package/src/sandbox-host/SandboxHost.test.tsx +165 -3
- package/src/sandbox-host/SandboxHost.tsx +42 -9
- package/src/tests/RemoteThreadListRuntime.adapterProvider.test.tsx +31 -1
- package/src/unstable/useComposerInputHistory.test.tsx +2 -1
- package/src/unstable/useLiveCompletionAdapter.test.tsx +60 -1
- package/src/unstable/useLiveCompletionAdapter.ts +4 -1
- package/src/unstable/useMentionAdapter.test.tsx +337 -0
- package/src/unstable/useMentionAdapter.ts +94 -57
- package/src/unstable/useModelContextSnapshot.test.tsx +132 -0
- package/src/unstable/useModelContextSnapshot.ts +67 -0
- package/src/unstable/useSlashCommandAdapter.test.tsx +141 -0
- package/src/unstable/useSlashCommandAdapter.ts +47 -19
- package/src/unstable/webmcp/WebMcpRegistrationResource.ts +92 -0
- package/src/unstable/webmcp/__tests__/webmcp.fake.tsx +168 -0
- package/src/unstable/webmcp/convertTools.test.ts +393 -0
- package/src/unstable/webmcp/convertTools.ts +180 -0
- package/src/unstable/webmcp/useWebMcpProvider.test.tsx +466 -0
- package/src/unstable/webmcp/useWebMcpProvider.ts +150 -0
- package/src/unstable/webmcp/webmcp-host.test.ts +142 -0
- package/src/unstable/webmcp/webmcp-host.ts +83 -0
- package/src/utils/Primitive.tsx +2 -2
- package/src/utils/createActionButton.tsx +1 -1
- package/src/utils/hooks/useOnResizeContent.ts +1 -1
- package/src/utils/hooks/useOnScrollToBottom.ts +1 -1
- package/src/utils/smooth/useSmooth.ts +1 -1
- package/dist/legacy-runtime/runtime/MessagePartRuntime.d.ts +0 -3
- package/dist/legacy-runtime/runtime/MessagePartRuntime.js +0 -2
- package/dist/legacy-runtime/runtime/MessageRuntime.d.ts +0 -3
- package/dist/legacy-runtime/runtime/MessageRuntime.js +0 -2
- package/dist/legacy-runtime/runtime/ThreadListRuntime.d.ts +0 -3
- package/dist/legacy-runtime/runtime/ThreadListRuntime.js +0 -2
- package/dist/utils/invokeCallbackSafely.d.ts +0 -5
- package/dist/utils/invokeCallbackSafely.d.ts.map +0 -1
- package/dist/utils/invokeCallbackSafely.js +0 -15
- package/dist/utils/invokeCallbackSafely.js.map +0 -1
- package/dist/utils/useToolArgsFieldStatus.d.ts +0 -15
- package/dist/utils/useToolArgsFieldStatus.d.ts.map +0 -1
- package/dist/utils/useToolArgsFieldStatus.js +0 -23
- package/dist/utils/useToolArgsFieldStatus.js.map +0 -1
- package/src/legacy-runtime/runtime/MessagePartRuntime.ts +0 -2
- package/src/legacy-runtime/runtime/MessageRuntime.ts +0 -3
- package/src/legacy-runtime/runtime/ThreadListRuntime.ts +0 -4
- package/src/utils/invokeCallbackSafely.ts +0 -11
- package/src/utils/useToolArgsFieldStatus.ts +0 -18
|
@@ -1 +1 @@
|
|
|
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","invalidMcpAppResource","options","Error","url","parseMcpAppResource","value","Array","isArray","uri","html","postToHost","method","params","doFetch","fetch","extraHeaders","headers","stringify","ok","status","statusText","json","cause","useMcpAppsRemoteHost","optionsRef","current","getCurrentOptions","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\nconst invalidMcpAppResource = (options: McpAppsRemoteHostOptions): never => {\n throw new Error(\n `Invalid MCP App host response \"mcp-apps/read-resource\" from \"${options.url}\": expected a resource with non-empty string \"uri\" and \"html\" fields`,\n );\n};\n\nconst parseMcpAppResource = (\n value: unknown,\n options: McpAppsRemoteHostOptions,\n): McpAppResource => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return invalidMcpAppResource(options);\n }\n\n const resource = value as Record<string, unknown>;\n if (\n typeof resource.uri !== \"string\" ||\n resource.uri.trim() === \"\" ||\n typeof resource.html !== \"string\" ||\n resource.html.trim() === \"\"\n ) {\n return invalidMcpAppResource(options);\n }\n\n return value as McpAppResource;\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 try {\n return await res.json();\n } catch (cause) {\n throw new Error(\n `Invalid MCP App host response \"${method}\" from \"${options.url}\": expected valid JSON`,\n { cause },\n );\n }\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 const url = options.url;\n\n
|
|
1
|
+
{"version":3,"file":"McpAppsRemoteHost.js","names":["useEffect","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","invalidMcpAppResource","options","Error","url","parseMcpAppResource","value","Array","isArray","uri","html","postToHost","method","params","doFetch","fetch","extraHeaders","headers","stringify","ok","status","statusText","json","cause","useMcpAppsRemoteHost","optionsRef","current","hostState","pendingOptions","getCurrentOptions","host","loadResource","callTool","readResource","listResources","updatePendingOptions","next","McpAppsRemoteHost"],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"sourcesContent":["import { useEffect, 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\nconst invalidMcpAppResource = (options: McpAppsRemoteHostOptions): never => {\n throw new Error(\n `Invalid MCP App host response \"mcp-apps/read-resource\" from \"${options.url}\": expected a resource with non-empty string \"uri\" and \"html\" fields`,\n );\n};\n\nconst parseMcpAppResource = (\n value: unknown,\n options: McpAppsRemoteHostOptions,\n): McpAppResource => {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return invalidMcpAppResource(options);\n }\n\n const resource = value as Record<string, unknown>;\n if (\n typeof resource.uri !== \"string\" ||\n resource.uri.trim() === \"\" ||\n typeof resource.html !== \"string\" ||\n resource.html.trim() === \"\"\n ) {\n return invalidMcpAppResource(options);\n }\n\n return value as McpAppResource;\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 try {\n return await res.json();\n } catch (cause) {\n throw new Error(\n `Invalid MCP App host response \"${method}\" from \"${options.url}\": expected valid JSON`,\n { cause },\n );\n }\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 useEffect(() => {\n optionsRef.current = options;\n });\n\n const url = options.url;\n\n const hostState = useMemo(() => {\n let pendingOptions = options;\n const getCurrentOptions = () =>\n optionsRef.current.url === url ? optionsRef.current : pendingOptions;\n const host: McpAppsHost = {\n loadResource: async (params) => {\n const options = getCurrentOptions();\n return parseMcpAppResource(\n await postToHost(options, \"mcp-apps/read-resource\", params),\n options,\n );\n },\n callTool: (params) =>\n postToHost(getCurrentOptions(), \"tools/call\", params),\n readResource: (params) =>\n postToHost(getCurrentOptions(), \"resources/read\", params),\n listResources: (params) =>\n postToHost(getCurrentOptions(), \"resources/list\", params),\n };\n return {\n host,\n updatePendingOptions: (next: McpAppsRemoteHostOptions) => {\n pendingOptions = next;\n },\n };\n // oxlint-disable-next-line react/exhaustive-deps -- URL changes replace the host identity; pending and same-URL options are refreshed outside the memo\n }, [url]);\n\n // The pending snapshot is read only while the committed ref still lags this\n // host's URL, and every write to it carries that same render's options, so\n // no render can pair one URL with another's credentials. A committed host can\n // be written here (a child layout effect re-rendering synchronously runs\n // before passive effects publish the ref), which stays coherent for the same\n // reason.\n if (optionsRef.current.url !== url) {\n hostState.updatePendingOptions(options);\n }\n\n return hostState.host;\n};\n\nexport const McpAppsRemoteHost = resource(useMcpAppsRemoteHost);\n"],"mappings":"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"}
|
|
@@ -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":";;iBAgJgB,cACd,KACA,UACA,OACA,QACA,SACA,UACA,UACA,aACA,aACC,mCAAgB,IAAA"}
|
|
@@ -2,20 +2,37 @@
|
|
|
2
2
|
import { createMcpAppBridge } from "./bridge.js";
|
|
3
3
|
import { SandboxHost } from "../sandbox-host/SandboxHost.js";
|
|
4
4
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
5
|
-
import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
|
|
5
|
+
import { useEffect, useLayoutEffect, useRef } from "@assistant-ui/tap/react-shim";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { isRecord } from "@assistant-ui/core/internal";
|
|
7
8
|
//#region src/mcp-apps/app-frame.tsx
|
|
8
9
|
const DEFAULT_PRODUCT = "assistant-ui-mcp-app";
|
|
9
10
|
const INIT_TIMEOUT_MS = 5e3;
|
|
10
11
|
const DEFAULT_MAX_HEIGHT = 800;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const isPlainObject = (value) => {
|
|
13
|
+
if (!isRecord(value)) return false;
|
|
14
|
+
const prototype = Object.getPrototypeOf(value);
|
|
15
|
+
return prototype === null || prototype === Object.prototype;
|
|
16
|
+
};
|
|
17
|
+
const isSameHostContext = (a, b, depth = 0) => {
|
|
18
|
+
if (Object.is(a, b)) return true;
|
|
19
|
+
if (depth > 100) return false;
|
|
20
|
+
if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => isSameHostContext(item, b[index], depth + 1));
|
|
21
|
+
if (!isPlainObject(a) || !isPlainObject(b)) return false;
|
|
22
|
+
const aKeys = Object.keys(a);
|
|
23
|
+
return aKeys.length === Object.keys(b).length && aKeys.every((key) => Object.hasOwn(b, key) && isSameHostContext(a[key], b[key], depth + 1));
|
|
24
|
+
};
|
|
25
|
+
function useBridgeNotify(value, bridgeRef, widgetReadyRef, pendingRef, lastSentRef, notify, t0) {
|
|
26
|
+
const $ = c(10);
|
|
27
|
+
const isEqual = t0 === void 0 ? Object.is : t0;
|
|
28
|
+
let t1;
|
|
29
|
+
if ($[0] !== bridgeRef || $[1] !== isEqual || $[2] !== lastSentRef || $[3] !== notify || $[4] !== pendingRef || $[5] !== value || $[6] !== widgetReadyRef) {
|
|
30
|
+
t1 = () => {
|
|
16
31
|
if (!bridgeRef.current) return;
|
|
17
|
-
if (value === void 0)
|
|
18
|
-
|
|
32
|
+
if (value === void 0 || isEqual(lastSentRef.current, value)) {
|
|
33
|
+
pendingRef.current = void 0;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
19
36
|
if (!widgetReadyRef.current) {
|
|
20
37
|
pendingRef.current = value;
|
|
21
38
|
return;
|
|
@@ -24,20 +41,21 @@ function useBridgeNotify(value, bridgeRef, widgetReadyRef, pendingRef, lastSentR
|
|
|
24
41
|
lastSentRef.current = value;
|
|
25
42
|
};
|
|
26
43
|
$[0] = bridgeRef;
|
|
27
|
-
$[1] =
|
|
28
|
-
$[2] =
|
|
29
|
-
$[3] =
|
|
30
|
-
$[4] =
|
|
31
|
-
$[5] =
|
|
32
|
-
$[6] =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
$[8] =
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
$[1] = isEqual;
|
|
45
|
+
$[2] = lastSentRef;
|
|
46
|
+
$[3] = notify;
|
|
47
|
+
$[4] = pendingRef;
|
|
48
|
+
$[5] = value;
|
|
49
|
+
$[6] = widgetReadyRef;
|
|
50
|
+
$[7] = t1;
|
|
51
|
+
} else t1 = $[7];
|
|
52
|
+
let t2;
|
|
53
|
+
if ($[8] !== value) {
|
|
54
|
+
t2 = [value];
|
|
55
|
+
$[8] = value;
|
|
56
|
+
$[9] = t2;
|
|
57
|
+
} else t2 = $[9];
|
|
58
|
+
useEffect(t1, t2);
|
|
41
59
|
}
|
|
42
60
|
function buildLiveHandlers(initial, liveRef) {
|
|
43
61
|
const live = () => liveRef.current.handlers;
|
|
@@ -67,7 +85,10 @@ function buildLiveHandlers(initial, liveRef) {
|
|
|
67
85
|
out.onError = (e) => live()?.onError?.(e);
|
|
68
86
|
return out;
|
|
69
87
|
}
|
|
70
|
-
function McpAppFrame(
|
|
88
|
+
function McpAppFrame(t0) {
|
|
89
|
+
const $ = c(29);
|
|
90
|
+
const { app, resource, input, output, sandbox, handlers, hostInfo, hostContext, maxHeight: t1 } = t0;
|
|
91
|
+
const maxHeight = t1 === void 0 ? DEFAULT_MAX_HEIGHT : t1;
|
|
71
92
|
const bridgeRef = useRef(null);
|
|
72
93
|
const lastSentInputRef = useRef(void 0);
|
|
73
94
|
const lastSentOutputRef = useRef(void 0);
|
|
@@ -76,105 +97,198 @@ function McpAppFrame({ app, resource, input, output, sandbox, handlers, hostInfo
|
|
|
76
97
|
const pendingInputRef = useRef(void 0);
|
|
77
98
|
const pendingOutputRef = useRef(void 0);
|
|
78
99
|
const pendingHostContextRef = useRef(void 0);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
lastSentHostContextRef.current = pendingHostContextRef.current;
|
|
108
|
-
pendingHostContextRef.current = void 0;
|
|
109
|
-
}
|
|
100
|
+
let t2;
|
|
101
|
+
if ($[0] !== handlers || $[1] !== hostContext || $[2] !== hostInfo || $[3] !== input || $[4] !== output) {
|
|
102
|
+
t2 = {
|
|
103
|
+
handlers,
|
|
104
|
+
hostInfo,
|
|
105
|
+
hostContext,
|
|
106
|
+
input,
|
|
107
|
+
output
|
|
108
|
+
};
|
|
109
|
+
$[0] = handlers;
|
|
110
|
+
$[1] = hostContext;
|
|
111
|
+
$[2] = hostInfo;
|
|
112
|
+
$[3] = input;
|
|
113
|
+
$[4] = output;
|
|
114
|
+
$[5] = t2;
|
|
115
|
+
} else t2 = $[5];
|
|
116
|
+
const liveRef = useRef(t2);
|
|
117
|
+
let t3;
|
|
118
|
+
let t4;
|
|
119
|
+
if ($[6] !== handlers || $[7] !== hostContext || $[8] !== hostInfo || $[9] !== input || $[10] !== output) {
|
|
120
|
+
t3 = () => {
|
|
121
|
+
liveRef.current = {
|
|
122
|
+
handlers,
|
|
123
|
+
hostInfo,
|
|
124
|
+
hostContext,
|
|
125
|
+
input,
|
|
126
|
+
output
|
|
127
|
+
};
|
|
110
128
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
129
|
+
t4 = [
|
|
130
|
+
handlers,
|
|
131
|
+
hostInfo,
|
|
132
|
+
hostContext,
|
|
133
|
+
input,
|
|
134
|
+
output
|
|
135
|
+
];
|
|
136
|
+
$[6] = handlers;
|
|
137
|
+
$[7] = hostContext;
|
|
138
|
+
$[8] = hostInfo;
|
|
139
|
+
$[9] = input;
|
|
140
|
+
$[10] = output;
|
|
141
|
+
$[11] = t3;
|
|
142
|
+
$[12] = t4;
|
|
143
|
+
} else {
|
|
144
|
+
t3 = $[11];
|
|
145
|
+
t4 = $[12];
|
|
146
|
+
}
|
|
147
|
+
useLayoutEffect(t3, t4);
|
|
148
|
+
let t5;
|
|
149
|
+
if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
|
|
150
|
+
t5 = (frame, host) => {
|
|
151
|
+
const current = liveRef.current;
|
|
152
|
+
let initTimeoutId = null;
|
|
153
|
+
const flushPending = () => {
|
|
154
|
+
if (widgetReadyRef.current) return;
|
|
155
|
+
widgetReadyRef.current = true;
|
|
156
|
+
const b = bridgeRef.current;
|
|
157
|
+
if (!b) return;
|
|
158
|
+
if (pendingInputRef.current !== void 0) {
|
|
159
|
+
b.notifyToolInput(pendingInputRef.current);
|
|
160
|
+
lastSentInputRef.current = pendingInputRef.current;
|
|
161
|
+
pendingInputRef.current = void 0;
|
|
162
|
+
}
|
|
163
|
+
if (pendingOutputRef.current !== void 0) {
|
|
164
|
+
b.notifyToolResult(pendingOutputRef.current);
|
|
165
|
+
lastSentOutputRef.current = pendingOutputRef.current;
|
|
166
|
+
pendingOutputRef.current = void 0;
|
|
167
|
+
}
|
|
168
|
+
if (pendingHostContextRef.current !== void 0) {
|
|
169
|
+
b.notifyHostContextChanged(pendingHostContextRef.current);
|
|
170
|
+
lastSentHostContextRef.current = pendingHostContextRef.current;
|
|
171
|
+
pendingHostContextRef.current = void 0;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const liveHandlers = buildLiveHandlers(current.handlers, liveRef);
|
|
175
|
+
const liveOnInitialized = liveHandlers.onInitialized;
|
|
176
|
+
const wrappedHandlers = {
|
|
177
|
+
...liveHandlers,
|
|
178
|
+
onInitialized: () => {
|
|
179
|
+
if (initTimeoutId !== null) {
|
|
180
|
+
clearTimeout(initTimeoutId);
|
|
181
|
+
initTimeoutId = null;
|
|
182
|
+
}
|
|
183
|
+
flushPending();
|
|
184
|
+
liveOnInitialized?.();
|
|
185
|
+
},
|
|
186
|
+
onSizeChange: (p) => {
|
|
187
|
+
if (p.height != null) host.setHeight(p.height);
|
|
188
|
+
liveHandlers.onSizeChange?.(p);
|
|
119
189
|
}
|
|
190
|
+
};
|
|
191
|
+
initTimeoutId = setTimeout(() => {
|
|
192
|
+
initTimeoutId = null;
|
|
120
193
|
flushPending();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
194
|
+
}, INIT_TIMEOUT_MS);
|
|
195
|
+
const bridge = createMcpAppBridge({
|
|
196
|
+
frame,
|
|
197
|
+
handlers: wrappedHandlers,
|
|
198
|
+
hostInfo: current.hostInfo,
|
|
199
|
+
hostContext: current.hostContext
|
|
200
|
+
});
|
|
201
|
+
bridgeRef.current = bridge;
|
|
202
|
+
if (current.input !== void 0) pendingInputRef.current = current.input;
|
|
203
|
+
if (current.output !== void 0) pendingOutputRef.current = current.output;
|
|
204
|
+
lastSentHostContextRef.current = current.hostContext ?? {};
|
|
205
|
+
return {
|
|
206
|
+
onMessage: bridge.onMessage,
|
|
207
|
+
dispose: () => {
|
|
208
|
+
if (initTimeoutId !== null) {
|
|
209
|
+
clearTimeout(initTimeoutId);
|
|
210
|
+
initTimeoutId = null;
|
|
211
|
+
}
|
|
212
|
+
bridge.dispose();
|
|
213
|
+
bridgeRef.current = null;
|
|
214
|
+
lastSentInputRef.current = void 0;
|
|
215
|
+
lastSentOutputRef.current = void 0;
|
|
216
|
+
lastSentHostContextRef.current = void 0;
|
|
217
|
+
widgetReadyRef.current = false;
|
|
218
|
+
pendingInputRef.current = void 0;
|
|
219
|
+
pendingOutputRef.current = void 0;
|
|
220
|
+
pendingHostContextRef.current = void 0;
|
|
147
221
|
}
|
|
148
|
-
|
|
149
|
-
bridgeRef.current = null;
|
|
150
|
-
lastSentInputRef.current = void 0;
|
|
151
|
-
lastSentOutputRef.current = void 0;
|
|
152
|
-
lastSentHostContextRef.current = void 0;
|
|
153
|
-
widgetReadyRef.current = false;
|
|
154
|
-
pendingInputRef.current = void 0;
|
|
155
|
-
pendingOutputRef.current = void 0;
|
|
156
|
-
pendingHostContextRef.current = void 0;
|
|
157
|
-
}
|
|
222
|
+
};
|
|
158
223
|
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
useBridgeNotify(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
224
|
+
$[13] = t5;
|
|
225
|
+
} else t5 = $[13];
|
|
226
|
+
const createBridge = t5;
|
|
227
|
+
useBridgeNotify(input, bridgeRef, widgetReadyRef, pendingInputRef, lastSentInputRef, _temp);
|
|
228
|
+
useBridgeNotify(output, bridgeRef, widgetReadyRef, pendingOutputRef, lastSentOutputRef, _temp2);
|
|
229
|
+
useBridgeNotify(hostContext, bridgeRef, widgetReadyRef, pendingHostContextRef, lastSentHostContextRef, _temp3, isSameHostContext);
|
|
230
|
+
let t6;
|
|
231
|
+
if ($[14] !== resource.html) {
|
|
232
|
+
t6 = { html: resource.html };
|
|
233
|
+
$[14] = resource.html;
|
|
234
|
+
$[15] = t6;
|
|
235
|
+
} else t6 = $[15];
|
|
236
|
+
const t7 = app.serverId ? `${app.serverId} ${resource.uri}` : resource.uri;
|
|
237
|
+
const t8 = sandbox?.product ?? DEFAULT_PRODUCT;
|
|
238
|
+
let t9;
|
|
239
|
+
if ($[16] !== sandbox || $[17] !== t8) {
|
|
240
|
+
t9 = {
|
|
167
241
|
...sandbox,
|
|
168
|
-
product:
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
242
|
+
product: t8
|
|
243
|
+
};
|
|
244
|
+
$[16] = sandbox;
|
|
245
|
+
$[17] = t8;
|
|
246
|
+
$[18] = t9;
|
|
247
|
+
} else t9 = $[18];
|
|
248
|
+
let t10;
|
|
249
|
+
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
|
250
|
+
t10 = (err) => liveRef.current.handlers?.onError?.(err);
|
|
251
|
+
$[19] = t10;
|
|
252
|
+
} else t10 = $[19];
|
|
253
|
+
const t11 = resource.meta?.prefersBorder ? "" : void 0;
|
|
254
|
+
let t12;
|
|
255
|
+
if ($[20] !== app.resourceUri || $[21] !== t11) {
|
|
256
|
+
t12 = {
|
|
174
257
|
"data-mcp-app-resource": app.resourceUri,
|
|
175
|
-
"data-mcp-app-prefers-border":
|
|
176
|
-
}
|
|
177
|
-
|
|
258
|
+
"data-mcp-app-prefers-border": t11
|
|
259
|
+
};
|
|
260
|
+
$[20] = app.resourceUri;
|
|
261
|
+
$[21] = t11;
|
|
262
|
+
$[22] = t12;
|
|
263
|
+
} else t12 = $[22];
|
|
264
|
+
let t13;
|
|
265
|
+
if ($[23] !== maxHeight || $[24] !== t12 || $[25] !== t6 || $[26] !== t7 || $[27] !== t9) {
|
|
266
|
+
t13 = /* @__PURE__ */ jsx(SandboxHost, {
|
|
267
|
+
content: t6,
|
|
268
|
+
contentKey: t7,
|
|
269
|
+
sandbox: t9,
|
|
270
|
+
maxHeight,
|
|
271
|
+
createBridge,
|
|
272
|
+
onError: t10,
|
|
273
|
+
containerProps: t12
|
|
274
|
+
});
|
|
275
|
+
$[23] = maxHeight;
|
|
276
|
+
$[24] = t12;
|
|
277
|
+
$[25] = t6;
|
|
278
|
+
$[26] = t7;
|
|
279
|
+
$[27] = t9;
|
|
280
|
+
$[28] = t13;
|
|
281
|
+
} else t13 = $[28];
|
|
282
|
+
return t13;
|
|
283
|
+
}
|
|
284
|
+
function _temp3(b_2, v_1) {
|
|
285
|
+
return b_2.notifyHostContextChanged(v_1);
|
|
286
|
+
}
|
|
287
|
+
function _temp2(b_1, v_0) {
|
|
288
|
+
return b_1.notifyToolResult(v_0);
|
|
289
|
+
}
|
|
290
|
+
function _temp(b_0, v) {
|
|
291
|
+
return b_0.notifyToolInput(v);
|
|
178
292
|
}
|
|
179
293
|
//#endregion
|
|
180
294
|
export { McpAppFrame };
|
|
@@ -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","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
|
+
{"version":3,"file":"app-frame.js","names":["c","_c","MutableRefObject","useEffect","useLayoutEffect","useRef","McpAppBridge","createMcpAppBridge","SandboxHost","SandboxBridge","SandboxHostApi","SandboxHostFrame","McpAppBridgeHandlers","McpAppFrameProps","McpAppHostContext","isRecord","DEFAULT_PRODUCT","INIT_TIMEOUT_MS","DEFAULT_MAX_HEIGHT","isPlainObject","value","Record","prototype","Object","getPrototypeOf","isSameHostContext","a","b","depth","is","Array","isArray","length","every","item","index","aKeys","keys","key","hasOwn","useBridgeNotify","bridgeRef","widgetReadyRef","pendingRef","lastSentRef","notify","t0","$","isEqual","undefined","t1","current","t2","LiveSnapshot","handlers","hostInfo","hostContext","input","output","buildLiveHandlers","initial","liveRef","live","has","K","out","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","t3","t4","t5","Symbol","for","frame","host","initTimeoutId","flushPending","notifyToolInput","notifyToolResult","notifyHostContextChanged","liveHandlers","liveOnInitialized","wrappedHandlers","clearTimeout","height","setHeight","setTimeout","bridge","onMessage","dispose","createBridge","_temp","_temp2","_temp3","t6","html","t7","serverId","uri","t8","product","t9","t10","err","t11","meta","prefersBorder","t12","resourceUri","t13","b_2","v_1","v","b_1","v_0","b_0"],"sources":["../../src/mcp-apps/app-frame.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type MutableRefObject,\n useEffect,\n useLayoutEffect,\n useRef,\n} 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\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-mcp-app\";\nconst INIT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_HEIGHT = 800;\n\n// Only a plain object can be compared by its own keys. Structured clone carries\n// a Date, Map, or class instance to the widget intact, and those expose no\n// enumerable keys, so walking them would report two different values as equal.\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n};\n\n// Hosts commonly rebuild an equal context object on every render, and the\n// widget cannot tell a repeated notification apart from a real change. The\n// open index signature on McpAppHostContext admits values JSON rejects (an\n// undefined property value is enough), so leaves the walk cannot compare fall\n// back to identity rather than failing the whole comparison.\nconst isSameHostContext = (a: unknown, b: unknown, depth = 0): boolean => {\n if (Object.is(a, b)) return true;\n if (depth > 100) return false;\n if (Array.isArray(a) || Array.isArray(b)) {\n return (\n Array.isArray(a) &&\n Array.isArray(b) &&\n a.length === b.length &&\n a.every((item, index) => isSameHostContext(item, b[index], depth + 1))\n );\n }\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const aKeys = Object.keys(a);\n return (\n aKeys.length === Object.keys(b).length &&\n aKeys.every(\n (key) =>\n Object.hasOwn(b, key) && isSameHostContext(a[key], b[key], depth + 1),\n )\n );\n};\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 isEqual: (sent: T | undefined, next: T) => boolean = Object.is,\n) {\n useEffect(() => {\n if (!bridgeRef.current) return;\n // Nothing to deliver, either because there is no value or because the\n // widget already holds it; a queued value here is superseded and would\n // otherwise flush after initialization as a stale update.\n if (value === undefined || isEqual(lastSentRef.current, value)) {\n pendingRef.current = undefined;\n return;\n }\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 and isEqual are 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>({\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n });\n useLayoutEffect(() => {\n liveRef.current = {\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n };\n }, [handlers, hostInfo, hostContext, input, output]);\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, where the\n // bridge defaults it to {}; recording that same normalized value keeps the\n // first later change from repeating what the widget already holds.\n lastSentHostContextRef.current = current.hostContext ?? {};\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 isSameHostContext,\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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"}
|
package/dist/mcp-apps/bridge.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { invokeCallbackSafely } from "../utils/invokeCallbackSafely.js";
|
|
2
1
|
import "./types.js";
|
|
3
|
-
import { isRecord } from "@assistant-ui/core/internal";
|
|
2
|
+
import { invokeUserCallback, isRecord } from "@assistant-ui/core/internal";
|
|
4
3
|
//#region src/mcp-apps/bridge.ts
|
|
5
4
|
const VALID_DISPLAY_MODES = [
|
|
6
5
|
"inline",
|
|
@@ -60,7 +59,7 @@ function createMcpAppBridge(opts) {
|
|
|
60
59
|
} });
|
|
61
60
|
};
|
|
62
61
|
const reportError = (error) => {
|
|
63
|
-
|
|
62
|
+
invokeUserCallback("assistant-ui", "MCP App onError", handlers.onError?.bind(handlers), error);
|
|
64
63
|
};
|
|
65
64
|
const handleRequest = async (req) => {
|
|
66
65
|
try {
|