@dbx-tools/ui-mastra

中文文档
0.9.206发布于 2026/11/11Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 8646

React chat UI for the AppKit-Mastra plugin

原始使用文档
文档目录16 节
  1. Quick start
  2. Choose a UI package
  3. Configure styles
  4. Add a persistent assistant
  5. Render a drop-in chat
  6. Use direct Genie chat
  7. Place the conversation list
  8. Use the headless driver
  9. Pass typed application context
  10. Build a controlled chat surface
  11. Call plugin routes directly
  12. Handle approvals, embeds, and feedback
  13. Configure chart themes
  14. Export conversations
  15. Copy and download content
  16. Package exports

@dbx-tools/ui-mastra

Add a React chat surface to @dbx-tools/appkit-mastra. The package supports streaming, model selection, AI/BI Genie progress, charts, tables, approvals, history, threads, export, and MLflow feedback.

Quick start

import { MastraChat } from "@dbx-tools/ui-mastra/react";
import "@dbx-tools/ui-mastra/styles.css";

export function Assistant() {
  return <MastraChat showModelPicker enableExport />;
}

The stylesheet imports the shared @dbx-tools/ui foundation. The host application must also load Databricks AppKit UI styles.

Package contents:

  • Drop-in MastraChat component that reads the plugin client config and wires itself to the default agent.
  • Reload recovery for agent-backed background turns: active run metadata is persisted per agent and thread, the cached stream reconnects after a page reload, and the final persisted history is refreshed when recovery completes.
  • Headless useMastraChat() driver for apps that want the same transport logic with custom layout.
  • Persistent MastraAssistant application shell with a floating launcher, dock/overlay modes, every edge, optional resizing, external controls, and route-stable chat state.
  • Controlled ChatView for hosts that own messages, streaming, model state, and route calls themselves.
  • MastraPluginClient combines Mastra's official AI SDK chat route, native memory APIs, and AppKit-Mastra model, suggestion, feedback, chart, and statement routes.
  • Tool-approval support for suspended Mastra requireApproval calls, including resumed-stream handling. An email-shaped input (the send_email tool) renders as a formatted To / Cc / Subject / Markdown-body preview rather than raw JSON.
  • Complete native tool input/results retained behind expandable, syntax-highlighted JSON Request and Response rows in each tool pill.
  • Typed per-turn application context through Mastra's native RequestContext and server-side requestContextSchema.
  • Inline embed rendering for [chart:<id>] and [data:<id>] markers produced by the server plugin.
  • Conversation sidebar with new, select, rename, delete, active-thread, and background-streaming states, plus a per-row cancel for a running thread.
  • Placeable conversation UI: dock the list left or right, switch to an editor-style tab strip across the top, turn it off, or let auto pick between a side panel and tabs from the chat's own width.
  • Concurrent threads: run several conversations at once, switch between them while each keeps streaming, and cancel any one independently. Abort routing is per thread, with no shared client state.
  • Mid-turn steering queue: messages submitted while a turn streams stack up as pending steers. They drain oldest-first when the turn ends. Each queued item can be sent now (interrupting the current turn), removed, or dragged to reorder the queue.
  • Export menu for PDF and Markdown, resolving charts and tables so exported conversations remain useful offline.

Choose a UI package

Use native @databricks/appkit-ui for its general primitives, AI/BI Genie chat, or Model Serving hooks with native AppKit plugins.

Use this package when the server is @dbx-tools/appkit-mastra and the UI needs to understand Mastra-specific behavior:

  • Mastra's official AI SDK chat stream, native resource-scoped memory APIs, and the plugin's model, suggestion, feedback, chart, and statement routes.
  • Suspended requireApproval tool calls resumed through native resumeData.
  • Genie writer events rendered as inline tool progress rather than only a terminal answer.
  • [chart:<id>] and [data:<id>] assistant markers rendered as ECharts charts and sortable tables.
  • Concurrent multi-thread streaming, per-thread cancel, and a mid-turn steering queue. Submit while running to enqueue, drain oldest-first, or send any item immediately to interrupt. The native AppKit chat surface runs one turn at a time and has no steering.
  • Conversation export that resolves those embeds into Markdown or PDF.

Import the AppKit UI stylesheet before this package's stylesheet. Mount the chat inside the application's authentication boundary. Agent chat can use either user identity or service-principal identity according to the server plugin's configuration. Direct Genie chat requires the signed-in user's on-behalf-of (OBO) context.

