agentic-ui-libs 1.2.0-beta.20 → 1.2.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/agentic-ui-libs.css +73 -0
- package/dist/features/dashboard/AnalyticsChart.d.ts.map +1 -1
- package/dist/features/dashboard/Dashboard.d.ts.map +1 -1
- package/dist/features/dashboard/DashboardSection.d.ts.map +1 -1
- package/dist/features/dashboard/MetricCard.d.ts.map +1 -1
- package/dist/features/dashboard/ModelListView.d.ts +1 -0
- package/dist/features/dashboard/ModelListView.d.ts.map +1 -1
- package/dist/features/dashboard/ToolListView.d.ts.map +1 -1
- package/dist/features/debug-logs/services/TreeBuilder.d.ts +9 -0
- package/dist/features/debug-logs/services/TreeBuilder.d.ts.map +1 -1
- package/dist/features/tracing/components/SessionsList.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/DetailPage.d.ts +1 -1
- package/dist/features/tracing/components/detail/DetailPage.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts +58 -0
- package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts.map +1 -0
- package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts +11 -0
- package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts.map +1 -0
- package/dist/features/tracing/components/detail/index.d.ts +2 -0
- package/dist/features/tracing/components/detail/index.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/services/DetailPageService.d.ts +1 -0
- package/dist/features/tracing/components/detail/services/DetailPageService.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/types.d.ts +19 -0
- package/dist/features/tracing/components/detail/types.d.ts.map +1 -1
- package/dist/features/tracing/types.d.ts +11 -0
- package/dist/features/tracing/types.d.ts.map +1 -1
- package/dist/index.js +1253 -373
- package/dist/lib/dashboard-api.service.d.ts +1 -0
- package/dist/lib/dashboard-api.service.d.ts.map +1 -1
- package/dist/shared/types/index.d.ts +7 -0
- package/dist/shared/types/index.d.ts.map +1 -1
- package/dist/ui-libs.umd.js +1253 -373
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4291,7 +4291,7 @@ const MetricCard = ({
|
|
|
4291
4291
|
onClick,
|
|
4292
4292
|
isFirst = false
|
|
4293
4293
|
}) => {
|
|
4294
|
-
const { title, value, change, info, highlighted } = data;
|
|
4294
|
+
const { title, value, change, info, highlighted, failedCount } = data;
|
|
4295
4295
|
const formatValue2 = (val) => {
|
|
4296
4296
|
if (typeof val === "number") {
|
|
4297
4297
|
return val.toLocaleString();
|
|
@@ -4345,6 +4345,11 @@ const MetricCard = ({
|
|
|
4345
4345
|
] }),
|
|
4346
4346
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline gap-3", "data-test-id": `dashboard_metric_card_value_container_${data.metricType || data.title.toLowerCase().replace(/\s+/g, "_")}`, children: [
|
|
4347
4347
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl font-semibold text-gray-900", "data-test-id": `dashboard_metric_card_value_${data.metricType || data.title.toLowerCase().replace(/\s+/g, "_")}`, children: formatValue2(value) }),
|
|
4348
|
+
(failedCount ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-medium text-red-500", "data-test-id": `dashboard_metric_card_failed_${data.metricType}`, children: [
|
|
4349
|
+
"(",
|
|
4350
|
+
failedCount,
|
|
4351
|
+
" failed)"
|
|
4352
|
+
] }),
|
|
4348
4353
|
change && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4349
4354
|
"div",
|
|
4350
4355
|
{
|
|
@@ -21355,7 +21360,7 @@ function _toPrimitive$g(t2, r2) {
|
|
|
21355
21360
|
if ("object" != _typeof$i(i2)) return i2;
|
|
21356
21361
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
21357
21362
|
}
|
|
21358
|
-
return
|
|
21363
|
+
return String(t2);
|
|
21359
21364
|
}
|
|
21360
21365
|
var Bar = /* @__PURE__ */ function(_PureComponent) {
|
|
21361
21366
|
function Bar2() {
|
|
@@ -28662,7 +28667,7 @@ const CustomTooltip = ({
|
|
|
28662
28667
|
return null;
|
|
28663
28668
|
}
|
|
28664
28669
|
const filteredPayload = payload.filter(
|
|
28665
|
-
(entry) => entry.name && entry.name !== "" && entry.name !== entry.dataKey
|
|
28670
|
+
(entry) => entry.name && entry.name !== "" && entry.name !== entry.dataKey && entry.value != null && !(typeof entry.value === "number" && Number.isNaN(entry.value)) && !(entry.dataKey === "failedModelRuns" && Number(entry.value) === 0)
|
|
28666
28671
|
);
|
|
28667
28672
|
if (filteredPayload.length === 0) {
|
|
28668
28673
|
return null;
|
|
@@ -28762,6 +28767,7 @@ const AnalyticsChart = ({
|
|
|
28762
28767
|
agentRuns: 0,
|
|
28763
28768
|
toolRuns: 0,
|
|
28764
28769
|
modelRuns: 0,
|
|
28770
|
+
failedModelRuns: null,
|
|
28765
28771
|
codeTools: 0,
|
|
28766
28772
|
workflowTools: 0,
|
|
28767
28773
|
knowledgeTools: 0,
|
|
@@ -28864,6 +28870,8 @@ const AnalyticsChart = ({
|
|
|
28864
28870
|
label: config2.title,
|
|
28865
28871
|
strokeWidth: 2
|
|
28866
28872
|
}];
|
|
28873
|
+
const lineSeries = chartLines.filter((c3) => (c3.seriesType ?? "line") === "line");
|
|
28874
|
+
const barSeries = chartLines.filter((c3) => c3.seriesType === "bar");
|
|
28867
28875
|
if (isLoading) {
|
|
28868
28876
|
console.log("AnalyticsChart: Loading state active");
|
|
28869
28877
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ChartSkeleton, { className, chartType: config2.type, height });
|
|
@@ -28970,7 +28978,7 @@ const AnalyticsChart = ({
|
|
|
28970
28978
|
bottom: 20
|
|
28971
28979
|
},
|
|
28972
28980
|
children: [
|
|
28973
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children:
|
|
28981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: lineSeries.map((lineConfig, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("linearGradient", { id: `gradient-${lineConfig.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
28974
28982
|
/* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "5%", stopColor: lineConfig.color, stopOpacity: 0.08 }),
|
|
28975
28983
|
/* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "95%", stopColor: lineConfig.color, stopOpacity: 0.01 })
|
|
28976
28984
|
] }, `gradient-${index}`)) }),
|
|
@@ -29022,7 +29030,7 @@ const AnalyticsChart = ({
|
|
|
29022
29030
|
allowEscapeViewBox: { x: false, y: false }
|
|
29023
29031
|
}
|
|
29024
29032
|
),
|
|
29025
|
-
|
|
29033
|
+
lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29026
29034
|
Area,
|
|
29027
29035
|
{
|
|
29028
29036
|
type: "monotone",
|
|
@@ -29030,12 +29038,13 @@ const AnalyticsChart = ({
|
|
|
29030
29038
|
stroke: "none",
|
|
29031
29039
|
fill: `url(#gradient-${lineConfig.dataKey})`,
|
|
29032
29040
|
fillOpacity: 1,
|
|
29041
|
+
connectNulls: false,
|
|
29033
29042
|
isAnimationActive: false,
|
|
29034
29043
|
name: ""
|
|
29035
29044
|
},
|
|
29036
29045
|
`area-${lineConfig.dataKey}`
|
|
29037
29046
|
)),
|
|
29038
|
-
|
|
29047
|
+
lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29039
29048
|
Line,
|
|
29040
29049
|
{
|
|
29041
29050
|
type: "monotone",
|
|
@@ -29043,6 +29052,7 @@ const AnalyticsChart = ({
|
|
|
29043
29052
|
stroke: lineConfig.color,
|
|
29044
29053
|
strokeWidth: 2.5,
|
|
29045
29054
|
strokeDasharray: lineConfig.strokeDasharray,
|
|
29055
|
+
connectNulls: false,
|
|
29046
29056
|
dot: false,
|
|
29047
29057
|
activeDot: {
|
|
29048
29058
|
r: 5,
|
|
@@ -29053,6 +29063,19 @@ const AnalyticsChart = ({
|
|
|
29053
29063
|
name: lineConfig.label
|
|
29054
29064
|
},
|
|
29055
29065
|
lineConfig.dataKey
|
|
29066
|
+
)),
|
|
29067
|
+
barSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29068
|
+
Bar,
|
|
29069
|
+
{
|
|
29070
|
+
dataKey: lineConfig.dataKey,
|
|
29071
|
+
fill: lineConfig.color,
|
|
29072
|
+
fillOpacity: 0.9,
|
|
29073
|
+
name: lineConfig.label,
|
|
29074
|
+
maxBarSize: 14,
|
|
29075
|
+
radius: [3, 3, 0, 0],
|
|
29076
|
+
isAnimationActive: false
|
|
29077
|
+
},
|
|
29078
|
+
`bar-${lineConfig.dataKey}`
|
|
29056
29079
|
))
|
|
29057
29080
|
]
|
|
29058
29081
|
}
|
|
@@ -29074,8 +29097,15 @@ const AnalyticsChart = ({
|
|
|
29074
29097
|
})
|
|
29075
29098
|
] })
|
|
29076
29099
|
] }) }),
|
|
29077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4", "data-test-id": "dashboard_analytics_chart_legend", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", "data-test-id": "dashboard_analytics_chart_legend_items", children: chartLines.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", "data-test-id": `dashboard_analytics_chart_legend_item_${lineConfig.dataKey}`, children: [
|
|
29078
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4", "data-test-id": "dashboard_analytics_chart_legend", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", "data-test-id": "dashboard_analytics_chart_legend_items", children: chartLines.filter((lineConfig) => !lineConfig.hideInLegend).map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", "data-test-id": `dashboard_analytics_chart_legend_item_${lineConfig.dataKey}`, children: [
|
|
29101
|
+
lineConfig.seriesType === "bar" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29102
|
+
"div",
|
|
29103
|
+
{
|
|
29104
|
+
className: "w-2 h-2 rounded-[2px]",
|
|
29105
|
+
style: { backgroundColor: lineConfig.color },
|
|
29106
|
+
"data-test-id": `dashboard_analytics_chart_legend_color_${lineConfig.dataKey}`
|
|
29107
|
+
}
|
|
29108
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29079
29109
|
"div",
|
|
29080
29110
|
{
|
|
29081
29111
|
className: "w-[8px] h-[8px] rounded-full",
|
|
@@ -29632,6 +29662,8 @@ function getToolTypeStyle(type) {
|
|
|
29632
29662
|
return "bg-green-100 text-green-800 border-green-200";
|
|
29633
29663
|
if (["knowledge", "KNOWLEDGE", "knowledge tool"].includes(type) || ["knowledge", "knowledge tool"].includes(normalized))
|
|
29634
29664
|
return "bg-purple-100 text-purple-800 border-purple-200";
|
|
29665
|
+
if (["PRE_PROCESSOR", "POST_PROCESSOR", "INPUT_PROCESSOR", "input_processor", "pre_processor", "post_processor", "processor"].includes(type) || ["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized))
|
|
29666
|
+
return "bg-yellow-100 text-yellow-800 border-yellow-200";
|
|
29635
29667
|
return "bg-gray-100 text-gray-800 border-gray-200";
|
|
29636
29668
|
}
|
|
29637
29669
|
function getToolTypeName(type) {
|
|
@@ -29640,6 +29672,8 @@ function getToolTypeName(type) {
|
|
|
29640
29672
|
if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
|
|
29641
29673
|
if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
|
|
29642
29674
|
if (["knowledge", "knowledge tool", "knowledge"].includes(normalized) || type === "KNOWLEDGE") return "Knowledge";
|
|
29675
|
+
if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized) || type === "PRE_PROCESSOR" || type === "POST_PROCESSOR" || type === "INPUT_PROCESSOR" || type === "input_processor")
|
|
29676
|
+
return "Processor";
|
|
29643
29677
|
if (type === "inlineTool") return "Code Tool";
|
|
29644
29678
|
if (type === "toolLibrary") return "Workflow Tool";
|
|
29645
29679
|
if (type === "KNOWLEDGE") return "Knowledge";
|
|
@@ -29866,7 +29900,14 @@ const ModelListView = ({
|
|
|
29866
29900
|
model.provider && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 truncate", "data-test-id": `dashboard_model_list_view_row_provider_${index}`, children: getProviderDisplayName(model.provider) })
|
|
29867
29901
|
] })
|
|
29868
29902
|
] }),
|
|
29869
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
29903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center font-medium text-xs text-gray-700 flex items-center justify-center gap-1", "data-test-id": `dashboard_model_list_view_row_runs_${index}`, children: [
|
|
29904
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatValue2(model.runs || 0) }),
|
|
29905
|
+
(model.failedRuns ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-red-500 text-[10px] font-medium", "data-test-id": `dashboard_model_list_view_row_failed_${index}`, children: [
|
|
29906
|
+
"(",
|
|
29907
|
+
model.failedRuns,
|
|
29908
|
+
" failed)"
|
|
29909
|
+
] })
|
|
29910
|
+
] }),
|
|
29870
29911
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center font-medium text-xs text-gray-700", "data-test-id": `dashboard_model_list_view_row_tokens_${index}`, children: formatValue2(model.tokens || model.totalTokens || 0) }),
|
|
29871
29912
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center font-medium text-xs text-gray-700", "data-test-id": `dashboard_model_list_view_row_response_time_${index}`, children: model.responseTime || (model.avgResponseTime ? `${model.avgResponseTime}ms` : "N/A") })
|
|
29872
29913
|
]
|
|
@@ -30546,6 +30587,7 @@ class DashboardApiService {
|
|
|
30546
30587
|
{
|
|
30547
30588
|
title: "Model Runs",
|
|
30548
30589
|
value: data.data.modelRuns,
|
|
30590
|
+
failedCount: data.data.failedModelRuns || 0,
|
|
30549
30591
|
metricType: "modelRuns",
|
|
30550
30592
|
icon: "cpu",
|
|
30551
30593
|
info: "Number of times the AI agents called various language models to generate responses",
|
|
@@ -30622,8 +30664,12 @@ class DashboardApiService {
|
|
|
30622
30664
|
basePoint.toolRuns = point2.count || 0;
|
|
30623
30665
|
break;
|
|
30624
30666
|
case "modelRuns":
|
|
30667
|
+
case "modelruns": {
|
|
30668
|
+
const failed = point2.failedModelRuns;
|
|
30625
30669
|
basePoint.modelRuns = point2.count || 0;
|
|
30670
|
+
basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
|
|
30626
30671
|
break;
|
|
30672
|
+
}
|
|
30627
30673
|
default:
|
|
30628
30674
|
basePoint.users = point2.count || 0;
|
|
30629
30675
|
basePoint.sessions = point2.count || 0;
|
|
@@ -30632,6 +30678,10 @@ class DashboardApiService {
|
|
|
30632
30678
|
basePoint.agentRuns = point2.count || 0;
|
|
30633
30679
|
basePoint.toolRuns = point2.count || 0;
|
|
30634
30680
|
basePoint.modelRuns = point2.count || 0;
|
|
30681
|
+
{
|
|
30682
|
+
const failed = point2.failedModelRuns;
|
|
30683
|
+
basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
|
|
30684
|
+
}
|
|
30635
30685
|
}
|
|
30636
30686
|
console.log(`Transformed point ${index} for metric ${metricType}:`, basePoint);
|
|
30637
30687
|
return basePoint;
|
|
@@ -30716,22 +30766,16 @@ class DashboardApiService {
|
|
|
30716
30766
|
id: `model-${index + 1}`,
|
|
30717
30767
|
name: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName || `Model ${index + 1}`,
|
|
30718
30768
|
modelName: item.modelName,
|
|
30719
|
-
// Keep original modelName field
|
|
30720
30769
|
provider: item.provider,
|
|
30721
|
-
// Include provider information
|
|
30722
30770
|
runs: item.count || 0,
|
|
30771
|
+
failedRuns: item.failedRuns || 0,
|
|
30723
30772
|
responseTime: item.avgResponseTime ? item.avgResponseTime < 1e3 ? `${Math.round(item.avgResponseTime)}ms` : `${(item.avgResponseTime / 1e3).toFixed(2)}s` : "0ms",
|
|
30724
30773
|
avgResponseTime: item.avgResponseTime,
|
|
30725
|
-
// Keep original avgResponseTime
|
|
30726
30774
|
tokens: item.tokens || item.totalTokens || Math.floor((item.count || 0) * 300),
|
|
30727
|
-
// Use actual token data when available
|
|
30728
30775
|
totalTokens: item.totalTokens || item.tokens,
|
|
30729
|
-
// Include totalTokens field
|
|
30730
30776
|
successRate: item.successRate ? `${Math.round(item.successRate)}%` : "98%",
|
|
30731
|
-
// Default success rate for models
|
|
30732
30777
|
lastRun: item.lastRun || new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1e3).toLocaleDateString(),
|
|
30733
30778
|
icon: item.icon
|
|
30734
|
-
// Preserve original icon data if available
|
|
30735
30779
|
}));
|
|
30736
30780
|
}
|
|
30737
30781
|
// Extract control options from listView data for agents
|
|
@@ -30785,9 +30829,11 @@ class DashboardApiService {
|
|
|
30785
30829
|
if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
|
|
30786
30830
|
if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
|
|
30787
30831
|
if (["knowledge", "knowledge tool"].includes(normalized) || toolType === "KNOWLEDGE") return "Knowledge";
|
|
30832
|
+
if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized)) return "Processor";
|
|
30788
30833
|
if (toolType === "inlineTool") return "Code Tool";
|
|
30789
30834
|
if (toolType === "toolLibrary") return "Workflow Tool";
|
|
30790
30835
|
if (toolType === "MCP" || toolType === "mcpTool") return "MCP Tool";
|
|
30836
|
+
if (toolType === "PRE_PROCESSOR" || toolType === "POST_PROCESSOR" || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") return "Processor";
|
|
30791
30837
|
return "Code Tool";
|
|
30792
30838
|
};
|
|
30793
30839
|
options.push({
|
|
@@ -30914,6 +30960,7 @@ class DashboardApiService {
|
|
|
30914
30960
|
if (aggregated.has(key)) {
|
|
30915
30961
|
const existing = aggregated.get(key);
|
|
30916
30962
|
existing.count = (existing.count || 0) + (item.count || 0);
|
|
30963
|
+
existing.failedRuns = (existing.failedRuns || 0) + (item.failedRuns || 0);
|
|
30917
30964
|
existing.avgResponseTime = existing.avgResponseTime && item.avgResponseTime ? (existing.avgResponseTime + item.avgResponseTime) / 2 : existing.avgResponseTime || item.avgResponseTime;
|
|
30918
30965
|
existing.tokens = (existing.tokens || 0) + (item.tokens || 0);
|
|
30919
30966
|
} else {
|
|
@@ -30925,11 +30972,24 @@ class DashboardApiService {
|
|
|
30925
30972
|
// Batch fetch enhanced data for all metrics with table and control data
|
|
30926
30973
|
async fetchEnhancedMetricsData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
30927
30974
|
try {
|
|
30928
|
-
const
|
|
30975
|
+
const results = await Promise.allSettled([
|
|
30929
30976
|
this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30930
30977
|
this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30931
30978
|
this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
30932
30979
|
]);
|
|
30980
|
+
if (results[0].status === "rejected") {
|
|
30981
|
+
console.error("Error fetching agent runs enhanced data:", results[0].reason);
|
|
30982
|
+
}
|
|
30983
|
+
if (results[1].status === "rejected") {
|
|
30984
|
+
console.error("Error fetching tool runs enhanced data:", results[1].reason);
|
|
30985
|
+
}
|
|
30986
|
+
if (results[2].status === "rejected") {
|
|
30987
|
+
console.error("Error fetching model runs enhanced data:", results[2].reason);
|
|
30988
|
+
}
|
|
30989
|
+
const emptyData = { chartData: [], tableData: [], controlOptions: [] };
|
|
30990
|
+
const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyData;
|
|
30991
|
+
const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyData;
|
|
30992
|
+
const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyData;
|
|
30933
30993
|
return {
|
|
30934
30994
|
agents: agentsData,
|
|
30935
30995
|
tools: toolsData,
|
|
@@ -30946,13 +31006,30 @@ class DashboardApiService {
|
|
|
30946
31006
|
const getChangeType = (changePercent) => {
|
|
30947
31007
|
return changePercent > 0 ? "increase" : "decrease";
|
|
30948
31008
|
};
|
|
30949
|
-
const
|
|
31009
|
+
const results = await Promise.allSettled([
|
|
30950
31010
|
this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30951
31011
|
this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30952
31012
|
this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30953
31013
|
this.fetchTimeSeriesData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
30954
31014
|
]);
|
|
30955
|
-
|
|
31015
|
+
if (results[0].status === "rejected") {
|
|
31016
|
+
console.error("Error fetching agent runs data:", results[0].reason);
|
|
31017
|
+
}
|
|
31018
|
+
if (results[1].status === "rejected") {
|
|
31019
|
+
console.error("Error fetching tool runs data:", results[1].reason);
|
|
31020
|
+
}
|
|
31021
|
+
if (results[2].status === "rejected") {
|
|
31022
|
+
console.error("Error fetching model runs data:", results[2].reason);
|
|
31023
|
+
}
|
|
31024
|
+
if (results[3].status === "rejected") {
|
|
31025
|
+
console.error("Error fetching tool runs time series data:", results[3].reason);
|
|
31026
|
+
}
|
|
31027
|
+
const emptyEnhancedData = { chartData: [], tableData: [], controlOptions: [] };
|
|
31028
|
+
const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyEnhancedData;
|
|
31029
|
+
const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyEnhancedData;
|
|
31030
|
+
const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyEnhancedData;
|
|
31031
|
+
const toolRunsTimeSeriesData = results[3].status === "fulfilled" ? results[3].value : void 0;
|
|
31032
|
+
const enhancedToolRunsChartData = toolRunsTimeSeriesData ? this.transformTimeSeriesDataForToolRuns(toolRunsTimeSeriesData) : [];
|
|
30956
31033
|
return [
|
|
30957
31034
|
{
|
|
30958
31035
|
title: "Agent Runs",
|
|
@@ -30966,68 +31043,70 @@ class DashboardApiService {
|
|
|
30966
31043
|
value: Math.abs(trends.agentRuns.changePercent),
|
|
30967
31044
|
type: getChangeType(trends.agentRuns.changePercent)
|
|
30968
31045
|
} : void 0,
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
30980
|
-
|
|
30981
|
-
|
|
30982
|
-
|
|
30983
|
-
|
|
30984
|
-
|
|
30985
|
-
|
|
30986
|
-
},
|
|
30987
|
-
table: {
|
|
30988
|
-
title: "Agent Runs",
|
|
30989
|
-
data: agentsData.tableData,
|
|
30990
|
-
columns: [
|
|
30991
|
-
{
|
|
30992
|
-
key: "name",
|
|
30993
|
-
title: "Name",
|
|
30994
|
-
width: 200,
|
|
30995
|
-
align: "left"
|
|
30996
|
-
},
|
|
30997
|
-
{
|
|
30998
|
-
key: "runs",
|
|
30999
|
-
title: "Runs",
|
|
31000
|
-
width: 100,
|
|
31001
|
-
align: "right",
|
|
31002
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31003
|
-
},
|
|
31004
|
-
{
|
|
31005
|
-
key: "responseTime",
|
|
31006
|
-
title: "Response Time",
|
|
31007
|
-
width: 120,
|
|
31008
|
-
align: "right"
|
|
31009
|
-
},
|
|
31010
|
-
{
|
|
31011
|
-
key: "tokens",
|
|
31012
|
-
title: "Tokens",
|
|
31013
|
-
width: 100,
|
|
31014
|
-
align: "right",
|
|
31015
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31046
|
+
...agentsData && {
|
|
31047
|
+
view: {
|
|
31048
|
+
type: "chart",
|
|
31049
|
+
chart: {
|
|
31050
|
+
type: "line",
|
|
31051
|
+
title: "Agent Runs",
|
|
31052
|
+
data: agentsData.chartData,
|
|
31053
|
+
dataKey: "agentRuns",
|
|
31054
|
+
color: "#0BA5EC",
|
|
31055
|
+
yAxisLabel: "Number of Agent Runs",
|
|
31056
|
+
height: 300,
|
|
31057
|
+
showGrid: true,
|
|
31058
|
+
curve: "monotone",
|
|
31059
|
+
tooltip: { show: true, style: "dark" },
|
|
31060
|
+
dateRange: {
|
|
31061
|
+
start: fromTimestamp.split("T")[0],
|
|
31062
|
+
end: toTimestamp.split("T")[0]
|
|
31016
31063
|
}
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
|
|
31022
|
-
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31064
|
+
},
|
|
31065
|
+
table: {
|
|
31066
|
+
title: "Agent Runs",
|
|
31067
|
+
data: agentsData.tableData,
|
|
31068
|
+
columns: [
|
|
31069
|
+
{
|
|
31070
|
+
key: "name",
|
|
31071
|
+
title: "Name",
|
|
31072
|
+
width: 200,
|
|
31073
|
+
align: "left"
|
|
31074
|
+
},
|
|
31075
|
+
{
|
|
31076
|
+
key: "runs",
|
|
31077
|
+
title: "Runs",
|
|
31078
|
+
width: 100,
|
|
31079
|
+
align: "right",
|
|
31080
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31081
|
+
},
|
|
31082
|
+
{
|
|
31083
|
+
key: "responseTime",
|
|
31084
|
+
title: "Response Time",
|
|
31085
|
+
width: 120,
|
|
31086
|
+
align: "right"
|
|
31087
|
+
},
|
|
31088
|
+
{
|
|
31089
|
+
key: "tokens",
|
|
31090
|
+
title: "Tokens",
|
|
31091
|
+
width: 100,
|
|
31092
|
+
align: "right",
|
|
31093
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31094
|
+
}
|
|
31095
|
+
]
|
|
31096
|
+
}
|
|
31027
31097
|
},
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
31098
|
+
controls: {
|
|
31099
|
+
dropdown: {
|
|
31100
|
+
label: "All Agents",
|
|
31101
|
+
options: agentsData.controlOptions,
|
|
31102
|
+
defaultValue: ["all"],
|
|
31103
|
+
multiSelect: true,
|
|
31104
|
+
searchable: true
|
|
31105
|
+
},
|
|
31106
|
+
toggle: {
|
|
31107
|
+
chartView: true,
|
|
31108
|
+
tableView: true
|
|
31109
|
+
}
|
|
31031
31110
|
}
|
|
31032
31111
|
}
|
|
31033
31112
|
},
|
|
@@ -31042,99 +31121,107 @@ class DashboardApiService {
|
|
|
31042
31121
|
value: Math.abs(trends.toolRuns.changePercent.total),
|
|
31043
31122
|
type: getChangeType(trends.toolRuns.changePercent.total)
|
|
31044
31123
|
} : void 0,
|
|
31045
|
-
|
|
31046
|
-
|
|
31047
|
-
|
|
31048
|
-
|
|
31049
|
-
|
|
31050
|
-
|
|
31051
|
-
|
|
31052
|
-
|
|
31053
|
-
|
|
31054
|
-
|
|
31055
|
-
|
|
31056
|
-
|
|
31057
|
-
|
|
31058
|
-
|
|
31059
|
-
|
|
31060
|
-
|
|
31061
|
-
|
|
31062
|
-
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
|
|
31071
|
-
|
|
31072
|
-
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31124
|
+
...toolsData && {
|
|
31125
|
+
view: {
|
|
31126
|
+
type: "chart",
|
|
31127
|
+
chart: {
|
|
31128
|
+
type: "line",
|
|
31129
|
+
title: "Tool Runs",
|
|
31130
|
+
data: enhancedToolRunsChartData,
|
|
31131
|
+
yAxisLabel: "Number of Tool Runs",
|
|
31132
|
+
lines: [
|
|
31133
|
+
{
|
|
31134
|
+
dataKey: "toolRuns",
|
|
31135
|
+
color: "#667085",
|
|
31136
|
+
label: "Tool Runs"
|
|
31137
|
+
},
|
|
31138
|
+
{
|
|
31139
|
+
dataKey: "codeTools",
|
|
31140
|
+
color: "#F38744",
|
|
31141
|
+
label: "Code Tools"
|
|
31142
|
+
},
|
|
31143
|
+
{
|
|
31144
|
+
dataKey: "workflowTools",
|
|
31145
|
+
color: "#2970FF",
|
|
31146
|
+
label: "Workflow Tools"
|
|
31147
|
+
},
|
|
31148
|
+
{
|
|
31149
|
+
dataKey: "knowledgeTools",
|
|
31150
|
+
color: "#7A5AF8",
|
|
31151
|
+
label: "Knowledge"
|
|
31152
|
+
},
|
|
31153
|
+
{
|
|
31154
|
+
dataKey: "mcpTools",
|
|
31155
|
+
color: "#47CD89",
|
|
31156
|
+
label: "MCP Tools"
|
|
31157
|
+
},
|
|
31158
|
+
{
|
|
31159
|
+
dataKey: "processors",
|
|
31160
|
+
color: "#EAB308",
|
|
31161
|
+
label: "Processors"
|
|
31162
|
+
}
|
|
31163
|
+
],
|
|
31164
|
+
height: 300,
|
|
31165
|
+
showGrid: true,
|
|
31166
|
+
showLegend: true,
|
|
31167
|
+
curve: "monotone",
|
|
31168
|
+
tooltip: { show: true, style: "dark" },
|
|
31169
|
+
dateRange: {
|
|
31170
|
+
start: fromTimestamp.split("T")[0],
|
|
31171
|
+
end: toTimestamp.split("T")[0]
|
|
31077
31172
|
}
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
|
|
31083
|
-
|
|
31084
|
-
|
|
31085
|
-
|
|
31086
|
-
|
|
31173
|
+
},
|
|
31174
|
+
table: {
|
|
31175
|
+
title: "Tool Runs",
|
|
31176
|
+
data: toolsData.tableData,
|
|
31177
|
+
columns: [
|
|
31178
|
+
{
|
|
31179
|
+
key: "name",
|
|
31180
|
+
title: "Name",
|
|
31181
|
+
width: 200,
|
|
31182
|
+
align: "left"
|
|
31183
|
+
},
|
|
31184
|
+
{
|
|
31185
|
+
key: "type",
|
|
31186
|
+
title: "Type",
|
|
31187
|
+
width: 150,
|
|
31188
|
+
align: "left"
|
|
31189
|
+
},
|
|
31190
|
+
{
|
|
31191
|
+
key: "runs",
|
|
31192
|
+
title: "Runs",
|
|
31193
|
+
width: 100,
|
|
31194
|
+
align: "right",
|
|
31195
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31196
|
+
},
|
|
31197
|
+
{
|
|
31198
|
+
key: "responseTime",
|
|
31199
|
+
title: "Response Time",
|
|
31200
|
+
width: 120,
|
|
31201
|
+
align: "right"
|
|
31202
|
+
}
|
|
31203
|
+
]
|
|
31087
31204
|
}
|
|
31088
31205
|
},
|
|
31089
|
-
|
|
31090
|
-
|
|
31091
|
-
|
|
31092
|
-
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
title: "Type",
|
|
31102
|
-
width: 150,
|
|
31103
|
-
align: "left"
|
|
31104
|
-
},
|
|
31105
|
-
{
|
|
31106
|
-
key: "runs",
|
|
31107
|
-
title: "Runs",
|
|
31108
|
-
width: 100,
|
|
31109
|
-
align: "right",
|
|
31110
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31111
|
-
},
|
|
31112
|
-
{
|
|
31113
|
-
key: "responseTime",
|
|
31114
|
-
title: "Response Time",
|
|
31115
|
-
width: 120,
|
|
31116
|
-
align: "right"
|
|
31117
|
-
}
|
|
31118
|
-
]
|
|
31119
|
-
}
|
|
31120
|
-
},
|
|
31121
|
-
controls: {
|
|
31122
|
-
dropdown: {
|
|
31123
|
-
label: "All Tools",
|
|
31124
|
-
options: toolsData.controlOptions,
|
|
31125
|
-
defaultValue: ["all"],
|
|
31126
|
-
multiSelect: true,
|
|
31127
|
-
searchable: true
|
|
31128
|
-
},
|
|
31129
|
-
toggle: {
|
|
31130
|
-
chartView: true,
|
|
31131
|
-
tableView: true
|
|
31206
|
+
controls: {
|
|
31207
|
+
dropdown: {
|
|
31208
|
+
label: "All Tools",
|
|
31209
|
+
options: toolsData.controlOptions,
|
|
31210
|
+
defaultValue: ["all"],
|
|
31211
|
+
multiSelect: true,
|
|
31212
|
+
searchable: true
|
|
31213
|
+
},
|
|
31214
|
+
toggle: {
|
|
31215
|
+
chartView: true,
|
|
31216
|
+
tableView: true
|
|
31217
|
+
}
|
|
31132
31218
|
}
|
|
31133
31219
|
}
|
|
31134
31220
|
},
|
|
31135
31221
|
{
|
|
31136
31222
|
title: "Model Runs",
|
|
31137
31223
|
value: data.data.modelRuns,
|
|
31224
|
+
failedCount: data.data.failedModelRuns || 0,
|
|
31138
31225
|
metricType: "modelRuns",
|
|
31139
31226
|
icon: "cpu",
|
|
31140
31227
|
highlighted: false,
|
|
@@ -31143,68 +31230,79 @@ class DashboardApiService {
|
|
|
31143
31230
|
value: Math.abs(trends.modelRuns.changePercent),
|
|
31144
31231
|
type: getChangeType(trends.modelRuns.changePercent)
|
|
31145
31232
|
} : void 0,
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
{
|
|
31169
|
-
|
|
31170
|
-
|
|
31171
|
-
|
|
31172
|
-
align: "left"
|
|
31173
|
-
},
|
|
31174
|
-
{
|
|
31175
|
-
key: "runs",
|
|
31176
|
-
title: "Runs",
|
|
31177
|
-
width: 100,
|
|
31178
|
-
align: "right",
|
|
31179
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31180
|
-
},
|
|
31181
|
-
{
|
|
31182
|
-
key: "tokens",
|
|
31183
|
-
title: "Tokens",
|
|
31184
|
-
width: 120,
|
|
31185
|
-
align: "right",
|
|
31186
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31187
|
-
},
|
|
31188
|
-
{
|
|
31189
|
-
key: "responseTime",
|
|
31190
|
-
title: "Response Time",
|
|
31191
|
-
width: 120,
|
|
31192
|
-
align: "right"
|
|
31233
|
+
...modelsData && {
|
|
31234
|
+
view: {
|
|
31235
|
+
type: "chart",
|
|
31236
|
+
chart: {
|
|
31237
|
+
type: "line",
|
|
31238
|
+
title: "Model Runs",
|
|
31239
|
+
data: modelsData.chartData,
|
|
31240
|
+
yAxisLabel: "Number of Model Runs",
|
|
31241
|
+
lines: [
|
|
31242
|
+
{ dataKey: "modelRuns", color: "#47CD89", label: "Model Runs" },
|
|
31243
|
+
{
|
|
31244
|
+
dataKey: "failedModelRuns",
|
|
31245
|
+
color: "#ef4444",
|
|
31246
|
+
label: "Failed",
|
|
31247
|
+
seriesType: "bar",
|
|
31248
|
+
hideInLegend: true
|
|
31249
|
+
}
|
|
31250
|
+
],
|
|
31251
|
+
height: 300,
|
|
31252
|
+
showGrid: true,
|
|
31253
|
+
showLegend: true,
|
|
31254
|
+
curve: "monotone",
|
|
31255
|
+
tooltip: { show: true, style: "dark" },
|
|
31256
|
+
dateRange: {
|
|
31257
|
+
start: fromTimestamp.split("T")[0],
|
|
31258
|
+
end: toTimestamp.split("T")[0]
|
|
31193
31259
|
}
|
|
31194
|
-
|
|
31195
|
-
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
|
|
31201
|
-
|
|
31202
|
-
|
|
31203
|
-
|
|
31260
|
+
},
|
|
31261
|
+
table: {
|
|
31262
|
+
title: "Model Runs",
|
|
31263
|
+
data: modelsData.tableData,
|
|
31264
|
+
columns: [
|
|
31265
|
+
{
|
|
31266
|
+
key: "name",
|
|
31267
|
+
title: "Model Name",
|
|
31268
|
+
width: 200,
|
|
31269
|
+
align: "left"
|
|
31270
|
+
},
|
|
31271
|
+
{
|
|
31272
|
+
key: "runs",
|
|
31273
|
+
title: "Runs",
|
|
31274
|
+
width: 100,
|
|
31275
|
+
align: "right",
|
|
31276
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31277
|
+
},
|
|
31278
|
+
{
|
|
31279
|
+
key: "tokens",
|
|
31280
|
+
title: "Tokens",
|
|
31281
|
+
width: 120,
|
|
31282
|
+
align: "right",
|
|
31283
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31284
|
+
},
|
|
31285
|
+
{
|
|
31286
|
+
key: "responseTime",
|
|
31287
|
+
title: "Response Time",
|
|
31288
|
+
width: 120,
|
|
31289
|
+
align: "right"
|
|
31290
|
+
}
|
|
31291
|
+
]
|
|
31292
|
+
}
|
|
31204
31293
|
},
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31294
|
+
controls: {
|
|
31295
|
+
dropdown: {
|
|
31296
|
+
label: "All Models",
|
|
31297
|
+
options: modelsData.controlOptions,
|
|
31298
|
+
defaultValue: ["all"],
|
|
31299
|
+
multiSelect: true,
|
|
31300
|
+
searchable: true
|
|
31301
|
+
},
|
|
31302
|
+
toggle: {
|
|
31303
|
+
chartView: true,
|
|
31304
|
+
tableView: true
|
|
31305
|
+
}
|
|
31208
31306
|
}
|
|
31209
31307
|
}
|
|
31210
31308
|
}
|
|
@@ -31216,12 +31314,34 @@ class DashboardApiService {
|
|
|
31216
31314
|
const getChangeType = (changePercent) => {
|
|
31217
31315
|
return changePercent > 0 ? "increase" : "decrease";
|
|
31218
31316
|
};
|
|
31219
|
-
const
|
|
31317
|
+
const results = await Promise.allSettled([
|
|
31220
31318
|
this.fetchTimeSeriesData("users", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31221
31319
|
this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31222
31320
|
this.fetchTimeSeriesData("messages", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31223
31321
|
this.fetchTimeSeriesData("tokens", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31224
31322
|
]);
|
|
31323
|
+
if (results[0].status === "rejected") {
|
|
31324
|
+
console.error("Error fetching users data:", results[0].reason);
|
|
31325
|
+
}
|
|
31326
|
+
if (results[1].status === "rejected") {
|
|
31327
|
+
console.error("Error fetching sessions data:", results[1].reason);
|
|
31328
|
+
}
|
|
31329
|
+
if (results[2].status === "rejected") {
|
|
31330
|
+
console.error("Error fetching messages data:", results[2].reason);
|
|
31331
|
+
}
|
|
31332
|
+
if (results[3].status === "rejected") {
|
|
31333
|
+
console.error("Error fetching tokens data:", results[3].reason);
|
|
31334
|
+
}
|
|
31335
|
+
const emptyTimeSeries = {
|
|
31336
|
+
type: "time-series",
|
|
31337
|
+
category: "usage-analytics",
|
|
31338
|
+
metric: "",
|
|
31339
|
+
data: []
|
|
31340
|
+
};
|
|
31341
|
+
const usersData = results[0].status === "fulfilled" ? results[0].value : { ...emptyTimeSeries, metric: "users" };
|
|
31342
|
+
const sessionsData = results[1].status === "fulfilled" ? results[1].value : { ...emptyTimeSeries, metric: "sessions" };
|
|
31343
|
+
const messagesData = results[2].status === "fulfilled" ? results[2].value : { ...emptyTimeSeries, metric: "messages" };
|
|
31344
|
+
const tokensData = results[3].status === "fulfilled" ? results[3].value : { ...emptyTimeSeries, metric: "tokens" };
|
|
31225
31345
|
return [
|
|
31226
31346
|
{
|
|
31227
31347
|
title: "Users",
|
|
@@ -31235,22 +31355,24 @@ class DashboardApiService {
|
|
|
31235
31355
|
value: Math.abs(trends.users.changePercent),
|
|
31236
31356
|
type: getChangeType(trends.users.changePercent)
|
|
31237
31357
|
} : void 0,
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
|
|
31250
|
-
|
|
31251
|
-
|
|
31252
|
-
|
|
31253
|
-
|
|
31358
|
+
...usersData && {
|
|
31359
|
+
view: {
|
|
31360
|
+
type: "chart",
|
|
31361
|
+
chart: {
|
|
31362
|
+
type: "line",
|
|
31363
|
+
title: "Total Users",
|
|
31364
|
+
data: this.transformTimeSeriesDataForMetric(usersData, "users"),
|
|
31365
|
+
dataKey: "users",
|
|
31366
|
+
color: "#4E5BA6",
|
|
31367
|
+
yAxisLabel: "Number of Users",
|
|
31368
|
+
height: 300,
|
|
31369
|
+
showGrid: true,
|
|
31370
|
+
curve: "monotone",
|
|
31371
|
+
tooltip: { show: true, style: "dark" },
|
|
31372
|
+
dateRange: {
|
|
31373
|
+
start: fromTimestamp.split("T")[0],
|
|
31374
|
+
end: toTimestamp.split("T")[0]
|
|
31375
|
+
}
|
|
31254
31376
|
}
|
|
31255
31377
|
}
|
|
31256
31378
|
}
|
|
@@ -31266,22 +31388,24 @@ class DashboardApiService {
|
|
|
31266
31388
|
value: Math.abs(trends.sessions.changePercent),
|
|
31267
31389
|
type: getChangeType(trends.sessions.changePercent)
|
|
31268
31390
|
} : void 0,
|
|
31269
|
-
|
|
31270
|
-
|
|
31271
|
-
|
|
31272
|
-
|
|
31273
|
-
|
|
31274
|
-
|
|
31275
|
-
|
|
31276
|
-
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
|
|
31283
|
-
|
|
31284
|
-
|
|
31391
|
+
...sessionsData && {
|
|
31392
|
+
view: {
|
|
31393
|
+
type: "chart",
|
|
31394
|
+
chart: {
|
|
31395
|
+
type: "line",
|
|
31396
|
+
title: "Total Sessions",
|
|
31397
|
+
data: this.transformTimeSeriesDataForMetric(sessionsData, "sessions"),
|
|
31398
|
+
dataKey: "sessions",
|
|
31399
|
+
color: "#0BA5EC",
|
|
31400
|
+
yAxisLabel: "Number of Sessions",
|
|
31401
|
+
height: 300,
|
|
31402
|
+
showGrid: true,
|
|
31403
|
+
curve: "monotone",
|
|
31404
|
+
tooltip: { show: true, style: "dark" },
|
|
31405
|
+
dateRange: {
|
|
31406
|
+
start: fromTimestamp.split("T")[0],
|
|
31407
|
+
end: toTimestamp.split("T")[0]
|
|
31408
|
+
}
|
|
31285
31409
|
}
|
|
31286
31410
|
}
|
|
31287
31411
|
}
|
|
@@ -31297,22 +31421,24 @@ class DashboardApiService {
|
|
|
31297
31421
|
value: Math.abs(trends.messages.changePercent.total),
|
|
31298
31422
|
type: getChangeType(trends.messages.changePercent.total)
|
|
31299
31423
|
} : void 0,
|
|
31300
|
-
|
|
31301
|
-
|
|
31302
|
-
|
|
31303
|
-
|
|
31304
|
-
|
|
31305
|
-
|
|
31306
|
-
|
|
31307
|
-
|
|
31308
|
-
|
|
31309
|
-
|
|
31310
|
-
|
|
31311
|
-
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31424
|
+
...messagesData && {
|
|
31425
|
+
view: {
|
|
31426
|
+
type: "chart",
|
|
31427
|
+
chart: {
|
|
31428
|
+
type: "line",
|
|
31429
|
+
title: "Total Messages",
|
|
31430
|
+
data: this.transformTimeSeriesDataForMetric(messagesData, "messages"),
|
|
31431
|
+
dataKey: "messages",
|
|
31432
|
+
color: "#E478FA",
|
|
31433
|
+
yAxisLabel: "Number of Messages",
|
|
31434
|
+
height: 300,
|
|
31435
|
+
showGrid: true,
|
|
31436
|
+
curve: "monotone",
|
|
31437
|
+
tooltip: { show: true, style: "dark" },
|
|
31438
|
+
dateRange: {
|
|
31439
|
+
start: fromTimestamp.split("T")[0],
|
|
31440
|
+
end: toTimestamp.split("T")[0]
|
|
31441
|
+
}
|
|
31316
31442
|
}
|
|
31317
31443
|
}
|
|
31318
31444
|
}
|
|
@@ -31328,38 +31454,40 @@ class DashboardApiService {
|
|
|
31328
31454
|
value: Math.abs(trends.tokens.changePercent.total),
|
|
31329
31455
|
type: getChangeType(trends.tokens.changePercent.total)
|
|
31330
31456
|
} : void 0,
|
|
31331
|
-
|
|
31332
|
-
|
|
31333
|
-
|
|
31334
|
-
|
|
31335
|
-
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
|
|
31340
|
-
|
|
31341
|
-
|
|
31342
|
-
|
|
31343
|
-
|
|
31344
|
-
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
|
|
31348
|
-
|
|
31349
|
-
|
|
31350
|
-
|
|
31351
|
-
|
|
31352
|
-
|
|
31457
|
+
...tokensData && {
|
|
31458
|
+
view: {
|
|
31459
|
+
type: "chart",
|
|
31460
|
+
chart: {
|
|
31461
|
+
type: "line",
|
|
31462
|
+
title: "Token Usage Breakdown",
|
|
31463
|
+
data: this.transformTimeSeriesDataForMetric(tokensData, "tokens"),
|
|
31464
|
+
yAxisLabel: "Number of Tokens",
|
|
31465
|
+
lines: [
|
|
31466
|
+
{
|
|
31467
|
+
dataKey: "totalTokens",
|
|
31468
|
+
color: "#FF692E",
|
|
31469
|
+
label: "Total Tokens"
|
|
31470
|
+
},
|
|
31471
|
+
{
|
|
31472
|
+
dataKey: "inputTokens",
|
|
31473
|
+
color: "#5925DC",
|
|
31474
|
+
label: "Input Tokens"
|
|
31475
|
+
},
|
|
31476
|
+
{
|
|
31477
|
+
dataKey: "outputTokens",
|
|
31478
|
+
color: "#E478FA",
|
|
31479
|
+
label: "Output Tokens"
|
|
31480
|
+
}
|
|
31481
|
+
],
|
|
31482
|
+
height: 300,
|
|
31483
|
+
showGrid: true,
|
|
31484
|
+
showLegend: true,
|
|
31485
|
+
curve: "monotone",
|
|
31486
|
+
tooltip: { show: true, style: "dark" },
|
|
31487
|
+
dateRange: {
|
|
31488
|
+
start: fromTimestamp.split("T")[0],
|
|
31489
|
+
end: toTimestamp.split("T")[0]
|
|
31353
31490
|
}
|
|
31354
|
-
],
|
|
31355
|
-
height: 300,
|
|
31356
|
-
showGrid: true,
|
|
31357
|
-
showLegend: true,
|
|
31358
|
-
curve: "monotone",
|
|
31359
|
-
tooltip: { show: true, style: "dark" },
|
|
31360
|
-
dateRange: {
|
|
31361
|
-
start: fromTimestamp.split("T")[0],
|
|
31362
|
-
end: toTimestamp.split("T")[0]
|
|
31363
31491
|
}
|
|
31364
31492
|
}
|
|
31365
31493
|
}
|
|
@@ -31387,35 +31515,27 @@ class DashboardApiService {
|
|
|
31387
31515
|
let workflowTools = 0;
|
|
31388
31516
|
let knowledgeTools = 0;
|
|
31389
31517
|
let mcpTools = 0;
|
|
31518
|
+
let processors = 0;
|
|
31390
31519
|
if (point2.listView && Array.isArray(point2.listView)) {
|
|
31391
31520
|
point2.listView.forEach((item) => {
|
|
31392
31521
|
const count = item.count || 0;
|
|
31393
|
-
const toolType =
|
|
31394
|
-
const toolName = (item.toolName || item.tool_name || "").toLowerCase();
|
|
31395
|
-
console.log(`Processing listView item:`, { toolType, toolName, count });
|
|
31522
|
+
const toolType = item.toolType || item.tool_type || "";
|
|
31396
31523
|
const normalizedToolType = toolType.toLowerCase();
|
|
31397
|
-
if (["inlinetool", "
|
|
31524
|
+
if (["inlinetool", "tool", "code", "codetool", "event"].includes(normalizedToolType)) {
|
|
31398
31525
|
codeTools += count;
|
|
31399
|
-
} else if (["toollibrary", "
|
|
31526
|
+
} else if (["toollibrary", "workflow"].includes(normalizedToolType)) {
|
|
31400
31527
|
workflowTools += count;
|
|
31401
|
-
} else if (["knowledge", "
|
|
31528
|
+
} else if (["knowledge", "knowledgetool"].includes(normalizedToolType) || toolType === "KNOWLEDGE") {
|
|
31402
31529
|
knowledgeTools += count;
|
|
31403
|
-
} else if (["mcp", "
|
|
31530
|
+
} else if (["mcp", "mcptool"].includes(normalizedToolType)) {
|
|
31404
31531
|
mcpTools += count;
|
|
31532
|
+
} else if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalizedToolType) || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") {
|
|
31533
|
+
processors += count;
|
|
31405
31534
|
} else {
|
|
31406
|
-
console.log(`Unknown tool type '${toolType}' for tool '${toolName}', defaulting to code tools`);
|
|
31407
31535
|
codeTools += count;
|
|
31408
31536
|
}
|
|
31409
31537
|
});
|
|
31410
|
-
|
|
31411
|
-
codeTools,
|
|
31412
|
-
workflowTools,
|
|
31413
|
-
knowledgeTools,
|
|
31414
|
-
mcpTools,
|
|
31415
|
-
total: codeTools + workflowTools + knowledgeTools + mcpTools,
|
|
31416
|
-
expectedTotal: totalToolRuns
|
|
31417
|
-
});
|
|
31418
|
-
const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools;
|
|
31538
|
+
const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools + processors;
|
|
31419
31539
|
if (Math.abs(calculatedTotal - totalToolRuns) > 1) {
|
|
31420
31540
|
console.warn(`Breakdown total (${calculatedTotal}) doesn't match expected total (${totalToolRuns}) for point ${index}`);
|
|
31421
31541
|
const difference = totalToolRuns - calculatedTotal;
|
|
@@ -31423,7 +31543,6 @@ class DashboardApiService {
|
|
|
31423
31543
|
console.log(`Adjusted codeTools by ${difference} to balance total`);
|
|
31424
31544
|
}
|
|
31425
31545
|
} else {
|
|
31426
|
-
console.log(`No listView data for point ${index}, assigning all ${totalToolRuns} to codeTools`);
|
|
31427
31546
|
codeTools = totalToolRuns;
|
|
31428
31547
|
}
|
|
31429
31548
|
const basePoint = {
|
|
@@ -31434,11 +31553,11 @@ class DashboardApiService {
|
|
|
31434
31553
|
toolRuns: totalToolRuns,
|
|
31435
31554
|
value: totalToolRuns,
|
|
31436
31555
|
count: totalToolRuns,
|
|
31437
|
-
// Tool breakdown data for multi-line chart (using actual data)
|
|
31438
31556
|
codeTools,
|
|
31439
31557
|
workflowTools,
|
|
31440
31558
|
knowledgeTools,
|
|
31441
31559
|
mcpTools,
|
|
31560
|
+
processors,
|
|
31442
31561
|
// Token data
|
|
31443
31562
|
input_tokens: point2.input_tokens || 0,
|
|
31444
31563
|
output_tokens: point2.output_tokens || 0,
|
|
@@ -31476,14 +31595,33 @@ class DashboardApiService {
|
|
|
31476
31595
|
// Enhanced batch fetch method that returns complete MetricData with embedded view and controls
|
|
31477
31596
|
async fetchAllCardsDataWithEnhancedViews(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
31478
31597
|
try {
|
|
31479
|
-
const
|
|
31598
|
+
const cardsResults = await Promise.allSettled([
|
|
31480
31599
|
this.fetchUsageAnalyticsCards(fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31481
31600
|
this.fetchRunsCards(fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31482
31601
|
]);
|
|
31483
|
-
|
|
31484
|
-
|
|
31485
|
-
|
|
31602
|
+
if (cardsResults[0].status === "rejected") {
|
|
31603
|
+
console.error("Error fetching usage analytics cards:", cardsResults[0].reason);
|
|
31604
|
+
}
|
|
31605
|
+
if (cardsResults[1].status === "rejected") {
|
|
31606
|
+
console.error("Error fetching runs cards:", cardsResults[1].reason);
|
|
31607
|
+
}
|
|
31608
|
+
if (cardsResults[0].status === "rejected" && cardsResults[1].status === "rejected") {
|
|
31609
|
+
throw new Error("Both usage analytics and runs cards failed to load");
|
|
31610
|
+
}
|
|
31611
|
+
const usageAnalyticsCards = cardsResults[0].status === "fulfilled" ? cardsResults[0].value : void 0;
|
|
31612
|
+
const runsCards = cardsResults[1].status === "fulfilled" ? cardsResults[1].value : void 0;
|
|
31613
|
+
const enhancementResults = await Promise.allSettled([
|
|
31614
|
+
usageAnalyticsCards ? this.transformUsageAnalyticsCardsWithEnhancedData(usageAnalyticsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([]),
|
|
31615
|
+
runsCards ? this.transformRunsCardsWithEnhancedData(runsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([])
|
|
31486
31616
|
]);
|
|
31617
|
+
if (enhancementResults[0].status === "rejected") {
|
|
31618
|
+
console.error("Error transforming usage analytics cards:", enhancementResults[0].reason);
|
|
31619
|
+
}
|
|
31620
|
+
if (enhancementResults[1].status === "rejected") {
|
|
31621
|
+
console.error("Error transforming runs cards:", enhancementResults[1].reason);
|
|
31622
|
+
}
|
|
31623
|
+
const enhancedUsageAnalytics = enhancementResults[0].status === "fulfilled" ? enhancementResults[0].value : [];
|
|
31624
|
+
const enhancedRuns = enhancementResults[1].status === "fulfilled" ? enhancementResults[1].value : [];
|
|
31487
31625
|
return {
|
|
31488
31626
|
usageAnalytics: enhancedUsageAnalytics,
|
|
31489
31627
|
runs: enhancedRuns
|
|
@@ -31496,13 +31634,21 @@ class DashboardApiService {
|
|
|
31496
31634
|
// Batch fetch time series data for default selected metrics
|
|
31497
31635
|
async fetchDefaultTimeSeriesData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
31498
31636
|
try {
|
|
31499
|
-
const
|
|
31637
|
+
const results = await Promise.allSettled([
|
|
31500
31638
|
this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31501
31639
|
this.fetchTimeSeriesData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31502
31640
|
]);
|
|
31641
|
+
if (results[0].status === "rejected") {
|
|
31642
|
+
console.error("Error fetching sessions data:", results[0].reason);
|
|
31643
|
+
}
|
|
31644
|
+
if (results[1].status === "rejected") {
|
|
31645
|
+
console.error("Error fetching agent runs data:", results[1].reason);
|
|
31646
|
+
}
|
|
31647
|
+
const sessionsData = results[0].status === "fulfilled" ? results[0].value : void 0;
|
|
31648
|
+
const agentRunsData = results[1].status === "fulfilled" ? results[1].value : void 0;
|
|
31503
31649
|
return {
|
|
31504
|
-
sessions: this.transformTimeSeriesData(sessionsData),
|
|
31505
|
-
agentRuns: this.transformTimeSeriesData(agentRunsData)
|
|
31650
|
+
sessions: sessionsData ? this.transformTimeSeriesData(sessionsData) : [],
|
|
31651
|
+
agentRuns: agentRunsData ? this.transformTimeSeriesData(agentRunsData) : []
|
|
31506
31652
|
};
|
|
31507
31653
|
} catch (error) {
|
|
31508
31654
|
console.error("Error fetching default time series data:", error);
|
|
@@ -32229,6 +32375,10 @@ const SectionControls = ({
|
|
|
32229
32375
|
] })
|
|
32230
32376
|
] });
|
|
32231
32377
|
};
|
|
32378
|
+
function modelListViewRowLabel(listItem) {
|
|
32379
|
+
if (!listItem.modelName) return "";
|
|
32380
|
+
return listItem.connectionName ? `${listItem.modelName} - ${listItem.connectionName}` : listItem.modelName;
|
|
32381
|
+
}
|
|
32232
32382
|
const DashboardSection = ({
|
|
32233
32383
|
section,
|
|
32234
32384
|
className,
|
|
@@ -32326,16 +32476,17 @@ const DashboardSection = ({
|
|
|
32326
32476
|
});
|
|
32327
32477
|
return baseData.map((item) => {
|
|
32328
32478
|
let filteredValue = 0;
|
|
32479
|
+
let matchingItems = [];
|
|
32329
32480
|
if (item["listView"] && Array.isArray(item["listView"])) {
|
|
32330
|
-
|
|
32481
|
+
matchingItems = item["listView"].filter((listItem) => {
|
|
32331
32482
|
if (metricType === "agentRuns" && listItem.agentName) {
|
|
32332
32483
|
return listItem.agentName === selectedLabel || listItem.agentName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
|
|
32333
32484
|
}
|
|
32334
32485
|
if (metricType === "toolRuns" && listItem.toolName) {
|
|
32335
32486
|
return listItem.toolName === selectedLabel || listItem.toolName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
|
|
32336
32487
|
}
|
|
32337
|
-
if (metricType === "modelRuns" && listItem.modelName) {
|
|
32338
|
-
return listItem
|
|
32488
|
+
if (metricType === "modelRuns" && listItem.modelName && selectedLabel) {
|
|
32489
|
+
return modelListViewRowLabel(listItem) === selectedLabel;
|
|
32339
32490
|
}
|
|
32340
32491
|
return false;
|
|
32341
32492
|
});
|
|
@@ -32345,10 +32496,17 @@ const DashboardSection = ({
|
|
|
32345
32496
|
);
|
|
32346
32497
|
}
|
|
32347
32498
|
console.log("📊 Filtered value for", selectedLabel, ":", filteredValue);
|
|
32499
|
+
const failedModelRunsSum = metricType === "modelRuns" ? matchingItems.reduce(
|
|
32500
|
+
(sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
|
|
32501
|
+
0
|
|
32502
|
+
) : 0;
|
|
32348
32503
|
const result = {
|
|
32349
32504
|
...item,
|
|
32350
32505
|
[metricType]: filteredValue
|
|
32351
32506
|
};
|
|
32507
|
+
if (metricType === "modelRuns") {
|
|
32508
|
+
result.failedModelRuns = failedModelRunsSum;
|
|
32509
|
+
}
|
|
32352
32510
|
return result;
|
|
32353
32511
|
});
|
|
32354
32512
|
}
|
|
@@ -32360,8 +32518,9 @@ const DashboardSection = ({
|
|
|
32360
32518
|
const selectedLabels = selectedOptions.map((opt) => opt.label);
|
|
32361
32519
|
return baseData.map((item) => {
|
|
32362
32520
|
let aggregatedValue = 0;
|
|
32521
|
+
let matchingItems = [];
|
|
32363
32522
|
if (item["listView"] && Array.isArray(item["listView"])) {
|
|
32364
|
-
|
|
32523
|
+
matchingItems = item["listView"].filter((listItem) => {
|
|
32365
32524
|
if (metricType === "agentRuns" && listItem.agentName) {
|
|
32366
32525
|
return selectedLabels.some(
|
|
32367
32526
|
(label) => listItem.agentName === label || listItem.agentName.toLowerCase() === (label == null ? void 0 : label.toLowerCase())
|
|
@@ -32373,9 +32532,8 @@ const DashboardSection = ({
|
|
|
32373
32532
|
);
|
|
32374
32533
|
}
|
|
32375
32534
|
if (metricType === "modelRuns" && listItem.modelName) {
|
|
32376
|
-
|
|
32377
|
-
|
|
32378
|
-
);
|
|
32535
|
+
const rowLabel = modelListViewRowLabel(listItem);
|
|
32536
|
+
return selectedLabels.some((label) => rowLabel === label);
|
|
32379
32537
|
}
|
|
32380
32538
|
return false;
|
|
32381
32539
|
});
|
|
@@ -32384,10 +32542,18 @@ const DashboardSection = ({
|
|
|
32384
32542
|
0
|
|
32385
32543
|
);
|
|
32386
32544
|
}
|
|
32387
|
-
|
|
32545
|
+
const failedModelRunsMulti = metricType === "modelRuns" ? matchingItems.reduce(
|
|
32546
|
+
(sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
|
|
32547
|
+
0
|
|
32548
|
+
) : 0;
|
|
32549
|
+
const multiResult = {
|
|
32388
32550
|
...item,
|
|
32389
32551
|
[metricType]: aggregatedValue
|
|
32390
32552
|
};
|
|
32553
|
+
if (metricType === "modelRuns") {
|
|
32554
|
+
multiResult.failedModelRuns = failedModelRunsMulti;
|
|
32555
|
+
}
|
|
32556
|
+
return multiResult;
|
|
32391
32557
|
});
|
|
32392
32558
|
}
|
|
32393
32559
|
return baseData;
|
|
@@ -32619,35 +32785,30 @@ const DashboardSection = ({
|
|
|
32619
32785
|
data: filteredData,
|
|
32620
32786
|
yAxisLabel: "Number of Tool Runs",
|
|
32621
32787
|
lines: [
|
|
32622
|
-
{
|
|
32623
|
-
dataKey: "toolRuns",
|
|
32624
|
-
color: "#06b6d4",
|
|
32625
|
-
// Blue for Tool Runs
|
|
32626
|
-
label: "Tool Runs"
|
|
32627
|
-
},
|
|
32628
32788
|
{
|
|
32629
32789
|
dataKey: "codeTools",
|
|
32630
32790
|
color: "#f97316",
|
|
32631
|
-
// Orange for Code Tools
|
|
32632
32791
|
label: "Code Tools"
|
|
32633
32792
|
},
|
|
32634
32793
|
{
|
|
32635
32794
|
dataKey: "workflowTools",
|
|
32636
32795
|
color: "#10b981",
|
|
32637
|
-
// Green for Workflow Tools
|
|
32638
32796
|
label: "Workflow Tools"
|
|
32639
32797
|
},
|
|
32640
32798
|
{
|
|
32641
32799
|
dataKey: "knowledgeTools",
|
|
32642
32800
|
color: "#8b5cf6",
|
|
32643
|
-
// Purple for Knowledge
|
|
32644
32801
|
label: "Knowledge"
|
|
32645
32802
|
},
|
|
32646
32803
|
{
|
|
32647
32804
|
dataKey: "mcpTools",
|
|
32648
32805
|
color: "#ef4444",
|
|
32649
|
-
// Red for MCP Tools
|
|
32650
32806
|
label: "MCP Tools"
|
|
32807
|
+
},
|
|
32808
|
+
{
|
|
32809
|
+
dataKey: "processors",
|
|
32810
|
+
color: "#eab308",
|
|
32811
|
+
label: "Processors"
|
|
32651
32812
|
}
|
|
32652
32813
|
],
|
|
32653
32814
|
height: 300,
|
|
@@ -32667,12 +32828,20 @@ const DashboardSection = ({
|
|
|
32667
32828
|
type: "line",
|
|
32668
32829
|
title: getChartTitle("Model Runs"),
|
|
32669
32830
|
data: getFilteredData(baseData, "modelRuns"),
|
|
32670
|
-
dataKey: "modelRuns",
|
|
32671
|
-
color: "#10b981",
|
|
32672
|
-
// Green as shown in Figma
|
|
32673
32831
|
yAxisLabel: "Number of Model Runs",
|
|
32832
|
+
lines: [
|
|
32833
|
+
{ dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
|
|
32834
|
+
{
|
|
32835
|
+
dataKey: "failedModelRuns",
|
|
32836
|
+
color: "#ef4444",
|
|
32837
|
+
label: "Failed",
|
|
32838
|
+
seriesType: "bar",
|
|
32839
|
+
hideInLegend: true
|
|
32840
|
+
}
|
|
32841
|
+
],
|
|
32674
32842
|
height: 300,
|
|
32675
32843
|
showGrid: true,
|
|
32844
|
+
showLegend: true,
|
|
32676
32845
|
curve: "monotone",
|
|
32677
32846
|
tooltip: { show: true, style: "dark" },
|
|
32678
32847
|
dateRange: {
|
|
@@ -32685,12 +32854,20 @@ const DashboardSection = ({
|
|
|
32685
32854
|
type: "line",
|
|
32686
32855
|
title: getChartTitle("Model Runs"),
|
|
32687
32856
|
data: filteredData,
|
|
32688
|
-
dataKey: "modelRuns",
|
|
32689
|
-
color: "#10b981",
|
|
32690
|
-
// Green as shown in Figma
|
|
32691
32857
|
yAxisLabel: "Number of Model Runs",
|
|
32858
|
+
lines: [
|
|
32859
|
+
{ dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
|
|
32860
|
+
{
|
|
32861
|
+
dataKey: "failedModelRuns",
|
|
32862
|
+
color: "#ef4444",
|
|
32863
|
+
label: "Failed",
|
|
32864
|
+
seriesType: "bar",
|
|
32865
|
+
hideInLegend: true
|
|
32866
|
+
}
|
|
32867
|
+
],
|
|
32692
32868
|
height: 300,
|
|
32693
32869
|
showGrid: true,
|
|
32870
|
+
showLegend: true,
|
|
32694
32871
|
curve: "monotone",
|
|
32695
32872
|
tooltip: { show: true, style: "dark" },
|
|
32696
32873
|
dateRange: {
|
|
@@ -34942,8 +35119,11 @@ const Dashboard = ({
|
|
|
34942
35119
|
if (appConfig) {
|
|
34943
35120
|
try {
|
|
34944
35121
|
apiServiceRef.current = new DashboardApiService(appConfig);
|
|
34945
|
-
|
|
34946
|
-
|
|
35122
|
+
const initDashboard = async () => {
|
|
35123
|
+
await loadEnvironments();
|
|
35124
|
+
await loadInitialData();
|
|
35125
|
+
};
|
|
35126
|
+
initDashboard();
|
|
34947
35127
|
} catch (err) {
|
|
34948
35128
|
console.error("Failed to initialize API service:", err);
|
|
34949
35129
|
}
|
|
@@ -106326,6 +106506,7 @@ class DetailPageService {
|
|
|
106326
106506
|
);
|
|
106327
106507
|
traceDetails = traceResponses.map((trace) => this.transformToTraceDetailData(trace));
|
|
106328
106508
|
}
|
|
106509
|
+
const resolvedSessionReference = typeof sessionResponse.sessionReference === "string" && sessionResponse.sessionReference.trim() !== "" ? sessionResponse.sessionReference.trim() : void 0;
|
|
106329
106510
|
return {
|
|
106330
106511
|
id: sessionResponse.id,
|
|
106331
106512
|
projectId: sessionResponse.projectId,
|
|
@@ -106333,7 +106514,8 @@ class DetailPageService {
|
|
|
106333
106514
|
bookmarked: false,
|
|
106334
106515
|
public: false,
|
|
106335
106516
|
traces: traceDetails,
|
|
106336
|
-
scores: []
|
|
106517
|
+
scores: [],
|
|
106518
|
+
sessionReference: resolvedSessionReference
|
|
106337
106519
|
};
|
|
106338
106520
|
}
|
|
106339
106521
|
/**
|
|
@@ -106410,10 +106592,12 @@ class DetailPageService {
|
|
|
106410
106592
|
projectId: this.projectId
|
|
106411
106593
|
});
|
|
106412
106594
|
const traceIds = (sessionResponse.traces || []).map((t2) => t2.id);
|
|
106595
|
+
const resolvedSessionReference = typeof sessionResponse.sessionReference === "string" && sessionResponse.sessionReference.trim() !== "" ? sessionResponse.sessionReference.trim() : void 0;
|
|
106413
106596
|
onSessionMeta({
|
|
106414
106597
|
id: sessionResponse.id,
|
|
106415
106598
|
traceCount: traceIds.length,
|
|
106416
|
-
traceIds
|
|
106599
|
+
traceIds,
|
|
106600
|
+
sessionReference: resolvedSessionReference
|
|
106417
106601
|
});
|
|
106418
106602
|
if (traceIds.length === 0) {
|
|
106419
106603
|
return {
|
|
@@ -106423,7 +106607,8 @@ class DetailPageService {
|
|
|
106423
106607
|
bookmarked: false,
|
|
106424
106608
|
public: false,
|
|
106425
106609
|
traces: [],
|
|
106426
|
-
scores: []
|
|
106610
|
+
scores: [],
|
|
106611
|
+
sessionReference: resolvedSessionReference
|
|
106427
106612
|
};
|
|
106428
106613
|
}
|
|
106429
106614
|
const firstTraceId = traceIds[0];
|
|
@@ -106470,7 +106655,8 @@ class DetailPageService {
|
|
|
106470
106655
|
bookmarked: false,
|
|
106471
106656
|
public: false,
|
|
106472
106657
|
traces: allTraces,
|
|
106473
|
-
scores: []
|
|
106658
|
+
scores: [],
|
|
106659
|
+
sessionReference: resolvedSessionReference
|
|
106474
106660
|
};
|
|
106475
106661
|
}
|
|
106476
106662
|
// ============================================================================
|
|
@@ -106564,6 +106750,7 @@ class DetailPageService {
|
|
|
106564
106750
|
totalCost: trace.totalCost || trace.calculatedTotalCost,
|
|
106565
106751
|
totalTokens: trace.totalTokens,
|
|
106566
106752
|
environment: trace.environment,
|
|
106753
|
+
source: typeof trace.source === "string" && trace.source.length > 0 ? trace.source : void 0,
|
|
106567
106754
|
observations: (trace.observations || []).map(
|
|
106568
106755
|
(obs) => this.transformObservation(obs)
|
|
106569
106756
|
),
|
|
@@ -109291,6 +109478,526 @@ function NodeDetailPanel({
|
|
|
109291
109478
|
)
|
|
109292
109479
|
] });
|
|
109293
109480
|
}
|
|
109481
|
+
const MicIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: [
|
|
109482
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109483
|
+
"path",
|
|
109484
|
+
{
|
|
109485
|
+
d: "M8 2C7.60218 2 7.22064 2.15804 6.93934 2.43934C6.65804 2.72064 6.5 3.10218 6.5 3.5V6.5C6.5 6.89782 6.65804 7.27936 6.93934 7.56066C7.22064 7.84196 7.60218 8 8 8C8.39782 8 8.77936 7.84196 9.06066 7.56066C9.34196 7.27936 9.5 6.89782 9.5 6.5V3.5C9.5 3.10218 9.34196 2.72064 9.06066 2.43934C8.77936 2.15804 8.39782 2 8 2Z",
|
|
109486
|
+
fill: "#155EEF"
|
|
109487
|
+
}
|
|
109488
|
+
),
|
|
109489
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109490
|
+
"path",
|
|
109491
|
+
{
|
|
109492
|
+
d: "M5.5 6V6.5C5.5 7.16304 5.76339 7.79893 6.23223 8.26777C6.70107 8.73661 7.33696 9 8 9C8.66304 9 9.29893 8.73661 9.76777 8.26777C10.2366 7.79893 10.5 7.16304 10.5 6.5V6",
|
|
109493
|
+
stroke: "#155EEF",
|
|
109494
|
+
strokeWidth: "1.2",
|
|
109495
|
+
strokeLinecap: "round",
|
|
109496
|
+
strokeLinejoin: "round"
|
|
109497
|
+
}
|
|
109498
|
+
),
|
|
109499
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109500
|
+
"path",
|
|
109501
|
+
{
|
|
109502
|
+
d: "M8 9V11",
|
|
109503
|
+
stroke: "#155EEF",
|
|
109504
|
+
strokeWidth: "1.2",
|
|
109505
|
+
strokeLinecap: "round",
|
|
109506
|
+
strokeLinejoin: "round"
|
|
109507
|
+
}
|
|
109508
|
+
),
|
|
109509
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109510
|
+
"path",
|
|
109511
|
+
{
|
|
109512
|
+
d: "M6.5 11H9.5",
|
|
109513
|
+
stroke: "#155EEF",
|
|
109514
|
+
strokeWidth: "1.2",
|
|
109515
|
+
strokeLinecap: "round",
|
|
109516
|
+
strokeLinejoin: "round"
|
|
109517
|
+
}
|
|
109518
|
+
)
|
|
109519
|
+
] });
|
|
109520
|
+
function VoiceEventLogsBanner({ onViewEventLogs }) {
|
|
109521
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between rounded-[8px] bg-[#FFFFFF] border border-[#D0D5DD] px-[12px] py-[8px] mb-[8px]", children: [
|
|
109522
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
|
|
109523
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MicIcon, {}),
|
|
109524
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.04em]", children: "Voice-to-Voice Event Logs" })
|
|
109525
|
+
] }),
|
|
109526
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109527
|
+
"button",
|
|
109528
|
+
{
|
|
109529
|
+
onClick: onViewEventLogs,
|
|
109530
|
+
className: "text-[12px] font-medium text-[#155EEF] hover:text-[#344054] hover:underline transition-colors cursor-pointer bg-transparent border-none p-0",
|
|
109531
|
+
"data-test-id": "view-event-logs-btn",
|
|
109532
|
+
children: "View Event Logs"
|
|
109533
|
+
}
|
|
109534
|
+
)
|
|
109535
|
+
] });
|
|
109536
|
+
}
|
|
109537
|
+
function AlignLeftIcon({ className }) {
|
|
109538
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109539
|
+
"svg",
|
|
109540
|
+
{
|
|
109541
|
+
width: "16",
|
|
109542
|
+
height: "16",
|
|
109543
|
+
viewBox: "0 0 16 16",
|
|
109544
|
+
fill: "none",
|
|
109545
|
+
className,
|
|
109546
|
+
"aria-hidden": "true",
|
|
109547
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109548
|
+
"path",
|
|
109549
|
+
{
|
|
109550
|
+
d: "M10.6667 6.66667H2M13.3333 4H2M13.3333 9.33333H2M10.6667 12H2",
|
|
109551
|
+
stroke: "currentColor",
|
|
109552
|
+
strokeWidth: "1.3",
|
|
109553
|
+
strokeLinecap: "round",
|
|
109554
|
+
strokeLinejoin: "round"
|
|
109555
|
+
}
|
|
109556
|
+
)
|
|
109557
|
+
}
|
|
109558
|
+
);
|
|
109559
|
+
}
|
|
109560
|
+
function JsonViewIcon({ className }) {
|
|
109561
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109562
|
+
"svg",
|
|
109563
|
+
{
|
|
109564
|
+
width: "16",
|
|
109565
|
+
height: "16",
|
|
109566
|
+
viewBox: "0 0 16 16",
|
|
109567
|
+
fill: "none",
|
|
109568
|
+
className,
|
|
109569
|
+
"aria-hidden": "true",
|
|
109570
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109571
|
+
"path",
|
|
109572
|
+
{
|
|
109573
|
+
d: "M14 6.16602H8M14 2.66602H2M14 9.83268H8M14 13.3327H2M2.85333 5.70602L5.43111 7.63935C5.62411 7.78409 5.7206 7.85647 5.75511 7.94519C5.78533 8.02291 5.78533 8.10913 5.75511 8.18684C5.7206 8.27556 5.62411 8.34794 5.43111 8.49268L2.85333 10.426C2.57868 10.632 2.44135 10.735 2.3264 10.7326C2.22637 10.7305 2.13256 10.6836 2.07088 10.6048C2 10.5143 2 10.3427 2 9.99935V6.13268C2 5.78937 2 5.61771 2.07088 5.52718C2.13256 5.4484 2.22637 5.4015 2.3264 5.39942C2.44135 5.39703 2.57868 5.50003 2.85333 5.70602Z",
|
|
109574
|
+
stroke: "currentColor",
|
|
109575
|
+
strokeWidth: "1.3",
|
|
109576
|
+
strokeLinecap: "round",
|
|
109577
|
+
strokeLinejoin: "round"
|
|
109578
|
+
}
|
|
109579
|
+
)
|
|
109580
|
+
}
|
|
109581
|
+
);
|
|
109582
|
+
}
|
|
109583
|
+
function pickString(obj, keys2) {
|
|
109584
|
+
for (const key of keys2) {
|
|
109585
|
+
const value = obj[key];
|
|
109586
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
109587
|
+
if (typeof value === "number") return String(value);
|
|
109588
|
+
}
|
|
109589
|
+
return void 0;
|
|
109590
|
+
}
|
|
109591
|
+
function coerceDirection(raw) {
|
|
109592
|
+
if (raw === "incoming" || raw === "server" || raw === "response") return "in";
|
|
109593
|
+
return "out";
|
|
109594
|
+
}
|
|
109595
|
+
function normalizeEvent(raw, fallbackId, docTimestamp) {
|
|
109596
|
+
if (!raw || typeof raw !== "object") {
|
|
109597
|
+
return {
|
|
109598
|
+
id: fallbackId,
|
|
109599
|
+
timestamp: docTimestamp,
|
|
109600
|
+
name: "event",
|
|
109601
|
+
direction: "out",
|
|
109602
|
+
payload: raw
|
|
109603
|
+
};
|
|
109604
|
+
}
|
|
109605
|
+
const obj = raw;
|
|
109606
|
+
const id = pickString(obj, ["event_id", "eventId", "_id", "id"]) ?? fallbackId;
|
|
109607
|
+
const name = pickString(obj, ["type", "eventType", "event", "name"]) ?? "event";
|
|
109608
|
+
const direction = coerceDirection(obj.direction);
|
|
109609
|
+
return {
|
|
109610
|
+
id,
|
|
109611
|
+
timestamp: docTimestamp,
|
|
109612
|
+
name,
|
|
109613
|
+
direction,
|
|
109614
|
+
payload: raw
|
|
109615
|
+
};
|
|
109616
|
+
}
|
|
109617
|
+
function flattenEvents(data) {
|
|
109618
|
+
if (data === null || data === void 0) return [];
|
|
109619
|
+
const out = [];
|
|
109620
|
+
const visitDoc = (doc2, docIdx) => {
|
|
109621
|
+
if (!doc2 || typeof doc2 !== "object") return;
|
|
109622
|
+
const docObj = doc2;
|
|
109623
|
+
const docTimestamp = pickString(docObj, ["createdOn", "sT", "createdAt"]);
|
|
109624
|
+
const events = docObj.events;
|
|
109625
|
+
if (Array.isArray(events)) {
|
|
109626
|
+
events.forEach((ev, evIdx) => {
|
|
109627
|
+
out.push(normalizeEvent(ev, `${docIdx}-${evIdx}`, docTimestamp));
|
|
109628
|
+
});
|
|
109629
|
+
} else {
|
|
109630
|
+
out.push(normalizeEvent(doc2, String(docIdx), docTimestamp));
|
|
109631
|
+
}
|
|
109632
|
+
};
|
|
109633
|
+
if (Array.isArray(data)) {
|
|
109634
|
+
data.forEach((doc2, docIdx) => visitDoc(doc2, docIdx));
|
|
109635
|
+
return out;
|
|
109636
|
+
}
|
|
109637
|
+
if (typeof data === "object") {
|
|
109638
|
+
const obj = data;
|
|
109639
|
+
if (Array.isArray(obj.events)) {
|
|
109640
|
+
visitDoc(obj, 0);
|
|
109641
|
+
return out;
|
|
109642
|
+
}
|
|
109643
|
+
if (Array.isArray(obj.data)) {
|
|
109644
|
+
return flattenEvents(obj.data);
|
|
109645
|
+
}
|
|
109646
|
+
}
|
|
109647
|
+
return [];
|
|
109648
|
+
}
|
|
109649
|
+
function formatEventTime(iso) {
|
|
109650
|
+
if (!iso) return "--:--:--:---";
|
|
109651
|
+
const d3 = new Date(iso);
|
|
109652
|
+
if (Number.isNaN(d3.getTime())) return "--:--:--:---";
|
|
109653
|
+
const hh = String(d3.getHours()).padStart(2, "0");
|
|
109654
|
+
const mm = String(d3.getMinutes()).padStart(2, "0");
|
|
109655
|
+
const ss = String(d3.getSeconds()).padStart(2, "0");
|
|
109656
|
+
const ms = String(d3.getMilliseconds()).padStart(3, "0");
|
|
109657
|
+
return `${hh}:${mm}:${ss}:${ms}`;
|
|
109658
|
+
}
|
|
109659
|
+
function stringifyPayload(payload) {
|
|
109660
|
+
if (payload === null || payload === void 0) return "";
|
|
109661
|
+
if (typeof payload === "string") {
|
|
109662
|
+
try {
|
|
109663
|
+
return JSON.stringify(JSON.parse(payload), null, 2);
|
|
109664
|
+
} catch {
|
|
109665
|
+
return payload;
|
|
109666
|
+
}
|
|
109667
|
+
}
|
|
109668
|
+
try {
|
|
109669
|
+
return JSON.stringify(payload, null, 2);
|
|
109670
|
+
} catch {
|
|
109671
|
+
return String(payload);
|
|
109672
|
+
}
|
|
109673
|
+
}
|
|
109674
|
+
function compactPayload(payload) {
|
|
109675
|
+
if (payload === null || payload === void 0) return "";
|
|
109676
|
+
if (typeof payload === "string") {
|
|
109677
|
+
try {
|
|
109678
|
+
return JSON.stringify(JSON.parse(payload));
|
|
109679
|
+
} catch {
|
|
109680
|
+
return payload;
|
|
109681
|
+
}
|
|
109682
|
+
}
|
|
109683
|
+
try {
|
|
109684
|
+
return JSON.stringify(payload);
|
|
109685
|
+
} catch {
|
|
109686
|
+
return String(payload);
|
|
109687
|
+
}
|
|
109688
|
+
}
|
|
109689
|
+
function PayloadPanel({ payload, compactText }) {
|
|
109690
|
+
const [viewMode, setViewMode] = useState("json");
|
|
109691
|
+
const [fullscreen, setFullscreen] = useState(false);
|
|
109692
|
+
const [copied, setCopied] = useState(false);
|
|
109693
|
+
const displayText = viewMode === "json" ? payload : compactText;
|
|
109694
|
+
const handleCopy = useCallback(async () => {
|
|
109695
|
+
try {
|
|
109696
|
+
await navigator.clipboard.writeText(displayText);
|
|
109697
|
+
setCopied(true);
|
|
109698
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
109699
|
+
} catch {
|
|
109700
|
+
} finally {
|
|
109701
|
+
setCopied(false);
|
|
109702
|
+
}
|
|
109703
|
+
}, [displayText]);
|
|
109704
|
+
const toolbar = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[42px] px-[10px] border-b border-[#D0D5DD] flex items-center justify-between flex-shrink-0 bg-white", children: [
|
|
109705
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
109706
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109707
|
+
"button",
|
|
109708
|
+
{
|
|
109709
|
+
type: "button",
|
|
109710
|
+
onClick: () => setViewMode("json"),
|
|
109711
|
+
className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
|
|
109712
|
+
title: "Pretty JSON",
|
|
109713
|
+
"aria-label": "Pretty JSON view",
|
|
109714
|
+
"aria-pressed": viewMode === "json",
|
|
109715
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
|
|
109716
|
+
}
|
|
109717
|
+
),
|
|
109718
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109719
|
+
"button",
|
|
109720
|
+
{
|
|
109721
|
+
type: "button",
|
|
109722
|
+
onClick: () => setViewMode("text"),
|
|
109723
|
+
className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
|
|
109724
|
+
title: "Compact text",
|
|
109725
|
+
"aria-label": "Compact text view",
|
|
109726
|
+
"aria-pressed": viewMode === "text",
|
|
109727
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
|
|
109728
|
+
}
|
|
109729
|
+
)
|
|
109730
|
+
] }),
|
|
109731
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
109732
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109733
|
+
"button",
|
|
109734
|
+
{
|
|
109735
|
+
type: "button",
|
|
109736
|
+
onClick: () => setFullscreen((v) => !v),
|
|
109737
|
+
className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
|
|
109738
|
+
title: fullscreen ? "Exit fullscreen" : "Fullscreen",
|
|
109739
|
+
"aria-label": fullscreen ? "Exit fullscreen" : "Fullscreen",
|
|
109740
|
+
children: fullscreen ? /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-[16px] h-[16px]" })
|
|
109741
|
+
}
|
|
109742
|
+
),
|
|
109743
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109744
|
+
"button",
|
|
109745
|
+
{
|
|
109746
|
+
type: "button",
|
|
109747
|
+
onClick: () => void handleCopy(),
|
|
109748
|
+
className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
|
|
109749
|
+
title: "Copy to clipboard",
|
|
109750
|
+
"aria-label": "Copy payload",
|
|
109751
|
+
"data-test-id": "event-logs-row-copy",
|
|
109752
|
+
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
|
|
109753
|
+
}
|
|
109754
|
+
)
|
|
109755
|
+
] })
|
|
109756
|
+
] });
|
|
109757
|
+
if (fullscreen) {
|
|
109758
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[20000] flex flex-col bg-[#F9FAFB]", children: [
|
|
109759
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[48px] px-[16px] border-b border-[#E4E7EC] flex items-center justify-between flex-shrink-0 bg-white", children: [
|
|
109760
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
109761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109762
|
+
"button",
|
|
109763
|
+
{
|
|
109764
|
+
type: "button",
|
|
109765
|
+
onClick: () => setViewMode("json"),
|
|
109766
|
+
className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
|
|
109767
|
+
title: "Pretty JSON",
|
|
109768
|
+
"aria-label": "Pretty JSON view",
|
|
109769
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
|
|
109770
|
+
}
|
|
109771
|
+
),
|
|
109772
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109773
|
+
"button",
|
|
109774
|
+
{
|
|
109775
|
+
type: "button",
|
|
109776
|
+
onClick: () => setViewMode("text"),
|
|
109777
|
+
className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
|
|
109778
|
+
title: "Compact text",
|
|
109779
|
+
"aria-label": "Compact text view",
|
|
109780
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
|
|
109781
|
+
}
|
|
109782
|
+
)
|
|
109783
|
+
] }),
|
|
109784
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
109785
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109786
|
+
"button",
|
|
109787
|
+
{
|
|
109788
|
+
type: "button",
|
|
109789
|
+
onClick: () => void handleCopy(),
|
|
109790
|
+
className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
|
|
109791
|
+
title: "Copy to clipboard",
|
|
109792
|
+
"aria-label": "Copy payload",
|
|
109793
|
+
children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
|
|
109794
|
+
}
|
|
109795
|
+
),
|
|
109796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109797
|
+
"button",
|
|
109798
|
+
{
|
|
109799
|
+
type: "button",
|
|
109800
|
+
onClick: () => setFullscreen(false),
|
|
109801
|
+
className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
|
|
109802
|
+
title: "Exit fullscreen",
|
|
109803
|
+
"aria-label": "Exit fullscreen",
|
|
109804
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" })
|
|
109805
|
+
}
|
|
109806
|
+
)
|
|
109807
|
+
] })
|
|
109808
|
+
] }),
|
|
109809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "flex-1 overflow-auto m-0 p-[20px] text-[13px] leading-[20px] font-mono text-[#344054] whitespace-pre-wrap break-all", children: displayText })
|
|
109810
|
+
] }) });
|
|
109811
|
+
}
|
|
109812
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[10px] border border-[#D0D5DD] overflow-hidden mt-[12px]", children: [
|
|
109813
|
+
toolbar,
|
|
109814
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "m-0 bg-[#F9FAFB] text-[#344054] p-[12px] text-[12px] leading-[18px] font-mono whitespace-pre-wrap break-all overflow-auto max-h-[360px]", children: displayText })
|
|
109815
|
+
] });
|
|
109816
|
+
}
|
|
109817
|
+
function EventRow({ event, isExpanded, onToggle }) {
|
|
109818
|
+
const jsonText = useMemo(() => stringifyPayload(event.payload), [event.payload]);
|
|
109819
|
+
const compactText = useMemo(() => compactPayload(event.payload), [event.payload]);
|
|
109820
|
+
const hasPayload = jsonText.length > 0;
|
|
109821
|
+
const isInput = event.direction === "in";
|
|
109822
|
+
const DirectionIcon = isInput ? ArrowUp : ArrowDown;
|
|
109823
|
+
const directionLabel = isInput ? "Input" : "Output";
|
|
109824
|
+
const circleClasses = isInput ? "border-[#079455] text-[#079455]" : "border-[#D92D20] text-[#D92D20]";
|
|
109825
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex items-start gap-[12px]", "data-test-id": "event-logs-row", children: [
|
|
109826
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative flex-shrink-0 flex flex-col items-center w-[16px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109827
|
+
"div",
|
|
109828
|
+
{
|
|
109829
|
+
className: `relative z-10 w-[16px] h-[16px] rounded-full bg-white border flex items-center justify-center ${circleClasses}`,
|
|
109830
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(DirectionIcon, { className: "w-[8px] h-[8px]", strokeWidth: 2.5 })
|
|
109831
|
+
}
|
|
109832
|
+
) }),
|
|
109833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 pb-[24px]", children: [
|
|
109834
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-[16px]", children: [
|
|
109835
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
109836
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[12px] leading-[16px] text-[#667085]", children: directionLabel }),
|
|
109837
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] font-medium text-[#344054] mt-[2px] break-all", children: event.name }),
|
|
109838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109839
|
+
"button",
|
|
109840
|
+
{
|
|
109841
|
+
type: "button",
|
|
109842
|
+
onClick: onToggle,
|
|
109843
|
+
className: "text-[13px] leading-[18px] text-[#155EEF] hover:underline mt-[4px] font-medium",
|
|
109844
|
+
"data-test-id": "event-logs-view-details",
|
|
109845
|
+
children: isExpanded ? "Hide details" : "View details"
|
|
109846
|
+
}
|
|
109847
|
+
)
|
|
109848
|
+
] }),
|
|
109849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-shrink-0 text-[12px] leading-[18px] text-[#344054] font-mono tabular-nums whitespace-nowrap pt-[2px]", children: formatEventTime(event.timestamp) })
|
|
109850
|
+
] }),
|
|
109851
|
+
isExpanded && (hasPayload ? /* @__PURE__ */ jsxRuntimeExports.jsx(PayloadPanel, { payload: jsonText, compactText }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-[12px] text-[12px] text-[#667085] italic", children: "No payload recorded for this event." }))
|
|
109852
|
+
] })
|
|
109853
|
+
] });
|
|
109854
|
+
}
|
|
109855
|
+
function EventLogsSlideout({
|
|
109856
|
+
isOpen,
|
|
109857
|
+
onClose,
|
|
109858
|
+
sessionId,
|
|
109859
|
+
fetchEventLogs
|
|
109860
|
+
}) {
|
|
109861
|
+
const [rawData, setRawData] = useState(null);
|
|
109862
|
+
const [loading, setLoading] = useState(false);
|
|
109863
|
+
const [error, setError] = useState(null);
|
|
109864
|
+
const [expandedIds, setExpandedIds] = useState(() => /* @__PURE__ */ new Set());
|
|
109865
|
+
useEffect(() => {
|
|
109866
|
+
if (!isOpen || !sessionId || !fetchEventLogs) return;
|
|
109867
|
+
let cancelled = false;
|
|
109868
|
+
setLoading(true);
|
|
109869
|
+
setError(null);
|
|
109870
|
+
setRawData(null);
|
|
109871
|
+
(async () => {
|
|
109872
|
+
try {
|
|
109873
|
+
const data = await fetchEventLogs(sessionId);
|
|
109874
|
+
if (cancelled) return;
|
|
109875
|
+
setRawData(data);
|
|
109876
|
+
} catch (err) {
|
|
109877
|
+
if (cancelled) return;
|
|
109878
|
+
setError(err instanceof Error ? err.message : "Failed to fetch event logs");
|
|
109879
|
+
} finally {
|
|
109880
|
+
if (!cancelled) setLoading(false);
|
|
109881
|
+
}
|
|
109882
|
+
})();
|
|
109883
|
+
return () => {
|
|
109884
|
+
cancelled = true;
|
|
109885
|
+
};
|
|
109886
|
+
}, [isOpen, sessionId, fetchEventLogs]);
|
|
109887
|
+
const events = useMemo(() => flattenEvents(rawData), [rawData]);
|
|
109888
|
+
useEffect(() => {
|
|
109889
|
+
if (!isOpen) return;
|
|
109890
|
+
const handleKey = (e3) => {
|
|
109891
|
+
if (e3.key === "Escape") onClose();
|
|
109892
|
+
};
|
|
109893
|
+
document.addEventListener("keydown", handleKey);
|
|
109894
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
109895
|
+
}, [isOpen, onClose]);
|
|
109896
|
+
useEffect(() => {
|
|
109897
|
+
if (!isOpen) {
|
|
109898
|
+
setExpandedIds(/* @__PURE__ */ new Set());
|
|
109899
|
+
setRawData(null);
|
|
109900
|
+
setError(null);
|
|
109901
|
+
}
|
|
109902
|
+
}, [isOpen]);
|
|
109903
|
+
const toggleRow = useCallback((id) => {
|
|
109904
|
+
setExpandedIds((prev) => {
|
|
109905
|
+
const next = new Set(prev);
|
|
109906
|
+
if (next.has(id)) next.delete(id);
|
|
109907
|
+
else next.add(id);
|
|
109908
|
+
return next;
|
|
109909
|
+
});
|
|
109910
|
+
}, []);
|
|
109911
|
+
const expandAll = useCallback(() => {
|
|
109912
|
+
setExpandedIds(new Set(events.map((e3) => e3.id)));
|
|
109913
|
+
}, [events]);
|
|
109914
|
+
const collapseAll = useCallback(() => {
|
|
109915
|
+
setExpandedIds(/* @__PURE__ */ new Set());
|
|
109916
|
+
}, []);
|
|
109917
|
+
if (!isOpen) return null;
|
|
109918
|
+
const showToolbar = !loading && !error && events.length > 0;
|
|
109919
|
+
const allExpanded = showToolbar && expandedIds.size === events.length;
|
|
109920
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[10000]", children: [
|
|
109921
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109922
|
+
"div",
|
|
109923
|
+
{
|
|
109924
|
+
className: "absolute inset-0 bg-black/40",
|
|
109925
|
+
onClick: onClose,
|
|
109926
|
+
"aria-hidden": "true"
|
|
109927
|
+
}
|
|
109928
|
+
),
|
|
109929
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
109930
|
+
"div",
|
|
109931
|
+
{
|
|
109932
|
+
className: "absolute top-0 right-0 bottom-0 bg-white shadow-2xl flex flex-col",
|
|
109933
|
+
style: { width: "720px", maxWidth: "100vw" },
|
|
109934
|
+
role: "dialog",
|
|
109935
|
+
"aria-label": "Event Logs",
|
|
109936
|
+
onClick: (e3) => e3.stopPropagation(),
|
|
109937
|
+
children: [
|
|
109938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between h-[56px] px-[20px] border-b border-[#E4E7EC] flex-shrink-0", children: [
|
|
109939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
|
|
109940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[16px] font-semibold text-[#101828]", children: "Event Logs" }),
|
|
109941
|
+
!loading && !error && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium text-[#667085] bg-[#F2F4F7] rounded-[10px] px-[8px] py-[2px]", children: events.length })
|
|
109942
|
+
] }),
|
|
109943
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
109944
|
+
showToolbar && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109945
|
+
"button",
|
|
109946
|
+
{
|
|
109947
|
+
type: "button",
|
|
109948
|
+
onClick: allExpanded ? collapseAll : expandAll,
|
|
109949
|
+
className: "text-[13px] font-medium text-[#155EEF] hover:underline px-[8px] py-[6px] rounded-[6px] transition-colors",
|
|
109950
|
+
"data-test-id": "event-logs-toggle-all",
|
|
109951
|
+
children: allExpanded ? "Collapse all" : "Expand all"
|
|
109952
|
+
}
|
|
109953
|
+
),
|
|
109954
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109955
|
+
"button",
|
|
109956
|
+
{
|
|
109957
|
+
type: "button",
|
|
109958
|
+
onClick: onClose,
|
|
109959
|
+
className: "p-[8px] rounded-[6px] hover:bg-[#F2F4F7] transition-colors",
|
|
109960
|
+
title: "Close Event Logs",
|
|
109961
|
+
"aria-label": "Close Event Logs",
|
|
109962
|
+
"data-test-id": "event-logs-close-btn",
|
|
109963
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[16px] h-[16px] text-[#344054]" })
|
|
109964
|
+
}
|
|
109965
|
+
)
|
|
109966
|
+
] })
|
|
109967
|
+
] }),
|
|
109968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto", children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-[8px] text-[13px] text-[#667085]", children: [
|
|
109969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-[20px] h-[20px] animate-spin text-[#155EEF]" }),
|
|
109970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Loading event logs…" })
|
|
109971
|
+
] }) : error ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-[8px] text-[13px] text-[#B42318] px-[24px] text-center", children: [
|
|
109972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Couldn't load event logs" }),
|
|
109973
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] text-[#667085]", children: error })
|
|
109974
|
+
] }) : events.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full flex items-center justify-center text-[13px] text-[#667085]", children: "No events recorded for this session yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative px-[24px] pt-[28px] pb-[8px]", children: [
|
|
109975
|
+
events.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109976
|
+
"div",
|
|
109977
|
+
{
|
|
109978
|
+
className: "absolute w-px bg-[#D0D5DD]",
|
|
109979
|
+
style: { left: "32px", top: "36px", bottom: "28px" },
|
|
109980
|
+
"aria-hidden": "true"
|
|
109981
|
+
}
|
|
109982
|
+
),
|
|
109983
|
+
events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109984
|
+
EventRow,
|
|
109985
|
+
{
|
|
109986
|
+
event,
|
|
109987
|
+
isExpanded: expandedIds.has(event.id),
|
|
109988
|
+
onToggle: () => toggleRow(event.id)
|
|
109989
|
+
},
|
|
109990
|
+
event.id
|
|
109991
|
+
))
|
|
109992
|
+
] }) })
|
|
109993
|
+
]
|
|
109994
|
+
}
|
|
109995
|
+
)
|
|
109996
|
+
] }) });
|
|
109997
|
+
}
|
|
109998
|
+
function hasNonEmptySessionReference(ref) {
|
|
109999
|
+
return typeof ref === "string" && ref.trim().length > 0;
|
|
110000
|
+
}
|
|
109294
110001
|
function DetailPage({
|
|
109295
110002
|
mode: initialMode,
|
|
109296
110003
|
sessionId: initialSessionId,
|
|
@@ -109303,7 +110010,9 @@ function DetailPage({
|
|
|
109303
110010
|
batchSize = DEFAULT_BATCH_SIZE,
|
|
109304
110011
|
initialTraceCount,
|
|
109305
110012
|
initialSessionData,
|
|
109306
|
-
runHeaderInputMode = "display"
|
|
110013
|
+
runHeaderInputMode = "display",
|
|
110014
|
+
onViewEventLogs,
|
|
110015
|
+
fetchEventLogs
|
|
109307
110016
|
}) {
|
|
109308
110017
|
const [currentMode, setCurrentMode] = useState(initialMode);
|
|
109309
110018
|
const [currentSessionId, setCurrentSessionId] = useState(initialSessionId);
|
|
@@ -109313,6 +110022,7 @@ function DetailPage({
|
|
|
109313
110022
|
const traceId = currentTraceId;
|
|
109314
110023
|
const [selectedNode, setSelectedNode] = useState(null);
|
|
109315
110024
|
const [copiedId, setCopiedId] = useState(false);
|
|
110025
|
+
const [isEventLogsOpen, setIsEventLogsOpen] = useState(false);
|
|
109316
110026
|
const minObservationLevel = "DEFAULT";
|
|
109317
110027
|
const [hasAutoSelected, setHasAutoSelected] = useState(false);
|
|
109318
110028
|
const hasInitialData = mode === "session" && initialSessionData;
|
|
@@ -109358,7 +110068,8 @@ function DetailPage({
|
|
|
109358
110068
|
bookmarked: false,
|
|
109359
110069
|
public: false,
|
|
109360
110070
|
traces: [],
|
|
109361
|
-
scores: []
|
|
110071
|
+
scores: [],
|
|
110072
|
+
sessionReference: meta.sessionReference
|
|
109362
110073
|
});
|
|
109363
110074
|
setLoadingState("success");
|
|
109364
110075
|
},
|
|
@@ -109542,6 +110253,10 @@ function DetailPage({
|
|
|
109542
110253
|
} : null
|
|
109543
110254
|
};
|
|
109544
110255
|
}, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
|
|
110256
|
+
const sessionReferenceForEventLogs = useMemo(() => {
|
|
110257
|
+
return (initialSessionData == null ? void 0 : initialSessionData.sessionReference) ?? (sessionData == null ? void 0 : sessionData.sessionReference);
|
|
110258
|
+
}, [initialSessionData == null ? void 0 : initialSessionData.sessionReference, sessionData == null ? void 0 : sessionData.sessionReference]);
|
|
110259
|
+
const showEventLogsBanner = mode === "session" && hasNonEmptySessionReference(sessionReferenceForEventLogs);
|
|
109545
110260
|
const traces = useMemo(() => {
|
|
109546
110261
|
if (mode === "session" && sessionData) {
|
|
109547
110262
|
const sorted = [...sessionData.traces].sort((a4, b2) => {
|
|
@@ -109590,6 +110305,16 @@ function DetailPage({
|
|
|
109590
110305
|
mode,
|
|
109591
110306
|
traceData
|
|
109592
110307
|
]);
|
|
110308
|
+
const handleViewEventLogs = useCallback(() => {
|
|
110309
|
+
setIsEventLogsOpen(true);
|
|
110310
|
+
if (onViewEventLogs && sessionId) {
|
|
110311
|
+
const firstTraceId = traces.length > 0 ? traces[0].id : void 0;
|
|
110312
|
+
onViewEventLogs(sessionId, firstTraceId);
|
|
110313
|
+
}
|
|
110314
|
+
}, [onViewEventLogs, sessionId, traces]);
|
|
110315
|
+
const handleCloseEventLogs = useCallback(() => {
|
|
110316
|
+
setIsEventLogsOpen(false);
|
|
110317
|
+
}, []);
|
|
109593
110318
|
const handleNodeSelect = useCallback((node) => {
|
|
109594
110319
|
setSelectedNode(node);
|
|
109595
110320
|
}, []);
|
|
@@ -109806,6 +110531,7 @@ function DetailPage({
|
|
|
109806
110531
|
] }),
|
|
109807
110532
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
|
|
109808
110533
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-[480px] min-w-[400px] max-w-[600px] border-r border-[#E4E7EC] flex flex-col bg-[#F9FAFB] overflow-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 p-[16px]", children: [
|
|
110534
|
+
showEventLogsBanner && /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceEventLogsBanner, { onViewEventLogs: handleViewEventLogs }),
|
|
109809
110535
|
traces.length === 0 && loadingState === "success" && progressiveState.traceCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[32px] text-center text-[13px] text-[#667085]", children: "No traces available" }),
|
|
109810
110536
|
traces.map((trace, index) => {
|
|
109811
110537
|
var _a, _b, _c, _d;
|
|
@@ -109855,7 +110581,16 @@ function DetailPage({
|
|
|
109855
110581
|
generationSummaryInputOverride
|
|
109856
110582
|
}
|
|
109857
110583
|
)
|
|
109858
|
-
] })
|
|
110584
|
+
] }),
|
|
110585
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
110586
|
+
EventLogsSlideout,
|
|
110587
|
+
{
|
|
110588
|
+
isOpen: isEventLogsOpen,
|
|
110589
|
+
onClose: handleCloseEventLogs,
|
|
110590
|
+
sessionId: sessionId ?? null,
|
|
110591
|
+
fetchEventLogs
|
|
110592
|
+
}
|
|
110593
|
+
)
|
|
109859
110594
|
] });
|
|
109860
110595
|
}
|
|
109861
110596
|
const trace1Observations = [
|
|
@@ -110269,7 +111004,7 @@ function EnvironmentNameCell$1({ envId }) {
|
|
|
110269
111004
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
|
|
110270
111005
|
}
|
|
110271
111006
|
function SessionsListContent(props) {
|
|
110272
|
-
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
|
|
111007
|
+
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId, onViewEventLogs, fetchEventLogs } = props;
|
|
110273
111008
|
const { environments, resolveEnvironmentName } = useEnvironment();
|
|
110274
111009
|
const [selectedSessionId, setSelectedSessionId] = useState(() => initialSessionId ?? null);
|
|
110275
111010
|
const [selectedSessionData, setSelectedSessionData] = useState(null);
|
|
@@ -110830,7 +111565,8 @@ function SessionsListContent(props) {
|
|
|
110830
111565
|
totalCost: session.totalCost,
|
|
110831
111566
|
totalTokens: session.totalTokens,
|
|
110832
111567
|
sessionDuration: session.sessionDuration,
|
|
110833
|
-
createdAt: session.createdAt
|
|
111568
|
+
createdAt: session.createdAt,
|
|
111569
|
+
sessionReference: session.sessionReference
|
|
110834
111570
|
});
|
|
110835
111571
|
setIsModalOpen(true);
|
|
110836
111572
|
if (onSessionClick) {
|
|
@@ -110940,7 +111676,9 @@ function SessionsListContent(props) {
|
|
|
110940
111676
|
sessionId: selectedSessionId,
|
|
110941
111677
|
apiConfig,
|
|
110942
111678
|
onClose: handleModalClose,
|
|
110943
|
-
initialSessionData: selectedSessionData || void 0
|
|
111679
|
+
initialSessionData: selectedSessionData || void 0,
|
|
111680
|
+
onViewEventLogs,
|
|
111681
|
+
fetchEventLogs
|
|
110944
111682
|
}
|
|
110945
111683
|
) })
|
|
110946
111684
|
] });
|
|
@@ -112816,6 +113554,57 @@ function calculateNodeMetrics(node) {
|
|
|
112816
113554
|
return { totalTokens, totalCost, totalDuration };
|
|
112817
113555
|
}
|
|
112818
113556
|
class TreeBuilder {
|
|
113557
|
+
static isPreProcessorNode(node) {
|
|
113558
|
+
const normalizedName = (node.name || "").replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
113559
|
+
return node.type === "tool" && normalizedName === "preprocessor";
|
|
113560
|
+
}
|
|
113561
|
+
static normalizeNodeName(name) {
|
|
113562
|
+
return (name || "").replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
113563
|
+
}
|
|
113564
|
+
static normalizeLinkedEventType(node) {
|
|
113565
|
+
var _a;
|
|
113566
|
+
const linkedEventType = (_a = node.metadata) == null ? void 0 : _a.linkedEventType;
|
|
113567
|
+
if (typeof linkedEventType !== "string" || linkedEventType.trim().length === 0) {
|
|
113568
|
+
return null;
|
|
113569
|
+
}
|
|
113570
|
+
return linkedEventType.replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
113571
|
+
}
|
|
113572
|
+
static normalizeParentId(parentId) {
|
|
113573
|
+
if (typeof parentId !== "string") {
|
|
113574
|
+
return parentId ?? null;
|
|
113575
|
+
}
|
|
113576
|
+
const trimmedParentId = parentId.trim();
|
|
113577
|
+
if (trimmedParentId.length === 0 || trimmedParentId.toLowerCase() === "null" || trimmedParentId.toLowerCase() === "undefined") {
|
|
113578
|
+
return null;
|
|
113579
|
+
}
|
|
113580
|
+
return trimmedParentId;
|
|
113581
|
+
}
|
|
113582
|
+
static isTargetSystemEventNode(node) {
|
|
113583
|
+
const normalizedName = this.normalizeNodeName(node.name || "");
|
|
113584
|
+
if (this.TARGET_EVENT_NAMES.has(normalizedName)) return true;
|
|
113585
|
+
return typeof node.type === "string" && node.type.toLowerCase() === "event";
|
|
113586
|
+
}
|
|
113587
|
+
static compareNodesForDisplay(a4, b2) {
|
|
113588
|
+
const aIsPreProcessor = this.isPreProcessorNode(a4);
|
|
113589
|
+
const bIsPreProcessor = this.isPreProcessorNode(b2);
|
|
113590
|
+
const aIsTargetEvent = this.isTargetSystemEventNode(a4);
|
|
113591
|
+
const bIsTargetEvent = this.isTargetSystemEventNode(b2);
|
|
113592
|
+
const aLinkedEventType = this.normalizeLinkedEventType(a4);
|
|
113593
|
+
const bLinkedEventType = this.normalizeLinkedEventType(b2);
|
|
113594
|
+
const aTargetName = this.normalizeNodeName(a4.name || "");
|
|
113595
|
+
const bTargetName = this.normalizeNodeName(b2.name || "");
|
|
113596
|
+
if (aIsPreProcessor && bIsTargetEvent && aLinkedEventType !== null && aLinkedEventType === bTargetName) {
|
|
113597
|
+
return -1;
|
|
113598
|
+
}
|
|
113599
|
+
if (aIsTargetEvent && bIsPreProcessor && bLinkedEventType !== null && bLinkedEventType === aTargetName) {
|
|
113600
|
+
return 1;
|
|
113601
|
+
}
|
|
113602
|
+
const timestampDiff = new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime();
|
|
113603
|
+
if (timestampDiff !== 0) {
|
|
113604
|
+
return timestampDiff;
|
|
113605
|
+
}
|
|
113606
|
+
return (a4.name || "").localeCompare(b2.name || "");
|
|
113607
|
+
}
|
|
112819
113608
|
/**
|
|
112820
113609
|
* Process execution events and build a hierarchical tree structure
|
|
112821
113610
|
* Session > Run > Node Tree
|
|
@@ -112874,6 +113663,7 @@ class TreeBuilder {
|
|
|
112874
113663
|
const node = this.createTreeNodeFromEvents(startedEvent, completedEvent, runId);
|
|
112875
113664
|
nodes.push(node);
|
|
112876
113665
|
}
|
|
113666
|
+
this.alignEventPreProcessorNodes(nodes);
|
|
112877
113667
|
const rootNodes = this.buildNodeHierarchy(nodes);
|
|
112878
113668
|
const runEvents = events.filter((e3) => e3.runId === runId);
|
|
112879
113669
|
const startTime = Math.min(...runEvents.map((e3) => new Date(e3.data.timestamp).getTime()));
|
|
@@ -112956,8 +113746,10 @@ class TreeBuilder {
|
|
|
112956
113746
|
nodes.forEach((node) => nodeMap.set(node.id, node));
|
|
112957
113747
|
const rootNodes = [];
|
|
112958
113748
|
nodes.forEach((node) => {
|
|
112959
|
-
|
|
112960
|
-
|
|
113749
|
+
const normalizedParentId = this.normalizeParentId(node.parentId);
|
|
113750
|
+
node.parentId = normalizedParentId;
|
|
113751
|
+
if (normalizedParentId && nodeMap.has(normalizedParentId)) {
|
|
113752
|
+
const parent = nodeMap.get(normalizedParentId);
|
|
112961
113753
|
parent.children.push(node);
|
|
112962
113754
|
node.level = parent.level + 1;
|
|
112963
113755
|
} else {
|
|
@@ -112965,12 +113757,98 @@ class TreeBuilder {
|
|
|
112965
113757
|
node.level = 0;
|
|
112966
113758
|
}
|
|
112967
113759
|
});
|
|
112968
|
-
rootNodes.sort(
|
|
112969
|
-
(a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime()
|
|
112970
|
-
);
|
|
113760
|
+
rootNodes.sort((a4, b2) => this.compareNodesForDisplay(a4, b2));
|
|
112971
113761
|
rootNodes.forEach((root2) => this.sortChildren(root2));
|
|
113762
|
+
this.relocateRootEventPreProcessors(rootNodes);
|
|
112972
113763
|
return rootNodes;
|
|
112973
113764
|
}
|
|
113765
|
+
static alignEventPreProcessorNodes(nodes) {
|
|
113766
|
+
const targetEvents = nodes.filter((node) => this.isTargetSystemEventNode(node)).sort((a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime());
|
|
113767
|
+
if (targetEvents.length === 0) {
|
|
113768
|
+
return;
|
|
113769
|
+
}
|
|
113770
|
+
const orphanPreProcessors = nodes.filter((node) => this.isPreProcessorNode(node) && this.normalizeParentId(node.parentId) === null).sort((a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime());
|
|
113771
|
+
for (const preProcessorNode of orphanPreProcessors) {
|
|
113772
|
+
const linkedEventType = this.normalizeLinkedEventType(preProcessorNode);
|
|
113773
|
+
if (linkedEventType === null) {
|
|
113774
|
+
continue;
|
|
113775
|
+
}
|
|
113776
|
+
const candidateEvents = targetEvents.filter(
|
|
113777
|
+
(eventNode) => this.normalizeNodeName(eventNode.name || "") === linkedEventType
|
|
113778
|
+
);
|
|
113779
|
+
if (candidateEvents.length === 0) {
|
|
113780
|
+
continue;
|
|
113781
|
+
}
|
|
113782
|
+
const preProcessorTime = new Date(preProcessorNode.startTime).getTime();
|
|
113783
|
+
let selectedTargetEvent = candidateEvents[0];
|
|
113784
|
+
let minDistance = Number.POSITIVE_INFINITY;
|
|
113785
|
+
for (const targetEvent of candidateEvents) {
|
|
113786
|
+
const distance = Math.abs(new Date(targetEvent.startTime).getTime() - preProcessorTime);
|
|
113787
|
+
if (distance < minDistance) {
|
|
113788
|
+
selectedTargetEvent = targetEvent;
|
|
113789
|
+
minDistance = distance;
|
|
113790
|
+
}
|
|
113791
|
+
}
|
|
113792
|
+
preProcessorNode.parentId = this.normalizeParentId(selectedTargetEvent.parentId);
|
|
113793
|
+
}
|
|
113794
|
+
}
|
|
113795
|
+
static relocateRootEventPreProcessors(rootNodes) {
|
|
113796
|
+
var _a;
|
|
113797
|
+
const preprocessorsAtRoot = rootNodes.filter((node) => this.isPreProcessorNode(node));
|
|
113798
|
+
if (preprocessorsAtRoot.length === 0) {
|
|
113799
|
+
return;
|
|
113800
|
+
}
|
|
113801
|
+
const collectTargetNodes = (nodesToSearch, parentNode2, collector) => {
|
|
113802
|
+
nodesToSearch.forEach((node, index) => {
|
|
113803
|
+
if (this.isTargetSystemEventNode(node)) {
|
|
113804
|
+
collector.push({ node, siblings: nodesToSearch, index, parentNode: parentNode2 });
|
|
113805
|
+
}
|
|
113806
|
+
if (node.children.length > 0) {
|
|
113807
|
+
collectTargetNodes(node.children, node, collector);
|
|
113808
|
+
}
|
|
113809
|
+
});
|
|
113810
|
+
};
|
|
113811
|
+
const targetNodes = [];
|
|
113812
|
+
collectTargetNodes(rootNodes, null, targetNodes);
|
|
113813
|
+
if (targetNodes.length === 0) {
|
|
113814
|
+
return;
|
|
113815
|
+
}
|
|
113816
|
+
const rootSet = new Set(rootNodes);
|
|
113817
|
+
for (const preProcessorNode of preprocessorsAtRoot) {
|
|
113818
|
+
if (!rootSet.has(preProcessorNode)) {
|
|
113819
|
+
continue;
|
|
113820
|
+
}
|
|
113821
|
+
const linkedEventType = this.normalizeLinkedEventType(preProcessorNode);
|
|
113822
|
+
if (linkedEventType === null) {
|
|
113823
|
+
continue;
|
|
113824
|
+
}
|
|
113825
|
+
const candidateTargets = targetNodes.filter(
|
|
113826
|
+
(target) => this.normalizeNodeName(target.node.name || "") === linkedEventType
|
|
113827
|
+
);
|
|
113828
|
+
if (candidateTargets.length === 0) {
|
|
113829
|
+
continue;
|
|
113830
|
+
}
|
|
113831
|
+
const preProcessorTime = new Date(preProcessorNode.startTime).getTime();
|
|
113832
|
+
let selectedTarget = candidateTargets[0];
|
|
113833
|
+
let selectedDistance = Number.POSITIVE_INFINITY;
|
|
113834
|
+
for (const candidate of candidateTargets) {
|
|
113835
|
+
const candidateTime = new Date(candidate.node.startTime).getTime();
|
|
113836
|
+
const distance = Math.abs(candidateTime - preProcessorTime);
|
|
113837
|
+
if (distance < selectedDistance) {
|
|
113838
|
+
selectedTarget = candidate;
|
|
113839
|
+
selectedDistance = distance;
|
|
113840
|
+
}
|
|
113841
|
+
}
|
|
113842
|
+
const rootIndex = rootNodes.indexOf(preProcessorNode);
|
|
113843
|
+
if (rootIndex >= 0) {
|
|
113844
|
+
rootNodes.splice(rootIndex, 1);
|
|
113845
|
+
rootSet.delete(preProcessorNode);
|
|
113846
|
+
}
|
|
113847
|
+
preProcessorNode.parentId = ((_a = selectedTarget.parentNode) == null ? void 0 : _a.id) ?? null;
|
|
113848
|
+
selectedTarget.siblings.splice(selectedTarget.index, 0, preProcessorNode);
|
|
113849
|
+
selectedTarget.siblings.sort((a4, b2) => this.compareNodesForDisplay(a4, b2));
|
|
113850
|
+
}
|
|
113851
|
+
}
|
|
112974
113852
|
/**
|
|
112975
113853
|
* Extract LLM usage metadata from output and event metadata (configurable path)
|
|
112976
113854
|
*/
|
|
@@ -113062,9 +113940,7 @@ class TreeBuilder {
|
|
|
113062
113940
|
*/
|
|
113063
113941
|
static sortChildren(node) {
|
|
113064
113942
|
if (!node) return;
|
|
113065
|
-
node.children.sort(
|
|
113066
|
-
(a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime()
|
|
113067
|
-
);
|
|
113943
|
+
node.children.sort((a4, b2) => this.compareNodesForDisplay(a4, b2));
|
|
113068
113944
|
node.children.forEach((child) => this.sortChildren(child));
|
|
113069
113945
|
}
|
|
113070
113946
|
/**
|
|
@@ -113318,6 +114194,10 @@ class TreeBuilder {
|
|
|
113318
114194
|
);
|
|
113319
114195
|
}
|
|
113320
114196
|
}
|
|
114197
|
+
__publicField(TreeBuilder, "TARGET_EVENT_NAMES", /* @__PURE__ */ new Set([
|
|
114198
|
+
"endofconversation",
|
|
114199
|
+
"agenthandoff"
|
|
114200
|
+
]));
|
|
113321
114201
|
const CodeEditor = ({
|
|
113322
114202
|
value,
|
|
113323
114203
|
onChange,
|