@mastra/react 1.12.0-alpha.8 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/{accumulator-C8kIc450.js → accumulator-BfvVnXJr.js} +1 -2
  2. package/dist/{accumulator-C8kIc450.js.map → accumulator-BfvVnXJr.js.map} +1 -1
  3. package/dist/{accumulator-BQGsraqS.cjs → accumulator-CgLQ_3q3.cjs} +1 -2
  4. package/dist/{accumulator-BQGsraqS.cjs.map → accumulator-CgLQ_3q3.cjs.map} +1 -1
  5. package/dist/chat/index.cjs +1 -1
  6. package/dist/chat/index.js +1 -2
  7. package/dist/combine-by-ids-D_lp6Dvq.cjs.map +1 -1
  8. package/dist/experiments-B7vRMK5T.js +306 -0
  9. package/dist/experiments-B7vRMK5T.js.map +1 -0
  10. package/dist/experiments-CJw1N3FB.cjs +353 -0
  11. package/dist/experiments-CJw1N3FB.cjs.map +1 -0
  12. package/dist/hooks/agents/index.cjs +2 -2
  13. package/dist/hooks/agents/index.cjs.map +1 -1
  14. package/dist/hooks/agents/index.js +2 -2
  15. package/dist/hooks/agents/index.js.map +1 -1
  16. package/dist/hooks/auth/index.cjs +2 -2
  17. package/dist/hooks/auth/index.cjs.map +1 -1
  18. package/dist/hooks/auth/index.js +2 -2
  19. package/dist/hooks/auth/index.js.map +1 -1
  20. package/dist/hooks/capabilities/index.cjs +16 -1
  21. package/dist/hooks/capabilities/index.cjs.map +1 -1
  22. package/dist/hooks/capabilities/index.d.ts +1 -0
  23. package/dist/hooks/capabilities/index.d.ts.map +1 -1
  24. package/dist/hooks/capabilities/index.js +16 -2
  25. package/dist/hooks/capabilities/index.js.map +1 -1
  26. package/dist/hooks/capabilities/use-trace-query-delta-polling-available.d.ts +10 -0
  27. package/dist/hooks/capabilities/use-trace-query-delta-polling-available.d.ts.map +1 -0
  28. package/dist/hooks/configuration/index.cjs.map +1 -1
  29. package/dist/hooks/datasets/index.cjs +25 -1
  30. package/dist/hooks/datasets/index.cjs.map +1 -1
  31. package/dist/hooks/datasets/index.js +25 -2
  32. package/dist/hooks/datasets/index.js.map +1 -1
  33. package/dist/hooks/datasets/use-datasets.d.ts +7 -0
  34. package/dist/hooks/datasets/use-datasets.d.ts.map +1 -1
  35. package/dist/hooks/embedders/index.cjs.map +1 -1
  36. package/dist/hooks/experiments/index.cjs +9 -235
  37. package/dist/hooks/experiments/index.d.ts +1 -0
  38. package/dist/hooks/experiments/index.d.ts.map +1 -1
  39. package/dist/hooks/experiments/index.js +1 -229
  40. package/dist/hooks/experiments/usage-accumulator.d.ts +25 -0
  41. package/dist/hooks/experiments/usage-accumulator.d.ts.map +1 -0
  42. package/dist/hooks/experiments/use-experiment-item-usage.d.ts +2 -7
  43. package/dist/hooks/experiments/use-experiment-item-usage.d.ts.map +1 -1
  44. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts +19 -0
  45. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts.map +1 -0
  46. package/dist/hooks/feedback/index.cjs.map +1 -1
  47. package/dist/hooks/llm/index.cjs.map +1 -1
  48. package/dist/hooks/logs/index.cjs.map +1 -1
  49. package/dist/hooks/mcps/index.cjs.map +1 -1
  50. package/dist/hooks/memory/index.cjs +10 -10
  51. package/dist/hooks/memory/index.cjs.map +1 -1
  52. package/dist/hooks/memory/index.js +10 -10
  53. package/dist/hooks/memory/index.js.map +1 -1
  54. package/dist/hooks/metrics/index.cjs +13 -11
  55. package/dist/hooks/metrics/index.cjs.map +1 -1
  56. package/dist/hooks/metrics/index.js +13 -11
  57. package/dist/hooks/metrics/index.js.map +1 -1
  58. package/dist/hooks/processors/index.cjs.map +1 -1
  59. package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
  60. package/dist/hooks/query/index.cjs.map +1 -1
  61. package/dist/hooks/review/index.cjs +2 -2
  62. package/dist/hooks/review/index.cjs.map +1 -1
  63. package/dist/hooks/review/index.js +1 -1
  64. package/dist/hooks/schedules/index.cjs.map +1 -1
  65. package/dist/hooks/scores/index.cjs.map +1 -1
  66. package/dist/hooks/templates/index.cjs +20 -18
  67. package/dist/hooks/templates/index.cjs.map +1 -1
  68. package/dist/hooks/templates/index.js +20 -18
  69. package/dist/hooks/templates/index.js.map +1 -1
  70. package/dist/hooks/tool-providers/index.cjs +1 -1
  71. package/dist/hooks/tool-providers/index.cjs.map +1 -1
  72. package/dist/hooks/tool-providers/index.js +1 -1
  73. package/dist/hooks/tool-providers/index.js.map +1 -1
  74. package/dist/hooks/tools/index.cjs.map +1 -1
  75. package/dist/hooks/traces/index.cjs +185 -10
  76. package/dist/hooks/traces/index.cjs.map +1 -1
  77. package/dist/hooks/traces/index.js +182 -11
  78. package/dist/hooks/traces/index.js.map +1 -1
  79. package/dist/hooks/traces/use-trace-query.d.ts +50 -1
  80. package/dist/hooks/traces/use-trace-query.d.ts.map +1 -1
  81. package/dist/hooks/vectors/index.cjs.map +1 -1
  82. package/dist/hooks/voice/index.cjs.map +1 -1
  83. package/dist/hooks/workflows/index.cjs +1 -1
  84. package/dist/hooks/workflows/index.cjs.map +1 -1
  85. package/dist/hooks/workflows/index.js +1 -1
  86. package/dist/hooks/workspace/index.cjs +1 -1
  87. package/dist/hooks/workspace/index.cjs.map +1 -1
  88. package/dist/hooks/workspace/index.js +1 -1
  89. package/dist/hooks/workspace/index.js.map +1 -1
  90. package/dist/{hooks-CIutb3DO.cjs → hooks-B1i-oHae.cjs} +6 -4
  91. package/dist/hooks-B1i-oHae.cjs.map +1 -0
  92. package/dist/{hooks-FVbeHlov.js → hooks-CLfMO5cH.js} +6 -4
  93. package/dist/{hooks-FVbeHlov.js.map → hooks-CLfMO5cH.js.map} +1 -1
  94. package/dist/{hooks-_YevKidX.cjs → hooks-D8nOYPUd.cjs} +2 -2
  95. package/dist/hooks-D8nOYPUd.cjs.map +1 -0
  96. package/dist/{hooks-0L0RNfau.js → hooks-NaZLZreZ.js} +2 -2
  97. package/dist/{hooks-0L0RNfau.js.map → hooks-NaZLZreZ.js.map} +1 -1
  98. package/dist/index.cjs +3 -3
  99. package/dist/index.cjs.map +1 -1
  100. package/dist/index.js +3 -3
  101. package/dist/mastra-client-context-DzX3f0RF.cjs.map +1 -1
  102. package/dist/ui/index.cjs +4 -4
  103. package/dist/ui/index.cjs.map +1 -1
  104. package/dist/ui/index.js +3 -3
  105. package/dist/ui/index.js.map +1 -1
  106. package/dist/use-in-view-B6eJO9Zi.cjs.map +1 -1
  107. package/dist/voice-BOtUdMi8.cjs.map +1 -1
  108. package/package.json +5 -5
  109. package/dist/hooks/experiments/index.cjs.map +0 -1
  110. package/dist/hooks/experiments/index.js.map +0 -1
  111. package/dist/hooks-CIutb3DO.cjs.map +0 -1
  112. package/dist/hooks-_YevKidX.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-datasets.d.ts","sourceRoot":"","sources":["../../../src/hooks/datasets/use-datasets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,KAAK,EAAgB,QAAQ,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5G,OAAO,KAAK,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG9F,KAAK,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC9E,KAAK,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,GAAG,oBAAoB,kCAGrD;IACD,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,YAAY,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;CAChE,KAAQ,cAAc,CAAC,KAAK,EAAE,KAAK,CAQnC,CAAC;AAIF,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,oBAAoB,GAAG,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;AAEzE,KAAK,aAAa,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,yBAAyB,CAAC,KAAK,GAAG,aAAa,EAAE,IAAI,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG;IACtG,mBAAmB,EAAE,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;CAC/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,GAAG,aAAa,EAAE,uCAIxD;IACD,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,YAAY,CAAC,EAAE,0BAA0B,CAAC,oBAAoB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;CAC1F,KAAQ,yBAAyB,CAAC,KAAK,CA6BvC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,GAAG,eAAe,gCAG/C;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;CAC3D,KAAG,cAAc,CAAC,KAAK,EAAE,KAAK,CAO9B,CAAC"}
