@gram-ai/elements 1.27.3 → 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.
Files changed (278) hide show
  1. package/README.md +72 -60
  2. package/README.typedoc.md +6 -6
  3. package/bin/cli.js +74 -74
  4. package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
  5. package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
  6. package/dist/compat-shims-DxtUrORi.js.map +1 -0
  7. package/dist/components/ShareButton/index.d.ts +2 -2
  8. package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
  9. package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
  10. package/dist/components/ui/avatar.d.ts +2 -2
  11. package/dist/components/ui/button.d.ts +1 -1
  12. package/dist/components/ui/calendar.d.ts +1 -1
  13. package/dist/components/ui/collapsible.d.ts +1 -1
  14. package/dist/components/ui/dialog.d.ts +4 -4
  15. package/dist/components/ui/popover.d.ts +2 -2
  16. package/dist/components/ui/skeleton.d.ts +1 -1
  17. package/dist/components/ui/time-range-picker.d.ts +4 -2
  18. package/dist/components/ui/tool-ui.d.ts +7 -7
  19. package/dist/components/ui/tooltip.d.ts +2 -2
  20. package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
  21. package/dist/elements.cjs +1 -1
  22. package/dist/elements.css +1 -1
  23. package/dist/elements.js +2 -2
  24. package/dist/hooks/useDensity.d.ts +73 -73
  25. package/dist/hooks/useMCPTools.d.ts +1 -1
  26. package/dist/hooks/useRadius.d.ts +1 -1
  27. package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
  28. package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
  29. package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
  30. package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
  31. package/dist/{index-DBrhzauj.js → index-DuCQRbcQ.js} +6386 -6337
  32. package/dist/index-DuCQRbcQ.js.map +1 -0
  33. package/dist/{index-DxfW52oA.cjs → index-y_PNN5vK.cjs} +64 -46
  34. package/dist/index-y_PNN5vK.cjs.map +1 -0
  35. package/dist/lib/cassette.d.ts +4 -4
  36. package/dist/lib/errorTracking.d.ts +1 -1
  37. package/dist/lib/messageConverter.d.ts +1 -1
  38. package/dist/lib/models.d.ts +1 -1
  39. package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
  40. package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
  41. package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
  42. package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
  43. package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
  44. package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
  45. package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
  46. package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
  47. package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
  48. package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
  49. package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
  50. package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
  51. package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
  52. package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
  53. package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
  54. package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
  55. package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
  56. package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
  57. package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
  58. package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
  59. package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
  60. package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
  61. package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
  62. package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
  63. package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
  64. package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
  65. package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
  66. package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
  67. package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
  68. package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
  69. package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
  70. package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
  71. package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
  72. package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
  73. package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
  74. package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
  75. package/dist/plugins.cjs +1 -1
  76. package/dist/plugins.js +1 -1
  77. package/dist/{profiler-D6ndqfsd.js → profiler-FpBY9eRv.js} +2 -2
  78. package/dist/{profiler-D6ndqfsd.js.map → profiler-FpBY9eRv.js.map} +1 -1
  79. package/dist/{profiler-DhnzZ34c.cjs → profiler-_mthyjvo.cjs} +2 -2
  80. package/dist/{profiler-DhnzZ34c.cjs.map → profiler-_mthyjvo.cjs.map} +1 -1
  81. package/dist/react-shim.js +1 -1
  82. package/dist/server/express.cjs.map +1 -1
  83. package/dist/server/express.js.map +1 -1
  84. package/dist/{startRecording-BwXmdmy1.cjs → startRecording-NJcpiHw-.cjs} +2 -2
  85. package/dist/{startRecording-BwXmdmy1.cjs.map → startRecording-NJcpiHw-.cjs.map} +1 -1
  86. package/dist/{startRecording-B_9CRZ_P.js → startRecording-r5MXQ2Dm.js} +2 -2
  87. package/dist/{startRecording-B_9CRZ_P.js.map → startRecording-r5MXQ2Dm.js.map} +1 -1
  88. package/dist/types/index.d.ts +2 -2
  89. package/package.json +1 -5
  90. package/src/compat-plugin.ts +14 -14
  91. package/src/compat-shims.ts +33 -31
  92. package/src/compat.test.ts +48 -48
  93. package/src/compat.ts +6 -6
  94. package/src/components/Chat/index.tsx +17 -17
  95. package/src/components/Chat/stories/Charts.stories.tsx +98 -98
  96. package/src/components/Chat/stories/Composer.stories.tsx +15 -15
  97. package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
  98. package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
  99. package/src/components/Chat/stories/Density.stories.tsx +20 -20
  100. package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
  101. package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
  102. package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
  103. package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
  104. package/src/components/Chat/stories/Modal.stories.tsx +28 -28
  105. package/src/components/Chat/stories/Model.stories.tsx +11 -11
  106. package/src/components/Chat/stories/Radius.stories.tsx +20 -20
  107. package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
  108. package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
  109. package/src/components/Chat/stories/Theme.stories.tsx +25 -25
  110. package/src/components/Chat/stories/Thread.stories.tsx +25 -25
  111. package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
  112. package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
  113. package/src/components/Chat/stories/Tools.stories.tsx +88 -88
  114. package/src/components/Chat/stories/Variants.stories.tsx +32 -32
  115. package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
  116. package/src/components/ChatHistory.tsx +7 -7
  117. package/src/components/FrontendTools/index.tsx +5 -5
  118. package/src/components/Replay.stories.tsx +157 -157
  119. package/src/components/Replay.tsx +76 -73
  120. package/src/components/ShadowRoot.tsx +40 -40
  121. package/src/components/ShareButton/index.tsx +32 -32
  122. package/src/components/assistant-ui/assistant-modal.tsx +92 -87
  123. package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
  124. package/src/components/assistant-ui/attachment.tsx +80 -80
  125. package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
  126. package/src/components/assistant-ui/error-boundary.tsx +34 -34
  127. package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
  128. package/src/components/assistant-ui/markdown-text.tsx +69 -69
  129. package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
  130. package/src/components/assistant-ui/message-feedback.tsx +74 -61
  131. package/src/components/assistant-ui/reasoning.tsx +83 -83
  132. package/src/components/assistant-ui/thread-list.tsx +45 -45
  133. package/src/components/assistant-ui/thread.tsx +278 -278
  134. package/src/components/assistant-ui/tool-fallback.tsx +37 -37
  135. package/src/components/assistant-ui/tool-group.tsx +26 -26
  136. package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
  137. package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
  138. package/src/components/ui/avatar.tsx +12 -12
  139. package/src/components/ui/button.tsx +12 -12
  140. package/src/components/ui/buttonVariants.ts +17 -17
  141. package/src/components/ui/calendar.tsx +106 -106
  142. package/src/components/ui/charts.stories.tsx +56 -56
  143. package/src/components/ui/collapsible.tsx +5 -5
  144. package/src/components/ui/dialog.tsx +30 -30
  145. package/src/components/ui/generative-ui.stories.tsx +200 -200
  146. package/src/components/ui/generative-ui.tsx +26 -26
  147. package/src/components/ui/popover.tsx +14 -14
  148. package/src/components/ui/skeleton.tsx +5 -5
  149. package/src/components/ui/time-range-picker.stories.tsx +80 -80
  150. package/src/components/ui/time-range-picker.tsx +272 -235
  151. package/src/components/ui/tool-ui.stories.tsx +37 -37
  152. package/src/components/ui/tool-ui.tsx +221 -215
  153. package/src/components/ui/tooltip.tsx +15 -15
  154. package/src/constants/tailwind.ts +1 -1
  155. package/src/contexts/ChatIdContext.tsx +7 -7
  156. package/src/contexts/ConnectionStatusContext.tsx +64 -64
  157. package/src/contexts/ElementsProvider.tsx +222 -211
  158. package/src/contexts/ReplayContext.ts +3 -3
  159. package/src/contexts/ToolApprovalContext.tsx +54 -54
  160. package/src/contexts/ToolExecutionContext.tsx +34 -34
  161. package/src/contexts/contexts.ts +7 -7
  162. package/src/contexts/portal-container-context.ts +2 -2
  163. package/src/contexts/portal-container.tsx +7 -7
  164. package/src/embedded.ts +1 -1
  165. package/src/global.css +25 -25
  166. package/src/hooks/useAuth.ts +72 -72
  167. package/src/hooks/useDensity.ts +79 -79
  168. package/src/hooks/useElements.ts +6 -6
  169. package/src/hooks/useExpanded.ts +12 -12
  170. package/src/hooks/useFollowOnSuggestions.ts +87 -82
  171. package/src/hooks/useGramThreadListAdapter.tsx +99 -99
  172. package/src/hooks/useMCPTools.ts +47 -47
  173. package/src/hooks/useModel.ts +14 -14
  174. package/src/hooks/usePluginComponents.ts +11 -11
  175. package/src/hooks/usePortalContainer.ts +5 -5
  176. package/src/hooks/useRadius.ts +23 -23
  177. package/src/hooks/useRecordCassette.ts +34 -34
  178. package/src/hooks/useSession.ts +11 -11
  179. package/src/hooks/useThemeProps.ts +13 -13
  180. package/src/hooks/useThreadId.ts +4 -4
  181. package/src/hooks/useToolApproval.ts +7 -7
  182. package/src/hooks/useToolMentions.ts +40 -40
  183. package/src/index.ts +26 -26
  184. package/src/lib/api.test.ts +61 -61
  185. package/src/lib/api.ts +4 -3
  186. package/src/lib/auth.ts +13 -13
  187. package/src/lib/cassette.ts +84 -84
  188. package/src/lib/easing.ts +1 -1
  189. package/src/lib/errorTracking.config.ts +5 -5
  190. package/src/lib/errorTracking.ts +29 -29
  191. package/src/lib/generative-ui.ts +7 -7
  192. package/src/lib/humanize.ts +3 -3
  193. package/src/lib/messageConverter.test.ts +130 -127
  194. package/src/lib/messageConverter.ts +196 -196
  195. package/src/lib/models.ts +21 -20
  196. package/src/lib/token.test.ts +56 -56
  197. package/src/lib/token.ts +14 -14
  198. package/src/lib/tool-mentions.ts +45 -45
  199. package/src/lib/tools.ts +66 -62
  200. package/src/lib/utils.ts +5 -5
  201. package/src/lib.d.ts +1 -1
  202. package/src/plugins/README.md +5 -5
  203. package/src/plugins/chart/catalog.ts +18 -18
  204. package/src/plugins/chart/chart.test.ts +31 -31
  205. package/src/plugins/chart/component.tsx +34 -34
  206. package/src/plugins/chart/index.ts +4 -4
  207. package/src/plugins/chart/ui/area-chart.tsx +42 -42
  208. package/src/plugins/chart/ui/bar-chart.tsx +46 -46
  209. package/src/plugins/chart/ui/donut-chart.tsx +48 -48
  210. package/src/plugins/chart/ui/index.ts +7 -7
  211. package/src/plugins/chart/ui/line-chart.tsx +43 -43
  212. package/src/plugins/chart/ui/pie-chart.tsx +44 -44
  213. package/src/plugins/chart/ui/radar-chart.tsx +33 -33
  214. package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
  215. package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
  216. package/src/plugins/components/PluginLoadingState.tsx +10 -10
  217. package/src/plugins/components/index.ts +1 -1
  218. package/src/plugins/generative-ui/catalog.ts +54 -54
  219. package/src/plugins/generative-ui/component.tsx +85 -85
  220. package/src/plugins/generative-ui/index.ts +4 -4
  221. package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
  222. package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
  223. package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
  224. package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
  225. package/src/plugins/generative-ui/ui/alert.tsx +20 -20
  226. package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
  227. package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
  228. package/src/plugins/generative-ui/ui/badge.tsx +22 -22
  229. package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
  230. package/src/plugins/generative-ui/ui/button.tsx +28 -28
  231. package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
  232. package/src/plugins/generative-ui/ui/card.tsx +27 -27
  233. package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
  234. package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
  235. package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
  236. package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
  237. package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
  238. package/src/plugins/generative-ui/ui/grid.tsx +12 -12
  239. package/src/plugins/generative-ui/ui/index.ts +40 -40
  240. package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
  241. package/src/plugins/generative-ui/ui/input.tsx +9 -9
  242. package/src/plugins/generative-ui/ui/label.tsx +8 -8
  243. package/src/plugins/generative-ui/ui/list.tsx +11 -11
  244. package/src/plugins/generative-ui/ui/metric.tsx +23 -23
  245. package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
  246. package/src/plugins/generative-ui/ui/popover.tsx +21 -21
  247. package/src/plugins/generative-ui/ui/progress.tsx +13 -13
  248. package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
  249. package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
  250. package/src/plugins/generative-ui/ui/select.tsx +37 -37
  251. package/src/plugins/generative-ui/ui/separator.tsx +9 -9
  252. package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
  253. package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
  254. package/src/plugins/generative-ui/ui/stack.tsx +28 -28
  255. package/src/plugins/generative-ui/ui/switch.tsx +11 -11
  256. package/src/plugins/generative-ui/ui/table.tsx +32 -32
  257. package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
  258. package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
  259. package/src/plugins/generative-ui/ui/text.tsx +12 -12
  260. package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
  261. package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
  262. package/src/plugins/index.ts +7 -7
  263. package/src/react-shim.ts +6 -6
  264. package/src/server/bun.ts +12 -12
  265. package/src/server/core.ts +25 -25
  266. package/src/server/express.ts +17 -15
  267. package/src/server/fastify.ts +14 -14
  268. package/src/server/hono.ts +9 -9
  269. package/src/server/nextjs.ts +12 -12
  270. package/src/server/tanstack-start.ts +12 -12
  271. package/src/server.ts +27 -27
  272. package/src/storybook.d.ts +4 -4
  273. package/src/types/index.ts +122 -122
  274. package/src/types/plugins.ts +7 -7
  275. package/src/vite-env.d.ts +12 -12
  276. package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
  277. package/dist/index-DBrhzauj.js.map +0 -1
  278. package/dist/index-DxfW52oA.cjs.map +0 -1
