@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
@@ -1,7 +1,7 @@
1
- 'use client'
1
+ "use client";
2
2
 
3
- import { useContext } from 'react'
4
- import { PortalContainerContext } from '@/contexts/portal-container-context'
3
+ import { useContext } from "react";
4
+ import { PortalContainerContext } from "@/contexts/portal-container-context";
5
5
 
6
6
  /**
7
7
  * Because we do not want Tailwind to leak from the Elements library, and
@@ -11,6 +11,6 @@ import { PortalContainerContext } from '@/contexts/portal-container-context'
11
11
  * scope so that they still inherit the Elements CSS
12
12
  */
13
13
  export function usePortalContainer(): HTMLElement | null {
14
- const ref = useContext(PortalContainerContext)
15
- return ref?.current ?? null
14
+ const ref = useContext(PortalContainerContext);
15
+ return ref?.current ?? null;
16
16
  }
@@ -1,42 +1,42 @@
1
- import { Radius } from '@/types'
2
- import { useElements } from './useElements'
1
+ import { Radius } from "@/types";
2
+ import { useElements } from "./useElements";
3
3
 
4
4
  /**
5
5
  * Radius class mappings for different UI elements
6
6
  */
7
7
  const radiusClasses: Record<Radius, Record<RadiusSize, string>> = {
8
8
  sharp: {
9
- sm: 'rounded-sm',
10
- md: 'rounded',
11
- lg: 'rounded-md',
12
- xl: 'rounded-lg',
13
- full: 'rounded-lg',
9
+ sm: "rounded-sm",
10
+ md: "rounded",
11
+ lg: "rounded-md",
12
+ xl: "rounded-lg",
13
+ full: "rounded-lg",
14
14
  },
15
15
  soft: {
16
- sm: 'rounded',
17
- md: 'rounded-lg',
18
- lg: 'rounded-xl',
19
- xl: 'rounded-2xl',
20
- full: 'rounded-full',
16
+ sm: "rounded",
17
+ md: "rounded-lg",
18
+ lg: "rounded-xl",
19
+ xl: "rounded-2xl",
20
+ full: "rounded-full",
21
21
  },
22
22
  round: {
23
- sm: 'rounded-lg',
24
- md: 'rounded-xl',
25
- lg: 'rounded-2xl',
26
- xl: 'rounded-3xl',
27
- full: 'rounded-full',
23
+ sm: "rounded-lg",
24
+ md: "rounded-xl",
25
+ lg: "rounded-2xl",
26
+ xl: "rounded-3xl",
27
+ full: "rounded-full",
28
28
  },
29
- } as const
29
+ } as const;
30
30
 
31
- type RadiusSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'
31
+ type RadiusSize = "sm" | "md" | "lg" | "xl" | "full";
32
32
 
33
33
  /**
34
34
  * Hook to get radius classes based on theme config
35
35
  * Use: const r = useRadius(); then r('lg') returns the appropriate rounded class
36
36
  */
