@mastra/react 1.12.0-alpha.10 → 1.12.0-alpha.12

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 (106) 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 +1 -1
  21. package/dist/hooks/capabilities/index.cjs.map +1 -1
  22. package/dist/hooks/capabilities/index.js +1 -1
  23. package/dist/hooks/capabilities/index.js.map +1 -1
  24. package/dist/hooks/configuration/index.cjs.map +1 -1
  25. package/dist/hooks/datasets/index.cjs +25 -1
  26. package/dist/hooks/datasets/index.cjs.map +1 -1
  27. package/dist/hooks/datasets/index.js +25 -2
  28. package/dist/hooks/datasets/index.js.map +1 -1
  29. package/dist/hooks/datasets/use-datasets.d.ts +7 -0
  30. package/dist/hooks/datasets/use-datasets.d.ts.map +1 -1
  31. package/dist/hooks/embedders/index.cjs.map +1 -1
  32. package/dist/hooks/experiments/index.cjs +9 -235
  33. package/dist/hooks/experiments/index.d.ts +1 -0
  34. package/dist/hooks/experiments/index.d.ts.map +1 -1
  35. package/dist/hooks/experiments/index.js +1 -229
  36. package/dist/hooks/experiments/usage-accumulator.d.ts +25 -0
  37. package/dist/hooks/experiments/usage-accumulator.d.ts.map +1 -0
  38. package/dist/hooks/experiments/use-experiment-item-usage.d.ts +2 -7
  39. package/dist/hooks/experiments/use-experiment-item-usage.d.ts.map +1 -1
  40. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts +19 -0
  41. package/dist/hooks/experiments/use-experiments-list-metrics.d.ts.map +1 -0
  42. package/dist/hooks/feedback/index.cjs.map +1 -1
  43. package/dist/hooks/llm/index.cjs.map +1 -1
  44. package/dist/hooks/logs/index.cjs.map +1 -1
  45. package/dist/hooks/mcps/index.cjs.map +1 -1
  46. package/dist/hooks/memory/index.cjs +10 -10
  47. package/dist/hooks/memory/index.cjs.map +1 -1
  48. package/dist/hooks/memory/index.js +10 -10
  49. package/dist/hooks/memory/index.js.map +1 -1
  50. package/dist/hooks/metrics/index.cjs +13 -11
  51. package/dist/hooks/metrics/index.cjs.map +1 -1
  52. package/dist/hooks/metrics/index.js +13 -11
  53. package/dist/hooks/metrics/index.js.map +1 -1
  54. package/dist/hooks/processors/index.cjs.map +1 -1
  55. package/dist/hooks/prompt-blocks/index.cjs.map +1 -1
  56. package/dist/hooks/query/index.cjs.map +1 -1
  57. package/dist/hooks/review/index.cjs +2 -2
  58. package/dist/hooks/review/index.cjs.map +1 -1
  59. package/dist/hooks/review/index.js +1 -1
  60. package/dist/hooks/schedules/index.cjs.map +1 -1
  61. package/dist/hooks/scores/index.cjs.map +1 -1
  62. package/dist/hooks/templates/index.cjs +20 -18
  63. package/dist/hooks/templates/index.cjs.map +1 -1
  64. package/dist/hooks/templates/index.js +20 -18
  65. package/dist/hooks/templates/index.js.map +1 -1
  66. package/dist/hooks/tool-providers/index.cjs +1 -1
  67. package/dist/hooks/tool-providers/index.cjs.map +1 -1
  68. package/dist/hooks/tool-providers/index.js +1 -1
  69. package/dist/hooks/tool-providers/index.js.map +1 -1
  70. package/dist/hooks/tools/index.cjs.map +1 -1
  71. package/dist/hooks/traces/index.cjs +4 -4
  72. package/dist/hooks/traces/index.cjs.map +1 -1
  73. package/dist/hooks/traces/index.js +4 -4
  74. package/dist/hooks/traces/index.js.map +1 -1
  75. package/dist/hooks/vectors/index.cjs.map +1 -1
  76. package/dist/hooks/voice/index.cjs.map +1 -1
  77. package/dist/hooks/workflows/index.cjs +1 -1
  78. package/dist/hooks/workflows/index.cjs.map +1 -1
  79. package/dist/hooks/workflows/index.js +1 -1
  80. package/dist/hooks/workspace/index.cjs +1 -1
  81. package/dist/hooks/workspace/index.cjs.map +1 -1
  82. package/dist/hooks/workspace/index.js +1 -1
  83. package/dist/hooks/workspace/index.js.map +1 -1
  84. package/dist/{hooks-CIutb3DO.cjs → hooks-B1i-oHae.cjs} +6 -4
  85. package/dist/hooks-B1i-oHae.cjs.map +1 -0
  86. package/dist/{hooks-FVbeHlov.js → hooks-CLfMO5cH.js} +6 -4
  87. package/dist/{hooks-FVbeHlov.js.map → hooks-CLfMO5cH.js.map} +1 -1
  88. package/dist/{hooks-_YevKidX.cjs → hooks-D8nOYPUd.cjs} +2 -2
  89. package/dist/hooks-D8nOYPUd.cjs.map +1 -0
  90. package/dist/{hooks-0L0RNfau.js → hooks-NaZLZreZ.js} +2 -2
  91. package/dist/{hooks-0L0RNfau.js.map → hooks-NaZLZreZ.js.map} +1 -1
  92. package/dist/index.cjs +3 -3
  93. package/dist/index.cjs.map +1 -1
  94. package/dist/index.js +3 -3
  95. package/dist/mastra-client-context-DzX3f0RF.cjs.map +1 -1
  96. package/dist/ui/index.cjs +4 -4
  97. package/dist/ui/index.cjs.map +1 -1
  98. package/dist/ui/index.js +3 -3
  99. package/dist/ui/index.js.map +1 -1
  100. package/dist/use-in-view-B6eJO9Zi.cjs.map +1 -1
  101. package/dist/voice-BOtUdMi8.cjs.map +1 -1
  102. package/package.json +3 -3
  103. package/dist/hooks/experiments/index.cjs.map +0 -1
  104. package/dist/hooks/experiments/index.js.map +0 -1
  105. package/dist/hooks-CIutb3DO.cjs.map +0 -1
  106. package/dist/hooks-_YevKidX.cjs.map +0 -1
@@ -71,8 +71,8 @@ const useMemory = ({ agentId, requestContext, queryOptions } = {}) => {
71
71
  requestContext
72
72
  ],
73
73
  queryFn: () => agentId ? client.getMemoryStatus(agentId, requestContext) : null,
74
- staleTime: 300 * 1e3,
75
- gcTime: 600 * 1e3,
74
+ staleTime: 3e5,
75
+ gcTime: 6e5,
76
76
  retry: false,
77
77
  ...queryOptions
78
78
  });
@@ -93,8 +93,8 @@ const useMemoryConfig = ({ agentId, requestContext, queryOptions } = {}) => {
93
93
  agentId,
94
94
  requestContext
95
95
  }) : null,
96
- staleTime: 300 * 1e3,
97
- gcTime: 600 * 1e3,
96
+ staleTime: 3e5,
97
+ gcTime: 6e5,
98
98
  retry: false,
99
99
  refetchOnWindowFocus: false,
100
100
  ...queryOptions
@@ -117,8 +117,8 @@ const useThread = ({ threadId, agentId, requestContext, queryOptions }) => {
117
117
  threadId,
118
118
  agentId
119
119
  }).get({ requestContext }),
120
- staleTime: 300 * 1e3,
121
- gcTime: 600 * 1e3,
120
+ staleTime: 3e5,
121
+ gcTime: 6e5,
122
122
  retry: false,
123
123
  refetchOnWindowFocus: false,
124
124
  ...queryOptions
@@ -260,8 +260,8 @@ const useObservationalMemoryWithHistory = ({ agentId, resourceId, threadId, isAc
260
260
  requestContext
261
261
  });
262
262
  },
263
- staleTime: isActive ? 1e3 : 30 * 1e3,
264
- gcTime: 300 * 1e3,
263
+ staleTime: isActive ? 1e3 : 3e4,
264
+ gcTime: 3e5,
265
265
  retry: false,
266
266
  refetchOnWindowFocus: false,
267
267
  refetchInterval: isActive ? 2e3 : false,
@@ -291,8 +291,8 @@ const useMemoryWithOMStatus = ({ agentId, resourceId, threadId, pollWhenActive =
291
291
  resourceId,
292
292
  threadId
293
293
  }) : null,
294
- staleTime: isActive && pollWhenActive ? 1e3 : 30 * 1e3,
295
- gcTime: 300 * 1e3,
294
+ staleTime: isActive && pollWhenActive ? 1e3 : 3e4,
295
+ gcTime: 3e5,
296
296
  retry: false,
297
297
  refetchOnWindowFocus: false,
