@gram-ai/elements 1.27.4 → 1.27.5
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 +72 -60
- package/README.typedoc.md +6 -6
- package/bin/cli.js +74 -74
- package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
- package/dist/compat-shims-DxtUrORi.js.map +1 -0
- package/dist/components/ShareButton/index.d.ts +2 -2
- package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
- package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
- package/dist/components/ui/avatar.d.ts +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/calendar.d.ts +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +4 -4
- package/dist/components/ui/popover.d.ts +2 -2
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +1 -1
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +2 -2
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.js +2 -2
- package/dist/hooks/useDensity.d.ts +73 -73
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
- package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
- package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
- package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
- package/dist/{index-D0bAYNQy.js → index-DuCQRbcQ.js} +279 -265
- package/dist/index-DuCQRbcQ.js.map +1 -0
- package/dist/{index-KSX4Qjip.cjs → index-y_PNN5vK.cjs} +10 -10
- package/dist/index-y_PNN5vK.cjs.map +1 -0
- package/dist/lib/cassette.d.ts +4 -4
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +1 -1
- package/dist/lib/models.d.ts +1 -1
- package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-BFkhZRxj.js → profiler-FpBY9eRv.js} +2 -2
- package/dist/{profiler-BFkhZRxj.js.map → profiler-FpBY9eRv.js.map} +1 -1
- package/dist/{profiler-CyzxBxVz.cjs → profiler-_mthyjvo.cjs} +2 -2
- package/dist/{profiler-CyzxBxVz.cjs.map → profiler-_mthyjvo.cjs.map} +1 -1
- package/dist/react-shim.js +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/{startRecording-Dq92sEHf.cjs → startRecording-NJcpiHw-.cjs} +2 -2
- package/dist/{startRecording-Dq92sEHf.cjs.map → startRecording-NJcpiHw-.cjs.map} +1 -1
- package/dist/{startRecording-C-PPAs_Z.js → startRecording-r5MXQ2Dm.js} +2 -2
- package/dist/{startRecording-C-PPAs_Z.js.map → startRecording-r5MXQ2Dm.js.map} +1 -1
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -5
- package/src/compat-plugin.ts +14 -14
- package/src/compat-shims.ts +33 -31
- package/src/compat.test.ts +48 -48
- package/src/compat.ts +6 -6
- package/src/components/Chat/index.tsx +17 -17
- package/src/components/Chat/stories/Charts.stories.tsx +98 -98
- package/src/components/Chat/stories/Composer.stories.tsx +15 -15
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
- package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
- package/src/components/Chat/stories/Density.stories.tsx +20 -20
- package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
- package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
- package/src/components/Chat/stories/Modal.stories.tsx +28 -28
- package/src/components/Chat/stories/Model.stories.tsx +11 -11
- package/src/components/Chat/stories/Radius.stories.tsx +20 -20
- package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
- package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
- package/src/components/Chat/stories/Theme.stories.tsx +25 -25
- package/src/components/Chat/stories/Thread.stories.tsx +25 -25
- package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
- package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
- package/src/components/Chat/stories/Tools.stories.tsx +88 -88
- package/src/components/Chat/stories/Variants.stories.tsx +32 -32
- package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
- package/src/components/ChatHistory.tsx +7 -7
- package/src/components/FrontendTools/index.tsx +5 -5
- package/src/components/Replay.stories.tsx +157 -157
- package/src/components/Replay.tsx +76 -73
- package/src/components/ShadowRoot.tsx +40 -40
- package/src/components/ShareButton/index.tsx +32 -32
- package/src/components/assistant-ui/assistant-modal.tsx +92 -87
- package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
- package/src/components/assistant-ui/attachment.tsx +80 -80
- package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
- package/src/components/assistant-ui/error-boundary.tsx +34 -34
- package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
- package/src/components/assistant-ui/markdown-text.tsx +69 -69
- package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
- package/src/components/assistant-ui/message-feedback.tsx +57 -50
- package/src/components/assistant-ui/reasoning.tsx +83 -83
- package/src/components/assistant-ui/thread-list.tsx +45 -45
- package/src/components/assistant-ui/thread.tsx +278 -278
- package/src/components/assistant-ui/tool-fallback.tsx +37 -37
- package/src/components/assistant-ui/tool-group.tsx +26 -26
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
- package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
- package/src/components/ui/avatar.tsx +12 -12
- package/src/components/ui/button.tsx +12 -12
- package/src/components/ui/buttonVariants.ts +17 -17
- package/src/components/ui/calendar.tsx +106 -106
- package/src/components/ui/charts.stories.tsx +56 -56
- package/src/components/ui/collapsible.tsx +5 -5
- package/src/components/ui/dialog.tsx +30 -30
- package/src/components/ui/generative-ui.stories.tsx +200 -200
- package/src/components/ui/generative-ui.tsx +26 -26
- package/src/components/ui/popover.tsx +14 -14
- package/src/components/ui/skeleton.tsx +5 -5
- package/src/components/ui/time-range-picker.stories.tsx +80 -80
- package/src/components/ui/time-range-picker.tsx +245 -244
- package/src/components/ui/tool-ui.stories.tsx +37 -37
- package/src/components/ui/tool-ui.tsx +221 -215
- package/src/components/ui/tooltip.tsx +15 -15
- package/src/constants/tailwind.ts +1 -1
- package/src/contexts/ChatIdContext.tsx +7 -7
- package/src/contexts/ConnectionStatusContext.tsx +64 -64
- package/src/contexts/ElementsProvider.tsx +214 -213
- package/src/contexts/ReplayContext.ts +3 -3
- package/src/contexts/ToolApprovalContext.tsx +54 -54
- package/src/contexts/ToolExecutionContext.tsx +34 -34
- package/src/contexts/contexts.ts +7 -7
- package/src/contexts/portal-container-context.ts +2 -2
- package/src/contexts/portal-container.tsx +7 -7
- package/src/embedded.ts +1 -1
- package/src/global.css +25 -25
- package/src/hooks/useAuth.ts +72 -72
- package/src/hooks/useDensity.ts +79 -79
- package/src/hooks/useElements.ts +6 -6
- package/src/hooks/useExpanded.ts +12 -12
- package/src/hooks/useFollowOnSuggestions.ts +83 -83
- package/src/hooks/useGramThreadListAdapter.tsx +99 -99
- package/src/hooks/useMCPTools.ts +47 -47
- package/src/hooks/useModel.ts +14 -14
- package/src/hooks/usePluginComponents.ts +11 -11
- package/src/hooks/usePortalContainer.ts +5 -5
- package/src/hooks/useRadius.ts +23 -23
- package/src/hooks/useRecordCassette.ts +34 -34
- package/src/hooks/useSession.ts +11 -11
- package/src/hooks/useThemeProps.ts +13 -13
- package/src/hooks/useThreadId.ts +4 -4
- package/src/hooks/useToolApproval.ts +7 -7
- package/src/hooks/useToolMentions.ts +40 -40
- package/src/index.ts +26 -26
- package/src/lib/api.test.ts +61 -61
- package/src/lib/api.ts +4 -3
- package/src/lib/auth.ts +13 -13
- package/src/lib/cassette.ts +84 -84
- package/src/lib/easing.ts +1 -1
- package/src/lib/errorTracking.config.ts +5 -5
- package/src/lib/errorTracking.ts +29 -29
- package/src/lib/generative-ui.ts +7 -7
- package/src/lib/humanize.ts +3 -3
- package/src/lib/messageConverter.test.ts +130 -127
- package/src/lib/messageConverter.ts +196 -196
- package/src/lib/models.ts +21 -20
- package/src/lib/token.test.ts +56 -56
- package/src/lib/token.ts +14 -14
- package/src/lib/tool-mentions.ts +45 -45
- package/src/lib/tools.ts +66 -62
- package/src/lib/utils.ts +5 -5
- package/src/lib.d.ts +1 -1
- package/src/plugins/README.md +5 -5
- package/src/plugins/chart/catalog.ts +18 -18
- package/src/plugins/chart/chart.test.ts +31 -31
- package/src/plugins/chart/component.tsx +34 -34
- package/src/plugins/chart/index.ts +4 -4
- package/src/plugins/chart/ui/area-chart.tsx +42 -42
- package/src/plugins/chart/ui/bar-chart.tsx +46 -46
- package/src/plugins/chart/ui/donut-chart.tsx +48 -48
- package/src/plugins/chart/ui/index.ts +7 -7
- package/src/plugins/chart/ui/line-chart.tsx +43 -43
- package/src/plugins/chart/ui/pie-chart.tsx +44 -44
- package/src/plugins/chart/ui/radar-chart.tsx +33 -33
- package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
- package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
- package/src/plugins/components/PluginLoadingState.tsx +10 -10
- package/src/plugins/components/index.ts +1 -1
- package/src/plugins/generative-ui/catalog.ts +54 -54
- package/src/plugins/generative-ui/component.tsx +85 -85
- package/src/plugins/generative-ui/index.ts +4 -4
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
- package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
- package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/alert.tsx +20 -20
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
- package/src/plugins/generative-ui/ui/badge.tsx +22 -22
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
- package/src/plugins/generative-ui/ui/button.tsx +28 -28
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/card.tsx +27 -27
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
- package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
- package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
- package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
- package/src/plugins/generative-ui/ui/grid.tsx +12 -12
- package/src/plugins/generative-ui/ui/index.ts +40 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/input.tsx +9 -9
- package/src/plugins/generative-ui/ui/label.tsx +8 -8
- package/src/plugins/generative-ui/ui/list.tsx +11 -11
- package/src/plugins/generative-ui/ui/metric.tsx +23 -23
- package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
- package/src/plugins/generative-ui/ui/popover.tsx +21 -21
- package/src/plugins/generative-ui/ui/progress.tsx +13 -13
- package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/select.tsx +37 -37
- package/src/plugins/generative-ui/ui/separator.tsx +9 -9
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
- package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
- package/src/plugins/generative-ui/ui/stack.tsx +28 -28
- package/src/plugins/generative-ui/ui/switch.tsx +11 -11
- package/src/plugins/generative-ui/ui/table.tsx +32 -32
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
- package/src/plugins/generative-ui/ui/text.tsx +12 -12
- package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
- package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
- package/src/plugins/index.ts +7 -7
- package/src/react-shim.ts +6 -6
- package/src/server/bun.ts +12 -12
- package/src/server/core.ts +25 -25
- package/src/server/express.ts +17 -15
- package/src/server/fastify.ts +14 -14
- package/src/server/hono.ts +9 -9
- package/src/server/nextjs.ts +12 -12
- package/src/server/tanstack-start.ts +12 -12
- package/src/server.ts +27 -27
- package/src/storybook.d.ts +4 -4
- package/src/types/index.ts +122 -122
- package/src/types/plugins.ts +7 -7
- package/src/vite-env.d.ts +12 -12
- package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
- package/dist/index-D0bAYNQy.js.map +0 -1
- package/dist/index-KSX4Qjip.cjs.map +0 -1
|
@@ -19,24 +19,27 @@
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { ROOT_SELECTOR } from
|
|
23
|
-
import { ChatIdContext } from
|
|
24
|
-
import { ElementsContext } from
|
|
25
|
-
import { ReplayContext } from
|
|
26
|
-
import { ToolApprovalProvider } from
|
|
22
|
+
import { ROOT_SELECTOR } from "@/constants/tailwind";
|
|
23
|
+
import { ChatIdContext } from "@/contexts/ChatIdContext";
|
|
24
|
+
import { ElementsContext } from "@/contexts/contexts";
|
|
25
|
+
import { ReplayContext } from "@/contexts/ReplayContext";
|
|
26
|
+
import { ToolApprovalProvider } from "@/contexts/ToolApprovalContext";
|
|
27
27
|
import {
|
|
28
28
|
createReplayTransport,
|
|
29
29
|
type Cassette,
|
|
30
30
|
type ReplayOptions,
|
|
31
|
-
} from
|
|
32
|
-
import { MODELS } from
|
|
33
|
-
import { cn } from
|
|
34
|
-
import { recommended } from
|
|
35
|
-
import type { ElementsConfig } from
|
|
36
|
-
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
} from "@/lib/cassette";
|
|
32
|
+
import { MODELS } from "@/lib/models";
|
|
33
|
+
import { cn } from "@/lib/utils";
|
|
34
|
+
import { recommended } from "@/plugins";
|
|
35
|
+
import type { ElementsConfig } from "@/types";
|
|
36
|
+
import {
|
|
37
|
+
AssistantRuntimeProvider,
|
|
38
|
+
useThreadRuntime,
|
|
39
|
+
} from "@assistant-ui/react";
|
|
40
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
41
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
42
|
+
import { ReactNode, useEffect, useMemo, useRef } from "react";
|
|
40
43
|
|
|
41
44
|
// ---------------------------------------------------------------------------
|
|
42
45
|
// Replay component
|
|
@@ -44,13 +47,13 @@ import { ReactNode, useEffect, useMemo, useRef } from 'react'
|
|
|
44
47
|
|
|
45
48
|
export interface ReplayProps extends ReplayOptions {
|
|
46
49
|
/** The recorded cassette to replay. */
|
|
47
|
-
cassette: Cassette
|
|
48
|
-
children: ReactNode
|
|
50
|
+
cassette: Cassette;
|
|
51
|
+
children: ReactNode;
|
|
49
52
|
/** Optional ElementsConfig for visual customization (theme, variant, etc.) */
|
|
50
|
-
config?: Partial<ElementsConfig
|
|
53
|
+
config?: Partial<ElementsConfig>;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
const replayQueryClient = new QueryClient()
|
|
56
|
+
const replayQueryClient = new QueryClient();
|
|
54
57
|
|
|
55
58
|
export const Replay = ({
|
|
56
59
|
cassette,
|
|
@@ -66,21 +69,21 @@ export const Replay = ({
|
|
|
66
69
|
userMessageDelay,
|
|
67
70
|
assistantStartDelay,
|
|
68
71
|
onComplete,
|
|
69
|
-
}
|
|
72
|
+
};
|
|
70
73
|
|
|
71
74
|
const transport = useMemo(
|
|
72
75
|
() => createReplayTransport(cassette, replayOptions),
|
|
73
|
-
[cassette, typingSpeed, userMessageDelay, assistantStartDelay, onComplete]
|
|
74
|
-
)
|
|
76
|
+
[cassette, typingSpeed, userMessageDelay, assistantStartDelay, onComplete],
|
|
77
|
+
);
|
|
75
78
|
|
|
76
|
-
const runtime = useChatRuntime({ transport })
|
|
79
|
+
const runtime = useChatRuntime({ transport });
|
|
77
80
|
|
|
78
|
-
const plugins = partialConfig?.plugins ?? recommended
|
|
81
|
+
const plugins = partialConfig?.plugins ?? recommended;
|
|
79
82
|
|
|
80
83
|
// Build a minimal ElementsConfig for child components
|
|
81
84
|
const config: ElementsConfig = useMemo(
|
|
82
85
|
() => ({
|
|
83
|
-
projectSlug: partialConfig?.projectSlug ??
|
|
86
|
+
projectSlug: partialConfig?.projectSlug ?? "replay",
|
|
84
87
|
variant: partialConfig?.variant,
|
|
85
88
|
theme: partialConfig?.theme,
|
|
86
89
|
welcome: partialConfig?.welcome,
|
|
@@ -91,8 +94,8 @@ export const Replay = ({
|
|
|
91
94
|
modal: partialConfig?.modal,
|
|
92
95
|
sidecar: partialConfig?.sidecar,
|
|
93
96
|
}),
|
|
94
|
-
[partialConfig, plugins]
|
|
95
|
-
)
|
|
97
|
+
[partialConfig, plugins],
|
|
98
|
+
);
|
|
96
99
|
|
|
97
100
|
const contextValue = useMemo(
|
|
98
101
|
() => ({
|
|
@@ -106,12 +109,12 @@ export const Replay = ({
|
|
|
106
109
|
plugins,
|
|
107
110
|
mcpTools: undefined,
|
|
108
111
|
}),
|
|
109
|
-
[config, plugins]
|
|
110
|
-
)
|
|
112
|
+
[config, plugins],
|
|
113
|
+
);
|
|
111
114
|
|
|
112
|
-
const replayCtx = useMemo(() => ({ isReplay: true }), [])
|
|
115
|
+
const replayCtx = useMemo(() => ({ isReplay: true }), []);
|
|
113
116
|
|
|
114
|
-
const chatIdValue = useMemo(() => ({ chatId:
|
|
117
|
+
const chatIdValue = useMemo(() => ({ chatId: "replay" }), []);
|
|
115
118
|
|
|
116
119
|
return (
|
|
117
120
|
<QueryClientProvider client={replayQueryClient}>
|
|
@@ -123,9 +126,9 @@ export const Replay = ({
|
|
|
123
126
|
<div
|
|
124
127
|
className={cn(
|
|
125
128
|
ROOT_SELECTOR,
|
|
126
|
-
(config.variant ===
|
|
127
|
-
config.variant ===
|
|
128
|
-
|
|
129
|
+
(config.variant === "standalone" ||
|
|
130
|
+
config.variant === "sidecar") &&
|
|
131
|
+
"h-full min-h-0 flex-1",
|
|
129
132
|
)}
|
|
130
133
|
>
|
|
131
134
|
{children}
|
|
@@ -137,15 +140,15 @@ export const Replay = ({
|
|
|
137
140
|
</ReplayContext.Provider>
|
|
138
141
|
</AssistantRuntimeProvider>
|
|
139
142
|
</QueryClientProvider>
|
|
140
|
-
)
|
|
141
|
-
}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
142
145
|
|
|
143
146
|
// ---------------------------------------------------------------------------
|
|
144
147
|
// ReplayController - auto-submits user messages to drive the replay
|
|
145
148
|
// ---------------------------------------------------------------------------
|
|
146
149
|
|
|
147
150
|
function sleep(ms: number): Promise<void> {
|
|
148
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
151
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
/**
|
|
@@ -155,23 +158,23 @@ function sleep(ms: number): Promise<void> {
|
|
|
155
158
|
* it to return to false — otherwise we resolve before the run begins.
|
|
156
159
|
*/
|
|
157
160
|
async function waitForRunComplete(
|
|
158
|
-
runtime: NonNullable<ReturnType<typeof useThreadRuntime
|
|
161
|
+
runtime: NonNullable<ReturnType<typeof useThreadRuntime>>,
|
|
159
162
|
): Promise<void> {
|
|
160
163
|
// Phase 1: wait for the runtime to start running
|
|
161
164
|
if (!runtime.getState().isRunning) {
|
|
162
165
|
await new Promise<void>((resolve) => {
|
|
163
166
|
const unsub = runtime.subscribe(() => {
|
|
164
167
|
if (runtime.getState().isRunning) {
|
|
165
|
-
unsub()
|
|
166
|
-
resolve()
|
|
168
|
+
unsub();
|
|
169
|
+
resolve();
|
|
167
170
|
}
|
|
168
|
-
})
|
|
171
|
+
});
|
|
169
172
|
// Re-check in case it started between getState and subscribe
|
|
170
173
|
if (runtime.getState().isRunning) {
|
|
171
|
-
unsub()
|
|
172
|
-
resolve()
|
|
174
|
+
unsub();
|
|
175
|
+
resolve();
|
|
173
176
|
}
|
|
174
|
-
})
|
|
177
|
+
});
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
// Phase 2: wait for the runtime to stop running
|
|
@@ -179,68 +182,68 @@ async function waitForRunComplete(
|
|
|
179
182
|
await new Promise<void>((resolve) => {
|
|
180
183
|
const unsub = runtime.subscribe(() => {
|
|
181
184
|
if (!runtime.getState().isRunning) {
|
|
182
|
-
unsub()
|
|
183
|
-
resolve()
|
|
185
|
+
unsub();
|
|
186
|
+
resolve();
|
|
184
187
|
}
|
|
185
|
-
})
|
|
188
|
+
});
|
|
186
189
|
// Re-check in case it stopped between getState and subscribe
|
|
187
190
|
if (!runtime.getState().isRunning) {
|
|
188
|
-
unsub()
|
|
189
|
-
resolve()
|
|
191
|
+
unsub();
|
|
192
|
+
resolve();
|
|
190
193
|
}
|
|
191
|
-
})
|
|
194
|
+
});
|
|
192
195
|
}
|
|
193
196
|
}
|
|
194
197
|
|
|
195
198
|
interface ReplayControllerProps {
|
|
196
|
-
cassette: Cassette
|
|
197
|
-
options: ReplayOptions
|
|
199
|
+
cassette: Cassette;
|
|
200
|
+
options: ReplayOptions;
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
const ReplayController = ({ cassette, options }: ReplayControllerProps) => {
|
|
201
|
-
const runtime = useThreadRuntime()
|
|
202
|
-
const hasStarted = useRef(false)
|
|
204
|
+
const runtime = useThreadRuntime();
|
|
205
|
+
const hasStarted = useRef(false);
|
|
203
206
|
|
|
204
207
|
useEffect(() => {
|
|
205
|
-
if (hasStarted.current) return
|
|
206
|
-
hasStarted.current = true
|
|
208
|
+
if (hasStarted.current) return;
|
|
209
|
+
hasStarted.current = true;
|
|
207
210
|
|
|
208
|
-
const userMessageDelay = options.userMessageDelay ?? 800
|
|
209
|
-
let cancelled = false
|
|
211
|
+
const userMessageDelay = options.userMessageDelay ?? 800;
|
|
212
|
+
let cancelled = false;
|
|
210
213
|
|
|
211
214
|
const runReplay = async () => {
|
|
212
215
|
for (const msg of cassette.messages) {
|
|
213
|
-
if (cancelled) return
|
|
216
|
+
if (cancelled) return;
|
|
214
217
|
|
|
215
|
-
if (msg.role ===
|
|
216
|
-
await sleep(userMessageDelay)
|
|
217
|
-
if (cancelled) return
|
|
218
|
+
if (msg.role === "user") {
|
|
219
|
+
await sleep(userMessageDelay);
|
|
220
|
+
if (cancelled) return;
|
|
218
221
|
|
|
219
222
|
// Extract text from user content parts
|
|
220
223
|
const text = msg.content
|
|
221
|
-
.filter((p) => p.type ===
|
|
224
|
+
.filter((p) => p.type === "text")
|
|
222
225
|
.map((p) => p.text)
|
|
223
|
-
.join(
|
|
226
|
+
.join("\n");
|
|
224
227
|
|
|
225
228
|
// Append the user message — triggers transport.sendMessages
|
|
226
|
-
runtime.append(text)
|
|
229
|
+
runtime.append(text);
|
|
227
230
|
|
|
228
231
|
// Wait for the assistant response to finish streaming
|
|
229
|
-
await waitForRunComplete(runtime)
|
|
232
|
+
await waitForRunComplete(runtime);
|
|
230
233
|
}
|
|
231
234
|
// Assistant messages are handled by the transport's sendMessages,
|
|
232
235
|
// so we skip them here.
|
|
233
236
|
}
|
|
234
237
|
|
|
235
|
-
options.onComplete?.()
|
|
236
|
-
}
|
|
238
|
+
options.onComplete?.();
|
|
239
|
+
};
|
|
237
240
|
|
|
238
|
-
runReplay()
|
|
241
|
+
runReplay();
|
|
239
242
|
|
|
240
243
|
return () => {
|
|
241
|
-
cancelled = true
|
|
242
|
-
}
|
|
243
|
-
}, [])
|
|
244
|
+
cancelled = true;
|
|
245
|
+
};
|
|
246
|
+
}, []);
|
|
244
247
|
|
|
245
|
-
return null
|
|
246
|
-
}
|
|
248
|
+
return null;
|
|
249
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
useEffect,
|
|
@@ -7,19 +7,19 @@ import {
|
|
|
7
7
|
useState,
|
|
8
8
|
type CSSProperties,
|
|
9
9
|
type ReactNode,
|
|
10
|
-
} from
|
|
11
|
-
import { createPortal } from
|
|
12
|
-
import { PortalContainerProvider } from
|
|
13
|
-
import { useElements } from
|
|
14
|
-
import { useThemeProps } from
|
|
15
|
-
import { cn } from
|
|
16
|
-
import { ROOT_SELECTOR } from
|
|
17
|
-
import elementsStyles from
|
|
10
|
+
} from "react";
|
|
11
|
+
import { createPortal } from "react-dom";
|
|
12
|
+
import { PortalContainerProvider } from "@/contexts/portal-container";
|
|
13
|
+
import { useElements } from "@/hooks/useElements";
|
|
14
|
+
import { useThemeProps } from "@/hooks/useThemeProps";
|
|
15
|
+
import { cn } from "@/lib/utils";
|
|
16
|
+
import { ROOT_SELECTOR } from "@/constants/tailwind";
|
|
17
|
+
import elementsStyles from "@/global.css?inline";
|
|
18
18
|
|
|
19
19
|
interface ShadowRootProps {
|
|
20
|
-
children: ReactNode
|
|
21
|
-
hostClassName?: string
|
|
22
|
-
hostStyle?: CSSProperties
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
hostClassName?: string;
|
|
22
|
+
hostStyle?: CSSProperties;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export const ShadowRoot = ({
|
|
@@ -27,52 +27,52 @@ export const ShadowRoot = ({
|
|
|
27
27
|
hostClassName,
|
|
28
28
|
hostStyle,
|
|
29
29
|
}: ShadowRootProps) => {
|
|
30
|
-
const hostRef = useRef<HTMLDivElement>(null)
|
|
31
|
-
const containerRef = useRef<HTMLDivElement>(null)
|
|
32
|
-
const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null)
|
|
33
|
-
const { config } = useElements()
|
|
34
|
-
const themeProps = useThemeProps()
|
|
30
|
+
const hostRef = useRef<HTMLDivElement>(null);
|
|
31
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
32
|
+
const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);
|
|
33
|
+
const { config } = useElements();
|
|
34
|
+
const themeProps = useThemeProps();
|
|
35
35
|
|
|
36
36
|
const rootClassName = useMemo(
|
|
37
37
|
() => cn(ROOT_SELECTOR, themeProps.className),
|
|
38
|
-
[themeProps.className]
|
|
39
|
-
)
|
|
38
|
+
[themeProps.className],
|
|
39
|
+
);
|
|
40
40
|
|
|
41
41
|
useEffect(() => {
|
|
42
|
-
const host = hostRef.current
|
|
42
|
+
const host = hostRef.current;
|
|
43
43
|
if (!host) {
|
|
44
|
-
return
|
|
44
|
+
return;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const root = host.shadowRoot ?? host.attachShadow({ mode:
|
|
48
|
-
setShadowRoot(root)
|
|
49
|
-
}, [])
|
|
47
|
+
const root = host.shadowRoot ?? host.attachShadow({ mode: "open" });
|
|
48
|
+
setShadowRoot(root);
|
|
49
|
+
}, []);
|
|
50
50
|
|
|
51
51
|
useEffect(() => {
|
|
52
52
|
if (!shadowRoot) {
|
|
53
|
-
return
|
|
53
|
+
return;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const existingStyle = shadowRoot.querySelector<HTMLStyleElement>(
|
|
57
|
-
|
|
58
|
-
)
|
|
57
|
+
"style[data-gram-elements]",
|
|
58
|
+
);
|
|
59
59
|
|
|
60
60
|
if (existingStyle) {
|
|
61
|
-
existingStyle.textContent = elementsStyles
|
|
62
|
-
return
|
|
61
|
+
existingStyle.textContent = elementsStyles;
|
|
62
|
+
return;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const styleElement = document.createElement(
|
|
66
|
-
styleElement.setAttribute(
|
|
67
|
-
styleElement.textContent = elementsStyles
|
|
68
|
-
shadowRoot.prepend(styleElement)
|
|
69
|
-
}, [shadowRoot, elementsStyles])
|
|
65
|
+
const styleElement = document.createElement("style");
|
|
66
|
+
styleElement.setAttribute("data-gram-elements", "true");
|
|
67
|
+
styleElement.textContent = elementsStyles;
|
|
68
|
+
shadowRoot.prepend(styleElement);
|
|
69
|
+
}, [shadowRoot, elementsStyles]);
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
72
|
<div
|
|
73
73
|
ref={hostRef}
|
|
74
74
|
className={hostClassName}
|
|
75
|
-
style={{ isolation:
|
|
75
|
+
style={{ isolation: "isolate", ...hostStyle }}
|
|
76
76
|
>
|
|
77
77
|
{shadowRoot
|
|
78
78
|
? createPortal(
|
|
@@ -81,8 +81,8 @@ export const ShadowRoot = ({
|
|
|
81
81
|
className={rootClassName}
|
|
82
82
|
data-radius={config.theme?.radius}
|
|
83
83
|
style={
|
|
84
|
-
config.variant ===
|
|
85
|
-
? { height:
|
|
84
|
+
config.variant === "standalone"
|
|
85
|
+
? { height: "100%", width: "100%" }
|
|
86
86
|
: undefined
|
|
87
87
|
}
|
|
88
88
|
>
|
|
@@ -90,9 +90,9 @@ export const ShadowRoot = ({
|
|
|
90
90
|
{children}
|
|
91
91
|
</PortalContainerProvider>
|
|
92
92
|
</div>,
|
|
93
|
-
shadowRoot
|
|
93
|
+
shadowRoot,
|
|
94
94
|
)
|
|
95
95
|
: null}
|
|
96
96
|
</div>
|
|
97
|
-
)
|
|
98
|
-
}
|
|
97
|
+
);
|
|
98
|
+
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import { Link } from
|
|
4
|
-
import { useCallback } from
|
|
3
|
+
import { Link } from "lucide-react";
|
|
4
|
+
import { useCallback } from "react";
|
|
5
5
|
|
|
6
|
-
import { Button } from
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
7
|
import {
|
|
8
8
|
Tooltip,
|
|
9
9
|
TooltipContent,
|
|
10
10
|
TooltipTrigger,
|
|
11
|
-
} from
|
|
12
|
-
import { useThreadId } from
|
|
13
|
-
import { cn } from
|
|
11
|
+
} from "@/components/ui/tooltip";
|
|
12
|
+
import { useThreadId } from "@/hooks/useThreadId";
|
|
13
|
+
import { cn } from "@/lib/utils";
|
|
14
14
|
|
|
15
15
|
export interface ShareButtonProps {
|
|
16
16
|
/**
|
|
@@ -18,35 +18,35 @@ export interface ShareButtonProps {
|
|
|
18
18
|
* Receives the share URL on success, or an Error on failure.
|
|
19
19
|
* Use this to show toast notifications or track analytics.
|
|
20
20
|
*/
|
|
21
|
-
onShare?: (result: { url: string } | { error: Error }) => void
|
|
21
|
+
onShare?: (result: { url: string } | { error: Error }) => void;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Custom URL builder. By default, appends `?threadId={id}` to current URL.
|
|
25
25
|
* Return the full share URL.
|
|
26
26
|
*/
|
|
27
|
-
buildShareUrl?: (threadId: string) => string
|
|
27
|
+
buildShareUrl?: (threadId: string) => string;
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Button variant
|
|
31
31
|
* @default "ghost"
|
|
32
32
|
*/
|
|
33
|
-
variant?:
|
|
33
|
+
variant?: "ghost" | "outline" | "default";
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Button size
|
|
37
37
|
* @default "sm"
|
|
38
38
|
*/
|
|
39
|
-
size?:
|
|
39
|
+
size?: "sm" | "default" | "lg" | "icon";
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Additional CSS classes
|
|
43
43
|
*/
|
|
44
|
-
className?: string
|
|
44
|
+
className?: string;
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Custom button content. If not provided, shows icon + "Share chat"
|
|
48
48
|
*/
|
|
49
|
-
children?: React.ReactNode
|
|
49
|
+
children?: React.ReactNode;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**
|
|
@@ -76,19 +76,19 @@ export interface ShareButtonProps {
|
|
|
76
76
|
export function ShareButton({
|
|
77
77
|
onShare,
|
|
78
78
|
buildShareUrl,
|
|
79
|
-
variant =
|
|
80
|
-
size =
|
|
79
|
+
variant = "ghost",
|
|
80
|
+
size = "sm",
|
|
81
81
|
className,
|
|
82
82
|
children,
|
|
83
83
|
}: ShareButtonProps) {
|
|
84
|
-
const { threadId } = useThreadId()
|
|
84
|
+
const { threadId } = useThreadId();
|
|
85
85
|
|
|
86
86
|
const handleShare = useCallback(async () => {
|
|
87
87
|
if (!threadId) {
|
|
88
88
|
onShare?.({
|
|
89
|
-
error: new Error(
|
|
90
|
-
})
|
|
91
|
-
return
|
|
89
|
+
error: new Error("No chat to share yet. Send a message first."),
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
try {
|
|
@@ -96,21 +96,21 @@ export function ShareButton({
|
|
|
96
96
|
const shareUrl = buildShareUrl
|
|
97
97
|
? buildShareUrl(threadId)
|
|
98
98
|
: (() => {
|
|
99
|
-
const url = new URL(window.location.href)
|
|
100
|
-
url.searchParams.set(
|
|
101
|
-
return url.toString()
|
|
102
|
-
})()
|
|
99
|
+
const url = new URL(window.location.href);
|
|
100
|
+
url.searchParams.set("threadId", threadId);
|
|
101
|
+
return url.toString();
|
|
102
|
+
})();
|
|
103
103
|
|
|
104
104
|
// Copy to clipboard
|
|
105
|
-
await navigator.clipboard.writeText(shareUrl)
|
|
106
|
-
onShare?.({ url: shareUrl })
|
|
105
|
+
await navigator.clipboard.writeText(shareUrl);
|
|
106
|
+
onShare?.({ url: shareUrl });
|
|
107
107
|
} catch (error) {
|
|
108
108
|
onShare?.({
|
|
109
109
|
error:
|
|
110
|
-
error instanceof Error ? error : new Error(
|
|
111
|
-
})
|
|
110
|
+
error instanceof Error ? error : new Error("Failed to copy link"),
|
|
111
|
+
});
|
|
112
112
|
}
|
|
113
|
-
}, [threadId, buildShareUrl, onShare])
|
|
113
|
+
}, [threadId, buildShareUrl, onShare]);
|
|
114
114
|
|
|
115
115
|
return (
|
|
116
116
|
<Tooltip>
|
|
@@ -120,7 +120,7 @@ export function ShareButton({
|
|
|
120
120
|
size={size}
|
|
121
121
|
onClick={handleShare}
|
|
122
122
|
disabled={!threadId}
|
|
123
|
-
className={cn(
|
|
123
|
+
className={cn("aui-share-button", className)}
|
|
124
124
|
aria-label="Share chat"
|
|
125
125
|
>
|
|
126
126
|
{children ?? (
|
|
@@ -133,9 +133,9 @@ export function ShareButton({
|
|
|
133
133
|
</TooltipTrigger>
|
|
134
134
|
<TooltipContent>
|
|
135
135
|
{threadId
|
|
136
|
-
?
|
|
137
|
-
:
|
|
136
|
+
? "Copy chat link to clipboard"
|
|
137
|
+
: "Send a message first to share"}
|
|
138
138
|
</TooltipContent>
|
|
139
139
|
</Tooltip>
|
|
140
|
-
)
|
|
140
|
+
);
|
|
141
141
|
}
|