Skip to content

Commit d2c99cc

Browse files
committed
feat(appkit): ui for the no-config chat
Signed-off-by: Hubert Zub <hubert.zub@databricks.com>
1 parent c70492a commit d2c99cc

39 files changed

Lines changed: 3233 additions & 0 deletions

apps/dev-playground/client/src/lib/nav.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ export const NAV_GROUPS: ReadonlyArray<NavGroup> = [
9898
"Chat agent over Databricks Model Serving with tools auto-discovered from AppKit plugins.",
9999
icon: BotIcon,
100100
},
101+
{
102+
to: "/agent-chat-full",
103+
label: "Custom Agent (full no-config chat)",
104+
description:
105+
"Drop-in <ChatApp /> with zero props — defaults to /api/agents/chat with the full UX.",
106+
icon: MessageCircleIcon,
107+
},
101108
{
102109
to: "/genie",
103110
label: "Genie",

apps/dev-playground/client/src/routeTree.gen.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Route as DataVisualizationRouteRouteImport } from './routes/data-visual
2525
import { Route as ChartInferenceRouteRouteImport } from './routes/chart-inference.route'
2626
import { Route as ArrowAnalyticsRouteRouteImport } from './routes/arrow-analytics.route'
2727
import { Route as AnalyticsRouteRouteImport } from './routes/analytics.route'
28+
import { Route as AgentChatFullRouteRouteImport } from './routes/agent-chat-full.route'
2829
import { Route as AgentRouteRouteImport } from './routes/agent.route'
2930
import { Route as IndexRouteImport } from './routes/index'
3031