1
+ {"version":3,"file":"use-datasets.d.ts","sourceRoot":"","sources":["../../../src/hooks/datasets/use-datasets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEhG,OAAO,KAAK,EAAgB,QAAQ,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5G,OAAO,KAAK,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG9F,KAAK,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAC9E,KAAK,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,GAAG,oBAAoB,kCAGrD;IACD,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,YAAY,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;CAChE,KAAQ,cAAc,CAAC,KAAK,EAAE,KAAK,CAQnC,CAAC;AAIF,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,oBAAoB,GAAG,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;AAEzE,KAAK,aAAa,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,yBAAyB,CAAC,KAAK,GAAG,aAAa,EAAE,IAAI,sBAAsB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG;IACtG,mBAAmB,EAAE,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;CAC/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,GAAG,aAAa,EAAE,uCAIxD;IACD,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,YAAY,CAAC,EAAE,0BAA0B,CAAC,oBAAoB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;CAC1F,KAAQ,yBAAyB,CAAC,KAAK,CA6BvC,CAAC;AAKF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,oBAE1B;IACD,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,KAAG,cAAc,CAAC,aAAa,EAAE,EAAE,KAAK,CAkBxC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,GAAG,eAAe,gCAG/C;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;CAC3D,KAAG,cAAc,CAAC,KAAK,EAAE,KAAK,CAO9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useMastraClient"],"sources":["../../../src/hooks/embedders/use-embedders.ts"],"sourcesContent":["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';\n\nexport interface Embedder {\n id: string;\n provider: string;\n name: string;\n description: string;\n dimensions: number;\n maxInputTokens: number;\n}\n\ntype ListEmbeddersResponse = Awaited<ReturnType<MastraClient['listEmbedders']>>;\n\nexport function useEmbedders<TData = ListEmbeddersResponse>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<ListEmbeddersResponse, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['embedders'],\n queryFn: async () => {\n const data = await client.listEmbedders();\n return data;\n },\n staleTime: 30000, // Cache for 30 seconds\n ...queryOptions,\n });\n}\n"],"mappings":";;;;AAiBA,SAAgB,aAA4C,EAC1D,iBACuE,CAAC,GAAiC;CACzG,MAAM,SAASA,8BAAAA,gBAAgB;CAE/B,QAAA,GAAA,sBAAA,SAAA,CAAgB;EACd,UAAU,CAAC,WAAW;EACtB,SAAS,YAAY;GAEnB,OAAO,MADY,OAAO,cAAc;EAE1C;EACA,WAAW;EACX,GAAG;CACL,CAAC;AACH"}
1
+ {"version":3,"file":"index.cjs","names":["useMastraClient","useQuery"],"sources":["../../../src/hooks/embedders/use-embedders.ts"],"sourcesContent":["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';\n\nexport interface Embedder {\n id: string;\n provider: string;\n name: string;\n description: string;\n dimensions: number;\n maxInputTokens: number;\n}\n\ntype ListEmbeddersResponse = Awaited<ReturnType<MastraClient['listEmbedders']>>;\n\nexport function useEmbedders<TData = ListEmbeddersResponse>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<ListEmbeddersResponse, TData> } = {}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['embedders'],\n queryFn: async () => {\n const data = await client.listEmbedders();\n return data;\n },\n staleTime: 30000, // Cache for 30 seconds\n ...queryOptions,\n });\n}\n"],"mappings":";;;;AAiBA,SAAgB,aAA4C,EAC1D,iBACuE,CAAC,GAAiC;CACzG,MAAM,SAASA,8BAAAA,gBAAgB;CAE/B,QAAA,GAAOC,sBAAAA,SAAAA,CAAS;EACd,UAAU,CAAC,WAAW;EACtB,SAAS,YAAY;GAEnB,OAAO,MADY,OAAO,cAAc;EAE1C;EACA,WAAW;EACX,GAAG;CACL,CAAC;AACH"}
@@ -1,236 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_mastra_client_context = require("../../mastra-client-context-DzX3f0RF.cjs");
3
- const require_use_in_view = require("../../use-in-view-B6eJO9Zi.cjs");
4
- const require_combine_by_ids = require("../../combine-by-ids-D_lp6Dvq.cjs");
5
- const require_map = require("../../map-wjmL1y5O.cjs");
6
- let react = require("react");
7
- let _tanstack_react_query = require("@tanstack/react-query");
8
- //#region src/hooks/experiments/use-experiment-item-usage.ts
9
- const INPUT_TOKEN_METRIC = "mastra_model_total_input_tokens";
10
- const OUTPUT_TOKEN_METRIC = "mastra_model_total_output_tokens";
11
- const POLL_INTERVAL_MS = 2e3;
12
- const createAccumulator = () => ({
13
- estimatedCost: 0,
14
- costUnits: /* @__PURE__ */ new Set(),
15
- hasUnknownCostUnit: false
16
- });
17
- function accumulate(accumulator, tokenField, group) {
18
- accumulator[tokenField] = (accumulator[tokenField] ?? 0) + group.value;
19
- if (group.estimatedCost == null) return;
20
- accumulator.estimatedCost += group.estimatedCost;
21
- if (group.costUnit) accumulator.costUnits.add(group.costUnit.toLowerCase());
22
- else accumulator.hasUnknownCostUnit = true;
23
- }
24
- function toUsage(accumulator) {
25
- const isPriced = !accumulator.hasUnknownCostUnit && accumulator.costUnits.size === 1;
26
- return {
27
- inputTokens: accumulator.inputTokens,
28
- outputTokens: accumulator.outputTokens,
29
- estimatedCost: isPriced ? accumulator.estimatedCost : void 0,
30
- costUnit: isPriced ? [...accumulator.costUnits][0] : void 0
31
- };
32
- }
33
- /** Builds the experiment totals and the per-trace usage in a single pass over the groups. */
34
- function toExperimentUsage(response) {
35
- const summary = createAccumulator();
36
- const accumulators = /* @__PURE__ */ new Map();
37
- for (const group of response.groups) {
38
- const metricName = group.dimensions.name;
39
- if (metricName !== INPUT_TOKEN_METRIC && metricName !== OUTPUT_TOKEN_METRIC) continue;
40
- const tokenField = metricName === INPUT_TOKEN_METRIC ? "inputTokens" : "outputTokens";
41
- accumulate(summary, tokenField, group);
42
- const traceId = group.dimensions.traceId;
43
- if (traceId) accumulate(require_map.getOrCreate(accumulators, traceId, createAccumulator), tokenField, group);
44
- }
45
- const traces = {};
46
- for (const [traceId, accumulator] of accumulators) traces[traceId] = toUsage(accumulator);
47
- return {
48
- summary: toUsage(summary),
49
- traces
50
- };
51
- }
52
- /** How many breakdowns to fetch after completion while the exporter may still be flushing metrics. */
53
- const MAX_EMPTY_ATTEMPTS = 5;
54
- const isEmptyUsage = (usage) => !usage || Object.keys(usage.traces).length === 0 && usage.summary.inputTokens === void 0 && usage.summary.outputTokens === void 0;
55
- /**
56
- * Token and cost usage of several experiments, keyed by experiment id: each entry holds the
57
- * experiment totals (`summary`) and every item's usage keyed by trace id (`traces`).
58
- * Sends one metric breakdown request per experiment, filtered by its id rather than by trace ids,
59
- * so it does not wait for the experiment results. Usage is only fetched once an experiment has
60
- * finished; while the breakdown is still empty (metrics flushing), it retries every 2 seconds up to
61
- * 5 attempts. No request is made when the observability store cannot serve metrics.
62
- */
63
- const useExperimentsItemUsage = ({ experiments, supportsMetrics }) => {
64
- const client = require_mastra_client_context.useMastraClient();
65
- const combine = require_combine_by_ids.useCombineByIds(experiments.map((experiment) => experiment.id));
66
- return (0, _tanstack_react_query.useQueries)({
67
- queries: experiments.map(({ id, status }) => {
68
- const finished = status !== "running" && status !== "pending";
69
- return {
70
- queryKey: [
71
- "experiment-item-usage",
72
- id,
73
- finished
74
- ],
75
- queryFn: async () => toExperimentUsage(await client.getMetricBreakdown({
76
- name: [INPUT_TOKEN_METRIC, OUTPUT_TOKEN_METRIC],
77
- aggregation: "sum",
78
- groupBy: ["traceId", "name"],
79
- filters: { experimentId: id }
80
- })),
81
- enabled: supportsMetrics && finished,
82
- refetchInterval: (query) => isEmptyUsage(query.state.data) && query.state.dataUpdateCount < MAX_EMPTY_ATTEMPTS ? POLL_INTERVAL_MS : false
83
- };
84
- }),
85
- combine
86
- });
87
- };
88
- //#endregion
89
- //#region src/hooks/experiments/use-experiment-metrics.ts
90
- /**
91
- * Experiment-scoped metrics (tokens, cost, avg agent latency).
92
- * Filters only by experimentId — no time window, since the experiment already bounds the row set.
93
- * Polls every 2 seconds while the experiment is running or pending.
94
- *
95
- * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
96
- */
97
- const useExperimentMetrics = ({ experimentId, experimentStatus, supportsMetrics, queryOptions }) => {
98
- const client = require_mastra_client_context.useMastraClient();
99
- const isEnabled = Boolean(experimentId) && supportsMetrics;
100
- const query = (0, _tanstack_react_query.useQuery)({
101
- queryKey: ["experiment-metrics", experimentId],
102
- refetchInterval: experimentStatus === "running" || experimentStatus === "pending" ? 2e3 : false,
103
- queryFn: async () => {
104
- if (!experimentId) throw new Error("experimentId is required");
105
- const filters = { experimentId };
106
- const [tokens, avgDuration, runs] = await Promise.all([
107
- client.getMetricAggregate({
108
- name: ["mastra_model_total_input_tokens", "mastra_model_total_output_tokens"],
109
- aggregation: "sum",
110
- filters
111
- }),
112
- client.getMetricAggregate({
113
- name: ["mastra_agent_duration_ms"],
114
- aggregation: "avg",
115
- filters
116
- }),
117
- client.getMetricAggregate({
118
- name: ["mastra_agent_duration_ms"],
119
- aggregation: "count",
120
- filters
121
- })
122
- ]);
123
- return {
124
- totalTokens: tokens.value ?? null,
125
- estimatedCost: tokens.estimatedCost ?? null,
126
- costUnit: tokens.costUnit ?? null,
127
- avgAgentDurationMs: avgDuration.value ?? null,
128
- agentRuns: runs.value ?? null
129
- };
130
- },
131
- ...queryOptions
132
- });
133
- return {
134
- data: query.data,
135
- isLoading: query.isLoading,
136
- isEnabled
137
- };
138
- };
139
- //#endregion
140
- //#region src/hooks/experiments/use-experiment-trace.ts
141
- /**
142
- * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
143
- */
144
- const useExperimentTrace = ({ traceId, queryOptions }) => {
145
- const client = require_mastra_client_context.useMastraClient();
146
- return (0, _tanstack_react_query.useQuery)({
147
- queryKey: ["experiment-trace-light", traceId],
148
- queryFn: async () => {
149
- if (!traceId) throw new Error("Trace ID is required");
150
- return client.getTraceLight(traceId);
151
- },
152
- ...queryOptions
153
- });
154
- };
155
- //#endregion
156
- //#region src/hooks/experiments/use-experiments-for-dataset-filter.ts
157
- /** Explicit page size: server defaults are 20 (global) / 10 (per dataset), which is too small for the list. */
158
- const EXPERIMENTS_PAGE_SIZE = 100;
159
- function useExperimentsForDatasetFilter({ datasetId, target, queryOptions }) {
160
- const client = require_mastra_client_context.useMastraClient();
161
- const params = { perPage: 100 };
162
- if (target?.targetType) params.targetType = target.targetType;
163
- if (target?.targetId) params.targetId = target.targetId;
164
- return (0, _tanstack_react_query.useQuery)({
165
- queryKey: datasetId ? [
166
- "dataset-experiments",
167
- datasetId,
168
- params
169
- ] : ["experiments", params],
170
- queryFn: () => datasetId ? client.listDatasetExperiments(datasetId, params) : client.listExperiments(params),
171
- ...queryOptions
172
- });
173
- }
174
- //#endregion
175
- //#region src/hooks/experiments/use-infinite-experiments.ts
176
- const EXPERIMENTS_PER_PAGE = 100;
177
- function useInfiniteExperiments({ datasetId, target, orderBy, queryOptions }) {
178
- const client = require_mastra_client_context.useMastraClient();
179
- const { inView: isEndOfListInView, setRef: setEndOfListElement } = require_use_in_view.useInView();
180
- const targetType = target?.targetType || void 0;
181
- const targetId = target?.targetId || void 0;
182
- const query = (0, _tanstack_react_query.useInfiniteQuery)({
183
- queryKey: datasetId ? [
184
- "dataset-experiments",
185
- datasetId,
186
- "infinite",
187
- {
188
- targetType,
189
- targetId,
190
- orderBy
191
- }
192
- ] : [
193
- "experiments",
194
- "infinite",
195
- {
196
- targetType,
197
- targetId,
198
- orderBy
199
- }
200
- ],
201
- queryFn: ({ pageParam }) => {
202
- const params = {
203
- page: pageParam,
204
- perPage: 100
205
- };
206
- if (targetType) params.targetType = targetType;
207
- if (targetId) params.targetId = targetId;
208
- if (orderBy) params.orderBy = orderBy;
209
- return datasetId ? client.listDatasetExperiments(datasetId, params) : client.listExperiments(params);
210
- },
211
- initialPageParam: 0,
212
- getNextPageParam: (lastPage, _, lastPageParam) => {
213
- if (!lastPage?.experiments?.length || !lastPage.pagination?.hasMore) return;
214
- return lastPageParam + 1;
215
- },
216
- select: (data) => data.pages.flatMap((page) => page?.experiments ?? []),
217
- ...queryOptions
218
- });
219
- (0, react.useEffect)(() => {
220
- if (isEndOfListInView && query.hasNextPage && !query.isFetchingNextPage) query.fetchNextPage();
221
- }, [isEndOfListInView, query]);
222
- return {
223
- ...query,
224
- setEndOfListElement
225
- };
226
- }
227
- //#endregion
228
- exports.EXPERIMENTS_PAGE_SIZE = EXPERIMENTS_PAGE_SIZE;
229
- exports.EXPERIMENTS_PER_PAGE = EXPERIMENTS_PER_PAGE;
230
- exports.useExperimentMetrics = useExperimentMetrics;
231
- exports.useExperimentTrace = useExperimentTrace;
232
- exports.useExperimentsForDatasetFilter = useExperimentsForDatasetFilter;
233
- exports.useExperimentsItemUsage = useExperimentsItemUsage;
234
- exports.useInfiniteExperiments = useInfiniteExperiments;
235
-
236
- //# sourceMappingURL=index.cjs.map
2
+ const require_experiments = require("../../experiments-CJw1N3FB.cjs");
3
+ exports.EXPERIMENTS_PAGE_SIZE = require_experiments.EXPERIMENTS_PAGE_SIZE;
4
+ exports.EXPERIMENTS_PER_PAGE = require_experiments.EXPERIMENTS_PER_PAGE;
5
+ exports.useExperimentMetrics = require_experiments.useExperimentMetrics;
6
+ exports.useExperimentTrace = require_experiments.useExperimentTrace;
7
+ exports.useExperimentsForDatasetFilter = require_experiments.useExperimentsForDatasetFilter;
8
+ exports.useExperimentsItemUsage = require_experiments.useExperimentsItemUsage;
9
+ exports.useExperimentsListMetrics = require_experiments.useExperimentsListMetrics;
10
+ exports.useInfiniteExperiments = require_experiments.useInfiniteExperiments;
@@ -2,5 +2,6 @@ export * from './use-experiment-item-usage.js';
2
2
  export * from './use-experiment-metrics.js';
