@dbx-tools/ui-mastra 0.9.153 → 0.9.157

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.
Files changed (38) hide show
  1. package/index.react.ts +61 -0
  2. package/index.support.ts +40 -0
  3. package/index.ts +1 -79
  4. package/package.json +21 -10
  5. package/src/react/_assistant-response-status.tsx +1 -1
  6. package/src/react/_external-link-dialog.tsx +1 -1
  7. package/src/react/_model-selector.tsx +5 -5
  8. package/src/react/bubbles.tsx +3 -3
  9. package/src/react/chat-composer.tsx +1 -1
  10. package/src/react/chat-feedback.ts +5 -5
  11. package/src/react/chat-history.ts +4 -4
  12. package/src/react/chat-stream.ts +4 -5
  13. package/src/react/chat-thread-layout.tsx +9 -2
  14. package/src/react/chat-transcript.tsx +3 -3
  15. package/src/react/data-grid.tsx +4 -4
  16. package/src/react/embed-slots.tsx +10 -6
  17. package/src/react/export-menu.tsx +1 -1
  18. package/src/react/feedback-controls.tsx +1 -1
  19. package/src/react/markdown.tsx +2 -4
  20. package/src/react/mastra-assistant.tsx +1 -1
  21. package/src/react/mastra-chat.tsx +17 -17
  22. package/src/react/suggestion-pills.tsx +1 -1
  23. package/src/react/suggestions.ts +1 -1
  24. package/src/react/thread-sidebar.tsx +1 -1
  25. package/src/react/thread-tabs.tsx +1 -1
  26. package/src/react/tool-pill.tsx +7 -9
  27. package/src/react/types.ts +1 -3
  28. package/src/react/use-chat-thread-query.ts +27 -0
  29. package/src/support/chart-option.ts +2 -2
  30. package/src/support/chart-theme.ts +2 -2
  31. package/src/support/export.ts +10 -13
  32. package/src/support/genie-client.ts +22 -13
  33. package/src/support/mastra-client.ts +39 -32
  34. package/src/support/thread-sessions.ts +0 -2
  35. package/src/support/thread-tabs.ts +12 -2
  36. package/src/support/tool-events.ts +1 -1
  37. package/src/react/index.ts +0 -72
  38. package/src/support/index.ts +0 -32
@@ -1,7 +1,7 @@
1
- import { errorUtils, hash, log } from "@dbx-tools/shared-core";
2
- import { isStaleMastraResumeError } from "@dbx-tools/shared-mastra/resume";
1
+ import { getAuthStatus } from "@dbx-tools/shared-auth";
2
+ import { hash, log, toError } from "@dbx-tools/shared-core";
3
+ import { isStaleMastraResumeError } from "@dbx-tools/shared-mastra";
3
4
  import type { ReasoningEffort } from "@dbx-tools/shared-model";
4
- import { getAuthStatus } from "@dbx-tools/ui/auth/react";
5
5
  import { useBrand } from "@dbx-tools/ui/branding/react";
6
6
  import type { RequestContext } from "@mastra/client-js";
7
7
  import type { FileUIPart, UIMessage } from "ai";
@@ -660,7 +660,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
660
660
  }
661
661
  logger.warn("chat stream disconnected; reconnecting to background run", {
662
662
  runId,
663
- error: errorUtils.toError(initialError),
663
+ error: toError(initialError),
664
664
  });
665
665
  const messagesBeforeReplay = getSession(threadId).messages;
