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.
Files changed (32) hide show
  1. package/dist/assets/agentic-ui-libs.css +73 -0
  2. package/dist/features/dashboard/AnalyticsChart.d.ts.map +1 -1
  3. package/dist/features/dashboard/Dashboard.d.ts.map +1 -1
  4. package/dist/features/dashboard/DashboardSection.d.ts.map +1 -1
  5. package/dist/features/dashboard/MetricCard.d.ts.map +1 -1
  6. package/dist/features/dashboard/ModelListView.d.ts +1 -0
  7. package/dist/features/dashboard/ModelListView.d.ts.map +1 -1
  8. package/dist/features/dashboard/ToolListView.d.ts.map +1 -1
  9. package/dist/features/debug-logs/services/TreeBuilder.d.ts +9 -0
  10. package/dist/features/debug-logs/services/TreeBuilder.d.ts.map +1 -1
  11. package/dist/features/tracing/components/SessionsList.d.ts.map +1 -1
  12. package/dist/features/tracing/components/detail/DetailPage.d.ts +1 -1
  13. package/dist/features/tracing/components/detail/DetailPage.d.ts.map +1 -1
  14. package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts +58 -0
  15. package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts.map +1 -0
  16. package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts +11 -0
  17. package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts.map +1 -0
  18. package/dist/features/tracing/components/detail/index.d.ts +2 -0
  19. package/dist/features/tracing/components/detail/index.d.ts.map +1 -1
  20. package/dist/features/tracing/components/detail/services/DetailPageService.d.ts +1 -0
  21. package/dist/features/tracing/components/detail/services/DetailPageService.d.ts.map +1 -1
  22. package/dist/features/tracing/components/detail/types.d.ts +19 -0
  23. package/dist/features/tracing/components/detail/types.d.ts.map +1 -1
  24. package/dist/features/tracing/types.d.ts +11 -0
  25. package/dist/features/tracing/types.d.ts.map +1 -1
  26. package/dist/index.js +1253 -373
  27. package/dist/lib/dashboard-api.service.d.ts +1 -0
  28. package/dist/lib/dashboard-api.service.d.ts.map +1 -1
  29. package/dist/shared/types/index.d.ts +7 -0
  30. package/dist/shared/types/index.d.ts.map +1 -1
  31. package/dist/ui-libs.umd.js +1253 -373
  32. package/package.json +1 -1
@@ -4331,7 +4331,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4331
4331
  onClick,
4332
4332
  isFirst = false
4333
4333
  }) => {
4334
- const { title, value, change, info, highlighted } = data;
4334
+ const { title, value, change, info, highlighted, failedCount } = data;
4335
4335
  const formatValue2 = (val) => {
4336
4336
  if (typeof val === "number") {
4337
4337
  return val.toLocaleString();
@@ -4385,6 +4385,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4385
4385
  ] }),
4386
4386
  /* @__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: [
4387
4387
  /* @__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) }),
4388
+ (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: [
4389
+ "(",
4390
+ failedCount,
4391
+ " failed)"
4392
+ ] }),
4388
4393
  change && /* @__PURE__ */ jsxRuntimeExports.jsxs(
4389
4394
  "div",
4390
4395
  {
@@ -21395,7 +21400,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
21395
21400
  if ("object" != _typeof$i(i2)) return i2;
21396
21401
  throw new TypeError("@@toPrimitive must return a primitive value.");
21397
21402
  }
21398
- return ("string" === r2 ? String : Number)(t);
21403
+ return String(t);
21399
21404
  }
21400
21405
  var Bar = /* @__PURE__ */ function(_PureComponent) {
21401
21406
  function Bar2() {
@@ -28702,7 +28707,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
28702
28707
  return null;
28703
28708
  }
28704
28709
  const filteredPayload = payload.filter(
28705
- (entry) => entry.name && entry.name !== "" && entry.name !== entry.dataKey
28710
+ (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)
28706
28711
  );
28707
28712
  if (filteredPayload.length === 0) {
28708
28713
  return null;
@@ -28802,6 +28807,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
28802
28807
  agentRuns: 0,
28803
28808
  toolRuns: 0,
28804
28809
  modelRuns: 0,
28810
+ failedModelRuns: null,
28805
28811
  codeTools: 0,
28806
28812
  workflowTools: 0,
28807
28813
  knowledgeTools: 0,
@@ -28904,6 +28910,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
28904
28910
  label: config2.title,
28905
28911
  strokeWidth: 2
28906
28912
  }];
28913
+ const lineSeries = chartLines.filter((c2) => (c2.seriesType ?? "line") === "line");
28914
+ const barSeries = chartLines.filter((c2) => c2.seriesType === "bar");
28907
28915
  if (isLoading) {
28908
28916
  console.log("AnalyticsChart: Loading state active");
28909
28917
  return /* @__PURE__ */ jsxRuntimeExports.jsx(ChartSkeleton, { className, chartType: config2.type, height });
@@ -29010,7 +29018,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29010
29018
  bottom: 20
29011
29019
  },