3
3
  export * from './use-experiment-trace.js';
4
4
  export * from './use-experiments-for-dataset-filter.js';
5
+ export * from './use-experiments-list-metrics.js';
5
6
  export * from './use-infinite-experiments.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sCAAsC,CAAC;AACrD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC"}
@@ -1,229 +1 @@
1
- import { n as useMastraClient } from "../../mastra-client-context-Bx_g84YB.js";
2
- import { t as useInView } from "../../use-in-view-C9sYPGRm.js";
3
- import { t as useCombineByIds } from "../../combine-by-ids-CcaZKGT9.js";
4
- import { t as getOrCreate } from "../../map-CDv4fbu4.js";
5
- import { useEffect } from "react";
6
- import { useInfiniteQuery, useQueries, useQuery } from "@tanstack/react-query";
7
- //#region src/hooks/experiments/use-experiment-item-usage.ts
8
- const INPUT_TOKEN_METRIC = "mastra_model_total_input_tokens";
9
- const OUTPUT_TOKEN_METRIC = "mastra_model_total_output_tokens";
10
- const POLL_INTERVAL_MS = 2e3;
11
- const createAccumulator = () => ({
12
- estimatedCost: 0,
13
- costUnits: /* @__PURE__ */ new Set(),
14
- hasUnknownCostUnit: false
15
- });
16
- function accumulate(accumulator, tokenField, group) {
17
- accumulator[tokenField] = (accumulator[tokenField] ?? 0) + group.value;
18
- if (group.estimatedCost == null) return;
19
- accumulator.estimatedCost += group.estimatedCost;
20
- if (group.costUnit) accumulator.costUnits.add(group.costUnit.toLowerCase());
21
- else accumulator.hasUnknownCostUnit = true;
22
- }
23
- function toUsage(accumulator) {
24
- const isPriced = !accumulator.hasUnknownCostUnit && accumulator.costUnits.size === 1;
25
- return {
26
- inputTokens: accumulator.inputTokens,
27
- outputTokens: accumulator.outputTokens,
28
- estimatedCost: isPriced ? accumulator.estimatedCost : void 0,
29
- costUnit: isPriced ? [...accumulator.costUnits][0] : void 0
30
- };
31
- }
32
- /** Builds the experiment totals and the per-trace usage in a single pass over the groups. */
33
- function toExperimentUsage(response) {
34
- const summary = createAccumulator();
35
- const accumulators = /* @__PURE__ */ new Map();
36
- for (const group of response.groups) {
37
- const metricName = group.dimensions.name;
38
- if (metricName !== INPUT_TOKEN_METRIC && metricName !== OUTPUT_TOKEN_METRIC) continue;
39
- const tokenField = metricName === INPUT_TOKEN_METRIC ? "inputTokens" : "outputTokens";
40
- accumulate(summary, tokenField, group);
41
- const traceId = group.dimensions.traceId;
42
- if (traceId) accumulate(getOrCreate(accumulators, traceId, createAccumulator), tokenField, group);
43
- }
44
- const traces = {};
45
- for (const [traceId, accumulator] of accumulators) traces[traceId] = toUsage(accumulator);
46
- return {
47
- summary: toUsage(summary),
48
- traces
49
- };
50
- }
51
- /** How many breakdowns to fetch after completion while the exporter may still be flushing metrics. */
52
- const MAX_EMPTY_ATTEMPTS = 5;
53
- const isEmptyUsage = (usage) => !usage || Object.keys(usage.traces).length === 0 && usage.summary.inputTokens === void 0 && usage.summary.outputTokens === void 0;
54
- /**
55
- * Token and cost usage of several experiments, keyed by experiment id: each entry holds the
56
- * experiment totals (`summary`) and every item's usage keyed by trace id (`traces`).
57
- * Sends one metric breakdown request per experiment, filtered by its id rather than by trace ids,
58
- * so it does not wait for the experiment results. Usage is only fetched once an experiment has
59
- * finished; while the breakdown is still empty (metrics flushing), it retries every 2 seconds up to
60
- * 5 attempts. No request is made when the observability store cannot serve metrics.
61
- */
62
- const useExperimentsItemUsage = ({ experiments, supportsMetrics }) => {
63
- const client = useMastraClient();
64
- const combine = useCombineByIds(experiments.map((experiment) => experiment.id));
65
- return useQueries({
66
- queries: experiments.map(({ id, status }) => {
67
- const finished = status !== "running" && status !== "pending";
68
- return {
69
- queryKey: [
70
- "experiment-item-usage",
71
- id,
72
- finished
73
- ],
74
- queryFn: async () => toExperimentUsage(await client.getMetricBreakdown({
75
- name: [INPUT_TOKEN_METRIC, OUTPUT_TOKEN_METRIC],
76
- aggregation: "sum",
77
- groupBy: ["traceId", "name"],
78
- filters: { experimentId: id }
79
- })),
80
- enabled: supportsMetrics && finished,
81
- refetchInterval: (query) => isEmptyUsage(query.state.data) && query.state.dataUpdateCount < MAX_EMPTY_ATTEMPTS ? POLL_INTERVAL_MS : false
82
- };
83
- }),
84
- combine
85
- });
86
- };
87
- //#endregion
88
- //#region src/hooks/experiments/use-experiment-metrics.ts
89
- /**
90
- * Experiment-scoped metrics (tokens, cost, avg agent latency).
91
- * Filters only by experimentId — no time window, since the experiment already bounds the row set.
92
- * Polls every 2 seconds while the experiment is running or pending.
93
- *
94
- * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
95
- */
96
- const useExperimentMetrics = ({ experimentId, experimentStatus, supportsMetrics, queryOptions }) => {
97
- const client = useMastraClient();
98
- const isEnabled = Boolean(experimentId) && supportsMetrics;
99
- const query = useQuery({
100
- queryKey: ["experiment-metrics", experimentId],
101
- refetchInterval: experimentStatus === "running" || experimentStatus === "pending" ? 2e3 : false,
102
- queryFn: async () => {
103
- if (!experimentId) throw new Error("experimentId is required");
104
- const filters = { experimentId };
105
- const [tokens, avgDuration, runs] = await Promise.all([
106
- client.getMetricAggregate({
107
- name: ["mastra_model_total_input_tokens", "mastra_model_total_output_tokens"],
108
- aggregation: "sum",
109
- filters
110
- }),
111
- client.getMetricAggregate({
112
- name: ["mastra_agent_duration_ms"],
113
- aggregation: "avg",
114
- filters
115
- }),
116
- client.getMetricAggregate({
117
- name: ["mastra_agent_duration_ms"],
118
- aggregation: "count",
119
- filters
120
- })
121
- ]);
122
- return {
123
- totalTokens: tokens.value ?? null,
124
- estimatedCost: tokens.estimatedCost ?? null,
125
- costUnit: tokens.costUnit ?? null,
126
- avgAgentDurationMs: avgDuration.value ?? null,
127
- agentRuns: runs.value ?? null
128
- };
129
- },
130
- ...queryOptions
131
- });
132
- return {
133
- data: query.data,
134
- isLoading: query.isLoading,
135
- isEnabled
136
- };
137
- };
138
- //#endregion
139
- //#region src/hooks/experiments/use-experiment-trace.ts
140
- /**
141
- * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.
142
- */
143
- const useExperimentTrace = ({ traceId, queryOptions }) => {
144
- const client = useMastraClient();
145
- return useQuery({
146
- queryKey: ["experiment-trace-light", traceId],
147
- queryFn: async () => {
148
- if (!traceId) throw new Error("Trace ID is required");
149
- return client.getTraceLight(traceId);
150
- },
151
- ...queryOptions
152
- });
153
- };
154
- //#endregion
155
- //#region src/hooks/experiments/use-experiments-for-dataset-filter.ts
156
- /** Explicit page size: server defaults are 20 (global) / 10 (per dataset), which is too small for the list. */
157
- const EXPERIMENTS_PAGE_SIZE = 100;
158
- function useExperimentsForDatasetFilter({ datasetId, target, queryOptions }) {
159
- const client = useMastraClient();
160
- const params = { perPage: 100 };
161
- if (target?.targetType) params.targetType = target.targetType;
162
- if (target?.targetId) params.targetId = target.targetId;
163
- return useQuery({
164
- queryKey: datasetId ? [
165
- "dataset-experiments",
166
- datasetId,
167
- params
168
- ] : ["experiments", params],
169
- queryFn: () => datasetId ? client.listDatasetExperiments(datasetId, params) : client.listExperiments(params),
170
- ...queryOptions
171
- });
172
- }
173
- //#endregion
174
- //#region src/hooks/experiments/use-infinite-experiments.ts
175
- const EXPERIMENTS_PER_PAGE = 100;
176
- function useInfiniteExperiments({ datasetId, target, orderBy, queryOptions }) {
177
- const client = useMastraClient();
178
- const { inView: isEndOfListInView, setRef: setEndOfListElement } = useInView();
179
- const targetType = target?.targetType || void 0;
180
- const targetId = target?.targetId || void 0;
181
- const query = useInfiniteQuery({
182
- queryKey: datasetId ? [
183
- "dataset-experiments",
184
- datasetId,
185
- "infinite",
186
- {
187
- targetType,
188
- targetId,
189
- orderBy
190
- }
191
- ] : [
192
- "experiments",
193
- "infinite",
194
- {
195
- targetType,
196
- targetId,
197
- orderBy
198
- }
199
- ],
200
- queryFn: ({ pageParam }) => {
201
- const params = {
202
- page: pageParam,
203
- perPage: 100
204
- };
205
- if (targetType) params.targetType = targetType;
206
- if (targetId) params.targetId = targetId;
207
- if (orderBy) params.orderBy = orderBy;
208
- return datasetId ? client.listDatasetExperiments(datasetId, params) : client.listExperiments(params);
209
- },
210
- initialPageParam: 0,
211
- getNextPageParam: (lastPage, _, lastPageParam) => {
212
- if (!lastPage?.experiments?.length || !lastPage.pagination?.hasMore) return;
213
- return lastPageParam + 1;
214
- },
215
- select: (data) => data.pages.flatMap((page) => page?.experiments ?? []),
216
- ...queryOptions
217
- });
218
- useEffect(() => {
219
- if (isEndOfListInView && query.hasNextPage && !query.isFetchingNextPage) query.fetchNextPage();
220
- }, [isEndOfListInView, query]);
221
- return {
222
- ...query,
223
- setEndOfListElement
224
- };
225
- }
226
- //#endregion
227
- export { EXPERIMENTS_PAGE_SIZE, EXPERIMENTS_PER_PAGE, useExperimentMetrics, useExperimentTrace, useExperimentsForDatasetFilter, useExperimentsItemUsage, useInfiniteExperiments };
228
-
229
- //# sourceMappingURL=index.js.map
1
+ export { i as EXPERIMENTS_PAGE_SIZE, t as EXPERIMENTS_PER_PAGE, s as useExperimentMetrics, o as useExperimentTrace, a as useExperimentsForDatasetFilter, c as useExperimentsItemUsage, r as useExperimentsListMetrics, n as useInfiniteExperiments } from "../../experiments-B7vRMK5T.js";
@@ -0,0 +1,25 @@
1
+ import type { GetMetricBreakdownResponse } from '@mastra/core/storage';
2
+ export declare const INPUT_TOKEN_METRIC = "mastra_model_total_input_tokens";
3
+ export declare const OUTPUT_TOKEN_METRIC = "mastra_model_total_output_tokens";
4
+ export interface ExperimentItemUsage {
5
+ inputTokens?: number;
6
+ outputTokens?: number;
7
+ /** Undefined when no group is priced or when groups use different cost units. */
8
+ estimatedCost?: number;
9
+ costUnit?: string;
10
+ }
11
+ export type UsageAccumulator = {
12
+ inputTokens?: number;
13
+ outputTokens?: number;
14
+ estimatedCost: number;
15
+ costUnits: Set<string>;
16
+ hasUnknownCostUnit: boolean;
17
+ };
18
+ export declare const createAccumulator: () => UsageAccumulator;
19
+ type BreakdownGroup = GetMetricBreakdownResponse['groups'][number];
20
+ /** The token field a breakdown group feeds, or undefined when the group is not a token metric. */
21
+ export declare function tokenFieldOf(group: BreakdownGroup): 'inputTokens' | 'outputTokens' | undefined;
22
+ export declare function accumulate(accumulator: UsageAccumulator, tokenField: 'inputTokens' | 'outputTokens', group: BreakdownGroup): void;
23
+ export declare function toUsage(accumulator: UsageAccumulator): ExperimentItemUsage;
24
+ export {};
25
+ //# sourceMappingURL=usage-accumulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-accumulator.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/usage-accumulator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEvE,eAAO,MAAM,kBAAkB,oCAAoC,CAAC;AACpE,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAO,gBAInC,CAAC;AAEH,KAAK,cAAc,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,kGAAkG;AAClG,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,GAAG,cAAc,GAAG,SAAS,CAK9F;AAED,wBAAgB,UAAU,CACxB,WAAW,EAAE,gBAAgB,EAC7B,UAAU,EAAE,aAAa,GAAG,cAAc,EAC1C,KAAK,EAAE,cAAc,QAWtB;AAED,wBAAgB,OAAO,CAAC,WAAW,EAAE,gBAAgB,GAAG,mBAAmB,CAS1E"}
@@ -1,12 +1,7 @@
1
1
  import type { ExperimentRef } from '../datasets/use-dataset-experiments.js';