MastraChat reads the mastra plugin's published clientConfig() payload through AppKit. The payload supplies the mount path, default agent, registered agents, feedback availability, background-turn support, and chat identity behavior. Don't hard-code plugin routes in browser code.

Use @dbx-tools/ui for common AppKit, authentication, email, and search components.

Configure styles

@import "@databricks/appkit-ui/styles.css";
@import "@dbx-tools/ui-mastra/styles.css";

The stylesheet imports the shared @dbx-tools/ui foundation and registers this package's React files with Tailwind. It does not define design tokens. The chat UI uses AppKit semantic tokens from the host app.

Add a persistent assistant

Mount MastraAssistant inside the app's existing authentication gate and above the route outlet. Closing the panel hides its presentation without unmounting the chat driver, so drafts, threads, and active streams survive page navigation.

import { MastraAssistant, useMastraAssistant } from "@dbx-tools/ui-mastra/react";

const AskAboutStore = ({ storeId }: { storeId: string }) => {
  const assistant = useMastraAssistant<{ storeId: string; route: string }>();
  return (
    <button onClick={() => assistant.open({ storeId, route: window.location.pathname })}>
      Ask assistant
    </button>
  );
};

export function App() {
  return (
    <MastraAssistant
      mode="overlay"
      side="right"
      resizable={{ defaultSize: 480, minSize: 360, storageKey: "assistant-size" }}
      title="Workflow assistant"
      launcher={{ position: "bottom-right", label: "Open assistant" }}
      chat={{ showModelPicker: true, enableExport: true, threadPlacement: "top" }}
    >
      <RouterAndAuthenticatedApplication />
    </MastraAssistant>
  );
}

mode="dock" reflows the child application. mode="overlay" overlaps it. side accepts top, right, bottom, or left. Set resizable={false} to lock size, launcher={false} when every launch comes from useMastraAssistant(), header={false} to place New, History, and Close beside the conversation pills. With the header enabled those controls move into it and the conversation pills remain on their own second row. Replace icon, closeIcon, newConversationIcon, historyIcon, and launcher.icon. Below mobileBreakpoint the panel becomes a focus-contained modal overlay with Escape dismissal while the covered application is inert. A storageKey retains horizontal and vertical sizes independently.

MastraAssistant remains mounted when closed, which preserves drafts, scroll state, active streams, and independent horizontal and vertical sizes.

Render a drop-in chat

import { MastraChat } from "@dbx-tools/ui-mastra/react";

export function App() {
  return (
    <MastraChat
      agentId="analyst"
      showModelPicker
      threadPlacement="auto"
      enableExport
      className="h-dvh"
    />
  );
}

MastraChat provides the bundled client for the AppKit-Mastra plugin. It reads the plugin's published client config, creates a MastraPluginClient, streams turns through Mastra's official AI SDK chat route, hydrates native memory, and renders the controlled ChatView. When Mastra returns persisted messages without a precomputed uiMessages projection, history hydration uses Mastra's native convertMessages(...).to("AIV5.UI") conversion.

Configure the client with these options:

  • agentId selects a registered agent and defaults to the plugin default agent.
  • genieSpace selects a configured Genie alias and bypasses the agent.
  • showModelPicker fetches /models and sends X-Mastra-Model overrides.
  • showSelectedModel adds the friendly model name to the assistant footer as soon as routing completes, with the concrete serving endpoint on hover or keyboard focus. It is off by default.
  • metrics adds one or more right-aligned per-turn footer counters: tokens, time, dbu, or usd. It is off by default. Hovering or focusing the metric group shows all four values even when only a subset is visible.
  • enableRetry={false} hides retry actions. Retry is enabled by default.
  • onModelRoute receives the concrete endpoint as soon as routing completes.
  • onModelUsage receives the latest cumulative tokens after each completed model step, along with the resolved endpoint, Smart Router observation when applicable, plus estimated DBU cost when Databricks publishes token rates. onModelRoute also carries the selected standard list-price row and Databricks USD-per-DBU prices by cloud so clients can derive cloud-specific costs while response text is still streaming.
  • composerActions places host-owned per-turn controls beside the model selector without replacing the built-in composer.
  • modelSelectorActions places host-owned controls inside the model menu after the endpoint choices. Supply it only when the active agent supports that option, such as a Genie transport toggle.
  • composerLeadingActions places attachment or app actions on the left side of the fixed composer footer. The textarea grows above it to a cap, then scrolls. Model and Send/Stop stay pinned bottom-right.
  • suggestions overrides Genie starter questions. Omit it to auto-fetch /suggestions, or pass [] to hide suggestions.
  • threadPlacement chooses where conversation management renders, or turns it off. See Place the conversation list.
  • enableThreads: false also sets threadPlacement: "disabled".
  • threadId and onThreadIdChange let a host bind the active conversation to URL state or another external selector. Unknown external IDs are replaced by a new thread and reported with the missing reason.
  • conversationHistory="browser" sends the complete browser-held transcript with each turn for agents without Mastra memory. The default "memory" sends only the newest message because the persisted Mastra thread is the authoritative history.
  • browserPersistence stores that browser-held transcript in local storage, scoped by plugin mount, agent, signed-in resource, and thread. Pass true for the default 100-message limit or { maxMessages } to set a bound.
  • enableExport adds whole-conversation and per-message export affordances.
  • Feedback defaults to auto: thumbs, dislike, and comment controls appear when the server reports MLflow feedback is available and a turn produced a trace id. Set enableFeedback={false} to hide them. Viewers with CAN_MANAGE on the experiment also get an experiment debug link at the end of the action row.

