@assistant-ui/react 0.15.24 → 0.15.26
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/dist/hooks/useToolCallElapsed.d.ts +3 -1
- package/dist/hooks/useToolCallElapsed.d.ts.map +1 -1
- package/dist/hooks/useToolCallElapsed.js +8 -8
- package/dist/hooks/useToolCallElapsed.js.map +1 -1
- package/dist/index.d.ts +39 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.js +3 -2
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/mcp-apps/app-frame.d.ts.map +1 -1
- package/dist/mcp-apps/app-frame.js +56 -46
- package/dist/mcp-apps/app-frame.js.map +1 -1
- package/dist/mcp-apps/csp.d.ts +4 -0
- package/dist/mcp-apps/csp.d.ts.map +1 -0
- package/dist/mcp-apps/csp.js +93 -0
- package/dist/mcp-apps/csp.js.map +1 -0
- package/dist/mcp-apps/types.d.ts +1 -0
- package/dist/mcp-apps/types.d.ts.map +1 -1
- package/dist/mcp-apps/types.js.map +1 -1
- package/dist/model-context/makeAssistantVisible.d.ts +1 -0
- package/dist/model-context/makeAssistantVisible.d.ts.map +1 -1
- package/dist/model-context/makeAssistantVisible.js +31 -12
- package/dist/model-context/makeAssistantVisible.js.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.d.ts +1 -0
- package/dist/primitives/assistantModal/AssistantModalRoot.d.ts.map +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
- package/dist/primitives/attachment.d.ts +3 -1
- package/dist/primitives/attachment.d.ts.map +1 -1
- package/dist/primitives/attachment.js.map +1 -1
- package/dist/primitives/composer/ComposerCancel.d.ts +5 -1
- package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerCancel.js +14 -1
- package/dist/primitives/composer/ComposerCancel.js.map +1 -1
- package/dist/primitives/composer/ComposerInput.d.ts +15 -1
- package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerInput.js +5 -4
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
- package/dist/primitives/composer/ComposerRoot.js +24 -19
- package/dist/primitives/composer/ComposerRoot.js.map +1 -1
- package/dist/primitives/composer/composerInputSelector.d.ts +3 -0
- package/dist/primitives/composer/composerInputSelector.d.ts.map +1 -0
- package/dist/primitives/composer/composerInputSelector.js +7 -0
- package/dist/primitives/composer/composerInputSelector.js.map +1 -0
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts +11 -11
- package/dist/primitives/composer/trigger/TriggerPopover.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.js +62 -60
- package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.d.ts +8 -8
- package/dist/primitives/composer/trigger/TriggerPopoverAction.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js +6 -6
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts +3 -3
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.d.ts +9 -9
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.js +7 -7
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts +5 -5
- package/dist/primitives/composer/trigger/TriggerPopoverItems.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.d.ts +8 -8
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +8 -8
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
- package/dist/primitives/composer/trigger/index.d.ts +1 -1
- package/dist/primitives/composer/useComposerCancelWithFocus.d.ts +2 -0
- package/dist/primitives/composer/useComposerCancelWithFocus.d.ts.map +1 -0
- package/dist/primitives/composer/useComposerCancelWithFocus.js +42 -0
- package/dist/primitives/composer/useComposerCancelWithFocus.js.map +1 -0
- package/dist/primitives/composer.d.ts +55 -15
- package/dist/primitives/composer.d.ts.map +1 -1
- package/dist/primitives/composer.js +8 -1
- package/dist/primitives/composer.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts +8 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js +58 -278
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +5 -2
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
- package/dist/primitives/thread/ThreadLoadEarlier.d.ts +19 -0
- package/dist/primitives/thread/ThreadLoadEarlier.d.ts.map +1 -0
- package/dist/primitives/thread/ThreadLoadEarlier.js +36 -0
- package/dist/primitives/thread/ThreadLoadEarlier.js.map +1 -0
- package/dist/primitives/thread/ThreadMessages.d.ts +1 -1
- package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadMessages.js +2 -2
- package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadViewport.js +4 -3
- package/dist/primitives/thread/ThreadViewport.js.map +1 -1
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +2 -2
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js +195 -17
- package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
- package/dist/primitives/thread.d.ts +2 -0
- package/dist/primitives/thread.d.ts.map +1 -1
- package/dist/primitives/thread.js +5 -2
- package/dist/primitives/thread.js.map +1 -1
- package/dist/sandbox-host/SandboxHost.d.ts.map +1 -1
- package/dist/sandbox-host/SandboxHost.js +9 -3
- package/dist/sandbox-host/SandboxHost.js.map +1 -1
- package/dist/unstable/useComposerInput.d.ts +7 -4
- package/dist/unstable/useComposerInput.d.ts.map +1 -1
- package/dist/unstable/useComposerInput.js +4 -4
- package/dist/unstable/useComposerInput.js.map +1 -1
- package/dist/unstable/useComposerInputHistory.d.ts +3 -2
- package/dist/unstable/useComposerInputHistory.d.ts.map +1 -1
- package/dist/unstable/useComposerInputHistory.js +2 -2
- package/dist/unstable/useComposerInputHistory.js.map +1 -1
- package/dist/unstable/useLiveCompletionAdapter.d.ts +3 -2
- package/dist/unstable/useLiveCompletionAdapter.d.ts.map +1 -1
- package/dist/unstable/useLiveCompletionAdapter.js +8 -7
- package/dist/unstable/useLiveCompletionAdapter.js.map +1 -1
- package/dist/unstable/useMentionAdapter.d.ts +12 -3
- package/dist/unstable/useMentionAdapter.d.ts.map +1 -1
- package/dist/unstable/useMentionAdapter.js +2 -2
- package/dist/unstable/useMentionAdapter.js.map +1 -1
- package/dist/unstable/useMessageStallDetection.d.ts +4 -2
- package/dist/unstable/useMessageStallDetection.d.ts.map +1 -1
- package/dist/unstable/useMessageStallDetection.js +12 -8
- package/dist/unstable/useMessageStallDetection.js.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.d.ts +5 -2
- package/dist/unstable/useSlashCommandAdapter.d.ts.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.js +5 -4
- package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
- package/dist/unstable/webmcp/useWebMcpProvider.d.ts +4 -0
- package/dist/unstable/webmcp/useWebMcpProvider.d.ts.map +1 -1
- package/dist/unstable/webmcp/useWebMcpProvider.js +2 -0
- package/dist/unstable/webmcp/useWebMcpProvider.js.map +1 -1
- package/dist/utils/getSelectionMessageId.d.ts.map +1 -1
- package/dist/utils/getSelectionMessageId.js +31 -8
- package/dist/utils/getSelectionMessageId.js.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.d.ts.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.js +2 -22
- package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
- package/dist/utils/smooth/useSmooth.js +6 -6
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/dist/utils/useIsomorphicLayoutEffect.d.ts +3 -0
- package/dist/utils/useIsomorphicLayoutEffect.d.ts.map +1 -0
- package/dist/utils/useIsomorphicLayoutEffect.js +6 -0
- package/dist/utils/useIsomorphicLayoutEffect.js.map +1 -0
- package/package.json +12 -11
- package/src/hooks/useToolCallElapsed.test.tsx +37 -0
- package/src/hooks/useToolCallElapsed.ts +10 -7
- package/src/index.ts +47 -5
- package/src/mcp-apps/McpAppRenderer.tsx +3 -9
- package/src/mcp-apps/app-frame.test.tsx +38 -0
- package/src/mcp-apps/app-frame.tsx +5 -8
- package/src/mcp-apps/csp.test.ts +112 -0
- package/src/mcp-apps/csp.ts +124 -0
- package/src/mcp-apps/types.ts +1 -0
- package/src/model-context/frame/AssistantFrame.test.ts +45 -0
- package/src/model-context/frame/SPEC_AssistantFrame.md +1 -0
- package/src/model-context/makeAssistantVisible.test.tsx +315 -5
- package/src/model-context/makeAssistantVisible.tsx +43 -7
- package/src/primitives/assistantModal/AssistantModalRoot.tsx +1 -0
- package/src/primitives/attachment.ts +4 -1
- package/src/primitives/composer/ComposerCancel.focus.test.tsx +307 -0
- package/src/primitives/composer/ComposerCancel.ts +8 -1
- package/src/primitives/composer/ComposerInput.tsx +20 -2
- package/src/primitives/composer/ComposerRoot.tsx +6 -5
- package/src/primitives/composer/composerInputSelector.ts +4 -0
- package/src/primitives/composer/trigger/TriggerPopover.tsx +11 -11
- package/src/primitives/composer/trigger/TriggerPopoverAction.tsx +10 -13
- package/src/primitives/composer/trigger/TriggerPopoverCategories.tsx +2 -2
- package/src/primitives/composer/trigger/TriggerPopoverDirective.tsx +11 -14
- package/src/primitives/composer/trigger/TriggerPopoverExports.test.ts +61 -0
- package/src/primitives/composer/trigger/TriggerPopoverItems.tsx +3 -3
- package/src/primitives/composer/trigger/TriggerPopoverRootContext.tsx +8 -8
- package/src/primitives/composer/useComposerCancelWithFocus.ts +57 -0
- package/src/primitives/composer.ts +70 -15
- package/src/primitives/message/MessagePartsGrouped.test.tsx +106 -2
- package/src/primitives/message/MessagePartsGrouped.tsx +36 -134
- package/src/primitives/message/MessageRoot.test.tsx +125 -2
- package/src/primitives/selectionToolbar/SelectionToolbarRoot.test.tsx +20 -12
- package/src/primitives/selectionToolbar/SelectionToolbarRoot.tsx +6 -2
- package/src/primitives/thread/ThreadLoadEarlier.tsx +35 -0
- package/src/primitives/thread/ThreadMessages.tsx +1 -0
- package/src/primitives/thread/ThreadViewport.tsx +3 -3
- package/src/primitives/thread/topAnchor/useTopAnchorReserve.ts +2 -2
- package/src/primitives/thread/useThreadViewportAutoScroll.test.tsx +922 -68
- package/src/primitives/thread/useThreadViewportAutoScroll.ts +330 -56
- package/src/primitives/thread.ts +2 -0
- package/src/sandbox-host/SandboxHost.test.tsx +34 -0
- package/src/sandbox-host/SandboxHost.tsx +11 -12
- package/src/tests/toolCallTiming.test.tsx +19 -2
- package/src/unstable/useComposerInput.ts +7 -4
- package/src/unstable/useComposerInputHistory.ts +3 -2
- package/src/unstable/useLiveCompletionAdapter.ts +9 -14
- package/src/unstable/useMentionAdapter.ts +12 -3
- package/src/unstable/useMessageStallDetection.test.tsx +40 -0
- package/src/unstable/useMessageStallDetection.ts +14 -8
- package/src/unstable/useSlashCommandAdapter.ts +8 -4
- package/src/unstable/webmcp/useWebMcpProvider.ts +4 -0
- package/src/utils/getSelectionMessageId.test.ts +231 -0
- package/src/utils/getSelectionMessageId.ts +45 -7
- package/src/utils/hooks/useOnResizeContent.ts +2 -29
- package/src/utils/smooth/useSmooth.test.tsx +16 -5
- package/src/utils/smooth/useSmooth.ts +7 -7
- package/src/utils/useIsomorphicLayoutEffect.test.tsx +21 -0
- package/src/utils/useIsomorphicLayoutEffect.ts +9 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
2
|
+
import * as ComposerPrimitive from "../../composer";
|
|
3
|
+
import {
|
|
4
|
+
defaultDirectiveFormatter,
|
|
5
|
+
unstable_defaultDirectiveFormatter,
|
|
6
|
+
type DirectiveFormatter,
|
|
7
|
+
type TriggerAdapter,
|
|
8
|
+
type TriggerCategory,
|
|
9
|
+
type TriggerItem,
|
|
10
|
+
type Unstable_DirectiveFormatter,
|
|
11
|
+
type Unstable_TriggerBehavior,
|
|
12
|
+
type Unstable_TriggerItem,
|
|
13
|
+
} from "../../../index";
|
|
14
|
+
import type { TriggerBehavior } from "./triggerSelectionResource";
|
|
15
|
+
|
|
16
|
+
describe("stable trigger popover exports", () => {
|
|
17
|
+
it("keeps every old composer member as an alias of its stable member", () => {
|
|
18
|
+
expect(ComposerPrimitive.Unstable_TriggerPopover).toBe(
|
|
19
|
+
ComposerPrimitive.TriggerPopover,
|
|
20
|
+
);
|
|
21
|
+
expect(ComposerPrimitive.Unstable_TriggerPopover.Directive).toBe(
|
|
22
|
+
ComposerPrimitive.TriggerPopover.Directive,
|
|
23
|
+
);
|
|
24
|
+
expect(ComposerPrimitive.Unstable_TriggerPopover.Action).toBe(
|
|
25
|
+
ComposerPrimitive.TriggerPopover.Action,
|
|
26
|
+
);
|
|
27
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverRoot).toBe(
|
|
28
|
+
ComposerPrimitive.TriggerPopoverRoot,
|
|
29
|
+
);
|
|
30
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverCategories).toBe(
|
|
31
|
+
ComposerPrimitive.TriggerPopoverCategories,
|
|
32
|
+
);
|
|
33
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverCategoryItem).toBe(
|
|
34
|
+
ComposerPrimitive.TriggerPopoverCategoryItem,
|
|
35
|
+
);
|
|
36
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverItems).toBe(
|
|
37
|
+
ComposerPrimitive.TriggerPopoverItems,
|
|
38
|
+
);
|
|
39
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverItem).toBe(
|
|
40
|
+
ComposerPrimitive.TriggerPopoverItem,
|
|
41
|
+
);
|
|
42
|
+
expect(ComposerPrimitive.Unstable_TriggerPopoverBack).toBe(
|
|
43
|
+
ComposerPrimitive.TriggerPopoverBack,
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("keeps the old members' namespaced prop types", () => {
|
|
48
|
+
expectTypeOf<ComposerPrimitive.Unstable_TriggerPopoverItem.Props>().toEqualTypeOf<ComposerPrimitive.TriggerPopoverItem.Props>();
|
|
49
|
+
expectTypeOf<ComposerPrimitive.Unstable_TriggerPopoverBack.Element>().toEqualTypeOf<ComposerPrimitive.TriggerPopoverBack.Element>();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("exports the stable adapter, item, category and formatter names beside the old ones", () => {
|
|
53
|
+
expect(unstable_defaultDirectiveFormatter).toBe(defaultDirectiveFormatter);
|
|
54
|
+
expectTypeOf<Unstable_TriggerItem>().toEqualTypeOf<TriggerItem>();
|
|
55
|
+
expectTypeOf<Unstable_DirectiveFormatter>().toEqualTypeOf<DirectiveFormatter>();
|
|
56
|
+
expectTypeOf<TriggerAdapter["categories"]>().returns.toEqualTypeOf<
|
|
57
|
+
readonly TriggerCategory[]
|
|
58
|
+
>();
|
|
59
|
+
expectTypeOf<Unstable_TriggerBehavior>().toEqualTypeOf<TriggerBehavior>();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "react";
|
|
11
11
|
import { composeEventHandlers } from "radix-ui/internal";
|
|
12
12
|
import { useTriggerPopoverScopeContext } from "./TriggerPopover";
|
|
13
|
-
import type {
|
|
13
|
+
import type { TriggerItem } from "@assistant-ui/core";
|
|
14
14
|
|
|
15
15
|
export namespace ComposerPrimitiveTriggerPopoverItems {
|
|
16
16
|
export type Element = ComponentRef<typeof Primitive.div>;
|
|
@@ -18,7 +18,7 @@ export namespace ComposerPrimitiveTriggerPopoverItems {
|
|
|
18
18
|
ComponentPropsWithoutRef<typeof Primitive.div>,
|
|
19
19
|
"children"
|
|
20
20
|
> & {
|
|
21
|
-
children: (items: readonly
|
|
21
|
+
children: (items: readonly TriggerItem[]) => ReactNode;
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -53,7 +53,7 @@ ComposerPrimitiveTriggerPopoverItems.displayName =
|
|
|
53
53
|
export namespace ComposerPrimitiveTriggerPopoverItem {
|
|
54
54
|
export type Element = ComponentRef<typeof Primitive.button>;
|
|
55
55
|
export type Props = ComponentPropsWithoutRef<typeof Primitive.button> & {
|
|
56
|
-
item:
|
|
56
|
+
item: TriggerItem;
|
|
57
57
|
index?: number | undefined;
|
|
58
58
|
};
|
|
59
59
|
}
|
|
@@ -294,21 +294,21 @@ const TriggerPopoverRootInner: FC<
|
|
|
294
294
|
*
|
|
295
295
|
* @example
|
|
296
296
|
* ```tsx
|
|
297
|
-
* <ComposerPrimitive.
|
|
298
|
-
* <ComposerPrimitive.
|
|
299
|
-
* <ComposerPrimitive.
|
|
297
|
+
* <ComposerPrimitive.TriggerPopoverRoot>
|
|
298
|
+
* <ComposerPrimitive.TriggerPopover char="@" adapter={mentionAdapter}>
|
|
299
|
+
* <ComposerPrimitive.TriggerPopover.Directive formatter={formatter} />
|
|
300
300
|
* ...
|
|
301
|
-
* </ComposerPrimitive.
|
|
301
|
+
* </ComposerPrimitive.TriggerPopover>
|
|
302
302
|
*
|
|
303
|
-
* <ComposerPrimitive.
|
|
304
|
-
* <ComposerPrimitive.
|
|
303
|
+
* <ComposerPrimitive.TriggerPopover char="/" adapter={slashAdapter}>
|
|
304
|
+
* <ComposerPrimitive.TriggerPopover.Action onExecute={handler} />
|
|
305
305
|
* ...
|
|
306
|
-
* </ComposerPrimitive.
|
|
306
|
+
* </ComposerPrimitive.TriggerPopover>
|
|
307
307
|
*
|
|
308
308
|
* <ComposerPrimitive.Root>
|
|
309
309
|
* <ComposerPrimitive.Input />
|
|
310
310
|
* </ComposerPrimitive.Root>
|
|
311
|
-
* </ComposerPrimitive.
|
|
311
|
+
* </ComposerPrimitive.TriggerPopoverRoot>
|
|
312
312
|
* ```
|
|
313
313
|
*/
|
|
314
314
|
export const ComposerPrimitiveTriggerPopoverRoot: FC<
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
import { useAui } from "@assistant-ui/store";
|
|
5
|
+
import { useThreadRootElementRef } from "../thread/ThreadRootElementContext";
|
|
6
|
+
import { COMPOSER_INPUT_SELECTOR } from "./composerInputSelector";
|
|
7
|
+
|
|
8
|
+
const COMPOSER_SELECTOR = "[data-aui-composer-type]";
|
|
9
|
+
const THREAD_SELECTOR = "[data-aui-thread-root]";
|
|
10
|
+
|
|
11
|
+
export const useComposerCancelWithFocus = (cancel: () => void) => {
|
|
12
|
+
const aui = useAui();
|
|
13
|
+
const threadRootRef = useThreadRootElementRef();
|
|
14
|
+
|
|
15
|
+
const cancelWithFocus = useCallback(
|
|
16
|
+
(source: HTMLElement | null) => {
|
|
17
|
+
const root = threadRootRef?.current;
|
|
18
|
+
const doc = source?.ownerDocument;
|
|
19
|
+
const active = doc?.activeElement;
|
|
20
|
+
const composer = source?.closest(COMPOSER_SELECTOR);
|
|
21
|
+
const shouldRestore =
|
|
22
|
+
aui.composer.getState().type === "edit" &&
|
|
23
|
+
root &&
|
|
24
|
+
active &&
|
|
25
|
+
composer?.getAttribute("data-aui-composer-type") === "edit" &&
|
|
26
|
+
composer.contains(active) &&
|
|
27
|
+
composer.closest(THREAD_SELECTOR) === root;
|
|
28
|
+
const candidates = shouldRestore
|
|
29
|
+
? Array.from(
|
|
30
|
+
root.querySelectorAll<HTMLElement>(COMPOSER_INPUT_SELECTOR),
|
|
31
|
+
).filter(
|
|
32
|
+
(input) =>
|
|
33
|
+
input.closest(THREAD_SELECTOR) === root &&
|
|
34
|
+
input
|
|
35
|
+
.closest(COMPOSER_SELECTOR)
|
|
36
|
+
?.getAttribute("data-aui-composer-type") === "thread",
|
|
37
|
+
)
|
|
38
|
+
: [];
|
|
39
|
+
|
|
40
|
+
cancel();
|
|
41
|
+
|
|
42
|
+
if (!doc || !active || !shouldRestore) return;
|
|
43
|
+
if (doc.activeElement !== active && doc.activeElement !== doc.body)
|
|
44
|
+
return;
|
|
45
|
+
|
|
46
|
+
for (const input of candidates) {
|
|
47
|
+
if (!input.isConnected || input.closest("[hidden], [inert]")) continue;
|
|
48
|
+
input.focus({ preventScroll: true });
|
|
49
|
+
if (doc.activeElement !== active && doc.activeElement !== doc.body)
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
[aui, cancel, threadRootRef],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return cancelWithFocus;
|
|
57
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { TriggerMatch, TriggerMatcher } from "./composer/trigger";
|
|
2
|
+
|
|
1
3
|
export { ComposerPrimitiveRoot as Root } from "./composer/ComposerRoot";
|
|
2
4
|
export { ComposerPrimitiveInput as Input } from "./composer/ComposerInput";
|
|
3
5
|
export { ComposerPrimitiveSend as Send } from "./composer/ComposerSend";
|
|
@@ -15,18 +17,71 @@ export { ComposerPrimitiveQuoteText as QuoteText } from "./composer/ComposerQuot
|
|
|
15
17
|
export { ComposerPrimitiveQuoteDismiss as QuoteDismiss } from "./composer/ComposerQuote";
|
|
16
18
|
export { ComposerPrimitiveQueue as Queue } from "./composer/ComposerQueue";
|
|
17
19
|
|
|
18
|
-
export { ComposerPrimitiveTriggerPopover as
|
|
19
|
-
export {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
export { ComposerPrimitiveTriggerPopover as TriggerPopover } from "./composer/trigger";
|
|
21
|
+
export {
|
|
22
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopover` instead. */
|
|
23
|
+
ComposerPrimitiveTriggerPopover as Unstable_TriggerPopover,
|
|
24
|
+
} from "./composer/trigger";
|
|
25
|
+
export { ComposerPrimitiveTriggerPopoverRoot as TriggerPopoverRoot } from "./composer/trigger";
|
|
26
|
+
export {
|
|
27
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverRoot` instead. */
|
|
28
|
+
ComposerPrimitiveTriggerPopoverRoot as Unstable_TriggerPopoverRoot,
|
|
29
|
+
} from "./composer/trigger";
|
|
30
|
+
export { ComposerPrimitiveTriggerPopoverCategories as TriggerPopoverCategories } from "./composer/trigger";
|
|
31
|
+
export {
|
|
32
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverCategories` instead. */
|
|
33
|
+
ComposerPrimitiveTriggerPopoverCategories as Unstable_TriggerPopoverCategories,
|
|
34
|
+
} from "./composer/trigger";
|
|
35
|
+
export { ComposerPrimitiveTriggerPopoverCategoryItem as TriggerPopoverCategoryItem } from "./composer/trigger";
|
|
36
|
+
export {
|
|
37
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverCategoryItem` instead. */
|
|
38
|
+
ComposerPrimitiveTriggerPopoverCategoryItem as Unstable_TriggerPopoverCategoryItem,
|
|
39
|
+
} from "./composer/trigger";
|
|
40
|
+
export { ComposerPrimitiveTriggerPopoverItems as TriggerPopoverItems } from "./composer/trigger";
|
|
41
|
+
export {
|
|
42
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverItems` instead. */
|
|
43
|
+
ComposerPrimitiveTriggerPopoverItems as Unstable_TriggerPopoverItems,
|
|
44
|
+
} from "./composer/trigger";
|
|
45
|
+
export { ComposerPrimitiveTriggerPopoverItem as TriggerPopoverItem } from "./composer/trigger";
|
|
46
|
+
export {
|
|
47
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverItem` instead. */
|
|
48
|
+
ComposerPrimitiveTriggerPopoverItem as Unstable_TriggerPopoverItem,
|
|
49
|
+
} from "./composer/trigger";
|
|
50
|
+
export { ComposerPrimitiveTriggerPopoverBack as TriggerPopoverBack } from "./composer/trigger";
|
|
51
|
+
export {
|
|
52
|
+
/** @deprecated Use `ComposerPrimitive.TriggerPopoverBack` instead. */
|
|
53
|
+
ComposerPrimitiveTriggerPopoverBack as Unstable_TriggerPopoverBack,
|
|
54
|
+
} from "./composer/trigger";
|
|
55
|
+
export {
|
|
56
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
57
|
+
useTriggerPopoverRootContext as unstable_useTriggerPopoverRootContext,
|
|
58
|
+
} from "./composer/trigger";
|
|
59
|
+
export {
|
|
60
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
61
|
+
useTriggerPopoverRootContextOptional as unstable_useTriggerPopoverRootContextOptional,
|
|
62
|
+
} from "./composer/trigger";
|
|
63
|
+
export {
|
|
64
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
65
|
+
useTriggerPopoverScopeContext as unstable_useTriggerPopoverScopeContext,
|
|
66
|
+
} from "./composer/trigger";
|
|
67
|
+
export {
|
|
68
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
69
|
+
useTriggerPopoverScopeContextOptional as unstable_useTriggerPopoverScopeContextOptional,
|
|
70
|
+
} from "./composer/trigger";
|
|
71
|
+
export {
|
|
72
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
73
|
+
useTriggerPopoverTriggers as unstable_useTriggerPopoverTriggers,
|
|
74
|
+
} from "./composer/trigger";
|
|
75
|
+
export {
|
|
76
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
77
|
+
useTriggerPopoverTriggersOptional as unstable_useTriggerPopoverTriggersOptional,
|
|
78
|
+
} from "./composer/trigger";
|
|
79
|
+
export type {
|
|
80
|
+
/** @deprecated Experimental since 2026-04-15. Not scheduled for removal; the API may change in any release. */
|
|
81
|
+
RegisteredTrigger as Unstable_RegisteredTrigger,
|
|
82
|
+
} from "./composer/trigger";
|
|
83
|
+
export type { TriggerMatch, TriggerMatcher } from "./composer/trigger";
|
|
84
|
+
/** @deprecated Use `TriggerMatcher` instead. */
|
|
85
|
+
export type Unstable_TriggerMatcher = TriggerMatcher;
|
|
86
|
+
/** @deprecated Use `TriggerMatch` instead. */
|
|
87
|
+
export type Unstable_TriggerMatch = TriggerMatch;
|
|
@@ -12,10 +12,12 @@ import { describe, expect, it } from "vitest";
|
|
|
12
12
|
import type { ThreadMessageLike } from "@assistant-ui/core";
|
|
13
13
|
import {
|
|
14
14
|
AssistantRuntimeProvider,
|
|
15
|
+
Tools,
|
|
15
16
|
useAssistantDataUI,
|
|
16
17
|
useExternalStoreRuntime,
|
|
17
18
|
} from "@assistant-ui/core/react";
|
|
18
|
-
import { useAui } from "@assistant-ui/store";
|
|
19
|
+
import { AuiConfig, useAui } from "@assistant-ui/store";
|
|
20
|
+
import { resource } from "@assistant-ui/tap";
|
|
19
21
|
import { ThreadPrimitiveMessageByIndex } from "../thread/ThreadMessages";
|
|
20
22
|
import {
|
|
21
23
|
type MessagePrimitiveUnstable_PartsGrouped,
|
|
@@ -48,6 +50,11 @@ const partsMessage =
|
|
|
48
50
|
const Named = () => <b>named</b>;
|
|
49
51
|
const Fallback = () => <i>fallback</i>;
|
|
50
52
|
const GlobalFallback = () => <b>global-fallback</b>;
|
|
53
|
+
const Mcp = () => <b>mcp</b>;
|
|
54
|
+
const McpApp = resource(function McpApp() {
|
|
55
|
+
return { render: Mcp };
|
|
56
|
+
});
|
|
57
|
+
const mcpConfig = AuiConfig({ tools: Tools({ mcpApp: McpApp() }) });
|
|
51
58
|
|
|
52
59
|
const RegisterFallbackDataUI: FC<{ render: typeof GlobalFallback }> = ({
|
|
53
60
|
render,
|
|
@@ -69,11 +76,13 @@ const Example = ({
|
|
|
69
76
|
content,
|
|
70
77
|
Message: MessageComponent = Message,
|
|
71
78
|
extra,
|
|
79
|
+
config,
|
|
72
80
|
isRunning = false,
|
|
73
81
|
}: {
|
|
74
82
|
content: ThreadMessageLike["content"];
|
|
75
83
|
Message?: FC;
|
|
76
84
|
extra?: ReactNode;
|
|
85
|
+
config?: AuiConfig;
|
|
77
86
|
isRunning?: boolean;
|
|
78
87
|
}) => {
|
|
79
88
|
const messages: ThreadMessageLike[] = [
|
|
@@ -86,7 +95,10 @@ const Example = ({
|
|
|
86
95
|
onNew: async () => {},
|
|
87
96
|
});
|
|
88
97
|
return (
|
|
89
|
-
<AssistantRuntimeProvider
|
|
98
|
+
<AssistantRuntimeProvider
|
|
99
|
+
runtime={runtime}
|
|
100
|
+
{...(config === undefined ? {} : { config })}
|
|
101
|
+
>
|
|
90
102
|
{extra}
|
|
91
103
|
<ThreadPrimitiveMessageByIndex
|
|
92
104
|
index={0}
|
|
@@ -439,6 +451,17 @@ describe("MessagePrimitive.Unstable_PartsGroupedByParentId", () => {
|
|
|
439
451
|
},
|
|
440
452
|
);
|
|
441
453
|
|
|
454
|
+
it("falls back to the default text component for an undefined slot", () => {
|
|
455
|
+
render(
|
|
456
|
+
<Example
|
|
457
|
+
content={[{ type: "text", text: "hello" }]}
|
|
458
|
+
Message={partsMessage({ Text: undefined })}
|
|
459
|
+
/>,
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
expect(screen.getByText("hello")).toBeTruthy();
|
|
463
|
+
});
|
|
464
|
+
|
|
442
465
|
it("renders tool and data UIs registered under an inherited name", () => {
|
|
443
466
|
const { container } = render(
|
|
444
467
|
<Example
|
|
@@ -461,6 +484,87 @@ describe("MessagePrimitive.Unstable_PartsGroupedByParentId", () => {
|
|
|
461
484
|
expect(container.innerHTML).toBe("<b>named</b><b>named</b>");
|
|
462
485
|
});
|
|
463
486
|
|
|
487
|
+
it("renders tools.mcpApp for a tool call with a ui:// resource", () => {
|
|
488
|
+
const { container } = render(
|
|
489
|
+
<Example
|
|
490
|
+
content={[
|
|
491
|
+
{
|
|
492
|
+
type: "tool-call",
|
|
493
|
+
toolCallId: "call",
|
|
494
|
+
toolName: "show_chart",
|
|
495
|
+
args: {},
|
|
496
|
+
mcp: { app: { resourceUri: "ui://chart" } },
|
|
497
|
+
},
|
|
498
|
+
]}
|
|
499
|
+
Message={partsMessage({ tools: { Fallback } })}
|
|
500
|
+
config={mcpConfig}
|
|
501
|
+
/>,
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
expect(container.innerHTML).toBe("<b>mcp</b>");
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it("prefers an inline by_name component over tools.mcpApp", () => {
|
|
508
|
+
const { container } = render(
|
|
509
|
+
<Example
|
|
510
|
+
content={[
|
|
511
|
+
{
|
|
512
|
+
type: "tool-call",
|
|
513
|
+
toolCallId: "call",
|
|
514
|
+
toolName: "show_chart",
|
|
515
|
+
args: {},
|
|
516
|
+
mcp: { app: { resourceUri: "ui://chart" } },
|
|
517
|
+
},
|
|
518
|
+
]}
|
|
519
|
+
Message={partsMessage({
|
|
520
|
+
tools: { by_name: { show_chart: Named }, Fallback },
|
|
521
|
+
})}
|
|
522
|
+
config={mcpConfig}
|
|
523
|
+
/>,
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
expect(container.innerHTML).toBe("<b>named</b>");
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it("uses inline Fallback when the tool call has no ui:// resource", () => {
|
|
530
|
+
const { container } = render(
|
|
531
|
+
<Example
|
|
532
|
+
content={[
|
|
533
|
+
{
|
|
534
|
+
type: "tool-call",
|
|
535
|
+
toolCallId: "call",
|
|
536
|
+
toolName: "show_chart",
|
|
537
|
+
args: {},
|
|
538
|
+
},
|
|
539
|
+
]}
|
|
540
|
+
Message={partsMessage({ tools: { Fallback } })}
|
|
541
|
+
config={mcpConfig}
|
|
542
|
+
/>,
|
|
543
|
+
);
|
|
544
|
+
|
|
545
|
+
expect(container.innerHTML).toBe("<i>fallback</i>");
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
it("uses inline Fallback when the resource URI is not an MCP App URI", () => {
|
|
549
|
+
const { container } = render(
|
|
550
|
+
<Example
|
|
551
|
+
content={[
|
|
552
|
+
{
|
|
553
|
+
type: "tool-call",
|
|
554
|
+
toolCallId: "call",
|
|
555
|
+
toolName: "show_chart",
|
|
556
|
+
args: {},
|
|
557
|
+
mcp: { app: { resourceUri: "https://example.com/chart" } },
|
|
558
|
+
},
|
|
559
|
+
]}
|
|
560
|
+
Message={partsMessage({ tools: { Fallback } })}
|
|
561
|
+
config={mcpConfig}
|
|
562
|
+
/>,
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
expect(container.innerHTML).toBe("<i>fallback</i>");
|
|
566
|
+
});
|
|
567
|
+
|
|
464
568
|
it("uses dataRenderers.fallbacks[0] before inline data.Fallback", async () => {
|
|
465
569
|
const { container } = render(
|
|
466
570
|
<Example
|
|
@@ -7,23 +7,23 @@ import {
|
|
|
7
7
|
type PropsWithChildren,
|
|
8
8
|
useMemo,
|
|
9
9
|
} from "react";
|
|
10
|
-
import { useAuiState
|
|
10
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
11
11
|
import { PartByIndexProvider } from "../../context/providers/PartByIndexProvider";
|
|
12
12
|
import { TextMessagePartProvider } from "../../context/providers/TextMessagePartProvider";
|
|
13
13
|
import { MessagePartPrimitiveText } from "../messagePart/MessagePartText";
|
|
14
14
|
import { MessagePartPrimitiveImage } from "../messagePart/MessagePartImage";
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
EmptyMessagePartComponent,
|
|
20
|
-
TextMessagePartComponent,
|
|
21
|
-
ImageMessagePartComponent,
|
|
22
|
-
SourceMessagePartComponent,
|
|
23
|
-
ToolCallMessagePartComponent,
|
|
24
|
-
ToolCallMessagePartProps,
|
|
25
|
-
FileMessagePartComponent,
|
|
26
|
-
ReasoningMessagePartComponent,
|
|
15
|
+
import {
|
|
16
|
+
MessagePartComponent,
|
|
17
|
+
type Unstable_AudioMessagePartComponent,
|
|
18
|
+
type DataMessagePartComponent,
|
|
19
|
+
type EmptyMessagePartComponent,
|
|
20
|
+
type TextMessagePartComponent,
|
|
21
|
+
type ImageMessagePartComponent,
|
|
22
|
+
type SourceMessagePartComponent,
|
|
23
|
+
type ToolCallMessagePartComponent,
|
|
24
|
+
type ToolCallMessagePartProps,
|
|
25
|
+
type FileMessagePartComponent,
|
|
26
|
+
type ReasoningMessagePartComponent,
|
|
27
27
|
} from "@assistant-ui/core/react";
|
|
28
28
|
import { MessagePartPrimitiveInProgress } from "../messagePart/MessagePartInProgress";
|
|
29
29
|
import type { MessagePartStatus } from "@assistant-ui/core";
|
|
@@ -86,6 +86,13 @@ const useMessagePartsGrouped = (
|
|
|
86
86
|
return { groups, partKeys: getMessagePartKeys(parts) };
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent
|
|
91
|
+
* grouping — it dispatches all rendering through one `switch (part.type)`
|
|
92
|
+
* and supports nested group paths. Keep this primitive only for
|
|
93
|
+
* non-adjacent clustering (e.g., gathering parts with the same parent-id
|
|
94
|
+
* across the message).
|
|
95
|
+
*/
|
|
89
96
|
export namespace MessagePrimitiveUnstable_PartsGrouped {
|
|
90
97
|
export type Props = {
|
|
91
98
|
/**
|
|
@@ -231,34 +238,6 @@ export namespace MessagePrimitiveUnstable_PartsGrouped {
|
|
|
231
238
|
};
|
|
232
239
|
}
|
|
233
240
|
|
|
234
|
-
const ToolUIDisplay = ({
|
|
235
|
-
Fallback,
|
|
236
|
-
...props
|
|
237
|
-
}: {
|
|
238
|
-
Fallback: ToolCallMessagePartComponent | undefined;
|
|
239
|
-
} & ToolCallMessagePartProps) => {
|
|
240
|
-
const Render = useAuiState(
|
|
241
|
-
(s) => s.tools.toolUIs[props.toolName]?.[0]?.render ?? Fallback,
|
|
242
|
-
);
|
|
243
|
-
if (!Render) return null;
|
|
244
|
-
return <Render {...props} />;
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const DataUIDisplay = ({
|
|
248
|
-
Fallback,
|
|
249
|
-
...props
|
|
250
|
-
}: {
|
|
251
|
-
Fallback: DataMessagePartComponent | undefined;
|
|
252
|
-
} & DataMessagePartProps) => {
|
|
253
|
-
const Render = useAuiState((s) => {
|
|
254
|
-
const named = s.dataRenderers.renderers[props.name]?.[0];
|
|
255
|
-
if (named) return named;
|
|
256
|
-
return s.dataRenderers.fallbacks[0] ?? Fallback;
|
|
257
|
-
});
|
|
258
|
-
if (!Render) return null;
|
|
259
|
-
return <Render {...props} />;
|
|
260
|
-
};
|
|
261
|
-
|
|
262
241
|
const defaultComponents = {
|
|
263
242
|
Text: () => (
|
|
264
243
|
<p style={{ whiteSpace: "pre-line" }}>
|
|
@@ -280,104 +259,17 @@ type MessagePartComponentProps = {
|
|
|
280
259
|
components: MessagePrimitiveUnstable_PartsGrouped.Props["components"];
|
|
281
260
|
};
|
|
282
261
|
|
|
283
|
-
const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
284
|
-
components: {
|
|
285
|
-
Text = defaultComponents.Text,
|
|
286
|
-
Reasoning = defaultComponents.Reasoning,
|
|
287
|
-
Image = defaultComponents.Image,
|
|
288
|
-
Source = defaultComponents.Source,
|
|
289
|
-
File = defaultComponents.File,
|
|
290
|
-
Unstable_Audio: Audio = defaultComponents.Unstable_Audio,
|
|
291
|
-
tools = {},
|
|
292
|
-
data,
|
|
293
|
-
} = {},
|
|
294
|
-
}) => {
|
|
295
|
-
const aui = useAui();
|
|
296
|
-
const part = useAuiState((s) => s.part);
|
|
297
|
-
|
|
298
|
-
const type = part.type;
|
|
299
|
-
if (type === "tool-call") {
|
|
300
|
-
const addResult = aui.part.addToolResult;
|
|
301
|
-
const resume = aui.part.resumeToolCall;
|
|
302
|
-
const respondToApproval = aui.part.respondToToolApproval;
|
|
303
|
-
const unstable_recordInteraction = aui.part.unstable_recordInteraction;
|
|
304
|
-
if ("Override" in tools)
|
|
305
|
-
return (
|
|
306
|
-
<tools.Override
|
|
307
|
-
{...part}
|
|
308
|
-
addResult={addResult}
|
|
309
|
-
resume={resume}
|
|
310
|
-
respondToApproval={respondToApproval}
|
|
311
|
-
{...(unstable_recordInteraction && { unstable_recordInteraction })}
|
|
312
|
-
/>
|
|
313
|
-
);
|
|
314
|
-
const Tool =
|
|
315
|
-
(tools.by_name && Object.hasOwn(tools.by_name, part.toolName)
|
|
316
|
-
? tools.by_name[part.toolName]
|
|
317
|
-
: undefined) ?? tools.Fallback;
|
|
318
|
-
return (
|
|
319
|
-
<ToolUIDisplay
|
|
320
|
-
{...part}
|
|
321
|
-
Fallback={Tool}
|
|
322
|
-
addResult={addResult}
|
|
323
|
-
resume={resume}
|
|
324
|
-
respondToApproval={respondToApproval}
|
|
325
|
-
{...(unstable_recordInteraction && { unstable_recordInteraction })}
|
|
326
|
-
/>
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (part.status?.type === "requires-action")
|
|
331
|
-
throw new Error("Encountered unexpected requires-action status");
|
|
332
|
-
|
|
333
|
-
switch (type) {
|
|
334
|
-
case "text":
|
|
335
|
-
return <Text {...part} />;
|
|
336
|
-
|
|
337
|
-
case "reasoning":
|
|
338
|
-
return <Reasoning {...part} />;
|
|
339
|
-
|
|
340
|
-
case "source":
|
|
341
|
-
return <Source {...part} />;
|
|
342
|
-
|
|
343
|
-
case "image":
|
|
344
|
-
return <Image {...part} />;
|
|
345
|
-
|
|
346
|
-
case "file":
|
|
347
|
-
return <File {...part} />;
|
|
348
|
-
|
|
349
|
-
case "audio":
|
|
350
|
-
return <Audio {...part} />;
|
|
351
|
-
|
|
352
|
-
case "data": {
|
|
353
|
-
const Data =
|
|
354
|
-
(data?.by_name && Object.hasOwn(data.by_name, part.name)
|
|
355
|
-
? data.by_name[part.name]
|
|
356
|
-
: undefined) ?? data?.Fallback;
|
|
357
|
-
return <DataUIDisplay {...part} Fallback={Data} />;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
default:
|
|
361
|
-
console.warn(`Unknown message part type: ${type}`);
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
|
|
366
262
|
type MessagePartProps = {
|
|
367
263
|
partIndex: number;
|
|
368
264
|
components: MessagePrimitiveUnstable_PartsGrouped.Props["components"];
|
|
369
265
|
};
|
|
370
266
|
|
|
371
|
-
const
|
|
372
|
-
|
|
267
|
+
const MessagePart = memo(
|
|
268
|
+
({ partIndex, components }: MessagePartProps) => (
|
|
373
269
|
<PartByIndexProvider index={partIndex}>
|
|
374
270
|
<MessagePartComponent components={components} />
|
|
375
271
|
</PartByIndexProvider>
|
|
376
|
-
)
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
const MessagePart = memo(
|
|
380
|
-
MessagePartImpl,
|
|
272
|
+
),
|
|
381
273
|
(prev, next) =>
|
|
382
274
|
prev.partIndex === next.partIndex &&
|
|
383
275
|
prev.components?.Text === next.components?.Text &&
|
|
@@ -387,8 +279,7 @@ const MessagePart = memo(
|
|
|
387
279
|
prev.components?.File === next.components?.File &&
|
|
388
280
|
prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&
|
|
389
281
|
prev.components?.tools === next.components?.tools &&
|
|
390
|
-
prev.components?.data === next.components?.data
|
|
391
|
-
prev.components?.Group === next.components?.Group,
|
|
282
|
+
prev.components?.data === next.components?.data,
|
|
392
283
|
);
|
|
393
284
|
|
|
394
285
|
const EmptyPartFallback: FC<{
|
|
@@ -473,6 +364,17 @@ export const MessagePrimitiveUnstable_PartsGrouped: FC<
|
|
|
473
364
|
return <EmptyParts components={components} />;
|
|
474
365
|
}
|
|
475
366
|
|
|
367
|
+
const leafComponents = {
|
|
368
|
+
...components,
|
|
369
|
+
Text: components?.Text ?? defaultComponents.Text,
|
|
370
|
+
Reasoning: components?.Reasoning ?? defaultComponents.Reasoning,
|
|
371
|
+
Image: components?.Image ?? defaultComponents.Image,
|
|
372
|
+
Source: components?.Source ?? defaultComponents.Source,
|
|
373
|
+
File: components?.File ?? defaultComponents.File,
|
|
374
|
+
Unstable_Audio:
|
|
375
|
+
components?.Unstable_Audio ?? defaultComponents.Unstable_Audio,
|
|
376
|
+
};
|
|
377
|
+
|
|
476
378
|
return messageGroups.map((group, groupIndex) => {
|
|
477
379
|
const GroupComponent = components?.Group ?? defaultComponents.Group;
|
|
478
380
|
const identity = partKeys[group.indices[0]!];
|
|
@@ -491,7 +393,7 @@ export const MessagePrimitiveUnstable_PartsGrouped: FC<
|
|
|
491
393
|
<MessagePart
|
|
492
394
|
key={partKeys[partIndex]}
|
|
493
395
|
partIndex={partIndex}
|
|
494
|
-
components={
|
|
396
|
+
components={leafComponents}
|
|
495
397
|
/>
|
|
496
398
|
))}
|
|
497
399
|
</GroupComponent>
|