37
37
  export const useRadius = () => {
38
- const { config } = useElements()
39
- const radius = config.theme?.radius ?? 'soft'
38
+ const { config } = useElements();
39
+ const radius = config.theme?.radius ?? "soft";
40
40
 
41
- return (size: RadiusSize) => radiusClasses[radius][size]
42
- }
41
+ return (size: RadiusSize) => radiusClasses[radius][size];
42
+ };
@@ -19,61 +19,61 @@
19
19
  * ```
20
20
  */
21
21
 
22
- import { useThreadRuntime } from '@assistant-ui/react'
23
- import { useCallback, useRef, useState, useSyncExternalStore } from 'react'
24
- import { recordCassette } from '@/lib/cassette'
22
+ import { useThreadRuntime } from "@assistant-ui/react";
23
+ import { useCallback, useRef, useState, useSyncExternalStore } from "react";
24
+ import { recordCassette } from "@/lib/cassette";
25
25
 
26
26
  export function useRecordCassette(): {
27
27
  /** Whether recording is currently active. */
28
- isRecording: boolean
28
+ isRecording: boolean;
29
29
  /** Current number of messages in the thread. */
30
- messageCount: number
30
+ messageCount: number;
31
31
  /** Start recording from the current point in the conversation. */
32
- startRecording: () => void
32
+ startRecording: () => void;
33
33
  /** Stop recording. */
34
- stopRecording: () => void
34
+ stopRecording: () => void;
35
35
  /** Downloads the recorded conversation as a `.cassette.json` file. */
36
- download: (filename?: string) => void
36
+ download: (filename?: string) => void;
37
37
  } {
38
- const runtime = useThreadRuntime()
39
- const [isRecording, setIsRecording] = useState(false)
40
- const startIndexRef = useRef(0)
38
+ const runtime = useThreadRuntime();
39
+ const [isRecording, setIsRecording] = useState(false);
40
+ const startIndexRef = useRef(0);
41
41
 
42
42
  // Subscribe to runtime state to get reactive message count
43
43
  const messageCount = useSyncExternalStore(
44
44
  (cb) => runtime.subscribe(cb),
45
- () => runtime.getState().messages.length
46
- )
45
+ () => runtime.getState().messages.length,
46
+ );
47
47
 
48
48
  const startRecording = useCallback(() => {
49
- startIndexRef.current = runtime.getState().messages.length
50
- setIsRecording(true)
51
- }, [runtime])
49
+ startIndexRef.current = runtime.getState().messages.length;
50
+ setIsRecording(true);
51
+ }, [runtime]);
52
52
 
53
53
  const stopRecording = useCallback(() => {
54
- setIsRecording(false)
55
- }, [])
54
+ setIsRecording(false);
55
+ }, []);
56
56
 
57
57
  const download = useCallback(
58
58
  (filename?: string) => {
59
- const state = runtime.getState()
60
- const messages = state.messages.slice(startIndexRef.current)
61
- const cassette = recordCassette(messages)
59
+ const state = runtime.getState();
60
+ const messages = state.messages.slice(startIndexRef.current);
61
+ const cassette = recordCassette(messages);
62
62
 
63
- const json = JSON.stringify(cassette, null, 2)
64
- const blob = new Blob([json], { type: 'application/json' })
65
- const url = URL.createObjectURL(blob)
63
+ const json = JSON.stringify(cassette, null, 2);
64
+ const blob = new Blob([json], { type: "application/json" });
65
+ const url = URL.createObjectURL(blob);
66
66
 
67
- const a = document.createElement('a')
68
- a.href = url
69
- a.download = `${filename ?? 'cassette'}.cassette.json`
70
- document.body.appendChild(a)
71
- a.click()
72
- document.body.removeChild(a)
73
- URL.revokeObjectURL(url)
67
+ const a = document.createElement("a");
68
+ a.href = url;
69
+ a.download = `${filename ?? "cassette"}.cassette.json`;
70
+ document.body.appendChild(a);
71
+ a.click();
72
+ document.body.removeChild(a);
73
+ URL.revokeObjectURL(url);
74
74
  },
75
- [runtime]
76
- )
75
+ [runtime],
76
+ );
77
77
 
78
- return { isRecording, messageCount, startRecording, stopRecording, download }
78
+ return { isRecording, messageCount, startRecording, stopRecording, download };
79
79
  }
@@ -1,8 +1,8 @@
1
- import { GetSessionFn } from '@/types'
2
- import { useQuery, useQueryClient } from '@tanstack/react-query'
1
+ import { GetSessionFn } from "@/types";
2
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
3
3
 
4
4
  export function getChatSessionQueryKey(projectSlug: string) {
5
- return ['chatSession', projectSlug] as const
5
+ return ["chatSession", projectSlug] as const;
6
6
  }
7
7
 
8
8
  /**
@@ -13,13 +13,13 @@ export const useSession = ({
13
13
  getSession,
14
14
  projectSlug,
15
15
  }: {
16
- getSession: GetSessionFn | null
17
- projectSlug: string
16
+ getSession: GetSessionFn | null;
17
+ projectSlug: string;
18
18
  }): string | null => {
19
- const queryClient = useQueryClient()
20
- const queryKey = getChatSessionQueryKey(projectSlug)
19
+ const queryClient = useQueryClient();
20
+ const queryKey = getChatSessionQueryKey(projectSlug);
21
21
 
22
- const hasData = queryClient.getQueryState(queryKey)?.data !== undefined
22
+ const hasData = queryClient.getQueryState(queryKey)?.data !== undefined;
23
23
 
24
24
  const { data: fetchedSessionToken } = useQuery({
25
25
  queryKey,
@@ -27,7 +27,7 @@ export const useSession = ({
27
27
  enabled: !hasData && getSession !== null,
28
28
  staleTime: Infinity, // Session tokens don't need to be refetched
29
29
  gcTime: Infinity, // Keep in cache indefinitely
30
- })
30
+ });
31
31
 
32
- return fetchedSessionToken ?? null
33
- }
32
+ return fetchedSessionToken ?? null;
33
+ };
@@ -1,24 +1,24 @@
1
- import { useMemo } from 'react'
2
- import { useElements } from './useElements'
1
+ import { useMemo } from "react";
2
+ import { useElements } from "./useElements";
3
3
 
4
4
  /**
5
5
  * Hook to get theme-related props including dark mode class
6
6
  */
7
7
  export const useThemeProps = () => {
8
- const { config } = useElements()
9
- const theme = config.theme ?? {}
8
+ const { config } = useElements();
9
+ const theme = config.theme ?? {};
10
10
 
11
11
  return useMemo(() => {
12
- const { colorScheme = 'light' } = theme
12
+ const { colorScheme = "light" } = theme;
13
13
 
14
14
  const isDark =
15
- colorScheme === 'dark' ||
16
- (colorScheme === 'system' &&
17
- typeof window !== 'undefined' &&
18
- window.matchMedia('(prefers-color-scheme: dark)').matches)
15
+ colorScheme === "dark" ||
16
+ (colorScheme === "system" &&
17
+ typeof window !== "undefined" &&
18
+ window.matchMedia("(prefers-color-scheme: dark)").matches);
19
19
 
20
20
  return {
21
- className: isDark ? 'dark' : undefined,
22
- } as const
23
- }, [theme])
24
- }
21
+ className: isDark ? "dark" : undefined,
22
+ } as const;
23
+ }, [theme]);
24
+ };
@@ -1,4 +1,4 @@
1
- import { useAssistantState } from '@assistant-ui/react'
1
+ import { useAssistantState } from "@assistant-ui/react";
2
2
 
3
3
  /**
4
4
  * Hook to access the current thread ID from the Elements chat.
@@ -23,8 +23,8 @@ import { useAssistantState } from '@assistant-ui/react'
23
23
  */
24
24
  export function useThreadId(): { threadId: string | null } {
25
25
  const threadId = useAssistantState(
26
- ({ threadListItem }) => threadListItem.remoteId ?? null
27
- )
26
+ ({ threadListItem }) => threadListItem.remoteId ?? null,
27
+ );
28
28
 
29
- return { threadId }
29
+ return { threadId };
30
30
  }
@@ -1,16 +1,16 @@
1
- import { useContext } from 'react'
2
- import { ToolApprovalContext } from '@/contexts/contexts'
1
+ import { useContext } from "react";
2
+ import { ToolApprovalContext } from "@/contexts/contexts";
3
3
 
4
4
  /**
5
5
  * Hook to access the tool approval context for managing human-in-the-loop
6
6
  * tool execution approval.
7
7
  */
8
8
  export const useToolApproval = () => {
9
- const context = useContext(ToolApprovalContext)
9
+ const context = useContext(ToolApprovalContext);
10
10
  if (!context) {
11
11
  throw new Error(
12
- 'useToolApproval must be used within a ToolApprovalProvider'
13
- )
12
+ "useToolApproval must be used within a ToolApprovalProvider",
13
+ );
14
14
  }
15
- return context
16
- }
15
+ return context;
16
+ };
@@ -1,83 +1,83 @@
1
- import { useCallback, useMemo, useRef, useState } from 'react'
2
- import { useAssistantApi, useAssistantState } from '@assistant-ui/react'
1
+ import { useCallback, useMemo, useRef, useState } from "react";
2
+ import { useAssistantApi, useAssistantState } from "@assistant-ui/react";
3
3
  import {
4
4
  MentionableTool,
5
5
  parseMentionedTools,
6
6
  removeToolMention,
7
7
  toolSetToMentionableTools,
8
- } from '@/lib/tool-mentions'
8
+ } from "@/lib/tool-mentions";
9
9
 
10
10
  export interface UseToolMentionsOptions {
11
- tools: Record<string, unknown> | undefined
12
- enabled?: boolean
11
+ tools: Record<string, unknown> | undefined;
12
+ enabled?: boolean;
13
13
  }
14
14
 
15
15
  export interface UseToolMentionsReturn {
16
- mentionableTools: MentionableTool[]
17
- mentionedToolIds: string[]
18
- value: string
19
- cursorPosition: number
20
- textareaRef: React.RefObject<HTMLTextAreaElement | null>
21
- updateCursorPosition: () => void
22
- handleAutocompleteChange: (value: string, cursorPosition: number) => void
23
- removeMention: (toolId: string) => void
24
- isActive: boolean
16
+ mentionableTools: MentionableTool[];
17
+ mentionedToolIds: string[];
18
+ value: string;
19
+ cursorPosition: number;
20
+ textareaRef: React.RefObject<HTMLTextAreaElement | null>;
21
+ updateCursorPosition: () => void;
22
+ handleAutocompleteChange: (value: string, cursorPosition: number) => void;
23
+ removeMention: (toolId: string) => void;
24
+ isActive: boolean;
25
25
  }
26
26
 
27
27
  export function useToolMentions({
28
28
  tools,
29
29
  enabled = true,
30
30
  }: UseToolMentionsOptions): UseToolMentionsReturn {
31
- const [cursorPosition, setCursorPosition] = useState(0)
32
- const textareaRef = useRef<HTMLTextAreaElement | null>(null)
33
- const api = useAssistantApi()
34
- const composerText = useAssistantState(({ composer }) => composer.text)
31
+ const [cursorPosition, setCursorPosition] = useState(0);
32
+ const textareaRef = useRef<HTMLTextAreaElement | null>(null);
33
+ const api = useAssistantApi();
34
+ const composerText = useAssistantState(({ composer }) => composer.text);
35
35
 
36
36
  const mentionableTools = useMemo(
37
37
  () => toolSetToMentionableTools(tools),
38
- [tools]
39
- )
38
+ [tools],
39
+ );
40
40
 
41
41
  const mentionedToolIds = useMemo(
42
42
  () => (enabled ? parseMentionedTools(composerText, tools) : []),
43
- [composerText, tools, enabled]
44
- )
43
+ [composerText, tools, enabled],
44
+ );
45
45
 
46
46
  const updateCursorPosition = useCallback(() => {
47
- const textarea = textareaRef.current
47
+ const textarea = textareaRef.current;
48
48
  if (textarea) {
49
- setCursorPosition(textarea.selectionStart)
49
+ setCursorPosition(textarea.selectionStart);
50
50
  }
51
- }, [])
51
+ }, []);
52
52
 
53
53
  const handleAutocompleteChange = useCallback(
54
54
  (newValue: string, newCursorPosition: number) => {
55
- api.composer().setText(newValue)
56
- setCursorPosition(newCursorPosition)
55
+ api.composer().setText(newValue);
56
+ setCursorPosition(newCursorPosition);
57
57
 
58
58
  setTimeout(() => {
59
- const textarea = textareaRef.current
59
+ const textarea = textareaRef.current;
60
60
  if (textarea) {
61
- textarea.focus()
62
- textarea.setSelectionRange(newCursorPosition, newCursorPosition)
61
+ textarea.focus();
62
+ textarea.setSelectionRange(newCursorPosition, newCursorPosition);
63
63
  }
64
- }, 0)
64
+ }, 0);
65
65
  },
66
- [api]
67
- )
66
+ [api],
67
+ );
68
68
 
69
69
  const removeMention = useCallback(
70
70
  (toolId: string) => {
71
- const tool = mentionableTools.find((t) => t.id === toolId)
71
+ const tool = mentionableTools.find((t) => t.id === toolId);
72
72
  if (tool) {
73
- const newValue = removeToolMention(composerText, tool.name)
74
- api.composer().setText(newValue)
73
+ const newValue = removeToolMention(composerText, tool.name);
74
+ api.composer().setText(newValue);
75
75
  }
76
76
  },
77
- [composerText, mentionableTools, api]
78
- )
77
+ [composerText, mentionableTools, api],
78
+ );
79
79
 
80
- const isActive = enabled && mentionableTools.length > 0
80
+ const isActive = enabled && mentionableTools.length > 0;
81
81
 
82
82
  return {
83
83
  mentionableTools,
@@ -89,5 +89,5 @@ export function useToolMentions({
89
89
  handleAutocompleteChange,
90
90
  removeMention,
91
91
  isActive,
92
- }
92
+ };
93
93
  }
package/src/index.ts CHANGED
@@ -1,40 +1,40 @@
1
1
  // Polyfill React 18 APIs for older React versions — must be the first import
2
- import './compat'
2
+ import "./compat";
3
3
 
4
4
  // Side-effect import to include CSS in build (consumers import via @gram-ai/elements/elements.css)
5
- import './global.css'
5
+ import "./global.css";
6
6
 
7
7
  // Context Providers
8
- export { ElementsProvider as GramElementsProvider } from './contexts/ElementsProvider'
9
- export { ElementsProvider } from './contexts/ElementsProvider'
10
- export { useElements as useGramElements } from './hooks/useElements'
11
- export { useElements } from './hooks/useElements'
12
- export { useThreadId } from './hooks/useThreadId'
13
- export { useChatId } from './contexts/ChatIdContext'
8
+ export { ElementsProvider as GramElementsProvider } from "./contexts/ElementsProvider";
9
+ export { ElementsProvider } from "./contexts/ElementsProvider";
10
+ export { useElements as useGramElements } from "./hooks/useElements";
11
+ export { useElements } from "./hooks/useElements";
12
+ export { useThreadId } from "./hooks/useThreadId";
13
+ export { useChatId } from "./contexts/ChatIdContext";
14
14
 
15
15
  // Core Components
16
- export { Chat } from '@/components/Chat'
17
- export { ChatHistory } from '@/components/ChatHistory'
18
- export { ShareButton } from '@/components/ShareButton'
19
- export type { ShareButtonProps } from '@/components/ShareButton'
16
+ export { Chat } from "@/components/Chat";
17
+ export { ChatHistory } from "@/components/ChatHistory";
18
+ export { ShareButton } from "@/components/ShareButton";
19
+ export type { ShareButtonProps } from "@/components/ShareButton";
20
20
 
21
21
  // Replay
22
- export { Replay } from '@/components/Replay'
23
- export { useRecordCassette } from '@/hooks/useRecordCassette'
22
+ export { Replay } from "@/components/Replay";
23
+ export { useRecordCassette } from "@/hooks/useRecordCassette";
24
24
  export type {
25
25
  Cassette,
26
26
  CassetteMessage,
27
27
  CassettePart,
28
28
  ReplayOptions,
29
- } from '@/lib/cassette'
29
+ } from "@/lib/cassette";
30
30
 
31
31
  // Frontend Tools
32
- export { defineFrontendTool } from './lib/tools'
33
- export type { FrontendTool } from './lib/tools'
32
+ export { defineFrontendTool } from "./lib/tools";
33
+ export type { FrontendTool } from "./lib/tools";
34
34
 
35
35
  // Error Tracking
36
- export { trackError } from './lib/errorTracking'
37
- export type { ErrorContext } from './lib/errorTracking'
36
+ export { trackError } from "./lib/errorTracking";
37
+ export type { ErrorContext } from "./lib/errorTracking";
38
38
 
39
39
  // Types
40
40
  export type {
@@ -68,23 +68,23 @@ export type {
68
68
  Variant,
69
69
  VARIANTS,
70
70
  WelcomeConfig,
71
- } from './types'
71
+ } from "./types";
72
72
 
73
- export { MODELS } from './lib/models'
73
+ export { MODELS } from "./lib/models";
74
74
 
75
- export type { Plugin } from './types/plugins'
75
+ export type { Plugin } from "./types/plugins";
76
76
 
77
77
  // Time Range Picker
78
78
  export {
79
79
  TimeRangePicker,
80
80
  getPresetRange,
81
81
  PRESETS,
82
- } from '@/components/ui/time-range-picker'
82
+ } from "@/components/ui/time-range-picker";
83
83
  export type {
84
84
  TimeRange,
85
85
  TimeRangePreset,
86
86
  TimeRangePickerProps,
87
87
  DateRangePreset,
88
- } from '@/components/ui/time-range-picker'
89
- export { Calendar } from '@/components/ui/calendar'
90
- export type { CalendarProps } from '@/components/ui/calendar'
88
+ } from "@/components/ui/time-range-picker";
89
+ export { Calendar } from "@/components/ui/calendar";
90
+ export type { CalendarProps } from "@/components/ui/calendar";