666
666
  writeMessages(
@@ -705,7 +705,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
705
705
  if (getSession(threadId).runToken !== token) return;
706
706
  if (isStaleMastraResumeError(caught)) {
707
707
  logger.warn("ignored stale mastra resume", {
708
- error: errorUtils.toError(caught),
708
+ error: toError(caught),
709
709
  });
710
710
  updateSession(threadId, (session) => {
711
711
  if (session.runToken !== token) return session;
@@ -725,11 +725,11 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
725
725
  return;
726
726
  }
727
727
  logger.error("stream error", {
728
- error: errorUtils.toError(caught),
728
+ error: toError(caught),
729
729
  });
730
730
  updateSession(threadId, (session) => ({
731
731
  ...session,
732
- error: errorUtils.toError(caught),
732
+ error: toError(caught),
733
733
  status: "error",
734
734
  abortController: session.abortController === controller ? null : session.abortController,
735
735
  runId: runIdRef.current,
@@ -905,7 +905,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
905
905
  .catch((error: unknown) => {
906
906
  logger.warn("failed to abort background run", {
907
907
  runId: current.runId,
908
- error: errorUtils.toError(error),
908
+ error: toError(error),
909
909
  });
910
910
  });
911
911
  }
@@ -948,7 +948,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
948
948
  .catch((error: unknown) => {
949
949
  logger.warn("failed to observe interrupted background run", {
950
950
  runId,
951
- error: errorUtils.toError(error),
951
+ error: toError(error),
952
952
  });
953
953
  })
954
954
  : undefined;
@@ -962,7 +962,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
962
962
  .catch((error: unknown) => {
963
963
  logger.warn("failed to abort interrupted background run", {
964
964
  runId,
965
- error: errorUtils.toError(error),
965
+ error: toError(error),
966
966
  });
967
967
  })
968
968
  : undefined;
@@ -1105,7 +1105,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1105
1105
  logger.info("history cleared", { threadId });
1106
1106
  } catch (error) {
1107
1107
  logger.error("history clear error", {
1108
- error: errorUtils.toError(error),
1108
+ error: toError(error),
1109
1109
  });
1110
1110
  }
1111
1111
  resetSession(threadId, true);
@@ -1164,7 +1164,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1164
1164
  } catch (error) {
1165
1165
  logger.error("thread delete error", {
1166
1166
  threadId,
1167
- error: errorUtils.toError(error),
1167
+ error: toError(error),
1168
1168
  });
1169
1169
  setRemovedThreadIds((prev) => {
1170
1170
  if (!prev.has(threadId)) return prev;
@@ -1207,7 +1207,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1207
1207
  } catch (error) {
1208
1208
  logger.error("thread rename error", {
1209
1209
  threadId,
1210
- error: errorUtils.toError(error),
1210
+ error: toError(error),
1211
1211
  });
1212
1212
  setRenamedThreads((prev) => {
1213
1213
  if (!(threadId in prev)) return prev;
@@ -1250,11 +1250,11 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1250
1250
  .catch((error: unknown) => {
1251
1251
  logger.error("regenerate cleanup error", {
1252
1252
  threadId,
1253
- error: errorUtils.toError(error),
1253
+ error: toError(error),
1254
1254
  });
1255
1255
  updateSession(threadId, (session) => ({
1256
1256
  ...session,
1257
- error: errorUtils.toError(error),
1257
+ error: toError(error),
1258
1258
  status: "error",
1259
1259
  }));
1260
1260
  });
@@ -1321,7 +1321,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1321
1321
  } catch (error) {
1322
1322
  logger.error("conversation export error", {
1323
1323
  format,
1324
- error: errorUtils.toError(error),
1324
+ error: toError(error),
1325
1325
  });
1326
1326
  }
1327
1327
  },
@@ -1343,7 +1343,7 @@ export const useMastraChat = <TValues extends Record<string, unknown> = Record<s
1343
1343
  } catch (error) {
1344
1344
  logger.error("message export error", {
1345
1345
  format,
1346
- error: errorUtils.toError(error),
1346
+ error: toError(error),
1347
1347
  });
1348
1348
  }
1349
1349
  },
@@ -1,4 +1,4 @@
1
- import { Button, cn } from "@dbx-tools/ui/react";
1
+ import { Button, cn } from "@databricks/appkit-ui/react";
2
2
 
3
3
  // Shared rendering for suggested questions. Both the initial starter
4
4
  // suggestions (above the composer when the transcript is empty) and
@@ -2,7 +2,7 @@ import {
2
2
  FOLLOW_UP_SUGGESTIONS_PART_TYPE,
3
3
  FollowUpSuggestionsPartDataSchema,
4
4
  type FollowUpSuggestionMode,
5
- } from "@dbx-tools/shared-mastra/wire";
5
+ } from "@dbx-tools/shared-mastra";
6
6
  import type { UIMessage } from "ai";
7
7
  import type { ToolEvent, ToolProgress } from "./types.ts";
8
8
 
@@ -6,7 +6,7 @@ import {
6
6
  TooltipContent,
7
7
  TooltipTrigger,
8
8
  cn,
9
- } from "@dbx-tools/ui/react";
9
+ } from "@databricks/appkit-ui/react";
10
10
  import {
11
11
  Loader2Icon,
12
12
  MessageSquarePlusIcon,
@@ -7,7 +7,7 @@ import {
7
7
  TooltipContent,
8
8
  TooltipTrigger,
9
9
  cn,
10
- } from "@dbx-tools/ui/react";
10
+ } from "@databricks/appkit-ui/react";
11
11
  import { HistoryIcon, Loader2Icon, PlusIcon, XIcon } from "lucide-react";
12
12
  import { type ReactNode, useEffect, useRef, useState } from "react";
13
13
  import { ThreadSidebar, type ThreadSidebarProps } from "./thread-sidebar.tsx";
@@ -1,15 +1,13 @@
1
- import { json, stringUtils } from "@dbx-tools/shared-core";
2
- import { genieModel } from "@dbx-tools/shared-genie";
3
1
  import {
4
2
  Collapsible,
5
3
  CollapsibleContent,
6
4
  CollapsibleTrigger,
7
- detectCodeLanguage,
8
- JsonBlock,
9
- RecordPreview,
10
5
  Spinner,
11
6
  cn,
12
- } from "@dbx-tools/ui/react";
7
+ } from "@databricks/appkit-ui/react";
8
+ import { parse, toLabel, capitalize } from "@dbx-tools/shared-core";
9
+ import { humanizeStatus } from "@dbx-tools/shared-genie";
10
+ import { detectCodeLanguage, JsonBlock, RecordPreview } from "@dbx-tools/ui/react";
13
11
  import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react";
14
12
  import { SourceBlock, ToolMarkdown } from "./markdown.tsx";
15
13
  import type { ToolEvent, ToolProgress } from "./types.ts";
@@ -49,7 +47,7 @@ export const humanizeToolName = (toolName: string): string => {
49
47
  const label = toolName.startsWith(MASTRA_WORKSPACE_TOOL_PREFIX)
50
48
  ? toolName.slice(MASTRA_WORKSPACE_TOOL_PREFIX.length)
51
49
  : toolName;
52
- return stringUtils.toLabel(label);
50
+ return toLabel(label);
53
51
  };
54
52
 
55
53
  /**
@@ -69,7 +67,7 @@ const runningLabelFor = (event: ToolEvent): string => {
69
67
  .reverse()
70
68
  .find((p): p is Extract<ToolProgress, { type: "status" }> => p.type === "status");
71
69
  return latest
72
- ? stringUtils.capitalize(genieModel.humanizeStatus(latest.status))
70
+ ? capitalize(humanizeStatus(latest.status))
73
71
  : `Calling ${humanizeToolName(event.toolName)}`;
74
72
  };
75
73
 
@@ -393,7 +391,7 @@ export function structuredToolPayload(value: unknown): unknown | undefined {
393
391
  if (typeof value !== "string") return undefined;
394
392
  const trimmed = value.trim();
395
393
  if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return undefined;
396
- const parsed = json.parse(trimmed);
394
+ const parsed = parse(trimmed);
397
395
  return typeof parsed === "object" && parsed !== null ? parsed : undefined;
398
396
  }
399
397
 
@@ -1,11 +1,9 @@
1
- import type { FollowUpSuggestionMode, ToolProgressEvent } from "@dbx-tools/shared-mastra/wire";
1
+ import type { FollowUpSuggestionMode, ToolProgressEvent } from "@dbx-tools/shared-mastra";
2
2
  import type { ReasoningEffort, ServingEndpointSummary } from "@dbx-tools/shared-model";
3
3
  import type { FileUIPart, UIMessage } from "ai";
4
4
  import type { ReactNode } from "react";
5
5
  import type { ExportFormat } from "../support/export.ts";
6
6
 
7
- export type { ExportFormat } from "../support/export.ts";
8
-
9
7
  // Public types for the chat UI: the controlled `ChatView` props plus
10
8
  // the supporting tool-event / approval shapes a host transport feeds
11
9
  // it. Kept dependency-free of the components so both the presentational
@@ -0,0 +1,27 @@
1
+ import { useCallback } from "react";
2
+ import { useSearchParams } from "react-router-dom";
3
+ import type { ThreadIdChangeReason } from "./mastra-chat.tsx";
4
+
5
+ const DEFAULT_THREAD_PARAMETER = "thread";
6
+
7
+ /** Bind Mastra's active thread to one URL search parameter. */
8
+ export function useChatThreadQuery(parameter = DEFAULT_THREAD_PARAMETER) {
9
+ const [searchParams, setSearchParams] = useSearchParams();
10
+ const threadId = searchParams.get(parameter)?.trim() || undefined;
11
+ const onThreadIdChange = useCallback(
12
+ (nextThreadId: string, reason: ThreadIdChangeReason) => {
13
+ setSearchParams(
14
+ (current) => {
15
+ if (current.get(parameter) === nextThreadId) return current;
16
+ const next = new URLSearchParams(current);
17
+ next.set(parameter, nextThreadId);
18
+ return next;
19
+ },
20
+ { replace: reason === "hydrate" || reason === "missing" || reason === "delete" },
21
+ );
22
+ },
23
+ [parameter, setSearchParams],
24
+ );
25
+
26
+ return { threadId, onThreadIdChange };
27
+ }
@@ -27,7 +27,7 @@
27
27
  *
28
28
  * @module
29
29
  */
30
- import { object } from "@dbx-tools/shared-core";
30
+ import { isRecord } from "@dbx-tools/shared-core";
31
31
  import type { ChartChrome } from "./chart-theme.ts";
32
32
 
33
33
  /** Compact SI formatter shared across every value-axis tick. */
@@ -52,7 +52,7 @@ function compactAxisLabel(value: number): string {
52
52
  /** A permissive record view of an option node we patch field-by-field. */
53
53
  type Obj = Record<string, unknown>;
54
54
 
55
- const isObj = object.isRecord;
55
+ const isObj = isRecord;
56
56
 
57
57
  /** True when `title` (object or array) carries any non-empty `text`. */
58
58
  function hasTitleText(title: unknown): boolean {
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * @module
22
22
  */
23
- import { object } from "@dbx-tools/shared-core";
23
+ import { deepEqual } from "@dbx-tools/shared-core";
24
24
  import { type RefObject, useEffect, useState } from "react";
25
25
 
26
26
  /**
@@ -122,7 +122,7 @@ export function useChartChrome(ref: RefObject<Element | null>): ChartChrome | un
122
122
  useEffect(() => {
123
123
  const read = () => {
124
124
  const next = resolveChartChrome(ref.current);
125
- setChrome((prev) => (object.deepEqual(prev, next) ? prev : next));
125
+ setChrome((prev) => (deepEqual(prev, next) ? prev : next));
126
126
  };
127
127
  read();
128
128
  const observer = new MutationObserver(read);
@@ -23,8 +23,8 @@
23
23
  * @module
24
24
  */
25
25
 
26
- import { stringUtils } from "@dbx-tools/shared-core";
27
- import { markers, type Chart, type StatementData } from "@dbx-tools/shared-mastra";
26
+ import { capitalize, toLabel, toSlugWithOptions, escapeHtml } from "@dbx-tools/shared-core";
27
+ import { type Chart, type StatementData, parseMarkers, isUuid } from "@dbx-tools/shared-mastra";
28
28
  import type { UIMessage } from "ai";
29
29
  import type { EChartsCoreOption } from "echarts";
30
30
  import { normalizeChartOption } from "./chart-option.ts";
@@ -199,15 +199,15 @@ type Segment =
199
199
  function splitSegments(text: string): Segment[] {
200
200
  const segments: Segment[] = [];
201
201
  let last = 0;
202
- for (const marker of markers.parseMarkers(text)) {
202
+ for (const marker of parseMarkers(text)) {
203
203
  if (marker.start > last) {
204
204
  segments.push({ kind: "text", text: text.slice(last, marker.start) });
205
205
  }
206
- if (markers.isUuid(marker.id) && marker.type === "chart") {
206
+ if (isUuid(marker.id) && marker.type === "chart") {
207
207
  segments.push({ kind: "chart", id: marker.id });
208
- } else if (markers.isUuid(marker.id) && marker.type === "data") {
208
+ } else if (isUuid(marker.id) && marker.type === "data") {
209
209
  segments.push({ kind: "data", id: marker.id });
210
- } else if (markers.isUuid(marker.id) && marker.type === "visualization") {
210
+ } else if (isUuid(marker.id) && marker.type === "visualization") {
211
211
  segments.push({ kind: "visualization", id: marker.id });
212
212
  }
213
213
  last = marker.end;
@@ -232,7 +232,7 @@ export function messageText(message: UIMessage): string {
232
232
  function roleLabel(role: UIMessage["role"], userLabel: string): string {
233
233
  if (role === "user") return userLabel;
234
234
  if (role === "assistant") return "Assistant";
235
- return stringUtils.capitalize(role);
235
+ return capitalize(role);
236
236
  }
237
237
 
238
238
  /* --------------------------------- HTML ---------------------------------- */
@@ -345,7 +345,7 @@ async function dataTableHtml(
345
345
  ): Promise<string | null> {
346
346
  const data = await safeStatement(resolver, id, visualization);
347
347
  if (!data || data.rows.length === 0) return null;
348
- const head = data.columns.map((c) => `<th>${escapeHtml(stringUtils.toLabel(c))}</th>`).join("");
348
+ const head = data.columns.map((c) => `<th>${escapeHtml(toLabel(c))}</th>`).join("");
349
349
  const body = data.rows
350
350
  .map(
351
351
  (row) =>
@@ -417,7 +417,7 @@ async function dataTableMarkdown(
417
417
  ): Promise<string | null> {
418
418
  const data = await safeStatement(resolver, id, visualization);
419
419
  if (!data || data.rows.length === 0) return null;
420
- const header = `| ${data.columns.map((c) => mdCell(stringUtils.toLabel(c))).join(" | ")} |`;
420
+ const header = `| ${data.columns.map((c) => mdCell(toLabel(c))).join(" | ")} |`;
421
421
  const sep = `| ${data.columns.map(() => "---").join(" | ")} |`;
422
422
  const rows = data.rows.map(
423
423
  (row) => `| ${data.columns.map((c) => mdCell(cellText(row[c]))).join(" | ")} |`,
@@ -462,12 +462,9 @@ function mdCell(value: string): string {
462
462
  return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
463
463
  }
464
464
 
465
- /** Escape HTML-significant characters (from the shared string utils). */
466
- const escapeHtml = stringUtils.escapeHtml;
467
-
468
465
  /** Turn a title into a safe, lowercase filename stem. */
469
466
  function slugify(value: string): string {
470
- return stringUtils.toSlugWithOptions({ maxLength: 60 }, value) || "conversation";
467
+ return toSlugWithOptions({ maxLength: 60 }, value) || "conversation";
471
468
  }
472
469
 
473
470
  /**
@@ -1,4 +1,13 @@
1
- import { routes, wire, type MastraClientConfig } from "@dbx-tools/shared-mastra";
1
+ import {
2
+ type MastraClientConfig,
3
+ genieRoutePath,
4
+ MASTRA_ROUTES,
5
+ GENIE_CONVERSATION_PART_TYPE,
6
+ GenieConversationPartDataSchema,
7
+ MastraSuggestionsResponseSchema,
8
+ GenieThreadsResponseSchema,
9
+ GenieThreadMessagesResponseSchema,
10
+ } from "@dbx-tools/shared-mastra";
2
11
  import type {
3
12
  ListAgentSuspendedRunsResponse,
4
13
  ListMemoryThreadMessagesResponse,
@@ -44,7 +53,7 @@ export class GenieChatClient extends MastraPluginClient {
44
53
  }
45
54
 
46
55
  #url(...parts: string[]): string {
47
- return `${this.basePath}${routes.genieRoutePath(this.alias, ...parts)}`;
56
+ return `${this.basePath}${genieRoutePath(this.alias, ...parts)}`;
48
57
  }
49
58
 
50
59
  async #delete(url: string, signal?: AbortSignal): Promise<void> {
@@ -72,7 +81,7 @@ export class GenieChatClient extends MastraPluginClient {
72
81
  const conversationId =
73
82
  params.threadId && this.#conversations.has(params.threadId) ? params.threadId : undefined;
74
83
  const response = await this.uiStream({
75
- path: this.#url(routes.MASTRA_ROUTES.chat),
84
+ path: this.#url(MASTRA_ROUTES.chat),
76
85
  chatId: params.threadId ?? params.runId,
77
86
  messages: userMessage ? [userMessage] : [],
78
87
  body: {
@@ -87,8 +96,8 @@ export class GenieChatClient extends MastraPluginClient {
87
96
  const stream = response.stream.pipeThrough(
88
97
  new TransformStream<UIMessageChunk, UIMessageChunk>({
89
98
  transform: (chunk, controller) => {
90
- if (chunk.type === wire.GENIE_CONVERSATION_PART_TYPE) {
91
- const data = wire.GenieConversationPartDataSchema.safeParse(chunk.data);
99
+ if (chunk.type === GENIE_CONVERSATION_PART_TYPE) {
100
+ const data = GenieConversationPartDataSchema.safeParse(chunk.data);
92
101
  if (data.success) {
93
102
  resolved = data.data.conversationId;
94
103
  this.#conversations.add(resolved);
@@ -122,8 +131,8 @@ export class GenieChatClient extends MastraPluginClient {
122
131
  /** Starter questions for this client's Genie space. */
123
132
  override async suggestions(_agentId?: string, signal?: AbortSignal): Promise<string[]> {
124
133
  const payload = await this.getJson(
125
- this.#url(routes.MASTRA_ROUTES.suggestions),
126
- wire.MastraSuggestionsResponseSchema,
134
+ this.#url(MASTRA_ROUTES.suggestions),
135
+ MastraSuggestionsResponseSchema,
127
136
  signal,
128
137
  );
129
138
  return payload.questions;
@@ -134,8 +143,8 @@ export class GenieChatClient extends MastraPluginClient {
134
143
  options: { signal?: AbortSignal } = {},
135
144
  ): Promise<ListMemoryThreadsResponse> {
136
145
  const payload = await this.getJson(
137
- this.#url(routes.MASTRA_ROUTES.threads),
138
- wire.GenieThreadsResponseSchema,
146
+ this.#url(MASTRA_ROUTES.threads),
147
+ GenieThreadsResponseSchema,
139
148
  options.signal,
140
149
  );
141
150
  for (const thread of payload.threads) this.#conversations.add(thread.id);
@@ -169,8 +178,8 @@ export class GenieChatClient extends MastraPluginClient {
169
178
  let messages: UIMessage[] = [];
170
179
  if (page === 0) {
171
180
  const payload = await this.getJson(
172
- this.#url(routes.MASTRA_ROUTES.threads, options.threadId, routes.MASTRA_ROUTES.messages),
173
- wire.GenieThreadMessagesResponseSchema,
181
+ this.#url(MASTRA_ROUTES.threads, options.threadId, MASTRA_ROUTES.messages),
182
+ GenieThreadMessagesResponseSchema,
174
183
  options.signal,
175
184
  );
176
185
  messages = await validateUIMessages({ messages: payload.messages });
@@ -195,7 +204,7 @@ export class GenieChatClient extends MastraPluginClient {
195
204
  options: { signal?: AbortSignal } = {},
196
205
  ): Promise<void> {
197
206
  if (!this.#conversations.has(threadId)) return;
198
- await this.#delete(this.#url(routes.MASTRA_ROUTES.threads, threadId), options.signal);
207
+ await this.#delete(this.#url(MASTRA_ROUTES.threads, threadId), options.signal);
199
208
  this.#conversations.delete(threadId);
200
209
  }
201
210
 
@@ -224,7 +233,7 @@ export class GenieChatClient extends MastraPluginClient {
224
233
  );
225
234
  for (const genieId of genieIds) {
226
235
  await this.#delete(
227
- this.#url(routes.MASTRA_ROUTES.threads, threadId, routes.MASTRA_ROUTES.messages, genieId),
236
+ this.#url(MASTRA_ROUTES.threads, threadId, MASTRA_ROUTES.messages, genieId),
228
237
  options.signal,
229
238
  );
230
239
  }
@@ -1,10 +1,6 @@
1
- import { errorUtils } from "@dbx-tools/shared-core";
1
+ import { usePluginClientConfig } from "@databricks/appkit-ui/react";
2
+ import { toError } from "@dbx-tools/shared-core";
2
3
  import {
3
- feedback,
4
- override,
5
- routes,
6
- thread,
7
- wire,
8
4
  type Chart,
9
5
  type DefaultModelResponse,
10
6
  type MastraClientConfig,
@@ -12,9 +8,20 @@ import {
12
8
  type MastraFeedbackResponse,
13
9
  type MastraMlflowExperimentResponse,
14
10
  type StatementData,
11
+ type FeedbackMode,
12
+ MastraFeedbackResponseSchema,
13
+ MastraMlflowExperimentResponseSchema,
14
+ MODEL_OVERRIDE_HEADER,
15
+ MASTRA_ROUTES,
16
+ THREAD_ID_HEADER,
17
+ MastraRunAbortResponseSchema,
18
+ ServingEndpointsResponseSchema,
19
+ DefaultModelResponseSchema,
20
+ MastraSuggestionsResponseSchema,
21
+ ChartSchema,
22
+ StatementDataSchema,
15
23
  } from "@dbx-tools/shared-mastra";
16
24
  import type { ReasoningEffort, ServingEndpointSummary } from "@dbx-tools/shared-model";
17
- import { usePluginClientConfig } from "@dbx-tools/ui/react";
18
25
  import {
19
26
  MastraClient,
20
27
  type ListAgentSuspendedRunsResponse,
@@ -80,7 +87,7 @@ export class MastraPluginClient extends MastraClient {
80
87
  /** Registered agent ids, surfaced for pickers. */
81
88
  readonly agents: readonly string[];
82
89
  /** Resolved feedback destination published by the server. */
83
- readonly feedbackMode: feedback.FeedbackMode;
90
+ readonly feedbackMode: FeedbackMode;
84
91
  /**
85
92
  * Whether the agents run their Databricks calls as the app service principal
86
93
  * rather than on-behalf-of the signed-in user. When `true` the chat works for
@@ -131,8 +138,8 @@ export class MastraPluginClient extends MastraClient {
131
138
  */
132
139
  #routingHeaders(routing: { threadId?: string; model?: string }): Record<string, string> {
133
140
  const headers: Record<string, string> = {};
134
- if (routing.threadId) headers[thread.THREAD_ID_HEADER] = routing.threadId;
135
- if (routing.model) headers[override.MODEL_OVERRIDE_HEADER] = routing.model;
141
+ if (routing.threadId) headers[THREAD_ID_HEADER] = routing.threadId;
142
+ if (routing.model) headers[MODEL_OVERRIDE_HEADER] = routing.model;
136
143
  return headers;
137
144
  }
138
145
 
@@ -232,7 +239,7 @@ export class MastraPluginClient extends MastraClient {
232
239
  signal?: AbortSignal;
233
240
  }): Promise<MastraStreamResponse> {
234
241
  return this.uiStream({
235
- path: `${this.basePath}${routes.MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}`,
242
+ path: `${this.basePath}${MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}`,
236
243
  chatId: params.threadId ?? params.runId,
237
244
  messages: params.messages,
238
245
  body: {
@@ -256,7 +263,7 @@ export class MastraPluginClient extends MastraClient {
256
263
  signal?: AbortSignal;
257
264
  }): Promise<MastraStreamResponse> {
258
265
  return this.#uiReconnect({
259
- path: `${this.basePath}${routes.MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}${routes.MASTRA_ROUTES.runs}/${encodeURIComponent(params.runId)}`,
266
+ path: `${this.basePath}${MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}${MASTRA_ROUTES.runs}/${encodeURIComponent(params.runId)}`,
260
267
  chatId: params.runId,
261
268
  routing: params,
262
269
  signal: params.signal,
@@ -273,11 +280,11 @@ export class MastraPluginClient extends MastraClient {
273
280
  const origin = typeof window !== "undefined" ? window.location.origin : "http://localhost";
274
281
  const response = await this.#mutateJson(
275
282
  new URL(
276
- `${this.basePath}${routes.MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}${routes.MASTRA_ROUTES.runs}/${encodeURIComponent(params.runId)}${routes.MASTRA_ROUTES.abort}`,
283
+ `${this.basePath}${MASTRA_ROUTES.chat}/${encodeURIComponent(params.agentId)}${MASTRA_ROUTES.runs}/${encodeURIComponent(params.runId)}${MASTRA_ROUTES.abort}`,
277
284
  origin,
278
285
  ).toString(),
279
286
  "POST",
280
- wire.MastraRunAbortResponseSchema,
287
+ MastraRunAbortResponseSchema,
281
288
  {
282
289
  headers: this.#routingHeaders({ threadId: params.threadId }),
283
290
  signal: params.signal,
@@ -333,7 +340,7 @@ export class MastraPluginClient extends MastraClient {
333
340
  },
334
341
  ): Promise<MastraStreamResponse> {
335
342
  return this.uiStream({
336
- path: `${this.basePath}${routes.MASTRA_ROUTES.chat}/${encodeURIComponent(agentId)}`,
343
+ path: `${this.basePath}${MASTRA_ROUTES.chat}/${encodeURIComponent(agentId)}`,
337
344
  chatId: params.threadId ?? params.runId,
338
345
  messages: [],
339
346
  body: {
@@ -358,8 +365,8 @@ export class MastraPluginClient extends MastraClient {
358
365
  */
359
366
  async models(signal?: AbortSignal): Promise<ServingEndpointSummary[]> {
360
367
  const payload = await this.getJson(
361
- `${this.basePath}${routes.MASTRA_ROUTES.models}`,
362
- wire.ServingEndpointsResponseSchema,
368
+ `${this.basePath}${MASTRA_ROUTES.models}`,
369
+ ServingEndpointsResponseSchema,
363
370
  signal,
364
371
  );
365
372
  return payload.endpoints;
@@ -382,8 +389,8 @@ export class MastraPluginClient extends MastraClient {
382
389
  /** Fetch the complete resolved default-model descriptor for an agent. */
383
390
  async defaultModelDetails(agentId?: string, signal?: AbortSignal): Promise<DefaultModelResponse> {
384
391
  const payload = await this.getJson(
385
- this.#agentScoped(routes.MASTRA_ROUTES.defaultModel, agentId),
386
- wire.DefaultModelResponseSchema,
392
+ this.#agentScoped(MASTRA_ROUTES.defaultModel, agentId),
393
+ DefaultModelResponseSchema,
387
394
  signal,
388
395
  );
389
396
  return payload;
@@ -396,8 +403,8 @@ export class MastraPluginClient extends MastraClient {
396
403
  */
397
404
  async suggestions(agentId?: string, signal?: AbortSignal): Promise<string[]> {
398
405
  const payload = await this.getJson(
399
- this.#agentScoped(routes.MASTRA_ROUTES.suggestions, agentId),
400
- wire.MastraSuggestionsResponseSchema,
406
+ this.#agentScoped(MASTRA_ROUTES.suggestions, agentId),
407
+ MastraSuggestionsResponseSchema,
401
408
  signal,
402
409
  );
403
410
  return payload.questions;
@@ -512,9 +519,9 @@ export class MastraPluginClient extends MastraClient {
512
519
  */
513
520
  async feedback(input: MastraFeedbackRequest): Promise<MastraFeedbackResponse> {
514
521
  return this.#mutateJson(
515
- `${this.basePath}${routes.MASTRA_ROUTES.feedback}`,
522
+ `${this.basePath}${MASTRA_ROUTES.feedback}`,
516
523
  "POST",
517
- feedback.MastraFeedbackResponseSchema,
524
+ MastraFeedbackResponseSchema,
518
525
  { body: input },
519
526
  );
520
527
  }
@@ -526,8 +533,8 @@ export class MastraPluginClient extends MastraClient {
526
533
  */
527
534
  async mlflowExperiment(signal?: AbortSignal): Promise<MastraMlflowExperimentResponse> {
528
535
  return this.getJson(
529
- `${this.basePath}${routes.MASTRA_ROUTES.mlflowExperiment}`,
530
- feedback.MastraMlflowExperimentResponseSchema,
536
+ `${this.basePath}${MASTRA_ROUTES.mlflowExperiment}`,
537
+ MastraMlflowExperimentResponseSchema,
531
538
  signal,
532
539
  );
533
540
  }
@@ -540,7 +547,7 @@ export class MastraPluginClient extends MastraClient {
540
547
  * resolves to `undefined` so the slot renders nothing.
541
548
  */
542
549
  chart(id: string, signal?: AbortSignal): Promise<Chart | undefined> {
543
- return this.#embed("chart", id, wire.ChartSchema.parse, signal);
550
+ return this.#embed("chart", id, ChartSchema.parse, signal);
544
551
  }
545
552
 
546
553
  /**
@@ -550,12 +557,12 @@ export class MastraPluginClient extends MastraClient {
550
557
  * `undefined`.
551
558
  */
552
559
  statement(id: string, signal?: AbortSignal): Promise<StatementData | undefined> {
553
- return this.#embed("data", id, wire.StatementDataSchema.parse, signal);
560
+ return this.#embed("data", id, StatementDataSchema.parse, signal);
554
561
  }
555
562
 
556
563
  /** Resolve AppKit UI visualization data for a direct Genie statement. */
557
564
  visualization(id: string, signal?: AbortSignal): Promise<StatementData | undefined> {
558
- return this.#embed("visualization", id, wire.StatementDataSchema.parse, signal);
565
+ return this.#embed("visualization", id, StatementDataSchema.parse, signal);
559
566
  }
560
567
 
561
568
  /**
@@ -638,7 +645,7 @@ export class MastraPluginClient extends MastraClient {
638
645
  parse: (raw: unknown) => T,
639
646
  signal?: AbortSignal,
640
647
  ): Promise<T | undefined> {
641
- const url = `${this.basePath}${routes.MASTRA_ROUTES.embed}/${encodeURIComponent(
648
+ const url = `${this.basePath}${MASTRA_ROUTES.embed}/${encodeURIComponent(
642
649
  type,
643
650
  )}/${encodeURIComponent(id)}`;
644
651
  const init: RequestInit = { credentials: "include" };
@@ -792,7 +799,7 @@ export const useMastraModels = (
792
799
  })
793
800
  .catch((e: unknown) => {
794
801
  if (controller.signal.aborted) return;
795
- setError(errorUtils.toError(e));
802
+ setError(toError(e));
796
803
  })
797
804
  .finally(() => {
798
805
  if (!controller.signal.aborted) setLoading(false);
@@ -960,7 +967,7 @@ export const useMastraThreads = (
960
967
  })
961
968
  .catch((e: unknown) => {
962
969
  if (controller.signal.aborted || (e as { name?: string }).name === "AbortError") return;
963
- setError(errorUtils.toError(e));
970
+ setError(toError(e));
964
971
  setThreads([]);
965
972
  })
966
973
  .finally(() => {
@@ -1125,7 +1132,7 @@ function useByIdFetch<T>(
1125
1132
  })
1126
1133
  .catch((e: unknown) => {
1127
1134
  if (cancelled) return;
1128
- setError(errorUtils.toError(e));
1135
+ setError(toError(e));
1129
1136
  setLoading(false);
1130
1137
  });
1131
1138
 
@@ -2,8 +2,6 @@ import type { RequestContext } from "@mastra/client-js";
2
2
  import type { UIMessage } from "ai";
3
3
  import type { ChatStatus, MessageFeedback, PendingApproval, QueuedSteer } from "../react/types.ts";
4
4
 
5
- export type { QueuedSteer } from "../react/types.ts";
6
-
7
5
  /** A queued steer plus the application context captured when it was submitted. */
8
6
  export type SessionQueuedSteer = QueuedSteer & {
9
7
  requestContext?: RequestContext;