Post-turn follow-ups follow the policy published by AppKit-Mastra. Native Genie questions and persisted data-follow-up-suggestions parts use the same near-duplicate filter and source round-robin. After a turn settles, the latest questions render through SuggestionPills at the end of the scrollable transcript. They disappear when the next user turn starts and remain available after history hydration because generated suggestions are persisted on the assistant message.

Use direct Genie chat

Use genieSpace when the application needs the same chat shell without a supervisor agent:

<MastraChat genieSpace="sales" threadPlacement="auto" enableExport />

Set genieVisualization="image" to show Genie's original rendered PNG in the Chart tab while keeping the linked query result in the Table tab:

<MastraChat genieSpace="sales" genieVisualization="image" />

The alias comes from the server plugin's genieSpaces. The client still uses AI SDK UIMessage streams and the same ChatView. Genie conversations replace Mastra threads and Genie messages remain the visible history. When Mastra memory is configured, the server injects resource-scoped semantic recall and saves completed direct turns without replacing Genie's conversation ownership.

Turns and history require the Genie Agent API and never fall back to classic Genie message polling. The sidebar filters the Genie conversation listing to Agent Mode conversations. Genie decides whether a query should be visualized. Visualization attachments render through AppKit UI's native GenieQueryVisualization, with Chart and Table tabs, unless image mode is selected. This does not invoke a supervisor or the Mastra Model Serving chart planner. Queries without a visualization attachment render through the existing sortable data table.

Direct mode requires the signed-in user's Databricks OBO context. It supports new/select/delete conversations, history, suggestions, thoughts, exports, and stream cancellation. It does not support conversation rename, file attachments, MLflow feedback, approvals, background turns, or stream reconnection. The newest 100 conversations are listed and each selected conversation loads as one history page.

Place the conversation list

Conversation management is on by default. Where it lives is one option:

<MastraChat threadPlacement="top" />
threadPlacementLayout
auto (default)left while the chat is wide, top once it is too narrow for a panel
left / rightList docked to that edge, collapsing to an overlay drawer on a narrow chat
topTab strip of open conversations, with a history menu for the rest
disabledNo thread UI. Uses a single thread on the session cookie

The docked placements render the sidebar as an inline column with a persisted show/hide toggle. Below 768px of chat width the panel becomes an overlay drawer on the same edge, so the transcript never loses room. The drawer is session-scoped and starts closed, and closes itself after a selection.

The composer accepts images from the upload action, drag and drop, or clipboard paste. Oversized images use the same client-side resize path before submission.

The top placement is the editor-tab model: each open conversation is a tab with its title, a spinner while it streams in the background, and a close affordance that only takes the tab off the strip (the conversation stays in history). A + starts a fresh conversation. The history button opens the full sidebar as a menu, so rename, delete, and cancel still work on conversations that aren't on the tab strip. Closing the active tab moves to a neighboring one, or starts a fresh conversation when it was the last tab open. The open set is session state. The strip reseeds from the most recent conversations on the next load.

For agent-backed chat, selecting a conversation fetches only the newest 20 native memory messages. Scrolling upward requests the next page and prepends it without moving the reader's viewport. Agent turns still send only the new user message. Mastra loads the remembered transcript server-side. Direct Genie mode loads the selected Genie conversation in one page.

