@databricks/appkit-ui 0.11.1 → 0.12.0

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 (318) hide show
  1. package/CLAUDE.md +4 -0
  2. package/NOTICE.md +1 -0
  3. package/dist/react/charts/area/index.d.ts +2 -2
  4. package/dist/react/charts/bar/index.d.ts +2 -2
  5. package/dist/react/charts/base.d.ts +2 -2
  6. package/dist/react/charts/base.d.ts.map +1 -1
  7. package/dist/react/charts/base.js.map +1 -1
  8. package/dist/react/charts/chart-error-boundary.js.map +1 -1
  9. package/dist/react/charts/create-chart.d.ts +2 -2
  10. package/dist/react/charts/create-chart.d.ts.map +1 -1
  11. package/dist/react/charts/create-chart.js.map +1 -1
  12. package/dist/react/charts/empty.js.map +1 -1
  13. package/dist/react/charts/error.js.map +1 -1
  14. package/dist/react/charts/heatmap/index.d.ts +2 -2
  15. package/dist/react/charts/line/index.d.ts +2 -2
  16. package/dist/react/charts/loading.js.map +1 -1
  17. package/dist/react/charts/options.d.ts.map +1 -1
  18. package/dist/react/charts/pie/index.d.ts +3 -3
  19. package/dist/react/charts/radar/index.d.ts +2 -2
  20. package/dist/react/charts/scatter/index.d.ts +2 -2
  21. package/dist/react/charts/wrapper.d.ts +2 -2
  22. package/dist/react/charts/wrapper.d.ts.map +1 -1
  23. package/dist/react/charts/wrapper.js.map +1 -1
  24. package/dist/react/genie/genie-chat-input.d.ts +23 -0
  25. package/dist/react/genie/genie-chat-input.d.ts.map +1 -0
  26. package/dist/react/genie/genie-chat-input.js +58 -0
  27. package/dist/react/genie/genie-chat-input.js.map +1 -0
  28. package/dist/react/genie/genie-chat-message-list.d.ts +21 -0
  29. package/dist/react/genie/genie-chat-message-list.d.ts.map +1 -0
  30. package/dist/react/genie/genie-chat-message-list.js +64 -0
  31. package/dist/react/genie/genie-chat-message-list.js.map +1 -0
  32. package/dist/react/genie/genie-chat-message.d.ts +18 -0
  33. package/dist/react/genie/genie-chat-message.d.ts.map +1 -0
  34. package/dist/react/genie/genie-chat-message.js +71 -0
  35. package/dist/react/genie/genie-chat-message.js.map +1 -0
  36. package/dist/react/genie/genie-chat.d.ts +14 -0
  37. package/dist/react/genie/genie-chat.d.ts.map +1 -0
  38. package/dist/react/genie/genie-chat.js +47 -0
  39. package/dist/react/genie/genie-chat.js.map +1 -0
  40. package/dist/react/genie/index.js +5 -0
  41. package/dist/react/genie/types.d.ts +44 -0
  42. package/dist/react/genie/types.d.ts.map +1 -0
  43. package/dist/react/genie/use-genie-chat.d.ts +17 -0
  44. package/dist/react/genie/use-genie-chat.d.ts.map +1 -0
  45. package/dist/react/genie/use-genie-chat.js +254 -0
  46. package/dist/react/genie/use-genie-chat.js.map +1 -0
  47. package/dist/react/index.d.ts +8 -1
  48. package/dist/react/index.js +14 -8
  49. package/dist/react/portal-container-context.js.map +1 -1
  50. package/dist/react/table/data-table.d.ts +2 -2
  51. package/dist/react/table/data-table.d.ts.map +1 -1
  52. package/dist/react/table/data-table.js +2 -2
  53. package/dist/react/table/data-table.js.map +1 -1
  54. package/dist/react/table/empty.js.map +1 -1
  55. package/dist/react/table/error.js.map +1 -1
  56. package/dist/react/table/loading.js.map +1 -1
  57. package/dist/react/table/table-wrapper.js +2 -2
  58. package/dist/react/table/table-wrapper.js.map +1 -1
  59. package/dist/react/ui/accordion.d.ts +5 -5
  60. package/dist/react/ui/accordion.d.ts.map +1 -1
  61. package/dist/react/ui/accordion.js.map +1 -1
  62. package/dist/react/ui/alert-dialog.d.ts +12 -12
  63. package/dist/react/ui/alert-dialog.js +1 -1
  64. package/dist/react/ui/alert-dialog.js.map +1 -1
  65. package/dist/react/ui/alert.d.ts +4 -4
  66. package/dist/react/ui/alert.d.ts.map +1 -1
  67. package/dist/react/ui/alert.js.map +1 -1
  68. package/dist/react/ui/aspect-ratio.d.ts +2 -2
  69. package/dist/react/ui/aspect-ratio.js.map +1 -1
  70. package/dist/react/ui/avatar.d.ts +4 -4
  71. package/dist/react/ui/avatar.js.map +1 -1
  72. package/dist/react/ui/badge.d.ts +2 -2
  73. package/dist/react/ui/badge.js.map +1 -1
  74. package/dist/react/ui/breadcrumb.d.ts +8 -8
  75. package/dist/react/ui/breadcrumb.js +1 -1
  76. package/dist/react/ui/breadcrumb.js.map +1 -1
  77. package/dist/react/ui/button-group.d.ts +4 -4
  78. package/dist/react/ui/button-group.js.map +1 -1
  79. package/dist/react/ui/button.d.ts +2 -2
  80. package/dist/react/ui/button.js.map +1 -1
  81. package/dist/react/ui/calendar.d.ts +3 -3
  82. package/dist/react/ui/calendar.js.map +1 -1
  83. package/dist/react/ui/card.d.ts +8 -8
  84. package/dist/react/ui/card.js.map +1 -1
  85. package/dist/react/ui/carousel.d.ts +6 -6
  86. package/dist/react/ui/carousel.js.map +1 -1
  87. package/dist/react/ui/chart.d.ts +5 -5
  88. package/dist/react/ui/chart.js.map +1 -1
  89. package/dist/react/ui/checkbox.d.ts +2 -2
  90. package/dist/react/ui/checkbox.js.map +1 -1
  91. package/dist/react/ui/collapsible.d.ts +4 -4
  92. package/dist/react/ui/collapsible.js.map +1 -1
  93. package/dist/react/ui/command.d.ts +10 -10
  94. package/dist/react/ui/command.js.map +1 -1
  95. package/dist/react/ui/context-menu.d.ts +16 -16
  96. package/dist/react/ui/context-menu.js.map +1 -1
  97. package/dist/react/ui/dialog.d.ts +11 -11
  98. package/dist/react/ui/dialog.js.map +1 -1
  99. package/dist/react/ui/drawer.d.ts +11 -11
  100. package/dist/react/ui/drawer.d.ts.map +1 -1
  101. package/dist/react/ui/drawer.js.map +1 -1
  102. package/dist/react/ui/dropdown-menu.d.ts +16 -16
  103. package/dist/react/ui/dropdown-menu.js.map +1 -1
  104. package/dist/react/ui/empty.d.ts +7 -7
  105. package/dist/react/ui/empty.js.map +1 -1
  106. package/dist/react/ui/field.d.ts +11 -11
  107. package/dist/react/ui/field.js.map +1 -1
  108. package/dist/react/ui/form.d.ts +7 -7
  109. package/dist/react/ui/form.js.map +1 -1
  110. package/dist/react/ui/hover-card.d.ts +4 -4
  111. package/dist/react/ui/hover-card.js.map +1 -1
  112. package/dist/react/ui/index.js +5 -5
  113. package/dist/react/ui/input-group.d.ts +7 -7
  114. package/dist/react/ui/input-group.js.map +1 -1
  115. package/dist/react/ui/input-otp.d.ts +5 -5
  116. package/dist/react/ui/input-otp.js.map +1 -1
  117. package/dist/react/ui/input.d.ts +2 -2
  118. package/dist/react/ui/input.js.map +1 -1
  119. package/dist/react/ui/item.d.ts +11 -11
  120. package/dist/react/ui/item.js.map +1 -1
  121. package/dist/react/ui/kbd.d.ts +3 -3
  122. package/dist/react/ui/kbd.js.map +1 -1
  123. package/dist/react/ui/label.d.ts +2 -2
  124. package/dist/react/ui/label.js.map +1 -1
  125. package/dist/react/ui/menubar.d.ts +17 -17
  126. package/dist/react/ui/menubar.js.map +1 -1
  127. package/dist/react/ui/navigation-menu.d.ts +9 -9
  128. package/dist/react/ui/navigation-menu.js +1 -1
  129. package/dist/react/ui/navigation-menu.js.map +1 -1
  130. package/dist/react/ui/pagination.d.ts +8 -8
  131. package/dist/react/ui/pagination.js.map +1 -1
  132. package/dist/react/ui/popover.d.ts +5 -5
  133. package/dist/react/ui/popover.js.map +1 -1
  134. package/dist/react/ui/progress.d.ts +2 -2
  135. package/dist/react/ui/progress.js.map +1 -1
  136. package/dist/react/ui/radio-group.d.ts +3 -3
  137. package/dist/react/ui/radio-group.js.map +1 -1
  138. package/dist/react/ui/resizable.d.ts +4 -4
  139. package/dist/react/ui/resizable.js.map +1 -1
  140. package/dist/react/ui/scroll-area.d.ts +3 -3
  141. package/dist/react/ui/scroll-area.js.map +1 -1
  142. package/dist/react/ui/select.d.ts +11 -11
  143. package/dist/react/ui/select.js.map +1 -1
  144. package/dist/react/ui/separator.d.ts +2 -2
  145. package/dist/react/ui/separator.js.map +1 -1
  146. package/dist/react/ui/sheet.d.ts +9 -9
  147. package/dist/react/ui/sheet.js.map +1 -1
  148. package/dist/react/ui/sidebar.d.ts +24 -24
  149. package/dist/react/ui/sidebar.js +2 -2
  150. package/dist/react/ui/sidebar.js.map +1 -1
  151. package/dist/react/ui/skeleton.d.ts +2 -2
  152. package/dist/react/ui/skeleton.js.map +1 -1
  153. package/dist/react/ui/slider.d.ts +2 -2
  154. package/dist/react/ui/slider.js.map +1 -1
  155. package/dist/react/ui/sonner.d.ts +2 -2
  156. package/dist/react/ui/sonner.js.map +1 -1
  157. package/dist/react/ui/spinner.d.ts +2 -2
  158. package/dist/react/ui/spinner.js.map +1 -1
  159. package/dist/react/ui/switch.d.ts +2 -2
  160. package/dist/react/ui/switch.js.map +1 -1
  161. package/dist/react/ui/table.d.ts +9 -9
  162. package/dist/react/ui/table.js.map +1 -1
  163. package/dist/react/ui/tabs.d.ts +5 -5
  164. package/dist/react/ui/tabs.js.map +1 -1
  165. package/dist/react/ui/textarea.d.ts +2 -2
  166. package/dist/react/ui/textarea.js.map +1 -1
  167. package/dist/react/ui/toggle-group.d.ts +3 -3
  168. package/dist/react/ui/toggle-group.js.map +1 -1
  169. package/dist/react/ui/toggle.d.ts +2 -2
  170. package/dist/react/ui/toggle.js.map +1 -1
  171. package/dist/react/ui/tooltip.d.ts +5 -5
  172. package/dist/react/ui/tooltip.d.ts.map +1 -1
  173. package/dist/react/ui/tooltip.js.map +1 -1
  174. package/dist/shared/src/genie.d.ts +48 -0
  175. package/dist/shared/src/genie.d.ts.map +1 -0
  176. package/docs/docs/api/appkit/Class.AppKitError/index.html +2 -2
  177. package/docs/docs/api/appkit/Class.AuthenticationError/index.html +2 -2
  178. package/docs/docs/api/appkit/Class.ConfigurationError/index.html +2 -2
  179. package/docs/docs/api/appkit/Class.ConnectionError/index.html +2 -2
  180. package/docs/docs/api/appkit/Class.ExecutionError/index.html +2 -2
  181. package/docs/docs/api/appkit/Class.InitializationError/index.html +2 -2
  182. package/docs/docs/api/appkit/Class.Plugin/index.html +2 -2
  183. package/docs/docs/api/appkit/Class.ResourceRegistry/index.html +2 -2
  184. package/docs/docs/api/appkit/Class.ServerError/index.html +2 -2
  185. package/docs/docs/api/appkit/Class.TunnelError/index.html +2 -2
  186. package/docs/docs/api/appkit/Class.ValidationError/index.html +2 -2
  187. package/docs/docs/api/appkit/Enumeration.RequestedClaimsPermissionSet/index.html +2 -2
  188. package/docs/docs/api/appkit/Enumeration.ResourceType/index.html +2 -2
  189. package/docs/docs/api/appkit/Function.appKitTypesPlugin/index.html +2 -2
  190. package/docs/docs/api/appkit/Function.createApp/index.html +2 -2
  191. package/docs/docs/api/appkit/Function.createLakebasePool/index.html +2 -2
  192. package/docs/docs/api/appkit/Function.generateDatabaseCredential/index.html +2 -2
  193. package/docs/docs/api/appkit/Function.getExecutionContext/index.html +2 -2
  194. package/docs/docs/api/appkit/Function.getLakebaseOrmConfig/index.html +2 -2
  195. package/docs/docs/api/appkit/Function.getLakebasePgConfig/index.html +2 -2
  196. package/docs/docs/api/appkit/Function.getPluginManifest/index.html +2 -2
  197. package/docs/docs/api/appkit/Function.getResourceRequirements/index.html +2 -2
  198. package/docs/docs/api/appkit/Function.getUsernameWithApiLookup/index.html +2 -2
  199. package/docs/docs/api/appkit/Function.getWorkspaceClient/index.html +2 -2
  200. package/docs/docs/api/appkit/Function.isSQLTypeMarker/index.html +2 -2
  201. package/docs/docs/api/appkit/Interface.BasePluginConfig/index.html +2 -2
  202. package/docs/docs/api/appkit/Interface.CacheConfig/index.html +2 -2
  203. package/docs/docs/api/appkit/Interface.DatabaseCredential/index.html +2 -2
  204. package/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest/index.html +2 -2
  205. package/docs/docs/api/appkit/Interface.ITelemetry/index.html +2 -2
  206. package/docs/docs/api/appkit/Interface.LakebasePoolConfig/index.html +2 -2
  207. package/docs/docs/api/appkit/Interface.PluginManifest/index.html +2 -2
  208. package/docs/docs/api/appkit/Interface.RequestedClaims/index.html +2 -2
  209. package/docs/docs/api/appkit/Interface.RequestedResource/index.html +2 -2
  210. package/docs/docs/api/appkit/Interface.ResourceEntry/index.html +2 -2
  211. package/docs/docs/api/appkit/Interface.ResourceFieldEntry/index.html +2 -2
  212. package/docs/docs/api/appkit/Interface.ResourceRequirement/index.html +2 -2
  213. package/docs/docs/api/appkit/Interface.StreamExecutionSettings/index.html +2 -2
  214. package/docs/docs/api/appkit/Interface.TelemetryConfig/index.html +2 -2
  215. package/docs/docs/api/appkit/Interface.ValidationResult/index.html +2 -2
  216. package/docs/docs/api/appkit/TypeAlias.ConfigSchema/index.html +2 -2
  217. package/docs/docs/api/appkit/TypeAlias.IAppRouter/index.html +2 -2
  218. package/docs/docs/api/appkit/TypeAlias.ResourcePermission/index.html +2 -2
  219. package/docs/docs/api/appkit/TypeAlias.ToPlugin/index.html +2 -2
  220. package/docs/docs/api/appkit/Variable.sql/index.html +2 -2
  221. package/docs/docs/api/appkit/index.html +2 -2
  222. package/docs/docs/api/appkit-ui/data/AreaChart/index.html +3 -3
  223. package/docs/docs/api/appkit-ui/data/BarChart/index.html +3 -3
  224. package/docs/docs/api/appkit-ui/data/DataTable/index.html +3 -3
  225. package/docs/docs/api/appkit-ui/data/DonutChart/index.html +3 -3
  226. package/docs/docs/api/appkit-ui/data/HeatmapChart/index.html +3 -3
  227. package/docs/docs/api/appkit-ui/data/LineChart/index.html +3 -3
  228. package/docs/docs/api/appkit-ui/data/PieChart/index.html +3 -3
  229. package/docs/docs/api/appkit-ui/data/RadarChart/index.html +3 -3
  230. package/docs/docs/api/appkit-ui/data/ScatterChart/index.html +4 -4
  231. package/docs/docs/api/appkit-ui/genie/GenieChat/index.html +26 -0
  232. package/docs/docs/api/appkit-ui/genie/GenieChat.md +43 -0
  233. package/docs/docs/api/appkit-ui/genie/GenieChatInput/index.html +24 -0
  234. package/docs/docs/api/appkit-ui/genie/GenieChatInput.md +27 -0
  235. package/docs/docs/api/appkit-ui/genie/GenieChatMessage/index.html +24 -0
  236. package/docs/docs/api/appkit-ui/genie/GenieChatMessage.md +25 -0
  237. package/docs/docs/api/appkit-ui/genie/GenieChatMessageList/index.html +24 -0
  238. package/docs/docs/api/appkit-ui/genie/GenieChatMessageList.md +26 -0
  239. package/docs/docs/api/appkit-ui/index.html +3 -3
  240. package/docs/docs/api/appkit-ui/styling/index.html +4 -4
  241. package/docs/docs/api/appkit-ui/ui/Accordion/index.html +3 -3
  242. package/docs/docs/api/appkit-ui/ui/Alert/index.html +3 -3
  243. package/docs/docs/api/appkit-ui/ui/AlertDialog/index.html +3 -3
  244. package/docs/docs/api/appkit-ui/ui/AspectRatio/index.html +3 -3
  245. package/docs/docs/api/appkit-ui/ui/Avatar/index.html +3 -3
  246. package/docs/docs/api/appkit-ui/ui/Badge/index.html +3 -3
  247. package/docs/docs/api/appkit-ui/ui/Breadcrumb/index.html +3 -3
  248. package/docs/docs/api/appkit-ui/ui/Button/index.html +3 -3
  249. package/docs/docs/api/appkit-ui/ui/ButtonGroup/index.html +3 -3
  250. package/docs/docs/api/appkit-ui/ui/Calendar/index.html +3 -3
  251. package/docs/docs/api/appkit-ui/ui/Card/index.html +3 -3
  252. package/docs/docs/api/appkit-ui/ui/Carousel/index.html +3 -3
  253. package/docs/docs/api/appkit-ui/ui/ChartContainer/index.html +3 -3
  254. package/docs/docs/api/appkit-ui/ui/Checkbox/index.html +3 -3
  255. package/docs/docs/api/appkit-ui/ui/Collapsible/index.html +3 -3
  256. package/docs/docs/api/appkit-ui/ui/Command/index.html +3 -3
  257. package/docs/docs/api/appkit-ui/ui/ContextMenu/index.html +3 -3
  258. package/docs/docs/api/appkit-ui/ui/Dialog/index.html +3 -3
  259. package/docs/docs/api/appkit-ui/ui/Drawer/index.html +3 -3
  260. package/docs/docs/api/appkit-ui/ui/DropdownMenu/index.html +3 -3
  261. package/docs/docs/api/appkit-ui/ui/Empty/index.html +3 -3
  262. package/docs/docs/api/appkit-ui/ui/Field/index.html +3 -3
  263. package/docs/docs/api/appkit-ui/ui/FormControl/index.html +3 -3
  264. package/docs/docs/api/appkit-ui/ui/HoverCard/index.html +3 -3
  265. package/docs/docs/api/appkit-ui/ui/Input/index.html +3 -3
  266. package/docs/docs/api/appkit-ui/ui/InputGroup/index.html +3 -3
  267. package/docs/docs/api/appkit-ui/ui/InputOTP/index.html +3 -3
  268. package/docs/docs/api/appkit-ui/ui/Item/index.html +3 -3
  269. package/docs/docs/api/appkit-ui/ui/Kbd/index.html +3 -3
  270. package/docs/docs/api/appkit-ui/ui/Label/index.html +3 -3
  271. package/docs/docs/api/appkit-ui/ui/Menubar/index.html +3 -3
  272. package/docs/docs/api/appkit-ui/ui/NavigationMenu/index.html +3 -3
  273. package/docs/docs/api/appkit-ui/ui/Pagination/index.html +3 -3
  274. package/docs/docs/api/appkit-ui/ui/Popover/index.html +3 -3
  275. package/docs/docs/api/appkit-ui/ui/Progress/index.html +3 -3
  276. package/docs/docs/api/appkit-ui/ui/RadioGroup/index.html +3 -3
  277. package/docs/docs/api/appkit-ui/ui/ResizableHandle/index.html +3 -3
  278. package/docs/docs/api/appkit-ui/ui/ScrollArea/index.html +3 -3
  279. package/docs/docs/api/appkit-ui/ui/Select/index.html +3 -3
  280. package/docs/docs/api/appkit-ui/ui/Separator/index.html +3 -3
  281. package/docs/docs/api/appkit-ui/ui/Sheet/index.html +3 -3
  282. package/docs/docs/api/appkit-ui/ui/Sidebar/index.html +3 -3
  283. package/docs/docs/api/appkit-ui/ui/Skeleton/index.html +3 -3
  284. package/docs/docs/api/appkit-ui/ui/Slider/index.html +3 -3
  285. package/docs/docs/api/appkit-ui/ui/Spinner/index.html +3 -3
  286. package/docs/docs/api/appkit-ui/ui/Switch/index.html +3 -3
  287. package/docs/docs/api/appkit-ui/ui/Table/index.html +3 -3
  288. package/docs/docs/api/appkit-ui/ui/Tabs/index.html +3 -3
  289. package/docs/docs/api/appkit-ui/ui/Textarea/index.html +3 -3
  290. package/docs/docs/api/appkit-ui/ui/Toaster/index.html +3 -3
  291. package/docs/docs/api/appkit-ui/ui/Toggle/index.html +3 -3
  292. package/docs/docs/api/appkit-ui/ui/ToggleGroup/index.html +3 -3
  293. package/docs/docs/api/appkit-ui/ui/Tooltip/index.html +3 -3
  294. package/docs/docs/api/index.html +2 -2
  295. package/docs/docs/app-management/index.html +2 -2
  296. package/docs/docs/architecture/index.html +2 -2
  297. package/docs/docs/category/development/index.html +2 -2
  298. package/docs/docs/configuration/index.html +2 -2
  299. package/docs/docs/core-principles/index.html +2 -2
  300. package/docs/docs/development/ai-assisted-development/index.html +2 -2
  301. package/docs/docs/development/index.html +2 -2
  302. package/docs/docs/development/llm-guide/index.html +2 -2
  303. package/docs/docs/development/local-development/index.html +2 -2
  304. package/docs/docs/development/project-setup/index.html +2 -2
  305. package/docs/docs/development/remote-bridge/index.html +2 -2
  306. package/docs/docs/development/type-generation/index.html +2 -2
  307. package/docs/docs/index.html +2 -2
  308. package/docs/docs/plugins/analytics/index.html +2 -2
  309. package/docs/docs/plugins/caching/index.html +2 -2
  310. package/docs/docs/plugins/custom-plugins/index.html +2 -2
  311. package/docs/docs/plugins/execution-context/index.html +2 -2
  312. package/docs/docs/plugins/index.html +2 -2
  313. package/docs/docs/plugins/lakebase/index.html +4 -4
  314. package/docs/docs/plugins/lakebase.md +25 -24
  315. package/docs/docs/plugins/plugin-management/index.html +2 -2
  316. package/docs/docs/plugins/server/index.html +2 -2
  317. package/llms.txt +4 -0
  318. package/package.json +2 -1
