@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
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/unstable/webmcp/webmcp-host.d.ts
|
|
2
|
+
type WebMcpContent = {
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: "image";
|
|
7
|
+
data: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
};
|
|
10
|
+
type WebMcpCallToolResult = {
|
|
11
|
+
content: WebMcpContent[];
|
|
12
|
+
isError?: boolean;
|
|
13
|
+
};
|
|
14
|
+
type WebMcpToolDescriptor = {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
inputSchema: unknown;
|
|
18
|
+
execute: (args: unknown, context?: {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
}) => Promise<WebMcpCallToolResult>;
|
|
21
|
+
};
|
|
22
|
+
type WebMcpModelContext = {
|
|
23
|
+
/**
|
|
24
|
+
* Aborting `options.signal` is what unregisters the tool. The explainer
|
|
25
|
+
* defines no other removal method, and a name-keyed one could not be used
|
|
26
|
+
* safely: a later registration may already hold the name.
|
|
27
|
+
*/
|
|
28
|
+
registerTool(tool: WebMcpToolDescriptor, options?: {
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
}): Promise<void> | void;
|
|
31
|
+
};
|
|
32
|
+
type WebMcpHost = {
|
|
33
|
+
available: boolean;
|
|
34
|
+
registerTool(def: WebMcpToolDescriptor, onError?: (error: unknown) => void): () => void;
|
|
35
|
+
};
|
|
36
|
+
declare const getDefaultWebMcpHost: () => WebMcpHost;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { WebMcpCallToolResult, WebMcpContent, WebMcpHost, WebMcpModelContext, WebMcpToolDescriptor, getDefaultWebMcpHost };
|
|
39
|
+
//# sourceMappingURL=webmcp-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webmcp-host.d.ts","names":[],"sources":["../../../src/unstable/webmcp/webmcp-host.ts"],"mappings":";KAAY;EACN;EAAc;;EACd;EAAe;EAAc;;KAEvB;EACV,SAAS;EACT;;KAGU;EACV;EACA;EACA;EACA,UACE,eACA;IAAY,SAAS;QAClB,QAAQ;;KAGH;;;;;;EAMV,aACE,MAAM,sBACN;IAAY,SAAS;MACpB;;KAGO;EACV;EACA,aACE,KAAK,sBACL,WAAW;;cAsCF,4BAA2B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/unstable/webmcp/webmcp-host.ts
|
|
2
|
+
const isThenable = (value) => typeof value?.then === "function";
|
|
3
|
+
const resolveModelContext = () => {
|
|
4
|
+
const context = globalThis.document?.modelContext ?? globalThis.navigator?.modelContext;
|
|
5
|
+
if (!context) return void 0;
|
|
6
|
+
if (typeof context.registerTool === "function") return context;
|
|
7
|
+
console.warn("[assistant-ui] Ignoring a modelContext with no callable registerTool; WebMCP reports unsupported.");
|
|
8
|
+
};
|
|
9
|
+
const createHost = (context) => ({
|
|
10
|
+
available: true,
|
|
11
|
+
registerTool: (def, onError) => {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const handle = context.registerTool(def, { signal: controller.signal });
|
|
14
|
+
if (isThenable(handle)) handle.then(() => {}, (error) => onError?.(error));
|
|
15
|
+
return () => controller.abort();
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const getDefaultWebMcpHost = () => {
|
|
19
|
+
const context = resolveModelContext();
|
|
20
|
+
if (!context) return {
|
|
21
|
+
available: false,
|
|
22
|
+
registerTool: () => () => {}
|
|
23
|
+
};
|
|
24
|
+
return createHost(context);
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { getDefaultWebMcpHost };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=webmcp-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webmcp-host.js","names":["WebMcpContent","type","text","data","mimeType","WebMcpCallToolResult","content","isError","WebMcpToolDescriptor","name","description","inputSchema","execute","args","context","signal","AbortSignal","Promise","WebMcpModelContext","registerTool","tool","options","WebMcpHost","available","def","onError","error","ModelContextHost","modelContext","isThenable","value","then","resolveModelContext","globalThis","document","navigator","undefined","console","warn","createHost","controller","AbortController","handle","abort","getDefaultWebMcpHost"],"sources":["../../../src/unstable/webmcp/webmcp-host.ts"],"sourcesContent":["export type WebMcpContent =\n | { type: \"text\"; text: string }\n | { type: \"image\"; data: string; mimeType: string };\n\nexport type WebMcpCallToolResult = {\n content: WebMcpContent[];\n isError?: boolean;\n};\n\nexport type WebMcpToolDescriptor = {\n name: string;\n description: string;\n inputSchema: unknown;\n execute: (\n args: unknown,\n context?: { signal?: AbortSignal },\n ) => Promise<WebMcpCallToolResult>;\n};\n\nexport type WebMcpModelContext = {\n /**\n * Aborting `options.signal` is what unregisters the tool. The explainer\n * defines no other removal method, and a name-keyed one could not be used\n * safely: a later registration may already hold the name.\n */\n registerTool(\n tool: WebMcpToolDescriptor,\n options?: { signal?: AbortSignal },\n ): Promise<void> | void;\n};\n\nexport type WebMcpHost = {\n available: boolean;\n registerTool(\n def: WebMcpToolDescriptor,\n onError?: (error: unknown) => void,\n ): () => void;\n};\n\ntype ModelContextHost = { modelContext?: WebMcpModelContext } | undefined;\n\nconst isThenable = (value: unknown): value is Promise<unknown> =>\n typeof (value as { then?: unknown } | null | undefined)?.then === \"function\";\n\n// The explainer puts modelContext on document; navigator is tolerated for\n// older drafts and extensions that still inject it there.\nconst resolveModelContext = (): WebMcpModelContext | undefined => {\n const context =\n (globalThis.document as ModelContextHost)?.modelContext ??\n (globalThis.navigator as ModelContextHost)?.modelContext;\n if (!context) return undefined;\n if (typeof context.registerTool === \"function\") return context;\n console.warn(\n \"[assistant-ui] Ignoring a modelContext with no callable registerTool; WebMCP reports unsupported.\",\n );\n return undefined;\n};\n\nconst createHost = (context: WebMcpModelContext): WebMcpHost => ({\n available: true,\n registerTool: (def, onError) => {\n const controller = new AbortController();\n const handle = context.registerTool(def, { signal: controller.signal });\n if (isThenable(handle)) {\n handle.then(\n () => {},\n (error) => onError?.(error),\n );\n }\n return () => controller.abort();\n },\n});\n\nexport const getDefaultWebMcpHost = (): WebMcpHost => {\n const context = resolveModelContext();\n if (!context) {\n return {\n available: false,\n registerTool: () => () => {},\n };\n }\n return createHost(context);\n};\n"],"mappings":";AAyCA,MAAM6B,cAAcC,UAClB,OAAQA,OAAiDC,SAAS;AAIpE,MAAMC,4BAA4D;CAChE,MAAMlB,UACHmB,WAAWC,UAA+BN,gBAC1CK,WAAWE,WAAgCP;CAC9C,IAAI,CAACd,SAAS,OAAOsB,KAAAA;CACrB,IAAI,OAAOtB,QAAQK,iBAAiB,YAAY,OAAOL;CACvDuB,QAAQC,KACN,mGACF;AAEF;AAEA,MAAMC,cAAczB,aAA6C;CAC/DS,WAAW;CACXJ,eAAeK,KAAKC,YAAY;EAC9B,MAAMe,aAAa,IAAIC,gBAAgB;EACvC,MAAMC,SAAS5B,QAAQK,aAAaK,KAAK,EAAET,QAAQyB,WAAWzB,OAAO,CAAC;EACtE,IAAIc,WAAWa,MAAM,GACnBA,OAAOX,WACC,CAAC,IACNL,UAAUD,UAAUC,KAAK,CAC5B;EAEF,aAAac,WAAWG,MAAM;CAChC;AACF;AAEA,MAAaC,6BAAyC;CACpD,MAAM9B,UAAUkB,oBAAoB;CACpC,IAAI,CAAClB,SACH,OAAO;EACLS,WAAW;EACXJ,0BAA0B,CAAC;CAC7B;CAEF,OAAOoB,WAAWzB,OAAO;AAC3B"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ComponentRef, ElementType, ForwardRefExoticComponent, ReactElement, RefAttributes } from "react";
|
|
2
|
-
import { Primitive as Primitive$1 } from "
|
|
2
|
+
import { Primitive as Primitive$1 } from "radix-ui/internal";
|
|
3
3
|
//#region src/utils/Primitive.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Thin wrapper around
|
|
5
|
+
* Thin wrapper around Radix `Primitive` that adds `render` prop support.
|
|
6
6
|
*
|
|
7
7
|
* When `render` is provided, it is converted to the equivalent `asChild` pattern:
|
|
8
8
|
* render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>
|
|
@@ -93,16 +93,16 @@ declare const Primitive: {
|
|
|
93
93
|
}, "ref"> & {
|
|
94
94
|
render?: ReactElement | undefined;
|
|
95
95
|
} & RefAttributes<HTMLSpanElement>>;
|
|
96
|
-
|
|
96
|
+
ul: ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLUListElement> & import("react").HTMLAttributes<HTMLUListElement> & {
|
|
97
97
|
asChild?: boolean;
|
|
98
98
|
}, "ref"> & {
|
|
99
99
|
render?: ReactElement | undefined;
|
|
100
|
-
} & RefAttributes<
|
|
101
|
-
|
|
100
|
+
} & RefAttributes<HTMLUListElement>>;
|
|
101
|
+
svg: ForwardRefExoticComponent<Omit<import("react").SVGProps<SVGSVGElement> & {
|
|
102
102
|
asChild?: boolean;
|
|
103
103
|
}, "ref"> & {
|
|
104
104
|
render?: ReactElement | undefined;
|
|
105
|
-
} & RefAttributes<
|
|
105
|
+
} & RefAttributes<SVGSVGElement>>;
|
|
106
106
|
};
|
|
107
107
|
//#endregion
|
|
108
108
|
export { Primitive, type PrimitiveProps, type WithRenderPropProps, withRenderProp };
|
package/dist/utils/Primitive.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
2
2
|
import { cloneElement, forwardRef, isValidElement } from "@assistant-ui/tap/react-shim";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
import { Primitive as Primitive$1 } from "
|
|
4
|
+
import { Primitive as Primitive$1 } from "radix-ui/internal";
|
|
5
5
|
//#region src/utils/Primitive.tsx
|
|
6
6
|
/**
|
|
7
|
-
* Thin wrapper around
|
|
7
|
+
* Thin wrapper around Radix `Primitive` that adds `render` prop support.
|
|
8
8
|
*
|
|
9
9
|
* When `render` is provided, it is converted to the equivalent `asChild` pattern:
|
|
10
10
|
* render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Primitive.js","names":["ComponentPropsWithoutRef","ComponentRef","ElementType","ForwardRefExoticComponent","PropsWithoutRef","ReactElement","ReactNode","RefAttributes","cloneElement","forwardRef","isValidElement","Primitive","RadixPrimitive","NODES","const","PrimitiveNode","WithRenderPropProps","T","render","PrimitiveProps","E","WithRenderPropRuntimeProps","asChild","children","PrimitiveRef","withRenderProp","Component","Wrapped","t0","ref","$","_c","rest","Comp","renderChildren","undefined","props","Record","t1","t2","t3","componentName","displayName","name","createPrimitive","node","RadixComp","reduce","acc","ReturnType","K"],"sources":["../../src/utils/Primitive.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ElementType,\n type ForwardRefExoticComponent,\n type PropsWithoutRef,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n} from \"react\";\nimport { Primitive as RadixPrimitive } from \"
|
|
1
|
+
{"version":3,"file":"Primitive.js","names":["ComponentPropsWithoutRef","ComponentRef","ElementType","ForwardRefExoticComponent","PropsWithoutRef","ReactElement","ReactNode","RefAttributes","cloneElement","forwardRef","isValidElement","Primitive","RadixPrimitive","NODES","const","PrimitiveNode","WithRenderPropProps","T","render","PrimitiveProps","E","WithRenderPropRuntimeProps","asChild","children","PrimitiveRef","withRenderProp","Component","Wrapped","t0","ref","$","_c","rest","Comp","renderChildren","undefined","props","Record","t1","t2","t3","componentName","displayName","name","createPrimitive","node","RadixComp","reduce","acc","ReturnType","K"],"sources":["../../src/utils/Primitive.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ElementType,\n type ForwardRefExoticComponent,\n type PropsWithoutRef,\n type ReactElement,\n type ReactNode,\n type RefAttributes,\n cloneElement,\n forwardRef,\n isValidElement,\n} from \"react\";\nimport { Primitive as RadixPrimitive } from \"radix-ui/internal\";\n\n/**\n * Thin wrapper around Radix `Primitive` that adds `render` prop support.\n *\n * When `render` is provided, it is converted to the equivalent `asChild` pattern:\n * render={<Comp props />} + children → asChild + <Comp props>{children}</Comp>\n *\n * All prop merging, ref composition, and event handler chaining remain handled\n * by Radix's battle-tested Slot implementation — we add zero custom logic for that.\n */\n\n// Match @radix-ui/react-primitive's full element set\nconst NODES = [\n \"a\",\n \"button\",\n \"div\",\n \"form\",\n \"h2\",\n \"h3\",\n \"img\",\n \"input\",\n \"label\",\n \"li\",\n \"nav\",\n \"ol\",\n \"p\",\n \"select\",\n \"span\",\n \"svg\",\n \"ul\",\n] as const;\ntype PrimitiveNode = (typeof NODES)[number];\n\ntype WithRenderPropProps<T extends ElementType> =\n ComponentPropsWithoutRef<T> & {\n render?: ReactElement | undefined;\n };\n\ntype PrimitiveProps<E extends PrimitiveNode> = WithRenderPropProps<\n (typeof RadixPrimitive)[E]\n>;\n\ntype WithRenderPropRuntimeProps<T extends ElementType> =\n WithRenderPropProps<T> & {\n asChild?: boolean | undefined;\n children?: ReactNode | undefined;\n };\n\ntype PrimitiveRef<E extends PrimitiveNode> = ComponentRef<\n (typeof RadixPrimitive)[E]\n>;\n\nfunction withRenderProp<T extends ElementType>(Component: T) {\n const Wrapped = forwardRef<ComponentRef<T>, WithRenderPropRuntimeProps<T>>(\n (\n {\n render,\n asChild,\n children,\n ...rest\n }: PropsWithoutRef<WithRenderPropRuntimeProps<T>>,\n ref,\n ) => {\n const Comp = Component as any;\n\n if (render && isValidElement(render)) {\n const renderChildren =\n children !== undefined\n ? children\n : ((render.props as Record<string, unknown>).children as ReactNode);\n\n return (\n <Comp {...(rest as any)} asChild ref={ref}>\n {cloneElement(render, undefined, renderChildren)}\n </Comp>\n );\n }\n\n return (\n <Comp {...(rest as any)} asChild={asChild} ref={ref}>\n {children}\n </Comp>\n );\n },\n );\n\n const componentName =\n typeof Component === \"string\"\n ? Component\n : (Component.displayName ?? Component.name ?? \"Component\");\n Wrapped.displayName = componentName;\n\n return Wrapped as ForwardRefExoticComponent<\n WithRenderPropProps<T> & RefAttributes<ComponentRef<T>>\n >;\n}\n\nfunction createPrimitive<E extends PrimitiveNode>(node: E) {\n const RadixComp = RadixPrimitive[node];\n const Component = withRenderProp(RadixComp);\n\n Component.displayName = `Primitive.${node}`;\n return Component as ForwardRefExoticComponent<\n PrimitiveProps<E> & RefAttributes<PrimitiveRef<E>>\n >;\n}\n\nconst Primitive = NODES.reduce(\n (acc, node) => {\n acc[node] = createPrimitive(node);\n return acc;\n },\n {} as {\n [K in PrimitiveNode]: ReturnType<typeof createPrimitive<K>>;\n },\n);\n\nexport { Primitive, withRenderProp };\nexport type { PrimitiveProps, WithRenderPropProps };\n"],"mappings":";;;;;;;;;;;;;;AA0BA,MAAMa,QAAQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAAI;AAuBN,SAASY,eAAsCC,WAAc;CAC3D,MAAMC,UAAUlB,YACdmB,IAAAC,QAAA;EAAA,MAAAC,IAAAC,EAAA,EAAA;EAAA,IAAAT;EAAA,IAAAC;EAAA,IAAAL;EAAA,IAAAc;EAAA,IAAAF,EAAA,OAAAF,IAAA;GACE,CAAA,CAAAV,QAAAI,SAAAC,UAAA,GAAAS,QAAAJ;GAKiDE,EAAA,KAAAF;GAAAE,EAAA,KAAAR;GAAAQ,EAAA,KAAAP;GAAAO,EAAA,KAAAZ;GAAAY,EAAA,KAAAE;EAAA,OAAA;GAAAV,UAAAQ,EAAA;GAAAP,WAAAO,EAAA;GAAAZ,SAAAY,EAAA;GAAAE,OAAAF,EAAA;EAAA;EAGjD,MAAAG,OAAaP;EAEb,IAAIR,UAAUR,eAAeQ,MAAM,GAAC;GAClC,MAAAgB,iBACEX,aAAaY,KAAAA,IAAbZ,WAEML,OAAMkB,MAAiCb;GAGlC,MAAAe,KAAAN;GAAW,IAAAO;GAAA,IAAAT,EAAA,OAAAZ,UAAAY,EAAA,OAAAI,gBAAA;IACnBK,KAAA/B,aAAaU,QAAQiB,KAAAA,GAAWD,cAAc;IAACJ,EAAA,KAAAZ;IAAAY,EAAA,KAAAI;IAAAJ,EAAA,KAAAS;GAAA,OAAAA,KAAAT,EAAA;GAAA,IAAAU;GAAA,IAAAV,EAAA,OAAAD,OAAAC,EAAA,OAAAQ,MAAAR,EAAA,QAAAS,IAAA;IADlDC,KAAA,oBAAC,MAAD;KAAK,GAAMF;KAAc,SAAA;KAAaT;KACnCU,UAAAA;IADE,CAAA;IAEET,EAAA,KAAAD;IAAAC,EAAA,KAAAQ;IAAAR,EAAA,MAAAS;IAAAT,EAAA,MAAAU;GAAA,OAAAA,KAAAV,EAAA;GAAA,OAFPU;EAEO;EAKE,MAAAF,KAAAN;EAAW,IAAAO;EAAA,IAAAT,EAAA,QAAAR,WAAAQ,EAAA,QAAAP,YAAAO,EAAA,QAAAD,OAAAC,EAAA,QAAAQ,IAAA;GAAtBC,KAAA,oBAAC,MAAD;IAAK,GAAMD;IAAuBhB;IAAcO;IAC7CN;GADE,CAAA;GAEEO,EAAA,MAAAR;GAAAQ,EAAA,MAAAP;GAAAO,EAAA,MAAAD;GAAAC,EAAA,MAAAQ;GAAAR,EAAA,MAAAS;EAAA,OAAAA,KAAAT,EAAA;EAAA,OAFPS;CAEO,CAGb;CAMAZ,QAAQe,cAHN,OAAOhB,cAAc,WACjBA,YACCA,UAAUgB,eAAehB,UAAUiB,QAAQ;CAGlD,OAAOhB;AAGT;AAEA,SAASiB,gBAAyCC,MAAS;CACzD,MAAMC,YAAYlC,YAAeiC;CACjC,MAAMnB,YAAYD,eAAeqB,SAAS;CAE1CpB,UAAUgB,cAAc,aAAaG;CACrC,OAAOnB;AAGT;AAEA,MAAMf,YAAYE,MAAMkC,QACrBC,KAAKH,SAAS;CACbG,IAAIH,QAAQD,gBAAgBC,IAAI;CAChC,OAAOG;AACT,GACA,CAAC,CAGH"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Primitive } from "./Primitive.js";
|
|
1
|
+
import { Primitive as Primitive$1 } from "./Primitive.js";
|
|
2
2
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
3
3
|
import { forwardRef } from "@assistant-ui/tap/react-shim";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { composeEventHandlers } from "
|
|
5
|
+
import { composeEventHandlers } from "radix-ui/internal";
|
|
6
6
|
//#region src/utils/createActionButton.tsx
|
|
7
7
|
const createActionButton = (displayName, useActionButton, forwardProps = []) => {
|
|
8
8
|
const ActionButton = forwardRef((props, forwardedRef) => {
|
|
@@ -14,7 +14,7 @@ const createActionButton = (displayName, useActionButton, forwardProps = []) =>
|
|
|
14
14
|
else primitiveProps[key] = props[key];
|
|
15
15
|
});
|
|
16
16
|
const callback = useActionButton(forwardedProps) ?? void 0;
|
|
17
|
-
const t0 = Primitive;
|
|
17
|
+
const t0 = Primitive$1;
|
|
18
18
|
const t1 = "button";
|
|
19
19
|
const t2 = primitiveProps.disabled || !callback;
|
|
20
20
|
const t3 = composeEventHandlers(primitiveProps.onClick, callback);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createActionButton.js","names":["ComponentRef","forwardRef","ComponentPropsWithoutRef","MouseEventHandler","Primitive","composeEventHandlers","ActionButtonCallback","props","TProps","HTMLButtonElement","PrimitiveButtonProps","button","ActionButtonProps","THook","ActionButtonElement","createActionButton","displayName","useActionButton","forwardProps","NonNullable","ActionButton","forwardedRef","$","_c","forwardedProps","primitiveProps","Object","keys","Array","forEach","key","includes","callback","undefined","t0","t1","t2","disabled","t3","onClick","t4"],"sources":["../../src/utils/createActionButton.tsx"],"sourcesContent":["import {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n type MouseEventHandler,\n} from \"react\";\nimport { Primitive } from \"./Primitive\";\nimport { composeEventHandlers } from \"
|
|
1
|
+
{"version":3,"file":"createActionButton.js","names":["ComponentRef","forwardRef","ComponentPropsWithoutRef","MouseEventHandler","Primitive","composeEventHandlers","ActionButtonCallback","props","TProps","HTMLButtonElement","PrimitiveButtonProps","button","ActionButtonProps","THook","ActionButtonElement","createActionButton","displayName","useActionButton","forwardProps","NonNullable","ActionButton","forwardedRef","$","_c","forwardedProps","primitiveProps","Object","keys","Array","forEach","key","includes","callback","undefined","t0","t1","t2","disabled","t3","onClick","t4"],"sources":["../../src/utils/createActionButton.tsx"],"sourcesContent":["import {\n type ComponentRef,\n forwardRef,\n type ComponentPropsWithoutRef,\n type MouseEventHandler,\n} from \"react\";\nimport { Primitive } from \"./Primitive\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\n\ntype ActionButtonCallback<TProps> = (\n props: TProps,\n) => MouseEventHandler<HTMLButtonElement> | null;\n\ntype PrimitiveButtonProps = ComponentPropsWithoutRef<typeof Primitive.button>;\n\nexport type ActionButtonProps<THook> = PrimitiveButtonProps &\n (THook extends (props: infer TProps) => unknown ? TProps : never);\n\nexport type ActionButtonElement = ComponentRef<typeof Primitive.button>;\n\nexport const createActionButton = <TProps,>(\n displayName: string,\n useActionButton: ActionButtonCallback<TProps>,\n forwardProps: (keyof NonNullable<TProps>)[] = [],\n) => {\n const ActionButton = forwardRef<\n ActionButtonElement,\n PrimitiveButtonProps & TProps\n >((props, forwardedRef) => {\n const forwardedProps = {} as TProps;\n const primitiveProps = {} as PrimitiveButtonProps;\n\n (Object.keys(props) as Array<keyof typeof props>).forEach((key) => {\n if (forwardProps.includes(key as keyof TProps)) {\n (forwardedProps as any)[key] = props[key];\n } else {\n (primitiveProps as any)[key] = props[key];\n }\n });\n\n const callback = useActionButton(forwardedProps as TProps) ?? undefined;\n return (\n <Primitive.button\n type=\"button\"\n {...primitiveProps}\n ref={forwardedRef}\n disabled={primitiveProps.disabled || !callback}\n onClick={composeEventHandlers(primitiveProps.onClick, callback)}\n />\n );\n });\n\n ActionButton.displayName = displayName;\n\n return ActionButton;\n};\n"],"mappings":";;;;;;AAoBA,MAAae,sBACXC,aACAC,iBACAC,eAA8C,CAAA,MAC3C;CACH,MAAME,eAAenB,YAGnBM,OAAAc,iBAAA;EAAA,MAAAC,IAAAC,EAAA,CAAA;EACA,MAAAC,iBAAuB,CAAC;EACxB,MAAAC,iBAAuB,CAAC;EAExB,OAAOE,KAAMpB,KAAK,CAAC,CAA6BsB,SAAUC,QAAA;GACxD,IAAIZ,aAAYa,SAAUD,GAAmB,GAC3C,eAAwBA,OAAOvB,MAAMuB;QAErC,eAAwBA,OAAOvB,MAAMuB;EACtC,CACF;EAED,MAAAE,WAAiBf,gBAAgBO,cAAqC,KAArDS,KAAAA;EAEd,MAAAC,KAAA9B;EACM,MAAA+B,KAAA;EAGK,MAAAC,KAAAX,eAAcY,YAAd,CAA4BL;EAC7B,MAAAM,KAAAjC,qBAAqBoB,eAAcc,SAAUP,QAAQ;EAAC,IAAAQ;EAAA,IAAAlB,EAAA,OAAAD,gBAAAC,EAAA,OAAAG,kBAAAH,EAAA,OAAAY,GAAAvB,UAAAW,EAAA,OAAAc,MAAAd,EAAA,OAAAgB,IAAA;GALjEE,KAAA,oBAAA,GAAA,QAAA;IACO,MAAAL;IAAQ,GACTV;IACCJ,KAAAA;IACK,UAAAe;IACD,SAAAE;GAAsD,CAAA;GAC/DhB,EAAA,KAAAD;GAAAC,EAAA,KAAAG;GAAAH,EAAA,KAAAY,GAAAvB;GAAAW,EAAA,KAAAc;GAAAd,EAAA,KAAAgB;GAAAhB,EAAA,KAAAkB;EAAA,OAAAA,KAAAlB,EAAA;EAAA,OANFkB;CAME,CAEL;CAEDpB,aAAaJ,cAAcA;CAE3B,OAAOI;AACT"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useManagedRef } from "./useManagedRef.js";
|
|
2
2
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
3
3
|
import "@assistant-ui/tap/react-shim";
|
|
4
|
-
import { useCallbackRef } from "
|
|
4
|
+
import { useCallbackRef } from "radix-ui/internal";
|
|
5
5
|
//#region src/utils/hooks/useOnResizeContent.ts
|
|
6
6
|
const useOnResizeContent = (callback) => {
|
|
7
7
|
const $ = c(2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnResizeContent.js","names":["useCallbackRef","useCallback","useManagedRef","useOnResizeContent","callback","$","_c","callbackRef","t0","el","resizeObserver","ResizeObserver","mutationObserver","MutationObserver","mutations","hasRelevantMutation","some","_temp","observe","childList","subtree","attributes","characterData","disconnect","refCallback","m","type","attributeName"],"sources":["../../../src/utils/hooks/useOnResizeContent.ts"],"sourcesContent":["import { useCallbackRef } from \"
|
|
1
|
+
{"version":3,"file":"useOnResizeContent.js","names":["useCallbackRef","useCallback","useManagedRef","useOnResizeContent","callback","$","_c","callbackRef","t0","el","resizeObserver","ResizeObserver","mutationObserver","MutationObserver","mutations","hasRelevantMutation","some","_temp","observe","childList","subtree","attributes","characterData","disconnect","refCallback","m","type","attributeName"],"sources":["../../../src/utils/hooks/useOnResizeContent.ts"],"sourcesContent":["import { useCallbackRef } from \"radix-ui/internal\";\nimport { useCallback } from \"react\";\nimport { useManagedRef } from \"./useManagedRef\";\n\nexport const useOnResizeContent = (callback: () => void) => {\n const callbackRef = useCallbackRef(callback);\n\n const refCallback = useCallback(\n (el: HTMLElement) => {\n const resizeObserver = new ResizeObserver(() => {\n callbackRef();\n });\n\n const mutationObserver = new MutationObserver((mutations) => {\n // Filter out style-only attribute mutations to prevent feedback loops\n // with code paths that write styles in response to viewport changes.\n const hasRelevantMutation = mutations.some(\n (m) => m.type !== \"attributes\" || m.attributeName !== \"style\",\n );\n if (hasRelevantMutation) {\n callbackRef();\n }\n });\n\n resizeObserver.observe(el);\n mutationObserver.observe(el, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n return () => {\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n },\n [callbackRef],\n );\n\n return useManagedRef(refCallback);\n};\n"],"mappings":";;;;;AAIA,MAAaG,sBAAqBC,aAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAChC,MAAAC,cAAoBP,eAAeI,QAAQ;CAAE,IAAAI;CAAA,IAAAH,EAAA,OAAAE,aAAA;EAG3CC,MAAAC,OAAA;GACE,MAAAC,iBAAuB,IAAIC,qBAAe;IACxCJ,YAAY;GAAC,CACd;GAED,MAAAK,mBAAyB,IAAIC,kBAAiBC,cAAA;IAM5C,IAH4BA,UAASE,KACnCC,KAEEF,GACFR,YAAY;GACb,CACF;GAEDG,eAAcQ,QAAST,EAAE;GACzBG,iBAAgBM,QAAST,IAAI;IAAAU,WAChB;IAAIC,SACN;IAAIC,YACD;IAAIC,eACD;GACjB,CAAC;GAAC,aAEK;IACLZ,eAAca,WAAY;IAC1BX,iBAAgBW,WAAY;GAAC;EAC9B;EACFlB,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAED,OAEKH,cAAcsB,EAAW;AAAC;AApCD,SAAAP,MAAAQ,GAAA;CAAA,OAajBA,EAACC,SAAU,gBAAgBD,EAACE,kBAAmB;AAAO"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { useThreadViewport } from "../../context/react/ThreadViewportContext.js";
|
|
3
3
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
4
4
|
import { useEffect } from "@assistant-ui/tap/react-shim";
|
|
5
|
-
import { useCallbackRef } from "
|
|
5
|
+
import { useCallbackRef } from "radix-ui/internal";
|
|
6
6
|
//#region src/utils/hooks/useOnScrollToBottom.ts
|
|
7
7
|
const useOnScrollToBottom = (callback) => {
|
|
8
8
|
const $ = c(4);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnScrollToBottom.js","names":["c","_c","useCallbackRef","useEffect","useThreadViewport","useOnScrollToBottom","callback","$","callbackRef","onScrollToBottom","_temp","t0","t1","vp"],"sources":["../../../src/utils/hooks/useOnScrollToBottom.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"
|
|
1
|
+
{"version":3,"file":"useOnScrollToBottom.js","names":["c","_c","useCallbackRef","useEffect","useThreadViewport","useOnScrollToBottom","callback","$","callbackRef","onScrollToBottom","_temp","t0","t1","vp"],"sources":["../../../src/utils/hooks/useOnScrollToBottom.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallbackRef } from \"radix-ui/internal\";\nimport { useEffect } from \"react\";\nimport { useThreadViewport } from \"../../context/react/ThreadViewportContext\";\n\nexport const useOnScrollToBottom = (\n callback: (config: { behavior: ScrollBehavior }) => void,\n) => {\n const callbackRef = useCallbackRef(callback);\n const onScrollToBottom = useThreadViewport((vp) => vp.onScrollToBottom);\n\n useEffect(() => {\n return onScrollToBottom(callbackRef);\n }, [onScrollToBottom, callbackRef]);\n};\n"],"mappings":";;;;;;AAMA,MAAaK,uBAAsBC,aAAA;CAAA,MAAAC,IAAAN,EAAA,CAAA;CAGjC,MAAAO,cAAoBN,eAAeI,QAAQ;CAC3C,MAAAG,mBAAyBL,kBAAkBM,KAA2B;CAAE,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAC,eAAAD,EAAA,OAAAE,kBAAA;EAE9DE,WACDF,iBAAiBD,WAAW;EAClCI,KAAA,CAACH,kBAAkBD,WAAW;EAACD,EAAA,KAAAC;EAAAD,EAAA,KAAAE;EAAAF,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAD,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAFlCJ,UAAUQ,IAEPC,EAA+B;AAAC;AARF,SAAAF,MAAAG,IAAA;CAAA,OAIkBA,GAAEJ;AAAiB"}
|
|
@@ -15,6 +15,10 @@ declare const useSmoothStatus: {
|
|
|
15
15
|
} | {
|
|
16
16
|
readonly type: "requires-action";
|
|
17
17
|
readonly reason: "tool-calls" | "interrupt";
|
|
18
|
+
} | {
|
|
19
|
+
readonly type: "incomplete";
|
|
20
|
+
readonly reason: "tool-calls";
|
|
21
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
18
22
|
};
|
|
19
23
|
<TSelected>(selector: (state: {
|
|
20
24
|
readonly type: "running";
|
|
@@ -27,6 +31,10 @@ declare const useSmoothStatus: {
|
|
|
27
31
|
} | {
|
|
28
32
|
readonly type: "requires-action";
|
|
29
33
|
readonly reason: "tool-calls" | "interrupt";
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: "incomplete";
|
|
36
|
+
readonly reason: "tool-calls";
|
|
37
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
30
38
|
}) => TSelected): TSelected;
|
|
31
39
|
(options: {
|
|
32
40
|
optional: true;
|
|
@@ -41,6 +49,10 @@ declare const useSmoothStatus: {
|
|
|
41
49
|
} | {
|
|
42
50
|
readonly type: "requires-action";
|
|
43
51
|
readonly reason: "tool-calls" | "interrupt";
|
|
52
|
+
} | {
|
|
53
|
+
readonly type: "incomplete";
|
|
54
|
+
readonly reason: "tool-calls";
|
|
55
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
44
56
|
} | null;
|
|
45
57
|
<TSelected>(options: {
|
|
46
58
|
optional: true;
|
|
@@ -55,6 +67,10 @@ declare const useSmoothStatus: {
|
|
|
55
67
|
} | {
|
|
56
68
|
readonly type: "requires-action";
|
|
57
69
|
readonly reason: "tool-calls" | "interrupt";
|
|
70
|
+
} | {
|
|
71
|
+
readonly type: "incomplete";
|
|
72
|
+
readonly reason: "tool-calls";
|
|
73
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
58
74
|
}) => TSelected;
|
|
59
75
|
}): TSelected | null;
|
|
60
76
|
}, useSmoothStatusStore: {
|
|
@@ -69,6 +85,10 @@ declare const useSmoothStatus: {
|
|
|
69
85
|
} | {
|
|
70
86
|
readonly type: "requires-action";
|
|
71
87
|
readonly reason: "tool-calls" | "interrupt";
|
|
88
|
+
} | {
|
|
89
|
+
readonly type: "incomplete";
|
|
90
|
+
readonly reason: "tool-calls";
|
|
91
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
72
92
|
}>;
|
|
73
93
|
(options: {
|
|
74
94
|
optional: true;
|
|
@@ -83,6 +103,10 @@ declare const useSmoothStatus: {
|
|
|
83
103
|
} | {
|
|
84
104
|
readonly type: "requires-action";
|
|
85
105
|
readonly reason: "tool-calls" | "interrupt";
|
|
106
|
+
} | {
|
|
107
|
+
readonly type: "incomplete";
|
|
108
|
+
readonly reason: "tool-calls";
|
|
109
|
+
readonly error?: import("assistant-stream/utils").ReadonlyJSONValue;
|
|
86
110
|
}> | null;
|
|
87
111
|
};
|
|
88
112
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmoothContext.d.ts","names":[],"sources":["../../../src/utils/smooth/SmoothContext.tsx"],"mappings":";;;cAmCa,uBAAuB,GAAG;cAgB1B,4BAA6B,UAAU,oBAClD,WAAW,MACV;cA2BY
|
|
1
|
+
{"version":3,"file":"SmoothContext.d.ts","names":[],"sources":["../../../src/utils/smooth/SmoothContext.tsx"],"mappings":";;;cAmCa,uBAAuB,GAAG;cAgB1B,4BAA6B,UAAU,oBAClD,WAAW,MACV;cA2BY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiB"}
|
|
@@ -4,7 +4,7 @@ import { useMediaQuery } from "../hooks/useMediaQuery.js";
|
|
|
4
4
|
import { useSmoothStatusStore } from "./SmoothContext.js";
|
|
5
5
|
import { useAui, useAuiState } from "@assistant-ui/store";
|
|
6
6
|
import { useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
7
|
-
import { useCallbackRef } from "
|
|
7
|
+
import { useCallbackRef } from "radix-ui/internal";
|
|
8
8
|
//#region src/utils/smooth/useSmooth.ts
|
|
9
9
|
const DEFAULT_DRAIN_MS = 250;
|
|
10
10
|
const DEFAULT_MAX_CHAR_INTERVAL_MS = 5;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSmooth.js","names":["useEffect","useMemo","useRef","useState","useAui","useAuiState","MessagePartStatus","ReasoningMessagePart","TextMessagePart","MessagePartState","useCallbackRef","useMediaQuery","useSmoothStatusStore","writableStore","SmoothOptions","drainMs","maxCharIntervalMs","maxCharsPerFrame","minCommitMs","DEFAULT_DRAIN_MS","DEFAULT_MAX_CHAR_INTERVAL_MS","TextStreamAnimator","animationFrameId","lastUpdateTime","Date","now","lastCommitTime","targetText","Infinity","currentText","setText","newText","constructor","start","animate","stop","cancelAnimationFrame","currentTime","deltaTime","timeToConsume","remainingChars","length","baseTimePerChar","Math","min","frameLimit","charsToAdd","requestAnimationFrame","slice","isComplete","SMOOTH_STATUS","Object","freeze","type","positiveOr","value","fallback","undefined","useSmooth","state","smooth","text","reduceMotion","options","enabled","displayedText","setDisplayedText","status","aui","part","prevPart","setPrevPart","startsWith","smoothStatusStore","optional","target","setState","animatorRef","animatorPartRef","partChanged","current"],"sources":["../../../src/utils/smooth/useSmooth.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type {\n MessagePartStatus,\n ReasoningMessagePart,\n TextMessagePart,\n MessagePartState,\n} from \"@assistant-ui/core\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\nimport { useMediaQuery } from \"../hooks/useMediaQuery\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\n\n/**\n * Tuning options for the smooth text streaming animation.\n */\nexport type SmoothOptions = {\n /**\n * Target time in milliseconds to drain the backlog of unrevealed\n * characters. Larger values reveal long backlogs more gradually.\n * @default 250\n */\n drainMs?: number | undefined;\n /**\n * Maximum time in milliseconds between revealed characters, i.e. the\n * slowest reveal rate when the backlog is short.\n * @default 5\n */\n maxCharIntervalMs?: number | undefined;\n /**\n * Maximum number of characters revealed per animation frame.\n * @default Infinity\n */\n maxCharsPerFrame?: number | undefined;\n /**\n * Minimum time in milliseconds between committed updates. The reveal keeps\n * advancing every frame, but the visible text (and the downstream re-render\n * and markdown re-parse it triggers) is committed at most once per interval.\n * The final frame always commits. `0` commits every frame.\n * @default 0\n */\n minCommitMs?: number | undefined;\n};\n\nconst DEFAULT_DRAIN_MS = 250;\nconst DEFAULT_MAX_CHAR_INTERVAL_MS = 5;\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n public lastCommitTime: number = 0;\n\n public targetText: string = \"\";\n public drainMs: number = DEFAULT_DRAIN_MS;\n public maxCharIntervalMs: number = DEFAULT_MAX_CHAR_INTERVAL_MS;\n public maxCharsPerFrame: number = Infinity;\n public minCommitMs: number = 0;\n\n public currentText: string;\n private setText: (newText: string) => void;\n\n constructor(currentText: string, setText: (newText: string) => void) {\n this.currentText = currentText;\n this.setText = setText;\n }\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(\n this.maxCharIntervalMs,\n this.drainMs / remainingChars,\n );\n\n const frameLimit = Math.min(remainingChars, this.maxCharsPerFrame);\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < frameLimit) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n // A cap-limited frame must not bank its surplus time, or the next\n // frame would burst past the cap.\n if (charsToAdd === frameLimit && frameLimit === this.maxCharsPerFrame) {\n timeToConsume = 0;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n\n const isComplete = charsToAdd === remainingChars;\n if (isComplete || currentTime - this.lastCommitTime >= this.minCommitMs) {\n this.lastCommitTime = currentTime;\n this.setText(this.currentText);\n }\n };\n}\n\nconst SMOOTH_STATUS: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nconst positiveOr = (value: number | undefined, fallback: number): number =>\n value !== undefined && value > 0 ? value : fallback;\n\n/**\n * Animates streamed message part text with a typewriter-style reveal.\n *\n * Takes the current part state and a `smooth` argument: `false` disables,\n * `true` uses the default rate, and a {@link SmoothOptions} object tunes\n * the reveal. Returns the part state with `text` replaced by the revealed\n * prefix and `status` reporting `running` until the reveal catches up.\n * If the source settles before any character has been revealed, the text\n * is committed immediately so a missed animation frame cannot leave an\n * empty bubble.\n *\n * The reveal auto-disables under `prefers-reduced-motion: reduce`,\n * committing the full text immediately; this takes precedence over an\n * explicit `smooth={true}`.\n *\n * @example\n * ```tsx\n * const { text, status } = useSmooth(useMessagePartText(), {\n * drainMs: 500,\n * maxCharsPerFrame: 30,\n * });\n * ```\n */\nexport const useSmooth = (\n state: MessagePartState & (TextMessagePart | ReasoningMessagePart),\n smooth: boolean | SmoothOptions = false,\n): MessagePartState & (TextMessagePart | ReasoningMessagePart) => {\n const { text } = state;\n const reduceMotion = useMediaQuery(\"(prefers-reduced-motion: reduce)\");\n const options =\n typeof smooth === \"object\" && smooth !== null ? smooth : undefined;\n const enabled = smooth !== false && smooth !== null && !reduceMotion;\n const drainMs = positiveOr(options?.drainMs, DEFAULT_DRAIN_MS);\n const maxCharIntervalMs = positiveOr(\n options?.maxCharIntervalMs,\n DEFAULT_MAX_CHAR_INTERVAL_MS,\n );\n const maxCharsPerFrame = positiveOr(options?.maxCharsPerFrame, Infinity);\n const minCommitMs = positiveOr(options?.minCommitMs, 0);\n\n const [displayedText, setDisplayedText] = useState(\n state.status.type === \"running\" ? \"\" : text,\n );\n\n // Render-phase resync on part flip or text discontinuity, so the\n // first paint after a thread switch never shows the previous\n // part's text (#4051). `displayedText` is already a prefix of\n // `text` during normal streaming, so use it as the previous-text\n // reference instead of carrying separate state — avoids the\n // double render per streaming token. Read part identity through\n // `useAuiState` so we actually subscribe to its changes instead\n // of relying on a render-time proxy reference that may be stable\n // across thread swaps.\n const aui = useAui();\n const part = useAuiState(() => aui.part);\n const [prevPart, setPrevPart] = useState(part);\n if (part !== prevPart || !text.startsWith(displayedText)) {\n setPrevPart(part);\n setDisplayedText(state.status.type === \"running\" ? \"\" : text);\n }\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n enabled && (displayedText !== text || state.status.type === \"running\")\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, enabled, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(displayedText, setText),\n );\n\n useEffect(() => {\n animatorRef.drainMs = drainMs;\n animatorRef.maxCharIntervalMs = maxCharIntervalMs;\n animatorRef.maxCharsPerFrame = maxCharsPerFrame;\n animatorRef.minCommitMs = minCommitMs;\n }, [animatorRef, drainMs, maxCharIntervalMs, maxCharsPerFrame, minCommitMs]);\n\n const animatorPartRef = useRef(part);\n useEffect(() => {\n if (!enabled) {\n animatorRef.stop();\n return;\n }\n\n const partChanged = animatorPartRef.current !== part;\n animatorPartRef.current = part;\n // A new part whose text shares a prefix with the previous target would\n // keep the stale cursor and flicker without this reset.\n if (partChanged || !text.startsWith(animatorRef.targetText)) {\n if (state.status.type === \"running\") {\n animatorRef.currentText = \"\";\n animatorRef.targetText = text;\n animatorRef.lastCommitTime = 0;\n animatorRef.start();\n } else {\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n setText(text);\n }\n return;\n }\n\n animatorRef.targetText = text;\n if (state.status.type !== \"running\") {\n // No character has painted. A pending frame that never runs would\n // leave an empty bubble after settle.\n if (animatorRef.currentText === \"\") {\n animatorRef.currentText = text;\n animatorRef.stop();\n setText(text);\n return;\n }\n animatorRef.start();\n return;\n }\n\n animatorRef.start();\n }, [animatorRef, enabled, text, state.status.type, part, setText]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n enabled\n ? {\n ...state,\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [enabled, displayedText, state, text],\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useSmooth.js","names":["useEffect","useMemo","useRef","useState","useAui","useAuiState","MessagePartStatus","ReasoningMessagePart","TextMessagePart","MessagePartState","useCallbackRef","useMediaQuery","useSmoothStatusStore","writableStore","SmoothOptions","drainMs","maxCharIntervalMs","maxCharsPerFrame","minCommitMs","DEFAULT_DRAIN_MS","DEFAULT_MAX_CHAR_INTERVAL_MS","TextStreamAnimator","animationFrameId","lastUpdateTime","Date","now","lastCommitTime","targetText","Infinity","currentText","setText","newText","constructor","start","animate","stop","cancelAnimationFrame","currentTime","deltaTime","timeToConsume","remainingChars","length","baseTimePerChar","Math","min","frameLimit","charsToAdd","requestAnimationFrame","slice","isComplete","SMOOTH_STATUS","Object","freeze","type","positiveOr","value","fallback","undefined","useSmooth","state","smooth","text","reduceMotion","options","enabled","displayedText","setDisplayedText","status","aui","part","prevPart","setPrevPart","startsWith","smoothStatusStore","optional","target","setState","animatorRef","animatorPartRef","partChanged","current"],"sources":["../../../src/utils/smooth/useSmooth.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type {\n MessagePartStatus,\n ReasoningMessagePart,\n TextMessagePart,\n MessagePartState,\n} from \"@assistant-ui/core\";\nimport { useCallbackRef } from \"radix-ui/internal\";\nimport { useMediaQuery } from \"../hooks/useMediaQuery\";\nimport { useSmoothStatusStore } from \"./SmoothContext\";\nimport { writableStore } from \"../../context/ReadonlyStore\";\n\n/**\n * Tuning options for the smooth text streaming animation.\n */\nexport type SmoothOptions = {\n /**\n * Target time in milliseconds to drain the backlog of unrevealed\n * characters. Larger values reveal long backlogs more gradually.\n * @default 250\n */\n drainMs?: number | undefined;\n /**\n * Maximum time in milliseconds between revealed characters, i.e. the\n * slowest reveal rate when the backlog is short.\n * @default 5\n */\n maxCharIntervalMs?: number | undefined;\n /**\n * Maximum number of characters revealed per animation frame.\n * @default Infinity\n */\n maxCharsPerFrame?: number | undefined;\n /**\n * Minimum time in milliseconds between committed updates. The reveal keeps\n * advancing every frame, but the visible text (and the downstream re-render\n * and markdown re-parse it triggers) is committed at most once per interval.\n * The final frame always commits. `0` commits every frame.\n * @default 0\n */\n minCommitMs?: number | undefined;\n};\n\nconst DEFAULT_DRAIN_MS = 250;\nconst DEFAULT_MAX_CHAR_INTERVAL_MS = 5;\n\nclass TextStreamAnimator {\n private animationFrameId: number | null = null;\n private lastUpdateTime: number = Date.now();\n public lastCommitTime: number = 0;\n\n public targetText: string = \"\";\n public drainMs: number = DEFAULT_DRAIN_MS;\n public maxCharIntervalMs: number = DEFAULT_MAX_CHAR_INTERVAL_MS;\n public maxCharsPerFrame: number = Infinity;\n public minCommitMs: number = 0;\n\n public currentText: string;\n private setText: (newText: string) => void;\n\n constructor(currentText: string, setText: (newText: string) => void) {\n this.currentText = currentText;\n this.setText = setText;\n }\n\n start() {\n if (this.animationFrameId !== null) return;\n this.lastUpdateTime = Date.now();\n this.animate();\n }\n\n stop() {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n }\n\n private animate = () => {\n const currentTime = Date.now();\n const deltaTime = currentTime - this.lastUpdateTime;\n let timeToConsume = deltaTime;\n\n const remainingChars = this.targetText.length - this.currentText.length;\n const baseTimePerChar = Math.min(\n this.maxCharIntervalMs,\n this.drainMs / remainingChars,\n );\n\n const frameLimit = Math.min(remainingChars, this.maxCharsPerFrame);\n let charsToAdd = 0;\n while (timeToConsume >= baseTimePerChar && charsToAdd < frameLimit) {\n charsToAdd++;\n timeToConsume -= baseTimePerChar;\n }\n // A cap-limited frame must not bank its surplus time, or the next\n // frame would burst past the cap.\n if (charsToAdd === frameLimit && frameLimit === this.maxCharsPerFrame) {\n timeToConsume = 0;\n }\n\n if (charsToAdd !== remainingChars) {\n this.animationFrameId = requestAnimationFrame(this.animate);\n } else {\n this.animationFrameId = null;\n }\n if (charsToAdd === 0) return;\n\n this.currentText = this.targetText.slice(\n 0,\n this.currentText.length + charsToAdd,\n );\n this.lastUpdateTime = currentTime - timeToConsume;\n\n const isComplete = charsToAdd === remainingChars;\n if (isComplete || currentTime - this.lastCommitTime >= this.minCommitMs) {\n this.lastCommitTime = currentTime;\n this.setText(this.currentText);\n }\n };\n}\n\nconst SMOOTH_STATUS: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nconst positiveOr = (value: number | undefined, fallback: number): number =>\n value !== undefined && value > 0 ? value : fallback;\n\n/**\n * Animates streamed message part text with a typewriter-style reveal.\n *\n * Takes the current part state and a `smooth` argument: `false` disables,\n * `true` uses the default rate, and a {@link SmoothOptions} object tunes\n * the reveal. Returns the part state with `text` replaced by the revealed\n * prefix and `status` reporting `running` until the reveal catches up.\n * If the source settles before any character has been revealed, the text\n * is committed immediately so a missed animation frame cannot leave an\n * empty bubble.\n *\n * The reveal auto-disables under `prefers-reduced-motion: reduce`,\n * committing the full text immediately; this takes precedence over an\n * explicit `smooth={true}`.\n *\n * @example\n * ```tsx\n * const { text, status } = useSmooth(useMessagePartText(), {\n * drainMs: 500,\n * maxCharsPerFrame: 30,\n * });\n * ```\n */\nexport const useSmooth = (\n state: MessagePartState & (TextMessagePart | ReasoningMessagePart),\n smooth: boolean | SmoothOptions = false,\n): MessagePartState & (TextMessagePart | ReasoningMessagePart) => {\n const { text } = state;\n const reduceMotion = useMediaQuery(\"(prefers-reduced-motion: reduce)\");\n const options =\n typeof smooth === \"object\" && smooth !== null ? smooth : undefined;\n const enabled = smooth !== false && smooth !== null && !reduceMotion;\n const drainMs = positiveOr(options?.drainMs, DEFAULT_DRAIN_MS);\n const maxCharIntervalMs = positiveOr(\n options?.maxCharIntervalMs,\n DEFAULT_MAX_CHAR_INTERVAL_MS,\n );\n const maxCharsPerFrame = positiveOr(options?.maxCharsPerFrame, Infinity);\n const minCommitMs = positiveOr(options?.minCommitMs, 0);\n\n const [displayedText, setDisplayedText] = useState(\n state.status.type === \"running\" ? \"\" : text,\n );\n\n // Render-phase resync on part flip or text discontinuity, so the\n // first paint after a thread switch never shows the previous\n // part's text (#4051). `displayedText` is already a prefix of\n // `text` during normal streaming, so use it as the previous-text\n // reference instead of carrying separate state — avoids the\n // double render per streaming token. Read part identity through\n // `useAuiState` so we actually subscribe to its changes instead\n // of relying on a render-time proxy reference that may be stable\n // across thread swaps.\n const aui = useAui();\n const part = useAuiState(() => aui.part);\n const [prevPart, setPrevPart] = useState(part);\n if (part !== prevPart || !text.startsWith(displayedText)) {\n setPrevPart(part);\n setDisplayedText(state.status.type === \"running\" ? \"\" : text);\n }\n\n const smoothStatusStore = useSmoothStatusStore({ optional: true });\n const setText = useCallbackRef((text: string) => {\n setDisplayedText(text);\n if (smoothStatusStore) {\n const target =\n displayedText !== text || state.status.type === \"running\"\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n });\n\n // TODO this is hacky\n useEffect(() => {\n if (smoothStatusStore) {\n const target =\n enabled && (displayedText !== text || state.status.type === \"running\")\n ? SMOOTH_STATUS\n : state.status;\n writableStore(smoothStatusStore).setState(target, true);\n }\n }, [smoothStatusStore, enabled, text, displayedText, state.status]);\n\n const [animatorRef] = useState<TextStreamAnimator>(\n new TextStreamAnimator(displayedText, setText),\n );\n\n useEffect(() => {\n animatorRef.drainMs = drainMs;\n animatorRef.maxCharIntervalMs = maxCharIntervalMs;\n animatorRef.maxCharsPerFrame = maxCharsPerFrame;\n animatorRef.minCommitMs = minCommitMs;\n }, [animatorRef, drainMs, maxCharIntervalMs, maxCharsPerFrame, minCommitMs]);\n\n const animatorPartRef = useRef(part);\n useEffect(() => {\n if (!enabled) {\n animatorRef.stop();\n return;\n }\n\n const partChanged = animatorPartRef.current !== part;\n animatorPartRef.current = part;\n // A new part whose text shares a prefix with the previous target would\n // keep the stale cursor and flicker without this reset.\n if (partChanged || !text.startsWith(animatorRef.targetText)) {\n if (state.status.type === \"running\") {\n animatorRef.currentText = \"\";\n animatorRef.targetText = text;\n animatorRef.lastCommitTime = 0;\n animatorRef.start();\n } else {\n animatorRef.currentText = text;\n animatorRef.targetText = text;\n animatorRef.stop();\n setText(text);\n }\n return;\n }\n\n animatorRef.targetText = text;\n if (state.status.type !== \"running\") {\n // No character has painted. A pending frame that never runs would\n // leave an empty bubble after settle.\n if (animatorRef.currentText === \"\") {\n animatorRef.currentText = text;\n animatorRef.stop();\n setText(text);\n return;\n }\n animatorRef.start();\n return;\n }\n\n animatorRef.start();\n }, [animatorRef, enabled, text, state.status.type, part, setText]);\n\n useEffect(() => {\n return () => {\n animatorRef.stop();\n };\n }, [animatorRef]);\n\n return useMemo(\n () =>\n enabled\n ? {\n ...state,\n text: displayedText,\n status: text === displayedText ? state.status : SMOOTH_STATUS,\n }\n : state,\n [enabled, displayedText, state, text],\n );\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.18",
|
|
4
4
|
"description": "Open-source TypeScript/React library for building production-grade AI chat experiences",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -55,23 +55,15 @@
|
|
|
55
55
|
],
|
|
56
56
|
"sideEffects": false,
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@assistant-ui/core": "^0.3.
|
|
59
|
-
"@assistant-ui/store": "^0.3.
|
|
60
|
-
"@assistant-ui/tap": "^0.9.
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"@radix-ui/react-compose-refs": "^1.1.5",
|
|
64
|
-
"@radix-ui/react-context": "^1.2.2",
|
|
65
|
-
"@radix-ui/react-primitive": "^2.1.10",
|
|
66
|
-
"@radix-ui/react-use-callback-ref": "^1.1.4",
|
|
67
|
-
"@radix-ui/react-use-controllable-state": "^1.2.6",
|
|
68
|
-
"@radix-ui/react-use-escape-keydown": "^1.1.5",
|
|
69
|
-
"assistant-cloud": "^0.1.41",
|
|
70
|
-
"assistant-stream": "^0.3.39",
|
|
58
|
+
"@assistant-ui/core": "^0.3.17",
|
|
59
|
+
"@assistant-ui/store": "^0.3.12",
|
|
60
|
+
"@assistant-ui/tap": "^0.9.16",
|
|
61
|
+
"assistant-cloud": "^0.1.43",
|
|
62
|
+
"assistant-stream": "^0.3.41",
|
|
71
63
|
"radix-ui": "^1.6.7",
|
|
72
64
|
"react-textarea-autosize": "^8.5.9",
|
|
73
|
-
"safe-content-frame": "^0.0.
|
|
74
|
-
"zod": "^4.4
|
|
65
|
+
"safe-content-frame": "^0.0.29",
|
|
66
|
+
"zod": "^4.5.4",
|
|
75
67
|
"zustand": "^5.0.15"
|
|
76
68
|
},
|
|
77
69
|
"peerDependencies": {
|
|
@@ -89,17 +81,17 @@
|
|
|
89
81
|
}
|
|
90
82
|
},
|
|
91
83
|
"devDependencies": {
|
|
92
|
-
"@
|
|
84
|
+
"@assistant-ui/vite": "0.0.16",
|
|
85
|
+
"@assistant-ui/x-buildutils": "0.0.25",
|
|
86
|
+
"@testing-library/react": "^16.3.3",
|
|
93
87
|
"@types/json-schema": "^7.0.15",
|
|
94
|
-
"@types/node": "^26.
|
|
88
|
+
"@types/node": "^26.4.0",
|
|
95
89
|
"@types/react": "^19.2.18",
|
|
96
|
-
"@types/react-dom": "^19.2.
|
|
90
|
+
"@types/react-dom": "^19.2.5",
|
|
97
91
|
"jsdom": "^30.0.1",
|
|
98
92
|
"react": "^19.2.8",
|
|
99
93
|
"react-dom": "^19.2.8",
|
|
100
|
-
"vitest": "^4.1.
|
|
101
|
-
"@assistant-ui/vite": "0.0.14",
|
|
102
|
-
"@assistant-ui/x-buildutils": "0.0.23"
|
|
94
|
+
"vitest": "^4.1.11"
|
|
103
95
|
},
|
|
104
96
|
"publishConfig": {
|
|
105
97
|
"access": "public",
|
package/src/index.ts
CHANGED
|
@@ -43,6 +43,8 @@ export type {
|
|
|
43
43
|
ThreadListItemState,
|
|
44
44
|
} from "@assistant-ui/core";
|
|
45
45
|
|
|
46
|
+
export { toolApprovalAcceptsText } from "@assistant-ui/core";
|
|
47
|
+
|
|
46
48
|
export { useCloudThreadListRuntime } from "@assistant-ui/core/react";
|
|
47
49
|
export { AssistantCloud } from "assistant-cloud";
|
|
48
50
|
|
|
@@ -83,7 +85,12 @@ export {
|
|
|
83
85
|
} from "@assistant-ui/core";
|
|
84
86
|
|
|
85
87
|
// --- adapters/suggestion ---
|
|
86
|
-
export type {
|
|
88
|
+
export type {
|
|
89
|
+
SuggestionAdapter,
|
|
90
|
+
SuggestionAdapterGenerateOptions,
|
|
91
|
+
CreateSuggestionAdapterOptions,
|
|
92
|
+
} from "@assistant-ui/core";
|
|
93
|
+
export { createSuggestionAdapter } from "@assistant-ui/core";
|
|
87
94
|
|
|
88
95
|
// --- adapters/RuntimeAdapterProvider ---
|
|
89
96
|
export {
|
|
@@ -355,6 +362,7 @@ export type {
|
|
|
355
362
|
GenerativeUISpec,
|
|
356
363
|
Unstable_AudioMessagePart,
|
|
357
364
|
RespondToToolApprovalOptions,
|
|
365
|
+
ToolApprovalDisplay,
|
|
358
366
|
ToolApprovalOption,
|
|
359
367
|
ToolApprovalOptionKind,
|
|
360
368
|
ToolApprovalResponse,
|
|
@@ -475,6 +483,8 @@ export {
|
|
|
475
483
|
useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers,
|
|
476
484
|
useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional,
|
|
477
485
|
type RegisteredTrigger as Unstable_RegisteredTrigger,
|
|
486
|
+
type TriggerMatch as Unstable_TriggerMatch,
|
|
487
|
+
type TriggerMatcher as Unstable_TriggerMatcher,
|
|
478
488
|
type TriggerBehavior as Unstable_TriggerBehavior,
|
|
479
489
|
} from "./primitives/composer/trigger";
|
|
480
490
|
export type {
|
|
@@ -508,6 +518,7 @@ export {
|
|
|
508
518
|
getMcpAppFromToolPart,
|
|
509
519
|
} from "./mcp-apps";
|
|
510
520
|
export type {
|
|
521
|
+
McpAppPartOptions,
|
|
511
522
|
McpAppRendererOptions,
|
|
512
523
|
McpAppMetadata,
|
|
513
524
|
McpAppResource,
|
|
@@ -520,6 +531,16 @@ export type {
|
|
|
520
531
|
McpAppsHost,
|
|
521
532
|
McpAppsRemoteHostOptions,
|
|
522
533
|
McpAppToolCallParams,
|
|
534
|
+
McpAppBridgeHandlers,
|
|
523
535
|
ToolCallMessagePartMcpMetadata,
|
|
524
536
|
} from "./mcp-apps";
|
|
525
537
|
export type { McpAppResourceOutput } from "@assistant-ui/core/react";
|
|
538
|
+
export type { ShimLoadError, ShimLoadErrorCode } from "safe-content-frame";
|
|
539
|
+
|
|
540
|
+
// Unstable - WebMCP provider (exposes frontend tools to a WebMCP-capable browser)
|
|
541
|
+
export {
|
|
542
|
+
unstable_useWebMcpProvider,
|
|
543
|
+
type Unstable_WebMcpProviderOptions,
|
|
544
|
+
type Unstable_WebMcpProviderResult,
|
|
545
|
+
} from "./unstable/webmcp/useWebMcpProvider";
|
|
546
|
+
export { defaultWebMcpFilter as unstable_defaultWebMcpFilter } from "./unstable/webmcp/convertTools";
|