Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cec8f0c
feat(appkit): add Genie plugin for AI/BI space integration
calvarjorge Feb 17, 2026
914910f
fix(shared): handle ajv v6/v8 ErrorObject type differences
calvarjorge Feb 17, 2026
62a84e4
docs: regenerate API docs for genie plugin export
calvarjorge Feb 17, 2026
e18c4e5
fix(appkit): copy genie manifest.json to dist during build
calvarjorge Feb 17, 2026
b7cf4b8
feat(appkit): add conversation history endpoint to Genie plugin
calvarjorge Feb 18, 2026
4c53d0b
fix(appkit): simplify genie plugin imports per PR feedback
calvarjorge Feb 25, 2026
6abe637
Merge remote-tracking branch 'origin/main' into feat/genie-plugin
calvarjorge Feb 25, 2026
bbf5560
docs(appkit): add @internal to genie export and document plugin in pl…
calvarjorge Feb 25, 2026
ae6c955
docs: remove Variable.genie from generated API docs sidebar and index
calvarjorge Feb 25, 2026
c535337
Merge remote-tracking branch 'origin/main' into feat/genie-plugin
calvarjorge Feb 26, 2026
26b9ec3
feat(genie): add SSE reconnection support via stable streamId
calvarjorge Feb 26, 2026
89c6a56
feat(genie): default spaces config from DATABRICKS_GENIE_SPACE_ID env…
calvarjorge Feb 26, 2026
f4850e3
refactor(genie): extract pollWaiter to simplify _handleSendMessage
calvarjorge Feb 26, 2026
eb7a173
feat(genie): use client-provided requestId query param as SSE streamId
calvarjorge Feb 27, 2026
9e3ab06
feat(appkit-ui): add Genie chat React components (#116)
calvarjorge Mar 2, 2026
1dbb2ea
Refactor Genie into Genie connector (#145)
calvarjorge Mar 2, 2026
3c4b108
chore: remove crypto/index.ts
calvarjorge Mar 2, 2026
14ed2f6
refactor: move shared Genie types to packages/shared
calvarjorge Mar 2, 2026
8db340d
chore: colocate poll-waiter test with its source
calvarjorge Mar 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/dev-playground/.env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ NODE_ENV='development'
OTEL_EXPORTER_OTLP_ENDPOINT='http://localhost:4318'
OTEL_RESOURCE_ATTRIBUTES='service.sample_attribute=dev'
OTEL_SERVICE_NAME='dev-playground'
DATABRICKS_GENIE_SPACE_ID=
LAKEBASE_ENDPOINT='' # Run: databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} — use the `name` field from the output
PGHOST=
PGUSER=
Expand Down
50 changes: 50 additions & 0 deletions apps/dev-playground/client/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import { Route as TypeSafetyRouteRouteImport } from './routes/type-safety.route'
import { Route as TelemetryRouteRouteImport } from './routes/telemetry.route'
import { Route as SqlHelpersRouteRouteImport } from './routes/sql-helpers.route'
import { Route as ReconnectRouteRouteImport } from './routes/reconnect.route'

import { Route as GenieRouteRouteImport } from './routes/genie.route'

import { Route as LakebaseRouteRouteImport } from './routes/lakebase.route'

import { Route as DataVisualizationRouteRouteImport } from './routes/data-visualization.route'
import { Route as ArrowAnalyticsRouteRouteImport } from './routes/arrow-analytics.route'
import { Route as AnalyticsRouteRouteImport } from './routes/analytics.route'
Expand All @@ -39,6 +43,12 @@ const ReconnectRouteRoute = ReconnectRouteRouteImport.update({
path: '/reconnect',
getParentRoute: () => rootRouteImport,
} as any)

const GenieRouteRoute = GenieRouteRouteImport.update({
id: '/genie',
path: '/genie',
getParentRoute: () => rootRouteImport,
} as any)
const LakebaseRouteRoute = LakebaseRouteRouteImport.update({
id: '/lakebase',
path: '/lakebase',
Expand Down Expand Up @@ -70,7 +80,11 @@ export interface FileRoutesByFullPath {
'/analytics': typeof AnalyticsRouteRoute
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
'/data-visualization': typeof DataVisualizationRouteRoute

'/genie': typeof GenieRouteRoute

'/lakebase': typeof LakebaseRouteRoute

'/reconnect': typeof ReconnectRouteRoute
'/sql-helpers': typeof SqlHelpersRouteRoute
'/telemetry': typeof TelemetryRouteRoute
Expand All @@ -81,7 +95,11 @@ export interface FileRoutesByTo {
'/analytics': typeof AnalyticsRouteRoute
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
'/data-visualization': typeof DataVisualizationRouteRoute

'/genie': typeof GenieRouteRoute

'/lakebase': typeof LakebaseRouteRoute

'/reconnect': typeof ReconnectRouteRoute
'/sql-helpers': typeof SqlHelpersRouteRoute
'/telemetry': typeof TelemetryRouteRoute
Expand All @@ -93,7 +111,11 @@ export interface FileRoutesById {
'/analytics': typeof AnalyticsRouteRoute
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
'/data-visualization': typeof DataVisualizationRouteRoute

'/genie': typeof GenieRouteRoute

'/lakebase': typeof LakebaseRouteRoute

'/reconnect': typeof ReconnectRouteRoute
'/sql-helpers': typeof SqlHelpersRouteRoute
'/telemetry': typeof TelemetryRouteRoute
Expand All @@ -106,7 +128,11 @@ export interface FileRouteTypes {
| '/analytics'
| '/arrow-analytics'
| '/data-visualization'

| '/genie'

| '/lakebase'

| '/reconnect'
| '/sql-helpers'
| '/telemetry'
Expand All @@ -117,7 +143,11 @@ export interface FileRouteTypes {
| '/analytics'
| '/arrow-analytics'
| '/data-visualization'

| '/genie'

| '/lakebase'

| '/reconnect'
| '/sql-helpers'
| '/telemetry'
Expand All @@ -128,7 +158,11 @@ export interface FileRouteTypes {
| '/analytics'
| '/arrow-analytics'
| '/data-visualization'

| '/genie'

| '/lakebase'

| '/reconnect'
| '/sql-helpers'
| '/telemetry'
Expand All @@ -140,7 +174,11 @@ export interface RootRouteChildren {
AnalyticsRouteRoute: typeof AnalyticsRouteRoute
ArrowAnalyticsRouteRoute: typeof ArrowAnalyticsRouteRoute
DataVisualizationRouteRoute: typeof DataVisualizationRouteRoute

GenieRouteRoute: typeof GenieRouteRoute

LakebaseRouteRoute: typeof LakebaseRouteRoute

ReconnectRouteRoute: typeof ReconnectRouteRoute
SqlHelpersRouteRoute: typeof SqlHelpersRouteRoute
TelemetryRouteRoute: typeof TelemetryRouteRoute
Expand Down Expand Up @@ -177,6 +215,14 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ReconnectRouteRouteImport
parentRoute: typeof rootRouteImport
}

'/genie': {
id: '/genie'
path: '/genie'
fullPath: '/genie'
preLoaderRoute: typeof GenieRouteRouteImport
parentRoute: typeof rootRouteImport
}
'/lakebase': {
id: '/lakebase'
path: '/lakebase'
Expand Down Expand Up @@ -220,7 +266,11 @@ const rootRouteChildren: RootRouteChildren = {
AnalyticsRouteRoute: AnalyticsRouteRoute,
ArrowAnalyticsRouteRoute: ArrowAnalyticsRouteRoute,
DataVisualizationRouteRoute: DataVisualizationRouteRoute,

GenieRouteRoute: GenieRouteRoute,

LakebaseRouteRoute: LakebaseRouteRoute,

ReconnectRouteRoute: ReconnectRouteRoute,
SqlHelpersRouteRoute: SqlHelpersRouteRoute,
TelemetryRouteRoute: TelemetryRouteRoute,
Expand Down
8 changes: 8 additions & 0 deletions apps/dev-playground/client/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ function RootComponent() {
SQL Helpers
</Button>
</Link>
<Link to="/genie" className="no-underline">
<Button
variant="ghost"
className="text-foreground hover:text-secondary-foreground"
>
Genie
</Button>
</Link>
<ThemeSelector />
</div>
</nav>
Expand Down
29 changes: 29 additions & 0 deletions apps/dev-playground/client/src/routes/genie.route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { GenieChat } from "@databricks/appkit-ui/react";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/genie")({
component: GenieRoute,
});

function GenieRoute() {
return (
<div className="min-h-screen bg-background">
<main className="max-w-4xl mx-auto px-6 py-12">
<div className="flex flex-col gap-6">
<div>
<h1 className="text-3xl font-bold tracking-tight text-foreground">
Genie Chat
</h1>
<p className="text-muted-foreground mt-2">
Ask natural language questions about your data using AI/BI Genie.
</p>
</div>

<div className="border rounded-lg h-[600px] flex flex-col">
<GenieChat alias="demo" />
</div>
</div>
</main>
</div>
);
}
19 changes: 19 additions & 0 deletions apps/dev-playground/client/src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,25 @@ function IndexRoute() {
</div>
</Card>

<Card className="p-6 hover:shadow-lg transition-shadow cursor-pointer">
<div className="flex flex-col h-full">
<h3 className="text-2xl font-semibold text-foreground mb-3">
Genie Chat
</h3>
<p className="text-muted-foreground mb-6 flex-grow">
Ask natural language questions about your data using AI/BI
Genie. Features SSE streaming, markdown rendering, and
conversation persistence.
</p>
<Button
onClick={() => navigate({ to: "/genie" })}
className="w-full"
>
Try Genie Chat
</Button>
</div>
</Card>

<Card className="p-6 hover:shadow-lg transition-shadow cursor-pointer">
<div className="flex flex-col h-full">
<h3 className="text-2xl font-semibold text-foreground mb-3">
Expand Down
5 changes: 4 additions & 1 deletion apps/dev-playground/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "reflect-metadata";
import { analytics, createApp, server } from "@databricks/appkit";
import { analytics, createApp, genie, server } from "@databricks/appkit";
import { WorkspaceClient } from "@databricks/sdk-experimental";
import { lakebaseExamples } from "./lakebase-examples-plugin";
import { reconnect } from "./reconnect-plugin";
Expand All @@ -21,6 +21,9 @@ createApp({
reconnect(),
telemetryExamples(),
analytics({}),
genie({
spaces: { demo: process.env.DATABRICKS_GENIE_SPACE_ID ?? "placeholder" },
}),
lakebaseExamples(),
],
...(process.env.APPKIT_E2E_TEST && { client: createMockClient() }),
Expand Down
48 changes: 48 additions & 0 deletions docs/docs/api/appkit-ui/genie/GenieChat.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# GenieChat

Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE.


## Example

```tsx
import { GenieChat } from "@databricks/appkit-ui/react";

export default function GenieChatExample() {
return (
<div style={{ height: 500, border: "1px solid #e2e8f0", borderRadius: 8 }}>
<GenieChat alias="my-space" />
</div>
);
}

```


## GenieChat

Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE.


**Source:** [`packages/appkit-ui/src/react/genie/genie-chat.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/genie/genie-chat.tsx)


### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `alias` | `string` | ✓ | - | Genie space alias (must match a key registered with the genie plugin on the server) |
| `basePath` | `string` | | - | Base API path |
| `placeholder` | `string` | | - | Placeholder text for the input |
| `className` | `string` | | - | Additional CSS class for the root container |



### Usage

```tsx
import { GenieChat } from '@databricks/appkit-ui';

<GenieChat /* props */ />
```

32 changes: 32 additions & 0 deletions docs/docs/api/appkit-ui/genie/GenieChatInput.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# GenieChatInput

Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline).


## GenieChatInput

Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline).


**Source:** [`packages/appkit-ui/src/react/genie/genie-chat-input.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/genie/genie-chat-input.tsx)


### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `onSend` | `(content: string) => void` | ✓ | - | Callback fired when the user submits a message |
| `disabled` | `boolean` | | `false` | Disable the input and send button |
| `placeholder` | `string` | | `Ask a question...` | Placeholder text shown in the textarea |
| `className` | `string` | | - | Additional CSS class for the container |



### Usage

```tsx
import { GenieChatInput } from '@databricks/appkit-ui';

<GenieChatInput /* props */ />
```

30 changes: 30 additions & 0 deletions docs/docs/api/appkit-ui/genie/GenieChatMessage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# GenieChatMessage

Renders a single Genie message bubble with optional expandable SQL query attachments.


## GenieChatMessage

Renders a single Genie message bubble with optional expandable SQL query attachments.


**Source:** [`packages/appkit-ui/src/react/genie/genie-chat-message.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/genie/genie-chat-message.tsx)


### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `message` | `GenieMessageItem` | ✓ | - | The message object to render |
| `className` | `string` | | - | Additional CSS class |



### Usage

```tsx
import { GenieChatMessage } from '@databricks/appkit-ui';

<GenieChatMessage /* props */ />
```

31 changes: 31 additions & 0 deletions docs/docs/api/appkit-ui/genie/GenieChatMessageList.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# GenieChatMessageList

Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator.


## GenieChatMessageList

Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator.


**Source:** [`packages/appkit-ui/src/react/genie/genie-chat-message-list.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/genie/genie-chat-message-list.tsx)


### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `messages` | `GenieMessageItem[]` | ✓ | - | Array of messages to display |
| `status` | `enum` | ✓ | - | Current chat status (controls loading indicators and skeleton placeholders) |
| `className` | `string` | | - | Additional CSS class for the scroll area |



### Usage

```tsx
import { GenieChatMessageList } from '@databricks/appkit-ui';

<GenieChatMessageList /* props */ />
```

4 changes: 4 additions & 0 deletions docs/docs/api/appkit-ui/genie/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Genie components",
"position": 4
}
Loading