@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.
- package/dist/{accumulator-BmD8-x9I.cjs → accumulator-Bjfckb5t.cjs} +5 -9
- package/dist/{accumulator-BmD8-x9I.cjs.map → accumulator-Bjfckb5t.cjs.map} +1 -1
- package/dist/{accumulator-D9jAph99.js → accumulator-DysrPe6U.js} +5 -9
- package/dist/{accumulator-D9jAph99.js.map → accumulator-DysrPe6U.js.map} +1 -1
- package/dist/chat/index.cjs +1 -1
- package/dist/chat/index.js +1 -1
- package/dist/{combine-by-ids-CcaZKGT9.js → combine-by-ids-C-0oe4eH.js} +2 -3
- package/dist/{combine-by-ids-CcaZKGT9.js.map → combine-by-ids-C-0oe4eH.js.map} +1 -1
- package/dist/{combine-by-ids-D_lp6Dvq.cjs → combine-by-ids-ERVPXXBi.cjs} +2 -3
- package/dist/{combine-by-ids-D_lp6Dvq.cjs.map → combine-by-ids-ERVPXXBi.cjs.map} +1 -1
- package/dist/{experiments-CJw1N3FB.cjs → experiments-Duv0RgkM.cjs} +12 -19
- package/dist/{experiments-CJw1N3FB.cjs.map → experiments-Duv0RgkM.cjs.map} +1 -1
- package/dist/{experiments-B7vRMK5T.js → experiments-DyecjEut.js} +12 -19
- package/dist/{experiments-B7vRMK5T.js.map → experiments-DyecjEut.js.map} +1 -1
- package/dist/{feedback-refetch-interval-XD5FVc2k.cjs → feedback-refetch-interval-BBcT9r8s.cjs} +3 -4
- package/dist/{feedback-refetch-interval-XD5FVc2k.cjs.map → feedback-refetch-interval-BBcT9r8s.cjs.map} +1 -1
- package/dist/{feedback-refetch-interval-DLHzQoVV.js → feedback-refetch-interval-C12Nzb2r.js} +3 -4
- package/dist/{feedback-refetch-interval-DLHzQoVV.js.map → feedback-refetch-interval-C12Nzb2r.js.map} +1 -1
- package/dist/hooks/agents/index.cjs +19 -37
- package/dist/hooks/agents/index.cjs.map +1 -1
- package/dist/hooks/agents/index.js +19 -37
- package/dist/hooks/agents/index.js.map +1 -1
- package/dist/hooks/auth/index.cjs +11 -21
- package/dist/hooks/auth/index.cjs.map +1 -1
- package/dist/hooks/auth/index.js +11 -21
- package/dist/hooks/auth/index.js.map +1 -1
- package/dist/hooks/capabilities/index.cjs +11 -21
- package/dist/hooks/capabilities/index.cjs.map +1 -1
- package/dist/hooks/capabilities/index.js +11 -21
- package/dist/hooks/capabilities/index.js.map +1 -1
- package/dist/hooks/configuration/index.cjs +2 -3
- package/dist/hooks/configuration/index.js +2 -3
- package/dist/hooks/datasets/index.cjs +12 -21
- package/dist/hooks/datasets/index.cjs.map +1 -1
- package/dist/hooks/datasets/index.js +12 -21
- package/dist/hooks/datasets/index.js.map +1 -1
- package/dist/hooks/embedders/index.cjs +2 -3
- package/dist/hooks/embedders/index.js +2 -3
- package/dist/hooks/experiments/index.cjs +1 -1
- package/dist/hooks/experiments/index.js +1 -1
- package/dist/hooks/feedback/index.cjs +3 -4
- package/dist/hooks/feedback/index.js +3 -4
- package/dist/hooks/llm/index.cjs +2 -3
- package/dist/hooks/llm/index.js +2 -3
- package/dist/hooks/logs/index.cjs +4 -5
- package/dist/hooks/logs/index.js +4 -5
- package/dist/hooks/mcps/index.cjs +8 -15
- package/dist/hooks/mcps/index.cjs.map +1 -1
- package/dist/hooks/mcps/index.js +8 -15
- package/dist/hooks/mcps/index.js.map +1 -1
- package/dist/hooks/memory/index.cjs +5 -9
- package/dist/hooks/memory/index.cjs.map +1 -1
- package/dist/hooks/memory/index.js +5 -9
- package/dist/hooks/memory/index.js.map +1 -1
- package/dist/hooks/metrics/index.cjs +19 -36
- package/dist/hooks/metrics/index.cjs.map +1 -1
- package/dist/hooks/metrics/index.js +19 -36
- package/dist/hooks/metrics/index.js.map +1 -1
- package/dist/hooks/processors/index.cjs +2 -3
- package/dist/hooks/processors/index.js +2 -3
- package/dist/hooks/prompt-blocks/index.cjs +3 -5
- package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
- package/dist/hooks/prompt-blocks/index.js +3 -5
- package/dist/hooks/prompt-blocks/index.js.map +1 -1
- package/dist/hooks/query/index.cjs +2 -3
- package/dist/hooks/query/index.js +2 -3
- package/dist/hooks/review/index.cjs +4 -6
- package/dist/hooks/review/index.cjs.map +1 -1
- package/dist/hooks/review/index.js +4 -6
- package/dist/hooks/review/index.js.map +1 -1
- package/dist/hooks/schedules/index.cjs +6 -10
- package/dist/hooks/schedules/index.cjs.map +1 -1
- package/dist/hooks/schedules/index.js +6 -10
- package/dist/hooks/schedules/index.js.map +1 -1
- package/dist/hooks/scores/index.cjs +8 -13
- package/dist/hooks/scores/index.cjs.map +1 -1
- package/dist/hooks/scores/index.js +8 -13
- package/dist/hooks/scores/index.js.map +1 -1
- package/dist/hooks/templates/index.cjs +2 -3
- package/dist/hooks/templates/index.js +2 -3
- package/dist/hooks/tool-providers/index.cjs +10 -19
- package/dist/hooks/tool-providers/index.cjs.map +1 -1
- package/dist/hooks/tool-providers/index.js +10 -19
- package/dist/hooks/tool-providers/index.js.map +1 -1
- package/dist/hooks/tools/index.cjs +3 -5
- package/dist/hooks/tools/index.cjs.map +1 -1
- package/dist/hooks/tools/index.js +3 -5
- package/dist/hooks/tools/index.js.map +1 -1
- package/dist/hooks/traces/index.cjs +71 -54
- package/dist/hooks/traces/index.cjs.map +1 -1
- package/dist/hooks/traces/index.d.ts +2 -0
- package/dist/hooks/traces/index.d.ts.map +1 -1
- package/dist/hooks/traces/index.js +70 -55
- package/dist/hooks/traces/index.js.map +1 -1
- package/dist/hooks/traces/use-span-aggregate.d.ts +16 -0
- package/dist/hooks/traces/use-span-aggregate.d.ts.map +1 -0
- package/dist/hooks/traces/use-trace-aggregate.d.ts +17 -0
- package/dist/hooks/traces/use-trace-aggregate.d.ts.map +1 -0
- package/dist/hooks/traces/use-trace-column-preferences-storage-key.d.ts +4 -2
- package/dist/hooks/traces/use-trace-column-preferences-storage-key.d.ts.map +1 -1
- package/dist/hooks/vectors/index.cjs +2 -3
- package/dist/hooks/vectors/index.js +2 -3
- package/dist/hooks/voice/index.cjs +3 -4
- package/dist/hooks/voice/index.js +3 -4
- package/dist/hooks/workflows/index.cjs +7 -11
- package/dist/hooks/workflows/index.cjs.map +1 -1
- package/dist/hooks/workflows/index.js +7 -11
- package/dist/hooks/workflows/index.js.map +1 -1
- package/dist/hooks/workspace/index.cjs +12 -22
- package/dist/hooks/workspace/index.cjs.map +1 -1
- package/dist/hooks/workspace/index.js +12 -22
- package/dist/hooks/workspace/index.js.map +1 -1
- package/dist/{hooks-XYsmqFCz.cjs → hooks-Bt15IwzP.cjs} +6 -9
- package/dist/{hooks-XYsmqFCz.cjs.map → hooks-Bt15IwzP.cjs.map} +1 -1
- package/dist/{hooks-DG-Y1KFe.js → hooks-Btt7PyI-.js} +6 -9
- package/dist/{hooks-DG-Y1KFe.js.map → hooks-Btt7PyI-.js.map} +1 -1
- package/dist/{hooks-BfysjY_K.js → hooks-CEikbhrN.js} +9 -15
- package/dist/{hooks-BfysjY_K.js.map → hooks-CEikbhrN.js.map} +1 -1
- package/dist/{hooks-BbUMSab8.cjs → hooks-D6LDSEcm.cjs} +9 -15
- package/dist/{hooks-BbUMSab8.cjs.map → hooks-D6LDSEcm.cjs.map} +1 -1
- package/dist/index.cjs +7 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/{map-CDv4fbu4.js → map-5-4U5rwA.js} +2 -3
- package/dist/{map-CDv4fbu4.js.map → map-5-4U5rwA.js.map} +1 -1
- package/dist/{map-wjmL1y5O.cjs → map-BGoWBTGy.cjs} +2 -3
- package/dist/{map-wjmL1y5O.cjs.map → map-BGoWBTGy.cjs.map} +1 -1
- package/dist/{mastra-client-context-Bx_g84YB.js → mastra-client-context-DQ5z_ze9.js} +2 -3
- package/dist/{mastra-client-context-Bx_g84YB.js.map → mastra-client-context-DQ5z_ze9.js.map} +1 -1
- package/dist/{mastra-client-context-DzX3f0RF.cjs → mastra-client-context-DX8wJM9p.cjs} +2 -3
- package/dist/{mastra-client-context-DzX3f0RF.cjs.map → mastra-client-context-DX8wJM9p.cjs.map} +1 -1
- package/dist/{query-utils-CcrChYgz.cjs → query-utils-BVgE_xxj.cjs} +2 -3
- package/dist/{query-utils-CcrChYgz.cjs.map → query-utils-BVgE_xxj.cjs.map} +1 -1
- package/dist/{query-utils-D1NgFnWU.js → query-utils-DvMERIwf.js} +2 -3
- package/dist/{query-utils-D1NgFnWU.js.map → query-utils-DvMERIwf.js.map} +1 -1
- package/dist/ui/index.cjs +15 -30
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +14 -28
- package/dist/ui/index.js.map +1 -1
- package/dist/{use-in-view-B6eJO9Zi.cjs → use-in-view-BxdrrnCw.cjs} +2 -3
- package/dist/{use-in-view-B6eJO9Zi.cjs.map → use-in-view-BxdrrnCw.cjs.map} +1 -1
- package/dist/{use-in-view-C9sYPGRm.js → use-in-view-CyjKdplM.js} +2 -3
- package/dist/{use-in-view-C9sYPGRm.js.map → use-in-view-CyjKdplM.js.map} +1 -1
- package/dist/{voice-BOtUdMi8.cjs → voice-Didej2E1.cjs} +5 -8
- package/dist/{voice-BOtUdMi8.cjs.map → voice-Didej2E1.cjs.map} +1 -1
- package/dist/{voice-DgirjEyH.js → voice-ugGu7VyA.js} +5 -8
- package/dist/{voice-DgirjEyH.js.map → voice-ugGu7VyA.js.map} +1 -1
- package/package.json +19 -19
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as useMastraClient } from "../../mastra-client-context-
|
|
2
|
-
import { t as getOrCreate } from "../../map-
|
|
1
|
+
import { n as useMastraClient } from "../../mastra-client-context-DQ5z_ze9.js";
|
|
2
|
+
import { t as getOrCreate } from "../../map-5-4U5rwA.js";
|
|
3
3
|
import { useMemo, useRef } from "react";
|
|
4
4
|
import { useQuery } from "@tanstack/react-query";
|
|
5
|
-
|
|
5
|
+
// src/hooks/metrics/metrics-query-filters.ts
|
|
6
6
|
const DEFAULT_WINDOW_MS = 864e5;
|
|
7
7
|
const PRESET_MS = {
|
|
8
8
|
"24h": DEFAULT_WINDOW_MS,
|
|
@@ -60,8 +60,7 @@ function useMetricsQueryFilters({ datePreset, customRange, dimensionalFilter, di
|
|
|
60
60
|
filterKey: useMemo(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey])
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
//#region src/hooks/shared/date-format.ts
|
|
63
|
+
// src/hooks/shared/date-format.ts
|
|
65
64
|
function toDate(value) {
|
|
66
65
|
if (value == null) return void 0;
|
|
67
66
|
const date = value instanceof Date ? value : new Date(value);
|
|
@@ -229,8 +228,7 @@ function formatDate(value, preset, options = {}) {
|
|
|
229
228
|
if (preset === "date") return formatShortDate(date, options);
|
|
230
229
|
return getFormatter(preset, locale, timeZone).format(date);
|
|
231
230
|
}
|
|
232
|
-
|
|
233
|
-
//#region src/hooks/metrics/metrics-interval.ts
|
|
231
|
+
// src/hooks/metrics/metrics-interval.ts
|
|
234
232
|
const HOURLY_MAX_RANGE_MS = 1728e5;
|
|
235
233
|
/** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */
|
|
236
234
|
function chooseMetricsInterval({ start, end }) {
|
|
@@ -240,8 +238,7 @@ function formatMetricsBucketLabel(ts, interval) {
|
|
|
240
238
|
if (interval === "1h") return formatDate(ts, "time") ?? "";
|
|
241
239
|
return formatShortDate(ts) ?? "";
|
|
242
240
|
}
|
|
243
|
-
|
|
244
|
-
//#region src/hooks/metrics/use-active-resources-kpi-metrics.tsx
|
|
241
|
+
// src/hooks/metrics/use-active-resources-kpi-metrics.tsx
|
|
245
242
|
/** Active Resources — number of distinct resource IDs observed in agent runs.
|
|
246
243
|
* Uses approximate `count_distinct` (HyperLogLog on ClickHouse,
|
|
247
244
|
* `approx_count_distinct` on DuckDB) so the query stays fast even on
|
|
@@ -265,8 +262,7 @@ function useActiveResourcesKpiMetrics(params) {
|
|
|
265
262
|
...queryOptions
|
|
266
263
|
});
|
|
267
264
|
}
|
|
268
|
-
|
|
269
|
-
//#region src/hooks/metrics/use-active-threads-kpi-metrics.tsx
|
|
265
|
+
// src/hooks/metrics/use-active-threads-kpi-metrics.tsx
|
|
270
266
|
/** Active Threads — number of distinct thread IDs observed in agent runs.
|
|
271
267
|
* Uses approximate `count_distinct` (HyperLogLog on ClickHouse,
|
|
272
268
|
* `approx_count_distinct` on DuckDB) so the query stays fast even on
|
|
@@ -290,8 +286,7 @@ function useActiveThreadsKpiMetrics(params) {
|
|
|
290
286
|
...queryOptions
|
|
291
287
|
});
|
|
292
288
|
}
|
|
293
|
-
|
|
294
|
-
//#region src/hooks/metrics/use-agent-runs-kpi-metrics.tsx
|
|
289
|
+
// src/hooks/metrics/use-agent-runs-kpi-metrics.tsx
|
|
295
290
|
/** Total Agent Runs — count of agent duration metric observations */
|
|
296
291
|
function useAgentRunsKpiMetrics(params) {
|
|
297
292
|
const client = useMastraClient();
|
|
@@ -311,8 +306,7 @@ function useAgentRunsKpiMetrics(params) {
|
|
|
311
306
|
...queryOptions
|
|
312
307
|
});
|
|
313
308
|
}
|
|
314
|
-
|
|
315
|
-
//#region src/hooks/metrics/use-latency-metrics.tsx
|
|
309
|
+
// src/hooks/metrics/use-latency-metrics.tsx
|
|
316
310
|
async function fetchPercentiles(client, metricName, filters, interval) {
|
|
317
311
|
const res = await client.getMetricPercentiles({
|
|
318
312
|
name: metricName,
|
|
@@ -362,8 +356,7 @@ function useLatencyMetrics(params) {
|
|
|
362
356
|
...queryOptions
|
|
363
357
|
});
|
|
364
358
|
}
|
|
365
|
-
|
|
366
|
-
//#region src/hooks/metrics/use-model-cost-kpi-metrics.tsx
|
|
359
|
+
// src/hooks/metrics/use-model-cost-kpi-metrics.tsx
|
|
367
360
|
function useModelCostKpiMetrics(params) {
|
|
368
361
|
const client = useMastraClient();
|
|
369
362
|
const { filters, filterKey, queryOptions } = params;
|
|
@@ -390,8 +383,7 @@ function useModelCostKpiMetrics(params) {
|
|
|
390
383
|
...queryOptions
|
|
391
384
|
});
|
|
392
385
|
}
|
|
393
|
-
|
|
394
|
-
//#region src/hooks/shared/cost.ts
|
|
386
|
+
// src/hooks/shared/cost.ts
|
|
395
387
|
const compactNumber = new Intl.NumberFormat("en-US", {
|
|
396
388
|
notation: "compact",
|
|
397
389
|
maximumSignificantDigits: 3
|
|
@@ -425,8 +417,7 @@ function formatFullNumber(value, { currency } = {}) {
|
|
|
425
417
|
if (value !== 0 && Math.abs(value) < smallestUnit) return `${value < 0 ? "-" : ""}<${formatter.format(smallestUnit)}`;
|
|
426
418
|
return formatter.format(value);
|
|
427
419
|
}
|
|
428
|
-
|
|
429
|
-
//#region src/hooks/metrics/use-model-usage-cost-metrics.tsx
|
|
420
|
+
// src/hooks/metrics/use-model-usage-cost-metrics.tsx
|
|
430
421
|
function useModelUsageCostMetrics(params) {
|
|
431
422
|
const client = useMastraClient();
|
|
432
423
|
const { filters, filterKey, queryOptions } = params;
|
|
@@ -503,8 +494,7 @@ function useModelUsageCostMetrics(params) {
|
|
|
503
494
|
...queryOptions
|
|
504
495
|
});
|
|
505
496
|
}
|
|
506
|
-
|
|
507
|
-
//#region src/hooks/metrics/use-scores-metrics.tsx
|
|
497
|
+
// src/hooks/metrics/use-scores-metrics.tsx
|
|
508
498
|
function useScoresMetrics(params) {
|
|
509
499
|
const client = useMastraClient();
|
|
510
500
|
const { datePreset, customRange, timestamp, queryOptions } = params;
|
|
@@ -606,8 +596,7 @@ function useScoresMetrics(params) {
|
|
|
606
596
|
...queryOptions
|
|
607
597
|
});
|
|
608
598
|
}
|
|
609
|
-
|
|
610
|
-
//#region src/hooks/metrics/use-token-usage-by-agent-metrics.tsx
|
|
599
|
+
// src/hooks/metrics/use-token-usage-by-agent-metrics.tsx
|
|
611
600
|
function useTokenUsageByAgentMetrics(params) {
|
|
612
601
|
const client = useMastraClient();
|
|
613
602
|
const { filters, filterKey, queryOptions } = params;
|
|
@@ -666,8 +655,7 @@ function useTokenUsageByAgentMetrics(params) {
|
|
|
666
655
|
...queryOptions
|
|
667
656
|
});
|
|
668
657
|
}
|
|
669
|
-
|
|
670
|
-
//#region src/hooks/metrics/use-token-usage-timeseries.tsx
|
|
658
|
+
// src/hooks/metrics/use-token-usage-timeseries.tsx
|
|
671
659
|
function addSeriesPoints(pointMap, series, key) {
|
|
672
660
|
for (const point of series?.points ?? []) {
|
|
673
661
|
const tsMs = new Date(point.timestamp).getTime();
|
|
@@ -737,8 +725,7 @@ function useTokenUsageTimeSeries(params) {
|
|
|
737
725
|
...queryOptions
|
|
738
726
|
});
|
|
739
727
|
}
|
|
740
|
-
|
|
741
|
-
//#region src/hooks/metrics/use-top-active-threads-metrics.tsx
|
|
728
|
+
// src/hooks/metrics/use-top-active-threads-metrics.tsx
|
|
742
729
|
const TOP_N$1 = 20;
|
|
743
730
|
/** Top Active Threads — the threads with the most agent runs in the selected
|
|
744
731
|
* range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the
|
|
@@ -817,8 +804,7 @@ function useTopActiveThreadsMetrics(params) {
|
|
|
817
804
|
...queryOptions
|
|
818
805
|
});
|
|
819
806
|
}
|
|
820
|
-
|
|
821
|
-
//#region src/hooks/metrics/use-top-resources-by-threads-metrics.tsx
|
|
807
|
+
// src/hooks/metrics/use-top-resources-by-threads-metrics.tsx
|
|
822
808
|
const TOP_N = 20;
|
|
823
809
|
/** Top Resources by Thread Count — the resources with the most distinct threads
|
|
824
810
|
* in the selected range. Uses `count_distinct(threadId)` per `resourceId`,
|
|
@@ -897,8 +883,7 @@ function useTopResourcesByThreadsMetrics(params) {
|
|
|
897
883
|
...queryOptions
|
|
898
884
|
});
|
|
899
885
|
}
|
|
900
|
-
|
|
901
|
-
//#region src/hooks/metrics/use-total-tokens-kpi-metrics.tsx
|
|
886
|
+
// src/hooks/metrics/use-total-tokens-kpi-metrics.tsx
|
|
902
887
|
function useTotalTokensKpiMetrics(params) {
|
|
903
888
|
const client = useMastraClient();
|
|
904
889
|
const { filters, filterKey, queryOptions } = params;
|
|
@@ -934,8 +919,7 @@ function useTotalTokensKpiMetrics(params) {
|
|
|
934
919
|
...queryOptions
|
|
935
920
|
});
|
|
936
921
|
}
|
|
937
|
-
|
|
938
|
-
//#region src/hooks/metrics/use-trace-volume-metrics.tsx
|
|
922
|
+
// src/hooks/metrics/use-trace-volume-metrics.tsx
|
|
939
923
|
async function fetchVolume(client, metricName, filters) {
|
|
940
924
|
const res = await client.getMetricBreakdown({
|
|
941
925
|
name: [metricName],
|
|
@@ -984,7 +968,6 @@ function useTraceVolumeMetrics(params) {
|
|
|
984
968
|
...queryOptions
|
|
985
969
|
});
|
|
986
970
|
}
|
|
987
|
-
//#endregion
|
|
988
971
|
export { chooseMetricsInterval, formatMetricsBucketLabel, useActiveResourcesKpiMetrics, useActiveThreadsKpiMetrics, useAgentRunsKpiMetrics, useLatencyMetrics, useMetricsQueryFilters, useModelCostKpiMetrics, useModelUsageCostMetrics, useScoresMetrics, useTokenUsageByAgentMetrics, useTokenUsageTimeSeries, useTopActiveThreadsMetrics, useTopResourcesByThreadsMetrics, useTotalTokensKpiMetrics, useTraceVolumeMetrics };
|
|
989
972
|
|
|
990
973
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["TOP_N"],"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":";;;;;AAgDA,MAAM,oBAAoB;AAE1B,MAAM,YAAoC;CACxC,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,OAAO;AACT;AAEA,SAAS,eACP,QACA,aACA,QACW;CACX,IAAI,WAAW,UAAU;EACvB,MAAM,KAAK,UAAU,WAAW;EAChC,OAAO;GAAE,OAAO,IAAI,KAAK,SAAS,EAAE;GAAG,KAAK,IAAI,KAAK,MAAM;EAAE;CAC/D;CACA,OAAO;EACL,OAAO,aAAa,wBAAQ,IAAI,KAAK,SAAS,iBAAiB;EAC/D,KAAK,aAAa,MAAM,IAAI,KAAK,MAAM;CACzC;AACF;;;;;;;;;;;;AAaA,SAAgB,uBAAuB,EACrC,YACA,aACA,mBACA,wBACgD;CAIhD,MAAM,YAAY,OAA+C,IAAI;CACrE,MAAM,YACJ,eAAe,WACX,UAAU,aAAa,MAAM,QAAQ,KAAK,GAAG,GAAG,aAAa,IAAI,QAAQ,KAAK,OAC9E,UAAU;CAChB,IAAI,CAAC,UAAU,WAAW,UAAU,QAAQ,QAAQ,WAClD,UAAU,UAAU;EAAE,KAAK;EAAW,QAAQ,KAAK,IAAI;CAAE;CAE3D,MAAM,SAAS,UAAU,QAAQ;CAEjC,MAAM,YAAY,cAAc,eAAe,YAAY,aAAa,MAAM,GAAG;EAAC;EAAY;EAAa;CAAM,CAAC;CAYlH,OAAO;EAAE;EAAY;EAAa;EAAW,SAV7B,eACP;GAAE;GAAW,GAAG;EAAkB,IAGzC,CAAC,WAAW,oBAAoB,CAMiB;EAAG;EAAmB,WAFvD,cAAc,GAAG,UAAU,GAAG,wBAAwB,CAAC,WAAW,oBAAoB,CAEvB;CAAE;AACrF;;;ACvGA,SAAgB,OAAO,OAAoC;CACzD,IAAI,SAAS,MAAM,OAAO,KAAA;CAC1B,MAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;CAC3D,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,KAAA,IAAY;AACpD;AAEA,MAAM,iBAAiB;CACrB,MAAM;EAAE,MAAM;EAAW,QAAQ;CAAU;CAC3C,gBAAgB;EAAE,MAAM;EAAW,QAAQ;EAAW,QAAQ;CAAU;CACxE,aAAa;EAAE,OAAO;EAAS,KAAK;EAAW,MAAM;EAAW,MAAM;EAAW,QAAQ;CAAU;CACnG,qBAAqB;EACnB,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,QAAQ;EACR,QAAQ;CACV;CACA,oBAAoB;EAAE,OAAO;EAAS,KAAK;EAAW,MAAM;EAAW,QAAQ;EAAW,QAAQ;CAAU;CAC5G,UAAU;EAAE,MAAM;EAAW,OAAO;EAAW,KAAK;EAAW,UAAU;EAAW,iBAAiB;CAAO;CAC5G,UAAU;EAAE,OAAO;EAAS,KAAK;CAAU;CAC3C,cAAc;EAAE,OAAO;EAAS,KAAK;EAAW,MAAM;CAAU;CAChE,SAAS;EACP,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,QAAQ;EACR,QAAQ;EACR,wBAAwB;CAC1B;CACA,aAAa;EAAE,MAAM;EAAW,QAAQ;EAAW,QAAQ;EAAW,wBAAwB;CAAE;AAClG;AAIA,MAAM,6BAAa,IAAI,IAAiC;AAExD,SAAS,aAAa,KAAmB,QAAiB,UAAmB;CAC3E,MAAM,WAAW,GAAG,UAAU,GAAG,GAAG,YAAY,GAAG,GAAG;CACtD,IAAI,YAAY,WAAW,IAAI,QAAQ;CACvC,IAAI,CAAC,WAAW;EACd,YAAY,IAAI,KAAK,eAAe,QAAQ;GAAE,GAAG,eAAe;GAAM;EAAS,CAAC;EAChF,WAAW,IAAI,UAAU,SAAS;CACpC;CACA,OAAO;AACT;AAEA,SAAS,aAAa,MAAY,UAAmB;CACnD,MAAM,QAAQ,aAAa,YAAY,SAAS,QAAQ,CAAC,CAAC,cAAc,IAAI;CAC5E,OAAO;EACL,MAAM,MAAM,MAAK,SAAQ,KAAK,SAAS,MAAM,CAAC,EAAE;EAChD,OAAO,MAAM,MAAK,SAAQ,KAAK,SAAS,OAAO,CAAC,EAAE;EAClD,KAAK,MAAM,MAAK,SAAQ,KAAK,SAAS,KAAK,CAAC,EAAE;CAChD;AACF;;AAGA,SAAgB,gBAAgB,OAAkB,EAAE,QAAQ,KAAK,aAA4B,CAAC,GAAG;CAC/F,MAAM,OAAO,OAAO,KAAK;CACzB,IAAI,CAAC,MAAM,OAAO,KAAA;CAClB,MAAM,YAAY,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC;CAG5C,OAAO,aADL,aAAa,MAAM,QAAQ,CAAC,CAAC,SAAS,aAAa,WAAW,QAAQ,CAAC,CAAC,OAAO,aAAa,gBACrE,QAAQ,QAAQ,CAAC,CAAC,OAAO,IAAI;AACxD;AAEA,MAAM,sBAAoE;CACxE,CAAC,QAAQ,OAAY;CACrB,CAAC,SAAS,MAAW;CACrB,CAAC,QAAQ,MAAU;CACnB,CAAC,OAAO,KAAM;CACd,CAAC,QAAQ,IAAK;CACd,CAAC,UAAU,EAAE;AACf;AAEA,MAAM,qCAAqB,IAAI,IAAqC;AAEpE,SAAS,qBAAqB,QAAiB;CAC7C,MAAM,MAAM,UAAU;CACtB,IAAI,YAAY,mBAAmB,IAAI,GAAG;CAC1C,IAAI,CAAC,WAAW;EACd,YAAY,IAAI,KAAK,mBAAmB,QAAQ,EAAE,SAAS,OAAO,CAAC;EACnE,mBAAmB,IAAI,KAAK,SAAS;CACvC;CACA,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,WAAW,OAAkB,QAAoB,UAAyB,CAAC,GAAG;CAC5F,MAAM,OAAO,OAAO,KAAK;CACzB,IAAI,CAAC,MAAM,OAAO,KAAA;CAClB,MAAM,EAAE,QAAQ,KAAK,aAAa;CAElC,IAAI,WAAW,iBAAiB;EAC9B,MAAM,OAAO,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ;EAClE,MAAM,MAAM,KAAK,IAAI,IAAI;EACzB,IAAI,MAAM,KAAO,OAAO;EAOxB,MAAM,QAAQ;GALZ;IAAE,OAAO;IAAQ,MAAM;IAAO,MAAM;GAAI;GACxC;IAAE,OAAO;IAAW,MAAM;IAAQ,MAAM;GAAI;GAC5C;IAAE,OAAO;IAAY,MAAM;IAAW,MAAM;GAAI;GAChD;IAAE,OAAO;IAAgB,MAAM;IAAY,MAAM;GAAI;EAErC,CAAC,CAAC,MAAM,EAAE,YAAY,MAAM,KAAK;EACnD,IAAI,CAAC,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO;EACnD,MAAM,QAAQ,GAAG,KAAK,MAAM,MAAM,MAAM,IAAI,IAAI,MAAM;EACtD,OAAO,OAAO,IAAI,GAAG,MAAM,QAAQ,MAAM;CAC3C;CACA,IAAI,WAAW,iBAAiB;EAC9B,MAAM,WAAW,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,KAAK;EAC3E,MAAM,CAAC,MAAM,QAAQ,oBAAoB,MAAM,GAAG,UAAU,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC;EACtG,OAAO,qBAAqB,MAAM,CAAC,CAAC,OAAO,KAAK,MAAM,UAAU,IAAI,GAAG,IAAI;CAC7E;CACA,IAAI,WAAW,QAAQ,OAAO,gBAAgB,MAAM,OAAO;CAE3D,OAAO,aAAa,QAAQ,QAAQ,QAAQ,CAAC,CAAC,OAAO,IAAI;AAC3D;;;ACvIA,MAAM,sBAAsB;;AAG5B,SAAgB,sBAAsB,EAAE,OAAO,OAAoD;CACjG,OAAO,IAAI,QAAQ,IAAI,MAAM,QAAQ,KAAK,sBAAsB,OAAO;AACzE;AAEA,SAAgB,yBAAyB,IAAU,UAAmC;CACpF,IAAI,aAAa,MACf,OAAO,WAAW,IAAI,MAAM,KAAK;CAEnC,OAAO,gBAAgB,EAAE,KAAK;AAChC;;;;;;;ACJA,SAAgB,6BACd,QAG8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAwB;EAAS;EACvD,eACE,OAAO,mBAAmB;GACxB,MAAM,CAAC,0BAA0B;GACjC,aAAa;GACb,gBAAgB;GAChB;GACA,eAAe;EACjB,CAAC;EACH,GAAG;CACL,CAAC;AACH;;;;;;;ACpBA,SAAgB,2BACd,QAG8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAsB;EAAS;EACrD,eACE,OAAO,mBAAmB;GACxB,MAAM,CAAC,0BAA0B;GACjC,aAAa;GACb,gBAAgB;GAChB;GACA,eAAe;EACjB,CAAC;EACH,GAAG;CACL,CAAC;AACH;;;;ACxBA,SAAgB,uBACd,QAG8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAkB;EAAS;EACjD,eACE,OAAO,mBAAmB;GACxB,MAAM,CAAC,0BAA0B;GACjC,aAAa;GACb;GACA,eAAe;EACjB,CAAC;EACH,GAAG;CACL,CAAC;AACH;;;ACTA,eAAe,iBACb,QACA,YACA,SACA,UACyB;CACzB,MAAM,MAAM,MAAM,OAAO,qBAAqB;EAC5C,MAAM;EACN,aAAa,CAAC,IAAK,GAAI;EACvB;EACA;CACF,CAAC;CAED,MAAM,YAAY,IAAI,OAAO,MAAK,MAAK,EAAE,eAAe,EAAG;CAC3D,MAAM,YAAY,IAAI,OAAO,MAAK,MAAK,EAAE,eAAe,GAAI;CAE5D,IAAI,CAAC,aAAa,CAAC,WAAW,OAAO,CAAC;CAEtC,MAAM,SAAS,IAAI,IAAI,UAAU,OAAO,KAAI,MAAK,CAAC,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;CAE5F,OAAO,UAAU,OAAO,KAAI,MAAK;EAC/B,MAAM,KAAK,IAAI,KAAK,EAAE,SAAS;EAC/B,MAAM,OAAO,GAAG,QAAQ;EACxB,OAAO;GACL,MAAM,yBAAyB,IAAI,QAAQ;GAC3C;GACA,KAAK,KAAK,MAAM,EAAE,KAAK;GACvB,KAAK,KAAK,MAAM,OAAO,IAAI,IAAI,KAAK,CAAC;EACvC;CACF,CAAC;AACH;AASA,SAAgB,kBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,WAAW,SAAS,WAAW,iBAAiB;CACxD,MAAM,WAAW,sBAAsB,SAAS;CAEhD,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAW;GAAW;EAAQ;EACpD,SAAS,YAAyC;GAChD,MAAM,CAAC,WAAW,cAAc,YAAY,MAAM,QAAQ,IAAI;IAC5D,iBAAiB,QAAQ,4BAA4B,SAAS,QAAQ;IACtE,iBAAiB,QAAQ,+BAA+B,SAAS,QAAQ;IACzE,iBAAiB,QAAQ,2BAA2B,SAAS,QAAQ;GACvE,CAAC;GACD,OAAO;IAAE;IAAW;IAAc;IAAU;GAAS;EACvD;EACA,GAAG;CACL,CAAC;AACH;;;AC9DA,SAAgB,uBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAkB;EAAS;EACjD,SAAS,YAAmC;GAC1C,MAAM,MAAM,MAAM,OAAO,mBAAmB;IAC1C,MAAM,CAAC,mCAAmC,kCAAkC;IAC5E,aAAa;IACb;IACA,eAAe;GACjB,CAAC;GAED,OAAO;IACL,MAAM,IAAI,iBAAiB;IAC3B,UAAU,IAAI,YAAY;IAC1B,cAAc,IAAI,yBAAyB;IAC3C,mBAAmB,IAAI,qBAAqB;GAC9C;EACF;EACA,GAAG;CACL,CAAC;AACH;;;ACnCA,MAAM,gBAAgB,IAAI,KAAK,aAAa,SAAS;CAAE,UAAU;CAAW,0BAA0B;AAAE,CAAC;AACzG,MAAM,aAAa,IAAI,KAAK,aAAa,OAAO;AAEhD,MAAM,gBAAgB,IAAI,IAAI,KAAK,kBAAkB,UAAU,CAAC;AAEhE,SAAS,WAAW,MAA0C;CAC5D,OAAO,SAAS,KAAA,KAAa,cAAc,IAAI,KAAK,YAAY,CAAC;AACnE;AAEA,SAAS,MAAM,UAAkB,SAAmC;CAClE,OAAO,IAAI,KAAK,aAAa,SAAS;EAAE,OAAO;EAAY;EAAU,GAAG;CAAQ,CAAC;AACnF;AAEA,SAAgB,oBAAoB,OAAe,EAAE,aAAyC,CAAC,GAAW;CACxG,IAAI,CAAC,WAAW,QAAQ,GAAG,OAAO,cAAc,OAAO,KAAK;CAC5D,MAAM,OAAO,KAAK,IAAI,KAAK;CAC3B,IAAI,OAAO,KAAK,OAAO,iBAAiB,OAAO,EAAE,SAAS,CAAC;CAC3D,IAAI,OAAO,KAAM,OAAO,MAAM,UAAU,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK;CAClF,OAAO,MAAM,UAAU;EAAE,UAAU;EAAW,0BAA0B;CAAE,CAAC,CAAC,CAAC,OAAO,KAAK;AAC3F;AAEA,SAAgB,iBAAiB,OAAe,EAAE,aAAyC,CAAC,GAAW;CACrG,IAAI,CAAC,WAAW,QAAQ,GAAG,OAAO,WAAW,OAAO,KAAK;CACzD,MAAM,YAAY,MAAM,UAAU,CAAC,CAAC;CACpC,MAAM,eAAe,MAAM,EAAE,UAAU,gBAAgB,CAAC,CAAC,yBAAyB;CAClF,IAAI,UAAU,KAAK,KAAK,IAAI,KAAK,IAAI,cACnC,OAAO,GAAG,QAAQ,IAAI,MAAM,GAAG,GAAG,UAAU,OAAO,YAAY;CAEjE,OAAO,UAAU,OAAO,KAAK;AAC/B;;;ACdA,SAAgB,yBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAoB;EAAS;EACnD,SAAS,YAAsC;GAC7C,MAAM,CAAC,UAAU,WAAW,cAAc,iBAAiB,MAAM,QAAQ,IAErE;IACE;IACA;IACA;IACA;GACF,CAAC,CACD,KAAI,SACJ,OAAO,mBAAmB;IACxB,MAAM,CAAC,IAAI;IACX,SAAS,CAAC,SAAS,UAAU;IAC7B,aAAa;IACb,gBAAgB;IAChB;GACF,CAAC,CACH,CACF;GAEA,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,gBAAgB,CAAC,eAAe,OAAO,CAAC;GAaxE,MAAM,2BAAW,IAAI,IAAwB;GAE7C,MAAM,eAAe,eAAgF;IACnG,MAAM,QAAQ,WAAW,SAAS;IAClC,MAAM,WAAW,WAAW,YAAY,KAAA;IACxC,OAAO,YAAY,UAAU,GAAG,MAAM,QAAQ,YAAY,aAAa;KACrE;KACA;KACA,OAAO;KACP,QAAQ;KACR,WAAW;KACX,YAAY;KACZ,MAAM;KACN,UAAU;IACZ,EAAE;GACJ;GAIA,MAAM,WAAW,OAAmB,UAAuE;IACzG,IAAI,MAAM,iBAAiB,MAAM;KAC/B,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM;KACvC,IAAI,MAAM,UAAU,MAAM,WAAW,MAAM;IAC7C;GACF;GAEA,KAAK,MAAM,SAAS,SAAS,QAAQ;IACnC,MAAM,QAAQ,YAAY,MAAM,UAAU;IAC1C,MAAM,QAAQ,MAAM;IACpB,QAAQ,OAAO,KAAK;GACtB;GACA,KAAK,MAAM,SAAS,UAAU,QAAQ;IACpC,MAAM,QAAQ,YAAY,MAAM,UAAU;IAC1C,MAAM,SAAS,MAAM;IACrB,QAAQ,OAAO,KAAK;GACtB;GACA,KAAK,MAAM,SAAS,aAAa,QAAQ;IACvC,MAAM,QAAQ,YAAY,MAAM,UAAU;IAC1C,MAAM,YAAY,MAAM;GAC1B;GACA,KAAK,MAAM,SAAS,cAAc,QAAQ;IACxC,MAAM,QAAQ,YAAY,MAAM,UAAU;IAC1C,MAAM,aAAa,MAAM;GAC3B;GAEA,OAAO,MAAM,KAAK,SAAS,OAAO,CAAC,CAAC,CACjC,KAAI,UAAS;IACZ,OAAO,KAAK;IACZ,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;IACnD,OAAO,oBAAoB,KAAK,KAAK;IACrC,QAAQ,oBAAoB,KAAK,MAAM;IACvC,WAAW,oBAAoB,KAAK,SAAS;IAC7C,YAAY,oBAAoB,KAAK,UAAU;IAC/C,MAAM,KAAK;IACX,UAAU,KAAK;GACjB,EAAE,CAAC,CACF,MAAM,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,MAAM,EAAE,YAAY,GAAA,CAAI,cAAc,EAAE,YAAY,EAAE,CAAC;EACxG;EACA,GAAG;CACL,CAAC;AACH;;;AC5FA,SAAgB,iBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,YAAY,aAAa,WAAW,iBAAiB;CAE7D,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAe;GAAY;EAAW;EAC5D,SAAS,YAAwC;GAC/C,MAAM,UAAU,EACd,WAAW;IAAE,OAAO,UAAU;IAAO,KAAK,UAAU;GAAI,EAC1D;GAEA,MAAM,aAAa,MAAM,OAAO,YAAY;GAC5C,MAAM,YAAY,OAAO,KAAK,cAAc,CAAC,CAAC;GAE9C,IAAI,UAAU,WAAW,GACvB,OAAO;IAAE,aAAa,CAAC;IAAG,cAAc,CAAC;IAAG,aAAa,CAAC;IAAG,UAAU;GAAK;GAsB9E,MAAM,eAA+B,MAlBR,QAAQ,IACnC,UAAU,IAAI,OAAM,aAAY;IAC9B,MAAM,CAAC,KAAK,KAAK,KAAK,SAAS,MAAM,QAAQ,IAAI;KAC/C,OAAO,kBAAkB;MAAE;MAAU,aAAa;MAAO;KAAQ,CAAC;KAClE,OAAO,kBAAkB;MAAE;MAAU,aAAa;MAAO;KAAQ,CAAC;KAClE,OAAO,kBAAkB;MAAE;MAAU,aAAa;MAAO;KAAQ,CAAC;KAClE,OAAO,kBAAkB;MAAE;MAAU,aAAa;MAAS;KAAQ,CAAC;IACtE,CAAC;IACD,OAAO;KACL,QAAQ;KACR,KAAK,IAAI,SAAS;KAClB,KAAK,IAAI,SAAS;KAClB,KAAK,IAAI,SAAS;KAClB,OAAO,MAAM,SAAS;IACxB;GACF,CAAC,CACH,EAAA,CAEoD,QAAO,MAAK,EAAE,QAAQ,CAAC;GAC3E,MAAM,cAAc,YAAY,KAAI,MAAK,EAAE,MAAM;GAEjD,IAAI,YAAY,WAAW,GACzB,OAAO;IAAE,aAAa,CAAC;IAAG,cAAc,CAAC;IAAG,aAAa,CAAC;IAAG,UAAU;GAAK;GAG9E,MAAM,gBAAgB,YAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC;GACzE,MAAM,aAAa,YAAY,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC;GAC9D,MAAM,WAAW,aAAa,KAAK,MAAO,gBAAgB,aAAc,GAAG,IAAI,MAAM;GAErF,MAAM,WAAW;GAGjB,MAAM,oBAAoB,MAAM,QAAQ,IACtC,YAAY,KAAI,aACd,OAAO,mBAAmB;IACxB;IACA;IACA,aAAa;IACb;GACF,CAAC,CACH,CACF;GAIA,MAAM,8BAAc,IAAI,IAAyD;GAEjF,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,KAAK;IAC3C,MAAM,WAAW,YAAY;IAC7B,MAAM,SAAS,kBAAkB,EAAE,EAAE,UAAU,CAAC;IAChD,KAAK,MAAM,KAAK,QACd,KAAK,MAAM,SAAS,EAAE,QAAQ;KAC5B,MAAM,KAAK,IAAI,KAAK,MAAM,SAAS;KACnC,MAAM,UAAU,GAAG,SAAS,IAAI,KAAK,GAAG,WAAW;KACnD,MAAM,YAAY,YAAY,aAAa,+BAAe,IAAI,IAAI,CAAC;KACnE,MAAM,MAAM,YAAY,WAAW,iBAAiB;MAAE,KAAK;MAAG,OAAO;KAAE,EAAE;KAEzE,IAAI,OAAO,MAAM;KACjB,IAAI,SAAS;IACf;GAEJ;GAeA,OAAO;IACL;IACA,cAd0C,MAAM,KAAK,YAAY,QAAQ,CAAC,CAAC,CAC1E,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CACzB,KAAK,CAAC,SAAS,eAAe;KAC7B,MAAM,QAA6B,EACjC,MAAM,WAAW,IAAI,KAAK,KAAM,GAAG,GAAG,KAAK,MAAM,UAAU,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,KAAK,GAC5F;KACA,KAAK,MAAM,CAAC,UAAU,QAAQ,WAC5B,MAAM,YAAY,EAAE,IAAI,MAAM,IAAI,MAAA,CAAO,QAAQ,CAAC;KAEpD,OAAO;IACT,CAIW;IACX;IACA;GACF;EACF;EACA,GAAG;CACL,CAAC;AACH;;;ACtHA,SAAgB,4BACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAwB;EAAS;EACvD,SAAS,YAA6C;GACpD,MAAM,gBAAgB;IACpB,SAAS,CAAC,YAAY;IACtB,aAAa;IACb,gBAAgB;IAChB;GACF;GAEA,MAAM,CAAC,UAAU,aAAa,MAAM,QAAQ,IAAI,CAC9C,OAAO,mBAAmB;IAAE,GAAG;IAAe,MAAM,CAAC,iCAAiC;GAAE,CAAC,GACzF,OAAO,mBAAmB;IAAE,GAAG;IAAe,MAAM,CAAC,kCAAkC;GAAE,CAAC,CAC5F,CAAC;GAID,MAAM,2BAAW,IAAI,IAAwB;GAE7C,MAAM,UAAU,SACd,YAAY,UAAU,aAAa;IAAE,OAAO;IAAG,QAAQ;IAAG,MAAM;IAAM,UAAU;GAAK,EAAE;GAEzF,MAAM,WAAW,OAAmB,UAAuE;IACzG,IAAI,MAAM,iBAAiB,MAAM;KAC/B,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM;KACvC,IAAI,MAAM,UAAU,MAAM,WAAW,MAAM;IAC7C;GACF;GAEA,KAAK,MAAM,SAAS,SAAS,QAAQ;IAEnC,MAAM,QAAQ,OADD,MAAM,WAAW,cAAc,SACnB;IACzB,MAAM,QAAQ,MAAM;IACpB,QAAQ,OAAO,KAAK;GACtB;GACA,KAAK,MAAM,SAAS,UAAU,QAAQ;IAEpC,MAAM,QAAQ,OADD,MAAM,WAAW,cAAc,SACnB;IACzB,MAAM,SAAS,MAAM;IACrB,QAAQ,OAAO,KAAK;GACtB;GAEA,OAAO,MAAM,KAAK,SAAS,QAAQ,CAAC,CAAC,CAClC,KAAK,CAAC,MAAM,WAAW;IACtB;IACA,OAAO,KAAK;IACZ,QAAQ,KAAK;IACb,OAAO,KAAK,QAAQ,KAAK;IACzB,MAAM,KAAK;IACX,UAAU,KAAK;GACjB,EAAE,CAAC,CACF,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;EACrC;EACA,GAAG;CACL,CAAC;AACH;;;AChCA,SAAS,gBACP,UACA,QACA,KACA;CACA,KAAK,MAAM,SAAS,QAAQ,UAAU,CAAC,GAAG;EACxC,MAAM,OAAO,IAAI,KAAK,MAAM,SAAS,CAAC,CAAC,QAAQ;EAC/C,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG;EAE5B,MAAM,WAAW,SAAS,IAAI,IAAI,KAAK;GACrC;GACA,OAAO;GACP,QAAQ;GACR,MAAM;GACN,2BAAW,IAAI,IAAY;GAC3B,oBAAoB;EACtB;EAEA,SAAS,QAAQ,MAAM;EAEvB,IAAI,MAAM,iBAAiB,MAAM;GAC/B,SAAS,QAAQ,SAAS,QAAQ,KAAK,MAAM;GAC7C,IAAI,QAAQ,UACV,SAAS,UAAU,IAAI,OAAO,QAAQ;QAEtC,SAAS,qBAAqB;EAElC;EAEA,SAAS,IAAI,MAAM,QAAQ;CAC7B;AACF;AAEA,SAAS,WAAW,OAAgD;CAClE,IAAI,MAAM,QAAQ,QAAQ,MAAM,sBAAsB,MAAM,UAAU,SAAS,GAAG,OAAO;CACzF,OAAO,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC,MAAM;AACpC;AAEA,SAAgB,wBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,WAAW,SAAS,WAAW,iBAAiB;CACxD,MAAM,WAAW,sBAAsB,SAAS;CAEhD,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAA0B;GAAW;EAAQ;EACnE,SAAS,YAA+C;GACtD,MAAM,CAAC,UAAU,aAAa,MAAM,QAAQ,IAAI,CAC9C,OAAO,oBAAoB;IACzB,MAAM,CAAC,iCAAiC;IACxC;IACA,aAAa;IACb;GACF,CAAC,GACD,OAAO,oBAAoB;IACzB,MAAM,CAAC,kCAAkC;IACzC;IACA,aAAa;IACb;GACF,CAAC,CACH,CAAC;GAED,MAAM,2BAAW,IAAI,IAAsC;GAC3D,gBAAgB,UAAU,SAAS,OAAO,IAAI,OAAO;GACrD,gBAAgB,UAAU,UAAU,OAAO,IAAI,QAAQ;GAiBvD,OAAO;IAAE,MAfI,MAAM,KAAK,SAAS,OAAO,CAAC,CAAC,CACvC,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAC/B,KAAI,UAAS;KAEZ,OAAO;MACL,MAAM,yBAAyB,IAFlB,KAAK,MAAM,IAEO,GAAI,QAAQ;MAC3C,MAAM,MAAM;MACZ,OAAO,MAAM;MACb,QAAQ,MAAM;MACd,OAAO,MAAM,QAAQ,MAAM;MAC3B,MAAM,MAAM;MACZ,UAAU,WAAW,KAAK;KAC5B;IACF,CAEU;IAAG;GAAS;EAC1B;EACA,GAAG;CACL,CAAC;AACH;;;AClHA,MAAMA,UAAQ;;;;;;;AAQd,SAAgB,2BACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAsB;EAAS;EACrD,SAAS,YAAwC;GAC/C,MAAM,gBAAgB;IACpB,SAAS,CAAC,YAAY,YAAY;IAClC,gBAAgB;IAChB;GACF;GAEA,MAAM,CAAC,SAAS,UAAU,aAAa,MAAM,QAAQ,IAAI;IACvD,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,0BAA0B;KACjC,aAAa;KACb,OAAOA;IACT,CAAC;IAMD,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,iCAAiC;KACxC,aAAa;KACb,OAAOA;IACT,CAAC;IACD,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,kCAAkC;KACzC,aAAa;KACb,OAAOA;IACT,CAAC;GACH,CAAC;GAGD,MAAM,2BAAW,IAAI,IAAmB;GAExC,MAAM,UAAU,aACd,YAAY,UAAU,iBAAiB;IAAE,QAAQ;IAAG,MAAM;IAAM,UAAU;GAAK,EAAE;GAEnF,MAAM,cAAc,WAAmC;IACrD,KAAK,MAAM,SAAS,QAAQ;KAC1B,MAAM,WAAW,MAAM,WAAW;KAClC,IAAI,CAAC,UAAU;KACf,MAAM,QAAQ,OAAO,QAAkB;KACvC,MAAM,UAAU,MAAM;KACtB,IAAI,MAAM,iBAAiB,MAAM;MAC/B,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM;MACvC,IAAI,MAAM,UAAU,MAAM,WAAW,MAAM;KAC7C;IACF;GACF;GACA,WAAW,SAAS,MAAM;GAC1B,WAAW,UAAU,MAAM;GAE3B,OAAO,QAAQ,OACZ,QAAO,UAAS,CAAC,CAAC,MAAM,WAAW,QAAQ,CAAC,CAC5C,KAAI,UAAS;IACZ,MAAM,WAAW,MAAM,WAAW;IAClC,MAAM,QAAQ,SAAS,IAAI,QAAQ;IACnC,OAAO;KACL;KACA,YAAa,MAAM,WAAW,cAAqC;KACnE,MAAM,MAAM;KACZ,QAAQ,OAAO,UAAU;KACzB,MAAM,OAAO,QAAQ;KACrB,UAAU,OAAO,YAAY;IAC/B;GACF,CAAC;EACL;EACA,GAAG;CACL,CAAC;AACH;;;ACxFA,MAAM,QAAQ;;;;;;;AAQd,SAAgB,gCACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAA4B;EAAS;EAC3D,SAAS,YAA2C;GAClD,MAAM,gBAAgB;IACpB,SAAS,CAAC,YAAY;IACtB,gBAAgB;IAChB;GACF;GAEA,MAAM,CAAC,YAAY,UAAU,aAAa,MAAM,QAAQ,IAAI;IAC1D,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,0BAA0B;KACjC,aAAa;KACb,gBAAgB;KAChB,OAAO;IACT,CAAC;IAMD,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,iCAAiC;KACxC,aAAa;KACb,OAAO;IACT,CAAC;IACD,OAAO,mBAAmB;KACxB,GAAG;KACH,MAAM,CAAC,kCAAkC;KACzC,aAAa;KACb,OAAO;IACT,CAAC;GACH,CAAC;GAGD,MAAM,6BAAa,IAAI,IAAmB;GAE1C,MAAM,UAAU,eACd,YAAY,YAAY,mBAAmB;IAAE,QAAQ;IAAG,MAAM;IAAM,UAAU;GAAK,EAAE;GAEvF,MAAM,cAAc,WAAmC;IACrD,KAAK,MAAM,SAAS,QAAQ;KAC1B,MAAM,aAAa,MAAM,WAAW;KACpC,IAAI,CAAC,YAAY;KACjB,MAAM,QAAQ,OAAO,UAAoB;KACzC,MAAM,UAAU,MAAM;KACtB,IAAI,MAAM,iBAAiB,MAAM;MAC/B,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM;MACvC,IAAI,MAAM,UAAU,MAAM,WAAW,MAAM;KAC7C;IACF;GACF;GACA,WAAW,SAAS,MAAM;GAC1B,WAAW,UAAU,MAAM;GAE3B,OAAO,WAAW,OACf,QAAO,UAAS,CAAC,CAAC,MAAM,WAAW,UAAU,CAAC,CAC9C,KAAI,UAAS;IACZ,MAAM,aAAa,MAAM,WAAW;IACpC,MAAM,QAAQ,WAAW,IAAI,UAAU;IACvC,OAAO;KACL;KACA,aAAa,MAAM;KACnB,QAAQ,OAAO,UAAU;KACzB,MAAM,OAAO,QAAQ;KACrB,UAAU,OAAO,YAAY;IAC/B;GACF,CAAC;EACL;EACA,GAAG;CACL,CAAC;AACH;;;AC1FA,SAAgB,yBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAoB;EAAS;EACnD,SAAS,YAAqC;GAC5C,MAAM,CAAC,OAAO,UAAU,MAAM,QAAQ,IAAI,CACxC,OAAO,mBAAmB;IACxB,MAAM,CAAC,iCAAiC;IACxC,aAAa;IACb;IACA,eAAe;GACjB,CAAC,GACD,OAAO,mBAAmB;IACxB,MAAM,CAAC,kCAAkC;IACzC,aAAa;IACb;IACA,eAAe;GACjB,CAAC,CACH,CAAC;GAED,MAAM,aAAa,MAAM,SAAS,QAAQ,OAAO,SAAS;GAC1D,MAAM,cAAc,MAAM,iBAAiB,QAAQ,OAAO,iBAAiB;GAC3E,MAAM,SAAS,MAAM,SAAS,MAAM,OAAO,SAAS;GACpD,MAAM,iBAAiB,MAAM,iBAAiB,MAAM,OAAO,iBAAiB;GAC5E,MAAM,gBAAgB,eAAe,gBAAgB,KAAM,QAAQ,iBAAiB,gBAAiB,MAAM;GAE3G,OAAO;IACL,OAAO,aAAa,QAAQ;IAC5B,eAAe,cAAc,gBAAgB;IAC7C;GACF;EACF;EACA,GAAG;CACL,CAAC;AACH;;;ACtCA,eAAe,YACb,QACA,YACA,SACsB;CACtB,MAAM,MAAM,MAAM,OAAO,mBAAmB;EAC1C,MAAM,CAAC,UAAU;EACjB,SAAS,CAAC,cAAc,QAAQ;EAChC,aAAa;EACb,gBAAgB;EAChB;CACF,CAAC;CAED,MAAM,sBAAM,IAAI,IAAmD;CAEnE,KAAK,MAAM,SAAS,IAAI,QAAQ;EAC9B,MAAM,OAAO,MAAM,WAAW,cAAc;EAC5C,MAAM,SAAS,MAAM,WAAW,UAAU;EAC1C,MAAM,QAAQ,YAAY,KAAK,aAAa;GAAE,WAAW;GAAG,QAAQ;EAAE,EAAE;EAExE,IAAI,WAAW,SACb,MAAM,UAAU,MAAM;OAEtB,MAAM,aAAa,MAAM;CAE7B;CAEA,OAAO,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,CAC7B,KAAK,CAAC,MAAM,WAAW;EAAE;EAAM,GAAG;CAAK,EAAE,CAAC,CAC1C,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO;AACrE;AAQA,SAAgB,sBACd,QAC8B;CAC9B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,EAAE,SAAS,WAAW,iBAAiB;CAE7C,OAAO,SAAS;EACd,UAAU;GAAC;GAAW;GAAgB;EAAS;EAC/C,SAAS,YAAsC;GAC7C,MAAM,CAAC,WAAW,cAAc,YAAY,MAAM,QAAQ,IAAI;IAC5D,YAAY,QAAQ,4BAA4B,OAAO;IACvD,YAAY,QAAQ,+BAA+B,OAAO;IAC1D,YAAY,QAAQ,2BAA2B,OAAO;GACxD,CAAC;GACD,OAAO;IAAE;IAAW;IAAc;GAAS;EAC7C;EACA,GAAG;CACL,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["TOP_N"],"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,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_mastra_client_context = require("../../mastra-client-context-
|
|
2
|
+
const require_mastra_client_context = require("../../mastra-client-context-DX8wJM9p.cjs");
|
|
3
3
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
4
|
-
|
|
4
|
+
// src/hooks/processors/use-processors.ts
|
|
5
5
|
const useProcessors = ({ requestContext, queryOptions } = {}) => {
|
|
6
6
|
const client = require_mastra_client_context.useMastraClient();
|
|
7
7
|
return (0, _tanstack_react_query.useQuery)({
|
|
@@ -35,7 +35,6 @@ const useExecuteProcessor = ({ requestContext, queryOptions } = {}) => {
|
|
|
35
35
|
...queryOptions
|
|
36
36
|
});
|
|
37
37
|
};
|
|
38
|
-
//#endregion
|
|
39
38
|
exports.useExecuteProcessor = useExecuteProcessor;
|
|
40
39
|
exports.useProcessor = useProcessor;
|
|
41
40
|
exports.useProcessors = useProcessors;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as useMastraClient } from "../../mastra-client-context-
|
|
1
|
+
import { n as useMastraClient } from "../../mastra-client-context-DQ5z_ze9.js";
|
|
2
2
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
3
|
-
|
|
3
|
+
// src/hooks/processors/use-processors.ts
|
|
4
4
|
const useProcessors = ({ requestContext, queryOptions } = {}) => {
|
|
5
5
|
const client = useMastraClient();
|
|
6
6
|
return useQuery({
|
|
@@ -34,7 +34,6 @@ const useExecuteProcessor = ({ requestContext, queryOptions } = {}) => {
|
|
|
34
34
|
...queryOptions
|
|
35
35
|
});
|
|
36
36
|
};
|
|
37
|
-
//#endregion
|
|
38
37
|
export { useExecuteProcessor, useProcessor, useProcessors };
|
|
39
38
|
|
|
40
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_mastra_client_context = require("../../mastra-client-context-
|
|
2
|
+
const require_mastra_client_context = require("../../mastra-client-context-DX8wJM9p.cjs");
|
|
3
3
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
4
|
-
|
|
4
|
+
// src/hooks/prompt-blocks/use-prompt-block-versions.ts
|
|
5
5
|
/**
|
|
6
6
|
* Hook to list versions of a stored prompt block
|
|
7
7
|
*
|
|
@@ -98,8 +98,7 @@ const useDeletePromptBlockVersion = ({ blockId, requestContext, queryOptions })
|
|
|
98
98
|
...queryOptions
|
|
99
99
|
});
|
|
100
100
|
};
|
|
101
|
-
|
|
102
|
-
//#region src/hooks/prompt-blocks/use-stored-prompt-blocks.ts
|
|
101
|
+
// src/hooks/prompt-blocks/use-stored-prompt-blocks.ts
|
|
103
102
|
const useStoredPromptBlocks = ({ requestContext, queryOptions, ...params } = {}) => {
|
|
104
103
|
const client = require_mastra_client_context.useMastraClient();
|
|
105
104
|
return (0, _tanstack_react_query.useQuery)({
|
|
@@ -167,7 +166,6 @@ const useStoredPromptBlockMutations = ({ blockId, requestContext, queryOptions }
|
|
|
167
166
|
})
|
|
168
167
|
};
|
|
169
168
|
};
|
|
170
|
-
//#endregion
|
|
171
169
|
exports.useActivatePromptBlockVersion = useActivatePromptBlockVersion;
|
|
172
170
|
exports.useCreatePromptBlockVersion = useCreatePromptBlockVersion;
|
|
173
171
|
exports.useDeletePromptBlockVersion = useDeletePromptBlockVersion;
|