298
298
  refetchInterval: isActive && pollWhenActive ? 2e3 : false,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/hooks/memory/use-memory-thread-messages.ts","../../../src/hooks/memory/use-observational-memory.ts","../../../src/hooks/memory/use-memory-status.ts","../../../src/hooks/memory/use-memory.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const memoryThreadMessagesQueryKey = (threadId: string | undefined, page?: number) =>\n ['memory', 'thread', threadId, 'messages', page ?? 0] as const;\n\ntype MemoryThreadMessagesResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['listMessages']>>;\n\nexport function useMemoryThreadMessages<TData = MemoryThreadMessagesResponse>({\n threadId,\n page = 0,\n perPage = 100,\n queryOptions,\n}: {\n threadId: string | undefined;\n page?: number;\n perPage?: number;\n queryOptions?: MastraQueryOptions<MemoryThreadMessagesResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: memoryThreadMessagesQueryKey(threadId, page),\n queryFn: threadId ? () => client.getMemoryThread({ threadId }).listMessages({ page, perPage }) : skipToken,\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const observationalMemoryQueryKey = (agentId: string | undefined, threadId: string | undefined) =>\n ['memory', 'observational-memory', agentId, threadId] as const;\n\ntype ObservationalMemoryResponse = Awaited<ReturnType<MastraClient['getObservationalMemory']>>;\n\nexport function useObservationalMemory<TData = ObservationalMemoryResponse>({\n agentId,\n threadId,\n resourceId,\n queryOptions,\n}: {\n agentId: string | undefined;\n threadId: string | undefined;\n resourceId?: string;\n queryOptions?: MastraQueryOptions<ObservationalMemoryResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: observationalMemoryQueryKey(agentId, threadId),\n queryFn:\n agentId && threadId\n ? () =>\n client.getObservationalMemory({\n agentId,\n threadId,\n resourceId,\n })\n : skipToken,\n // The record is read by several surfaces at once (collapsed memory bar, OM\n // section, detail panel). A short stale window lets a newly mounted consumer\n // reuse the cached record instead of refiring the request; freshness still\n // comes from the explicit refetch on stream finish/observation signals.\n staleTime: 5_000,\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const memoryStatusQueryKey = (agentId: string | undefined, threadId?: string) =>\n ['memory', 'status', agentId, threadId] as const;\n\ntype MemoryStatusResponse = Awaited<ReturnType<MastraClient['getMemoryStatus']>>;\n\nexport function useMemoryStatus<TData = MemoryStatusResponse>({\n agentId,\n threadId,\n queryOptions,\n}: {\n agentId: string | undefined;\n threadId?: string;\n queryOptions?: MastraQueryOptions<MemoryStatusResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: memoryStatusQueryKey(agentId, threadId),\n queryFn: agentId\n ? () =>\n client.getMemoryStatus(agentId, undefined, {\n threadId,\n })\n : skipToken,\n ...queryOptions,\n });\n}\n","import type { GetObservationalMemoryResponse, GetMemoryStatusResponse, MastraClient } from '@mastra/client-js';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { UseMutationResult, UseQueryResult } from '@tanstack/react-query';\nimport { useState, useEffect } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions, MastraQueryOptions } from '../shared/query-options';\n\nexport interface MemorySearchParams {\n lastMessages?: number | false;\n}\n\ntype MemoryStatusResponse = Awaited<ReturnType<MastraClient['getMemoryStatus']>> | null;\ntype MemoryConfigResponse = Awaited<ReturnType<MastraClient['getMemoryConfig']>> | null;\ntype ThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['get']>>;\ntype ThreadsResponse = Awaited<ReturnType<MastraClient['listMemoryThreads']>>['threads'] | null;\ntype UpdateThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['update']>>;\ntype CloneThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['clone']>>;\ntype SearchMemoryResponse = Awaited<ReturnType<MastraClient['searchMemory']>>;\ntype ThreadVariables = { threadId: string; agentId: string };\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemory = <TData = MemoryStatusResponse>({\n agentId,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<MemoryStatusResponse, TData>;\n} = {}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', agentId, requestContext],\n queryFn: () => (agentId ? client.getMemoryStatus(agentId, requestContext) : null),\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n retry: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemoryConfig = <TData = MemoryConfigResponse>({\n agentId,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<MemoryConfigResponse, TData>;\n} = {}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'config', agentId, requestContext],\n queryFn: () => (agentId ? client.getMemoryConfig({ agentId, requestContext }) : null),\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useThread = <TData = ThreadResponse>({\n threadId,\n agentId,\n requestContext,\n queryOptions,\n}: {\n threadId?: string;\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<ThreadResponse, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'thread', threadId, agentId, requestContext],\n queryFn: () => client.getMemoryThread({ threadId: threadId!, agentId }).get({ requestContext }),\n staleTime: 5 * 60 * 1000,\n gcTime: 10 * 60 * 1000,\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useThreads = <TData = ThreadsResponse>({\n resourceId,\n agentId,\n isMemoryEnabled,\n requestContext,\n queryOptions,\n}: {\n resourceId: string;\n agentId: string;\n isMemoryEnabled: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<ThreadsResponse, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'threads', resourceId, agentId, requestContext],\n queryFn: async () => {\n if (!isMemoryEnabled) return null;\n const result = await client.listMemoryThreads({ resourceId, agentId, requestContext });\n return result.threads;\n },\n staleTime: 0,\n gcTime: 0,\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\nexport type DeleteThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['delete']>>;\n\nexport const useDeleteThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<DeleteThreadResponse, ThreadVariables>;\n} = {}): UseMutationResult<DeleteThreadResponse, Error, ThreadVariables> => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ threadId, agentId }: { threadId: string; agentId: string }) => {\n const thread = client.getMemoryThread({ threadId, agentId });\n return thread.delete({ requestContext });\n },\n onSuccess: (_, variables) => {\n const { agentId } = variables;\n if (agentId) {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads', agentId, agentId] });\n }\n },\n ...queryOptions,\n });\n};\n\nexport const useUpdateThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<UpdateThreadResponse, ThreadVariables & { title: string }>;\n} = {}) => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ threadId, agentId, title }: { threadId: string; agentId: string; title: string }) =>\n client.getMemoryThread({ threadId, agentId }).update({ title, agentId, requestContext }),\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads'] });\n void queryClient.invalidateQueries({ queryKey: ['memory', 'thread'] });\n },\n ...queryOptions,\n });\n};\n\nexport const useMemorySearch = ({\n agentId,\n resourceId,\n threadId,\n requestContext,\n queryOptions,\n}: {\n agentId: string;\n resourceId: string;\n threadId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<\n SearchMemoryResponse,\n { searchQuery: string; memoryConfig?: MemorySearchParams }\n >;\n}) => {\n const client = useMastraClient();\n return useMutation({\n mutationFn: async ({ searchQuery, memoryConfig }: { searchQuery: string; memoryConfig?: MemorySearchParams }) => {\n return client.searchMemory({ agentId, resourceId, threadId, searchQuery, memoryConfig, requestContext });\n },\n ...queryOptions,\n });\n};\n\nexport const useCloneThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<CloneThreadResponse, ThreadVariables & { title?: string }>;\n} = {}) => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ threadId, agentId, title }: { threadId: string; agentId: string; title?: string }) => {\n const thread = client.getMemoryThread({ threadId, agentId });\n return thread.clone({ title, requestContext });\n },\n onSuccess: (_, variables) => {\n const { agentId } = variables;\n if (agentId) {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads', agentId, agentId] });\n }\n },\n ...queryOptions,\n });\n};\n\n/**\n * Hook to fetch Observational Memory data for an agent\n * Returns the current OM record and history for a given resource/thread\n * Polls more frequently when observing/reflecting is in progress\n *\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useObservationalMemoryWithHistory = <TData = GetObservationalMemoryResponse | null>({\n agentId,\n resourceId,\n threadId,\n isActive = false,\n requestContext,\n queryOptions,\n}: {\n agentId: string;\n resourceId?: string;\n threadId?: string;\n isActive?: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<GetObservationalMemoryResponse | null, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['observational-memory', agentId, resourceId, threadId, requestContext],\n queryFn: async (): Promise<GetObservationalMemoryResponse | null> => {\n if (!resourceId && !threadId) return null;\n return client.getObservationalMemory({\n agentId,\n resourceId,\n threadId,\n requestContext,\n });\n },\n staleTime: isActive ? 1000 : 30 * 1000, // 1 second when active, 30 seconds otherwise\n gcTime: 5 * 60 * 1000, // 5 minutes\n retry: false,\n refetchOnWindowFocus: false,\n refetchInterval: isActive ? 2000 : false, // Poll every 2 seconds when active\n placeholderData: previousData => previousData, // Keep previous data during refetch to prevent skeleton flash\n ...queryOptions,\n });\n};\n\n/**\n * Hook to get OM-aware memory status\n * Extends useMemory with OM-specific status information\n * Polls more frequently when observing/reflecting is in progress\n *\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemoryWithOMStatus = ({\n agentId,\n resourceId,\n threadId,\n pollWhenActive = true,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n resourceId?: string;\n threadId?: string;\n pollWhenActive?: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<GetMemoryStatusResponse | null>;\n}) => {\n const client = useMastraClient();\n const [isActive, setIsActive] = useState(false);\n\n const query = useQuery<GetMemoryStatusResponse | null>({\n queryKey: ['memory-status', agentId, resourceId, threadId, requestContext],\n queryFn: () =>\n agentId\n ? client.getMemoryStatus(agentId, requestContext, {\n resourceId,\n threadId,\n })\n : null,\n staleTime: isActive && pollWhenActive ? 1000 : 30 * 1000, // 1 second when active, 30 seconds otherwise\n gcTime: 5 * 60 * 1000, // 5 minutes\n retry: false,\n refetchOnWindowFocus: false,\n refetchInterval: isActive && pollWhenActive ? 2000 : false, // Poll every 2 seconds when active\n placeholderData: previousData => previousData, // Keep previous data during refetch to prevent skeleton flash\n ...queryOptions,\n });\n\n // Update isActive state when data changes\n const isObserving = query.data?.observationalMemory?.isObserving;\n const isReflecting = query.data?.observationalMemory?.isReflecting;\n\n useEffect(() => {\n const newIsActive = isObserving || isReflecting || false;\n setIsActive(newIsActive);\n }, [isObserving, isReflecting]);\n\n return query;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/hooks/memory/use-memory-thread-messages.ts","../../../src/hooks/memory/use-observational-memory.ts","../../../src/hooks/memory/use-memory-status.ts","../../../src/hooks/memory/use-memory.ts"],"sourcesContent":["import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const memoryThreadMessagesQueryKey = (threadId: string | undefined, page?: number) =>\n ['memory', 'thread', threadId, 'messages', page ?? 0] as const;\n\ntype MemoryThreadMessagesResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['listMessages']>>;\n\nexport function useMemoryThreadMessages<TData = MemoryThreadMessagesResponse>({\n threadId,\n page = 0,\n perPage = 100,\n queryOptions,\n}: {\n threadId: string | undefined;\n page?: number;\n perPage?: number;\n queryOptions?: MastraQueryOptions<MemoryThreadMessagesResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: memoryThreadMessagesQueryKey(threadId, page),\n queryFn: threadId ? () => client.getMemoryThread({ threadId }).listMessages({ page, perPage }) : skipToken,\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const observationalMemoryQueryKey = (agentId: string | undefined, threadId: string | undefined) =>\n ['memory', 'observational-memory', agentId, threadId] as const;\n\ntype ObservationalMemoryResponse = Awaited<ReturnType<MastraClient['getObservationalMemory']>>;\n\nexport function useObservationalMemory<TData = ObservationalMemoryResponse>({\n agentId,\n threadId,\n resourceId,\n queryOptions,\n}: {\n agentId: string | undefined;\n threadId: string | undefined;\n resourceId?: string;\n queryOptions?: MastraQueryOptions<ObservationalMemoryResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: observationalMemoryQueryKey(agentId, threadId),\n queryFn:\n agentId && threadId\n ? () =>\n client.getObservationalMemory({\n agentId,\n threadId,\n resourceId,\n })\n : skipToken,\n // The record is read by several surfaces at once (collapsed memory bar, OM\n // section, detail panel). A short stale window lets a newly mounted consumer\n // reuse the cached record instead of refiring the request; freshness still\n // comes from the explicit refetch on stream finish/observation signals.\n staleTime: 5_000,\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { skipToken, useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\n\nexport const memoryStatusQueryKey = (agentId: string | undefined, threadId?: string) =>\n ['memory', 'status', agentId, threadId] as const;\n\ntype MemoryStatusResponse = Awaited<ReturnType<MastraClient['getMemoryStatus']>>;\n\nexport function useMemoryStatus<TData = MemoryStatusResponse>({\n agentId,\n threadId,\n queryOptions,\n}: {\n agentId: string | undefined;\n threadId?: string;\n queryOptions?: MastraQueryOptions<MemoryStatusResponse, TData>;\n}): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: memoryStatusQueryKey(agentId, threadId),\n queryFn: agentId\n ? () =>\n client.getMemoryStatus(agentId, undefined, {\n threadId,\n })\n : skipToken,\n ...queryOptions,\n });\n}\n","import type { GetObservationalMemoryResponse, GetMemoryStatusResponse, MastraClient } from '@mastra/client-js';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { UseMutationResult, UseQueryResult } from '@tanstack/react-query';\nimport { useState, useEffect } from 'react';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraMutationOptions, MastraQueryOptions } from '../shared/query-options';\n\nexport interface MemorySearchParams {\n lastMessages?: number | false;\n}\n\ntype MemoryStatusResponse = Awaited<ReturnType<MastraClient['getMemoryStatus']>> | null;\ntype MemoryConfigResponse = Awaited<ReturnType<MastraClient['getMemoryConfig']>> | null;\ntype ThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['get']>>;\ntype ThreadsResponse = Awaited<ReturnType<MastraClient['listMemoryThreads']>>['threads'] | null;\ntype UpdateThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['update']>>;\ntype CloneThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['clone']>>;\ntype SearchMemoryResponse = Awaited<ReturnType<MastraClient['searchMemory']>>;\ntype ThreadVariables = { threadId: string; agentId: string };\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemory = <TData = MemoryStatusResponse>({\n agentId,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<MemoryStatusResponse, TData>;\n} = {}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', agentId, requestContext],\n queryFn: () => (agentId ? client.getMemoryStatus(agentId, requestContext) : null),\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n retry: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemoryConfig = <TData = MemoryConfigResponse>({\n agentId,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<MemoryConfigResponse, TData>;\n} = {}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'config', agentId, requestContext],\n queryFn: () => (agentId ? client.getMemoryConfig({ agentId, requestContext }) : null),\n staleTime: 5 * 60 * 1000, // 5 minutes\n gcTime: 10 * 60 * 1000, // 10 minutes\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useThread = <TData = ThreadResponse>({\n threadId,\n agentId,\n requestContext,\n queryOptions,\n}: {\n threadId?: string;\n agentId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<ThreadResponse, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'thread', threadId, agentId, requestContext],\n queryFn: () => client.getMemoryThread({ threadId: threadId!, agentId }).get({ requestContext }),\n staleTime: 5 * 60 * 1000,\n gcTime: 10 * 60 * 1000,\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\n/**\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useThreads = <TData = ThreadsResponse>({\n resourceId,\n agentId,\n isMemoryEnabled,\n requestContext,\n queryOptions,\n}: {\n resourceId: string;\n agentId: string;\n isMemoryEnabled: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<ThreadsResponse, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['memory', 'threads', resourceId, agentId, requestContext],\n queryFn: async () => {\n if (!isMemoryEnabled) return null;\n const result = await client.listMemoryThreads({ resourceId, agentId, requestContext });\n return result.threads;\n },\n staleTime: 0,\n gcTime: 0,\n retry: false,\n refetchOnWindowFocus: false,\n ...queryOptions,\n });\n};\n\nexport type DeleteThreadResponse = Awaited<ReturnType<ReturnType<MastraClient['getMemoryThread']>['delete']>>;\n\nexport const useDeleteThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<DeleteThreadResponse, ThreadVariables>;\n} = {}): UseMutationResult<DeleteThreadResponse, Error, ThreadVariables> => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ threadId, agentId }: { threadId: string; agentId: string }) => {\n const thread = client.getMemoryThread({ threadId, agentId });\n return thread.delete({ requestContext });\n },\n onSuccess: (_, variables) => {\n const { agentId } = variables;\n if (agentId) {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads', agentId, agentId] });\n }\n },\n ...queryOptions,\n });\n};\n\nexport const useUpdateThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<UpdateThreadResponse, ThreadVariables & { title: string }>;\n} = {}) => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ threadId, agentId, title }: { threadId: string; agentId: string; title: string }) =>\n client.getMemoryThread({ threadId, agentId }).update({ title, agentId, requestContext }),\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads'] });\n void queryClient.invalidateQueries({ queryKey: ['memory', 'thread'] });\n },\n ...queryOptions,\n });\n};\n\nexport const useMemorySearch = ({\n agentId,\n resourceId,\n threadId,\n requestContext,\n queryOptions,\n}: {\n agentId: string;\n resourceId: string;\n threadId?: string;\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<\n SearchMemoryResponse,\n { searchQuery: string; memoryConfig?: MemorySearchParams }\n >;\n}) => {\n const client = useMastraClient();\n return useMutation({\n mutationFn: async ({ searchQuery, memoryConfig }: { searchQuery: string; memoryConfig?: MemorySearchParams }) => {\n return client.searchMemory({ agentId, resourceId, threadId, searchQuery, memoryConfig, requestContext });\n },\n ...queryOptions,\n });\n};\n\nexport const useCloneThread = ({\n requestContext,\n queryOptions,\n}: {\n requestContext?: Record<string, any>;\n queryOptions?: MastraMutationOptions<CloneThreadResponse, ThreadVariables & { title?: string }>;\n} = {}) => {\n const client = useMastraClient();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: async ({ threadId, agentId, title }: { threadId: string; agentId: string; title?: string }) => {\n const thread = client.getMemoryThread({ threadId, agentId });\n return thread.clone({ title, requestContext });\n },\n onSuccess: (_, variables) => {\n const { agentId } = variables;\n if (agentId) {\n void queryClient.invalidateQueries({ queryKey: ['memory', 'threads', agentId, agentId] });\n }\n },\n ...queryOptions,\n });\n};\n\n/**\n * Hook to fetch Observational Memory data for an agent\n * Returns the current OM record and history for a given resource/thread\n * Polls more frequently when observing/reflecting is in progress\n *\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useObservationalMemoryWithHistory = <TData = GetObservationalMemoryResponse | null>({\n agentId,\n resourceId,\n threadId,\n isActive = false,\n requestContext,\n queryOptions,\n}: {\n agentId: string;\n resourceId?: string;\n threadId?: string;\n isActive?: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<GetObservationalMemoryResponse | null, TData>;\n}): UseQueryResult<TData, Error> => {\n const client = useMastraClient();\n\n return useQuery({\n queryKey: ['observational-memory', agentId, resourceId, threadId, requestContext],\n queryFn: async (): Promise<GetObservationalMemoryResponse | null> => {\n if (!resourceId && !threadId) return null;\n return client.getObservationalMemory({\n agentId,\n resourceId,\n threadId,\n requestContext,\n });\n },\n staleTime: isActive ? 1000 : 30 * 1000, // 1 second when active, 30 seconds otherwise\n gcTime: 5 * 60 * 1000, // 5 minutes\n retry: false,\n refetchOnWindowFocus: false,\n refetchInterval: isActive ? 2000 : false, // Poll every 2 seconds when active\n placeholderData: previousData => previousData, // Keep previous data during refetch to prevent skeleton flash\n ...queryOptions,\n });\n};\n\n/**\n * Hook to get OM-aware memory status\n * Extends useMemory with OM-specific status information\n * Polls more frequently when observing/reflecting is in progress\n *\n * Does not guard on empty ids; pass `queryOptions: { enabled }` to skip the fetch.\n */\nexport const useMemoryWithOMStatus = ({\n agentId,\n resourceId,\n threadId,\n pollWhenActive = true,\n requestContext,\n queryOptions,\n}: {\n agentId?: string;\n resourceId?: string;\n threadId?: string;\n pollWhenActive?: boolean;\n requestContext?: Record<string, any>;\n queryOptions?: MastraQueryOptions<GetMemoryStatusResponse | null>;\n}) => {\n const client = useMastraClient();\n const [isActive, setIsActive] = useState(false);\n\n const query = useQuery<GetMemoryStatusResponse | null>({\n queryKey: ['memory-status', agentId, resourceId, threadId, requestContext],\n queryFn: () =>\n agentId\n ? client.getMemoryStatus(agentId, requestContext, {\n resourceId,\n threadId,\n })\n : null,\n staleTime: isActive && pollWhenActive ? 1000 : 30 * 1000, // 1 second when active, 30 seconds otherwise\n gcTime: 5 * 60 * 1000, // 5 minutes\n retry: false,\n refetchOnWindowFocus: false,\n refetchInterval: isActive && pollWhenActive ? 2000 : false, // Poll every 2 seconds when active\n placeholderData: previousData => previousData, // Keep previous data during refetch to prevent skeleton flash\n ...queryOptions,\n });\n\n // Update isActive state when data changes\n const isObserving = query.data?.observationalMemory?.isObserving;\n const isReflecting = query.data?.observationalMemory?.isReflecting;\n\n useEffect(() => {\n const newIsActive = isObserving || isReflecting || false;\n setIsActive(newIsActive);\n }, [isObserving, isReflecting]);\n\n return query;\n};\n"],"mappings":"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"}
@@ -4,13 +4,13 @@ const require_map = require("../../map-wjmL1y5O.cjs");
4
4
  let react = require("react");
5
5
  let _tanstack_react_query = require("@tanstack/react-query");
6
6
  //#region src/hooks/metrics/metrics-query-filters.ts
7
- const DEFAULT_WINDOW_MS = 1440 * 60 * 1e3;
7
+ const DEFAULT_WINDOW_MS = 864e5;
8
8
  const PRESET_MS = {
9
9
  "24h": DEFAULT_WINDOW_MS,
10
- "3d": 4320 * 60 * 1e3,
11
- "7d": 10080 * 60 * 1e3,
12
- "14d": 336 * 60 * 60 * 1e3,
13
- "30d": 720 * 60 * 60 * 1e3
10
+ "3d": 2592e5,
11
+ "7d": 6048e5,
12
+ "14d": 12096e5,
13
+ "30d": 2592e6
14
14
  };
15
15
  function buildTimestamp(preset, customRange, anchor) {
16
16
  if (preset !== "custom") {
@@ -161,9 +161,9 @@ function formatShortDate(value, { locale, now, timeZone } = {}) {
161
161
  return getFormatter(calendarDate(date, timeZone).year === calendarDate(reference, timeZone).year ? "dayMonth" : "dayMonthYear", locale, timeZone).format(date);
162
162
  }
163
163
  const LONG_RELATIVE_UNITS = [
164
- ["year", 365 * 86400],
165
- ["month", 30 * 86400],
166
- ["week", 7 * 86400],
164
+ ["year", 31536e3],
165
+ ["month", 2592e3],
166
+ ["week", 604800],
167
167
  ["day", 86400],
168
168
  ["hour", 3600],
169
169
  ["minute", 60]
@@ -213,7 +213,7 @@ function formatDate(value, preset, options = {}) {
213
213
  unit: "h"
214
214
  },
215
215
  {
216
- limit: 7 * 864e5,
216
+ limit: 6048e5,
217
217
  size: 864e5,
218
218
  unit: "d"
219
219
  }
@@ -232,7 +232,7 @@ function formatDate(value, preset, options = {}) {
232
232
  }
233
233
  //#endregion
234
234
  //#region src/hooks/metrics/metrics-interval.ts
235
- const HOURLY_MAX_RANGE_MS = 2880 * 60 * 1e3;
235
+ const HOURLY_MAX_RANGE_MS = 1728e5;
236
236
  /** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */
237
237
  function chooseMetricsInterval({ start, end }) {
238
238
  return end.getTime() - start.getTime() <= HOURLY_MAX_RANGE_MS ? "1h" : "1d";
@@ -583,7 +583,9 @@ function useScoresMetrics(params) {
583
583
  const series = timeSeriesResults[i]?.series ?? [];
584
584
  for (const s of series) for (const point of s.points) {
585
585
  const ts = new Date(point.timestamp);
586
- const acc = require_map.getOrCreate(require_map.getOrCreate(hourBuckets, ts.getHours() * 60 + ts.getMinutes(), () => /* @__PURE__ */ new Map()), scorerId, () => ({
586
+ const hourKey = ts.getHours() * 60 + ts.getMinutes();
587
+ const scorerMap = require_map.getOrCreate(hourBuckets, hourKey, () => /* @__PURE__ */ new Map());
588
+ const acc = require_map.getOrCreate(scorerMap, scorerId, () => ({
587
589
  sum: 0,
588
590
  count: 0
589
591
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useMastraClient","useMastraClient","useMastraClient","useMastraClient","useMastraClient","useMastraClient","getOrCreate","useMastraClient","getOrCreate","useMastraClient","getOrCreate","useMastraClient","TOP_N","useMastraClient","getOrCreate","useMastraClient","getOrCreate","useMastraClient","getOrCreate","useMastraClient"],"sources":["../../../src/hooks/metrics/metrics-query-filters.ts","../../../src/hooks/shared/date-format.ts","../../../src/hooks/metrics/metrics-interval.ts","../../../src/hooks/metrics/use-active-resources-kpi-metrics.tsx","../../../src/hooks/metrics/use-active-threads-kpi-metrics.tsx","../../../src/hooks/metrics/use-agent-runs-kpi-metrics.tsx","../../../src/hooks/metrics/use-latency-metrics.tsx","../../../src/hooks/metrics/use-model-cost-kpi-metrics.tsx","../../../src/hooks/shared/cost.ts","../../../src/hooks/metrics/use-model-usage-cost-metrics.tsx","../../../src/hooks/metrics/use-scores-metrics.tsx","../../../src/hooks/metrics/use-token-usage-by-agent-metrics.tsx","../../../src/hooks/metrics/use-token-usage-timeseries.tsx","../../../src/hooks/metrics/use-top-active-threads-metrics.tsx","../../../src/hooks/metrics/use-top-resources-by-threads-metrics.tsx","../../../src/hooks/metrics/use-total-tokens-kpi-metrics.tsx","../../../src/hooks/metrics/use-trace-volume-metrics.tsx"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport { useMemo, useRef } from 'react';\n\nexport type MetricsDatePreset = '24h' | '3d' | '7d' | '14d' | '30d' | 'custom';\n\nexport type MetricsDateRange = { from?: Date; to?: Date };\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\nexport interface MetricsQueryFiltersInput {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n dimensionalFilter: MetricsDimensionalFilter;\n /** Stable JSON representation of `dimensionalFilter`, safe for query keys. */\n dimensionalFilterKey: string;\n}\n\ntype Timestamp = { start: Date; end: Date };\n\nexport interface MetricsQueryFilters {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n timestamp: Timestamp;\n filters: MetricsDimensionalFilter & { timestamp: Timestamp };\n dimensionalFilter: MetricsDimensionalFilter;\n filterKey: string;\n}\n\nconst DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nconst PRESET_MS: Record<string, number> = {\n '24h': DEFAULT_WINDOW_MS,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '14d': 14 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n};\n\nfunction buildTimestamp(\n preset: MetricsDatePreset,\n customRange: MetricsDateRange | undefined,\n anchor: number,\n): Timestamp {\n if (preset !== 'custom') {\n const ms = PRESET_MS[preset] ?? DEFAULT_WINDOW_MS;\n return { start: new Date(anchor - ms), end: new Date(anchor) };\n }\n return {\n start: customRange?.from ?? new Date(anchor - DEFAULT_WINDOW_MS),\n end: customRange?.to ?? new Date(anchor),\n };\n}\n\n/**\n * Compose a ready-to-use metrics filter object from a date window and a\n * dimensional filter. Pass the result to the metrics hooks.\n *\n * Stability guarantees (important for react-query):\n * - `timestamp` is frozen at the moment the inputs change and does NOT update\n * on every render. Otherwise each render would mint a new `new Date()` and\n * every metrics query would re-fetch on every keystroke.\n * - `filters` and `filterKey` are referentially stable while inputs are\n * unchanged, so `queryKey` hashing is cheap and caches hit.\n */\nexport function useMetricsQueryFilters({\n datePreset,\n customRange,\n dimensionalFilter,\n dimensionalFilterKey,\n}: MetricsQueryFiltersInput): MetricsQueryFilters {\n // Anchor the \"now\" used for preset windows. We only recompute when the\n // preset or custom range changes — this gives a stable timestamp per query\n // boundary rather than a new Date on every render.\n const anchorRef = useRef<{ key: string; anchor: number } | null>(null);\n const windowKey =\n datePreset === 'custom'\n ? `custom:${customRange?.from?.getTime() ?? ''}:${customRange?.to?.getTime() ?? ''}`\n : `preset:${datePreset}`;\n if (!anchorRef.current || anchorRef.current.key !== windowKey) {\n anchorRef.current = { key: windowKey, anchor: Date.now() };\n }\n const anchor = anchorRef.current.anchor;\n\n const timestamp = useMemo(() => buildTimestamp(datePreset, customRange, anchor), [datePreset, customRange, anchor]);\n\n const filters = useMemo(\n () => ({ timestamp, ...dimensionalFilter }),\n // dimensionalFilterKey is a stringified digest, so this dep set gives a\n // stable ref while content is unchanged.\n [timestamp, dimensionalFilterKey],\n );\n\n // filterKey combines window + dimensions so react-query keys are cheap.\n const filterKey = useMemo(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey]);\n\n return { datePreset, customRange, timestamp, filters, dimensionalFilter, filterKey };\n}\n","export type DateInput = Date | string | number | null | undefined;\nexport type DatePreset =\n | 'date'\n | 'date-time'\n | 'date-time-seconds'\n | 'day-time-seconds'\n | 'time'\n | 'time-seconds'\n | 'relative-time'\n | 'relative-long';\n\ntype FormatOptions = { locale?: string; now?: Date | number; timeZone?: string };\n\nexport function toDate(value: DateInput): Date | undefined {\n if (value == null) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nconst PRESET_OPTIONS = {\n time: { hour: 'numeric', minute: '2-digit' },\n 'time-seconds': { hour: 'numeric', minute: '2-digit', second: '2-digit' },\n 'date-time': { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' },\n 'date-time-seconds': {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n },\n 'day-time-seconds': { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit' },\n calendar: { year: 'numeric', month: 'numeric', day: 'numeric', calendar: 'gregory', numberingSystem: 'latn' },\n dayMonth: { month: 'short', day: 'numeric' },\n dayMonthYear: { month: 'short', day: 'numeric', year: 'numeric' },\n precise: {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n },\n timePrecise: { hour: 'numeric', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3 },\n} satisfies Record<string, Intl.DateTimeFormatOptions>;\n\ntype FormatterKey = keyof typeof PRESET_OPTIONS;\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\nfunction getFormatter(key: FormatterKey, locale?: string, timeZone?: string) {\n const cacheKey = `${locale ?? ''}|${timeZone ?? ''}|${key}`;\n let formatter = formatters.get(cacheKey);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...PRESET_OPTIONS[key], timeZone });\n formatters.set(cacheKey, formatter);\n }\n return formatter;\n}\n\nfunction calendarDate(date: Date, timeZone?: string) {\n const parts = getFormatter('calendar', 'en-US', timeZone).formatToParts(date);\n return {\n year: parts.find(part => part.type === 'year')?.value,\n month: parts.find(part => part.type === 'month')?.value,\n day: parts.find(part => part.type === 'day')?.value,\n };\n}\n\n/** Short absolute date without time: `Sep 24` this year, `Sep 24, 2025` otherwise. */\nexport function formatShortDate(value: DateInput, { locale, now, timeZone }: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const reference = new Date(now ?? Date.now());\n const key =\n calendarDate(date, timeZone).year === calendarDate(reference, timeZone).year ? 'dayMonth' : 'dayMonthYear';\n return getFormatter(key, locale, timeZone).format(date);\n}\n\nconst LONG_RELATIVE_UNITS: Array<[Intl.RelativeTimeFormatUnit, number]> = [\n ['year', 365 * 86_400],\n ['month', 30 * 86_400],\n ['week', 7 * 86_400],\n ['day', 86_400],\n ['hour', 3_600],\n ['minute', 60],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\n\nfunction getRelativeFormatter(locale?: string) {\n const key = locale ?? '';\n let formatter = relativeFormatters.get(key);\n if (!formatter) {\n formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n relativeFormatters.set(key, formatter);\n }\n return formatter;\n}\n\n/**\n * Uses the browser locale unless `locale` is given.\n * - `date`: date only; omits the year when it matches `now` in the requested timezone\n * - `date-time`: date, year and time to minutes, including historical dates\n * - `date-time-seconds`: date, year and time to seconds\n * - `day-time-seconds`: month, day and time to seconds, without the year\n * - `time`: time to minutes, without a date\n * - `time-seconds`: time to seconds, without a date\n * - `relative-time`: short relative label; delegates to `date` at seven days\n */\nexport function formatDate(value: DateInput, preset: DatePreset, options: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const { locale, now, timeZone } = options;\n\n if (preset === 'relative-time') {\n const diff = date.getTime() - new Date(now ?? Date.now()).getTime();\n const abs = Math.abs(diff);\n if (abs < 5_000) return 'just now';\n const units = [\n { limit: 60_000, size: 1_000, unit: 's' },\n { limit: 3_600_000, size: 60_000, unit: 'm' },\n { limit: 86_400_000, size: 3_600_000, unit: 'h' },\n { limit: 7 * 86_400_000, size: 86_400_000, unit: 'd' },\n ];\n const match = units.find(({ limit }) => abs < limit);\n if (!match) return formatDate(date, 'date', options);\n const label = `${Math.floor(abs / match.size)}${match.unit}`;\n return diff < 0 ? `${label} ago` : `in ${label}`;\n }\n if (preset === 'relative-long') {\n const seconds = (date.getTime() - new Date(now ?? Date.now()).getTime()) / 1000;\n const [unit, size] = LONG_RELATIVE_UNITS.find(([, size]) => Math.abs(seconds) >= size) ?? ['second', 1];\n return getRelativeFormatter(locale).format(Math.round(seconds / size), unit);\n }\n if (preset === 'date') return formatShortDate(date, options);\n\n return getFormatter(preset, locale, timeZone).format(date);\n}\n\n/** Locale-aware compact date range, e.g. `Sep 2 – 5, 2026`. */\nexport function formatDateRange(start: DateInput, end: DateInput, options: Omit<FormatOptions, 'now'> = {}) {\n const from = toDate(start);\n const to = toDate(end);\n if (!from || !to) return undefined;\n return getFormatter('dayMonthYear', options.locale, options.timeZone)\n .formatRange(from, to)\n .replace(/\\u2009/g, ' ');\n}\n\n/** Date and time down to milliseconds, for trace debugging. `withDate: false` keeps only the time. */\nexport function formatTimestampPrecise(\n value: DateInput,\n { locale, withDate = true }: { locale?: string; withDate?: boolean } = {},\n) {\n const date = toDate(value);\n return date ? getFormatter(withDate ? 'precise' : 'timePrecise', locale).format(date) : undefined;\n}\n","import { formatDate, formatShortDate } from '../shared/date-format';\n\nexport type MetricsInterval = '1h' | '1d';\n\nconst HOURLY_MAX_RANGE_MS = 48 * 60 * 60 * 1000;\n\n/** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */\nexport function chooseMetricsInterval({ start, end }: { start: Date; end: Date }): MetricsInterval {\n return end.getTime() - start.getTime() <= HOURLY_MAX_RANGE_MS ? '1h' : '1d';\n}\n\nexport function formatMetricsBucketLabel(ts: Date, interval: MetricsInterval): string {\n if (interval === '1h') {\n return formatDate(ts, 'time') ?? '';\n }\n return formatShortDate(ts) ?? '';\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Resources — number of distinct resource IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveResourcesKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-resources-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'resourceId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Threads — number of distinct thread IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveThreadsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-threads-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Agent Runs — count of agent duration metric observations */\nexport function useAgentRunsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'agent-runs-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface LatencyPoint {\n [key: string]: unknown;\n time: string;\n /** Raw timestamp (ms since epoch) for the bucket this point represents.\n * Used by drilldown clicks to compute a narrow time window. */\n tsMs: number;\n p50: number;\n p95: number;\n}\n\nasync function fetchPercentiles(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n interval: MetricsInterval,\n): Promise<LatencyPoint[]> {\n const res = await client.getMetricPercentiles({\n name: metricName,\n percentiles: [0.5, 0.95],\n interval,\n filters,\n });\n\n const p50Series = res.series.find(s => s.percentile === 0.5);\n const p95Series = res.series.find(s => s.percentile === 0.95);\n\n if (!p50Series || !p95Series) return [];\n\n const p95Map = new Map(p95Series.points.map(p => [new Date(p.timestamp).getTime(), p.value]));\n\n return p50Series.points.map(p => {\n const ts = new Date(p.timestamp);\n const tsMs = ts.getTime();\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs,\n p50: Math.round(p.value),\n p95: Math.round(p95Map.get(tsMs) ?? 0),\n };\n });\n}\n\nexport interface LatencyMetricsData {\n agentData: LatencyPoint[];\n workflowData: LatencyPoint[];\n toolData: LatencyPoint[];\n interval: MetricsInterval;\n}\n\nexport function useLatencyMetrics<TData = LatencyMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<LatencyMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'latency', filterKey, interval],\n queryFn: async (): Promise<LatencyMetricsData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchPercentiles(client, 'mastra_agent_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_workflow_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_tool_duration_ms', filters, interval),\n ]);\n return { agentData, workflowData, toolData, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Model Cost — sum of estimatedCost across input and output token metrics */\nexport interface ModelCostKpi {\n cost: number | null;\n costUnit: string | null;\n previousCost: number | null;\n costChangePercent: number | null;\n}\n\nexport function useModelCostKpiMetrics<TData = ModelCostKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelCostKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-cost-kpi', filterKey],\n queryFn: async (): Promise<ModelCostKpi> => {\n const res = await client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens', 'mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n });\n\n return {\n cost: res.estimatedCost ?? null,\n costUnit: res.costUnit ?? null,\n previousCost: res.previousEstimatedCost ?? null,\n costChangePercent: res.costChangePercent ?? null,\n };\n },\n ...queryOptions,\n });\n}\n","export interface CompactNumberFormatOptions {\n currency?: string;\n}\n\nconst compactNumber = new Intl.NumberFormat('en-US', { notation: 'compact', maximumSignificantDigits: 3 });\nconst fullNumber = new Intl.NumberFormat('en-US');\n\nconst currencyCodes = new Set(Intl.supportedValuesOf('currency'));\n\nfunction isCurrency(code: string | undefined): code is string {\n return code !== undefined && currencyCodes.has(code.toUpperCase());\n}\n\nfunction money(currency: string, options: Intl.NumberFormatOptions) {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency, ...options });\n}\n\nexport function formatCompactNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return compactNumber.format(value);\n const size = Math.abs(value);\n if (size < 100) return formatFullNumber(value, { currency });\n if (size < 1000) return money(currency, { maximumFractionDigits: 0 }).format(value);\n return money(currency, { notation: 'compact', maximumSignificantDigits: 3 }).format(value);\n}\n\nexport function formatFullNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return fullNumber.format(value);\n const formatter = money(currency, {});\n const smallestUnit = 10 ** -(formatter.resolvedOptions().maximumFractionDigits ?? 2);\n if (value !== 0 && Math.abs(value) < smallestUnit) {\n return `${value < 0 ? '-' : ''}<${formatter.format(smallestUnit)}`;\n }\n return formatter.format(value);\n}\n\nexport function formatCost(value: number, unit?: string | null): string {\n const isUsd = !unit || unit.toLowerCase() === 'usd';\n const amount = value > 0 && value < 0.01 ? '<0.01' : value.toFixed(2);\n if (!isUsd) return `${amount} ${unit}`;\n return amount.startsWith('<') ? '<$0.01' : `$${amount}`;\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatCompactNumber } from '../shared/cost';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ModelUsageRow {\n model: string;\n provider?: string;\n input: string;\n output: string;\n cacheRead: string;\n cacheWrite: string;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useModelUsageCostMetrics<TData = ModelUsageRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelUsageRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-usage-cost', filterKey],\n queryFn: async (): Promise<ModelUsageRow[]> => {\n const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all(\n (\n [\n 'mastra_model_total_input_tokens',\n 'mastra_model_total_output_tokens',\n 'mastra_model_input_cache_read_tokens',\n 'mastra_model_input_cache_write_tokens',\n ] as const\n ).map(name =>\n client.getMetricBreakdown({\n name: [name],\n groupBy: ['model', 'provider'],\n aggregation: 'sum',\n orderDirection: 'DESC',\n filters,\n }),\n ),\n );\n\n if (!inputRes || !outputRes || !cacheReadRes || !cacheWriteRes) return [];\n\n type ModelEntry = {\n model: string;\n provider: string | undefined;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number | null;\n costUnit: string | null;\n };\n\n const modelMap = new Map<string, ModelEntry>();\n\n const ensureModel = (dimensions: { model?: string | null; provider?: string | null }): ModelEntry => {\n const model = dimensions.model ?? 'unknown';\n const provider = dimensions.provider ?? undefined;\n return getOrCreate(modelMap, `${model}\\u0000${provider ?? ''}`, () => ({\n model,\n provider,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n cost: null,\n costUnit: null,\n }));\n };\n\n // total_input/total_output estimatedCost already rolls up cache + other detail\n // costs. The cache breakdowns are kept for their token counts only.\n const addCost = (entry: ModelEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.output = group.value;\n addCost(entry, group);\n }\n for (const group of cacheReadRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheRead = group.value;\n }\n for (const group of cacheWriteRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheWrite = group.value;\n }\n\n return Array.from(modelMap.values())\n .map(vals => ({\n model: vals.model,\n ...(vals.provider ? { provider: vals.provider } : {}),\n input: formatCompactNumber(vals.input),\n output: formatCompactNumber(vals.output),\n cacheRead: formatCompactNumber(vals.cacheRead),\n cacheWrite: formatCompactNumber(vals.cacheWrite),\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => a.model.localeCompare(b.model) || (a.provider ?? '').localeCompare(b.provider ?? ''));\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatDate } from '../shared/date-format';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ScorerSummary {\n scorer: string;\n avg: number;\n min: number;\n max: number;\n count: number;\n}\n\nexport interface ScoresOverTimePoint {\n time: string;\n [scorer: string]: string | number;\n}\n\nexport interface ScoresMetricsData {\n summaryData: ScorerSummary[];\n overTimeData: ScoresOverTimePoint[];\n scorerNames: string[];\n avgScore: number | null;\n}\n\nexport function useScoresMetrics<TData = ScoresMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ScoresMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { datePreset, customRange, timestamp, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'scores-card', datePreset, customRange],\n queryFn: async (): Promise<ScoresMetricsData> => {\n const filters = {\n timestamp: { start: timestamp.start, end: timestamp.end },\n };\n\n const scorersMap = await client.listScorers();\n const scorerIds = Object.keys(scorersMap ?? {});\n\n if (scorerIds.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n // Fetch summary stats first to determine which scorers have data\n const summaryResults = await Promise.all(\n scorerIds.map(async scorerId => {\n const [avg, min, max, count] = await Promise.all([\n client.getScoreAggregate({ scorerId, aggregation: 'avg', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'min', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'max', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'count', filters }),\n ]);\n return {\n scorer: scorerId,\n avg: avg.value ?? 0,\n min: min.value ?? 0,\n max: max.value ?? 0,\n count: count.value ?? 0,\n };\n }),\n );\n\n const summaryData: ScorerSummary[] = summaryResults.filter(s => s.count > 0);\n const scorerNames = summaryData.map(s => s.scorer);\n\n if (summaryData.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n const totalWeighted = summaryData.reduce((s, d) => s + d.avg * d.count, 0);\n const totalCount = summaryData.reduce((s, d) => s + d.count, 0);\n const avgScore = totalCount ? Math.round((totalWeighted / totalCount) * 100) / 100 : 0;\n\n const interval = '1h';\n\n // Fetch hourly time series from the full period for active scorers\n const timeSeriesResults = await Promise.all(\n scorerNames.map(scorerId =>\n client.getScoreTimeSeries({\n scorerId,\n interval,\n aggregation: 'avg',\n filters,\n }),\n ),\n );\n\n // Collapse all days into a single 24-hour view (00:00–23:00).\n // For each hour-of-day, average the values across all days in the range.\n const hourBuckets = new Map<number, Map<string, { sum: number; count: number }>>();\n\n for (let i = 0; i < scorerNames.length; i++) {\n const scorerId = scorerNames[i];\n const series = timeSeriesResults[i]?.series ?? [];\n for (const s of series) {\n for (const point of s.points) {\n const ts = new Date(point.timestamp);\n const hourKey = ts.getHours() * 60 + ts.getMinutes();\n const scorerMap = getOrCreate(hourBuckets, hourKey, () => new Map());\n const acc = getOrCreate(scorerMap, scorerId, () => ({ sum: 0, count: 0 }));\n\n acc.sum += point.value;\n acc.count += 1;\n }\n }\n }\n\n // Build sorted 24h chart data\n const overTimeData: ScoresOverTimePoint[] = Array.from(hourBuckets.entries())\n .sort(([a], [b]) => a - b)\n .map(([hourKey, scorerMap]) => {\n const point: ScoresOverTimePoint = {\n time: formatDate(new Date(2000, 0, 1, Math.floor(hourKey / 60), hourKey % 60), 'time') ?? '',\n };\n for (const [scorerId, acc] of scorerMap) {\n point[scorerId] = +(acc.sum / acc.count).toFixed(2);\n }\n return point;\n });\n\n return {\n summaryData,\n overTimeData,\n scorerNames,\n avgScore,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface TokenUsageByAgentRow {\n name: string;\n total: number;\n input: number;\n output: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useTokenUsageByAgentMetrics<TData = TokenUsageByAgentRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageByAgentRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-by-agent', filterKey],\n queryFn: async (): Promise<TokenUsageByAgentRow[]> => {\n const breakdownBase = {\n groupBy: ['entityName'],\n aggregation: 'sum' as const,\n orderDirection: 'DESC' as const,\n filters,\n };\n // total_input/total_output estimatedCost already rolls up cache + other detail costs.\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_input_tokens'] }),\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_output_tokens'] }),\n ]);\n\n type AgentEntry = { input: number; output: number; cost: number | null; costUnit: string | null };\n\n const agentMap = new Map<string, AgentEntry>();\n\n const ensure = (name: string): AgentEntry =>\n getOrCreate(agentMap, name, () => ({ input: 0, output: 0, cost: null, costUnit: null }));\n\n const addCost = (entry: AgentEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.output = group.value;\n addCost(entry, group);\n }\n\n return Array.from(agentMap.entries())\n .map(([name, vals]) => ({\n name,\n input: vals.input,\n output: vals.output,\n total: vals.input + vals.output,\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => b.total - a.total);\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport type TokenUsageTimeSeriesInterval = MetricsInterval;\n\nexport interface TokenTimelinePoint {\n time: string;\n tsMs: number;\n input: number;\n output: number;\n total: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport interface TokenUsageTimeSeriesData {\n data: TokenTimelinePoint[];\n interval: TokenUsageTimeSeriesInterval;\n}\n\ntype TimeSeriesPoint = {\n timestamp: string | Date;\n value: number;\n estimatedCost?: number | null;\n};\n\ntype SeriesWithCost = {\n costUnit?: string | null;\n points: TimeSeriesPoint[];\n};\n\ntype TokenTimelineAccumulator = {\n tsMs: number;\n input: number;\n output: number;\n cost: number | null;\n costUnits: Set<string>;\n hasUnknownCostUnit: boolean;\n};\n\nfunction addSeriesPoints(\n pointMap: Map<number, TokenTimelineAccumulator>,\n series: SeriesWithCost | undefined,\n key: 'input' | 'output',\n) {\n for (const point of series?.points ?? []) {\n const tsMs = new Date(point.timestamp).getTime();\n if (!Number.isFinite(tsMs)) continue;\n\n const existing = pointMap.get(tsMs) ?? {\n tsMs,\n input: 0,\n output: 0,\n cost: null,\n costUnits: new Set<string>(),\n hasUnknownCostUnit: false,\n };\n\n existing[key] += point.value;\n\n if (point.estimatedCost != null) {\n existing.cost = (existing.cost ?? 0) + point.estimatedCost;\n if (series?.costUnit) {\n existing.costUnits.add(series.costUnit);\n } else {\n existing.hasUnknownCostUnit = true;\n }\n }\n\n pointMap.set(tsMs, existing);\n }\n}\n\nfunction toCostUnit(entry: TokenTimelineAccumulator): string | null {\n if (entry.cost == null || entry.hasUnknownCostUnit || entry.costUnits.size !== 1) return null;\n return [...entry.costUnits][0] ?? null;\n}\n\nexport function useTokenUsageTimeSeries<TData = TokenUsageTimeSeriesData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageTimeSeriesData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-timeseries', filterKey, interval],\n queryFn: async (): Promise<TokenUsageTimeSeriesData> => {\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricTimeSeries({\n name: ['mastra_model_total_input_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n client.getMetricTimeSeries({\n name: ['mastra_model_total_output_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n ]);\n\n const pointMap = new Map<number, TokenTimelineAccumulator>();\n addSeriesPoints(pointMap, inputRes.series[0], 'input');\n addSeriesPoints(pointMap, outputRes.series[0], 'output');\n\n const data = Array.from(pointMap.values())\n .sort((a, b) => a.tsMs - b.tsMs)\n .map(point => {\n const ts = new Date(point.tsMs);\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs: point.tsMs,\n input: point.input,\n output: point.output,\n total: point.input + point.output,\n cost: point.cost,\n costUnit: toCostUnit(point),\n };\n });\n\n return { data, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ActiveThreadRow {\n threadId: string;\n resourceId: string | null;\n runs: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Active Threads — the threads with the most agent runs in the selected\n * range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the\n * query never returns the full thread set when cardinality is in the millions.\n *\n * Tokens + cost are joined in from parallel breakdowns on the same `threadId`\n * grouping so we don't need any new backend aggregation support. */\nexport function useTopActiveThreadsMetrics<TData = ActiveThreadRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ActiveThreadRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-active-threads', filterKey],\n queryFn: async (): Promise<ActiveThreadRow[]> => {\n const breakdownBase = {\n groupBy: ['threadId', 'resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [runsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying thread set has very\n // high cardinality. Threads that are top-N by runs but not by tokens\n // will display 0 tokens (an acceptable approximation in exchange for\n // a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byThread = new Map<string, Entry>();\n\n const ensure = (threadId: string): Entry =>\n getOrCreate(byThread, threadId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const threadId = group.dimensions.threadId;\n if (!threadId) continue;\n const entry = ensure(threadId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return runsRes.groups\n .filter(group => !!group.dimensions.threadId)\n .map(group => {\n const threadId = group.dimensions.threadId as string;\n const extra = byThread.get(threadId);\n return {\n threadId,\n resourceId: (group.dimensions.resourceId as string | undefined) ?? null,\n runs: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ResourceThreadsRow {\n resourceId: string;\n threadCount: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Resources by Thread Count — the resources with the most distinct threads\n * in the selected range. Uses `count_distinct(threadId)` per `resourceId`,\n * with server-side TopK (`ORDER BY value DESC LIMIT 20`).\n *\n * Tokens + cost are joined in from parallel breakdowns on `resourceId` so the\n * table can show cost/usage without a separate backend aggregation. */\nexport function useTopResourcesByThreadsMetrics<TData = ResourceThreadsRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ResourceThreadsRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-resources-by-threads', filterKey],\n queryFn: async (): Promise<ResourceThreadsRow[]> => {\n const breakdownBase = {\n groupBy: ['resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [threadsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying resource set has very\n // high cardinality. Resources that are top-N by thread count but not by\n // tokens will display 0 tokens (an acceptable approximation in exchange\n // for a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byResource = new Map<string, Entry>();\n\n const ensure = (resourceId: string): Entry =>\n getOrCreate(byResource, resourceId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const resourceId = group.dimensions.resourceId;\n if (!resourceId) continue;\n const entry = ensure(resourceId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return threadsRes.groups\n .filter(group => !!group.dimensions.resourceId)\n .map(group => {\n const resourceId = group.dimensions.resourceId as string;\n const extra = byResource.get(resourceId);\n return {\n resourceId,\n threadCount: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Tokens — sum of all input + output tokens */\nexport interface TotalTokensKpi {\n value: number | null;\n previousValue: number | null;\n changePercent: number | null;\n}\n\nexport function useTotalTokensKpiMetrics<TData = TotalTokensKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TotalTokensKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'total-tokens-kpi', filterKey],\n queryFn: async (): Promise<TotalTokensKpi> => {\n const [input, output] = await Promise.all([\n client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n client.getMetricAggregate({\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n ]);\n\n const hasCurrent = input.value != null || output.value != null;\n const hasPrevious = input.previousValue != null || output.previousValue != null;\n const value = (input.value ?? 0) + (output.value ?? 0);\n const previousValue = (input.previousValue ?? 0) + (output.previousValue ?? 0);\n const changePercent = hasPrevious && previousValue > 0 ? ((value - previousValue) / previousValue) * 100 : null;\n\n return {\n value: hasCurrent ? value : null,\n previousValue: hasPrevious ? previousValue : null,\n changePercent,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface VolumeRow {\n name: string;\n completed: number;\n errors: number;\n}\n\nasync function fetchVolume(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n): Promise<VolumeRow[]> {\n const res = await client.getMetricBreakdown({\n name: [metricName],\n groupBy: ['entityName', 'status'],\n aggregation: 'count',\n orderDirection: 'DESC',\n filters,\n });\n\n const map = new Map<string, { completed: number; errors: number }>();\n\n for (const group of res.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const status = group.dimensions.status ?? 'ok';\n const entry = getOrCreate(map, name, () => ({ completed: 0, errors: 0 }));\n\n if (status === 'error') {\n entry.errors += group.value;\n } else {\n entry.completed += group.value;\n }\n }\n\n return Array.from(map.entries())\n .map(([name, vals]) => ({ name, ...vals }))\n .sort((a, b) => b.completed + b.errors - (a.completed + a.errors));\n}\n\nexport interface TraceVolumeData {\n agentData: VolumeRow[];\n workflowData: VolumeRow[];\n toolData: VolumeRow[];\n}\n\nexport function useTraceVolumeMetrics<TData = TraceVolumeData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TraceVolumeData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'trace-volume', filterKey],\n queryFn: async (): Promise<TraceVolumeData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchVolume(client, 'mastra_agent_duration_ms', filters),\n fetchVolume(client, 'mastra_workflow_duration_ms', filters),\n fetchVolume(client, 'mastra_tool_duration_ms', filters),\n ]);\n return { agentData, workflowData, toolData };\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["useRef","useMemo","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","TOP_N","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery","getOrCreate","useMastraClient","useQuery"],"sources":["../../../src/hooks/metrics/metrics-query-filters.ts","../../../src/hooks/shared/date-format.ts","../../../src/hooks/metrics/metrics-interval.ts","../../../src/hooks/metrics/use-active-resources-kpi-metrics.tsx","../../../src/hooks/metrics/use-active-threads-kpi-metrics.tsx","../../../src/hooks/metrics/use-agent-runs-kpi-metrics.tsx","../../../src/hooks/metrics/use-latency-metrics.tsx","../../../src/hooks/metrics/use-model-cost-kpi-metrics.tsx","../../../src/hooks/shared/cost.ts","../../../src/hooks/metrics/use-model-usage-cost-metrics.tsx","../../../src/hooks/metrics/use-scores-metrics.tsx","../../../src/hooks/metrics/use-token-usage-by-agent-metrics.tsx","../../../src/hooks/metrics/use-token-usage-timeseries.tsx","../../../src/hooks/metrics/use-top-active-threads-metrics.tsx","../../../src/hooks/metrics/use-top-resources-by-threads-metrics.tsx","../../../src/hooks/metrics/use-total-tokens-kpi-metrics.tsx","../../../src/hooks/metrics/use-trace-volume-metrics.tsx"],"sourcesContent":["import type { EntityType } from '@mastra/core/observability';\nimport { useMemo, useRef } from 'react';\n\nexport type MetricsDatePreset = '24h' | '3d' | '7d' | '14d' | '30d' | 'custom';\n\nexport type MetricsDateRange = { from?: Date; to?: Date };\n\n/** Shape of the dimensional filter object fed into `MetricsFilter` on client\n * calls. Kept compatible with `metricsFilterSchema` in @internal/core — every\n * scalar field maps to a single-string column filter, and `tags` is the only\n * array field (matched via `has()` / equivalent on backends). */\nexport type MetricsDimensionalFilter = {\n rootEntityType?: EntityType;\n entityName?: string;\n tags?: string[];\n serviceName?: string;\n environment?: string;\n provider?: string;\n model?: string;\n threadId?: string;\n resourceId?: string;\n userId?: string;\n organizationId?: string;\n runId?: string;\n sessionId?: string;\n requestId?: string;\n experimentId?: string;\n};\n\nexport interface MetricsQueryFiltersInput {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n dimensionalFilter: MetricsDimensionalFilter;\n /** Stable JSON representation of `dimensionalFilter`, safe for query keys. */\n dimensionalFilterKey: string;\n}\n\ntype Timestamp = { start: Date; end: Date };\n\nexport interface MetricsQueryFilters {\n datePreset: MetricsDatePreset;\n customRange: MetricsDateRange | undefined;\n timestamp: Timestamp;\n filters: MetricsDimensionalFilter & { timestamp: Timestamp };\n dimensionalFilter: MetricsDimensionalFilter;\n filterKey: string;\n}\n\nconst DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;\n\nconst PRESET_MS: Record<string, number> = {\n '24h': DEFAULT_WINDOW_MS,\n '3d': 3 * 24 * 60 * 60 * 1000,\n '7d': 7 * 24 * 60 * 60 * 1000,\n '14d': 14 * 24 * 60 * 60 * 1000,\n '30d': 30 * 24 * 60 * 60 * 1000,\n};\n\nfunction buildTimestamp(\n preset: MetricsDatePreset,\n customRange: MetricsDateRange | undefined,\n anchor: number,\n): Timestamp {\n if (preset !== 'custom') {\n const ms = PRESET_MS[preset] ?? DEFAULT_WINDOW_MS;\n return { start: new Date(anchor - ms), end: new Date(anchor) };\n }\n return {\n start: customRange?.from ?? new Date(anchor - DEFAULT_WINDOW_MS),\n end: customRange?.to ?? new Date(anchor),\n };\n}\n\n/**\n * Compose a ready-to-use metrics filter object from a date window and a\n * dimensional filter. Pass the result to the metrics hooks.\n *\n * Stability guarantees (important for react-query):\n * - `timestamp` is frozen at the moment the inputs change and does NOT update\n * on every render. Otherwise each render would mint a new `new Date()` and\n * every metrics query would re-fetch on every keystroke.\n * - `filters` and `filterKey` are referentially stable while inputs are\n * unchanged, so `queryKey` hashing is cheap and caches hit.\n */\nexport function useMetricsQueryFilters({\n datePreset,\n customRange,\n dimensionalFilter,\n dimensionalFilterKey,\n}: MetricsQueryFiltersInput): MetricsQueryFilters {\n // Anchor the \"now\" used for preset windows. We only recompute when the\n // preset or custom range changes — this gives a stable timestamp per query\n // boundary rather than a new Date on every render.\n const anchorRef = useRef<{ key: string; anchor: number } | null>(null);\n const windowKey =\n datePreset === 'custom'\n ? `custom:${customRange?.from?.getTime() ?? ''}:${customRange?.to?.getTime() ?? ''}`\n : `preset:${datePreset}`;\n if (!anchorRef.current || anchorRef.current.key !== windowKey) {\n anchorRef.current = { key: windowKey, anchor: Date.now() };\n }\n const anchor = anchorRef.current.anchor;\n\n const timestamp = useMemo(() => buildTimestamp(datePreset, customRange, anchor), [datePreset, customRange, anchor]);\n\n const filters = useMemo(\n () => ({ timestamp, ...dimensionalFilter }),\n // dimensionalFilterKey is a stringified digest, so this dep set gives a\n // stable ref while content is unchanged.\n [timestamp, dimensionalFilterKey],\n );\n\n // filterKey combines window + dimensions so react-query keys are cheap.\n const filterKey = useMemo(() => `${windowKey}|${dimensionalFilterKey}`, [windowKey, dimensionalFilterKey]);\n\n return { datePreset, customRange, timestamp, filters, dimensionalFilter, filterKey };\n}\n","export type DateInput = Date | string | number | null | undefined;\nexport type DatePreset =\n | 'date'\n | 'date-time'\n | 'date-time-seconds'\n | 'day-time-seconds'\n | 'time'\n | 'time-seconds'\n | 'relative-time'\n | 'relative-long';\n\ntype FormatOptions = { locale?: string; now?: Date | number; timeZone?: string };\n\nexport function toDate(value: DateInput): Date | undefined {\n if (value == null) return undefined;\n const date = value instanceof Date ? value : new Date(value);\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n\nconst PRESET_OPTIONS = {\n time: { hour: 'numeric', minute: '2-digit' },\n 'time-seconds': { hour: 'numeric', minute: '2-digit', second: '2-digit' },\n 'date-time': { month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' },\n 'date-time-seconds': {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n },\n 'day-time-seconds': { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit' },\n calendar: { year: 'numeric', month: 'numeric', day: 'numeric', calendar: 'gregory', numberingSystem: 'latn' },\n dayMonth: { month: 'short', day: 'numeric' },\n dayMonthYear: { month: 'short', day: 'numeric', year: 'numeric' },\n precise: {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: 3,\n },\n timePrecise: { hour: 'numeric', minute: '2-digit', second: '2-digit', fractionalSecondDigits: 3 },\n} satisfies Record<string, Intl.DateTimeFormatOptions>;\n\ntype FormatterKey = keyof typeof PRESET_OPTIONS;\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\nfunction getFormatter(key: FormatterKey, locale?: string, timeZone?: string) {\n const cacheKey = `${locale ?? ''}|${timeZone ?? ''}|${key}`;\n let formatter = formatters.get(cacheKey);\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...PRESET_OPTIONS[key], timeZone });\n formatters.set(cacheKey, formatter);\n }\n return formatter;\n}\n\nfunction calendarDate(date: Date, timeZone?: string) {\n const parts = getFormatter('calendar', 'en-US', timeZone).formatToParts(date);\n return {\n year: parts.find(part => part.type === 'year')?.value,\n month: parts.find(part => part.type === 'month')?.value,\n day: parts.find(part => part.type === 'day')?.value,\n };\n}\n\n/** Short absolute date without time: `Sep 24` this year, `Sep 24, 2025` otherwise. */\nexport function formatShortDate(value: DateInput, { locale, now, timeZone }: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const reference = new Date(now ?? Date.now());\n const key =\n calendarDate(date, timeZone).year === calendarDate(reference, timeZone).year ? 'dayMonth' : 'dayMonthYear';\n return getFormatter(key, locale, timeZone).format(date);\n}\n\nconst LONG_RELATIVE_UNITS: Array<[Intl.RelativeTimeFormatUnit, number]> = [\n ['year', 365 * 86_400],\n ['month', 30 * 86_400],\n ['week', 7 * 86_400],\n ['day', 86_400],\n ['hour', 3_600],\n ['minute', 60],\n];\n\nconst relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();\n\nfunction getRelativeFormatter(locale?: string) {\n const key = locale ?? '';\n let formatter = relativeFormatters.get(key);\n if (!formatter) {\n formatter = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n relativeFormatters.set(key, formatter);\n }\n return formatter;\n}\n\n/**\n * Uses the browser locale unless `locale` is given.\n * - `date`: date only; omits the year when it matches `now` in the requested timezone\n * - `date-time`: date, year and time to minutes, including historical dates\n * - `date-time-seconds`: date, year and time to seconds\n * - `day-time-seconds`: month, day and time to seconds, without the year\n * - `time`: time to minutes, without a date\n * - `time-seconds`: time to seconds, without a date\n * - `relative-time`: short relative label; delegates to `date` at seven days\n */\nexport function formatDate(value: DateInput, preset: DatePreset, options: FormatOptions = {}) {\n const date = toDate(value);\n if (!date) return undefined;\n const { locale, now, timeZone } = options;\n\n if (preset === 'relative-time') {\n const diff = date.getTime() - new Date(now ?? Date.now()).getTime();\n const abs = Math.abs(diff);\n if (abs < 5_000) return 'just now';\n const units = [\n { limit: 60_000, size: 1_000, unit: 's' },\n { limit: 3_600_000, size: 60_000, unit: 'm' },\n { limit: 86_400_000, size: 3_600_000, unit: 'h' },\n { limit: 7 * 86_400_000, size: 86_400_000, unit: 'd' },\n ];\n const match = units.find(({ limit }) => abs < limit);\n if (!match) return formatDate(date, 'date', options);\n const label = `${Math.floor(abs / match.size)}${match.unit}`;\n return diff < 0 ? `${label} ago` : `in ${label}`;\n }\n if (preset === 'relative-long') {\n const seconds = (date.getTime() - new Date(now ?? Date.now()).getTime()) / 1000;\n const [unit, size] = LONG_RELATIVE_UNITS.find(([, size]) => Math.abs(seconds) >= size) ?? ['second', 1];\n return getRelativeFormatter(locale).format(Math.round(seconds / size), unit);\n }\n if (preset === 'date') return formatShortDate(date, options);\n\n return getFormatter(preset, locale, timeZone).format(date);\n}\n\n/** Locale-aware compact date range, e.g. `Sep 2 – 5, 2026`. */\nexport function formatDateRange(start: DateInput, end: DateInput, options: Omit<FormatOptions, 'now'> = {}) {\n const from = toDate(start);\n const to = toDate(end);\n if (!from || !to) return undefined;\n return getFormatter('dayMonthYear', options.locale, options.timeZone)\n .formatRange(from, to)\n .replace(/\\u2009/g, ' ');\n}\n\n/** Date and time down to milliseconds, for trace debugging. `withDate: false` keeps only the time. */\nexport function formatTimestampPrecise(\n value: DateInput,\n { locale, withDate = true }: { locale?: string; withDate?: boolean } = {},\n) {\n const date = toDate(value);\n return date ? getFormatter(withDate ? 'precise' : 'timePrecise', locale).format(date) : undefined;\n}\n","import { formatDate, formatShortDate } from '../shared/date-format';\n\nexport type MetricsInterval = '1h' | '1d';\n\nconst HOURLY_MAX_RANGE_MS = 48 * 60 * 60 * 1000;\n\n/** Hourly buckets up to 48h, daily buckets beyond, so long ranges stay readable. */\nexport function chooseMetricsInterval({ start, end }: { start: Date; end: Date }): MetricsInterval {\n return end.getTime() - start.getTime() <= HOURLY_MAX_RANGE_MS ? '1h' : '1d';\n}\n\nexport function formatMetricsBucketLabel(ts: Date, interval: MetricsInterval): string {\n if (interval === '1h') {\n return formatDate(ts, 'time') ?? '';\n }\n return formatShortDate(ts) ?? '';\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Resources — number of distinct resource IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveResourcesKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-resources-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'resourceId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Active Threads — number of distinct thread IDs observed in agent runs.\n * Uses approximate `count_distinct` (HyperLogLog on ClickHouse,\n * `approx_count_distinct` on DuckDB) so the query stays fast even on\n * tens of millions of rows. */\nexport function useActiveThreadsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'active-threads-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { MastraClient } from '@mastra/client-js';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Agent Runs — count of agent duration metric observations */\nexport function useAgentRunsKpiMetrics<TData = Awaited<ReturnType<MastraClient['getMetricAggregate']>>>(\n params: MetricsQueryFilters & {\n queryOptions?: MastraQueryOptions<Awaited<ReturnType<MastraClient['getMetricAggregate']>>, TData>;\n },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'agent-runs-kpi', filterKey],\n queryFn: () =>\n client.getMetricAggregate({\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n filters,\n comparePeriod: 'previous_period',\n }),\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface LatencyPoint {\n [key: string]: unknown;\n time: string;\n /** Raw timestamp (ms since epoch) for the bucket this point represents.\n * Used by drilldown clicks to compute a narrow time window. */\n tsMs: number;\n p50: number;\n p95: number;\n}\n\nasync function fetchPercentiles(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n interval: MetricsInterval,\n): Promise<LatencyPoint[]> {\n const res = await client.getMetricPercentiles({\n name: metricName,\n percentiles: [0.5, 0.95],\n interval,\n filters,\n });\n\n const p50Series = res.series.find(s => s.percentile === 0.5);\n const p95Series = res.series.find(s => s.percentile === 0.95);\n\n if (!p50Series || !p95Series) return [];\n\n const p95Map = new Map(p95Series.points.map(p => [new Date(p.timestamp).getTime(), p.value]));\n\n return p50Series.points.map(p => {\n const ts = new Date(p.timestamp);\n const tsMs = ts.getTime();\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs,\n p50: Math.round(p.value),\n p95: Math.round(p95Map.get(tsMs) ?? 0),\n };\n });\n}\n\nexport interface LatencyMetricsData {\n agentData: LatencyPoint[];\n workflowData: LatencyPoint[];\n toolData: LatencyPoint[];\n interval: MetricsInterval;\n}\n\nexport function useLatencyMetrics<TData = LatencyMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<LatencyMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'latency', filterKey, interval],\n queryFn: async (): Promise<LatencyMetricsData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchPercentiles(client, 'mastra_agent_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_workflow_duration_ms', filters, interval),\n fetchPercentiles(client, 'mastra_tool_duration_ms', filters, interval),\n ]);\n return { agentData, workflowData, toolData, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Model Cost — sum of estimatedCost across input and output token metrics */\nexport interface ModelCostKpi {\n cost: number | null;\n costUnit: string | null;\n previousCost: number | null;\n costChangePercent: number | null;\n}\n\nexport function useModelCostKpiMetrics<TData = ModelCostKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelCostKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-cost-kpi', filterKey],\n queryFn: async (): Promise<ModelCostKpi> => {\n const res = await client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens', 'mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n });\n\n return {\n cost: res.estimatedCost ?? null,\n costUnit: res.costUnit ?? null,\n previousCost: res.previousEstimatedCost ?? null,\n costChangePercent: res.costChangePercent ?? null,\n };\n },\n ...queryOptions,\n });\n}\n","export interface CompactNumberFormatOptions {\n currency?: string;\n}\n\nconst compactNumber = new Intl.NumberFormat('en-US', { notation: 'compact', maximumSignificantDigits: 3 });\nconst fullNumber = new Intl.NumberFormat('en-US');\n\nconst currencyCodes = new Set(Intl.supportedValuesOf('currency'));\n\nfunction isCurrency(code: string | undefined): code is string {\n return code !== undefined && currencyCodes.has(code.toUpperCase());\n}\n\nfunction money(currency: string, options: Intl.NumberFormatOptions) {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency, ...options });\n}\n\nexport function formatCompactNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return compactNumber.format(value);\n const size = Math.abs(value);\n if (size < 100) return formatFullNumber(value, { currency });\n if (size < 1000) return money(currency, { maximumFractionDigits: 0 }).format(value);\n return money(currency, { notation: 'compact', maximumSignificantDigits: 3 }).format(value);\n}\n\nexport function formatFullNumber(value: number, { currency }: CompactNumberFormatOptions = {}): string {\n if (!isCurrency(currency)) return fullNumber.format(value);\n const formatter = money(currency, {});\n const smallestUnit = 10 ** -(formatter.resolvedOptions().maximumFractionDigits ?? 2);\n if (value !== 0 && Math.abs(value) < smallestUnit) {\n return `${value < 0 ? '-' : ''}<${formatter.format(smallestUnit)}`;\n }\n return formatter.format(value);\n}\n\nexport function formatCost(value: number, unit?: string | null): string {\n const isUsd = !unit || unit.toLowerCase() === 'usd';\n const amount = value > 0 && value < 0.01 ? '<0.01' : value.toFixed(2);\n if (!isUsd) return `${amount} ${unit}`;\n return amount.startsWith('<') ? '<$0.01' : `$${amount}`;\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatCompactNumber } from '../shared/cost';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ModelUsageRow {\n model: string;\n provider?: string;\n input: string;\n output: string;\n cacheRead: string;\n cacheWrite: string;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useModelUsageCostMetrics<TData = ModelUsageRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ModelUsageRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'model-usage-cost', filterKey],\n queryFn: async (): Promise<ModelUsageRow[]> => {\n const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all(\n (\n [\n 'mastra_model_total_input_tokens',\n 'mastra_model_total_output_tokens',\n 'mastra_model_input_cache_read_tokens',\n 'mastra_model_input_cache_write_tokens',\n ] as const\n ).map(name =>\n client.getMetricBreakdown({\n name: [name],\n groupBy: ['model', 'provider'],\n aggregation: 'sum',\n orderDirection: 'DESC',\n filters,\n }),\n ),\n );\n\n if (!inputRes || !outputRes || !cacheReadRes || !cacheWriteRes) return [];\n\n type ModelEntry = {\n model: string;\n provider: string | undefined;\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number | null;\n costUnit: string | null;\n };\n\n const modelMap = new Map<string, ModelEntry>();\n\n const ensureModel = (dimensions: { model?: string | null; provider?: string | null }): ModelEntry => {\n const model = dimensions.model ?? 'unknown';\n const provider = dimensions.provider ?? undefined;\n return getOrCreate(modelMap, `${model}\\u0000${provider ?? ''}`, () => ({\n model,\n provider,\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n cost: null,\n costUnit: null,\n }));\n };\n\n // total_input/total_output estimatedCost already rolls up cache + other detail\n // costs. The cache breakdowns are kept for their token counts only.\n const addCost = (entry: ModelEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.output = group.value;\n addCost(entry, group);\n }\n for (const group of cacheReadRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheRead = group.value;\n }\n for (const group of cacheWriteRes.groups) {\n const entry = ensureModel(group.dimensions);\n entry.cacheWrite = group.value;\n }\n\n return Array.from(modelMap.values())\n .map(vals => ({\n model: vals.model,\n ...(vals.provider ? { provider: vals.provider } : {}),\n input: formatCompactNumber(vals.input),\n output: formatCompactNumber(vals.output),\n cacheRead: formatCompactNumber(vals.cacheRead),\n cacheWrite: formatCompactNumber(vals.cacheWrite),\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => a.model.localeCompare(b.model) || (a.provider ?? '').localeCompare(b.provider ?? ''));\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { formatDate } from '../shared/date-format';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ScorerSummary {\n scorer: string;\n avg: number;\n min: number;\n max: number;\n count: number;\n}\n\nexport interface ScoresOverTimePoint {\n time: string;\n [scorer: string]: string | number;\n}\n\nexport interface ScoresMetricsData {\n summaryData: ScorerSummary[];\n overTimeData: ScoresOverTimePoint[];\n scorerNames: string[];\n avgScore: number | null;\n}\n\nexport function useScoresMetrics<TData = ScoresMetricsData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ScoresMetricsData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { datePreset, customRange, timestamp, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'scores-card', datePreset, customRange],\n queryFn: async (): Promise<ScoresMetricsData> => {\n const filters = {\n timestamp: { start: timestamp.start, end: timestamp.end },\n };\n\n const scorersMap = await client.listScorers();\n const scorerIds = Object.keys(scorersMap ?? {});\n\n if (scorerIds.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n // Fetch summary stats first to determine which scorers have data\n const summaryResults = await Promise.all(\n scorerIds.map(async scorerId => {\n const [avg, min, max, count] = await Promise.all([\n client.getScoreAggregate({ scorerId, aggregation: 'avg', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'min', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'max', filters }),\n client.getScoreAggregate({ scorerId, aggregation: 'count', filters }),\n ]);\n return {\n scorer: scorerId,\n avg: avg.value ?? 0,\n min: min.value ?? 0,\n max: max.value ?? 0,\n count: count.value ?? 0,\n };\n }),\n );\n\n const summaryData: ScorerSummary[] = summaryResults.filter(s => s.count > 0);\n const scorerNames = summaryData.map(s => s.scorer);\n\n if (summaryData.length === 0) {\n return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };\n }\n\n const totalWeighted = summaryData.reduce((s, d) => s + d.avg * d.count, 0);\n const totalCount = summaryData.reduce((s, d) => s + d.count, 0);\n const avgScore = totalCount ? Math.round((totalWeighted / totalCount) * 100) / 100 : 0;\n\n const interval = '1h';\n\n // Fetch hourly time series from the full period for active scorers\n const timeSeriesResults = await Promise.all(\n scorerNames.map(scorerId =>\n client.getScoreTimeSeries({\n scorerId,\n interval,\n aggregation: 'avg',\n filters,\n }),\n ),\n );\n\n // Collapse all days into a single 24-hour view (00:00–23:00).\n // For each hour-of-day, average the values across all days in the range.\n const hourBuckets = new Map<number, Map<string, { sum: number; count: number }>>();\n\n for (let i = 0; i < scorerNames.length; i++) {\n const scorerId = scorerNames[i];\n const series = timeSeriesResults[i]?.series ?? [];\n for (const s of series) {\n for (const point of s.points) {\n const ts = new Date(point.timestamp);\n const hourKey = ts.getHours() * 60 + ts.getMinutes();\n const scorerMap = getOrCreate(hourBuckets, hourKey, () => new Map());\n const acc = getOrCreate(scorerMap, scorerId, () => ({ sum: 0, count: 0 }));\n\n acc.sum += point.value;\n acc.count += 1;\n }\n }\n }\n\n // Build sorted 24h chart data\n const overTimeData: ScoresOverTimePoint[] = Array.from(hourBuckets.entries())\n .sort(([a], [b]) => a - b)\n .map(([hourKey, scorerMap]) => {\n const point: ScoresOverTimePoint = {\n time: formatDate(new Date(2000, 0, 1, Math.floor(hourKey / 60), hourKey % 60), 'time') ?? '',\n };\n for (const [scorerId, acc] of scorerMap) {\n point[scorerId] = +(acc.sum / acc.count).toFixed(2);\n }\n return point;\n });\n\n return {\n summaryData,\n overTimeData,\n scorerNames,\n avgScore,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface TokenUsageByAgentRow {\n name: string;\n total: number;\n input: number;\n output: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport function useTokenUsageByAgentMetrics<TData = TokenUsageByAgentRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageByAgentRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-by-agent', filterKey],\n queryFn: async (): Promise<TokenUsageByAgentRow[]> => {\n const breakdownBase = {\n groupBy: ['entityName'],\n aggregation: 'sum' as const,\n orderDirection: 'DESC' as const,\n filters,\n };\n // total_input/total_output estimatedCost already rolls up cache + other detail costs.\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_input_tokens'] }),\n client.getMetricBreakdown({ ...breakdownBase, name: ['mastra_model_total_output_tokens'] }),\n ]);\n\n type AgentEntry = { input: number; output: number; cost: number | null; costUnit: string | null };\n\n const agentMap = new Map<string, AgentEntry>();\n\n const ensure = (name: string): AgentEntry =>\n getOrCreate(agentMap, name, () => ({ input: 0, output: 0, cost: null, costUnit: null }));\n\n const addCost = (entry: AgentEntry, group: { estimatedCost?: number | null; costUnit?: string | null }) => {\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n };\n\n for (const group of inputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.input = group.value;\n addCost(entry, group);\n }\n for (const group of outputRes.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const entry = ensure(name);\n entry.output = group.value;\n addCost(entry, group);\n }\n\n return Array.from(agentMap.entries())\n .map(([name, vals]) => ({\n name,\n input: vals.input,\n output: vals.output,\n total: vals.input + vals.output,\n cost: vals.cost,\n costUnit: vals.costUnit,\n }))\n .sort((a, b) => b.total - a.total);\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport { chooseMetricsInterval, formatMetricsBucketLabel } from './metrics-interval';\nimport type { MetricsInterval } from './metrics-interval';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport type TokenUsageTimeSeriesInterval = MetricsInterval;\n\nexport interface TokenTimelinePoint {\n time: string;\n tsMs: number;\n input: number;\n output: number;\n total: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nexport interface TokenUsageTimeSeriesData {\n data: TokenTimelinePoint[];\n interval: TokenUsageTimeSeriesInterval;\n}\n\ntype TimeSeriesPoint = {\n timestamp: string | Date;\n value: number;\n estimatedCost?: number | null;\n};\n\ntype SeriesWithCost = {\n costUnit?: string | null;\n points: TimeSeriesPoint[];\n};\n\ntype TokenTimelineAccumulator = {\n tsMs: number;\n input: number;\n output: number;\n cost: number | null;\n costUnits: Set<string>;\n hasUnknownCostUnit: boolean;\n};\n\nfunction addSeriesPoints(\n pointMap: Map<number, TokenTimelineAccumulator>,\n series: SeriesWithCost | undefined,\n key: 'input' | 'output',\n) {\n for (const point of series?.points ?? []) {\n const tsMs = new Date(point.timestamp).getTime();\n if (!Number.isFinite(tsMs)) continue;\n\n const existing = pointMap.get(tsMs) ?? {\n tsMs,\n input: 0,\n output: 0,\n cost: null,\n costUnits: new Set<string>(),\n hasUnknownCostUnit: false,\n };\n\n existing[key] += point.value;\n\n if (point.estimatedCost != null) {\n existing.cost = (existing.cost ?? 0) + point.estimatedCost;\n if (series?.costUnit) {\n existing.costUnits.add(series.costUnit);\n } else {\n existing.hasUnknownCostUnit = true;\n }\n }\n\n pointMap.set(tsMs, existing);\n }\n}\n\nfunction toCostUnit(entry: TokenTimelineAccumulator): string | null {\n if (entry.cost == null || entry.hasUnknownCostUnit || entry.costUnits.size !== 1) return null;\n return [...entry.costUnits][0] ?? null;\n}\n\nexport function useTokenUsageTimeSeries<TData = TokenUsageTimeSeriesData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TokenUsageTimeSeriesData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { timestamp, filters, filterKey, queryOptions } = params;\n const interval = chooseMetricsInterval(timestamp);\n\n return useQuery({\n queryKey: ['metrics', 'token-usage-timeseries', filterKey, interval],\n queryFn: async (): Promise<TokenUsageTimeSeriesData> => {\n const [inputRes, outputRes] = await Promise.all([\n client.getMetricTimeSeries({\n name: ['mastra_model_total_input_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n client.getMetricTimeSeries({\n name: ['mastra_model_total_output_tokens'],\n interval,\n aggregation: 'sum',\n filters,\n }),\n ]);\n\n const pointMap = new Map<number, TokenTimelineAccumulator>();\n addSeriesPoints(pointMap, inputRes.series[0], 'input');\n addSeriesPoints(pointMap, outputRes.series[0], 'output');\n\n const data = Array.from(pointMap.values())\n .sort((a, b) => a.tsMs - b.tsMs)\n .map(point => {\n const ts = new Date(point.tsMs);\n return {\n time: formatMetricsBucketLabel(ts, interval),\n tsMs: point.tsMs,\n input: point.input,\n output: point.output,\n total: point.input + point.output,\n cost: point.cost,\n costUnit: toCostUnit(point),\n };\n });\n\n return { data, interval };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ActiveThreadRow {\n threadId: string;\n resourceId: string | null;\n runs: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Active Threads — the threads with the most agent runs in the selected\n * range. Server-side TopK (`ORDER BY value DESC LIMIT 20`) is required so the\n * query never returns the full thread set when cardinality is in the millions.\n *\n * Tokens + cost are joined in from parallel breakdowns on the same `threadId`\n * grouping so we don't need any new backend aggregation support. */\nexport function useTopActiveThreadsMetrics<TData = ActiveThreadRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ActiveThreadRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-active-threads', filterKey],\n queryFn: async (): Promise<ActiveThreadRow[]> => {\n const breakdownBase = {\n groupBy: ['threadId', 'resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [runsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count',\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying thread set has very\n // high cardinality. Threads that are top-N by runs but not by tokens\n // will display 0 tokens (an acceptable approximation in exchange for\n // a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byThread = new Map<string, Entry>();\n\n const ensure = (threadId: string): Entry =>\n getOrCreate(byThread, threadId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const threadId = group.dimensions.threadId;\n if (!threadId) continue;\n const entry = ensure(threadId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return runsRes.groups\n .filter(group => !!group.dimensions.threadId)\n .map(group => {\n const threadId = group.dimensions.threadId as string;\n const extra = byThread.get(threadId);\n return {\n threadId,\n resourceId: (group.dimensions.resourceId as string | undefined) ?? null,\n runs: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\n\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface ResourceThreadsRow {\n resourceId: string;\n threadCount: number;\n tokens: number;\n cost: number | null;\n costUnit: string | null;\n}\n\nconst TOP_N = 20;\n\n/** Top Resources by Thread Count — the resources with the most distinct threads\n * in the selected range. Uses `count_distinct(threadId)` per `resourceId`,\n * with server-side TopK (`ORDER BY value DESC LIMIT 20`).\n *\n * Tokens + cost are joined in from parallel breakdowns on `resourceId` so the\n * table can show cost/usage without a separate backend aggregation. */\nexport function useTopResourcesByThreadsMetrics<TData = ResourceThreadsRow[]>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<ResourceThreadsRow[], TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'top-resources-by-threads', filterKey],\n queryFn: async (): Promise<ResourceThreadsRow[]> => {\n const breakdownBase = {\n groupBy: ['resourceId'],\n orderDirection: 'DESC' as const,\n filters,\n };\n\n const [threadsRes, inputRes, outputRes] = await Promise.all([\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_agent_duration_ms'],\n aggregation: 'count_distinct',\n distinctColumn: 'threadId' as never,\n limit: TOP_N,\n }),\n // Token breakdowns use the same groupBy and a server-side TopK so the\n // response stays bounded even when the underlying resource set has very\n // high cardinality. Resources that are top-N by thread count but not by\n // tokens will display 0 tokens (an acceptable approximation in exchange\n // for a bounded query).\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n client.getMetricBreakdown({\n ...breakdownBase,\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n limit: TOP_N,\n }),\n ]);\n\n type Entry = { tokens: number; cost: number | null; costUnit: string | null };\n const byResource = new Map<string, Entry>();\n\n const ensure = (resourceId: string): Entry =>\n getOrCreate(byResource, resourceId, () => ({ tokens: 0, cost: null, costUnit: null }));\n\n const foldTokens = (groups: typeof inputRes.groups) => {\n for (const group of groups) {\n const resourceId = group.dimensions.resourceId;\n if (!resourceId) continue;\n const entry = ensure(resourceId as string);\n entry.tokens += group.value;\n if (group.estimatedCost != null) {\n entry.cost = (entry.cost ?? 0) + group.estimatedCost;\n if (group.costUnit) entry.costUnit = group.costUnit;\n }\n }\n };\n foldTokens(inputRes.groups);\n foldTokens(outputRes.groups);\n\n return threadsRes.groups\n .filter(group => !!group.dimensions.resourceId)\n .map(group => {\n const resourceId = group.dimensions.resourceId as string;\n const extra = byResource.get(resourceId);\n return {\n resourceId,\n threadCount: group.value,\n tokens: extra?.tokens ?? 0,\n cost: extra?.cost ?? null,\n costUnit: extra?.costUnit ?? null,\n };\n });\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\n/** Total Tokens — sum of all input + output tokens */\nexport interface TotalTokensKpi {\n value: number | null;\n previousValue: number | null;\n changePercent: number | null;\n}\n\nexport function useTotalTokensKpiMetrics<TData = TotalTokensKpi>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TotalTokensKpi, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'total-tokens-kpi', filterKey],\n queryFn: async (): Promise<TotalTokensKpi> => {\n const [input, output] = await Promise.all([\n client.getMetricAggregate({\n name: ['mastra_model_total_input_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n client.getMetricAggregate({\n name: ['mastra_model_total_output_tokens'],\n aggregation: 'sum',\n filters,\n comparePeriod: 'previous_period',\n }),\n ]);\n\n const hasCurrent = input.value != null || output.value != null;\n const hasPrevious = input.previousValue != null || output.previousValue != null;\n const value = (input.value ?? 0) + (output.value ?? 0);\n const previousValue = (input.previousValue ?? 0) + (output.previousValue ?? 0);\n const changePercent = hasPrevious && previousValue > 0 ? ((value - previousValue) / previousValue) * 100 : null;\n\n return {\n value: hasCurrent ? value : null,\n previousValue: hasPrevious ? previousValue : null,\n changePercent,\n };\n },\n ...queryOptions,\n });\n}\n","import type { UseQueryResult } from '@tanstack/react-query';\nimport { useQuery } from '@tanstack/react-query';\nimport { useMastraClient } from '../../mastra-client-context';\nimport { getOrCreate } from '../shared/map';\nimport type { MastraQueryOptions } from '../shared/query-options';\nimport type { MetricsQueryFilters } from './metrics-query-filters';\n\nexport interface VolumeRow {\n name: string;\n completed: number;\n errors: number;\n}\n\nasync function fetchVolume(\n client: ReturnType<typeof useMastraClient>,\n metricName: string,\n filters: Record<string, unknown>,\n): Promise<VolumeRow[]> {\n const res = await client.getMetricBreakdown({\n name: [metricName],\n groupBy: ['entityName', 'status'],\n aggregation: 'count',\n orderDirection: 'DESC',\n filters,\n });\n\n const map = new Map<string, { completed: number; errors: number }>();\n\n for (const group of res.groups) {\n const name = group.dimensions.entityName ?? 'unknown';\n const status = group.dimensions.status ?? 'ok';\n const entry = getOrCreate(map, name, () => ({ completed: 0, errors: 0 }));\n\n if (status === 'error') {\n entry.errors += group.value;\n } else {\n entry.completed += group.value;\n }\n }\n\n return Array.from(map.entries())\n .map(([name, vals]) => ({ name, ...vals }))\n .sort((a, b) => b.completed + b.errors - (a.completed + a.errors));\n}\n\nexport interface TraceVolumeData {\n agentData: VolumeRow[];\n workflowData: VolumeRow[];\n toolData: VolumeRow[];\n}\n\nexport function useTraceVolumeMetrics<TData = TraceVolumeData>(\n params: MetricsQueryFilters & { queryOptions?: MastraQueryOptions<TraceVolumeData, TData> },\n): UseQueryResult<TData, Error> {\n const client = useMastraClient();\n const { filters, filterKey, queryOptions } = params;\n\n return useQuery({\n queryKey: ['metrics', 'trace-volume', filterKey],\n queryFn: async (): Promise<TraceVolumeData> => {\n const [agentData, workflowData, toolData] = await Promise.all([\n fetchVolume(client, 'mastra_agent_duration_ms', filters),\n fetchVolume(client, 'mastra_workflow_duration_ms', filters),\n fetchVolume(client, 'mastra_tool_duration_ms', filters),\n ]);\n return { agentData, workflowData, toolData };\n },\n ...queryOptions,\n });\n}\n"],"mappings":"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"}