@mastra/react 1.12.0-alpha.9 → 1.12.0

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 (112) hide show
  1. package/dist/{accumulator-C8kIc450.js → accumulator-BfvVnXJr.js} +1 -2
  2. package/dist/{accumulator-C8kIc450.js.map → accumulator-BfvVnXJr.js.map} +1 -1
  3. package/dist/{accumulator-BQGsraqS.cjs → accumulator-CgLQ_3q3.cjs} +1 -2
  4. package/dist/{accumulator-BQGsraqS.cjs.map → accumulator-CgLQ_3q3.cjs.map} +1 -1
  5. package/dist/chat/index.cjs +1 -1
  6. package/dist/chat/index.js +1 -2
  7. package/dist/combine-by-ids-D_lp6Dvq.cjs.map +1 -1
  8. package/dist/experiments-B7vRMK5T.js +306 -0
  9. package/dist/experiments-B7vRMK5T.js.map +1 -0
  10. package/dist/experiments-CJw1N3FB.cjs +353 -0
  11. package/dist/experiments-CJw1N3FB.cjs.map +1 -0
  12. package/dist/hooks/agents/index.cjs +2 -2
  13. package/dist/hooks/agents/index.cjs.map +1 -1
  14. package/dist/hooks/agents/index.js +2 -2
  15. package/dist/hooks/agents/index.js.map +1 -1
  16. package/dist/hooks/auth/index.cjs +2 -2
  17. package/dist/hooks/auth/index.cjs.map +1 -1
  18. package/dist/hooks/auth/index.js +2 -2
  19. package/dist/hooks/auth/index.js.map +1 -1
  20. package/dist/hooks/capabilities/index.cjs +16 -1
  21. package/dist/hooks/capabilities/index.cjs.map +1 -1
  22. package/dist/hooks/capabilities/index.d.ts +1 -0
  23. package/dist/hooks/capabilities/index.d.ts.map +1 -1
  24. package/dist/hooks/capabilities/index.js +16 -2
  25. package/dist/hooks/capabilities/index.js.map +1 -1
  26. package/dist/hooks/capabilities/use-trace-query-delta-polling-available.d.ts +10 -0
  27. package/dist/hooks/capabilities/use-trace-query-delta-polling-available.d.ts.map +1 -0
  28. package/dist/hooks/configuration/index.cjs.map +1 -1
  29. package/dist/hooks/datasets/index.cjs +25 -1
  30. package/dist/hooks/datasets/index.cjs.map +1 -1
  31. package/dist/hooks/datasets/index.js +25 -2
  32. package/dist/hooks/datasets/index.js.map +1 -1
  33. package/dist/hooks/datasets/use-datasets.d.ts +7 -0
  34. package/dist/hooks/datasets/use-datasets.d.ts.map +1 -1
  35. package/dist/hooks/embedders/index.cjs.map +1 -1
  36. package/dist/hooks/experiments/index.cjs +9 -235
  37. package/dist/hooks/experiments/index.d.ts +1 -0
  38. package/dist/hooks/experiments/index.d.ts.map +1 -1
  39. package/dist/hooks/experiments/index.js +1 -229
  40. package/dist/hooks/experiments/usage-accumulator.d.ts +25 -0
  41. package/dist/hooks/experiments/usage-accumulator.d.ts.map +1 -0
  42. package/dist/hooks/experiments/use-experiment-item-usage.d.ts +2 -7
  43. package/dist/hooks/experiments/use-experiment-item-usage.d.ts.map +1 -1
  44. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts +19 -0
  45. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts.map +1 -0
  46. package/dist/hooks/feedback/index.cjs.map +1 -1
  47. package/dist/hooks/llm/index.cjs.map +1 -1
  48. package/dist/hooks/logs/index.cjs.map +1 -1
  49. package/dist/hooks/mcps/index.cjs.map +1 -1
  50. package/dist/hooks/memory/index.cjs +10 -10
  51. package/dist/hooks/memory/index.cjs.map +1 -1
  52. package/dist/hooks/memory/index.js +10 -10
  53. package/dist/hooks/memory/index.js.map +1 -1
  54. package/dist/hooks/metrics/index.cjs +13 -11
  55. package/dist/hooks/metrics/index.cjs.map +1 -1
  56. package/dist/hooks/metrics/index.js +13 -11
  57. package/dist/hooks/metrics/index.js.map +1 -1
  58. package/dist/hooks/processors/index.cjs.map +1 -1
  59. package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
  60. package/dist/hooks/query/index.cjs.map +1 -1
  61. package/dist/hooks/review/index.cjs +2 -2
  62. package/dist/hooks/review/index.cjs.map +1 -1
  63. package/dist/hooks/review/index.js +1 -1
  64. package/dist/hooks/schedules/index.cjs.map +1 -1
  65. package/dist/hooks/scores/index.cjs.map +1 -1
  66. package/dist/hooks/templates/index.cjs +20 -18
  67. package/dist/hooks/templates/index.cjs.map +1 -1
  68. package/dist/hooks/templates/index.js +20 -18
  69. package/dist/hooks/templates/index.js.map +1 -1
  70. package/dist/hooks/tool-providers/index.cjs +1 -1
  71. package/dist/hooks/tool-providers/index.cjs.map +1 -1
  72. package/dist/hooks/tool-providers/index.js +1 -1
  73. package/dist/hooks/tool-providers/index.js.map +1 -1
  74. package/dist/hooks/tools/index.cjs.map +1 -1
  75. package/dist/hooks/traces/index.cjs +185 -10
  76. package/dist/hooks/traces/index.cjs.map +1 -1
  77. package/dist/hooks/traces/index.js +182 -11
  78. package/dist/hooks/traces/index.js.map +1 -1
  79. package/dist/hooks/traces/use-trace-query.d.ts +50 -1
  80. package/dist/hooks/traces/use-trace-query.d.ts.map +1 -1
  81. package/dist/hooks/vectors/index.cjs.map +1 -1
  82. package/dist/hooks/voice/index.cjs.map +1 -1
  83. package/dist/hooks/workflows/index.cjs +1 -1
  84. package/dist/hooks/workflows/index.cjs.map +1 -1
  85. package/dist/hooks/workflows/index.js +1 -1
  86. package/dist/hooks/workspace/index.cjs +1 -1
  87. package/dist/hooks/workspace/index.cjs.map +1 -1
  88. package/dist/hooks/workspace/index.js +1 -1
  89. package/dist/hooks/workspace/index.js.map +1 -1
  90. package/dist/{hooks-CIutb3DO.cjs → hooks-B1i-oHae.cjs} +6 -4
  91. package/dist/hooks-B1i-oHae.cjs.map +1 -0
  92. package/dist/{hooks-FVbeHlov.js → hooks-CLfMO5cH.js} +6 -4
  93. package/dist/{hooks-FVbeHlov.js.map → hooks-CLfMO5cH.js.map} +1 -1
  94. package/dist/{hooks-_YevKidX.cjs → hooks-D8nOYPUd.cjs} +2 -2
  95. package/dist/hooks-D8nOYPUd.cjs.map +1 -0
  96. package/dist/{hooks-0L0RNfau.js → hooks-NaZLZreZ.js} +2 -2
  97. package/dist/{hooks-0L0RNfau.js.map → hooks-NaZLZreZ.js.map} +1 -1
  98. package/dist/index.cjs +3 -3
  99. package/dist/index.cjs.map +1 -1
  100. package/dist/index.js +3 -3
  101. package/dist/mastra-client-context-DzX3f0RF.cjs.map +1 -1
  102. package/dist/ui/index.cjs +4 -4
  103. package/dist/ui/index.cjs.map +1 -1
  104. package/dist/ui/index.js +3 -3
  105. package/dist/ui/index.js.map +1 -1
  106. package/dist/use-in-view-B6eJO9Zi.cjs.map +1 -1
  107. package/dist/voice-BOtUdMi8.cjs.map +1 -1
  108. package/package.json +5 -5
  109. package/dist/hooks/experiments/index.cjs.map +0 -1
  110. package/dist/hooks/experiments/index.js.map +0 -1
  111. package/dist/hooks-CIutb3DO.cjs.map +0 -1
  112. package/dist/hooks-_YevKidX.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { n as useMastraClient } from "../../mastra-client-context-Bx_g84YB.js";
