@mastra/playground-ui 19.0.0-alpha.2 → 19.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/dist/index.cjs.js +1259 -19
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +1237 -22
- package/dist/index.es.js.map +1 -1
- package/dist/src/domains/agents/components/agent-metadata/agent-metadata.d.ts +1 -0
- package/dist/src/domains/metrics/components/date-range-selector.d.ts +1 -0
- package/dist/src/domains/metrics/components/index.d.ts +28 -0
- package/dist/src/domains/metrics/components/latency-card.d.ts +1 -0
- package/dist/src/domains/metrics/components/metrics-dashboard.d.ts +1 -0
- package/dist/src/domains/metrics/components/metrics-kpi-cards.d.ts +4 -0
- package/dist/src/domains/metrics/components/metrics-utils.d.ts +14 -0
- package/dist/src/domains/metrics/components/model-usage-cost-card.d.ts +1 -0
- package/dist/src/domains/metrics/components/scores-card.d.ts +1 -0
- package/dist/src/domains/metrics/components/token-usage-by-agent-card.d.ts +1 -0
- package/dist/src/domains/metrics/components/traces-volume-card.d.ts +1 -0
- package/dist/src/domains/metrics/hooks/use-agent-runs-kpi-metrics.d.ts +10 -0
- package/dist/src/domains/metrics/hooks/use-avg-score-kpi-metrics.d.ts +10 -0
- package/dist/src/domains/metrics/hooks/use-latency-metrics.d.ts +11 -0
- package/dist/src/domains/metrics/hooks/use-metrics-filters.d.ts +9 -0
- package/dist/src/domains/metrics/hooks/use-metrics.d.ts +56 -0
- package/dist/src/domains/metrics/hooks/use-model-usage-cost-metrics.d.ts +8 -0
- package/dist/src/domains/metrics/hooks/use-scores-metrics.d.ts +22 -0
- package/dist/src/domains/metrics/hooks/use-token-usage-by-agent-metrics.d.ts +7 -0
- package/dist/src/domains/metrics/hooks/use-total-tokens-kpi-metrics.d.ts +6 -0
- package/dist/src/domains/metrics/hooks/use-trace-volume-metrics.d.ts +10 -0
- package/dist/src/domains/metrics/index.d.ts +1 -0
- package/dist/src/domains/workspace/hooks/use-workspace-skills.d.ts +5 -1
- package/dist/src/domains/workspace/types.d.ts +1 -1
- package/dist/src/ds/components/DashboardCard/dashboard-card.d.ts +6 -0
- package/dist/src/ds/components/DashboardCard/dashboard-card.stories.d.ts +8 -0
- package/dist/src/ds/components/DashboardCard/index.d.ts +1 -0
- package/dist/src/ds/components/EntityList/entity-list-no-match.d.ts +5 -0
- package/dist/src/ds/components/EntityList/entity-list.d.ts +2 -0
- package/dist/src/ds/components/HorizontalBars/horizontal-bars.d.ts +15 -0
- package/dist/src/ds/components/HorizontalBars/horizontal-bars.stories.d.ts +7 -0
- package/dist/src/ds/components/HorizontalBars/index.d.ts +1 -0
- package/dist/src/ds/components/MetricsCard/index.d.ts +2 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-content.d.ts +5 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-description.d.ts +4 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-error.d.ts +4 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-loading.d.ts +3 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-no-data.d.ts +4 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-root.d.ts +5 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-summary.d.ts +5 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-title-and-description.d.ts +15 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-title.d.ts +4 -0
- package/dist/src/ds/components/MetricsCard/metrics-card-top-bar.d.ts +5 -0
- package/dist/src/ds/components/MetricsCard/metrics-card.d.ts +31 -0
- package/dist/src/ds/components/MetricsCard/metrics-card.stories.d.ts +11 -0
- package/dist/src/ds/components/MetricsDataTable/index.d.ts +1 -0
- package/dist/src/ds/components/MetricsDataTable/metrics-data-table.d.ts +13 -0
- package/dist/src/ds/components/MetricsDataTable/metrics-data-table.stories.d.ts +16 -0
- package/dist/src/ds/components/MetricsFlexGrid/index.d.ts +1 -0
- package/dist/src/ds/components/MetricsFlexGrid/metrics-flex-grid.d.ts +5 -0
- package/dist/src/ds/components/MetricsFlexGrid/metrics-flex-grid.stories.d.ts +7 -0
- package/dist/src/ds/components/MetricsKpiCard/index.d.ts +1 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-change.d.ts +6 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-error.d.ts +4 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-label.d.ts +4 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-loading.d.ts +3 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-no-change.d.ts +4 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-no-data.d.ts +4 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-root.d.ts +5 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card-value.d.ts +4 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card.d.ts +17 -0
- package/dist/src/ds/components/MetricsKpiCard/metrics-kpi-card.stories.d.ts +10 -0
- package/dist/src/ds/components/MetricsLineChart/index.d.ts +2 -0
- package/dist/src/ds/components/MetricsLineChart/metrics-line-chart-tooltip.d.ts +10 -0
- package/dist/src/ds/components/MetricsLineChart/metrics-line-chart.d.ts +15 -0
- package/dist/src/ds/components/Tabs/tabs-list.d.ts +2 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/lib/framework.d.ts +3 -3
- package/package.json +11 -10
package/dist/index.cjs.js
CHANGED
|
@@ -70,6 +70,7 @@ const semver = require('semver');
|
|
|
70
70
|
const DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
|
|
71
71
|
const features = require('@mastra/core/features');
|
|
72
72
|
const observability = require('@mastra/core/observability');
|
|
73
|
+
const recharts = require('recharts');
|
|
73
74
|
const Papa = require('papaparse');
|
|
74
75
|
const reactDom = require('react-dom');
|
|
75
76
|
const isToday = require('date-fns/isToday');
|
|
@@ -12612,6 +12613,10 @@ function EntityListDescriptionCell({ children, className }) {
|
|
|
12612
12613
|
return /* @__PURE__ */ jsxRuntime.jsx(EntityListCell, { className: cn("text-neutral2", className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children }) });
|
|
12613
12614
|
}
|
|
12614
12615
|
|
|
12616
|
+
function EntityListNoMatch({ message = "Nothing matches your search", className }) {
|
|
12617
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("col-span-full flex flex-col items-center justify-center gap-2 py-12 text-neutral3", className), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-md", children: message }) });
|
|
12618
|
+
}
|
|
12619
|
+
|
|
12615
12620
|
function EntityListRoot({ children, columns, className }) {
|
|
12616
12621
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12617
12622
|
"div",
|
|
@@ -12723,7 +12728,8 @@ const EntityList = Object.assign(EntityListRoot, {
|
|
|
12723
12728
|
Cell: EntityListCell,
|
|
12724
12729
|
TextCell: EntityListTextCell,
|
|
12725
12730
|
NameCell: EntityListNameCell,
|
|
12726
|
-
DescriptionCell: EntityListDescriptionCell
|
|
12731
|
+
DescriptionCell: EntityListDescriptionCell,
|
|
12732
|
+
NoMatch: EntityListNoMatch
|
|
12727
12733
|
});
|
|
12728
12734
|
|
|
12729
12735
|
const widths$2 = ["75%", "50%", "65%", "90%", "60%", "80%"];
|
|
@@ -12797,6 +12803,7 @@ function WorkflowsList({ workflows, isLoading, error, search = "" }) {
|
|
|
12797
12803
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { children: "Description" }),
|
|
12798
12804
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { children: "Number of steps" })
|
|
12799
12805
|
] }),
|
|
12806
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Workflows match your search" }) : null,
|
|
12800
12807
|
filteredData.map((wf) => {
|
|
12801
12808
|
const name = truncateString(wf.name, 50);
|
|
12802
12809
|
const description = truncateString(wf.description ?? "", 200);
|
|
@@ -13033,7 +13040,7 @@ const Tabs = ({ children, defaultTab, value, onValueChange, className }) => {
|
|
|
13033
13040
|
return /* @__PURE__ */ jsxRuntime.jsx(RadixTabs__namespace.Root, { value: currentTab, onValueChange: handleTabChange, className: cn("overflow-y-auto", className), children });
|
|
13034
13041
|
};
|
|
13035
13042
|
|
|
13036
|
-
const TabList = ({ children, variant = "default", className }) => {
|
|
13043
|
+
const TabList = ({ children, variant = "default", alignment = "left", className }) => {
|
|
13037
13044
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13038
13045
|
RadixTabs__namespace.List,
|
|
13039
13046
|
{
|
|
@@ -13042,7 +13049,8 @@ const TabList = ({ children, variant = "default", className }) => {
|
|
|
13042
13049
|
{
|
|
13043
13050
|
// variant: default
|
|
13044
13051
|
"text-ui-lg": variant === "default",
|
|
13045
|
-
"[&>button]:py-2 [&>button]:px-6 [&>button]:font-normal [&>button]:text-neutral3 [&>button]:
|
|
13052
|
+
"[&>button]:py-2 [&>button]:px-6 [&>button]:font-normal [&>button]:text-neutral3 [&>button]:border-b [&>button]:border-border1": variant === "default",
|
|
13053
|
+
"[&>button]:flex-1": variant === "default" && alignment === "full-width",
|
|
13046
13054
|
[`[&>button]:${transitions.colors} [&>button]:hover:text-neutral4`]: variant === "default",
|
|
13047
13055
|
"[&>button[data-state=active]]:text-neutral5 [&>button[data-state=active]]:border-white/50": variant === "default",
|
|
13048
13056
|
// variant: buttons
|
|
@@ -19990,6 +19998,7 @@ function ScorersList({ scorers, isLoading, error, search = "" }) {
|
|
|
19990
19998
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Agents" }),
|
|
19991
19999
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Workflows" })
|
|
19992
20000
|
] }),
|
|
20001
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Scorers match your search" }) : null,
|
|
19993
20002
|
filteredData.map((scorer) => {
|
|
19994
20003
|
const name = truncateString(scorer.scorer.config?.name ?? scorer.id, 50);
|
|
19995
20004
|
const description = truncateString(scorer.scorer.config?.description ?? "", 200);
|
|
@@ -22026,9 +22035,16 @@ const AgentMetadataSkillList = ({ skills, agentId, workspaceId }) => {
|
|
|
22026
22035
|
}
|
|
22027
22036
|
);
|
|
22028
22037
|
return /* @__PURE__ */ jsxRuntime.jsx(AgentMetadataListItem, { children: isActivated ? /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
22029
|
-
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22038
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22039
|
+
Link,
|
|
22040
|
+
{
|
|
22041
|
+
href: paths.agentSkillLink(agentId, skill.name, skill.path, workspaceId),
|
|
22042
|
+
"data-testid": "skill-badge",
|
|
22043
|
+
children: badge
|
|
22044
|
+
}
|
|
22045
|
+
) }),
|
|
22030
22046
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { className: "bg-surface3 text-neutral6 border border-border1", children: "Active" })
|
|
22031
|
-
] }) }) : /* @__PURE__ */ jsxRuntime.jsx(Link, { href: paths.agentSkillLink(agentId, skill.name, workspaceId), "data-testid": "skill-badge", children: badge }) }, skill.
|
|
22047
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsx(Link, { href: paths.agentSkillLink(agentId, skill.name, skill.path, workspaceId), "data-testid": "skill-badge", children: badge }) }, skill.path);
|
|
22032
22048
|
}) });
|
|
22033
22049
|
};
|
|
22034
22050
|
function formatWorkspaceToolName(toolName) {
|
|
@@ -22767,6 +22783,8 @@ const AgentMemoryConfig = ({ agentId }) => {
|
|
|
22767
22783
|
};
|
|
22768
22784
|
|
|
22769
22785
|
const formatTokens = (n) => {
|
|
22786
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
22787
|
+
if (n >= 1e5) return `${(n / 1e3).toFixed(0)}k`;
|
|
22770
22788
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
|
|
22771
22789
|
return Math.round(n).toString();
|
|
22772
22790
|
};
|
|
@@ -22774,6 +22792,11 @@ const getBarColor = (percentage) => {
|
|
|
22774
22792
|
if (percentage >= 60) return "bg-blue-500";
|
|
22775
22793
|
return "bg-green-500";
|
|
22776
22794
|
};
|
|
22795
|
+
const getModelLabel = (model, modelRouting) => {
|
|
22796
|
+
if (typeof model === "string") return model;
|
|
22797
|
+
if (modelRouting?.length) return "Auto (tiered)";
|
|
22798
|
+
return void 0;
|
|
22799
|
+
};
|
|
22777
22800
|
const useElapsedTime = (isActive) => {
|
|
22778
22801
|
const [elapsed, setElapsed] = React.useState(0);
|
|
22779
22802
|
const startTimeRef = React.useRef(null);
|
|
@@ -22800,6 +22823,7 @@ const ProgressBar = ({
|
|
|
22800
22823
|
label,
|
|
22801
22824
|
isActive = false,
|
|
22802
22825
|
model,
|
|
22826
|
+
modelRouting,
|
|
22803
22827
|
baseThreshold,
|
|
22804
22828
|
totalBudget
|
|
22805
22829
|
}) => {
|
|
@@ -22832,7 +22856,15 @@ const ProgressBar = ({
|
|
|
22832
22856
|
" ",
|
|
22833
22857
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-neutral5", children: model || "not configured" })
|
|
22834
22858
|
] }),
|
|
22835
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
22859
|
+
modelRouting?.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
22860
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-neutral4", children: "Routing:" }),
|
|
22861
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 pl-2 space-y-0.5", children: modelRouting.map((route) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-neutral5", children: [
|
|
22862
|
+
"≤",
|
|
22863
|
+
formatTokens(route.upTo),
|
|
22864
|
+
" → ",
|
|
22865
|
+
route.model
|
|
22866
|
+
] }, `${route.upTo}-${route.model}`)) })
|
|
22867
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
22836
22868
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-neutral4", children: "Threshold:" }),
|
|
22837
22869
|
" ",
|
|
22838
22870
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-neutral5", children: [
|
|
@@ -22953,8 +22985,16 @@ const AgentObservationalMemory = ({ agentId, resourceId, threadId }) => {
|
|
|
22953
22985
|
const history = omData?.history ?? [];
|
|
22954
22986
|
const omAgentConfig = configData?.config?.observationalMemory;
|
|
22955
22987
|
const recordConfig = record?.config;
|
|
22956
|
-
const
|
|
22957
|
-
const
|
|
22988
|
+
const observationModelRouting = recordConfig?.observationModelRouting ?? recordConfig?.observation?.routing ?? omAgentConfig?.observationModelRouting ?? omAgentConfig?.observation?.routing;
|
|
22989
|
+
const reflectionModelRouting = recordConfig?.reflectionModelRouting ?? recordConfig?.reflection?.routing ?? omAgentConfig?.reflectionModelRouting ?? omAgentConfig?.reflection?.routing;
|
|
22990
|
+
const observationModel = getModelLabel(
|
|
22991
|
+
recordConfig?.observationModel ?? recordConfig?.observation?.model ?? omAgentConfig?.observationModel ?? omAgentConfig?.model ?? omAgentConfig?.observation?.model,
|
|
22992
|
+
observationModelRouting
|
|
22993
|
+
);
|
|
22994
|
+
const reflectionModel = getModelLabel(
|
|
22995
|
+
recordConfig?.reflectionModel ?? recordConfig?.reflection?.model ?? omAgentConfig?.reflectionModel ?? omAgentConfig?.model ?? omAgentConfig?.reflection?.model,
|
|
22996
|
+
reflectionModelRouting
|
|
22997
|
+
);
|
|
22958
22998
|
const getThresholdValue = (threshold, defaultValue) => {
|
|
22959
22999
|
if (!threshold) return defaultValue;
|
|
22960
23000
|
if (typeof threshold === "number") return threshold;
|
|
@@ -23063,6 +23103,7 @@ const AgentObservationalMemory = ({ agentId, resourceId, threadId }) => {
|
|
|
23063
23103
|
label: "Messages",
|
|
23064
23104
|
isActive: isObserving,
|
|
23065
23105
|
model: observationModel,
|
|
23106
|
+
modelRouting: observationModelRouting,
|
|
23066
23107
|
baseThreshold: baseMessageTokens,
|
|
23067
23108
|
totalBudget
|
|
23068
23109
|
}
|
|
@@ -23076,6 +23117,7 @@ const AgentObservationalMemory = ({ agentId, resourceId, threadId }) => {
|
|
|
23076
23117
|
isActive: isReflecting,
|
|
23077
23118
|
baseThreshold: baseObservationTokens,
|
|
23078
23119
|
model: reflectionModel,
|
|
23120
|
+
modelRouting: reflectionModelRouting,
|
|
23079
23121
|
totalBudget
|
|
23080
23122
|
}
|
|
23081
23123
|
)
|
|
@@ -25119,6 +25161,7 @@ function PromptsList({ promptBlocks, isLoading, error, search = "" }) {
|
|
|
25119
25161
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Has Draft" }),
|
|
25120
25162
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Is Published" })
|
|
25121
25163
|
] }),
|
|
25164
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Prompts match your search" }) : null,
|
|
25122
25165
|
filteredData.map((block) => {
|
|
25123
25166
|
const name = truncateString(block.name, 50);
|
|
25124
25167
|
const description = truncateString(block.description ?? "", 200);
|
|
@@ -30627,7 +30670,7 @@ const useWorkspaceSkills = (options) => {
|
|
|
30627
30670
|
const useWorkspaceSkill = (skillName, options) => {
|
|
30628
30671
|
const client = react.useMastraClient();
|
|
30629
30672
|
return reactQuery.useQuery({
|
|
30630
|
-
queryKey: ["workspace", "skills", skillName, options?.workspaceId],
|
|
30673
|
+
queryKey: ["workspace", "skills", skillName, options?.path, options?.workspaceId],
|
|
30631
30674
|
queryFn: async () => {
|
|
30632
30675
|
if (!compatibility.isWorkspaceV1Supported(client)) {
|
|
30633
30676
|
throw new Error("Workspace v1 not supported by core or client");
|
|
@@ -30636,7 +30679,7 @@ const useWorkspaceSkill = (skillName, options) => {
|
|
|
30636
30679
|
throw new Error("workspaceId is required");
|
|
30637
30680
|
}
|
|
30638
30681
|
const workspace = client.getWorkspace(options.workspaceId);
|
|
30639
|
-
const skill = workspace.getSkill(skillName);
|
|
30682
|
+
const skill = workspace.getSkill(skillName, options?.path);
|
|
30640
30683
|
return skill.details();
|
|
30641
30684
|
},
|
|
30642
30685
|
enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && compatibility.isWorkspaceV1Supported(client),
|
|
@@ -30646,7 +30689,7 @@ const useWorkspaceSkill = (skillName, options) => {
|
|
|
30646
30689
|
const useWorkspaceSkillReferences = (skillName, options) => {
|
|
30647
30690
|
const client = react.useMastraClient();
|
|
30648
30691
|
return reactQuery.useQuery({
|
|
30649
|
-
queryKey: ["workspace", "skills", skillName, "references", options?.workspaceId],
|
|
30692
|
+
queryKey: ["workspace", "skills", skillName, options?.path, "references", options?.workspaceId],
|
|
30650
30693
|
queryFn: async () => {
|
|
30651
30694
|
if (!compatibility.isWorkspaceV1Supported(client)) {
|
|
30652
30695
|
throw new Error("Workspace v1 not supported by core or client");
|
|
@@ -30655,7 +30698,7 @@ const useWorkspaceSkillReferences = (skillName, options) => {
|
|
|
30655
30698
|
throw new Error("workspaceId is required");
|
|
30656
30699
|
}
|
|
30657
30700
|
const workspace = client.getWorkspace(options.workspaceId);
|
|
30658
|
-
const skill = workspace.getSkill(skillName);
|
|
30701
|
+
const skill = workspace.getSkill(skillName, options?.path);
|
|
30659
30702
|
return skill.listReferences();
|
|
30660
30703
|
},
|
|
30661
30704
|
enabled: options?.enabled !== false && !!skillName && !!options?.workspaceId && compatibility.isWorkspaceV1Supported(client),
|
|
@@ -30665,7 +30708,7 @@ const useWorkspaceSkillReferences = (skillName, options) => {
|
|
|
30665
30708
|
const useWorkspaceSkillReference = (skillName, referencePath, options) => {
|
|
30666
30709
|
const client = react.useMastraClient();
|
|
30667
30710
|
return reactQuery.useQuery({
|
|
30668
|
-
queryKey: ["workspace", "skills", skillName, "references", referencePath, options?.workspaceId],
|
|
30711
|
+
queryKey: ["workspace", "skills", skillName, options?.path, "references", referencePath, options?.workspaceId],
|
|
30669
30712
|
queryFn: async () => {
|
|
30670
30713
|
if (!compatibility.isWorkspaceV1Supported(client)) {
|
|
30671
30714
|
throw new Error("Workspace v1 not supported by core or client");
|
|
@@ -30674,7 +30717,7 @@ const useWorkspaceSkillReference = (skillName, referencePath, options) => {
|
|
|
30674
30717
|
throw new Error("workspaceId is required");
|
|
30675
30718
|
}
|
|
30676
30719
|
const workspace = client.getWorkspace(options.workspaceId);
|
|
30677
|
-
const skill = workspace.getSkill(skillName);
|
|
30720
|
+
const skill = workspace.getSkill(skillName, options?.path);
|
|
30678
30721
|
return skill.getReference(referencePath);
|
|
30679
30722
|
},
|
|
30680
30723
|
enabled: options?.enabled !== false && !!skillName && !!referencePath && !!options?.workspaceId && compatibility.isWorkspaceV1Supported(client),
|
|
@@ -30696,7 +30739,7 @@ const useSearchWorkspaceSkills = () => {
|
|
|
30696
30739
|
const useAgentSkill = (agentId, skillName, options) => {
|
|
30697
30740
|
const client = react.useMastraClient();
|
|
30698
30741
|
return reactQuery.useQuery({
|
|
30699
|
-
queryKey: ["agents", agentId, "skills", skillName, options?.workspaceId],
|
|
30742
|
+
queryKey: ["agents", agentId, "skills", skillName, options?.path, options?.workspaceId],
|
|
30700
30743
|
queryFn: async () => {
|
|
30701
30744
|
if (!compatibility.isWorkspaceV1Supported(client)) {
|
|
30702
30745
|
throw new Error("Workspace v1 not supported by core or client");
|
|
@@ -30705,7 +30748,7 @@ const useAgentSkill = (agentId, skillName, options) => {
|
|
|
30705
30748
|
throw new Error("workspaceId is required");
|
|
30706
30749
|
}
|
|
30707
30750
|
const workspace = client.getWorkspace(options.workspaceId);
|
|
30708
|
-
const skill = workspace.getSkill(skillName);
|
|
30751
|
+
const skill = workspace.getSkill(skillName, options?.path);
|
|
30709
30752
|
return skill.details();
|
|
30710
30753
|
},
|
|
30711
30754
|
enabled: options?.enabled !== false && !!agentId && !!skillName && !!options?.workspaceId && compatibility.isWorkspaceV1Supported(client),
|
|
@@ -39313,6 +39356,7 @@ function AgentsList({ agents, isLoading, error, search = "" }) {
|
|
|
39313
39356
|
}
|
|
39314
39357
|
)
|
|
39315
39358
|
] }),
|
|
39359
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Agents match your search" }) : null,
|
|
39316
39360
|
filteredData.map((agent) => {
|
|
39317
39361
|
const name = truncateString(agent.name, 50);
|
|
39318
39362
|
const instructions = truncateString(extractPrompt(agent.instructions), 200);
|
|
@@ -39584,6 +39628,7 @@ function ProcessorsList({ processors, isLoading, error, search = "" }) {
|
|
|
39584
39628
|
),
|
|
39585
39629
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCellSmart, { short: "Used by", long: "Used by Agents", className: "text-center" })
|
|
39586
39630
|
] }),
|
|
39631
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Processors match your search" }) : null,
|
|
39587
39632
|
filteredData.map((processor) => {
|
|
39588
39633
|
const name = truncateString(processor.name || processor.id, 50);
|
|
39589
39634
|
const description = truncateString(processor.description ?? "", 200);
|
|
@@ -40038,6 +40083,7 @@ function ToolsList({ tools, agents, isLoading, error, search = "" }) {
|
|
|
40038
40083
|
}
|
|
40039
40084
|
)
|
|
40040
40085
|
] }),
|
|
40086
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Tools match your search" }) : null,
|
|
40041
40087
|
filteredData.map((tool) => {
|
|
40042
40088
|
const name = truncateString(tool.id, 50);
|
|
40043
40089
|
const description = truncateString(tool.description ?? "", 200);
|
|
@@ -40860,6 +40906,1173 @@ function TemplateFailure({ errorMsg, validationErrors }) {
|
|
|
40860
40906
|
] });
|
|
40861
40907
|
}
|
|
40862
40908
|
|
|
40909
|
+
const DATE_PRESETS$1 = [
|
|
40910
|
+
{ label: "Last 24 hours", value: "24h" },
|
|
40911
|
+
{ label: "Last 3 days", value: "3d" },
|
|
40912
|
+
{ label: "Last 7 days", value: "7d" },
|
|
40913
|
+
{ label: "Last 14 days", value: "14d" },
|
|
40914
|
+
{ label: "Last 30 days", value: "30d" }
|
|
40915
|
+
];
|
|
40916
|
+
const VALID_PRESETS = new Set(DATE_PRESETS$1.map((p) => p.value));
|
|
40917
|
+
function isValidPreset(value) {
|
|
40918
|
+
return typeof value === "string" && (VALID_PRESETS.has(value) || value === "custom");
|
|
40919
|
+
}
|
|
40920
|
+
const PRESET_DAYS = {
|
|
40921
|
+
"24h": 1,
|
|
40922
|
+
"3d": 3,
|
|
40923
|
+
"7d": 7,
|
|
40924
|
+
"14d": 14,
|
|
40925
|
+
"30d": 30
|
|
40926
|
+
};
|
|
40927
|
+
const ENV_PCTS = {
|
|
40928
|
+
"Studio Cloud": 42,
|
|
40929
|
+
Production: 31,
|
|
40930
|
+
Staging: 18,
|
|
40931
|
+
Dev: 7,
|
|
40932
|
+
"CI / Preview": 2
|
|
40933
|
+
};
|
|
40934
|
+
function getMultiplier(preset, customRange, filterGroups) {
|
|
40935
|
+
let dateMul = 1;
|
|
40936
|
+
if (preset !== "custom") {
|
|
40937
|
+
dateMul = PRESET_DAYS[preset] ?? 1;
|
|
40938
|
+
} else if (customRange?.from && customRange?.to) {
|
|
40939
|
+
dateMul = Math.max(1, dateFns.differenceInDays(customRange.to, customRange.from) + 1);
|
|
40940
|
+
}
|
|
40941
|
+
const envGroups = filterGroups.filter((g) => g.field === "Environment" && g.comparator === "is");
|
|
40942
|
+
const envPct = envGroups.length === 0 ? 100 : envGroups.flatMap((g) => g.values).reduce((s, v) => s + (ENV_PCTS[v] ?? 0), 0);
|
|
40943
|
+
return dateMul * (envPct / 100);
|
|
40944
|
+
}
|
|
40945
|
+
const MetricsContext = React.createContext({
|
|
40946
|
+
datePreset: "24h",
|
|
40947
|
+
setDatePreset: () => {
|
|
40948
|
+
},
|
|
40949
|
+
customRange: void 0,
|
|
40950
|
+
setCustomRange: () => {
|
|
40951
|
+
},
|
|
40952
|
+
dateRangeLabel: "Last 24 hours",
|
|
40953
|
+
filterGroups: [],
|
|
40954
|
+
setFilterGroups: () => {
|
|
40955
|
+
},
|
|
40956
|
+
multiplier: 1
|
|
40957
|
+
});
|
|
40958
|
+
function useMetrics() {
|
|
40959
|
+
return React.useContext(MetricsContext);
|
|
40960
|
+
}
|
|
40961
|
+
function getDateRangeLabel(preset, customRange) {
|
|
40962
|
+
if (preset !== "custom") {
|
|
40963
|
+
return DATE_PRESETS$1.find((p) => p.value === preset).label;
|
|
40964
|
+
}
|
|
40965
|
+
if (customRange?.from) {
|
|
40966
|
+
if (customRange.to) {
|
|
40967
|
+
return `${dateFns.format(customRange.from, "MMM d, yyyy")} – ${dateFns.format(customRange.to, "MMM d, yyyy")}`;
|
|
40968
|
+
}
|
|
40969
|
+
return dateFns.format(customRange.from, "MMM d, yyyy");
|
|
40970
|
+
}
|
|
40971
|
+
return "Custom range";
|
|
40972
|
+
}
|
|
40973
|
+
function MetricsProvider({
|
|
40974
|
+
children,
|
|
40975
|
+
initialPreset,
|
|
40976
|
+
onPresetChange
|
|
40977
|
+
}) {
|
|
40978
|
+
const [datePreset, setDatePresetState] = React.useState(initialPreset ?? "24h");
|
|
40979
|
+
const [customRange, setCustomRange] = React.useState(void 0);
|
|
40980
|
+
const [filterGroups, setFilterGroups] = React.useState([]);
|
|
40981
|
+
const dateRangeLabel = getDateRangeLabel(datePreset, customRange);
|
|
40982
|
+
const multiplier = getMultiplier(datePreset, customRange, filterGroups);
|
|
40983
|
+
React.useEffect(() => {
|
|
40984
|
+
if (initialPreset && initialPreset !== datePreset) {
|
|
40985
|
+
setDatePresetState(initialPreset);
|
|
40986
|
+
}
|
|
40987
|
+
}, [initialPreset]);
|
|
40988
|
+
const setDatePreset = React.useCallback(
|
|
40989
|
+
(v) => {
|
|
40990
|
+
setDatePresetState(v);
|
|
40991
|
+
onPresetChange?.(v);
|
|
40992
|
+
},
|
|
40993
|
+
[onPresetChange]
|
|
40994
|
+
);
|
|
40995
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40996
|
+
MetricsContext.Provider,
|
|
40997
|
+
{
|
|
40998
|
+
value: {
|
|
40999
|
+
datePreset,
|
|
41000
|
+
setDatePreset,
|
|
41001
|
+
customRange,
|
|
41002
|
+
setCustomRange,
|
|
41003
|
+
dateRangeLabel,
|
|
41004
|
+
filterGroups,
|
|
41005
|
+
setFilterGroups,
|
|
41006
|
+
multiplier
|
|
41007
|
+
},
|
|
41008
|
+
children
|
|
41009
|
+
}
|
|
41010
|
+
);
|
|
41011
|
+
}
|
|
41012
|
+
|
|
41013
|
+
const PRESET_MS = {
|
|
41014
|
+
"24h": 24 * 60 * 60 * 1e3,
|
|
41015
|
+
"3d": 3 * 24 * 60 * 60 * 1e3,
|
|
41016
|
+
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
41017
|
+
"14d": 14 * 24 * 60 * 60 * 1e3,
|
|
41018
|
+
"30d": 30 * 24 * 60 * 60 * 1e3
|
|
41019
|
+
};
|
|
41020
|
+
function buildTimestamp(preset, customRange) {
|
|
41021
|
+
const now = /* @__PURE__ */ new Date();
|
|
41022
|
+
if (preset !== "custom") {
|
|
41023
|
+
const ms = PRESET_MS[preset] ?? PRESET_MS["24h"];
|
|
41024
|
+
return { start: new Date(now.getTime() - ms), end: now };
|
|
41025
|
+
}
|
|
41026
|
+
return {
|
|
41027
|
+
start: customRange?.from ?? new Date(now.getTime() - PRESET_MS["24h"]),
|
|
41028
|
+
end: customRange?.to ?? now
|
|
41029
|
+
};
|
|
41030
|
+
}
|
|
41031
|
+
function useMetricsFilters() {
|
|
41032
|
+
const { datePreset, customRange } = useMetrics();
|
|
41033
|
+
const timestamp = buildTimestamp(datePreset, customRange);
|
|
41034
|
+
return { datePreset, customRange, timestamp };
|
|
41035
|
+
}
|
|
41036
|
+
|
|
41037
|
+
async function fetchPercentiles(client, metricName, timestamp) {
|
|
41038
|
+
const res = await client.getMetricPercentiles({
|
|
41039
|
+
name: metricName,
|
|
41040
|
+
percentiles: [0.5, 0.95],
|
|
41041
|
+
interval: "1h",
|
|
41042
|
+
filters: { timestamp }
|
|
41043
|
+
});
|
|
41044
|
+
const p50Series = res.series.find((s) => s.percentile === 0.5);
|
|
41045
|
+
const p95Series = res.series.find((s) => s.percentile === 0.95);
|
|
41046
|
+
if (!p50Series || !p95Series) return [];
|
|
41047
|
+
const p95Map = new Map(p95Series.points.map((p) => [new Date(p.timestamp).getTime(), p.value]));
|
|
41048
|
+
return p50Series.points.map((p) => {
|
|
41049
|
+
const ts = new Date(p.timestamp);
|
|
41050
|
+
return {
|
|
41051
|
+
time: ts.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false }),
|
|
41052
|
+
p50: Math.round(p.value),
|
|
41053
|
+
p95: Math.round(p95Map.get(ts.getTime()) ?? 0)
|
|
41054
|
+
};
|
|
41055
|
+
});
|
|
41056
|
+
}
|
|
41057
|
+
function useLatencyMetrics() {
|
|
41058
|
+
const client = react.useMastraClient();
|
|
41059
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41060
|
+
return reactQuery.useQuery({
|
|
41061
|
+
queryKey: ["metrics", "latency", datePreset, customRange],
|
|
41062
|
+
queryFn: async () => {
|
|
41063
|
+
const [agentData, workflowData, toolData] = await Promise.all([
|
|
41064
|
+
fetchPercentiles(client, "mastra_agent_duration_ms", timestamp),
|
|
41065
|
+
fetchPercentiles(client, "mastra_workflow_duration_ms", timestamp),
|
|
41066
|
+
fetchPercentiles(client, "mastra_tool_duration_ms", timestamp)
|
|
41067
|
+
]);
|
|
41068
|
+
return { agentData, workflowData, toolData };
|
|
41069
|
+
}
|
|
41070
|
+
});
|
|
41071
|
+
}
|
|
41072
|
+
|
|
41073
|
+
function formatCompact(n) {
|
|
41074
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
41075
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
41076
|
+
return n.toLocaleString();
|
|
41077
|
+
}
|
|
41078
|
+
const CHART_COLORS = {
|
|
41079
|
+
green: "#22c55e",
|
|
41080
|
+
orange: "#fb923c",
|
|
41081
|
+
pink: "#f472b6",
|
|
41082
|
+
purple: "#8b5cf6",
|
|
41083
|
+
blue: "#4f83f1",
|
|
41084
|
+
blueDark: "#2b5cd9",
|
|
41085
|
+
blueLight: "#6b8fe5",
|
|
41086
|
+
red: "#f87171",
|
|
41087
|
+
greenDark: "#15613a",
|
|
41088
|
+
redDark: "#991b1b",
|
|
41089
|
+
yellow: "#facc15"
|
|
41090
|
+
};
|
|
41091
|
+
|
|
41092
|
+
function MetricsCardContent({ children, className }) {
|
|
41093
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("overflow-x-auto ", className), children });
|
|
41094
|
+
}
|
|
41095
|
+
|
|
41096
|
+
function MetricsCardDescription({ children, className }) {
|
|
41097
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-ui-md text-neutral2 leading-tight mt-0.5", className), children });
|
|
41098
|
+
}
|
|
41099
|
+
|
|
41100
|
+
function MetricsCardError({
|
|
41101
|
+
message = "Failed to load data",
|
|
41102
|
+
className
|
|
41103
|
+
}) {
|
|
41104
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col gap-3 items-center justify-center", className), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-sm text-accent2", children: message }) });
|
|
41105
|
+
}
|
|
41106
|
+
|
|
41107
|
+
function MetricsCardLoading({ className }) {
|
|
41108
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center justify-center", className), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "md", color: spacings.Colors.neutral1 }) });
|
|
41109
|
+
}
|
|
41110
|
+
|
|
41111
|
+
function MetricsCardNoData({ message = "No data yet", className }) {
|
|
41112
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center justify-center h-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-neutral1 text-sm", children: message }) });
|
|
41113
|
+
}
|
|
41114
|
+
|
|
41115
|
+
function DashboardCard({ children, className }) {
|
|
41116
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("border border-border1 rounded-lg p-6 bg-surface2", className), children });
|
|
41117
|
+
}
|
|
41118
|
+
|
|
41119
|
+
function MetricsCardRoot({ children, className }) {
|
|
41120
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
41121
|
+
DashboardCard,
|
|
41122
|
+
{
|
|
41123
|
+
className: cn(
|
|
41124
|
+
"flex-1 grid grid-rows-[4rem_20rem] gap-2 min-w-[20rem] md:min-w-[22rem] lg:min-w-[24rem] xl:min-w-[26rem] 2xl:min-w-[30rem] 3xl:min-w-[32rem]",
|
|
41125
|
+
className
|
|
41126
|
+
),
|
|
41127
|
+
children
|
|
41128
|
+
}
|
|
41129
|
+
);
|
|
41130
|
+
}
|
|
41131
|
+
|
|
41132
|
+
function MetricsCardSummary({ value, label, className }) {
|
|
41133
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid justify-end content-start text-right gap-1", className), children: [
|
|
41134
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-lg font-semibold text-neutral4 leading-none", children: value }),
|
|
41135
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-md text-neutral2", children: label })
|
|
41136
|
+
] });
|
|
41137
|
+
}
|
|
41138
|
+
|
|
41139
|
+
function MetricsCardTitle({ children, className }) {
|
|
41140
|
+
return /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-ui-md font-normal text-neutral4", className), children });
|
|
41141
|
+
}
|
|
41142
|
+
|
|
41143
|
+
function MetricsCardTitleAndDescription(props) {
|
|
41144
|
+
if ("children" in props) {
|
|
41145
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: props.className, children: props.children });
|
|
41146
|
+
}
|
|
41147
|
+
const { title, description } = props;
|
|
41148
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: props.className, children: [
|
|
41149
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsCardTitle, { children: title }),
|
|
41150
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(MetricsCardDescription, { children: description })
|
|
41151
|
+
] });
|
|
41152
|
+
}
|
|
41153
|
+
|
|
41154
|
+
function MetricsCardTopBar({ children, className }) {
|
|
41155
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("grid grid-cols-[1fr_auto] gap-4", className), children });
|
|
41156
|
+
}
|
|
41157
|
+
|
|
41158
|
+
function MetricsKpiCardChange({
|
|
41159
|
+
changePct,
|
|
41160
|
+
prevValue,
|
|
41161
|
+
lowerIsBetter,
|
|
41162
|
+
className
|
|
41163
|
+
}) {
|
|
41164
|
+
const isGood = lowerIsBetter ? changePct < 0 : changePct >= 0;
|
|
41165
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-1 text-sm text-neutral1 flex-wrap", className), children: [
|
|
41166
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
41167
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("[&>svg]:w-4 [&>svg]:h-4", isGood ? "text-green-600" : "text-red-600"), children: changePct >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingUpIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingDownIcon, {}) }),
|
|
41168
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41169
|
+
"span",
|
|
41170
|
+
{
|
|
41171
|
+
className: cn(isGood ? "text-green-600" : "text-red-600"),
|
|
41172
|
+
children: `${changePct >= 0 ? "+" : "-"}${Math.abs(changePct).toFixed(1)}%`
|
|
41173
|
+
}
|
|
41174
|
+
)
|
|
41175
|
+
] }),
|
|
41176
|
+
prevValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
41177
|
+
"vs previous ",
|
|
41178
|
+
/* @__PURE__ */ jsxRuntime.jsx("b", { className: "text-neutral2 font-semibold", children: prevValue })
|
|
41179
|
+
] })
|
|
41180
|
+
] });
|
|
41181
|
+
}
|
|
41182
|
+
|
|
41183
|
+
function MetricsKpiCardError({
|
|
41184
|
+
message = "Failed to load data",
|
|
41185
|
+
className
|
|
41186
|
+
}) {
|
|
41187
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-sm text-accent2", className), children: message });
|
|
41188
|
+
}
|
|
41189
|
+
|
|
41190
|
+
function MetricsKpiCardLabel({ children, className }) {
|
|
41191
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-ui-md text-neutral3 leading-relaxed", className), children });
|
|
41192
|
+
}
|
|
41193
|
+
|
|
41194
|
+
function MetricsKpiCardLoading({ className }) {
|
|
41195
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm", className), children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "md", color: spacings.Colors.neutral1 }) });
|
|
41196
|
+
}
|
|
41197
|
+
|
|
41198
|
+
function MetricsKpiCardNoChange({
|
|
41199
|
+
message = "No previous value to compare",
|
|
41200
|
+
className
|
|
41201
|
+
}) {
|
|
41202
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm text-neutral1", className), children: message });
|
|
41203
|
+
}
|
|
41204
|
+
|
|
41205
|
+
function MetricsKpiCardNoData({ message = "No data yet", className }) {
|
|
41206
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm text-neutral1", className), children: message });
|
|
41207
|
+
}
|
|
41208
|
+
|
|
41209
|
+
function MetricsKpiCardRoot({ children, className }) {
|
|
41210
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DashboardCard, { className: cn("flex-1 min-w-[15rem]", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-1", children }) });
|
|
41211
|
+
}
|
|
41212
|
+
|
|
41213
|
+
function MetricsKpiCardValue({ children, className }) {
|
|
41214
|
+
return /* @__PURE__ */ jsxRuntime.jsx("strong", { className: cn("text-header-lg text-neutral4 font-semibold", className), children });
|
|
41215
|
+
}
|
|
41216
|
+
|
|
41217
|
+
const MetricsKpiCard = Object.assign(MetricsKpiCardRoot, {
|
|
41218
|
+
Label: MetricsKpiCardLabel,
|
|
41219
|
+
Value: MetricsKpiCardValue,
|
|
41220
|
+
Change: MetricsKpiCardChange,
|
|
41221
|
+
NoChange: MetricsKpiCardNoChange,
|
|
41222
|
+
NoData: MetricsKpiCardNoData,
|
|
41223
|
+
Error: MetricsKpiCardError,
|
|
41224
|
+
Loading: MetricsKpiCardLoading
|
|
41225
|
+
});
|
|
41226
|
+
|
|
41227
|
+
const MetricsCard = Object.assign(MetricsCardRoot, {
|
|
41228
|
+
Root: MetricsCardRoot,
|
|
41229
|
+
Kpi: MetricsKpiCard,
|
|
41230
|
+
TopBar: MetricsCardTopBar,
|
|
41231
|
+
TitleAndDescription: MetricsCardTitleAndDescription,
|
|
41232
|
+
Title: MetricsCardTitle,
|
|
41233
|
+
Description: MetricsCardDescription,
|
|
41234
|
+
Summary: MetricsCardSummary,
|
|
41235
|
+
Loading: MetricsCardLoading,
|
|
41236
|
+
Error: MetricsCardError,
|
|
41237
|
+
Content: MetricsCardContent,
|
|
41238
|
+
NoData: MetricsCardNoData
|
|
41239
|
+
});
|
|
41240
|
+
|
|
41241
|
+
function MetricsLineChartTooltip({
|
|
41242
|
+
active,
|
|
41243
|
+
payload,
|
|
41244
|
+
label,
|
|
41245
|
+
suffix
|
|
41246
|
+
}) {
|
|
41247
|
+
if (!active || !payload?.length) return null;
|
|
41248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-border1 bg-surface2 px-3 py-2 text-xs shadow-lg", children: [
|
|
41249
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1 font-medium text-icon6", children: label }),
|
|
41250
|
+
payload.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-icon2", children: [
|
|
41251
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2 inline-block size-2 rounded-full", style: { backgroundColor: entry.color } }),
|
|
41252
|
+
entry.name,
|
|
41253
|
+
":",
|
|
41254
|
+
" ",
|
|
41255
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
|
|
41256
|
+
entry.value,
|
|
41257
|
+
suffix
|
|
41258
|
+
] })
|
|
41259
|
+
] }, entry.name))
|
|
41260
|
+
] });
|
|
41261
|
+
}
|
|
41262
|
+
|
|
41263
|
+
const LABEL_COLOR = "#a1a1aa";
|
|
41264
|
+
function MetricsLineChart({
|
|
41265
|
+
data,
|
|
41266
|
+
series,
|
|
41267
|
+
height = 210,
|
|
41268
|
+
yDomain
|
|
41269
|
+
}) {
|
|
41270
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
41271
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap w-full items-end gap-4 gap-y-1 mb-4", children: series.map((s) => {
|
|
41272
|
+
const aggregated = s.aggregate?.(data);
|
|
41273
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-baseline gap-2", children: [
|
|
41274
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-2 shrink-0 rounded-full translate-y-[-1px]", style: { backgroundColor: s.color } }),
|
|
41275
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-sm text-neutral3 truncate max-w-24", children: s.label }),
|
|
41276
|
+
aggregated && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-lg text-neutral4", children: [
|
|
41277
|
+
aggregated.value,
|
|
41278
|
+
aggregated.suffix && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-ui-sm text-neutral2", children: [
|
|
41279
|
+
" ",
|
|
41280
|
+
aggregated.suffix
|
|
41281
|
+
] })
|
|
41282
|
+
] })
|
|
41283
|
+
] }, s.dataKey);
|
|
41284
|
+
}) }),
|
|
41285
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { height }, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data, children: [
|
|
41286
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { stroke: "rgba(255,255,255,0.08)", vertical: false }),
|
|
41287
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41288
|
+
recharts.XAxis,
|
|
41289
|
+
{
|
|
41290
|
+
dataKey: "time",
|
|
41291
|
+
tick: { fontSize: 10, fill: LABEL_COLOR, fontFamily: "var(--font-mono)" },
|
|
41292
|
+
tickLine: false,
|
|
41293
|
+
axisLine: false,
|
|
41294
|
+
interval: 5
|
|
41295
|
+
}
|
|
41296
|
+
),
|
|
41297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41298
|
+
recharts.YAxis,
|
|
41299
|
+
{
|
|
41300
|
+
tick: { fontSize: 10, fill: LABEL_COLOR, fontFamily: "var(--font-mono)" },
|
|
41301
|
+
tickLine: false,
|
|
41302
|
+
axisLine: false,
|
|
41303
|
+
width: 30,
|
|
41304
|
+
domain: yDomain
|
|
41305
|
+
}
|
|
41306
|
+
),
|
|
41307
|
+
/* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: /* @__PURE__ */ jsxRuntime.jsx(MetricsLineChartTooltip, {}) }),
|
|
41308
|
+
series.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
41309
|
+
recharts.Line,
|
|
41310
|
+
{
|
|
41311
|
+
type: "linear",
|
|
41312
|
+
dataKey: s.dataKey,
|
|
41313
|
+
stroke: s.color,
|
|
41314
|
+
strokeWidth: 2,
|
|
41315
|
+
dot: false,
|
|
41316
|
+
name: s.label
|
|
41317
|
+
},
|
|
41318
|
+
s.dataKey
|
|
41319
|
+
))
|
|
41320
|
+
] }) }) })
|
|
41321
|
+
] });
|
|
41322
|
+
}
|
|
41323
|
+
|
|
41324
|
+
const latencySeries = [
|
|
41325
|
+
{
|
|
41326
|
+
dataKey: "p50",
|
|
41327
|
+
label: "p50",
|
|
41328
|
+
color: CHART_COLORS.blue,
|
|
41329
|
+
aggregate: (data) => ({
|
|
41330
|
+
value: data.length > 0 ? `${Math.round(data.reduce((s, d) => s + d.p50, 0) / data.length)}` : "0",
|
|
41331
|
+
suffix: "avg ms"
|
|
41332
|
+
})
|
|
41333
|
+
},
|
|
41334
|
+
{
|
|
41335
|
+
dataKey: "p95",
|
|
41336
|
+
label: "p95",
|
|
41337
|
+
color: CHART_COLORS.yellow,
|
|
41338
|
+
aggregate: (data) => ({
|
|
41339
|
+
value: data.length > 0 ? `${Math.round(data.reduce((s, d) => s + d.p95, 0) / data.length)}` : "0",
|
|
41340
|
+
suffix: "avg ms"
|
|
41341
|
+
})
|
|
41342
|
+
}
|
|
41343
|
+
];
|
|
41344
|
+
function LatencyChart({ data }) {
|
|
41345
|
+
if (data.length === 0) {
|
|
41346
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No latency data yet" });
|
|
41347
|
+
}
|
|
41348
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MetricsLineChart, { data, series: latencySeries });
|
|
41349
|
+
}
|
|
41350
|
+
function LatencyCard() {
|
|
41351
|
+
const { data, isLoading, isError } = useLatencyMetrics();
|
|
41352
|
+
const hasData = !!data && (data.agentData.length > 0 || data.workflowData.length > 0 || data.toolData.length > 0);
|
|
41353
|
+
const avgP50 = data && data.agentData.length > 0 ? `${Math.round(data.agentData.reduce((s, d) => s + d.p50, 0) / data.agentData.length)}ms` : "—";
|
|
41354
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
|
|
41355
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
|
|
41356
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Latency", description: "Hourly p50 and p95 latency." }),
|
|
41357
|
+
hasData && /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: avgP50, label: "Avg p50" })
|
|
41358
|
+
] }),
|
|
41359
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load latency data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No latency data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultTab: "agents", className: "overflow-visible", children: [
|
|
41360
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabList, { children: [
|
|
41361
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "agents", children: "Agents" }),
|
|
41362
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "workflows", children: "Workflows" }),
|
|
41363
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "tools", children: "Tools" })
|
|
41364
|
+
] }),
|
|
41365
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "agents", children: /* @__PURE__ */ jsxRuntime.jsx(LatencyChart, { data: data.agentData }) }),
|
|
41366
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "workflows", children: /* @__PURE__ */ jsxRuntime.jsx(LatencyChart, { data: data.workflowData }) }),
|
|
41367
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "tools", children: /* @__PURE__ */ jsxRuntime.jsx(LatencyChart, { data: data.toolData }) })
|
|
41368
|
+
] }) })
|
|
41369
|
+
] });
|
|
41370
|
+
}
|
|
41371
|
+
|
|
41372
|
+
function useAgentRunsKpiMetrics() {
|
|
41373
|
+
const client = react.useMastraClient();
|
|
41374
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41375
|
+
return reactQuery.useQuery({
|
|
41376
|
+
queryKey: ["metrics", "agent-runs-kpi", datePreset, customRange],
|
|
41377
|
+
queryFn: () => client.getMetricAggregate({
|
|
41378
|
+
name: ["mastra_agent_duration_ms"],
|
|
41379
|
+
aggregation: "count",
|
|
41380
|
+
filters: { timestamp },
|
|
41381
|
+
comparePeriod: "previous_period"
|
|
41382
|
+
})
|
|
41383
|
+
});
|
|
41384
|
+
}
|
|
41385
|
+
|
|
41386
|
+
function useAvgScoreKpiMetrics() {
|
|
41387
|
+
const client = react.useMastraClient();
|
|
41388
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41389
|
+
return reactQuery.useQuery({
|
|
41390
|
+
queryKey: ["metrics", "avg-score-kpi", datePreset, customRange],
|
|
41391
|
+
queryFn: async () => {
|
|
41392
|
+
const scorersMap = await client.listScorers();
|
|
41393
|
+
const scorerIds = Object.keys(scorersMap ?? {});
|
|
41394
|
+
if (scorerIds.length === 0) {
|
|
41395
|
+
return { value: null, previousValue: null, changePercent: null };
|
|
41396
|
+
}
|
|
41397
|
+
const allResults = await Promise.all(
|
|
41398
|
+
scorerIds.map((scorerId) => client.listScoresByScorerId({ scorerId, perPage: 100 }))
|
|
41399
|
+
);
|
|
41400
|
+
const startMs = timestamp.start.getTime();
|
|
41401
|
+
const endMs = timestamp.end.getTime();
|
|
41402
|
+
const allScoreValues = [];
|
|
41403
|
+
for (const result of allResults) {
|
|
41404
|
+
for (const s of result?.scores ?? []) {
|
|
41405
|
+
const ts = new Date(s.createdAt).getTime();
|
|
41406
|
+
if (ts >= startMs && ts <= endMs) {
|
|
41407
|
+
allScoreValues.push(s.score);
|
|
41408
|
+
}
|
|
41409
|
+
}
|
|
41410
|
+
}
|
|
41411
|
+
if (allScoreValues.length === 0) {
|
|
41412
|
+
return { value: null, previousValue: null, changePercent: null };
|
|
41413
|
+
}
|
|
41414
|
+
const avg = allScoreValues.reduce((sum, v) => sum + v, 0) / allScoreValues.length;
|
|
41415
|
+
return { value: Math.round(avg * 100) / 100, previousValue: null, changePercent: null };
|
|
41416
|
+
}
|
|
41417
|
+
});
|
|
41418
|
+
}
|
|
41419
|
+
|
|
41420
|
+
function useTotalTokensKpiMetrics() {
|
|
41421
|
+
const client = react.useMastraClient();
|
|
41422
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41423
|
+
return reactQuery.useQuery({
|
|
41424
|
+
queryKey: ["metrics", "total-tokens-kpi", datePreset, customRange],
|
|
41425
|
+
queryFn: async () => {
|
|
41426
|
+
const [input, output] = await Promise.all([
|
|
41427
|
+
client.getMetricAggregate({
|
|
41428
|
+
name: ["mastra_model_total_input_tokens"],
|
|
41429
|
+
aggregation: "sum",
|
|
41430
|
+
filters: { timestamp },
|
|
41431
|
+
comparePeriod: "previous_period"
|
|
41432
|
+
}),
|
|
41433
|
+
client.getMetricAggregate({
|
|
41434
|
+
name: ["mastra_model_total_output_tokens"],
|
|
41435
|
+
aggregation: "sum",
|
|
41436
|
+
filters: { timestamp },
|
|
41437
|
+
comparePeriod: "previous_period"
|
|
41438
|
+
})
|
|
41439
|
+
]);
|
|
41440
|
+
const hasCurrent = input.value != null || output.value != null;
|
|
41441
|
+
const hasPrevious = input.previousValue != null || output.previousValue != null;
|
|
41442
|
+
const value = (input.value ?? 0) + (output.value ?? 0);
|
|
41443
|
+
const previousValue = (input.previousValue ?? 0) + (output.previousValue ?? 0);
|
|
41444
|
+
const changePercent = hasPrevious && previousValue > 0 ? (value - previousValue) / previousValue * 100 : null;
|
|
41445
|
+
return {
|
|
41446
|
+
value: hasCurrent ? value : null,
|
|
41447
|
+
previousValue: hasPrevious ? previousValue : null,
|
|
41448
|
+
changePercent
|
|
41449
|
+
};
|
|
41450
|
+
}
|
|
41451
|
+
});
|
|
41452
|
+
}
|
|
41453
|
+
|
|
41454
|
+
function AgentRunsKpiCard() {
|
|
41455
|
+
const { data: agentRunsKpi, isLoading, isError } = useAgentRunsKpiMetrics();
|
|
41456
|
+
const hasData = agentRunsKpi?.value != null;
|
|
41457
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsKpiCard, { children: [
|
|
41458
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Label, { children: "Total Agent Runs" }),
|
|
41459
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Value, { className: hasData ? void 0 : "invisible", children: hasData ? agentRunsKpi.value.toLocaleString() : "—" }),
|
|
41460
|
+
isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Error, {}) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Loading, {}) : hasData ? agentRunsKpi.changePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
41461
|
+
MetricsKpiCard.Change,
|
|
41462
|
+
{
|
|
41463
|
+
changePct: agentRunsKpi.changePercent,
|
|
41464
|
+
prevValue: agentRunsKpi.previousValue?.toLocaleString()
|
|
41465
|
+
}
|
|
41466
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoChange, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoData, {})
|
|
41467
|
+
] });
|
|
41468
|
+
}
|
|
41469
|
+
function TotalTokensKpiCard() {
|
|
41470
|
+
const { data: totalTokensKpi, isLoading, isError } = useTotalTokensKpiMetrics();
|
|
41471
|
+
const hasData = totalTokensKpi?.value != null;
|
|
41472
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsKpiCard, { children: [
|
|
41473
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Label, { children: "Total Tokens" }),
|
|
41474
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Value, { className: hasData ? void 0 : "invisible", children: hasData ? formatCompact(totalTokensKpi.value) : "—" }),
|
|
41475
|
+
isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Error, {}) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Loading, {}) : hasData ? totalTokensKpi.changePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
41476
|
+
MetricsKpiCard.Change,
|
|
41477
|
+
{
|
|
41478
|
+
changePct: totalTokensKpi.changePercent,
|
|
41479
|
+
prevValue: totalTokensKpi.previousValue != null ? formatCompact(totalTokensKpi.previousValue) : void 0
|
|
41480
|
+
}
|
|
41481
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoChange, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoData, {})
|
|
41482
|
+
] });
|
|
41483
|
+
}
|
|
41484
|
+
function AvgScoreKpiCard() {
|
|
41485
|
+
const { data: avgScoreKpi, isLoading, isError } = useAvgScoreKpiMetrics();
|
|
41486
|
+
const hasData = avgScoreKpi?.value != null;
|
|
41487
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsKpiCard, { children: [
|
|
41488
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Label, { children: "Avg Score" }),
|
|
41489
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Value, { className: hasData ? void 0 : "invisible", children: hasData ? String(avgScoreKpi.value) : "—" }),
|
|
41490
|
+
isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Error, {}) : isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.Loading, {}) : hasData ? avgScoreKpi.changePercent != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
41491
|
+
MetricsKpiCard.Change,
|
|
41492
|
+
{
|
|
41493
|
+
changePct: avgScoreKpi.changePercent,
|
|
41494
|
+
prevValue: avgScoreKpi.previousValue != null ? String(avgScoreKpi.previousValue) : void 0
|
|
41495
|
+
}
|
|
41496
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoChange, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetricsKpiCard.NoData, {})
|
|
41497
|
+
] });
|
|
41498
|
+
}
|
|
41499
|
+
|
|
41500
|
+
function useModelUsageCostMetrics() {
|
|
41501
|
+
const client = react.useMastraClient();
|
|
41502
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41503
|
+
return reactQuery.useQuery({
|
|
41504
|
+
queryKey: ["metrics", "model-usage-cost", datePreset, customRange],
|
|
41505
|
+
queryFn: async () => {
|
|
41506
|
+
const metrics = [
|
|
41507
|
+
"mastra_model_total_input_tokens",
|
|
41508
|
+
"mastra_model_total_output_tokens",
|
|
41509
|
+
"mastra_model_input_cache_read_tokens",
|
|
41510
|
+
"mastra_model_input_cache_write_tokens"
|
|
41511
|
+
];
|
|
41512
|
+
const [inputRes, outputRes, cacheReadRes, cacheWriteRes] = await Promise.all(
|
|
41513
|
+
metrics.map(
|
|
41514
|
+
(name) => client.getMetricBreakdown({
|
|
41515
|
+
name: [name],
|
|
41516
|
+
groupBy: ["model"],
|
|
41517
|
+
aggregation: "sum",
|
|
41518
|
+
filters: { timestamp }
|
|
41519
|
+
})
|
|
41520
|
+
)
|
|
41521
|
+
);
|
|
41522
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
41523
|
+
const ensureModel = (model) => {
|
|
41524
|
+
if (!modelMap.has(model)) {
|
|
41525
|
+
modelMap.set(model, { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
|
|
41526
|
+
}
|
|
41527
|
+
return modelMap.get(model);
|
|
41528
|
+
};
|
|
41529
|
+
for (const group of inputRes.groups) {
|
|
41530
|
+
const m = group.dimensions.model ?? "unknown";
|
|
41531
|
+
ensureModel(m).input = group.value;
|
|
41532
|
+
}
|
|
41533
|
+
for (const group of outputRes.groups) {
|
|
41534
|
+
const m = group.dimensions.model ?? "unknown";
|
|
41535
|
+
ensureModel(m).output = group.value;
|
|
41536
|
+
}
|
|
41537
|
+
for (const group of cacheReadRes.groups) {
|
|
41538
|
+
const m = group.dimensions.model ?? "unknown";
|
|
41539
|
+
ensureModel(m).cacheRead = group.value;
|
|
41540
|
+
}
|
|
41541
|
+
for (const group of cacheWriteRes.groups) {
|
|
41542
|
+
const m = group.dimensions.model ?? "unknown";
|
|
41543
|
+
ensureModel(m).cacheWrite = group.value;
|
|
41544
|
+
}
|
|
41545
|
+
return Array.from(modelMap.entries()).map(([model, vals]) => ({
|
|
41546
|
+
model,
|
|
41547
|
+
input: formatCompact(vals.input),
|
|
41548
|
+
output: formatCompact(vals.output),
|
|
41549
|
+
cacheRead: formatCompact(vals.cacheRead),
|
|
41550
|
+
cacheWrite: formatCompact(vals.cacheWrite)
|
|
41551
|
+
})).sort((a, b) => a.model.localeCompare(b.model));
|
|
41552
|
+
}
|
|
41553
|
+
});
|
|
41554
|
+
}
|
|
41555
|
+
|
|
41556
|
+
function MetricsDataTable({
|
|
41557
|
+
columns,
|
|
41558
|
+
data,
|
|
41559
|
+
className
|
|
41560
|
+
}) {
|
|
41561
|
+
if (columns.length === 0) return null;
|
|
41562
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: cn("w-full h-full", className), maxHeight: "20rem", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41563
|
+
"div",
|
|
41564
|
+
{
|
|
41565
|
+
className: "grid items-center",
|
|
41566
|
+
style: {
|
|
41567
|
+
gridTemplateColumns: `auto ${columns.slice(1).map(() => "1fr").join(" ")}`
|
|
41568
|
+
},
|
|
41569
|
+
children: [
|
|
41570
|
+
columns.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
41571
|
+
"span",
|
|
41572
|
+
{
|
|
41573
|
+
className: cn(
|
|
41574
|
+
"h-9 py-1 flex items-center border-b border-surface5 uppercase whitespace-nowrap text-neutral2 tracking-widest text-ui-xs sticky top-0 z-10 bg-surface2",
|
|
41575
|
+
i === 0 ? "text-left sticky left-0 z-20 bg-surface2 pr-4 after:absolute after:right-1 after:top-1/2 after:-translate-y-1/2 after:h-3/5 after:w-px after:bg-surface5" : "px-4 text-right"
|
|
41576
|
+
),
|
|
41577
|
+
children: col.label
|
|
41578
|
+
},
|
|
41579
|
+
`${i}-${col.label}`
|
|
41580
|
+
)),
|
|
41581
|
+
data.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: columns.map((col, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
41582
|
+
"span",
|
|
41583
|
+
{
|
|
41584
|
+
className: cn(
|
|
41585
|
+
"h-10 flex items-center text-ui-sm whitespace-nowrap border-t border-surface5",
|
|
41586
|
+
rowIndex === 0 && "border-t-transparent",
|
|
41587
|
+
i === 0 ? "text-left text-neutral3 sticky left-0 z-10 bg-surface2 pr-4 after:absolute after:right-1 after:top-1/2 after:-translate-y-1/2 after:h-3/5 after:w-px after:bg-surface5" : cn(
|
|
41588
|
+
"px-4 text-right tabular-nums",
|
|
41589
|
+
col.highlight ? "text-neutral4 font-semibold" : "text-neutral3"
|
|
41590
|
+
)
|
|
41591
|
+
),
|
|
41592
|
+
children: col.value(row)
|
|
41593
|
+
},
|
|
41594
|
+
`${row.key}-${i}`
|
|
41595
|
+
)) }, row.key))
|
|
41596
|
+
]
|
|
41597
|
+
}
|
|
41598
|
+
) });
|
|
41599
|
+
}
|
|
41600
|
+
|
|
41601
|
+
function ModelUsageCostCard() {
|
|
41602
|
+
const { data: rows, isLoading, isError } = useModelUsageCostMetrics();
|
|
41603
|
+
const hasData = !!rows && rows.length > 0;
|
|
41604
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
|
|
41605
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TopBar, { children: /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Model Usage", description: "Token consumption by model." }) }),
|
|
41606
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load model usage data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No model usage data yet" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
41607
|
+
MetricsDataTable,
|
|
41608
|
+
{
|
|
41609
|
+
columns: [
|
|
41610
|
+
{ label: "Model", value: (row) => row.model },
|
|
41611
|
+
{ label: "Input", value: (row) => row.input },
|
|
41612
|
+
{ label: "Output", value: (row) => row.output },
|
|
41613
|
+
{ label: "Cache Read", value: (row) => row.cacheRead },
|
|
41614
|
+
{ label: "Cache Write", value: (row) => row.cacheWrite }
|
|
41615
|
+
// { label: 'Cost', value: () => '—', highlight: true },
|
|
41616
|
+
],
|
|
41617
|
+
data: rows.map((row) => ({ ...row, key: row.model }))
|
|
41618
|
+
}
|
|
41619
|
+
) })
|
|
41620
|
+
] });
|
|
41621
|
+
}
|
|
41622
|
+
|
|
41623
|
+
function useScoresMetrics() {
|
|
41624
|
+
const client = react.useMastraClient();
|
|
41625
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41626
|
+
return reactQuery.useQuery({
|
|
41627
|
+
queryKey: ["metrics", "scores-card", datePreset, customRange],
|
|
41628
|
+
queryFn: async () => {
|
|
41629
|
+
const scorersMap = await client.listScorers();
|
|
41630
|
+
const scorerIds = Object.keys(scorersMap ?? {});
|
|
41631
|
+
if (scorerIds.length === 0) {
|
|
41632
|
+
return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };
|
|
41633
|
+
}
|
|
41634
|
+
const allResults = await Promise.all(
|
|
41635
|
+
// Limited to 100 most recent scores per scorer; pagination not yet implemented
|
|
41636
|
+
scorerIds.map((scorerId) => client.listScoresByScorerId({ scorerId, perPage: 100 }))
|
|
41637
|
+
);
|
|
41638
|
+
const startMs = timestamp.start.getTime();
|
|
41639
|
+
const endMs = timestamp.end.getTime();
|
|
41640
|
+
const allScores = [];
|
|
41641
|
+
for (let i = 0; i < scorerIds.length; i++) {
|
|
41642
|
+
const scores = allResults[i]?.scores ?? [];
|
|
41643
|
+
for (const s of scores) {
|
|
41644
|
+
const ts = new Date(s.createdAt).getTime();
|
|
41645
|
+
if (ts >= startMs && ts <= endMs) {
|
|
41646
|
+
allScores.push({
|
|
41647
|
+
scorerId: scorerIds[i],
|
|
41648
|
+
score: s.score,
|
|
41649
|
+
createdAt: s.createdAt
|
|
41650
|
+
});
|
|
41651
|
+
}
|
|
41652
|
+
}
|
|
41653
|
+
}
|
|
41654
|
+
if (allScores.length === 0) {
|
|
41655
|
+
return { summaryData: [], overTimeData: [], scorerNames: [], avgScore: null };
|
|
41656
|
+
}
|
|
41657
|
+
const byScorer = /* @__PURE__ */ new Map();
|
|
41658
|
+
for (const s of allScores) {
|
|
41659
|
+
if (!byScorer.has(s.scorerId)) byScorer.set(s.scorerId, []);
|
|
41660
|
+
byScorer.get(s.scorerId).push(s.score);
|
|
41661
|
+
}
|
|
41662
|
+
const summaryData = Array.from(byScorer.entries()).map(([scorer, vals]) => ({
|
|
41663
|
+
scorer,
|
|
41664
|
+
avg: vals.reduce((a, b) => a + b, 0) / vals.length,
|
|
41665
|
+
min: Math.min(...vals),
|
|
41666
|
+
max: Math.max(...vals),
|
|
41667
|
+
count: vals.length
|
|
41668
|
+
}));
|
|
41669
|
+
const scorerNames = summaryData.map((s) => s.scorer);
|
|
41670
|
+
const avgScore = summaryData.reduce((s, d) => s + d.avg, 0) / summaryData.length;
|
|
41671
|
+
const bucketMap = /* @__PURE__ */ new Map();
|
|
41672
|
+
for (const s of allScores) {
|
|
41673
|
+
const ts = new Date(s.createdAt);
|
|
41674
|
+
const bucket = Math.floor(ts.getTime() / 36e5) * 36e5;
|
|
41675
|
+
if (!bucketMap.has(bucket)) bucketMap.set(bucket, /* @__PURE__ */ new Map());
|
|
41676
|
+
const scorerMap = bucketMap.get(bucket);
|
|
41677
|
+
if (!scorerMap.has(s.scorerId)) scorerMap.set(s.scorerId, []);
|
|
41678
|
+
scorerMap.get(s.scorerId).push(s.score);
|
|
41679
|
+
}
|
|
41680
|
+
const overTimeData = Array.from(bucketMap.entries()).sort(([a], [b]) => a - b).map(([bucket, scorerMap]) => {
|
|
41681
|
+
const point = {
|
|
41682
|
+
time: new Date(bucket).toLocaleTimeString("en-US", {
|
|
41683
|
+
hour: "2-digit",
|
|
41684
|
+
minute: "2-digit",
|
|
41685
|
+
hour12: false
|
|
41686
|
+
})
|
|
41687
|
+
};
|
|
41688
|
+
for (const name of scorerNames) {
|
|
41689
|
+
const vals = scorerMap.get(name);
|
|
41690
|
+
if (vals && vals.length > 0) {
|
|
41691
|
+
point[name] = +(vals.reduce((a, b) => a + b, 0) / vals.length).toFixed(2);
|
|
41692
|
+
}
|
|
41693
|
+
}
|
|
41694
|
+
return point;
|
|
41695
|
+
});
|
|
41696
|
+
return {
|
|
41697
|
+
summaryData,
|
|
41698
|
+
overTimeData,
|
|
41699
|
+
scorerNames,
|
|
41700
|
+
avgScore: Math.round(avgScore * 100) / 100
|
|
41701
|
+
};
|
|
41702
|
+
}
|
|
41703
|
+
});
|
|
41704
|
+
}
|
|
41705
|
+
|
|
41706
|
+
const SERIES_COLORS = [
|
|
41707
|
+
CHART_COLORS.green,
|
|
41708
|
+
CHART_COLORS.blue,
|
|
41709
|
+
CHART_COLORS.purple,
|
|
41710
|
+
CHART_COLORS.orange,
|
|
41711
|
+
CHART_COLORS.pink,
|
|
41712
|
+
CHART_COLORS.yellow
|
|
41713
|
+
];
|
|
41714
|
+
function ScoresCard() {
|
|
41715
|
+
const { data, isLoading, isError } = useScoresMetrics();
|
|
41716
|
+
const hasData = !!data && data.summaryData.length > 0;
|
|
41717
|
+
const series = React.useMemo(() => {
|
|
41718
|
+
if (!data?.scorerNames) return [];
|
|
41719
|
+
return data.scorerNames.map((name, i) => ({
|
|
41720
|
+
dataKey: name,
|
|
41721
|
+
label: name,
|
|
41722
|
+
color: SERIES_COLORS[i % SERIES_COLORS.length],
|
|
41723
|
+
aggregate: (points) => ({
|
|
41724
|
+
value: points.length > 0 ? (points.reduce((s, d) => s + (d[name] ?? 0), 0) / points.length).toFixed(2) : "0",
|
|
41725
|
+
suffix: "avg"
|
|
41726
|
+
})
|
|
41727
|
+
}));
|
|
41728
|
+
}, [data?.scorerNames]);
|
|
41729
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
|
|
41730
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
|
|
41731
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Scores", description: "Evaluation scorer performance." }),
|
|
41732
|
+
hasData && /* @__PURE__ */ jsxRuntime.jsx(
|
|
41733
|
+
MetricsCard.Summary,
|
|
41734
|
+
{
|
|
41735
|
+
value: data?.avgScore != null ? `avg ${data.avgScore}` : "—",
|
|
41736
|
+
label: "Across all scorers"
|
|
41737
|
+
}
|
|
41738
|
+
)
|
|
41739
|
+
] }),
|
|
41740
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load scores data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No scores data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultTab: "over-time", className: "overflow-visible", children: [
|
|
41741
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabList, { children: [
|
|
41742
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "over-time", children: "Over Time" }),
|
|
41743
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "summary", children: "Summary" })
|
|
41744
|
+
] }),
|
|
41745
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "over-time", children: data.overTimeData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(MetricsLineChart, { data: data.overTimeData, series, yDomain: [0, 1] }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No time series data yet" }) }),
|
|
41746
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "summary", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
41747
|
+
MetricsDataTable,
|
|
41748
|
+
{
|
|
41749
|
+
columns: [
|
|
41750
|
+
{ label: "Scorer", value: (row) => row.scorer },
|
|
41751
|
+
{ label: "Avg", value: (row) => row.avg.toFixed(2), highlight: true },
|
|
41752
|
+
{ label: "Min", value: (row) => row.min.toFixed(2) },
|
|
41753
|
+
{ label: "Max", value: (row) => row.max.toFixed(2) },
|
|
41754
|
+
{ label: "Count", value: (row) => row.count.toLocaleString() }
|
|
41755
|
+
],
|
|
41756
|
+
data: data.summaryData.map((row) => ({ ...row, key: row.scorer }))
|
|
41757
|
+
}
|
|
41758
|
+
) })
|
|
41759
|
+
] }) })
|
|
41760
|
+
] });
|
|
41761
|
+
}
|
|
41762
|
+
|
|
41763
|
+
function useTokenUsageByAgentMetrics() {
|
|
41764
|
+
const client = react.useMastraClient();
|
|
41765
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41766
|
+
return reactQuery.useQuery({
|
|
41767
|
+
queryKey: ["metrics", "token-usage-by-agent", datePreset, customRange],
|
|
41768
|
+
queryFn: async () => {
|
|
41769
|
+
const [inputRes, outputRes] = await Promise.all([
|
|
41770
|
+
client.getMetricBreakdown({
|
|
41771
|
+
name: ["mastra_model_total_input_tokens"],
|
|
41772
|
+
groupBy: ["entityName"],
|
|
41773
|
+
aggregation: "sum",
|
|
41774
|
+
filters: { timestamp }
|
|
41775
|
+
}),
|
|
41776
|
+
client.getMetricBreakdown({
|
|
41777
|
+
name: ["mastra_model_total_output_tokens"],
|
|
41778
|
+
groupBy: ["entityName"],
|
|
41779
|
+
aggregation: "sum",
|
|
41780
|
+
filters: { timestamp }
|
|
41781
|
+
})
|
|
41782
|
+
]);
|
|
41783
|
+
const agentMap = /* @__PURE__ */ new Map();
|
|
41784
|
+
const ensure = (name) => {
|
|
41785
|
+
if (!agentMap.has(name)) {
|
|
41786
|
+
agentMap.set(name, { input: 0, output: 0 });
|
|
41787
|
+
}
|
|
41788
|
+
return agentMap.get(name);
|
|
41789
|
+
};
|
|
41790
|
+
for (const group of inputRes.groups) {
|
|
41791
|
+
const name = group.dimensions.entityName ?? "unknown";
|
|
41792
|
+
ensure(name).input = group.value;
|
|
41793
|
+
}
|
|
41794
|
+
for (const group of outputRes.groups) {
|
|
41795
|
+
const name = group.dimensions.entityName ?? "unknown";
|
|
41796
|
+
ensure(name).output = group.value;
|
|
41797
|
+
}
|
|
41798
|
+
return Array.from(agentMap.entries()).map(([name, vals]) => ({
|
|
41799
|
+
name,
|
|
41800
|
+
input: vals.input,
|
|
41801
|
+
output: vals.output,
|
|
41802
|
+
total: vals.input + vals.output
|
|
41803
|
+
})).sort((a, b) => b.total - a.total);
|
|
41804
|
+
}
|
|
41805
|
+
});
|
|
41806
|
+
}
|
|
41807
|
+
|
|
41808
|
+
function HorizontalBars({
|
|
41809
|
+
data,
|
|
41810
|
+
segments,
|
|
41811
|
+
maxVal,
|
|
41812
|
+
fmt,
|
|
41813
|
+
className
|
|
41814
|
+
}) {
|
|
41815
|
+
const sorted = [...data].sort((a, b) => {
|
|
41816
|
+
const totalB = b.values.reduce((s, v) => s + v, 0);
|
|
41817
|
+
const totalA = a.values.reduce((s, v) => s + v, 0);
|
|
41818
|
+
return totalB - totalA;
|
|
41819
|
+
});
|
|
41820
|
+
const isStacked = segments.length > 1;
|
|
41821
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: cn("w-full h-full", className), children: [
|
|
41822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mb-4 mt-2", children: [
|
|
41823
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center gap-4", children: segments.map((seg) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
41824
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-2 rounded-full", style: { backgroundColor: seg.color } }),
|
|
41825
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-sm text-neutral3", children: seg.label })
|
|
41826
|
+
] }, seg.label)) }),
|
|
41827
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-ui-sm text-neutral2 pr-2", children: "Total" })
|
|
41828
|
+
] }),
|
|
41829
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-3.5", children: sorted.map((d) => {
|
|
41830
|
+
const total = d.values.reduce((s, v) => s + v, 0);
|
|
41831
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-14 h-6 ", children: [
|
|
41832
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full flex-1 min-w-0", children: [
|
|
41833
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
41834
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
41835
|
+
"div",
|
|
41836
|
+
{
|
|
41837
|
+
className: "absolute inset-y-0 left-0 cursor-default",
|
|
41838
|
+
style: { width: `${maxVal > 0 ? total / maxVal * 100 : 0}%` },
|
|
41839
|
+
children: segments.map((seg, si) => {
|
|
41840
|
+
const val = d.values[si] ?? 0;
|
|
41841
|
+
const pct = total > 0 ? val / total * 100 : 0;
|
|
41842
|
+
const left = d.values.slice(0, si).reduce((s, v) => s + (total > 0 ? v / total * 100 : 0), 0);
|
|
41843
|
+
const isLastWithValue = d.values.slice(si + 1).every((v) => !v);
|
|
41844
|
+
if (isStacked) {
|
|
41845
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
41846
|
+
"div",
|
|
41847
|
+
{
|
|
41848
|
+
className: cn(
|
|
41849
|
+
"absolute inset-y-0",
|
|
41850
|
+
si === 0 && "rounded-l",
|
|
41851
|
+
isLastWithValue && "rounded-r"
|
|
41852
|
+
),
|
|
41853
|
+
style: {
|
|
41854
|
+
left: `${left}%`,
|
|
41855
|
+
width: `${pct}%`,
|
|
41856
|
+
backgroundColor: seg.color
|
|
41857
|
+
}
|
|
41858
|
+
},
|
|
41859
|
+
seg.label
|
|
41860
|
+
);
|
|
41861
|
+
}
|
|
41862
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
41863
|
+
"div",
|
|
41864
|
+
{
|
|
41865
|
+
className: "absolute inset-y-0 left-0 rounded",
|
|
41866
|
+
style: { width: `${pct}%`, backgroundColor: seg.color }
|
|
41867
|
+
},
|
|
41868
|
+
seg.label
|
|
41869
|
+
);
|
|
41870
|
+
})
|
|
41871
|
+
}
|
|
41872
|
+
) }),
|
|
41873
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "top", className: "font-mono", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-1", children: segments.map((seg, si) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
41874
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: seg.label }),
|
|
41875
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto pl-3", children: fmt(d.values[si] ?? 0) })
|
|
41876
|
+
] }, seg.label)) }) })
|
|
41877
|
+
] }),
|
|
41878
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-y-0 left-2.5 flex items-center text-ui-sm text-neutral4 truncate z-10 pointer-events-none", children: d.name })
|
|
41879
|
+
] }),
|
|
41880
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-md text-neutral4 tabular-nums shrink-0 pr-3", children: fmt(total) })
|
|
41881
|
+
] }, d.name);
|
|
41882
|
+
}) })
|
|
41883
|
+
] });
|
|
41884
|
+
}
|
|
41885
|
+
|
|
41886
|
+
function TokenUsageByAgentCard() {
|
|
41887
|
+
const { data, isLoading, isError } = useTokenUsageByAgentMetrics();
|
|
41888
|
+
const hasData = !!data && data.length > 0;
|
|
41889
|
+
const totalTokens = data?.reduce((s, d) => s + d.total, 0) ?? 0;
|
|
41890
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
|
|
41891
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
|
|
41892
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41893
|
+
MetricsCard.TitleAndDescription,
|
|
41894
|
+
{
|
|
41895
|
+
title: "Token Usage by Agent",
|
|
41896
|
+
description: "Token consumption grouped by agent."
|
|
41897
|
+
}
|
|
41898
|
+
),
|
|
41899
|
+
hasData && /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: formatCompact(totalTokens), label: "Total tokens" })
|
|
41900
|
+
] }),
|
|
41901
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load token usage data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No token usage data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultTab: "tokens", className: "grid grid-rows-[auto_1fr] overflow-y-auto h-full", children: [
|
|
41902
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabList, { children: /* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "tokens", children: "Tokens" }) }),
|
|
41903
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "tokens", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
41904
|
+
HorizontalBars,
|
|
41905
|
+
{
|
|
41906
|
+
data: data.map((d) => ({ name: d.name, values: [d.input, d.output] })),
|
|
41907
|
+
segments: [
|
|
41908
|
+
{ label: "Input", color: CHART_COLORS.blueDark },
|
|
41909
|
+
{ label: "Output", color: CHART_COLORS.blue }
|
|
41910
|
+
],
|
|
41911
|
+
maxVal: Math.max(...data.map((d) => d.input + d.output)),
|
|
41912
|
+
fmt: formatCompact
|
|
41913
|
+
}
|
|
41914
|
+
) })
|
|
41915
|
+
] }) })
|
|
41916
|
+
] });
|
|
41917
|
+
}
|
|
41918
|
+
|
|
41919
|
+
async function fetchVolume(client, metricName, timestamp) {
|
|
41920
|
+
const res = await client.getMetricBreakdown({
|
|
41921
|
+
name: [metricName],
|
|
41922
|
+
groupBy: ["entityName", "status"],
|
|
41923
|
+
aggregation: "count",
|
|
41924
|
+
filters: { timestamp }
|
|
41925
|
+
});
|
|
41926
|
+
const map = /* @__PURE__ */ new Map();
|
|
41927
|
+
for (const group of res.groups) {
|
|
41928
|
+
const name = group.dimensions.entityName ?? "unknown";
|
|
41929
|
+
const status = group.dimensions.status ?? "ok";
|
|
41930
|
+
if (!map.has(name)) {
|
|
41931
|
+
map.set(name, { completed: 0, errors: 0 });
|
|
41932
|
+
}
|
|
41933
|
+
const entry = map.get(name);
|
|
41934
|
+
if (status === "error") {
|
|
41935
|
+
entry.errors += group.value;
|
|
41936
|
+
} else {
|
|
41937
|
+
entry.completed += group.value;
|
|
41938
|
+
}
|
|
41939
|
+
}
|
|
41940
|
+
return Array.from(map.entries()).map(([name, vals]) => ({ name, ...vals })).sort((a, b) => b.completed + b.errors - (a.completed + a.errors));
|
|
41941
|
+
}
|
|
41942
|
+
function useTraceVolumeMetrics() {
|
|
41943
|
+
const client = react.useMastraClient();
|
|
41944
|
+
const { datePreset, customRange, timestamp } = useMetricsFilters();
|
|
41945
|
+
return reactQuery.useQuery({
|
|
41946
|
+
queryKey: ["metrics", "trace-volume", datePreset, customRange],
|
|
41947
|
+
queryFn: async () => {
|
|
41948
|
+
const [agentData, workflowData, toolData] = await Promise.all([
|
|
41949
|
+
fetchVolume(client, "mastra_agent_duration_ms", timestamp),
|
|
41950
|
+
fetchVolume(client, "mastra_workflow_duration_ms", timestamp),
|
|
41951
|
+
fetchVolume(client, "mastra_tool_duration_ms", timestamp)
|
|
41952
|
+
]);
|
|
41953
|
+
return { agentData, workflowData, toolData };
|
|
41954
|
+
}
|
|
41955
|
+
});
|
|
41956
|
+
}
|
|
41957
|
+
|
|
41958
|
+
function VolumeBars({ data }) {
|
|
41959
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
41960
|
+
HorizontalBars,
|
|
41961
|
+
{
|
|
41962
|
+
data: data.map((d) => ({ name: d.name, values: [d.completed, d.errors] })),
|
|
41963
|
+
segments: [
|
|
41964
|
+
{ label: "Completed", color: CHART_COLORS.blueDark },
|
|
41965
|
+
{ label: "Errors", color: CHART_COLORS.pink }
|
|
41966
|
+
],
|
|
41967
|
+
maxVal: Math.max(...data.map((d) => d.completed + d.errors)),
|
|
41968
|
+
fmt: formatCompact
|
|
41969
|
+
}
|
|
41970
|
+
);
|
|
41971
|
+
}
|
|
41972
|
+
function TracesVolumeCard() {
|
|
41973
|
+
const { data, isLoading, isError } = useTraceVolumeMetrics();
|
|
41974
|
+
const hasData = !!data && (data.agentData.length > 0 || data.workflowData.length > 0 || data.toolData.length > 0);
|
|
41975
|
+
const total = data ? [...data.agentData, ...data.workflowData, ...data.toolData].reduce((s, d) => s + d.completed + d.errors, 0) : 0;
|
|
41976
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(MetricsCard, { children: [
|
|
41977
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsCard.TopBar, { children: [
|
|
41978
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetricsCard.TitleAndDescription, { title: "Trace Volume", description: "Runs and call counts." }),
|
|
41979
|
+
hasData && /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Summary, { value: formatCompact(total), label: "Total runs" })
|
|
41980
|
+
] }),
|
|
41981
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Loading, {}) : isError ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Error, { message: "Failed to load trace volume data" }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.Content, { children: !hasData ? /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No trace volume data yet" }) : /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { defaultTab: "agents", className: "grid grid-rows-[auto_1fr] overflow-y-auto h-full", children: [
|
|
41982
|
+
/* @__PURE__ */ jsxRuntime.jsxs(TabList, { children: [
|
|
41983
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "agents", children: "Agents" }),
|
|
41984
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "workflows", children: "Workflows" }),
|
|
41985
|
+
/* @__PURE__ */ jsxRuntime.jsx(Tab, { value: "tools", children: "Tools" })
|
|
41986
|
+
] }),
|
|
41987
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "agents", children: data.agentData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(VolumeBars, { data: data.agentData }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No agent data yet" }) }),
|
|
41988
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "workflows", children: data.workflowData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(VolumeBars, { data: data.workflowData }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No workflow data yet" }) }),
|
|
41989
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabContent, { value: "tools", children: data.toolData.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(VolumeBars, { data: data.toolData }) : /* @__PURE__ */ jsxRuntime.jsx(MetricsCard.NoData, { message: "No tool data yet" }) })
|
|
41990
|
+
] }) })
|
|
41991
|
+
] });
|
|
41992
|
+
}
|
|
41993
|
+
|
|
41994
|
+
function MetricsFlexGrid({ children, className }) {
|
|
41995
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-8", className), children });
|
|
41996
|
+
}
|
|
41997
|
+
|
|
41998
|
+
const ANALYTICS_OBSERVABILITY_TYPES = /* @__PURE__ */ new Set([
|
|
41999
|
+
// 'ObservabilityStorageClickhouse',
|
|
42000
|
+
// 'ObservabilityStorageDuckDB',
|
|
42001
|
+
"ObservabilityInMemory"
|
|
42002
|
+
]);
|
|
42003
|
+
function MetricsDashboard() {
|
|
42004
|
+
const { data, isLoading } = useMastraPackages();
|
|
42005
|
+
const observabilityType = data?.observabilityStorageType;
|
|
42006
|
+
const supportsMetrics = observabilityType ? ANALYTICS_OBSERVABILITY_TYPES.has(observabilityType) : false;
|
|
42007
|
+
const isInMemory = observabilityType === "ObservabilityInMemory";
|
|
42008
|
+
if (isLoading) {
|
|
42009
|
+
return null;
|
|
42010
|
+
}
|
|
42011
|
+
if (!supportsMetrics) {
|
|
42012
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
42013
|
+
EmptyState$1,
|
|
42014
|
+
{
|
|
42015
|
+
iconSlot: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleSlashIcon, {}),
|
|
42016
|
+
titleSlot: "Metrics are not available with your current storage",
|
|
42017
|
+
descriptionSlot: "Metrics currently require in-memory storage for observability. ClickHouse and DuckDB support is coming soon. Relational databases (PostgreSQL, LibSQL) do not support metrics collection. To enable metrics on an existing project, switch the observability storage in the Mastra configuration.",
|
|
42018
|
+
actionSlot: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
42019
|
+
Button,
|
|
42020
|
+
{
|
|
42021
|
+
variant: "ghost",
|
|
42022
|
+
as: "a",
|
|
42023
|
+
href: "https://mastra.ai/en/docs/observability/metrics",
|
|
42024
|
+
target: "_blank",
|
|
42025
|
+
rel: "noopener noreferrer",
|
|
42026
|
+
children: [
|
|
42027
|
+
"Metrics Documentation ",
|
|
42028
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLinkIcon, {})
|
|
42029
|
+
]
|
|
42030
|
+
}
|
|
42031
|
+
)
|
|
42032
|
+
}
|
|
42033
|
+
) });
|
|
42034
|
+
}
|
|
42035
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-8 content-start pb-10", children: [
|
|
42036
|
+
isInMemory && /* @__PURE__ */ jsxRuntime.jsxs(Alert, { variant: "info", children: [
|
|
42037
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertTitle, { children: "Metrics are not persisted" }),
|
|
42038
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertDescription, { as: "p", children: "This project uses in-memory storage for observability. Metrics will be lost on every server restart. For persistent metrics, switch the observability storage to ClickHouse or DuckDB." })
|
|
42039
|
+
] }),
|
|
42040
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsFlexGrid, { children: [
|
|
42041
|
+
/* @__PURE__ */ jsxRuntime.jsx(AgentRunsKpiCard, {}),
|
|
42042
|
+
/* @__PURE__ */ jsxRuntime.jsx(TotalTokensKpiCard, {}),
|
|
42043
|
+
/* @__PURE__ */ jsxRuntime.jsx(AvgScoreKpiCard, {})
|
|
42044
|
+
] }),
|
|
42045
|
+
/* @__PURE__ */ jsxRuntime.jsxs(MetricsFlexGrid, { children: [
|
|
42046
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModelUsageCostCard, {}),
|
|
42047
|
+
/* @__PURE__ */ jsxRuntime.jsx(TokenUsageByAgentCard, {}),
|
|
42048
|
+
/* @__PURE__ */ jsxRuntime.jsx(ScoresCard, {}),
|
|
42049
|
+
/* @__PURE__ */ jsxRuntime.jsx(TracesVolumeCard, {}),
|
|
42050
|
+
/* @__PURE__ */ jsxRuntime.jsx(LatencyCard, {})
|
|
42051
|
+
] })
|
|
42052
|
+
] });
|
|
42053
|
+
}
|
|
42054
|
+
|
|
42055
|
+
const DATE_PRESETS = [
|
|
42056
|
+
{ label: "Last 24 hours", value: "24h" },
|
|
42057
|
+
{ label: "Last 3 days", value: "3d" },
|
|
42058
|
+
{ label: "Last 7 days", value: "7d" },
|
|
42059
|
+
{ label: "Last 14 days", value: "14d" },
|
|
42060
|
+
{ label: "Last 30 days", value: "30d" }
|
|
42061
|
+
];
|
|
42062
|
+
function DateRangeSelector() {
|
|
42063
|
+
const { datePreset, setDatePreset } = useMetrics();
|
|
42064
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
42065
|
+
SelectFieldBlock,
|
|
42066
|
+
{
|
|
42067
|
+
name: "date-range",
|
|
42068
|
+
labelIsHidden: true,
|
|
42069
|
+
value: datePreset,
|
|
42070
|
+
options: DATE_PRESETS,
|
|
42071
|
+
onValueChange: (value) => setDatePreset(value)
|
|
42072
|
+
}
|
|
42073
|
+
);
|
|
42074
|
+
}
|
|
42075
|
+
|
|
40863
42076
|
function groupTracesByThread(traces) {
|
|
40864
42077
|
const threadMap = /* @__PURE__ */ new Map();
|
|
40865
42078
|
const ungrouped = [];
|
|
@@ -42061,6 +43274,7 @@ function DatasetsList({ datasets, isLoading, error, search = "" }) {
|
|
|
42061
43274
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Version" }),
|
|
42062
43275
|
/* @__PURE__ */ jsxRuntime.jsx(EntityList.TopCell, { className: "text-center", children: "Created" })
|
|
42063
43276
|
] }),
|
|
43277
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No Datasets match your search" }) : null,
|
|
42064
43278
|
filteredData.map((ds) => {
|
|
42065
43279
|
const name = truncateString(ds.name, 50);
|
|
42066
43280
|
const description = truncateString(ds.description ?? "", 200);
|
|
@@ -49058,6 +50272,7 @@ function McpServersList({ mcpServers, isLoading, error, search = "" }) {
|
|
|
49058
50272
|
}
|
|
49059
50273
|
)
|
|
49060
50274
|
] }),
|
|
50275
|
+
filteredData.length === 0 && search ? /* @__PURE__ */ jsxRuntime.jsx(EntityList.NoMatch, { message: "No MCP Servers match your search" }) : null,
|
|
49061
50276
|
filteredData.map((server) => /* @__PURE__ */ jsxRuntime.jsx(McpServerRow, { server }, server.id))
|
|
49062
50277
|
] });
|
|
49063
50278
|
}
|
|
@@ -49971,7 +51186,7 @@ function SkillsTable({
|
|
|
49971
51186
|
/* @__PURE__ */ jsxRuntime.jsx(EntryList.Header, { columns: effectiveColumns }),
|
|
49972
51187
|
skills.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(EntryList.Entries, { children: skills.map((skill) => {
|
|
49973
51188
|
const entry = {
|
|
49974
|
-
id: skill.
|
|
51189
|
+
id: skill.path,
|
|
49975
51190
|
name: skill.name,
|
|
49976
51191
|
description: skill.description || "—"
|
|
49977
51192
|
};
|
|
@@ -49982,7 +51197,7 @@ function SkillsTable({
|
|
|
49982
51197
|
entry,
|
|
49983
51198
|
columns: effectiveColumns,
|
|
49984
51199
|
onClick: () => {
|
|
49985
|
-
const url = `${basePath}/${encodeURIComponent(skill.name)}`;
|
|
51200
|
+
const url = `${basePath}/${encodeURIComponent(skill.name)}?path=${encodeURIComponent(skill.path)}`;
|
|
49986
51201
|
navigate(url);
|
|
49987
51202
|
},
|
|
49988
51203
|
children: [
|
|
@@ -50017,7 +51232,7 @@ function SkillsTable({
|
|
|
50017
51232
|
] }) })
|
|
50018
51233
|
]
|
|
50019
51234
|
},
|
|
50020
|
-
skill.
|
|
51235
|
+
skill.path
|
|
50021
51236
|
);
|
|
50022
51237
|
}) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
50023
51238
|
EntryList.Message,
|
|
@@ -51284,6 +52499,7 @@ exports.Breadcrumb = Breadcrumb$1;
|
|
|
51284
52499
|
exports.Button = Button;
|
|
51285
52500
|
exports.ButtonWithTooltip = ButtonWithTooltip;
|
|
51286
52501
|
exports.ButtonsGroup = ButtonsGroup;
|
|
52502
|
+
exports.CHART_COLORS = CHART_COLORS;
|
|
51287
52503
|
exports.CODE_AGENT_OVERRIDE_SECTIONS = CODE_AGENT_OVERRIDE_SECTIONS;
|
|
51288
52504
|
exports.CSVImportDialog = CSVImportDialog;
|
|
51289
52505
|
exports.Cell = Cell;
|
|
@@ -51334,6 +52550,7 @@ exports.DatasetVersionsPanel = DatasetVersionsPanel;
|
|
|
51334
52550
|
exports.DatasetsList = DatasetsList;
|
|
51335
52551
|
exports.DatasetsTable = DatasetsTable;
|
|
51336
52552
|
exports.DatePicker = DatePicker;
|
|
52553
|
+
exports.DateRangeSelector = DateRangeSelector;
|
|
51337
52554
|
exports.DateTimeCell = DateTimeCell;
|
|
51338
52555
|
exports.DateTimePicker = DateTimePicker;
|
|
51339
52556
|
exports.DateTimePickerContent = DateTimePickerContent;
|
|
@@ -51407,6 +52624,7 @@ exports.HeaderAction = HeaderAction;
|
|
|
51407
52624
|
exports.HeaderGroup = HeaderGroup;
|
|
51408
52625
|
exports.HeaderTitle = HeaderTitle;
|
|
51409
52626
|
exports.HomeIcon = HomeIcon;
|
|
52627
|
+
exports.HorizontalBars = HorizontalBars;
|
|
51410
52628
|
exports.HoverPopover = HoverPopover;
|
|
51411
52629
|
exports.Icon = Icon;
|
|
51412
52630
|
exports.InfoIcon = InfoIcon;
|
|
@@ -51425,6 +52643,7 @@ exports.KeyValueList = KeyValueList;
|
|
|
51425
52643
|
exports.LLMModels = LLMModels;
|
|
51426
52644
|
exports.LLMProviders = LLMProviders;
|
|
51427
52645
|
exports.Label = Label;
|
|
52646
|
+
exports.LatencyCard = LatencyCard;
|
|
51428
52647
|
exports.LatencyIcon = LatencyIcon;
|
|
51429
52648
|
exports.LinkComponentProvider = LinkComponentProvider;
|
|
51430
52649
|
exports.ListSearch = ListSearch;
|
|
@@ -51456,6 +52675,12 @@ exports.MemoryIcon = MemoryIcon;
|
|
|
51456
52675
|
exports.MemoryPage = MemoryPage;
|
|
51457
52676
|
exports.MemorySearch = MemorySearch;
|
|
51458
52677
|
exports.MemorySection = MemorySection;
|
|
52678
|
+
exports.MetricsCard = MetricsCard;
|
|
52679
|
+
exports.MetricsDashboard = MetricsDashboard;
|
|
52680
|
+
exports.MetricsDataTable = MetricsDataTable;
|
|
52681
|
+
exports.MetricsKpiCard = MetricsKpiCard;
|
|
52682
|
+
exports.MetricsProvider = MetricsProvider;
|
|
52683
|
+
exports.ModelUsageCostCard = ModelUsageCostCard;
|
|
51459
52684
|
exports.MultiColumn = MultiColumn;
|
|
51460
52685
|
exports.MultiCombobox = MultiCombobox;
|
|
51461
52686
|
exports.NavigationCommand = NavigationCommand;
|
|
@@ -51523,6 +52748,7 @@ exports.ScorersList = ScorersList;
|
|
|
51523
52748
|
exports.ScorersPage = ScorersPage;
|
|
51524
52749
|
exports.ScorersSection = ScorersSection;
|
|
51525
52750
|
exports.ScorersTable = ScorersTable;
|
|
52751
|
+
exports.ScoresCard = ScoresCard;
|
|
51526
52752
|
exports.ScoresList = ScoresList;
|
|
51527
52753
|
exports.ScoresTools = ScoresTools;
|
|
51528
52754
|
exports.ScrollArea = ScrollArea;
|
|
@@ -51587,6 +52813,7 @@ exports.ThreadLink = ThreadLink;
|
|
|
51587
52813
|
exports.ThreadList = ThreadList;
|
|
51588
52814
|
exports.Threads = Threads;
|
|
51589
52815
|
exports.TimePicker = TimePicker;
|
|
52816
|
+
exports.TokenUsageByAgentCard = TokenUsageByAgentCard;
|
|
51590
52817
|
exports.ToolCoinIcon = ToolCoinIcon;
|
|
51591
52818
|
exports.ToolCombobox = ToolCombobox;
|
|
51592
52819
|
exports.ToolFallback = ToolFallback;
|
|
@@ -51613,6 +52840,7 @@ exports.TraceTimelineSpan = TraceTimelineSpan;
|
|
|
51613
52840
|
exports.TraceTimelineTools = TraceTimelineTools;
|
|
51614
52841
|
exports.TracesList = TracesList;
|
|
51615
52842
|
exports.TracesTools = TracesTools;
|
|
52843
|
+
exports.TracesVolumeCard = TracesVolumeCard;
|
|
51616
52844
|
exports.TracingSettingsContext = TracingSettingsContext;
|
|
51617
52845
|
exports.TracingSettingsProvider = TracingSettingsProvider;
|
|
51618
52846
|
exports.Tree = Tree;
|
|
@@ -51670,6 +52898,7 @@ exports.fieldConfig = fieldConfig;
|
|
|
51670
52898
|
exports.fieldsToJSONSchema = fieldsToJSONSchema;
|
|
51671
52899
|
exports.findProviderById = findProviderById;
|
|
51672
52900
|
exports.flattenSchemaToVariables = flattenSchemaToVariables;
|
|
52901
|
+
exports.formatCompact = formatCompact;
|
|
51673
52902
|
exports.formatHierarchicalSpans = formatHierarchicalSpans;
|
|
51674
52903
|
exports.getChildFieldOptions = getChildFieldOptions;
|
|
51675
52904
|
exports.getColumnTemplate = getColumnTemplate;
|
|
@@ -51692,6 +52921,7 @@ exports.isActive = isActive;
|
|
|
51692
52921
|
exports.isAuthenticated = isAuthenticated;
|
|
51693
52922
|
exports.isRule = isRule;
|
|
51694
52923
|
exports.isRuleGroup = isRuleGroup;
|
|
52924
|
+
exports.isValidPreset = isValidPreset;
|
|
51695
52925
|
exports.joinModelId = joinModelId;
|
|
51696
52926
|
exports.jsonSchemaToFields = jsonSchemaToFields;
|
|
51697
52927
|
exports.makeAuthCapabilitiesRequest = makeAuthCapabilitiesRequest;
|
|
@@ -51736,6 +52966,7 @@ exports.useAgentEditForm = useAgentEditForm;
|
|
|
51736
52966
|
exports.useAgentEditFormContext = useAgentEditFormContext;
|
|
51737
52967
|
exports.useAgentExperiments = useAgentExperiments;
|
|
51738
52968
|
exports.useAgentInformationTab = useAgentInformationTab;
|
|
52969
|
+
exports.useAgentRunsKpiMetrics = useAgentRunsKpiMetrics;
|
|
51739
52970
|
exports.useAgentSettings = useAgentSettings;
|
|
51740
52971
|
exports.useAgentSkill = useAgentSkill;
|
|
51741
52972
|
exports.useAgentVersion = useAgentVersion;
|
|
@@ -51744,6 +52975,7 @@ exports.useAgents = useAgents;
|
|
|
51744
52975
|
exports.useAllIntegrationTools = useAllIntegrationTools;
|
|
51745
52976
|
exports.useAllModels = useAllModels;
|
|
51746
52977
|
exports.useAuthCapabilities = useAuthCapabilities;
|
|
52978
|
+
exports.useAvgScoreKpiMetrics = useAvgScoreKpiMetrics;
|
|
51747
52979
|
exports.useCSVParser = useCSVParser;
|
|
51748
52980
|
exports.useCloneThread = useCloneThread;
|
|
51749
52981
|
exports.useCodemirrorTheme = useCodemirrorTheme$1;
|
|
@@ -51795,6 +53027,7 @@ exports.useJSONSchemaForm = useJSONSchemaForm;
|
|
|
51795
53027
|
exports.useJSONSchemaFormField = useJSONSchemaFormField;
|
|
51796
53028
|
exports.useJSONSchemaFormNestedContext = useJSONSchemaFormNestedContext;
|
|
51797
53029
|
exports.useLLMProviders = useLLMProviders;
|
|
53030
|
+
exports.useLatencyMetrics = useLatencyMetrics;
|
|
51798
53031
|
exports.useLinkComponent = useLinkComponent;
|
|
51799
53032
|
exports.useLogout = useLogout;
|
|
51800
53033
|
exports.useMCPServerTool = useMCPServerTool;
|
|
@@ -51810,6 +53043,9 @@ exports.useMemoryConfig = useMemoryConfig;
|
|
|
51810
53043
|
exports.useMemorySearch = useMemorySearch;
|
|
51811
53044
|
exports.useMemoryWithOMStatus = useMemoryWithOMStatus;
|
|
51812
53045
|
exports.useMergedRequestContext = useMergedRequestContext;
|
|
53046
|
+
exports.useMetrics = useMetrics;
|
|
53047
|
+
exports.useMetricsFilters = useMetricsFilters;
|
|
53048
|
+
exports.useModelUsageCostMetrics = useModelUsageCostMetrics;
|
|
51813
53049
|
exports.useNavigationCommand = useNavigationCommand;
|
|
51814
53050
|
exports.useObservationalMemory = useObservationalMemory;
|
|
51815
53051
|
exports.useObservationalMemoryContext = useObservationalMemoryContext;
|
|
@@ -51842,6 +53078,7 @@ exports.useScorerVersions = useScorerVersions;
|
|
|
51842
53078
|
exports.useScorers = useScorers;
|
|
51843
53079
|
exports.useScoresByExperimentId = useScoresByExperimentId;
|
|
51844
53080
|
exports.useScoresByScorerId = useScoresByScorerId;
|
|
53081
|
+
exports.useScoresMetrics = useScoresMetrics;
|
|
51845
53082
|
exports.useSearchSkillsSh = useSearchSkillsSh;
|
|
51846
53083
|
exports.useSearchWorkspace = useSearchWorkspace;
|
|
51847
53084
|
exports.useSearchWorkspaceSkills = useSearchWorkspaceSkills;
|
|
@@ -51861,11 +53098,14 @@ exports.useTableKeyboardNavigation = useTableKeyboardNavigation;
|
|
|
51861
53098
|
exports.useThread = useThread;
|
|
51862
53099
|
exports.useThreadInput = useThreadInput;
|
|
51863
53100
|
exports.useThreads = useThreads;
|
|
53101
|
+
exports.useTokenUsageByAgentMetrics = useTokenUsageByAgentMetrics;
|
|
51864
53102
|
exports.useTool = useTool;
|
|
51865
53103
|
exports.useToolProviders = useToolProviders;
|
|
51866
53104
|
exports.useToolkits = useToolkits;
|
|
51867
53105
|
exports.useTools = useTools;
|
|
53106
|
+
exports.useTotalTokensKpiMetrics = useTotalTokensKpiMetrics;
|
|
51868
53107
|
exports.useTraceSpanScores = useTraceSpanScores;
|
|
53108
|
+
exports.useTraceVolumeMetrics = useTraceVolumeMetrics;
|
|
51869
53109
|
exports.useTracingSettings = useTracingSettings;
|
|
51870
53110
|
exports.useTryConnectMcp = useTryConnectMcp;
|
|
51871
53111
|
exports.useUpdateAgentModel = useUpdateAgentModel;
|