agentic-ui-libs 1.2.0-beta.2 → 1.2.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/agentic-ui-libs.css +78 -4
- package/dist/features/dashboard/AnalyticsChart.d.ts.map +1 -1
- package/dist/features/dashboard/Dashboard.d.ts.map +1 -1
- package/dist/features/dashboard/DashboardSection.d.ts.map +1 -1
- package/dist/features/dashboard/MetricCard.d.ts.map +1 -1
- package/dist/features/dashboard/ModelListView.d.ts +1 -0
- package/dist/features/dashboard/ModelListView.d.ts.map +1 -1
- package/dist/features/dashboard/ToolListView.d.ts.map +1 -1
- package/dist/features/debug-logs/DebugPanel.d.ts.map +1 -1
- package/dist/features/debug-logs/components/DebugCard.d.ts.map +1 -1
- package/dist/features/debug-logs/index.d.ts +1 -1
- package/dist/features/debug-logs/index.d.ts.map +1 -1
- package/dist/features/debug-logs/services/ApiService.d.ts.map +1 -1
- package/dist/features/debug-logs/services/TreeBuilder.d.ts +3 -3
- package/dist/features/debug-logs/services/TreeBuilder.d.ts.map +1 -1
- package/dist/features/debug-logs/types.d.ts +13 -2
- package/dist/features/debug-logs/types.d.ts.map +1 -1
- package/dist/features/md-editor/MDEditor.d.ts.map +1 -1
- package/dist/features/md-editor/components/AIDesignPanel.d.ts.map +1 -1
- package/dist/features/md-editor/components/EmptyStatePlaceholder.d.ts +21 -0
- package/dist/features/md-editor/components/EmptyStatePlaceholder.d.ts.map +1 -0
- package/dist/features/md-editor/components/UnifiedToolbar.d.ts +4 -0
- package/dist/features/md-editor/components/UnifiedToolbar.d.ts.map +1 -1
- package/dist/features/md-editor/components/VariableMenu.d.ts.map +1 -1
- package/dist/features/md-editor/components/icons/CategoryIcons.d.ts +1 -0
- package/dist/features/md-editor/components/icons/CategoryIcons.d.ts.map +1 -1
- package/dist/features/md-editor/components/index.d.ts +2 -0
- package/dist/features/md-editor/components/index.d.ts.map +1 -1
- package/dist/features/md-editor/hooks/useAIRefinementSession.d.ts +3 -1
- package/dist/features/md-editor/hooks/useAIRefinementSession.d.ts.map +1 -1
- package/dist/features/md-editor/index.d.ts +1 -1
- package/dist/features/md-editor/index.d.ts.map +1 -1
- package/dist/features/md-editor/types.d.ts +58 -2
- package/dist/features/md-editor/types.d.ts.map +1 -1
- package/dist/features/md-editor/utils/index.d.ts +1 -0
- package/dist/features/md-editor/utils/index.d.ts.map +1 -1
- package/dist/features/md-editor/utils/variableContext.d.ts +38 -0
- package/dist/features/md-editor/utils/variableContext.d.ts.map +1 -0
- package/dist/features/tracing/components/SessionsList.d.ts.map +1 -1
- package/dist/features/tracing/components/TracesList.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/DetailPage.d.ts +1 -1
- package/dist/features/tracing/components/detail/DetailPage.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/NodeDetailPanel.d.ts +1 -1
- package/dist/features/tracing/components/detail/NodeDetailPanel.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/ObservationNode.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/TraceTree.d.ts +1 -1
- package/dist/features/tracing/components/detail/TraceTree.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/config/observationFilterConfig.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/services/DetailPageService.d.ts.map +1 -1
- package/dist/features/tracing/components/detail/types.d.ts +22 -0
- package/dist/features/tracing/components/detail/types.d.ts.map +1 -1
- package/dist/features/tracing/components/shared/CopyableId.d.ts +11 -0
- package/dist/features/tracing/components/shared/CopyableId.d.ts.map +1 -0
- package/dist/features/tracing/components/shared/TracingListHeader.d.ts +2 -1
- package/dist/features/tracing/components/shared/TracingListHeader.d.ts.map +1 -1
- package/dist/features/tracing/components/shared/TracingTable.d.ts.map +1 -1
- package/dist/features/tracing/components/shared/index.d.ts +1 -0
- package/dist/features/tracing/components/shared/index.d.ts.map +1 -1
- package/dist/features/tracing/services/TraceTreeService.d.ts +39 -2
- package/dist/features/tracing/services/TraceTreeService.d.ts.map +1 -1
- package/dist/features/tracing/services/TracingApiService.d.ts +13 -1
- package/dist/features/tracing/services/TracingApiService.d.ts.map +1 -1
- package/dist/features/tracing/types.d.ts +10 -0
- package/dist/features/tracing/types.d.ts.map +1 -1
- package/dist/index.angular.d.ts +1 -1
- package/dist/index.angular.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2089 -788
- package/dist/lib/dashboard-api.service.d.ts +1 -0
- package/dist/lib/dashboard-api.service.d.ts.map +1 -1
- package/dist/shared/types/index.d.ts +7 -0
- package/dist/shared/types/index.d.ts.map +1 -1
- package/dist/shared/ui/DataViewer.d.ts.map +1 -1
- package/dist/ui-libs.umd.js +2089 -788
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -4291,7 +4291,7 @@ const MetricCard = ({
|
|
|
4291
4291
|
onClick,
|
|
4292
4292
|
isFirst = false
|
|
4293
4293
|
}) => {
|
|
4294
|
-
const { title, value, change, info, highlighted } = data;
|
|
4294
|
+
const { title, value, change, info, highlighted, failedCount } = data;
|
|
4295
4295
|
const formatValue2 = (val) => {
|
|
4296
4296
|
if (typeof val === "number") {
|
|
4297
4297
|
return val.toLocaleString();
|
|
@@ -4345,6 +4345,11 @@ const MetricCard = ({
|
|
|
4345
4345
|
] }),
|
|
4346
4346
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline gap-3", "data-test-id": `dashboard_metric_card_value_container_${data.metricType || data.title.toLowerCase().replace(/\s+/g, "_")}`, children: [
|
|
4347
4347
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl font-semibold text-gray-900", "data-test-id": `dashboard_metric_card_value_${data.metricType || data.title.toLowerCase().replace(/\s+/g, "_")}`, children: formatValue2(value) }),
|
|
4348
|
+
(failedCount ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs font-medium text-red-500", "data-test-id": `dashboard_metric_card_failed_${data.metricType}`, children: [
|
|
4349
|
+
"(",
|
|
4350
|
+
failedCount,
|
|
4351
|
+
" failed)"
|
|
4352
|
+
] }),
|
|
4348
4353
|
change && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4349
4354
|
"div",
|
|
4350
4355
|
{
|
|
@@ -21355,7 +21360,7 @@ function _toPrimitive$g(t2, r2) {
|
|
|
21355
21360
|
if ("object" != _typeof$i(i2)) return i2;
|
|
21356
21361
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
21357
21362
|
}
|
|
21358
|
-
return
|
|
21363
|
+
return String(t2);
|
|
21359
21364
|
}
|
|
21360
21365
|
var Bar = /* @__PURE__ */ function(_PureComponent) {
|
|
21361
21366
|
function Bar2() {
|
|
@@ -28662,7 +28667,7 @@ const CustomTooltip = ({
|
|
|
28662
28667
|
return null;
|
|
28663
28668
|
}
|
|
28664
28669
|
const filteredPayload = payload.filter(
|
|
28665
|
-
(entry) => entry.name && entry.name !== "" && entry.name !== entry.dataKey
|
|
28670
|
+
(entry) => entry.name && entry.name !== "" && entry.name !== entry.dataKey && entry.value != null && !(typeof entry.value === "number" && Number.isNaN(entry.value)) && !(entry.dataKey === "failedModelRuns" && Number(entry.value) === 0)
|
|
28666
28671
|
);
|
|
28667
28672
|
if (filteredPayload.length === 0) {
|
|
28668
28673
|
return null;
|
|
@@ -28762,6 +28767,7 @@ const AnalyticsChart = ({
|
|
|
28762
28767
|
agentRuns: 0,
|
|
28763
28768
|
toolRuns: 0,
|
|
28764
28769
|
modelRuns: 0,
|
|
28770
|
+
failedModelRuns: null,
|
|
28765
28771
|
codeTools: 0,
|
|
28766
28772
|
workflowTools: 0,
|
|
28767
28773
|
knowledgeTools: 0,
|
|
@@ -28864,6 +28870,8 @@ const AnalyticsChart = ({
|
|
|
28864
28870
|
label: config2.title,
|
|
28865
28871
|
strokeWidth: 2
|
|
28866
28872
|
}];
|
|
28873
|
+
const lineSeries = chartLines.filter((c3) => (c3.seriesType ?? "line") === "line");
|
|
28874
|
+
const barSeries = chartLines.filter((c3) => c3.seriesType === "bar");
|
|
28867
28875
|
if (isLoading) {
|
|
28868
28876
|
console.log("AnalyticsChart: Loading state active");
|
|
28869
28877
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ChartSkeleton, { className, chartType: config2.type, height });
|
|
@@ -28970,7 +28978,7 @@ const AnalyticsChart = ({
|
|
|
28970
28978
|
bottom: 20
|
|
28971
28979
|
},
|
|
28972
28980
|
children: [
|
|
28973
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children:
|
|
28981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: lineSeries.map((lineConfig, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("linearGradient", { id: `gradient-${lineConfig.dataKey}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
28974
28982
|
/* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "5%", stopColor: lineConfig.color, stopOpacity: 0.08 }),
|
|
28975
28983
|
/* @__PURE__ */ jsxRuntimeExports.jsx("stop", { offset: "95%", stopColor: lineConfig.color, stopOpacity: 0.01 })
|
|
28976
28984
|
] }, `gradient-${index}`)) }),
|
|
@@ -29022,7 +29030,7 @@ const AnalyticsChart = ({
|
|
|
29022
29030
|
allowEscapeViewBox: { x: false, y: false }
|
|
29023
29031
|
}
|
|
29024
29032
|
),
|
|
29025
|
-
|
|
29033
|
+
lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29026
29034
|
Area,
|
|
29027
29035
|
{
|
|
29028
29036
|
type: "monotone",
|
|
@@ -29030,12 +29038,13 @@ const AnalyticsChart = ({
|
|
|
29030
29038
|
stroke: "none",
|
|
29031
29039
|
fill: `url(#gradient-${lineConfig.dataKey})`,
|
|
29032
29040
|
fillOpacity: 1,
|
|
29041
|
+
connectNulls: false,
|
|
29033
29042
|
isAnimationActive: false,
|
|
29034
29043
|
name: ""
|
|
29035
29044
|
},
|
|
29036
29045
|
`area-${lineConfig.dataKey}`
|
|
29037
29046
|
)),
|
|
29038
|
-
|
|
29047
|
+
lineSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29039
29048
|
Line,
|
|
29040
29049
|
{
|
|
29041
29050
|
type: "monotone",
|
|
@@ -29043,6 +29052,7 @@ const AnalyticsChart = ({
|
|
|
29043
29052
|
stroke: lineConfig.color,
|
|
29044
29053
|
strokeWidth: 2.5,
|
|
29045
29054
|
strokeDasharray: lineConfig.strokeDasharray,
|
|
29055
|
+
connectNulls: false,
|
|
29046
29056
|
dot: false,
|
|
29047
29057
|
activeDot: {
|
|
29048
29058
|
r: 5,
|
|
@@ -29053,6 +29063,19 @@ const AnalyticsChart = ({
|
|
|
29053
29063
|
name: lineConfig.label
|
|
29054
29064
|
},
|
|
29055
29065
|
lineConfig.dataKey
|
|
29066
|
+
)),
|
|
29067
|
+
barSeries.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29068
|
+
Bar,
|
|
29069
|
+
{
|
|
29070
|
+
dataKey: lineConfig.dataKey,
|
|
29071
|
+
fill: lineConfig.color,
|
|
29072
|
+
fillOpacity: 0.9,
|
|
29073
|
+
name: lineConfig.label,
|
|
29074
|
+
maxBarSize: 14,
|
|
29075
|
+
radius: [3, 3, 0, 0],
|
|
29076
|
+
isAnimationActive: false
|
|
29077
|
+
},
|
|
29078
|
+
`bar-${lineConfig.dataKey}`
|
|
29056
29079
|
))
|
|
29057
29080
|
]
|
|
29058
29081
|
}
|
|
@@ -29074,8 +29097,15 @@ const AnalyticsChart = ({
|
|
|
29074
29097
|
})
|
|
29075
29098
|
] })
|
|
29076
29099
|
] }) }),
|
|
29077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4", "data-test-id": "dashboard_analytics_chart_legend", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", "data-test-id": "dashboard_analytics_chart_legend_items", children: chartLines.map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", "data-test-id": `dashboard_analytics_chart_legend_item_${lineConfig.dataKey}`, children: [
|
|
29078
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4", "data-test-id": "dashboard_analytics_chart_legend", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", "data-test-id": "dashboard_analytics_chart_legend_items", children: chartLines.filter((lineConfig) => !lineConfig.hideInLegend).map((lineConfig) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", "data-test-id": `dashboard_analytics_chart_legend_item_${lineConfig.dataKey}`, children: [
|
|
29101
|
+
lineConfig.seriesType === "bar" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29102
|
+
"div",
|
|
29103
|
+
{
|
|
29104
|
+
className: "w-2 h-2 rounded-[2px]",
|
|
29105
|
+
style: { backgroundColor: lineConfig.color },
|
|
29106
|
+
"data-test-id": `dashboard_analytics_chart_legend_color_${lineConfig.dataKey}`
|
|
29107
|
+
}
|
|
29108
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
29079
29109
|
"div",
|
|
29080
29110
|
{
|
|
29081
29111
|
className: "w-[8px] h-[8px] rounded-full",
|
|
@@ -29632,6 +29662,8 @@ function getToolTypeStyle(type) {
|
|
|
29632
29662
|
return "bg-green-100 text-green-800 border-green-200";
|
|
29633
29663
|
if (["knowledge", "KNOWLEDGE", "knowledge tool"].includes(type) || ["knowledge", "knowledge tool"].includes(normalized))
|
|
29634
29664
|
return "bg-purple-100 text-purple-800 border-purple-200";
|
|
29665
|
+
if (["PRE_PROCESSOR", "POST_PROCESSOR", "INPUT_PROCESSOR", "input_processor", "pre_processor", "post_processor", "processor"].includes(type) || ["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized))
|
|
29666
|
+
return "bg-yellow-100 text-yellow-800 border-yellow-200";
|
|
29635
29667
|
return "bg-gray-100 text-gray-800 border-gray-200";
|
|
29636
29668
|
}
|
|
29637
29669
|
function getToolTypeName(type) {
|
|
@@ -29640,6 +29672,8 @@ function getToolTypeName(type) {
|
|
|
29640
29672
|
if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
|
|
29641
29673
|
if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
|
|
29642
29674
|
if (["knowledge", "knowledge tool", "knowledge"].includes(normalized) || type === "KNOWLEDGE") return "Knowledge";
|
|
29675
|
+
if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized) || type === "PRE_PROCESSOR" || type === "POST_PROCESSOR" || type === "INPUT_PROCESSOR" || type === "input_processor")
|
|
29676
|
+
return "Processor";
|
|
29643
29677
|
if (type === "inlineTool") return "Code Tool";
|
|
29644
29678
|
if (type === "toolLibrary") return "Workflow Tool";
|
|
29645
29679
|
if (type === "KNOWLEDGE") return "Knowledge";
|
|
@@ -29866,7 +29900,14 @@ const ModelListView = ({
|
|
|
29866
29900
|
model.provider && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 truncate", "data-test-id": `dashboard_model_list_view_row_provider_${index}`, children: getProviderDisplayName(model.provider) })
|
|
29867
29901
|
] })
|
|
29868
29902
|
] }),
|
|
29869
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
29903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center font-medium text-xs text-gray-700 flex items-center justify-center gap-1", "data-test-id": `dashboard_model_list_view_row_runs_${index}`, children: [
|
|
29904
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formatValue2(model.runs || 0) }),
|
|
29905
|
+
(model.failedRuns ?? 0) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-red-500 text-[10px] font-medium", "data-test-id": `dashboard_model_list_view_row_failed_${index}`, children: [
|
|
29906
|
+
"(",
|
|
29907
|
+
model.failedRuns,
|
|
29908
|
+
" failed)"
|
|
29909
|
+
] })
|
|
29910
|
+
] }),
|
|
29870
29911
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center font-medium text-xs text-gray-700", "data-test-id": `dashboard_model_list_view_row_tokens_${index}`, children: formatValue2(model.tokens || model.totalTokens || 0) }),
|
|
29871
29912
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center font-medium text-xs text-gray-700", "data-test-id": `dashboard_model_list_view_row_response_time_${index}`, children: model.responseTime || (model.avgResponseTime ? `${model.avgResponseTime}ms` : "N/A") })
|
|
29872
29913
|
]
|
|
@@ -30546,6 +30587,7 @@ class DashboardApiService {
|
|
|
30546
30587
|
{
|
|
30547
30588
|
title: "Model Runs",
|
|
30548
30589
|
value: data.data.modelRuns,
|
|
30590
|
+
failedCount: data.data.failedModelRuns || 0,
|
|
30549
30591
|
metricType: "modelRuns",
|
|
30550
30592
|
icon: "cpu",
|
|
30551
30593
|
info: "Number of times the AI agents called various language models to generate responses",
|
|
@@ -30622,8 +30664,12 @@ class DashboardApiService {
|
|
|
30622
30664
|
basePoint.toolRuns = point2.count || 0;
|
|
30623
30665
|
break;
|
|
30624
30666
|
case "modelRuns":
|
|
30667
|
+
case "modelruns": {
|
|
30668
|
+
const failed = point2.failedModelRuns;
|
|
30625
30669
|
basePoint.modelRuns = point2.count || 0;
|
|
30670
|
+
basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
|
|
30626
30671
|
break;
|
|
30672
|
+
}
|
|
30627
30673
|
default:
|
|
30628
30674
|
basePoint.users = point2.count || 0;
|
|
30629
30675
|
basePoint.sessions = point2.count || 0;
|
|
@@ -30632,6 +30678,10 @@ class DashboardApiService {
|
|
|
30632
30678
|
basePoint.agentRuns = point2.count || 0;
|
|
30633
30679
|
basePoint.toolRuns = point2.count || 0;
|
|
30634
30680
|
basePoint.modelRuns = point2.count || 0;
|
|
30681
|
+
{
|
|
30682
|
+
const failed = point2.failedModelRuns;
|
|
30683
|
+
basePoint.failedModelRuns = typeof failed === "number" && failed >= 0 ? failed : 0;
|
|
30684
|
+
}
|
|
30635
30685
|
}
|
|
30636
30686
|
console.log(`Transformed point ${index} for metric ${metricType}:`, basePoint);
|
|
30637
30687
|
return basePoint;
|
|
@@ -30716,22 +30766,16 @@ class DashboardApiService {
|
|
|
30716
30766
|
id: `model-${index + 1}`,
|
|
30717
30767
|
name: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName || `Model ${index + 1}`,
|
|
30718
30768
|
modelName: item.modelName,
|
|
30719
|
-
// Keep original modelName field
|
|
30720
30769
|
provider: item.provider,
|
|
30721
|
-
// Include provider information
|
|
30722
30770
|
runs: item.count || 0,
|
|
30771
|
+
failedRuns: item.failedRuns || 0,
|
|
30723
30772
|
responseTime: item.avgResponseTime ? item.avgResponseTime < 1e3 ? `${Math.round(item.avgResponseTime)}ms` : `${(item.avgResponseTime / 1e3).toFixed(2)}s` : "0ms",
|
|
30724
30773
|
avgResponseTime: item.avgResponseTime,
|
|
30725
|
-
// Keep original avgResponseTime
|
|
30726
30774
|
tokens: item.tokens || item.totalTokens || Math.floor((item.count || 0) * 300),
|
|
30727
|
-
// Use actual token data when available
|
|
30728
30775
|
totalTokens: item.totalTokens || item.tokens,
|
|
30729
|
-
// Include totalTokens field
|
|
30730
30776
|
successRate: item.successRate ? `${Math.round(item.successRate)}%` : "98%",
|
|
30731
|
-
// Default success rate for models
|
|
30732
30777
|
lastRun: item.lastRun || new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1e3).toLocaleDateString(),
|
|
30733
30778
|
icon: item.icon
|
|
30734
|
-
// Preserve original icon data if available
|
|
30735
30779
|
}));
|
|
30736
30780
|
}
|
|
30737
30781
|
// Extract control options from listView data for agents
|
|
@@ -30785,9 +30829,11 @@ class DashboardApiService {
|
|
|
30785
30829
|
if (["toollibrary", "workflow tool"].includes(normalized)) return "Workflow Tool";
|
|
30786
30830
|
if (["mcp", "mcptool"].includes(normalized)) return "MCP Tool";
|
|
30787
30831
|
if (["knowledge", "knowledge tool"].includes(normalized) || toolType === "KNOWLEDGE") return "Knowledge";
|
|
30832
|
+
if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalized)) return "Processor";
|
|
30788
30833
|
if (toolType === "inlineTool") return "Code Tool";
|
|
30789
30834
|
if (toolType === "toolLibrary") return "Workflow Tool";
|
|
30790
30835
|
if (toolType === "MCP" || toolType === "mcpTool") return "MCP Tool";
|
|
30836
|
+
if (toolType === "PRE_PROCESSOR" || toolType === "POST_PROCESSOR" || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") return "Processor";
|
|
30791
30837
|
return "Code Tool";
|
|
30792
30838
|
};
|
|
30793
30839
|
options.push({
|
|
@@ -30860,7 +30906,7 @@ class DashboardApiService {
|
|
|
30860
30906
|
listViewData.forEach((item) => {
|
|
30861
30907
|
if (item.modelName) {
|
|
30862
30908
|
options.push({
|
|
30863
|
-
label: item.modelName,
|
|
30909
|
+
label: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName,
|
|
30864
30910
|
value: item.modelName.replace(/[-\.]/g, ""),
|
|
30865
30911
|
icon: getModelIconPath2(item.provider),
|
|
30866
30912
|
// Use actual SVG icon path
|
|
@@ -30914,6 +30960,7 @@ class DashboardApiService {
|
|
|
30914
30960
|
if (aggregated.has(key)) {
|
|
30915
30961
|
const existing = aggregated.get(key);
|
|
30916
30962
|
existing.count = (existing.count || 0) + (item.count || 0);
|
|
30963
|
+
existing.failedRuns = (existing.failedRuns || 0) + (item.failedRuns || 0);
|
|
30917
30964
|
existing.avgResponseTime = existing.avgResponseTime && item.avgResponseTime ? (existing.avgResponseTime + item.avgResponseTime) / 2 : existing.avgResponseTime || item.avgResponseTime;
|
|
30918
30965
|
existing.tokens = (existing.tokens || 0) + (item.tokens || 0);
|
|
30919
30966
|
} else {
|
|
@@ -30925,11 +30972,24 @@ class DashboardApiService {
|
|
|
30925
30972
|
// Batch fetch enhanced data for all metrics with table and control data
|
|
30926
30973
|
async fetchEnhancedMetricsData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
30927
30974
|
try {
|
|
30928
|
-
const
|
|
30975
|
+
const results = await Promise.allSettled([
|
|
30929
30976
|
this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30930
30977
|
this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30931
30978
|
this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
30932
30979
|
]);
|
|
30980
|
+
if (results[0].status === "rejected") {
|
|
30981
|
+
console.error("Error fetching agent runs enhanced data:", results[0].reason);
|
|
30982
|
+
}
|
|
30983
|
+
if (results[1].status === "rejected") {
|
|
30984
|
+
console.error("Error fetching tool runs enhanced data:", results[1].reason);
|
|
30985
|
+
}
|
|
30986
|
+
if (results[2].status === "rejected") {
|
|
30987
|
+
console.error("Error fetching model runs enhanced data:", results[2].reason);
|
|
30988
|
+
}
|
|
30989
|
+
const emptyData = { chartData: [], tableData: [], controlOptions: [] };
|
|
30990
|
+
const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyData;
|
|
30991
|
+
const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyData;
|
|
30992
|
+
const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyData;
|
|
30933
30993
|
return {
|
|
30934
30994
|
agents: agentsData,
|
|
30935
30995
|
tools: toolsData,
|
|
@@ -30946,13 +31006,30 @@ class DashboardApiService {
|
|
|
30946
31006
|
const getChangeType = (changePercent) => {
|
|
30947
31007
|
return changePercent > 0 ? "increase" : "decrease";
|
|
30948
31008
|
};
|
|
30949
|
-
const
|
|
31009
|
+
const results = await Promise.allSettled([
|
|
30950
31010
|
this.fetchTimeSeriesDataWithTableData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30951
31011
|
this.fetchTimeSeriesDataWithTableData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30952
31012
|
this.fetchTimeSeriesDataWithTableData("model-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
30953
31013
|
this.fetchTimeSeriesData("tool-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
30954
31014
|
]);
|
|
30955
|
-
|
|
31015
|
+
if (results[0].status === "rejected") {
|
|
31016
|
+
console.error("Error fetching agent runs data:", results[0].reason);
|
|
31017
|
+
}
|
|
31018
|
+
if (results[1].status === "rejected") {
|
|
31019
|
+
console.error("Error fetching tool runs data:", results[1].reason);
|
|
31020
|
+
}
|
|
31021
|
+
if (results[2].status === "rejected") {
|
|
31022
|
+
console.error("Error fetching model runs data:", results[2].reason);
|
|
31023
|
+
}
|
|
31024
|
+
if (results[3].status === "rejected") {
|
|
31025
|
+
console.error("Error fetching tool runs time series data:", results[3].reason);
|
|
31026
|
+
}
|
|
31027
|
+
const emptyEnhancedData = { chartData: [], tableData: [], controlOptions: [] };
|
|
31028
|
+
const agentsData = results[0].status === "fulfilled" ? results[0].value : emptyEnhancedData;
|
|
31029
|
+
const toolsData = results[1].status === "fulfilled" ? results[1].value : emptyEnhancedData;
|
|
31030
|
+
const modelsData = results[2].status === "fulfilled" ? results[2].value : emptyEnhancedData;
|
|
31031
|
+
const toolRunsTimeSeriesData = results[3].status === "fulfilled" ? results[3].value : void 0;
|
|
31032
|
+
const enhancedToolRunsChartData = toolRunsTimeSeriesData ? this.transformTimeSeriesDataForToolRuns(toolRunsTimeSeriesData) : [];
|
|
30956
31033
|
return [
|
|
30957
31034
|
{
|
|
30958
31035
|
title: "Agent Runs",
|
|
@@ -30966,68 +31043,70 @@ class DashboardApiService {
|
|
|
30966
31043
|
value: Math.abs(trends.agentRuns.changePercent),
|
|
30967
31044
|
type: getChangeType(trends.agentRuns.changePercent)
|
|
30968
31045
|
} : void 0,
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
30980
|
-
|
|
30981
|
-
|
|
30982
|
-
|
|
30983
|
-
|
|
30984
|
-
|
|
30985
|
-
|
|
30986
|
-
},
|
|
30987
|
-
table: {
|
|
30988
|
-
title: "Agent Runs",
|
|
30989
|
-
data: agentsData.tableData,
|
|
30990
|
-
columns: [
|
|
30991
|
-
{
|
|
30992
|
-
key: "name",
|
|
30993
|
-
title: "Name",
|
|
30994
|
-
width: 200,
|
|
30995
|
-
align: "left"
|
|
30996
|
-
},
|
|
30997
|
-
{
|
|
30998
|
-
key: "runs",
|
|
30999
|
-
title: "Runs",
|
|
31000
|
-
width: 100,
|
|
31001
|
-
align: "right",
|
|
31002
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31003
|
-
},
|
|
31004
|
-
{
|
|
31005
|
-
key: "responseTime",
|
|
31006
|
-
title: "Response Time",
|
|
31007
|
-
width: 120,
|
|
31008
|
-
align: "right"
|
|
31009
|
-
},
|
|
31010
|
-
{
|
|
31011
|
-
key: "tokens",
|
|
31012
|
-
title: "Tokens",
|
|
31013
|
-
width: 100,
|
|
31014
|
-
align: "right",
|
|
31015
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31046
|
+
...agentsData && {
|
|
31047
|
+
view: {
|
|
31048
|
+
type: "chart",
|
|
31049
|
+
chart: {
|
|
31050
|
+
type: "line",
|
|
31051
|
+
title: "Agent Runs",
|
|
31052
|
+
data: agentsData.chartData,
|
|
31053
|
+
dataKey: "agentRuns",
|
|
31054
|
+
color: "#0BA5EC",
|
|
31055
|
+
yAxisLabel: "Number of Agent Runs",
|
|
31056
|
+
height: 300,
|
|
31057
|
+
showGrid: true,
|
|
31058
|
+
curve: "monotone",
|
|
31059
|
+
tooltip: { show: true, style: "dark" },
|
|
31060
|
+
dateRange: {
|
|
31061
|
+
start: fromTimestamp.split("T")[0],
|
|
31062
|
+
end: toTimestamp.split("T")[0]
|
|
31016
31063
|
}
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
|
|
31021
|
-
|
|
31022
|
-
|
|
31023
|
-
|
|
31024
|
-
|
|
31025
|
-
|
|
31026
|
-
|
|
31064
|
+
},
|
|
31065
|
+
table: {
|
|
31066
|
+
title: "Agent Runs",
|
|
31067
|
+
data: agentsData.tableData,
|
|
31068
|
+
columns: [
|
|
31069
|
+
{
|
|
31070
|
+
key: "name",
|
|
31071
|
+
title: "Name",
|
|
31072
|
+
width: 200,
|
|
31073
|
+
align: "left"
|
|
31074
|
+
},
|
|
31075
|
+
{
|
|
31076
|
+
key: "runs",
|
|
31077
|
+
title: "Runs",
|
|
31078
|
+
width: 100,
|
|
31079
|
+
align: "right",
|
|
31080
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31081
|
+
},
|
|
31082
|
+
{
|
|
31083
|
+
key: "responseTime",
|
|
31084
|
+
title: "Response Time",
|
|
31085
|
+
width: 120,
|
|
31086
|
+
align: "right"
|
|
31087
|
+
},
|
|
31088
|
+
{
|
|
31089
|
+
key: "tokens",
|
|
31090
|
+
title: "Tokens",
|
|
31091
|
+
width: 100,
|
|
31092
|
+
align: "right",
|
|
31093
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31094
|
+
}
|
|
31095
|
+
]
|
|
31096
|
+
}
|
|
31027
31097
|
},
|
|
31028
|
-
|
|
31029
|
-
|
|
31030
|
-
|
|
31098
|
+
controls: {
|
|
31099
|
+
dropdown: {
|
|
31100
|
+
label: "All Agents",
|
|
31101
|
+
options: agentsData.controlOptions,
|
|
31102
|
+
defaultValue: ["all"],
|
|
31103
|
+
multiSelect: true,
|
|
31104
|
+
searchable: true
|
|
31105
|
+
},
|
|
31106
|
+
toggle: {
|
|
31107
|
+
chartView: true,
|
|
31108
|
+
tableView: true
|
|
31109
|
+
}
|
|
31031
31110
|
}
|
|
31032
31111
|
}
|
|
31033
31112
|
},
|
|
@@ -31042,99 +31121,107 @@ class DashboardApiService {
|
|
|
31042
31121
|
value: Math.abs(trends.toolRuns.changePercent.total),
|
|
31043
31122
|
type: getChangeType(trends.toolRuns.changePercent.total)
|
|
31044
31123
|
} : void 0,
|
|
31045
|
-
|
|
31046
|
-
|
|
31047
|
-
|
|
31048
|
-
|
|
31049
|
-
|
|
31050
|
-
|
|
31051
|
-
|
|
31052
|
-
|
|
31053
|
-
|
|
31054
|
-
|
|
31055
|
-
|
|
31056
|
-
|
|
31057
|
-
|
|
31058
|
-
|
|
31059
|
-
|
|
31060
|
-
|
|
31061
|
-
|
|
31062
|
-
|
|
31063
|
-
|
|
31064
|
-
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
|
|
31071
|
-
|
|
31072
|
-
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31124
|
+
...toolsData && {
|
|
31125
|
+
view: {
|
|
31126
|
+
type: "chart",
|
|
31127
|
+
chart: {
|
|
31128
|
+
type: "line",
|
|
31129
|
+
title: "Tool Runs",
|
|
31130
|
+
data: enhancedToolRunsChartData,
|
|
31131
|
+
yAxisLabel: "Number of Tool Runs",
|
|
31132
|
+
lines: [
|
|
31133
|
+
{
|
|
31134
|
+
dataKey: "toolRuns",
|
|
31135
|
+
color: "#667085",
|
|
31136
|
+
label: "Tool Runs"
|
|
31137
|
+
},
|
|
31138
|
+
{
|
|
31139
|
+
dataKey: "codeTools",
|
|
31140
|
+
color: "#F38744",
|
|
31141
|
+
label: "Code Tools"
|
|
31142
|
+
},
|
|
31143
|
+
{
|
|
31144
|
+
dataKey: "workflowTools",
|
|
31145
|
+
color: "#2970FF",
|
|
31146
|
+
label: "Workflow Tools"
|
|
31147
|
+
},
|
|
31148
|
+
{
|
|
31149
|
+
dataKey: "knowledgeTools",
|
|
31150
|
+
color: "#7A5AF8",
|
|
31151
|
+
label: "Knowledge"
|
|
31152
|
+
},
|
|
31153
|
+
{
|
|
31154
|
+
dataKey: "mcpTools",
|
|
31155
|
+
color: "#47CD89",
|
|
31156
|
+
label: "MCP Tools"
|
|
31157
|
+
},
|
|
31158
|
+
{
|
|
31159
|
+
dataKey: "processors",
|
|
31160
|
+
color: "#EAB308",
|
|
31161
|
+
label: "Processors"
|
|
31162
|
+
}
|
|
31163
|
+
],
|
|
31164
|
+
height: 300,
|
|
31165
|
+
showGrid: true,
|
|
31166
|
+
showLegend: true,
|
|
31167
|
+
curve: "monotone",
|
|
31168
|
+
tooltip: { show: true, style: "dark" },
|
|
31169
|
+
dateRange: {
|
|
31170
|
+
start: fromTimestamp.split("T")[0],
|
|
31171
|
+
end: toTimestamp.split("T")[0]
|
|
31077
31172
|
}
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
31082
|
-
|
|
31083
|
-
|
|
31084
|
-
|
|
31085
|
-
|
|
31086
|
-
|
|
31173
|
+
},
|
|
31174
|
+
table: {
|
|
31175
|
+
title: "Tool Runs",
|
|
31176
|
+
data: toolsData.tableData,
|
|
31177
|
+
columns: [
|
|
31178
|
+
{
|
|
31179
|
+
key: "name",
|
|
31180
|
+
title: "Name",
|
|
31181
|
+
width: 200,
|
|
31182
|
+
align: "left"
|
|
31183
|
+
},
|
|
31184
|
+
{
|
|
31185
|
+
key: "type",
|
|
31186
|
+
title: "Type",
|
|
31187
|
+
width: 150,
|
|
31188
|
+
align: "left"
|
|
31189
|
+
},
|
|
31190
|
+
{
|
|
31191
|
+
key: "runs",
|
|
31192
|
+
title: "Runs",
|
|
31193
|
+
width: 100,
|
|
31194
|
+
align: "right",
|
|
31195
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31196
|
+
},
|
|
31197
|
+
{
|
|
31198
|
+
key: "responseTime",
|
|
31199
|
+
title: "Response Time",
|
|
31200
|
+
width: 120,
|
|
31201
|
+
align: "right"
|
|
31202
|
+
}
|
|
31203
|
+
]
|
|
31087
31204
|
}
|
|
31088
31205
|
},
|
|
31089
|
-
|
|
31090
|
-
|
|
31091
|
-
|
|
31092
|
-
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
title: "Type",
|
|
31102
|
-
width: 150,
|
|
31103
|
-
align: "left"
|
|
31104
|
-
},
|
|
31105
|
-
{
|
|
31106
|
-
key: "runs",
|
|
31107
|
-
title: "Runs",
|
|
31108
|
-
width: 100,
|
|
31109
|
-
align: "right",
|
|
31110
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31111
|
-
},
|
|
31112
|
-
{
|
|
31113
|
-
key: "responseTime",
|
|
31114
|
-
title: "Response Time",
|
|
31115
|
-
width: 120,
|
|
31116
|
-
align: "right"
|
|
31117
|
-
}
|
|
31118
|
-
]
|
|
31119
|
-
}
|
|
31120
|
-
},
|
|
31121
|
-
controls: {
|
|
31122
|
-
dropdown: {
|
|
31123
|
-
label: "All Tools",
|
|
31124
|
-
options: toolsData.controlOptions,
|
|
31125
|
-
defaultValue: ["all"],
|
|
31126
|
-
multiSelect: true,
|
|
31127
|
-
searchable: true
|
|
31128
|
-
},
|
|
31129
|
-
toggle: {
|
|
31130
|
-
chartView: true,
|
|
31131
|
-
tableView: true
|
|
31206
|
+
controls: {
|
|
31207
|
+
dropdown: {
|
|
31208
|
+
label: "All Tools",
|
|
31209
|
+
options: toolsData.controlOptions,
|
|
31210
|
+
defaultValue: ["all"],
|
|
31211
|
+
multiSelect: true,
|
|
31212
|
+
searchable: true
|
|
31213
|
+
},
|
|
31214
|
+
toggle: {
|
|
31215
|
+
chartView: true,
|
|
31216
|
+
tableView: true
|
|
31217
|
+
}
|
|
31132
31218
|
}
|
|
31133
31219
|
}
|
|
31134
31220
|
},
|
|
31135
31221
|
{
|
|
31136
31222
|
title: "Model Runs",
|
|
31137
31223
|
value: data.data.modelRuns,
|
|
31224
|
+
failedCount: data.data.failedModelRuns || 0,
|
|
31138
31225
|
metricType: "modelRuns",
|
|
31139
31226
|
icon: "cpu",
|
|
31140
31227
|
highlighted: false,
|
|
@@ -31143,68 +31230,79 @@ class DashboardApiService {
|
|
|
31143
31230
|
value: Math.abs(trends.modelRuns.changePercent),
|
|
31144
31231
|
type: getChangeType(trends.modelRuns.changePercent)
|
|
31145
31232
|
} : void 0,
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
{
|
|
31169
|
-
|
|
31170
|
-
|
|
31171
|
-
|
|
31172
|
-
align: "left"
|
|
31173
|
-
},
|
|
31174
|
-
{
|
|
31175
|
-
key: "runs",
|
|
31176
|
-
title: "Runs",
|
|
31177
|
-
width: 100,
|
|
31178
|
-
align: "right",
|
|
31179
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31180
|
-
},
|
|
31181
|
-
{
|
|
31182
|
-
key: "tokens",
|
|
31183
|
-
title: "Tokens",
|
|
31184
|
-
width: 120,
|
|
31185
|
-
align: "right",
|
|
31186
|
-
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31187
|
-
},
|
|
31188
|
-
{
|
|
31189
|
-
key: "responseTime",
|
|
31190
|
-
title: "Response Time",
|
|
31191
|
-
width: 120,
|
|
31192
|
-
align: "right"
|
|
31233
|
+
...modelsData && {
|
|
31234
|
+
view: {
|
|
31235
|
+
type: "chart",
|
|
31236
|
+
chart: {
|
|
31237
|
+
type: "line",
|
|
31238
|
+
title: "Model Runs",
|
|
31239
|
+
data: modelsData.chartData,
|
|
31240
|
+
yAxisLabel: "Number of Model Runs",
|
|
31241
|
+
lines: [
|
|
31242
|
+
{ dataKey: "modelRuns", color: "#47CD89", label: "Model Runs" },
|
|
31243
|
+
{
|
|
31244
|
+
dataKey: "failedModelRuns",
|
|
31245
|
+
color: "#ef4444",
|
|
31246
|
+
label: "Failed",
|
|
31247
|
+
seriesType: "bar",
|
|
31248
|
+
hideInLegend: true
|
|
31249
|
+
}
|
|
31250
|
+
],
|
|
31251
|
+
height: 300,
|
|
31252
|
+
showGrid: true,
|
|
31253
|
+
showLegend: true,
|
|
31254
|
+
curve: "monotone",
|
|
31255
|
+
tooltip: { show: true, style: "dark" },
|
|
31256
|
+
dateRange: {
|
|
31257
|
+
start: fromTimestamp.split("T")[0],
|
|
31258
|
+
end: toTimestamp.split("T")[0]
|
|
31193
31259
|
}
|
|
31194
|
-
|
|
31195
|
-
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
|
|
31201
|
-
|
|
31202
|
-
|
|
31203
|
-
|
|
31260
|
+
},
|
|
31261
|
+
table: {
|
|
31262
|
+
title: "Model Runs",
|
|
31263
|
+
data: modelsData.tableData,
|
|
31264
|
+
columns: [
|
|
31265
|
+
{
|
|
31266
|
+
key: "name",
|
|
31267
|
+
title: "Model Name",
|
|
31268
|
+
width: 200,
|
|
31269
|
+
align: "left"
|
|
31270
|
+
},
|
|
31271
|
+
{
|
|
31272
|
+
key: "runs",
|
|
31273
|
+
title: "Runs",
|
|
31274
|
+
width: 100,
|
|
31275
|
+
align: "right",
|
|
31276
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31277
|
+
},
|
|
31278
|
+
{
|
|
31279
|
+
key: "tokens",
|
|
31280
|
+
title: "Tokens",
|
|
31281
|
+
width: 120,
|
|
31282
|
+
align: "right",
|
|
31283
|
+
formatter: (value) => `${Math.floor(value / 1e3)}k`
|
|
31284
|
+
},
|
|
31285
|
+
{
|
|
31286
|
+
key: "responseTime",
|
|
31287
|
+
title: "Response Time",
|
|
31288
|
+
width: 120,
|
|
31289
|
+
align: "right"
|
|
31290
|
+
}
|
|
31291
|
+
]
|
|
31292
|
+
}
|
|
31204
31293
|
},
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31294
|
+
controls: {
|
|
31295
|
+
dropdown: {
|
|
31296
|
+
label: "All Models",
|
|
31297
|
+
options: modelsData.controlOptions,
|
|
31298
|
+
defaultValue: ["all"],
|
|
31299
|
+
multiSelect: true,
|
|
31300
|
+
searchable: true
|
|
31301
|
+
},
|
|
31302
|
+
toggle: {
|
|
31303
|
+
chartView: true,
|
|
31304
|
+
tableView: true
|
|
31305
|
+
}
|
|
31208
31306
|
}
|
|
31209
31307
|
}
|
|
31210
31308
|
}
|
|
@@ -31216,12 +31314,34 @@ class DashboardApiService {
|
|
|
31216
31314
|
const getChangeType = (changePercent) => {
|
|
31217
31315
|
return changePercent > 0 ? "increase" : "decrease";
|
|
31218
31316
|
};
|
|
31219
|
-
const
|
|
31317
|
+
const results = await Promise.allSettled([
|
|
31220
31318
|
this.fetchTimeSeriesData("users", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31221
31319
|
this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31222
31320
|
this.fetchTimeSeriesData("messages", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31223
31321
|
this.fetchTimeSeriesData("tokens", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31224
31322
|
]);
|
|
31323
|
+
if (results[0].status === "rejected") {
|
|
31324
|
+
console.error("Error fetching users data:", results[0].reason);
|
|
31325
|
+
}
|
|
31326
|
+
if (results[1].status === "rejected") {
|
|
31327
|
+
console.error("Error fetching sessions data:", results[1].reason);
|
|
31328
|
+
}
|
|
31329
|
+
if (results[2].status === "rejected") {
|
|
31330
|
+
console.error("Error fetching messages data:", results[2].reason);
|
|
31331
|
+
}
|
|
31332
|
+
if (results[3].status === "rejected") {
|
|
31333
|
+
console.error("Error fetching tokens data:", results[3].reason);
|
|
31334
|
+
}
|
|
31335
|
+
const emptyTimeSeries = {
|
|
31336
|
+
type: "time-series",
|
|
31337
|
+
category: "usage-analytics",
|
|
31338
|
+
metric: "",
|
|
31339
|
+
data: []
|
|
31340
|
+
};
|
|
31341
|
+
const usersData = results[0].status === "fulfilled" ? results[0].value : { ...emptyTimeSeries, metric: "users" };
|
|
31342
|
+
const sessionsData = results[1].status === "fulfilled" ? results[1].value : { ...emptyTimeSeries, metric: "sessions" };
|
|
31343
|
+
const messagesData = results[2].status === "fulfilled" ? results[2].value : { ...emptyTimeSeries, metric: "messages" };
|
|
31344
|
+
const tokensData = results[3].status === "fulfilled" ? results[3].value : { ...emptyTimeSeries, metric: "tokens" };
|
|
31225
31345
|
return [
|
|
31226
31346
|
{
|
|
31227
31347
|
title: "Users",
|
|
@@ -31235,22 +31355,24 @@ class DashboardApiService {
|
|
|
31235
31355
|
value: Math.abs(trends.users.changePercent),
|
|
31236
31356
|
type: getChangeType(trends.users.changePercent)
|
|
31237
31357
|
} : void 0,
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
|
|
31250
|
-
|
|
31251
|
-
|
|
31252
|
-
|
|
31253
|
-
|
|
31358
|
+
...usersData && {
|
|
31359
|
+
view: {
|
|
31360
|
+
type: "chart",
|
|
31361
|
+
chart: {
|
|
31362
|
+
type: "line",
|
|
31363
|
+
title: "Total Users",
|
|
31364
|
+
data: this.transformTimeSeriesDataForMetric(usersData, "users"),
|
|
31365
|
+
dataKey: "users",
|
|
31366
|
+
color: "#4E5BA6",
|
|
31367
|
+
yAxisLabel: "Number of Users",
|
|
31368
|
+
height: 300,
|
|
31369
|
+
showGrid: true,
|
|
31370
|
+
curve: "monotone",
|
|
31371
|
+
tooltip: { show: true, style: "dark" },
|
|
31372
|
+
dateRange: {
|
|
31373
|
+
start: fromTimestamp.split("T")[0],
|
|
31374
|
+
end: toTimestamp.split("T")[0]
|
|
31375
|
+
}
|
|
31254
31376
|
}
|
|
31255
31377
|
}
|
|
31256
31378
|
}
|
|
@@ -31266,22 +31388,24 @@ class DashboardApiService {
|
|
|
31266
31388
|
value: Math.abs(trends.sessions.changePercent),
|
|
31267
31389
|
type: getChangeType(trends.sessions.changePercent)
|
|
31268
31390
|
} : void 0,
|
|
31269
|
-
|
|
31270
|
-
|
|
31271
|
-
|
|
31272
|
-
|
|
31273
|
-
|
|
31274
|
-
|
|
31275
|
-
|
|
31276
|
-
|
|
31277
|
-
|
|
31278
|
-
|
|
31279
|
-
|
|
31280
|
-
|
|
31281
|
-
|
|
31282
|
-
|
|
31283
|
-
|
|
31284
|
-
|
|
31391
|
+
...sessionsData && {
|
|
31392
|
+
view: {
|
|
31393
|
+
type: "chart",
|
|
31394
|
+
chart: {
|
|
31395
|
+
type: "line",
|
|
31396
|
+
title: "Total Sessions",
|
|
31397
|
+
data: this.transformTimeSeriesDataForMetric(sessionsData, "sessions"),
|
|
31398
|
+
dataKey: "sessions",
|
|
31399
|
+
color: "#0BA5EC",
|
|
31400
|
+
yAxisLabel: "Number of Sessions",
|
|
31401
|
+
height: 300,
|
|
31402
|
+
showGrid: true,
|
|
31403
|
+
curve: "monotone",
|
|
31404
|
+
tooltip: { show: true, style: "dark" },
|
|
31405
|
+
dateRange: {
|
|
31406
|
+
start: fromTimestamp.split("T")[0],
|
|
31407
|
+
end: toTimestamp.split("T")[0]
|
|
31408
|
+
}
|
|
31285
31409
|
}
|
|
31286
31410
|
}
|
|
31287
31411
|
}
|
|
@@ -31297,22 +31421,24 @@ class DashboardApiService {
|
|
|
31297
31421
|
value: Math.abs(trends.messages.changePercent.total),
|
|
31298
31422
|
type: getChangeType(trends.messages.changePercent.total)
|
|
31299
31423
|
} : void 0,
|
|
31300
|
-
|
|
31301
|
-
|
|
31302
|
-
|
|
31303
|
-
|
|
31304
|
-
|
|
31305
|
-
|
|
31306
|
-
|
|
31307
|
-
|
|
31308
|
-
|
|
31309
|
-
|
|
31310
|
-
|
|
31311
|
-
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31424
|
+
...messagesData && {
|
|
31425
|
+
view: {
|
|
31426
|
+
type: "chart",
|
|
31427
|
+
chart: {
|
|
31428
|
+
type: "line",
|
|
31429
|
+
title: "Total Messages",
|
|
31430
|
+
data: this.transformTimeSeriesDataForMetric(messagesData, "messages"),
|
|
31431
|
+
dataKey: "messages",
|
|
31432
|
+
color: "#E478FA",
|
|
31433
|
+
yAxisLabel: "Number of Messages",
|
|
31434
|
+
height: 300,
|
|
31435
|
+
showGrid: true,
|
|
31436
|
+
curve: "monotone",
|
|
31437
|
+
tooltip: { show: true, style: "dark" },
|
|
31438
|
+
dateRange: {
|
|
31439
|
+
start: fromTimestamp.split("T")[0],
|
|
31440
|
+
end: toTimestamp.split("T")[0]
|
|
31441
|
+
}
|
|
31316
31442
|
}
|
|
31317
31443
|
}
|
|
31318
31444
|
}
|
|
@@ -31328,38 +31454,40 @@ class DashboardApiService {
|
|
|
31328
31454
|
value: Math.abs(trends.tokens.changePercent.total),
|
|
31329
31455
|
type: getChangeType(trends.tokens.changePercent.total)
|
|
31330
31456
|
} : void 0,
|
|
31331
|
-
|
|
31332
|
-
|
|
31333
|
-
|
|
31334
|
-
|
|
31335
|
-
|
|
31336
|
-
|
|
31337
|
-
|
|
31338
|
-
|
|
31339
|
-
|
|
31340
|
-
|
|
31341
|
-
|
|
31342
|
-
|
|
31343
|
-
|
|
31344
|
-
|
|
31345
|
-
|
|
31346
|
-
|
|
31347
|
-
|
|
31348
|
-
|
|
31349
|
-
|
|
31350
|
-
|
|
31351
|
-
|
|
31352
|
-
|
|
31457
|
+
...tokensData && {
|
|
31458
|
+
view: {
|
|
31459
|
+
type: "chart",
|
|
31460
|
+
chart: {
|
|
31461
|
+
type: "line",
|
|
31462
|
+
title: "Token Usage Breakdown",
|
|
31463
|
+
data: this.transformTimeSeriesDataForMetric(tokensData, "tokens"),
|
|
31464
|
+
yAxisLabel: "Number of Tokens",
|
|
31465
|
+
lines: [
|
|
31466
|
+
{
|
|
31467
|
+
dataKey: "totalTokens",
|
|
31468
|
+
color: "#FF692E",
|
|
31469
|
+
label: "Total Tokens"
|
|
31470
|
+
},
|
|
31471
|
+
{
|
|
31472
|
+
dataKey: "inputTokens",
|
|
31473
|
+
color: "#5925DC",
|
|
31474
|
+
label: "Input Tokens"
|
|
31475
|
+
},
|
|
31476
|
+
{
|
|
31477
|
+
dataKey: "outputTokens",
|
|
31478
|
+
color: "#E478FA",
|
|
31479
|
+
label: "Output Tokens"
|
|
31480
|
+
}
|
|
31481
|
+
],
|
|
31482
|
+
height: 300,
|
|
31483
|
+
showGrid: true,
|
|
31484
|
+
showLegend: true,
|
|
31485
|
+
curve: "monotone",
|
|
31486
|
+
tooltip: { show: true, style: "dark" },
|
|
31487
|
+
dateRange: {
|
|
31488
|
+
start: fromTimestamp.split("T")[0],
|
|
31489
|
+
end: toTimestamp.split("T")[0]
|
|
31353
31490
|
}
|
|
31354
|
-
],
|
|
31355
|
-
height: 300,
|
|
31356
|
-
showGrid: true,
|
|
31357
|
-
showLegend: true,
|
|
31358
|
-
curve: "monotone",
|
|
31359
|
-
tooltip: { show: true, style: "dark" },
|
|
31360
|
-
dateRange: {
|
|
31361
|
-
start: fromTimestamp.split("T")[0],
|
|
31362
|
-
end: toTimestamp.split("T")[0]
|
|
31363
31491
|
}
|
|
31364
31492
|
}
|
|
31365
31493
|
}
|
|
@@ -31387,35 +31515,27 @@ class DashboardApiService {
|
|
|
31387
31515
|
let workflowTools = 0;
|
|
31388
31516
|
let knowledgeTools = 0;
|
|
31389
31517
|
let mcpTools = 0;
|
|
31518
|
+
let processors = 0;
|
|
31390
31519
|
if (point2.listView && Array.isArray(point2.listView)) {
|
|
31391
31520
|
point2.listView.forEach((item) => {
|
|
31392
31521
|
const count = item.count || 0;
|
|
31393
|
-
const toolType =
|
|
31394
|
-
const toolName = (item.toolName || item.tool_name || "").toLowerCase();
|
|
31395
|
-
console.log(`Processing listView item:`, { toolType, toolName, count });
|
|
31522
|
+
const toolType = item.toolType || item.tool_type || "";
|
|
31396
31523
|
const normalizedToolType = toolType.toLowerCase();
|
|
31397
|
-
if (["inlinetool", "
|
|
31524
|
+
if (["inlinetool", "tool", "code", "codetool", "event"].includes(normalizedToolType)) {
|
|
31398
31525
|
codeTools += count;
|
|
31399
|
-
} else if (["toollibrary", "
|
|
31526
|
+
} else if (["toollibrary", "workflow"].includes(normalizedToolType)) {
|
|
31400
31527
|
workflowTools += count;
|
|
31401
|
-
} else if (["knowledge", "
|
|
31528
|
+
} else if (["knowledge", "knowledgetool"].includes(normalizedToolType) || toolType === "KNOWLEDGE") {
|
|
31402
31529
|
knowledgeTools += count;
|
|
31403
|
-
} else if (["mcp", "
|
|
31530
|
+
} else if (["mcp", "mcptool"].includes(normalizedToolType)) {
|
|
31404
31531
|
mcpTools += count;
|
|
31532
|
+
} else if (["pre_processor", "post_processor", "processor", "input_processor"].includes(normalizedToolType) || toolType === "INPUT_PROCESSOR" || toolType === "input_processor") {
|
|
31533
|
+
processors += count;
|
|
31405
31534
|
} else {
|
|
31406
|
-
console.log(`Unknown tool type '${toolType}' for tool '${toolName}', defaulting to code tools`);
|
|
31407
31535
|
codeTools += count;
|
|
31408
31536
|
}
|
|
31409
31537
|
});
|
|
31410
|
-
|
|
31411
|
-
codeTools,
|
|
31412
|
-
workflowTools,
|
|
31413
|
-
knowledgeTools,
|
|
31414
|
-
mcpTools,
|
|
31415
|
-
total: codeTools + workflowTools + knowledgeTools + mcpTools,
|
|
31416
|
-
expectedTotal: totalToolRuns
|
|
31417
|
-
});
|
|
31418
|
-
const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools;
|
|
31538
|
+
const calculatedTotal = codeTools + workflowTools + knowledgeTools + mcpTools + processors;
|
|
31419
31539
|
if (Math.abs(calculatedTotal - totalToolRuns) > 1) {
|
|
31420
31540
|
console.warn(`Breakdown total (${calculatedTotal}) doesn't match expected total (${totalToolRuns}) for point ${index}`);
|
|
31421
31541
|
const difference = totalToolRuns - calculatedTotal;
|
|
@@ -31423,7 +31543,6 @@ class DashboardApiService {
|
|
|
31423
31543
|
console.log(`Adjusted codeTools by ${difference} to balance total`);
|
|
31424
31544
|
}
|
|
31425
31545
|
} else {
|
|
31426
|
-
console.log(`No listView data for point ${index}, assigning all ${totalToolRuns} to codeTools`);
|
|
31427
31546
|
codeTools = totalToolRuns;
|
|
31428
31547
|
}
|
|
31429
31548
|
const basePoint = {
|
|
@@ -31434,11 +31553,11 @@ class DashboardApiService {
|
|
|
31434
31553
|
toolRuns: totalToolRuns,
|
|
31435
31554
|
value: totalToolRuns,
|
|
31436
31555
|
count: totalToolRuns,
|
|
31437
|
-
// Tool breakdown data for multi-line chart (using actual data)
|
|
31438
31556
|
codeTools,
|
|
31439
31557
|
workflowTools,
|
|
31440
31558
|
knowledgeTools,
|
|
31441
31559
|
mcpTools,
|
|
31560
|
+
processors,
|
|
31442
31561
|
// Token data
|
|
31443
31562
|
input_tokens: point2.input_tokens || 0,
|
|
31444
31563
|
output_tokens: point2.output_tokens || 0,
|
|
@@ -31476,14 +31595,33 @@ class DashboardApiService {
|
|
|
31476
31595
|
// Enhanced batch fetch method that returns complete MetricData with embedded view and controls
|
|
31477
31596
|
async fetchAllCardsDataWithEnhancedViews(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
31478
31597
|
try {
|
|
31479
|
-
const
|
|
31598
|
+
const cardsResults = await Promise.allSettled([
|
|
31480
31599
|
this.fetchUsageAnalyticsCards(fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31481
31600
|
this.fetchRunsCards(fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31482
31601
|
]);
|
|
31483
|
-
|
|
31484
|
-
|
|
31485
|
-
|
|
31602
|
+
if (cardsResults[0].status === "rejected") {
|
|
31603
|
+
console.error("Error fetching usage analytics cards:", cardsResults[0].reason);
|
|
31604
|
+
}
|
|
31605
|
+
if (cardsResults[1].status === "rejected") {
|
|
31606
|
+
console.error("Error fetching runs cards:", cardsResults[1].reason);
|
|
31607
|
+
}
|
|
31608
|
+
if (cardsResults[0].status === "rejected" && cardsResults[1].status === "rejected") {
|
|
31609
|
+
throw new Error("Both usage analytics and runs cards failed to load");
|
|
31610
|
+
}
|
|
31611
|
+
const usageAnalyticsCards = cardsResults[0].status === "fulfilled" ? cardsResults[0].value : void 0;
|
|
31612
|
+
const runsCards = cardsResults[1].status === "fulfilled" ? cardsResults[1].value : void 0;
|
|
31613
|
+
const enhancementResults = await Promise.allSettled([
|
|
31614
|
+
usageAnalyticsCards ? this.transformUsageAnalyticsCardsWithEnhancedData(usageAnalyticsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([]),
|
|
31615
|
+
runsCards ? this.transformRunsCardsWithEnhancedData(runsCards, fromTimestamp, toTimestamp, timeDimension, filters) : Promise.resolve([])
|
|
31486
31616
|
]);
|
|
31617
|
+
if (enhancementResults[0].status === "rejected") {
|
|
31618
|
+
console.error("Error transforming usage analytics cards:", enhancementResults[0].reason);
|
|
31619
|
+
}
|
|
31620
|
+
if (enhancementResults[1].status === "rejected") {
|
|
31621
|
+
console.error("Error transforming runs cards:", enhancementResults[1].reason);
|
|
31622
|
+
}
|
|
31623
|
+
const enhancedUsageAnalytics = enhancementResults[0].status === "fulfilled" ? enhancementResults[0].value : [];
|
|
31624
|
+
const enhancedRuns = enhancementResults[1].status === "fulfilled" ? enhancementResults[1].value : [];
|
|
31487
31625
|
return {
|
|
31488
31626
|
usageAnalytics: enhancedUsageAnalytics,
|
|
31489
31627
|
runs: enhancedRuns
|
|
@@ -31496,13 +31634,21 @@ class DashboardApiService {
|
|
|
31496
31634
|
// Batch fetch time series data for default selected metrics
|
|
31497
31635
|
async fetchDefaultTimeSeriesData(fromTimestamp, toTimestamp, timeDimension, filters = []) {
|
|
31498
31636
|
try {
|
|
31499
|
-
const
|
|
31637
|
+
const results = await Promise.allSettled([
|
|
31500
31638
|
this.fetchTimeSeriesData("sessions", "usage-analytics", fromTimestamp, toTimestamp, timeDimension, filters),
|
|
31501
31639
|
this.fetchTimeSeriesData("agent-runs", "runs", fromTimestamp, toTimestamp, timeDimension, filters)
|
|
31502
31640
|
]);
|
|
31641
|
+
if (results[0].status === "rejected") {
|
|
31642
|
+
console.error("Error fetching sessions data:", results[0].reason);
|
|
31643
|
+
}
|
|
31644
|
+
if (results[1].status === "rejected") {
|
|
31645
|
+
console.error("Error fetching agent runs data:", results[1].reason);
|
|
31646
|
+
}
|
|
31647
|
+
const sessionsData = results[0].status === "fulfilled" ? results[0].value : void 0;
|
|
31648
|
+
const agentRunsData = results[1].status === "fulfilled" ? results[1].value : void 0;
|
|
31503
31649
|
return {
|
|
31504
|
-
sessions: this.transformTimeSeriesData(sessionsData),
|
|
31505
|
-
agentRuns: this.transformTimeSeriesData(agentRunsData)
|
|
31650
|
+
sessions: sessionsData ? this.transformTimeSeriesData(sessionsData) : [],
|
|
31651
|
+
agentRuns: agentRunsData ? this.transformTimeSeriesData(agentRunsData) : []
|
|
31506
31652
|
};
|
|
31507
31653
|
} catch (error) {
|
|
31508
31654
|
console.error("Error fetching default time series data:", error);
|
|
@@ -32229,6 +32375,10 @@ const SectionControls = ({
|
|
|
32229
32375
|
] })
|
|
32230
32376
|
] });
|
|
32231
32377
|
};
|
|
32378
|
+
function modelListViewRowLabel(listItem) {
|
|
32379
|
+
if (!listItem.modelName) return "";
|
|
32380
|
+
return listItem.connectionName ? `${listItem.modelName} - ${listItem.connectionName}` : listItem.modelName;
|
|
32381
|
+
}
|
|
32232
32382
|
const DashboardSection = ({
|
|
32233
32383
|
section,
|
|
32234
32384
|
className,
|
|
@@ -32326,16 +32476,17 @@ const DashboardSection = ({
|
|
|
32326
32476
|
});
|
|
32327
32477
|
return baseData.map((item) => {
|
|
32328
32478
|
let filteredValue = 0;
|
|
32479
|
+
let matchingItems = [];
|
|
32329
32480
|
if (item["listView"] && Array.isArray(item["listView"])) {
|
|
32330
|
-
|
|
32481
|
+
matchingItems = item["listView"].filter((listItem) => {
|
|
32331
32482
|
if (metricType === "agentRuns" && listItem.agentName) {
|
|
32332
32483
|
return listItem.agentName === selectedLabel || listItem.agentName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
|
|
32333
32484
|
}
|
|
32334
32485
|
if (metricType === "toolRuns" && listItem.toolName) {
|
|
32335
32486
|
return listItem.toolName === selectedLabel || listItem.toolName.toLowerCase() === (selectedLabel == null ? void 0 : selectedLabel.toLowerCase());
|
|
32336
32487
|
}
|
|
32337
|
-
if (metricType === "modelRuns" && listItem.modelName) {
|
|
32338
|
-
return listItem
|
|
32488
|
+
if (metricType === "modelRuns" && listItem.modelName && selectedLabel) {
|
|
32489
|
+
return modelListViewRowLabel(listItem) === selectedLabel;
|
|
32339
32490
|
}
|
|
32340
32491
|
return false;
|
|
32341
32492
|
});
|
|
@@ -32345,10 +32496,17 @@ const DashboardSection = ({
|
|
|
32345
32496
|
);
|
|
32346
32497
|
}
|
|
32347
32498
|
console.log("📊 Filtered value for", selectedLabel, ":", filteredValue);
|
|
32499
|
+
const failedModelRunsSum = metricType === "modelRuns" ? matchingItems.reduce(
|
|
32500
|
+
(sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
|
|
32501
|
+
0
|
|
32502
|
+
) : 0;
|
|
32348
32503
|
const result = {
|
|
32349
32504
|
...item,
|
|
32350
32505
|
[metricType]: filteredValue
|
|
32351
32506
|
};
|
|
32507
|
+
if (metricType === "modelRuns") {
|
|
32508
|
+
result.failedModelRuns = failedModelRunsSum;
|
|
32509
|
+
}
|
|
32352
32510
|
return result;
|
|
32353
32511
|
});
|
|
32354
32512
|
}
|
|
@@ -32360,8 +32518,9 @@ const DashboardSection = ({
|
|
|
32360
32518
|
const selectedLabels = selectedOptions.map((opt) => opt.label);
|
|
32361
32519
|
return baseData.map((item) => {
|
|
32362
32520
|
let aggregatedValue = 0;
|
|
32521
|
+
let matchingItems = [];
|
|
32363
32522
|
if (item["listView"] && Array.isArray(item["listView"])) {
|
|
32364
|
-
|
|
32523
|
+
matchingItems = item["listView"].filter((listItem) => {
|
|
32365
32524
|
if (metricType === "agentRuns" && listItem.agentName) {
|
|
32366
32525
|
return selectedLabels.some(
|
|
32367
32526
|
(label) => listItem.agentName === label || listItem.agentName.toLowerCase() === (label == null ? void 0 : label.toLowerCase())
|
|
@@ -32373,9 +32532,8 @@ const DashboardSection = ({
|
|
|
32373
32532
|
);
|
|
32374
32533
|
}
|
|
32375
32534
|
if (metricType === "modelRuns" && listItem.modelName) {
|
|
32376
|
-
|
|
32377
|
-
|
|
32378
|
-
);
|
|
32535
|
+
const rowLabel = modelListViewRowLabel(listItem);
|
|
32536
|
+
return selectedLabels.some((label) => rowLabel === label);
|
|
32379
32537
|
}
|
|
32380
32538
|
return false;
|
|
32381
32539
|
});
|
|
@@ -32384,10 +32542,18 @@ const DashboardSection = ({
|
|
|
32384
32542
|
0
|
|
32385
32543
|
);
|
|
32386
32544
|
}
|
|
32387
|
-
|
|
32545
|
+
const failedModelRunsMulti = metricType === "modelRuns" ? matchingItems.reduce(
|
|
32546
|
+
(sum2, listItem) => sum2 + (Number(listItem.failedRuns) || 0),
|
|
32547
|
+
0
|
|
32548
|
+
) : 0;
|
|
32549
|
+
const multiResult = {
|
|
32388
32550
|
...item,
|
|
32389
32551
|
[metricType]: aggregatedValue
|
|
32390
32552
|
};
|
|
32553
|
+
if (metricType === "modelRuns") {
|
|
32554
|
+
multiResult.failedModelRuns = failedModelRunsMulti;
|
|
32555
|
+
}
|
|
32556
|
+
return multiResult;
|
|
32391
32557
|
});
|
|
32392
32558
|
}
|
|
32393
32559
|
return baseData;
|
|
@@ -32619,35 +32785,30 @@ const DashboardSection = ({
|
|
|
32619
32785
|
data: filteredData,
|
|
32620
32786
|
yAxisLabel: "Number of Tool Runs",
|
|
32621
32787
|
lines: [
|
|
32622
|
-
{
|
|
32623
|
-
dataKey: "toolRuns",
|
|
32624
|
-
color: "#06b6d4",
|
|
32625
|
-
// Blue for Tool Runs
|
|
32626
|
-
label: "Tool Runs"
|
|
32627
|
-
},
|
|
32628
32788
|
{
|
|
32629
32789
|
dataKey: "codeTools",
|
|
32630
32790
|
color: "#f97316",
|
|
32631
|
-
// Orange for Code Tools
|
|
32632
32791
|
label: "Code Tools"
|
|
32633
32792
|
},
|
|
32634
32793
|
{
|
|
32635
32794
|
dataKey: "workflowTools",
|
|
32636
32795
|
color: "#10b981",
|
|
32637
|
-
// Green for Workflow Tools
|
|
32638
32796
|
label: "Workflow Tools"
|
|
32639
32797
|
},
|
|
32640
32798
|
{
|
|
32641
32799
|
dataKey: "knowledgeTools",
|
|
32642
32800
|
color: "#8b5cf6",
|
|
32643
|
-
// Purple for Knowledge
|
|
32644
32801
|
label: "Knowledge"
|
|
32645
32802
|
},
|
|
32646
32803
|
{
|
|
32647
32804
|
dataKey: "mcpTools",
|
|
32648
32805
|
color: "#ef4444",
|
|
32649
|
-
// Red for MCP Tools
|
|
32650
32806
|
label: "MCP Tools"
|
|
32807
|
+
},
|
|
32808
|
+
{
|
|
32809
|
+
dataKey: "processors",
|
|
32810
|
+
color: "#eab308",
|
|
32811
|
+
label: "Processors"
|
|
32651
32812
|
}
|
|
32652
32813
|
],
|
|
32653
32814
|
height: 300,
|
|
@@ -32667,12 +32828,20 @@ const DashboardSection = ({
|
|
|
32667
32828
|
type: "line",
|
|
32668
32829
|
title: getChartTitle("Model Runs"),
|
|
32669
32830
|
data: getFilteredData(baseData, "modelRuns"),
|
|
32670
|
-
dataKey: "modelRuns",
|
|
32671
|
-
color: "#10b981",
|
|
32672
|
-
// Green as shown in Figma
|
|
32673
32831
|
yAxisLabel: "Number of Model Runs",
|
|
32832
|
+
lines: [
|
|
32833
|
+
{ dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
|
|
32834
|
+
{
|
|
32835
|
+
dataKey: "failedModelRuns",
|
|
32836
|
+
color: "#ef4444",
|
|
32837
|
+
label: "Failed",
|
|
32838
|
+
seriesType: "bar",
|
|
32839
|
+
hideInLegend: true
|
|
32840
|
+
}
|
|
32841
|
+
],
|
|
32674
32842
|
height: 300,
|
|
32675
32843
|
showGrid: true,
|
|
32844
|
+
showLegend: true,
|
|
32676
32845
|
curve: "monotone",
|
|
32677
32846
|
tooltip: { show: true, style: "dark" },
|
|
32678
32847
|
dateRange: {
|
|
@@ -32685,12 +32854,20 @@ const DashboardSection = ({
|
|
|
32685
32854
|
type: "line",
|
|
32686
32855
|
title: getChartTitle("Model Runs"),
|
|
32687
32856
|
data: filteredData,
|
|
32688
|
-
dataKey: "modelRuns",
|
|
32689
|
-
color: "#10b981",
|
|
32690
|
-
// Green as shown in Figma
|
|
32691
32857
|
yAxisLabel: "Number of Model Runs",
|
|
32858
|
+
lines: [
|
|
32859
|
+
{ dataKey: "modelRuns", color: "#10b981", label: "Model Runs" },
|
|
32860
|
+
{
|
|
32861
|
+
dataKey: "failedModelRuns",
|
|
32862
|
+
color: "#ef4444",
|
|
32863
|
+
label: "Failed",
|
|
32864
|
+
seriesType: "bar",
|
|
32865
|
+
hideInLegend: true
|
|
32866
|
+
}
|
|
32867
|
+
],
|
|
32692
32868
|
height: 300,
|
|
32693
32869
|
showGrid: true,
|
|
32870
|
+
showLegend: true,
|
|
32694
32871
|
curve: "monotone",
|
|
32695
32872
|
tooltip: { show: true, style: "dark" },
|
|
32696
32873
|
dateRange: {
|
|
@@ -34942,8 +35119,11 @@ const Dashboard = ({
|
|
|
34942
35119
|
if (appConfig) {
|
|
34943
35120
|
try {
|
|
34944
35121
|
apiServiceRef.current = new DashboardApiService(appConfig);
|
|
34945
|
-
|
|
34946
|
-
|
|
35122
|
+
const initDashboard = async () => {
|
|
35123
|
+
await loadEnvironments();
|
|
35124
|
+
await loadInitialData();
|
|
35125
|
+
};
|
|
35126
|
+
initDashboard();
|
|
34947
35127
|
} catch (err) {
|
|
34948
35128
|
console.error("Failed to initialize API service:", err);
|
|
34949
35129
|
}
|
|
@@ -35509,6 +35689,31 @@ class TracingApiService {
|
|
|
35509
35689
|
traces: data.traces || []
|
|
35510
35690
|
};
|
|
35511
35691
|
}
|
|
35692
|
+
/**
|
|
35693
|
+
* Get total count of traces matching filters (for pagination)
|
|
35694
|
+
* Endpoint: /tracing/api/trpc/traces.countAll
|
|
35695
|
+
*/
|
|
35696
|
+
async fetchTracesCount(projectId, filters, options = {}) {
|
|
35697
|
+
const input = {
|
|
35698
|
+
json: {
|
|
35699
|
+
projectId,
|
|
35700
|
+
filter: filters,
|
|
35701
|
+
searchQuery: options.searchQuery ?? null,
|
|
35702
|
+
searchType: options.searchType ?? ["id"],
|
|
35703
|
+
page: 0,
|
|
35704
|
+
limit: 0,
|
|
35705
|
+
orderBy: options.orderBy ?? null
|
|
35706
|
+
},
|
|
35707
|
+
meta: {
|
|
35708
|
+
values: this.buildMetaValues(filters)
|
|
35709
|
+
}
|
|
35710
|
+
};
|
|
35711
|
+
const url = this.buildTrpcUrl("traces.countAll", input);
|
|
35712
|
+
const data = await this.makeRequest(url);
|
|
35713
|
+
return {
|
|
35714
|
+
totalCount: (data == null ? void 0 : data.totalCount) ?? 0
|
|
35715
|
+
};
|
|
35716
|
+
}
|
|
35512
35717
|
/**
|
|
35513
35718
|
* Fetch metrics for multiple traces (latency, tokens, cost)
|
|
35514
35719
|
* Endpoint: /tracing/api/trpc/traces.metrics
|
|
@@ -36582,6 +36787,140 @@ function TokenBreakdownTooltip(props) {
|
|
|
36582
36787
|
] }) })
|
|
36583
36788
|
] });
|
|
36584
36789
|
}
|
|
36790
|
+
const CopyButton$1 = ({
|
|
36791
|
+
text,
|
|
36792
|
+
className = "",
|
|
36793
|
+
iconClassName = "",
|
|
36794
|
+
iconStyle,
|
|
36795
|
+
title = "Copy to clipboard",
|
|
36796
|
+
onCopySuccess,
|
|
36797
|
+
onCopyError,
|
|
36798
|
+
tooltipText = "Copied!",
|
|
36799
|
+
tooltipPosition = "bottom",
|
|
36800
|
+
size = "md"
|
|
36801
|
+
}) => {
|
|
36802
|
+
const [showTooltip, setShowTooltip] = useState(false);
|
|
36803
|
+
const getSizeClasses = () => {
|
|
36804
|
+
switch (size) {
|
|
36805
|
+
case "sm":
|
|
36806
|
+
return {
|
|
36807
|
+
button: "p-1",
|
|
36808
|
+
icon: "w-[12px] h-[12px]",
|
|
36809
|
+
tooltip: "text-xs py-1 px-2"
|
|
36810
|
+
};
|
|
36811
|
+
case "lg":
|
|
36812
|
+
return {
|
|
36813
|
+
button: "p-2",
|
|
36814
|
+
icon: "w-[20px] h-[20px]",
|
|
36815
|
+
tooltip: "text-sm py-2 px-3"
|
|
36816
|
+
};
|
|
36817
|
+
default:
|
|
36818
|
+
return {
|
|
36819
|
+
button: "p-1.5",
|
|
36820
|
+
icon: "w-[16px] h-[16px]",
|
|
36821
|
+
tooltip: "text-xs py-1 px-2"
|
|
36822
|
+
};
|
|
36823
|
+
}
|
|
36824
|
+
};
|
|
36825
|
+
const getTooltipPositionClasses = () => {
|
|
36826
|
+
const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
|
|
36827
|
+
switch (tooltipPosition) {
|
|
36828
|
+
case "bottom":
|
|
36829
|
+
return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
|
|
36830
|
+
case "left":
|
|
36831
|
+
return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
|
|
36832
|
+
case "right":
|
|
36833
|
+
return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
|
|
36834
|
+
default:
|
|
36835
|
+
return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
|
|
36836
|
+
}
|
|
36837
|
+
};
|
|
36838
|
+
const sizeClasses2 = getSizeClasses();
|
|
36839
|
+
const showCopyTooltip = useCallback(() => {
|
|
36840
|
+
setShowTooltip(true);
|
|
36841
|
+
setTimeout(() => setShowTooltip(false), 1e3);
|
|
36842
|
+
}, []);
|
|
36843
|
+
const copyToClipboard2 = useCallback(async () => {
|
|
36844
|
+
try {
|
|
36845
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
36846
|
+
await navigator.clipboard.writeText(text);
|
|
36847
|
+
showCopyTooltip();
|
|
36848
|
+
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
36849
|
+
return;
|
|
36850
|
+
}
|
|
36851
|
+
const textArea = document.createElement("textarea");
|
|
36852
|
+
textArea.value = text;
|
|
36853
|
+
textArea.style.position = "fixed";
|
|
36854
|
+
textArea.style.left = "-999999px";
|
|
36855
|
+
textArea.style.top = "-999999px";
|
|
36856
|
+
document.body.appendChild(textArea);
|
|
36857
|
+
textArea.focus();
|
|
36858
|
+
textArea.select();
|
|
36859
|
+
try {
|
|
36860
|
+
document.execCommand("copy");
|
|
36861
|
+
showCopyTooltip();
|
|
36862
|
+
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
36863
|
+
} catch (err) {
|
|
36864
|
+
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
36865
|
+
console.warn("Copy to clipboard failed:", error);
|
|
36866
|
+
onCopyError == null ? void 0 : onCopyError(error);
|
|
36867
|
+
} finally {
|
|
36868
|
+
document.body.removeChild(textArea);
|
|
36869
|
+
}
|
|
36870
|
+
} catch (err) {
|
|
36871
|
+
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
36872
|
+
console.warn("Copy to clipboard failed:", error);
|
|
36873
|
+
onCopyError == null ? void 0 : onCopyError(error);
|
|
36874
|
+
}
|
|
36875
|
+
}, [text, showCopyTooltip, onCopySuccess, onCopyError]);
|
|
36876
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
|
|
36877
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36878
|
+
"button",
|
|
36879
|
+
{
|
|
36880
|
+
onClick: copyToClipboard2,
|
|
36881
|
+
className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
|
|
36882
|
+
title,
|
|
36883
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
|
|
36884
|
+
}
|
|
36885
|
+
),
|
|
36886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36887
|
+
"div",
|
|
36888
|
+
{
|
|
36889
|
+
className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
|
|
36890
|
+
style: {
|
|
36891
|
+
visibility: showTooltip ? "visible" : "hidden"
|
|
36892
|
+
},
|
|
36893
|
+
children: tooltipText
|
|
36894
|
+
}
|
|
36895
|
+
)
|
|
36896
|
+
] });
|
|
36897
|
+
};
|
|
36898
|
+
function CopyableId({ value, truncateLength = 30 }) {
|
|
36899
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "copyable-id-wrapper", title: value, children: [
|
|
36900
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: TracingUtils.truncate(value, truncateLength) }),
|
|
36901
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36902
|
+
"span",
|
|
36903
|
+
{
|
|
36904
|
+
className: "copyable-id-btn",
|
|
36905
|
+
onClick: (e3) => {
|
|
36906
|
+
e3.stopPropagation();
|
|
36907
|
+
e3.preventDefault();
|
|
36908
|
+
},
|
|
36909
|
+
onMouseDown: (e3) => e3.stopPropagation(),
|
|
36910
|
+
onMouseUp: (e3) => e3.stopPropagation(),
|
|
36911
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36912
|
+
CopyButton$1,
|
|
36913
|
+
{
|
|
36914
|
+
text: value,
|
|
36915
|
+
size: "sm",
|
|
36916
|
+
title: "Copy to clipboard",
|
|
36917
|
+
iconClassName: "text-[#667085]"
|
|
36918
|
+
}
|
|
36919
|
+
)
|
|
36920
|
+
}
|
|
36921
|
+
)
|
|
36922
|
+
] });
|
|
36923
|
+
}
|
|
36585
36924
|
function Shimmer$2({ className = "", children }) {
|
|
36586
36925
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-[#F2F4F7] rounded ${className}`, children });
|
|
36587
36926
|
}
|
|
@@ -104592,6 +104931,9 @@ function TracingTable(props) {
|
|
|
104592
104931
|
}, [columns]);
|
|
104593
104932
|
const handleRowClick = useCallback(
|
|
104594
104933
|
(event) => {
|
|
104934
|
+
var _a;
|
|
104935
|
+
const target = (_a = event.event) == null ? void 0 : _a.target;
|
|
104936
|
+
if (target == null ? void 0 : target.closest(".copyable-id-btn")) return;
|
|
104595
104937
|
if (onRowClick && event.data) {
|
|
104596
104938
|
onRowClick(event.data);
|
|
104597
104939
|
}
|
|
@@ -104688,9 +105030,10 @@ function TracingTable(props) {
|
|
|
104688
105030
|
onClick: goToFirstPage,
|
|
104689
105031
|
disabled: currentPage === 0,
|
|
104690
105032
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
105033
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104691
105034
|
title: "First page",
|
|
104692
105035
|
"data-test-id": "tracing-table-first-page-btn",
|
|
104693
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, {
|
|
105036
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, { size: 16 })
|
|
104694
105037
|
}
|
|
104695
105038
|
),
|
|
104696
105039
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -104699,12 +105042,13 @@ function TracingTable(props) {
|
|
|
104699
105042
|
onClick: goToPreviousPage,
|
|
104700
105043
|
disabled: currentPage === 0,
|
|
104701
105044
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
105045
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104702
105046
|
title: "Previous page",
|
|
104703
105047
|
"data-test-id": "tracing-table-prev-page-btn",
|
|
104704
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, {
|
|
105048
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { size: 16 })
|
|
104705
105049
|
}
|
|
104706
105050
|
),
|
|
104707
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-4 py-2 text-sm
|
|
105051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-4 py-2 text-sm", style: { color: "var(--colors-gray-light-mode-700, #344054)" }, "data-test-id": "tracing-table-page-info", children: [
|
|
104708
105052
|
"Page ",
|
|
104709
105053
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: currentPage + 1 }),
|
|
104710
105054
|
" of",
|
|
@@ -104717,9 +105061,10 @@ function TracingTable(props) {
|
|
|
104717
105061
|
onClick: goToNextPage,
|
|
104718
105062
|
disabled: currentPage >= totalPages - 1,
|
|
104719
105063
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
105064
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104720
105065
|
title: "Next page",
|
|
104721
105066
|
"data-test-id": "tracing-table-next-page-btn",
|
|
104722
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, {
|
|
105067
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 16 })
|
|
104723
105068
|
}
|
|
104724
105069
|
),
|
|
104725
105070
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -104728,13 +105073,14 @@ function TracingTable(props) {
|
|
|
104728
105073
|
onClick: goToLastPage,
|
|
104729
105074
|
disabled: currentPage >= totalPages - 1,
|
|
104730
105075
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
105076
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104731
105077
|
title: "Last page",
|
|
104732
105078
|
"data-test-id": "tracing-table-last-page-btn",
|
|
104733
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, {
|
|
105079
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, { size: 16 })
|
|
104734
105080
|
}
|
|
104735
105081
|
)
|
|
104736
105082
|
] }),
|
|
104737
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center text-sm
|
|
105083
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center text-sm shrink-0 absolute right-[24px]", style: { color: "var(--colors-gray-light-mode-700, #344054)" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
104738
105084
|
"Showing ",
|
|
104739
105085
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: startRow }),
|
|
104740
105086
|
" to",
|
|
@@ -104762,9 +105108,12 @@ function TracingListHeader(props) {
|
|
|
104762
105108
|
timeRangePresetLabel,
|
|
104763
105109
|
onTimeRangeChange,
|
|
104764
105110
|
filters,
|
|
105111
|
+
filterColumns: filterColumnsProp,
|
|
104765
105112
|
onFiltersClick,
|
|
104766
105113
|
onModifyColumnsClick,
|
|
104767
105114
|
showModifyColumns = true,
|
|
105115
|
+
onClearFilters,
|
|
105116
|
+
onRemoveFilter,
|
|
104768
105117
|
onRefresh,
|
|
104769
105118
|
isRefreshing = false
|
|
104770
105119
|
} = props;
|
|
@@ -104809,6 +105158,50 @@ function TracingListHeader(props) {
|
|
|
104809
105158
|
}
|
|
104810
105159
|
return `Searches in ${fields}.`;
|
|
104811
105160
|
};
|
|
105161
|
+
const activeFilters = filters.filter(TracingUtils.isFilterActive);
|
|
105162
|
+
const [filtersExpanded, setFiltersExpanded] = useState(false);
|
|
105163
|
+
const [isOverflowing, setIsOverflowing] = useState(false);
|
|
105164
|
+
const chipsContainerRef = useRef(null);
|
|
105165
|
+
const checkOverflow = useCallback(() => {
|
|
105166
|
+
const el = chipsContainerRef.current;
|
|
105167
|
+
if (!el) return;
|
|
105168
|
+
setIsOverflowing(el.scrollHeight > el.clientHeight);
|
|
105169
|
+
}, []);
|
|
105170
|
+
useEffect(() => {
|
|
105171
|
+
checkOverflow();
|
|
105172
|
+
window.addEventListener("resize", checkOverflow);
|
|
105173
|
+
return () => window.removeEventListener("resize", checkOverflow);
|
|
105174
|
+
}, [checkOverflow, activeFilters.length]);
|
|
105175
|
+
const getFilterChipLabel = (filter) => {
|
|
105176
|
+
const col = filterColumnsProp == null ? void 0 : filterColumnsProp.find((c3) => c3.field === filter.column);
|
|
105177
|
+
const label = (col == null ? void 0 : col.label) ?? filter.column;
|
|
105178
|
+
let valueText;
|
|
105179
|
+
if (filter.type === "datetime") {
|
|
105180
|
+
valueText = new Date(filter.value).toLocaleDateString();
|
|
105181
|
+
} else if (filter.type === "number") {
|
|
105182
|
+
valueText = parseFloat(filter.value).toLocaleString();
|
|
105183
|
+
} else if (Array.isArray(filter.value)) {
|
|
105184
|
+
valueText = filter.value.length <= 2 ? filter.value.join(", ") : `${filter.value.length} selected`;
|
|
105185
|
+
} else {
|
|
105186
|
+
valueText = String(filter.value ?? "");
|
|
105187
|
+
}
|
|
105188
|
+
const shortOp = {
|
|
105189
|
+
"=": "",
|
|
105190
|
+
"!=": "≠ ",
|
|
105191
|
+
">": "> ",
|
|
105192
|
+
">=": "≥ ",
|
|
105193
|
+
"<": "< ",
|
|
105194
|
+
"<=": "≤ ",
|
|
105195
|
+
"contains": "~ ",
|
|
105196
|
+
"does not contain": "!~ ",
|
|
105197
|
+
"starts with": "starts ",
|
|
105198
|
+
"ends with": "ends ",
|
|
105199
|
+
"any of": "",
|
|
105200
|
+
"none of": "not "
|
|
105201
|
+
};
|
|
105202
|
+
const op = shortOp[filter.operator] ?? `${filter.operator} `;
|
|
105203
|
+
return `${label}: ${op}${valueText}`;
|
|
105204
|
+
};
|
|
104812
105205
|
const handleDateRangeChange = (dateRange, presetLabel) => {
|
|
104813
105206
|
if (dateRange && dateRange.from && dateRange.to) {
|
|
104814
105207
|
const fromDate = dateRange.from;
|
|
@@ -104961,7 +105354,66 @@ function TracingListHeader(props) {
|
|
|
104961
105354
|
}
|
|
104962
105355
|
)
|
|
104963
105356
|
] })
|
|
104964
|
-
] })
|
|
105357
|
+
] }),
|
|
105358
|
+
activeFilters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105359
|
+
"div",
|
|
105360
|
+
{
|
|
105361
|
+
className: "flex items-start gap-[8px] border border-gray-200 rounded-[8px] px-[12px] py-[8px]",
|
|
105362
|
+
"data-test-id": "tracing-filter-chips",
|
|
105363
|
+
children: [
|
|
105364
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[28px] text-gray-500 shrink-0", children: "Filters" }),
|
|
105365
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105366
|
+
"div",
|
|
105367
|
+
{
|
|
105368
|
+
ref: chipsContainerRef,
|
|
105369
|
+
className: `flex items-center gap-[8px] flex-wrap flex-1 min-w-0 ${!filtersExpanded ? "max-h-[28px] overflow-hidden" : ""}`,
|
|
105370
|
+
children: activeFilters.map((filter, idx) => {
|
|
105371
|
+
const originalIndex = filters.indexOf(filter);
|
|
105372
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105373
|
+
"div",
|
|
105374
|
+
{
|
|
105375
|
+
className: "inline-flex items-center gap-[4px] h-[28px] px-[10px] py-[4px] bg-blue-50 border border-blue-200 rounded-[6px] text-[12px] leading-[16px] text-blue-800 max-w-[260px]",
|
|
105376
|
+
children: [
|
|
105377
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-medium", children: getFilterChipLabel(filter) }),
|
|
105378
|
+
onRemoveFilter && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105379
|
+
"button",
|
|
105380
|
+
{
|
|
105381
|
+
onClick: () => onRemoveFilter(originalIndex),
|
|
105382
|
+
className: "flex items-center justify-center shrink-0 text-blue-400 hover:text-blue-700 transition-colors",
|
|
105383
|
+
title: "Remove filter",
|
|
105384
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[14px] h-[14px]", strokeWidth: 2 })
|
|
105385
|
+
}
|
|
105386
|
+
)
|
|
105387
|
+
]
|
|
105388
|
+
},
|
|
105389
|
+
`chip-${idx}`
|
|
105390
|
+
);
|
|
105391
|
+
})
|
|
105392
|
+
}
|
|
105393
|
+
),
|
|
105394
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] shrink-0 leading-[28px]", children: [
|
|
105395
|
+
(isOverflowing || filtersExpanded) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105396
|
+
"button",
|
|
105397
|
+
{
|
|
105398
|
+
onClick: () => setFiltersExpanded((prev) => !prev),
|
|
105399
|
+
className: "text-[12px] font-medium text-blue-600 hover:text-blue-800 transition-colors whitespace-nowrap",
|
|
105400
|
+
"data-test-id": "tracing-filter-toggle",
|
|
105401
|
+
children: filtersExpanded ? "View less" : "View all"
|
|
105402
|
+
}
|
|
105403
|
+
),
|
|
105404
|
+
onClearFilters && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105405
|
+
"button",
|
|
105406
|
+
{
|
|
105407
|
+
onClick: onClearFilters,
|
|
105408
|
+
className: "text-[12px] font-medium text-gray-500 hover:text-gray-700 transition-colors whitespace-nowrap",
|
|
105409
|
+
"data-test-id": "tracing-filter-clear-all",
|
|
105410
|
+
children: "Clear all"
|
|
105411
|
+
}
|
|
105412
|
+
)
|
|
105413
|
+
] })
|
|
105414
|
+
]
|
|
105415
|
+
}
|
|
105416
|
+
)
|
|
104965
105417
|
] });
|
|
104966
105418
|
}
|
|
104967
105419
|
function ColumnCustomization(props) {
|
|
@@ -105448,6 +105900,8 @@ function FilterPanel(props) {
|
|
|
105448
105900
|
] })
|
|
105449
105901
|
] });
|
|
105450
105902
|
}
|
|
105903
|
+
const TRACE_PII_DISPLAY_USER_MESSAGE_KEY = "piiDisplayUserMessage";
|
|
105904
|
+
const TRACE_PII_DISPLAY_APP_RESPONSE_KEY = "piiDisplayAppResponse";
|
|
105451
105905
|
class TraceTreeService {
|
|
105452
105906
|
/**
|
|
105453
105907
|
* Build a hierarchical tree from a flat list of observations
|
|
@@ -105620,43 +106074,205 @@ class TraceTreeService {
|
|
|
105620
106074
|
});
|
|
105621
106075
|
}
|
|
105622
106076
|
/**
|
|
105623
|
-
* Extract user message from trace input
|
|
106077
|
+
* Extract user message from trace input for display.
|
|
106078
|
+
* Handles string, object with message/content/text/query, and messages array (e.g. voice/chat).
|
|
106079
|
+
*/
|
|
106080
|
+
/**
|
|
106081
|
+
* Parse trace metadata from API (string or object) into a plain object.
|
|
106082
|
+
*/
|
|
106083
|
+
static parseTraceMetadata(metadata) {
|
|
106084
|
+
if (metadata === null || metadata === void 0) {
|
|
106085
|
+
return {};
|
|
106086
|
+
}
|
|
106087
|
+
if (typeof metadata === "string") {
|
|
106088
|
+
try {
|
|
106089
|
+
return JSON.parse(metadata);
|
|
106090
|
+
} catch {
|
|
106091
|
+
return {};
|
|
106092
|
+
}
|
|
106093
|
+
}
|
|
106094
|
+
if (typeof metadata === "object" && !Array.isArray(metadata)) {
|
|
106095
|
+
return metadata;
|
|
106096
|
+
}
|
|
106097
|
+
return {};
|
|
106098
|
+
}
|
|
106099
|
+
/**
|
|
106100
|
+
* Read PII display strings from Langfuse/Kore trace metadata (if present).
|
|
105624
106101
|
*/
|
|
106102
|
+
static extractPiiDisplayFromTraceMetadata(metadata) {
|
|
106103
|
+
const obj = this.parseTraceMetadata(metadata);
|
|
106104
|
+
const userRaw = obj[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
|
|
106105
|
+
const appRaw = obj[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
|
|
106106
|
+
const result = {};
|
|
106107
|
+
if (typeof userRaw === "string" && userRaw.length > 0) {
|
|
106108
|
+
result.displayUserMessage = userRaw;
|
|
106109
|
+
}
|
|
106110
|
+
if (typeof appRaw === "string" && appRaw.length > 0) {
|
|
106111
|
+
result.displayAppResponse = appRaw;
|
|
106112
|
+
}
|
|
106113
|
+
return result;
|
|
106114
|
+
}
|
|
106115
|
+
/**
|
|
106116
|
+
* Some tracing APIs expose custom PII display keys on trace root as well as under metadata.
|
|
106117
|
+
*/
|
|
106118
|
+
static extractPiiDisplayFromApiTrace(trace) {
|
|
106119
|
+
const fromMeta = this.extractPiiDisplayFromTraceMetadata(trace.metadata);
|
|
106120
|
+
const userTop = trace[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
|
|
106121
|
+
const appTop = trace[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
|
|
106122
|
+
const fromTop = {};
|
|
106123
|
+
if (typeof userTop === "string" && userTop.length > 0) {
|
|
106124
|
+
fromTop.displayUserMessage = userTop;
|
|
106125
|
+
}
|
|
106126
|
+
if (typeof appTop === "string" && appTop.length > 0) {
|
|
106127
|
+
fromTop.displayAppResponse = appTop;
|
|
106128
|
+
}
|
|
106129
|
+
return {
|
|
106130
|
+
displayUserMessage: fromTop.displayUserMessage ?? fromMeta.displayUserMessage,
|
|
106131
|
+
displayAppResponse: fromTop.displayAppResponse ?? fromMeta.displayAppResponse
|
|
106132
|
+
};
|
|
106133
|
+
}
|
|
105625
106134
|
static extractUserMessage(input) {
|
|
105626
106135
|
if (!input) return "";
|
|
105627
106136
|
if (typeof input === "string") {
|
|
105628
106137
|
try {
|
|
105629
106138
|
const parsed = JSON.parse(input);
|
|
105630
|
-
|
|
106139
|
+
const fromParsed = (parsed == null ? void 0 : parsed.message) ?? (parsed == null ? void 0 : parsed.content) ?? (parsed == null ? void 0 : parsed.text) ?? (parsed == null ? void 0 : parsed.query);
|
|
106140
|
+
if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
|
|
106141
|
+
if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
|
|
106142
|
+
return this.extractLastUserMessageFromArray(parsed.messages);
|
|
106143
|
+
}
|
|
106144
|
+
return input;
|
|
105631
106145
|
} catch {
|
|
105632
106146
|
return input;
|
|
105633
106147
|
}
|
|
105634
106148
|
}
|
|
105635
106149
|
if (typeof input === "object") {
|
|
105636
106150
|
const obj = input;
|
|
105637
|
-
|
|
106151
|
+
const direct = (obj == null ? void 0 : obj["message"]) ?? (obj == null ? void 0 : obj["content"]) ?? (obj == null ? void 0 : obj["text"]) ?? (obj == null ? void 0 : obj["query"]);
|
|
106152
|
+
if (direct !== void 0 && direct !== null && direct !== "") {
|
|
106153
|
+
return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
|
|
106154
|
+
}
|
|
106155
|
+
if (Array.isArray(obj == null ? void 0 : obj.messages)) {
|
|
106156
|
+
return this.extractLastUserMessageFromArray(obj.messages);
|
|
106157
|
+
}
|
|
106158
|
+
if (Array.isArray(input)) {
|
|
106159
|
+
return this.extractLastUserMessageFromArray(input);
|
|
106160
|
+
}
|
|
106161
|
+
return JSON.stringify(obj);
|
|
105638
106162
|
}
|
|
105639
106163
|
return String(input);
|
|
105640
106164
|
}
|
|
105641
106165
|
/**
|
|
105642
|
-
*
|
|
106166
|
+
* LangChain-serialized messages store role/content under `kwargs` and type in `id`.
|
|
106167
|
+
*/
|
|
106168
|
+
static getLangchainMessageContent(msg) {
|
|
106169
|
+
if (msg["content"] !== void 0 && msg["content"] !== null) {
|
|
106170
|
+
return msg["content"];
|
|
106171
|
+
}
|
|
106172
|
+
const kwargs = msg["kwargs"];
|
|
106173
|
+
if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
|
|
106174
|
+
const c3 = kwargs["content"];
|
|
106175
|
+
if (c3 !== void 0 && c3 !== null) {
|
|
106176
|
+
return c3;
|
|
106177
|
+
}
|
|
106178
|
+
}
|
|
106179
|
+
return void 0;
|
|
106180
|
+
}
|
|
106181
|
+
static inferLangchainMessageRole(msg) {
|
|
106182
|
+
if (typeof msg["role"] === "string") {
|
|
106183
|
+
return msg["role"];
|
|
106184
|
+
}
|
|
106185
|
+
const kwargs = msg["kwargs"];
|
|
106186
|
+
if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
|
|
106187
|
+
const r2 = kwargs["role"];
|
|
106188
|
+
if (typeof r2 === "string") {
|
|
106189
|
+
return r2;
|
|
106190
|
+
}
|
|
106191
|
+
}
|
|
106192
|
+
const id = msg["id"];
|
|
106193
|
+
if (Array.isArray(id)) {
|
|
106194
|
+
const tail = id[id.length - 1];
|
|
106195
|
+
if (tail === "HumanMessage") {
|
|
106196
|
+
return "user";
|
|
106197
|
+
}
|
|
106198
|
+
if (tail === "AIMessage" || tail === "AIMessageChunk") {
|
|
106199
|
+
return "assistant";
|
|
106200
|
+
}
|
|
106201
|
+
if (tail === "SystemMessage") {
|
|
106202
|
+
return "system";
|
|
106203
|
+
}
|
|
106204
|
+
if (tail === "ToolMessage") {
|
|
106205
|
+
return "tool";
|
|
106206
|
+
}
|
|
106207
|
+
}
|
|
106208
|
+
return void 0;
|
|
106209
|
+
}
|
|
106210
|
+
/**
|
|
106211
|
+
* Get last user message content from a messages array (chat/voice format).
|
|
106212
|
+
*/
|
|
106213
|
+
static extractLastUserMessageFromArray(messages) {
|
|
106214
|
+
if (!messages.length) return "";
|
|
106215
|
+
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
106216
|
+
const msg = messages[i2];
|
|
106217
|
+
const role = this.inferLangchainMessageRole(msg);
|
|
106218
|
+
const content2 = this.getLangchainMessageContent(msg);
|
|
106219
|
+
if (role === "user" && content2 != null) {
|
|
106220
|
+
return typeof content2 === "string" ? content2 : JSON.stringify(content2);
|
|
106221
|
+
}
|
|
106222
|
+
}
|
|
106223
|
+
const last2 = messages[messages.length - 1];
|
|
106224
|
+
const content = this.getLangchainMessageContent(last2);
|
|
106225
|
+
if (content != null) {
|
|
106226
|
+
return typeof content === "string" ? content : JSON.stringify(content);
|
|
106227
|
+
}
|
|
106228
|
+
return JSON.stringify(messages[messages.length - 1]);
|
|
106229
|
+
}
|
|
106230
|
+
/**
|
|
106231
|
+
* Extract app response from trace output for display.
|
|
106232
|
+
* Handles string, object with message/content/text/response, and messages array.
|
|
105643
106233
|
*/
|
|
105644
106234
|
static extractAppResponse(output) {
|
|
105645
106235
|
if (!output) return "";
|
|
105646
106236
|
if (typeof output === "string") {
|
|
105647
106237
|
try {
|
|
105648
106238
|
const parsed = JSON.parse(output);
|
|
105649
|
-
|
|
106239
|
+
const fromParsed = (parsed == null ? void 0 : parsed.message) ?? (parsed == null ? void 0 : parsed.content) ?? (parsed == null ? void 0 : parsed.text) ?? (parsed == null ? void 0 : parsed.response);
|
|
106240
|
+
if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
|
|
106241
|
+
if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
|
|
106242
|
+
return this.extractLastMessageContentFromArray(parsed.messages);
|
|
106243
|
+
}
|
|
106244
|
+
return output;
|
|
105650
106245
|
} catch {
|
|
105651
106246
|
return output;
|
|
105652
106247
|
}
|
|
105653
106248
|
}
|
|
105654
106249
|
if (typeof output === "object") {
|
|
105655
106250
|
const obj = output;
|
|
105656
|
-
|
|
106251
|
+
const direct = (obj == null ? void 0 : obj["message"]) ?? (obj == null ? void 0 : obj["content"]) ?? (obj == null ? void 0 : obj["text"]) ?? (obj == null ? void 0 : obj["response"]);
|
|
106252
|
+
if (direct !== void 0 && direct !== null && direct !== "") {
|
|
106253
|
+
return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
|
|
106254
|
+
}
|
|
106255
|
+
if (Array.isArray(obj == null ? void 0 : obj.messages)) {
|
|
106256
|
+
return this.extractLastMessageContentFromArray(obj.messages);
|
|
106257
|
+
}
|
|
106258
|
+
if (Array.isArray(output)) {
|
|
106259
|
+
return this.extractLastMessageContentFromArray(output);
|
|
106260
|
+
}
|
|
106261
|
+
return JSON.stringify(obj);
|
|
105657
106262
|
}
|
|
105658
106263
|
return String(output);
|
|
105659
106264
|
}
|
|
106265
|
+
/**
|
|
106266
|
+
* Get last message content from a messages array for output display.
|
|
106267
|
+
*/
|
|
106268
|
+
static extractLastMessageContentFromArray(messages) {
|
|
106269
|
+
if (!messages.length) return "";
|
|
106270
|
+
const last2 = messages[messages.length - 1];
|
|
106271
|
+
const fromKwargs = this.getLangchainMessageContent(last2);
|
|
106272
|
+
const content = fromKwargs ?? (last2 == null ? void 0 : last2.message) ?? (last2 == null ? void 0 : last2.text);
|
|
106273
|
+
if (content != null) return typeof content === "string" ? content : JSON.stringify(content);
|
|
106274
|
+
return JSON.stringify(last2);
|
|
106275
|
+
}
|
|
105660
106276
|
/**
|
|
105661
106277
|
* Calculate trace metrics from observations
|
|
105662
106278
|
*/
|
|
@@ -105666,7 +106282,9 @@ class TraceTreeService {
|
|
|
105666
106282
|
let maxEndTime = 0;
|
|
105667
106283
|
let minStartTime = Infinity;
|
|
105668
106284
|
observations.forEach((obs) => {
|
|
105669
|
-
|
|
106285
|
+
var _a;
|
|
106286
|
+
const obsTokens = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
|
|
106287
|
+
totalTokens += typeof obsTokens === "number" ? obsTokens : parseInt(String(obsTokens || 0), 10) || 0;
|
|
105670
106288
|
const cost = parseFloat(obs.totalCost || "0");
|
|
105671
106289
|
if (!isNaN(cost)) totalCost += cost;
|
|
105672
106290
|
const startMs = new Date(obs.startTime).getTime();
|
|
@@ -105689,7 +106307,15 @@ class TraceTreeService {
|
|
|
105689
106307
|
);
|
|
105690
106308
|
const generation = sorted.find((obs) => obs.type === "GENERATION");
|
|
105691
106309
|
if (!generation) {
|
|
105692
|
-
|
|
106310
|
+
const tree = this.buildObservationTree(observations);
|
|
106311
|
+
if (tree.length === 0) return { observation: null, ancestorIds: [] };
|
|
106312
|
+
const findFirstLeaf = (node) => {
|
|
106313
|
+
if (node.children.length === 0) return node;
|
|
106314
|
+
return findFirstLeaf(node.children[0]);
|
|
106315
|
+
};
|
|
106316
|
+
const leafNode = findFirstLeaf(tree[0]);
|
|
106317
|
+
const ancestorIds2 = this.getAncestorIds(observations, leafNode.observation.id);
|
|
106318
|
+
return { observation: leafNode.observation, ancestorIds: ancestorIds2 };
|
|
105693
106319
|
}
|
|
105694
106320
|
const ancestorIds = this.getAncestorIds(observations, generation.id);
|
|
105695
106321
|
return { observation: generation, ancestorIds };
|
|
@@ -105836,6 +106462,7 @@ const observationFilterConfig = {
|
|
|
105836
106462
|
"toolNode",
|
|
105837
106463
|
"agent_toolNode",
|
|
105838
106464
|
"PreProcessor",
|
|
106465
|
+
"PostProcessor",
|
|
105839
106466
|
"MergerNode"
|
|
105840
106467
|
]
|
|
105841
106468
|
}
|
|
@@ -106095,6 +106722,7 @@ class DetailPageService {
|
|
|
106095
106722
|
* Transform API trace response to TraceDetailData
|
|
106096
106723
|
*/
|
|
106097
106724
|
transformToTraceDetailData(trace) {
|
|
106725
|
+
const piiDisplay = TraceTreeService.extractPiiDisplayFromApiTrace(trace);
|
|
106098
106726
|
return {
|
|
106099
106727
|
id: trace.id,
|
|
106100
106728
|
name: trace.name || "",
|
|
@@ -106107,6 +106735,8 @@ class DetailPageService {
|
|
|
106107
106735
|
input: trace.input,
|
|
106108
106736
|
output: trace.output,
|
|
106109
106737
|
metadata: trace.metadata,
|
|
106738
|
+
displayUserMessage: piiDisplay.displayUserMessage,
|
|
106739
|
+
displayAppResponse: piiDisplay.displayAppResponse,
|
|
106110
106740
|
tags: trace.tags || [],
|
|
106111
106741
|
bookmarked: trace.bookmarked || false,
|
|
106112
106742
|
public: trace.public || false,
|
|
@@ -106168,6 +106798,8 @@ class DetailPageService {
|
|
|
106168
106798
|
timestamp: trace.timestamp,
|
|
106169
106799
|
input: trace.input,
|
|
106170
106800
|
output: trace.output,
|
|
106801
|
+
displayUserMessage: trace.displayUserMessage,
|
|
106802
|
+
displayAppResponse: trace.displayAppResponse,
|
|
106171
106803
|
latency: trace.latency,
|
|
106172
106804
|
totalTokens: trace.totalTokens,
|
|
106173
106805
|
totalCost: typeof trace.totalCost === "number" ? String(trace.totalCost) : trace.totalCost,
|
|
@@ -106321,6 +106953,19 @@ function getObservationIconProps(observation) {
|
|
|
106321
106953
|
name
|
|
106322
106954
|
};
|
|
106323
106955
|
}
|
|
106956
|
+
function getObservationTokens(obs) {
|
|
106957
|
+
var _a;
|
|
106958
|
+
const total = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
|
|
106959
|
+
if (total === void 0 || total === null) return 0;
|
|
106960
|
+
return typeof total === "number" ? total : parseInt(String(total), 10) || 0;
|
|
106961
|
+
}
|
|
106962
|
+
function getAggregatedTotalTokens(node) {
|
|
106963
|
+
let sum2 = getObservationTokens(node.observation);
|
|
106964
|
+
node.children.forEach((child) => {
|
|
106965
|
+
sum2 += getAggregatedTotalTokens(child);
|
|
106966
|
+
});
|
|
106967
|
+
return sum2;
|
|
106968
|
+
}
|
|
106324
106969
|
const SuccessIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
106325
106970
|
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "6", cy: "6", r: "5.5", fill: "#17B26A" }),
|
|
106326
106971
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 6L5.5 7.5L8 4.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
@@ -106382,7 +107027,11 @@ function ObservationNode({
|
|
|
106382
107027
|
return observation.name || observation.type || "";
|
|
106383
107028
|
};
|
|
106384
107029
|
const displayName = getDisplayName3();
|
|
106385
|
-
const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total)
|
|
107030
|
+
const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total) ?? observation.totalUsage ?? observation.totalTokens;
|
|
107031
|
+
const aggregatedTotalTokens = useMemo(() => {
|
|
107032
|
+
if (!isSupervisorOrAgent) return 0;
|
|
107033
|
+
return getAggregatedTotalTokens(node);
|
|
107034
|
+
}, [node, isSupervisorOrAgent]);
|
|
106386
107035
|
const handleRowClick = () => {
|
|
106387
107036
|
if (hasChildren) {
|
|
106388
107037
|
onToggle(observation.id);
|
|
@@ -106429,34 +107078,43 @@ function ObservationNode({
|
|
|
106429
107078
|
className: "w-[24px] h-[24px] rounded-[8px]"
|
|
106430
107079
|
}
|
|
106431
107080
|
) }),
|
|
106432
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
106433
|
-
|
|
106434
|
-
isSupervisorOrAgent &&
|
|
106435
|
-
|
|
106436
|
-
|
|
107081
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[2px] flex-1 min-w-0", children: [
|
|
107082
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[12px] leading-[16px] text-[#101828] truncate", title: displayName, children: displayName }),
|
|
107083
|
+
isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[6px] flex-wrap text-[10px] leading-[12px] text-[#667085] font-normal", children: [
|
|
107084
|
+
modelFromMetadata || observation.model ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: modelFromMetadata || observation.model }) : null,
|
|
107085
|
+
aggregatedTotalTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
107086
|
+
(modelFromMetadata || observation.model) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }),
|
|
107087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap", children: [
|
|
107088
|
+
TraceTreeService.formatTokens(aggregatedTotalTokens),
|
|
107089
|
+
" Tokens"
|
|
107090
|
+
] })
|
|
107091
|
+
] }),
|
|
107092
|
+
duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
107093
|
+
modelFromMetadata || observation.model || aggregatedTotalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }) : null,
|
|
107094
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap flex items-center gap-[4px]", children: [
|
|
107095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
|
|
107096
|
+
TraceTreeService.formatDuration(duration)
|
|
107097
|
+
] })
|
|
107098
|
+
] })
|
|
107099
|
+
] })
|
|
107100
|
+
] }),
|
|
107101
|
+
!isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] flex-shrink-0", children: [
|
|
107102
|
+
isGeneration && displayTokens !== void 0 && Number(displayTokens) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: [
|
|
107103
|
+
TraceTreeService.formatTokens(Number(displayTokens)),
|
|
106437
107104
|
" Tokens"
|
|
106438
107105
|
] }),
|
|
106439
107106
|
duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
106440
107107
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
|
|
106441
107108
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: TraceTreeService.formatDuration(duration) })
|
|
106442
107109
|
] }),
|
|
106443
|
-
isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106444
|
-
|
|
106445
|
-
{
|
|
106446
|
-
className: "flex-shrink-0 cursor-help",
|
|
106447
|
-
title: statusTooltip,
|
|
106448
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {})
|
|
106449
|
-
}
|
|
106450
|
-
),
|
|
106451
|
-
isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106452
|
-
"div",
|
|
106453
|
-
{
|
|
106454
|
-
className: "flex-shrink-0 cursor-help",
|
|
106455
|
-
title: statusTooltip,
|
|
106456
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {})
|
|
106457
|
-
}
|
|
106458
|
-
),
|
|
107110
|
+
isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
|
|
107111
|
+
isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
|
|
106459
107112
|
isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
|
|
107113
|
+
] }),
|
|
107114
|
+
isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-shrink-0 flex items-center", children: [
|
|
107115
|
+
isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
|
|
107116
|
+
isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
|
|
107117
|
+
isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
|
|
106460
107118
|
] })
|
|
106461
107119
|
]
|
|
106462
107120
|
}
|
|
@@ -106494,8 +107152,10 @@ function TraceTree({
|
|
|
106494
107152
|
onNodeSelect,
|
|
106495
107153
|
onExpandToggle,
|
|
106496
107154
|
showTraceId = true,
|
|
107155
|
+
onTraceIdClick,
|
|
106497
107156
|
isLoading = false,
|
|
106498
|
-
defaultExpandedNodeIds
|
|
107157
|
+
defaultExpandedNodeIds,
|
|
107158
|
+
runHeaderInputMode = "display"
|
|
106499
107159
|
}) {
|
|
106500
107160
|
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
106501
107161
|
const [expandedNodeIds, setExpandedNodeIds] = useState(
|
|
@@ -106513,11 +107173,20 @@ function TraceTree({
|
|
|
106513
107173
|
return TraceTreeService.buildObservationTree(observations);
|
|
106514
107174
|
}, [observations]);
|
|
106515
107175
|
const userMessage = useMemo(() => {
|
|
107176
|
+
if (runHeaderInputMode !== "tokenized" && trace.displayUserMessage !== void 0 && trace.displayUserMessage.length > 0) {
|
|
107177
|
+
return trace.displayUserMessage;
|
|
107178
|
+
}
|
|
106516
107179
|
return TraceTreeService.extractUserMessage(trace.input);
|
|
106517
|
-
}, [trace.input]);
|
|
107180
|
+
}, [trace.input, trace.displayUserMessage, runHeaderInputMode]);
|
|
106518
107181
|
const appResponse = useMemo(() => {
|
|
107182
|
+
if (runHeaderInputMode !== "tokenized" && trace.displayAppResponse !== void 0 && trace.displayAppResponse.length > 0) {
|
|
107183
|
+
return trace.displayAppResponse;
|
|
107184
|
+
}
|
|
106519
107185
|
return TraceTreeService.extractAppResponse(trace.output);
|
|
106520
|
-
}, [trace.output]);
|
|
107186
|
+
}, [trace.output, trace.displayAppResponse, runHeaderInputMode]);
|
|
107187
|
+
const traceMetrics = useMemo(() => {
|
|
107188
|
+
return TraceTreeService.calculateTraceMetrics(trace, observations);
|
|
107189
|
+
}, [trace, observations]);
|
|
106521
107190
|
const handleTraceToggle = useCallback(() => {
|
|
106522
107191
|
setIsExpanded((prev) => !prev);
|
|
106523
107192
|
onExpandToggle == null ? void 0 : onExpandToggle();
|
|
@@ -106544,7 +107213,16 @@ function TraceTree({
|
|
|
106544
107213
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[4px] w-full mb-[8px]", children: [
|
|
106545
107214
|
showTraceId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center px-0 py-[4px] w-full", children: [
|
|
106546
107215
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#98A2B3]", children: "Trace ID" }),
|
|
106547
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107216
|
+
onTraceIdClick ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107217
|
+
"button",
|
|
107218
|
+
{
|
|
107219
|
+
onClick: () => onTraceIdClick(trace.id),
|
|
107220
|
+
className: "font-medium text-[10px] leading-[12px] text-[#155EEF] hover:underline cursor-pointer bg-transparent border-none p-0",
|
|
107221
|
+
title: "View Trace Details",
|
|
107222
|
+
"data-test-id": `trace-tree-id-link-${trace.id}`,
|
|
107223
|
+
children: trace.id
|
|
107224
|
+
}
|
|
107225
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
|
|
106548
107226
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106549
107227
|
"button",
|
|
106550
107228
|
{
|
|
@@ -106619,10 +107297,18 @@ function TraceTree({
|
|
|
106619
107297
|
rootNode.observation.id
|
|
106620
107298
|
)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[16px] text-[12px] text-[#667085] text-center", children: "No observations available" }) }),
|
|
106621
107299
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white flex flex-col gap-[8px] p-[12px] border-t border-[#EAECF0]", children: [
|
|
106622
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
106623
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
106624
|
-
|
|
106625
|
-
|
|
107300
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center w-full", children: [
|
|
107301
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center flex-1 min-w-0", children: [
|
|
107302
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AppResponseIcon, {}),
|
|
107303
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.02em]", children: "APP RESPONSE" })
|
|
107304
|
+
] }),
|
|
107305
|
+
(traceMetrics.latency > 0 || traceMetrics.totalTokens > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap flex-shrink-0", children: [
|
|
107306
|
+
TraceTreeService.formatDuration(traceMetrics.latency),
|
|
107307
|
+
" · ",
|
|
107308
|
+
TraceTreeService.formatTokens(traceMetrics.totalTokens),
|
|
107309
|
+
" Tokens"
|
|
107310
|
+
] })
|
|
107311
|
+
] }),
|
|
106626
107312
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium text-[12px] leading-[16px] text-[#101828]", children: appResponse ? appResponse.length > 150 && !isResponseExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
106627
107313
|
appResponse.substring(0, 150),
|
|
106628
107314
|
"...",
|
|
@@ -106655,114 +107341,6 @@ function TraceTree({
|
|
|
106655
107341
|
] })
|
|
106656
107342
|
] });
|
|
106657
107343
|
}
|
|
106658
|
-
const CopyButton$1 = ({
|
|
106659
|
-
text,
|
|
106660
|
-
className = "",
|
|
106661
|
-
iconClassName = "",
|
|
106662
|
-
iconStyle,
|
|
106663
|
-
title = "Copy to clipboard",
|
|
106664
|
-
onCopySuccess,
|
|
106665
|
-
onCopyError,
|
|
106666
|
-
tooltipText = "Copied!",
|
|
106667
|
-
tooltipPosition = "bottom",
|
|
106668
|
-
size = "md"
|
|
106669
|
-
}) => {
|
|
106670
|
-
const [showTooltip, setShowTooltip] = useState(false);
|
|
106671
|
-
const getSizeClasses = () => {
|
|
106672
|
-
switch (size) {
|
|
106673
|
-
case "sm":
|
|
106674
|
-
return {
|
|
106675
|
-
button: "p-1",
|
|
106676
|
-
icon: "w-[12px] h-[12px]",
|
|
106677
|
-
tooltip: "text-xs py-1 px-2"
|
|
106678
|
-
};
|
|
106679
|
-
case "lg":
|
|
106680
|
-
return {
|
|
106681
|
-
button: "p-2",
|
|
106682
|
-
icon: "w-[20px] h-[20px]",
|
|
106683
|
-
tooltip: "text-sm py-2 px-3"
|
|
106684
|
-
};
|
|
106685
|
-
default:
|
|
106686
|
-
return {
|
|
106687
|
-
button: "p-1.5",
|
|
106688
|
-
icon: "w-[16px] h-[16px]",
|
|
106689
|
-
tooltip: "text-xs py-1 px-2"
|
|
106690
|
-
};
|
|
106691
|
-
}
|
|
106692
|
-
};
|
|
106693
|
-
const getTooltipPositionClasses = () => {
|
|
106694
|
-
const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
|
|
106695
|
-
switch (tooltipPosition) {
|
|
106696
|
-
case "bottom":
|
|
106697
|
-
return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
|
|
106698
|
-
case "left":
|
|
106699
|
-
return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
|
|
106700
|
-
case "right":
|
|
106701
|
-
return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
|
|
106702
|
-
default:
|
|
106703
|
-
return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
|
|
106704
|
-
}
|
|
106705
|
-
};
|
|
106706
|
-
const sizeClasses2 = getSizeClasses();
|
|
106707
|
-
const showCopyTooltip = useCallback(() => {
|
|
106708
|
-
setShowTooltip(true);
|
|
106709
|
-
setTimeout(() => setShowTooltip(false), 1e3);
|
|
106710
|
-
}, []);
|
|
106711
|
-
const copyToClipboard2 = useCallback(async () => {
|
|
106712
|
-
try {
|
|
106713
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
106714
|
-
await navigator.clipboard.writeText(text);
|
|
106715
|
-
showCopyTooltip();
|
|
106716
|
-
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
106717
|
-
return;
|
|
106718
|
-
}
|
|
106719
|
-
const textArea = document.createElement("textarea");
|
|
106720
|
-
textArea.value = text;
|
|
106721
|
-
textArea.style.position = "fixed";
|
|
106722
|
-
textArea.style.left = "-999999px";
|
|
106723
|
-
textArea.style.top = "-999999px";
|
|
106724
|
-
document.body.appendChild(textArea);
|
|
106725
|
-
textArea.focus();
|
|
106726
|
-
textArea.select();
|
|
106727
|
-
try {
|
|
106728
|
-
document.execCommand("copy");
|
|
106729
|
-
showCopyTooltip();
|
|
106730
|
-
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
106731
|
-
} catch (err) {
|
|
106732
|
-
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
106733
|
-
console.warn("Copy to clipboard failed:", error);
|
|
106734
|
-
onCopyError == null ? void 0 : onCopyError(error);
|
|
106735
|
-
} finally {
|
|
106736
|
-
document.body.removeChild(textArea);
|
|
106737
|
-
}
|
|
106738
|
-
} catch (err) {
|
|
106739
|
-
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
106740
|
-
console.warn("Copy to clipboard failed:", error);
|
|
106741
|
-
onCopyError == null ? void 0 : onCopyError(error);
|
|
106742
|
-
}
|
|
106743
|
-
}, [text, showCopyTooltip, onCopySuccess, onCopyError]);
|
|
106744
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
|
|
106745
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106746
|
-
"button",
|
|
106747
|
-
{
|
|
106748
|
-
onClick: copyToClipboard2,
|
|
106749
|
-
className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
|
|
106750
|
-
title,
|
|
106751
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
|
|
106752
|
-
}
|
|
106753
|
-
),
|
|
106754
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106755
|
-
"div",
|
|
106756
|
-
{
|
|
106757
|
-
className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
|
|
106758
|
-
style: {
|
|
106759
|
-
visibility: showTooltip ? "visible" : "hidden"
|
|
106760
|
-
},
|
|
106761
|
-
children: tooltipText
|
|
106762
|
-
}
|
|
106763
|
-
)
|
|
106764
|
-
] });
|
|
106765
|
-
};
|
|
106766
107344
|
function __awaiter(thisArg, _arguments, P2, generator) {
|
|
106767
107345
|
function adopt(value) {
|
|
106768
107346
|
return value instanceof P2 ? value : new P2(function(resolve) {
|
|
@@ -107927,21 +108505,35 @@ const DataModal = ({
|
|
|
107927
108505
|
)
|
|
107928
108506
|
] })
|
|
107929
108507
|
] }),
|
|
107930
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107931
|
-
|
|
108508
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
108509
|
+
"div",
|
|
107932
108510
|
{
|
|
107933
|
-
|
|
107934
|
-
|
|
107935
|
-
|
|
107936
|
-
|
|
107937
|
-
|
|
107938
|
-
|
|
107939
|
-
|
|
107940
|
-
|
|
107941
|
-
|
|
107942
|
-
|
|
108511
|
+
className: "flex-1 overflow-auto bg-gray-800 p-4",
|
|
108512
|
+
style: {
|
|
108513
|
+
"--json-property": "#ffffff",
|
|
108514
|
+
"--json-index": "#e2e8f0",
|
|
108515
|
+
"--json-number": "#e2e8f0",
|
|
108516
|
+
"--json-string": "#e2e8f0",
|
|
108517
|
+
"--json-boolean": "#e2e8f0",
|
|
108518
|
+
"--json-null": "#e2e8f0"
|
|
108519
|
+
},
|
|
108520
|
+
children: viewMode === "interactive" && useEnhancedJsonView ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
108521
|
+
JsonView,
|
|
108522
|
+
{
|
|
108523
|
+
src: parsedData,
|
|
108524
|
+
dark: true,
|
|
108525
|
+
collapseObjectsAfterLength: 20,
|
|
108526
|
+
collapseStringsAfterLength: 500,
|
|
108527
|
+
collapseStringMode: "word",
|
|
108528
|
+
displaySize: "collapsed",
|
|
108529
|
+
matchesURL: true,
|
|
108530
|
+
customizeCopy: (node) => stringifyJsonNode(node),
|
|
108531
|
+
className: "w-full text-xs",
|
|
108532
|
+
style: { color: "#f1f5f9" }
|
|
108533
|
+
}
|
|
108534
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs whitespace-pre text-white font-mono", children: stringifyJsonNode(parsedData) })
|
|
107943
108535
|
}
|
|
107944
|
-
)
|
|
108536
|
+
)
|
|
107945
108537
|
] }) });
|
|
107946
108538
|
};
|
|
107947
108539
|
const JsonViewer = ({
|
|
@@ -108309,6 +108901,23 @@ function formatUnknownValue(value) {
|
|
|
108309
108901
|
function isObservation(node) {
|
|
108310
108902
|
return node !== null && "traceId" in node && "type" in node;
|
|
108311
108903
|
}
|
|
108904
|
+
function metadataForDisplay(metadata) {
|
|
108905
|
+
if (metadata === null || metadata === void 0) return {};
|
|
108906
|
+
let obj;
|
|
108907
|
+
if (typeof metadata === "string") {
|
|
108908
|
+
try {
|
|
108909
|
+
obj = JSON.parse(metadata);
|
|
108910
|
+
} catch {
|
|
108911
|
+
return {};
|
|
108912
|
+
}
|
|
108913
|
+
} else if (typeof metadata === "object") {
|
|
108914
|
+
obj = metadata;
|
|
108915
|
+
} else {
|
|
108916
|
+
return {};
|
|
108917
|
+
}
|
|
108918
|
+
const { tools: _tools, ...rest } = obj;
|
|
108919
|
+
return rest;
|
|
108920
|
+
}
|
|
108312
108921
|
const defaultMetrics = {
|
|
108313
108922
|
totalCost: "0",
|
|
108314
108923
|
totalTokens: 0,
|
|
@@ -108357,7 +108966,7 @@ function SectionHeader({ title }) {
|
|
|
108357
108966
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-[1px] bg-[#EAECF0]" })
|
|
108358
108967
|
] });
|
|
108359
108968
|
}
|
|
108360
|
-
function PreviewContent({ input, output, metadata, statusMessage, isLoading = false
|
|
108969
|
+
function PreviewContent({ input, output, metadata, statusMessage, isLoading = false }) {
|
|
108361
108970
|
const [showAllMetadata, setShowAllMetadata] = useState(false);
|
|
108362
108971
|
const messages = useMemo(() => {
|
|
108363
108972
|
if (!input || typeof input !== "object") return null;
|
|
@@ -108389,15 +108998,6 @@ function PreviewContent({ input, output, metadata, statusMessage, isLoading = fa
|
|
|
108389
108998
|
}
|
|
108390
108999
|
return String(output);
|
|
108391
109000
|
}, [output]);
|
|
108392
|
-
const modelName = useMemo(() => {
|
|
108393
|
-
if (!input || typeof input !== "object") return null;
|
|
108394
|
-
return input["model"] ?? null;
|
|
108395
|
-
}, [input]);
|
|
108396
|
-
const formatParamValue = (value) => {
|
|
108397
|
-
if (value === null || value === void 0) return "";
|
|
108398
|
-
if (typeof value === "object") return JSON.stringify(value);
|
|
108399
|
-
return String(value);
|
|
108400
|
-
};
|
|
108401
109001
|
if (isLoading) {
|
|
108402
109002
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[16px] p-[16px] overflow-y-auto h-full", children: [
|
|
108403
109003
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
@@ -108411,29 +109011,6 @@ function PreviewContent({ input, output, metadata, statusMessage, isLoading = fa
|
|
|
108411
109011
|
] });
|
|
108412
109012
|
}
|
|
108413
109013
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[20px] p-[16px] overflow-y-auto h-full", children: [
|
|
108414
|
-
(modelName || modelParameters && Object.keys(modelParameters).length > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
|
|
108415
|
-
modelName && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-[8px] py-[4px] bg-[#F2F4F7] rounded-[4px] text-[11px] font-medium text-[#344054]", children: [
|
|
108416
|
-
"Model: ",
|
|
108417
|
-
modelName
|
|
108418
|
-
] }),
|
|
108419
|
-
modelParameters && typeof modelParameters === "object" && Object.entries(modelParameters).filter(([_2, value]) => value !== null && value !== void 0).map(([key, value]) => {
|
|
108420
|
-
const valueString = formatParamValue(value);
|
|
108421
|
-
const displayKey = key.replace(/_/g, " ");
|
|
108422
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
108423
|
-
"span",
|
|
108424
|
-
{
|
|
108425
|
-
className: "px-[8px] py-[4px] bg-[#F2F4F7] border border-[#EAECF0] rounded-[4px] text-[11px] font-medium text-[#344054] max-w-[200px] truncate",
|
|
108426
|
-
title: `${key}: ${valueString}`,
|
|
108427
|
-
children: [
|
|
108428
|
-
displayKey,
|
|
108429
|
-
": ",
|
|
108430
|
-
valueString
|
|
108431
|
-
]
|
|
108432
|
-
},
|
|
108433
|
-
key
|
|
108434
|
-
);
|
|
108435
|
-
})
|
|
108436
|
-
] }),
|
|
108437
109014
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
108438
109015
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { title: "Input" }),
|
|
108439
109016
|
messages ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-[8px]", children: messages.map((msg, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -108520,14 +109097,21 @@ function CodeEditorSection({
|
|
|
108520
109097
|
showHeader: true,
|
|
108521
109098
|
useEnhancedJsonView: true,
|
|
108522
109099
|
collapseStringsAfterLength: 500,
|
|
108523
|
-
collapseObjectsAfterLength: 20,
|
|
109100
|
+
collapseObjectsAfterLength: selectedTab === "metadata" ? 100 : 20,
|
|
109101
|
+
defaultExpanded: selectedTab === "metadata",
|
|
108524
109102
|
maxHeight: "100%",
|
|
108525
109103
|
className: "h-full border-0 rounded-none"
|
|
108526
|
-
}
|
|
109104
|
+
},
|
|
109105
|
+
selectedTab
|
|
108527
109106
|
) })
|
|
108528
109107
|
] });
|
|
108529
109108
|
}
|
|
108530
|
-
function NodeDetailPanel({
|
|
109109
|
+
function NodeDetailPanel({
|
|
109110
|
+
node,
|
|
109111
|
+
nodeType: _nodeType,
|
|
109112
|
+
apiConfig,
|
|
109113
|
+
generationSummaryInputOverride = null
|
|
109114
|
+
}) {
|
|
108531
109115
|
const [selectedTab, setSelectedTab] = useState("preview");
|
|
108532
109116
|
const [showTokenTooltip, setShowTokenTooltip] = useState(false);
|
|
108533
109117
|
const tooltipTimeoutRef = useRef(null);
|
|
@@ -108614,6 +109198,7 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108614
109198
|
}
|
|
108615
109199
|
return TraceTreeService.extractUserMessage(displayNode.input);
|
|
108616
109200
|
}, [displayNode]);
|
|
109201
|
+
const summaryInputLine = generationSummaryInputOverride !== null && generationSummaryInputOverride.length > 0 ? generationSummaryInputOverride : inputText;
|
|
108617
109202
|
const isGeneration = useMemo(() => {
|
|
108618
109203
|
return node !== null && isObservation(node) && node.type === "GENERATION";
|
|
108619
109204
|
}, [node]);
|
|
@@ -108697,7 +109282,7 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108697
109282
|
case "response":
|
|
108698
109283
|
return displayNode.output || {};
|
|
108699
109284
|
case "metadata":
|
|
108700
|
-
return isObservation(displayNode) ? displayNode.metadata || {} : {};
|
|
109285
|
+
return isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {};
|
|
108701
109286
|
case "logs":
|
|
108702
109287
|
return {
|
|
108703
109288
|
id: isObservation(displayNode) ? displayNode.id : displayNode.id,
|
|
@@ -108717,11 +109302,17 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108717
109302
|
return {
|
|
108718
109303
|
input: formattedInput,
|
|
108719
109304
|
output: displayNode.output || {},
|
|
108720
|
-
metadata: isObservation(displayNode) ? displayNode.metadata || {} : {},
|
|
109305
|
+
metadata: isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {},
|
|
108721
109306
|
statusMessage: isObservation(displayNode) ? displayNode.statusMessage : void 0,
|
|
108722
109307
|
modelParameters: isObservation(displayNode) ? displayNode.modelParameters : void 0
|
|
108723
109308
|
};
|
|
108724
109309
|
}, [displayNode, formattedInput]);
|
|
109310
|
+
const summaryModelInfo = useMemo(() => {
|
|
109311
|
+
if (!isGeneration || !displayNode) return { modelName: null, modelParameters: {} };
|
|
109312
|
+
const modelName = typeof formattedInput === "object" && formattedInput !== null && "model" in formattedInput ? formattedInput.model ?? null : null;
|
|
109313
|
+
const modelParameters = isObservation(displayNode) && displayNode.modelParameters && typeof displayNode.modelParameters === "object" ? displayNode.modelParameters : {};
|
|
109314
|
+
return { modelName, modelParameters };
|
|
109315
|
+
}, [isGeneration, displayNode, formattedInput]);
|
|
108725
109316
|
const tokenTooltipContent = metrics.totalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
108726
109317
|
"div",
|
|
108727
109318
|
{
|
|
@@ -108814,10 +109405,10 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108814
109405
|
] })
|
|
108815
109406
|
),
|
|
108816
109407
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {}),
|
|
108817
|
-
isGeneration &&
|
|
109408
|
+
isGeneration && summaryInputLine.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
108818
109409
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
|
|
108819
109410
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[16px] text-[#98A2B3]", children: "Input" }),
|
|
108820
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[12px] font-medium leading-[16px] text-[#101828] truncate", children:
|
|
109411
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[12px] font-medium leading-[16px] text-[#101828] truncate", children: summaryInputLine })
|
|
108821
109412
|
] }),
|
|
108822
109413
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
108823
109414
|
] }),
|
|
@@ -108833,6 +109424,37 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108833
109424
|
] })
|
|
108834
109425
|
] }),
|
|
108835
109426
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
109427
|
+
] }),
|
|
109428
|
+
isGeneration && (summaryModelInfo.modelName || Object.keys(summaryModelInfo.modelParameters).length > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
109429
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
|
|
109430
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[16px] text-[#98A2B3]", children: "Model parameters" }),
|
|
109431
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
|
|
109432
|
+
summaryModelInfo.modelName && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-[8px] py-[4px] bg-[#F2F4F7] rounded-[4px] text-[11px] font-medium text-[#344054]", children: [
|
|
109433
|
+
"Model: ",
|
|
109434
|
+
summaryModelInfo.modelName
|
|
109435
|
+
] }),
|
|
109436
|
+
Object.entries(summaryModelInfo.modelParameters).filter(
|
|
109437
|
+
([_2, value]) => value !== null && value !== void 0
|
|
109438
|
+
).map(([key, value]) => {
|
|
109439
|
+
const valueStr = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
109440
|
+
const displayKey = key.replace(/_/g, " ");
|
|
109441
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
109442
|
+
"span",
|
|
109443
|
+
{
|
|
109444
|
+
className: "px-[8px] py-[4px] bg-[#F2F4F7] border border-[#EAECF0] rounded-[4px] text-[11px] font-medium text-[#344054] max-w-[200px] truncate",
|
|
109445
|
+
title: `${key}: ${valueStr}`,
|
|
109446
|
+
children: [
|
|
109447
|
+
displayKey,
|
|
109448
|
+
": ",
|
|
109449
|
+
valueStr
|
|
109450
|
+
]
|
|
109451
|
+
},
|
|
109452
|
+
key
|
|
109453
|
+
);
|
|
109454
|
+
})
|
|
109455
|
+
] })
|
|
109456
|
+
] }),
|
|
109457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
108836
109458
|
] })
|
|
108837
109459
|
] })
|
|
108838
109460
|
] }),
|
|
@@ -108860,7 +109482,8 @@ function DetailPage({
|
|
|
108860
109482
|
selectedObservationId,
|
|
108861
109483
|
batchSize = DEFAULT_BATCH_SIZE,
|
|
108862
109484
|
initialTraceCount,
|
|
108863
|
-
initialSessionData
|
|
109485
|
+
initialSessionData,
|
|
109486
|
+
runHeaderInputMode = "display"
|
|
108864
109487
|
}) {
|
|
108865
109488
|
const [currentMode, setCurrentMode] = useState(initialMode);
|
|
108866
109489
|
const [currentSessionId, setCurrentSessionId] = useState(initialSessionId);
|
|
@@ -109101,12 +109724,52 @@ function DetailPage({
|
|
|
109101
109724
|
}, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
|
|
109102
109725
|
const traces = useMemo(() => {
|
|
109103
109726
|
if (mode === "session" && sessionData) {
|
|
109104
|
-
|
|
109727
|
+
const sorted = [...sessionData.traces].sort((a4, b2) => {
|
|
109728
|
+
const tA = a4.timestamp ? new Date(a4.timestamp).getTime() : 0;
|
|
109729
|
+
const tB = b2.timestamp ? new Date(b2.timestamp).getTime() : 0;
|
|
109730
|
+
return tA - tB;
|
|
109731
|
+
});
|
|
109732
|
+
return sorted.map((t2) => service.transformToTraceData(t2));
|
|
109105
109733
|
} else if (mode === "trace" && traceData) {
|
|
109106
109734
|
return [service.transformToTraceData(traceData)];
|
|
109107
109735
|
}
|
|
109108
109736
|
return [];
|
|
109109
109737
|
}, [mode, sessionData, traceData, service]);
|
|
109738
|
+
const generationSummaryInputOverride = useMemo(() => {
|
|
109739
|
+
var _a;
|
|
109740
|
+
if (runHeaderInputMode === "tokenized") {
|
|
109741
|
+
return null;
|
|
109742
|
+
}
|
|
109743
|
+
if (!selectedNode || !("traceId" in selectedNode) || !("type" in selectedNode)) {
|
|
109744
|
+
return null;
|
|
109745
|
+
}
|
|
109746
|
+
const obs = selectedNode;
|
|
109747
|
+
if (obs.type !== "GENERATION") {
|
|
109748
|
+
return null;
|
|
109749
|
+
}
|
|
109750
|
+
const traceRow = traces.find((t2) => t2.id === obs.traceId);
|
|
109751
|
+
if (!traceRow) {
|
|
109752
|
+
return null;
|
|
109753
|
+
}
|
|
109754
|
+
const displayUser = traceRow.displayUserMessage && traceRow.displayUserMessage.length > 0 ? traceRow.displayUserMessage : TraceTreeService.extractUserMessage(traceRow.input);
|
|
109755
|
+
if (!displayUser || displayUser.length === 0) {
|
|
109756
|
+
return null;
|
|
109757
|
+
}
|
|
109758
|
+
const fromState = (_a = traceObservations[obs.traceId]) == null ? void 0 : _a.observations;
|
|
109759
|
+
const observations = fromState && fromState.length > 0 ? fromState : mode === "trace" && (traceData == null ? void 0 : traceData.id) === obs.traceId && traceData.observations.length > 0 ? traceData.observations : [];
|
|
109760
|
+
const { observation: firstGen } = TraceTreeService.findFirstGeneration(observations);
|
|
109761
|
+
if (!firstGen || firstGen.id !== obs.id) {
|
|
109762
|
+
return null;
|
|
109763
|
+
}
|
|
109764
|
+
return displayUser;
|
|
109765
|
+
}, [
|
|
109766
|
+
runHeaderInputMode,
|
|
109767
|
+
selectedNode,
|
|
109768
|
+
traces,
|
|
109769
|
+
traceObservations,
|
|
109770
|
+
mode,
|
|
109771
|
+
traceData
|
|
109772
|
+
]);
|
|
109110
109773
|
const handleNodeSelect = useCallback((node) => {
|
|
109111
109774
|
setSelectedNode(node);
|
|
109112
109775
|
}, []);
|
|
@@ -109155,6 +109818,23 @@ function DetailPage({
|
|
|
109155
109818
|
firstTraceId: null
|
|
109156
109819
|
});
|
|
109157
109820
|
}, []);
|
|
109821
|
+
const handleNavigateToTrace = useCallback((targetTraceId) => {
|
|
109822
|
+
setSelectedNode(null);
|
|
109823
|
+
setSessionData(null);
|
|
109824
|
+
setTraceData(null);
|
|
109825
|
+
setTraceObservations({});
|
|
109826
|
+
setLoadingState("idle");
|
|
109827
|
+
setError(null);
|
|
109828
|
+
setHasAutoSelected(false);
|
|
109829
|
+
setCurrentMode("trace");
|
|
109830
|
+
setCurrentTraceId(targetTraceId);
|
|
109831
|
+
setProgressiveState({
|
|
109832
|
+
traceCount: 0,
|
|
109833
|
+
pendingTraceIds: [],
|
|
109834
|
+
firstTraceLoaded: false,
|
|
109835
|
+
firstTraceId: null
|
|
109836
|
+
});
|
|
109837
|
+
}, []);
|
|
109158
109838
|
if (loadingState === "loading") {
|
|
109159
109839
|
const canShowHeader = mode === "session" && initialSessionData;
|
|
109160
109840
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col bg-white ${className}`, children: [
|
|
@@ -109323,8 +110003,10 @@ function DetailPage({
|
|
|
109323
110003
|
onNodeSelect: handleNodeSelect,
|
|
109324
110004
|
onExpandToggle: () => handleTraceExpand(trace.id, trace.timestamp),
|
|
109325
110005
|
showTraceId: mode === "session",
|
|
110006
|
+
onTraceIdClick: mode === "session" ? handleNavigateToTrace : void 0,
|
|
109326
110007
|
isLoading: isLoadingObservations,
|
|
109327
|
-
defaultExpandedNodeIds: autoExpandIds
|
|
110008
|
+
defaultExpandedNodeIds: autoExpandIds,
|
|
110009
|
+
runHeaderInputMode
|
|
109328
110010
|
},
|
|
109329
110011
|
trace.id
|
|
109330
110012
|
);
|
|
@@ -109344,7 +110026,15 @@ function DetailPage({
|
|
|
109344
110026
|
);
|
|
109345
110027
|
}) })
|
|
109346
110028
|
] }) }),
|
|
109347
|
-
!selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
110029
|
+
!selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
110030
|
+
NodeDetailPanel,
|
|
110031
|
+
{
|
|
110032
|
+
node: selectedNode,
|
|
110033
|
+
nodeType,
|
|
110034
|
+
apiConfig,
|
|
110035
|
+
generationSummaryInputOverride
|
|
110036
|
+
}
|
|
110037
|
+
)
|
|
109348
110038
|
] })
|
|
109349
110039
|
] });
|
|
109350
110040
|
}
|
|
@@ -109759,22 +110449,25 @@ function EnvironmentNameCell$1({ envId }) {
|
|
|
109759
110449
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
|
|
109760
110450
|
}
|
|
109761
110451
|
function SessionsListContent(props) {
|
|
109762
|
-
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours" } = props;
|
|
109763
|
-
const { environments } = useEnvironment();
|
|
109764
|
-
const [selectedSessionId, setSelectedSessionId] = useState(null);
|
|
110452
|
+
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
|
|
110453
|
+
const { environments, resolveEnvironmentName } = useEnvironment();
|
|
110454
|
+
const [selectedSessionId, setSelectedSessionId] = useState(() => initialSessionId ?? null);
|
|
109765
110455
|
const [selectedSessionData, setSelectedSessionData] = useState(null);
|
|
109766
|
-
const [isModalOpen, setIsModalOpen] = useState(
|
|
110456
|
+
const [isModalOpen, setIsModalOpen] = useState(() => !!initialSessionId);
|
|
109767
110457
|
const [sessions, setSessions] = useState([]);
|
|
109768
110458
|
const [totalCount, setTotalCount] = useState(0);
|
|
109769
110459
|
const [loading, setLoading] = useState(true);
|
|
109770
110460
|
const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
|
|
110461
|
+
const [appVersionOptions, setAppVersionOptions] = useState([]);
|
|
110462
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
109771
110463
|
const initialFilters = useMemo(() => {
|
|
109772
110464
|
const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
|
|
109773
|
-
|
|
109774
|
-
|
|
110465
|
+
const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter$1(), ...defaultFilters];
|
|
110466
|
+
if (initialSessionId) {
|
|
110467
|
+
return [...base2, { column: "id", type: "string", operator: "=", value: initialSessionId }];
|
|
109775
110468
|
}
|
|
109776
|
-
return
|
|
109777
|
-
}, [defaultFilters]);
|
|
110469
|
+
return base2;
|
|
110470
|
+
}, [defaultFilters, initialSessionId]);
|
|
109778
110471
|
const [filters, setFilters] = useState(initialFilters);
|
|
109779
110472
|
const [showFilterPanel, setShowFilterPanel] = useState(false);
|
|
109780
110473
|
const [showColumnCustomization, setShowColumnCustomization] = useState(false);
|
|
@@ -109783,6 +110476,32 @@ function SessionsListContent(props) {
|
|
|
109783
110476
|
const [pagination, setPagination] = useState({ page: 0, limit: 50 });
|
|
109784
110477
|
const [orderBy, setOrderBy] = useState({ column: "createdAt", order: "DESC" });
|
|
109785
110478
|
const apiService = useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
|
|
110479
|
+
useEffect(() => {
|
|
110480
|
+
if (initialSessionId) {
|
|
110481
|
+
setSelectedSessionId(initialSessionId);
|
|
110482
|
+
setIsModalOpen(true);
|
|
110483
|
+
}
|
|
110484
|
+
}, [initialSessionId]);
|
|
110485
|
+
useEffect(() => {
|
|
110486
|
+
const fetchAppVersions = async () => {
|
|
110487
|
+
try {
|
|
110488
|
+
const filterOptionsData = await apiService.fetchFilterOptions({
|
|
110489
|
+
projectId: apiConfig.projectId
|
|
110490
|
+
});
|
|
110491
|
+
if ((filterOptionsData == null ? void 0 : filterOptionsData.appvIds) && Array.isArray(filterOptionsData.appvIds)) {
|
|
110492
|
+
setAppVersionOptions(
|
|
110493
|
+
filterOptionsData.appvIds.map((item) => ({
|
|
110494
|
+
value: item.value,
|
|
110495
|
+
label: item.value
|
|
110496
|
+
}))
|
|
110497
|
+
);
|
|
110498
|
+
}
|
|
110499
|
+
} catch (error) {
|
|
110500
|
+
console.warn("Failed to fetch app version filter options:", error);
|
|
110501
|
+
}
|
|
110502
|
+
};
|
|
110503
|
+
fetchAppVersions();
|
|
110504
|
+
}, [apiService, apiConfig.projectId]);
|
|
109786
110505
|
const convertPresetToDateRange = (preset) => {
|
|
109787
110506
|
const now2 = /* @__PURE__ */ new Date();
|
|
109788
110507
|
let pastDate;
|
|
@@ -109844,7 +110563,6 @@ function SessionsListContent(props) {
|
|
|
109844
110563
|
});
|
|
109845
110564
|
}
|
|
109846
110565
|
const allFilters = [...timeFilters, ...filters];
|
|
109847
|
-
if (apiConfig.projectId) ;
|
|
109848
110566
|
return allFilters;
|
|
109849
110567
|
}, [timeRange, filters]);
|
|
109850
110568
|
const fetchSessions = useCallback(async () => {
|
|
@@ -109904,6 +110622,28 @@ function SessionsListContent(props) {
|
|
|
109904
110622
|
useEffect(() => {
|
|
109905
110623
|
fetchSessions();
|
|
109906
110624
|
}, [fetchSessions]);
|
|
110625
|
+
const filteredSessions = useMemo(() => {
|
|
110626
|
+
const term = searchTerm.trim().toLowerCase();
|
|
110627
|
+
if (!term) return sessions;
|
|
110628
|
+
return sessions.filter((session) => {
|
|
110629
|
+
var _a;
|
|
110630
|
+
const envName = ((_a = resolveEnvironmentName(session.envId)) == null ? void 0 : _a.toLowerCase()) || "";
|
|
110631
|
+
const searchableFields = [
|
|
110632
|
+
session.id,
|
|
110633
|
+
envName,
|
|
110634
|
+
session.envId,
|
|
110635
|
+
session.appvId,
|
|
110636
|
+
session.source,
|
|
110637
|
+
session.environment,
|
|
110638
|
+
session.sessionReference,
|
|
110639
|
+
session.userReference,
|
|
110640
|
+
...session.userIds || []
|
|
110641
|
+
];
|
|
110642
|
+
return searchableFields.some(
|
|
110643
|
+
(field) => field && String(field).toLowerCase().includes(term)
|
|
110644
|
+
);
|
|
110645
|
+
});
|
|
110646
|
+
}, [sessions, searchTerm, resolveEnvironmentName]);
|
|
109907
110647
|
const defaultColumns = useMemo(
|
|
109908
110648
|
() => [
|
|
109909
110649
|
{
|
|
@@ -109912,8 +110652,7 @@ function SessionsListContent(props) {
|
|
|
109912
110652
|
width: 320,
|
|
109913
110653
|
pinned: "left",
|
|
109914
110654
|
hide: false,
|
|
109915
|
-
|
|
109916
|
-
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
|
|
110655
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
|
|
109917
110656
|
},
|
|
109918
110657
|
{
|
|
109919
110658
|
field: "envId",
|
|
@@ -110040,6 +110779,20 @@ function SessionsListContent(props) {
|
|
|
110040
110779
|
disabled: true,
|
|
110041
110780
|
valueFormatter: (params) => TracingUtils.formatTokens(params.value),
|
|
110042
110781
|
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", children: TracingUtils.formatTokens(params.value) })
|
|
110782
|
+
},
|
|
110783
|
+
{
|
|
110784
|
+
field: "sessionReference",
|
|
110785
|
+
headerName: "Session Reference",
|
|
110786
|
+
width: 180,
|
|
110787
|
+
hide: true,
|
|
110788
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
110789
|
+
},
|
|
110790
|
+
{
|
|
110791
|
+
field: "identity",
|
|
110792
|
+
headerName: "User Reference",
|
|
110793
|
+
width: 180,
|
|
110794
|
+
hide: true,
|
|
110795
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
110043
110796
|
}
|
|
110044
110797
|
// {
|
|
110045
110798
|
// field: 'traceTags',
|
|
@@ -110159,8 +110912,9 @@ function SessionsListContent(props) {
|
|
|
110159
110912
|
// User-friendly label
|
|
110160
110913
|
apiColumnName: "App Version ID",
|
|
110161
110914
|
// API expects "App Version ID" (koretracing uiTableName)
|
|
110162
|
-
type: "
|
|
110163
|
-
operators: ["
|
|
110915
|
+
type: "stringOptions",
|
|
110916
|
+
operators: ["any of", "none of"],
|
|
110917
|
+
options: appVersionOptions
|
|
110164
110918
|
},
|
|
110165
110919
|
{
|
|
110166
110920
|
field: "source",
|
|
@@ -110212,10 +110966,27 @@ function SessionsListContent(props) {
|
|
|
110212
110966
|
// API expects "Output Tokens" (koretracing uiTableName)
|
|
110213
110967
|
type: "number",
|
|
110214
110968
|
operators: ["=", ">", ">=", "<", "<="]
|
|
110969
|
+
},
|
|
110970
|
+
{
|
|
110971
|
+
field: "sessionReference",
|
|
110972
|
+
label: "Session Reference",
|
|
110973
|
+
apiColumnName: "Session Reference",
|
|
110974
|
+
type: "string",
|
|
110975
|
+
operators: ["=", "!=", "contains"]
|
|
110976
|
+
},
|
|
110977
|
+
{
|
|
110978
|
+
field: "identity",
|
|
110979
|
+
label: "User Reference",
|
|
110980
|
+
apiColumnName: "User Reference",
|
|
110981
|
+
type: "string",
|
|
110982
|
+
operators: ["=", "!=", "contains"]
|
|
110215
110983
|
}
|
|
110216
110984
|
],
|
|
110217
|
-
[environments]
|
|
110985
|
+
[environments, appVersionOptions]
|
|
110218
110986
|
);
|
|
110987
|
+
const handleSearch = useCallback((term) => {
|
|
110988
|
+
setSearchTerm(term);
|
|
110989
|
+
}, []);
|
|
110219
110990
|
const handleTimeRangeChange = (value, presetLabel) => {
|
|
110220
110991
|
console.log("🗓️ SessionsList: Time range change requested:", value, presetLabel);
|
|
110221
110992
|
setTimeRange(value);
|
|
@@ -110257,6 +111028,7 @@ function SessionsListContent(props) {
|
|
|
110257
111028
|
};
|
|
110258
111029
|
const handleClearFilters = () => {
|
|
110259
111030
|
setFilters([]);
|
|
111031
|
+
setSearchTerm("");
|
|
110260
111032
|
setTimeRange("24 hours");
|
|
110261
111033
|
};
|
|
110262
111034
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col w-full ${className}`, children: [
|
|
@@ -110265,11 +111037,19 @@ function SessionsListContent(props) {
|
|
|
110265
111037
|
{
|
|
110266
111038
|
title: "Sessions",
|
|
110267
111039
|
description: "Review session logs and trace details to analyze conversation logs and app behavior.",
|
|
110268
|
-
|
|
111040
|
+
searchPlaceholder: "Search sessions...",
|
|
111041
|
+
showSearch: true,
|
|
111042
|
+
searchConfig: {
|
|
111043
|
+
metadataSearchFields: ["Session ID", "Environment", "App Version", "User ID", "Source"],
|
|
111044
|
+
updateQuery: handleSearch,
|
|
111045
|
+
currentQuery: searchTerm,
|
|
111046
|
+
tableAllowsFullTextSearch: false
|
|
111047
|
+
},
|
|
110269
111048
|
timeRange,
|
|
110270
111049
|
timeRangePresetLabel,
|
|
110271
111050
|
onTimeRangeChange: handleTimeRangeChange,
|
|
110272
111051
|
filters,
|
|
111052
|
+
filterColumns,
|
|
110273
111053
|
onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
|
|
110274
111054
|
onModifyColumnsClick: () => setShowColumnCustomization(true),
|
|
110275
111055
|
onExportClick: handleExport,
|
|
@@ -110320,10 +111100,10 @@ function SessionsListContent(props) {
|
|
|
110320
111100
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto p-[24px] pt-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
110321
111101
|
TracingTable,
|
|
110322
111102
|
{
|
|
110323
|
-
data:
|
|
111103
|
+
data: filteredSessions,
|
|
110324
111104
|
columns,
|
|
110325
111105
|
loading,
|
|
110326
|
-
totalCount,
|
|
111106
|
+
totalCount: searchTerm.trim() ? filteredSessions.length : totalCount,
|
|
110327
111107
|
pagination,
|
|
110328
111108
|
onPaginationChange: setPagination,
|
|
110329
111109
|
onRowClick: handleRowClick,
|
|
@@ -110370,24 +111150,26 @@ function TracesListContent(props) {
|
|
|
110370
111150
|
onTraceClick,
|
|
110371
111151
|
className = "",
|
|
110372
111152
|
defaultFilters = [],
|
|
110373
|
-
sessionId
|
|
111153
|
+
sessionId,
|
|
111154
|
+
initialTraceId
|
|
110374
111155
|
} = props;
|
|
110375
111156
|
const { environments } = useEnvironment();
|
|
110376
|
-
const [selectedTraceId, setSelectedTraceId] = useState(null);
|
|
110377
|
-
const [isModalOpen, setIsModalOpen] = useState(
|
|
111157
|
+
const [selectedTraceId, setSelectedTraceId] = useState(() => initialTraceId ?? null);
|
|
111158
|
+
const [isModalOpen, setIsModalOpen] = useState(() => !!initialTraceId);
|
|
110378
111159
|
const [traces, setTraces] = useState([]);
|
|
110379
111160
|
const [totalCount, setTotalCount] = useState(0);
|
|
110380
111161
|
const [loading, setLoading] = useState(true);
|
|
110381
111162
|
const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
|
|
110382
111163
|
const [searchTerm, setSearchTerm] = useState("");
|
|
110383
|
-
const [searchType, setSearchType] = useState(["id"]);
|
|
111164
|
+
const [searchType, setSearchType] = useState(["id", "content"]);
|
|
110384
111165
|
const initialFilters = useMemo(() => {
|
|
110385
111166
|
const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
|
|
110386
|
-
|
|
110387
|
-
|
|
111167
|
+
const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter(), ...defaultFilters];
|
|
111168
|
+
if (initialTraceId) {
|
|
111169
|
+
return [...base2, { column: "id", type: "string", operator: "=", value: initialTraceId }];
|
|
110388
111170
|
}
|
|
110389
|
-
return
|
|
110390
|
-
}, [defaultFilters]);
|
|
111171
|
+
return base2;
|
|
111172
|
+
}, [defaultFilters, initialTraceId]);
|
|
110391
111173
|
const [filters, setFilters] = useState(initialFilters);
|
|
110392
111174
|
const [showFilterPanel, setShowFilterPanel] = useState(false);
|
|
110393
111175
|
const [showColumnCustomization, setShowColumnCustomization] = useState(false);
|
|
@@ -110396,6 +111178,12 @@ function TracesListContent(props) {
|
|
|
110396
111178
|
const [pagination, setPagination] = useState({ page: 0, limit: 50 });
|
|
110397
111179
|
const [orderBy, setOrderBy] = useState({ column: "timestamp", order: "DESC" });
|
|
110398
111180
|
const [detailedTraceData, setDetailedTraceData] = useState(/* @__PURE__ */ new Map());
|
|
111181
|
+
useEffect(() => {
|
|
111182
|
+
if (initialTraceId) {
|
|
111183
|
+
setSelectedTraceId(initialTraceId);
|
|
111184
|
+
setIsModalOpen(true);
|
|
111185
|
+
}
|
|
111186
|
+
}, [initialTraceId]);
|
|
110399
111187
|
const apiService = useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
|
|
110400
111188
|
const convertPresetToDateRange = (preset) => {
|
|
110401
111189
|
const now2 = /* @__PURE__ */ new Date();
|
|
@@ -110481,18 +111269,24 @@ function TracesListContent(props) {
|
|
|
110481
111269
|
orderBy
|
|
110482
111270
|
});
|
|
110483
111271
|
const apiFilters = TracingUtils.convertFiltersToApiFormat(effectiveFilters, filterColumns);
|
|
110484
|
-
const tracesResponse = await
|
|
110485
|
-
|
|
110486
|
-
|
|
110487
|
-
|
|
110488
|
-
|
|
110489
|
-
|
|
110490
|
-
|
|
110491
|
-
|
|
110492
|
-
|
|
110493
|
-
|
|
111272
|
+
const [tracesResponse, countResponse] = await Promise.all([
|
|
111273
|
+
apiService.fetchTraces({
|
|
111274
|
+
projectId: apiConfig.projectId,
|
|
111275
|
+
filter: apiFilters,
|
|
111276
|
+
orderBy,
|
|
111277
|
+
page: pagination.page,
|
|
111278
|
+
limit: pagination.limit,
|
|
111279
|
+
searchQuery: searchTerm || null,
|
|
111280
|
+
searchType
|
|
111281
|
+
}),
|
|
111282
|
+
apiService.fetchTracesCount(apiConfig.projectId, apiFilters, {
|
|
111283
|
+
searchQuery: searchTerm || null,
|
|
111284
|
+
searchType,
|
|
111285
|
+
orderBy
|
|
111286
|
+
})
|
|
111287
|
+
]);
|
|
110494
111288
|
const basicTraces = tracesResponse.traces || [];
|
|
110495
|
-
console.log("✅ Basic traces loaded:", { count: basicTraces.length });
|
|
111289
|
+
console.log("✅ Basic traces loaded:", { count: basicTraces.length, total: countResponse.totalCount });
|
|
110496
111290
|
if (basicTraces.length > 0) {
|
|
110497
111291
|
const traceIds = basicTraces.map((t2) => t2.id);
|
|
110498
111292
|
try {
|
|
@@ -110527,7 +111321,7 @@ function TracesListContent(props) {
|
|
|
110527
111321
|
} else {
|
|
110528
111322
|
setTraces([]);
|
|
110529
111323
|
}
|
|
110530
|
-
setTotalCount(
|
|
111324
|
+
setTotalCount(countResponse.totalCount);
|
|
110531
111325
|
} catch (error) {
|
|
110532
111326
|
console.error("❌ Error fetching traces:", error);
|
|
110533
111327
|
setTraces([]);
|
|
@@ -110556,11 +111350,13 @@ function TracesListContent(props) {
|
|
|
110556
111350
|
projectId: apiConfig.projectId,
|
|
110557
111351
|
timestamp: trace.timestamp
|
|
110558
111352
|
});
|
|
111353
|
+
const inputDisplay = TraceTreeService.extractUserMessage(detail["input"]);
|
|
111354
|
+
const outputDisplay = TraceTreeService.extractAppResponse(detail["output"]);
|
|
110559
111355
|
setDetailedTraceData((prev) => {
|
|
110560
111356
|
const newMap = new Map(prev);
|
|
110561
111357
|
newMap.set(traceId, {
|
|
110562
|
-
input:
|
|
110563
|
-
output:
|
|
111358
|
+
input: inputDisplay,
|
|
111359
|
+
output: outputDisplay,
|
|
110564
111360
|
totalCost: detail["totalCost"],
|
|
110565
111361
|
envId: detail["envId"],
|
|
110566
111362
|
source: detail["source"]
|
|
@@ -110597,8 +111393,7 @@ function TracesListContent(props) {
|
|
|
110597
111393
|
width: 320,
|
|
110598
111394
|
pinned: "left",
|
|
110599
111395
|
hide: false,
|
|
110600
|
-
|
|
110601
|
-
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
|
|
111396
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
|
|
110602
111397
|
}
|
|
110603
111398
|
];
|
|
110604
111399
|
{
|
|
@@ -110609,11 +111404,13 @@ function TracesListContent(props) {
|
|
|
110609
111404
|
hide: false,
|
|
110610
111405
|
cellRenderer: (params) => {
|
|
110611
111406
|
const detailData = detailedTraceData.get(params.data.id);
|
|
110612
|
-
const
|
|
110613
|
-
if (
|
|
111407
|
+
const rawInput = detailData == null ? void 0 : detailData.input;
|
|
111408
|
+
if (rawInput === void 0) {
|
|
110614
111409
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
|
|
110615
111410
|
}
|
|
110616
|
-
|
|
111411
|
+
const inputText = typeof rawInput === "string" ? rawInput : TraceTreeService.extractUserMessage(rawInput);
|
|
111412
|
+
const displayText = TracingUtils.truncate(inputText || "-", 50);
|
|
111413
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: inputText || void 0, children: displayText });
|
|
110617
111414
|
}
|
|
110618
111415
|
});
|
|
110619
111416
|
}
|
|
@@ -110642,11 +111439,13 @@ function TracesListContent(props) {
|
|
|
110642
111439
|
hide: false,
|
|
110643
111440
|
cellRenderer: (params) => {
|
|
110644
111441
|
const detailData = detailedTraceData.get(params.data.id);
|
|
110645
|
-
const
|
|
110646
|
-
if (
|
|
111442
|
+
const rawOutput = detailData == null ? void 0 : detailData.output;
|
|
111443
|
+
if (rawOutput === void 0) {
|
|
110647
111444
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
|
|
110648
111445
|
}
|
|
110649
|
-
|
|
111446
|
+
const outputText = typeof rawOutput === "string" ? rawOutput : TraceTreeService.extractAppResponse(rawOutput);
|
|
111447
|
+
const displayText = TracingUtils.truncate(outputText || "-", 50);
|
|
111448
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: outputText || void 0, children: displayText });
|
|
110650
111449
|
}
|
|
110651
111450
|
});
|
|
110652
111451
|
}
|
|
@@ -110709,11 +111508,9 @@ function TracesListContent(props) {
|
|
|
110709
111508
|
// },
|
|
110710
111509
|
{
|
|
110711
111510
|
field: "timestamp",
|
|
110712
|
-
headerName: "
|
|
111511
|
+
headerName: "Created At",
|
|
110713
111512
|
width: 180,
|
|
110714
|
-
hide:
|
|
110715
|
-
// DISABLED - This is the main sort column for traces
|
|
110716
|
-
disabled: true,
|
|
111513
|
+
hide: false,
|
|
110717
111514
|
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: params.value ? new Date(params.value).toLocaleString() : "-" })
|
|
110718
111515
|
},
|
|
110719
111516
|
{
|
|
@@ -110788,6 +111585,20 @@ function TracesListContent(props) {
|
|
|
110788
111585
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", children: source || "-" });
|
|
110789
111586
|
}
|
|
110790
111587
|
},
|
|
111588
|
+
{
|
|
111589
|
+
field: "sessionReference",
|
|
111590
|
+
headerName: "Session Reference",
|
|
111591
|
+
width: 180,
|
|
111592
|
+
hide: true,
|
|
111593
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
111594
|
+
},
|
|
111595
|
+
{
|
|
111596
|
+
field: "identity",
|
|
111597
|
+
headerName: "User Reference",
|
|
111598
|
+
width: 180,
|
|
111599
|
+
hide: true,
|
|
111600
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
111601
|
+
},
|
|
110791
111602
|
{
|
|
110792
111603
|
field: "promptTokens",
|
|
110793
111604
|
headerName: "Input Tokens",
|
|
@@ -110964,10 +111775,9 @@ function TracesListContent(props) {
|
|
|
110964
111775
|
},
|
|
110965
111776
|
{
|
|
110966
111777
|
field: "timestamp",
|
|
110967
|
-
label: "
|
|
110968
|
-
// Same as API
|
|
111778
|
+
label: "Created At",
|
|
110969
111779
|
apiColumnName: "Timestamp",
|
|
110970
|
-
//
|
|
111780
|
+
// Backend payload: keep "Timestamp" for API
|
|
110971
111781
|
type: "datetime",
|
|
110972
111782
|
operators: [">=", "<=", "="]
|
|
110973
111783
|
},
|
|
@@ -111058,6 +111868,20 @@ function TracesListContent(props) {
|
|
|
111058
111868
|
label: "Output Tokens",
|
|
111059
111869
|
type: "number",
|
|
111060
111870
|
operators: ["=", ">", ">=", "<", "<="]
|
|
111871
|
+
},
|
|
111872
|
+
{
|
|
111873
|
+
field: "sessionReference",
|
|
111874
|
+
label: "Session Reference",
|
|
111875
|
+
apiColumnName: "Session Reference",
|
|
111876
|
+
type: "string",
|
|
111877
|
+
operators: ["=", "!=", "contains"]
|
|
111878
|
+
},
|
|
111879
|
+
{
|
|
111880
|
+
field: "identity",
|
|
111881
|
+
label: "User Reference",
|
|
111882
|
+
apiColumnName: "User Reference",
|
|
111883
|
+
type: "string",
|
|
111884
|
+
operators: ["=", "!=", "contains"]
|
|
111061
111885
|
}
|
|
111062
111886
|
);
|
|
111063
111887
|
return baseColumns;
|
|
@@ -111124,6 +111948,7 @@ function TracesListContent(props) {
|
|
|
111124
111948
|
timeRangePresetLabel,
|
|
111125
111949
|
onTimeRangeChange: handleTimeRangeChange,
|
|
111126
111950
|
filters,
|
|
111951
|
+
filterColumns,
|
|
111127
111952
|
onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
|
|
111128
111953
|
onModifyColumnsClick: () => setShowColumnCustomization(true),
|
|
111129
111954
|
onExportClick: handleExport,
|
|
@@ -112175,12 +113000,12 @@ class TreeBuilder {
|
|
|
112175
113000
|
* Process execution events and build a hierarchical tree structure
|
|
112176
113001
|
* Session > Run > Node Tree
|
|
112177
113002
|
*/
|
|
112178
|
-
static buildSessionTree(events, sessionId) {
|
|
113003
|
+
static buildSessionTree(events, sessionId, options) {
|
|
112179
113004
|
var _a;
|
|
112180
113005
|
const runGroups = this.groupEventsByRun(events);
|
|
112181
113006
|
const runs = [];
|
|
112182
113007
|
for (const [runId, runEvents] of runGroups.entries()) {
|
|
112183
|
-
const runTree = this.buildRunTree(runId, runEvents);
|
|
113008
|
+
const runTree = this.buildRunTree(runId, runEvents, options);
|
|
112184
113009
|
runs.push(runTree);
|
|
112185
113010
|
}
|
|
112186
113011
|
runs.sort((a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime());
|
|
@@ -112206,11 +113031,11 @@ class TreeBuilder {
|
|
|
112206
113031
|
/**
|
|
112207
113032
|
* Build tree for a single run
|
|
112208
113033
|
*/
|
|
112209
|
-
static buildRunTree(runId, events) {
|
|
113034
|
+
static buildRunTree(runId, events, options) {
|
|
112210
113035
|
var _a;
|
|
112211
113036
|
const nodeEventMap = /* @__PURE__ */ new Map();
|
|
112212
113037
|
events.forEach((event) => {
|
|
112213
|
-
const nodeKey =
|
|
113038
|
+
const nodeKey = event.data.id;
|
|
112214
113039
|
if (!nodeEventMap.has(nodeKey)) {
|
|
112215
113040
|
nodeEventMap.set(nodeKey, {});
|
|
112216
113041
|
}
|
|
@@ -112237,7 +113062,7 @@ class TreeBuilder {
|
|
|
112237
113062
|
const status = this.calculateRunStatus(runEvents);
|
|
112238
113063
|
const duration = endTime && startTime ? endTime - startTime : void 0;
|
|
112239
113064
|
const totalTokens = this.calculateRunTokens(runEvents);
|
|
112240
|
-
const userInput = this.extractUserInput(runEvents);
|
|
113065
|
+
const userInput = this.extractUserInput(runEvents, options);
|
|
112241
113066
|
const finalOutput = this.extractFinalOutput(runEvents);
|
|
112242
113067
|
return {
|
|
112243
113068
|
runId,
|
|
@@ -112256,11 +113081,12 @@ class TreeBuilder {
|
|
|
112256
113081
|
* Create TreeNode from paired started/completed events
|
|
112257
113082
|
*/
|
|
112258
113083
|
static createTreeNodeFromEvents(startedEvent, completedEvent, runId) {
|
|
113084
|
+
var _a;
|
|
112259
113085
|
const startTime = startedEvent.data.timestamp;
|
|
112260
113086
|
const endTime = completedEvent == null ? void 0 : completedEvent.data.timestamp;
|
|
112261
113087
|
const duration = endTime && startTime ? new Date(endTime).getTime() - new Date(startTime).getTime() : void 0;
|
|
112262
113088
|
const primaryEvent = completedEvent || startedEvent;
|
|
112263
|
-
const hasInputOutput = primaryEvent.data.type === "llm" || primaryEvent.data.type === "tool" || primaryEvent.data.type === "GuardrailsInputScan" || primaryEvent.data.type === "GuardrailsOutputScan" || primaryEvent.data.type === "Agent" || primaryEvent.data.type === "External Orchestrator" || primaryEvent.data.type === "ProxyWorker" || primaryEvent.data.type === "event";
|
|
113089
|
+
const hasInputOutput = primaryEvent.data.type === "llm" || primaryEvent.data.type === "tool" || primaryEvent.data.type === "GuardrailsInputScan" || primaryEvent.data.type === "GuardrailsOutputScan" || primaryEvent.data.type === "Agent" || primaryEvent.data.type === "External Orchestrator" || primaryEvent.data.type === "ProxyWorker" || primaryEvent.data.type === "PostProcessor" || primaryEvent.data.type === "event";
|
|
112264
113090
|
const input = hasInputOutput ? startedEvent.data.input : void 0;
|
|
112265
113091
|
let output = void 0;
|
|
112266
113092
|
let error = void 0;
|
|
@@ -112274,7 +113100,8 @@ class TreeBuilder {
|
|
|
112274
113100
|
const { toolInvocations, isResponse } = this.extractToolInvocations(output);
|
|
112275
113101
|
console.log("toolInvocations", toolInvocations);
|
|
112276
113102
|
console.log("isResponse", isResponse);
|
|
112277
|
-
const
|
|
113103
|
+
const extractedProvider = primaryEvent.data.type === "llm" ? this.extractProvider(primaryEvent.data.name || primaryEvent.data.toolName) : void 0;
|
|
113104
|
+
const provider = ((_a = primaryEvent.data.metadata) == null ? void 0 : _a.provider) || extractedProvider;
|
|
112278
113105
|
return {
|
|
112279
113106
|
id: primaryEvent.data.id,
|
|
112280
113107
|
parentId: primaryEvent.data.parentId,
|
|
@@ -112433,12 +113260,22 @@ class TreeBuilder {
|
|
|
112433
113260
|
/**
|
|
112434
113261
|
* Extract initial user input from the first LLM node's input
|
|
112435
113262
|
*/
|
|
112436
|
-
static extractUserInput(events) {
|
|
113263
|
+
static extractUserInput(events, options) {
|
|
113264
|
+
const preferDisplay = ((options == null ? void 0 : options.runHeaderInputMode) ?? "display") === "display";
|
|
112437
113265
|
const llmEvents = events.filter(
|
|
112438
113266
|
(e3) => e3.type === "node_started" && e3.data.type === "llm"
|
|
112439
113267
|
).sort((a4, b2) => new Date(a4.data.timestamp).getTime() - new Date(b2.data.timestamp).getTime());
|
|
112440
113268
|
if (llmEvents.length > 0) {
|
|
112441
113269
|
const firstLlmEvent = llmEvents[0];
|
|
113270
|
+
if (preferDisplay && firstLlmEvent.data.displayInput !== void 0 && firstLlmEvent.data.displayInput !== null) {
|
|
113271
|
+
const d3 = firstLlmEvent.data.displayInput;
|
|
113272
|
+
if (typeof d3 === "string") {
|
|
113273
|
+
return d3;
|
|
113274
|
+
}
|
|
113275
|
+
if (typeof d3 === "object") {
|
|
113276
|
+
return JSON.stringify(d3);
|
|
113277
|
+
}
|
|
113278
|
+
}
|
|
112442
113279
|
if (firstLlmEvent.data.input) {
|
|
112443
113280
|
if (typeof firstLlmEvent.data.input === "string") {
|
|
112444
113281
|
return firstLlmEvent.data.input;
|
|
@@ -112506,6 +113343,22 @@ class TreeBuilder {
|
|
|
112506
113343
|
*/
|
|
112507
113344
|
static extractFinalOutput(events) {
|
|
112508
113345
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
113346
|
+
const postProcessorEvents = events.filter(
|
|
113347
|
+
(e3) => {
|
|
113348
|
+
var _a2;
|
|
113349
|
+
return e3.type === "node_completed" && e3.data.type === "tool" && ((_a2 = e3.data.metadata) == null ? void 0 : _a2.type) === "PostProcessor" && e3.data.output;
|
|
113350
|
+
}
|
|
113351
|
+
);
|
|
113352
|
+
if (postProcessorEvents.length > 0) {
|
|
113353
|
+
const lastPP = postProcessorEvents[postProcessorEvents.length - 1];
|
|
113354
|
+
const ppOutput = lastPP.data.output;
|
|
113355
|
+
if (typeof ppOutput === "object" && ppOutput.output) {
|
|
113356
|
+
return typeof ppOutput.output === "string" ? ppOutput.output : JSON.stringify(ppOutput.output);
|
|
113357
|
+
}
|
|
113358
|
+
if (typeof ppOutput === "string") {
|
|
113359
|
+
return ppOutput;
|
|
113360
|
+
}
|
|
113361
|
+
}
|
|
112509
113362
|
const errorEvents = events.filter(
|
|
112510
113363
|
(e3) => e3.type === "node_completed" && e3.data.error && (e3.data.status === "errored" || e3.data.status === "failed")
|
|
112511
113364
|
);
|
|
@@ -112632,8 +113485,8 @@ class TreeBuilder {
|
|
|
112632
113485
|
/**
|
|
112633
113486
|
* Update tree with new events (optimized for real-time updates)
|
|
112634
113487
|
*/
|
|
112635
|
-
static updateTree(existingTree, _newEvents, allEvents) {
|
|
112636
|
-
return this.buildSessionTree(allEvents, existingTree.sessionId);
|
|
113488
|
+
static updateTree(existingTree, _newEvents, allEvents, options) {
|
|
113489
|
+
return this.buildSessionTree(allEvents, existingTree.sessionId, options);
|
|
112637
113490
|
}
|
|
112638
113491
|
/**
|
|
112639
113492
|
* Merge new events into existing events efficiently
|
|
@@ -112985,7 +113838,7 @@ class ApiService {
|
|
|
112985
113838
|
nodeId,
|
|
112986
113839
|
totalObservations: observations.length
|
|
112987
113840
|
});
|
|
112988
|
-
const
|
|
113841
|
+
const matchingObservations = observations.filter((obs) => {
|
|
112989
113842
|
let metadata = obs.metadata;
|
|
112990
113843
|
if (typeof metadata === "string") {
|
|
112991
113844
|
try {
|
|
@@ -113006,6 +113859,7 @@ class ApiService {
|
|
|
113006
113859
|
});
|
|
113007
113860
|
return nodeId === observationNodeId;
|
|
113008
113861
|
});
|
|
113862
|
+
const matchedObservation = matchingObservations.find((obs) => obs.type === "GENERATION") || matchingObservations[0] || null;
|
|
113009
113863
|
if (!matchedObservation) {
|
|
113010
113864
|
const parts = nodeId.split("_");
|
|
113011
113865
|
if (parts.length === 2) {
|
|
@@ -113147,6 +114001,36 @@ class ApiService {
|
|
|
113147
114001
|
return this.config;
|
|
113148
114002
|
}
|
|
113149
114003
|
}
|
|
114004
|
+
function sanitizeForTestId(value) {
|
|
114005
|
+
return value.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "") || "node";
|
|
114006
|
+
}
|
|
114007
|
+
function getDebuggerCallTypeTestId(node) {
|
|
114008
|
+
const name = (node.name ?? "unknown").toString();
|
|
114009
|
+
let slug = sanitizeForTestId(name);
|
|
114010
|
+
switch (node.type) {
|
|
114011
|
+
case "event":
|
|
114012
|
+
slug = slug.replace(/-event$/, "") || "event";
|
|
114013
|
+
return `debugger-event-${slug}`;
|
|
114014
|
+
case "Agent":
|
|
114015
|
+
return `debugger-${slug}-call`;
|
|
114016
|
+
case "tool":
|
|
114017
|
+
return `debugger-${slug}-call`;
|
|
114018
|
+
case "llm":
|
|
114019
|
+
return `debugger-llm-${slug}`;
|
|
114020
|
+
case "GuardrailsInputScan":
|
|
114021
|
+
return `debugger-guardrails-input-${slug}`;
|
|
114022
|
+
case "GuardrailsOutputScan":
|
|
114023
|
+
return `debugger-guardrails-output-${slug}`;
|
|
114024
|
+
case "External Orchestrator":
|
|
114025
|
+
return `debugger-orchestrator-${slug}`;
|
|
114026
|
+
case "ProxyWorker":
|
|
114027
|
+
return `debugger-proxy-${slug}`;
|
|
114028
|
+
case "PostProcessor":
|
|
114029
|
+
return `debugger-postprocessor-${slug}`;
|
|
114030
|
+
default:
|
|
114031
|
+
return `debugger-${String(node.type).toLowerCase().replace(/\s+/g, "-")}-${slug}`;
|
|
114032
|
+
}
|
|
114033
|
+
}
|
|
113150
114034
|
function DebugCard({
|
|
113151
114035
|
node,
|
|
113152
114036
|
onToggle,
|
|
@@ -113158,9 +114042,12 @@ function DebugCard({
|
|
|
113158
114042
|
projectId,
|
|
113159
114043
|
nodeIndex = 0
|
|
113160
114044
|
}) {
|
|
114045
|
+
var _a;
|
|
114046
|
+
const callTypeTestId = useMemo(() => getDebuggerCallTypeTestId(node), [node.type, node.name]);
|
|
114047
|
+
const cardTestId = useMemo(() => `${callTypeTestId}_${node.id}`, [callTypeTestId, node.id]);
|
|
113161
114048
|
const isGuardrailsNode = useMemo(() => {
|
|
113162
|
-
var
|
|
113163
|
-
return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((
|
|
114049
|
+
var _a2;
|
|
114050
|
+
return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((_a2 = node.name) == null ? void 0 : _a2.toLowerCase().includes("guardrail"));
|
|
113164
114051
|
}, [node.type, node.name]);
|
|
113165
114052
|
const availableTabs = useMemo(() => {
|
|
113166
114053
|
switch (node.type) {
|
|
@@ -113337,7 +114224,7 @@ function DebugCard({
|
|
|
113337
114224
|
}
|
|
113338
114225
|
};
|
|
113339
114226
|
const getNodeIcon = () => {
|
|
113340
|
-
var
|
|
114227
|
+
var _a2, _b;
|
|
113341
114228
|
if (isGuardrailsNode) {
|
|
113342
114229
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 relative w-[24px] h-[24px] bg-gray-200 rounded-[8px] flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "17", height: "21", viewBox: "0 0 17 21", fill: "none", className: "w-[16px] h-[16px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113343
114230
|
"path",
|
|
@@ -113372,7 +114259,7 @@ function DebugCard({
|
|
|
113372
114259
|
size: "small",
|
|
113373
114260
|
name: node.name,
|
|
113374
114261
|
className: "w-[24px] h-[24px]",
|
|
113375
|
-
toolType: node.type === "tool" ? (
|
|
114262
|
+
toolType: node.type === "tool" ? (_a2 = node.metadata) == null ? void 0 : _a2.type : void 0,
|
|
113376
114263
|
provider: node.type === "llm" ? (_b = node.metadata) == null ? void 0 : _b.provider : void 0,
|
|
113377
114264
|
modelName: node.type === "llm" ? node.name : void 0
|
|
113378
114265
|
}
|
|
@@ -113396,7 +114283,7 @@ function DebugCard({
|
|
|
113396
114283
|
return availableTabs;
|
|
113397
114284
|
};
|
|
113398
114285
|
const renderActionContent = () => {
|
|
113399
|
-
var
|
|
114286
|
+
var _a2, _b;
|
|
113400
114287
|
let toolInvocations = node.toolInvocations || [];
|
|
113401
114288
|
if (node.type === "llm" && Array.isArray(node.output)) {
|
|
113402
114289
|
toolInvocations = node.output.filter(
|
|
@@ -113418,7 +114305,7 @@ function DebugCard({
|
|
|
113418
114305
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 truncate", children: child.name || "Unknown" })
|
|
113419
114306
|
] }, child.id || index))
|
|
113420
114307
|
] }),
|
|
113421
|
-
toolInvocations.length > 0 && ((_b = (
|
|
114308
|
+
toolInvocations.length > 0 && ((_b = (_a2 = toolInvocations[0]) == null ? void 0 : _a2.args) == null ? void 0 : _b.reason) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
113422
114309
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-400 mb-[4px]", children: "Reason" }),
|
|
113423
114310
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-600", children: toolInvocations[0].args.reason })
|
|
113424
114311
|
] })
|
|
@@ -113445,14 +114332,14 @@ function DebugCard({
|
|
|
113445
114332
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 italic", children: "No actions taken" });
|
|
113446
114333
|
};
|
|
113447
114334
|
const extractOutputMessage = (output) => {
|
|
113448
|
-
var
|
|
114335
|
+
var _a2, _b, _c, _d;
|
|
113449
114336
|
if (!output || typeof output !== "object") return void 0;
|
|
113450
114337
|
if (Array.isArray(output)) {
|
|
113451
114338
|
const routeToUserTool = output.find(
|
|
113452
114339
|
(item) => item && typeof item === "object" && (item.name === "route_to_user" || item.toolName === "route_to_user")
|
|
113453
114340
|
);
|
|
113454
114341
|
if (routeToUserTool) {
|
|
113455
|
-
return ((
|
|
114342
|
+
return ((_a2 = routeToUserTool.args) == null ? void 0 : _a2.message) || routeToUserTool.message || ((_b = routeToUserTool.output) == null ? void 0 : _b.message);
|
|
113456
114343
|
}
|
|
113457
114344
|
} else if (output.name === "route_to_user" || output.toolName === "route_to_user") {
|
|
113458
114345
|
return ((_c = output.args) == null ? void 0 : _c.message) || output.message || ((_d = output.output) == null ? void 0 : _d.message);
|
|
@@ -113549,7 +114436,7 @@ function DebugCard({
|
|
|
113549
114436
|
] });
|
|
113550
114437
|
};
|
|
113551
114438
|
const renderTabContent = () => {
|
|
113552
|
-
var
|
|
114439
|
+
var _a2;
|
|
113553
114440
|
switch (activeTab) {
|
|
113554
114441
|
case "summary":
|
|
113555
114442
|
if (isGuardrailsNode) {
|
|
@@ -113740,7 +114627,7 @@ function DebugCard({
|
|
|
113740
114627
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113741
114628
|
DataViewer,
|
|
113742
114629
|
{
|
|
113743
|
-
data: ((
|
|
114630
|
+
data: ((_a2 = node.metadata) == null ? void 0 : _a2["logs"]) || {},
|
|
113744
114631
|
title: "Execution Logs",
|
|
113745
114632
|
maxHeight: "250px",
|
|
113746
114633
|
defaultExpanded: true,
|
|
@@ -113753,15 +114640,15 @@ function DebugCard({
|
|
|
113753
114640
|
};
|
|
113754
114641
|
return (
|
|
113755
114642
|
// bg-white w-full border-t border-gray-200
|
|
113756
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id":
|
|
114643
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id": cardTestId, "data-call-type-test-id": callTypeTestId, children: [
|
|
113757
114644
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113758
114645
|
"div",
|
|
113759
114646
|
{
|
|
113760
114647
|
className: `flex items-center pl-[8px] pr-[8px] relative transition-colors cursor-pointer w-full
|
|
113761
114648
|
${isSelected ? "" : ""}`,
|
|
113762
114649
|
onClick: handleNodeClick,
|
|
113763
|
-
"data-test-id":
|
|
113764
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id":
|
|
114650
|
+
"data-test-id": `${callTypeTestId}_header`,
|
|
114651
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id": `${callTypeTestId}_header_content`, children: [
|
|
113765
114652
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113766
114653
|
"div",
|
|
113767
114654
|
{
|
|
@@ -113775,7 +114662,7 @@ function DebugCard({
|
|
|
113775
114662
|
}
|
|
113776
114663
|
},
|
|
113777
114664
|
title: hasChildren ? isExpanded ? "Collapse" : "Expand" : "Show details",
|
|
113778
|
-
"data-test-id":
|
|
114665
|
+
"data-test-id": `${callTypeTestId}_toggle`,
|
|
113779
114666
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113780
114667
|
ChevronRight,
|
|
113781
114668
|
{
|
|
@@ -113784,28 +114671,28 @@ function DebugCard({
|
|
|
113784
114671
|
)
|
|
113785
114672
|
}
|
|
113786
114673
|
),
|
|
113787
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] w-full py-[8px] border-b border-gray-200", "data-test-id":
|
|
113788
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 rounded-[8px] bg-[#B2DDFF]", "data-test-id":
|
|
114674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] w-full py-[8px] border-b border-gray-200", "data-test-id": `${callTypeTestId}_node_info`, children: [
|
|
114675
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 rounded-[8px] bg-[#B2DDFF]", "data-test-id": `${callTypeTestId}_node_icon`, children: getNodeIcon() }),
|
|
113789
114676
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113790
114677
|
"span",
|
|
113791
114678
|
{
|
|
113792
114679
|
className: "font-semibold text-gray-900 text-xs truncate w-full",
|
|
113793
114680
|
title: node.type === "llm" ? node.name : void 0,
|
|
113794
|
-
"data-test-id":
|
|
113795
|
-
children: isGuardrailsNode ? node.type === "GuardrailsInputScan" ? "Input Guardrails Scanner" : "Output Guardrails Scanner" : node.type === "llm" ? "AI Model Call" : node.type === "tool" ? formatToolName(node.name) : node.name
|
|
114681
|
+
"data-test-id": `${callTypeTestId}_node_name`,
|
|
114682
|
+
children: isGuardrailsNode ? node.type === "GuardrailsInputScan" ? "Input Guardrails Scanner" : "Output Guardrails Scanner" : node.type === "llm" ? ((_a = node == null ? void 0 : node.metadata) == null ? void 0 : _a.isRoutedModel) ? `AI Model Call (${node.name})` : "AI Model Call" : node.type === "PostProcessor" ? "Response Processor" : node.type === "tool" ? formatToolName(node.name) : node.name
|
|
113796
114683
|
}
|
|
113797
114684
|
),
|
|
113798
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id":
|
|
114685
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id": `${callTypeTestId}_node_metadata`, children: [
|
|
113799
114686
|
node.type === "Agent" && (() => {
|
|
113800
|
-
var
|
|
113801
|
-
const llmChild = (
|
|
114687
|
+
var _a2;
|
|
114688
|
+
const llmChild = (_a2 = node.children) == null ? void 0 : _a2.find((child) => child.type === "llm");
|
|
113802
114689
|
if (llmChild == null ? void 0 : llmChild.name) {
|
|
113803
114690
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113804
114691
|
"span",
|
|
113805
114692
|
{
|
|
113806
114693
|
className: "text-[10px] text-gray-500 truncate max-w-[100px]",
|
|
113807
114694
|
title: llmChild.name,
|
|
113808
|
-
"data-test-id":
|
|
114695
|
+
"data-test-id": `${callTypeTestId}_node_model_name`,
|
|
113809
114696
|
children: llmChild.name
|
|
113810
114697
|
}
|
|
113811
114698
|
);
|
|
@@ -113813,7 +114700,7 @@ function DebugCard({
|
|
|
113813
114700
|
return null;
|
|
113814
114701
|
})(),
|
|
113815
114702
|
(node.type === "Agent" || node.type === "llm" || isGuardrailsNode) && (() => {
|
|
113816
|
-
var
|
|
114703
|
+
var _a2, _b, _c;
|
|
113817
114704
|
let llmUsage = node.llmUsage;
|
|
113818
114705
|
if (node.type === "Agent" && node.children) {
|
|
113819
114706
|
const llmChildren = node.children.filter((child) => child.type === "llm");
|
|
@@ -113835,10 +114722,10 @@ function DebugCard({
|
|
|
113835
114722
|
"span",
|
|
113836
114723
|
{
|
|
113837
114724
|
className: "text-[10px] text-gray-500 whitespace-nowrap cursor-help",
|
|
113838
|
-
title: `Input: ${((
|
|
114725
|
+
title: `Input: ${((_a2 = llmUsage.input_tokens) == null ? void 0 : _a2.toLocaleString()) || 0} tokens
|
|
113839
114726
|
Output: ${((_b = llmUsage.output_tokens) == null ? void 0 : _b.toLocaleString()) || 0} tokens
|
|
113840
114727
|
Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) || 0} tokens`,
|
|
113841
|
-
"data-test-id":
|
|
114728
|
+
"data-test-id": `${callTypeTestId}_node_tokens`,
|
|
113842
114729
|
children: [
|
|
113843
114730
|
llmUsage.total_tokens.toLocaleString(),
|
|
113844
114731
|
" Tokens"
|
|
@@ -113848,34 +114735,34 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
|
|
|
113848
114735
|
}
|
|
113849
114736
|
return null;
|
|
113850
114737
|
})(),
|
|
113851
|
-
node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id":
|
|
114738
|
+
node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id": `${callTypeTestId}_node_duration`, children: [
|
|
113852
114739
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-[12px] h-[12px]" }),
|
|
113853
114740
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-gray-500 whitespace-nowrap", children: formatDuration(node.duration) })
|
|
113854
114741
|
] })
|
|
113855
114742
|
] }),
|
|
113856
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id":
|
|
114743
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id": `${callTypeTestId}_node_status`, children: getStatusIcon() })
|
|
113857
114744
|
] })
|
|
113858
114745
|
] })
|
|
113859
114746
|
}
|
|
113860
114747
|
),
|
|
113861
|
-
isSelected && availableTabs.length > 0 && showDetailView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id":
|
|
113862
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-[-40px] left-[16px] w-[1px] border-l border-dashed border-gray-200 h-[calc(100%+40px)] z-[1]", "data-test-id":
|
|
113863
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-[4px] py-[8px] w-full", "data-test-id":
|
|
113864
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 rounded-[4px] p-[4px] inline-flex gap-[4px] mb-[8px] border border-gray-200", "data-test-id":
|
|
114748
|
+
isSelected && availableTabs.length > 0 && showDetailView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_detail_panel`, children: [
|
|
114749
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-[-40px] left-[16px] w-[1px] border-l border-dashed border-gray-200 h-[calc(100%+40px)] z-[1]", "data-test-id": `${callTypeTestId}_detail_panel_connector` }),
|
|
114750
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-[4px] py-[8px] w-full", "data-test-id": `${callTypeTestId}_detail_panel_content`, children: [
|
|
114751
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 rounded-[4px] p-[4px] inline-flex gap-[4px] mb-[8px] border border-gray-200", "data-test-id": `${callTypeTestId}_detail_panel_tabs`, children: getTabsForNodeType().map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113865
114752
|
"button",
|
|
113866
114753
|
{
|
|
113867
114754
|
onClick: () => handleTabClick(tab),
|
|
113868
114755
|
className: `px-[8px] py-[4px] text-xs font-medium rounded-[4px] text-gray-500 hover:text-gray-700 hover:shadow-tab hover:bg-white transition-colors ${activeTab === tab ? "bg-white text-gray-900 shadow-tab" : "text-gray-500 hover:text-gray-700 hover:bg-white"}`,
|
|
113869
|
-
"data-test-id":
|
|
114756
|
+
"data-test-id": `${callTypeTestId}_detail_panel_tab_${tab}`,
|
|
113870
114757
|
children: tab.charAt(0).toUpperCase() + tab.slice(1)
|
|
113871
114758
|
},
|
|
113872
114759
|
tab
|
|
113873
114760
|
)) }),
|
|
113874
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id":
|
|
114761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id": `${callTypeTestId}_detail_panel_tab_content`, children: renderTabContent() })
|
|
113875
114762
|
] })
|
|
113876
114763
|
] }),
|
|
113877
|
-
isExpanded && hasChildren && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id":
|
|
113878
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-[-40px] left-[16px] w-[1px] border-l border-dashed border-gray-200 h-[calc(100%+40px)] z-[1]", "data-test-id":
|
|
114764
|
+
isExpanded && hasChildren && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_children`, children: [
|
|
114765
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-[-40px] left-[16px] w-[1px] border-l border-dashed border-gray-200 h-[calc(100%+40px)] z-[1]", "data-test-id": `${callTypeTestId}_children_connector` }),
|
|
113879
114766
|
node.children.map((child, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113880
114767
|
DebugCard,
|
|
113881
114768
|
{
|
|
@@ -113911,6 +114798,7 @@ const DebugPanel = forwardRef(({
|
|
|
113911
114798
|
expansionMode = "none",
|
|
113912
114799
|
showExpansionControls = false,
|
|
113913
114800
|
defaultDetailView = true,
|
|
114801
|
+
runHeaderInputMode = "display",
|
|
113914
114802
|
apiConfig
|
|
113915
114803
|
} = config2;
|
|
113916
114804
|
console.log("🔧 DebugPanel - Config received:", {
|
|
@@ -113971,10 +114859,12 @@ const DebugPanel = forwardRef(({
|
|
|
113971
114859
|
}
|
|
113972
114860
|
}), []);
|
|
113973
114861
|
const sessionTree = useMemo(() => {
|
|
113974
|
-
const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId
|
|
114862
|
+
const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId, {
|
|
114863
|
+
runHeaderInputMode
|
|
114864
|
+
});
|
|
113975
114865
|
prevSessionTreeRef.current = tree;
|
|
113976
114866
|
return tree;
|
|
113977
|
-
}, [executionEvents, sessionId]);
|
|
114867
|
+
}, [executionEvents, sessionId, runHeaderInputMode]);
|
|
113978
114868
|
const getAllNodeIds = (tree) => {
|
|
113979
114869
|
const nodeIds = [];
|
|
113980
114870
|
const collectIds = (node) => {
|
|
@@ -114382,16 +115272,25 @@ const DebugPanel = forwardRef(({
|
|
|
114382
115272
|
const findFinalOutput = (nodes) => {
|
|
114383
115273
|
let lastOutput = void 0;
|
|
114384
115274
|
let routeToUserOutput = void 0;
|
|
115275
|
+
let postProcessorOutput = void 0;
|
|
114385
115276
|
const traverse = (nodeList) => {
|
|
114386
|
-
var _a, _b, _c, _d, _e;
|
|
115277
|
+
var _a, _b, _c, _d, _e, _f;
|
|
114387
115278
|
for (const node of nodeList) {
|
|
115279
|
+
if (node.type === "tool" && ((_a = node.metadata) == null ? void 0 : _a.type) === "PostProcessor" && node.output) {
|
|
115280
|
+
const ppOut = node.output;
|
|
115281
|
+
if (typeof ppOut === "object" && ppOut.output) {
|
|
115282
|
+
postProcessorOutput = typeof ppOut.output === "string" ? ppOut.output : JSON.stringify(ppOut.output);
|
|
115283
|
+
} else if (typeof ppOut === "string") {
|
|
115284
|
+
postProcessorOutput = ppOut;
|
|
115285
|
+
}
|
|
115286
|
+
}
|
|
114388
115287
|
if (node.type === "tool" && (node.name === "route_to_user" || node.name === "route_to_user")) {
|
|
114389
115288
|
if (node.output) {
|
|
114390
115289
|
if (typeof node.output === "string") {
|
|
114391
115290
|
routeToUserOutput = node.output;
|
|
114392
|
-
} else if ((
|
|
115291
|
+
} else if ((_b = node.output) == null ? void 0 : _b.message) {
|
|
114393
115292
|
routeToUserOutput = node.output.message;
|
|
114394
|
-
} else if ((
|
|
115293
|
+
} else if ((_c = node.output) == null ? void 0 : _c.result) {
|
|
114395
115294
|
routeToUserOutput = node.output.result;
|
|
114396
115295
|
}
|
|
114397
115296
|
}
|
|
@@ -114401,7 +115300,7 @@ const DebugPanel = forwardRef(({
|
|
|
114401
115300
|
(item) => (item == null ? void 0 : item.name) === "route_to_user" || (item == null ? void 0 : item.toolName) === "route_to_user"
|
|
114402
115301
|
);
|
|
114403
115302
|
if (routeItem) {
|
|
114404
|
-
if ((
|
|
115303
|
+
if ((_d = routeItem.args) == null ? void 0 : _d.message) {
|
|
114405
115304
|
routeToUserOutput = routeItem.args.message;
|
|
114406
115305
|
} else if (routeItem.message) {
|
|
114407
115306
|
routeToUserOutput = routeItem.message;
|
|
@@ -114412,9 +115311,9 @@ const DebugPanel = forwardRef(({
|
|
|
114412
115311
|
if (typeof node.output === "string") {
|
|
114413
115312
|
lastOutput = node.output;
|
|
114414
115313
|
} else if (!Array.isArray(node.output)) {
|
|
114415
|
-
if ((
|
|
115314
|
+
if ((_e = node.output) == null ? void 0 : _e.message) {
|
|
114416
115315
|
lastOutput = node.output.message;
|
|
114417
|
-
} else if ((
|
|
115316
|
+
} else if ((_f = node.output) == null ? void 0 : _f.result) {
|
|
114418
115317
|
lastOutput = node.output.result;
|
|
114419
115318
|
} else if (typeof node.output === "object") {
|
|
114420
115319
|
if (!node.output.name && !node.output.toolName) {
|
|
@@ -114429,7 +115328,7 @@ const DebugPanel = forwardRef(({
|
|
|
114429
115328
|
}
|
|
114430
115329
|
};
|
|
114431
115330
|
traverse(nodes);
|
|
114432
|
-
return routeToUserOutput || lastOutput;
|
|
115331
|
+
return postProcessorOutput || routeToUserOutput || lastOutput;
|
|
114433
115332
|
};
|
|
114434
115333
|
const outputFromNodes = run2.rootNodes ? findFinalOutput(run2.rootNodes) : void 0;
|
|
114435
115334
|
const finalOutput = outputFromNodes || run2.finalOutput;
|
|
@@ -141250,6 +142149,57 @@ function nodeContentToInline(content) {
|
|
|
141250
142149
|
};
|
|
141251
142150
|
});
|
|
141252
142151
|
}
|
|
142152
|
+
function getVariableContextAtPosition(editor, pos) {
|
|
142153
|
+
const { doc: doc2 } = editor.state;
|
|
142154
|
+
if (pos < 2 || pos > doc2.content.size) {
|
|
142155
|
+
return null;
|
|
142156
|
+
}
|
|
142157
|
+
const $pos = doc2.resolve(pos);
|
|
142158
|
+
const parent = $pos.parent;
|
|
142159
|
+
if (!parent.isTextblock) {
|
|
142160
|
+
return null;
|
|
142161
|
+
}
|
|
142162
|
+
const contentStart = $pos.start();
|
|
142163
|
+
let text = "";
|
|
142164
|
+
const posMap = [];
|
|
142165
|
+
parent.forEach((node, offset2) => {
|
|
142166
|
+
const nodeDocStart = contentStart + offset2;
|
|
142167
|
+
if (nodeDocStart >= pos) return;
|
|
142168
|
+
if (node.isText && node.text) {
|
|
142169
|
+
const charsToTake = Math.min(node.text.length, pos - nodeDocStart);
|
|
142170
|
+
for (let i2 = 0; i2 < charsToTake; i2++) {
|
|
142171
|
+
posMap.push(nodeDocStart + i2);
|
|
142172
|
+
text += node.text[i2];
|
|
142173
|
+
}
|
|
142174
|
+
}
|
|
142175
|
+
});
|
|
142176
|
+
const lastOpen = text.lastIndexOf("{{");
|
|
142177
|
+
if (lastOpen === -1) {
|
|
142178
|
+
return null;
|
|
142179
|
+
}
|
|
142180
|
+
const queryText = text.substring(lastOpen + 2);
|
|
142181
|
+
if (queryText.includes("}}")) {
|
|
142182
|
+
return null;
|
|
142183
|
+
}
|
|
142184
|
+
const triggerFrom = posMap[lastOpen];
|
|
142185
|
+
if (triggerFrom === void 0) {
|
|
142186
|
+
return null;
|
|
142187
|
+
}
|
|
142188
|
+
const trimmedQuery = /^\}*$/.test(queryText) ? "" : queryText;
|
|
142189
|
+
return { triggerFrom, query: trimmedQuery };
|
|
142190
|
+
}
|
|
142191
|
+
const TYPE_PREFIXES = ["env", "memory", "system", "content"];
|
|
142192
|
+
function inferVariableType(path) {
|
|
142193
|
+
const firstDot = path.indexOf(".");
|
|
142194
|
+
if (firstDot === -1) return "custom";
|
|
142195
|
+
const prefix2 = path.substring(0, firstDot).toLowerCase();
|
|
142196
|
+
return TYPE_PREFIXES.includes(prefix2) ? prefix2 : "custom";
|
|
142197
|
+
}
|
|
142198
|
+
function removeTypePrefix(path) {
|
|
142199
|
+
const type = inferVariableType(path);
|
|
142200
|
+
if (type === "custom") return path;
|
|
142201
|
+
return path.substring(type.length + 1);
|
|
142202
|
+
}
|
|
141253
142203
|
const buildVariableSyntax = (variableType, path) => {
|
|
141254
142204
|
if (variableType === "system" || variableType === "custom") {
|
|
141255
142205
|
return `{{${path}}}`;
|
|
@@ -141968,6 +142918,27 @@ const ChevronRightIcon = ({ size = 16, className }) => /* @__PURE__ */ jsxRuntim
|
|
|
141968
142918
|
)
|
|
141969
142919
|
}
|
|
141970
142920
|
);
|
|
142921
|
+
const AIStarIcon = ({ size = 14, className }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
142922
|
+
"svg",
|
|
142923
|
+
{
|
|
142924
|
+
width: size,
|
|
142925
|
+
height: size,
|
|
142926
|
+
viewBox: "0 0 14 14",
|
|
142927
|
+
fill: "none",
|
|
142928
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
142929
|
+
className,
|
|
142930
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
142931
|
+
"path",
|
|
142932
|
+
{
|
|
142933
|
+
d: "M2.10833 12.3167V9.4M2.10833 3.56667V0.65M0.65 2.10833H3.56667M0.65 10.8583H3.56667M7.06667 1.23333L6.05506 3.8635C5.89056 4.29122 5.8083 4.50508 5.68039 4.68497C5.56703 4.8444 5.42773 4.98369 5.2683 5.09706C5.08841 5.22497 4.87455 5.30722 4.44684 5.47173L1.81667 6.48333L4.44684 7.49494C4.87455 7.65944 5.08841 7.7417 5.2683 7.86961C5.42773 7.98297 5.56703 8.12227 5.68039 8.2817C5.8083 8.46159 5.89056 8.67545 6.05506 9.10316L7.06667 11.7333L8.07827 9.10316C8.24278 8.67545 8.32503 8.46159 8.45294 8.2817C8.56631 8.12227 8.7056 7.98297 8.86503 7.86961C9.04492 7.7417 9.25878 7.65944 9.6865 7.49494L12.3167 6.48333L9.6865 5.47173C9.25878 5.30722 9.04492 5.22497 8.86503 5.09706C8.7056 4.98369 8.56631 4.8444 8.45294 4.68497C8.32503 4.50508 8.24278 4.29122 8.07827 3.8635L7.06667 1.23333Z",
|
|
142934
|
+
stroke: "currentColor",
|
|
142935
|
+
strokeWidth: "1.3",
|
|
142936
|
+
strokeLinecap: "round",
|
|
142937
|
+
strokeLinejoin: "round"
|
|
142938
|
+
}
|
|
142939
|
+
)
|
|
142940
|
+
}
|
|
142941
|
+
);
|
|
141971
142942
|
const CATEGORY_ICON_MAP = {
|
|
141972
142943
|
agents: AgentsIcon,
|
|
141973
142944
|
tools: ToolsIcon,
|
|
@@ -142844,7 +143815,7 @@ const VariableMenu = ({
|
|
|
142844
143815
|
setCurrentPath(parsedQuery.path);
|
|
142845
143816
|
}
|
|
142846
143817
|
}, [parsedQuery.category, parsedQuery.path, activeCategory]);
|
|
142847
|
-
|
|
143818
|
+
useLayoutEffect(() => {
|
|
142848
143819
|
if (!menuRef.current) return;
|
|
142849
143820
|
const menuRect = menuRef.current.getBoundingClientRect();
|
|
142850
143821
|
const viewportWidth = window.innerWidth;
|
|
@@ -142865,7 +143836,7 @@ const VariableMenu = ({
|
|
|
142865
143836
|
newTop = padding;
|
|
142866
143837
|
}
|
|
142867
143838
|
setAdjustedPosition({ top: newTop, left: newLeft });
|
|
142868
|
-
}, [position]);
|
|
143839
|
+
}, [position, activeCategory, currentPath.length, query]);
|
|
142869
143840
|
const categories = [
|
|
142870
143841
|
{ id: "env", label: "Environment Variables", icon: VariableIcon, variables: envVariables },
|
|
142871
143842
|
{ id: "memory", label: "Memory", icon: MemoryIcon, variables: memoryVariables },
|
|
@@ -142940,13 +143911,21 @@ const VariableMenu = ({
|
|
|
142940
143911
|
}
|
|
142941
143912
|
}, [editorControlled]);
|
|
142942
143913
|
useEffect(() => {
|
|
143914
|
+
const isEventInsideMenu = (event) => {
|
|
143915
|
+
if (!menuRef.current) return false;
|
|
143916
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
143917
|
+
if (path.length > 0) {
|
|
143918
|
+
return path.includes(menuRef.current);
|
|
143919
|
+
}
|
|
143920
|
+
return menuRef.current.contains(event.target);
|
|
143921
|
+
};
|
|
142943
143922
|
const handleClickOutside = (e3) => {
|
|
142944
|
-
if (
|
|
143923
|
+
if (!isEventInsideMenu(e3)) {
|
|
142945
143924
|
onClose();
|
|
142946
143925
|
}
|
|
142947
143926
|
};
|
|
142948
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
142949
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
143927
|
+
document.addEventListener("mousedown", handleClickOutside, true);
|
|
143928
|
+
return () => document.removeEventListener("mousedown", handleClickOutside, true);
|
|
142950
143929
|
}, [onClose]);
|
|
142951
143930
|
useEffect(() => {
|
|
142952
143931
|
const handleKeyDown2 = (e3) => {
|
|
@@ -143033,6 +144012,10 @@ const VariableMenu = ({
|
|
|
143033
144012
|
"button",
|
|
143034
144013
|
{
|
|
143035
144014
|
type: "button",
|
|
144015
|
+
onMouseDown: (e3) => {
|
|
144016
|
+
e3.preventDefault();
|
|
144017
|
+
e3.stopPropagation();
|
|
144018
|
+
},
|
|
143036
144019
|
onClick: handleBack,
|
|
143037
144020
|
className: "flex items-center justify-center w-[24px] h-[24px] p-0 border-0 bg-[#F9FAFB] rounded-[4px] cursor-pointer text-[#667085] hover:bg-[#F2F4F7]",
|
|
143038
144021
|
"aria-label": "Go back",
|
|
@@ -143058,7 +144041,7 @@ const VariableMenu = ({
|
|
|
143058
144041
|
)
|
|
143059
144042
|
] }) }),
|
|
143060
144043
|
!activeCategory && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-[8px] pb-[4px] px-[12px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] leading-[16px] font-normal text-[#667085]", children: "Type to search or choose from:" }) }),
|
|
143061
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[16px] text-center text-[#667085] text-[14px]", children: "No items found" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: items.map((item, index) => {
|
|
144044
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[16px] text-center text-[#667085] text-[14px]", children: "No items found" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: items.map((item, index) => {
|
|
143062
144045
|
var _a;
|
|
143063
144046
|
const isCategory = "variables" in item;
|
|
143064
144047
|
const Icon = isCategory ? item.icon : getIconForType(item.type);
|
|
@@ -143067,7 +144050,11 @@ const VariableMenu = ({
|
|
|
143067
144050
|
"button",
|
|
143068
144051
|
{
|
|
143069
144052
|
type: "button",
|
|
143070
|
-
|
|
144053
|
+
onMouseDown: (e3) => {
|
|
144054
|
+
e3.preventDefault();
|
|
144055
|
+
e3.stopPropagation();
|
|
144056
|
+
handleItemClick(item);
|
|
144057
|
+
},
|
|
143071
144058
|
className: `flex items-center gap-[8px] w-full px-[12px] py-[8px] border-0 rounded-[4px] text-left cursor-pointer transition-colors duration-100 ${index === selectedIndex ? "bg-[#F9FAFB]" : "bg-transparent hover:bg-[#F9FAFB]"}`,
|
|
143072
144059
|
onMouseEnter: () => setSelectedIndex(index),
|
|
143073
144060
|
"data-test-id": `md-editor-variable-item-${isCategory ? item.id : item.id}`,
|
|
@@ -143643,7 +144630,9 @@ const UnifiedToolbar = ({
|
|
|
143643
144630
|
theme = "light",
|
|
143644
144631
|
disabled = false,
|
|
143645
144632
|
containerRef,
|
|
143646
|
-
followSelection = false
|
|
144633
|
+
followSelection = false,
|
|
144634
|
+
showDesignWithAI = false,
|
|
144635
|
+
onDesignWithAI
|
|
143647
144636
|
}) => {
|
|
143648
144637
|
const [position, setPosition] = useState(null);
|
|
143649
144638
|
const [isAtSelection, setIsAtSelection] = useState(false);
|
|
@@ -144001,7 +144990,30 @@ const UnifiedToolbar = ({
|
|
|
144001
144990
|
)
|
|
144002
144991
|
] }),
|
|
144003
144992
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarDivider$2, {}),
|
|
144004
|
-
|
|
144993
|
+
showDesignWithAI && onDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
144994
|
+
"button",
|
|
144995
|
+
{
|
|
144996
|
+
type: "button",
|
|
144997
|
+
onClick: (e3) => {
|
|
144998
|
+
e3.preventDefault();
|
|
144999
|
+
e3.stopPropagation();
|
|
145000
|
+
onDesignWithAI();
|
|
145001
|
+
},
|
|
145002
|
+
disabled,
|
|
145003
|
+
className: `
|
|
145004
|
+
flex items-center justify-center gap-1 px-3 py-1 rounded-[4px]
|
|
145005
|
+
text-[12px] leading-[16px] font-medium transition-colors duration-150 whitespace-nowrap
|
|
145006
|
+
border border-[#6A11CB] text-[#004EEB] hover:bg-[#EFF4FF]
|
|
145007
|
+
${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
|
|
145008
|
+
`,
|
|
145009
|
+
"data-id": "toolbar-design-with-ai",
|
|
145010
|
+
children: [
|
|
145011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AIStarIcon, { size: 14, className: "text-[#155EEF]" }),
|
|
145012
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Design with AI" })
|
|
145013
|
+
]
|
|
145014
|
+
}
|
|
145015
|
+
),
|
|
145016
|
+
showAIButton && onAIAction && !showDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: aiDropdownRef, className: "relative shrink-0", children: [
|
|
144005
145017
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
144006
145018
|
"button",
|
|
144007
145019
|
{
|
|
@@ -144116,7 +145128,8 @@ const ACTION_LABELS = {
|
|
|
144116
145128
|
"make-shorter": "Make Shorter",
|
|
144117
145129
|
"make-longer": "Make Longer",
|
|
144118
145130
|
"convert-to-yaml": "Convert to YAML",
|
|
144119
|
-
"custom": "Custom Modify"
|
|
145131
|
+
"custom": "Custom Modify",
|
|
145132
|
+
"generate": "Generate"
|
|
144120
145133
|
};
|
|
144121
145134
|
function calculateTextSimilarity(text1, text2) {
|
|
144122
145135
|
if (text1 === text2) return 1;
|
|
@@ -144150,7 +145163,7 @@ const AIDesignPanel = ({
|
|
|
144150
145163
|
sessionState,
|
|
144151
145164
|
sessionActions
|
|
144152
145165
|
}) => {
|
|
144153
|
-
var _a, _b;
|
|
145166
|
+
var _a, _b, _c;
|
|
144154
145167
|
const useSessionMode = !!sessionState && !!sessionActions;
|
|
144155
145168
|
const [messages, setMessages] = useState([]);
|
|
144156
145169
|
const [inputValue, setInputValue] = useState("");
|
|
@@ -144166,6 +145179,36 @@ const AIDesignPanel = ({
|
|
|
144166
145179
|
const modificationReason = useSessionMode ? sessionState.modificationReason : selectionModifiedReason;
|
|
144167
145180
|
const currentGeneratedContent = useSessionMode ? (_b = sessionState.session) == null ? void 0 : _b.lastGeneratedContent : generatedContent;
|
|
144168
145181
|
const displayMessages = useSessionMode ? convertSessionHistoryToMessages(sessionState) : messages;
|
|
145182
|
+
const [appliedFeedback, setAppliedFeedback] = useState(null);
|
|
145183
|
+
const [copiedFeedback, setCopiedFeedback] = useState(false);
|
|
145184
|
+
const [pendingApplyMode, setPendingApplyMode] = useState(null);
|
|
145185
|
+
const [autocopiedOnFail, setAutocopiedOnFail] = useState(false);
|
|
145186
|
+
const appliedTimerRef = useRef(null);
|
|
145187
|
+
const copiedTimerRef = useRef(null);
|
|
145188
|
+
const lastAssistantMsgId = useMemo(() => {
|
|
145189
|
+
const assistantMsgs = displayMessages.filter(
|
|
145190
|
+
(m3) => m3.type === "assistant" && !m3.isGenerating && !m3.isError
|
|
145191
|
+
);
|
|
145192
|
+
return assistantMsgs.length > 0 ? assistantMsgs[assistantMsgs.length - 1].id : null;
|
|
145193
|
+
}, [displayMessages]);
|
|
145194
|
+
const showInsertButton = isSelectionMode;
|
|
145195
|
+
const cursorInsertActive = useSessionMode && sessionState.cursorInsertPosition !== null;
|
|
145196
|
+
const replaceTooltip = isSelectionMode ? "Replace selection" : "Replace all";
|
|
145197
|
+
const insertTooltip = cursorInsertActive ? "Insert at cursor" : "Insert below selection";
|
|
145198
|
+
useEffect(() => {
|
|
145199
|
+
return () => {
|
|
145200
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145201
|
+
if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
|
|
145202
|
+
};
|
|
145203
|
+
}, []);
|
|
145204
|
+
useEffect(() => {
|
|
145205
|
+
if (isCurrentlyGenerating) {
|
|
145206
|
+
setAppliedFeedback(null);
|
|
145207
|
+
setCopiedFeedback(false);
|
|
145208
|
+
setPendingApplyMode(null);
|
|
145209
|
+
setAutocopiedOnFail(false);
|
|
145210
|
+
}
|
|
145211
|
+
}, [isCurrentlyGenerating]);
|
|
144169
145212
|
useEffect(() => {
|
|
144170
145213
|
var _a2;
|
|
144171
145214
|
(_a2 = messagesEndRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
@@ -144269,8 +145312,9 @@ const AIDesignPanel = ({
|
|
|
144269
145312
|
setGeneratedContent(response.refinedText);
|
|
144270
145313
|
onContentGenerated == null ? void 0 : onContentGenerated(true);
|
|
144271
145314
|
} catch (error) {
|
|
145315
|
+
const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
|
|
144272
145316
|
setMessages((prev) => prev.map(
|
|
144273
|
-
(msg) => msg.id === aiMsgId ? { ...msg, content:
|
|
145317
|
+
(msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
|
|
144274
145318
|
));
|
|
144275
145319
|
} finally {
|
|
144276
145320
|
setIsGenerating(false);
|
|
@@ -144312,8 +145356,9 @@ const AIDesignPanel = ({
|
|
|
144312
145356
|
setGeneratedContent(response.refinedText);
|
|
144313
145357
|
onContentGenerated == null ? void 0 : onContentGenerated(true);
|
|
144314
145358
|
} catch (error) {
|
|
145359
|
+
const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
|
|
144315
145360
|
setMessages((prev) => prev.map(
|
|
144316
|
-
(msg) => msg.id === aiMsgId ? { ...msg, content:
|
|
145361
|
+
(msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
|
|
144317
145362
|
));
|
|
144318
145363
|
} finally {
|
|
144319
145364
|
setIsGenerating(false);
|
|
@@ -144348,6 +145393,52 @@ const AIDesignPanel = ({
|
|
|
144348
145393
|
};
|
|
144349
145394
|
}
|
|
144350
145395
|
}, [useSessionMode, sessionActions, generatedContent, onReplace, isSelectionMode]);
|
|
145396
|
+
const handleCopy = useCallback(async () => {
|
|
145397
|
+
var _a2;
|
|
145398
|
+
const content = useSessionMode ? (_a2 = sessionState == null ? void 0 : sessionState.session) == null ? void 0 : _a2.lastGeneratedContent : generatedContent;
|
|
145399
|
+
if (content) {
|
|
145400
|
+
await navigator.clipboard.writeText(content);
|
|
145401
|
+
setCopiedFeedback(true);
|
|
145402
|
+
if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
|
|
145403
|
+
copiedTimerRef.current = setTimeout(() => setCopiedFeedback(false), 2e3);
|
|
145404
|
+
}
|
|
145405
|
+
}, [useSessionMode, sessionState, generatedContent]);
|
|
145406
|
+
const handleInsertWithFeedback = useCallback(() => {
|
|
145407
|
+
setPendingApplyMode("insert");
|
|
145408
|
+
setAutocopiedOnFail(false);
|
|
145409
|
+
handleInsert();
|
|
145410
|
+
}, [handleInsert]);
|
|
145411
|
+
const handleReplaceWithFeedback = useCallback(() => {
|
|
145412
|
+
setPendingApplyMode("replace");
|
|
145413
|
+
setAutocopiedOnFail(false);
|
|
145414
|
+
handleReplace();
|
|
145415
|
+
}, [handleReplace]);
|
|
145416
|
+
useEffect(() => {
|
|
145417
|
+
var _a2;
|
|
145418
|
+
if (!pendingApplyMode) return;
|
|
145419
|
+
if (useSessionMode) {
|
|
145420
|
+
if (sessionState.status === "applied") {
|
|
145421
|
+
setAppliedFeedback(pendingApplyMode);
|
|
145422
|
+
setPendingApplyMode(null);
|
|
145423
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145424
|
+
appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
|
|
145425
|
+
} else if (sessionState.isOriginalModified) {
|
|
145426
|
+
const content = (_a2 = sessionState.session) == null ? void 0 : _a2.lastGeneratedContent;
|
|
145427
|
+
if (content) {
|
|
145428
|
+
navigator.clipboard.writeText(content).catch(() => {
|
|
145429
|
+
});
|
|
145430
|
+
setAutocopiedOnFail(true);
|
|
145431
|
+
}
|
|
145432
|
+
setAppliedFeedback(null);
|
|
145433
|
+
setPendingApplyMode(null);
|
|
145434
|
+
}
|
|
145435
|
+
} else {
|
|
145436
|
+
setAppliedFeedback(pendingApplyMode);
|
|
145437
|
+
setPendingApplyMode(null);
|
|
145438
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145439
|
+
appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
|
|
145440
|
+
}
|
|
145441
|
+
}, [pendingApplyMode, useSessionMode, sessionState == null ? void 0 : sessionState.status, sessionState == null ? void 0 : sessionState.isOriginalModified, (_c = sessionState == null ? void 0 : sessionState.session) == null ? void 0 : _c.lastGeneratedContent]);
|
|
144351
145442
|
const handleStop = useCallback(() => {
|
|
144352
145443
|
if (useSessionMode) {
|
|
144353
145444
|
return;
|
|
@@ -144447,34 +145538,71 @@ const AIDesignPanel = ({
|
|
|
144447
145538
|
// Result - gray background bubble
|
|
144448
145539
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full", children: [
|
|
144449
145540
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-[#F2F4F7] rounded-xl p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-[#101828] leading-relaxed whitespace-pre-wrap", children: message.content }) }),
|
|
144450
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
144451
|
-
/*
|
|
144452
|
-
|
|
144453
|
-
{
|
|
144454
|
-
|
|
144455
|
-
|
|
144456
|
-
|
|
144457
|
-
|
|
144458
|
-
|
|
144459
|
-
|
|
144460
|
-
|
|
144461
|
-
|
|
144462
|
-
|
|
144463
|
-
"
|
|
144464
|
-
|
|
144465
|
-
|
|
144466
|
-
|
|
144467
|
-
|
|
144468
|
-
|
|
144469
|
-
|
|
144470
|
-
|
|
144471
|
-
|
|
144472
|
-
|
|
144473
|
-
|
|
144474
|
-
|
|
144475
|
-
|
|
144476
|
-
|
|
144477
|
-
|
|
145541
|
+
message.id === lastAssistantMsgId && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: appliedFeedback ? (
|
|
145542
|
+
/* Success feedback */
|
|
145543
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-[#12B76A] animate-[fadeIn_0.2s_ease-out]", children: [
|
|
145544
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, strokeWidth: 2.5 }),
|
|
145545
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: appliedFeedback === "replace" ? "Replaced" : "Inserted" }),
|
|
145546
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-[#667085] ml-1", children: [
|
|
145547
|
+
navigator.platform.includes("Mac") ? "⌘Z" : "Ctrl+Z",
|
|
145548
|
+
" to undo"
|
|
145549
|
+
] })
|
|
145550
|
+
] })
|
|
145551
|
+
) : isModified ? (
|
|
145552
|
+
/* Recovery UI -- original text was modified, apply would fail */
|
|
145553
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 animate-[fadeIn_0.2s_ease-out]", children: [
|
|
145554
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145555
|
+
"button",
|
|
145556
|
+
{
|
|
145557
|
+
type: "button",
|
|
145558
|
+
onClick: handleCopy,
|
|
145559
|
+
className: "px-2.5 py-0.5 text-sm font-medium rounded-full border transition-colors text-[#344054] bg-white border-[#EAECF0] hover:bg-gray-50 cursor-pointer flex items-center gap-1.5",
|
|
145560
|
+
children: copiedFeedback || autocopiedOnFail ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
145561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 12, className: "text-[#12B76A]" }),
|
|
145562
|
+
" Copied"
|
|
145563
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
145564
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 12 }),
|
|
145565
|
+
" Copy content"
|
|
145566
|
+
] })
|
|
145567
|
+
}
|
|
145568
|
+
) }),
|
|
145569
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-[#667085] mt-1.5", children: autocopiedOnFail ? "Content saved to clipboard. Paste manually or re-select text to try again." : `${modificationReason || "Original text changed"}. Copy content and paste manually, or re-select text.` })
|
|
145570
|
+
] })
|
|
145571
|
+
) : (
|
|
145572
|
+
/* Normal action buttons */
|
|
145573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
145574
|
+
(onReplace || useSessionMode) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145575
|
+
"button",
|
|
145576
|
+
{
|
|
145577
|
+
type: "button",
|
|
145578
|
+
onClick: handleReplaceWithFeedback,
|
|
145579
|
+
title: replaceTooltip,
|
|
145580
|
+
className: "px-2.5 py-0.5 text-sm font-medium rounded-full border transition-colors text-white bg-[#155EEF] border-[#155EEF] hover:bg-[#1849D6] cursor-pointer",
|
|
145581
|
+
children: "Replace"
|
|
145582
|
+
}
|
|
145583
|
+
),
|
|
145584
|
+
showInsertButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145585
|
+
"button",
|
|
145586
|
+
{
|
|
145587
|
+
type: "button",
|
|
145588
|
+
onClick: handleInsertWithFeedback,
|
|
145589
|
+
title: insertTooltip,
|
|
145590
|
+
className: "px-2.5 py-0.5 text-sm font-medium rounded-full border transition-colors text-[#344054] bg-white border-[#EAECF0] hover:bg-gray-50 cursor-pointer",
|
|
145591
|
+
children: "Insert"
|
|
145592
|
+
}
|
|
145593
|
+
),
|
|
145594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145595
|
+
"button",
|
|
145596
|
+
{
|
|
145597
|
+
type: "button",
|
|
145598
|
+
onClick: handleCopy,
|
|
145599
|
+
title: copiedFeedback ? "Copied!" : "Copy to clipboard",
|
|
145600
|
+
className: "p-1 text-[#667085] hover:text-[#344054] hover:bg-gray-100 rounded transition-colors cursor-pointer",
|
|
145601
|
+
children: copiedFeedback ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 })
|
|
145602
|
+
}
|
|
145603
|
+
)
|
|
145604
|
+
] })
|
|
145605
|
+
) })
|
|
144478
145606
|
] })
|
|
144479
145607
|
) })
|
|
144480
145608
|
) }, message.id)),
|
|
@@ -144557,6 +145685,32 @@ function convertSessionHistoryToMessages(sessionState) {
|
|
|
144557
145685
|
}
|
|
144558
145686
|
return messages;
|
|
144559
145687
|
}
|
|
145688
|
+
const EmptyStatePlaceholder = ({
|
|
145689
|
+
placeholder = "Write your agent definition here or type '/' to insert variables, agents, tools, memory & more",
|
|
145690
|
+
example,
|
|
145691
|
+
isFocused = false
|
|
145692
|
+
}) => {
|
|
145693
|
+
if (isFocused) return null;
|
|
145694
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
145695
|
+
"div",
|
|
145696
|
+
{
|
|
145697
|
+
className: "absolute inset-0 pointer-events-none px-[32px] py-[24px] overflow-hidden",
|
|
145698
|
+
"data-id": "md-editor-empty-state",
|
|
145699
|
+
children: [
|
|
145700
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3] mb-[8px]", children: placeholder }),
|
|
145701
|
+
example && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3]", children: example })
|
|
145702
|
+
]
|
|
145703
|
+
}
|
|
145704
|
+
);
|
|
145705
|
+
};
|
|
145706
|
+
const AgentDefinitionExample = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
145707
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mb-[14px]", children: "e.g., You are a meeting scheduler agent who coordinate sales meetings by checking team availability, matching prospect needs with appropriate sales specialists, and sending prep materials." }),
|
|
145708
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-disc ml-[21px]", children: [
|
|
145709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Match prospect needs with sales expertise" }) }),
|
|
145710
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Find optimal meeting times across calendars" }) }),
|
|
145711
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Distribute meeting agenda and materials" }) })
|
|
145712
|
+
] })
|
|
145713
|
+
] });
|
|
144560
145714
|
function hashString(str) {
|
|
144561
145715
|
let hash2 = 5381;
|
|
144562
145716
|
for (let i2 = 0; i2 < str.length; i2++) {
|
|
@@ -144766,7 +145920,8 @@ const initialState = {
|
|
|
144766
145920
|
modificationReason: "",
|
|
144767
145921
|
pendingSelection: null,
|
|
144768
145922
|
showSwitchBanner: false,
|
|
144769
|
-
error: null
|
|
145923
|
+
error: null,
|
|
145924
|
+
cursorInsertPosition: null
|
|
144770
145925
|
};
|
|
144771
145926
|
function refinementReducer(state, action) {
|
|
144772
145927
|
switch (action.type) {
|
|
@@ -144877,7 +146032,7 @@ function refinementReducer(state, action) {
|
|
|
144877
146032
|
}
|
|
144878
146033
|
case "APPLY_CONTENT": {
|
|
144879
146034
|
if (!state.session) return state;
|
|
144880
|
-
const { appliedContent } = action.payload;
|
|
146035
|
+
const { appliedContent, newFingerprint } = action.payload;
|
|
144881
146036
|
return {
|
|
144882
146037
|
...state,
|
|
144883
146038
|
status: "applied",
|
|
@@ -144885,8 +146040,11 @@ function refinementReducer(state, action) {
|
|
|
144885
146040
|
...state.session,
|
|
144886
146041
|
appliedContent,
|
|
144887
146042
|
applyCount: state.session.applyCount + 1,
|
|
144888
|
-
workingContent: appliedContent
|
|
146043
|
+
workingContent: appliedContent,
|
|
144889
146044
|
// For subsequent refinements
|
|
146045
|
+
// Update fingerprint to track the newly applied content's position
|
|
146046
|
+
// This enables subsequent iterations to work on the replaced content
|
|
146047
|
+
fingerprint: newFingerprint || state.session.fingerprint
|
|
144890
146048
|
},
|
|
144891
146049
|
isOriginalModified: false,
|
|
144892
146050
|
modificationReason: ""
|
|
@@ -144894,9 +146052,9 @@ function refinementReducer(state, action) {
|
|
|
144894
146052
|
}
|
|
144895
146053
|
case "SELECTION_CHANGED": {
|
|
144896
146054
|
if (!state.session) return state;
|
|
144897
|
-
const { fingerprint } = action.payload;
|
|
144898
|
-
const
|
|
144899
|
-
const newMode =
|
|
146055
|
+
const { fingerprint, explicitMode } = action.payload;
|
|
146056
|
+
const inferredMode = fingerprint.contextBefore === "" && fingerprint.contextAfter === "" ? "full-document" : "selection";
|
|
146057
|
+
const newMode = explicitMode ?? inferredMode;
|
|
144900
146058
|
return {
|
|
144901
146059
|
...state,
|
|
144902
146060
|
session: {
|
|
@@ -144904,8 +146062,10 @@ function refinementReducer(state, action) {
|
|
|
144904
146062
|
mode: newMode,
|
|
144905
146063
|
fingerprint,
|
|
144906
146064
|
workingContent: fingerprint.selectedMarkdown,
|
|
144907
|
-
// Reset
|
|
144908
|
-
appliedContent: null
|
|
146065
|
+
// Reset apply state since selection changed -- previous apply context is irrelevant
|
|
146066
|
+
appliedContent: null,
|
|
146067
|
+
applyCount: 0,
|
|
146068
|
+
lastGeneratedContent: null
|
|
144909
146069
|
},
|
|
144910
146070
|
// Clear modification state since we have a fresh selection
|
|
144911
146071
|
isOriginalModified: false,
|
|
@@ -144913,7 +146073,8 @@ function refinementReducer(state, action) {
|
|
|
144913
146073
|
// Only show switch banner if there was content and this is user-initiated selection change
|
|
144914
146074
|
// For now, keep it simple - don't show banner, just update context
|
|
144915
146075
|
pendingSelection: null,
|
|
144916
|
-
showSwitchBanner: false
|
|
146076
|
+
showSwitchBanner: false,
|
|
146077
|
+
cursorInsertPosition: null
|
|
144917
146078
|
};
|
|
144918
146079
|
}
|
|
144919
146080
|
case "CONFIRM_SWITCH": {
|
|
@@ -144982,6 +146143,11 @@ function refinementReducer(state, action) {
|
|
|
144982
146143
|
}
|
|
144983
146144
|
};
|
|
144984
146145
|
}
|
|
146146
|
+
case "SET_CURSOR_INSERT_POSITION":
|
|
146147
|
+
return {
|
|
146148
|
+
...state,
|
|
146149
|
+
cursorInsertPosition: action.payload.position
|
|
146150
|
+
};
|
|
144985
146151
|
default:
|
|
144986
146152
|
return state;
|
|
144987
146153
|
}
|
|
@@ -144991,7 +146157,8 @@ function useAIRefinementSession({
|
|
|
144991
146157
|
onRefine,
|
|
144992
146158
|
editorContent,
|
|
144993
146159
|
promptType,
|
|
144994
|
-
agentContext
|
|
146160
|
+
agentContext,
|
|
146161
|
+
onContentApplied
|
|
144995
146162
|
}) {
|
|
144996
146163
|
const [state, dispatch] = useReducer(refinementReducer, initialState);
|
|
144997
146164
|
const hasGeneratedContentRef = useRef(false);
|
|
@@ -145010,14 +146177,18 @@ function useAIRefinementSession({
|
|
|
145010
146177
|
});
|
|
145011
146178
|
if (editor) {
|
|
145012
146179
|
let fingerprint;
|
|
145013
|
-
|
|
146180
|
+
const isSelection = !!range3 && range3.from !== range3.to;
|
|
146181
|
+
if (isSelection) {
|
|
145014
146182
|
fingerprint = createSelectionFingerprint(editor, range3.from, range3.to);
|
|
145015
146183
|
} else {
|
|
145016
146184
|
fingerprint = createFullDocumentFingerprint(editor);
|
|
145017
146185
|
}
|
|
145018
146186
|
dispatch({
|
|
145019
146187
|
type: "SELECTION_CHANGED",
|
|
145020
|
-
payload: {
|
|
146188
|
+
payload: {
|
|
146189
|
+
fingerprint,
|
|
146190
|
+
explicitMode: isSelection ? "selection" : "full-document"
|
|
146191
|
+
}
|
|
145021
146192
|
});
|
|
145022
146193
|
}
|
|
145023
146194
|
}, [editor]);
|
|
@@ -145027,13 +146198,24 @@ function useAIRefinementSession({
|
|
|
145027
146198
|
}, []);
|
|
145028
146199
|
const startGeneration = useCallback(async (action, instruction) => {
|
|
145029
146200
|
if (!onRefine || !state.session) return;
|
|
145030
|
-
|
|
146201
|
+
let contextText;
|
|
146202
|
+
if (state.session.mode === "full-document" && state.session.applyCount > 0) {
|
|
146203
|
+
contextText = editorContent || state.session.appliedContent || state.session.workingContent;
|
|
146204
|
+
} else if (state.session.applyCount > 0) {
|
|
146205
|
+
contextText = state.session.appliedContent || state.session.workingContent;
|
|
146206
|
+
} else {
|
|
146207
|
+
contextText = state.session.lastGeneratedContent || state.session.workingContent;
|
|
146208
|
+
}
|
|
146209
|
+
if (!contextText) {
|
|
146210
|
+
contextText = editorContent;
|
|
146211
|
+
}
|
|
145031
146212
|
const actionLabels = {
|
|
145032
146213
|
"improve": "Improve",
|
|
145033
146214
|
"make-shorter": "Make Shorter",
|
|
145034
146215
|
"make-longer": "Make Longer",
|
|
145035
146216
|
"convert-to-yaml": "Convert to YAML",
|
|
145036
|
-
"custom": instruction || "Custom"
|
|
146217
|
+
"custom": instruction || "Custom",
|
|
146218
|
+
"generate": "Generate new content"
|
|
145037
146219
|
};
|
|
145038
146220
|
const displayMessage = instruction || actionLabels[action] || action;
|
|
145039
146221
|
const isFirstMessage = state.session.conversationHistory.length === 0;
|
|
@@ -145093,7 +146275,7 @@ function useAIRefinementSession({
|
|
|
145093
146275
|
"custom": instruction || "Custom"
|
|
145094
146276
|
};
|
|
145095
146277
|
const displayMessage = instruction || actionLabels[action] || action;
|
|
145096
|
-
const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent;
|
|
146278
|
+
const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent || editorContent;
|
|
145097
146279
|
const quotedText = contentForAI.length > 100 ? `${contentForAI.substring(0, 100)}...` : contentForAI;
|
|
145098
146280
|
dispatch({
|
|
145099
146281
|
type: "START_GENERATION",
|
|
@@ -145137,11 +146319,13 @@ function useAIRefinementSession({
|
|
|
145137
146319
|
if (!editor || !state.session || !state.session.lastGeneratedContent) return;
|
|
145138
146320
|
const refinedText = state.session.lastGeneratedContent;
|
|
145139
146321
|
let result;
|
|
146322
|
+
let newFingerprint;
|
|
145140
146323
|
if (state.session.mode === "full-document") {
|
|
145141
146324
|
try {
|
|
145142
146325
|
const parsed = markdownToEditorJson(refinedText);
|
|
145143
146326
|
editor.commands.setContent(parsed);
|
|
145144
146327
|
result = { success: true };
|
|
146328
|
+
newFingerprint = createFullDocumentFingerprint(editor);
|
|
145145
146329
|
} catch (error) {
|
|
145146
146330
|
result = {
|
|
145147
146331
|
success: false,
|
|
@@ -145161,10 +146345,17 @@ function useAIRefinementSession({
|
|
|
145161
146345
|
} else {
|
|
145162
146346
|
try {
|
|
145163
146347
|
const parsedContent = markdownToEditorJson(refinedText);
|
|
146348
|
+
const insertionStart = matchedRange.from;
|
|
145164
146349
|
if (mode === "replace") {
|
|
145165
146350
|
editor.chain().focus().setTextSelection(matchedRange).deleteSelection().insertContent(parsedContent).run();
|
|
146351
|
+
const newEndPos = editor.state.selection.to;
|
|
146352
|
+
newFingerprint = createSelectionFingerprint(editor, insertionStart, newEndPos);
|
|
145166
146353
|
} else {
|
|
145167
|
-
|
|
146354
|
+
const useCursorPos = state.cursorInsertPosition !== null && state.cursorInsertPosition !== matchedRange.to;
|
|
146355
|
+
const insertPos = useCursorPos ? state.cursorInsertPosition : matchedRange.to;
|
|
146356
|
+
editor.chain().focus().setTextSelection({ from: insertPos, to: insertPos }).insertContent("\n\n").insertContent(parsedContent).run();
|
|
146357
|
+
const newEndPos = editor.state.selection.to;
|
|
146358
|
+
newFingerprint = createSelectionFingerprint(editor, insertPos + 2, newEndPos);
|
|
145168
146359
|
}
|
|
145169
146360
|
result = { success: true };
|
|
145170
146361
|
} catch (error) {
|
|
@@ -145179,8 +146370,12 @@ function useAIRefinementSession({
|
|
|
145179
146370
|
if (result.success) {
|
|
145180
146371
|
dispatch({
|
|
145181
146372
|
type: "APPLY_CONTENT",
|
|
145182
|
-
payload: { mode, appliedContent: refinedText }
|
|
146373
|
+
payload: { mode, appliedContent: refinedText, newFingerprint }
|
|
145183
146374
|
});
|
|
146375
|
+
if (onContentApplied && editor) {
|
|
146376
|
+
const fullMarkdown = state.session.mode === "full-document" ? refinedText : editorJsonToMarkdown(editor.getJSON());
|
|
146377
|
+
onContentApplied(fullMarkdown);
|
|
146378
|
+
}
|
|
145184
146379
|
} else {
|
|
145185
146380
|
dispatch({
|
|
145186
146381
|
type: "SET_MODIFIED",
|
|
@@ -145190,7 +146385,7 @@ function useAIRefinementSession({
|
|
|
145190
146385
|
}
|
|
145191
146386
|
});
|
|
145192
146387
|
}
|
|
145193
|
-
}, [editor, state.session]);
|
|
146388
|
+
}, [editor, state.session, state.cursorInsertPosition, onContentApplied]);
|
|
145194
146389
|
const handleSelectionChange = useCallback((from2, to, _text) => {
|
|
145195
146390
|
if (!editor || !state.session) return;
|
|
145196
146391
|
if (from2 === to) return;
|
|
@@ -145202,7 +146397,7 @@ function useAIRefinementSession({
|
|
|
145202
146397
|
}
|
|
145203
146398
|
dispatch({
|
|
145204
146399
|
type: "SELECTION_CHANGED",
|
|
145205
|
-
payload: { fingerprint: newFingerprint }
|
|
146400
|
+
payload: { fingerprint: newFingerprint, explicitMode: "selection" }
|
|
145206
146401
|
});
|
|
145207
146402
|
}, [editor, state.session]);
|
|
145208
146403
|
const confirmSwitch = useCallback(() => {
|
|
@@ -145241,19 +146436,31 @@ function useAIRefinementSession({
|
|
|
145241
146436
|
useEffect(() => {
|
|
145242
146437
|
if (!editor || state.status === "idle") return;
|
|
145243
146438
|
const handleSelectionUpdate = () => {
|
|
146439
|
+
var _a, _b;
|
|
145244
146440
|
const { from: from2, to } = editor.state.selection;
|
|
145245
146441
|
const hasSelection2 = from2 !== to;
|
|
145246
|
-
if (
|
|
145247
|
-
|
|
146442
|
+
if (hasSelection2) {
|
|
146443
|
+
if (hasGeneratedContentRef.current) {
|
|
146444
|
+
const selectedText = editor.state.doc.textBetween(from2, to, " ", "\n");
|
|
146445
|
+
handleSelectionChange(from2, to, selectedText);
|
|
146446
|
+
}
|
|
146447
|
+
if (state.cursorInsertPosition !== null) {
|
|
146448
|
+
dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: null } });
|
|
146449
|
+
}
|
|
146450
|
+
} else if (((_a = state.session) == null ? void 0 : _a.mode) === "selection" && ((_b = state.session) == null ? void 0 : _b.fingerprint) && hasGeneratedContentRef.current) {
|
|
146451
|
+
const fp = state.session.fingerprint;
|
|
146452
|
+
const isOutside = from2 < fp.originalRange.from || from2 > fp.originalRange.to;
|
|
146453
|
+
const newPos = isOutside ? from2 : null;
|
|
146454
|
+
if (newPos !== state.cursorInsertPosition) {
|
|
146455
|
+
dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: newPos } });
|
|
146456
|
+
}
|
|
145248
146457
|
}
|
|
145249
|
-
const selectedText = editor.state.doc.textBetween(from2, to, " ", "\n");
|
|
145250
|
-
handleSelectionChange(from2, to, selectedText);
|
|
145251
146458
|
};
|
|
145252
146459
|
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
145253
146460
|
return () => {
|
|
145254
146461
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
145255
146462
|
};
|
|
145256
|
-
}, [editor, state.status, handleSelectionChange]);
|
|
146463
|
+
}, [editor, state.status, state.session, state.cursorInsertPosition, handleSelectionChange]);
|
|
145257
146464
|
const actions = {
|
|
145258
146465
|
openPanel,
|
|
145259
146466
|
closePanel,
|
|
@@ -145320,7 +146527,12 @@ const MDEditor = forwardRef(
|
|
|
145320
146527
|
onFocus,
|
|
145321
146528
|
onBlur,
|
|
145322
146529
|
onLoadSuggestions,
|
|
145323
|
-
suggestionsLoading: propSuggestionsLoading = false
|
|
146530
|
+
suggestionsLoading: propSuggestionsLoading = false,
|
|
146531
|
+
// Empty state props
|
|
146532
|
+
emptyStatePlaceholder,
|
|
146533
|
+
emptyStateExample,
|
|
146534
|
+
showDesignWithAI = false,
|
|
146535
|
+
onDesignWithAI
|
|
145324
146536
|
} = props;
|
|
145325
146537
|
const mergedSlashConfig = { ...DEFAULT_SLASH_COMMAND_CONFIG, ...slashCommandConfig };
|
|
145326
146538
|
const mergedAIConfig = { ...DEFAULT_AI_CONFIG, ...aiConfig };
|
|
@@ -145328,13 +146540,16 @@ const MDEditor = forwardRef(
|
|
|
145328
146540
|
const lastEmittedMarkdownRef = useRef("");
|
|
145329
146541
|
const isInternalUpdateRef = useRef(false);
|
|
145330
146542
|
const editorContainerRef = useRef(null);
|
|
146543
|
+
const skipRawSyncRef = useRef(false);
|
|
146544
|
+
const skipEditorSyncRef = useRef(false);
|
|
145331
146545
|
const [asyncSuggestions, setAsyncSuggestions] = useState(null);
|
|
145332
146546
|
const [suggestionsLoading, setSuggestionsLoading] = useState(false);
|
|
145333
146547
|
const [variableMenuOpen, setVariableMenuOpen] = useState(false);
|
|
145334
146548
|
const [variableMenuPosition, setVariableMenuPosition] = useState({ top: 0, left: 0 });
|
|
145335
146549
|
const [variableMenuQuery, setVariableMenuQuery] = useState("");
|
|
145336
|
-
const [editingVariableChip, setEditingVariableChip] = useState(null);
|
|
145337
146550
|
const variableTriggerPosRef = useRef(null);
|
|
146551
|
+
const hasVariableSuggestionsRef = useRef(false);
|
|
146552
|
+
const variableMenuOpenRef = useRef(false);
|
|
145338
146553
|
const [editorMode, setEditorMode] = useState("editor");
|
|
145339
146554
|
const [rawMarkdown, setRawMarkdown] = useState("");
|
|
145340
146555
|
const isRawMode = editorMode === "preview";
|
|
@@ -145378,12 +146593,7 @@ const MDEditor = forwardRef(
|
|
|
145378
146593
|
contentVariables: mergedContentVariables,
|
|
145379
146594
|
loading: finalSuggestionsLoading
|
|
145380
146595
|
};
|
|
145381
|
-
|
|
145382
|
-
agentsCount: mergedAgents.length,
|
|
145383
|
-
toolsCount: mergedTools.length,
|
|
145384
|
-
knowledgeCount: mergedKnowledge.length,
|
|
145385
|
-
hasAsyncSuggestions: !!asyncSuggestions
|
|
145386
|
-
});
|
|
146596
|
+
hasVariableSuggestionsRef.current = mergedEnvVariables.length > 0 || mergedMemoryVariables.length > 0 || mergedSystemVariables.length > 0 || mergedContentVariables.length > 0;
|
|
145387
146597
|
const defaultCategories = useMemo(() => {
|
|
145388
146598
|
const categories = [];
|
|
145389
146599
|
if (mergedAgents.length > 0) {
|
|
@@ -145448,21 +146658,6 @@ const MDEditor = forwardRef(
|
|
|
145448
146658
|
(variable, triggerPos) => {
|
|
145449
146659
|
if (!editorRef.current) return;
|
|
145450
146660
|
const editor2 = editorRef.current;
|
|
145451
|
-
if (editingVariableChip) {
|
|
145452
|
-
const { position, nodeSize: nodeSize2 } = editingVariableChip;
|
|
145453
|
-
editor2.chain().focus().deleteRange({ from: position, to: position + nodeSize2 }).insertContentAt(position, {
|
|
145454
|
-
type: "variableChip",
|
|
145455
|
-
attrs: {
|
|
145456
|
-
variableType: variable.type,
|
|
145457
|
-
path: variable.path,
|
|
145458
|
-
displayName: variable.name
|
|
145459
|
-
}
|
|
145460
|
-
}).run();
|
|
145461
|
-
setEditingVariableChip(null);
|
|
145462
|
-
setVariableMenuOpen(false);
|
|
145463
|
-
setVariableMenuQuery("");
|
|
145464
|
-
return;
|
|
145465
|
-
}
|
|
145466
146661
|
const deleteFrom = triggerPos ?? variableTriggerPosRef.current;
|
|
145467
146662
|
if (deleteFrom !== null) {
|
|
145468
146663
|
const { from: from2 } = editor2.state.selection;
|
|
@@ -145475,6 +146670,10 @@ const MDEditor = forwardRef(
|
|
|
145475
146670
|
displayName: variable.name
|
|
145476
146671
|
}
|
|
145477
146672
|
}).insertContent(" ").run();
|
|
146673
|
+
const posAfter = editor2.state.selection.from;
|
|
146674
|
+
if (posAfter + 2 <= editor2.state.doc.content.size && editor2.state.doc.textBetween(posAfter, posAfter + 2) === "}}") {
|
|
146675
|
+
editor2.chain().focus().deleteRange({ from: posAfter, to: posAfter + 2 }).run();
|
|
146676
|
+
}
|
|
145478
146677
|
} else {
|
|
145479
146678
|
editor2.chain().focus().insertContent({
|
|
145480
146679
|
type: "variableChip",
|
|
@@ -145489,7 +146688,19 @@ const MDEditor = forwardRef(
|
|
|
145489
146688
|
setVariableMenuQuery("");
|
|
145490
146689
|
variableTriggerPosRef.current = null;
|
|
145491
146690
|
},
|
|
145492
|
-
[
|
|
146691
|
+
[]
|
|
146692
|
+
);
|
|
146693
|
+
const handleVariableQueryChange = useCallback(
|
|
146694
|
+
(newQuery) => {
|
|
146695
|
+
setVariableMenuQuery(newQuery);
|
|
146696
|
+
if (!editorRef.current || variableTriggerPosRef.current === null) return;
|
|
146697
|
+
const editor2 = editorRef.current;
|
|
146698
|
+
const triggerPos = variableTriggerPosRef.current;
|
|
146699
|
+
const insertFrom = triggerPos + 2;
|
|
146700
|
+
const { from: from2 } = editor2.state.selection;
|
|
146701
|
+
editor2.chain().focus().deleteRange({ from: insertFrom, to: from2 }).insertContentAt(insertFrom, newQuery).run();
|
|
146702
|
+
},
|
|
146703
|
+
[]
|
|
145493
146704
|
);
|
|
145494
146705
|
const insertMention = useCallback(
|
|
145495
146706
|
(mention) => {
|
|
@@ -145524,14 +146735,23 @@ const MDEditor = forwardRef(
|
|
|
145524
146735
|
const json = editorRef.current.getJSON();
|
|
145525
146736
|
const markdown = editorJsonToMarkdown(json);
|
|
145526
146737
|
setRawMarkdown(markdown);
|
|
146738
|
+
lastEmittedMarkdownRef.current = markdown;
|
|
146739
|
+
skipRawSyncRef.current = true;
|
|
145527
146740
|
}
|
|
145528
146741
|
if (currentMode === "preview" && newMode === "editor") {
|
|
145529
146742
|
const parsedContent = markdownToEditorJson(rawMarkdown);
|
|
146743
|
+
isInternalUpdateRef.current = true;
|
|
145530
146744
|
editorRef.current.commands.setContent(parsedContent);
|
|
145531
146745
|
lastEmittedMarkdownRef.current = rawMarkdown;
|
|
146746
|
+
skipEditorSyncRef.current = true;
|
|
146747
|
+
onMarkdownChange == null ? void 0 : onMarkdownChange(rawMarkdown);
|
|
146748
|
+
if (onChange) {
|
|
146749
|
+
const doc2 = editorJsonToDocument(parsedContent);
|
|
146750
|
+
onChange(doc2, rawMarkdown);
|
|
146751
|
+
}
|
|
145532
146752
|
}
|
|
145533
146753
|
setEditorMode(newMode);
|
|
145534
|
-
}, [editorMode, rawMarkdown]);
|
|
146754
|
+
}, [editorMode, rawMarkdown, onChange, onMarkdownChange]);
|
|
145535
146755
|
const toggleRawMode = useCallback(() => {
|
|
145536
146756
|
handleModeChange(isRawMode ? "editor" : "preview");
|
|
145537
146757
|
}, [handleModeChange, isRawMode]);
|
|
@@ -145546,13 +146766,17 @@ const MDEditor = forwardRef(
|
|
|
145546
146766
|
dropcursor: false
|
|
145547
146767
|
}),
|
|
145548
146768
|
Placeholder.configure({
|
|
145549
|
-
placeholder: ({ node }) => {
|
|
146769
|
+
placeholder: ({ node, editor: placeholderEditor }) => {
|
|
146770
|
+
if (emptyStatePlaceholder && placeholderEditor.isEmpty) {
|
|
146771
|
+
return "";
|
|
146772
|
+
}
|
|
145550
146773
|
if (node.type.name === "heading") {
|
|
145551
146774
|
const level = node.attrs["level"];
|
|
145552
146775
|
return `Heading ${level}`;
|
|
145553
146776
|
}
|
|
145554
146777
|
if (node.type.name === "paragraph") {
|
|
145555
|
-
|
|
146778
|
+
const focusPlaceholder = "Type here or '/' to insert variables, agents, tools, memory & more";
|
|
146779
|
+
return placeholderEditor.isEmpty ? placeholder : focusPlaceholder;
|
|
145556
146780
|
}
|
|
145557
146781
|
return "";
|
|
145558
146782
|
},
|
|
@@ -145622,7 +146846,7 @@ const MDEditor = forwardRef(
|
|
|
145622
146846
|
);
|
|
145623
146847
|
}
|
|
145624
146848
|
return exts;
|
|
145625
|
-
}, [mergedFeatures, placeholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
|
|
146849
|
+
}, [mergedFeatures, placeholder, emptyStatePlaceholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
|
|
145626
146850
|
const editorRef = useRef(null);
|
|
145627
146851
|
const editor = useEditor({
|
|
145628
146852
|
extensions,
|
|
@@ -145656,12 +146880,24 @@ const MDEditor = forwardRef(
|
|
|
145656
146880
|
editorRef.current = editor;
|
|
145657
146881
|
}, [editor]);
|
|
145658
146882
|
const editorContent = editor ? editorJsonToMarkdown(editor.getJSON()) : "";
|
|
146883
|
+
const handleAIContentApplied = useCallback((markdown) => {
|
|
146884
|
+
lastEmittedMarkdownRef.current = markdown;
|
|
146885
|
+
if (onMarkdownChange) {
|
|
146886
|
+
onMarkdownChange(markdown);
|
|
146887
|
+
}
|
|
146888
|
+
if (onChange) {
|
|
146889
|
+
const json = markdownToEditorJson(markdown);
|
|
146890
|
+
const doc2 = editorJsonToDocument(json);
|
|
146891
|
+
onChange(doc2, markdown);
|
|
146892
|
+
}
|
|
146893
|
+
}, [onMarkdownChange, onChange]);
|
|
145659
146894
|
const { state: aiSessionState, actions: aiSessionActions, isOpen: aiPanelOpen } = useAIRefinementSession({
|
|
145660
146895
|
editor,
|
|
145661
146896
|
onRefine: onAIRefine,
|
|
145662
146897
|
editorContent,
|
|
145663
146898
|
promptType: props.promptType,
|
|
145664
|
-
agentContext: props.agentContext
|
|
146899
|
+
agentContext: props.agentContext,
|
|
146900
|
+
onContentApplied: handleAIContentApplied
|
|
145665
146901
|
});
|
|
145666
146902
|
const openAIRefine = useCallback(
|
|
145667
146903
|
(_type = "selection") => {
|
|
@@ -145688,6 +146924,22 @@ const MDEditor = forwardRef(
|
|
|
145688
146924
|
// autoGenerate
|
|
145689
146925
|
);
|
|
145690
146926
|
}, [aiSessionActions]);
|
|
146927
|
+
const handleDesignWithAI = useCallback(() => {
|
|
146928
|
+
aiSessionActions.openPanel(
|
|
146929
|
+
"generate",
|
|
146930
|
+
"",
|
|
146931
|
+
// Empty text since we're generating from scratch
|
|
146932
|
+
void 0,
|
|
146933
|
+
// No selection range
|
|
146934
|
+
void 0,
|
|
146935
|
+
// No custom prompt - AI will use context
|
|
146936
|
+
true
|
|
146937
|
+
// autoGenerate - start generation immediately
|
|
146938
|
+
);
|
|
146939
|
+
if (onDesignWithAI) {
|
|
146940
|
+
onDesignWithAI();
|
|
146941
|
+
}
|
|
146942
|
+
}, [aiSessionActions, onDesignWithAI]);
|
|
145691
146943
|
const handleCloseAIPanel = useCallback(() => {
|
|
145692
146944
|
if (editorRef.current) {
|
|
145693
146945
|
editorRef.current.setEditable(!readOnly);
|
|
@@ -145722,11 +146974,27 @@ const MDEditor = forwardRef(
|
|
|
145722
146974
|
from2
|
|
145723
146975
|
);
|
|
145724
146976
|
if (textAfterTrigger.includes("}}")) {
|
|
146977
|
+
const pathRaw = textAfterTrigger.split("}}")[0].trim();
|
|
146978
|
+
if (pathRaw) {
|
|
146979
|
+
const varType = inferVariableType(pathRaw);
|
|
146980
|
+
const cleanPath = removeTypePrefix(pathRaw);
|
|
146981
|
+
const displayName = cleanPath.split(".").pop() || cleanPath;
|
|
146982
|
+
editor.chain().focus().deleteRange({ from: triggerPos, to: from2 }).insertContent({
|
|
146983
|
+
type: "variableChip",
|
|
146984
|
+
attrs: {
|
|
146985
|
+
variableType: varType,
|
|
146986
|
+
path: cleanPath,
|
|
146987
|
+
displayName
|
|
146988
|
+
}
|
|
146989
|
+
}).insertContent(" ").run();
|
|
146990
|
+
}
|
|
145725
146991
|
setVariableMenuOpen(false);
|
|
145726
146992
|
variableTriggerPosRef.current = null;
|
|
145727
146993
|
return;
|
|
145728
146994
|
}
|
|
145729
146995
|
setVariableMenuQuery(textAfterTrigger);
|
|
146996
|
+
const coords = editor.view.coordsAtPos(from2);
|
|
146997
|
+
setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
|
|
145730
146998
|
};
|
|
145731
146999
|
const editorElement = editor.view.dom;
|
|
145732
147000
|
editorElement.addEventListener("keydown", handleKeyDown2);
|
|
@@ -145736,12 +147004,36 @@ const MDEditor = forwardRef(
|
|
|
145736
147004
|
editorElement.removeEventListener("input", handleInput);
|
|
145737
147005
|
};
|
|
145738
147006
|
}, [editor, mergedFeatures.variableChips, variableMenuOpen]);
|
|
147007
|
+
useEffect(() => {
|
|
147008
|
+
variableMenuOpenRef.current = variableMenuOpen;
|
|
147009
|
+
}, [variableMenuOpen]);
|
|
147010
|
+
useEffect(() => {
|
|
147011
|
+
if (!editor || !mergedFeatures.variableChips) return;
|
|
147012
|
+
const detectVariableContext = () => {
|
|
147013
|
+
if (variableMenuOpenRef.current) return;
|
|
147014
|
+
if (!hasVariableSuggestionsRef.current) return;
|
|
147015
|
+
const { from: from2 } = editor.state.selection;
|
|
147016
|
+
const context = getVariableContextAtPosition(editor, from2);
|
|
147017
|
+
if (context) {
|
|
147018
|
+
variableTriggerPosRef.current = context.triggerFrom;
|
|
147019
|
+
setVariableMenuQuery(context.query);
|
|
147020
|
+
const coords = editor.view.coordsAtPos(from2);
|
|
147021
|
+
setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
|
|
147022
|
+
setVariableMenuOpen(true);
|
|
147023
|
+
}
|
|
147024
|
+
};
|
|
147025
|
+
editor.on("focus", detectVariableContext);
|
|
147026
|
+
editor.on("selectionUpdate", detectVariableContext);
|
|
147027
|
+
return () => {
|
|
147028
|
+
editor.off("focus", detectVariableContext);
|
|
147029
|
+
editor.off("selectionUpdate", detectVariableContext);
|
|
147030
|
+
};
|
|
147031
|
+
}, [editor, mergedFeatures.variableChips]);
|
|
145739
147032
|
useEffect(() => {
|
|
145740
147033
|
if (!variableMenuOpen) return;
|
|
145741
147034
|
const handleKeyDown2 = (event) => {
|
|
145742
147035
|
if (event.key === "Escape") {
|
|
145743
147036
|
setVariableMenuOpen(false);
|
|
145744
|
-
setEditingVariableChip(null);
|
|
145745
147037
|
variableTriggerPosRef.current = null;
|
|
145746
147038
|
editor == null ? void 0 : editor.chain().focus().run();
|
|
145747
147039
|
}
|
|
@@ -145754,19 +147046,11 @@ const MDEditor = forwardRef(
|
|
|
145754
147046
|
const handleVariableChipEdit = (event) => {
|
|
145755
147047
|
const customEvent = event;
|
|
145756
147048
|
const { variableType, path, position, nodeSize: nodeSize2 } = customEvent.detail;
|
|
145757
|
-
const
|
|
145758
|
-
|
|
145759
|
-
|
|
145760
|
-
|
|
145761
|
-
|
|
145762
|
-
path
|
|
145763
|
-
});
|
|
145764
|
-
setVariableMenuPosition({
|
|
145765
|
-
top: coords.bottom + 8,
|
|
145766
|
-
left: coords.left
|
|
145767
|
-
});
|
|
145768
|
-
setVariableMenuQuery("");
|
|
145769
|
-
setVariableMenuOpen(true);
|
|
147049
|
+
const innerPath = variableType === "system" || variableType === "custom" ? path : `${variableType}.${path}`;
|
|
147050
|
+
const fullText = `{{${innerPath}}}`;
|
|
147051
|
+
editor.chain().focus().deleteRange({ from: position, to: position + nodeSize2 }).insertContentAt(position, fullText).run();
|
|
147052
|
+
const cursorPos = position + 2 + innerPath.length;
|
|
147053
|
+
editor.chain().focus().setTextSelection(cursorPos).run();
|
|
145770
147054
|
};
|
|
145771
147055
|
const editorElement = editor.view.dom;
|
|
145772
147056
|
editorElement.addEventListener("variable-chip-edit", handleVariableChipEdit);
|
|
@@ -145775,6 +147059,10 @@ const MDEditor = forwardRef(
|
|
|
145775
147059
|
};
|
|
145776
147060
|
}, [editor]);
|
|
145777
147061
|
useEffect(() => {
|
|
147062
|
+
if (skipEditorSyncRef.current) {
|
|
147063
|
+
skipEditorSyncRef.current = false;
|
|
147064
|
+
return;
|
|
147065
|
+
}
|
|
145778
147066
|
if (!editor || isInternalUpdateRef.current) {
|
|
145779
147067
|
isInternalUpdateRef.current = false;
|
|
145780
147068
|
return;
|
|
@@ -145806,6 +147094,10 @@ const MDEditor = forwardRef(
|
|
|
145806
147094
|
return () => clearTimeout(timer);
|
|
145807
147095
|
}, [rawMarkdown, isRawMode, onMarkdownChange, onChange]);
|
|
145808
147096
|
useEffect(() => {
|
|
147097
|
+
if (skipRawSyncRef.current) {
|
|
147098
|
+
skipRawSyncRef.current = false;
|
|
147099
|
+
return;
|
|
147100
|
+
}
|
|
145809
147101
|
if (isRawMode && markdownValue !== void 0 && markdownValue !== lastEmittedMarkdownRef.current) {
|
|
145810
147102
|
setRawMarkdown(markdownValue);
|
|
145811
147103
|
}
|
|
@@ -145946,6 +147238,13 @@ const MDEditor = forwardRef(
|
|
|
145946
147238
|
editor,
|
|
145947
147239
|
className: "k-md-editor__content w-full h-full"
|
|
145948
147240
|
}
|
|
147241
|
+
),
|
|
147242
|
+
(editor == null ? void 0 : editor.isEmpty) && emptyStatePlaceholder && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
147243
|
+
EmptyStatePlaceholder,
|
|
147244
|
+
{
|
|
147245
|
+
placeholder: emptyStatePlaceholder,
|
|
147246
|
+
example: emptyStateExample
|
|
147247
|
+
}
|
|
145949
147248
|
)
|
|
145950
147249
|
] })
|
|
145951
147250
|
) }),
|
|
@@ -145954,20 +147253,18 @@ const MDEditor = forwardRef(
|
|
|
145954
147253
|
{
|
|
145955
147254
|
position: variableMenuPosition,
|
|
145956
147255
|
query: variableMenuQuery,
|
|
145957
|
-
onQueryChange:
|
|
147256
|
+
onQueryChange: handleVariableQueryChange,
|
|
145958
147257
|
onSelect: (variable) => insertVariable(variable),
|
|
145959
147258
|
onClose: () => {
|
|
145960
147259
|
setVariableMenuOpen(false);
|
|
145961
147260
|
setVariableMenuQuery("");
|
|
145962
|
-
setEditingVariableChip(null);
|
|
145963
147261
|
variableTriggerPosRef.current = null;
|
|
145964
147262
|
},
|
|
145965
147263
|
envVariables: mergedEnvVariables,
|
|
145966
147264
|
memoryVariables: mergedMemoryVariables,
|
|
145967
147265
|
systemVariables: mergedSystemVariables,
|
|
145968
147266
|
contentVariables: mergedContentVariables,
|
|
145969
|
-
editorControlled:
|
|
145970
|
-
isEditMode: !!editingVariableChip
|
|
147267
|
+
editorControlled: true
|
|
145971
147268
|
}
|
|
145972
147269
|
)
|
|
145973
147270
|
] }),
|
|
@@ -145981,7 +147278,9 @@ const MDEditor = forwardRef(
|
|
|
145981
147278
|
onAIAction: isAIEnabled ? handleAIToolbarAction : void 0,
|
|
145982
147279
|
theme: theme === "dark" || theme.includes("dark") ? "dark" : "light",
|
|
145983
147280
|
disabled: readOnly,
|
|
145984
|
-
containerRef: editorContainerRef
|
|
147281
|
+
containerRef: editorContainerRef,
|
|
147282
|
+
showDesignWithAI: showDesignWithAI && (editor == null ? void 0 : editor.isEmpty),
|
|
147283
|
+
onDesignWithAI: isAIEnabled ? handleDesignWithAI : onDesignWithAI
|
|
145985
147284
|
}
|
|
145986
147285
|
)
|
|
145987
147286
|
] }),
|
|
@@ -149524,6 +150823,7 @@ export {
|
|
|
149524
150823
|
AIRefineDropdown,
|
|
149525
150824
|
AIRefineExtension,
|
|
149526
150825
|
AIRefinePanel,
|
|
150826
|
+
AgentDefinitionExample,
|
|
149527
150827
|
AgentListView,
|
|
149528
150828
|
AnalyticsChart,
|
|
149529
150829
|
AnalyticsTable,
|
|
@@ -149549,6 +150849,7 @@ export {
|
|
|
149549
150849
|
DetailPage,
|
|
149550
150850
|
DetailPageService,
|
|
149551
150851
|
EmptyState,
|
|
150852
|
+
EmptyStatePlaceholder,
|
|
149552
150853
|
EndpointsConfigService,
|
|
149553
150854
|
EnvironmentContext,
|
|
149554
150855
|
EnvironmentProvider,
|