2
2
  import { t as useInView } from "../../use-in-view-C9sYPGRm.js";
3
- import { t as getOrCreate } from "../../map-CDv4fbu4.js";
4
3
  import { n as is403ForbiddenError } from "../../query-utils-D1NgFnWU.js";
5
4
  import { t as getFeedbackRefetchInterval } from "../../feedback-refetch-interval-DLHzQoVV.js";
5
+ import { t as getOrCreate } from "../../map-CDv4fbu4.js";
6
6
  import { MastraClient, MastraClientError } from "@mastra/client-js";
7
7
  import { useEffect, useMemo, useRef, useState } from "react";
8
8
  import { keepPreviousData, queryOptions, skipToken, useInfiniteQuery, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/react-query";
@@ -18,7 +18,7 @@ import { EntityType } from "@mastra/core/observability";
18
18
  * through to the store's discovery refresh. Matching the server TTL keeps the
19
19
  * client from asking more often than the answer can change.
20
20
  */
21
- const DISCOVERY_STALE_TIME = 300 * 1e3;
21
+ const DISCOVERY_STALE_TIME = 3e5;
22
22
  //#endregion
23
23
  //#region src/hooks/traces/use-branch.ts
24
24
  /**
@@ -135,7 +135,7 @@ const useServiceNames = ({ queryOptions } = {}) => {
135
135
  };
136
136
  //#endregion
137
137
  //#region src/hooks/traces/use-span-detail.ts
138
- const IMMUTABLE_CACHE_TIME$1 = 1e3 * 60 * 60 * 24 * 30;
138
+ const IMMUTABLE_CACHE_TIME$1 = 2592e6;
139
139
  /**
140
140
  * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
141
141
  */
@@ -200,7 +200,7 @@ function useThreadHasOtherTraces({ threadId, queryOptions }) {
200
200
  }
201
201
  //#endregion
202
202
  //#region src/hooks/traces/use-trace-light-spans.ts
203
- const IMMUTABLE_CACHE_TIME = 1e3 * 60 * 60 * 24 * 30;
203
+ const IMMUTABLE_CACHE_TIME = 2592e6;
204
204
  /**
205
205
  * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
206
206
  */
@@ -319,6 +319,8 @@ function useTraceOrBranchSpans({ traceId, anchorSpanId, listMode, depth, queryOp
319
319
  //#endregion
320
320
  //#region src/hooks/traces/use-trace-query.ts
321
321
  const TRACE_QUERY_PER_PAGE = 25;
322
+ /** Max traces per delta request; the server caps `limit` at 100. */
323
+ const TRACE_QUERY_DELTA_LIMIT = 100;
322
324
  function getTraceQueryNextPageParam(lastPage) {
323
325
  return lastPage?.page.next ?? void 0;
324
326
  }
@@ -368,16 +370,101 @@ function selectLegacyTraceQueryTraces(data) {
368
370
  function getLegacyTraceQueryNextPageParam(lastPage) {
369
371
  return lastPage.pagination?.hasMore ? lastPage.pagination.page + 1 : void 0;
370
372
  }
373
+ /** Cache key of `useTraceQuery`'s trace-query list. Pass the same `query` and `limit` to share it. */
374
+ const traceQueryKey = (query, limit = 25) => [
375
+ "trace-query",
376
+ query,
377
+ limit
378
+ ];
379
+ function traceSortValue(trace, field) {
380
+ if (field === "timeToFirstChunkMs") return trace.timeToFirstChunkMs ?? null;
381
+ const value = trace[field];
382
+ return value == null ? null : Date.parse(value);
383
+ }
384
+ /** Mirrors the server's keyset order: empty values last in both directions, ties by ascending `traceId`. */
385
+ function compareTraces(orderBy) {
386
+ return (a, b) => {
387
+ const va = traceSortValue(a, orderBy.field);
388
+ const vb = traceSortValue(b, orderBy.field);
389
+ if (va !== vb) {
390
+ if (va === null) return 1;
391
+ if (vb === null) return -1;
392
+ return orderBy.direction === "asc" ? va - vb : vb - va;
393
+ }
394
+ return a.traceId < b.traceId ? -1 : a.traceId > b.traceId ? 1 : 0;
395
+ };
396
+ }
397
+ /**
398
+ * Merges delta-polled traces into the pages of a `useTraceQuery` list, without mutating `data`.
399
+ * A trace already on a page is replaced in place when its sort value is unchanged; otherwise it is
400
+ * removed and placed again like a new trace (sorting by `endedAt`, a running trace moves once it
401
+ * ends). A new trace goes into the first page whose last row sorts after it; when no loaded page does, it is
402
+ * appended to the last page if that is the end of the list, and skipped otherwise, since keyset
403
+ * pagination returns it once the user scrolls there. Page cursors are kept as they are, and `data`
404
+ * itself is returned when nothing changed.
405
+ */
406
+ function mergeTraceQueryDelta(data, traces, orderBy) {
407
+ if (traces.length === 0 || data.pages.length === 0) return data;
408
+ const incoming = new Map(traces.map((trace) => [trace.traceId, trace]));
409
+ const rows = data.pages.map((page) => page.traces);
410
+ const changed = /* @__PURE__ */ new Set();
411
+ const write = (pageIndex, next) => {
412
+ rows[pageIndex] = next;
413
+ changed.add(pageIndex);
414
+ };
415
+ const sortBy = orderBy?.[0] ?? {
416
+ field: "startedAt",
417
+ direction: "desc"
418
+ };
419
+ const compare = compareTraces(sortBy);
420
+ const replacedInPlace = /* @__PURE__ */ new Set();
421
+ rows.forEach((pageRows, pageIndex) => {
422
+ if (!pageRows.some((row) => incoming.has(row.traceId))) return;
423
+ const next = [];
424
+ for (const row of pageRows) {
425
+ const update = incoming.get(row.traceId);
426
+ if (!update) next.push(row);
427
+ else if (traceSortValue(update, sortBy.field) === traceSortValue(row, sortBy.field)) {
428
+ next.push(update);
429
+ replacedInPlace.add(row.traceId);
430
+ }
431
+ }
432
+ write(pageIndex, next);
433
+ });
434
+ for (const traceId of replacedInPlace) incoming.delete(traceId);
435
+ const lastIndex = rows.length - 1;
436
+ for (const trace of incoming.values()) {
437
+ let pageIndex = rows.findIndex((pageRows) => {
438
+ const last = pageRows[pageRows.length - 1];
439
+ return last !== void 0 && compare(trace, last) < 0;
440
+ });
441
+ if (pageIndex === -1) {
442
+ if (data.pages[lastIndex].page.next !== null) continue;
443
+ pageIndex = lastIndex;
444
+ }
445
+ const pageRows = rows[pageIndex];
446
+ const at = pageRows.findIndex((row) => compare(trace, row) < 0);
447
+ write(pageIndex, at === -1 ? [...pageRows, trace] : [
448
+ ...pageRows.slice(0, at),
449
+ trace,
450
+ ...pageRows.slice(at)
451
+ ]);
452
+ }
453
+ if (changed.size === 0) return data;
454
+ return {
455
+ ...data,
456
+ pages: data.pages.map((page, pageIndex) => changed.has(pageIndex) ? {
457
+ ...page,
458
+ traces: rows[pageIndex]
459
+ } : page)
460
+ };
461
+ }
371
462
  /** Queries traces with cursor pagination and viewport-driven loading. */
372
463
  function useTraceQuery({ query, limit = 25, enabled = true, withQueryTrace = true, legacyFilters, queryOptions }) {
373
464
  const client = useMastraClient();
374
465
  const { inView, setRef: setEndOfListElement } = useInView();
375
466
  const queryResult = useInfiniteQuery({
376
- queryKey: [
377
- "trace-query",
378
- query,
379
- limit
380
- ],
467
+ queryKey: traceQueryKey(query, limit),
381
468
  queryFn: query ? async ({ pageParam }) => {
382
469
  const response = await new MastraClient({
383
470
  ...client.options,
@@ -455,6 +542,90 @@ function useTraceQuery({ query, limit = 25, enabled = true, withQueryTrace = tru
455
542
  setEndOfListElement
456
543
  };
457
544
  }
545
+ function omitOrderBy({ orderBy: _orderBy, ...rest }) {
546
+ return rest;
547
+ }
548
+ /** Request timeouts and rate limits clear up on their own, unlike the other 4xx refusals. */
549
+ const TRANSIENT_CLIENT_ERROR_STATUSES = /* @__PURE__ */ new Set([408, 429]);
550
+ /** The server refused the request or does not support delta polling; polling again cannot change that. */
551
+ function isRejectedDeltaRequest(error) {
552
+ if (!(error instanceof MastraClientError) || TRANSIENT_CLIENT_ERROR_STATUSES.has(error.status)) return false;
553
+ return error.status >= 400 && error.status < 500 || error.status === 501;
554
+ }
555
+ const isCursorConflict = (error) => error instanceof MastraClientError && error.status === 409;
556
+ /**
557
+ * Polls `queryTraces({ mode: 'delta' })` and merges new or updated traces into the list of a
558
+ * `useTraceQuery` rendered with the same `query` and `limit`. The first request only establishes
559
+ * the server cursor; each later poll drains every batch since that cursor. A cursor conflict (409)
560
+ * starts over with a new cursor. A poll that returns while the list is loading a page, or before
561
+ * the list has loaded at all, keeps its cursor and asks again on the next poll.
562
+ *
563
+ * The cursor is keyed on the query without `orderBy` (delta polls cannot sort) and on `limit`, so
564
+ * re-sorting the list keeps polling from the same cursor, and lists with different page sizes each
565
+ * get their own cursor.
566
+ *
567
+ * Requires the `deltaPolling` capability (see `useTraceQueryDeltaPollingAvailable`). The list's
568
+ * `timeRange.to` must not move between polls, so a live list needs a `to` in the future.
569
+ *
570
+ * Known limitation: the cursor is established in parallel with the list's first page, so a trace
571
+ * that completes between the first page's read and the cursor can be missed until the list is
572
+ * refetched. Traces returned by both are merged by `traceId`.
573
+ */
574
+ function useTraceQueryLatest({ query, limit = 25, enabled = true, refetchInterval = false, queryOptions }) {
575
+ const client = useMastraClient();
576
+ const queryClient = useQueryClient();
577
+ const deltaQuery = query && omitOrderBy(query);
578
+ const queryKey = [
579
+ "trace-query-latest",
580
+ deltaQuery,
581
+ limit
582
+ ];
583
+ return useQuery({
584
+ queryKey,
585
+ queryFn: query && deltaQuery ? async () => {
586
+ const mastra = new MastraClient({
587
+ ...client.options,
588
+ retries: 0
589
+ });
590
+ const bootstrap = async () => {
591
+ return { deltaCursor: (await mastra.queryTraces({
592
+ ...deltaQuery,
593
+ mode: "delta"
594
+ })).deltaCursor };
595
+ };
596
+ const previous = queryClient.getQueryData(queryKey);
597
+ if (!previous) return bootstrap();
598
+ const traces = [];
599
+ let deltaCursor = previous.deltaCursor;
600
+ try {
601
+ for (let hasMore = true; hasMore;) {
602
+ const response = await mastra.queryTraces({
603
+ ...deltaQuery,
604
+ mode: "delta",
605
+ after: deltaCursor,
606
+ limit: 100
607
+ });
608
+ traces.push(...response.traces);
609
+ deltaCursor = response.deltaCursor;
610
+ hasMore = response.delta.hasMore;
611
+ }
612
+ } catch (error) {
613
+ if (isCursorConflict(error)) return bootstrap();
614
+ throw error;
615
+ }
616
+ const listKey = traceQueryKey(query, limit);
617
+ const listState = queryClient.getQueryState(listKey);
618
+ if (!listState?.data || listState.fetchStatus === "fetching") return previous;
619
+ queryClient.setQueryData(listKey, (data) => data ? mergeTraceQueryDelta(data, traces, query.orderBy) : data);
620
+ return { deltaCursor };
621
+ } : skipToken,
622
+ retry: false,
623
+ refetchInterval: (q) => isRejectedDeltaRequest(q.state.error) ? false : refetchInterval,
624
+ refetchIntervalInBackground: false,
625
+ enabled: enabled && !!query,
626
+ ...queryOptions
627
+ });
628
+ }
458
629
  //#endregion
459
630
  //#region src/hooks/traces/use-trace-usage.ts
460
631
  const INPUT_TOKEN_METRIC = "mastra_model_total_input_tokens";
@@ -551,7 +722,7 @@ const DEFAULT_POLLING_CONFIG = {
551
722
  deltaLimit: 100,
552
723
  pageModeRefetchIntervalMs: 1e4,
553
724
  page0StatusRefreshIntervalMs: 6e4,
554
- idleGuardThresholdMs: 15 * 6e4,
725
+ idleGuardThresholdMs: 9e5,
555
726
  minRefetchSpinMs: 400,
556
727
  deltaHighlightMs: 1e3
557
728
  };
@@ -1129,6 +1300,6 @@ function useTraceColumnPreferencesStorageKey() {
1129
1300
  return `mastra:traces:columns:${client.options.baseUrl || (typeof window === "undefined" ? "local" : window.location.origin || "local")}:${client.options.apiPrefix ?? "/api"}`;
1130
1301
  }
1131
1302
  //#endregion
1132
- export { DISCOVERY_STALE_TIME, ROOT_ENTITY_TYPES, TRACES_PER_PAGE, TRACE_QUERY_PER_PAGE, createTraceQueryValuesResolver, getLegacyTraceQueryNextPageParam, getTraceQueryNextPageParam, getTracesNextPageParam, lightSpanToTraceQueryTrace, mergeDeltaIntoPage0, refreshPage0Rows, selectLegacyTraceQueryTraces, selectTraceQueryTraces, selectUniqueTraces, shouldPinLightList, shouldResetAfterIdle, traceQueryFieldsQueryKey, traceSpansQueryOptions, useBranch, useCreateFeedback, useDeleteFeedback, useEntityNames, useEnvironments, useFetchTraceSpans, useServiceNames, useSpanDetail, useSpanFeedback, useTags, useThreadHasOtherTraces, useTraceColumnPreferencesStorageKey, useTraceFeedback, useTraceLightSpans, useTraceMetadataFilterFields, useTraceOrBranchSpans, useTraceQuery, useTraceSpans, useTraceSpansQueries, useTraceUsage, useTraces };
1303
+ export { DISCOVERY_STALE_TIME, ROOT_ENTITY_TYPES, TRACES_PER_PAGE, TRACE_QUERY_DELTA_LIMIT, TRACE_QUERY_PER_PAGE, createTraceQueryValuesResolver, getLegacyTraceQueryNextPageParam, getTraceQueryNextPageParam, getTracesNextPageParam, lightSpanToTraceQueryTrace, mergeDeltaIntoPage0, mergeTraceQueryDelta, refreshPage0Rows, selectLegacyTraceQueryTraces, selectTraceQueryTraces, selectUniqueTraces, shouldPinLightList, shouldResetAfterIdle, traceQueryFieldsQueryKey, traceQueryKey, traceSpansQueryOptions, useBranch, useCreateFeedback, useDeleteFeedback, useEntityNames, useEnvironments, useFetchTraceSpans, useServiceNames, useSpanDetail, useSpanFeedback, useTags, useThreadHasOtherTraces, useTraceColumnPreferencesStorageKey, useTraceFeedback, useTraceLightSpans, useTraceMetadataFilterFields, useTraceOrBranchSpans, useTraceQuery, useTraceQueryLatest, useTraceSpans, useTraceSpansQueries, useTraceUsage, useTraces };
1133
1304
 
1134
1305
  //# sourceMappingURL=index.js.map