2
2
  import type { ExperimentQueriesResult } from '../shared/combine-by-ids.js';
3
- export interface ExperimentItemUsage {
4
- inputTokens?: number;
5
- outputTokens?: number;
6
- /** Undefined when no group is priced or when groups use different cost units. */
7
- estimatedCost?: number;
8
- costUnit?: string;
9
- }
3
+ import type { ExperimentItemUsage } from './usage-accumulator.js';
4
+ export type { ExperimentItemUsage } from './usage-accumulator.js';
10
5
  /** Usage of one experiment: its totals, and each item's usage keyed by the trace id of its run. */
11
6
  export interface ExperimentUsage {
12
7
  /** Totals across every item. The cost sums priced groups only. */
@@ -1 +1 @@
1
- {"version":3,"file":"use-experiment-item-usage.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/use-experiment-item-usage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAOxE,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC7C;AAyED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,sCAGjC;IACD,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CAC1B,KAAG,uBAAuB,CAAC,eAAe,CAyB1C,CAAC"}
1
+ {"version":3,"file":"use-experiment-item-usage.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/use-experiment-item-usage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAUxE,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,qBAAqB,CAAC;AAEjF,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC7C;AAiCD;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,sCAGjC;IACD,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CAC1B,KAAG,uBAAuB,CAAC,eAAe,CAyB1C,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { UseQueryResult } from '@tanstack/react-query';
2
+ import type { ExperimentRef } from '../datasets/use-dataset-experiments.js';
3
+ import type { ExperimentItemUsage } from './usage-accumulator.js';
4
+ /** Totals of one experiment: token usage, its estimated cost, and the average agent run duration. */
5
+ export interface ExperimentListMetrics extends ExperimentItemUsage {
6
+ avgDurationMs?: number;
7
+ }
8
+ /**
9
+ * Token usage, estimated cost and average agent duration of many experiments, keyed by experiment id.
10
+ * Sends two metric breakdowns per 500 experiments (tokens grouped by experiment and metric name,
11
+ * durations grouped by experiment) instead of one request per experiment.
12
+ * Experiments without any metric are absent from the map. Polls while an experiment is running
13
+ * or pending. No request is made when the observability store cannot serve metrics.
14
+ */
15
+ export declare const useExperimentsListMetrics: ({ experiments, supportsMetrics, }: {
16
+ experiments: ExperimentRef[];
17
+ supportsMetrics: boolean;
18
+ }) => UseQueryResult<Map<string, ExperimentListMetrics>, Error>;
19
+ //# sourceMappingURL=use-experiments-list-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-experiments-list-metrics.d.ts","sourceRoot":"","sources":["../../../src/hooks/experiments/use-experiments-list-metrics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAUzE,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,qBAAqB,CAAC;AAOjF,qGAAqG;AACrG,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA4CD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,sCAGnC;IACD,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CAC1B,KAAG,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,KAAK,CAwC3D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useMastraClient"],"sources":["../../../src/hooks/feedback/use-feedback.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type FeedbackReviewStatus = 'needs-review' | 'reviewed';\n\ntype UpdateFeedbackReviewStatusVariables = { feedbackId: string; reviewStatus: FeedbackReviewStatus };\ntype UpdateFeedbackReviewStatusResponse = Awaited<ReturnType<MastraClient['updateFeedbackReviewStatus']>>;\n\nexport function useUpdateFeedbackReviewStatus({\n queryOptions,\n}: {\n queryOptions?: MastraMutationOptions<UpdateFeedbackReviewStatusResponse, UpdateFeedbackReviewStatusVariables>;\n} = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ feedbackId, reviewStatus }: UpdateFeedbackReviewStatusVariables) =>\n client.updateFeedbackReviewStatus({ feedbackId, reviewStatus }),\n onSuccess: () =>\n Promise.all([\n queryClient.invalidateQueries({ queryKey: ['trace-feedback'] }),\n queryClient.invalidateQueries({ queryKey: ['span-feedback'] }),\n ]),\n ...queryOptions,\n });\n}\n"],"mappings":";;;;;AAUA,SAAgB,8BAA8B,EAC5C,iBAGE,CAAC,GAAG;CACN,MAAM,SAASA,8BAAAA,gBAAgB;CAC/B,MAAM,eAAA,GAAA,sBAAA,eAAA,CAA6B;CAEnC,QAAA,GAAA,sBAAA,YAAA,CAAmB;EACjB,aAAa,EAAE,YAAY,mBACzB,OAAO,2BAA2B;GAAE;GAAY;EAAa,CAAC;EAChE,iBACE,QAAQ,IAAI,CACV,YAAY,kBAAkB,EAAE,UAAU,CAAC,gBAAgB,EAAE,CAAC,GAC9D,YAAY,kBAAkB,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAC/D,CAAC;EACH,GAAG;CACL,CAAC;AACH"}
1
+ {"version":3,"file":"index.cjs","names":["useMastraClient","useQueryClient","useMutation"],"sources":["../../../src/hooks/feedback/use-feedback.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions } from '../shared/query-options';\n\nexport type FeedbackReviewStatus = 'needs-review' | 'reviewed';\n\ntype UpdateFeedbackReviewStatusVariables = { feedbackId: string; reviewStatus: FeedbackReviewStatus };\ntype UpdateFeedbackReviewStatusResponse = Awaited<ReturnType<MastraClient['updateFeedbackReviewStatus']>>;\n\nexport function useUpdateFeedbackReviewStatus({\n queryOptions,\n}: {\n queryOptions?: MastraMutationOptions<UpdateFeedbackReviewStatusResponse, UpdateFeedbackReviewStatusVariables>;\n} = {}) {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ feedbackId, reviewStatus }: UpdateFeedbackReviewStatusVariables) =>\n client.updateFeedbackReviewStatus({ feedbackId, reviewStatus }),\n onSuccess: () =>\n Promise.all([\n queryClient.invalidateQueries({ queryKey: ['trace-feedback'] }),\n queryClient.invalidateQueries({ queryKey: ['span-feedback'] }),\n ]),\n ...queryOptions,\n });\n}\n"],"mappings":";;;;;AAUA,SAAgB,8BAA8B,EAC5C,iBAGE,CAAC,GAAG;CACN,MAAM,SAASA,8BAAAA,gBAAgB;CAC/B,MAAM,eAAA,GAAcC,sBAAAA,eAAAA,CAAe;CAEnC,QAAA,GAAOC,sBAAAA,YAAAA,CAAY;EACjB,aAAa,EAAE,YAAY,mBACzB,OAAO,2BAA2B;GAAE;GAAY;EAAa,CAAC;EAChE,iBACE,QAAQ,IAAI,CACV,YAAY,kBAAkB,EAAE,UAAU,CAAC,gBAAgB,EAAE,CAAC,GAC9D,YAAY,kBAAkB,EAAE,UAAU,CAAC,eAAe,EAAE,CAAC,CAC/D,CAAC;EACH,GAAG;CACL,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useMastraClient"],"sources":["../../../src/hooks/llm/use-llm-providers.ts"],"sourcesContent":["import type { ListAgentsModelProvidersResponse } 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';\n\nexport const useLLMProviders = <TData = ListAgentsModelProvidersResponse>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<ListAgentsModelProvidersResponse, TData> } = {}): UseQueryResult<\n TData,\n Error\n> => {\n const client = useMastraClient();\n\n return useQuery<ListAgentsModelProvidersResponse, Error, TData>({\n queryKey: ['llm-providers'],\n queryFn: async () => client.listAgentsModelProviders(),\n retry: false,\n ...queryOptions,\n });\n};\n"],"mappings":";;;;AAMA,MAAa,mBAA6D,EACxE,iBACkF,CAAC,MAGhF;CACH,MAAM,SAASA,8BAAAA,gBAAgB;CAE/B,QAAA,GAAA,sBAAA,SAAA,CAAgE;EAC9D,UAAU,CAAC,eAAe;EAC1B,SAAS,YAAY,OAAO,yBAAyB;EACrD,OAAO;EACP,GAAG;CACL,CAAC;AACH"}
1
+ {"version":3,"file":"index.cjs","names":["useMastraClient","useQuery"],"sources":["../../../src/hooks/llm/use-llm-providers.ts"],"sourcesContent":["import type { ListAgentsModelProvidersResponse } 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';\n\nexport const useLLMProviders = <TData = ListAgentsModelProvidersResponse>({\n queryOptions,\n}: { queryOptions?: MastraQueryOptions<ListAgentsModelProvidersResponse, TData> } = {}): UseQueryResult<\n TData,\n Error\n> => {\n const client = useMastraClient();\n\n return useQuery<ListAgentsModelProvidersResponse, Error, TData>({\n queryKey: ['llm-providers'],\n queryFn: async () => client.listAgentsModelProviders(),\n retry: false,\n ...queryOptions,\n });\n};\n"],"mappings":";;;;AAMA,MAAa,mBAA6D,EACxE,iBACkF,CAAC,MAGhF;CACH,MAAM,SAASA,8BAAAA,gBAAgB;CAE/B,QAAA,GAAOC,sBAAAA,SAAAA,CAAyD;EAC9D,UAAU,CAAC,eAAe;EAC1B,SAAS,YAAY,OAAO,yBAAyB;EACrD,OAAO;EACP,GAAG;CACL,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["isUnsupportedObservabilityOperationError","isObservabilityUnavailableError","useMastraClient","useInView"],"sources":["../../../src/hooks/logs/use-logs.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useInfiniteQuery } from '@tanstack/react-query';\nimport { useEffect } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { isObservabilityUnavailableError, isUnsupportedObservabilityOperationError } from '../query/query-utils';\nimport type { MastraInfiniteQueryOptions } from '../shared/query-options';\n\nimport { useInView } from '../shared/use-in-view';\nimport type { LogRecord } from './types';\n\ntype ListLogsArgs = NonNullable<Parameters<MastraClient['listLogsVNext']>[0]>;\ntype ListLogsResponse = Awaited<ReturnType<MastraClient['listLogsVNext']>>;\n\ninterface UseLogsReturn {\n data: LogRecord[] | undefined;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n isLoading: boolean;\n isError: boolean;\n error: Error | null;\n setEndOfListElement: (node: HTMLDivElement | null) => void;\n}\n\nconst LOGS_PER_PAGE = 20;\nconst LOGS_REFETCH_INTERVAL_MS = 10000;\n\nexport type LogsOrderBy = NonNullable<ListLogsArgs['orderBy']>;\n\nconst DEFAULT_LOGS_ORDER_BY: LogsOrderBy = { field: 'timestamp', direction: 'DESC' };\n\nexport interface LogsFilters {\n filters?: ListLogsArgs['filters'];\n orderBy?: LogsOrderBy;\n /** TanStack overrides spread last. The hook returns the selected log list, so `select` must keep that shape. */\n queryOptions?: MastraInfiniteQueryOptions<\n ListLogsResponse,\n ReturnType<typeof selectLogs>,\n readonly unknown[],\n number\n >;\n}\n\nfunction getNextPageParam(lastPage: ListLogsResponse | undefined, _allPages: unknown, lastPageParam: number) {\n if (lastPage?.pagination?.hasMore) {\n return lastPageParam + 1;\n }\n return undefined;\n}\n\n/** Deduplicates logs across loaded pages. Offset-based pagination duplicates rows at the page\n * boundary whenever new logs are inserted between sequential `fetchNextPage` calls — without\n * this filter the duplicates produce duplicate React keys and chaotic virtualizer offsets.\n * Falls back to the full serialized record when `logId` is absent so logs that happen to\n * share `(timestamp, message, data)` but differ in other fields aren't collapsed. */\nfunction selectLogs(data: { pages: ListLogsResponse[] }) {\n const seen = new Set<string>();\n const result = [];\n for (const page of data.pages) {\n for (const log of page.logs ?? []) {\n const key = log.logId ?? JSON.stringify(log);\n if (seen.has(key)) continue;\n seen.add(key);\n result.push(log);\n }\n }\n return result;\n}\n\nexport function getLogsRefetchInterval(query: { state: { error: unknown } }) {\n if (\n isUnsupportedObservabilityOperationError(query.state.error, 'logs') ||\n isObservabilityUnavailableError(query.state.error)\n ) {\n return false;\n }\n return LOGS_REFETCH_INTERVAL_MS;\n}\n\nexport const useLogs: (props?: LogsFilters) => UseLogsReturn = ({\n filters,\n orderBy = DEFAULT_LOGS_ORDER_BY,\n queryOptions,\n}: LogsFilters = {}) => {\n const client = useMastraClient();\n const { inView: isEndOfListInView, setRef: setEndOfListElement } = useInView();\n\n const query = useInfiniteQuery<ListLogsResponse, Error, ReturnType<typeof selectLogs>, readonly unknown[], number>({\n queryKey: ['logs', filters, orderBy],\n queryFn: ({ pageParam }) =>\n client.listLogsVNext({\n pagination: { page: pageParam, perPage: LOGS_PER_PAGE },\n filters,\n orderBy,\n }),\n initialPageParam: 0,\n getNextPageParam,\n select: selectLogs,\n retry: false,\n refetchInterval: getLogsRefetchInterval,\n ...queryOptions,\n });\n\n const { hasNextPage, isFetchingNextPage, fetchNextPage, data, isLoading, isError, error } = query;\n\n useEffect(() => {\n if (isEndOfListInView && hasNextPage && !isFetchingNextPage) {\n void fetchNextPage();\n }\n }, [isEndOfListInView, hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n return { data, hasNextPage, isFetchingNextPage, fetchNextPage, isLoading, isError, error, setEndOfListElement };\n};\n"],"mappings":";;;;;;;AAwBA,MAAM,gBAAgB;AACtB,MAAM,2BAA2B;AAIjC,MAAM,wBAAqC;CAAE,OAAO;CAAa,WAAW;AAAO;AAcnF,SAAS,iBAAiB,UAAwC,WAAoB,eAAuB;CAC3G,IAAI,UAAU,YAAY,SACxB,OAAO,gBAAgB;AAG3B;;;;;;AAOA,SAAS,WAAW,MAAqC;CACvD,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,QAAQ,KAAK,OACtB,KAAK,MAAM,OAAO,KAAK,QAAQ,CAAC,GAAG;EACjC,MAAM,MAAM,IAAI,SAAS,KAAK,UAAU,GAAG;EAC3C,IAAI,KAAK,IAAI,GAAG,GAAG;EACnB,KAAK,IAAI,GAAG;EACZ,OAAO,KAAK,GAAG;CACjB;CAEF,OAAO;AACT;AAEA,SAAgB,uBAAuB,OAAsC;CAC3E,IACEA,oBAAAA,yCAAyC,MAAM,MAAM,OAAO,MAAM,KAClEC,oBAAAA,gCAAgC,MAAM,MAAM,KAAK,GAEjD,OAAO;CAET,OAAO;AACT;AAEA,MAAa,WAAmD,EAC9D,SACA,UAAU,uBACV,iBACe,CAAC,MAAM;CACtB,MAAM,SAASC,8BAAAA,gBAAgB;CAC/B,MAAM,EAAE,QAAQ,mBAAmB,QAAQ,wBAAwBC,oBAAAA,UAAU;CAkB7E,MAAM,EAAE,aAAa,oBAAoB,eAAe,MAAM,WAAW,SAAS,WAAA,GAAA,sBAAA,iBAAA,CAhBiC;EACjH,UAAU;GAAC;GAAQ;GAAS;EAAO;EACnC,UAAU,EAAE,gBACV,OAAO,cAAc;GACnB,YAAY;IAAE,MAAM;IAAW,SAAS;GAAc;GACtD;GACA;EACF,CAAC;EACH,kBAAkB;EAClB;EACA,QAAQ;EACR,OAAO;EACP,iBAAiB;EACjB,GAAG;CACL,CAEgG;CAEhG,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,qBAAqB,eAAe,CAAC,oBACvC,cAAmB;CAEvB,GAAG;EAAC;EAAmB;EAAa;EAAoB;CAAa,CAAC;CAEtE,OAAO;EAAE;EAAM;EAAa;EAAoB;EAAe;EAAW;EAAS;EAAO;CAAoB;AAChH"}
1
+ {"version":3,"file":"index.cjs","names":["isUnsupportedObservabilityOperationError","isObservabilityUnavailableError","useMastraClient","useInView","useInfiniteQuery"],"sources":["../../../src/hooks/logs/use-logs.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport { useInfiniteQuery } from '@tanstack/react-query';\nimport { useEffect } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { isObservabilityUnavailableError, isUnsupportedObservabilityOperationError } from '../query/query-utils';\nimport type { MastraInfiniteQueryOptions } from '../shared/query-options';\n\nimport { useInView } from '../shared/use-in-view';\nimport type { LogRecord } from './types';\n\ntype ListLogsArgs = NonNullable<Parameters<MastraClient['listLogsVNext']>[0]>;\ntype ListLogsResponse = Awaited<ReturnType<MastraClient['listLogsVNext']>>;\n\ninterface UseLogsReturn {\n data: LogRecord[] | undefined;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => void;\n isLoading: boolean;\n isError: boolean;\n error: Error | null;\n setEndOfListElement: (node: HTMLDivElement | null) => void;\n}\n\nconst LOGS_PER_PAGE = 20;\nconst LOGS_REFETCH_INTERVAL_MS = 10000;\n\nexport type LogsOrderBy = NonNullable<ListLogsArgs['orderBy']>;\n\nconst DEFAULT_LOGS_ORDER_BY: LogsOrderBy = { field: 'timestamp', direction: 'DESC' };\n\nexport interface LogsFilters {\n filters?: ListLogsArgs['filters'];\n orderBy?: LogsOrderBy;\n /** TanStack overrides spread last. The hook returns the selected log list, so `select` must keep that shape. */\n queryOptions?: MastraInfiniteQueryOptions<\n ListLogsResponse,\n ReturnType<typeof selectLogs>,\n readonly unknown[],\n number\n >;\n}\n\nfunction getNextPageParam(lastPage: ListLogsResponse | undefined, _allPages: unknown, lastPageParam: number) {\n if (lastPage?.pagination?.hasMore) {\n return lastPageParam + 1;\n }\n return undefined;\n}\n\n/** Deduplicates logs across loaded pages. Offset-based pagination duplicates rows at the page\n * boundary whenever new logs are inserted between sequential `fetchNextPage` calls — without\n * this filter the duplicates produce duplicate React keys and chaotic virtualizer offsets.\n * Falls back to the full serialized record when `logId` is absent so logs that happen to\n * share `(timestamp, message, data)` but differ in other fields aren't collapsed. */\nfunction selectLogs(data: { pages: ListLogsResponse[] }) {\n const seen = new Set<string>();\n const result = [];\n for (const page of data.pages) {\n for (const log of page.logs ?? []) {\n const key = log.logId ?? JSON.stringify(log);\n if (seen.has(key)) continue;\n seen.add(key);\n result.push(log);\n }\n }\n return result;\n}\n\nexport function getLogsRefetchInterval(query: { state: { error: unknown } }) {\n if (\n isUnsupportedObservabilityOperationError(query.state.error, 'logs') ||\n isObservabilityUnavailableError(query.state.error)\n ) {\n return false;\n }\n return LOGS_REFETCH_INTERVAL_MS;\n}\n\nexport const useLogs: (props?: LogsFilters) => UseLogsReturn = ({\n filters,\n orderBy = DEFAULT_LOGS_ORDER_BY,\n queryOptions,\n}: LogsFilters = {}) => {\n const client = useMastraClient();\n const { inView: isEndOfListInView, setRef: setEndOfListElement } = useInView();\n\n const query = useInfiniteQuery<ListLogsResponse, Error, ReturnType<typeof selectLogs>, readonly unknown[], number>({\n queryKey: ['logs', filters, orderBy],\n queryFn: ({ pageParam }) =>\n client.listLogsVNext({\n pagination: { page: pageParam, perPage: LOGS_PER_PAGE },\n filters,\n orderBy,\n }),\n initialPageParam: 0,\n getNextPageParam,\n select: selectLogs,\n retry: false,\n refetchInterval: getLogsRefetchInterval,\n ...queryOptions,\n });\n\n const { hasNextPage, isFetchingNextPage, fetchNextPage, data, isLoading, isError, error } = query;\n\n useEffect(() => {\n if (isEndOfListInView && hasNextPage && !isFetchingNextPage) {\n void fetchNextPage();\n }\n }, [isEndOfListInView, hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n return { data, hasNextPage, isFetchingNextPage, fetchNextPage, isLoading, isError, error, setEndOfListElement };\n};\n"],"mappings":";;;;;;;AAwBA,MAAM,gBAAgB;AACtB,MAAM,2BAA2B;AAIjC,MAAM,wBAAqC;CAAE,OAAO;CAAa,WAAW;AAAO;AAcnF,SAAS,iBAAiB,UAAwC,WAAoB,eAAuB;CAC3G,IAAI,UAAU,YAAY,SACxB,OAAO,gBAAgB;AAG3B;;;;;;AAOA,SAAS,WAAW,MAAqC;CACvD,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,SAAS,CAAC;CAChB,KAAK,MAAM,QAAQ,KAAK,OACtB,KAAK,MAAM,OAAO,KAAK,QAAQ,CAAC,GAAG;EACjC,MAAM,MAAM,IAAI,SAAS,KAAK,UAAU,GAAG;EAC3C,IAAI,KAAK,IAAI,GAAG,GAAG;EACnB,KAAK,IAAI,GAAG;EACZ,OAAO,KAAK,GAAG;CACjB;CAEF,OAAO;AACT;AAEA,SAAgB,uBAAuB,OAAsC;CAC3E,IACEA,oBAAAA,yCAAyC,MAAM,MAAM,OAAO,MAAM,KAClEC,oBAAAA,gCAAgC,MAAM,MAAM,KAAK,GAEjD,OAAO;CAET,OAAO;AACT;AAEA,MAAa,WAAmD,EAC9D,SACA,UAAU,uBACV,iBACe,CAAC,MAAM;CACtB,MAAM,SAASC,8BAAAA,gBAAgB;CAC/B,MAAM,EAAE,QAAQ,mBAAmB,QAAQ,wBAAwBC,oBAAAA,UAAU;CAkB7E,MAAM,EAAE,aAAa,oBAAoB,eAAe,MAAM,WAAW,SAAS,WAAA,GAhBpEC,sBAAAA,iBAAAA,CAAqG;EACjH,UAAU;GAAC;GAAQ;GAAS;EAAO;EACnC,UAAU,EAAE,gBACV,OAAO,cAAc;GACnB,YAAY;IAAE,MAAM;IAAW,SAAS;GAAc;GACtD;GACA;EACF,CAAC;EACH,kBAAkB;EAClB;EACA,QAAQ;EACR,OAAO;EACP,iBAAiB;EACjB,GAAG;CACL,CAEgG;CAEhG,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,qBAAqB,eAAe,CAAC,oBACvC,cAAmB;CAEvB,GAAG;EAAC;EAAmB;EAAa;EAAoB;CAAa,CAAC;CAEtE,OAAO;EAAE;EAAM;EAAa;EAAoB;EAAe;EAAW;EAAS;EAAO;CAAoB;AAChH"}