29012
29020
  children: [
29013
- /* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: chartLines.map((lineConfig, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("linearGradient", { id: `gradient-${lineConfig.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
29021
+ /* @__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: [
29014
29022
  /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "5%", stopColor: lineConfig.color, stopOpacity: 0.08 }),
29015
29023
  /* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "95%", stopColor: lineConfig.color, stopOpacity: 0.01 })
29016
29024
  ] }, `gradient-${index}`)) }),
@@ -29062,7 +29070,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29062
29070
  allowEscapeViewBox: { x: false, y: false }
29063
29071
  }
29064
29072
  ),
29065
- chartLines.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29073
+ lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29066
29074
  Area,
29067
29075
  {
29068
29076
  type: "monotone",
@@ -29070,12 +29078,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29070
29078
  stroke: "none",
29071
29079
  fill: `url(#gradient-${lineConfig.dataKey})`,
29072
29080
  fillOpacity: 1,
29081
+ connectNulls: false,
29073
29082
  isAnimationActive: false,
29074
29083
  name: ""
29075
29084
  },
29076
29085
  `area-${lineConfig.dataKey}`
29077
29086
  )),
29078
- chartLines.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29087
+ lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29079
29088
  Line,
29080
29089
  {
29081
29090
  type: "monotone",
@@ -29083,6 +29092,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29083
29092
  stroke: lineConfig.color,
29084
29093
  strokeWidth: 2.5,
29085
29094
  strokeDasharray: lineConfig.strokeDasharray,
29095
+ connectNulls: false,
29086
29096
  dot: false,
29087
29097
  activeDot: {
29088
29098
  r: 5,
@@ -29093,6 +29103,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29093
29103
  name: lineConfig.label
29094
29104
  },
29095
29105
  lineConfig.dataKey
29106
+ )),
29107
+ barSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
29108
+ Bar,
29109
+ {
29110
+ dataKey: lineConfig.dataKey,
29111
+ fill: lineConfig.color,
29112
+ fillOpacity: 0.9,
29113
+ name: lineConfig.label,
29114
+ maxBarSize: 14,
29115
+ radius: [3, 3, 0, 0],
29116
+ isAnimationActive: false
29117
+ },
29118
+ `bar-${lineConfig.dataKey}`
29096
29119
  ))
29097
29120
  ]
29098
29121
  }
@@ -29114,8 +29137,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29114
29137
  })
29115
29138
  ] })
29116
29139
  ] }) }),
29117
- /* @__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: [
29118
- /* @__PURE__ */ jsxRuntimeExports.jsx(
29140
+ /* @__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: [
29141
+ lineConfig.seriesType === "bar" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
29142
+ "div",
29143
+ {
29144
+ className: "w-2 h-2 rounded-[2px]",
29145
+ style: { backgroundColor: lineConfig.color },
29146
+ "data-test-id": `dashboard_analytics_chart_legend_color_${lineConfig.dataKey}`
29147
+ }
29148
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
29119
29149
  "div",
29120
29150
  {
29121
29151
  className: "w-[8px] h-[8px] rounded-full",
@@ -29672,6 +29702,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29672
29702
  return "bg-green-100 text-green-800 border-green-200";
29673
29703
  if (["knowledge", "KNOWLEDGE", "knowledge tool"].includes(type) || ["knowledge", "knowledge tool"].includes(normalized))
29674
29704
  return "bg-purple-100 text-purple-800 border-purple-200";
29705
+ 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))
29706
+ return "bg-yellow-100 text-yellow-800 border-yellow-200";
29675
29707
  return "bg-gray-100 text-gray-800 border-gray-200";
29676
29708
  }
29677
29709
  function getToolTypeName(type) {
@@ -29680,6 +29712,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29680
29712
  if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
29681
29713
  if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
29682
29714
  if (["knowledge", "knowledge tool", "knowledge"].includes(normalized) || type === "KNOWLEDGE") return "Knowledge";
29715
+ if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized) || type === "PRE_PROCESSOR" || type === "POST_PROCESSOR" || type === "INPUT_PROCESSOR" || type === "input_processor")
29716
+ return "Processor";
29683
29717
  if (type === "inlineTool") return "Code Tool";
29684
29718
  if (type === "toolLibrary") return "Workflow Tool";
29685
29719
  if (type === "KNOWLEDGE") return "Knowledge";
@@ -29906,7 +29940,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
29906
29940
  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) })
29907
29941
  ] })
29908
29942
  ] }),
29909
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center font-medium text-xs text-gray-700", "data-test-id": `dashboard_model_list_view_row_runs_${index}`, children: formatValue2(model.runs || 0) }),
29943
+ /* @__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: [
29944
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatValue2(model.runs || 0) }),
29945
+ (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: [
29946
+ "(",
29947
+ model.failedRuns,
29948
+ " failed)"
29949
+ ] })
29950
+ ] }),
29910
29951
  /* @__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) }),
29911
29952
  /* @__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") })
29912
29953
  ]
@@ -30586,6 +30627,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30586
30627
  {
30587
30628
  title: "Model Runs",
30588
30629
  value: data.data.modelRuns,
30630
+ failedCount: data.data.failedModelRuns || 0,
30589
30631
  metricType: "modelRuns",
30590
30632
  icon: "cpu",
30591
30633
  info: "Number of times the AI agents called various language models to generate responses",
@@ -30662,8 +30704,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30662
30704
  basePoint.toolRuns = point2.count || 0;
30663
30705
  break;
30664
30706
  case "modelRuns":
30707
+ case "modelruns": {
30708
+ const failed = point2.failedModelRuns;
30665
30709
  basePoint.modelRuns = point2.count || 0;
30710
+ basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
30666
30711
  break;
30712
+ }
30667
30713
  default:
30668
30714
  basePoint.users = point2.count || 0;
30669
30715
  basePoint.sessions = point2.count || 0;
@@ -30672,6 +30718,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30672
30718
  basePoint.agentRuns = point2.count || 0;
30673
30719
  basePoint.toolRuns = point2.count || 0;
30674
30720
  basePoint.modelRuns = point2.count || 0;
30721
+ {
30722
+ const failed = point2.failedModelRuns;
30723
+ basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
30724
+ }
30675
30725
  }
30676
30726
  console.log(`Transformed point ${index} for metric ${metricType}:`, basePoint);
30677
30727
  return basePoint;
@@ -30756,22 +30806,16 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30756
30806
  id: `model-${index + 1}`,
30757
30807
  name: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName || `Model ${index + 1}`,
30758
30808
  modelName: item.modelName,
30759
- // Keep original modelName field
30760
30809
  provider: item.provider,
30761
- // Include provider information
30762
30810
  runs: item.count || 0,
30811
+ failedRuns: item.failedRuns || 0,
30763
30812
  responseTime: item.avgResponseTime ? item.avgResponseTime < 1e3 ? `${Math.round(item.avgResponseTime)}ms` : `${(item.avgResponseTime / 1e3).toFixed(2)}s` : "0ms",
30764
30813
  avgResponseTime: item.avgResponseTime,
30765
- // Keep original avgResponseTime
30766
30814
  tokens: item.tokens || item.totalTokens || Math.floor((item.count || 0) * 300),
30767
- // Use actual token data when available
30768
30815
  totalTokens: item.totalTokens || item.tokens,
30769
- // Include totalTokens field
30770
30816
  successRate: item.successRate ? `${Math.round(item.successRate)}%` : "98%",
30771
- // Default success rate for models
30772
30817
  lastRun: item.lastRun || new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1e3).toLocaleDateString(),
30773
30818
  icon: item.icon
30774
- // Preserve original icon data if available
30775
30819
  }));
30776
30820
  }
30777
30821
  // Extract control options from listView data for agents
@@ -30825,9 +30869,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30825
30869
  if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
30826
30870
  if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
30827
30871
  if (["knowledge", "knowledge tool"].includes(normalized) || toolType === "KNOWLEDGE") return "Knowledge";
30872
+ if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized)) return "Processor";
30828
30873
  if (toolType === "inlineTool") return "Code Tool";
30829
30874
  if (toolType === "toolLibrary") return "Workflow Tool";
30830
30875
  if (toolType === "MCP" || toolType === "mcpTool") return "MCP Tool";
30876
+ if (toolType === "PRE_PROCESSOR" || toolType === "POST_PROCESSOR" || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") return "Processor";
30831
30877
  return "Code Tool";
30832
30878
  };
30833
30879
  options.push({
@@ -30954,6 +31000,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30954
31000
  if (aggregated.has(key)) {
30955
31001
  const existing = aggregated.get(key);
30956
31002
  existing.count = (existing.count || 0) + (item.count || 0);
31003
+ existing.failedRuns = (existing.failedRuns || 0) + (item.failedRuns || 0);
30957
31004
  existing.avgResponseTime = existing.avgResponseTime && item.avgResponseTime ? (existing.avgResponseTime + item.avgResponseTime) / 2 : existing.avgResponseTime || item.avgResponseTime;
30958
31005
  existing.tokens = (existing.tokens || 0) + (item.tokens || 0);
30959
31006
  } else {
@@ -30965,11 +31012,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30965
31012
  // Batch fetch enhanced data for all metrics with table and control data
30966
31013
  async fetchEnhancedMetricsData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
30967
31014
  try {
30968
- const [agentsData, toolsData, modelsData] = await Promise.all([
31015
+ const results = await Promise.allSettled([
30969
31016
  this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
30970
31017
  this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
30971
31018
  this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
30972
31019
  ]);
31020
+ if (results[0].status === "rejected") {
31021
+ console.error("Error fetching agent runs enhanced data:", results[0].reason);
31022
+ }
31023
+ if (results[1].status === "rejected") {
31024
+ console.error("Error fetching tool runs enhanced data:", results[1].reason);
31025
+ }
31026
+ if (results[2].status === "rejected") {
31027
+ console.error("Error fetching model runs enhanced data:", results[2].reason);
31028
+ }
31029
+ const emptyData = { chartData: [], tableData: [], controlOptions: [] };
31030
+ const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyData;
31031
+ const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyData;
31032
+ const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyData;
30973
31033
  return {
30974
31034
  agents: agentsData,
30975
31035
  tools: toolsData,
@@ -30986,13 +31046,30 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30986
31046
  const getChangeType = (changePercent) => {
30987
31047
  return changePercent > 0 ? "increase" : "decrease";
30988
31048
  };
30989
- const [agentsData, toolsData, modelsData, toolRunsTimeSeriesData] = await Promise.all([
31049
+ const results = await Promise.allSettled([
30990
31050
  this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
30991
31051
  this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
30992
31052
  this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
30993
31053
  this.fetchTimeSeriesData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
30994
31054
  ]);
30995
- const enhancedToolRunsChartData = this.transformTimeSeriesDataForToolRuns(toolRunsTimeSeriesData);
31055
+ if (results[0].status === "rejected") {
31056
+ console.error("Error fetching agent runs data:", results[0].reason);
31057
+ }
31058
+ if (results[1].status === "rejected") {
31059
+ console.error("Error fetching tool runs data:", results[1].reason);
31060
+ }
31061
+ if (results[2].status === "rejected") {
31062
+ console.error("Error fetching model runs data:", results[2].reason);
31063
+ }
31064
+ if (results[3].status === "rejected") {
31065
+ console.error("Error fetching tool runs time series data:", results[3].reason);
31066
+ }
31067
+ const emptyEnhancedData = { chartData: [], tableData: [], controlOptions: [] };
31068
+ const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyEnhancedData;
31069
+ const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyEnhancedData;
31070
+ const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyEnhancedData;
31071
+ const toolRunsTimeSeriesData = results[3].status === "fulfilled" ? results[3].value : void 0;
31072
+ const enhancedToolRunsChartData = toolRunsTimeSeriesData ? this.transformTimeSeriesDataForToolRuns(toolRunsTimeSeriesData) : [];
30996
31073
  return [
30997
31074
  {
30998
31075
  title: "Agent Runs",
@@ -31006,68 +31083,70 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31006
31083
  value: Math.abs(trends.agentRuns.changePercent),
31007
31084
  type: getChangeType(trends.agentRuns.changePercent)
31008
31085
  } : void 0,
31009
- view: {
31010
- type: "chart",
31011
- chart: {
31012
- type: "line",
31013
- title: "Agent Runs",
31014
- data: agentsData.chartData,
31015
- dataKey: "agentRuns",
31016
- color: "#0BA5EC",
31017
- yAxisLabel: "Number of Agent Runs",
31018
- height: 300,
31019
- showGrid: true,
31020
- curve: "monotone",
31021
- tooltip: { show: true, style: "dark" },
31022
- dateRange: {
31023
- start: fromTimestamp.split("T")[0],
31024
- end: toTimestamp.split("T")[0]
31025
- }
31026
- },
31027
- table: {
31028
- title: "Agent Runs",
31029
- data: agentsData.tableData,
31030
- columns: [
31031
- {
31032
- key: "name",
31033
- title: "Name",
31034
- width: 200,
31035
- align: "left"
31036
- },
31037
- {
31038
- key: "runs",
31039
- title: "Runs",
31040
- width: 100,
31041
- align: "right",
31042
- formatter: (value) => `${Math.floor(value / 1e3)}k`
31043
- },
31044
- {
31045
- key: "responseTime",
31046
- title: "Response Time",
31047
- width: 120,
31048
- align: "right"
31049
- },
31050
- {
31051
- key: "tokens",
31052
- title: "Tokens",
31053
- width: 100,
31054
- align: "right",
31055
- formatter: (value) => `${Math.floor(value / 1e3)}k`
31086
+ ...agentsData && {
31087
+ view: {
31088
+ type: "chart",
31089
+ chart: {
31090
+ type: "line",
31091
+ title: "Agent Runs",
31092
+ data: agentsData.chartData,
31093
+ dataKey: "agentRuns",
31094
+ color: "#0BA5EC",
31095
+ yAxisLabel: "Number of Agent Runs",
31096
+ height: 300,
31097
+ showGrid: true,
31098
+ curve: "monotone",
31099
+ tooltip: { show: true, style: "dark" },
31100
+ dateRange: {
31101
+ start: fromTimestamp.split("T")[0],
31102
+ end: toTimestamp.split("T")[0]
31056
31103
  }
31057
- ]
31058
- }
31059
- },
31060
- controls: {
31061
- dropdown: {
31062
- label: "All Agents",
31063
- options: agentsData.controlOptions,
31064
- defaultValue: ["all"],
31065
- multiSelect: true,
31066
- searchable: true
31104
+ },
31105
+ table: {
31106
+ title: "Agent Runs",
31107
+ data: agentsData.tableData,
31108
+ columns: [
31109
+ {
31110
+ key: "name",
31111
+ title: "Name",
31112
+ width: 200,
31113
+ align: "left"
31114
+ },
31115
+ {
31116
+ key: "runs",
31117
+ title: "Runs",
31118
+ width: 100,
31119
+ align: "right",
31120
+ formatter: (value) => `${Math.floor(value / 1e3)}k`
31121
+ },
31122
+ {
31123
+ key: "responseTime",
31124
+ title: "Response Time",
31125
+ width: 120,
31126
+ align: "right"
31127
+ },
31128
+ {
31129
+ key: "tokens",
31130
+ title: "Tokens",
31131
+ width: 100,
31132
+ align: "right",
31133
+ formatter: (value) => `${Math.floor(value / 1e3)}k`
31134
+ }
31135
+ ]
31136
+ }
31067
31137
  },
31068
- toggle: {
31069
- chartView: true,
31070
- tableView: true
31138
+ controls: {
31139
+ dropdown: {
31140
+ label: "All Agents",
31141
+ options: agentsData.controlOptions,
31142
+ defaultValue: ["all"],
31143
+ multiSelect: true,
31144
+ searchable: true
31145
+ },
31146
+ toggle: {
31147
+ chartView: true,
31148
+ tableView: true
31149
+ }
31071
31150
  }
31072
31151
  }
31073
31152
  },
@@ -31082,99 +31161,107 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31082
31161
  value: Math.abs(trends.toolRuns.changePercent.total),
31083
31162
  type: getChangeType(trends.toolRuns.changePercent.total)
31084
31163
  } : void 0,
31085
- view: {
31086
- type: "chart",
31087
- chart: {
31088
- type: "line",
31089
- title: "Tool Runs",
31090
- data: enhancedToolRunsChartData,
31091
- yAxisLabel: "Number of Tool Runs",
31092
- lines: [
31093
- {
31094
- dataKey: "toolRuns",
31095
- color: "#667085",
31096
- label: "Tool Runs"
31097
- },
31098
- {
31099
- dataKey: "codeTools",
31100
- color: "#F38744",
31101
- label: "Code Tools"
31102
- },
31103
- {
31104
- dataKey: "workflowTools",
31105
- color: "#2970FF",
31106
- label: "Workflow Tools"
31107
- },
31108
- {
31109
- dataKey: "knowledgeTools",
31110
- color: "#7A5AF8",
31111
- label: "Knowledge"
31112
- },
31113
- {
31114
- dataKey: "mcpTools",
31115
- color: "#47CD89",
31116
- label: "MCP Tools"
31164
+ ...toolsData && {
31165
+ view: {
31166
+ type: "chart",
31167
+ chart: {
31168
+ type: "line",
31169
+ title: "Tool Runs",
31170
+ data: enhancedToolRunsChartData,
31171
+ yAxisLabel: "Number of Tool Runs",
31172
+ lines: [
31173
+ {
31174
+ dataKey: "toolRuns",
31175
+ color: "#667085",
31176
+ label: "Tool Runs"
31177
+ },
31178
+ {
31179
+ dataKey: "codeTools",
31180
+ color: "#F38744",
31181
+ label: "Code Tools"
31182
+ },
31183
+ {
31184
+ dataKey: "workflowTools",
31185
+ color: "#2970FF",
31186
+ label: "Workflow Tools"
31187
+ },
31188
+ {
31189
+ dataKey: "knowledgeTools",
31190
+ color: "#7A5AF8",
31191
+ label: "Knowledge"
31192
+ },
31193
+ {
31194
+ dataKey: "mcpTools",
31195
+ color: "#47CD89",
31196
+ label: "MCP Tools"
31197
+ },
31198
+ {
31199
+ dataKey: "processors",
31200
+ color: "#EAB308",
31201
+ label: "Processors"
31202
+ }
31203
+ ],
31204
+ height: 300,
31205
+ showGrid: true,
31206
+ showLegend: true,
31207
+ curve: "monotone",
31208
+ tooltip: { show: true, style: "dark" },
31209
+ dateRange: {
31210
+ start: fromTimestamp.split("T")[0],
31211
+ end: toTimestamp.split("T")[0]
31117
31212
  }
31118
- ],
31119
- height: 300,
31120
- showGrid: true,
31121
- showLegend: true,
31122
- curve: "monotone",
31123
- tooltip: { show: true, style: "dark" },
31124
- dateRange: {
31125
- start: fromTimestamp.split("T")[0],
31126
- end: toTimestamp.split("T")[0]
31213
+ },
31214
+ table: {
31215
+ title: "Tool Runs",
31216
+ data: toolsData.tableData,
31217
+ columns: [
31218
+ {
31219
+ key: "name",
31220
+ title: "Name",
31221
+ width: 200,
31222
+ align: "left"
31223
+ },
31224
+ {
31225
+ key: "type",
31226
+ title: "Type",
31227
+ width: 150,
31228
+ align: "left"
31229
+ },
31230
+ {
31231
+ key: "runs",
31232
+ title: "Runs",
31233
+ width: 100,
31234
+ align: "right",
31235
+ formatter: (value) => `${Math.floor(value / 1e3)}k`
31236
+ },
31237
+ {
31238
+ key: "responseTime",
31239
+ title: "Response Time",
31240
+ width: 120,
31241
+ align: "right"
31242
+ }
31243
+ ]
31127
31244
  }
31128
31245
  },
31129
- table: {
31130
- title: "Tool Runs",
31131
- data: toolsData.tableData,
31132
- columns: [
31133
- {
31134
- key: "name",
31135
- title: "Name",
31136
- width: 200,
31137
- align: "left"
31138
- },
31139
- {
31140
- key: "type",
31141
- title: "Type",
31142
- width: 150,
31143
- align: "left"
31144
- },
31145
- {
31146
- key: "runs",
31147
- title: "Runs",
31148
- width: 100,
31149
- align: "right",
31150
- formatter: (value) => `${Math.floor(value / 1e3)}k`
31151
- },
31152
- {
31153
- key: "responseTime",
31154
- title: "Response Time",
31155
- width: 120,
31156
- align: "right"
31157
- }
31158
- ]
31159
- }
31160
- },
31161
- controls: {
31162
- dropdown: {
31163
- label: "All Tools",
31164
- options: toolsData.controlOptions,
31165
- defaultValue: ["all"],
31166
- multiSelect: true,
31167
- searchable: true
31168
- },
31169
- toggle: {
31170
- chartView: true,
31171
- tableView: true
31246
+ controls: {
31247
+ dropdown: {
31248
+ label: "All Tools",
31249
+ options: toolsData.controlOptions,
31250
+ defaultValue: ["all"],
31251
+ multiSelect: true,
31252
+ searchable: true
31253
+ },
31254
+ toggle: {
31255
+ chartView: true,
31256
+ tableView: true
31257
+ }
31172
31258
  }
31173
31259
  }
31174
31260
  },
31175
31261
  {
31176
31262
  title: "Model Runs",
31177
31263
  value: data.data.modelRuns,
31264
+ failedCount: data.data.failedModelRuns || 0,
31178
31265
  metricType: "modelRuns",
31179
31266
  icon: "cpu",
31180
31267
  highlighted: false,
@@ -31183,68 +31270,79 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31183
31270
  value: Math.abs(trends.modelRuns.changePercent),
31184
31271
  type: getChangeType(trends.modelRuns.changePercent)
31185
31272
  } : void 0,
31186
- view: {
31187
- type: "chart",
31188
- chart: {
31189
- type: "line",
31190
- title: "Model Runs",
31191
- data: modelsData.chartData,
31192
- dataKey: "modelRuns",
31193
- color: "#47CD89",
31194
- yAxisLabel: "Number of Model Runs",
31195
- height: 300,
31196
- showGrid: true,
31197
- curve: "monotone",
31198
- tooltip: { show: true, style: "dark" },
31199
- dateRange: {
31200
- start: fromTimestamp.split("T")[0],
31201
- end: toTimestamp.split("T")[0]
31202
- }
31203
- },
31204
- table: {
31205
- title: "Model Runs",
31206
- data: modelsData.tableData,
31207
- columns: [
31208
- {
31209
- key: "name",
31210
- title: "Model Name",
31211
- width: 200,
31212
- align: "left"
31213
- },
31214
- {
31215
- key: "runs",
31216
- title: "Runs",
31217
- width: 100,
31218
- align: "right",
31219
- formatter: (value) => `${Math.floor(value / 1e3)}k`
31220
- },
31221
- {
31222
- key: "tokens",
31223
- title: "Tokens",
31224
- width: 120,
31225
- align: "right",
31226
- formatter: (value) => `${Math.floor(value / 1e3)}k`
31227
- },
31228
- {
31229
- key: "responseTime",
31230
- title: "Response Time",
31231
- width: 120,
31232
- align: "right"
31273
+ ...modelsData && {
31274
+ view: {
31275
+ type: "chart",
31276
+ chart: {
31277
+ type: "line",
31278
+ title: "Model Runs",
31279
+ data: modelsData.chartData,
31280
+ yAxisLabel: "Number of Model Runs",
31281
+ lines: [
31282
+ { dataKey: "modelRuns", color: "#47CD89", label: "Model Runs" },
31283
+ {
31284
+ dataKey: "failedModelRuns",
31285
+ color: "#ef4444",
31286
+ label: "Failed",
31287
+ seriesType: "bar",
31288
+ hideInLegend: true
31289
+ }
31290
+ ],
31291
+ height: 300,
31292
+ showGrid: true,
31293
+ showLegend: true,
31294
+ curve: "monotone",
31295
+ tooltip: { show: true, style: "dark" },
31296
+ dateRange: {
31297
+ start: fromTimestamp.split("T")[0],
31298
+ end: toTimestamp.split("T")[0]
31233
31299
  }
31234
- ]
31235
- }
31236
- },
31237
- controls: {
31238
- dropdown: {
31239
- label: "All Models",
31240
- options: modelsData.controlOptions,
31241
- defaultValue: ["all"],
31242
- multiSelect: true,
31243
- searchable: true
31300
+ },
31301
+ table: {
31302
+ title: "Model Runs",
31303
+ data: modelsData.tableData,
31304
+ columns: [
31305
+ {
31306
+ key: "name",
31307
+ title: "Model Name",
31308
+ width: 200,
31309
+ align: "left"
31310
+ },
31311
+ {
31312
+ key: "runs",
31313
+ title: "Runs",
31314
+ width: 100,
31315
+ align: "right",
31316
+ formatter: (value) => `${Math.floor(value / 1e3)}k`
31317
+ },
31318
+ {
31319
+ key: "tokens",
31320
+ title: "Tokens",
31321
+ width: 120,
31322
+ align: "right",
31323
+ formatter: (value) => `${Math.floor(value / 1e3)}k`
31324
+ },
31325
+ {
31326
+ key: "responseTime",
31327
+ title: "Response Time",
31328
+ width: 120,
31329
+ align: "right"
31330
+ }
31331
+ ]
31332
+ }
31244
31333
  },
31245
- toggle: {
31246
- chartView: true,
31247
- tableView: true
31334
+ controls: {
31335
+ dropdown: {
31336
+ label: "All Models",
31337
+ options: modelsData.controlOptions,
31338
+ defaultValue: ["all"],
31339
+ multiSelect: true,
31340
+ searchable: true
31341
+ },
31342
+ toggle: {
31343
+ chartView: true,
31344
+ tableView: true
31345
+ }
31248
31346
  }
31249
31347
  }
31250
31348
  }
@@ -31256,12 +31354,34 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31256
31354
  const getChangeType = (changePercent) => {
31257
31355
  return changePercent > 0 ? "increase" : "decrease";
31258
31356
  };
31259
- const [usersData, sessionsData, messagesData, tokensData] = await Promise.all([
31357
+ const results = await Promise.allSettled([
31260
31358
  this.fetchTimeSeriesData("users", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
31261
31359
  this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
31262
31360
  this.fetchTimeSeriesData("messages", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
31263
31361
  this.fetchTimeSeriesData("tokens", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters)
31264
31362
  ]);
31363
+ if (results[0].status === "rejected") {
31364
+ console.error("Error fetching users data:", results[0].reason);
31365
+ }
31366
+ if (results[1].status === "rejected") {
31367
+ console.error("Error fetching sessions data:", results[1].reason);
31368
+ }
31369
+ if (results[2].status === "rejected") {
31370
+ console.error("Error fetching messages data:", results[2].reason);
31371
+ }
31372
+ if (results[3].status === "rejected") {
31373
+ console.error("Error fetching tokens data:", results[3].reason);
31374
+ }
31375
+ const emptyTimeSeries = {
31376
+ type: "time-series",
31377
+ category: "usage-analytics",
31378
+ metric: "",
31379
+ data: []
31380
+ };
31381
+ const usersData = results[0].status === "fulfilled" ? results[0].value : { ...emptyTimeSeries, metric: "users" };
31382
+ const sessionsData = results[1].status === "fulfilled" ? results[1].value : { ...emptyTimeSeries, metric: "sessions" };
31383
+ const messagesData = results[2].status === "fulfilled" ? results[2].value : { ...emptyTimeSeries, metric: "messages" };
31384
+ const tokensData = results[3].status === "fulfilled" ? results[3].value : { ...emptyTimeSeries, metric: "tokens" };
31265
31385
  return [
31266
31386
  {
31267
31387
  title: "Users",
@@ -31275,22 +31395,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31275
31395
  value: Math.abs(trends.users.changePercent),
31276
31396
  type: getChangeType(trends.users.changePercent)
31277
31397
  } : void 0,
31278
- view: {
31279
- type: "chart",
31280
- chart: {
31281
- type: "line",
31282
- title: "Total Users",
31283
- data: this.transformTimeSeriesDataForMetric(usersData, "users"),
31284
- dataKey: "users",
31285
- color: "#4E5BA6",
31286
- yAxisLabel: "Number of Users",
31287
- height: 300,
31288
- showGrid: true,
31289
- curve: "monotone",
31290
- tooltip: { show: true, style: "dark" },
31291
- dateRange: {
31292
- start: fromTimestamp.split("T")[0],
31293
- end: toTimestamp.split("T")[0]
31398
+ ...usersData && {
31399
+ view: {
31400
+ type: "chart",
31401
+ chart: {
31402
+ type: "line",
31403
+ title: "Total Users",
31404
+ data: this.transformTimeSeriesDataForMetric(usersData, "users"),
31405
+ dataKey: "users",
31406
+ color: "#4E5BA6",
31407
+ yAxisLabel: "Number of Users",
31408
+ height: 300,
31409
+ showGrid: true,
31410
+ curve: "monotone",
31411
+ tooltip: { show: true, style: "dark" },
31412
+ dateRange: {
31413
+ start: fromTimestamp.split("T")[0],
31414
+ end: toTimestamp.split("T")[0]
31415
+ }
31294
31416
  }
31295
31417
  }
31296
31418
  }
@@ -31306,22 +31428,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31306
31428
  value: Math.abs(trends.sessions.changePercent),
31307
31429
  type: getChangeType(trends.sessions.changePercent)
31308
31430
  } : void 0,
31309
- view: {
31310
- type: "chart",
31311
- chart: {
31312
- type: "line",
31313
- title: "Total Sessions",
31314
- data: this.transformTimeSeriesDataForMetric(sessionsData, "sessions"),
31315
- dataKey: "sessions",
31316
- color: "#0BA5EC",
31317
- yAxisLabel: "Number of Sessions",
31318
- height: 300,
31319
- showGrid: true,
31320
- curve: "monotone",
31321
- tooltip: { show: true, style: "dark" },
31322
- dateRange: {
31323
- start: fromTimestamp.split("T")[0],
31324
- end: toTimestamp.split("T")[0]
31431
+ ...sessionsData && {
31432
+ view: {
31433
+ type: "chart",
31434
+ chart: {
31435
+ type: "line",
31436
+ title: "Total Sessions",
31437
+ data: this.transformTimeSeriesDataForMetric(sessionsData, "sessions"),
31438
+ dataKey: "sessions",
31439
+ color: "#0BA5EC",
31440
+ yAxisLabel: "Number of Sessions",
31441
+ height: 300,
31442
+ showGrid: true,
31443
+ curve: "monotone",
31444
+ tooltip: { show: true, style: "dark" },
31445
+ dateRange: {
31446
+ start: fromTimestamp.split("T")[0],
31447
+ end: toTimestamp.split("T")[0]
31448
+ }
31325
31449
  }
31326
31450
  }
31327
31451
  }
@@ -31337,22 +31461,24 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31337
31461
  value: Math.abs(trends.messages.changePercent.total),
31338
31462
  type: getChangeType(trends.messages.changePercent.total)
31339
31463
  } : void 0,
31340
- view: {
31341
- type: "chart",
31342
- chart: {
31343
- type: "line",
31344
- title: "Total Messages",
31345
- data: this.transformTimeSeriesDataForMetric(messagesData, "messages"),
31346
- dataKey: "messages",
31347
- color: "#E478FA",
31348
- yAxisLabel: "Number of Messages",
31349
- height: 300,
31350
- showGrid: true,
31351
- curve: "monotone",
31352
- tooltip: { show: true, style: "dark" },
31353
- dateRange: {
31354
- start: fromTimestamp.split("T")[0],
31355
- end: toTimestamp.split("T")[0]
31464
+ ...messagesData && {
31465
+ view: {
31466
+ type: "chart",
31467
+ chart: {
31468
+ type: "line",
31469
+ title: "Total Messages",
31470
+ data: this.transformTimeSeriesDataForMetric(messagesData, "messages"),
31471
+ dataKey: "messages",
31472
+ color: "#E478FA",
31473
+ yAxisLabel: "Number of Messages",
31474
+ height: 300,
31475
+ showGrid: true,
31476
+ curve: "monotone",
31477
+ tooltip: { show: true, style: "dark" },
31478
+ dateRange: {
31479
+ start: fromTimestamp.split("T")[0],
31480
+ end: toTimestamp.split("T")[0]
31481
+ }
31356
31482
  }
31357
31483
  }
31358
31484
  }
@@ -31368,38 +31494,40 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31368
31494
  value: Math.abs(trends.tokens.changePercent.total),
31369
31495
  type: getChangeType(trends.tokens.changePercent.total)
31370
31496
  } : void 0,
31371
- view: {
31372
- type: "chart",
31373
- chart: {
31374
- type: "line",
31375
- title: "Token Usage Breakdown",
31376
- data: this.transformTimeSeriesDataForMetric(tokensData, "tokens"),
31377
- yAxisLabel: "Number of Tokens",
31378
- lines: [
31379
- {
31380
- dataKey: "totalTokens",
31381
- color: "#FF692E",
31382
- label: "Total Tokens"
31383
- },
31384
- {
31385
- dataKey: "inputTokens",
31386
- color: "#5925DC",
31387
- label: "Input Tokens"
31388
- },
31389
- {
31390
- dataKey: "outputTokens",
31391
- color: "#E478FA",
31392
- label: "Output Tokens"
31497
+ ...tokensData && {
31498
+ view: {
31499
+ type: "chart",
31500
+ chart: {
31501
+ type: "line",
31502
+ title: "Token Usage Breakdown",
31503
+ data: this.transformTimeSeriesDataForMetric(tokensData, "tokens"),
31504
+ yAxisLabel: "Number of Tokens",
31505
+ lines: [
31506
+ {
31507
+ dataKey: "totalTokens",
31508
+ color: "#FF692E",
31509
+ label: "Total Tokens"
31510
+ },
31511
+ {
31512
+ dataKey: "inputTokens",
31513
+ color: "#5925DC",
31514
+ label: "Input Tokens"
31515
+ },
31516
+ {
31517
+ dataKey: "outputTokens",
31518
+ color: "#E478FA",
31519
+ label: "Output Tokens"
31520
+ }
31521
+ ],
31522
+ height: 300,
31523
+ showGrid: true,
31524
+ showLegend: true,
31525
+ curve: "monotone",
31526
+ tooltip: { show: true, style: "dark" },
31527
+ dateRange: {
31528
+ start: fromTimestamp.split("T")[0],
31529
+ end: toTimestamp.split("T")[0]
31393
31530
  }
31394
- ],
31395
- height: 300,
31396
- showGrid: true,
31397
- showLegend: true,
31398
- curve: "monotone",
31399
- tooltip: { show: true, style: "dark" },
31400
- dateRange: {
31401
- start: fromTimestamp.split("T")[0],
31402
- end: toTimestamp.split("T")[0]
31403
31531
  }
31404
31532
  }
31405
31533
  }
@@ -31427,35 +31555,27 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31427
31555
  let workflowTools = 0;
31428
31556
  let knowledgeTools = 0;
31429
31557
  let mcpTools = 0;
31558
+ let processors = 0;
31430
31559
  if (point2.listView && Array.isArray(point2.listView)) {
31431
31560
  point2.listView.forEach((item) => {
31432
31561
  const count = item.count || 0;
31433
- const toolType = (item.toolType || item.tool_type || "").toLowerCase();
31434
- const toolName = (item.toolName || item.tool_name || "").toLowerCase();
31435
- console.log(`Processing listView item:`, { toolType, toolName, count });
31562
+ const toolType = item.toolType || item.tool_type || "";
31436
31563
  const normalizedToolType = toolType.toLowerCase();
31437
- if (["inlinetool", "inlineTool", "tool", "code", "codetool", "event", "EVENT"].includes(toolType) || ["inlinetool", "tool", "code", "codetool", "event"].includes(normalizedToolType)) {
31564
+ if (["inlinetool", "tool", "code", "codetool", "event"].includes(normalizedToolType)) {
31438
31565
  codeTools += count;
31439
- } else if (["toollibrary", "toolLibrary", "workflow", "tool"].includes(toolType) || ["toollibrary", "workflow", "tool"].includes(normalizedToolType)) {
31566
+ } else if (["toollibrary", "workflow"].includes(normalizedToolType)) {
31440
31567
  workflowTools += count;
31441
- } else if (["knowledge", "KNOWLEDGE", "knowledgetool"].includes(toolType) || ["knowledge", "knowledgetool"].includes(normalizedToolType)) {
31568
+ } else if (["knowledge", "knowledgetool"].includes(normalizedToolType) || toolType === "KNOWLEDGE") {
31442
31569
  knowledgeTools += count;
31443
- } else if (["mcp", "MCP", "mcptool", "mcpTool"].includes(toolType) || ["mcp", "mcptool"].includes(normalizedToolType)) {
31570
+ } else if (["mcp", "mcptool"].includes(normalizedToolType)) {
31444
31571
  mcpTools += count;
31572
+ } else if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalizedToolType) || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") {
31573
+ processors += count;
31445
31574
  } else {
31446
- console.log(`Unknown tool type '${toolType}' for tool '${toolName}', defaulting to code tools`);
31447
31575
  codeTools += count;
31448
31576
  }
31449
31577
  });
31450
- console.log(`Calculated breakdown for point ${index}:`, {
31451
- codeTools,
31452
- workflowTools,
31453
- knowledgeTools,
31454
- mcpTools,
31455
- total: codeTools + workflowTools + knowledgeTools + mcpTools,
31456
- expectedTotal: totalToolRuns
31457
- });
31458
- const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools;
31578
+ const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools + processors;
31459
31579
  if (Math.abs(calculatedTotal - totalToolRuns) > 1) {
31460
31580
  console.warn(`Breakdown total (${calculatedTotal}) doesn't match expected total (${totalToolRuns}) for point ${index}`);
31461
31581
  const difference = totalToolRuns - calculatedTotal;
@@ -31463,7 +31583,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31463
31583
  console.log(`Adjusted codeTools by ${difference} to balance total`);
31464
31584
  }
31465
31585
  } else {
31466
- console.log(`No listView data for point ${index}, assigning all ${totalToolRuns} to codeTools`);
31467
31586
  codeTools = totalToolRuns;
31468
31587
  }
31469
31588
  const basePoint = {
@@ -31474,11 +31593,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31474
31593
  toolRuns: totalToolRuns,
31475
31594
  value: totalToolRuns,
31476
31595
  count: totalToolRuns,
31477
- // Tool breakdown data for multi-line chart (using actual data)
31478
31596
  codeTools,
31479
31597
  workflowTools,
31480
31598
  knowledgeTools,
31481
31599
  mcpTools,
31600
+ processors,
31482
31601
  // Token data
31483
31602
  input_tokens: point2.input_tokens || 0,
31484
31603
  output_tokens: point2.output_tokens || 0,
@@ -31516,14 +31635,33 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31516
31635
  // Enhanced batch fetch method that returns complete MetricData with embedded view and controls
31517
31636
  async fetchAllCardsDataWithEnhancedViews(fromTimestamp, toTimestamp, timeDimension, filters = []) {
31518
31637
  try {
31519
- const [usageAnalyticsCards, runsCards] = await Promise.all([
31638
+ const cardsResults = await Promise.allSettled([
31520
31639
  this.fetchUsageAnalyticsCards(fromTimestamp, toTimestamp, timeDimension, filters),
31521
31640
  this.fetchRunsCards(fromTimestamp, toTimestamp, timeDimension, filters)
31522
31641
  ]);
31523
- const [enhancedUsageAnalytics, enhancedRuns] = await Promise.all([
31524
- this.transformUsageAnalyticsCardsWithEnhancedData(usageAnalyticsCards, fromTimestamp, toTimestamp, timeDimension, filters),
31525
- this.transformRunsCardsWithEnhancedData(runsCards, fromTimestamp, toTimestamp, timeDimension, filters)
31642
+ if (cardsResults[0].status === "rejected") {
31643
+ console.error("Error fetching usage analytics cards:", cardsResults[0].reason);
31644
+ }
31645
+ if (cardsResults[1].status === "rejected") {
31646
+ console.error("Error fetching runs cards:", cardsResults[1].reason);
31647
+ }
31648
+ if (cardsResults[0].status === "rejected" && cardsResults[1].status === "rejected") {
31649
+ throw new Error("Both usage analytics and runs cards failed to load");
31650
+ }
31651
+ const usageAnalyticsCards = cardsResults[0].status === "fulfilled" ? cardsResults[0].value : void 0;
31652
+ const runsCards = cardsResults[1].status === "fulfilled" ? cardsResults[1].value : void 0;
31653
+ const enhancementResults = await Promise.allSettled([
31654
+ usageAnalyticsCards ? this.transformUsageAnalyticsCardsWithEnhancedData(usageAnalyticsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([]),
31655
+ runsCards ? this.transformRunsCardsWithEnhancedData(runsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([])
31526
31656
  ]);
31657
+ if (enhancementResults[0].status === "rejected") {
31658
+ console.error("Error transforming usage analytics cards:", enhancementResults[0].reason);
31659
+ }
31660
+ if (enhancementResults[1].status === "rejected") {
31661
+ console.error("Error transforming runs cards:", enhancementResults[1].reason);
31662
+ }
31663
+ const enhancedUsageAnalytics = enhancementResults[0].status === "fulfilled" ? enhancementResults[0].value : [];
31664
+ const enhancedRuns = enhancementResults[1].status === "fulfilled" ? enhancementResults[1].value : [];
31527
31665
  return {
31528
31666
  usageAnalytics: enhancedUsageAnalytics,
31529
31667
  runs: enhancedRuns
@@ -31536,13 +31674,21 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31536
31674
  // Batch fetch time series data for default selected metrics
31537
31675
  async fetchDefaultTimeSeriesData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
31538
31676
  try {
31539
- const [sessionsData, agentRunsData] = await Promise.all([
31677
+ const results = await Promise.allSettled([
31540
31678
  this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
31541
31679
  this.fetchTimeSeriesData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
31542
31680
  ]);
31681
+ if (results[0].status === "rejected") {
31682
+ console.error("Error fetching sessions data:", results[0].reason);
31683
+ }
31684
+ if (results[1].status === "rejected") {
31685
+ console.error("Error fetching agent runs data:", results[1].reason);
31686
+ }
31687
+ const sessionsData = results[0].status === "fulfilled" ? results[0].value : void 0;
31688
+ const agentRunsData = results[1].status === "fulfilled" ? results[1].value : void 0;
31543
31689
  return {
31544
- sessions: this.transformTimeSeriesData(sessionsData),
31545
- agentRuns: this.transformTimeSeriesData(agentRunsData)
31690
+ sessions: sessionsData ? this.transformTimeSeriesData(sessionsData) : [],
31691
+ agentRuns: agentRunsData ? this.transformTimeSeriesData(agentRunsData) : []
31546
31692
  };
31547
31693
  } catch (error) {
31548
31694
  console.error("Error fetching default time series data:", error);
@@ -32269,6 +32415,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32269
32415
  ] })
32270
32416
  ] });
32271
32417
  };
32418
+ function modelListViewRowLabel(listItem) {
32419
+ if (!listItem.modelName) return "";
32420
+ return listItem.connectionName ? `${listItem.modelName} - ${listItem.connectionName}` : listItem.modelName;
32421
+ }
32272
32422
  const DashboardSection = ({
32273
32423
  section,
32274
32424
  className,
@@ -32366,16 +32516,17 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32366
32516
  });
32367
32517
  return baseData.map((item) => {
32368
32518
  let filteredValue = 0;
32519
+ let matchingItems = [];
32369
32520
  if (item["listView"] && Array.isArray(item["listView"])) {
32370
- const matchingItems = item["listView"].filter((listItem) => {
32521
+ matchingItems = item["listView"].filter((listItem) => {
32371
32522
  if (metricType === "agentRuns" && listItem.agentName) {
32372
32523
  return listItem.agentName === selectedLabel || listItem.agentName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
32373
32524
  }
32374
32525
  if (metricType === "toolRuns" && listItem.toolName) {
32375
32526
  return listItem.toolName === selectedLabel || listItem.toolName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
32376
32527
  }
32377
- if (metricType === "modelRuns" && listItem.modelName) {
32378
- return listItem.modelName === selectedLabel || listItem.modelName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
32528
+ if (metricType === "modelRuns" && listItem.modelName && selectedLabel) {
32529
+ return modelListViewRowLabel(listItem) === selectedLabel;
32379
32530
  }
32380
32531
  return false;
32381
32532
  });
@@ -32385,10 +32536,17 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32385
32536
  );
32386
32537
  }
32387
32538
  console.log("📊 Filtered value for", selectedLabel, ":", filteredValue);
32539
+ const failedModelRunsSum = metricType === "modelRuns" ? matchingItems.reduce(
32540
+ (sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
32541
+ 0
32542
+ ) : 0;
32388
32543
  const result = {
32389
32544
  ...item,
32390
32545
  [metricType]: filteredValue
32391
32546
  };
32547
+ if (metricType === "modelRuns") {
32548
+ result.failedModelRuns = failedModelRunsSum;
32549
+ }
32392
32550
  return result;
32393
32551
  });
32394
32552
  }
@@ -32400,8 +32558,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32400
32558
  const selectedLabels = selectedOptions.map((opt) => opt.label);
32401
32559
  return baseData.map((item) => {
32402
32560
  let aggregatedValue = 0;
32561
+ let matchingItems = [];
32403
32562
  if (item["listView"] && Array.isArray(item["listView"])) {
32404
- const matchingItems = item["listView"].filter((listItem) => {
32563
+ matchingItems = item["listView"].filter((listItem) => {
32405
32564
  if (metricType === "agentRuns" && listItem.agentName) {
32406
32565
  return selectedLabels.some(
32407
32566
  (label) => listItem.agentName === label || listItem.agentName.toLowerCase() === (label == null ? void 0 : label.toLowerCase())
@@ -32413,9 +32572,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32413
32572
  );
32414
32573
  }
32415
32574
  if (metricType === "modelRuns" && listItem.modelName) {
32416
- return selectedLabels.some(
32417
- (label) => listItem.modelName === label || listItem.modelName.toLowerCase() === (label == null ? void 0 : label.toLowerCase())
32418
- );
32575
+ const rowLabel = modelListViewRowLabel(listItem);
32576
+ return selectedLabels.some((label) => rowLabel === label);
32419
32577
  }
32420
32578
  return false;
32421
32579
  });
@@ -32424,10 +32582,18 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32424
32582
  0
32425
32583
  );
32426
32584
  }
32427
- return {
32585
+ const failedModelRunsMulti = metricType === "modelRuns" ? matchingItems.reduce(
32586
+ (sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
32587
+ 0
32588
+ ) : 0;
32589
+ const multiResult = {
32428
32590
  ...item,
32429
32591
  [metricType]: aggregatedValue
32430
32592
  };
32593
+ if (metricType === "modelRuns") {
32594
+ multiResult.failedModelRuns = failedModelRunsMulti;
32595
+ }
32596
+ return multiResult;
32431
32597
  });
32432
32598
  }
32433
32599
  return baseData;
@@ -32659,35 +32825,30 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32659
32825
  data: filteredData,
32660
32826
  yAxisLabel: "Number of Tool Runs",
32661
32827
  lines: [
32662
- {
32663
- dataKey: "toolRuns",
32664
- color: "#06b6d4",
32665
- // Blue for Tool Runs
32666
- label: "Tool Runs"
32667
- },
32668
32828
  {
32669
32829
  dataKey: "codeTools",
32670
32830
  color: "#f97316",
32671
- // Orange for Code Tools
32672
32831
  label: "Code Tools"
32673
32832
  },
32674
32833
  {
32675
32834
  dataKey: "workflowTools",
32676
32835
  color: "#10b981",
32677
- // Green for Workflow Tools
32678
32836
  label: "Workflow Tools"
32679
32837
  },
32680
32838
  {
32681
32839
  dataKey: "knowledgeTools",
32682
32840
  color: "#8b5cf6",
32683
- // Purple for Knowledge
32684
32841
  label: "Knowledge"
32685
32842
  },
32686
32843
  {
32687
32844
  dataKey: "mcpTools",
32688
32845
  color: "#ef4444",
32689
- // Red for MCP Tools
32690
32846
  label: "MCP Tools"
32847
+ },
32848
+ {
32849
+ dataKey: "processors",
32850
+ color: "#eab308",
32851
+ label: "Processors"
32691
32852
  }
32692
32853
  ],
32693
32854
  height: 300,
@@ -32707,12 +32868,20 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32707
32868
  type: "line",
32708
32869
  title: getChartTitle("Model Runs"),
32709
32870
  data: getFilteredData(baseData, "modelRuns"),
32710
- dataKey: "modelRuns",
32711
- color: "#10b981",
32712
- // Green as shown in Figma
32713
32871
  yAxisLabel: "Number of Model Runs",
32872
+ lines: [
32873
+ { dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
32874
+ {
32875
+ dataKey: "failedModelRuns",
32876
+ color: "#ef4444",
32877
+ label: "Failed",
32878
+ seriesType: "bar",
32879
+ hideInLegend: true
32880
+ }
32881
+ ],
32714
32882
  height: 300,
32715
32883
  showGrid: true,
32884
+ showLegend: true,
32716
32885
  curve: "monotone",
32717
32886
  tooltip: { show: true, style: "dark" },
32718
32887
  dateRange: {
@@ -32725,12 +32894,20 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
32725
32894
  type: "line",
32726
32895
  title: getChartTitle("Model Runs"),
32727
32896
  data: filteredData,
32728
- dataKey: "modelRuns",
32729
- color: "#10b981",
32730
- // Green as shown in Figma
32731
32897
  yAxisLabel: "Number of Model Runs",
32898
+ lines: [
32899
+ { dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
32900
+ {
32901
+ dataKey: "failedModelRuns",
32902
+ color: "#ef4444",
32903
+ label: "Failed",
32904
+ seriesType: "bar",
32905
+ hideInLegend: true
32906
+ }
32907
+ ],
32732
32908
  height: 300,
32733
32909
  showGrid: true,
32910
+ showLegend: true,
32734
32911
  curve: "monotone",
32735
32912
  tooltip: { show: true, style: "dark" },
32736
32913
  dateRange: {
@@ -34982,8 +35159,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
34982
35159
  if (appConfig) {
34983
35160
  try {
34984
35161
  apiServiceRef.current = new DashboardApiService(appConfig);
34985
- loadEnvironments();
34986
- loadInitialData();
35162
+ const initDashboard = async () => {
35163
+ await loadEnvironments();
35164
+ await loadInitialData();
35165
+ };
35166
+ initDashboard();
34987
35167
  } catch (err) {
34988
35168
  console.error("Failed to initialize API service:", err);
34989
35169
  }
@@ -106366,6 +106546,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106366
106546
  );
106367
106547
  traceDetails = traceResponses.map((trace) => this.transformToTraceDetailData(trace));
106368
106548
  }
106549
+ const resolvedSessionReference = typeof sessionResponse.sessionReference === "string" && sessionResponse.sessionReference.trim() !== "" ? sessionResponse.sessionReference.trim() : void 0;
106369
106550
  return {
106370
106551
  id: sessionResponse.id,
106371
106552
  projectId: sessionResponse.projectId,
@@ -106373,7 +106554,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106373
106554
  bookmarked: false,
106374
106555
  public: false,
106375
106556
  traces: traceDetails,
106376
- scores: []
106557
+ scores: [],
106558
+ sessionReference: resolvedSessionReference
106377
106559
  };
106378
106560
  }
106379
106561
  /**
@@ -106450,10 +106632,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106450
106632
  projectId: this.projectId
106451
106633
  });
106452
106634
  const traceIds = (sessionResponse.traces || []).map((t) => t.id);
106635
+ const resolvedSessionReference = typeof sessionResponse.sessionReference === "string" && sessionResponse.sessionReference.trim() !== "" ? sessionResponse.sessionReference.trim() : void 0;
106453
106636
  onSessionMeta({
106454
106637
  id: sessionResponse.id,
106455
106638
  traceCount: traceIds.length,
106456
- traceIds
106639
+ traceIds,
106640
+ sessionReference: resolvedSessionReference
106457
106641
  });
106458
106642
  if (traceIds.length === 0) {
106459
106643
  return {
@@ -106463,7 +106647,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106463
106647
  bookmarked: false,
106464
106648
  public: false,
106465
106649
  traces: [],
106466
- scores: []
106650
+ scores: [],
106651
+ sessionReference: resolvedSessionReference
106467
106652
  };
106468
106653
  }
106469
106654
  const firstTraceId = traceIds[0];
@@ -106510,7 +106695,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106510
106695
  bookmarked: false,
106511
106696
  public: false,
106512
106697
  traces: allTraces,
106513
- scores: []
106698
+ scores: [],
106699
+ sessionReference: resolvedSessionReference
106514
106700
  };
106515
106701
  }
106516
106702
  // ============================================================================
@@ -106604,6 +106790,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106604
106790
  totalCost: trace.totalCost || trace.calculatedTotalCost,
106605
106791
  totalTokens: trace.totalTokens,
106606
106792
  environment: trace.environment,
106793
+ source: typeof trace.source === "string" && trace.source.length > 0 ? trace.source : void 0,
106607
106794
  observations: (trace.observations || []).map(
106608
106795
  (obs) => this.transformObservation(obs)
106609
106796
  ),
@@ -109331,6 +109518,526 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109331
109518
  )
109332
109519
  ] });
109333
109520
  }
109521
+ const MicIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: [
109522
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109523
+ "path",
109524
+ {
109525
+ 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",
109526
+ fill: "#155EEF"
109527
+ }
109528
+ ),
109529
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109530
+ "path",
109531
+ {
109532
+ 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",
109533
+ stroke: "#155EEF",
109534
+ strokeWidth: "1.2",
109535
+ strokeLinecap: "round",
109536
+ strokeLinejoin: "round"
109537
+ }
109538
+ ),
109539
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109540
+ "path",
109541
+ {
109542
+ d: "M8 9V11",
109543
+ stroke: "#155EEF",
109544
+ strokeWidth: "1.2",
109545
+ strokeLinecap: "round",
109546
+ strokeLinejoin: "round"
109547
+ }
109548
+ ),
109549
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109550
+ "path",
109551
+ {
109552
+ d: "M6.5 11H9.5",
109553
+ stroke: "#155EEF",
109554
+ strokeWidth: "1.2",
109555
+ strokeLinecap: "round",
109556
+ strokeLinejoin: "round"
109557
+ }
109558
+ )
109559
+ ] });
109560
+ function VoiceEventLogsBanner({ onViewEventLogs }) {
109561
+ 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: [
109562
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109563
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MicIcon, {}),
109564
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.04em]", children: "Voice-to-Voice Event Logs" })
109565
+ ] }),
109566
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109567
+ "button",
109568
+ {
109569
+ onClick: onViewEventLogs,
109570
+ className: "text-[12px] font-medium text-[#155EEF] hover:text-[#344054] hover:underline transition-colors cursor-pointer bg-transparent border-none p-0",
109571
+ "data-test-id": "view-event-logs-btn",
109572
+ children: "View Event Logs"
109573
+ }
109574
+ )
109575
+ ] });
109576
+ }
109577
+ function AlignLeftIcon({ className }) {
109578
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109579
+ "svg",
109580
+ {
109581
+ width: "16",
109582
+ height: "16",
109583
+ viewBox: "0 0 16 16",
109584
+ fill: "none",
109585
+ className,
109586
+ "aria-hidden": "true",
109587
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109588
+ "path",
109589
+ {
109590
+ d: "M10.6667 6.66667H2M13.3333 4H2M13.3333 9.33333H2M10.6667 12H2",
109591
+ stroke: "currentColor",
109592
+ strokeWidth: "1.3",
109593
+ strokeLinecap: "round",
109594
+ strokeLinejoin: "round"
109595
+ }
109596
+ )
109597
+ }
109598
+ );
109599
+ }
109600
+ function JsonViewIcon({ className }) {
109601
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109602
+ "svg",
109603
+ {
109604
+ width: "16",
109605
+ height: "16",
109606
+ viewBox: "0 0 16 16",
109607
+ fill: "none",
109608
+ className,
109609
+ "aria-hidden": "true",
109610
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109611
+ "path",
109612
+ {
109613
+ 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",
109614
+ stroke: "currentColor",
109615
+ strokeWidth: "1.3",
109616
+ strokeLinecap: "round",
109617
+ strokeLinejoin: "round"
109618
+ }
109619
+ )
109620
+ }
109621
+ );
109622
+ }
109623
+ function pickString(obj, keys2) {
109624
+ for (const key of keys2) {
109625
+ const value = obj[key];
109626
+ if (typeof value === "string" && value.length > 0) return value;
109627
+ if (typeof value === "number") return String(value);
109628
+ }
109629
+ return void 0;
109630
+ }
109631
+ function coerceDirection(raw) {
109632
+ if (raw === "incoming" || raw === "server" || raw === "response") return "in";
109633
+ return "out";
109634
+ }
109635
+ function normalizeEvent(raw, fallbackId, docTimestamp) {
109636
+ if (!raw || typeof raw !== "object") {
109637
+ return {
109638
+ id: fallbackId,
109639
+ timestamp: docTimestamp,
109640
+ name: "event",
109641
+ direction: "out",
109642
+ payload: raw
109643
+ };
109644
+ }
109645
+ const obj = raw;
109646
+ const id = pickString(obj, ["event_id", "eventId", "_id", "id"]) ?? fallbackId;
109647
+ const name = pickString(obj, ["type", "eventType", "event", "name"]) ?? "event";
109648
+ const direction = coerceDirection(obj.direction);
109649
+ return {
109650
+ id,
109651
+ timestamp: docTimestamp,
109652
+ name,
109653
+ direction,
109654
+ payload: raw
109655
+ };
109656
+ }
109657
+ function flattenEvents(data) {
109658
+ if (data === null || data === void 0) return [];
109659
+ const out = [];
109660
+ const visitDoc = (doc2, docIdx) => {
109661
+ if (!doc2 || typeof doc2 !== "object") return;
109662
+ const docObj = doc2;
109663
+ const docTimestamp = pickString(docObj, ["createdOn", "sT", "createdAt"]);
109664
+ const events = docObj.events;
109665
+ if (Array.isArray(events)) {
109666
+ events.forEach((ev, evIdx) => {
109667
+ out.push(normalizeEvent(ev, `${docIdx}-${evIdx}`, docTimestamp));
109668
+ });
109669
+ } else {
109670
+ out.push(normalizeEvent(doc2, String(docIdx), docTimestamp));
109671
+ }
109672
+ };
109673
+ if (Array.isArray(data)) {
109674
+ data.forEach((doc2, docIdx) => visitDoc(doc2, docIdx));
109675
+ return out;
109676
+ }
109677
+ if (typeof data === "object") {
109678
+ const obj = data;
109679
+ if (Array.isArray(obj.events)) {
109680
+ visitDoc(obj, 0);
109681
+ return out;
109682
+ }
109683
+ if (Array.isArray(obj.data)) {
109684
+ return flattenEvents(obj.data);
109685
+ }
109686
+ }
109687
+ return [];
109688
+ }
109689
+ function formatEventTime(iso) {
109690
+ if (!iso) return "--:--:--:---";
109691
+ const d = new Date(iso);
109692
+ if (Number.isNaN(d.getTime())) return "--:--:--:---";
109693
+ const hh = String(d.getHours()).padStart(2, "0");
109694
+ const mm = String(d.getMinutes()).padStart(2, "0");
109695
+ const ss = String(d.getSeconds()).padStart(2, "0");
109696
+ const ms = String(d.getMilliseconds()).padStart(3, "0");
109697
+ return `${hh}:${mm}:${ss}:${ms}`;
109698
+ }
109699
+ function stringifyPayload(payload) {
109700
+ if (payload === null || payload === void 0) return "";
109701
+ if (typeof payload === "string") {
109702
+ try {
109703
+ return JSON.stringify(JSON.parse(payload), null, 2);
109704
+ } catch {
109705
+ return payload;
109706
+ }
109707
+ }
109708
+ try {
109709
+ return JSON.stringify(payload, null, 2);
109710
+ } catch {
109711
+ return String(payload);
109712
+ }
109713
+ }
109714
+ function compactPayload(payload) {
109715
+ if (payload === null || payload === void 0) return "";
109716
+ if (typeof payload === "string") {
109717
+ try {
109718
+ return JSON.stringify(JSON.parse(payload));
109719
+ } catch {
109720
+ return payload;
109721
+ }
109722
+ }
109723
+ try {
109724
+ return JSON.stringify(payload);
109725
+ } catch {
109726
+ return String(payload);
109727
+ }
109728
+ }
109729
+ function PayloadPanel({ payload, compactText }) {
109730
+ const [viewMode, setViewMode] = React.useState("json");
109731
+ const [fullscreen, setFullscreen] = React.useState(false);
109732
+ const [copied, setCopied] = React.useState(false);
109733
+ const displayText = viewMode === "json" ? payload : compactText;
109734
+ const handleCopy = React.useCallback(async () => {
109735
+ try {
109736
+ await navigator.clipboard.writeText(displayText);
109737
+ setCopied(true);
109738
+ await new Promise((resolve) => setTimeout(resolve, 1500));
109739
+ } catch {
109740
+ } finally {
109741
+ setCopied(false);
109742
+ }
109743
+ }, [displayText]);
109744
+ 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: [
109745
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109746
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109747
+ "button",
109748
+ {
109749
+ type: "button",
109750
+ onClick: () => setViewMode("json"),
109751
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109752
+ title: "Pretty JSON",
109753
+ "aria-label": "Pretty JSON view",
109754
+ "aria-pressed": viewMode === "json",
109755
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109756
+ }
109757
+ ),
109758
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109759
+ "button",
109760
+ {
109761
+ type: "button",
109762
+ onClick: () => setViewMode("text"),
109763
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109764
+ title: "Compact text",
109765
+ "aria-label": "Compact text view",
109766
+ "aria-pressed": viewMode === "text",
109767
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109768
+ }
109769
+ )
109770
+ ] }),
109771
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109772
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109773
+ "button",
109774
+ {
109775
+ type: "button",
109776
+ onClick: () => setFullscreen((v) => !v),
109777
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109778
+ title: fullscreen ? "Exit fullscreen" : "Fullscreen",
109779
+ "aria-label": fullscreen ? "Exit fullscreen" : "Fullscreen",
109780
+ children: fullscreen ? /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-[16px] h-[16px]" })
109781
+ }
109782
+ ),
109783
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109784
+ "button",
109785
+ {
109786
+ type: "button",
109787
+ onClick: () => void handleCopy(),
109788
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109789
+ title: "Copy to clipboard",
109790
+ "aria-label": "Copy payload",
109791
+ "data-test-id": "event-logs-row-copy",
109792
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109793
+ }
109794
+ )
109795
+ ] })
109796
+ ] });
109797
+ if (fullscreen) {
109798
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[20000] flex flex-col bg-[#F9FAFB]", children: [
109799
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[48px] px-[16px] border-b border-[#E4E7EC] flex items-center justify-between flex-shrink-0 bg-white", children: [
109800
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109801
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109802
+ "button",
109803
+ {
109804
+ type: "button",
109805
+ onClick: () => setViewMode("json"),
109806
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109807
+ title: "Pretty JSON",
109808
+ "aria-label": "Pretty JSON view",
109809
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109810
+ }
109811
+ ),
109812
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109813
+ "button",
109814
+ {
109815
+ type: "button",
109816
+ onClick: () => setViewMode("text"),
109817
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109818
+ title: "Compact text",
109819
+ "aria-label": "Compact text view",
109820
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109821
+ }
109822
+ )
109823
+ ] }),
109824
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109825
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109826
+ "button",
109827
+ {
109828
+ type: "button",
109829
+ onClick: () => void handleCopy(),
109830
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109831
+ title: "Copy to clipboard",
109832
+ "aria-label": "Copy payload",
109833
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109834
+ }
109835
+ ),
109836
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109837
+ "button",
109838
+ {
109839
+ type: "button",
109840
+ onClick: () => setFullscreen(false),
109841
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109842
+ title: "Exit fullscreen",
109843
+ "aria-label": "Exit fullscreen",
109844
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" })
109845
+ }
109846
+ )
109847
+ ] })
109848
+ ] }),
109849
+ /* @__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 })
109850
+ ] }) });
109851
+ }
109852
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[10px] border border-[#D0D5DD] overflow-hidden mt-[12px]", children: [
109853
+ toolbar,
109854
+ /* @__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 })
109855
+ ] });
109856
+ }
109857
+ function EventRow({ event, isExpanded, onToggle }) {
109858
+ const jsonText = React.useMemo(() => stringifyPayload(event.payload), [event.payload]);
109859
+ const compactText = React.useMemo(() => compactPayload(event.payload), [event.payload]);
109860
+ const hasPayload = jsonText.length > 0;
109861
+ const isInput = event.direction === "in";
109862
+ const DirectionIcon = isInput ? ArrowUp : ArrowDown;
109863
+ const directionLabel = isInput ? "Input" : "Output";
109864
+ const circleClasses = isInput ? "border-[#079455] text-[#079455]" : "border-[#D92D20] text-[#D92D20]";
109865
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex items-start gap-[12px]", "data-test-id": "event-logs-row", children: [
109866
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative flex-shrink-0 flex flex-col items-center w-[16px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109867
+ "div",
109868
+ {
109869
+ className: `relative z-10 w-[16px] h-[16px] rounded-full bg-white border flex items-center justify-center ${circleClasses}`,
109870
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(DirectionIcon, { className: "w-[8px] h-[8px]", strokeWidth: 2.5 })
109871
+ }
109872
+ ) }),
109873
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 pb-[24px]", children: [
109874
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-[16px]", children: [
109875
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
109876
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[12px] leading-[16px] text-[#667085]", children: directionLabel }),
109877
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] font-medium text-[#344054] mt-[2px] break-all", children: event.name }),
109878
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109879
+ "button",
109880
+ {
109881
+ type: "button",
109882
+ onClick: onToggle,
109883
+ className: "text-[13px] leading-[18px] text-[#155EEF] hover:underline mt-[4px] font-medium",
109884
+ "data-test-id": "event-logs-view-details",
109885
+ children: isExpanded ? "Hide details" : "View details"
109886
+ }
109887
+ )
109888
+ ] }),
109889
+ /* @__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) })
109890
+ ] }),
109891
+ 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." }))
109892
+ ] })
109893
+ ] });
109894
+ }
109895
+ function EventLogsSlideout({
109896
+ isOpen,
109897
+ onClose,
109898
+ sessionId,
109899
+ fetchEventLogs
109900
+ }) {
109901
+ const [rawData, setRawData] = React.useState(null);
109902
+ const [loading, setLoading] = React.useState(false);
109903
+ const [error, setError] = React.useState(null);
109904
+ const [expandedIds, setExpandedIds] = React.useState(() => /* @__PURE__ */ new Set());
109905
+ React.useEffect(() => {
109906
+ if (!isOpen || !sessionId || !fetchEventLogs) return;
109907
+ let cancelled = false;
109908
+ setLoading(true);
109909
+ setError(null);
109910
+ setRawData(null);
109911
+ (async () => {
109912
+ try {
109913
+ const data = await fetchEventLogs(sessionId);
109914
+ if (cancelled) return;
109915
+ setRawData(data);
109916
+ } catch (err) {
109917
+ if (cancelled) return;
109918
+ setError(err instanceof Error ? err.message : "Failed to fetch event logs");
109919
+ } finally {
109920
+ if (!cancelled) setLoading(false);
109921
+ }
109922
+ })();
109923
+ return () => {
109924
+ cancelled = true;
109925
+ };
109926
+ }, [isOpen, sessionId, fetchEventLogs]);
109927
+ const events = React.useMemo(() => flattenEvents(rawData), [rawData]);
109928
+ React.useEffect(() => {
109929
+ if (!isOpen) return;
109930
+ const handleKey = (e) => {
109931
+ if (e.key === "Escape") onClose();
109932
+ };
109933
+ document.addEventListener("keydown", handleKey);
109934
+ return () => document.removeEventListener("keydown", handleKey);
109935
+ }, [isOpen, onClose]);
109936
+ React.useEffect(() => {
109937
+ if (!isOpen) {
109938
+ setExpandedIds(/* @__PURE__ */ new Set());
109939
+ setRawData(null);
109940
+ setError(null);
109941
+ }
109942
+ }, [isOpen]);
109943
+ const toggleRow = React.useCallback((id) => {
109944
+ setExpandedIds((prev) => {
109945
+ const next = new Set(prev);
109946
+ if (next.has(id)) next.delete(id);
109947
+ else next.add(id);
109948
+ return next;
109949
+ });
109950
+ }, []);
109951
+ const expandAll = React.useCallback(() => {
109952
+ setExpandedIds(new Set(events.map((e) => e.id)));
109953
+ }, [events]);
109954
+ const collapseAll = React.useCallback(() => {
109955
+ setExpandedIds(/* @__PURE__ */ new Set());
109956
+ }, []);
109957
+ if (!isOpen) return null;
109958
+ const showToolbar = !loading && !error && events.length > 0;
109959
+ const allExpanded = showToolbar && expandedIds.size === events.length;
109960
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[10000]", children: [
109961
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109962
+ "div",
109963
+ {
109964
+ className: "absolute inset-0 bg-black/40",
109965
+ onClick: onClose,
109966
+ "aria-hidden": "true"
109967
+ }
109968
+ ),
109969
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
109970
+ "div",
109971
+ {
109972
+ className: "absolute top-0 right-0 bottom-0 bg-white shadow-2xl flex flex-col",
109973
+ style: { width: "720px", maxWidth: "100vw" },
109974
+ role: "dialog",
109975
+ "aria-label": "Event Logs",
109976
+ onClick: (e) => e.stopPropagation(),
109977
+ children: [
109978
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between h-[56px] px-[20px] border-b border-[#E4E7EC] flex-shrink-0", children: [
109979
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109980
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[16px] font-semibold text-[#101828]", children: "Event Logs" }),
109981
+ !loading && !error && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium text-[#667085] bg-[#F2F4F7] rounded-[10px] px-[8px] py-[2px]", children: events.length })
109982
+ ] }),
109983
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109984
+ showToolbar && /* @__PURE__ */ jsxRuntimeExports.jsx(
109985
+ "button",
109986
+ {
109987
+ type: "button",
109988
+ onClick: allExpanded ? collapseAll : expandAll,
109989
+ className: "text-[13px] font-medium text-[#155EEF] hover:underline px-[8px] py-[6px] rounded-[6px] transition-colors",
109990
+ "data-test-id": "event-logs-toggle-all",
109991
+ children: allExpanded ? "Collapse all" : "Expand all"
109992
+ }
109993
+ ),
109994
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109995
+ "button",
109996
+ {
109997
+ type: "button",
109998
+ onClick: onClose,
109999
+ className: "p-[8px] rounded-[6px] hover:bg-[#F2F4F7] transition-colors",
110000
+ title: "Close Event Logs",
110001
+ "aria-label": "Close Event Logs",
110002
+ "data-test-id": "event-logs-close-btn",
110003
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[16px] h-[16px] text-[#344054]" })
110004
+ }
110005
+ )
110006
+ ] })
110007
+ ] }),
110008
+ /* @__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: [
110009
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-[20px] h-[20px] animate-spin text-[#155EEF]" }),
110010
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Loading event logs…" })
110011
+ ] }) : 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: [
110012
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Couldn't load event logs" }),
110013
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] text-[#667085]", children: error })
110014
+ ] }) : 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: [
110015
+ events.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
110016
+ "div",
110017
+ {
110018
+ className: "absolute w-px bg-[#D0D5DD]",
110019
+ style: { left: "32px", top: "36px", bottom: "28px" },
110020
+ "aria-hidden": "true"
110021
+ }
110022
+ ),
110023
+ events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(
110024
+ EventRow,
110025
+ {
110026
+ event,
110027
+ isExpanded: expandedIds.has(event.id),
110028
+ onToggle: () => toggleRow(event.id)
110029
+ },
110030
+ event.id
110031
+ ))
110032
+ ] }) })
110033
+ ]
110034
+ }
110035
+ )
110036
+ ] }) });
110037
+ }
110038
+ function hasNonEmptySessionReference(ref) {
110039
+ return typeof ref === "string" && ref.trim().length > 0;
110040
+ }
109334
110041
  function DetailPage({
109335
110042
  mode: initialMode,
109336
110043
  sessionId: initialSessionId,
@@ -109343,7 +110050,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109343
110050
  batchSize = DEFAULT_BATCH_SIZE,
109344
110051
  initialTraceCount,
109345
110052
  initialSessionData,
109346
- runHeaderInputMode = "display"
110053
+ runHeaderInputMode = "display",
110054
+ onViewEventLogs,
110055
+ fetchEventLogs
109347
110056
  }) {
109348
110057
  const [currentMode, setCurrentMode] = React.useState(initialMode);
109349
110058
  const [currentSessionId, setCurrentSessionId] = React.useState(initialSessionId);
@@ -109353,6 +110062,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109353
110062
  const traceId = currentTraceId;
109354
110063
  const [selectedNode, setSelectedNode] = React.useState(null);
109355
110064
  const [copiedId, setCopiedId] = React.useState(false);
110065
+ const [isEventLogsOpen, setIsEventLogsOpen] = React.useState(false);
109356
110066
  const minObservationLevel = "DEFAULT";
109357
110067
  const [hasAutoSelected, setHasAutoSelected] = React.useState(false);
109358
110068
  const hasInitialData = mode === "session" && initialSessionData;
@@ -109398,7 +110108,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109398
110108
  bookmarked: false,
109399
110109
  public: false,
109400
110110
  traces: [],
109401
- scores: []
110111
+ scores: [],
110112
+ sessionReference: meta.sessionReference
109402
110113
  });
109403
110114
  setLoadingState("success");
109404
110115
  },
@@ -109582,6 +110293,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109582
110293
  } : null
109583
110294
  };
109584
110295
  }, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
110296
+ const sessionReferenceForEventLogs = React.useMemo(() => {
110297
+ return (initialSessionData == null ? void 0 : initialSessionData.sessionReference) ?? (sessionData == null ? void 0 : sessionData.sessionReference);
110298
+ }, [initialSessionData == null ? void 0 : initialSessionData.sessionReference, sessionData == null ? void 0 : sessionData.sessionReference]);
110299
+ const showEventLogsBanner = mode === "session" && hasNonEmptySessionReference(sessionReferenceForEventLogs);
109585
110300
  const traces = React.useMemo(() => {
109586
110301
  if (mode === "session" && sessionData) {
109587
110302
  const sorted = [...sessionData.traces].sort((a2, b) => {
@@ -109630,6 +110345,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109630
110345
  mode,
109631
110346
  traceData
109632
110347
  ]);
110348
+ const handleViewEventLogs = React.useCallback(() => {
110349
+ setIsEventLogsOpen(true);
110350
+ if (onViewEventLogs && sessionId) {
110351
+ const firstTraceId = traces.length > 0 ? traces[0].id : void 0;
110352
+ onViewEventLogs(sessionId, firstTraceId);
110353
+ }
110354
+ }, [onViewEventLogs, sessionId, traces]);
110355
+ const handleCloseEventLogs = React.useCallback(() => {
110356
+ setIsEventLogsOpen(false);
110357
+ }, []);
109633
110358
  const handleNodeSelect = React.useCallback((node) => {
109634
110359
  setSelectedNode(node);
109635
110360
  }, []);
@@ -109846,6 +110571,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109846
110571
  ] }),
109847
110572
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
109848
110573
  /* @__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: [
110574
+ showEventLogsBanner && /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceEventLogsBanner, { onViewEventLogs: handleViewEventLogs }),
109849
110575
  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" }),
109850
110576
  traces.map((trace, index) => {
109851
110577
  var _a, _b, _c, _d;
@@ -109895,7 +110621,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109895
110621
  generationSummaryInputOverride
109896
110622
  }
109897
110623
  )
109898
- ] })
110624
+ ] }),
110625
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
110626
+ EventLogsSlideout,
110627
+ {
110628
+ isOpen: isEventLogsOpen,
110629
+ onClose: handleCloseEventLogs,
110630
+ sessionId: sessionId ?? null,
110631
+ fetchEventLogs
110632
+ }
110633
+ )
109899
110634
  ] });
109900
110635
  }
109901
110636
  const trace1Observations = [
@@ -110309,7 +111044,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110309
111044
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
110310
111045
  }
110311
111046
  function SessionsListContent(props) {
110312
- const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
111047
+ const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId, onViewEventLogs, fetchEventLogs } = props;
110313
111048
  const { environments, resolveEnvironmentName } = useEnvironment();
110314
111049
  const [selectedSessionId, setSelectedSessionId] = React.useState(() => initialSessionId ?? null);
110315
111050
  const [selectedSessionData, setSelectedSessionData] = React.useState(null);
@@ -110870,7 +111605,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110870
111605
  totalCost: session.totalCost,
110871
111606
  totalTokens: session.totalTokens,
110872
111607
  sessionDuration: session.sessionDuration,
110873
- createdAt: session.createdAt
111608
+ createdAt: session.createdAt,
111609
+ sessionReference: session.sessionReference
110874
111610
  });
110875
111611
  setIsModalOpen(true);
110876
111612
  if (onSessionClick) {
@@ -110980,7 +111716,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110980
111716
  sessionId: selectedSessionId,
110981
111717
  apiConfig,
110982
111718
  onClose: handleModalClose,
110983
- initialSessionData: selectedSessionData || void 0
111719
+ initialSessionData: selectedSessionData || void 0,
111720
+ onViewEventLogs,
111721
+ fetchEventLogs
110984
111722
  }
110985
111723
  ) })
110986
111724
  ] });
@@ -112856,6 +113594,57 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112856
113594
  return { totalTokens, totalCost, totalDuration };
112857
113595
  }
112858
113596
  class TreeBuilder {
113597
+ static isPreProcessorNode(node) {
113598
+ const normalizedName = (node.name || "").replace(/[^a-z0-9]/gi, "").toLowerCase();
113599
+ return node.type === "tool" && normalizedName === "preprocessor";
113600
+ }
113601
+ static normalizeNodeName(name) {
113602
+ return (name || "").replace(/[^a-z0-9]/gi, "").toLowerCase();
113603
+ }
113604
+ static normalizeLinkedEventType(node) {
113605
+ var _a;
113606
+ const linkedEventType = (_a = node.metadata) == null ? void 0 : _a.linkedEventType;
113607
+ if (typeof linkedEventType !== "string" || linkedEventType.trim().length === 0) {
113608
+ return null;
113609
+ }
113610
+ return linkedEventType.replace(/[^a-z0-9]/gi, "").toLowerCase();
113611
+ }
113612
+ static normalizeParentId(parentId) {
113613
+ if (typeof parentId !== "string") {
113614
+ return parentId ?? null;
113615
+ }
113616
+ const trimmedParentId = parentId.trim();
113617
+ if (trimmedParentId.length === 0 || trimmedParentId.toLowerCase() === "null" || trimmedParentId.toLowerCase() === "undefined") {
113618
+ return null;
113619
+ }
113620
+ return trimmedParentId;
113621
+ }
113622
+ static isTargetSystemEventNode(node) {
113623
+ const normalizedName = this.normalizeNodeName(node.name || "");
113624
+ if (this.TARGET_EVENT_NAMES.has(normalizedName)) return true;
113625
+ return typeof node.type === "string" && node.type.toLowerCase() === "event";
113626
+ }
113627
+ static compareNodesForDisplay(a2, b) {
113628
+ const aIsPreProcessor = this.isPreProcessorNode(a2);
113629
+ const bIsPreProcessor = this.isPreProcessorNode(b);
113630
+ const aIsTargetEvent = this.isTargetSystemEventNode(a2);
113631
+ const bIsTargetEvent = this.isTargetSystemEventNode(b);
113632
+ const aLinkedEventType = this.normalizeLinkedEventType(a2);
113633
+ const bLinkedEventType = this.normalizeLinkedEventType(b);
113634
+ const aTargetName = this.normalizeNodeName(a2.name || "");
113635
+ const bTargetName = this.normalizeNodeName(b.name || "");
113636
+ if (aIsPreProcessor && bIsTargetEvent && aLinkedEventType !== null && aLinkedEventType === bTargetName) {
113637
+ return -1;
113638
+ }
113639
+ if (aIsTargetEvent && bIsPreProcessor && bLinkedEventType !== null && bLinkedEventType === aTargetName) {
113640
+ return 1;
113641
+ }
113642
+ const timestampDiff = new Date(a2.startTime).getTime() - new Date(b.startTime).getTime();
113643
+ if (timestampDiff !== 0) {
113644
+ return timestampDiff;
113645
+ }
113646
+ return (a2.name || "").localeCompare(b.name || "");
113647
+ }
112859
113648
  /**
112860
113649
  * Process execution events and build a hierarchical tree structure
112861
113650
  * Session > Run > Node Tree
@@ -112914,6 +113703,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112914
113703
  const node = this.createTreeNodeFromEvents(startedEvent, completedEvent, runId);
112915
113704
  nodes.push(node);
112916
113705
  }
113706
+ this.alignEventPreProcessorNodes(nodes);
112917
113707
  const rootNodes = this.buildNodeHierarchy(nodes);
112918
113708
  const runEvents = events.filter((e) => e.runId === runId);
112919
113709
  const startTime = Math.min(...runEvents.map((e) => new Date(e.data.timestamp).getTime()));
@@ -112996,8 +113786,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112996
113786
  nodes.forEach((node) => nodeMap.set(node.id, node));
112997
113787
  const rootNodes = [];
112998
113788
  nodes.forEach((node) => {
112999
- if (node.parentId && nodeMap.has(node.parentId)) {
113000
- const parent = nodeMap.get(node.parentId);
113789
+ const normalizedParentId = this.normalizeParentId(node.parentId);
113790
+ node.parentId = normalizedParentId;
113791
+ if (normalizedParentId && nodeMap.has(normalizedParentId)) {
113792
+ const parent = nodeMap.get(normalizedParentId);
113001
113793
  parent.children.push(node);
113002
113794
  node.level = parent.level + 1;
113003
113795
  } else {
@@ -113005,12 +113797,98 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113005
113797
  node.level = 0;
113006
113798
  }
113007
113799
  });
113008
- rootNodes.sort(
113009
- (a2, b) => new Date(a2.startTime).getTime() - new Date(b.startTime).getTime()
113010
- );
113800
+ rootNodes.sort((a2, b) => this.compareNodesForDisplay(a2, b));
113011
113801
  rootNodes.forEach((root2) => this.sortChildren(root2));
113802
+ this.relocateRootEventPreProcessors(rootNodes);
113012
113803
  return rootNodes;
113013
113804
  }
113805
+ static alignEventPreProcessorNodes(nodes) {
113806
+ const targetEvents = nodes.filter((node) => this.isTargetSystemEventNode(node)).sort((a2, b) => new Date(a2.startTime).getTime() - new Date(b.startTime).getTime());
113807
+ if (targetEvents.length === 0) {
113808
+ return;
113809
+ }
113810
+ const orphanPreProcessors = nodes.filter((node) => this.isPreProcessorNode(node) && this.normalizeParentId(node.parentId) === null).sort((a2, b) => new Date(a2.startTime).getTime() - new Date(b.startTime).getTime());
113811
+ for (const preProcessorNode of orphanPreProcessors) {
113812
+ const linkedEventType = this.normalizeLinkedEventType(preProcessorNode);
113813
+ if (linkedEventType === null) {
113814
+ continue;
113815
+ }
113816
+ const candidateEvents = targetEvents.filter(
113817
+ (eventNode) => this.normalizeNodeName(eventNode.name || "") === linkedEventType
113818
+ );
113819
+ if (candidateEvents.length === 0) {
113820
+ continue;
113821
+ }
113822
+ const preProcessorTime = new Date(preProcessorNode.startTime).getTime();
113823
+ let selectedTargetEvent = candidateEvents[0];
113824
+ let minDistance = Number.POSITIVE_INFINITY;
113825
+ for (const targetEvent of candidateEvents) {
113826
+ const distance = Math.abs(new Date(targetEvent.startTime).getTime() - preProcessorTime);
113827
+ if (distance < minDistance) {
113828
+ selectedTargetEvent = targetEvent;
113829
+ minDistance = distance;
113830
+ }
113831
+ }
113832
+ preProcessorNode.parentId = this.normalizeParentId(selectedTargetEvent.parentId);
113833
+ }
113834
+ }
113835
+ static relocateRootEventPreProcessors(rootNodes) {
113836
+ var _a;
113837
+ const preprocessorsAtRoot = rootNodes.filter((node) => this.isPreProcessorNode(node));
113838
+ if (preprocessorsAtRoot.length === 0) {
113839
+ return;
113840
+ }
113841
+ const collectTargetNodes = (nodesToSearch, parentNode2, collector) => {
113842
+ nodesToSearch.forEach((node, index) => {
113843
+ if (this.isTargetSystemEventNode(node)) {
113844
+ collector.push({ node, siblings: nodesToSearch, index, parentNode: parentNode2 });
113845
+ }
113846
+ if (node.children.length > 0) {
113847
+ collectTargetNodes(node.children, node, collector);
113848
+ }
113849
+ });
113850
+ };
113851
+ const targetNodes = [];
113852
+ collectTargetNodes(rootNodes, null, targetNodes);
113853
+ if (targetNodes.length === 0) {
113854
+ return;
113855
+ }
113856
+ const rootSet = new Set(rootNodes);
113857
+ for (const preProcessorNode of preprocessorsAtRoot) {
113858
+ if (!rootSet.has(preProcessorNode)) {
113859
+ continue;
113860
+ }
113861
+ const linkedEventType = this.normalizeLinkedEventType(preProcessorNode);
113862
+ if (linkedEventType === null) {
113863
+ continue;
113864
+ }
113865
+ const candidateTargets = targetNodes.filter(
113866
+ (target) => this.normalizeNodeName(target.node.name || "") === linkedEventType
113867
+ );
113868
+ if (candidateTargets.length === 0) {
113869
+ continue;
113870
+ }
113871
+ const preProcessorTime = new Date(preProcessorNode.startTime).getTime();
113872
+ let selectedTarget = candidateTargets[0];
113873
+ let selectedDistance = Number.POSITIVE_INFINITY;
113874
+ for (const candidate of candidateTargets) {
113875
+ const candidateTime = new Date(candidate.node.startTime).getTime();
113876
+ const distance = Math.abs(candidateTime - preProcessorTime);
113877
+ if (distance < selectedDistance) {
113878
+ selectedTarget = candidate;
113879
+ selectedDistance = distance;
113880
+ }
113881
+ }
113882
+ const rootIndex = rootNodes.indexOf(preProcessorNode);
113883
+ if (rootIndex >= 0) {
113884
+ rootNodes.splice(rootIndex, 1);
113885
+ rootSet.delete(preProcessorNode);
113886
+ }
113887
+ preProcessorNode.parentId = ((_a = selectedTarget.parentNode) == null ? void 0 : _a.id) ?? null;
113888
+ selectedTarget.siblings.splice(selectedTarget.index, 0, preProcessorNode);
113889
+ selectedTarget.siblings.sort((a2, b) => this.compareNodesForDisplay(a2, b));
113890
+ }
113891
+ }
113014
113892
  /**
113015
113893
  * Extract LLM usage metadata from output and event metadata (configurable path)
113016
113894
  */
@@ -113102,9 +113980,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113102
113980
  */
113103
113981
  static sortChildren(node) {
113104
113982
  if (!node) return;
113105
- node.children.sort(
113106
- (a2, b) => new Date(a2.startTime).getTime() - new Date(b.startTime).getTime()
113107
- );
113983
+ node.children.sort((a2, b) => this.compareNodesForDisplay(a2, b));
113108
113984
  node.children.forEach((child) => this.sortChildren(child));
113109
113985
  }
113110
113986
  /**
@@ -113358,6 +114234,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113358
114234
  );
113359
114235
  }
113360
114236
  }
114237
+ __publicField(TreeBuilder, "TARGET_EVENT_NAMES", /* @__PURE__ */ new Set([
114238
+ "endofconversation",
114239
+ "agenthandoff"
114240
+ ]));
113361
114241
  const CodeEditor = ({
113362
114242
  value,
113363
114243
  onChange,