@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.
- package/CLAUDE.md +4 -0
- package/NOTICE.md +1 -0
- package/dist/react/charts/area/index.d.ts +2 -2
- package/dist/react/charts/bar/index.d.ts +2 -2
- package/dist/react/charts/base.d.ts +2 -2
- package/dist/react/charts/base.d.ts.map +1 -1
- package/dist/react/charts/base.js.map +1 -1
- package/dist/react/charts/chart-error-boundary.js.map +1 -1
- package/dist/react/charts/create-chart.d.ts +2 -2
- package/dist/react/charts/create-chart.d.ts.map +1 -1
- package/dist/react/charts/create-chart.js.map +1 -1
- package/dist/react/charts/empty.js.map +1 -1
- package/dist/react/charts/error.js.map +1 -1
- package/dist/react/charts/heatmap/index.d.ts +2 -2
- package/dist/react/charts/line/index.d.ts +2 -2
- package/dist/react/charts/loading.js.map +1 -1
- package/dist/react/charts/options.d.ts.map +1 -1
- package/dist/react/charts/pie/index.d.ts +3 -3
- package/dist/react/charts/radar/index.d.ts +2 -2
- package/dist/react/charts/scatter/index.d.ts +2 -2
- package/dist/react/charts/wrapper.d.ts +2 -2
- package/dist/react/charts/wrapper.d.ts.map +1 -1
- package/dist/react/charts/wrapper.js.map +1 -1
- package/dist/react/genie/genie-chat-input.d.ts +23 -0
- package/dist/react/genie/genie-chat-input.d.ts.map +1 -0
- package/dist/react/genie/genie-chat-input.js +58 -0
- package/dist/react/genie/genie-chat-input.js.map +1 -0
- package/dist/react/genie/genie-chat-message-list.d.ts +21 -0
- package/dist/react/genie/genie-chat-message-list.d.ts.map +1 -0
- package/dist/react/genie/genie-chat-message-list.js +64 -0
- package/dist/react/genie/genie-chat-message-list.js.map +1 -0
- package/dist/react/genie/genie-chat-message.d.ts +18 -0
- package/dist/react/genie/genie-chat-message.d.ts.map +1 -0
- package/dist/react/genie/genie-chat-message.js +71 -0
- package/dist/react/genie/genie-chat-message.js.map +1 -0
- package/dist/react/genie/genie-chat.d.ts +14 -0
- package/dist/react/genie/genie-chat.d.ts.map +1 -0
- package/dist/react/genie/genie-chat.js +47 -0
- package/dist/react/genie/genie-chat.js.map +1 -0
- package/dist/react/genie/index.js +5 -0
- package/dist/react/genie/types.d.ts +44 -0
- package/dist/react/genie/types.d.ts.map +1 -0
- package/dist/react/genie/use-genie-chat.d.ts +17 -0
- package/dist/react/genie/use-genie-chat.d.ts.map +1 -0
- package/dist/react/genie/use-genie-chat.js +254 -0
- package/dist/react/genie/use-genie-chat.js.map +1 -0
- package/dist/react/index.d.ts +8 -1
- package/dist/react/index.js +14 -8
- package/dist/react/portal-container-context.js.map +1 -1
- package/dist/react/table/data-table.d.ts +2 -2
- package/dist/react/table/data-table.d.ts.map +1 -1
- package/dist/react/table/data-table.js +2 -2
- package/dist/react/table/data-table.js.map +1 -1
- package/dist/react/table/empty.js.map +1 -1
- package/dist/react/table/error.js.map +1 -1
- package/dist/react/table/loading.js.map +1 -1
- package/dist/react/table/table-wrapper.js +2 -2
- package/dist/react/table/table-wrapper.js.map +1 -1
- package/dist/react/ui/accordion.d.ts +5 -5
- package/dist/react/ui/accordion.d.ts.map +1 -1
- package/dist/react/ui/accordion.js.map +1 -1
- package/dist/react/ui/alert-dialog.d.ts +12 -12
- package/dist/react/ui/alert-dialog.js +1 -1
- package/dist/react/ui/alert-dialog.js.map +1 -1
- package/dist/react/ui/alert.d.ts +4 -4
- package/dist/react/ui/alert.d.ts.map +1 -1
- package/dist/react/ui/alert.js.map +1 -1
- package/dist/react/ui/aspect-ratio.d.ts +2 -2
- package/dist/react/ui/aspect-ratio.js.map +1 -1
- package/dist/react/ui/avatar.d.ts +4 -4
- package/dist/react/ui/avatar.js.map +1 -1
- package/dist/react/ui/badge.d.ts +2 -2
- package/dist/react/ui/badge.js.map +1 -1
- package/dist/react/ui/breadcrumb.d.ts +8 -8
- package/dist/react/ui/breadcrumb.js +1 -1
- package/dist/react/ui/breadcrumb.js.map +1 -1
- package/dist/react/ui/button-group.d.ts +4 -4
- package/dist/react/ui/button-group.js.map +1 -1
- package/dist/react/ui/button.d.ts +2 -2
- package/dist/react/ui/button.js.map +1 -1
- package/dist/react/ui/calendar.d.ts +3 -3
- package/dist/react/ui/calendar.js.map +1 -1
- package/dist/react/ui/card.d.ts +8 -8
- package/dist/react/ui/card.js.map +1 -1
- package/dist/react/ui/carousel.d.ts +6 -6
- package/dist/react/ui/carousel.js.map +1 -1
- package/dist/react/ui/chart.d.ts +5 -5
- package/dist/react/ui/chart.js.map +1 -1
- package/dist/react/ui/checkbox.d.ts +2 -2
- package/dist/react/ui/checkbox.js.map +1 -1
- package/dist/react/ui/collapsible.d.ts +4 -4
- package/dist/react/ui/collapsible.js.map +1 -1
- package/dist/react/ui/command.d.ts +10 -10
- package/dist/react/ui/command.js.map +1 -1
- package/dist/react/ui/context-menu.d.ts +16 -16
- package/dist/react/ui/context-menu.js.map +1 -1
- package/dist/react/ui/dialog.d.ts +11 -11
- package/dist/react/ui/dialog.js.map +1 -1
- package/dist/react/ui/drawer.d.ts +11 -11
- package/dist/react/ui/drawer.d.ts.map +1 -1
- package/dist/react/ui/drawer.js.map +1 -1
- package/dist/react/ui/dropdown-menu.d.ts +16 -16
- package/dist/react/ui/dropdown-menu.js.map +1 -1
- package/dist/react/ui/empty.d.ts +7 -7
- package/dist/react/ui/empty.js.map +1 -1
- package/dist/react/ui/field.d.ts +11 -11
- package/dist/react/ui/field.js.map +1 -1
- package/dist/react/ui/form.d.ts +7 -7
- package/dist/react/ui/form.js.map +1 -1
- package/dist/react/ui/hover-card.d.ts +4 -4
- package/dist/react/ui/hover-card.js.map +1 -1
- package/dist/react/ui/index.js +5 -5
- package/dist/react/ui/input-group.d.ts +7 -7
- package/dist/react/ui/input-group.js.map +1 -1
- package/dist/react/ui/input-otp.d.ts +5 -5
- package/dist/react/ui/input-otp.js.map +1 -1
- package/dist/react/ui/input.d.ts +2 -2
- package/dist/react/ui/input.js.map +1 -1
- package/dist/react/ui/item.d.ts +11 -11
- package/dist/react/ui/item.js.map +1 -1
- package/dist/react/ui/kbd.d.ts +3 -3
- package/dist/react/ui/kbd.js.map +1 -1
- package/dist/react/ui/label.d.ts +2 -2
- package/dist/react/ui/label.js.map +1 -1
- package/dist/react/ui/menubar.d.ts +17 -17
- package/dist/react/ui/menubar.js.map +1 -1
- package/dist/react/ui/navigation-menu.d.ts +9 -9
- package/dist/react/ui/navigation-menu.js +1 -1
- package/dist/react/ui/navigation-menu.js.map +1 -1
- package/dist/react/ui/pagination.d.ts +8 -8
- package/dist/react/ui/pagination.js.map +1 -1
- package/dist/react/ui/popover.d.ts +5 -5
- package/dist/react/ui/popover.js.map +1 -1
- package/dist/react/ui/progress.d.ts +2 -2
- package/dist/react/ui/progress.js.map +1 -1
- package/dist/react/ui/radio-group.d.ts +3 -3
- package/dist/react/ui/radio-group.js.map +1 -1
- package/dist/react/ui/resizable.d.ts +4 -4
- package/dist/react/ui/resizable.js.map +1 -1
- package/dist/react/ui/scroll-area.d.ts +3 -3
- package/dist/react/ui/scroll-area.js.map +1 -1
- package/dist/react/ui/select.d.ts +11 -11
- package/dist/react/ui/select.js.map +1 -1
- package/dist/react/ui/separator.d.ts +2 -2
- package/dist/react/ui/separator.js.map +1 -1
- package/dist/react/ui/sheet.d.ts +9 -9
- package/dist/react/ui/sheet.js.map +1 -1
- package/dist/react/ui/sidebar.d.ts +24 -24
- package/dist/react/ui/sidebar.js +2 -2
- package/dist/react/ui/sidebar.js.map +1 -1
- package/dist/react/ui/skeleton.d.ts +2 -2
- package/dist/react/ui/skeleton.js.map +1 -1
- package/dist/react/ui/slider.d.ts +2 -2
- package/dist/react/ui/slider.js.map +1 -1
- package/dist/react/ui/sonner.d.ts +2 -2
- package/dist/react/ui/sonner.js.map +1 -1
- package/dist/react/ui/spinner.d.ts +2 -2
- package/dist/react/ui/spinner.js.map +1 -1
- package/dist/react/ui/switch.d.ts +2 -2
- package/dist/react/ui/switch.js.map +1 -1
- package/dist/react/ui/table.d.ts +9 -9
- package/dist/react/ui/table.js.map +1 -1
- package/dist/react/ui/tabs.d.ts +5 -5
- package/dist/react/ui/tabs.js.map +1 -1
- package/dist/react/ui/textarea.d.ts +2 -2
- package/dist/react/ui/textarea.js.map +1 -1
- package/dist/react/ui/toggle-group.d.ts +3 -3
- package/dist/react/ui/toggle-group.js.map +1 -1
- package/dist/react/ui/toggle.d.ts +2 -2
- package/dist/react/ui/toggle.js.map +1 -1
- package/dist/react/ui/tooltip.d.ts +5 -5
- package/dist/react/ui/tooltip.d.ts.map +1 -1
- package/dist/react/ui/tooltip.js.map +1 -1
- package/dist/shared/src/genie.d.ts +48 -0
- package/dist/shared/src/genie.d.ts.map +1 -0
- package/docs/docs/api/appkit/Class.AppKitError/index.html +2 -2
- package/docs/docs/api/appkit/Class.AuthenticationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ConfigurationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ConnectionError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ExecutionError/index.html +2 -2
- package/docs/docs/api/appkit/Class.InitializationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.Plugin/index.html +2 -2
- package/docs/docs/api/appkit/Class.ResourceRegistry/index.html +2 -2
- package/docs/docs/api/appkit/Class.ServerError/index.html +2 -2
- package/docs/docs/api/appkit/Class.TunnelError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ValidationError/index.html +2 -2
- package/docs/docs/api/appkit/Enumeration.RequestedClaimsPermissionSet/index.html +2 -2
- package/docs/docs/api/appkit/Enumeration.ResourceType/index.html +2 -2
- package/docs/docs/api/appkit/Function.appKitTypesPlugin/index.html +2 -2
- package/docs/docs/api/appkit/Function.createApp/index.html +2 -2
- package/docs/docs/api/appkit/Function.createLakebasePool/index.html +2 -2
- package/docs/docs/api/appkit/Function.generateDatabaseCredential/index.html +2 -2
- package/docs/docs/api/appkit/Function.getExecutionContext/index.html +2 -2
- package/docs/docs/api/appkit/Function.getLakebaseOrmConfig/index.html +2 -2
- package/docs/docs/api/appkit/Function.getLakebasePgConfig/index.html +2 -2
- package/docs/docs/api/appkit/Function.getPluginManifest/index.html +2 -2
- package/docs/docs/api/appkit/Function.getResourceRequirements/index.html +2 -2
- package/docs/docs/api/appkit/Function.getUsernameWithApiLookup/index.html +2 -2
- package/docs/docs/api/appkit/Function.getWorkspaceClient/index.html +2 -2
- package/docs/docs/api/appkit/Function.isSQLTypeMarker/index.html +2 -2
- package/docs/docs/api/appkit/Interface.BasePluginConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.CacheConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.DatabaseCredential/index.html +2 -2
- package/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ITelemetry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.LakebasePoolConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.PluginManifest/index.html +2 -2
- package/docs/docs/api/appkit/Interface.RequestedClaims/index.html +2 -2
- package/docs/docs/api/appkit/Interface.RequestedResource/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceEntry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceFieldEntry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceRequirement/index.html +2 -2
- package/docs/docs/api/appkit/Interface.StreamExecutionSettings/index.html +2 -2
- package/docs/docs/api/appkit/Interface.TelemetryConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ValidationResult/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ConfigSchema/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.IAppRouter/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ResourcePermission/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ToPlugin/index.html +2 -2
- package/docs/docs/api/appkit/Variable.sql/index.html +2 -2
- package/docs/docs/api/appkit/index.html +2 -2
- package/docs/docs/api/appkit-ui/data/AreaChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/BarChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/DataTable/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/DonutChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/HeatmapChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/LineChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/PieChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/RadarChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/ScatterChart/index.html +4 -4
- package/docs/docs/api/appkit-ui/genie/GenieChat/index.html +26 -0
- package/docs/docs/api/appkit-ui/genie/GenieChat.md +43 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatInput/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatInput.md +27 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessage/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessage.md +25 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessageList/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessageList.md +26 -0
- package/docs/docs/api/appkit-ui/index.html +3 -3
- package/docs/docs/api/appkit-ui/styling/index.html +4 -4
- package/docs/docs/api/appkit-ui/ui/Accordion/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Alert/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/AlertDialog/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/AspectRatio/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Avatar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Badge/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Breadcrumb/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Button/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ButtonGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Calendar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Card/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Carousel/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ChartContainer/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Checkbox/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Collapsible/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Command/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ContextMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Dialog/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Drawer/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/DropdownMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Empty/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Field/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/FormControl/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/HoverCard/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Input/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/InputGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/InputOTP/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Item/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Kbd/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Label/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Menubar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/NavigationMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Pagination/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Popover/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Progress/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/RadioGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ResizableHandle/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ScrollArea/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Select/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Separator/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Sheet/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Sidebar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Skeleton/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Slider/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Spinner/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Switch/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Table/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Tabs/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Textarea/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Toaster/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Toggle/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ToggleGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Tooltip/index.html +3 -3
- package/docs/docs/api/index.html +2 -2
- package/docs/docs/app-management/index.html +2 -2
- package/docs/docs/architecture/index.html +2 -2
- package/docs/docs/category/development/index.html +2 -2
- package/docs/docs/configuration/index.html +2 -2
- package/docs/docs/core-principles/index.html +2 -2
- package/docs/docs/development/ai-assisted-development/index.html +2 -2
- package/docs/docs/development/index.html +2 -2
- package/docs/docs/development/llm-guide/index.html +2 -2
- package/docs/docs/development/local-development/index.html +2 -2
- package/docs/docs/development/project-setup/index.html +2 -2
- package/docs/docs/development/remote-bridge/index.html +2 -2
- package/docs/docs/development/type-generation/index.html +2 -2
- package/docs/docs/index.html +2 -2
- package/docs/docs/plugins/analytics/index.html +2 -2
- package/docs/docs/plugins/caching/index.html +2 -2
- package/docs/docs/plugins/custom-plugins/index.html +2 -2
- package/docs/docs/plugins/execution-context/index.html +2 -2
- package/docs/docs/plugins/index.html +2 -2
- package/docs/docs/plugins/lakebase/index.html +4 -4
- package/docs/docs/plugins/lakebase.md +25 -24
- package/docs/docs/plugins/plugin-management/index.html +2 -2
- package/docs/docs/plugins/server/index.html +2 -2
- package/llms.txt +4 -0
- 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":";;;;;AAWA,SAAS,YAAY,MAA6B;AAChD,QAAO,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAAC,IAAI,KAAK;;AAG9D,SAAS,YAAY,MAAc,OAAqB;CACtD,MAAM,MAAM,IAAI,IAAI,OAAO,SAAS,KAAK;AACzC,KAAI,aAAa,IAAI,MAAM,MAAM;AACjC,QAAO,QAAQ,aAAa,EAAE,EAAE,IAAI,IAAI,UAAU,CAAC;;AAGrD,SAAS,eAAe,MAAoB;CAC1C,MAAM,MAAM,IAAI,IAAI,OAAO,SAAS,KAAK;AACzC,KAAI,aAAa,OAAO,KAAK;AAC7B,QAAO,QAAQ,aAAa,EAAE,EAAE,IAAI,IAAI,UAAU,CAAC;;;;;;;AAQrD,SAAS,wBAAwB,KAAmC;CAClE,MAAM,aAAa,IAAI,eAAe,EAAE,EACrC,KAAK,QAAQ,IAAI,MAAM,QAAQ,CAC/B,OAAO,QAAQ;AAClB,QAAO,UAAU,SAAS,IAAI,UAAU,KAAK,OAAO,GAAG,IAAI;;AAG7D,SAAS,aACP,KACA,WAAW,IACO;AAClB,QAAO;EACL,IAAI,GAAG,IAAI,YAAY;EACvB,MAAM;EACN,SAAS,IAAI;EACb,QAAQ,IAAI;EACZ,aAAa,EAAE;EACf,8BAAc,IAAI,KAAK;EACxB;;AAGH,SAAS,kBAAkB,KAA6C;AACtE,QAAO;EACL,IAAI,IAAI;EACR,MAAM;EACN,SAAS,wBAAwB,IAAI;EACrC,QAAQ,IAAI;EACZ,aAAa,IAAI,eAAe,EAAE;EAClC,8BAAc,IAAI,KAAK;EACvB,OAAO,IAAI;EACZ;;;;;;AAOH,SAAS,qBAAqB,KAA+C;AAE3E,KAAI,GADoB,IAAI,aAAa,UAAU,KAAK,GACnC,QAAO,CAAC,aAAa,IAAI,CAAC;AAC/C,QAAO,CAAC,aAAa,KAAK,QAAQ,EAAE,kBAAkB,IAAI,CAAC;;;;;;;;;;;AAY7D,SAAgB,aAAa,SAAkD;CAC7E,MAAM,EACJ,OACA,WAAW,cACX,eAAe,MACf,eAAe,qBACb;CAEJ,MAAM,CAAC,UAAU,eAAe,SAA6B,EAAE,CAAC;CAChE,MAAM,CAAC,QAAQ,aAAa,SAA0B,OAAO;CAC7D,MAAM,CAAC,gBAAgB,qBAAqB,SAAwB,KAAK;CACzE,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,qBAAqB,OAA+B,KAAK;CAC/D,MAAM,oBAAoB,OAAsB,KAAK;AAErD,iBAAgB;AACd,oBAAkB,UAAU;IAC3B,CAAC,eAAe,CAAC;CAEpB,MAAM,eAAe,aAClB,OAAyB,cAAuB;AAC/C,UAAQ,MAAM,MAAd;GACE,KAAK;AACH,sBAAkB,MAAM,eAAe;AACvC,QAAI,aACF,aAAY,cAAc,MAAM,eAAe;AAEjD;GAGF,KAAK;AACH,iBAAa,SAAS;KACpB,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,SAAI,MAAM,SAAS,YACjB,QAAO,CAAC,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE;MAAE,GAAG;MAAM,QAAQ,MAAM;MAAQ,CAAC;AAElE,YAAO;MACP;AACF;GAGF,KAAK,kBAAkB;IACrB,MAAM,MAAM,MAAM;IAClB,MAAM,kBAAkB,IAAI,aAAa,UAAU,KAAK;AAExD,QAAI,WAAW;KACb,MAAM,QAAQ,qBAAqB,IAAI;AACvC,kBAAa,SAAS,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;eACjC,gBAAgB;KAIzB,MAAM,OAAO,kBAAkB,IAAI;AACnC,kBAAa,SAAS;MACpB,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,UAAI,MAAM,SAAS,eAAe,KAAK,OAAO,GAC5C,QAAO,CAAC,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK;AAErC,aAAO,CAAC,GAAG,MAAM,KAAK;OACtB;;AAEJ;;GAGF,KAAK;AACH,iBAAa,SAAS;KACpB,MAAM,UAAU,CAAC,GAAG,KAAK;AACzB,UAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;MAC5C,MAAM,MAAM,QAAQ;AACpB,UACE,IAAI,YAAY,MACb,MAAM,EAAE,iBAAiB,MAAM,aACjC,EACD;OACA,MAAM,eAAe,IAAI,IAAI,IAAI,aAAa;AAC9C,oBAAa,IAAI,MAAM,cAAc,MAAM,KAAK;AAChD,eAAQ,KAAK;QAAE,GAAG;QAAK;QAAc;AACrC;;;AAGJ,YAAO;MACP;AACF;GAGF,KAAK;AACH,aAAS,MAAM,MAAM;AACrB,cAAU,QAAQ;AAClB;;IAIN,CAAC,cAAc,aAAa,CAC7B;CAED,MAAM,cAAc,aACjB,YAAoB;EACnB,MAAM,UAAU,QAAQ,MAAM;AAC9B,MAAI,CAAC,QAAS;AAEd,qBAAmB,SAAS,OAAO;AACnC,WAAS,KAAK;AACd,YAAU,YAAY;EAEtB,MAAM,cAAgC;GACpC,IAAI,OAAO,YAAY;GACvB,MAAM;GACN,SAAS;GACT,QAAQ;GACR,aAAa,EAAE;GACf,8BAAc,IAAI,KAAK;GACxB;EAED,MAAM,uBAAyC;GAC7C,IAAI;GACJ,MAAM;GACN,SAAS;GACT,QAAQ;GACR,aAAa,EAAE;GACf,8BAAc,IAAI,KAAK;GACxB;AAED,eAAa,SAAS;GAAC,GAAG;GAAM;GAAa;GAAqB,CAAC;EAEnE,MAAM,kBAAkB,IAAI,iBAAiB;AAC7C,qBAAmB,UAAU;EAE7B,MAAM,YAAY,OAAO,YAAY;AAErC,aAAW;GACT,KAAK,GAAG,SAAS,GAAG,mBAAmB,MAAM,CAAC,sBAAsB,mBAAmB,UAAU;GACjG,SAAS;IACP,SAAS;IACT,gBAAgB,kBAAkB,WAAW;IAC9C;GACD,QAAQ,gBAAgB;GACxB,WAAW,OAAO,YAAY;AAC5B,QAAI;AACF,kBAAa,KAAK,MAAM,QAAQ,KAAK,EAAsB,MAAM;YAC3D;;GAIV,UAAU,QAAQ;AAChB,QAAI,gBAAgB,OAAO,QAAS;AACpC,aACE,eAAe,QACX,IAAI,UACJ,sCACL;AACD,cAAU,QAAQ;AAClB,iBAAa,SAAS;KACpB,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,YAAO,MAAM,SAAS,eAAe,KAAK,OAAO,KAC7C,KAAK,MAAM,GAAG,GAAG,GACjB;MACJ;;GAEL,CAAC,CAAC,WAAW;AACZ,OAAI,CAAC,gBAAgB,OAAO,QAC1B,YAAW,SAAU,SAAS,UAAU,UAAU,OAAQ;IAE5D;IAEJ;EAAC;EAAO;EAAU;EAAa,CAChC;CAED,MAAM,cAAc,aACjB,WAAmB;AAClB,qBAAmB,SAAS,OAAO;AACnC,YAAU,kBAAkB;AAC5B,WAAS,KAAK;AACd,cAAY,EAAE,CAAC;AACf,oBAAkB,OAAO;EAEzB,MAAM,kBAAkB,IAAI,iBAAiB;AAC7C,qBAAmB,UAAU;EAE7B,MAAM,YAAY,OAAO,YAAY;AAErC,aAAW;GACT,KAAK,GAAG,SAAS,GAAG,mBAAmB,MAAM,CAAC,iBAAiB,mBAAmB,OAAO,CAAC,aAAa,mBAAmB,UAAU;GACpI,QAAQ,gBAAgB;GACxB,WAAW,OAAO,YAAY;AAC5B,QAAI;AACF,kBAAa,KAAK,MAAM,QAAQ,KAAK,EAAsB,KAAK;YAC1D;;GAIV,UAAU,QAAQ;AAChB,QAAI,gBAAgB,OAAO,QAAS;AACpC,aACE,eAAe,QACX,IAAI,UACJ,uCACL;AACD,cAAU,QAAQ;;GAErB,CAAC,CAAC,WAAW;AACZ,OAAI,CAAC,gBAAgB,OAAO,QAC1B,YAAW,SAAU,SAAS,UAAU,UAAU,OAAQ;IAE5D;IAEJ;EAAC;EAAO;EAAU;EAAa,CAChC;CAED,MAAM,QAAQ,kBAAkB;AAC9B,qBAAmB,SAAS,OAAO;AACnC,cAAY,EAAE,CAAC;AACf,oBAAkB,KAAK;AACvB,WAAS,KAAK;AACd,YAAU,OAAO;AACjB,MAAI,aACF,gBAAe,aAAa;IAE7B,CAAC,cAAc,aAAa,CAAC;AAEhC,iBAAgB;AACd,MAAI,CAAC,aAAc;EACnB,MAAM,aAAa,YAAY,aAAa;AAC5C,MAAI,WACF,aAAY,WAAW;AAEzB,eAAa;AACX,sBAAmB,SAAS,OAAO;;IAEpC;EAAC;EAAc;EAAc;EAAY,CAAC;AAE7C,QAAO;EAAE;EAAU;EAAQ;EAAgB;EAAO;EAAa;EAAO"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -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 };
|