@dbx-tools/ui-mastra 0.6.82 → 0.6.85

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/index.ts CHANGED
@@ -23,6 +23,7 @@ export * as supportDownload from "./src/support/download.ts";
23
23
  export * as supportExport from "./src/support/export.ts";
24
24
  export * as supportMastraClient from "./src/support/mastra-client.ts";
25
25
  export * as supportMastraStream from "./src/support/mastra-stream.ts";
26
+ export * as supportModelSelection from "./src/support/model-selection.ts";
26
27
  export * as supportShikiPlugin from "./src/support/shiki-plugin.ts";
27
28
  export * as supportThreadLabels from "./src/support/thread-labels.ts";
28
29
  export * as supportThreadSessions from "./src/support/thread-sessions.ts";
@@ -52,6 +53,7 @@ export type { ExportFormat, ExportBrand, EmbedResolver, ExportChatOptions } from
52
53
  export { MastraPluginClient, useMastraConfig, useMastraClient, useMastraModels, useMastraDefaultModel, useMastraSuggestions, useMastraThreads, useChartFetch, useStatementFetch } from "./src/support/mastra-client.ts";
53
54
  export type { ByIdFetchState } from "./src/support/mastra-client.ts";
54
55
  export type { MastraStreamChunk, MastraStreamResponse } from "./src/support/mastra-stream.ts";
56
+ export { modelStorageKey, readStoredModel, storeSelectedModel } from "./src/support/model-selection.ts";
55
57
  export { DEFAULT_THREAD_SESSION_KEY } from "./src/support/thread-sessions.ts";
56
58
  export type { ThreadSession } from "./src/support/thread-sessions.ts";
57
59
  export { THREAD_TAB_SEED_MAX } from "./src/support/thread-tabs.ts";
package/package.json CHANGED
@@ -24,12 +24,12 @@
24
24
  "typescript": "^5.9.3"
25
25
  },