@@ -108,6 +109,11 @@ const AnalyticsRouteRoute = AnalyticsRouteRouteImport.update({
108109
path: '/analytics',
109110
getParentRoute: () => rootRouteImport,
110111
} as any)
112+
const AgentChatFullRouteRoute = AgentChatFullRouteRouteImport.update({
113+
id: '/agent-chat-full',
114+
path: '/agent-chat-full',
115+
getParentRoute: () => rootRouteImport,
116+
} as any)
111117
const AgentRouteRoute = AgentRouteRouteImport.update({
112118
id: '/agent',
113119
path: '/agent',
@@ -122,6 +128,7 @@ const IndexRoute = IndexRouteImport.update({
122128
export interface FileRoutesByFullPath {
123129
'/': typeof IndexRoute
124130
'/agent': typeof AgentRouteRoute
131+
'/agent-chat-full': typeof AgentChatFullRouteRoute
125132
'/analytics': typeof AnalyticsRouteRoute
126133
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
127134
'/chart-inference': typeof ChartInferenceRouteRoute
@@ -142,6 +149,7 @@ export interface FileRoutesByFullPath {
142149
export interface FileRoutesByTo {
143150
'/': typeof IndexRoute
144151
'/agent': typeof AgentRouteRoute
152+
'/agent-chat-full': typeof AgentChatFullRouteRoute
145153
'/analytics': typeof AnalyticsRouteRoute
146154
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
147155
'/chart-inference': typeof ChartInferenceRouteRoute
@@ -163,6 +171,7 @@ export interface FileRoutesById {
163171
__root__: typeof rootRouteImport
164172
'/': typeof IndexRoute
165173
'/agent': typeof AgentRouteRoute
174+
'/agent-chat-full': typeof AgentChatFullRouteRoute
166175
'/analytics': typeof AnalyticsRouteRoute
167176
'/arrow-analytics': typeof ArrowAnalyticsRouteRoute
168177
'/chart-inference': typeof ChartInferenceRouteRoute
@@ -185,6 +194,7 @@ export interface FileRouteTypes {
185194
fullPaths:
186195
| '/'
187196
| '/agent'
197+
| '/agent-chat-full'
188198
| '/analytics'
189199
| '/arrow-analytics'
190200
| '/chart-inference'
@@ -205,6 +215,7 @@ export interface FileRouteTypes {
205215
to:
206216
| '/'
207217
| '/agent'
218+
| '/agent-chat-full'
208219
| '/analytics'
209220
| '/arrow-analytics'
210221
| '/chart-inference'
@@ -225,6 +236,7 @@ export interface FileRouteTypes {
225236
| '__root__'
226237
| '/'
227238
| '/agent'
239+
| '/agent-chat-full'
228240
| '/analytics'
229241
| '/arrow-analytics'
230242
| '/chart-inference'
@@ -246,6 +258,7 @@ export interface FileRouteTypes {
246258
export interface RootRouteChildren {
247259
IndexRoute: typeof IndexRoute
248260
AgentRouteRoute: typeof AgentRouteRoute
261+
AgentChatFullRouteRoute: typeof AgentChatFullRouteRoute
249262
AnalyticsRouteRoute: typeof AnalyticsRouteRoute
250263
ArrowAnalyticsRouteRoute: typeof ArrowAnalyticsRouteRoute
251264
ChartInferenceRouteRoute: typeof ChartInferenceRouteRoute
@@ -378,6 +391,13 @@ declare module '@tanstack/react-router' {
378391
preLoaderRoute: typeof AnalyticsRouteRouteImport
379392
parentRoute: typeof rootRouteImport
380393
}
394+
'/agent-chat-full': {
395+
id: '/agent-chat-full'
396+
path: '/agent-chat-full'
397+
fullPath: '/agent-chat-full'
398+
preLoaderRoute: typeof AgentChatFullRouteRouteImport
399+
parentRoute: typeof rootRouteImport
400+
}
381401
'/agent': {
382402
id: '/agent'
383403
path: '/agent'
@@ -398,6 +418,7 @@ declare module '@tanstack/react-router' {
398418
const rootRouteChildren: RootRouteChildren = {
399419
IndexRoute: IndexRoute,
400420
AgentRouteRoute: AgentRouteRoute,
421+
AgentChatFullRouteRoute: AgentChatFullRouteRoute,
401422
AnalyticsRouteRoute: AnalyticsRouteRoute,
402423
ArrowAnalyticsRouteRoute: ArrowAnalyticsRouteRoute,
403424
ChartInferenceRouteRoute: ChartInferenceRouteRoute,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ChatApp } from "@databricks/appkit-ui/react/chat";
2+
import { createFileRoute } from "@tanstack/react-router";
3+
4+
export const Route = createFileRoute("/agent-chat-full")({
5+
component: AgentChatFullRoute,
6+
});
7+
8+
/**
9+
* No-config showcase of `<ChatApp />`. For the build-your-own variant
10+
* that wires `useChat` by hand, see `agent.route.tsx`.
11+
*/
12+
function AgentChatFullRoute() {
13+
return (
14+
<div className="h-svh bg-background">
15+
<ChatApp api="/api/agents/chat" />
16+
</div>
17+
);
18+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# ApprovalEntry
2+
3+
Approval-gate lifecycle, owned by `ChatApp`.
4+
5+
6+
## ApprovalEntry
7+
8+
Approval-gate lifecycle, owned by `ChatApp`.
9+
10+
11+
**Source:** [`packages/appkit-ui/src/react/chat/app/chat-app.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/chat/app/chat-app.tsx)
12+
13+
14+
### Props
15+
16+
This component extends standard HTML element attributes.
17+
18+
19+
20+
### Usage
21+
22+
```tsx
23+
import { ApprovalEntry } from '@databricks/appkit-ui';
24+
25+
<ApprovalEntry /* props */ />
26+
```
27+
28+
29+
## ChatApp
30+
31+
Drop-in chat against an `agents()`-backed AppKit server. Fills its
32+
parent — provide a sized container. For history, feedback, or file
33+
attachments, wrap `useChat` directly instead.
34+
35+
36+
**Source:** [`packages/appkit-ui/src/react/chat/app/chat-app.tsx`](https://github.com/databricks/appkit/blob/main/packages/appkit-ui/src/react/chat/app/chat-app.tsx)
37+
38+
39+
### Props
40+
41+
| Prop | Type | Required | Default | Description |
42+
|------|------|----------|---------|-------------|
43+
| `api` | `string` | | `/api/agents/chat` | Chat endpoint URL. Defaults to `/api/agents/chat`. |
44+
| `emptyState` | `ReactNode` | | - | Empty-state node shown when there are no messages yet. |
45+
| `placeholder` | `string` | | - | Placeholder text for the default composer. |
46+
| `composerCaption` | `string \| null` | | - | Caption shown below the composer. Pass `null` to suppress. |
47+
| `renderMessage` | `((props: ChatMessageProps<TMessage>) => ReactNode)` | | - | Override per-message rendering. Return undefined to fall through. |
48+
| `renderToolCall` | `((props: ChatToolCallProps) => ReactNode)` | | - | Override tool-call rendering. Return undefined to fall through. |
49+
| `renderComposer` | `((props: ChatComposerProps<TMessage>) => ReactNode)` | | - | Override the composer entirely. |
50+
| `onApprovalDecision` | `((decision: ApprovalDecision) => void \| Promise<void>)` | | - | Called when the user clicks Allow / Deny. Throw to keep the card `pending`. Defaults to a POST against approveUrl. |
51+
| `approveUrl` | `string` | | - | Defaults to `api` with `/chat` swapped for `/approve`. |
52+
| `className` | `string` | | - | - |
53+
| `id` | `string` | | - | Stable chat id. Defaults to a fresh UUID per mount. |
54+
| `onError` | `((error: Error) => void)` | | - | Called on stream errors. |
55+
| `headers` | `Resolvable<Record<string, string> \| Headers>` | | - | Extra fetch headers forwarded to the transport. |
56+
| `messages` | `TMessage[]` | | - | Initial messages (e.g. when hydrating from history). |
57+
| `onData` | `ChatOnDataCallback<TMessage>` | | - | Fires for every `data-*` chunk (e.g. `data-approval-pending`). |
58+
| `onStreamPart` | `((chunk: UIMessageChunk) => void)` | | - | Fires synchronously for every chunk. Unaffected by render throttling. |
59+
60+
61+
62+
### Usage
63+
64+
```tsx
65+
import { ChatApp } from '@databricks/appkit-ui';
66+
67+
<ChatApp /* props */ />
68+
```
69+

0 commit comments

Comments
 (0)