@@ -0,0 +1,71 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Avatar, AvatarFallback } from "../ui/avatar.js";
3
+ import { Card } from "../ui/card.js";
4
+ import { useMemo } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { marked } from "marked";
7
+
8
+ //#region src/react/genie/genie-chat-message.tsx
9
+ /**
10
+ * Using `marked` instead of `react-markdown` because `react-markdown` depends on
11
+ * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.
12
+ * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.
13
+ */
14
+ marked.setOptions({
15
+ breaks: true,
16
+ gfm: true
17
+ });
18
+ const markdownStyles = cn("text-sm", "[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0", "[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto", "[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded", "[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1", "[&_table]:border-collapse [&_th]:border [&_td]:border", "[&_th]:border-border [&_td]:border-border", "[&_a]:underline");
19
+ function isQueryAttachment(att) {
20
+ return !!(att.query?.title || att.query?.query);
21
+ }
22
+ /** Renders a single Genie message bubble with optional expandable SQL query attachments. */
23
+ function GenieChatMessage({ message, className }) {
24
+ const isUser = message.role === "user";
25
+ const queryAttachments = message.attachments.filter(isQueryAttachment);
26
+ const html = useMemo(() => message.content ? marked.parse(message.content) : "", [message.content]);
27
+ return /* @__PURE__ */ jsxs("div", {
28
+ className: cn("flex gap-3", isUser ? "flex-row-reverse" : "flex-row", className),
29
+ children: [/* @__PURE__ */ jsx(Avatar, {
30
+ className: "h-8 w-8 shrink-0 mt-1",
31
+ children: /* @__PURE__ */ jsx(AvatarFallback, {
32
+ className: cn("text-xs font-medium", isUser ? "bg-primary text-primary-foreground" : "bg-muted"),
33
+ children: isUser ? "You" : "AI"
34
+ })
35
+ }), /* @__PURE__ */ jsxs("div", {
36
+ className: cn("flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden", isUser ? "items-end" : "items-start"),
37
+ children: [/* @__PURE__ */ jsxs(Card, {
38
+ className: cn("px-4 py-3 max-w-full overflow-hidden", isUser ? "bg-primary text-primary-foreground" : "bg-muted"),
39
+ children: [html && /* @__PURE__ */ jsx("div", {
40
+ className: markdownStyles,
41
+ dangerouslySetInnerHTML: { __html: html }
42
+ }), message.error && /* @__PURE__ */ jsx("p", {
43
+ className: "text-sm text-destructive mt-1",
44
+ children: message.error
45
+ })]
46
+ }), queryAttachments.length > 0 && /* @__PURE__ */ jsx("div", {
47
+ className: "flex flex-col gap-2 w-full min-w-0",
48
+ children: queryAttachments.map((att) => /* @__PURE__ */ jsx(Card, {
49
+ className: "px-4 py-3 text-xs overflow-hidden shadow-none",
50
+ children: /* @__PURE__ */ jsxs("details", { children: [/* @__PURE__ */ jsx("summary", {
51
+ className: "cursor-pointer select-none font-medium",
52
+ children: att.query?.title ?? "SQL Query"
53
+ }), /* @__PURE__ */ jsxs("div", {
54
+ className: "mt-2 flex flex-col gap-1",
55
+ children: [att.query?.description && /* @__PURE__ */ jsx("span", {
56
+ className: "text-muted-foreground",
57
+ children: att.query.description
58
+ }), att.query?.query && /* @__PURE__ */ jsx("pre", {
59
+ className: "mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all",
60
+ children: att.query.query
61
+ })]
62
+ })] })
63
+ }, att.attachmentId ?? "query"))
64
+ })]
65
+ })]
66
+ });
67
+ }
68
+
69
+ //#endregion
70
+ export { GenieChatMessage };
71
+ //# sourceMappingURL=genie-chat-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-chat-message.js","names":[],"sources":["../../../src/react/genie/genie-chat-message.tsx"],"sourcesContent":["import { marked } from \"marked\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Avatar, AvatarFallback } from \"../ui/avatar\";\nimport { Card } from \"../ui/card\";\nimport type { GenieAttachmentResponse, GenieMessageItem } from \"./types\";\n\n/**\n * Using `marked` instead of `react-markdown` because `react-markdown` depends on\n * `micromark-util-symbol` which has broken ESM exports with `rolldown-vite`.\n * Content comes from our own Genie API so `dangerouslySetInnerHTML` is safe.\n */\nmarked.setOptions({ breaks: true, gfm: true });\n\nconst markdownStyles = cn(\n \"text-sm\",\n \"[&_p]:my-1 [&_ul]:my-1 [&_ol]:my-1 [&_li]:my-0\",\n \"[&_pre]:bg-background/50 [&_pre]:p-2 [&_pre]:rounded [&_pre]:text-xs [&_pre]:overflow-x-auto\",\n \"[&_code]:text-xs [&_code]:bg-background/50 [&_code]:px-1 [&_code]:rounded\",\n \"[&_table]:text-xs [&_th]:px-2 [&_th]:py-1 [&_td]:px-2 [&_td]:py-1\",\n \"[&_table]:border-collapse [&_th]:border [&_td]:border\",\n \"[&_th]:border-border [&_td]:border-border\",\n \"[&_a]:underline\",\n);\n\nexport interface GenieChatMessageProps {\n /** The message object to render */\n message: GenieMessageItem;\n /** Additional CSS class */\n className?: string;\n}\n\nfunction isQueryAttachment(att: GenieAttachmentResponse): boolean {\n return !!(att.query?.title || att.query?.query);\n}\n\n/** Renders a single Genie message bubble with optional expandable SQL query attachments. */\nexport function GenieChatMessage({\n message,\n className,\n}: GenieChatMessageProps) {\n const isUser = message.role === \"user\";\n const queryAttachments = message.attachments.filter(isQueryAttachment);\n const html = useMemo(\n () => (message.content ? (marked.parse(message.content) as string) : \"\"),\n [message.content],\n );\n\n return (\n <div\n className={cn(\n \"flex gap-3\",\n isUser ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Avatar className=\"h-8 w-8 shrink-0 mt-1\">\n <AvatarFallback\n className={cn(\n \"text-xs font-medium\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {isUser ? \"You\" : \"AI\"}\n </AvatarFallback>\n </Avatar>\n\n <div\n className={cn(\n \"flex flex-col gap-2 max-w-[80%] min-w-0 overflow-hidden\",\n isUser ? \"items-end\" : \"items-start\",\n )}\n >\n <Card\n className={cn(\n \"px-4 py-3 max-w-full overflow-hidden\",\n isUser ? \"bg-primary text-primary-foreground\" : \"bg-muted\",\n )}\n >\n {html && (\n <div\n className={markdownStyles}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n )}\n\n {message.error && (\n <p className=\"text-sm text-destructive mt-1\">{message.error}</p>\n )}\n </Card>\n\n {queryAttachments.length > 0 && (\n <div className=\"flex flex-col gap-2 w-full min-w-0\">\n {queryAttachments.map((att) => (\n <Card\n key={att.attachmentId ?? \"query\"}\n className=\"px-4 py-3 text-xs overflow-hidden shadow-none\"\n >\n <details>\n <summary className=\"cursor-pointer select-none font-medium\">\n {att.query?.title ?? \"SQL Query\"}\n </summary>\n <div className=\"mt-2 flex flex-col gap-1\">\n {att.query?.description && (\n <span className=\"text-muted-foreground\">\n {att.query.description}\n </span>\n )}\n {att.query?.query && (\n <pre className=\"mt-1 p-2 rounded bg-background text-[11px] whitespace-pre-wrap break-all\">\n {att.query.query}\n </pre>\n )}\n </div>\n </details>\n </Card>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,OAAO,WAAW;CAAE,QAAQ;CAAM,KAAK;CAAM,CAAC;AAE9C,MAAM,iBAAiB,GACrB,WACA,kDACA,gGACA,6EACA,qEACA,yDACA,6CACA,kBACD;AASD,SAAS,kBAAkB,KAAuC;AAChE,QAAO,CAAC,EAAE,IAAI,OAAO,SAAS,IAAI,OAAO;;;AAI3C,SAAgB,iBAAiB,EAC/B,SACA,aACwB;CACxB,MAAM,SAAS,QAAQ,SAAS;CAChC,MAAM,mBAAmB,QAAQ,YAAY,OAAO,kBAAkB;CACtE,MAAM,OAAO,cACJ,QAAQ,UAAW,OAAO,MAAM,QAAQ,QAAQ,GAAc,IACrE,CAAC,QAAQ,QAAQ,CAClB;AAED,QACE,qBAAC,OAAD;EACE,WAAW,GACT,cACA,SAAS,qBAAqB,YAC9B,UACD;YALH,CAOE,oBAAC,QAAD;GAAQ,WAAU;aAChB,oBAAC,gBAAD;IACE,WAAW,GACT,uBACA,SAAS,uCAAuC,WACjD;cAEA,SAAS,QAAQ;IACH;GACV,GAET,qBAAC,OAAD;GACE,WAAW,GACT,2DACA,SAAS,cAAc,cACxB;aAJH,CAME,qBAAC,MAAD;IACE,WAAW,GACT,wCACA,SAAS,uCAAuC,WACjD;cAJH,CAMG,QACC,oBAAC,OAAD;KACE,WAAW;KACX,yBAAyB,EAAE,QAAQ,MAAM;KACzC,GAGH,QAAQ,SACP,oBAAC,KAAD;KAAG,WAAU;eAAiC,QAAQ;KAAU,EAE7D;OAEN,iBAAiB,SAAS,KACzB,oBAAC,OAAD;IAAK,WAAU;cACZ,iBAAiB,KAAK,QACrB,oBAAC,MAAD;KAEE,WAAU;eAEV,qBAAC,WAAD,aACE,oBAAC,WAAD;MAAS,WAAU;gBAChB,IAAI,OAAO,SAAS;MACb,GACV,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,IAAI,OAAO,eACV,oBAAC,QAAD;OAAM,WAAU;iBACb,IAAI,MAAM;OACN,GAER,IAAI,OAAO,SACV,oBAAC,OAAD;OAAK,WAAU;iBACZ,IAAI,MAAM;OACP,EAEJ;QACE;KACL,EApBA,IAAI,gBAAgB,QAoBpB,CACP;IACE,EAEJ;KACF"}
@@ -0,0 +1,14 @@
1
+ import { GenieChatProps } from "./types.js";
2
+ import * as react_jsx_runtime286 from "react/jsx-runtime";
3
+
4
+ //#region src/react/genie/genie-chat.d.ts
5
+ /** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */
6
+ declare function GenieChat({
7
+ alias,
8
+ basePath,
9
+ placeholder,
10
+ className
11
+ }: GenieChatProps): react_jsx_runtime286.JSX.Element;
12
+ //#endregion
13
+ export { GenieChat };
14
+ //# sourceMappingURL=genie-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"sourcesContent":[],"mappings":";;;;;iBAQgB,SAAA;;;;;GAKb,iBAAc,oBAAA,CAAA,GAAA,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Button } from "../ui/button.js";
3
+ import { GenieChatInput } from "./genie-chat-input.js";
4
+ import { GenieChatMessageList } from "./genie-chat-message-list.js";
5
+ import { useGenieChat } from "./use-genie-chat.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/react/genie/genie-chat.tsx
9
+ /** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */
10
+ function GenieChat({ alias, basePath, placeholder, className }) {
11
+ const { messages, status, error, sendMessage, reset } = useGenieChat({
12
+ alias,
13
+ basePath
14
+ });
15
+ return /* @__PURE__ */ jsxs("div", {
16
+ className: cn("flex flex-col h-full overflow-hidden", className),
17
+ children: [
18
+ messages.length > 0 && /* @__PURE__ */ jsx("div", {
19
+ className: "shrink-0 flex justify-end px-4 pt-3 pb-1",
20
+ children: /* @__PURE__ */ jsx(Button, {
21
+ variant: "ghost",
22
+ size: "sm",
23
+ onClick: reset,
24
+ className: "text-xs text-muted-foreground",
25
+ children: "New conversation"
26
+ })
27
+ }),
28
+ /* @__PURE__ */ jsx(GenieChatMessageList, {
29
+ messages,
30
+ status
31
+ }),
32
+ error && /* @__PURE__ */ jsx("div", {
33
+ className: "shrink-0 px-4 py-2 text-sm text-destructive bg-destructive/10 border-t",
34
+ children: error
35
+ }),
36
+ /* @__PURE__ */ jsx(GenieChatInput, {
37
+ onSend: sendMessage,
38
+ disabled: status === "streaming" || status === "loading-history",
39
+ placeholder
40
+ })
41
+ ]
42
+ });
43
+ }
44
+
45
+ //#endregion
46
+ export { GenieChat };
47
+ //# sourceMappingURL=genie-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genie-chat.js","names":[],"sources":["../../../src/react/genie/genie-chat.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport { GenieChatInput } from \"./genie-chat-input\";\nimport { GenieChatMessageList } from \"./genie-chat-message-list\";\nimport type { GenieChatProps } from \"./types\";\nimport { useGenieChat } from \"./use-genie-chat\";\n\n/** Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE. */\nexport function GenieChat({\n alias,\n basePath,\n placeholder,\n className,\n}: GenieChatProps) {\n const { messages, status, error, sendMessage, reset } = useGenieChat({\n alias,\n basePath,\n });\n\n return (\n <div className={cn(\"flex flex-col h-full overflow-hidden\", className)}>\n {messages.length > 0 && (\n <div className=\"shrink-0 flex justify-end px-4 pt-3 pb-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={reset}\n className=\"text-xs text-muted-foreground\"\n >\n New conversation\n </Button>\n </div>\n )}\n\n <GenieChatMessageList messages={messages} status={status} />\n\n {error && (\n <div className=\"shrink-0 px-4 py-2 text-sm text-destructive bg-destructive/10 border-t\">\n {error}\n </div>\n )}\n\n <GenieChatInput\n onSend={sendMessage}\n disabled={status === \"streaming\" || status === \"loading-history\"}\n placeholder={placeholder}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,UAAU,EACxB,OACA,UACA,aACA,aACiB;CACjB,MAAM,EAAE,UAAU,QAAQ,OAAO,aAAa,UAAU,aAAa;EACnE;EACA;EACD,CAAC;AAEF,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,wCAAwC,UAAU;YAArE;GACG,SAAS,SAAS,KACjB,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,SAAS;KACT,WAAU;eACX;KAEQ;IACL;GAGR,oBAAC,sBAAD;IAAgC;IAAkB;IAAU;GAE3D,SACC,oBAAC,OAAD;IAAK,WAAU;cACZ;IACG;GAGR,oBAAC,gBAAD;IACE,QAAQ;IACR,UAAU,WAAW,eAAe,WAAW;IAClC;IACb;GACE"}
@@ -0,0 +1,5 @@
1
+ import { GenieChatInput } from "./genie-chat-input.js";
2
+ import { GenieChatMessage } from "./genie-chat-message.js";
3
+ import { GenieChatMessageList } from "./genie-chat-message-list.js";
4
+ import { useGenieChat } from "./use-genie-chat.js";
5
+ import { GenieChat } from "./genie-chat.js";
@@ -0,0 +1,44 @@
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
2
+
3
+ //#region src/react/genie/types.d.ts
4
+ type GenieChatStatus = "idle" | "loading-history" | "streaming" | "error";
5
+ interface GenieMessageItem {
6
+ id: string;
7
+ role: "user" | "assistant";
8
+ content: string;
9
+ status: string;
10
+ attachments: GenieAttachmentResponse[];
11
+ queryResults: Map<string, unknown>;
12
+ error?: string;
13
+ }
14
+ interface UseGenieChatOptions {
15
+ /** Genie space alias (maps to backend route param) */
16
+ alias: string;
17
+ /** Base API path. Default: "/api/genie" */
18
+ basePath?: string;
19
+ /** Read/write conversationId from URL search params. Default: true */
20
+ persistInUrl?: boolean;
21
+ /** URL search param name. Default: "conversationId" */
22
+ urlParamName?: string;
23
+ }
24
+ interface UseGenieChatReturn {
25
+ messages: GenieMessageItem[];
26
+ status: GenieChatStatus;
27
+ conversationId: string | null;
28
+ error: string | null;
29
+ sendMessage: (content: string) => void;
30
+ reset: () => void;
31
+ }
32
+ interface GenieChatProps {
33
+ /** Genie space alias (must match a key registered with the genie plugin on the server) */
34
+ alias: string;
35
+ /** Base API path */
36
+ basePath?: string;
37
+ /** Placeholder text for the input */
38
+ placeholder?: string;
39
+ /** Additional CSS class for the root container */
40
+ className?: string;
41
+ }
42
+ //#endregion
43
+ export { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn };
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/react/genie/types.ts"],"sourcesContent":[],"mappings":";;;KAQY,eAAA;AAAA,UAMK,gBAAA,CANU;EAMV,EAAA,EAAA,MAAA;EAAgB,IAAA,EAAA,MAAA,GAAA,WAAA;SAKlB,EAAA,MAAA;QACC,EAAA,MAAA;EAAG,WAAA,EADJ,uBACI,EAAA;EAIF,YAAA,EAJD,GAIC,CAAA,MAAmB,EAAA,OAAA,CAAA;EAWnB,KAAA,CAAA,EAAA,MAAA;;AACL,UAZK,mBAAA,CAYL;;EACa,KAAA,EAAA,MAAA;EAOR;;;;;;;UATA,kBAAA;YACL;UACF;;;;;;UAOO,cAAA"}
@@ -0,0 +1,17 @@
1
+ import { UseGenieChatOptions, UseGenieChatReturn } from "./types.js";
2
+
3
+ //#region src/react/genie/use-genie-chat.d.ts
4
+
5
+ /**
6
+ * Manages the full Genie chat lifecycle:
7
+ * SSE streaming, conversation persistence via URL, and history replay.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const { messages, status, sendMessage, reset } = useGenieChat({ alias: "demo" });
12
+ * ```
13
+ */
14
+ declare function useGenieChat(options: UseGenieChatOptions): UseGenieChatReturn;
15
+ //#endregion
16
+ export { useGenieChat };
17
+ //# sourceMappingURL=use-genie-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-genie-chat.d.ts","names":[],"sources":["../../../src/react/genie/use-genie-chat.ts"],"sourcesContent":[],"mappings":";;;;;;AAoFA;;;;;;;iBAAgB,YAAA,UAAsB,sBAAsB"}
@@ -0,0 +1,254 @@
1
+ import { connectSSE } from "../../js/sse/connect-sse.js";
2
+ import "../../js/index.js";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+
5
+ //#region src/react/genie/use-genie-chat.ts
6
+ function getUrlParam(name) {
7
+ return new URLSearchParams(window.location.search).get(name);
8
+ }
9
+ function setUrlParam(name, value) {
10
+ const url = new URL(window.location.href);
11
+ url.searchParams.set(name, value);
12
+ window.history.replaceState({}, "", url.toString());
13
+ }
14
+ function removeUrlParam(name) {
15
+ const url = new URL(window.location.href);
16
+ url.searchParams.delete(name);
17
+ window.history.replaceState({}, "", url.toString());
18
+ }
19
+ /**
20
+ * The Genie API puts the user's question in `message.content` and the
21
+ * actual AI answer in text attachments. Extract the text attachment
22
+ * content so we display the real answer, not the question echo.
23
+ */
24
+ function extractAssistantContent(msg) {
25
+ const textParts = (msg.attachments ?? []).map((att) => att.text?.content).filter(Boolean);
26
+ return textParts.length > 0 ? textParts.join("\n\n") : msg.content;
27
+ }
28
+ function makeUserItem(msg, idSuffix = "") {
29
+ return {
30
+ id: `${msg.messageId}${idSuffix}`,
31
+ role: "user",
32
+ content: msg.content,
33
+ status: msg.status,
34
+ attachments: [],
35
+ queryResults: /* @__PURE__ */ new Map()
36
+ };
37
+ }
38
+ function makeAssistantItem(msg) {
39
+ return {
40
+ id: msg.messageId,
41
+ role: "assistant",
42
+ content: extractAssistantContent(msg),
43
+ status: msg.status,
44
+ attachments: msg.attachments ?? [],
45
+ queryResults: /* @__PURE__ */ new Map(),
46
+ error: msg.error
47
+ };
48
+ }
49
+ /**
50
+ * The API bundles user question (content) and AI answer (attachments) in one message.
51
+ * Split into separate user + assistant items for display.
52
+ */
53
+ function messageResultToItems(msg) {
54
+ if (!((msg.attachments?.length ?? 0) > 0)) return [makeUserItem(msg)];
55
+ return [makeUserItem(msg, "-user"), makeAssistantItem(msg)];
56
+ }
57
+ /**
58
+ * Manages the full Genie chat lifecycle:
59
+ * SSE streaming, conversation persistence via URL, and history replay.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * const { messages, status, sendMessage, reset } = useGenieChat({ alias: "demo" });
64
+ * ```
65
+ */
66
+ function useGenieChat(options) {
67
+ const { alias, basePath = "/api/genie", persistInUrl = true, urlParamName = "conversationId" } = options;
68
+ const [messages, setMessages] = useState([]);
69
+ const [status, setStatus] = useState("idle");
70
+ const [conversationId, setConversationId] = useState(null);
71
+ const [error, setError] = useState(null);
72
+ const abortControllerRef = useRef(null);
73
+ const conversationIdRef = useRef(null);
74
+ useEffect(() => {
75
+ conversationIdRef.current = conversationId;
76
+ }, [conversationId]);
77
+ const processEvent = useCallback((event, isHistory) => {
78
+ switch (event.type) {
79
+ case "message_start":
80
+ setConversationId(event.conversationId);
81
+ if (persistInUrl) setUrlParam(urlParamName, event.conversationId);
82
+ break;
83
+ case "status":
84
+ setMessages((prev) => {
85
+ const last = prev[prev.length - 1];
86
+ if (last?.role === "assistant") return [...prev.slice(0, -1), {
87
+ ...last,
88
+ status: event.status
89
+ }];
90
+ return prev;
91
+ });
92
+ break;
93
+ case "message_result": {
94
+ const msg = event.message;
95
+ const hasAttachments = (msg.attachments?.length ?? 0) > 0;
96
+ if (isHistory) {
97
+ const items = messageResultToItems(msg);
98
+ setMessages((prev) => [...prev, ...items]);
99
+ } else if (hasAttachments) {
100
+ const item = makeAssistantItem(msg);
101
+ setMessages((prev) => {
102
+ const last = prev[prev.length - 1];
103
+ if (last?.role === "assistant" && last.id === "") return [...prev.slice(0, -1), item];
104
+ return [...prev, item];
105
+ });
106
+ }
107
+ break;
108
+ }
109
+ case "query_result":
110
+ setMessages((prev) => {
111
+ const updated = [...prev];
112
+ for (let i = updated.length - 1; i >= 0; i--) {
113
+ const msg = updated[i];
114
+ if (msg.attachments.some((a) => a.attachmentId === event.attachmentId)) {
115
+ const queryResults = new Map(msg.queryResults);
116
+ queryResults.set(event.attachmentId, event.data);
117
+ updated[i] = {
118
+ ...msg,
119
+ queryResults
120
+ };
121
+ break;
122
+ }
123
+ }
124
+ return updated;
125
+ });
126
+ break;
127
+ case "error":
128
+ setError(event.error);
129
+ setStatus("error");
130
+ break;
131
+ }
132
+ }, [persistInUrl, urlParamName]);
133
+ const sendMessage = useCallback((content) => {
134
+ const trimmed = content.trim();
135
+ if (!trimmed) return;
136
+ abortControllerRef.current?.abort();
137
+ setError(null);
138
+ setStatus("streaming");
139
+ const userMessage = {
140
+ id: crypto.randomUUID(),
141
+ role: "user",
142
+ content: trimmed,
143
+ status: "COMPLETED",
144
+ attachments: [],
145
+ queryResults: /* @__PURE__ */ new Map()
146
+ };
147
+ const assistantPlaceholder = {
148
+ id: "",
149
+ role: "assistant",
150
+ content: "",
151
+ status: "ASKING_AI",
152
+ attachments: [],
153
+ queryResults: /* @__PURE__ */ new Map()
154
+ };
155
+ setMessages((prev) => [
156
+ ...prev,
157
+ userMessage,
158
+ assistantPlaceholder
159
+ ]);
160
+ const abortController = new AbortController();
161
+ abortControllerRef.current = abortController;
162
+ const requestId = crypto.randomUUID();
163
+ connectSSE({
164
+ url: `${basePath}/${encodeURIComponent(alias)}/messages?requestId=${encodeURIComponent(requestId)}`,
165
+ payload: {
166
+ content: trimmed,
167
+ conversationId: conversationIdRef.current ?? void 0
168
+ },
169
+ signal: abortController.signal,
170
+ onMessage: async (message) => {
171
+ try {
172
+ processEvent(JSON.parse(message.data), false);
173
+ } catch {}
174
+ },
175
+ onError: (err) => {
176
+ if (abortController.signal.aborted) return;
177
+ setError(err instanceof Error ? err.message : "Connection error. Please try again.");
178
+ setStatus("error");
179
+ setMessages((prev) => {
180
+ const last = prev[prev.length - 1];
181
+ return last?.role === "assistant" && last.id === "" ? prev.slice(0, -1) : prev;
182
+ });
183
+ }
184
+ }).then(() => {
185
+ if (!abortController.signal.aborted) setStatus((prev) => prev === "error" ? "error" : "idle");
186
+ });
187
+ }, [
188
+ alias,
189
+ basePath,
190
+ processEvent
191
+ ]);
192
+ const loadHistory = useCallback((convId) => {
193
+ abortControllerRef.current?.abort();
194
+ setStatus("loading-history");
195
+ setError(null);
196
+ setMessages([]);
197
+ setConversationId(convId);
198
+ const abortController = new AbortController();
199
+ abortControllerRef.current = abortController;
200
+ const requestId = crypto.randomUUID();
201
+ connectSSE({
202
+ url: `${basePath}/${encodeURIComponent(alias)}/conversations/${encodeURIComponent(convId)}?requestId=${encodeURIComponent(requestId)}`,
203
+ signal: abortController.signal,
204
+ onMessage: async (message) => {
205
+ try {
206
+ processEvent(JSON.parse(message.data), true);
207
+ } catch {}
208
+ },
209
+ onError: (err) => {
210
+ if (abortController.signal.aborted) return;
211
+ setError(err instanceof Error ? err.message : "Failed to load conversation history.");
212
+ setStatus("error");
213
+ }
214
+ }).then(() => {
215
+ if (!abortController.signal.aborted) setStatus((prev) => prev === "error" ? "error" : "idle");
216
+ });
217
+ }, [
218
+ alias,
219
+ basePath,
220
+ processEvent
221
+ ]);
222
+ const reset = useCallback(() => {
223
+ abortControllerRef.current?.abort();
224
+ setMessages([]);
225
+ setConversationId(null);
226
+ setError(null);
227
+ setStatus("idle");
228
+ if (persistInUrl) removeUrlParam(urlParamName);
229
+ }, [persistInUrl, urlParamName]);
230
+ useEffect(() => {
231
+ if (!persistInUrl) return;
232
+ const existingId = getUrlParam(urlParamName);
233
+ if (existingId) loadHistory(existingId);
234
+ return () => {
235
+ abortControllerRef.current?.abort();
236
+ };
237
+ }, [
238
+ persistInUrl,
239
+ urlParamName,
240
+ loadHistory
241
+ ]);
242
+ return {
243
+ messages,
244
+ status,
245
+ conversationId,
246
+ error,
247
+ sendMessage,
248
+ reset
249
+ };
250
+ }
251
+
252
+ //#endregion
253
+ export { useGenieChat };
254
+ //# sourceMappingURL=use-genie-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-genie-chat.js","names":[],"sources":["../../../src/react/genie/use-genie-chat.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { connectSSE } from \"@/js\";\nimport type {\n GenieChatStatus,\n GenieMessageItem,\n GenieMessageResponse,\n GenieStreamEvent,\n UseGenieChatOptions,\n UseGenieChatReturn,\n} from \"./types\";\n\nfunction getUrlParam(name: string): string | null {\n return new URLSearchParams(window.location.search).get(name);\n}\n\nfunction setUrlParam(name: string, value: string): void {\n const url = new URL(window.location.href);\n url.searchParams.set(name, value);\n window.history.replaceState({}, \"\", url.toString());\n}\n\nfunction removeUrlParam(name: string): void {\n const url = new URL(window.location.href);\n url.searchParams.delete(name);\n window.history.replaceState({}, \"\", url.toString());\n}\n\n/**\n * The Genie API puts the user's question in `message.content` and the\n * actual AI answer in text attachments. Extract the text attachment\n * content so we display the real answer, not the question echo.\n */\nfunction extractAssistantContent(msg: GenieMessageResponse): string {\n const textParts = (msg.attachments ?? [])\n .map((att) => att.text?.content)\n .filter(Boolean) as string[];\n return textParts.length > 0 ? textParts.join(\"\\n\\n\") : msg.content;\n}\n\nfunction makeUserItem(\n msg: GenieMessageResponse,\n idSuffix = \"\",\n): GenieMessageItem {\n return {\n id: `${msg.messageId}${idSuffix}`,\n role: \"user\",\n content: msg.content,\n status: msg.status,\n attachments: [],\n queryResults: new Map(),\n };\n}\n\nfunction makeAssistantItem(msg: GenieMessageResponse): GenieMessageItem {\n return {\n id: msg.messageId,\n role: \"assistant\",\n content: extractAssistantContent(msg),\n status: msg.status,\n attachments: msg.attachments ?? [],\n queryResults: new Map(),\n error: msg.error,\n };\n}\n\n/**\n * The API bundles user question (content) and AI answer (attachments) in one message.\n * Split into separate user + assistant items for display.\n */\nfunction messageResultToItems(msg: GenieMessageResponse): GenieMessageItem[] {\n const hasAttachments = (msg.attachments?.length ?? 0) > 0;\n if (!hasAttachments) return [makeUserItem(msg)];\n return [makeUserItem(msg, \"-user\"), makeAssistantItem(msg)];\n}\n\n/**\n * Manages the full Genie chat lifecycle:\n * SSE streaming, conversation persistence via URL, and history replay.\n *\n * @example\n * ```tsx\n * const { messages, status, sendMessage, reset } = useGenieChat({ alias: \"demo\" });\n * ```\n */\nexport function useGenieChat(options: UseGenieChatOptions): UseGenieChatReturn {\n const {\n alias,\n basePath = \"/api/genie\",\n persistInUrl = true,\n urlParamName = \"conversationId\",\n } = options;\n\n const [messages, setMessages] = useState<GenieMessageItem[]>([]);\n const [status, setStatus] = useState<GenieChatStatus>(\"idle\");\n const [conversationId, setConversationId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const conversationIdRef = useRef<string | null>(null);\n\n useEffect(() => {\n conversationIdRef.current = conversationId;\n }, [conversationId]);\n\n const processEvent = useCallback(\n (event: GenieStreamEvent, isHistory: boolean) => {\n switch (event.type) {\n case \"message_start\": {\n setConversationId(event.conversationId);\n if (persistInUrl) {\n setUrlParam(urlParamName, event.conversationId);\n }\n break;\n }\n\n case \"status\": {\n setMessages((prev) => {\n const last = prev[prev.length - 1];\n if (last?.role === \"assistant\") {\n return [...prev.slice(0, -1), { ...last, status: event.status }];\n }\n return prev;\n });\n break;\n }\n\n case \"message_result\": {\n const msg = event.message;\n const hasAttachments = (msg.attachments?.length ?? 0) > 0;\n\n if (isHistory) {\n const items = messageResultToItems(msg);\n setMessages((prev) => [...prev, ...items]);\n } else if (hasAttachments) {\n // During streaming we already appended the user message locally,\n // so only handle assistant results. Messages without attachments\n // are the user-message echo from the API — skip those.\n const item = makeAssistantItem(msg);\n setMessages((prev) => {\n const last = prev[prev.length - 1];\n if (last?.role === \"assistant\" && last.id === \"\") {\n return [...prev.slice(0, -1), item];\n }\n return [...prev, item];\n });\n }\n break;\n }\n\n case \"query_result\": {\n setMessages((prev) => {\n const updated = [...prev];\n for (let i = updated.length - 1; i >= 0; i--) {\n const msg = updated[i];\n if (\n msg.attachments.some(\n (a) => a.attachmentId === event.attachmentId,\n )\n ) {\n const queryResults = new Map(msg.queryResults);\n queryResults.set(event.attachmentId, event.data);\n updated[i] = { ...msg, queryResults };\n break;\n }\n }\n return updated;\n });\n break;\n }\n\n case \"error\": {\n setError(event.error);\n setStatus(\"error\");\n break;\n }\n }\n },\n [persistInUrl, urlParamName],\n );\n\n const sendMessage = useCallback(\n (content: string) => {\n const trimmed = content.trim();\n if (!trimmed) return;\n\n abortControllerRef.current?.abort();\n setError(null);\n setStatus(\"streaming\");\n\n const userMessage: GenieMessageItem = {\n id: crypto.randomUUID(),\n role: \"user\",\n content: trimmed,\n status: \"COMPLETED\",\n attachments: [],\n queryResults: new Map(),\n };\n\n const assistantPlaceholder: GenieMessageItem = {\n id: \"\",\n role: \"assistant\",\n content: \"\",\n status: \"ASKING_AI\",\n attachments: [],\n queryResults: new Map(),\n };\n\n setMessages((prev) => [...prev, userMessage, assistantPlaceholder]);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const requestId = crypto.randomUUID();\n\n connectSSE({\n url: `${basePath}/${encodeURIComponent(alias)}/messages?requestId=${encodeURIComponent(requestId)}`,\n payload: {\n content: trimmed,\n conversationId: conversationIdRef.current ?? undefined,\n },\n signal: abortController.signal,\n onMessage: async (message) => {\n try {\n processEvent(JSON.parse(message.data) as GenieStreamEvent, false);\n } catch {\n // Malformed SSE data\n }\n },\n onError: (err) => {\n if (abortController.signal.aborted) return;\n setError(\n err instanceof Error\n ? err.message\n : \"Connection error. Please try again.\",\n );\n setStatus(\"error\");\n setMessages((prev) => {\n const last = prev[prev.length - 1];\n return last?.role === \"assistant\" && last.id === \"\"\n ? prev.slice(0, -1)\n : prev;\n });\n },\n }).then(() => {\n if (!abortController.signal.aborted) {\n setStatus((prev) => (prev === \"error\" ? \"error\" : \"idle\"));\n }\n });\n },\n [alias, basePath, processEvent],\n );\n\n const loadHistory = useCallback(\n (convId: string) => {\n abortControllerRef.current?.abort();\n setStatus(\"loading-history\");\n setError(null);\n setMessages([]);\n setConversationId(convId);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const requestId = crypto.randomUUID();\n\n connectSSE({\n url: `${basePath}/${encodeURIComponent(alias)}/conversations/${encodeURIComponent(convId)}?requestId=${encodeURIComponent(requestId)}`,\n signal: abortController.signal,\n onMessage: async (message) => {\n try {\n processEvent(JSON.parse(message.data) as GenieStreamEvent, true);\n } catch {\n // Malformed SSE data\n }\n },\n onError: (err) => {\n if (abortController.signal.aborted) return;\n setError(\n err instanceof Error\n ? err.message\n : \"Failed to load conversation history.\",\n );\n setStatus(\"error\");\n },\n }).then(() => {\n if (!abortController.signal.aborted) {\n setStatus((prev) => (prev === \"error\" ? \"error\" : \"idle\"));\n }\n });\n },\n [alias, basePath, processEvent],\n );\n\n const reset = useCallback(() => {\n abortControllerRef.current?.abort();\n setMessages([]);\n setConversationId(null);\n setError(null);\n setStatus(\"idle\");\n if (persistInUrl) {\n removeUrlParam(urlParamName);\n }\n }, [persistInUrl, urlParamName]);\n\n useEffect(() => {\n if (!persistInUrl) return;\n const existingId = getUrlParam(urlParamName);\n if (existingId) {\n loadHistory(existingId);\n }\n return () => {\n abortControllerRef.current?.abort();\n };\n }, [persistInUrl, urlParamName, loadHistory]);\n\n return { messages, status, conversationId, error, sendMessage, reset };\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../shared/src/genie.js";
1
2
  import { DATE_FIELD_PATTERNS, METADATA_DATE_PATTERNS, NAME_FIELD_PATTERNS } from "../js/constants.js";
