@dbx-tools/ui-mastra 0.9.131 → 0.9.136
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 +129 -172
- package/index.ts +3 -2
- package/package.json +6 -6
- package/src/react/_assistant-activity.ts +6 -3
- package/src/react/bubbles.tsx +8 -0
- package/src/react/chat-feedback.ts +68 -12
- package/src/react/chat-transcript.tsx +19 -2
- package/src/react/chat-view.tsx +2 -0
- package/src/react/feedback-controls.tsx +104 -0
- package/src/react/mastra-chat.tsx +12 -16
- package/src/react/thread-sidebar.tsx +4 -2
- package/src/react/types.ts +4 -1
- package/src/support/export.ts +1 -1
- package/src/support/genie-client.ts +14 -7
- package/src/support/index.ts +1 -1
- package/src/support/mastra-client.ts +8 -13
- package/src/support/request-context.ts +9 -14
- package/src/support/thread-sessions.ts +5 -5
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,9 +16,12 @@ 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
26
|
- Reload recovery for agent-backed background turns: active run metadata is
|
|
26
27
|
persisted per agent and thread, the cached stream reconnects after a page
|
|
@@ -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,16 @@ 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.
|
|
175
188
|
- `genieSpace` selects a configured Genie alias and bypasses the agent.
|
|
176
189
|
- `showModelPicker` fetches `/models` and sends `X-Mastra-Model` overrides.
|
|
177
190
|
- `composerActions` places host-owned per-turn controls beside the model
|
|
@@ -180,16 +193,16 @@ Useful options:
|
|
|
180
193
|
the endpoint choices. Supply it only when the active agent supports that
|
|
181
194
|
option, such as a Genie transport toggle.
|
|
182
195
|
- `composerLeadingActions` places attachment or app actions on the left side of
|
|
183
|
-
the fixed composer footer. The textarea grows above it to a cap, then scrolls
|
|
184
|
-
|
|
185
|
-
- `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
|
|
186
199
|
`/suggestions`, or pass `[]` to hide suggestions.
|
|
187
200
|
- `threadPlacement` chooses where conversation management renders, or turns it
|
|
188
|
-
off. See [Place
|
|
189
|
-
- `enableThreads: false`
|
|
201
|
+
off. See [Place the conversation list](#place-the-conversation-list).
|
|
202
|
+
- `enableThreads: false` also sets
|
|
190
203
|
`threadPlacement: "disabled"`.
|
|
191
204
|
- `threadId` and `onThreadIdChange` let a host bind the active conversation to
|
|
192
|
-
URL state or another external selector. Unknown external
|
|
205
|
+
URL state or another external selector. Unknown external IDs are replaced by
|
|
193
206
|
a new thread and reported with the `missing` reason.
|
|
194
207
|
- `enableExport` adds whole-conversation and per-message export affordances.
|
|
195
208
|
- Feedback defaults to auto: thumbs, dislike, and comment controls appear when
|
|
@@ -197,7 +210,7 @@ Useful options:
|
|
|
197
210
|
id. Set `enableFeedback={false}` to hide them. Viewers with `CAN_MANAGE` on
|
|
198
211
|
the experiment also get an experiment debug link at the end of the action row.
|
|
199
212
|
|
|
200
|
-
## Use
|
|
213
|
+
## Use direct Genie chat
|
|
201
214
|
|
|
202
215
|
Use `genieSpace` when the application needs the same chat shell without a
|
|
203
216
|
supervisor agent:
|
|
@@ -207,13 +220,15 @@ supervisor agent:
|
|
|
207
220
|
```
|
|
208
221
|
|
|
209
222
|
The alias comes from the server plugin's `genieSpaces`. The client still uses
|
|
210
|
-
AI SDK `UIMessage` streams and the same `ChatView
|
|
211
|
-
Mastra threads and Genie messages
|
|
223
|
+
AI SDK `UIMessage` streams and the same `ChatView`. Genie conversations replace
|
|
224
|
+
Mastra threads and Genie messages remain the visible history. When Mastra
|
|
225
|
+
memory is configured, the server injects resource-scoped semantic recall and
|
|
226
|
+
saves completed direct turns without replacing Genie's conversation ownership.
|
|
212
227
|
|
|
213
228
|
Turns and history require the Genie Agent API and never fall back to classic
|
|
214
|
-
Genie message polling. The sidebar filters the
|
|
215
|
-
Agent Mode conversations. Genie decides whether a query should be visualized
|
|
216
|
-
|
|
229
|
+
Genie message polling. The sidebar filters the Genie conversation listing to
|
|
230
|
+
Agent Mode conversations. Genie decides whether a query should be visualized.
|
|
231
|
+
Visualization attachments render through AppKit UI's native
|
|
217
232
|
`GenieQueryVisualization`, with Chart and Table tabs. This does not invoke a
|
|
218
233
|
supervisor or the Mastra Model Serving chart planner. Queries without a
|
|
219
234
|
visualization attachment render through the existing sortable data table.
|
|
@@ -225,7 +240,7 @@ attachments, MLflow feedback, approvals, background turns, or stream
|
|
|
225
240
|
reconnection. The newest 100 conversations are listed and each selected
|
|
226
241
|
conversation loads as one history page.
|
|
227
242
|
|
|
228
|
-
## Place
|
|
243
|
+
## Place the conversation list
|
|
229
244
|
|
|
230
245
|
Conversation management is on by default. Where it lives is one option:
|
|
231
246
|
|
|
@@ -238,11 +253,11 @@ Conversation management is on by default. Where it lives is one option:
|
|
|
238
253
|
| `auto` (default) | `left` while the chat is wide, `top` once it is too narrow for a panel |
|
|
239
254
|
| `left` / `right` | List docked to that edge, collapsing to an overlay drawer on a narrow chat |
|
|
240
255
|
| `top` | Tab strip of open conversations, with a history menu for the rest |
|
|
241
|
-
| `disabled` | No thread UI
|
|
256
|
+
| `disabled` | No thread UI. Uses a single thread on the session cookie |
|
|
242
257
|
|
|
243
258
|
The docked placements render the sidebar as an inline column with a persisted
|
|
244
259
|
show/hide toggle. Below 768px of chat width the panel becomes an overlay drawer
|
|
245
|
-
on the same edge, so the transcript never loses room
|
|
260
|
+
on the same edge, so the transcript never loses room. The drawer is
|
|
246
261
|
session-scoped and starts closed, and closes itself after a selection.
|
|
247
262
|
|
|
248
263
|
The composer accepts images from the upload action, drag and drop, or clipboard
|
|
@@ -251,24 +266,24 @@ paste. Oversized images use the same client-side resize path before submission.
|
|
|
251
266
|
The `top` placement is the editor-tab model: each open conversation is a tab with
|
|
252
267
|
its title, a spinner while it streams in the background, and a close affordance
|
|
253
268
|
that only takes the tab off the strip (the conversation stays in history). A `+`
|
|
254
|
-
starts a fresh conversation
|
|
255
|
-
|
|
256
|
-
|
|
269
|
+
starts a fresh conversation. The history button opens the full sidebar as a
|
|
270
|
+
menu, so rename, delete, and cancel still work on conversations that aren't on
|
|
271
|
+
the tab strip. Closing the active tab moves to a neighboring one, or
|
|
257
272
|
starts a fresh conversation when it was the last tab open. The open set is
|
|
258
|
-
session state
|
|
273
|
+
session state. The strip reseeds from the most recent conversations on the next
|
|
259
274
|
load.
|
|
260
275
|
|
|
261
276
|
For agent-backed chat, selecting a conversation fetches only the newest 20
|
|
262
277
|
native memory messages. Scrolling upward requests the next page and prepends it
|
|
263
278
|
without moving the reader's viewport. Agent turns still send only the new user
|
|
264
|
-
message
|
|
279
|
+
message. Mastra loads the remembered transcript server-side. Direct Genie mode
|
|
265
280
|
loads the selected Genie conversation in one page.
|
|
266
281
|
|
|
267
282
|
`auto` measures the chat's own element rather than the viewport, so a chat
|
|
268
283
|
embedded in a split view or side panel switches to tabs on the space it actually
|
|
269
284
|
has instead of waiting for the window to shrink.
|
|
270
285
|
|
|
271
|
-
## Use
|
|
286
|
+
## Use the headless driver
|
|
272
287
|
|
|
273
288
|
```tsx
|
|
274
289
|
import { ChatView, useMastraChat } from "@dbx-tools/ui-mastra/react";
|
|
@@ -284,33 +299,37 @@ export function CustomChat() {
|
|
|
284
299
|
}
|
|
285
300
|
```
|
|
286
301
|
|
|
287
|
-
Use `useMastraChat()` when
|
|
288
|
-
|
|
302
|
+
Use `useMastraChat()` when you want package transport behavior with your own
|
|
303
|
+
layout. The hook owns streaming, aborts, history paging, thread
|
|
289
304
|
selection, model overrides, suggestions, exports, approvals, and feedback state.
|
|
290
305
|
|
|
291
|
-
## Pass
|
|
306
|
+
## Pass typed application context
|
|
292
307
|
|
|
293
308
|
`requestContext` accepts a typed plain record, Mastra `RequestContext<T>`, or a
|
|
294
309
|
per-turn resolver. The driver snapshots it when a message is submitted and
|
|
295
310
|
keeps that snapshot with queued steers, regeneration, and approval continuation.
|
|
296
311
|
|
|
297
312
|
```tsx
|
|
313
|
+
import { RequestContext } from "@mastra/client-js";
|
|
314
|
+
|
|
298
315
|
type StoreContext = { storeId: string; route: string };
|
|
299
316
|
|
|
300
317
|
const chat = useMastraChat<StoreContext>({
|
|
301
|
-
requestContext: () =>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
318
|
+
requestContext: () =>
|
|
319
|
+
new RequestContext<StoreContext>([
|
|
320
|
+
["storeId", selectedStore.id],
|
|
321
|
+
["route", location.pathname],
|
|
322
|
+
]),
|
|
305
323
|
});
|
|
306
324
|
```
|
|
307
325
|
|
|
308
326
|
On the server, declare the same contract with Mastra's native
|
|
309
327
|
`requestContextSchema` on `createAgent<StoreContext>()`. Application context
|
|
310
328
|
cannot override the authenticated memory resource, thread, user, scopes, model,
|
|
311
|
-
or trace fields stamped by AppKit-Mastra.
|
|
329
|
+
or trace fields stamped by AppKit-Mastra. Direct Genie chat forwards the same
|
|
330
|
+
native context as reference data for its one Agent Mode user message.
|
|
312
331
|
|
|
313
|
-
## Build
|
|
332
|
+
## Build a controlled chat surface
|
|
314
333
|
|
|
315
334
|
```tsx
|
|
316
335
|
import { ChatView, type ChatViewProps } from "@dbx-tools/ui-mastra/react";
|
|
@@ -330,66 +349,45 @@ is being resolved. The picker groups endpoints into
|
|
|
330
349
|
model-family submenus. Its compact first popup shows only the current
|
|
331
350
|
model, host-owned actions such as Genie Agent Mode, and a reasoning slider when
|
|
332
351
|
the selected endpoint supports it. The current model opens the family picker,
|
|
333
|
-
so the long endpoint
|
|
352
|
+
so the long endpoint catalog stays out of the primary control popup. Family
|
|
334
353
|
and model menus use the same compact utility type as the composer actions,
|
|
335
354
|
omit repeated headers, and omit the already-selected model. The model menu puts
|
|
336
355
|
`Default (<resolved model>)` first, keeps `Other` last, and makes a one-model
|
|
337
356
|
family directly selectable instead of opening another submenu.
|
|
338
357
|
|
|
339
|
-
## Call
|
|
358
|
+
## Call plugin routes directly
|
|
340
359
|
|
|
341
360
|
```ts
|
|
342
|
-
import {
|
|
343
|
-
|
|
344
|
-
useMastraClient,
|
|
345
|
-
useMastraDefaultModel,
|
|
346
|
-
useMastraModels,
|
|
347
|
-
useMastraSuggestions,
|
|
348
|
-
useMastraThreads,
|
|
349
|
-
} from "@dbx-tools/ui-mastra/react";
|
|
350
|
-
|
|
351
|
-
const client = new MastraPluginClient(clientConfig);
|
|
352
|
-
|
|
353
|
-
// Routing (thread + model) is passed per call, so concurrent runs on
|
|
354
|
-
// different threads never share state.
|
|
355
|
-
const stream = await client.streamAgent({
|
|
356
|
-
agentId: client.defaultAgent,
|
|
357
|
-
messages: [
|
|
358
|
-
{
|
|
359
|
-
id: "user-1",
|
|
360
|
-
role: "user",
|
|
361
|
-
parts: [{ type: "text", text: "Hello" }],
|
|
362
|
-
},
|
|
363
|
-
],
|
|
364
|
-
runId,
|
|
365
|
-
threadId: activeThreadId,
|
|
366
|
-
model: "claude sonnet",
|
|
367
|
-
signal: controller.signal,
|
|
368
|
-
});
|
|
361
|
+
import type { MastraClientConfig } from "@dbx-tools/shared-mastra";
|
|
362
|
+
import { MastraPluginClient } from "@dbx-tools/ui-mastra/react";
|
|
369
363
|
|
|
370
|
-
|
|
371
|
-
const
|
|
364
|
+
export async function listChatModels(clientConfig: MastraClientConfig) {
|
|
365
|
+
const client = new MastraPluginClient(clientConfig);
|
|
366
|
+
return client.models();
|
|
367
|
+
}
|
|
372
368
|
```
|
|
373
369
|
|
|
374
370
|
Each conversation thread runs independently: start a turn on one thread, switch
|
|
375
|
-
to another and start a second, and both stream concurrently. Cancel one
|
|
371
|
+
to another and start a second, and both stream concurrently. Cancel one using its
|
|
376
372
|
`AbortSignal` (or the driver's `onCancelThread`) without touching the others.
|
|
377
373
|
|
|
378
374
|
`MastraPluginClient` extends `@mastra/client-js` with the official AI SDK
|
|
379
375
|
`chatRoute` transport and AppKit-Mastra additions. It uses
|
|
380
376
|
`credentials: "include"` so session cookies travel with streaming and REST
|
|
381
|
-
calls. The React hooks wrap native memory plus model
|
|
382
|
-
chart fetches, and statement-data fetches.
|
|
377
|
+
calls. The React hooks wrap native memory plus model catalogs, suggestions,
|
|
378
|
+
chart fetches, and statement-data fetches. Use `useMastraClient()` to access the
|
|
379
|
+
configured client inside React. `useMastraModels()`, `useMastraDefaultModel()`,
|
|
380
|
+
`useMastraSuggestions()`, and `useMastraThreads()` expose route-specific state.
|
|
383
381
|
|
|
384
|
-
##
|
|
382
|
+
## Handle approvals, embeds, and feedback
|
|
385
383
|
|
|
386
384
|
The UI understands the extra events produced by
|
|
387
|
-
[
|
|
385
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra):
|
|
388
386
|
|
|
389
387
|
- Approval chunks become inline approval cards and continue the official chat
|
|
390
388
|
route with Mastra's native `{ approved, reason? }` resume data.
|
|
391
389
|
- Native tool-call and tool-result payloads remain complete. Expanding a tool
|
|
392
|
-
row reveals default-closed Request and Response viewers
|
|
390
|
+
row reveals default-closed Request and Response viewers. Large values scroll
|
|
393
391
|
without string or collection truncation.
|
|
394
392
|
- Genie `thinking` events stream into the assistant's collapsed Thoughts
|
|
395
393
|
panel. Intermediate answer attachments and query-result tables stay on tool
|
|
@@ -404,42 +402,25 @@ The UI understands the extra events produced by
|
|
|
404
402
|
- MLflow trace headers enable per-message feedback controls when the server
|
|
405
403
|
reports feedback is available.
|
|
406
404
|
|
|
407
|
-
##
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
theme-dependent is resolved here at render time by `src/support/chart-theme.ts`,
|
|
419
|
-
which reads AppKit's `--chart-axis-label`, `--chart-axis-title`, `--chart-grid`,
|
|
420
|
-
and `--chart-tooltip-bg` (plus `--popover-foreground` and `--border` for the
|
|
421
|
-
tooltip) into a `ChartChrome`, and `normalizeChartOption` paints it onto the
|
|
422
|
-
axes, title, legend, and tooltip. Nothing to configure: a chart follows the
|
|
423
|
-
theme wherever it renders.
|
|
424
|
-
|
|
425
|
-
Two details worth knowing if you embed the chat:
|
|
426
|
-
|
|
427
|
-
- Tokens are read off the **chart's own element**, not `:root`, so a theme
|
|
428
|
-
scoped to a subtree - a chat panel inside an otherwise-light app - wins. The
|
|
429
|
-
value re-resolves when a `.dark` / `.light` class lands on the document root
|
|
430
|
-
and when the OS `prefers-color-scheme` flips, so a live theme switch recolors
|
|
431
|
-
charts in place.
|
|
405
|
+
## Configure chart themes
|
|
406
|
+
|
|
407
|
+
ECharts draws to a canvas and doesn't inherit CSS colors from its frame. The
|
|
408
|
+
server planner provides the series palette and font stack. The browser resolves
|
|
409
|
+
axis, grid, title, legend, and tooltip colors from AppKit semantic tokens at
|
|
410
|
+
render time.
|
|
411
|
+
|
|
412
|
+
- Theme tokens are read from the chart element, so a theme scoped to a chat
|
|
413
|
+
subtree takes precedence over the document theme. Charts update when the
|
|
414
|
+
document's `.dark` or `.light` class changes or when the operating-system
|
|
415
|
+
color preference changes.
|
|
432
416
|
- AppKit darkens its tokens under `@media (prefers-color-scheme: dark)` for any
|
|
433
417
|
`:root` that is not explicitly `.light`. If your host renders its own light
|
|
434
418
|
chrome, pin `.light` (or `.dark`) on `:root` rather than leaving AppKit on the
|
|
435
|
-
|
|
436
|
-
stays light.
|
|
419
|
+
operating-system preference.
|
|
437
420
|
|
|
438
|
-
|
|
439
|
-
`LIGHT_CHART_CHROME`, because its document forces `color-scheme: light` on a
|
|
440
|
-
white body for printing.
|
|
421
|
+
PDF export uses a light chart theme on a white print document.
|
|
441
422
|
|
|
442
|
-
## Export
|
|
423
|
+
## Export conversations
|
|
443
424
|
|
|
444
425
|
```tsx
|
|
445
426
|
<MastraChat enableExport />
|
|
@@ -450,65 +431,41 @@ resolved during export: charts are rendered to inline SVG with ECharts' server
|
|
|
450
431
|
renderer, and data markers become real tables. Expired or missing embeds are
|
|
451
432
|
skipped so old transcripts still export cleanly.
|
|
452
433
|
|
|
453
|
-
##
|
|
434
|
+
## Copy and download content
|
|
454
435
|
|
|
455
|
-
Copy and download
|
|
456
|
-
|
|
457
|
-
same everywhere because each is backed by one internal module rather than
|
|
458
|
-
per-component code.
|
|
436
|
+
Copy and download controls appear in message bubbles, code blocks, conversation
|
|
437
|
+
exports, and the data-grid CSV menu.
|
|
459
438
|
|
|
460
439
|
Copying works on hosts served over plain HTTP. An insecure context has no
|
|
461
440
|
Clipboard API, so a bare `navigator.clipboard.writeText` silently does nothing on
|
|
462
|
-
a local or intranet deployment
|
|
441
|
+
a local or intranet deployment. The package falls back to a hidden
|
|
463
442
|
`<textarea>` plus `document.execCommand("copy")` and reports whether the copy
|
|
464
443
|
actually succeeded. Downloads revoke their object URL after the temporary anchor
|
|
465
444
|
fires, so a long session does not accumulate blobs.
|
|
466
445
|
|
|
467
|
-
|
|
468
|
-
anything. Adding a new copy or download button anywhere in this package should
|
|
469
|
-
reuse `src/support/clipboard.ts` and `src/support/download.ts` instead of
|
|
470
|
-
touching `navigator.clipboard` or `URL.createObjectURL` again.
|
|
471
|
-
|
|
472
|
-
## Modules
|
|
446
|
+
## Package exports
|
|
473
447
|
|
|
474
|
-
- `MastraChat
|
|
475
|
-
- `MastraAssistant` / `useMastraAssistant
|
|
448
|
+
- `MastraChat`: self-contained drop-in chat component.
|
|
449
|
+
- `MastraAssistant` / `useMastraAssistant`: persistent application shell and
|
|
476
450
|
external open/close/context controller.
|
|
477
|
-
- `useMastraChat
|
|
478
|
-
- `ChatView
|
|
479
|
-
- `MastraPluginClient
|
|
451
|
+
- `useMastraChat`: headless driver that returns `ChatView` props.
|
|
452
|
+
- `ChatView`: controlled presentational chat shell.
|
|
453
|
+
- `MastraPluginClient`: native `@mastra/client-js` memory/agent APIs plus
|
|
480
454
|
AppKit-Mastra model, suggestion, feedback, and embed routes.
|
|
481
455
|
- `useMastraClient`, `useMastraConfig`, `useMastraModels`,
|
|
482
456
|
`useMastraDefaultModel`, `useMastraSuggestions`, `useMastraThreads`,
|
|
483
|
-
`useChartFetch`, `useStatementFetch
|
|
457
|
+
`useChartFetch`, `useStatementFetch`: route/config hooks for controlled
|
|
484
458
|
clients.
|
|
485
|
-
- `ThreadSidebar
|
|
486
|
-
- `ThreadTabs` / `ThreadActions
|
|
459
|
+
- `ThreadSidebar`: controlled conversation list, dockable to either edge.
|
|
460
|
+
- `ThreadTabs` / `ThreadActions`: conversation pills plus reusable New/History
|
|
487
461
|
controls for the top strip or persistent assistant header.
|
|
488
|
-
- `ExportMenu
|
|
489
|
-
- `
|
|
490
|
-
`closeThreadTab`, `nextActiveThreadTab`) so the strip's state is testable
|
|
491
|
-
without a DOM.
|
|
492
|
-
- `src/support/thread-labels.ts` - `threadTitle` / `relativeTime`, shared by
|
|
493
|
-
the sidebar and the tab strip so a row and a tab never disagree about how an
|
|
494
|
-
untitled or freshly-updated conversation reads.
|
|
495
|
-
- `src/support/request-context.ts` - immutable per-run snapshots around Mastra's
|
|
496
|
-
native typed `RequestContext`.
|
|
497
|
-
- `src/support/tool-events.ts` - projection of native AI SDK persisted tool
|
|
498
|
-
parts onto the live pill view model.
|
|
499
|
-
- `src/support/chart-theme.ts` - `ChartChrome`, `LIGHT_CHART_CHROME`,
|
|
500
|
-
`resolveChartChrome`, and the `useChartChrome` hook that keeps an inline
|
|
501
|
-
chart's colors in step with the active theme.
|
|
502
|
-
- `src/support/chart-option.ts` - `normalizeChartOption`, the pure pass that
|
|
503
|
-
patches layout (compact ticks, axis-name placement, title/grid spacing) and
|
|
504
|
-
an optional `ChartChrome` into a planner spec, shared by the inline chart and
|
|
505
|
-
the PDF export so both read the same.
|
|
506
|
-
- Types - `ChatViewProps`, `MastraChatProps`, `UseMastraChatOptions`,
|
|
462
|
+
- `ExportMenu`: shared export format menu.
|
|
463
|
+
- Types: `ChatViewProps`, `MastraChatProps`, `UseMastraChatOptions`,
|
|
507
464
|
`MastraAssistantProps`, `MastraRequestContextInput`, `ThreadPlacement`,
|
|
508
465
|
`ThreadSummary`, `ToolEvent`, `ToolProgress`, `PendingApproval`,
|
|
509
466
|
`FeedbackSubmission`, and related UI contract types.
|
|
510
467
|
|
|
511
468
|
Server-side routes and event production live in
|
|
512
|
-
[
|
|
469
|
+
[@dbx-tools/appkit-mastra](../../node/appkit-mastra). Browser-safe route,
|
|
513
470
|
marker, feedback, and wire schemas live in
|
|
514
|
-
[
|
|
471
|
+
[@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.136";
|
|
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";
|
|
@@ -44,6 +44,7 @@ export * as supportThreadTabs from "./src/support/thread-tabs.ts";
|
|
|
44
44
|
export * as supportToolEvents from "./src/support/tool-events.ts";
|
|
45
45
|
export { AssistantBubble, UserBubble } from "./src/react/bubbles.tsx";
|
|
46
46
|
export { ChatComposer } from "./src/react/chat-composer.tsx";
|
|
47
|
+
export type { GenieFeedbackTarget } from "./src/react/chat-feedback.ts";
|
|
47
48
|
export type { ThreadSessionReader, ThreadSessionUpdater, ThreadMessageWriter } from "./src/react/chat-sessions.ts";
|
|
48
49
|
export { ChatThreadLayout } from "./src/react/chat-thread-layout.tsx";
|
|
49
50
|
export { useChatTranscriptController, ChatTranscript } from "./src/react/chat-transcript.tsx";
|
|
@@ -77,7 +78,7 @@ export { GenieChatClient } from "./src/support/genie-client.ts";
|
|
|
77
78
|
export { MastraChatRequestError, MastraPluginClient, useMastraConfig, useMastraClient, useMastraMlflowExperiment, useMastraModels, useMastraDefaultModel, useMastraSuggestions, useMastraThreads, useChartFetch, useStatementFetch, useVisualizationFetch } from "./src/support/mastra-client.ts";
|
|
78
79
|
export type { MastraStreamResponse, MastraMemoryThread, ByIdFetchState } from "./src/support/mastra-client.ts";
|
|
79
80
|
export { defaultReasoningEffort, modelStorageKey, readStoredModel, storeSelectedModel } from "./src/support/model-selection.ts";
|
|
80
|
-
export type { MastraRequestContextInput, MastraRequestContextSource
|
|
81
|
+
export type { MastraRequestContextInput, MastraRequestContextSource } from "./src/support/request-context.ts";
|
|
81
82
|
export { DEFAULT_THREAD_SESSION_KEY } from "./src/support/thread-sessions.ts";
|
|
82
83
|
export type { SessionQueuedSteer, SessionRun, ThreadSession } from "./src/support/thread-sessions.ts";
|
|
83
84
|
export { THREAD_TAB_SEED_MAX } from "./src/support/thread-tabs.ts";
|
package/package.json
CHANGED
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@databricks/appkit-ui": "0.81.0",
|
|
33
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
34
|
-
"@dbx-tools/shared-genie": "^0.9.
|
|
35
|
-
"@dbx-tools/shared-mastra": "^0.9.
|
|
36
|
-
"@dbx-tools/shared-model": "^0.9.
|
|
37
|
-
"@dbx-tools/ui": "^0.9.
|
|
33
|
+
"@dbx-tools/shared-core": "^0.9.136",
|
|
34
|
+
"@dbx-tools/shared-genie": "^0.9.136",
|
|
35
|
+
"@dbx-tools/shared-mastra": "^0.9.136",
|
|
36
|
+
"@dbx-tools/shared-model": "^0.9.136",
|
|
37
|
+
"@dbx-tools/ui": "^0.9.136",
|
|
38
38
|
"@mastra/client-js": "1.50.0",
|
|
39
39
|
"@mastra/core": "1.71.0",
|
|
40
40
|
"@tanstack/react-table": "^8.21.3",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
|
-
"version": "0.9.
|
|
54
|
+
"version": "0.9.136",
|
|
55
55
|
"dbxToolsConfig": {
|
|
56
56
|
"tags": [
|
|
57
57
|
"ui"
|
|
@@ -20,10 +20,13 @@ export const assistantActivityItems = (
|
|
|
20
20
|
if (renderedEventIds.has(event.id)) return;
|
|
21
21
|
renderedEventIds.add(event.id);
|
|
22
22
|
items.push({ type: "tool", key: `tool-${event.id}`, event });
|
|
23
|
-
|
|
24
|
-
if (progress.type !== "thinking")
|
|
23
|
+
const thoughts = (event.progress ?? []).flatMap((progress) => {
|
|
24
|
+
if (progress.type !== "thinking") return [];
|
|
25
25
|
const text = compactReasoningText(progress.text);
|
|
26
|
-
|
|
26
|
+
return text ? [text] : [];
|
|
27
|
+
});
|
|
28
|
+
if (thoughts.length > 0) {
|
|
29
|
+
items.push({ type: "thought", key: `thought-${event.id}`, text: thoughts.join("\n\n") });
|
|
27
30
|
}
|
|
28
31
|
};
|
|
29
32
|
|
package/src/react/bubbles.tsx
CHANGED
|
@@ -336,6 +336,10 @@ type AssistantBubbleProps = {
|
|
|
336
336
|
* when MLflow logging is enabled and the turn has a captured trace id.
|
|
337
337
|
*/
|
|
338
338
|
onFeedback?: (submission: FeedbackSubmission) => void | Promise<void>;
|
|
339
|
+
/** Feedback destination selected by the server. */
|
|
340
|
+
feedbackMode?: "mlflow" | "genie";
|
|
341
|
+
/** Original user request shown in Genie feedback. */
|
|
342
|
+
feedbackRequest?: string;
|
|
339
343
|
/** Last thumbs the user left on this message, for highlighting. */
|
|
340
344
|
feedbackValue?: FeedbackValue;
|
|
341
345
|
/** MLflow experiment link shown only to viewers with `CAN_MANAGE`. */
|
|
@@ -354,6 +358,8 @@ export const AssistantBubble = ({
|
|
|
354
358
|
externalApprovals,
|
|
355
359
|
onExport,
|
|
356
360
|
onFeedback,
|
|
361
|
+
feedbackMode,
|
|
362
|
+
feedbackRequest,
|
|
357
363
|
feedbackValue,
|
|
358
364
|
mlflowExperimentUrl,
|
|
359
365
|
}: AssistantBubbleProps) => {
|
|
@@ -493,6 +499,8 @@ export const AssistantBubble = ({
|
|
|
493
499
|
{hasText && onFeedback && (
|
|
494
500
|
<FeedbackControls
|
|
495
501
|
onSubmit={onFeedback}
|
|
502
|
+
{...(feedbackMode ? { mode: feedbackMode } : {})}
|
|
503
|
+
{...(feedbackRequest ? { request: feedbackRequest } : {})}
|
|
496
504
|
{...(feedbackValue ? { value: feedbackValue } : {})}
|
|
497
505
|
/>
|
|
498
506
|
)}
|