@mastra/react 1.13.0-alpha.3 → 1.13.0-alpha.5

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 (149) hide show
  1. package/dist/{accumulator-BmD8-x9I.cjs → accumulator-Bjfckb5t.cjs} +5 -9
  2. package/dist/{accumulator-BmD8-x9I.cjs.map → accumulator-Bjfckb5t.cjs.map} +1 -1
  3. package/dist/{accumulator-D9jAph99.js → accumulator-DysrPe6U.js} +5 -9
  4. package/dist/{accumulator-D9jAph99.js.map → accumulator-DysrPe6U.js.map} +1 -1
  5. package/dist/chat/index.cjs +1 -1
  6. package/dist/chat/index.js +1 -1
  7. package/dist/{combine-by-ids-CcaZKGT9.js → combine-by-ids-C-0oe4eH.js} +2 -3
  8. package/dist/{combine-by-ids-CcaZKGT9.js.map → combine-by-ids-C-0oe4eH.js.map} +1 -1
  9. package/dist/{combine-by-ids-D_lp6Dvq.cjs → combine-by-ids-ERVPXXBi.cjs} +2 -3
  10. package/dist/{combine-by-ids-D_lp6Dvq.cjs.map → combine-by-ids-ERVPXXBi.cjs.map} +1 -1
  11. package/dist/{experiments-CJw1N3FB.cjs → experiments-Duv0RgkM.cjs} +12 -19
  12. package/dist/{experiments-CJw1N3FB.cjs.map → experiments-Duv0RgkM.cjs.map} +1 -1
  13. package/dist/{experiments-B7vRMK5T.js → experiments-DyecjEut.js} +12 -19
  14. package/dist/{experiments-B7vRMK5T.js.map → experiments-DyecjEut.js.map} +1 -1
  15. package/dist/{feedback-refetch-interval-XD5FVc2k.cjs → feedback-refetch-interval-BBcT9r8s.cjs} +3 -4
  16. package/dist/{feedback-refetch-interval-XD5FVc2k.cjs.map → feedback-refetch-interval-BBcT9r8s.cjs.map} +1 -1
  17. package/dist/{feedback-refetch-interval-DLHzQoVV.js → feedback-refetch-interval-C12Nzb2r.js} +3 -4
  18. package/dist/{feedback-refetch-interval-DLHzQoVV.js.map → feedback-refetch-interval-C12Nzb2r.js.map} +1 -1
  19. package/dist/hooks/agents/index.cjs +19 -37
  20. package/dist/hooks/agents/index.cjs.map +1 -1
  21. package/dist/hooks/agents/index.js +19 -37
  22. package/dist/hooks/agents/index.js.map +1 -1
  23. package/dist/hooks/auth/index.cjs +11 -21
  24. package/dist/hooks/auth/index.cjs.map +1 -1
  25. package/dist/hooks/auth/index.js +11 -21
  26. package/dist/hooks/auth/index.js.map +1 -1
  27. package/dist/hooks/capabilities/index.cjs +11 -21
  28. package/dist/hooks/capabilities/index.cjs.map +1 -1
  29. package/dist/hooks/capabilities/index.js +11 -21
  30. package/dist/hooks/capabilities/index.js.map +1 -1
  31. package/dist/hooks/configuration/index.cjs +2 -3
  32. package/dist/hooks/configuration/index.js +2 -3
  33. package/dist/hooks/datasets/index.cjs +12 -21
  34. package/dist/hooks/datasets/index.cjs.map +1 -1
  35. package/dist/hooks/datasets/index.js +12 -21
  36. package/dist/hooks/datasets/index.js.map +1 -1
  37. package/dist/hooks/embedders/index.cjs +2 -3
  38. package/dist/hooks/embedders/index.js +2 -3
  39. package/dist/hooks/experiments/index.cjs +1 -1
  40. package/dist/hooks/experiments/index.js +1 -1
  41. package/dist/hooks/feedback/index.cjs +3 -4
  42. package/dist/hooks/feedback/index.js +3 -4
  43. package/dist/hooks/llm/index.cjs +2 -3
  44. package/dist/hooks/llm/index.js +2 -3
  45. package/dist/hooks/logs/index.cjs +4 -5
  46. package/dist/hooks/logs/index.js +4 -5
  47. package/dist/hooks/mcps/index.cjs +8 -15
  48. package/dist/hooks/mcps/index.cjs.map +1 -1
  49. package/dist/hooks/mcps/index.js +8 -15
  50. package/dist/hooks/mcps/index.js.map +1 -1
  51. package/dist/hooks/memory/index.cjs +5 -9
  52. package/dist/hooks/memory/index.cjs.map +1 -1
  53. package/dist/hooks/memory/index.js +5 -9
  54. package/dist/hooks/memory/index.js.map +1 -1
  55. package/dist/hooks/metrics/index.cjs +19 -36
  56. package/dist/hooks/metrics/index.cjs.map +1 -1
  57. package/dist/hooks/metrics/index.js +19 -36
  58. package/dist/hooks/metrics/index.js.map +1 -1
  59. package/dist/hooks/processors/index.cjs +2 -3
  60. package/dist/hooks/processors/index.js +2 -3
  61. package/dist/hooks/prompt-blocks/index.cjs +3 -5
  62. package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
  63. package/dist/hooks/prompt-blocks/index.js +3 -5
  64. package/dist/hooks/prompt-blocks/index.js.map +1 -1
  65. package/dist/hooks/query/index.cjs +2 -3
  66. package/dist/hooks/query/index.js +2 -3
  67. package/dist/hooks/review/index.cjs +4 -6
  68. package/dist/hooks/review/index.cjs.map +1 -1
  69. package/dist/hooks/review/index.js +4 -6
  70. package/dist/hooks/review/index.js.map +1 -1
  71. package/dist/hooks/schedules/index.cjs +6 -10
  72. package/dist/hooks/schedules/index.cjs.map +1 -1
  73. package/dist/hooks/schedules/index.js +6 -10
  74. package/dist/hooks/schedules/index.js.map +1 -1
  75. package/dist/hooks/scores/index.cjs +8 -13
  76. package/dist/hooks/scores/index.cjs.map +1 -1
  77. package/dist/hooks/scores/index.js +8 -13
  78. package/dist/hooks/scores/index.js.map +1 -1
  79. package/dist/hooks/templates/index.cjs +2 -3
  80. package/dist/hooks/templates/index.js +2 -3
  81. package/dist/hooks/tool-providers/index.cjs +10 -19
  82. package/dist/hooks/tool-providers/index.cjs.map +1 -1
  83. package/dist/hooks/tool-providers/index.js +10 -19
  84. package/dist/hooks/tool-providers/index.js.map +1 -1
  85. package/dist/hooks/tools/index.cjs +3 -5
  86. package/dist/hooks/tools/index.cjs.map +1 -1
  87. package/dist/hooks/tools/index.js +3 -5
  88. package/dist/hooks/tools/index.js.map +1 -1
  89. package/dist/hooks/traces/index.cjs +71 -54
  90. package/dist/hooks/traces/index.cjs.map +1 -1
  91. package/dist/hooks/traces/index.d.ts +2 -0
  92. package/dist/hooks/traces/index.d.ts.map +1 -1
  93. package/dist/hooks/traces/index.js +70 -55
  94. package/dist/hooks/traces/index.js.map +1 -1
  95. package/dist/hooks/traces/use-span-aggregate.d.ts +16 -0
  96. package/dist/hooks/traces/use-span-aggregate.d.ts.map +1 -0
  97. package/dist/hooks/traces/use-trace-aggregate.d.ts +17 -0
  98. package/dist/hooks/traces/use-trace-aggregate.d.ts.map +1 -0
  99. package/dist/hooks/traces/use-trace-column-preferences-storage-key.d.ts +4 -2
  100. package/dist/hooks/traces/use-trace-column-preferences-storage-key.d.ts.map +1 -1
  101. package/dist/hooks/vectors/index.cjs +2 -3
  102. package/dist/hooks/vectors/index.js +2 -3
  103. package/dist/hooks/voice/index.cjs +3 -4
  104. package/dist/hooks/voice/index.js +3 -4
  105. package/dist/hooks/workflows/index.cjs +7 -11
  106. package/dist/hooks/workflows/index.cjs.map +1 -1
  107. package/dist/hooks/workflows/index.js +7 -11
  108. package/dist/hooks/workflows/index.js.map +1 -1
  109. package/dist/hooks/workspace/index.cjs +12 -22
  110. package/dist/hooks/workspace/index.cjs.map +1 -1
  111. package/dist/hooks/workspace/index.js +12 -22
  112. package/dist/hooks/workspace/index.js.map +1 -1
  113. package/dist/{hooks-XYsmqFCz.cjs → hooks-Bt15IwzP.cjs} +6 -9
  114. package/dist/{hooks-XYsmqFCz.cjs.map → hooks-Bt15IwzP.cjs.map} +1 -1
  115. package/dist/{hooks-DG-Y1KFe.js → hooks-Btt7PyI-.js} +6 -9
  116. package/dist/{hooks-DG-Y1KFe.js.map → hooks-Btt7PyI-.js.map} +1 -1
  117. package/dist/{hooks-BfysjY_K.js → hooks-CEikbhrN.js} +9 -15
  118. package/dist/{hooks-BfysjY_K.js.map → hooks-CEikbhrN.js.map} +1 -1
  119. package/dist/{hooks-BbUMSab8.cjs → hooks-D6LDSEcm.cjs} +9 -15
  120. package/dist/{hooks-BbUMSab8.cjs.map → hooks-D6LDSEcm.cjs.map} +1 -1
  121. package/dist/index.cjs +7 -9
  122. package/dist/index.cjs.map +1 -1
  123. package/dist/index.js +7 -9
  124. package/dist/index.js.map +1 -1
  125. package/dist/{map-CDv4fbu4.js → map-5-4U5rwA.js} +2 -3
  126. package/dist/{map-CDv4fbu4.js.map → map-5-4U5rwA.js.map} +1 -1
  127. package/dist/{map-wjmL1y5O.cjs → map-BGoWBTGy.cjs} +2 -3
  128. package/dist/{map-wjmL1y5O.cjs.map → map-BGoWBTGy.cjs.map} +1 -1
  129. package/dist/{mastra-client-context-Bx_g84YB.js → mastra-client-context-DQ5z_ze9.js} +2 -3
  130. package/dist/{mastra-client-context-Bx_g84YB.js.map → mastra-client-context-DQ5z_ze9.js.map} +1 -1
  131. package/dist/{mastra-client-context-DzX3f0RF.cjs → mastra-client-context-DX8wJM9p.cjs} +2 -3
  132. package/dist/{mastra-client-context-DzX3f0RF.cjs.map → mastra-client-context-DX8wJM9p.cjs.map} +1 -1
  133. package/dist/{query-utils-CcrChYgz.cjs → query-utils-BVgE_xxj.cjs} +2 -3
  134. package/dist/{query-utils-CcrChYgz.cjs.map → query-utils-BVgE_xxj.cjs.map} +1 -1
  135. package/dist/{query-utils-D1NgFnWU.js → query-utils-DvMERIwf.js} +2 -3
  136. package/dist/{query-utils-D1NgFnWU.js.map → query-utils-DvMERIwf.js.map} +1 -1
  137. package/dist/ui/index.cjs +15 -30
  138. package/dist/ui/index.cjs.map +1 -1
  139. package/dist/ui/index.js +14 -28
  140. package/dist/ui/index.js.map +1 -1
  141. package/dist/{use-in-view-B6eJO9Zi.cjs → use-in-view-BxdrrnCw.cjs} +2 -3
  142. package/dist/{use-in-view-B6eJO9Zi.cjs.map → use-in-view-BxdrrnCw.cjs.map} +1 -1
  143. package/dist/{use-in-view-C9sYPGRm.js → use-in-view-CyjKdplM.js} +2 -3
  144. package/dist/{use-in-view-C9sYPGRm.js.map → use-in-view-CyjKdplM.js.map} +1 -1
  145. package/dist/{voice-BOtUdMi8.cjs → voice-Didej2E1.cjs} +5 -8
  146. package/dist/{voice-BOtUdMi8.cjs.map → voice-Didej2E1.cjs.map} +1 -1
  147. package/dist/{voice-DgirjEyH.js → voice-ugGu7VyA.js} +5 -8
  148. package/dist/{voice-DgirjEyH.js.map → voice-ugGu7VyA.js.map} +1 -1
  149. package/package.json +19 -19
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_mastra_client_context = require("../../mastra-client-context-DzX3f0RF.cjs");
3
- const require_map = require("../../map-wjmL1y5O.cjs");
2
+ const require_mastra_client_context = require("../../mastra-client-context-DX8wJM9p.cjs");
3
+ const require_map = require("../../map-BGoWBTGy.cjs");
4
4
  let react = require("react");
