@dbx-tools/ui-mastra 0.9.129 → 0.9.132
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/README.md +155 -166
- package/index.ts +6 -3
- package/package.json +7 -6
- package/src/react/bubbles.tsx +3 -1
- package/src/react/chat-composer.tsx +93 -38
- package/src/react/chat-sessions.ts +9 -0
- package/src/react/chat-stream.ts +12 -0
- package/src/react/chat-view.tsx +2 -0
- package/src/react/embed-slots.tsx +40 -10
- package/src/react/index.ts +5 -1
- package/src/react/mastra-chat.tsx +330 -55
- package/src/react/types.ts +2 -0
- package/src/support/active-runs.ts +8 -2
- package/src/support/export.ts +30 -15
- package/src/support/genie-client.ts +220 -0
- package/src/support/index.ts +4 -1
- package/src/support/mastra-client.ts +49 -14
- package/src/support/thread-persistence.ts +9 -0
- package/src/support/thread-sessions.ts +19 -0
package/README.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
# @dbx-tools/ui-mastra
|
|
2
2
|
|
|
3
|
-
React chat
|
|
3
|
+
Add a React chat surface to
|
|
4
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra). The package supports
|
|
5
|
+
streaming, model selection, AI/BI Genie progress, charts, tables, approvals,
|
|
6
|
+
history, threads, export, and MLflow feedback.
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
[`@dbx-tools/appkit-mastra`](../../node/appkit-mastra), including streaming,
|
|
7
|
-
model selection, Genie progress, charts, tables, approvals, history, threads,
|
|
8
|
-
export, and MLflow feedback.
|
|
9
|
-
|
|
10
|
-
## Quick Start
|
|
8
|
+
## Quick start
|
|
11
9
|
|
|
12
10
|
```tsx
|
|
13
11
|
import { MastraChat } from "@dbx-tools/ui-mastra/react";
|
|
@@ -18,13 +16,16 @@ export function Assistant() {
|
|
|
18
16
|
}
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
The stylesheet imports the shared [@dbx-tools/ui](../appkit) foundation. The
|
|
20
|
+
host application must also load Databricks AppKit UI styles.
|
|
21
|
+
|
|
22
|
+
Package contents:
|
|
22
23
|
|
|
23
|
-
- Drop-in `MastraChat` component that
|
|
24
|
+
- Drop-in `MastraChat` component that reads the plugin client config and
|
|
24
25
|
wires itself to the default agent.
|
|
25
|
-
- Reload recovery for background turns: active run metadata is
|
|
26
|
-
agent and thread, the cached stream reconnects after a page
|
|
27
|
-
final persisted history is refreshed when recovery completes.
|
|
26
|
+
- Reload recovery for agent-backed background turns: active run metadata is
|
|
27
|
+
persisted per agent and thread, the cached stream reconnects after a page
|
|
28
|
+
reload, and the final persisted history is refreshed when recovery completes.
|
|
28
29
|
- Headless `useMastraChat()` driver for apps that want the same transport logic
|
|
29
30
|
with custom layout.
|
|
30
31
|
- Persistent `MastraAssistant` application shell with a floating launcher,
|
|
@@ -51,38 +52,53 @@ Key features:
|
|
|
51
52
|
editor-style tab strip across the top, turn it off, or let `auto` pick between
|
|
52
53
|
a side panel and tabs from the chat's own width.
|
|
53
54
|
- Concurrent threads: run several conversations at once, switch between them
|
|
54
|
-
while each keeps streaming, and cancel any one independently
|
|
55
|
-
|
|
55
|
+
while each keeps streaming, and cancel any one independently. Abort routing
|
|
56
|
+
is per thread, with no shared client state.
|
|
56
57
|
- Mid-turn steering queue: messages submitted while a turn streams stack up as
|
|
57
|
-
pending steers
|
|
58
|
+
pending steers. They drain oldest-first when the turn ends. Each queued item
|
|
58
59
|
can be sent now (interrupting the current turn), removed, or dragged to
|
|
59
60
|
reorder the queue.
|
|
60
61
|
- Export menu for PDF and Markdown, resolving charts and tables so
|
|
61
62
|
exported conversations remain useful offline.
|
|
62
63
|
|
|
63
|
-
## Choose
|
|
64
|
+
## Choose a UI package
|
|
64
65
|
|
|
65
|
-
Use native `@databricks/appkit-ui`
|
|
66
|
-
|
|
66
|
+
Use native `@databricks/appkit-ui` for its general primitives, AI/BI Genie chat,
|
|
67
|
+
or Model Serving hooks with native AppKit plugins.
|
|
67
68
|
|
|
68
69
|
Use this package when the server is
|
|
69
|
-
[
|
|
70
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra) and the UI needs to
|
|
70
71
|
understand Mastra-specific behavior:
|
|
71
72
|
|
|
72
73
|
- Mastra's official AI SDK chat stream, native resource-scoped memory APIs, and
|
|
73
74
|
the plugin's model, suggestion, feedback, chart, and statement routes.
|
|
74
75
|
- Suspended `requireApproval` tool calls resumed through native `resumeData`.
|
|
75
|
-
- Genie writer events rendered as inline tool progress
|
|
76
|
-
answer.
|
|
76
|
+
- Genie writer events rendered as inline tool progress rather than only a
|
|
77
|
+
terminal answer.
|
|
77
78
|
- `[chart:<id>]` and `[data:<id>]` assistant markers rendered as ECharts charts
|
|
78
79
|
and sortable tables.
|
|
79
80
|
- Concurrent multi-thread streaming, per-thread cancel, and a mid-turn steering
|
|
80
|
-
queue
|
|
81
|
-
|
|
81
|
+
queue. Submit while running to enqueue, drain oldest-first, or send any item
|
|
82
|
+
immediately to interrupt. The native AppKit chat surface runs one turn at a time and
|
|
82
83
|
has no steering.
|
|
83
84
|
- Conversation export that resolves those embeds into Markdown or PDF.
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
Import the AppKit UI stylesheet before this package's stylesheet. Mount the chat
|
|
87
|
+
inside the application's authentication boundary. Agent chat can use either
|
|
88
|
+
user identity or service-principal identity according to the server plugin's
|
|
89
|
+
configuration. Direct Genie chat requires the signed-in user's on-behalf-of
|
|
90
|
+
(OBO) context.
|
|
91
|
+
|
|
92
|
+
`MastraChat` reads the `mastra` plugin's published `clientConfig()` payload
|
|
93
|
+
through AppKit. The payload supplies the mount path, default agent, registered
|
|
94
|
+
agents, feedback availability, background-turn support, and chat identity
|
|
95
|
+
behavior. Don't hard-code plugin routes in browser code.
|
|
96
|
+
|
|
97
|
+
Use [@dbx-tools/ui](../appkit) for common AppKit, authentication, email, and
|
|
98
|
+
search components. Use [@dbx-tools/ui-teams](../teams) for Microsoft Teams
|
|
99
|
+
Adaptive Cards and conversation previews.
|
|
100
|
+
|
|
101
|
+
## Configure styles
|
|
86
102
|
|
|
87
103
|
```css
|
|
88
104
|
@import "@databricks/appkit-ui/styles.css";
|
|
@@ -90,10 +106,10 @@ understand Mastra-specific behavior:
|
|
|
90
106
|
```
|
|
91
107
|
|
|
92
108
|
The stylesheet imports the shared `@dbx-tools/ui` foundation and registers
|
|
93
|
-
this package's React files with Tailwind. It does not define design tokens
|
|
109
|
+
this package's React files with Tailwind. It does not define design tokens. The
|
|
94
110
|
chat UI uses AppKit semantic tokens from the host app.
|
|
95
111
|
|
|
96
|
-
## Add
|
|
112
|
+
## Add a persistent assistant
|
|
97
113
|
|
|
98
114
|
Mount `MastraAssistant` inside the app's existing authentication gate and above
|
|
99
115
|
the route outlet. Closing the panel hides its presentation without unmounting
|
|
@@ -127,7 +143,7 @@ export function App() {
|
|
|
127
143
|
}
|
|
128
144
|
```
|
|
129
145
|
|
|
130
|
-
`mode="dock"` reflows the child application
|
|
146
|
+
`mode="dock"` reflows the child application. `mode="overlay"` overlaps it.
|
|
131
147
|
`side` accepts `top`, `right`, `bottom`, or `left`. Set `resizable={false}` to
|
|
132
148
|
lock size, `launcher={false}` when every launch comes from
|
|
133
149
|
`useMastraAssistant()`, `header={false}` to place New, History, and Close beside
|
|
@@ -138,13 +154,10 @@ the conversation pills remain on their own second row. Replace `icon`, `closeIco
|
|
|
138
154
|
dismissal while the covered application is inert. A `storageKey` retains
|
|
139
155
|
horizontal and vertical sizes independently.
|
|
140
156
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
and native resizable panels persist percentages rather than this component's
|
|
144
|
-
independent horizontal/vertical pixel sizes; either change would lose drafts,
|
|
145
|
-
scroll state, active streams, or sizing parity.
|
|
157
|
+
`MastraAssistant` remains mounted when closed, which preserves drafts, scroll
|
|
158
|
+
state, active streams, and independent horizontal and vertical sizes.
|
|
146
159
|
|
|
147
|
-
## Render
|
|
160
|
+
## Render a drop-in chat
|
|
148
161
|
|
|
149
162
|
```tsx
|
|
150
163
|
import { MastraChat } from "@dbx-tools/ui-mastra/react";
|
|
@@ -162,16 +175,17 @@ export function App() {
|
|
|
162
175
|
}
|
|
163
176
|
```
|
|
164
177
|
|
|
165
|
-
`MastraChat`
|
|
178
|
+
`MastraChat` provides the bundled client for the AppKit-Mastra plugin. It reads the
|
|
166
179
|
plugin's published client config, creates a `MastraPluginClient`, streams turns
|
|
167
180
|
through Mastra's official AI SDK chat route, hydrates native memory, and renders
|
|
168
181
|
the controlled `ChatView`. When Mastra returns persisted `messages` without a
|
|
169
182
|
precomputed `uiMessages` projection, history hydration uses Mastra's native
|
|
170
183
|
`convertMessages(...).to("AIV5.UI")` conversion.
|
|
171
184
|
|
|
172
|
-
|
|
185
|
+
Configure the client with these options:
|
|
173
186
|
|
|
174
|
-
- `agentId` selects a registered agent
|
|
187
|
+
- `agentId` selects a registered agent and defaults to the plugin default agent.
|
|
188
|
+
- `genieSpace` selects a configured Genie alias and bypasses the agent.
|
|
175
189
|
- `showModelPicker` fetches `/models` and sends `X-Mastra-Model` overrides.
|
|
176
190
|
- `composerActions` places host-owned per-turn controls beside the model
|
|
177
191
|
selector without replacing the built-in composer.
|
|
@@ -179,21 +193,52 @@ Useful options:
|
|
|
179
193
|
the endpoint choices. Supply it only when the active agent supports that
|
|
180
194
|
option, such as a Genie transport toggle.
|
|
181
195
|
- `composerLeadingActions` places attachment or app actions on the left side of
|
|
182
|
-
the fixed composer footer. The textarea grows above it to a cap, then scrolls
|
|
183
|
-
|
|
184
|
-
- `suggestions` overrides Genie starter questions
|
|
196
|
+
the fixed composer footer. The textarea grows above it to a cap, then scrolls.
|
|
197
|
+
Model and Send/Stop stay pinned bottom-right.
|
|
198
|
+
- `suggestions` overrides Genie starter questions. Omit it to auto-fetch
|
|
185
199
|
`/suggestions`, or pass `[]` to hide suggestions.
|
|
186
200
|
- `threadPlacement` chooses where conversation management renders, or turns it
|
|
187
|
-
off. See [Place
|
|
188
|
-
- `enableThreads: false`
|
|
201
|
+
off. See [Place the conversation list](#place-the-conversation-list).
|
|
202
|
+
- `enableThreads: false` also sets
|
|
189
203
|
`threadPlacement: "disabled"`.
|
|
204
|
+
- `threadId` and `onThreadIdChange` let a host bind the active conversation to
|
|
205
|
+
URL state or another external selector. Unknown external IDs are replaced by
|
|
206
|
+
a new thread and reported with the `missing` reason.
|
|
190
207
|
- `enableExport` adds whole-conversation and per-message export affordances.
|
|
191
208
|
- Feedback defaults to auto: thumbs, dislike, and comment controls appear when
|
|
192
209
|
the server reports MLflow feedback is available and a turn produced a trace
|
|
193
210
|
id. Set `enableFeedback={false}` to hide them. Viewers with `CAN_MANAGE` on
|
|
194
211
|
the experiment also get an experiment debug link at the end of the action row.
|
|
195
212
|
|
|
196
|
-
##
|
|
213
|
+
## Use direct Genie chat
|
|
214
|
+
|
|
215
|
+
Use `genieSpace` when the application needs the same chat shell without a
|
|
216
|
+
supervisor agent:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<MastraChat genieSpace="sales" threadPlacement="auto" enableExport />
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The alias comes from the server plugin's `genieSpaces`. The client still uses
|
|
223
|
+
AI SDK `UIMessage` streams and the same `ChatView`. Genie conversations replace
|
|
224
|
+
Mastra threads and Genie messages replace Mastra Memory history.
|
|
225
|
+
|
|
226
|
+
Turns and history require the Genie Agent API and never fall back to classic
|
|
227
|
+
Genie message polling. The sidebar filters the Genie conversation listing to
|
|
228
|
+
Agent Mode conversations. Genie decides whether a query should be visualized.
|
|
229
|
+
Visualization attachments render through AppKit UI's native
|
|
230
|
+
`GenieQueryVisualization`, with Chart and Table tabs. This does not invoke a
|
|
231
|
+
supervisor or the Mastra Model Serving chart planner. Queries without a
|
|
232
|
+
visualization attachment render through the existing sortable data table.
|
|
233
|
+
|
|
234
|
+
Direct mode requires the signed-in user's Databricks OBO context. It supports
|
|
235
|
+
new/select/delete conversations, history, suggestions, thoughts, exports, and
|
|
236
|
+
stream cancellation. It does not support conversation rename, file
|
|
237
|
+
attachments, MLflow feedback, approvals, background turns, or stream
|
|
238
|
+
reconnection. The newest 100 conversations are listed and each selected
|
|
239
|
+
conversation loads as one history page.
|
|
240
|
+
|
|
241
|
+
## Place the conversation list
|
|
197
242
|
|
|
198
243
|
Conversation management is on by default. Where it lives is one option:
|
|
199
244
|
|
|
@@ -206,33 +251,37 @@ Conversation management is on by default. Where it lives is one option:
|
|
|
206
251
|
| `auto` (default) | `left` while the chat is wide, `top` once it is too narrow for a panel |
|
|
207
252
|
| `left` / `right` | List docked to that edge, collapsing to an overlay drawer on a narrow chat |
|
|
208
253
|
| `top` | Tab strip of open conversations, with a history menu for the rest |
|
|
209
|
-
| `disabled` | No thread UI
|
|
254
|
+
| `disabled` | No thread UI. Uses a single thread on the session cookie |
|
|
210
255
|
|
|
211
256
|
The docked placements render the sidebar as an inline column with a persisted
|
|
212
257
|
show/hide toggle. Below 768px of chat width the panel becomes an overlay drawer
|
|
213
|
-
on the same edge, so the transcript never loses room
|
|
258
|
+
on the same edge, so the transcript never loses room. The drawer is
|
|
214
259
|
session-scoped and starts closed, and closes itself after a selection.
|
|
215
260
|
|
|
261
|
+
The composer accepts images from the upload action, drag and drop, or clipboard
|
|
262
|
+
paste. Oversized images use the same client-side resize path before submission.
|
|
263
|
+
|
|
216
264
|
The `top` placement is the editor-tab model: each open conversation is a tab with
|
|
217
265
|
its title, a spinner while it streams in the background, and a close affordance
|
|
218
266
|
that only takes the tab off the strip (the conversation stays in history). A `+`
|
|
219
|
-
starts a fresh conversation
|
|
220
|
-
|
|
221
|
-
|
|
267
|
+
starts a fresh conversation. The history button opens the full sidebar as a
|
|
268
|
+
menu, so rename, delete, and cancel still work on conversations that aren't on
|
|
269
|
+
the tab strip. Closing the active tab moves to a neighboring one, or
|
|
222
270
|
starts a fresh conversation when it was the last tab open. The open set is
|
|
223
|
-
session state
|
|
271
|
+
session state. The strip reseeds from the most recent conversations on the next
|
|
224
272
|
load.
|
|
225
273
|
|
|
226
|
-
|
|
227
|
-
Scrolling upward requests the next page and prepends it
|
|
228
|
-
reader's viewport. Agent turns still send only the new user
|
|
229
|
-
loads the remembered transcript server-side.
|
|
274
|
+
For agent-backed chat, selecting a conversation fetches only the newest 20
|
|
275
|
+
native memory messages. Scrolling upward requests the next page and prepends it
|
|
276
|
+
without moving the reader's viewport. Agent turns still send only the new user
|
|
277
|
+
message. Mastra loads the remembered transcript server-side. Direct Genie mode
|
|
278
|
+
loads the selected Genie conversation in one page.
|
|
230
279
|
|
|
231
280
|
`auto` measures the chat's own element rather than the viewport, so a chat
|
|
232
281
|
embedded in a split view or side panel switches to tabs on the space it actually
|
|
233
282
|
has instead of waiting for the window to shrink.
|
|
234
283
|
|
|
235
|
-
## Use
|
|
284
|
+
## Use the headless driver
|
|
236
285
|
|
|
237
286
|
```tsx
|
|
238
287
|
import { ChatView, useMastraChat } from "@dbx-tools/ui-mastra/react";
|
|
@@ -248,11 +297,11 @@ export function CustomChat() {
|
|
|
248
297
|
}
|
|
249
298
|
```
|
|
250
299
|
|
|
251
|
-
Use `useMastraChat()` when
|
|
252
|
-
|
|
300
|
+
Use `useMastraChat()` when you want package transport behavior with your own
|
|
301
|
+
layout. The hook owns streaming, aborts, history paging, thread
|
|
253
302
|
selection, model overrides, suggestions, exports, approvals, and feedback state.
|
|
254
303
|
|
|
255
|
-
## Pass
|
|
304
|
+
## Pass typed application context
|
|
256
305
|
|
|
257
306
|
`requestContext` accepts a typed plain record, Mastra `RequestContext<T>`, or a
|
|
258
307
|
per-turn resolver. The driver snapshots it when a message is submitted and
|
|
@@ -274,7 +323,7 @@ On the server, declare the same contract with Mastra's native
|
|
|
274
323
|
cannot override the authenticated memory resource, thread, user, scopes, model,
|
|
275
324
|
or trace fields stamped by AppKit-Mastra.
|
|
276
325
|
|
|
277
|
-
## Build
|
|
326
|
+
## Build a controlled chat surface
|
|
278
327
|
|
|
279
328
|
```tsx
|
|
280
329
|
import { ChatView, type ChatViewProps } from "@dbx-tools/ui-mastra/react";
|
|
@@ -294,66 +343,45 @@ is being resolved. The picker groups endpoints into
|
|
|
294
343
|
model-family submenus. Its compact first popup shows only the current
|
|
295
344
|
model, host-owned actions such as Genie Agent Mode, and a reasoning slider when
|
|
296
345
|
the selected endpoint supports it. The current model opens the family picker,
|
|
297
|
-
so the long endpoint
|
|
346
|
+
so the long endpoint catalog stays out of the primary control popup. Family
|
|
298
347
|
and model menus use the same compact utility type as the composer actions,
|
|
299
348
|
omit repeated headers, and omit the already-selected model. The model menu puts
|
|
300
349
|
`Default (<resolved model>)` first, keeps `Other` last, and makes a one-model
|
|
301
350
|
family directly selectable instead of opening another submenu.
|
|
302
351
|
|
|
303
|
-
## Call
|
|
352
|
+
## Call plugin routes directly
|
|
304
353
|
|
|
305
354
|
```ts
|
|
306
|
-
import {
|
|
307
|
-
|
|
308
|
-
useMastraClient,
|
|
309
|
-
useMastraDefaultModel,
|
|
310
|
-
useMastraModels,
|
|
311
|
-
useMastraSuggestions,
|
|
312
|
-
useMastraThreads,
|
|
313
|
-
} from "@dbx-tools/ui-mastra/react";
|
|
314
|
-
|
|
315
|
-
const client = new MastraPluginClient(clientConfig);
|
|
316
|
-
|
|
317
|
-
// Routing (thread + model) is passed per call, so concurrent runs on
|
|
318
|
-
// different threads never share state.
|
|
319
|
-
const stream = await client.streamAgent({
|
|
320
|
-
agentId: client.defaultAgent,
|
|
321
|
-
messages: [
|
|
322
|
-
{
|
|
323
|
-
id: "user-1",
|
|
324
|
-
role: "user",
|
|
325
|
-
parts: [{ type: "text", text: "Hello" }],
|
|
326
|
-
},
|
|
327
|
-
],
|
|
328
|
-
runId,
|
|
329
|
-
threadId: activeThreadId,
|
|
330
|
-
model: "claude sonnet",
|
|
331
|
-
signal: controller.signal,
|
|
332
|
-
});
|
|
355
|
+
import type { MastraClientConfig } from "@dbx-tools/shared-mastra";
|
|
356
|
+
import { MastraPluginClient } from "@dbx-tools/ui-mastra/react";
|
|
333
357
|
|
|
334
|
-
|
|
335
|
-
const
|
|
358
|
+
export async function listChatModels(clientConfig: MastraClientConfig) {
|
|
359
|
+
const client = new MastraPluginClient(clientConfig);
|
|
360
|
+
return client.models();
|
|
361
|
+
}
|
|
336
362
|
```
|
|
337
363
|
|
|
338
364
|
Each conversation thread runs independently: start a turn on one thread, switch
|
|
339
|
-
to another and start a second, and both stream concurrently. Cancel one
|
|
365
|
+
to another and start a second, and both stream concurrently. Cancel one using its
|
|
340
366
|
`AbortSignal` (or the driver's `onCancelThread`) without touching the others.
|
|
341
367
|
|
|
342
368
|
`MastraPluginClient` extends `@mastra/client-js` with the official AI SDK
|
|
343
369
|
`chatRoute` transport and AppKit-Mastra additions. It uses
|
|
344
370
|
`credentials: "include"` so session cookies travel with streaming and REST
|
|
345
|
-
calls. The React hooks wrap native memory plus model
|
|
346
|
-
chart fetches, and statement-data fetches.
|
|
371
|
+
calls. The React hooks wrap native memory plus model catalogs, suggestions,
|
|
372
|
+
chart fetches, and statement-data fetches. Use `useMastraClient()` to access the
|
|
373
|
+
configured client inside React. `useMastraModels()`, `useMastraDefaultModel()`,
|
|
374
|
+
`useMastraSuggestions()`, and `useMastraThreads()` expose route-specific state.
|
|
347
375
|
|
|
348
|
-
##
|
|
376
|
+
## Handle approvals, embeds, and feedback
|
|
349
377
|
|
|
350
378
|
The UI understands the extra events produced by
|
|
351
|
-
[
|
|
379
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra):
|
|
352
380
|
|
|
353
381
|
- Approval chunks become inline approval cards and continue the official chat
|
|
354
382
|
route with Mastra's native `{ approved, reason? }` resume data.
|
|
355
383
|
- Native tool-call and tool-result payloads remain complete. Expanding a tool
|
|
356
|
-
row reveals default-closed Request and Response viewers
|
|
384
|
+
row reveals default-closed Request and Response viewers. Large values scroll
|
|
357
385
|
without string or collection truncation.
|
|
358
386
|
- Genie `thinking` events stream into the assistant's collapsed Thoughts
|
|
359
387
|
panel. Intermediate answer attachments and query-result tables stay on tool
|
|
@@ -363,45 +391,30 @@ The UI understands the extra events produced by
|
|
|
363
391
|
- `[chart:<id>]` markers long-poll the chart cache and render ECharts inline.
|
|
364
392
|
- `[data:<id>]` markers fetch statement rows and render a sortable table with
|
|
365
393
|
column toggles and CSV export.
|
|
394
|
+
- `[visualization:<id>]` markers fetch the same statement under OBO identity and
|
|
395
|
+
render AppKit UI's native Genie Chart/Table component.
|
|
366
396
|
- MLflow trace headers enable per-message feedback controls when the server
|
|
367
397
|
reports feedback is available.
|
|
368
398
|
|
|
369
|
-
##
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
theme-dependent is resolved here at render time by `src/support/chart-theme.ts`,
|
|
381
|
-
which reads AppKit's `--chart-axis-label`, `--chart-axis-title`, `--chart-grid`,
|
|
382
|
-
and `--chart-tooltip-bg` (plus `--popover-foreground` and `--border` for the
|
|
383
|
-
tooltip) into a `ChartChrome`, and `normalizeChartOption` paints it onto the
|
|
384
|
-
axes, title, legend, and tooltip. Nothing to configure: a chart follows the
|
|
385
|
-
theme wherever it renders.
|
|
386
|
-
|
|
387
|
-
Two details worth knowing if you embed the chat:
|
|
388
|
-
|
|
389
|
-
- Tokens are read off the **chart's own element**, not `:root`, so a theme
|
|
390
|
-
scoped to a subtree - a chat panel inside an otherwise-light app - wins. The
|
|
391
|
-
value re-resolves when a `.dark` / `.light` class lands on the document root
|
|
392
|
-
and when the OS `prefers-color-scheme` flips, so a live theme switch recolors
|
|
393
|
-
charts in place.
|
|
399
|
+
## Configure chart themes
|
|
400
|
+
|
|
401
|
+
ECharts draws to a canvas and doesn't inherit CSS colors from its frame. The
|
|
402
|
+
server planner provides the series palette and font stack. The browser resolves
|
|
403
|
+
axis, grid, title, legend, and tooltip colors from AppKit semantic tokens at
|
|
404
|
+
render time.
|
|
405
|
+
|
|
406
|
+
- Theme tokens are read from the chart element, so a theme scoped to a chat
|
|
407
|
+
subtree takes precedence over the document theme. Charts update when the
|
|
408
|
+
document's `.dark` or `.light` class changes or when the operating-system
|
|
409
|
+
color preference changes.
|
|
394
410
|
- AppKit darkens its tokens under `@media (prefers-color-scheme: dark)` for any
|
|
395
411
|
`:root` that is not explicitly `.light`. If your host renders its own light
|
|
396
412
|
chrome, pin `.light` (or `.dark`) on `:root` rather than leaving AppKit on the
|
|
397
|
-
|
|
398
|
-
stays light.
|
|
413
|
+
operating-system preference.
|
|
399
414
|
|
|
400
|
-
|
|
401
|
-
`LIGHT_CHART_CHROME`, because its document forces `color-scheme: light` on a
|
|
402
|
-
white body for printing.
|
|
415
|
+
PDF export uses a light chart theme on a white print document.
|
|
403
416
|
|
|
404
|
-
## Export
|
|
417
|
+
## Export conversations
|
|
405
418
|
|
|
406
419
|
```tsx
|
|
407
420
|
<MastraChat enableExport />
|
|
@@ -412,65 +425,41 @@ resolved during export: charts are rendered to inline SVG with ECharts' server
|
|
|
412
425
|
renderer, and data markers become real tables. Expired or missing embeds are
|
|
413
426
|
skipped so old transcripts still export cleanly.
|
|
414
427
|
|
|
415
|
-
##
|
|
428
|
+
## Copy and download content
|
|
416
429
|
|
|
417
|
-
Copy and download
|
|
418
|
-
|
|
419
|
-
same everywhere because each is backed by one internal module rather than
|
|
420
|
-
per-component code.
|
|
430
|
+
Copy and download controls appear in message bubbles, code blocks, conversation
|
|
431
|
+
exports, and the data-grid CSV menu.
|
|
421
432
|
|
|
422
433
|
Copying works on hosts served over plain HTTP. An insecure context has no
|
|
423
434
|
Clipboard API, so a bare `navigator.clipboard.writeText` silently does nothing on
|
|
424
|
-
a local or intranet deployment
|
|
435
|
+
a local or intranet deployment. The package falls back to a hidden
|
|
425
436
|
`<textarea>` plus `document.execCommand("copy")` and reports whether the copy
|
|
426
437
|
actually succeeded. Downloads revoke their object URL after the temporary anchor
|
|
427
438
|
fires, so a long session does not accumulate blobs.
|
|
428
439
|
|
|
429
|
-
|
|
430
|
-
anything. Adding a new copy or download button anywhere in this package should
|
|
431
|
-
reuse `src/support/clipboard.ts` and `src/support/download.ts` instead of
|
|
432
|
-
touching `navigator.clipboard` or `URL.createObjectURL` again.
|
|
433
|
-
|
|
434
|
-
## Modules
|
|
440
|
+
## Package exports
|
|
435
441
|
|
|
436
|
-
- `MastraChat
|
|
437
|
-
- `MastraAssistant` / `useMastraAssistant
|
|
442
|
+
- `MastraChat`: self-contained drop-in chat component.
|
|
443
|
+
- `MastraAssistant` / `useMastraAssistant`: persistent application shell and
|
|
438
444
|
external open/close/context controller.
|
|
439
|
-
- `useMastraChat
|
|
440
|
-
- `ChatView
|
|
441
|
-
- `MastraPluginClient
|
|
445
|
+
- `useMastraChat`: headless driver that returns `ChatView` props.
|
|
446
|
+
- `ChatView`: controlled presentational chat shell.
|
|
447
|
+
- `MastraPluginClient`: native `@mastra/client-js` memory/agent APIs plus
|
|
442
448
|
AppKit-Mastra model, suggestion, feedback, and embed routes.
|
|
443
449
|
- `useMastraClient`, `useMastraConfig`, `useMastraModels`,
|
|
444
450
|
`useMastraDefaultModel`, `useMastraSuggestions`, `useMastraThreads`,
|
|
445
|
-
`useChartFetch`, `useStatementFetch
|
|
451
|
+
`useChartFetch`, `useStatementFetch`: route/config hooks for controlled
|
|
446
452
|
clients.
|
|
447
|
-
- `ThreadSidebar
|
|
448
|
-
- `ThreadTabs` / `ThreadActions
|
|
453
|
+
- `ThreadSidebar`: controlled conversation list, dockable to either edge.
|
|
454
|
+
- `ThreadTabs` / `ThreadActions`: conversation pills plus reusable New/History
|
|
449
455
|
controls for the top strip or persistent assistant header.
|
|
450
|
-
- `ExportMenu
|
|
451
|
-
- `
|
|
452
|
-
`closeThreadTab`, `nextActiveThreadTab`) so the strip's state is testable
|
|
453
|
-
without a DOM.
|
|
454
|
-
- `src/support/thread-labels.ts` - `threadTitle` / `relativeTime`, shared by
|
|
455
|
-
the sidebar and the tab strip so a row and a tab never disagree about how an
|
|
456
|
-
untitled or freshly-updated conversation reads.
|
|
457
|
-
- `src/support/request-context.ts` - immutable per-run snapshots around Mastra's
|
|
458
|
-
native typed `RequestContext`.
|
|
459
|
-
- `src/support/tool-events.ts` - projection of native AI SDK persisted tool
|
|
460
|
-
parts onto the live pill view model.
|
|
461
|
-
- `src/support/chart-theme.ts` - `ChartChrome`, `LIGHT_CHART_CHROME`,
|
|
462
|
-
`resolveChartChrome`, and the `useChartChrome` hook that keeps an inline
|
|
463
|
-
chart's colors in step with the active theme.
|
|
464
|
-
- `src/support/chart-option.ts` - `normalizeChartOption`, the pure pass that
|
|
465
|
-
patches layout (compact ticks, axis-name placement, title/grid spacing) and
|
|
466
|
-
an optional `ChartChrome` into a planner spec, shared by the inline chart and
|
|
467
|
-
the PDF export so both read the same.
|
|
468
|
-
- Types - `ChatViewProps`, `MastraChatProps`, `UseMastraChatOptions`,
|
|
456
|
+
- `ExportMenu`: shared export format menu.
|
|
457
|
+
- Types: `ChatViewProps`, `MastraChatProps`, `UseMastraChatOptions`,
|
|
469
458
|
`MastraAssistantProps`, `MastraRequestContextInput`, `ThreadPlacement`,
|
|
470
459
|
`ThreadSummary`, `ToolEvent`, `ToolProgress`, `PendingApproval`,
|
|
471
460
|
`FeedbackSubmission`, and related UI contract types.
|
|
472
461
|
|
|
473
462
|
Server-side routes and event production live in
|
|
474
|
-
[
|
|
463
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra). Browser-safe route,
|
|
475
464
|
marker, feedback, and wire schemas live in
|
|
476
|
-
[
|
|
465
|
+
[@dbx-tools/shared-mastra](../../shared/mastra).
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/ui-mastra";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.132";
|
|
7
7
|
export * as reactBubbles from "./src/react/bubbles.tsx";
|
|
8
8
|
export * as reactChatApprovals from "./src/react/chat-approvals.ts";
|
|
9
9
|
export * as reactChatComposer from "./src/react/chat-composer.tsx";
|
|
@@ -33,10 +33,12 @@ export * as supportChartTheme from "./src/support/chart-theme.ts";
|
|
|
33
33
|
export * as supportClipboard from "./src/support/clipboard.ts";
|
|
34
34
|
export * as supportDownload from "./src/support/download.ts";
|
|
35
35
|
export * as supportExport from "./src/support/export.ts";
|
|
36
|
+
export * as supportGenieClient from "./src/support/genie-client.ts";
|
|
36
37
|
export * as supportMastraClient from "./src/support/mastra-client.ts";
|
|
37
38
|
export * as supportModelSelection from "./src/support/model-selection.ts";
|
|
38
39
|
export * as supportRequestContext from "./src/support/request-context.ts";
|
|
39
40
|
export * as supportThreadLabels from "./src/support/thread-labels.ts";
|
|
41
|
+
export * as supportThreadPersistence from "./src/support/thread-persistence.ts";
|
|
40
42
|
export * as supportThreadSessions from "./src/support/thread-sessions.ts";
|
|
41
43
|
export * as supportThreadTabs from "./src/support/thread-tabs.ts";
|
|
42
44
|
export * as supportToolEvents from "./src/support/tool-events.ts";
|
|
@@ -55,7 +57,7 @@ export { FeedbackControls } from "./src/react/feedback-controls.tsx";
|
|
|
55
57
|
export { AssistantMarkdown, ToolMarkdown, SqlBlock, SourceBlock } from "./src/react/markdown.tsx";
|
|
56
58
|
export type { MastraAssistantMode, MastraAssistantSide, MastraAssistantLauncherPosition, MastraAssistantResizeOptions, MastraAssistantLauncherOptions, MastraAssistantController, MastraAssistantProps } from "./src/react/mastra-assistant.tsx";
|
|
57
59
|
export { useMastraChat, MastraChat } from "./src/react/mastra-chat.tsx";
|
|
58
|
-
export type { UseMastraChatOptions, MastraChatProps } from "./src/react/mastra-chat.tsx";
|
|
60
|
+
export type { ThreadIdChangeReason, UseMastraChatOptions, MastraChatProps } from "./src/react/mastra-chat.tsx";
|
|
59
61
|
export { SuggestionPills } from "./src/react/suggestion-pills.tsx";
|
|
60
62
|
export type { SuggestionPillsProps } from "./src/react/suggestion-pills.tsx";
|
|
61
63
|
export { dedupeSuggestions, collectSuggestions } from "./src/react/suggestions.ts";
|
|
@@ -71,7 +73,8 @@ export type { StoredActiveRun } from "./src/support/active-runs.ts";
|
|
|
71
73
|
export { LIGHT_CHART_CHROME } from "./src/support/chart-theme.ts";
|
|
72
74
|
export type { ChartChrome } from "./src/support/chart-theme.ts";
|
|
73
75
|
export type { ExportFormat, ExportBrand, EmbedResolver, ExportChatOptions } from "./src/support/export.ts";
|
|
74
|
-
export {
|
|
76
|
+
export { GenieChatClient } from "./src/support/genie-client.ts";
|
|
77
|
+
export { MastraChatRequestError, MastraPluginClient, useMastraConfig, useMastraClient, useMastraMlflowExperiment, useMastraModels, useMastraDefaultModel, useMastraSuggestions, useMastraThreads, useChartFetch, useStatementFetch, useVisualizationFetch } from "./src/support/mastra-client.ts";
|
|
75
78
|
export type { MastraStreamResponse, MastraMemoryThread, ByIdFetchState } from "./src/support/mastra-client.ts";
|
|
76
79
|
export { defaultReasoningEffort, modelStorageKey, readStoredModel, storeSelectedModel } from "./src/support/model-selection.ts";
|
|
77
80
|
export type { MastraRequestContextInput, MastraRequestContextSource, MastraRequestContextSnapshot } from "./src/support/request-context.ts";
|
package/package.json
CHANGED
|
@@ -29,11 +29,12 @@
|
|
|
29
29
|
"react-dom": "~19.2.4"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@
|
|
33
|
-
"@dbx-tools/shared-
|
|
34
|
-
"@dbx-tools/shared-
|
|
35
|
-
"@dbx-tools/shared-
|
|
36
|
-
"@dbx-tools/
|
|
32
|
+
"@databricks/appkit-ui": "0.81.0",
|
|
33
|
+
"@dbx-tools/shared-core": "^0.9.132",
|
|
34
|
+
"@dbx-tools/shared-genie": "^0.9.132",
|
|
35
|
+
"@dbx-tools/shared-mastra": "^0.9.132",
|
|
36
|
+
"@dbx-tools/shared-model": "^0.9.132",
|
|
37
|
+
"@dbx-tools/ui": "^0.9.132",
|
|
37
38
|
"@mastra/client-js": "1.50.0",
|
|
38
39
|
"@mastra/core": "1.71.0",
|
|
39
40
|
"@tanstack/react-table": "^8.21.3",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"publishConfig": {
|
|
51
52
|
"access": "public"
|
|
52
53
|
},
|
|
53
|
-
"version": "0.9.
|
|
54
|
+
"version": "0.9.132",
|
|
54
55
|
"dbxToolsConfig": {
|
|
55
56
|
"tags": [
|
|
56
57
|
"ui"
|
package/src/react/bubbles.tsx
CHANGED
|
@@ -18,6 +18,7 @@ import type { UIMessage } from "ai";
|
|
|
18
18
|
import {
|
|
19
19
|
BugIcon,
|
|
20
20
|
CheckIcon,
|
|
21
|
+
ChevronDownIcon,
|
|
21
22
|
CopyIcon,
|
|
22
23
|
MessageSquareIcon,
|
|
23
24
|
RefreshCcwIcon,
|
|
@@ -63,7 +64,8 @@ const UserAvatar = () => (
|
|
|
63
64
|
|
|
64
65
|
const ThoughtsDisclosure = ({ text }: { text: string }) => (
|
|
65
66
|
<Collapsible>
|
|
66
|
-
<CollapsibleTrigger className="w-fit cursor-pointer
|
|
67
|
+
<CollapsibleTrigger className="group flex w-fit cursor-pointer items-center gap-1.5 px-0 py-0.5 text-left text-xs text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
|
|
68
|
+
<ChevronDownIcon className="size-3 shrink-0 transition-transform group-data-[state=closed]:-rotate-90" />
|
|
67
69
|
Thoughts
|
|
68
70
|
</CollapsibleTrigger>
|
|
69
71
|
<CollapsibleContent>
|