auto measures the chat's own element rather than the viewport, so a chat embedded in a split view or side panel switches to tabs on the space it actually has instead of waiting for the window to shrink.

Use the headless driver

import { ChatView, useMastraChat } from "@dbx-tools/ui-mastra/react";

export function CustomChat() {
  const chat = useMastraChat({
    agentId: "analyst",
    showModelPicker: true,
    threadPlacement: "left",
  });

  return <ChatView {...chat} className="h-full" />;
}

Use useMastraChat() when you want package transport behavior with your own layout. The hook owns streaming, aborts, history paging, thread selection, model overrides, suggestions, exports, approvals, and feedback state.

Pass typed application context

requestContext accepts a typed plain record, Mastra RequestContext<T>, or a per-turn resolver. The driver snapshots it when a message is submitted and keeps that snapshot with queued steers, regeneration, and approval continuation.

import { RequestContext } from "@mastra/client-js";

type StoreContext = { storeId: string; route: string };

const chat = useMastraChat<StoreContext>({
  requestContext: () =>
    new RequestContext<StoreContext>([
      ["storeId", selectedStore.id],
      ["route", location.pathname],
    ]),
});

On the server, declare the same contract with Mastra's native requestContextSchema on createAgent<StoreContext>(). Application context cannot override the authenticated memory resource, thread, user, scopes, model, or trace fields stamped by AppKit-Mastra. Direct Genie chat forwards the same native context as reference data for its one Agent Mode user message.

Build a controlled chat surface

import { ChatView, type ChatViewProps } from "@dbx-tools/ui-mastra/react";

export function ReviewChat(props: ChatViewProps) {
  return <ChatView {...props} className="h-[640px]" />;
}

ChatView is presentational. It renders the header, model picker, conversation sidebar, transcript, tool progress, approval cards, suggestions, export controls, feedback controls, and composer from props. Use it when your app already has a transport or needs to combine Mastra messages with another state model. Set showComposer={false} when a parent surface owns one shared input, such as a side-by-side model comparison.

MastraChat shows a spinner in the model control while its live default model is being resolved. The picker groups endpoints into model-family submenus. Its compact first popup shows only the current model, host-owned actions such as Genie Agent Mode, and a reasoning slider when the selected endpoint supports it. The current model opens the family picker, so the long endpoint catalog stays out of the primary control popup. Family and model menus use the same compact utility type as the composer actions, omit repeated headers, and omit the already-selected model. The model menu puts Default (<resolved model>) first, keeps Other last, and makes a one-model family directly selectable instead of opening another submenu.

Call plugin routes directly

import type { MastraClientConfig } from "@dbx-tools/shared-mastra";
import { MastraPluginClient } from "@dbx-tools/ui-mastra/react";

export async function listChatModels(clientConfig: MastraClientConfig) {
  const client = new MastraPluginClient(clientConfig);
  return client.models();
}