26
26
  "dependencies": {
27
- "@dbx-tools/shared-core": "0.6.82",
28
- "@dbx-tools/shared-genie": "0.6.82",
29
- "@dbx-tools/shared-mastra": "0.6.82",
30
- "@dbx-tools/shared-model": "0.6.82",
31
- "@dbx-tools/ui-appkit": "0.6.82",
32
- "@dbx-tools/ui-branding": "0.6.82",
27
+ "@dbx-tools/shared-core": "0.6.85",
28
+ "@dbx-tools/shared-genie": "0.6.85",
29
+ "@dbx-tools/shared-mastra": "0.6.85",
30
+ "@dbx-tools/shared-model": "0.6.85",
31
+ "@dbx-tools/ui-appkit": "0.6.85",
32
+ "@dbx-tools/ui-branding": "0.6.85",
33
33
  "@mastra/client-js": "^1.28.0",
34
34
  "@tanstack/react-table": "^8.21.3",
35
35
  "ai": "^5.0.0",
@@ -47,7 +47,7 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "version": "0.6.82",
50
+ "version": "0.6.85",
51
51
  "type": "module",
52
52
  "exports": {
53
53
  "./react": "./src/react/index.ts",
@@ -24,6 +24,11 @@ import {
24
24
  useMastraThreads,
25
25
  } from "../support/mastra-client.ts";
26
26
  import type { MastraStreamResponse } from "../support/mastra-stream.ts";
27
+ import {
28
+ modelStorageKey,
29
+ readStoredModel,
30
+ storeSelectedModel,
31
+ } from "../support/model-selection.ts";
27
32
  import {
28
33
  createThreadSession,
29
34
  DEFAULT_THREAD_SESSION_KEY,
@@ -250,7 +255,6 @@ class StreamAborted extends Error {}
250
255
  export const useMastraChat = (
251
256
  options: UseMastraChatOptions = {},
252
257
  ): Omit<ChatViewProps, "className"> => {
253
- const [model, setModel] = useState("");
254
258
  // One client drives both the agent stream and the plugin's custom
255
259
  // routes (history / threads / models / suggestions / feedback /
256
260
  // embeds). Its identity is
@@ -258,6 +262,20 @@ export const useMastraChat = (
258
262
  // using it as a hook dep doesn't refire the initial-history fetch on
259
263
  // every parent render.
260
264
  const mastraClient = useMastraClient();
265
+ const agentId = options.agentId ?? mastraClient.defaultAgent;
266
+ const showModelPicker = Boolean(options.showModelPicker);
267
+ const modelKey = modelStorageKey(mastraClient.basePath, agentId);
268
+ const [model, setModel] = useState(() => (showModelPicker ? readStoredModel(modelKey) : ""));
269
+ const handleModelChange = useCallback(
270
+ (nextModel: string) => {
271
+ setModel(nextModel);
272
+ storeSelectedModel(modelKey, nextModel);
273
+ },
274
+ [modelKey],
275
+ );
276
+ useEffect(() => {
277
+ setModel(showModelPicker ? readStoredModel(modelKey) : "");
278
+ }, [modelKey, showModelPicker]);
261
279
  // The selected model rides each turn as a per-call override (see
262
280
  // `runStream`), never stored on the shared client - so two threads can
263
281
  // stream under different models without clobbering each other. Mirror it
@@ -265,7 +283,6 @@ export const useMastraChat = (
265
283
  // `model` to its dependency list.
266
284
  const modelRef = useRef(model);
267
285
  modelRef.current = model;
268
- const agentId = options.agentId ?? mastraClient.defaultAgent;
269
286
  // Built-in conversation management. When on, the chat always drives an
270
287
  // explicit client thread id (rather than leaning on the per-session
271
288
  // cookie) so it can reference, persist, and switch between the
@@ -359,7 +376,6 @@ export const useMastraChat = (
359
376
  );
360
377
  // Picker is opt-in: an omitted (or falsy) `showModelPicker` keeps it
361
378
  // hidden and skips the catalogue fetch entirely.
362
- const showModelPicker = Boolean(options.showModelPicker);
363
379
  const { models } = useMastraModels(showModelPicker);
364
380
  // The humanized name of the model the active agent falls back to when no
365
381
  // model is pinned, so the picker can label its default option. Fetched only
@@ -1453,7 +1469,7 @@ export const useMastraChat = (
1453
1469
  // it (ChatView shows it only when both are present).
1454
1470
  models: showModelPicker ? models : undefined,
1455
1471
  model,
1456
- onModelChange: showModelPicker ? setModel : undefined,
1472
+ onModelChange: showModelPicker ? handleModelChange : undefined,
1457
1473
  defaultModelName: showModelPicker ? (defaultModelName ?? undefined) : undefined,
1458
1474
  onLoadMore: loadOlderHistory,
1459
1475
  isLoadingMore,
@@ -0,0 +1,38 @@
1
+ type StorageLike = Pick<Storage, "getItem" | "setItem">;
2
+
3
+ /** Namespace the last-selected model by plugin mount and agent. */
4
+ export const modelStorageKey = (basePath: string, agentId: string): string =>
5
+ `dbx-mastra-model:${basePath}:${agentId}`;
6
+
7
+ const browserStorage = (): StorageLike | undefined => {
8
+ try {
9
+ return typeof window === "undefined" ? undefined : window.localStorage;
10
+ } catch {
11
+ return undefined;
12
+ }
13
+ };
14
+
15
+ /** Read the last-selected model, tolerating unavailable browser storage. */
16
+ export const readStoredModel = (
17
+ key: string,
18
+ storage: StorageLike | undefined = browserStorage(),
19
+ ): string => {
20
+ try {
21
+ return storage?.getItem(key) ?? "";
22
+ } catch {
23
+ return "";
24
+ }
25
+ };
26
+
27
+ /** Persist the selected model, including the empty server-default choice. */
28
+ export const storeSelectedModel = (
29
+ key: string,
30
+ model: string,
31
+ storage: StorageLike | undefined = browserStorage(),
32
+ ): void => {
33
+ try {
34
+ storage?.setItem(key, model);
35
+ } catch {
36
+ // Best-effort; the in-memory selection still works without persistence.
37
+ }
38
+ };