@@ -19,24 +19,27 @@
19
19
  * ```
20
20
  */
21
21
 
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'
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 '@/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 { AssistantRuntimeProvider, useThreadRuntime } from '@assistant-ui/react'
37
- import { useChatRuntime } from '@assistant-ui/react-ai-sdk'
38
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
39
- import { ReactNode, useEffect, useMemo, useRef } from 'react'
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 ?? 'replay',
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: 'replay' }), [])
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 === 'standalone' ||
127
- config.variant === 'sidecar') &&
128
- 'h-full min-h-0 flex-1'
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 === 'user') {
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 === 'text')
224
+ .filter((p) => p.type === "text")
222
225
  .map((p) => p.text)
223
- .join('\n')
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
- 'use client'
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 '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'
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: 'open' })
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
- 'style[data-gram-elements]'
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('style')
66
- styleElement.setAttribute('data-gram-elements', 'true')
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: 'isolate', ...hostStyle }}
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 === 'standalone'
85
- ? { height: '100%', width: '100%' }
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
- 'use client'
1
+ "use client";
2
2
 
3
- import { Link } from 'lucide-react'
4
- import { useCallback } from 'react'
3
+ import { Link } from "lucide-react";
4
+ import { useCallback } from "react";
5
5
 
6
- import { Button } from '@/components/ui/button'
6
+ import { Button } from "@/components/ui/button";
7
7
  import {
8
8
  Tooltip,
9
9
  TooltipContent,
10
10
  TooltipTrigger,
11
- } from '@/components/ui/tooltip'
12
- import { useThreadId } from '@/hooks/useThreadId'
13
- import { cn } from '@/lib/utils'
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?: 'ghost' | 'outline' | 'default'
33
+ variant?: "ghost" | "outline" | "default";
34
34
 
35
35
  /**
36
36
  * Button size
37
37
  * @default "sm"
38
38
  */
39
- size?: 'sm' | 'default' | 'lg' | 'icon'
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 = 'ghost',
80
- size = 'sm',
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('No chat to share yet. Send a message first.'),
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('threadId', threadId)
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('Failed to copy link'),
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('aui-share-button', className)}
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
- ? 'Copy chat link to clipboard'
137
- : 'Send a message first to share'}
136
+ ? "Copy chat link to clipboard"
137
+ : "Send a message first to share"}
138
138
  </TooltipContent>
139
139
  </Tooltip>
140
- )
140
+ );
141
141
  }