Each conversation thread runs independently: start a turn on one thread, switch to another and start a second, and both stream concurrently. Cancel one using its AbortSignal (or the driver's onCancelThread) without touching the others.

MastraPluginClient extends @mastra/client-js with the official AI SDK chatRoute transport and AppKit-Mastra additions. It uses credentials: "include" so session cookies travel with streaming and REST calls. The React hooks wrap native memory plus model catalogs, suggestions, chart fetches, and statement-data fetches. Use useMastraClient() to access the configured client inside React. useMastraModels(), useMastraDefaultModel(), useMastraSuggestions(), and useMastraThreads() expose route-specific state.

Handle approvals, embeds, and feedback

The UI understands the extra events produced by @dbx-tools/appkit-mastra:

  • Approval chunks become inline approval cards and continue the official chat route with Mastra's native { approved, reason? } resume data.
  • Native tool-call and tool-result payloads remain complete. Expanding a tool row reveals default-closed Request and Response viewers. Large values scroll without string or collection truncation.
  • Genie thinking events stream into the assistant's collapsed Thoughts panel. Intermediate answer attachments and query-result tables stay on tool progress, not in Thoughts. Other writer events remain attached to tool progress, including SQL, row counts, result summaries, and chart/data markers.
  • [chart:<id>] markers long-poll the chart cache and render ECharts inline.
  • [data:<id>] markers fetch statement rows and render a sortable table with column toggles and CSV export.
  • [visualization:<id>] markers fetch the same statement under OBO identity and render AppKit UI's native Genie Chart/Table component.
  • MLflow trace headers enable per-message feedback controls when the server reports feedback is available.

Configure chart themes

ECharts draws to a canvas and doesn't inherit CSS colors from its frame. The server planner provides the series palette and font stack. The browser resolves axis, grid, title, legend, and tooltip colors from AppKit semantic tokens at render time.

  • Theme tokens are read from the chart element, so a theme scoped to a chat subtree takes precedence over the document theme. Charts update when the document's .dark or .light class changes or when the operating-system color preference changes.
  • AppKit darkens its tokens under @media (prefers-color-scheme: dark) for any :root that is not explicitly .light. If your host renders its own light chrome, pin .light (or .dark) on :root rather than leaving AppKit on the operating-system preference.

PDF export uses a light chart theme on a white print document.

Export conversations

<MastraChat enableExport />

Exports support Markdown downloads and PDF (rendered through a hidden print iframe, so the browser's Save-as-PDF dialog opens with no popup tab). Chart and data markers are resolved during export: charts are rendered to inline SVG with ECharts' server renderer, and data markers become real tables. Expired or missing embeds are skipped so old transcripts still export cleanly.

Copy and download content

Copy and download controls appear in message bubbles, code blocks, conversation exports, and the data-grid CSV menu.

Copying works on hosts served over plain HTTP. An insecure context has no Clipboard API, so a bare navigator.clipboard.writeText silently does nothing on a local or intranet deployment. The package falls back to a hidden <textarea> plus document.execCommand("copy") and reports whether the copy actually succeeded. Downloads revoke their object URL after the temporary anchor fires, so a long session does not accumulate blobs.

Package exports

  • MastraChat: self-contained drop-in chat component.
  • MastraAssistant / useMastraAssistant: persistent application shell and external open/close/context controller.
  • useMastraChat: headless driver that returns ChatView props.
  • ChatView: controlled presentational chat shell.
  • MastraPluginClient: native @mastra/client-js memory/agent APIs plus AppKit-Mastra model, suggestion, feedback, and embed routes.
  • useMastraClient, useMastraConfig, useMastraModels, useMastraDefaultModel, useMastraSuggestions, useMastraThreads, useChartFetch, useStatementFetch: route/config hooks for controlled clients.
  • ThreadSidebar: controlled conversation list, dockable to either edge.
  • ThreadTabs / ThreadActions: conversation pills plus reusable New/History controls for the top strip or persistent assistant header.
  • ExportMenu: shared export format menu.
  • Types: ChatViewProps, MastraChatProps, UseMastraChatOptions, MastraAssistantProps, MastraRequestContextInput, ThreadPlacement, ThreadSummary, ToolEvent, ToolProgress, PendingApproval, FeedbackSubmission, and related UI contract types.

Server-side routes and event production live in @dbx-tools/appkit-mastra. Browser-safe route, marker, feedback, and wire schemas live in @dbx-tools/shared-mastra.

版本与发布记录

@dbx-tools/ui-mastra 共发布 354 个版本,首次发布于 2026/07/18;过去 12 个月发布了 354 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.206latest2026/11/11今天
0.9.2052026/11/111 天前
0.9.2042026/11/101 天前
0.9.2032026/11/074 天前
0.9.2022026/11/065 天前
0.9.2012026/11/056 天前

关于 @dbx-tools/ui-mastra 的常见问题

@dbx-tools/ui-mastra 是什么?

React chat UI for the AppKit-Mastra plugin

如何安装 @dbx-tools/ui-mastra?

在项目目录运行 npm install @dbx-tools/ui-mastra,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(~19.2.4)、react-dom(~19.2.4)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@dbx-tools/ui-mastra 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dbx-tools/ui-mastra 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@dbx-tools/ui-mastra 可以商用吗?

@dbx-tools/ui-mastra 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@dbx-tools/ui-mastra 的下载量有多少?

根据 npm 官方下载统计,@dbx-tools/ui-mastra 在 2026/10/12 – 2026/11/10 这 30 天内被下载 8,646 次,日均约 288 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dbx-tools/ui-mastra 还在维护吗?

最新版本 0.9.206 发布于 2026/11/11(今天);至今共发布 354 个版本,其中过去 12 个月发布了 354 个;首次发布于 2026/07/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。