2
3
  import { AreaChartProps, AreaChartSpecificProps, BarChartProps, BarChartSpecificProps, ChartBaseProps, ChartColorPalette, ChartData, ChartType, DataFormat, DataProps, DonutChartProps, HeatmapChartProps, HeatmapChartSpecificProps, LineChartProps, LineChartSpecificProps, NormalizedChartData, NormalizedChartDataBase, Orientation, PieChartProps, PieChartSpecificProps, QueryProps, RadarChartProps, RadarChartSpecificProps, ScatterChartProps, ScatterChartSpecificProps, UnifiedChartProps, isArrowTable, isDataProps, isQueryProps } from "./charts/types.js";
3
4
  import { AreaChart } from "./charts/area/index.js";
@@ -16,6 +17,12 @@ import { CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERG
16
17
  import { useAllThemeColors, useThemeColors } from "./charts/theme.js";
17
18
  import { createTimeSeriesData, formatLabel, sortTimeSeriesAscending, toChartArray, toChartValue, truncateLabel } from "./charts/utils.js";
18
19
  import { CartesianContext, HeatmapContext, OptionBuilderContext, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./charts/options.js";
20
+ import { GenieChatProps, GenieChatStatus, GenieMessageItem, UseGenieChatOptions, UseGenieChatReturn } from "./genie/types.js";
21
+ import { GenieChat } from "./genie/genie-chat.js";
22
+ import { GenieChatInput } from "./genie/genie-chat-input.js";
23
+ import { GenieChatMessage } from "./genie/genie-chat-message.js";
24
+ import { GenieChatMessageList } from "./genie/genie-chat-message-list.js";
25
+ import { useGenieChat } from "./genie/use-genie-chat.js";
19
26
  import { AnalyticsFormat, InferResultByFormat, InferRowType, PluginRegistry, QueryRegistry, TypedArrowTable, UseAnalyticsQueryOptions, UseAnalyticsQueryResult } from "./hooks/types.js";
20
27
  import { useAnalyticsQuery } from "./hooks/use-analytics-query.js";
21
28
  import { cn } from "./lib/utils.js";
@@ -74,4 +81,4 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs.js";
74
81
  import { Textarea } from "./ui/textarea.js";
75
82
  import { Toggle, toggleVariants } from "./ui/toggle.js";
76
83
  import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group.js";
77
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnalyticsFormat, AreaChart, AreaChartProps, AreaChartSpecificProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BarChartProps, BarChartSpecificProps, BaseChart, BaseChartProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianContext, ChartBaseProps, ChartColorPalette, ChartConfig, ChartContainer, ChartData, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DATE_FIELD_PATTERNS, DataFormat, DataProps, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, DonutChartProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FALLBACK_COLORS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HeatmapChart, HeatmapChartProps, HeatmapChartSpecificProps, HeatmapContext, HoverCard, HoverCardContent, HoverCardTrigger, InferResultByFormat, InferRowType, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, LineChart, LineChartProps, LineChartSpecificProps, METADATA_DATE_PATTERNS, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NAME_FIELD_PATTERNS, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NormalizedChartData, NormalizedChartDataBase, NormalizedHeatmapData, OptionBuilderContext, Orientation, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, PieChartProps, PieChartSpecificProps, PluginRegistry, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, QueryProps, QueryRegistry, RadarChart, RadarChartProps, RadarChartSpecificProps, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, ScatterChartProps, ScatterChartSpecificProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };
84
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnalyticsFormat, AreaChart, AreaChartProps, AreaChartSpecificProps, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BarChart, BarChartProps, BarChartSpecificProps, BaseChart, BaseChartProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianContext, ChartBaseProps, ChartColorPalette, ChartConfig, ChartContainer, ChartData, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, ChartType, ChartWrapper, ChartWrapperProps, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DATE_FIELD_PATTERNS, DataFormat, DataProps, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DonutChart, DonutChartProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FALLBACK_COLORS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GenieAttachmentResponse, GenieChat, GenieChatInput, GenieChatMessage, GenieChatMessageList, GenieChatProps, GenieChatStatus, GenieMessageItem, GenieMessageResponse, GenieStreamEvent, HeatmapChart, HeatmapChartProps, HeatmapChartSpecificProps, HeatmapContext, HoverCard, HoverCardContent, HoverCardTrigger, InferResultByFormat, InferRowType, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label, LineChart, LineChartProps, LineChartSpecificProps, METADATA_DATE_PATTERNS, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NAME_FIELD_PATTERNS, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NormalizedChartData, NormalizedChartDataBase, NormalizedHeatmapData, OptionBuilderContext, Orientation, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PieChart, PieChartProps, PieChartSpecificProps, PluginRegistry, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PortalContainerContext, PortalContainerProvider, Progress, QueryProps, QueryRegistry, RadarChart, RadarChartProps, RadarChartSpecificProps, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScatterChart, ScatterChartProps, ScatterChartSpecificProps, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypedArrowTable, UnifiedChartProps, UseAnalyticsQueryOptions, UseAnalyticsQueryResult, UseChartDataOptions, UseChartDataResult, UseGenieChatOptions, UseGenieChatReturn, badgeVariants, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption, buttonGroupVariants, buttonVariants, cn, createChart, createTimeSeriesData, formatLabel, isArrowTable, isDataProps, isQueryProps, navigationMenuTriggerStyle, normalizeChartData, normalizeHeatmapData, sortTimeSeriesAscending, toChartArray, toChartValue, toggleVariants, truncateLabel, useAllThemeColors, useAnalyticsQuery, useChartData, useFormField, useGenieChat, usePortalContainer, useResolvedPortalContainer, useSidebar, useThemeColors };