5
5
  let _tanstack_react_query = require("@tanstack/react-query");
6
- //#region src/hooks/metrics/metrics-query-filters.ts
6
+ // src/hooks/metrics/metrics-query-filters.ts
7
7
  const DEFAULT_WINDOW_MS = 864e5;
8
8
  const PRESET_MS = {
9
9
  "24h": DEFAULT_WINDOW_MS,
@@ -61,8 +61,7 @@ function useMetricsQueryFilters({ datePreset, customRange, dimensionalFilter, di
61
61
  filterKey: (0, react.useMemo)(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey])
62
62
  };
63
63
  }
64
- //#endregion
65
- //#region src/hooks/shared/date-format.ts
64
+ // src/hooks/shared/date-format.ts
66
65
  function toDate(value) {
67
66
  if (value == null) return void 0;
68
67
  const date = value instanceof Date ? value : new Date(value);
@@ -230,8 +229,7 @@ function formatDate(value, preset, options = {}) {
230
229
  if (preset === "date") return formatShortDate(date, options);
231
230
  return getFormatter(preset, locale, timeZone).format(date);
232
231
  }
233
- //#endregion
234
- //#region src/hooks/metrics/metrics-interval.ts
232
+ // src/hooks/metrics/metrics-interval.ts
235
233
  const HOURLY_MAX_RANGE_MS = 1728e5;
236
234
  /** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */
237
235
  function chooseMetricsInterval({ start, end }) {
@@ -241,8 +239,7 @@ function formatMetricsBucketLabel(ts, interval) {
241
239
  if (interval === "1h") return formatDate(ts, "time") ?? "";
242
240
  return formatShortDate(ts) ?? "";
243
241
  }
244
- //#endregion
245
- //#region src/hooks/metrics/use-active-resources-kpi-metrics.tsx
242
+ // src/hooks/metrics/use-active-resources-kpi-metrics.tsx
246
243
  /** Active Resources — number of distinct resource IDs observed in agent runs.
247
244
  * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,
248
245
  * `approx_count_distinct` on DuckDB) so the query stays fast even on
@@ -266,8 +263,7 @@ function useActiveResourcesKpiMetrics(params) {
266
263
  ...queryOptions
267
264
  });
268
265
  }
269
- //#endregion
270
- //#region src/hooks/metrics/use-active-threads-kpi-metrics.tsx
266
+ // src/hooks/metrics/use-active-threads-kpi-metrics.tsx
271
267
  /** Active Threads — number of distinct thread IDs observed in agent runs.
272
268
  * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,
273
269
  * `approx_count_distinct` on DuckDB) so the query stays fast even on
@@ -291,8 +287,7 @@ function useActiveThreadsKpiMetrics(params) {
291
287
  ...queryOptions
292
288
  });
293
289
  }
294
- //#endregion
295
- //#region src/hooks/metrics/use-agent-runs-kpi-metrics.tsx
290
+ // src/hooks/metrics/use-agent-runs-kpi-metrics.tsx
296
291
  /** Total Agent Runs — count of agent duration metric observations */
297
292
  function useAgentRunsKpiMetrics(params) {
298
293
  const client = require_mastra_client_context.useMastraClient();
@@ -312,8 +307,7 @@ function useAgentRunsKpiMetrics(params) {
312
307
  ...queryOptions
313
308
  });
314
309
  }
315
- //#endregion
316
- //#region src/hooks/metrics/use-latency-metrics.tsx
310
+ // src/hooks/metrics/use-latency-metrics.tsx
317
311
  async function fetchPercentiles(client, metricName, filters, interval) {
318
312
  const res = await client.getMetricPercentiles({
319
313
  name: metricName,
@@ -363,8 +357,7 @@ function useLatencyMetrics(params) {
363
357
  ...queryOptions
364
358
  });
365
359
  }
366
- //#endregion
367
- //#region src/hooks/metrics/use-model-cost-kpi-metrics.tsx
360
+ // src/hooks/metrics/use-model-cost-kpi-metrics.tsx
368
361
  function useModelCostKpiMetrics(params) {
369
362
  const client = require_mastra_client_context.useMastraClient();
370
363
  const { filters, filterKey, queryOptions } = params;
@@ -391,8 +384,7 @@ function useModelCostKpiMetrics(params) {
391
384
  ...queryOptions
392
385
  });
393
386
  }
394
- //#endregion
395
- //#region src/hooks/shared/cost.ts
387
+ // src/hooks/shared/cost.ts
396
388
  const compactNumber = new Intl.NumberFormat("en-US", {
397
389
  notation: "compact",
398
390
  maximumSignificantDigits: 3
@@ -426,8 +418,7 @@ function formatFullNumber(value, { currency } = {}) {
426
418
  if (value !== 0 && Math.abs(value) < smallestUnit) return `${value < 0 ? "-" : ""}<${formatter.format(smallestUnit)}`;
427
419
  return formatter.format(value);
428
420
  }
429
- //#endregion
430
- //#region src/hooks/metrics/use-model-usage-cost-metrics.tsx
421
+ // src/hooks/metrics/use-model-usage-cost-metrics.tsx
431
422
  function useModelUsageCostMetrics(params) {
432
423
  const client = require_mastra_client_context.useMastraClient();
433
424
  const { filters, filterKey, queryOptions } = params;
@@ -504,8 +495,7 @@ function useModelUsageCostMetrics(params) {
504
495
  ...queryOptions
505
496
  });
506
497
  }
507
- //#endregion
508
- //#region src/hooks/metrics/use-scores-metrics.tsx
498
+ // src/hooks/metrics/use-scores-metrics.tsx
509
499
  function useScoresMetrics(params) {
510
500
  const client = require_mastra_client_context.useMastraClient();
511
501
  const { datePreset, customRange, timestamp, queryOptions } = params;
@@ -607,8 +597,7 @@ function useScoresMetrics(params) {
607
597
  ...queryOptions
608
598
  });
609
599
  }
610
- //#endregion
611
- //#region src/hooks/metrics/use-token-usage-by-agent-metrics.tsx
600
+ // src/hooks/metrics/use-token-usage-by-agent-metrics.tsx
612
601
  function useTokenUsageByAgentMetrics(params) {
613
602
  const client = require_mastra_client_context.useMastraClient();
614
603
  const { filters, filterKey, queryOptions } = params;
@@ -667,8 +656,7 @@ function useTokenUsageByAgentMetrics(params) {
667
656
  ...queryOptions
668
657
  });
669
658
  }
670
- //#endregion
671
- //#region src/hooks/metrics/use-token-usage-timeseries.tsx
659
+ // src/hooks/metrics/use-token-usage-timeseries.tsx
672
660
  function addSeriesPoints(pointMap, series, key) {
673
661
  for (const point of series?.points ?? []) {
674
662
  const tsMs = new Date(point.timestamp).getTime();
@@ -738,8 +726,7 @@ function useTokenUsageTimeSeries(params) {
738
726
  ...queryOptions
739
727
  });
740
728
  }
741
- //#endregion
742
- //#region src/hooks/metrics/use-top-active-threads-metrics.tsx
729
+ // src/hooks/metrics/use-top-active-threads-metrics.tsx
743
730
  const TOP_N$1 = 20;
744
731
  /** Top Active Threads — the threads with the most agent runs in the selected
745
732
  * range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the
@@ -818,8 +805,7 @@ function useTopActiveThreadsMetrics(params) {
818
805
  ...queryOptions
819
806
  });
820
807
  }
821
- //#endregion
822
- //#region src/hooks/metrics/use-top-resources-by-threads-metrics.tsx
808
+ // src/hooks/metrics/use-top-resources-by-threads-metrics.tsx
823
809
  const TOP_N = 20;
824
810
  /** Top Resources by Thread Count — the resources with the most distinct threads
825
811
  * in the selected range. Uses `count_distinct(threadId)` per `resourceId`,
@@ -898,8 +884,7 @@ function useTopResourcesByThreadsMetrics(params) {
898
884
  ...queryOptions
899
885
  });
900
886
  }
901
- //#endregion
902
- //#region src/hooks/metrics/use-total-tokens-kpi-metrics.tsx
887
+ // src/hooks/metrics/use-total-tokens-kpi-metrics.tsx
903
888
  function useTotalTokensKpiMetrics(params) {
904
889
  const client = require_mastra_client_context.useMastraClient();
905
890
  const { filters, filterKey, queryOptions } = params;
@@ -935,8 +920,7 @@ function useTotalTokensKpiMetrics(params) {
935
920
  ...queryOptions
936
921
  });
937
922
  }
938
- //#endregion
939
- //#region src/hooks/metrics/use-trace-volume-metrics.tsx
923
+ // src/hooks/metrics/use-trace-volume-metrics.tsx
940
924
  async function fetchVolume(client, metricName, filters) {
941
925
  const res = await client.getMetricBreakdown({
942
926
  name: [metricName],
@@ -985,7 +969,6 @@ function useTraceVolumeMetrics(params) {
985
969
  ...queryOptions
986
970
  });
987
971
  }
988
- //#endregion
989
972
  exports.chooseMetricsInterval = chooseMetricsInterval;
990
973
  exports.formatMetricsBucketLabel = formatMetricsBucketLabel;
991
974
  exports.useActiveResourcesKpiMetrics = useActiveResourcesKpiMetrics;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useRef","useMemo","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","TOP_N","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery"],"sources":["../../../src/hooks/metrics/metrics-query-filters.ts","../../../src/hooks/shared/date-format.ts","../../../src/hooks/metrics/metrics-interval.ts","../../../src/hooks/metrics/use-active-resources-kpi-metrics.tsx","../../../src/hooks/metrics/use-active-threads-kpi-metrics.tsx","../../../src/hooks/metrics/use-agent-runs-kpi-metrics.tsx","../../../src/hooks/metrics/use-latency-metrics.tsx","../../../src/hooks/metrics/use-model-cost-kpi-metrics.tsx","../../../src/hooks/shared/cost.ts","../../../src/hooks/metrics/use-model-usage-cost-metrics.tsx","../../../src/hooks/metrics/use-scores-metrics.tsx","../../../src/hooks/metrics/use-token-usage-by-agent-metrics.tsx","../../../src/hooks/metrics/use-token-usage-timeseries.tsx","../../../src/hooks/metrics/use-top-active-threads-metrics.tsx","../../../src/hooks/metrics/use-top-resources-by-threads-metrics.tsx","../../../src/hooks/metrics/use-total-tokens-kpi-metrics.tsx","../../../src/hooks/metrics/use-trace-volume-metrics.tsx"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport { useMemo, useRef } from 'react';\n\nexport type MetricsDatePreset = '24h' | '3d' | '7d' | '14d' | '30d' | 'custom';\n\nexport type MetricsDateRange = { from?: Date; to?: Date };\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\nexport interface MetricsQueryFiltersInput {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n dimensionalFilter: MetricsDimensionalFilter;\n /** Stable JSON representation of `dimensionalFilter`, safe for query keys. */\n dimensionalFilterKey: string;\n}\n\ntype Timestamp = { start: Date; end: Date };\n\nexport interface MetricsQueryFilters {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n timestamp: Timestamp;\n filters: MetricsDimensionalFilter & { timestamp: Timestamp };\n dimensionalFilter: MetricsDimensionalFilter;\n filterKey: string;\n}\n\nconst DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nconst PRESET_MS: Record<string, number> = {\n '24h': DEFAULT_WINDOW_MS,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '14d': 14 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n};\n\nfunction buildTimestamp(\n preset: MetricsDatePreset,\n customRange: MetricsDateRange | undefined,\n anchor: number,\n): Timestamp {\n if (preset !== 'custom') {\n const ms = PRESET_MS[preset] ?? DEFAULT_WINDOW_MS;\n return { start: new Date(anchor - ms), end: new Date(anchor) };\n }\n return {\n start: customRange?.from ?? new Date(anchor - DEFAULT_WINDOW_MS),\n end: customRange?.to ?? new Date(anchor),\n };\n}\n\n/**\n * Compose a ready-to-use metrics filter object from a date window and a\n * dimensional filter. Pass the result to the metrics hooks.\n *\n * Stability guarantees (important for react-query):\n * - `timestamp` is frozen at the moment the inputs change and does NOT update\n * on every render. Otherwise each render would mint a new `new Date()` and\n * every metrics query would re-fetch on every keystroke.\n * - `filters` and `filterKey` are referentially stable while inputs are\n * unchanged, so `queryKey` hashing is cheap and caches hit.\n */\nexport function useMetricsQueryFilters({\n datePreset,\n customRange,\n dimensionalFilter,\n dimensionalFilterKey,\n}: MetricsQueryFiltersInput): MetricsQueryFilters {\n // Anchor the \"now\" used for preset windows. We only recompute when the\n // preset or custom range changes — this gives a stable timestamp per query\n // boundary rather than a new Date on every render.\n const anchorRef = useRef<{ key: string; anchor: number } | null>(null);\n const windowKey =\n datePreset === 'custom'\n ? `custom:${customRange?.from?.getTime() ?? ''}:${customRange?.to?.getTime() ?? ''}`\n : `preset:${datePreset}`;\n if (!anchorRef.current || anchorRef.current.key !== windowKey) {\n anchorRef.current = { key: windowKey, anchor: Date.now() };\n }\n const anchor = anchorRef.current.anchor;\n\n const timestamp = useMemo(() => buildTimestamp(datePreset, customRange, anchor), [datePreset, customRange, anchor]);\n\n const filters = useMemo(\n () => ({ timestamp, ...dimensionalFilter }),\n // dimensionalFilterKey is a stringified digest, so this dep set gives a\n // stable ref while content is unchanged.\n [timestamp, dimensionalFilterKey],\n );\n\n // filterKey combines window + dimensions so react-query keys are cheap.\n const filterKey = useMemo(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey]);\n\n return { datePreset, customRange, timestamp, filters, dimensionalFilter, filterKey };\n}\n","export type DateInput = Date | string | number | null | undefined;\nexport type DatePreset =\n | 'date'\n | 'date-time'\n | 'date-time-seconds'\n | 'day-time-seconds'\n | 'time'\n | 'time-seconds'\n | 'relative-time'\n | 'relative-long';\n\ntype FormatOptions = { locale?: string; now?: Date | number; timeZone?: string };\n\nexport function toDate(value: DateInput): Date | undefined {\n if (value == null) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nconst PRESET_OPTIONS = {\n time: { hour: 'numeric', minute: '2-digit' },\n 'time-seconds': { hour: 'numeric', minute: '2-digit', second: '2-digit' },\n 'date-time': { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' },\n 'date-time-seconds': {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n },\n 'day-time-seconds': { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit' },\n calendar: { year: 'numeric', month: 'numeric', day: 'numeric', calendar: 'gregory', numberingSystem: 'latn' },\n dayMonth: { month: 'short', day: 'numeric' },\n dayMonthYear: { month: 'short', day: 'numeric', year: 'numeric' },\n precise: {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n },\n timePrecise: { hour: 'numeric', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3 },\n} satisfies Record<string, Intl.DateTimeFormatOptions>;\n\ntype FormatterKey = keyof typeof PRESET_OPTIONS;\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\nfunction getFormatter(key: FormatterKey, locale?: string, timeZone?: string) {\n const cacheKey = `${locale ?? ''}|${timeZone ?? ''}|${key}`;\n let formatter = formatters.get(cacheKey);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...PRESET_OPTIONS[key], timeZone });\n formatters.set(cacheKey, formatter);\n }\n return formatter;\n}\n\nfunction calendarDate(date: Date, timeZone?: string) {\n const parts = getFormatter('calendar', 'en-US', timeZone).formatToParts(date);\n return {\n year: parts.find(part => part.type === 'year')?.value,\n month: parts.find(part => part.type === 'month')?.value,\n day: parts.find(part => part.type === 'day')?.value,\n };\n}\n\n/** Short absolute date without time: `Sep 24` this year, `Sep 24, 2025` otherwise. */\nexport function formatShortDate(value: DateInput, { locale, now, timeZone }: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const reference = new Date(now ?? Date.now());\n const key =\n calendarDate(date, timeZone).year === calendarDate(reference, timeZone).year ? 'dayMonth' : 'dayMonthYear';\n return getFormatter(key, locale, timeZone).format(date);\n}\n\nconst LONG_RELATIVE_UNITS: Array<[Intl.RelativeTimeFormatUnit, number]> = [\n ['year', 365 * 86_400],\n ['month', 30 * 86_400],\n ['week', 7 * 86_400],\n ['day', 86_400],\n ['hour', 3_600],\n ['minute', 60],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\n\nfunction getRelativeFormatter(locale?: string) {\n const key = locale ?? '';\n let formatter = relativeFormatters.get(key);\n if (!formatter) {\n formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n relativeFormatters.set(key, formatter);\n }\n return formatter;\n}\n\n/**\n * Uses the browser locale unless `locale` is given.\n * - `date`: date only; omits the year when it matches `now` in the requested timezone\n * - `date-time`: date, year and time to minutes, including historical dates\n * - `date-time-seconds`: date, year and time to seconds\n * - `day-time-seconds`: month, day and time to seconds, without the year\n * - `time`: time to minutes, without a date\n * - `time-seconds`: time to seconds, without a date\n * - `relative-time`: short relative label; delegates to `date` at seven days\n */\nexport function formatDate(value: DateInput, preset: DatePreset, options: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const { locale, now, timeZone } = options;\n\n if (preset === 'relative-time') {\n const diff = date.getTime() - new Date(now ?? Date.now()).getTime();\n const abs = Math.abs(diff);\n if (abs < 5_000) return 'just now';\n const units = [\n { limit: 60_000, size: 1_000, unit: 's' },\n { limit: 3_600_000, size: 60_000, unit: 'm' },\n { limit: 86_400_000, size: 3_600_000, unit: 'h' },\n { limit: 7 * 86_400_000, size: 86_400_000, unit: 'd' },\n ];\n const match = units.find(({ limit }) => abs < limit);\n if (!match) return formatDate(date, 'date', options);\n const label = `${Math.floor(abs / match.size)}${match.unit}`;\n return diff < 0 ? `${label} ago` : `in ${label}`;\n }\n if (preset === 'relative-long') {\n const seconds = (date.getTime() - new Date(now ?? Date.now()).getTime()) / 1000;\n const [unit, size] = LONG_RELATIVE_UNITS.find(([, size]) => Math.abs(seconds) >= size) ?? ['second', 1];\n return getRelativeFormatter(locale).format(Math.round(seconds / size), unit);\n }\n if (preset === 'date') return formatShortDate(date, options);\n\n return getFormatter(preset, locale, timeZone).format(date);\n}\n\n/** Locale-aware compact date range, e.g. `Sep 2 – 5, 2026`. */\nexport function formatDateRange(start: DateInput, end: DateInput, options: Omit<FormatOptions, 'now'> = {}) {\n const from = toDate(start);\n const to = toDate(end);\n if (!from || !to) return undefined;\n return getFormatter('dayMonthYear', options.locale, options.timeZone)\n .formatRange(from, to)\n .replace(/\\u2009/g, ' ');\n}\n\n/** Date and time down to milliseconds, for trace debugging. `withDate: false` keeps only the time. */\nexport function formatTimestampPrecise(\n value: DateInput,\n { locale, withDate = true }: { locale?: string; withDate?: boolean } = {},\n) {\n const date = toDate(value);\n return date ? getFormatter(withDate ? 'precise' : 'timePrecise', locale).format(date) : undefined;\n}\n","import { formatDate, formatShortDate } from '../shared/date-format';\n\nexport type MetricsInterval = '1h' | '1d';\n\nconst HOURLY_MAX_RANGE_MS = 48 * 60 * 60 * 1000;\n\n/** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */\nexport function chooseMetricsInterval({ start, end }: { start: Date; end: Date }): MetricsInterval {\n return end.getTime() - start.getTime() <= HOURLY_MAX_RANGE_MS ? '1h' : '1d';\n}\n\nexport function formatMetricsBucketLabel(ts: Date, interval: MetricsInterval): string {\n if (interval === '1h') {\n return formatDate(ts, 'time') ?? '';\n }\n return formatShortDate(ts) ?? '';\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Resources — number of distinct resource IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveResourcesKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-resources-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'resourceId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Threads — number of distinct thread IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveThreadsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-threads-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Agent Runs — count of agent duration metric observations */\nexport function useAgentRunsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'agent-runs-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface LatencyPoint {\n [key: string]: unknown;\n time: string;\n /** Raw timestamp (ms since epoch) for the bucket this point represents.\n * Used by drilldown clicks to compute a narrow time window. */\n tsMs: number;\n p50: number;\n p95: number;\n}\n\nasync function fetchPercentiles(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n interval: MetricsInterval,\n): Promise<LatencyPoint[]> {\n const res = await client.getMetricPercentiles({\n name: metricName,\n percentiles: [0.5, 0.95],\n interval,\n filters,\n });\n\n const p50Series = res.series.find(s => s.percentile === 0.5);\n const p95Series = res.series.find(s => s.percentile === 0.95);\n\n if (!p50Series || !p95Series) return [];\n\n const p95Map = new Map(p95Series.points.map(p => [new Date(p.timestamp).getTime(), p.value]));\n\n return p50Series.points.map(p => {\n const ts = new Date(p.timestamp);\n const tsMs = ts.getTime();\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs,\n p50: Math.round(p.value),\n p95: Math.round(p95Map.get(tsMs) ?? 0),\n };\n });\n}\n\nexport interface LatencyMetricsData {\n agentData: LatencyPoint[];\n workflowData: LatencyPoint[];\n toolData: LatencyPoint[];\n interval: MetricsInterval;\n}\n\nexport function useLatencyMetrics<TData = LatencyMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<LatencyMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'latency', filterKey, interval],\n queryFn: async (): Promise<LatencyMetricsData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchPercentiles(client, 'mastra_agent_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_workflow_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_tool_duration_ms', filters, interval),\n ]);\n return { agentData, workflowData, toolData, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Model Cost — sum of estimatedCost across input and output token metrics */\nexport interface ModelCostKpi {\n cost: number | null;\n costUnit: string | null;\n previousCost: number | null;\n costChangePercent: number | null;\n}\n\nexport function useModelCostKpiMetrics<TData = ModelCostKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelCostKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-cost-kpi', filterKey],\n queryFn: async (): Promise<ModelCostKpi> => {\n const res = await client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens', 'mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n });\n\n return {\n cost: res.estimatedCost ?? null,\n costUnit: res.costUnit ?? null,\n previousCost: res.previousEstimatedCost ?? null,\n costChangePercent: res.costChangePercent ?? null,\n };\n },\n ...queryOptions,\n });\n}\n","export interface CompactNumberFormatOptions {\n currency?: string;\n}\n\nconst compactNumber = new Intl.NumberFormat('en-US', { notation: 'compact', maximumSignificantDigits: 3 });\nconst fullNumber = new Intl.NumberFormat('en-US');\n\nconst currencyCodes = new Set(Intl.supportedValuesOf('currency'));\n\nfunction isCurrency(code: string | undefined): code is string {\n return code !== undefined && currencyCodes.has(code.toUpperCase());\n}\n\nfunction money(currency: string, options: Intl.NumberFormatOptions) {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency, ...options });\n}\n\nexport function formatCompactNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return compactNumber.format(value);\n const size = Math.abs(value);\n if (size < 100) return formatFullNumber(value, { currency });\n if (size < 1000) return money(currency, { maximumFractionDigits: 0 }).format(value);\n return money(currency, { notation: 'compact', maximumSignificantDigits: 3 }).format(value);\n}\n\nexport function formatFullNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return fullNumber.format(value);\n const formatter = money(currency, {});\n const smallestUnit = 10 ** -(formatter.resolvedOptions().maximumFractionDigits ?? 2);\n if (value !== 0 && Math.abs(value) < smallestUnit) {\n return `${value < 0 ? '-' : ''}<${formatter.format(smallestUnit)}`;\n }\n return formatter.format(value);\n}\n\nexport function formatCost(value: number, unit?: string | null): string {\n const isUsd = !unit || unit.toLowerCase() === 'usd';\n const amount = value > 0 && value < 0.01 ? '<0.01' : value.toFixed(2);\n if (!isUsd) return `${amount} ${unit}`;\n return amount.startsWith('<') ? '<$0.01' : `$${amount}`;\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatCompactNumber } from '../shared/cost';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ModelUsageRow {\n model: string;\n provider?: string;\n input: string;\n output: string;\n cacheRead: string;\n cacheWrite: string;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useModelUsageCostMetrics<TData = ModelUsageRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelUsageRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-usage-cost', filterKey],\n queryFn: async (): Promise<ModelUsageRow[]> => {\n const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all(\n (\n [\n 'mastra_model_total_input_tokens',\n 'mastra_model_total_output_tokens',\n 'mastra_model_input_cache_read_tokens',\n 'mastra_model_input_cache_write_tokens',\n ] as const\n ).map(name =>\n client.getMetricBreakdown({\n name: [name],\n groupBy: ['model', 'provider'],\n aggregation: 'sum',\n orderDirection: 'DESC',\n filters,\n }),\n ),\n );\n\n if (!inputRes || !outputRes || !cacheReadRes || !cacheWriteRes) return [];\n\n type ModelEntry = {\n model: string;\n provider: string | undefined;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number | null;\n costUnit: string | null;\n };\n\n const modelMap = new Map<string, ModelEntry>();\n\n const ensureModel = (dimensions: { model?: string | null; provider?: string | null }): ModelEntry => {\n const model = dimensions.model ?? 'unknown';\n const provider = dimensions.provider ?? undefined;\n return getOrCreate(modelMap, `${model}\\u0000${provider ?? ''}`, () => ({\n model,\n provider,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n cost: null,\n costUnit: null,\n }));\n };\n\n // total_input/total_output estimatedCost already rolls up cache + other detail\n // costs. The cache breakdowns are kept for their token counts only.\n const addCost = (entry: ModelEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.output = group.value;\n addCost(entry, group);\n }\n for (const group of cacheReadRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheRead = group.value;\n }\n for (const group of cacheWriteRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheWrite = group.value;\n }\n\n return Array.from(modelMap.values())\n .map(vals => ({\n model: vals.model,\n ...(vals.provider ? { provider: vals.provider } : {}),\n input: formatCompactNumber(vals.input),\n output: formatCompactNumber(vals.output),\n cacheRead: formatCompactNumber(vals.cacheRead),\n cacheWrite: formatCompactNumber(vals.cacheWrite),\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => a.model.localeCompare(b.model) || (a.provider ?? '').localeCompare(b.provider ?? ''));\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatDate } from '../shared/date-format';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ScorerSummary {\n scorer: string;\n avg: number;\n min: number;\n max: number;\n count: number;\n}\n\nexport interface ScoresOverTimePoint {\n time: string;\n [scorer: string]: string | number;\n}\n\nexport interface ScoresMetricsData {\n summaryData: ScorerSummary[];\n overTimeData: ScoresOverTimePoint[];\n scorerNames: string[];\n avgScore: number | null;\n}\n\nexport function useScoresMetrics<TData = ScoresMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ScoresMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { datePreset, customRange, timestamp, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'scores-card', datePreset, customRange],\n queryFn: async (): Promise<ScoresMetricsData> => {\n const filters = {\n timestamp: { start: timestamp.start, end: timestamp.end },\n };\n\n const scorersMap = await client.listScorers();\n const scorerIds = Object.keys(scorersMap ?? {});\n\n if (scorerIds.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n // Fetch summary stats first to determine which scorers have data\n const summaryResults = await Promise.all(\n scorerIds.map(async scorerId => {\n const [avg, min, max, count] = await Promise.all([\n client.getScoreAggregate({ scorerId, aggregation: 'avg', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'min', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'max', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'count', filters }),\n ]);\n return {\n scorer: scorerId,\n avg: avg.value ?? 0,\n min: min.value ?? 0,\n max: max.value ?? 0,\n count: count.value ?? 0,\n };\n }),\n );\n\n const summaryData: ScorerSummary[] = summaryResults.filter(s => s.count > 0);\n const scorerNames = summaryData.map(s => s.scorer);\n\n if (summaryData.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n const totalWeighted = summaryData.reduce((s, d) => s + d.avg * d.count, 0);\n const totalCount = summaryData.reduce((s, d) => s + d.count, 0);\n const avgScore = totalCount ? Math.round((totalWeighted / totalCount) * 100) / 100 : 0;\n\n const interval = '1h';\n\n // Fetch hourly time series from the full period for active scorers\n const timeSeriesResults = await Promise.all(\n scorerNames.map(scorerId =>\n client.getScoreTimeSeries({\n scorerId,\n interval,\n aggregation: 'avg',\n filters,\n }),\n ),\n );\n\n // Collapse all days into a single 24-hour view (00:00–23:00).\n // For each hour-of-day, average the values across all days in the range.\n const hourBuckets = new Map<number, Map<string, { sum: number; count: number }>>();\n\n for (let i = 0; i < scorerNames.length; i++) {\n const scorerId = scorerNames[i];\n const series = timeSeriesResults[i]?.series ?? [];\n for (const s of series) {\n for (const point of s.points) {\n const ts = new Date(point.timestamp);\n const hourKey = ts.getHours() * 60 + ts.getMinutes();\n const scorerMap = getOrCreate(hourBuckets, hourKey, () => new Map());\n const acc = getOrCreate(scorerMap, scorerId, () => ({ sum: 0, count: 0 }));\n\n acc.sum += point.value;\n acc.count += 1;\n }\n }\n }\n\n // Build sorted 24h chart data\n const overTimeData: ScoresOverTimePoint[] = Array.from(hourBuckets.entries())\n .sort(([a], [b]) => a - b)\n .map(([hourKey, scorerMap]) => {\n const point: ScoresOverTimePoint = {\n time: formatDate(new Date(2000, 0, 1, Math.floor(hourKey / 60), hourKey % 60), 'time') ?? '',\n };\n for (const [scorerId, acc] of scorerMap) {\n point[scorerId] = +(acc.sum / acc.count).toFixed(2);\n }\n return point;\n });\n\n return {\n summaryData,\n overTimeData,\n scorerNames,\n avgScore,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface TokenUsageByAgentRow {\n name: string;\n total: number;\n input: number;\n output: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useTokenUsageByAgentMetrics<TData = TokenUsageByAgentRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageByAgentRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-by-agent', filterKey],\n queryFn: async (): Promise<TokenUsageByAgentRow[]> => {\n const breakdownBase = {\n groupBy: ['entityName'],\n aggregation: 'sum' as const,\n orderDirection: 'DESC' as const,\n filters,\n };\n // total_input/total_output estimatedCost already rolls up cache + other detail costs.\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_input_tokens'] }),\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_output_tokens'] }),\n ]);\n\n type AgentEntry = { input: number; output: number; cost: number | null; costUnit: string | null };\n\n const agentMap = new Map<string, AgentEntry>();\n\n const ensure = (name: string): AgentEntry =>\n getOrCreate(agentMap, name, () => ({ input: 0, output: 0, cost: null, costUnit: null }));\n\n const addCost = (entry: AgentEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.output = group.value;\n addCost(entry, group);\n }\n\n return Array.from(agentMap.entries())\n .map(([name, vals]) => ({\n name,\n input: vals.input,\n output: vals.output,\n total: vals.input + vals.output,\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => b.total - a.total);\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport type TokenUsageTimeSeriesInterval = MetricsInterval;\n\nexport interface TokenTimelinePoint {\n time: string;\n tsMs: number;\n input: number;\n output: number;\n total: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport interface TokenUsageTimeSeriesData {\n data: TokenTimelinePoint[];\n interval: TokenUsageTimeSeriesInterval;\n}\n\ntype TimeSeriesPoint = {\n timestamp: string | Date;\n value: number;\n estimatedCost?: number | null;\n};\n\ntype SeriesWithCost = {\n costUnit?: string | null;\n points: TimeSeriesPoint[];\n};\n\ntype TokenTimelineAccumulator = {\n tsMs: number;\n input: number;\n output: number;\n cost: number | null;\n costUnits: Set<string>;\n hasUnknownCostUnit: boolean;\n};\n\nfunction addSeriesPoints(\n pointMap: Map<number, TokenTimelineAccumulator>,\n series: SeriesWithCost | undefined,\n key: 'input' | 'output',\n) {\n for (const point of series?.points ?? []) {\n const tsMs = new Date(point.timestamp).getTime();\n if (!Number.isFinite(tsMs)) continue;\n\n const existing = pointMap.get(tsMs) ?? {\n tsMs,\n input: 0,\n output: 0,\n cost: null,\n costUnits: new Set<string>(),\n hasUnknownCostUnit: false,\n };\n\n existing[key] += point.value;\n\n if (point.estimatedCost != null) {\n existing.cost = (existing.cost ?? 0) + point.estimatedCost;\n if (series?.costUnit) {\n existing.costUnits.add(series.costUnit);\n } else {\n existing.hasUnknownCostUnit = true;\n }\n }\n\n pointMap.set(tsMs, existing);\n }\n}\n\nfunction toCostUnit(entry: TokenTimelineAccumulator): string | null {\n if (entry.cost == null || entry.hasUnknownCostUnit || entry.costUnits.size !== 1) return null;\n return [...entry.costUnits][0] ?? null;\n}\n\nexport function useTokenUsageTimeSeries<TData = TokenUsageTimeSeriesData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageTimeSeriesData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-timeseries', filterKey, interval],\n queryFn: async (): Promise<TokenUsageTimeSeriesData> => {\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricTimeSeries({\n name: ['mastra_model_total_input_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n client.getMetricTimeSeries({\n name: ['mastra_model_total_output_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n ]);\n\n const pointMap = new Map<number, TokenTimelineAccumulator>();\n addSeriesPoints(pointMap, inputRes.series[0], 'input');\n addSeriesPoints(pointMap, outputRes.series[0], 'output');\n\n const data = Array.from(pointMap.values())\n .sort((a, b) => a.tsMs - b.tsMs)\n .map(point => {\n const ts = new Date(point.tsMs);\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs: point.tsMs,\n input: point.input,\n output: point.output,\n total: point.input + point.output,\n cost: point.cost,\n costUnit: toCostUnit(point),\n };\n });\n\n return { data, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ActiveThreadRow {\n threadId: string;\n resourceId: string | null;\n runs: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Active Threads — the threads with the most agent runs in the selected\n * range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the\n * query never returns the full thread set when cardinality is in the millions.\n *\n * Tokens + cost are joined in from parallel breakdowns on the same `threadId`\n * grouping so we don't need any new backend aggregation support. */\nexport function useTopActiveThreadsMetrics<TData = ActiveThreadRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ActiveThreadRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-active-threads', filterKey],\n queryFn: async (): Promise<ActiveThreadRow[]> => {\n const breakdownBase = {\n groupBy: ['threadId', 'resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [runsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying thread set has very\n // high cardinality. Threads that are top-N by runs but not by tokens\n // will display 0 tokens (an acceptable approximation in exchange for\n // a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byThread = new Map<string, Entry>();\n\n const ensure = (threadId: string): Entry =>\n getOrCreate(byThread, threadId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const threadId = group.dimensions.threadId;\n if (!threadId) continue;\n const entry = ensure(threadId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return runsRes.groups\n .filter(group => !!group.dimensions.threadId)\n .map(group => {\n const threadId = group.dimensions.threadId as string;\n const extra = byThread.get(threadId);\n return {\n threadId,\n resourceId: (group.dimensions.resourceId as string | undefined) ?? null,\n runs: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ResourceThreadsRow {\n resourceId: string;\n threadCount: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Resources by Thread Count — the resources with the most distinct threads\n * in the selected range. Uses `count_distinct(threadId)` per `resourceId`,\n * with server-side TopK (`ORDER BY value DESC LIMIT 20`).\n *\n * Tokens + cost are joined in from parallel breakdowns on `resourceId` so the\n * table can show cost/usage without a separate backend aggregation. */\nexport function useTopResourcesByThreadsMetrics<TData = ResourceThreadsRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ResourceThreadsRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-resources-by-threads', filterKey],\n queryFn: async (): Promise<ResourceThreadsRow[]> => {\n const breakdownBase = {\n groupBy: ['resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [threadsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying resource set has very\n // high cardinality. Resources that are top-N by thread count but not by\n // tokens will display 0 tokens (an acceptable approximation in exchange\n // for a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byResource = new Map<string, Entry>();\n\n const ensure = (resourceId: string): Entry =>\n getOrCreate(byResource, resourceId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const resourceId = group.dimensions.resourceId;\n if (!resourceId) continue;\n const entry = ensure(resourceId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return threadsRes.groups\n .filter(group => !!group.dimensions.resourceId)\n .map(group => {\n const resourceId = group.dimensions.resourceId as string;\n const extra = byResource.get(resourceId);\n return {\n resourceId,\n threadCount: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Tokens — sum of all input + output tokens */\nexport interface TotalTokensKpi {\n value: number | null;\n previousValue: number | null;\n changePercent: number | null;\n}\n\nexport function useTotalTokensKpiMetrics<TData = TotalTokensKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TotalTokensKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'total-tokens-kpi', filterKey],\n queryFn: async (): Promise<TotalTokensKpi> => {\n const [input, output] = await Promise.all([\n client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n client.getMetricAggregate({\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n ]);\n\n const hasCurrent = input.value != null || output.value != null;\n const hasPrevious = input.previousValue != null || output.previousValue != null;\n const value = (input.value ?? 0) + (output.value ?? 0);\n const previousValue = (input.previousValue ?? 0) + (output.previousValue ?? 0);\n const changePercent = hasPrevious && previousValue > 0 ? ((value - previousValue) / previousValue) * 100 : null;\n\n return {\n value: hasCurrent ? value : null,\n previousValue: hasPrevious ? previousValue : null,\n changePercent,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface VolumeRow {\n name: string;\n completed: number;\n errors: number;\n}\n\nasync function fetchVolume(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n): Promise<VolumeRow[]> {\n const res = await client.getMetricBreakdown({\n name: [metricName],\n groupBy: ['entityName', 'status'],\n aggregation: 'count',\n orderDirection: 'DESC',\n filters,\n });\n\n const map = new Map<string, { completed: number; errors: number }>();\n\n for (const group of res.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const status = group.dimensions.status ?? 'ok';\n const entry = getOrCreate(map, name, () => ({ completed: 0, errors: 0 }));\n\n if (status === 'error') {\n entry.errors += group.value;\n } else {\n entry.completed += group.value;\n }\n }\n\n return Array.from(map.entries())\n .map(([name, vals]) => ({ name, ...vals }))\n .sort((a, b) => b.completed + b.errors - (a.completed + a.errors));\n}\n\nexport interface TraceVolumeData {\n agentData: VolumeRow[];\n workflowData: VolumeRow[];\n toolData: VolumeRow[];\n}\n\nexport function useTraceVolumeMetrics<TData = TraceVolumeData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TraceVolumeData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'trace-volume', filterKey],\n queryFn: async (): Promise<TraceVolumeData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchVolume(client, 'mastra_agent_duration_ms', filters),\n fetchVolume(client, 'mastra_workflow_duration_ms', filters),\n fetchVolume(client, 'mastra_tool_duration_ms', filters),\n ]);\n return { agentData, workflowData, toolData };\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["useRef","useMemo","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","TOP_N","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery"],"sources":["../../../src/hooks/metrics/metrics-query-filters.ts","../../../src/hooks/shared/date-format.ts","../../../src/hooks/metrics/metrics-interval.ts","../../../src/hooks/metrics/use-active-resources-kpi-metrics.tsx","../../../src/hooks/metrics/use-active-threads-kpi-metrics.tsx","../../../src/hooks/metrics/use-agent-runs-kpi-metrics.tsx","../../../src/hooks/metrics/use-latency-metrics.tsx","../../../src/hooks/metrics/use-model-cost-kpi-metrics.tsx","../../../src/hooks/shared/cost.ts","../../../src/hooks/metrics/use-model-usage-cost-metrics.tsx","../../../src/hooks/metrics/use-scores-metrics.tsx","../../../src/hooks/metrics/use-token-usage-by-agent-metrics.tsx","../../../src/hooks/metrics/use-token-usage-timeseries.tsx","../../../src/hooks/metrics/use-top-active-threads-metrics.tsx","../../../src/hooks/metrics/use-top-resources-by-threads-metrics.tsx","../../../src/hooks/metrics/use-total-tokens-kpi-metrics.tsx","../../../src/hooks/metrics/use-trace-volume-metrics.tsx"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport { useMemo, useRef } from 'react';\n\nexport type MetricsDatePreset = '24h' | '3d' | '7d' | '14d' | '30d' | 'custom';\n\nexport type MetricsDateRange = { from?: Date; to?: Date };\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\nexport interface MetricsQueryFiltersInput {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n dimensionalFilter: MetricsDimensionalFilter;\n /** Stable JSON representation of `dimensionalFilter`, safe for query keys. */\n dimensionalFilterKey: string;\n}\n\ntype Timestamp = { start: Date; end: Date };\n\nexport interface MetricsQueryFilters {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n timestamp: Timestamp;\n filters: MetricsDimensionalFilter & { timestamp: Timestamp };\n dimensionalFilter: MetricsDimensionalFilter;\n filterKey: string;\n}\n\nconst DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nconst PRESET_MS: Record<string, number> = {\n '24h': DEFAULT_WINDOW_MS,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '14d': 14 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n};\n\nfunction buildTimestamp(\n preset: MetricsDatePreset,\n customRange: MetricsDateRange | undefined,\n anchor: number,\n): Timestamp {\n if (preset !== 'custom') {\n const ms = PRESET_MS[preset] ?? DEFAULT_WINDOW_MS;\n return { start: new Date(anchor - ms), end: new Date(anchor) };\n }\n return {\n start: customRange?.from ?? new Date(anchor - DEFAULT_WINDOW_MS),\n end: customRange?.to ?? new Date(anchor),\n };\n}\n\n/**\n * Compose a ready-to-use metrics filter object from a date window and a\n * dimensional filter. Pass the result to the metrics hooks.\n *\n * Stability guarantees (important for react-query):\n * - `timestamp` is frozen at the moment the inputs change and does NOT update\n * on every render. Otherwise each render would mint a new `new Date()` and\n * every metrics query would re-fetch on every keystroke.\n * - `filters` and `filterKey` are referentially stable while inputs are\n * unchanged, so `queryKey` hashing is cheap and caches hit.\n */\nexport function useMetricsQueryFilters({\n datePreset,\n customRange,\n dimensionalFilter,\n dimensionalFilterKey,\n}: MetricsQueryFiltersInput): MetricsQueryFilters {\n // Anchor the \"now\" used for preset windows. We only recompute when the\n // preset or custom range changes — this gives a stable timestamp per query\n // boundary rather than a new Date on every render.\n const anchorRef = useRef<{ key: string; anchor: number } | null>(null);\n const windowKey =\n datePreset === 'custom'\n ? `custom:${customRange?.from?.getTime() ?? ''}:${customRange?.to?.getTime() ?? ''}`\n : `preset:${datePreset}`;\n if (!anchorRef.current || anchorRef.current.key !== windowKey) {\n anchorRef.current = { key: windowKey, anchor: Date.now() };\n }\n const anchor = anchorRef.current.anchor;\n\n const timestamp = useMemo(() => buildTimestamp(datePreset, customRange, anchor), [datePreset, customRange, anchor]);\n\n const filters = useMemo(\n () => ({ timestamp, ...dimensionalFilter }),\n // dimensionalFilterKey is a stringified digest, so this dep set gives a\n // stable ref while content is unchanged.\n [timestamp, dimensionalFilterKey],\n );\n\n // filterKey combines window + dimensions so react-query keys are cheap.\n const filterKey = useMemo(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey]);\n\n return { datePreset, customRange, timestamp, filters, dimensionalFilter, filterKey };\n}\n","export type DateInput = Date | string | number | null | undefined;\nexport type DatePreset =\n | 'date'\n | 'date-time'\n | 'date-time-seconds'\n | 'day-time-seconds'\n | 'time'\n | 'time-seconds'\n | 'relative-time'\n | 'relative-long';\n\ntype FormatOptions = { locale?: string; now?: Date | number; timeZone?: string };\n\nexport function toDate(value: DateInput): Date | undefined {\n if (value == null) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nconst PRESET_OPTIONS = {\n time: { hour: 'numeric', minute: '2-digit' },\n 'time-seconds': { hour: 'numeric', minute: '2-digit', second: '2-digit' },\n 'date-time': { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' },\n 'date-time-seconds': {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n },\n 'day-time-seconds': { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit' },\n calendar: { year: 'numeric', month: 'numeric', day: 'numeric', calendar: 'gregory', numberingSystem: 'latn' },\n dayMonth: { month: 'short', day: 'numeric' },\n dayMonthYear: { month: 'short', day: 'numeric', year: 'numeric' },\n precise: {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n },\n timePrecise: { hour: 'numeric', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3 },\n} satisfies Record<string, Intl.DateTimeFormatOptions>;\n\ntype FormatterKey = keyof typeof PRESET_OPTIONS;\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\nfunction getFormatter(key: FormatterKey, locale?: string, timeZone?: string) {\n const cacheKey = `${locale ?? ''}|${timeZone ?? ''}|${key}`;\n let formatter = formatters.get(cacheKey);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...PRESET_OPTIONS[key], timeZone });\n formatters.set(cacheKey, formatter);\n }\n return formatter;\n}\n\nfunction calendarDate(date: Date, timeZone?: string) {\n const parts = getFormatter('calendar', 'en-US', timeZone).formatToParts(date);\n return {\n year: parts.find(part => part.type === 'year')?.value,\n month: parts.find(part => part.type === 'month')?.value,\n day: parts.find(part => part.type === 'day')?.value,\n };\n}\n\n/** Short absolute date without time: `Sep 24` this year, `Sep 24, 2025` otherwise. */\nexport function formatShortDate(value: DateInput, { locale, now, timeZone }: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const reference = new Date(now ?? Date.now());\n const key =\n calendarDate(date, timeZone).year === calendarDate(reference, timeZone).year ? 'dayMonth' : 'dayMonthYear';\n return getFormatter(key, locale, timeZone).format(date);\n}\n\nconst LONG_RELATIVE_UNITS: Array<[Intl.RelativeTimeFormatUnit, number]> = [\n ['year', 365 * 86_400],\n ['month', 30 * 86_400],\n ['week', 7 * 86_400],\n ['day', 86_400],\n ['hour', 3_600],\n ['minute', 60],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\n\nfunction getRelativeFormatter(locale?: string) {\n const key = locale ?? '';\n let formatter = relativeFormatters.get(key);\n if (!formatter) {\n formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n relativeFormatters.set(key, formatter);\n }\n return formatter;\n}\n\n/**\n * Uses the browser locale unless `locale` is given.\n * - `date`: date only; omits the year when it matches `now` in the requested timezone\n * - `date-time`: date, year and time to minutes, including historical dates\n * - `date-time-seconds`: date, year and time to seconds\n * - `day-time-seconds`: month, day and time to seconds, without the year\n * - `time`: time to minutes, without a date\n * - `time-seconds`: time to seconds, without a date\n * - `relative-time`: short relative label; delegates to `date` at seven days\n */\nexport function formatDate(value: DateInput, preset: DatePreset, options: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const { locale, now, timeZone } = options;\n\n if (preset === 'relative-time') {\n const diff = date.getTime() - new Date(now ?? Date.now()).getTime();\n const abs = Math.abs(diff);\n if (abs < 5_000) return 'just now';\n const units = [\n { limit: 60_000, size: 1_000, unit: 's' },\n { limit: 3_600_000, size: 60_000, unit: 'm' },\n { limit: 86_400_000, size: 3_600_000, unit: 'h' },\n { limit: 7 * 86_400_000, size: 86_400_000, unit: 'd' },\n ];\n const match = units.find(({ limit }) => abs < limit);\n if (!match) return formatDate(date, 'date', options);\n const label = `${Math.floor(abs / match.size)}${match.unit}`;\n return diff < 0 ? `${label} ago` : `in ${label}`;\n }\n if (preset === 'relative-long') {\n const seconds = (date.getTime() - new Date(now ?? Date.now()).getTime()) / 1000;\n const [unit, size] = LONG_RELATIVE_UNITS.find(([, size]) => Math.abs(seconds) >= size) ?? ['second', 1];\n return getRelativeFormatter(locale).format(Math.round(seconds / size), unit);\n }\n if (preset === 'date') return formatShortDate(date, options);\n\n return getFormatter(preset, locale, timeZone).format(date);\n}\n\n/** Locale-aware compact date range, e.g. `Sep 2 – 5, 2026`. */\nexport function formatDateRange(start: DateInput, end: DateInput, options: Omit<FormatOptions, 'now'> = {}) {\n const from = toDate(start);\n const to = toDate(end);\n if (!from || !to) return undefined;\n return getFormatter('dayMonthYear', options.locale, options.timeZone)\n .formatRange(from, to)\n .replace(/\\u2009/g, ' ');\n}\n\n/** Date and time down to milliseconds, for trace debugging. `withDate: false` keeps only the time. */\nexport function formatTimestampPrecise(\n value: DateInput,\n { locale, withDate = true }: { locale?: string; withDate?: boolean } = {},\n) {\n const date = toDate(value);\n return date ? getFormatter(withDate ? 'precise' : 'timePrecise', locale).format(date) : undefined;\n}\n","import { formatDate, formatShortDate } from '../shared/date-format';\n\nexport type MetricsInterval = '1h' | '1d';\n\nconst HOURLY_MAX_RANGE_MS = 48 * 60 * 60 * 1000;\n\n/** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */\nexport function chooseMetricsInterval({ start, end }: { start: Date; end: Date }): MetricsInterval {\n return end.getTime() - start.getTime() <= HOURLY_MAX_RANGE_MS ? '1h' : '1d';\n}\n\nexport function formatMetricsBucketLabel(ts: Date, interval: MetricsInterval): string {\n if (interval === '1h') {\n return formatDate(ts, 'time') ?? '';\n }\n return formatShortDate(ts) ?? '';\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Resources — number of distinct resource IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveResourcesKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-resources-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'resourceId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Threads — number of distinct thread IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveThreadsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-threads-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Agent Runs — count of agent duration metric observations */\nexport function useAgentRunsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'agent-runs-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface LatencyPoint {\n [key: string]: unknown;\n time: string;\n /** Raw timestamp (ms since epoch) for the bucket this point represents.\n * Used by drilldown clicks to compute a narrow time window. */\n tsMs: number;\n p50: number;\n p95: number;\n}\n\nasync function fetchPercentiles(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n interval: MetricsInterval,\n): Promise<LatencyPoint[]> {\n const res = await client.getMetricPercentiles({\n name: metricName,\n percentiles: [0.5, 0.95],\n interval,\n filters,\n });\n\n const p50Series = res.series.find(s => s.percentile === 0.5);\n const p95Series = res.series.find(s => s.percentile === 0.95);\n\n if (!p50Series || !p95Series) return [];\n\n const p95Map = new Map(p95Series.points.map(p => [new Date(p.timestamp).getTime(), p.value]));\n\n return p50Series.points.map(p => {\n const ts = new Date(p.timestamp);\n const tsMs = ts.getTime();\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs,\n p50: Math.round(p.value),\n p95: Math.round(p95Map.get(tsMs) ?? 0),\n };\n });\n}\n\nexport interface LatencyMetricsData {\n agentData: LatencyPoint[];\n workflowData: LatencyPoint[];\n toolData: LatencyPoint[];\n interval: MetricsInterval;\n}\n\nexport function useLatencyMetrics<TData = LatencyMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<LatencyMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'latency', filterKey, interval],\n queryFn: async (): Promise<LatencyMetricsData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchPercentiles(client, 'mastra_agent_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_workflow_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_tool_duration_ms', filters, interval),\n ]);\n return { agentData, workflowData, toolData, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Model Cost — sum of estimatedCost across input and output token metrics */\nexport interface ModelCostKpi {\n cost: number | null;\n costUnit: string | null;\n previousCost: number | null;\n costChangePercent: number | null;\n}\n\nexport function useModelCostKpiMetrics<TData = ModelCostKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelCostKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-cost-kpi', filterKey],\n queryFn: async (): Promise<ModelCostKpi> => {\n const res = await client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens', 'mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n });\n\n return {\n cost: res.estimatedCost ?? null,\n costUnit: res.costUnit ?? null,\n previousCost: res.previousEstimatedCost ?? null,\n costChangePercent: res.costChangePercent ?? null,\n };\n },\n ...queryOptions,\n });\n}\n","export interface CompactNumberFormatOptions {\n currency?: string;\n}\n\nconst compactNumber = new Intl.NumberFormat('en-US', { notation: 'compact', maximumSignificantDigits: 3 });\nconst fullNumber = new Intl.NumberFormat('en-US');\n\nconst currencyCodes = new Set(Intl.supportedValuesOf('currency'));\n\nfunction isCurrency(code: string | undefined): code is string {\n return code !== undefined && currencyCodes.has(code.toUpperCase());\n}\n\nfunction money(currency: string, options: Intl.NumberFormatOptions) {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency, ...options });\n}\n\nexport function formatCompactNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return compactNumber.format(value);\n const size = Math.abs(value);\n if (size < 100) return formatFullNumber(value, { currency });\n if (size < 1000) return money(currency, { maximumFractionDigits: 0 }).format(value);\n return money(currency, { notation: 'compact', maximumSignificantDigits: 3 }).format(value);\n}\n\nexport function formatFullNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return fullNumber.format(value);\n const formatter = money(currency, {});\n const smallestUnit = 10 ** -(formatter.resolvedOptions().maximumFractionDigits ?? 2);\n if (value !== 0 && Math.abs(value) < smallestUnit) {\n return `${value < 0 ? '-' : ''}<${formatter.format(smallestUnit)}`;\n }\n return formatter.format(value);\n}\n\nexport function formatCost(value: number, unit?: string | null): string {\n const isUsd = !unit || unit.toLowerCase() === 'usd';\n const amount = value > 0 && value < 0.01 ? '<0.01' : value.toFixed(2);\n if (!isUsd) return `${amount} ${unit}`;\n return amount.startsWith('<') ? '<$0.01' : `$${amount}`;\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatCompactNumber } from '../shared/cost';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ModelUsageRow {\n model: string;\n provider?: string;\n input: string;\n output: string;\n cacheRead: string;\n cacheWrite: string;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useModelUsageCostMetrics<TData = ModelUsageRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelUsageRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-usage-cost', filterKey],\n queryFn: async (): Promise<ModelUsageRow[]> => {\n const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all(\n (\n [\n 'mastra_model_total_input_tokens',\n 'mastra_model_total_output_tokens',\n 'mastra_model_input_cache_read_tokens',\n 'mastra_model_input_cache_write_tokens',\n ] as const\n ).map(name =>\n client.getMetricBreakdown({\n name: [name],\n groupBy: ['model', 'provider'],\n aggregation: 'sum',\n orderDirection: 'DESC',\n filters,\n }),\n ),\n );\n\n if (!inputRes || !outputRes || !cacheReadRes || !cacheWriteRes) return [];\n\n type ModelEntry = {\n model: string;\n provider: string | undefined;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number | null;\n costUnit: string | null;\n };\n\n const modelMap = new Map<string, ModelEntry>();\n\n const ensureModel = (dimensions: { model?: string | null; provider?: string | null }): ModelEntry => {\n const model = dimensions.model ?? 'unknown';\n const provider = dimensions.provider ?? undefined;\n return getOrCreate(modelMap, `${model}\\u0000${provider ?? ''}`, () => ({\n model,\n provider,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n cost: null,\n costUnit: null,\n }));\n };\n\n // total_input/total_output estimatedCost already rolls up cache + other detail\n // costs. The cache breakdowns are kept for their token counts only.\n const addCost = (entry: ModelEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.output = group.value;\n addCost(entry, group);\n }\n for (const group of cacheReadRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheRead = group.value;\n }\n for (const group of cacheWriteRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheWrite = group.value;\n }\n\n return Array.from(modelMap.values())\n .map(vals => ({\n model: vals.model,\n ...(vals.provider ? { provider: vals.provider } : {}),\n input: formatCompactNumber(vals.input),\n output: formatCompactNumber(vals.output),\n cacheRead: formatCompactNumber(vals.cacheRead),\n cacheWrite: formatCompactNumber(vals.cacheWrite),\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => a.model.localeCompare(b.model) || (a.provider ?? '').localeCompare(b.provider ?? ''));\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatDate } from '../shared/date-format';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ScorerSummary {\n scorer: string;\n avg: number;\n min: number;\n max: number;\n count: number;\n}\n\nexport interface ScoresOverTimePoint {\n time: string;\n [scorer: string]: string | number;\n}\n\nexport interface ScoresMetricsData {\n summaryData: ScorerSummary[];\n overTimeData: ScoresOverTimePoint[];\n scorerNames: string[];\n avgScore: number | null;\n}\n\nexport function useScoresMetrics<TData = ScoresMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ScoresMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { datePreset, customRange, timestamp, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'scores-card', datePreset, customRange],\n queryFn: async (): Promise<ScoresMetricsData> => {\n const filters = {\n timestamp: { start: timestamp.start, end: timestamp.end },\n };\n\n const scorersMap = await client.listScorers();\n const scorerIds = Object.keys(scorersMap ?? {});\n\n if (scorerIds.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n // Fetch summary stats first to determine which scorers have data\n const summaryResults = await Promise.all(\n scorerIds.map(async scorerId => {\n const [avg, min, max, count] = await Promise.all([\n client.getScoreAggregate({ scorerId, aggregation: 'avg', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'min', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'max', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'count', filters }),\n ]);\n return {\n scorer: scorerId,\n avg: avg.value ?? 0,\n min: min.value ?? 0,\n max: max.value ?? 0,\n count: count.value ?? 0,\n };\n }),\n );\n\n const summaryData: ScorerSummary[] = summaryResults.filter(s => s.count > 0);\n const scorerNames = summaryData.map(s => s.scorer);\n\n if (summaryData.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n const totalWeighted = summaryData.reduce((s, d) => s + d.avg * d.count, 0);\n const totalCount = summaryData.reduce((s, d) => s + d.count, 0);\n const avgScore = totalCount ? Math.round((totalWeighted / totalCount) * 100) / 100 : 0;\n\n const interval = '1h';\n\n // Fetch hourly time series from the full period for active scorers\n const timeSeriesResults = await Promise.all(\n scorerNames.map(scorerId =>\n client.getScoreTimeSeries({\n scorerId,\n interval,\n aggregation: 'avg',\n filters,\n }),\n ),\n );\n\n // Collapse all days into a single 24-hour view (00:00–23:00).\n // For each hour-of-day, average the values across all days in the range.\n const hourBuckets = new Map<number, Map<string, { sum: number; count: number }>>();\n\n for (let i = 0; i < scorerNames.length; i++) {\n const scorerId = scorerNames[i];\n const series = timeSeriesResults[i]?.series ?? [];\n for (const s of series) {\n for (const point of s.points) {\n const ts = new Date(point.timestamp);\n const hourKey = ts.getHours() * 60 + ts.getMinutes();\n const scorerMap = getOrCreate(hourBuckets, hourKey, () => new Map());\n const acc = getOrCreate(scorerMap, scorerId, () => ({ sum: 0, count: 0 }));\n\n acc.sum += point.value;\n acc.count += 1;\n }\n }\n }\n\n // Build sorted 24h chart data\n const overTimeData: ScoresOverTimePoint[] = Array.from(hourBuckets.entries())\n .sort(([a], [b]) => a - b)\n .map(([hourKey, scorerMap]) => {\n const point: ScoresOverTimePoint = {\n time: formatDate(new Date(2000, 0, 1, Math.floor(hourKey / 60), hourKey % 60), 'time') ?? '',\n };\n for (const [scorerId, acc] of scorerMap) {\n point[scorerId] = +(acc.sum / acc.count).toFixed(2);\n }\n return point;\n });\n\n return {\n summaryData,\n overTimeData,\n scorerNames,\n avgScore,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface TokenUsageByAgentRow {\n name: string;\n total: number;\n input: number;\n output: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useTokenUsageByAgentMetrics<TData = TokenUsageByAgentRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageByAgentRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-by-agent', filterKey],\n queryFn: async (): Promise<TokenUsageByAgentRow[]> => {\n const breakdownBase = {\n groupBy: ['entityName'],\n aggregation: 'sum' as const,\n orderDirection: 'DESC' as const,\n filters,\n };\n // total_input/total_output estimatedCost already rolls up cache + other detail costs.\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_input_tokens'] }),\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_output_tokens'] }),\n ]);\n\n type AgentEntry = { input: number; output: number; cost: number | null; costUnit: string | null };\n\n const agentMap = new Map<string, AgentEntry>();\n\n const ensure = (name: string): AgentEntry =>\n getOrCreate(agentMap, name, () => ({ input: 0, output: 0, cost: null, costUnit: null }));\n\n const addCost = (entry: AgentEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.output = group.value;\n addCost(entry, group);\n }\n\n return Array.from(agentMap.entries())\n .map(([name, vals]) => ({\n name,\n input: vals.input,\n output: vals.output,\n total: vals.input + vals.output,\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => b.total - a.total);\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport type TokenUsageTimeSeriesInterval = MetricsInterval;\n\nexport interface TokenTimelinePoint {\n time: string;\n tsMs: number;\n input: number;\n output: number;\n total: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport interface TokenUsageTimeSeriesData {\n data: TokenTimelinePoint[];\n interval: TokenUsageTimeSeriesInterval;\n}\n\ntype TimeSeriesPoint = {\n timestamp: string | Date;\n value: number;\n estimatedCost?: number | null;\n};\n\ntype SeriesWithCost = {\n costUnit?: string | null;\n points: TimeSeriesPoint[];\n};\n\ntype TokenTimelineAccumulator = {\n tsMs: number;\n input: number;\n output: number;\n cost: number | null;\n costUnits: Set<string>;\n hasUnknownCostUnit: boolean;\n};\n\nfunction addSeriesPoints(\n pointMap: Map<number, TokenTimelineAccumulator>,\n series: SeriesWithCost | undefined,\n key: 'input' | 'output',\n) {\n for (const point of series?.points ?? []) {\n const tsMs = new Date(point.timestamp).getTime();\n if (!Number.isFinite(tsMs)) continue;\n\n const existing = pointMap.get(tsMs) ?? {\n tsMs,\n input: 0,\n output: 0,\n cost: null,\n costUnits: new Set<string>(),\n hasUnknownCostUnit: false,\n };\n\n existing[key] += point.value;\n\n if (point.estimatedCost != null) {\n existing.cost = (existing.cost ?? 0) + point.estimatedCost;\n if (series?.costUnit) {\n existing.costUnits.add(series.costUnit);\n } else {\n existing.hasUnknownCostUnit = true;\n }\n }\n\n pointMap.set(tsMs, existing);\n }\n}\n\nfunction toCostUnit(entry: TokenTimelineAccumulator): string | null {\n if (entry.cost == null || entry.hasUnknownCostUnit || entry.costUnits.size !== 1) return null;\n return [...entry.costUnits][0] ?? null;\n}\n\nexport function useTokenUsageTimeSeries<TData = TokenUsageTimeSeriesData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageTimeSeriesData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-timeseries', filterKey, interval],\n queryFn: async (): Promise<TokenUsageTimeSeriesData> => {\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricTimeSeries({\n name: ['mastra_model_total_input_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n client.getMetricTimeSeries({\n name: ['mastra_model_total_output_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n ]);\n\n const pointMap = new Map<number, TokenTimelineAccumulator>();\n addSeriesPoints(pointMap, inputRes.series[0], 'input');\n addSeriesPoints(pointMap, outputRes.series[0], 'output');\n\n const data = Array.from(pointMap.values())\n .sort((a, b) => a.tsMs - b.tsMs)\n .map(point => {\n const ts = new Date(point.tsMs);\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs: point.tsMs,\n input: point.input,\n output: point.output,\n total: point.input + point.output,\n cost: point.cost,\n costUnit: toCostUnit(point),\n };\n });\n\n return { data, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ActiveThreadRow {\n threadId: string;\n resourceId: string | null;\n runs: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Active Threads — the threads with the most agent runs in the selected\n * range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the\n * query never returns the full thread set when cardinality is in the millions.\n *\n * Tokens + cost are joined in from parallel breakdowns on the same `threadId`\n * grouping so we don't need any new backend aggregation support. */\nexport function useTopActiveThreadsMetrics<TData = ActiveThreadRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ActiveThreadRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-active-threads', filterKey],\n queryFn: async (): Promise<ActiveThreadRow[]> => {\n const breakdownBase = {\n groupBy: ['threadId', 'resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [runsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying thread set has very\n // high cardinality. Threads that are top-N by runs but not by tokens\n // will display 0 tokens (an acceptable approximation in exchange for\n // a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byThread = new Map<string, Entry>();\n\n const ensure = (threadId: string): Entry =>\n getOrCreate(byThread, threadId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const threadId = group.dimensions.threadId;\n if (!threadId) continue;\n const entry = ensure(threadId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return runsRes.groups\n .filter(group => !!group.dimensions.threadId)\n .map(group => {\n const threadId = group.dimensions.threadId as string;\n const extra = byThread.get(threadId);\n return {\n threadId,\n resourceId: (group.dimensions.resourceId as string | undefined) ?? null,\n runs: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ResourceThreadsRow {\n resourceId: string;\n threadCount: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Resources by Thread Count — the resources with the most distinct threads\n * in the selected range. Uses `count_distinct(threadId)` per `resourceId`,\n * with server-side TopK (`ORDER BY value DESC LIMIT 20`).\n *\n * Tokens + cost are joined in from parallel breakdowns on `resourceId` so the\n * table can show cost/usage without a separate backend aggregation. */\nexport function useTopResourcesByThreadsMetrics<TData = ResourceThreadsRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ResourceThreadsRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-resources-by-threads', filterKey],\n queryFn: async (): Promise<ResourceThreadsRow[]> => {\n const breakdownBase = {\n groupBy: ['resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [threadsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying resource set has very\n // high cardinality. Resources that are top-N by thread count but not by\n // tokens will display 0 tokens (an acceptable approximation in exchange\n // for a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byResource = new Map<string, Entry>();\n\n const ensure = (resourceId: string): Entry =>\n getOrCreate(byResource, resourceId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const resourceId = group.dimensions.resourceId;\n if (!resourceId) continue;\n const entry = ensure(resourceId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return threadsRes.groups\n .filter(group => !!group.dimensions.resourceId)\n .map(group => {\n const resourceId = group.dimensions.resourceId as string;\n const extra = byResource.get(resourceId);\n return {\n resourceId,\n threadCount: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Tokens — sum of all input + output tokens */\nexport interface TotalTokensKpi {\n value: number | null;\n previousValue: number | null;\n changePercent: number | null;\n}\n\nexport function useTotalTokensKpiMetrics<TData = TotalTokensKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TotalTokensKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'total-tokens-kpi', filterKey],\n queryFn: async (): Promise<TotalTokensKpi> => {\n const [input, output] = await Promise.all([\n client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n client.getMetricAggregate({\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n ]);\n\n const hasCurrent = input.value != null || output.value != null;\n const hasPrevious = input.previousValue != null || output.previousValue != null;\n const value = (input.value ?? 0) + (output.value ?? 0);\n const previousValue = (input.previousValue ?? 0) + (output.previousValue ?? 0);\n const changePercent = hasPrevious && previousValue > 0 ? ((value - previousValue) / previousValue) * 100 : null;\n\n return {\n value: hasCurrent ? value : null,\n previousValue: hasPrevious ? previousValue : null,\n changePercent,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface VolumeRow {\n name: string;\n completed: number;\n errors: number;\n}\n\nasync function fetchVolume(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n): Promise<VolumeRow[]> {\n const res = await client.getMetricBreakdown({\n name: [metricName],\n groupBy: ['entityName', 'status'],\n aggregation: 'count',\n orderDirection: 'DESC',\n filters,\n });\n\n const map = new Map<string, { completed: number; errors: number }>();\n\n for (const group of res.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const status = group.dimensions.status ?? 'ok';\n const entry = getOrCreate(map, name, () => ({ completed: 0, errors: 0 }));\n\n if (status === 'error') {\n entry.errors += group.value;\n } else {\n entry.completed += group.value;\n }\n }\n\n return Array.from(map.entries())\n .map(([name, vals]) => ({ name, ...vals }))\n .sort((a, b) => b.completed + b.errors - (a.completed + a.errors));\n}\n\nexport interface TraceVolumeData {\n agentData: VolumeRow[];\n workflowData: VolumeRow[];\n toolData: VolumeRow[];\n}\n\nexport function useTraceVolumeMetrics<TData = TraceVolumeData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TraceVolumeData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'trace-volume', filterKey],\n queryFn: async (): Promise<TraceVolumeData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchVolume(client, 'mastra_agent_duration_ms', filters),\n fetchVolume(client, 'mastra_workflow_duration_ms', filters),\n fetchVolume(client, 'mastra_tool_duration_ms', filters),\n ]);\n return { agentData, workflowData, toolData };\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}