agentic-ui-libs 1.2.0-beta.2 → 1.2.0-beta.20
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 +69 -4
- 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 +1554 -433
- package/dist/shared/ui/DataViewer.d.ts.map +1 -1
- package/dist/ui-libs.umd.js +1554 -433
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -30860,7 +30860,7 @@ class DashboardApiService {
|
|
|
30860
30860
|
listViewData.forEach((item) => {
|
|
30861
30861
|
if (item.modelName) {
|
|
30862
30862
|
options.push({
|
|
30863
|
-
label: item.modelName,
|
|
30863
|
+
label: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName,
|
|
30864
30864
|
value: item.modelName.replace(/[-\.]/g, ""),
|
|
30865
30865
|
icon: getModelIconPath2(item.provider),
|
|
30866
30866
|
// Use actual SVG icon path
|
|
@@ -35509,6 +35509,31 @@ class TracingApiService {
|
|
|
35509
35509
|
traces: data.traces || []
|
|
35510
35510
|
};
|
|
35511
35511
|
}
|
|
35512
|
+
/**
|
|
35513
|
+
* Get total count of traces matching filters (for pagination)
|
|
35514
|
+
* Endpoint: /tracing/api/trpc/traces.countAll
|
|
35515
|
+
*/
|
|
35516
|
+
async fetchTracesCount(projectId, filters, options = {}) {
|
|
35517
|
+
const input = {
|
|
35518
|
+
json: {
|
|
35519
|
+
projectId,
|
|
35520
|
+
filter: filters,
|
|
35521
|
+
searchQuery: options.searchQuery ?? null,
|
|
35522
|
+
searchType: options.searchType ?? ["id"],
|
|
35523
|
+
page: 0,
|
|
35524
|
+
limit: 0,
|
|
35525
|
+
orderBy: options.orderBy ?? null
|
|
35526
|
+
},
|
|
35527
|
+
meta: {
|
|
35528
|
+
values: this.buildMetaValues(filters)
|
|
35529
|
+
}
|
|
35530
|
+
};
|
|
35531
|
+
const url = this.buildTrpcUrl("traces.countAll", input);
|
|
35532
|
+
const data = await this.makeRequest(url);
|
|
35533
|
+
return {
|
|
35534
|
+
totalCount: (data == null ? void 0 : data.totalCount) ?? 0
|
|
35535
|
+
};
|
|
35536
|
+
}
|
|
35512
35537
|
/**
|
|
35513
35538
|
* Fetch metrics for multiple traces (latency, tokens, cost)
|
|
35514
35539
|
* Endpoint: /tracing/api/trpc/traces.metrics
|
|
@@ -36582,6 +36607,140 @@ function TokenBreakdownTooltip(props) {
|
|
|
36582
36607
|
] }) })
|
|
36583
36608
|
] });
|
|
36584
36609
|
}
|
|
36610
|
+
const CopyButton$1 = ({
|
|
36611
|
+
text,
|
|
36612
|
+
className = "",
|
|
36613
|
+
iconClassName = "",
|
|
36614
|
+
iconStyle,
|
|
36615
|
+
title = "Copy to clipboard",
|
|
36616
|
+
onCopySuccess,
|
|
36617
|
+
onCopyError,
|
|
36618
|
+
tooltipText = "Copied!",
|
|
36619
|
+
tooltipPosition = "bottom",
|
|
36620
|
+
size = "md"
|
|
36621
|
+
}) => {
|
|
36622
|
+
const [showTooltip, setShowTooltip] = useState(false);
|
|
36623
|
+
const getSizeClasses = () => {
|
|
36624
|
+
switch (size) {
|
|
36625
|
+
case "sm":
|
|
36626
|
+
return {
|
|
36627
|
+
button: "p-1",
|
|
36628
|
+
icon: "w-[12px] h-[12px]",
|
|
36629
|
+
tooltip: "text-xs py-1 px-2"
|
|
36630
|
+
};
|
|
36631
|
+
case "lg":
|
|
36632
|
+
return {
|
|
36633
|
+
button: "p-2",
|
|
36634
|
+
icon: "w-[20px] h-[20px]",
|
|
36635
|
+
tooltip: "text-sm py-2 px-3"
|
|
36636
|
+
};
|
|
36637
|
+
default:
|
|
36638
|
+
return {
|
|
36639
|
+
button: "p-1.5",
|
|
36640
|
+
icon: "w-[16px] h-[16px]",
|
|
36641
|
+
tooltip: "text-xs py-1 px-2"
|
|
36642
|
+
};
|
|
36643
|
+
}
|
|
36644
|
+
};
|
|
36645
|
+
const getTooltipPositionClasses = () => {
|
|
36646
|
+
const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
|
|
36647
|
+
switch (tooltipPosition) {
|
|
36648
|
+
case "bottom":
|
|
36649
|
+
return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
|
|
36650
|
+
case "left":
|
|
36651
|
+
return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
|
|
36652
|
+
case "right":
|
|
36653
|
+
return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
|
|
36654
|
+
default:
|
|
36655
|
+
return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
|
|
36656
|
+
}
|
|
36657
|
+
};
|
|
36658
|
+
const sizeClasses2 = getSizeClasses();
|
|
36659
|
+
const showCopyTooltip = useCallback(() => {
|
|
36660
|
+
setShowTooltip(true);
|
|
36661
|
+
setTimeout(() => setShowTooltip(false), 1e3);
|
|
36662
|
+
}, []);
|
|
36663
|
+
const copyToClipboard2 = useCallback(async () => {
|
|
36664
|
+
try {
|
|
36665
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
36666
|
+
await navigator.clipboard.writeText(text);
|
|
36667
|
+
showCopyTooltip();
|
|
36668
|
+
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
36669
|
+
return;
|
|
36670
|
+
}
|
|
36671
|
+
const textArea = document.createElement("textarea");
|
|
36672
|
+
textArea.value = text;
|
|
36673
|
+
textArea.style.position = "fixed";
|
|
36674
|
+
textArea.style.left = "-999999px";
|
|
36675
|
+
textArea.style.top = "-999999px";
|
|
36676
|
+
document.body.appendChild(textArea);
|
|
36677
|
+
textArea.focus();
|
|
36678
|
+
textArea.select();
|
|
36679
|
+
try {
|
|
36680
|
+
document.execCommand("copy");
|
|
36681
|
+
showCopyTooltip();
|
|
36682
|
+
onCopySuccess == null ? void 0 : onCopySuccess();
|
|
36683
|
+
} catch (err) {
|
|
36684
|
+
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
36685
|
+
console.warn("Copy to clipboard failed:", error);
|
|
36686
|
+
onCopyError == null ? void 0 : onCopyError(error);
|
|
36687
|
+
} finally {
|
|
36688
|
+
document.body.removeChild(textArea);
|
|
36689
|
+
}
|
|
36690
|
+
} catch (err) {
|
|
36691
|
+
const error = err instanceof Error ? err : new Error("Copy failed");
|
|
36692
|
+
console.warn("Copy to clipboard failed:", error);
|
|
36693
|
+
onCopyError == null ? void 0 : onCopyError(error);
|
|
36694
|
+
}
|
|
36695
|
+
}, [text, showCopyTooltip, onCopySuccess, onCopyError]);
|
|
36696
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
|
|
36697
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36698
|
+
"button",
|
|
36699
|
+
{
|
|
36700
|
+
onClick: copyToClipboard2,
|
|
36701
|
+
className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
|
|
36702
|
+
title,
|
|
36703
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
|
|
36704
|
+
}
|
|
36705
|
+
),
|
|
36706
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36707
|
+
"div",
|
|
36708
|
+
{
|
|
36709
|
+
className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
|
|
36710
|
+
style: {
|
|
36711
|
+
visibility: showTooltip ? "visible" : "hidden"
|
|
36712
|
+
},
|
|
36713
|
+
children: tooltipText
|
|
36714
|
+
}
|
|
36715
|
+
)
|
|
36716
|
+
] });
|
|
36717
|
+
};
|
|
36718
|
+
function CopyableId({ value, truncateLength = 30 }) {
|
|
36719
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "copyable-id-wrapper", title: value, children: [
|
|
36720
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: TracingUtils.truncate(value, truncateLength) }),
|
|
36721
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36722
|
+
"span",
|
|
36723
|
+
{
|
|
36724
|
+
className: "copyable-id-btn",
|
|
36725
|
+
onClick: (e3) => {
|
|
36726
|
+
e3.stopPropagation();
|
|
36727
|
+
e3.preventDefault();
|
|
36728
|
+
},
|
|
36729
|
+
onMouseDown: (e3) => e3.stopPropagation(),
|
|
36730
|
+
onMouseUp: (e3) => e3.stopPropagation(),
|
|
36731
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36732
|
+
CopyButton$1,
|
|
36733
|
+
{
|
|
36734
|
+
text: value,
|
|
36735
|
+
size: "sm",
|
|
36736
|
+
title: "Copy to clipboard",
|
|
36737
|
+
iconClassName: "text-[#667085]"
|
|
36738
|
+
}
|
|
36739
|
+
)
|
|
36740
|
+
}
|
|
36741
|
+
)
|
|
36742
|
+
] });
|
|
36743
|
+
}
|
|
36585
36744
|
function Shimmer$2({ className = "", children }) {
|
|
36586
36745
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-[#F2F4F7] rounded ${className}`, children });
|
|
36587
36746
|
}
|
|
@@ -104592,6 +104751,9 @@ function TracingTable(props) {
|
|
|
104592
104751
|
}, [columns]);
|
|
104593
104752
|
const handleRowClick = useCallback(
|
|
104594
104753
|
(event) => {
|
|
104754
|
+
var _a;
|
|
104755
|
+
const target = (_a = event.event) == null ? void 0 : _a.target;
|
|
104756
|
+
if (target == null ? void 0 : target.closest(".copyable-id-btn")) return;
|
|
104595
104757
|
if (onRowClick && event.data) {
|
|
104596
104758
|
onRowClick(event.data);
|
|
104597
104759
|
}
|
|
@@ -104688,9 +104850,10 @@ function TracingTable(props) {
|
|
|
104688
104850
|
onClick: goToFirstPage,
|
|
104689
104851
|
disabled: currentPage === 0,
|
|
104690
104852
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
104853
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104691
104854
|
title: "First page",
|
|
104692
104855
|
"data-test-id": "tracing-table-first-page-btn",
|
|
104693
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, {
|
|
104856
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, { size: 16 })
|
|
104694
104857
|
}
|
|
104695
104858
|
),
|
|
104696
104859
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -104699,12 +104862,13 @@ function TracingTable(props) {
|
|
|
104699
104862
|
onClick: goToPreviousPage,
|
|
104700
104863
|
disabled: currentPage === 0,
|
|
104701
104864
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
104865
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104702
104866
|
title: "Previous page",
|
|
104703
104867
|
"data-test-id": "tracing-table-prev-page-btn",
|
|
104704
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, {
|
|
104868
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { size: 16 })
|
|
104705
104869
|
}
|
|
104706
104870
|
),
|
|
104707
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-4 py-2 text-sm
|
|
104871
|
+
/* @__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
104872
|
"Page ",
|
|
104709
104873
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: currentPage + 1 }),
|
|
104710
104874
|
" of",
|
|
@@ -104717,9 +104881,10 @@ function TracingTable(props) {
|
|
|
104717
104881
|
onClick: goToNextPage,
|
|
104718
104882
|
disabled: currentPage >= totalPages - 1,
|
|
104719
104883
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
104884
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104720
104885
|
title: "Next page",
|
|
104721
104886
|
"data-test-id": "tracing-table-next-page-btn",
|
|
104722
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, {
|
|
104887
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 16 })
|
|
104723
104888
|
}
|
|
104724
104889
|
),
|
|
104725
104890
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -104728,13 +104893,14 @@ function TracingTable(props) {
|
|
|
104728
104893
|
onClick: goToLastPage,
|
|
104729
104894
|
disabled: currentPage >= totalPages - 1,
|
|
104730
104895
|
className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
104896
|
+
style: { color: "var(--colors-gray-light-mode-700, #344054)" },
|
|
104731
104897
|
title: "Last page",
|
|
104732
104898
|
"data-test-id": "tracing-table-last-page-btn",
|
|
104733
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, {
|
|
104899
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, { size: 16 })
|
|
104734
104900
|
}
|
|
104735
104901
|
)
|
|
104736
104902
|
] }),
|
|
104737
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center text-sm
|
|
104903
|
+
/* @__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
104904
|
"Showing ",
|
|
104739
104905
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: startRow }),
|
|
104740
104906
|
" to",
|
|
@@ -104762,9 +104928,12 @@ function TracingListHeader(props) {
|
|
|
104762
104928
|
timeRangePresetLabel,
|
|
104763
104929
|
onTimeRangeChange,
|
|
104764
104930
|
filters,
|
|
104931
|
+
filterColumns: filterColumnsProp,
|
|
104765
104932
|
onFiltersClick,
|
|
104766
104933
|
onModifyColumnsClick,
|
|
104767
104934
|
showModifyColumns = true,
|
|
104935
|
+
onClearFilters,
|
|
104936
|
+
onRemoveFilter,
|
|
104768
104937
|
onRefresh,
|
|
104769
104938
|
isRefreshing = false
|
|
104770
104939
|
} = props;
|
|
@@ -104809,6 +104978,50 @@ function TracingListHeader(props) {
|
|
|
104809
104978
|
}
|
|
104810
104979
|
return `Searches in ${fields}.`;
|
|
104811
104980
|
};
|
|
104981
|
+
const activeFilters = filters.filter(TracingUtils.isFilterActive);
|
|
104982
|
+
const [filtersExpanded, setFiltersExpanded] = useState(false);
|
|
104983
|
+
const [isOverflowing, setIsOverflowing] = useState(false);
|
|
104984
|
+
const chipsContainerRef = useRef(null);
|
|
104985
|
+
const checkOverflow = useCallback(() => {
|
|
104986
|
+
const el = chipsContainerRef.current;
|
|
104987
|
+
if (!el) return;
|
|
104988
|
+
setIsOverflowing(el.scrollHeight > el.clientHeight);
|
|
104989
|
+
}, []);
|
|
104990
|
+
useEffect(() => {
|
|
104991
|
+
checkOverflow();
|
|
104992
|
+
window.addEventListener("resize", checkOverflow);
|
|
104993
|
+
return () => window.removeEventListener("resize", checkOverflow);
|
|
104994
|
+
}, [checkOverflow, activeFilters.length]);
|
|
104995
|
+
const getFilterChipLabel = (filter) => {
|
|
104996
|
+
const col = filterColumnsProp == null ? void 0 : filterColumnsProp.find((c3) => c3.field === filter.column);
|
|
104997
|
+
const label = (col == null ? void 0 : col.label) ?? filter.column;
|
|
104998
|
+
let valueText;
|
|
104999
|
+
if (filter.type === "datetime") {
|
|
105000
|
+
valueText = new Date(filter.value).toLocaleDateString();
|
|
105001
|
+
} else if (filter.type === "number") {
|
|
105002
|
+
valueText = parseFloat(filter.value).toLocaleString();
|
|
105003
|
+
} else if (Array.isArray(filter.value)) {
|
|
105004
|
+
valueText = filter.value.length <= 2 ? filter.value.join(", ") : `${filter.value.length} selected`;
|
|
105005
|
+
} else {
|
|
105006
|
+
valueText = String(filter.value ?? "");
|
|
105007
|
+
}
|
|
105008
|
+
const shortOp = {
|
|
105009
|
+
"=": "",
|
|
105010
|
+
"!=": "≠ ",
|
|
105011
|
+
">": "> ",
|
|
105012
|
+
">=": "≥ ",
|
|
105013
|
+
"<": "< ",
|
|
105014
|
+
"<=": "≤ ",
|
|
105015
|
+
"contains": "~ ",
|
|
105016
|
+
"does not contain": "!~ ",
|
|
105017
|
+
"starts with": "starts ",
|
|
105018
|
+
"ends with": "ends ",
|
|
105019
|
+
"any of": "",
|
|
105020
|
+
"none of": "not "
|
|
105021
|
+
};
|
|
105022
|
+
const op = shortOp[filter.operator] ?? `${filter.operator} `;
|
|
105023
|
+
return `${label}: ${op}${valueText}`;
|
|
105024
|
+
};
|
|
104812
105025
|
const handleDateRangeChange = (dateRange, presetLabel) => {
|
|
104813
105026
|
if (dateRange && dateRange.from && dateRange.to) {
|
|
104814
105027
|
const fromDate = dateRange.from;
|
|
@@ -104961,7 +105174,66 @@ function TracingListHeader(props) {
|
|
|
104961
105174
|
}
|
|
104962
105175
|
)
|
|
104963
105176
|
] })
|
|
104964
|
-
] })
|
|
105177
|
+
] }),
|
|
105178
|
+
activeFilters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105179
|
+
"div",
|
|
105180
|
+
{
|
|
105181
|
+
className: "flex items-start gap-[8px] border border-gray-200 rounded-[8px] px-[12px] py-[8px]",
|
|
105182
|
+
"data-test-id": "tracing-filter-chips",
|
|
105183
|
+
children: [
|
|
105184
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[28px] text-gray-500 shrink-0", children: "Filters" }),
|
|
105185
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105186
|
+
"div",
|
|
105187
|
+
{
|
|
105188
|
+
ref: chipsContainerRef,
|
|
105189
|
+
className: `flex items-center gap-[8px] flex-wrap flex-1 min-w-0 ${!filtersExpanded ? "max-h-[28px] overflow-hidden" : ""}`,
|
|
105190
|
+
children: activeFilters.map((filter, idx) => {
|
|
105191
|
+
const originalIndex = filters.indexOf(filter);
|
|
105192
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105193
|
+
"div",
|
|
105194
|
+
{
|
|
105195
|
+
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]",
|
|
105196
|
+
children: [
|
|
105197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-medium", children: getFilterChipLabel(filter) }),
|
|
105198
|
+
onRemoveFilter && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105199
|
+
"button",
|
|
105200
|
+
{
|
|
105201
|
+
onClick: () => onRemoveFilter(originalIndex),
|
|
105202
|
+
className: "flex items-center justify-center shrink-0 text-blue-400 hover:text-blue-700 transition-colors",
|
|
105203
|
+
title: "Remove filter",
|
|
105204
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[14px] h-[14px]", strokeWidth: 2 })
|
|
105205
|
+
}
|
|
105206
|
+
)
|
|
105207
|
+
]
|
|
105208
|
+
},
|
|
105209
|
+
`chip-${idx}`
|
|
105210
|
+
);
|
|
105211
|
+
})
|
|
105212
|
+
}
|
|
105213
|
+
),
|
|
105214
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] shrink-0 leading-[28px]", children: [
|
|
105215
|
+
(isOverflowing || filtersExpanded) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105216
|
+
"button",
|
|
105217
|
+
{
|
|
105218
|
+
onClick: () => setFiltersExpanded((prev) => !prev),
|
|
105219
|
+
className: "text-[12px] font-medium text-blue-600 hover:text-blue-800 transition-colors whitespace-nowrap",
|
|
105220
|
+
"data-test-id": "tracing-filter-toggle",
|
|
105221
|
+
children: filtersExpanded ? "View less" : "View all"
|
|
105222
|
+
}
|
|
105223
|
+
),
|
|
105224
|
+
onClearFilters && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105225
|
+
"button",
|
|
105226
|
+
{
|
|
105227
|
+
onClick: onClearFilters,
|
|
105228
|
+
className: "text-[12px] font-medium text-gray-500 hover:text-gray-700 transition-colors whitespace-nowrap",
|
|
105229
|
+
"data-test-id": "tracing-filter-clear-all",
|
|
105230
|
+
children: "Clear all"
|
|
105231
|
+
}
|
|
105232
|
+
)
|
|
105233
|
+
] })
|
|
105234
|
+
]
|
|
105235
|
+
}
|
|
105236
|
+
)
|
|
104965
105237
|
] });
|
|
104966
105238
|
}
|
|
104967
105239
|
function ColumnCustomization(props) {
|
|
@@ -105448,6 +105720,8 @@ function FilterPanel(props) {
|
|
|
105448
105720
|
] })
|
|
105449
105721
|
] });
|
|
105450
105722
|
}
|
|
105723
|
+
const TRACE_PII_DISPLAY_USER_MESSAGE_KEY = "piiDisplayUserMessage";
|
|
105724
|
+
const TRACE_PII_DISPLAY_APP_RESPONSE_KEY = "piiDisplayAppResponse";
|
|
105451
105725
|
class TraceTreeService {
|
|
105452
105726
|
/**
|
|
105453
105727
|
* Build a hierarchical tree from a flat list of observations
|
|
@@ -105620,43 +105894,205 @@ class TraceTreeService {
|
|
|
105620
105894
|
});
|
|
105621
105895
|
}
|
|
105622
105896
|
/**
|
|
105623
|
-
* Extract user message from trace input
|
|
105897
|
+
* Extract user message from trace input for display.
|
|
105898
|
+
* Handles string, object with message/content/text/query, and messages array (e.g. voice/chat).
|
|
105899
|
+
*/
|
|
105900
|
+
/**
|
|
105901
|
+
* Parse trace metadata from API (string or object) into a plain object.
|
|
105902
|
+
*/
|
|
105903
|
+
static parseTraceMetadata(metadata) {
|
|
105904
|
+
if (metadata === null || metadata === void 0) {
|
|
105905
|
+
return {};
|
|
105906
|
+
}
|
|
105907
|
+
if (typeof metadata === "string") {
|
|
105908
|
+
try {
|
|
105909
|
+
return JSON.parse(metadata);
|
|
105910
|
+
} catch {
|
|
105911
|
+
return {};
|
|
105912
|
+
}
|
|
105913
|
+
}
|
|
105914
|
+
if (typeof metadata === "object" && !Array.isArray(metadata)) {
|
|
105915
|
+
return metadata;
|
|
105916
|
+
}
|
|
105917
|
+
return {};
|
|
105918
|
+
}
|
|
105919
|
+
/**
|
|
105920
|
+
* Read PII display strings from Langfuse/Kore trace metadata (if present).
|
|
105624
105921
|
*/
|
|
105922
|
+
static extractPiiDisplayFromTraceMetadata(metadata) {
|
|
105923
|
+
const obj = this.parseTraceMetadata(metadata);
|
|
105924
|
+
const userRaw = obj[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
|
|
105925
|
+
const appRaw = obj[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
|
|
105926
|
+
const result = {};
|
|
105927
|
+
if (typeof userRaw === "string" && userRaw.length > 0) {
|
|
105928
|
+
result.displayUserMessage = userRaw;
|
|
105929
|
+
}
|
|
105930
|
+
if (typeof appRaw === "string" && appRaw.length > 0) {
|
|
105931
|
+
result.displayAppResponse = appRaw;
|
|
105932
|
+
}
|
|
105933
|
+
return result;
|
|
105934
|
+
}
|
|
105935
|
+
/**
|
|
105936
|
+
* Some tracing APIs expose custom PII display keys on trace root as well as under metadata.
|
|
105937
|
+
*/
|
|
105938
|
+
static extractPiiDisplayFromApiTrace(trace) {
|
|
105939
|
+
const fromMeta = this.extractPiiDisplayFromTraceMetadata(trace.metadata);
|
|
105940
|
+
const userTop = trace[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
|
|
105941
|
+
const appTop = trace[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
|
|
105942
|
+
const fromTop = {};
|
|
105943
|
+
if (typeof userTop === "string" && userTop.length > 0) {
|
|
105944
|
+
fromTop.displayUserMessage = userTop;
|
|
105945
|
+
}
|
|
105946
|
+
if (typeof appTop === "string" && appTop.length > 0) {
|
|
105947
|
+
fromTop.displayAppResponse = appTop;
|
|
105948
|
+
}
|
|
105949
|
+
return {
|
|
105950
|
+
displayUserMessage: fromTop.displayUserMessage ?? fromMeta.displayUserMessage,
|
|
105951
|
+
displayAppResponse: fromTop.displayAppResponse ?? fromMeta.displayAppResponse
|
|
105952
|
+
};
|
|
105953
|
+
}
|
|
105625
105954
|
static extractUserMessage(input) {
|
|
105626
105955
|
if (!input) return "";
|
|
105627
105956
|
if (typeof input === "string") {
|
|
105628
105957
|
try {
|
|
105629
105958
|
const parsed = JSON.parse(input);
|
|
105630
|
-
|
|
105959
|
+
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);
|
|
105960
|
+
if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
|
|
105961
|
+
if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
|
|
105962
|
+
return this.extractLastUserMessageFromArray(parsed.messages);
|
|
105963
|
+
}
|
|
105964
|
+
return input;
|
|
105631
105965
|
} catch {
|
|
105632
105966
|
return input;
|
|
105633
105967
|
}
|
|
105634
105968
|
}
|
|
105635
105969
|
if (typeof input === "object") {
|
|
105636
105970
|
const obj = input;
|
|
105637
|
-
|
|
105971
|
+
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"]);
|
|
105972
|
+
if (direct !== void 0 && direct !== null && direct !== "") {
|
|
105973
|
+
return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
|
|
105974
|
+
}
|
|
105975
|
+
if (Array.isArray(obj == null ? void 0 : obj.messages)) {
|
|
105976
|
+
return this.extractLastUserMessageFromArray(obj.messages);
|
|
105977
|
+
}
|
|
105978
|
+
if (Array.isArray(input)) {
|
|
105979
|
+
return this.extractLastUserMessageFromArray(input);
|
|
105980
|
+
}
|
|
105981
|
+
return JSON.stringify(obj);
|
|
105638
105982
|
}
|
|
105639
105983
|
return String(input);
|
|
105640
105984
|
}
|
|
105641
105985
|
/**
|
|
105642
|
-
*
|
|
105986
|
+
* LangChain-serialized messages store role/content under `kwargs` and type in `id`.
|
|
105987
|
+
*/
|
|
105988
|
+
static getLangchainMessageContent(msg) {
|
|
105989
|
+
if (msg["content"] !== void 0 && msg["content"] !== null) {
|
|
105990
|
+
return msg["content"];
|
|
105991
|
+
}
|
|
105992
|
+
const kwargs = msg["kwargs"];
|
|
105993
|
+
if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
|
|
105994
|
+
const c3 = kwargs["content"];
|
|
105995
|
+
if (c3 !== void 0 && c3 !== null) {
|
|
105996
|
+
return c3;
|
|
105997
|
+
}
|
|
105998
|
+
}
|
|
105999
|
+
return void 0;
|
|
106000
|
+
}
|
|
106001
|
+
static inferLangchainMessageRole(msg) {
|
|
106002
|
+
if (typeof msg["role"] === "string") {
|
|
106003
|
+
return msg["role"];
|
|
106004
|
+
}
|
|
106005
|
+
const kwargs = msg["kwargs"];
|
|
106006
|
+
if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
|
|
106007
|
+
const r2 = kwargs["role"];
|
|
106008
|
+
if (typeof r2 === "string") {
|
|
106009
|
+
return r2;
|
|
106010
|
+
}
|
|
106011
|
+
}
|
|
106012
|
+
const id = msg["id"];
|
|
106013
|
+
if (Array.isArray(id)) {
|
|
106014
|
+
const tail = id[id.length - 1];
|
|
106015
|
+
if (tail === "HumanMessage") {
|
|
106016
|
+
return "user";
|
|
106017
|
+
}
|
|
106018
|
+
if (tail === "AIMessage" || tail === "AIMessageChunk") {
|
|
106019
|
+
return "assistant";
|
|
106020
|
+
}
|
|
106021
|
+
if (tail === "SystemMessage") {
|
|
106022
|
+
return "system";
|
|
106023
|
+
}
|
|
106024
|
+
if (tail === "ToolMessage") {
|
|
106025
|
+
return "tool";
|
|
106026
|
+
}
|
|
106027
|
+
}
|
|
106028
|
+
return void 0;
|
|
106029
|
+
}
|
|
106030
|
+
/**
|
|
106031
|
+
* Get last user message content from a messages array (chat/voice format).
|
|
106032
|
+
*/
|
|
106033
|
+
static extractLastUserMessageFromArray(messages) {
|
|
106034
|
+
if (!messages.length) return "";
|
|
106035
|
+
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
106036
|
+
const msg = messages[i2];
|
|
106037
|
+
const role = this.inferLangchainMessageRole(msg);
|
|
106038
|
+
const content2 = this.getLangchainMessageContent(msg);
|
|
106039
|
+
if (role === "user" && content2 != null) {
|
|
106040
|
+
return typeof content2 === "string" ? content2 : JSON.stringify(content2);
|
|
106041
|
+
}
|
|
106042
|
+
}
|
|
106043
|
+
const last2 = messages[messages.length - 1];
|
|
106044
|
+
const content = this.getLangchainMessageContent(last2);
|
|
106045
|
+
if (content != null) {
|
|
106046
|
+
return typeof content === "string" ? content : JSON.stringify(content);
|
|
106047
|
+
}
|
|
106048
|
+
return JSON.stringify(messages[messages.length - 1]);
|
|
106049
|
+
}
|
|
106050
|
+
/**
|
|
106051
|
+
* Extract app response from trace output for display.
|
|
106052
|
+
* Handles string, object with message/content/text/response, and messages array.
|
|
105643
106053
|
*/
|
|
105644
106054
|
static extractAppResponse(output) {
|
|
105645
106055
|
if (!output) return "";
|
|
105646
106056
|
if (typeof output === "string") {
|
|
105647
106057
|
try {
|
|
105648
106058
|
const parsed = JSON.parse(output);
|
|
105649
|
-
|
|
106059
|
+
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);
|
|
106060
|
+
if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
|
|
106061
|
+
if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
|
|
106062
|
+
return this.extractLastMessageContentFromArray(parsed.messages);
|
|
106063
|
+
}
|
|
106064
|
+
return output;
|
|
105650
106065
|
} catch {
|
|
105651
106066
|
return output;
|
|
105652
106067
|
}
|
|
105653
106068
|
}
|
|
105654
106069
|
if (typeof output === "object") {
|
|
105655
106070
|
const obj = output;
|
|
105656
|
-
|
|
106071
|
+
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"]);
|
|
106072
|
+
if (direct !== void 0 && direct !== null && direct !== "") {
|
|
106073
|
+
return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
|
|
106074
|
+
}
|
|
106075
|
+
if (Array.isArray(obj == null ? void 0 : obj.messages)) {
|
|
106076
|
+
return this.extractLastMessageContentFromArray(obj.messages);
|
|
106077
|
+
}
|
|
106078
|
+
if (Array.isArray(output)) {
|
|
106079
|
+
return this.extractLastMessageContentFromArray(output);
|
|
106080
|
+
}
|
|
106081
|
+
return JSON.stringify(obj);
|
|
105657
106082
|
}
|
|
105658
106083
|
return String(output);
|
|
105659
106084
|
}
|
|
106085
|
+
/**
|
|
106086
|
+
* Get last message content from a messages array for output display.
|
|
106087
|
+
*/
|
|
106088
|
+
static extractLastMessageContentFromArray(messages) {
|
|
106089
|
+
if (!messages.length) return "";
|
|
106090
|
+
const last2 = messages[messages.length - 1];
|
|
106091
|
+
const fromKwargs = this.getLangchainMessageContent(last2);
|
|
106092
|
+
const content = fromKwargs ?? (last2 == null ? void 0 : last2.message) ?? (last2 == null ? void 0 : last2.text);
|
|
106093
|
+
if (content != null) return typeof content === "string" ? content : JSON.stringify(content);
|
|
106094
|
+
return JSON.stringify(last2);
|
|
106095
|
+
}
|
|
105660
106096
|
/**
|
|
105661
106097
|
* Calculate trace metrics from observations
|
|
105662
106098
|
*/
|
|
@@ -105666,7 +106102,9 @@ class TraceTreeService {
|
|
|
105666
106102
|
let maxEndTime = 0;
|
|
105667
106103
|
let minStartTime = Infinity;
|
|
105668
106104
|
observations.forEach((obs) => {
|
|
105669
|
-
|
|
106105
|
+
var _a;
|
|
106106
|
+
const obsTokens = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
|
|
106107
|
+
totalTokens += typeof obsTokens === "number" ? obsTokens : parseInt(String(obsTokens || 0), 10) || 0;
|
|
105670
106108
|
const cost = parseFloat(obs.totalCost || "0");
|
|
105671
106109
|
if (!isNaN(cost)) totalCost += cost;
|
|
105672
106110
|
const startMs = new Date(obs.startTime).getTime();
|
|
@@ -105689,7 +106127,15 @@ class TraceTreeService {
|
|
|
105689
106127
|
);
|
|
105690
106128
|
const generation = sorted.find((obs) => obs.type === "GENERATION");
|
|
105691
106129
|
if (!generation) {
|
|
105692
|
-
|
|
106130
|
+
const tree = this.buildObservationTree(observations);
|
|
106131
|
+
if (tree.length === 0) return { observation: null, ancestorIds: [] };
|
|
106132
|
+
const findFirstLeaf = (node) => {
|
|
106133
|
+
if (node.children.length === 0) return node;
|
|
106134
|
+
return findFirstLeaf(node.children[0]);
|
|
106135
|
+
};
|
|
106136
|
+
const leafNode = findFirstLeaf(tree[0]);
|
|
106137
|
+
const ancestorIds2 = this.getAncestorIds(observations, leafNode.observation.id);
|
|
106138
|
+
return { observation: leafNode.observation, ancestorIds: ancestorIds2 };
|
|
105693
106139
|
}
|
|
105694
106140
|
const ancestorIds = this.getAncestorIds(observations, generation.id);
|
|
105695
106141
|
return { observation: generation, ancestorIds };
|
|
@@ -105836,6 +106282,7 @@ const observationFilterConfig = {
|
|
|
105836
106282
|
"toolNode",
|
|
105837
106283
|
"agent_toolNode",
|
|
105838
106284
|
"PreProcessor",
|
|
106285
|
+
"PostProcessor",
|
|
105839
106286
|
"MergerNode"
|
|
105840
106287
|
]
|
|
105841
106288
|
}
|
|
@@ -106095,6 +106542,7 @@ class DetailPageService {
|
|
|
106095
106542
|
* Transform API trace response to TraceDetailData
|
|
106096
106543
|
*/
|
|
106097
106544
|
transformToTraceDetailData(trace) {
|
|
106545
|
+
const piiDisplay = TraceTreeService.extractPiiDisplayFromApiTrace(trace);
|
|
106098
106546
|
return {
|
|
106099
106547
|
id: trace.id,
|
|
106100
106548
|
name: trace.name || "",
|
|
@@ -106107,6 +106555,8 @@ class DetailPageService {
|
|
|
106107
106555
|
input: trace.input,
|
|
106108
106556
|
output: trace.output,
|
|
106109
106557
|
metadata: trace.metadata,
|
|
106558
|
+
displayUserMessage: piiDisplay.displayUserMessage,
|
|
106559
|
+
displayAppResponse: piiDisplay.displayAppResponse,
|
|
106110
106560
|
tags: trace.tags || [],
|
|
106111
106561
|
bookmarked: trace.bookmarked || false,
|
|
106112
106562
|
public: trace.public || false,
|
|
@@ -106168,6 +106618,8 @@ class DetailPageService {
|
|
|
106168
106618
|
timestamp: trace.timestamp,
|
|
106169
106619
|
input: trace.input,
|
|
106170
106620
|
output: trace.output,
|
|
106621
|
+
displayUserMessage: trace.displayUserMessage,
|
|
106622
|
+
displayAppResponse: trace.displayAppResponse,
|
|
106171
106623
|
latency: trace.latency,
|
|
106172
106624
|
totalTokens: trace.totalTokens,
|
|
106173
106625
|
totalCost: typeof trace.totalCost === "number" ? String(trace.totalCost) : trace.totalCost,
|
|
@@ -106321,6 +106773,19 @@ function getObservationIconProps(observation) {
|
|
|
106321
106773
|
name
|
|
106322
106774
|
};
|
|
106323
106775
|
}
|
|
106776
|
+
function getObservationTokens(obs) {
|
|
106777
|
+
var _a;
|
|
106778
|
+
const total = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
|
|
106779
|
+
if (total === void 0 || total === null) return 0;
|
|
106780
|
+
return typeof total === "number" ? total : parseInt(String(total), 10) || 0;
|
|
106781
|
+
}
|
|
106782
|
+
function getAggregatedTotalTokens(node) {
|
|
106783
|
+
let sum2 = getObservationTokens(node.observation);
|
|
106784
|
+
node.children.forEach((child) => {
|
|
106785
|
+
sum2 += getAggregatedTotalTokens(child);
|
|
106786
|
+
});
|
|
106787
|
+
return sum2;
|
|
106788
|
+
}
|
|
106324
106789
|
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
106790
|
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "6", cy: "6", r: "5.5", fill: "#17B26A" }),
|
|
106326
106791
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 6L5.5 7.5L8 4.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
@@ -106382,7 +106847,11 @@ function ObservationNode({
|
|
|
106382
106847
|
return observation.name || observation.type || "";
|
|
106383
106848
|
};
|
|
106384
106849
|
const displayName = getDisplayName3();
|
|
106385
|
-
const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total)
|
|
106850
|
+
const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total) ?? observation.totalUsage ?? observation.totalTokens;
|
|
106851
|
+
const aggregatedTotalTokens = useMemo(() => {
|
|
106852
|
+
if (!isSupervisorOrAgent) return 0;
|
|
106853
|
+
return getAggregatedTotalTokens(node);
|
|
106854
|
+
}, [node, isSupervisorOrAgent]);
|
|
106386
106855
|
const handleRowClick = () => {
|
|
106387
106856
|
if (hasChildren) {
|
|
106388
106857
|
onToggle(observation.id);
|
|
@@ -106429,34 +106898,43 @@ function ObservationNode({
|
|
|
106429
106898
|
className: "w-[24px] h-[24px] rounded-[8px]"
|
|
106430
106899
|
}
|
|
106431
106900
|
) }),
|
|
106432
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
106433
|
-
|
|
106434
|
-
isSupervisorOrAgent &&
|
|
106435
|
-
|
|
106436
|
-
|
|
106901
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[2px] flex-1 min-w-0", children: [
|
|
106902
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[12px] leading-[16px] text-[#101828] truncate", title: displayName, children: displayName }),
|
|
106903
|
+
isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[6px] flex-wrap text-[10px] leading-[12px] text-[#667085] font-normal", children: [
|
|
106904
|
+
modelFromMetadata || observation.model ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: modelFromMetadata || observation.model }) : null,
|
|
106905
|
+
aggregatedTotalTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
106906
|
+
(modelFromMetadata || observation.model) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }),
|
|
106907
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap", children: [
|
|
106908
|
+
TraceTreeService.formatTokens(aggregatedTotalTokens),
|
|
106909
|
+
" Tokens"
|
|
106910
|
+
] })
|
|
106911
|
+
] }),
|
|
106912
|
+
duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
106913
|
+
modelFromMetadata || observation.model || aggregatedTotalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }) : null,
|
|
106914
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap flex items-center gap-[4px]", children: [
|
|
106915
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
|
|
106916
|
+
TraceTreeService.formatDuration(duration)
|
|
106917
|
+
] })
|
|
106918
|
+
] })
|
|
106919
|
+
] })
|
|
106920
|
+
] }),
|
|
106921
|
+
!isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] flex-shrink-0", children: [
|
|
106922
|
+
isGeneration && displayTokens !== void 0 && Number(displayTokens) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: [
|
|
106923
|
+
TraceTreeService.formatTokens(Number(displayTokens)),
|
|
106437
106924
|
" Tokens"
|
|
106438
106925
|
] }),
|
|
106439
106926
|
duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
|
|
106440
106927
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
|
|
106441
106928
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: TraceTreeService.formatDuration(duration) })
|
|
106442
106929
|
] }),
|
|
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
|
-
),
|
|
106930
|
+
isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
|
|
106931
|
+
isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
|
|
106459
106932
|
isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
|
|
106933
|
+
] }),
|
|
106934
|
+
isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-shrink-0 flex items-center", children: [
|
|
106935
|
+
isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
|
|
106936
|
+
isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
|
|
106937
|
+
isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
|
|
106460
106938
|
] })
|
|
106461
106939
|
]
|
|
106462
106940
|
}
|
|
@@ -106494,8 +106972,10 @@ function TraceTree({
|
|
|
106494
106972
|
onNodeSelect,
|
|
106495
106973
|
onExpandToggle,
|
|
106496
106974
|
showTraceId = true,
|
|
106975
|
+
onTraceIdClick,
|
|
106497
106976
|
isLoading = false,
|
|
106498
|
-
defaultExpandedNodeIds
|
|
106977
|
+
defaultExpandedNodeIds,
|
|
106978
|
+
runHeaderInputMode = "display"
|
|
106499
106979
|
}) {
|
|
106500
106980
|
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
106501
106981
|
const [expandedNodeIds, setExpandedNodeIds] = useState(
|
|
@@ -106513,11 +106993,20 @@ function TraceTree({
|
|
|
106513
106993
|
return TraceTreeService.buildObservationTree(observations);
|
|
106514
106994
|
}, [observations]);
|
|
106515
106995
|
const userMessage = useMemo(() => {
|
|
106996
|
+
if (runHeaderInputMode !== "tokenized" && trace.displayUserMessage !== void 0 && trace.displayUserMessage.length > 0) {
|
|
106997
|
+
return trace.displayUserMessage;
|
|
106998
|
+
}
|
|
106516
106999
|
return TraceTreeService.extractUserMessage(trace.input);
|
|
106517
|
-
}, [trace.input]);
|
|
107000
|
+
}, [trace.input, trace.displayUserMessage, runHeaderInputMode]);
|
|
106518
107001
|
const appResponse = useMemo(() => {
|
|
107002
|
+
if (runHeaderInputMode !== "tokenized" && trace.displayAppResponse !== void 0 && trace.displayAppResponse.length > 0) {
|
|
107003
|
+
return trace.displayAppResponse;
|
|
107004
|
+
}
|
|
106519
107005
|
return TraceTreeService.extractAppResponse(trace.output);
|
|
106520
|
-
}, [trace.output]);
|
|
107006
|
+
}, [trace.output, trace.displayAppResponse, runHeaderInputMode]);
|
|
107007
|
+
const traceMetrics = useMemo(() => {
|
|
107008
|
+
return TraceTreeService.calculateTraceMetrics(trace, observations);
|
|
107009
|
+
}, [trace, observations]);
|
|
106521
107010
|
const handleTraceToggle = useCallback(() => {
|
|
106522
107011
|
setIsExpanded((prev) => !prev);
|
|
106523
107012
|
onExpandToggle == null ? void 0 : onExpandToggle();
|
|
@@ -106544,7 +107033,16 @@ function TraceTree({
|
|
|
106544
107033
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[4px] w-full mb-[8px]", children: [
|
|
106545
107034
|
showTraceId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center px-0 py-[4px] w-full", children: [
|
|
106546
107035
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#98A2B3]", children: "Trace ID" }),
|
|
106547
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107036
|
+
onTraceIdClick ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107037
|
+
"button",
|
|
107038
|
+
{
|
|
107039
|
+
onClick: () => onTraceIdClick(trace.id),
|
|
107040
|
+
className: "font-medium text-[10px] leading-[12px] text-[#155EEF] hover:underline cursor-pointer bg-transparent border-none p-0",
|
|
107041
|
+
title: "View Trace Details",
|
|
107042
|
+
"data-test-id": `trace-tree-id-link-${trace.id}`,
|
|
107043
|
+
children: trace.id
|
|
107044
|
+
}
|
|
107045
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
|
|
106548
107046
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106549
107047
|
"button",
|
|
106550
107048
|
{
|
|
@@ -106619,10 +107117,18 @@ function TraceTree({
|
|
|
106619
107117
|
rootNode.observation.id
|
|
106620
107118
|
)) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[16px] text-[12px] text-[#667085] text-center", children: "No observations available" }) }),
|
|
106621
107119
|
/* @__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
|
-
|
|
107120
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center w-full", children: [
|
|
107121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center flex-1 min-w-0", children: [
|
|
107122
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AppResponseIcon, {}),
|
|
107123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.02em]", children: "APP RESPONSE" })
|
|
107124
|
+
] }),
|
|
107125
|
+
(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: [
|
|
107126
|
+
TraceTreeService.formatDuration(traceMetrics.latency),
|
|
107127
|
+
" · ",
|
|
107128
|
+
TraceTreeService.formatTokens(traceMetrics.totalTokens),
|
|
107129
|
+
" Tokens"
|
|
107130
|
+
] })
|
|
107131
|
+
] }),
|
|
106626
107132
|
/* @__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
107133
|
appResponse.substring(0, 150),
|
|
106628
107134
|
"...",
|
|
@@ -106655,114 +107161,6 @@ function TraceTree({
|
|
|
106655
107161
|
] })
|
|
106656
107162
|
] });
|
|
106657
107163
|
}
|
|
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
107164
|
function __awaiter(thisArg, _arguments, P2, generator) {
|
|
106767
107165
|
function adopt(value) {
|
|
106768
107166
|
return value instanceof P2 ? value : new P2(function(resolve) {
|
|
@@ -107927,21 +108325,35 @@ const DataModal = ({
|
|
|
107927
108325
|
)
|
|
107928
108326
|
] })
|
|
107929
108327
|
] }),
|
|
107930
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107931
|
-
|
|
108328
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
108329
|
+
"div",
|
|
107932
108330
|
{
|
|
107933
|
-
|
|
107934
|
-
|
|
107935
|
-
|
|
107936
|
-
|
|
107937
|
-
|
|
107938
|
-
|
|
107939
|
-
|
|
107940
|
-
|
|
107941
|
-
|
|
107942
|
-
|
|
108331
|
+
className: "flex-1 overflow-auto bg-gray-800 p-4",
|
|
108332
|
+
style: {
|
|
108333
|
+
"--json-property": "#ffffff",
|
|
108334
|
+
"--json-index": "#e2e8f0",
|
|
108335
|
+
"--json-number": "#e2e8f0",
|
|
108336
|
+
"--json-string": "#e2e8f0",
|
|
108337
|
+
"--json-boolean": "#e2e8f0",
|
|
108338
|
+
"--json-null": "#e2e8f0"
|
|
108339
|
+
},
|
|
108340
|
+
children: viewMode === "interactive" && useEnhancedJsonView ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
108341
|
+
JsonView,
|
|
108342
|
+
{
|
|
108343
|
+
src: parsedData,
|
|
108344
|
+
dark: true,
|
|
108345
|
+
collapseObjectsAfterLength: 20,
|
|
108346
|
+
collapseStringsAfterLength: 500,
|
|
108347
|
+
collapseStringMode: "word",
|
|
108348
|
+
displaySize: "collapsed",
|
|
108349
|
+
matchesURL: true,
|
|
108350
|
+
customizeCopy: (node) => stringifyJsonNode(node),
|
|
108351
|
+
className: "w-full text-xs",
|
|
108352
|
+
style: { color: "#f1f5f9" }
|
|
108353
|
+
}
|
|
108354
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs whitespace-pre text-white font-mono", children: stringifyJsonNode(parsedData) })
|
|
107943
108355
|
}
|
|
107944
|
-
)
|
|
108356
|
+
)
|
|
107945
108357
|
] }) });
|
|
107946
108358
|
};
|
|
107947
108359
|
const JsonViewer = ({
|
|
@@ -108309,6 +108721,23 @@ function formatUnknownValue(value) {
|
|
|
108309
108721
|
function isObservation(node) {
|
|
108310
108722
|
return node !== null && "traceId" in node && "type" in node;
|
|
108311
108723
|
}
|
|
108724
|
+
function metadataForDisplay(metadata) {
|
|
108725
|
+
if (metadata === null || metadata === void 0) return {};
|
|
108726
|
+
let obj;
|
|
108727
|
+
if (typeof metadata === "string") {
|
|
108728
|
+
try {
|
|
108729
|
+
obj = JSON.parse(metadata);
|
|
108730
|
+
} catch {
|
|
108731
|
+
return {};
|
|
108732
|
+
}
|
|
108733
|
+
} else if (typeof metadata === "object") {
|
|
108734
|
+
obj = metadata;
|
|
108735
|
+
} else {
|
|
108736
|
+
return {};
|
|
108737
|
+
}
|
|
108738
|
+
const { tools: _tools, ...rest } = obj;
|
|
108739
|
+
return rest;
|
|
108740
|
+
}
|
|
108312
108741
|
const defaultMetrics = {
|
|
108313
108742
|
totalCost: "0",
|
|
108314
108743
|
totalTokens: 0,
|
|
@@ -108357,7 +108786,7 @@ function SectionHeader({ title }) {
|
|
|
108357
108786
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-[1px] bg-[#EAECF0]" })
|
|
108358
108787
|
] });
|
|
108359
108788
|
}
|
|
108360
|
-
function PreviewContent({ input, output, metadata, statusMessage, isLoading = false
|
|
108789
|
+
function PreviewContent({ input, output, metadata, statusMessage, isLoading = false }) {
|
|
108361
108790
|
const [showAllMetadata, setShowAllMetadata] = useState(false);
|
|
108362
108791
|
const messages = useMemo(() => {
|
|
108363
108792
|
if (!input || typeof input !== "object") return null;
|
|
@@ -108389,15 +108818,6 @@ function PreviewContent({ input, output, metadata, statusMessage, isLoading = fa
|
|
|
108389
108818
|
}
|
|
108390
108819
|
return String(output);
|
|
108391
108820
|
}, [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
108821
|
if (isLoading) {
|
|
108402
108822
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[16px] p-[16px] overflow-y-auto h-full", children: [
|
|
108403
108823
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
@@ -108411,29 +108831,6 @@ function PreviewContent({ input, output, metadata, statusMessage, isLoading = fa
|
|
|
108411
108831
|
] });
|
|
108412
108832
|
}
|
|
108413
108833
|
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
108834
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
108438
108835
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { title: "Input" }),
|
|
108439
108836
|
messages ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-[8px]", children: messages.map((msg, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -108520,14 +108917,21 @@ function CodeEditorSection({
|
|
|
108520
108917
|
showHeader: true,
|
|
108521
108918
|
useEnhancedJsonView: true,
|
|
108522
108919
|
collapseStringsAfterLength: 500,
|
|
108523
|
-
collapseObjectsAfterLength: 20,
|
|
108920
|
+
collapseObjectsAfterLength: selectedTab === "metadata" ? 100 : 20,
|
|
108921
|
+
defaultExpanded: selectedTab === "metadata",
|
|
108524
108922
|
maxHeight: "100%",
|
|
108525
108923
|
className: "h-full border-0 rounded-none"
|
|
108526
|
-
}
|
|
108924
|
+
},
|
|
108925
|
+
selectedTab
|
|
108527
108926
|
) })
|
|
108528
108927
|
] });
|
|
108529
108928
|
}
|
|
108530
|
-
function NodeDetailPanel({
|
|
108929
|
+
function NodeDetailPanel({
|
|
108930
|
+
node,
|
|
108931
|
+
nodeType: _nodeType,
|
|
108932
|
+
apiConfig,
|
|
108933
|
+
generationSummaryInputOverride = null
|
|
108934
|
+
}) {
|
|
108531
108935
|
const [selectedTab, setSelectedTab] = useState("preview");
|
|
108532
108936
|
const [showTokenTooltip, setShowTokenTooltip] = useState(false);
|
|
108533
108937
|
const tooltipTimeoutRef = useRef(null);
|
|
@@ -108614,6 +109018,7 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108614
109018
|
}
|
|
108615
109019
|
return TraceTreeService.extractUserMessage(displayNode.input);
|
|
108616
109020
|
}, [displayNode]);
|
|
109021
|
+
const summaryInputLine = generationSummaryInputOverride !== null && generationSummaryInputOverride.length > 0 ? generationSummaryInputOverride : inputText;
|
|
108617
109022
|
const isGeneration = useMemo(() => {
|
|
108618
109023
|
return node !== null && isObservation(node) && node.type === "GENERATION";
|
|
108619
109024
|
}, [node]);
|
|
@@ -108697,7 +109102,7 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108697
109102
|
case "response":
|
|
108698
109103
|
return displayNode.output || {};
|
|
108699
109104
|
case "metadata":
|
|
108700
|
-
return isObservation(displayNode) ? displayNode.metadata || {} : {};
|
|
109105
|
+
return isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {};
|
|
108701
109106
|
case "logs":
|
|
108702
109107
|
return {
|
|
108703
109108
|
id: isObservation(displayNode) ? displayNode.id : displayNode.id,
|
|
@@ -108717,11 +109122,17 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108717
109122
|
return {
|
|
108718
109123
|
input: formattedInput,
|
|
108719
109124
|
output: displayNode.output || {},
|
|
108720
|
-
metadata: isObservation(displayNode) ? displayNode.metadata || {} : {},
|
|
109125
|
+
metadata: isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {},
|
|
108721
109126
|
statusMessage: isObservation(displayNode) ? displayNode.statusMessage : void 0,
|
|
108722
109127
|
modelParameters: isObservation(displayNode) ? displayNode.modelParameters : void 0
|
|
108723
109128
|
};
|
|
108724
109129
|
}, [displayNode, formattedInput]);
|
|
109130
|
+
const summaryModelInfo = useMemo(() => {
|
|
109131
|
+
if (!isGeneration || !displayNode) return { modelName: null, modelParameters: {} };
|
|
109132
|
+
const modelName = typeof formattedInput === "object" && formattedInput !== null && "model" in formattedInput ? formattedInput.model ?? null : null;
|
|
109133
|
+
const modelParameters = isObservation(displayNode) && displayNode.modelParameters && typeof displayNode.modelParameters === "object" ? displayNode.modelParameters : {};
|
|
109134
|
+
return { modelName, modelParameters };
|
|
109135
|
+
}, [isGeneration, displayNode, formattedInput]);
|
|
108725
109136
|
const tokenTooltipContent = metrics.totalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
108726
109137
|
"div",
|
|
108727
109138
|
{
|
|
@@ -108814,10 +109225,10 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108814
109225
|
] })
|
|
108815
109226
|
),
|
|
108816
109227
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {}),
|
|
108817
|
-
isGeneration &&
|
|
109228
|
+
isGeneration && summaryInputLine.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
108818
109229
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
|
|
108819
109230
|
/* @__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:
|
|
109231
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[12px] font-medium leading-[16px] text-[#101828] truncate", children: summaryInputLine })
|
|
108821
109232
|
] }),
|
|
108822
109233
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
108823
109234
|
] }),
|
|
@@ -108833,6 +109244,37 @@ function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
|
|
|
108833
109244
|
] })
|
|
108834
109245
|
] }),
|
|
108835
109246
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
109247
|
+
] }),
|
|
109248
|
+
isGeneration && (summaryModelInfo.modelName || Object.keys(summaryModelInfo.modelParameters).length > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
109249
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
|
|
109250
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[16px] text-[#98A2B3]", children: "Model parameters" }),
|
|
109251
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
|
|
109252
|
+
summaryModelInfo.modelName && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-[8px] py-[4px] bg-[#F2F4F7] rounded-[4px] text-[11px] font-medium text-[#344054]", children: [
|
|
109253
|
+
"Model: ",
|
|
109254
|
+
summaryModelInfo.modelName
|
|
109255
|
+
] }),
|
|
109256
|
+
Object.entries(summaryModelInfo.modelParameters).filter(
|
|
109257
|
+
([_2, value]) => value !== null && value !== void 0
|
|
109258
|
+
).map(([key, value]) => {
|
|
109259
|
+
const valueStr = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
109260
|
+
const displayKey = key.replace(/_/g, " ");
|
|
109261
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
109262
|
+
"span",
|
|
109263
|
+
{
|
|
109264
|
+
className: "px-[8px] py-[4px] bg-[#F2F4F7] border border-[#EAECF0] rounded-[4px] text-[11px] font-medium text-[#344054] max-w-[200px] truncate",
|
|
109265
|
+
title: `${key}: ${valueStr}`,
|
|
109266
|
+
children: [
|
|
109267
|
+
displayKey,
|
|
109268
|
+
": ",
|
|
109269
|
+
valueStr
|
|
109270
|
+
]
|
|
109271
|
+
},
|
|
109272
|
+
key
|
|
109273
|
+
);
|
|
109274
|
+
})
|
|
109275
|
+
] })
|
|
109276
|
+
] }),
|
|
109277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
|
|
108836
109278
|
] })
|
|
108837
109279
|
] })
|
|
108838
109280
|
] }),
|
|
@@ -108860,7 +109302,8 @@ function DetailPage({
|
|
|
108860
109302
|
selectedObservationId,
|
|
108861
109303
|
batchSize = DEFAULT_BATCH_SIZE,
|
|
108862
109304
|
initialTraceCount,
|
|
108863
|
-
initialSessionData
|
|
109305
|
+
initialSessionData,
|
|
109306
|
+
runHeaderInputMode = "display"
|
|
108864
109307
|
}) {
|
|
108865
109308
|
const [currentMode, setCurrentMode] = useState(initialMode);
|
|
108866
109309
|
const [currentSessionId, setCurrentSessionId] = useState(initialSessionId);
|
|
@@ -109101,12 +109544,52 @@ function DetailPage({
|
|
|
109101
109544
|
}, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
|
|
109102
109545
|
const traces = useMemo(() => {
|
|
109103
109546
|
if (mode === "session" && sessionData) {
|
|
109104
|
-
|
|
109547
|
+
const sorted = [...sessionData.traces].sort((a4, b2) => {
|
|
109548
|
+
const tA = a4.timestamp ? new Date(a4.timestamp).getTime() : 0;
|
|
109549
|
+
const tB = b2.timestamp ? new Date(b2.timestamp).getTime() : 0;
|
|
109550
|
+
return tA - tB;
|
|
109551
|
+
});
|
|
109552
|
+
return sorted.map((t2) => service.transformToTraceData(t2));
|
|
109105
109553
|
} else if (mode === "trace" && traceData) {
|
|
109106
109554
|
return [service.transformToTraceData(traceData)];
|
|
109107
109555
|
}
|
|
109108
109556
|
return [];
|
|
109109
109557
|
}, [mode, sessionData, traceData, service]);
|
|
109558
|
+
const generationSummaryInputOverride = useMemo(() => {
|
|
109559
|
+
var _a;
|
|
109560
|
+
if (runHeaderInputMode === "tokenized") {
|
|
109561
|
+
return null;
|
|
109562
|
+
}
|
|
109563
|
+
if (!selectedNode || !("traceId" in selectedNode) || !("type" in selectedNode)) {
|
|
109564
|
+
return null;
|
|
109565
|
+
}
|
|
109566
|
+
const obs = selectedNode;
|
|
109567
|
+
if (obs.type !== "GENERATION") {
|
|
109568
|
+
return null;
|
|
109569
|
+
}
|
|
109570
|
+
const traceRow = traces.find((t2) => t2.id === obs.traceId);
|
|
109571
|
+
if (!traceRow) {
|
|
109572
|
+
return null;
|
|
109573
|
+
}
|
|
109574
|
+
const displayUser = traceRow.displayUserMessage && traceRow.displayUserMessage.length > 0 ? traceRow.displayUserMessage : TraceTreeService.extractUserMessage(traceRow.input);
|
|
109575
|
+
if (!displayUser || displayUser.length === 0) {
|
|
109576
|
+
return null;
|
|
109577
|
+
}
|
|
109578
|
+
const fromState = (_a = traceObservations[obs.traceId]) == null ? void 0 : _a.observations;
|
|
109579
|
+
const observations = fromState && fromState.length > 0 ? fromState : mode === "trace" && (traceData == null ? void 0 : traceData.id) === obs.traceId && traceData.observations.length > 0 ? traceData.observations : [];
|
|
109580
|
+
const { observation: firstGen } = TraceTreeService.findFirstGeneration(observations);
|
|
109581
|
+
if (!firstGen || firstGen.id !== obs.id) {
|
|
109582
|
+
return null;
|
|
109583
|
+
}
|
|
109584
|
+
return displayUser;
|
|
109585
|
+
}, [
|
|
109586
|
+
runHeaderInputMode,
|
|
109587
|
+
selectedNode,
|
|
109588
|
+
traces,
|
|
109589
|
+
traceObservations,
|
|
109590
|
+
mode,
|
|
109591
|
+
traceData
|
|
109592
|
+
]);
|
|
109110
109593
|
const handleNodeSelect = useCallback((node) => {
|
|
109111
109594
|
setSelectedNode(node);
|
|
109112
109595
|
}, []);
|
|
@@ -109155,6 +109638,23 @@ function DetailPage({
|
|
|
109155
109638
|
firstTraceId: null
|
|
109156
109639
|
});
|
|
109157
109640
|
}, []);
|
|
109641
|
+
const handleNavigateToTrace = useCallback((targetTraceId) => {
|
|
109642
|
+
setSelectedNode(null);
|
|
109643
|
+
setSessionData(null);
|
|
109644
|
+
setTraceData(null);
|
|
109645
|
+
setTraceObservations({});
|
|
109646
|
+
setLoadingState("idle");
|
|
109647
|
+
setError(null);
|
|
109648
|
+
setHasAutoSelected(false);
|
|
109649
|
+
setCurrentMode("trace");
|
|
109650
|
+
setCurrentTraceId(targetTraceId);
|
|
109651
|
+
setProgressiveState({
|
|
109652
|
+
traceCount: 0,
|
|
109653
|
+
pendingTraceIds: [],
|
|
109654
|
+
firstTraceLoaded: false,
|
|
109655
|
+
firstTraceId: null
|
|
109656
|
+
});
|
|
109657
|
+
}, []);
|
|
109158
109658
|
if (loadingState === "loading") {
|
|
109159
109659
|
const canShowHeader = mode === "session" && initialSessionData;
|
|
109160
109660
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col bg-white ${className}`, children: [
|
|
@@ -109323,8 +109823,10 @@ function DetailPage({
|
|
|
109323
109823
|
onNodeSelect: handleNodeSelect,
|
|
109324
109824
|
onExpandToggle: () => handleTraceExpand(trace.id, trace.timestamp),
|
|
109325
109825
|
showTraceId: mode === "session",
|
|
109826
|
+
onTraceIdClick: mode === "session" ? handleNavigateToTrace : void 0,
|
|
109326
109827
|
isLoading: isLoadingObservations,
|
|
109327
|
-
defaultExpandedNodeIds: autoExpandIds
|
|
109828
|
+
defaultExpandedNodeIds: autoExpandIds,
|
|
109829
|
+
runHeaderInputMode
|
|
109328
109830
|
},
|
|
109329
109831
|
trace.id
|
|
109330
109832
|
);
|
|
@@ -109344,7 +109846,15 @@ function DetailPage({
|
|
|
109344
109846
|
);
|
|
109345
109847
|
}) })
|
|
109346
109848
|
] }) }),
|
|
109347
|
-
!selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109849
|
+
!selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
109850
|
+
NodeDetailPanel,
|
|
109851
|
+
{
|
|
109852
|
+
node: selectedNode,
|
|
109853
|
+
nodeType,
|
|
109854
|
+
apiConfig,
|
|
109855
|
+
generationSummaryInputOverride
|
|
109856
|
+
}
|
|
109857
|
+
)
|
|
109348
109858
|
] })
|
|
109349
109859
|
] });
|
|
109350
109860
|
}
|
|
@@ -109759,22 +110269,25 @@ function EnvironmentNameCell$1({ envId }) {
|
|
|
109759
110269
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
|
|
109760
110270
|
}
|
|
109761
110271
|
function SessionsListContent(props) {
|
|
109762
|
-
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours" } = props;
|
|
109763
|
-
const { environments } = useEnvironment();
|
|
109764
|
-
const [selectedSessionId, setSelectedSessionId] = useState(null);
|
|
110272
|
+
const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
|
|
110273
|
+
const { environments, resolveEnvironmentName } = useEnvironment();
|
|
110274
|
+
const [selectedSessionId, setSelectedSessionId] = useState(() => initialSessionId ?? null);
|
|
109765
110275
|
const [selectedSessionData, setSelectedSessionData] = useState(null);
|
|
109766
|
-
const [isModalOpen, setIsModalOpen] = useState(
|
|
110276
|
+
const [isModalOpen, setIsModalOpen] = useState(() => !!initialSessionId);
|
|
109767
110277
|
const [sessions, setSessions] = useState([]);
|
|
109768
110278
|
const [totalCount, setTotalCount] = useState(0);
|
|
109769
110279
|
const [loading, setLoading] = useState(true);
|
|
109770
110280
|
const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
|
|
110281
|
+
const [appVersionOptions, setAppVersionOptions] = useState([]);
|
|
110282
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
109771
110283
|
const initialFilters = useMemo(() => {
|
|
109772
110284
|
const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
|
|
109773
|
-
|
|
109774
|
-
|
|
110285
|
+
const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter$1(), ...defaultFilters];
|
|
110286
|
+
if (initialSessionId) {
|
|
110287
|
+
return [...base2, { column: "id", type: "string", operator: "=", value: initialSessionId }];
|
|
109775
110288
|
}
|
|
109776
|
-
return
|
|
109777
|
-
}, [defaultFilters]);
|
|
110289
|
+
return base2;
|
|
110290
|
+
}, [defaultFilters, initialSessionId]);
|
|
109778
110291
|
const [filters, setFilters] = useState(initialFilters);
|
|
109779
110292
|
const [showFilterPanel, setShowFilterPanel] = useState(false);
|
|
109780
110293
|
const [showColumnCustomization, setShowColumnCustomization] = useState(false);
|
|
@@ -109783,6 +110296,32 @@ function SessionsListContent(props) {
|
|
|
109783
110296
|
const [pagination, setPagination] = useState({ page: 0, limit: 50 });
|
|
109784
110297
|
const [orderBy, setOrderBy] = useState({ column: "createdAt", order: "DESC" });
|
|
109785
110298
|
const apiService = useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
|
|
110299
|
+
useEffect(() => {
|
|
110300
|
+
if (initialSessionId) {
|
|
110301
|
+
setSelectedSessionId(initialSessionId);
|
|
110302
|
+
setIsModalOpen(true);
|
|
110303
|
+
}
|
|
110304
|
+
}, [initialSessionId]);
|
|
110305
|
+
useEffect(() => {
|
|
110306
|
+
const fetchAppVersions = async () => {
|
|
110307
|
+
try {
|
|
110308
|
+
const filterOptionsData = await apiService.fetchFilterOptions({
|
|
110309
|
+
projectId: apiConfig.projectId
|
|
110310
|
+
});
|
|
110311
|
+
if ((filterOptionsData == null ? void 0 : filterOptionsData.appvIds) && Array.isArray(filterOptionsData.appvIds)) {
|
|
110312
|
+
setAppVersionOptions(
|
|
110313
|
+
filterOptionsData.appvIds.map((item) => ({
|
|
110314
|
+
value: item.value,
|
|
110315
|
+
label: item.value
|
|
110316
|
+
}))
|
|
110317
|
+
);
|
|
110318
|
+
}
|
|
110319
|
+
} catch (error) {
|
|
110320
|
+
console.warn("Failed to fetch app version filter options:", error);
|
|
110321
|
+
}
|
|
110322
|
+
};
|
|
110323
|
+
fetchAppVersions();
|
|
110324
|
+
}, [apiService, apiConfig.projectId]);
|
|
109786
110325
|
const convertPresetToDateRange = (preset) => {
|
|
109787
110326
|
const now2 = /* @__PURE__ */ new Date();
|
|
109788
110327
|
let pastDate;
|
|
@@ -109844,7 +110383,6 @@ function SessionsListContent(props) {
|
|
|
109844
110383
|
});
|
|
109845
110384
|
}
|
|
109846
110385
|
const allFilters = [...timeFilters, ...filters];
|
|
109847
|
-
if (apiConfig.projectId) ;
|
|
109848
110386
|
return allFilters;
|
|
109849
110387
|
}, [timeRange, filters]);
|
|
109850
110388
|
const fetchSessions = useCallback(async () => {
|
|
@@ -109904,6 +110442,28 @@ function SessionsListContent(props) {
|
|
|
109904
110442
|
useEffect(() => {
|
|
109905
110443
|
fetchSessions();
|
|
109906
110444
|
}, [fetchSessions]);
|
|
110445
|
+
const filteredSessions = useMemo(() => {
|
|
110446
|
+
const term = searchTerm.trim().toLowerCase();
|
|
110447
|
+
if (!term) return sessions;
|
|
110448
|
+
return sessions.filter((session) => {
|
|
110449
|
+
var _a;
|
|
110450
|
+
const envName = ((_a = resolveEnvironmentName(session.envId)) == null ? void 0 : _a.toLowerCase()) || "";
|
|
110451
|
+
const searchableFields = [
|
|
110452
|
+
session.id,
|
|
110453
|
+
envName,
|
|
110454
|
+
session.envId,
|
|
110455
|
+
session.appvId,
|
|
110456
|
+
session.source,
|
|
110457
|
+
session.environment,
|
|
110458
|
+
session.sessionReference,
|
|
110459
|
+
session.userReference,
|
|
110460
|
+
...session.userIds || []
|
|
110461
|
+
];
|
|
110462
|
+
return searchableFields.some(
|
|
110463
|
+
(field) => field && String(field).toLowerCase().includes(term)
|
|
110464
|
+
);
|
|
110465
|
+
});
|
|
110466
|
+
}, [sessions, searchTerm, resolveEnvironmentName]);
|
|
109907
110467
|
const defaultColumns = useMemo(
|
|
109908
110468
|
() => [
|
|
109909
110469
|
{
|
|
@@ -109912,8 +110472,7 @@ function SessionsListContent(props) {
|
|
|
109912
110472
|
width: 320,
|
|
109913
110473
|
pinned: "left",
|
|
109914
110474
|
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) })
|
|
110475
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
|
|
109917
110476
|
},
|
|
109918
110477
|
{
|
|
109919
110478
|
field: "envId",
|
|
@@ -110040,6 +110599,20 @@ function SessionsListContent(props) {
|
|
|
110040
110599
|
disabled: true,
|
|
110041
110600
|
valueFormatter: (params) => TracingUtils.formatTokens(params.value),
|
|
110042
110601
|
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", children: TracingUtils.formatTokens(params.value) })
|
|
110602
|
+
},
|
|
110603
|
+
{
|
|
110604
|
+
field: "sessionReference",
|
|
110605
|
+
headerName: "Session Reference",
|
|
110606
|
+
width: 180,
|
|
110607
|
+
hide: true,
|
|
110608
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
110609
|
+
},
|
|
110610
|
+
{
|
|
110611
|
+
field: "identity",
|
|
110612
|
+
headerName: "User Reference",
|
|
110613
|
+
width: 180,
|
|
110614
|
+
hide: true,
|
|
110615
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
110043
110616
|
}
|
|
110044
110617
|
// {
|
|
110045
110618
|
// field: 'traceTags',
|
|
@@ -110159,8 +110732,9 @@ function SessionsListContent(props) {
|
|
|
110159
110732
|
// User-friendly label
|
|
110160
110733
|
apiColumnName: "App Version ID",
|
|
110161
110734
|
// API expects "App Version ID" (koretracing uiTableName)
|
|
110162
|
-
type: "
|
|
110163
|
-
operators: ["
|
|
110735
|
+
type: "stringOptions",
|
|
110736
|
+
operators: ["any of", "none of"],
|
|
110737
|
+
options: appVersionOptions
|
|
110164
110738
|
},
|
|
110165
110739
|
{
|
|
110166
110740
|
field: "source",
|
|
@@ -110212,10 +110786,27 @@ function SessionsListContent(props) {
|
|
|
110212
110786
|
// API expects "Output Tokens" (koretracing uiTableName)
|
|
110213
110787
|
type: "number",
|
|
110214
110788
|
operators: ["=", ">", ">=", "<", "<="]
|
|
110789
|
+
},
|
|
110790
|
+
{
|
|
110791
|
+
field: "sessionReference",
|
|
110792
|
+
label: "Session Reference",
|
|
110793
|
+
apiColumnName: "Session Reference",
|
|
110794
|
+
type: "string",
|
|
110795
|
+
operators: ["=", "!=", "contains"]
|
|
110796
|
+
},
|
|
110797
|
+
{
|
|
110798
|
+
field: "identity",
|
|
110799
|
+
label: "User Reference",
|
|
110800
|
+
apiColumnName: "User Reference",
|
|
110801
|
+
type: "string",
|
|
110802
|
+
operators: ["=", "!=", "contains"]
|
|
110215
110803
|
}
|
|
110216
110804
|
],
|
|
110217
|
-
[environments]
|
|
110805
|
+
[environments, appVersionOptions]
|
|
110218
110806
|
);
|
|
110807
|
+
const handleSearch = useCallback((term) => {
|
|
110808
|
+
setSearchTerm(term);
|
|
110809
|
+
}, []);
|
|
110219
110810
|
const handleTimeRangeChange = (value, presetLabel) => {
|
|
110220
110811
|
console.log("🗓️ SessionsList: Time range change requested:", value, presetLabel);
|
|
110221
110812
|
setTimeRange(value);
|
|
@@ -110257,6 +110848,7 @@ function SessionsListContent(props) {
|
|
|
110257
110848
|
};
|
|
110258
110849
|
const handleClearFilters = () => {
|
|
110259
110850
|
setFilters([]);
|
|
110851
|
+
setSearchTerm("");
|
|
110260
110852
|
setTimeRange("24 hours");
|
|
110261
110853
|
};
|
|
110262
110854
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col w-full ${className}`, children: [
|
|
@@ -110265,11 +110857,19 @@ function SessionsListContent(props) {
|
|
|
110265
110857
|
{
|
|
110266
110858
|
title: "Sessions",
|
|
110267
110859
|
description: "Review session logs and trace details to analyze conversation logs and app behavior.",
|
|
110268
|
-
|
|
110860
|
+
searchPlaceholder: "Search sessions...",
|
|
110861
|
+
showSearch: true,
|
|
110862
|
+
searchConfig: {
|
|
110863
|
+
metadataSearchFields: ["Session ID", "Environment", "App Version", "User ID", "Source"],
|
|
110864
|
+
updateQuery: handleSearch,
|
|
110865
|
+
currentQuery: searchTerm,
|
|
110866
|
+
tableAllowsFullTextSearch: false
|
|
110867
|
+
},
|
|
110269
110868
|
timeRange,
|
|
110270
110869
|
timeRangePresetLabel,
|
|
110271
110870
|
onTimeRangeChange: handleTimeRangeChange,
|
|
110272
110871
|
filters,
|
|
110872
|
+
filterColumns,
|
|
110273
110873
|
onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
|
|
110274
110874
|
onModifyColumnsClick: () => setShowColumnCustomization(true),
|
|
110275
110875
|
onExportClick: handleExport,
|
|
@@ -110320,10 +110920,10 @@ function SessionsListContent(props) {
|
|
|
110320
110920
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto p-[24px] pt-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
110321
110921
|
TracingTable,
|
|
110322
110922
|
{
|
|
110323
|
-
data:
|
|
110923
|
+
data: filteredSessions,
|
|
110324
110924
|
columns,
|
|
110325
110925
|
loading,
|
|
110326
|
-
totalCount,
|
|
110926
|
+
totalCount: searchTerm.trim() ? filteredSessions.length : totalCount,
|
|
110327
110927
|
pagination,
|
|
110328
110928
|
onPaginationChange: setPagination,
|
|
110329
110929
|
onRowClick: handleRowClick,
|
|
@@ -110370,24 +110970,26 @@ function TracesListContent(props) {
|
|
|
110370
110970
|
onTraceClick,
|
|
110371
110971
|
className = "",
|
|
110372
110972
|
defaultFilters = [],
|
|
110373
|
-
sessionId
|
|
110973
|
+
sessionId,
|
|
110974
|
+
initialTraceId
|
|
110374
110975
|
} = props;
|
|
110375
110976
|
const { environments } = useEnvironment();
|
|
110376
|
-
const [selectedTraceId, setSelectedTraceId] = useState(null);
|
|
110377
|
-
const [isModalOpen, setIsModalOpen] = useState(
|
|
110977
|
+
const [selectedTraceId, setSelectedTraceId] = useState(() => initialTraceId ?? null);
|
|
110978
|
+
const [isModalOpen, setIsModalOpen] = useState(() => !!initialTraceId);
|
|
110378
110979
|
const [traces, setTraces] = useState([]);
|
|
110379
110980
|
const [totalCount, setTotalCount] = useState(0);
|
|
110380
110981
|
const [loading, setLoading] = useState(true);
|
|
110381
110982
|
const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
|
|
110382
110983
|
const [searchTerm, setSearchTerm] = useState("");
|
|
110383
|
-
const [searchType, setSearchType] = useState(["id"]);
|
|
110984
|
+
const [searchType, setSearchType] = useState(["id", "content"]);
|
|
110384
110985
|
const initialFilters = useMemo(() => {
|
|
110385
110986
|
const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
|
|
110386
|
-
|
|
110387
|
-
|
|
110987
|
+
const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter(), ...defaultFilters];
|
|
110988
|
+
if (initialTraceId) {
|
|
110989
|
+
return [...base2, { column: "id", type: "string", operator: "=", value: initialTraceId }];
|
|
110388
110990
|
}
|
|
110389
|
-
return
|
|
110390
|
-
}, [defaultFilters]);
|
|
110991
|
+
return base2;
|
|
110992
|
+
}, [defaultFilters, initialTraceId]);
|
|
110391
110993
|
const [filters, setFilters] = useState(initialFilters);
|
|
110392
110994
|
const [showFilterPanel, setShowFilterPanel] = useState(false);
|
|
110393
110995
|
const [showColumnCustomization, setShowColumnCustomization] = useState(false);
|
|
@@ -110396,6 +110998,12 @@ function TracesListContent(props) {
|
|
|
110396
110998
|
const [pagination, setPagination] = useState({ page: 0, limit: 50 });
|
|
110397
110999
|
const [orderBy, setOrderBy] = useState({ column: "timestamp", order: "DESC" });
|
|
110398
111000
|
const [detailedTraceData, setDetailedTraceData] = useState(/* @__PURE__ */ new Map());
|
|
111001
|
+
useEffect(() => {
|
|
111002
|
+
if (initialTraceId) {
|
|
111003
|
+
setSelectedTraceId(initialTraceId);
|
|
111004
|
+
setIsModalOpen(true);
|
|
111005
|
+
}
|
|
111006
|
+
}, [initialTraceId]);
|
|
110399
111007
|
const apiService = useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
|
|
110400
111008
|
const convertPresetToDateRange = (preset) => {
|
|
110401
111009
|
const now2 = /* @__PURE__ */ new Date();
|
|
@@ -110481,18 +111089,24 @@ function TracesListContent(props) {
|
|
|
110481
111089
|
orderBy
|
|
110482
111090
|
});
|
|
110483
111091
|
const apiFilters = TracingUtils.convertFiltersToApiFormat(effectiveFilters, filterColumns);
|
|
110484
|
-
const tracesResponse = await
|
|
110485
|
-
|
|
110486
|
-
|
|
110487
|
-
|
|
110488
|
-
|
|
110489
|
-
|
|
110490
|
-
|
|
110491
|
-
|
|
110492
|
-
|
|
110493
|
-
|
|
111092
|
+
const [tracesResponse, countResponse] = await Promise.all([
|
|
111093
|
+
apiService.fetchTraces({
|
|
111094
|
+
projectId: apiConfig.projectId,
|
|
111095
|
+
filter: apiFilters,
|
|
111096
|
+
orderBy,
|
|
111097
|
+
page: pagination.page,
|
|
111098
|
+
limit: pagination.limit,
|
|
111099
|
+
searchQuery: searchTerm || null,
|
|
111100
|
+
searchType
|
|
111101
|
+
}),
|
|
111102
|
+
apiService.fetchTracesCount(apiConfig.projectId, apiFilters, {
|
|
111103
|
+
searchQuery: searchTerm || null,
|
|
111104
|
+
searchType,
|
|
111105
|
+
orderBy
|
|
111106
|
+
})
|
|
111107
|
+
]);
|
|
110494
111108
|
const basicTraces = tracesResponse.traces || [];
|
|
110495
|
-
console.log("✅ Basic traces loaded:", { count: basicTraces.length });
|
|
111109
|
+
console.log("✅ Basic traces loaded:", { count: basicTraces.length, total: countResponse.totalCount });
|
|
110496
111110
|
if (basicTraces.length > 0) {
|
|
110497
111111
|
const traceIds = basicTraces.map((t2) => t2.id);
|
|
110498
111112
|
try {
|
|
@@ -110527,7 +111141,7 @@ function TracesListContent(props) {
|
|
|
110527
111141
|
} else {
|
|
110528
111142
|
setTraces([]);
|
|
110529
111143
|
}
|
|
110530
|
-
setTotalCount(
|
|
111144
|
+
setTotalCount(countResponse.totalCount);
|
|
110531
111145
|
} catch (error) {
|
|
110532
111146
|
console.error("❌ Error fetching traces:", error);
|
|
110533
111147
|
setTraces([]);
|
|
@@ -110556,11 +111170,13 @@ function TracesListContent(props) {
|
|
|
110556
111170
|
projectId: apiConfig.projectId,
|
|
110557
111171
|
timestamp: trace.timestamp
|
|
110558
111172
|
});
|
|
111173
|
+
const inputDisplay = TraceTreeService.extractUserMessage(detail["input"]);
|
|
111174
|
+
const outputDisplay = TraceTreeService.extractAppResponse(detail["output"]);
|
|
110559
111175
|
setDetailedTraceData((prev) => {
|
|
110560
111176
|
const newMap = new Map(prev);
|
|
110561
111177
|
newMap.set(traceId, {
|
|
110562
|
-
input:
|
|
110563
|
-
output:
|
|
111178
|
+
input: inputDisplay,
|
|
111179
|
+
output: outputDisplay,
|
|
110564
111180
|
totalCost: detail["totalCost"],
|
|
110565
111181
|
envId: detail["envId"],
|
|
110566
111182
|
source: detail["source"]
|
|
@@ -110597,8 +111213,7 @@ function TracesListContent(props) {
|
|
|
110597
111213
|
width: 320,
|
|
110598
111214
|
pinned: "left",
|
|
110599
111215
|
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) })
|
|
111216
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
|
|
110602
111217
|
}
|
|
110603
111218
|
];
|
|
110604
111219
|
{
|
|
@@ -110609,11 +111224,13 @@ function TracesListContent(props) {
|
|
|
110609
111224
|
hide: false,
|
|
110610
111225
|
cellRenderer: (params) => {
|
|
110611
111226
|
const detailData = detailedTraceData.get(params.data.id);
|
|
110612
|
-
const
|
|
110613
|
-
if (
|
|
111227
|
+
const rawInput = detailData == null ? void 0 : detailData.input;
|
|
111228
|
+
if (rawInput === void 0) {
|
|
110614
111229
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
|
|
110615
111230
|
}
|
|
110616
|
-
|
|
111231
|
+
const inputText = typeof rawInput === "string" ? rawInput : TraceTreeService.extractUserMessage(rawInput);
|
|
111232
|
+
const displayText = TracingUtils.truncate(inputText || "-", 50);
|
|
111233
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: inputText || void 0, children: displayText });
|
|
110617
111234
|
}
|
|
110618
111235
|
});
|
|
110619
111236
|
}
|
|
@@ -110642,11 +111259,13 @@ function TracesListContent(props) {
|
|
|
110642
111259
|
hide: false,
|
|
110643
111260
|
cellRenderer: (params) => {
|
|
110644
111261
|
const detailData = detailedTraceData.get(params.data.id);
|
|
110645
|
-
const
|
|
110646
|
-
if (
|
|
111262
|
+
const rawOutput = detailData == null ? void 0 : detailData.output;
|
|
111263
|
+
if (rawOutput === void 0) {
|
|
110647
111264
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
|
|
110648
111265
|
}
|
|
110649
|
-
|
|
111266
|
+
const outputText = typeof rawOutput === "string" ? rawOutput : TraceTreeService.extractAppResponse(rawOutput);
|
|
111267
|
+
const displayText = TracingUtils.truncate(outputText || "-", 50);
|
|
111268
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: outputText || void 0, children: displayText });
|
|
110650
111269
|
}
|
|
110651
111270
|
});
|
|
110652
111271
|
}
|
|
@@ -110709,11 +111328,9 @@ function TracesListContent(props) {
|
|
|
110709
111328
|
// },
|
|
110710
111329
|
{
|
|
110711
111330
|
field: "timestamp",
|
|
110712
|
-
headerName: "
|
|
111331
|
+
headerName: "Created At",
|
|
110713
111332
|
width: 180,
|
|
110714
|
-
hide:
|
|
110715
|
-
// DISABLED - This is the main sort column for traces
|
|
110716
|
-
disabled: true,
|
|
111333
|
+
hide: false,
|
|
110717
111334
|
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: params.value ? new Date(params.value).toLocaleString() : "-" })
|
|
110718
111335
|
},
|
|
110719
111336
|
{
|
|
@@ -110788,6 +111405,20 @@ function TracesListContent(props) {
|
|
|
110788
111405
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", children: source || "-" });
|
|
110789
111406
|
}
|
|
110790
111407
|
},
|
|
111408
|
+
{
|
|
111409
|
+
field: "sessionReference",
|
|
111410
|
+
headerName: "Session Reference",
|
|
111411
|
+
width: 180,
|
|
111412
|
+
hide: true,
|
|
111413
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
111414
|
+
},
|
|
111415
|
+
{
|
|
111416
|
+
field: "identity",
|
|
111417
|
+
headerName: "User Reference",
|
|
111418
|
+
width: 180,
|
|
111419
|
+
hide: true,
|
|
111420
|
+
cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
|
|
111421
|
+
},
|
|
110791
111422
|
{
|
|
110792
111423
|
field: "promptTokens",
|
|
110793
111424
|
headerName: "Input Tokens",
|
|
@@ -110964,10 +111595,9 @@ function TracesListContent(props) {
|
|
|
110964
111595
|
},
|
|
110965
111596
|
{
|
|
110966
111597
|
field: "timestamp",
|
|
110967
|
-
label: "
|
|
110968
|
-
// Same as API
|
|
111598
|
+
label: "Created At",
|
|
110969
111599
|
apiColumnName: "Timestamp",
|
|
110970
|
-
//
|
|
111600
|
+
// Backend payload: keep "Timestamp" for API
|
|
110971
111601
|
type: "datetime",
|
|
110972
111602
|
operators: [">=", "<=", "="]
|
|
110973
111603
|
},
|
|
@@ -111058,6 +111688,20 @@ function TracesListContent(props) {
|
|
|
111058
111688
|
label: "Output Tokens",
|
|
111059
111689
|
type: "number",
|
|
111060
111690
|
operators: ["=", ">", ">=", "<", "<="]
|
|
111691
|
+
},
|
|
111692
|
+
{
|
|
111693
|
+
field: "sessionReference",
|
|
111694
|
+
label: "Session Reference",
|
|
111695
|
+
apiColumnName: "Session Reference",
|
|
111696
|
+
type: "string",
|
|
111697
|
+
operators: ["=", "!=", "contains"]
|
|
111698
|
+
},
|
|
111699
|
+
{
|
|
111700
|
+
field: "identity",
|
|
111701
|
+
label: "User Reference",
|
|
111702
|
+
apiColumnName: "User Reference",
|
|
111703
|
+
type: "string",
|
|
111704
|
+
operators: ["=", "!=", "contains"]
|
|
111061
111705
|
}
|
|
111062
111706
|
);
|
|
111063
111707
|
return baseColumns;
|
|
@@ -111124,6 +111768,7 @@ function TracesListContent(props) {
|
|
|
111124
111768
|
timeRangePresetLabel,
|
|
111125
111769
|
onTimeRangeChange: handleTimeRangeChange,
|
|
111126
111770
|
filters,
|
|
111771
|
+
filterColumns,
|
|
111127
111772
|
onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
|
|
111128
111773
|
onModifyColumnsClick: () => setShowColumnCustomization(true),
|
|
111129
111774
|
onExportClick: handleExport,
|
|
@@ -112175,12 +112820,12 @@ class TreeBuilder {
|
|
|
112175
112820
|
* Process execution events and build a hierarchical tree structure
|
|
112176
112821
|
* Session > Run > Node Tree
|
|
112177
112822
|
*/
|
|
112178
|
-
static buildSessionTree(events, sessionId) {
|
|
112823
|
+
static buildSessionTree(events, sessionId, options) {
|
|
112179
112824
|
var _a;
|
|
112180
112825
|
const runGroups = this.groupEventsByRun(events);
|
|
112181
112826
|
const runs = [];
|
|
112182
112827
|
for (const [runId, runEvents] of runGroups.entries()) {
|
|
112183
|
-
const runTree = this.buildRunTree(runId, runEvents);
|
|
112828
|
+
const runTree = this.buildRunTree(runId, runEvents, options);
|
|
112184
112829
|
runs.push(runTree);
|
|
112185
112830
|
}
|
|
112186
112831
|
runs.sort((a4, b2) => new Date(a4.startTime).getTime() - new Date(b2.startTime).getTime());
|
|
@@ -112206,11 +112851,11 @@ class TreeBuilder {
|
|
|
112206
112851
|
/**
|
|
112207
112852
|
* Build tree for a single run
|
|
112208
112853
|
*/
|
|
112209
|
-
static buildRunTree(runId, events) {
|
|
112854
|
+
static buildRunTree(runId, events, options) {
|
|
112210
112855
|
var _a;
|
|
112211
112856
|
const nodeEventMap = /* @__PURE__ */ new Map();
|
|
112212
112857
|
events.forEach((event) => {
|
|
112213
|
-
const nodeKey =
|
|
112858
|
+
const nodeKey = event.data.id;
|
|
112214
112859
|
if (!nodeEventMap.has(nodeKey)) {
|
|
112215
112860
|
nodeEventMap.set(nodeKey, {});
|
|
112216
112861
|
}
|
|
@@ -112237,7 +112882,7 @@ class TreeBuilder {
|
|
|
112237
112882
|
const status = this.calculateRunStatus(runEvents);
|
|
112238
112883
|
const duration = endTime && startTime ? endTime - startTime : void 0;
|
|
112239
112884
|
const totalTokens = this.calculateRunTokens(runEvents);
|
|
112240
|
-
const userInput = this.extractUserInput(runEvents);
|
|
112885
|
+
const userInput = this.extractUserInput(runEvents, options);
|
|
112241
112886
|
const finalOutput = this.extractFinalOutput(runEvents);
|
|
112242
112887
|
return {
|
|
112243
112888
|
runId,
|
|
@@ -112256,11 +112901,12 @@ class TreeBuilder {
|
|
|
112256
112901
|
* Create TreeNode from paired started/completed events
|
|
112257
112902
|
*/
|
|
112258
112903
|
static createTreeNodeFromEvents(startedEvent, completedEvent, runId) {
|
|
112904
|
+
var _a;
|
|
112259
112905
|
const startTime = startedEvent.data.timestamp;
|
|
112260
112906
|
const endTime = completedEvent == null ? void 0 : completedEvent.data.timestamp;
|
|
112261
112907
|
const duration = endTime && startTime ? new Date(endTime).getTime() - new Date(startTime).getTime() : void 0;
|
|
112262
112908
|
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";
|
|
112909
|
+
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
112910
|
const input = hasInputOutput ? startedEvent.data.input : void 0;
|
|
112265
112911
|
let output = void 0;
|
|
112266
112912
|
let error = void 0;
|
|
@@ -112274,7 +112920,8 @@ class TreeBuilder {
|
|
|
112274
112920
|
const { toolInvocations, isResponse } = this.extractToolInvocations(output);
|
|
112275
112921
|
console.log("toolInvocations", toolInvocations);
|
|
112276
112922
|
console.log("isResponse", isResponse);
|
|
112277
|
-
const
|
|
112923
|
+
const extractedProvider = primaryEvent.data.type === "llm" ? this.extractProvider(primaryEvent.data.name || primaryEvent.data.toolName) : void 0;
|
|
112924
|
+
const provider = ((_a = primaryEvent.data.metadata) == null ? void 0 : _a.provider) || extractedProvider;
|
|
112278
112925
|
return {
|
|
112279
112926
|
id: primaryEvent.data.id,
|
|
112280
112927
|
parentId: primaryEvent.data.parentId,
|
|
@@ -112433,12 +113080,22 @@ class TreeBuilder {
|
|
|
112433
113080
|
/**
|
|
112434
113081
|
* Extract initial user input from the first LLM node's input
|
|
112435
113082
|
*/
|
|
112436
|
-
static extractUserInput(events) {
|
|
113083
|
+
static extractUserInput(events, options) {
|
|
113084
|
+
const preferDisplay = ((options == null ? void 0 : options.runHeaderInputMode) ?? "display") === "display";
|
|
112437
113085
|
const llmEvents = events.filter(
|
|
112438
113086
|
(e3) => e3.type === "node_started" && e3.data.type === "llm"
|
|
112439
113087
|
).sort((a4, b2) => new Date(a4.data.timestamp).getTime() - new Date(b2.data.timestamp).getTime());
|
|
112440
113088
|
if (llmEvents.length > 0) {
|
|
112441
113089
|
const firstLlmEvent = llmEvents[0];
|
|
113090
|
+
if (preferDisplay && firstLlmEvent.data.displayInput !== void 0 && firstLlmEvent.data.displayInput !== null) {
|
|
113091
|
+
const d3 = firstLlmEvent.data.displayInput;
|
|
113092
|
+
if (typeof d3 === "string") {
|
|
113093
|
+
return d3;
|
|
113094
|
+
}
|
|
113095
|
+
if (typeof d3 === "object") {
|
|
113096
|
+
return JSON.stringify(d3);
|
|
113097
|
+
}
|
|
113098
|
+
}
|
|
112442
113099
|
if (firstLlmEvent.data.input) {
|
|
112443
113100
|
if (typeof firstLlmEvent.data.input === "string") {
|
|
112444
113101
|
return firstLlmEvent.data.input;
|
|
@@ -112506,6 +113163,22 @@ class TreeBuilder {
|
|
|
112506
113163
|
*/
|
|
112507
113164
|
static extractFinalOutput(events) {
|
|
112508
113165
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
113166
|
+
const postProcessorEvents = events.filter(
|
|
113167
|
+
(e3) => {
|
|
113168
|
+
var _a2;
|
|
113169
|
+
return e3.type === "node_completed" && e3.data.type === "tool" && ((_a2 = e3.data.metadata) == null ? void 0 : _a2.type) === "PostProcessor" && e3.data.output;
|
|
113170
|
+
}
|
|
113171
|
+
);
|
|
113172
|
+
if (postProcessorEvents.length > 0) {
|
|
113173
|
+
const lastPP = postProcessorEvents[postProcessorEvents.length - 1];
|
|
113174
|
+
const ppOutput = lastPP.data.output;
|
|
113175
|
+
if (typeof ppOutput === "object" && ppOutput.output) {
|
|
113176
|
+
return typeof ppOutput.output === "string" ? ppOutput.output : JSON.stringify(ppOutput.output);
|
|
113177
|
+
}
|
|
113178
|
+
if (typeof ppOutput === "string") {
|
|
113179
|
+
return ppOutput;
|
|
113180
|
+
}
|
|
113181
|
+
}
|
|
112509
113182
|
const errorEvents = events.filter(
|
|
112510
113183
|
(e3) => e3.type === "node_completed" && e3.data.error && (e3.data.status === "errored" || e3.data.status === "failed")
|
|
112511
113184
|
);
|
|
@@ -112632,8 +113305,8 @@ class TreeBuilder {
|
|
|
112632
113305
|
/**
|
|
112633
113306
|
* Update tree with new events (optimized for real-time updates)
|
|
112634
113307
|
*/
|
|
112635
|
-
static updateTree(existingTree, _newEvents, allEvents) {
|
|
112636
|
-
return this.buildSessionTree(allEvents, existingTree.sessionId);
|
|
113308
|
+
static updateTree(existingTree, _newEvents, allEvents, options) {
|
|
113309
|
+
return this.buildSessionTree(allEvents, existingTree.sessionId, options);
|
|
112637
113310
|
}
|
|
112638
113311
|
/**
|
|
112639
113312
|
* Merge new events into existing events efficiently
|
|
@@ -112985,7 +113658,7 @@ class ApiService {
|
|
|
112985
113658
|
nodeId,
|
|
112986
113659
|
totalObservations: observations.length
|
|
112987
113660
|
});
|
|
112988
|
-
const
|
|
113661
|
+
const matchingObservations = observations.filter((obs) => {
|
|
112989
113662
|
let metadata = obs.metadata;
|
|
112990
113663
|
if (typeof metadata === "string") {
|
|
112991
113664
|
try {
|
|
@@ -113006,6 +113679,7 @@ class ApiService {
|
|
|
113006
113679
|
});
|
|
113007
113680
|
return nodeId === observationNodeId;
|
|
113008
113681
|
});
|
|
113682
|
+
const matchedObservation = matchingObservations.find((obs) => obs.type === "GENERATION") || matchingObservations[0] || null;
|
|
113009
113683
|
if (!matchedObservation) {
|
|
113010
113684
|
const parts = nodeId.split("_");
|
|
113011
113685
|
if (parts.length === 2) {
|
|
@@ -113147,6 +113821,36 @@ class ApiService {
|
|
|
113147
113821
|
return this.config;
|
|
113148
113822
|
}
|
|
113149
113823
|
}
|
|
113824
|
+
function sanitizeForTestId(value) {
|
|
113825
|
+
return value.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "") || "node";
|
|
113826
|
+
}
|
|
113827
|
+
function getDebuggerCallTypeTestId(node) {
|
|
113828
|
+
const name = (node.name ?? "unknown").toString();
|
|
113829
|
+
let slug = sanitizeForTestId(name);
|
|
113830
|
+
switch (node.type) {
|
|
113831
|
+
case "event":
|
|
113832
|
+
slug = slug.replace(/-event$/, "") || "event";
|
|
113833
|
+
return `debugger-event-${slug}`;
|
|
113834
|
+
case "Agent":
|
|
113835
|
+
return `debugger-${slug}-call`;
|
|
113836
|
+
case "tool":
|
|
113837
|
+
return `debugger-${slug}-call`;
|
|
113838
|
+
case "llm":
|
|
113839
|
+
return `debugger-llm-${slug}`;
|
|
113840
|
+
case "GuardrailsInputScan":
|
|
113841
|
+
return `debugger-guardrails-input-${slug}`;
|
|
113842
|
+
case "GuardrailsOutputScan":
|
|
113843
|
+
return `debugger-guardrails-output-${slug}`;
|
|
113844
|
+
case "External Orchestrator":
|
|
113845
|
+
return `debugger-orchestrator-${slug}`;
|
|
113846
|
+
case "ProxyWorker":
|
|
113847
|
+
return `debugger-proxy-${slug}`;
|
|
113848
|
+
case "PostProcessor":
|
|
113849
|
+
return `debugger-postprocessor-${slug}`;
|
|
113850
|
+
default:
|
|
113851
|
+
return `debugger-${String(node.type).toLowerCase().replace(/\s+/g, "-")}-${slug}`;
|
|
113852
|
+
}
|
|
113853
|
+
}
|
|
113150
113854
|
function DebugCard({
|
|
113151
113855
|
node,
|
|
113152
113856
|
onToggle,
|
|
@@ -113158,9 +113862,12 @@ function DebugCard({
|
|
|
113158
113862
|
projectId,
|
|
113159
113863
|
nodeIndex = 0
|
|
113160
113864
|
}) {
|
|
113865
|
+
var _a;
|
|
113866
|
+
const callTypeTestId = useMemo(() => getDebuggerCallTypeTestId(node), [node.type, node.name]);
|
|
113867
|
+
const cardTestId = useMemo(() => `${callTypeTestId}_${node.id}`, [callTypeTestId, node.id]);
|
|
113161
113868
|
const isGuardrailsNode = useMemo(() => {
|
|
113162
|
-
var
|
|
113163
|
-
return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((
|
|
113869
|
+
var _a2;
|
|
113870
|
+
return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((_a2 = node.name) == null ? void 0 : _a2.toLowerCase().includes("guardrail"));
|
|
113164
113871
|
}, [node.type, node.name]);
|
|
113165
113872
|
const availableTabs = useMemo(() => {
|
|
113166
113873
|
switch (node.type) {
|
|
@@ -113337,7 +114044,7 @@ function DebugCard({
|
|
|
113337
114044
|
}
|
|
113338
114045
|
};
|
|
113339
114046
|
const getNodeIcon = () => {
|
|
113340
|
-
var
|
|
114047
|
+
var _a2, _b;
|
|
113341
114048
|
if (isGuardrailsNode) {
|
|
113342
114049
|
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
114050
|
"path",
|
|
@@ -113372,7 +114079,7 @@ function DebugCard({
|
|
|
113372
114079
|
size: "small",
|
|
113373
114080
|
name: node.name,
|
|
113374
114081
|
className: "w-[24px] h-[24px]",
|
|
113375
|
-
toolType: node.type === "tool" ? (
|
|
114082
|
+
toolType: node.type === "tool" ? (_a2 = node.metadata) == null ? void 0 : _a2.type : void 0,
|
|
113376
114083
|
provider: node.type === "llm" ? (_b = node.metadata) == null ? void 0 : _b.provider : void 0,
|
|
113377
114084
|
modelName: node.type === "llm" ? node.name : void 0
|
|
113378
114085
|
}
|
|
@@ -113396,7 +114103,7 @@ function DebugCard({
|
|
|
113396
114103
|
return availableTabs;
|
|
113397
114104
|
};
|
|
113398
114105
|
const renderActionContent = () => {
|
|
113399
|
-
var
|
|
114106
|
+
var _a2, _b;
|
|
113400
114107
|
let toolInvocations = node.toolInvocations || [];
|
|
113401
114108
|
if (node.type === "llm" && Array.isArray(node.output)) {
|
|
113402
114109
|
toolInvocations = node.output.filter(
|
|
@@ -113418,7 +114125,7 @@ function DebugCard({
|
|
|
113418
114125
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 truncate", children: child.name || "Unknown" })
|
|
113419
114126
|
] }, child.id || index))
|
|
113420
114127
|
] }),
|
|
113421
|
-
toolInvocations.length > 0 && ((_b = (
|
|
114128
|
+
toolInvocations.length > 0 && ((_b = (_a2 = toolInvocations[0]) == null ? void 0 : _a2.args) == null ? void 0 : _b.reason) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
113422
114129
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-400 mb-[4px]", children: "Reason" }),
|
|
113423
114130
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-600", children: toolInvocations[0].args.reason })
|
|
113424
114131
|
] })
|
|
@@ -113445,14 +114152,14 @@ function DebugCard({
|
|
|
113445
114152
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 italic", children: "No actions taken" });
|
|
113446
114153
|
};
|
|
113447
114154
|
const extractOutputMessage = (output) => {
|
|
113448
|
-
var
|
|
114155
|
+
var _a2, _b, _c, _d;
|
|
113449
114156
|
if (!output || typeof output !== "object") return void 0;
|
|
113450
114157
|
if (Array.isArray(output)) {
|
|
113451
114158
|
const routeToUserTool = output.find(
|
|
113452
114159
|
(item) => item && typeof item === "object" && (item.name === "route_to_user" || item.toolName === "route_to_user")
|
|
113453
114160
|
);
|
|
113454
114161
|
if (routeToUserTool) {
|
|
113455
|
-
return ((
|
|
114162
|
+
return ((_a2 = routeToUserTool.args) == null ? void 0 : _a2.message) || routeToUserTool.message || ((_b = routeToUserTool.output) == null ? void 0 : _b.message);
|
|
113456
114163
|
}
|
|
113457
114164
|
} else if (output.name === "route_to_user" || output.toolName === "route_to_user") {
|
|
113458
114165
|
return ((_c = output.args) == null ? void 0 : _c.message) || output.message || ((_d = output.output) == null ? void 0 : _d.message);
|
|
@@ -113549,7 +114256,7 @@ function DebugCard({
|
|
|
113549
114256
|
] });
|
|
113550
114257
|
};
|
|
113551
114258
|
const renderTabContent = () => {
|
|
113552
|
-
var
|
|
114259
|
+
var _a2;
|
|
113553
114260
|
switch (activeTab) {
|
|
113554
114261
|
case "summary":
|
|
113555
114262
|
if (isGuardrailsNode) {
|
|
@@ -113740,7 +114447,7 @@ function DebugCard({
|
|
|
113740
114447
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113741
114448
|
DataViewer,
|
|
113742
114449
|
{
|
|
113743
|
-
data: ((
|
|
114450
|
+
data: ((_a2 = node.metadata) == null ? void 0 : _a2["logs"]) || {},
|
|
113744
114451
|
title: "Execution Logs",
|
|
113745
114452
|
maxHeight: "250px",
|
|
113746
114453
|
defaultExpanded: true,
|
|
@@ -113753,15 +114460,15 @@ function DebugCard({
|
|
|
113753
114460
|
};
|
|
113754
114461
|
return (
|
|
113755
114462
|
// bg-white w-full border-t border-gray-200
|
|
113756
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id":
|
|
114463
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id": cardTestId, "data-call-type-test-id": callTypeTestId, children: [
|
|
113757
114464
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113758
114465
|
"div",
|
|
113759
114466
|
{
|
|
113760
114467
|
className: `flex items-center pl-[8px] pr-[8px] relative transition-colors cursor-pointer w-full
|
|
113761
114468
|
${isSelected ? "" : ""}`,
|
|
113762
114469
|
onClick: handleNodeClick,
|
|
113763
|
-
"data-test-id":
|
|
113764
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id":
|
|
114470
|
+
"data-test-id": `${callTypeTestId}_header`,
|
|
114471
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id": `${callTypeTestId}_header_content`, children: [
|
|
113765
114472
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113766
114473
|
"div",
|
|
113767
114474
|
{
|
|
@@ -113775,7 +114482,7 @@ function DebugCard({
|
|
|
113775
114482
|
}
|
|
113776
114483
|
},
|
|
113777
114484
|
title: hasChildren ? isExpanded ? "Collapse" : "Expand" : "Show details",
|
|
113778
|
-
"data-test-id":
|
|
114485
|
+
"data-test-id": `${callTypeTestId}_toggle`,
|
|
113779
114486
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113780
114487
|
ChevronRight,
|
|
113781
114488
|
{
|
|
@@ -113784,28 +114491,28 @@ function DebugCard({
|
|
|
113784
114491
|
)
|
|
113785
114492
|
}
|
|
113786
114493
|
),
|
|
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":
|
|
114494
|
+
/* @__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: [
|
|
114495
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 rounded-[8px] bg-[#B2DDFF]", "data-test-id": `${callTypeTestId}_node_icon`, children: getNodeIcon() }),
|
|
113789
114496
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113790
114497
|
"span",
|
|
113791
114498
|
{
|
|
113792
114499
|
className: "font-semibold text-gray-900 text-xs truncate w-full",
|
|
113793
114500
|
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
|
|
114501
|
+
"data-test-id": `${callTypeTestId}_node_name`,
|
|
114502
|
+
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
114503
|
}
|
|
113797
114504
|
),
|
|
113798
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id":
|
|
114505
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id": `${callTypeTestId}_node_metadata`, children: [
|
|
113799
114506
|
node.type === "Agent" && (() => {
|
|
113800
|
-
var
|
|
113801
|
-
const llmChild = (
|
|
114507
|
+
var _a2;
|
|
114508
|
+
const llmChild = (_a2 = node.children) == null ? void 0 : _a2.find((child) => child.type === "llm");
|
|
113802
114509
|
if (llmChild == null ? void 0 : llmChild.name) {
|
|
113803
114510
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113804
114511
|
"span",
|
|
113805
114512
|
{
|
|
113806
114513
|
className: "text-[10px] text-gray-500 truncate max-w-[100px]",
|
|
113807
114514
|
title: llmChild.name,
|
|
113808
|
-
"data-test-id":
|
|
114515
|
+
"data-test-id": `${callTypeTestId}_node_model_name`,
|
|
113809
114516
|
children: llmChild.name
|
|
113810
114517
|
}
|
|
113811
114518
|
);
|
|
@@ -113813,7 +114520,7 @@ function DebugCard({
|
|
|
113813
114520
|
return null;
|
|
113814
114521
|
})(),
|
|
113815
114522
|
(node.type === "Agent" || node.type === "llm" || isGuardrailsNode) && (() => {
|
|
113816
|
-
var
|
|
114523
|
+
var _a2, _b, _c;
|
|
113817
114524
|
let llmUsage = node.llmUsage;
|
|
113818
114525
|
if (node.type === "Agent" && node.children) {
|
|
113819
114526
|
const llmChildren = node.children.filter((child) => child.type === "llm");
|
|
@@ -113835,10 +114542,10 @@ function DebugCard({
|
|
|
113835
114542
|
"span",
|
|
113836
114543
|
{
|
|
113837
114544
|
className: "text-[10px] text-gray-500 whitespace-nowrap cursor-help",
|
|
113838
|
-
title: `Input: ${((
|
|
114545
|
+
title: `Input: ${((_a2 = llmUsage.input_tokens) == null ? void 0 : _a2.toLocaleString()) || 0} tokens
|
|
113839
114546
|
Output: ${((_b = llmUsage.output_tokens) == null ? void 0 : _b.toLocaleString()) || 0} tokens
|
|
113840
114547
|
Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) || 0} tokens`,
|
|
113841
|
-
"data-test-id":
|
|
114548
|
+
"data-test-id": `${callTypeTestId}_node_tokens`,
|
|
113842
114549
|
children: [
|
|
113843
114550
|
llmUsage.total_tokens.toLocaleString(),
|
|
113844
114551
|
" Tokens"
|
|
@@ -113848,34 +114555,34 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
|
|
|
113848
114555
|
}
|
|
113849
114556
|
return null;
|
|
113850
114557
|
})(),
|
|
113851
|
-
node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id":
|
|
114558
|
+
node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id": `${callTypeTestId}_node_duration`, children: [
|
|
113852
114559
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-[12px] h-[12px]" }),
|
|
113853
114560
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-gray-500 whitespace-nowrap", children: formatDuration(node.duration) })
|
|
113854
114561
|
] })
|
|
113855
114562
|
] }),
|
|
113856
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id":
|
|
114563
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id": `${callTypeTestId}_node_status`, children: getStatusIcon() })
|
|
113857
114564
|
] })
|
|
113858
114565
|
] })
|
|
113859
114566
|
}
|
|
113860
114567
|
),
|
|
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":
|
|
114568
|
+
isSelected && availableTabs.length > 0 && showDetailView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_detail_panel`, children: [
|
|
114569
|
+
/* @__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` }),
|
|
114570
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-[4px] py-[8px] w-full", "data-test-id": `${callTypeTestId}_detail_panel_content`, children: [
|
|
114571
|
+
/* @__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
114572
|
"button",
|
|
113866
114573
|
{
|
|
113867
114574
|
onClick: () => handleTabClick(tab),
|
|
113868
114575
|
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":
|
|
114576
|
+
"data-test-id": `${callTypeTestId}_detail_panel_tab_${tab}`,
|
|
113870
114577
|
children: tab.charAt(0).toUpperCase() + tab.slice(1)
|
|
113871
114578
|
},
|
|
113872
114579
|
tab
|
|
113873
114580
|
)) }),
|
|
113874
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id":
|
|
114581
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id": `${callTypeTestId}_detail_panel_tab_content`, children: renderTabContent() })
|
|
113875
114582
|
] })
|
|
113876
114583
|
] }),
|
|
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":
|
|
114584
|
+
isExpanded && hasChildren && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_children`, children: [
|
|
114585
|
+
/* @__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
114586
|
node.children.map((child, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
113880
114587
|
DebugCard,
|
|
113881
114588
|
{
|
|
@@ -113911,6 +114618,7 @@ const DebugPanel = forwardRef(({
|
|
|
113911
114618
|
expansionMode = "none",
|
|
113912
114619
|
showExpansionControls = false,
|
|
113913
114620
|
defaultDetailView = true,
|
|
114621
|
+
runHeaderInputMode = "display",
|
|
113914
114622
|
apiConfig
|
|
113915
114623
|
} = config2;
|
|
113916
114624
|
console.log("🔧 DebugPanel - Config received:", {
|
|
@@ -113971,10 +114679,12 @@ const DebugPanel = forwardRef(({
|
|
|
113971
114679
|
}
|
|
113972
114680
|
}), []);
|
|
113973
114681
|
const sessionTree = useMemo(() => {
|
|
113974
|
-
const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId
|
|
114682
|
+
const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId, {
|
|
114683
|
+
runHeaderInputMode
|
|
114684
|
+
});
|
|
113975
114685
|
prevSessionTreeRef.current = tree;
|
|
113976
114686
|
return tree;
|
|
113977
|
-
}, [executionEvents, sessionId]);
|
|
114687
|
+
}, [executionEvents, sessionId, runHeaderInputMode]);
|
|
113978
114688
|
const getAllNodeIds = (tree) => {
|
|
113979
114689
|
const nodeIds = [];
|
|
113980
114690
|
const collectIds = (node) => {
|
|
@@ -114382,16 +115092,25 @@ const DebugPanel = forwardRef(({
|
|
|
114382
115092
|
const findFinalOutput = (nodes) => {
|
|
114383
115093
|
let lastOutput = void 0;
|
|
114384
115094
|
let routeToUserOutput = void 0;
|
|
115095
|
+
let postProcessorOutput = void 0;
|
|
114385
115096
|
const traverse = (nodeList) => {
|
|
114386
|
-
var _a, _b, _c, _d, _e;
|
|
115097
|
+
var _a, _b, _c, _d, _e, _f;
|
|
114387
115098
|
for (const node of nodeList) {
|
|
115099
|
+
if (node.type === "tool" && ((_a = node.metadata) == null ? void 0 : _a.type) === "PostProcessor" && node.output) {
|
|
115100
|
+
const ppOut = node.output;
|
|
115101
|
+
if (typeof ppOut === "object" && ppOut.output) {
|
|
115102
|
+
postProcessorOutput = typeof ppOut.output === "string" ? ppOut.output : JSON.stringify(ppOut.output);
|
|
115103
|
+
} else if (typeof ppOut === "string") {
|
|
115104
|
+
postProcessorOutput = ppOut;
|
|
115105
|
+
}
|
|
115106
|
+
}
|
|
114388
115107
|
if (node.type === "tool" && (node.name === "route_to_user" || node.name === "route_to_user")) {
|
|
114389
115108
|
if (node.output) {
|
|
114390
115109
|
if (typeof node.output === "string") {
|
|
114391
115110
|
routeToUserOutput = node.output;
|
|
114392
|
-
} else if ((
|
|
115111
|
+
} else if ((_b = node.output) == null ? void 0 : _b.message) {
|
|
114393
115112
|
routeToUserOutput = node.output.message;
|
|
114394
|
-
} else if ((
|
|
115113
|
+
} else if ((_c = node.output) == null ? void 0 : _c.result) {
|
|
114395
115114
|
routeToUserOutput = node.output.result;
|
|
114396
115115
|
}
|
|
114397
115116
|
}
|
|
@@ -114401,7 +115120,7 @@ const DebugPanel = forwardRef(({
|
|
|
114401
115120
|
(item) => (item == null ? void 0 : item.name) === "route_to_user" || (item == null ? void 0 : item.toolName) === "route_to_user"
|
|
114402
115121
|
);
|
|
114403
115122
|
if (routeItem) {
|
|
114404
|
-
if ((
|
|
115123
|
+
if ((_d = routeItem.args) == null ? void 0 : _d.message) {
|
|
114405
115124
|
routeToUserOutput = routeItem.args.message;
|
|
114406
115125
|
} else if (routeItem.message) {
|
|
114407
115126
|
routeToUserOutput = routeItem.message;
|
|
@@ -114412,9 +115131,9 @@ const DebugPanel = forwardRef(({
|
|
|
114412
115131
|
if (typeof node.output === "string") {
|
|
114413
115132
|
lastOutput = node.output;
|
|
114414
115133
|
} else if (!Array.isArray(node.output)) {
|
|
114415
|
-
if ((
|
|
115134
|
+
if ((_e = node.output) == null ? void 0 : _e.message) {
|
|
114416
115135
|
lastOutput = node.output.message;
|
|
114417
|
-
} else if ((
|
|
115136
|
+
} else if ((_f = node.output) == null ? void 0 : _f.result) {
|
|
114418
115137
|
lastOutput = node.output.result;
|
|
114419
115138
|
} else if (typeof node.output === "object") {
|
|
114420
115139
|
if (!node.output.name && !node.output.toolName) {
|
|
@@ -114429,7 +115148,7 @@ const DebugPanel = forwardRef(({
|
|
|
114429
115148
|
}
|
|
114430
115149
|
};
|
|
114431
115150
|
traverse(nodes);
|
|
114432
|
-
return routeToUserOutput || lastOutput;
|
|
115151
|
+
return postProcessorOutput || routeToUserOutput || lastOutput;
|
|
114433
115152
|
};
|
|
114434
115153
|
const outputFromNodes = run2.rootNodes ? findFinalOutput(run2.rootNodes) : void 0;
|
|
114435
115154
|
const finalOutput = outputFromNodes || run2.finalOutput;
|
|
@@ -141250,6 +141969,57 @@ function nodeContentToInline(content) {
|
|
|
141250
141969
|
};
|
|
141251
141970
|
});
|
|
141252
141971
|
}
|
|
141972
|
+
function getVariableContextAtPosition(editor, pos) {
|
|
141973
|
+
const { doc: doc2 } = editor.state;
|
|
141974
|
+
if (pos < 2 || pos > doc2.content.size) {
|
|
141975
|
+
return null;
|
|
141976
|
+
}
|
|
141977
|
+
const $pos = doc2.resolve(pos);
|
|
141978
|
+
const parent = $pos.parent;
|
|
141979
|
+
if (!parent.isTextblock) {
|
|
141980
|
+
return null;
|
|
141981
|
+
}
|
|
141982
|
+
const contentStart = $pos.start();
|
|
141983
|
+
let text = "";
|
|
141984
|
+
const posMap = [];
|
|
141985
|
+
parent.forEach((node, offset2) => {
|
|
141986
|
+
const nodeDocStart = contentStart + offset2;
|
|
141987
|
+
if (nodeDocStart >= pos) return;
|
|
141988
|
+
if (node.isText && node.text) {
|
|
141989
|
+
const charsToTake = Math.min(node.text.length, pos - nodeDocStart);
|
|
141990
|
+
for (let i2 = 0; i2 < charsToTake; i2++) {
|
|
141991
|
+
posMap.push(nodeDocStart + i2);
|
|
141992
|
+
text += node.text[i2];
|
|
141993
|
+
}
|
|
141994
|
+
}
|
|
141995
|
+
});
|
|
141996
|
+
const lastOpen = text.lastIndexOf("{{");
|
|
141997
|
+
if (lastOpen === -1) {
|
|
141998
|
+
return null;
|
|
141999
|
+
}
|
|
142000
|
+
const queryText = text.substring(lastOpen + 2);
|
|
142001
|
+
if (queryText.includes("}}")) {
|
|
142002
|
+
return null;
|
|
142003
|
+
}
|
|
142004
|
+
const triggerFrom = posMap[lastOpen];
|
|
142005
|
+
if (triggerFrom === void 0) {
|
|
142006
|
+
return null;
|
|
142007
|
+
}
|
|
142008
|
+
const trimmedQuery = /^\}*$/.test(queryText) ? "" : queryText;
|
|
142009
|
+
return { triggerFrom, query: trimmedQuery };
|
|
142010
|
+
}
|
|
142011
|
+
const TYPE_PREFIXES = ["env", "memory", "system", "content"];
|
|
142012
|
+
function inferVariableType(path) {
|
|
142013
|
+
const firstDot = path.indexOf(".");
|
|
142014
|
+
if (firstDot === -1) return "custom";
|
|
142015
|
+
const prefix2 = path.substring(0, firstDot).toLowerCase();
|
|
142016
|
+
return TYPE_PREFIXES.includes(prefix2) ? prefix2 : "custom";
|
|
142017
|
+
}
|
|
142018
|
+
function removeTypePrefix(path) {
|
|
142019
|
+
const type = inferVariableType(path);
|
|
142020
|
+
if (type === "custom") return path;
|
|
142021
|
+
return path.substring(type.length + 1);
|
|
142022
|
+
}
|
|
141253
142023
|
const buildVariableSyntax = (variableType, path) => {
|
|
141254
142024
|
if (variableType === "system" || variableType === "custom") {
|
|
141255
142025
|
return `{{${path}}}`;
|
|
@@ -141968,6 +142738,27 @@ const ChevronRightIcon = ({ size = 16, className }) => /* @__PURE__ */ jsxRuntim
|
|
|
141968
142738
|
)
|
|
141969
142739
|
}
|
|
141970
142740
|
);
|
|
142741
|
+
const AIStarIcon = ({ size = 14, className }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
142742
|
+
"svg",
|
|
142743
|
+
{
|
|
142744
|
+
width: size,
|
|
142745
|
+
height: size,
|
|
142746
|
+
viewBox: "0 0 14 14",
|
|
142747
|
+
fill: "none",
|
|
142748
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
142749
|
+
className,
|
|
142750
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
142751
|
+
"path",
|
|
142752
|
+
{
|
|
142753
|
+
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",
|
|
142754
|
+
stroke: "currentColor",
|
|
142755
|
+
strokeWidth: "1.3",
|
|
142756
|
+
strokeLinecap: "round",
|
|
142757
|
+
strokeLinejoin: "round"
|
|
142758
|
+
}
|
|
142759
|
+
)
|
|
142760
|
+
}
|
|
142761
|
+
);
|
|
141971
142762
|
const CATEGORY_ICON_MAP = {
|
|
141972
142763
|
agents: AgentsIcon,
|
|
141973
142764
|
tools: ToolsIcon,
|
|
@@ -142844,7 +143635,7 @@ const VariableMenu = ({
|
|
|
142844
143635
|
setCurrentPath(parsedQuery.path);
|
|
142845
143636
|
}
|
|
142846
143637
|
}, [parsedQuery.category, parsedQuery.path, activeCategory]);
|
|
142847
|
-
|
|
143638
|
+
useLayoutEffect(() => {
|
|
142848
143639
|
if (!menuRef.current) return;
|
|
142849
143640
|
const menuRect = menuRef.current.getBoundingClientRect();
|
|
142850
143641
|
const viewportWidth = window.innerWidth;
|
|
@@ -142865,7 +143656,7 @@ const VariableMenu = ({
|
|
|
142865
143656
|
newTop = padding;
|
|
142866
143657
|
}
|
|
142867
143658
|
setAdjustedPosition({ top: newTop, left: newLeft });
|
|
142868
|
-
}, [position]);
|
|
143659
|
+
}, [position, activeCategory, currentPath.length, query]);
|
|
142869
143660
|
const categories = [
|
|
142870
143661
|
{ id: "env", label: "Environment Variables", icon: VariableIcon, variables: envVariables },
|
|
142871
143662
|
{ id: "memory", label: "Memory", icon: MemoryIcon, variables: memoryVariables },
|
|
@@ -142940,13 +143731,21 @@ const VariableMenu = ({
|
|
|
142940
143731
|
}
|
|
142941
143732
|
}, [editorControlled]);
|
|
142942
143733
|
useEffect(() => {
|
|
143734
|
+
const isEventInsideMenu = (event) => {
|
|
143735
|
+
if (!menuRef.current) return false;
|
|
143736
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
143737
|
+
if (path.length > 0) {
|
|
143738
|
+
return path.includes(menuRef.current);
|
|
143739
|
+
}
|
|
143740
|
+
return menuRef.current.contains(event.target);
|
|
143741
|
+
};
|
|
142943
143742
|
const handleClickOutside = (e3) => {
|
|
142944
|
-
if (
|
|
143743
|
+
if (!isEventInsideMenu(e3)) {
|
|
142945
143744
|
onClose();
|
|
142946
143745
|
}
|
|
142947
143746
|
};
|
|
142948
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
142949
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
143747
|
+
document.addEventListener("mousedown", handleClickOutside, true);
|
|
143748
|
+
return () => document.removeEventListener("mousedown", handleClickOutside, true);
|
|
142950
143749
|
}, [onClose]);
|
|
142951
143750
|
useEffect(() => {
|
|
142952
143751
|
const handleKeyDown2 = (e3) => {
|
|
@@ -143033,6 +143832,10 @@ const VariableMenu = ({
|
|
|
143033
143832
|
"button",
|
|
143034
143833
|
{
|
|
143035
143834
|
type: "button",
|
|
143835
|
+
onMouseDown: (e3) => {
|
|
143836
|
+
e3.preventDefault();
|
|
143837
|
+
e3.stopPropagation();
|
|
143838
|
+
},
|
|
143036
143839
|
onClick: handleBack,
|
|
143037
143840
|
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
143841
|
"aria-label": "Go back",
|
|
@@ -143058,7 +143861,7 @@ const VariableMenu = ({
|
|
|
143058
143861
|
)
|
|
143059
143862
|
] }) }),
|
|
143060
143863
|
!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) => {
|
|
143864
|
+
/* @__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
143865
|
var _a;
|
|
143063
143866
|
const isCategory = "variables" in item;
|
|
143064
143867
|
const Icon = isCategory ? item.icon : getIconForType(item.type);
|
|
@@ -143067,7 +143870,11 @@ const VariableMenu = ({
|
|
|
143067
143870
|
"button",
|
|
143068
143871
|
{
|
|
143069
143872
|
type: "button",
|
|
143070
|
-
|
|
143873
|
+
onMouseDown: (e3) => {
|
|
143874
|
+
e3.preventDefault();
|
|
143875
|
+
e3.stopPropagation();
|
|
143876
|
+
handleItemClick(item);
|
|
143877
|
+
},
|
|
143071
143878
|
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
143879
|
onMouseEnter: () => setSelectedIndex(index),
|
|
143073
143880
|
"data-test-id": `md-editor-variable-item-${isCategory ? item.id : item.id}`,
|
|
@@ -143643,7 +144450,9 @@ const UnifiedToolbar = ({
|
|
|
143643
144450
|
theme = "light",
|
|
143644
144451
|
disabled = false,
|
|
143645
144452
|
containerRef,
|
|
143646
|
-
followSelection = false
|
|
144453
|
+
followSelection = false,
|
|
144454
|
+
showDesignWithAI = false,
|
|
144455
|
+
onDesignWithAI
|
|
143647
144456
|
}) => {
|
|
143648
144457
|
const [position, setPosition] = useState(null);
|
|
143649
144458
|
const [isAtSelection, setIsAtSelection] = useState(false);
|
|
@@ -144001,7 +144810,30 @@ const UnifiedToolbar = ({
|
|
|
144001
144810
|
)
|
|
144002
144811
|
] }),
|
|
144003
144812
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarDivider$2, {}),
|
|
144004
|
-
|
|
144813
|
+
showDesignWithAI && onDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
144814
|
+
"button",
|
|
144815
|
+
{
|
|
144816
|
+
type: "button",
|
|
144817
|
+
onClick: (e3) => {
|
|
144818
|
+
e3.preventDefault();
|
|
144819
|
+
e3.stopPropagation();
|
|
144820
|
+
onDesignWithAI();
|
|
144821
|
+
},
|
|
144822
|
+
disabled,
|
|
144823
|
+
className: `
|
|
144824
|
+
flex items-center justify-center gap-1 px-3 py-1 rounded-[4px]
|
|
144825
|
+
text-[12px] leading-[16px] font-medium transition-colors duration-150 whitespace-nowrap
|
|
144826
|
+
border border-[#6A11CB] text-[#004EEB] hover:bg-[#EFF4FF]
|
|
144827
|
+
${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
|
|
144828
|
+
`,
|
|
144829
|
+
"data-id": "toolbar-design-with-ai",
|
|
144830
|
+
children: [
|
|
144831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AIStarIcon, { size: 14, className: "text-[#155EEF]" }),
|
|
144832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Design with AI" })
|
|
144833
|
+
]
|
|
144834
|
+
}
|
|
144835
|
+
),
|
|
144836
|
+
showAIButton && onAIAction && !showDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: aiDropdownRef, className: "relative shrink-0", children: [
|
|
144005
144837
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
144006
144838
|
"button",
|
|
144007
144839
|
{
|
|
@@ -144116,7 +144948,8 @@ const ACTION_LABELS = {
|
|
|
144116
144948
|
"make-shorter": "Make Shorter",
|
|
144117
144949
|
"make-longer": "Make Longer",
|
|
144118
144950
|
"convert-to-yaml": "Convert to YAML",
|
|
144119
|
-
"custom": "Custom Modify"
|
|
144951
|
+
"custom": "Custom Modify",
|
|
144952
|
+
"generate": "Generate"
|
|
144120
144953
|
};
|
|
144121
144954
|
function calculateTextSimilarity(text1, text2) {
|
|
144122
144955
|
if (text1 === text2) return 1;
|
|
@@ -144150,7 +144983,7 @@ const AIDesignPanel = ({
|
|
|
144150
144983
|
sessionState,
|
|
144151
144984
|
sessionActions
|
|
144152
144985
|
}) => {
|
|
144153
|
-
var _a, _b;
|
|
144986
|
+
var _a, _b, _c;
|
|
144154
144987
|
const useSessionMode = !!sessionState && !!sessionActions;
|
|
144155
144988
|
const [messages, setMessages] = useState([]);
|
|
144156
144989
|
const [inputValue, setInputValue] = useState("");
|
|
@@ -144166,6 +144999,36 @@ const AIDesignPanel = ({
|
|
|
144166
144999
|
const modificationReason = useSessionMode ? sessionState.modificationReason : selectionModifiedReason;
|
|
144167
145000
|
const currentGeneratedContent = useSessionMode ? (_b = sessionState.session) == null ? void 0 : _b.lastGeneratedContent : generatedContent;
|
|
144168
145001
|
const displayMessages = useSessionMode ? convertSessionHistoryToMessages(sessionState) : messages;
|
|
145002
|
+
const [appliedFeedback, setAppliedFeedback] = useState(null);
|
|
145003
|
+
const [copiedFeedback, setCopiedFeedback] = useState(false);
|
|
145004
|
+
const [pendingApplyMode, setPendingApplyMode] = useState(null);
|
|
145005
|
+
const [autocopiedOnFail, setAutocopiedOnFail] = useState(false);
|
|
145006
|
+
const appliedTimerRef = useRef(null);
|
|
145007
|
+
const copiedTimerRef = useRef(null);
|
|
145008
|
+
const lastAssistantMsgId = useMemo(() => {
|
|
145009
|
+
const assistantMsgs = displayMessages.filter(
|
|
145010
|
+
(m3) => m3.type === "assistant" && !m3.isGenerating && !m3.isError
|
|
145011
|
+
);
|
|
145012
|
+
return assistantMsgs.length > 0 ? assistantMsgs[assistantMsgs.length - 1].id : null;
|
|
145013
|
+
}, [displayMessages]);
|
|
145014
|
+
const showInsertButton = isSelectionMode;
|
|
145015
|
+
const cursorInsertActive = useSessionMode && sessionState.cursorInsertPosition !== null;
|
|
145016
|
+
const replaceTooltip = isSelectionMode ? "Replace selection" : "Replace all";
|
|
145017
|
+
const insertTooltip = cursorInsertActive ? "Insert at cursor" : "Insert below selection";
|
|
145018
|
+
useEffect(() => {
|
|
145019
|
+
return () => {
|
|
145020
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145021
|
+
if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
|
|
145022
|
+
};
|
|
145023
|
+
}, []);
|
|
145024
|
+
useEffect(() => {
|
|
145025
|
+
if (isCurrentlyGenerating) {
|
|
145026
|
+
setAppliedFeedback(null);
|
|
145027
|
+
setCopiedFeedback(false);
|
|
145028
|
+
setPendingApplyMode(null);
|
|
145029
|
+
setAutocopiedOnFail(false);
|
|
145030
|
+
}
|
|
145031
|
+
}, [isCurrentlyGenerating]);
|
|
144169
145032
|
useEffect(() => {
|
|
144170
145033
|
var _a2;
|
|
144171
145034
|
(_a2 = messagesEndRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
|
|
@@ -144269,8 +145132,9 @@ const AIDesignPanel = ({
|
|
|
144269
145132
|
setGeneratedContent(response.refinedText);
|
|
144270
145133
|
onContentGenerated == null ? void 0 : onContentGenerated(true);
|
|
144271
145134
|
} catch (error) {
|
|
145135
|
+
const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
|
|
144272
145136
|
setMessages((prev) => prev.map(
|
|
144273
|
-
(msg) => msg.id === aiMsgId ? { ...msg, content:
|
|
145137
|
+
(msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
|
|
144274
145138
|
));
|
|
144275
145139
|
} finally {
|
|
144276
145140
|
setIsGenerating(false);
|
|
@@ -144312,8 +145176,9 @@ const AIDesignPanel = ({
|
|
|
144312
145176
|
setGeneratedContent(response.refinedText);
|
|
144313
145177
|
onContentGenerated == null ? void 0 : onContentGenerated(true);
|
|
144314
145178
|
} catch (error) {
|
|
145179
|
+
const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
|
|
144315
145180
|
setMessages((prev) => prev.map(
|
|
144316
|
-
(msg) => msg.id === aiMsgId ? { ...msg, content:
|
|
145181
|
+
(msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
|
|
144317
145182
|
));
|
|
144318
145183
|
} finally {
|
|
144319
145184
|
setIsGenerating(false);
|
|
@@ -144348,6 +145213,52 @@ const AIDesignPanel = ({
|
|
|
144348
145213
|
};
|
|
144349
145214
|
}
|
|
144350
145215
|
}, [useSessionMode, sessionActions, generatedContent, onReplace, isSelectionMode]);
|
|
145216
|
+
const handleCopy = useCallback(async () => {
|
|
145217
|
+
var _a2;
|
|
145218
|
+
const content = useSessionMode ? (_a2 = sessionState == null ? void 0 : sessionState.session) == null ? void 0 : _a2.lastGeneratedContent : generatedContent;
|
|
145219
|
+
if (content) {
|
|
145220
|
+
await navigator.clipboard.writeText(content);
|
|
145221
|
+
setCopiedFeedback(true);
|
|
145222
|
+
if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
|
|
145223
|
+
copiedTimerRef.current = setTimeout(() => setCopiedFeedback(false), 2e3);
|
|
145224
|
+
}
|
|
145225
|
+
}, [useSessionMode, sessionState, generatedContent]);
|
|
145226
|
+
const handleInsertWithFeedback = useCallback(() => {
|
|
145227
|
+
setPendingApplyMode("insert");
|
|
145228
|
+
setAutocopiedOnFail(false);
|
|
145229
|
+
handleInsert();
|
|
145230
|
+
}, [handleInsert]);
|
|
145231
|
+
const handleReplaceWithFeedback = useCallback(() => {
|
|
145232
|
+
setPendingApplyMode("replace");
|
|
145233
|
+
setAutocopiedOnFail(false);
|
|
145234
|
+
handleReplace();
|
|
145235
|
+
}, [handleReplace]);
|
|
145236
|
+
useEffect(() => {
|
|
145237
|
+
var _a2;
|
|
145238
|
+
if (!pendingApplyMode) return;
|
|
145239
|
+
if (useSessionMode) {
|
|
145240
|
+
if (sessionState.status === "applied") {
|
|
145241
|
+
setAppliedFeedback(pendingApplyMode);
|
|
145242
|
+
setPendingApplyMode(null);
|
|
145243
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145244
|
+
appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
|
|
145245
|
+
} else if (sessionState.isOriginalModified) {
|
|
145246
|
+
const content = (_a2 = sessionState.session) == null ? void 0 : _a2.lastGeneratedContent;
|
|
145247
|
+
if (content) {
|
|
145248
|
+
navigator.clipboard.writeText(content).catch(() => {
|
|
145249
|
+
});
|
|
145250
|
+
setAutocopiedOnFail(true);
|
|
145251
|
+
}
|
|
145252
|
+
setAppliedFeedback(null);
|
|
145253
|
+
setPendingApplyMode(null);
|
|
145254
|
+
}
|
|
145255
|
+
} else {
|
|
145256
|
+
setAppliedFeedback(pendingApplyMode);
|
|
145257
|
+
setPendingApplyMode(null);
|
|
145258
|
+
if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
|
|
145259
|
+
appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
|
|
145260
|
+
}
|
|
145261
|
+
}, [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
145262
|
const handleStop = useCallback(() => {
|
|
144352
145263
|
if (useSessionMode) {
|
|
144353
145264
|
return;
|
|
@@ -144447,34 +145358,71 @@ const AIDesignPanel = ({
|
|
|
144447
145358
|
// Result - gray background bubble
|
|
144448
145359
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full", children: [
|
|
144449
145360
|
/* @__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
|
-
|
|
145361
|
+
message.id === lastAssistantMsgId && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: appliedFeedback ? (
|
|
145362
|
+
/* Success feedback */
|
|
145363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-[#12B76A] animate-[fadeIn_0.2s_ease-out]", children: [
|
|
145364
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, strokeWidth: 2.5 }),
|
|
145365
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: appliedFeedback === "replace" ? "Replaced" : "Inserted" }),
|
|
145366
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-[#667085] ml-1", children: [
|
|
145367
|
+
navigator.platform.includes("Mac") ? "⌘Z" : "Ctrl+Z",
|
|
145368
|
+
" to undo"
|
|
145369
|
+
] })
|
|
145370
|
+
] })
|
|
145371
|
+
) : isModified ? (
|
|
145372
|
+
/* Recovery UI -- original text was modified, apply would fail */
|
|
145373
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 animate-[fadeIn_0.2s_ease-out]", children: [
|
|
145374
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145375
|
+
"button",
|
|
145376
|
+
{
|
|
145377
|
+
type: "button",
|
|
145378
|
+
onClick: handleCopy,
|
|
145379
|
+
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",
|
|
145380
|
+
children: copiedFeedback || autocopiedOnFail ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
145381
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 12, className: "text-[#12B76A]" }),
|
|
145382
|
+
" Copied"
|
|
145383
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
145384
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 12 }),
|
|
145385
|
+
" Copy content"
|
|
145386
|
+
] })
|
|
145387
|
+
}
|
|
145388
|
+
) }),
|
|
145389
|
+
/* @__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.` })
|
|
145390
|
+
] })
|
|
145391
|
+
) : (
|
|
145392
|
+
/* Normal action buttons */
|
|
145393
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
145394
|
+
(onReplace || useSessionMode) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145395
|
+
"button",
|
|
145396
|
+
{
|
|
145397
|
+
type: "button",
|
|
145398
|
+
onClick: handleReplaceWithFeedback,
|
|
145399
|
+
title: replaceTooltip,
|
|
145400
|
+
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",
|
|
145401
|
+
children: "Replace"
|
|
145402
|
+
}
|
|
145403
|
+
),
|
|
145404
|
+
showInsertButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145405
|
+
"button",
|
|
145406
|
+
{
|
|
145407
|
+
type: "button",
|
|
145408
|
+
onClick: handleInsertWithFeedback,
|
|
145409
|
+
title: insertTooltip,
|
|
145410
|
+
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",
|
|
145411
|
+
children: "Insert"
|
|
145412
|
+
}
|
|
145413
|
+
),
|
|
145414
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
145415
|
+
"button",
|
|
145416
|
+
{
|
|
145417
|
+
type: "button",
|
|
145418
|
+
onClick: handleCopy,
|
|
145419
|
+
title: copiedFeedback ? "Copied!" : "Copy to clipboard",
|
|
145420
|
+
className: "p-1 text-[#667085] hover:text-[#344054] hover:bg-gray-100 rounded transition-colors cursor-pointer",
|
|
145421
|
+
children: copiedFeedback ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 })
|
|
145422
|
+
}
|
|
145423
|
+
)
|
|
145424
|
+
] })
|
|
145425
|
+
) })
|
|
144478
145426
|
] })
|
|
144479
145427
|
) })
|
|
144480
145428
|
) }, message.id)),
|
|
@@ -144557,6 +145505,32 @@ function convertSessionHistoryToMessages(sessionState) {
|
|
|
144557
145505
|
}
|
|
144558
145506
|
return messages;
|
|
144559
145507
|
}
|
|
145508
|
+
const EmptyStatePlaceholder = ({
|
|
145509
|
+
placeholder = "Write your agent definition here or type '/' to insert variables, agents, tools, memory & more",
|
|
145510
|
+
example,
|
|
145511
|
+
isFocused = false
|
|
145512
|
+
}) => {
|
|
145513
|
+
if (isFocused) return null;
|
|
145514
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
145515
|
+
"div",
|
|
145516
|
+
{
|
|
145517
|
+
className: "absolute inset-0 pointer-events-none px-[32px] py-[24px] overflow-hidden",
|
|
145518
|
+
"data-id": "md-editor-empty-state",
|
|
145519
|
+
children: [
|
|
145520
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3] mb-[8px]", children: placeholder }),
|
|
145521
|
+
example && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3]", children: example })
|
|
145522
|
+
]
|
|
145523
|
+
}
|
|
145524
|
+
);
|
|
145525
|
+
};
|
|
145526
|
+
const AgentDefinitionExample = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
145527
|
+
/* @__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." }),
|
|
145528
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-disc ml-[21px]", children: [
|
|
145529
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Match prospect needs with sales expertise" }) }),
|
|
145530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Find optimal meeting times across calendars" }) }),
|
|
145531
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Distribute meeting agenda and materials" }) })
|
|
145532
|
+
] })
|
|
145533
|
+
] });
|
|
144560
145534
|
function hashString(str) {
|
|
144561
145535
|
let hash2 = 5381;
|
|
144562
145536
|
for (let i2 = 0; i2 < str.length; i2++) {
|
|
@@ -144766,7 +145740,8 @@ const initialState = {
|
|
|
144766
145740
|
modificationReason: "",
|
|
144767
145741
|
pendingSelection: null,
|
|
144768
145742
|
showSwitchBanner: false,
|
|
144769
|
-
error: null
|
|
145743
|
+
error: null,
|
|
145744
|
+
cursorInsertPosition: null
|
|
144770
145745
|
};
|
|
144771
145746
|
function refinementReducer(state, action) {
|
|
144772
145747
|
switch (action.type) {
|
|
@@ -144877,7 +145852,7 @@ function refinementReducer(state, action) {
|
|
|
144877
145852
|
}
|
|
144878
145853
|
case "APPLY_CONTENT": {
|
|
144879
145854
|
if (!state.session) return state;
|
|
144880
|
-
const { appliedContent } = action.payload;
|
|
145855
|
+
const { appliedContent, newFingerprint } = action.payload;
|
|
144881
145856
|
return {
|
|
144882
145857
|
...state,
|
|
144883
145858
|
status: "applied",
|
|
@@ -144885,8 +145860,11 @@ function refinementReducer(state, action) {
|
|
|
144885
145860
|
...state.session,
|
|
144886
145861
|
appliedContent,
|
|
144887
145862
|
applyCount: state.session.applyCount + 1,
|
|
144888
|
-
workingContent: appliedContent
|
|
145863
|
+
workingContent: appliedContent,
|
|
144889
145864
|
// For subsequent refinements
|
|
145865
|
+
// Update fingerprint to track the newly applied content's position
|
|
145866
|
+
// This enables subsequent iterations to work on the replaced content
|
|
145867
|
+
fingerprint: newFingerprint || state.session.fingerprint
|
|
144890
145868
|
},
|
|
144891
145869
|
isOriginalModified: false,
|
|
144892
145870
|
modificationReason: ""
|
|
@@ -144894,9 +145872,9 @@ function refinementReducer(state, action) {
|
|
|
144894
145872
|
}
|
|
144895
145873
|
case "SELECTION_CHANGED": {
|
|
144896
145874
|
if (!state.session) return state;
|
|
144897
|
-
const { fingerprint } = action.payload;
|
|
144898
|
-
const
|
|
144899
|
-
const newMode =
|
|
145875
|
+
const { fingerprint, explicitMode } = action.payload;
|
|
145876
|
+
const inferredMode = fingerprint.contextBefore === "" && fingerprint.contextAfter === "" ? "full-document" : "selection";
|
|
145877
|
+
const newMode = explicitMode ?? inferredMode;
|
|
144900
145878
|
return {
|
|
144901
145879
|
...state,
|
|
144902
145880
|
session: {
|
|
@@ -144904,8 +145882,10 @@ function refinementReducer(state, action) {
|
|
|
144904
145882
|
mode: newMode,
|
|
144905
145883
|
fingerprint,
|
|
144906
145884
|
workingContent: fingerprint.selectedMarkdown,
|
|
144907
|
-
// Reset
|
|
144908
|
-
appliedContent: null
|
|
145885
|
+
// Reset apply state since selection changed -- previous apply context is irrelevant
|
|
145886
|
+
appliedContent: null,
|
|
145887
|
+
applyCount: 0,
|
|
145888
|
+
lastGeneratedContent: null
|
|
144909
145889
|
},
|
|
144910
145890
|
// Clear modification state since we have a fresh selection
|
|
144911
145891
|
isOriginalModified: false,
|
|
@@ -144913,7 +145893,8 @@ function refinementReducer(state, action) {
|
|
|
144913
145893
|
// Only show switch banner if there was content and this is user-initiated selection change
|
|
144914
145894
|
// For now, keep it simple - don't show banner, just update context
|
|
144915
145895
|
pendingSelection: null,
|
|
144916
|
-
showSwitchBanner: false
|
|
145896
|
+
showSwitchBanner: false,
|
|
145897
|
+
cursorInsertPosition: null
|
|
144917
145898
|
};
|
|
144918
145899
|
}
|
|
144919
145900
|
case "CONFIRM_SWITCH": {
|
|
@@ -144982,6 +145963,11 @@ function refinementReducer(state, action) {
|
|
|
144982
145963
|
}
|
|
144983
145964
|
};
|
|
144984
145965
|
}
|
|
145966
|
+
case "SET_CURSOR_INSERT_POSITION":
|
|
145967
|
+
return {
|
|
145968
|
+
...state,
|
|
145969
|
+
cursorInsertPosition: action.payload.position
|
|
145970
|
+
};
|
|
144985
145971
|
default:
|
|
144986
145972
|
return state;
|
|
144987
145973
|
}
|
|
@@ -144991,7 +145977,8 @@ function useAIRefinementSession({
|
|
|
144991
145977
|
onRefine,
|
|
144992
145978
|
editorContent,
|
|
144993
145979
|
promptType,
|
|
144994
|
-
agentContext
|
|
145980
|
+
agentContext,
|
|
145981
|
+
onContentApplied
|
|
144995
145982
|
}) {
|
|
144996
145983
|
const [state, dispatch] = useReducer(refinementReducer, initialState);
|
|
144997
145984
|
const hasGeneratedContentRef = useRef(false);
|
|
@@ -145010,14 +145997,18 @@ function useAIRefinementSession({
|
|
|
145010
145997
|
});
|
|
145011
145998
|
if (editor) {
|
|
145012
145999
|
let fingerprint;
|
|
145013
|
-
|
|
146000
|
+
const isSelection = !!range3 && range3.from !== range3.to;
|
|
146001
|
+
if (isSelection) {
|
|
145014
146002
|
fingerprint = createSelectionFingerprint(editor, range3.from, range3.to);
|
|
145015
146003
|
} else {
|
|
145016
146004
|
fingerprint = createFullDocumentFingerprint(editor);
|
|
145017
146005
|
}
|
|
145018
146006
|
dispatch({
|
|
145019
146007
|
type: "SELECTION_CHANGED",
|
|
145020
|
-
payload: {
|
|
146008
|
+
payload: {
|
|
146009
|
+
fingerprint,
|
|
146010
|
+
explicitMode: isSelection ? "selection" : "full-document"
|
|
146011
|
+
}
|
|
145021
146012
|
});
|
|
145022
146013
|
}
|
|
145023
146014
|
}, [editor]);
|
|
@@ -145027,13 +146018,24 @@ function useAIRefinementSession({
|
|
|
145027
146018
|
}, []);
|
|
145028
146019
|
const startGeneration = useCallback(async (action, instruction) => {
|
|
145029
146020
|
if (!onRefine || !state.session) return;
|
|
145030
|
-
|
|
146021
|
+
let contextText;
|
|
146022
|
+
if (state.session.mode === "full-document" && state.session.applyCount > 0) {
|
|
146023
|
+
contextText = editorContent || state.session.appliedContent || state.session.workingContent;
|
|
146024
|
+
} else if (state.session.applyCount > 0) {
|
|
146025
|
+
contextText = state.session.appliedContent || state.session.workingContent;
|
|
146026
|
+
} else {
|
|
146027
|
+
contextText = state.session.lastGeneratedContent || state.session.workingContent;
|
|
146028
|
+
}
|
|
146029
|
+
if (!contextText) {
|
|
146030
|
+
contextText = editorContent;
|
|
146031
|
+
}
|
|
145031
146032
|
const actionLabels = {
|
|
145032
146033
|
"improve": "Improve",
|
|
145033
146034
|
"make-shorter": "Make Shorter",
|
|
145034
146035
|
"make-longer": "Make Longer",
|
|
145035
146036
|
"convert-to-yaml": "Convert to YAML",
|
|
145036
|
-
"custom": instruction || "Custom"
|
|
146037
|
+
"custom": instruction || "Custom",
|
|
146038
|
+
"generate": "Generate new content"
|
|
145037
146039
|
};
|
|
145038
146040
|
const displayMessage = instruction || actionLabels[action] || action;
|
|
145039
146041
|
const isFirstMessage = state.session.conversationHistory.length === 0;
|
|
@@ -145093,7 +146095,7 @@ function useAIRefinementSession({
|
|
|
145093
146095
|
"custom": instruction || "Custom"
|
|
145094
146096
|
};
|
|
145095
146097
|
const displayMessage = instruction || actionLabels[action] || action;
|
|
145096
|
-
const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent;
|
|
146098
|
+
const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent || editorContent;
|
|
145097
146099
|
const quotedText = contentForAI.length > 100 ? `${contentForAI.substring(0, 100)}...` : contentForAI;
|
|
145098
146100
|
dispatch({
|
|
145099
146101
|
type: "START_GENERATION",
|
|
@@ -145137,11 +146139,13 @@ function useAIRefinementSession({
|
|
|
145137
146139
|
if (!editor || !state.session || !state.session.lastGeneratedContent) return;
|
|
145138
146140
|
const refinedText = state.session.lastGeneratedContent;
|
|
145139
146141
|
let result;
|
|
146142
|
+
let newFingerprint;
|
|
145140
146143
|
if (state.session.mode === "full-document") {
|
|
145141
146144
|
try {
|
|
145142
146145
|
const parsed = markdownToEditorJson(refinedText);
|
|
145143
146146
|
editor.commands.setContent(parsed);
|
|
145144
146147
|
result = { success: true };
|
|
146148
|
+
newFingerprint = createFullDocumentFingerprint(editor);
|
|
145145
146149
|
} catch (error) {
|
|
145146
146150
|
result = {
|
|
145147
146151
|
success: false,
|
|
@@ -145161,10 +146165,17 @@ function useAIRefinementSession({
|
|
|
145161
146165
|
} else {
|
|
145162
146166
|
try {
|
|
145163
146167
|
const parsedContent = markdownToEditorJson(refinedText);
|
|
146168
|
+
const insertionStart = matchedRange.from;
|
|
145164
146169
|
if (mode === "replace") {
|
|
145165
146170
|
editor.chain().focus().setTextSelection(matchedRange).deleteSelection().insertContent(parsedContent).run();
|
|
146171
|
+
const newEndPos = editor.state.selection.to;
|
|
146172
|
+
newFingerprint = createSelectionFingerprint(editor, insertionStart, newEndPos);
|
|
145166
146173
|
} else {
|
|
145167
|
-
|
|
146174
|
+
const useCursorPos = state.cursorInsertPosition !== null && state.cursorInsertPosition !== matchedRange.to;
|
|
146175
|
+
const insertPos = useCursorPos ? state.cursorInsertPosition : matchedRange.to;
|
|
146176
|
+
editor.chain().focus().setTextSelection({ from: insertPos, to: insertPos }).insertContent("\n\n").insertContent(parsedContent).run();
|
|
146177
|
+
const newEndPos = editor.state.selection.to;
|
|
146178
|
+
newFingerprint = createSelectionFingerprint(editor, insertPos + 2, newEndPos);
|
|
145168
146179
|
}
|
|
145169
146180
|
result = { success: true };
|
|
145170
146181
|
} catch (error) {
|
|
@@ -145179,8 +146190,12 @@ function useAIRefinementSession({
|
|
|
145179
146190
|
if (result.success) {
|
|
145180
146191
|
dispatch({
|
|
145181
146192
|
type: "APPLY_CONTENT",
|
|
145182
|
-
payload: { mode, appliedContent: refinedText }
|
|
146193
|
+
payload: { mode, appliedContent: refinedText, newFingerprint }
|
|
145183
146194
|
});
|
|
146195
|
+
if (onContentApplied && editor) {
|
|
146196
|
+
const fullMarkdown = state.session.mode === "full-document" ? refinedText : editorJsonToMarkdown(editor.getJSON());
|
|
146197
|
+
onContentApplied(fullMarkdown);
|
|
146198
|
+
}
|
|
145184
146199
|
} else {
|
|
145185
146200
|
dispatch({
|
|
145186
146201
|
type: "SET_MODIFIED",
|
|
@@ -145190,7 +146205,7 @@ function useAIRefinementSession({
|
|
|
145190
146205
|
}
|
|
145191
146206
|
});
|
|
145192
146207
|
}
|
|
145193
|
-
}, [editor, state.session]);
|
|
146208
|
+
}, [editor, state.session, state.cursorInsertPosition, onContentApplied]);
|
|
145194
146209
|
const handleSelectionChange = useCallback((from2, to, _text) => {
|
|
145195
146210
|
if (!editor || !state.session) return;
|
|
145196
146211
|
if (from2 === to) return;
|
|
@@ -145202,7 +146217,7 @@ function useAIRefinementSession({
|
|
|
145202
146217
|
}
|
|
145203
146218
|
dispatch({
|
|
145204
146219
|
type: "SELECTION_CHANGED",
|
|
145205
|
-
payload: { fingerprint: newFingerprint }
|
|
146220
|
+
payload: { fingerprint: newFingerprint, explicitMode: "selection" }
|
|
145206
146221
|
});
|
|
145207
146222
|
}, [editor, state.session]);
|
|
145208
146223
|
const confirmSwitch = useCallback(() => {
|
|
@@ -145241,19 +146256,31 @@ function useAIRefinementSession({
|
|
|
145241
146256
|
useEffect(() => {
|
|
145242
146257
|
if (!editor || state.status === "idle") return;
|
|
145243
146258
|
const handleSelectionUpdate = () => {
|
|
146259
|
+
var _a, _b;
|
|
145244
146260
|
const { from: from2, to } = editor.state.selection;
|
|
145245
146261
|
const hasSelection2 = from2 !== to;
|
|
145246
|
-
if (
|
|
145247
|
-
|
|
146262
|
+
if (hasSelection2) {
|
|
146263
|
+
if (hasGeneratedContentRef.current) {
|
|
146264
|
+
const selectedText = editor.state.doc.textBetween(from2, to, " ", "\n");
|
|
146265
|
+
handleSelectionChange(from2, to, selectedText);
|
|
146266
|
+
}
|
|
146267
|
+
if (state.cursorInsertPosition !== null) {
|
|
146268
|
+
dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: null } });
|
|
146269
|
+
}
|
|
146270
|
+
} else if (((_a = state.session) == null ? void 0 : _a.mode) === "selection" && ((_b = state.session) == null ? void 0 : _b.fingerprint) && hasGeneratedContentRef.current) {
|
|
146271
|
+
const fp = state.session.fingerprint;
|
|
146272
|
+
const isOutside = from2 < fp.originalRange.from || from2 > fp.originalRange.to;
|
|
146273
|
+
const newPos = isOutside ? from2 : null;
|
|
146274
|
+
if (newPos !== state.cursorInsertPosition) {
|
|
146275
|
+
dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: newPos } });
|
|
146276
|
+
}
|
|
145248
146277
|
}
|
|
145249
|
-
const selectedText = editor.state.doc.textBetween(from2, to, " ", "\n");
|
|
145250
|
-
handleSelectionChange(from2, to, selectedText);
|
|
145251
146278
|
};
|
|
145252
146279
|
editor.on("selectionUpdate", handleSelectionUpdate);
|
|
145253
146280
|
return () => {
|
|
145254
146281
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
145255
146282
|
};
|
|
145256
|
-
}, [editor, state.status, handleSelectionChange]);
|
|
146283
|
+
}, [editor, state.status, state.session, state.cursorInsertPosition, handleSelectionChange]);
|
|
145257
146284
|
const actions = {
|
|
145258
146285
|
openPanel,
|
|
145259
146286
|
closePanel,
|
|
@@ -145320,7 +146347,12 @@ const MDEditor = forwardRef(
|
|
|
145320
146347
|
onFocus,
|
|
145321
146348
|
onBlur,
|
|
145322
146349
|
onLoadSuggestions,
|
|
145323
|
-
suggestionsLoading: propSuggestionsLoading = false
|
|
146350
|
+
suggestionsLoading: propSuggestionsLoading = false,
|
|
146351
|
+
// Empty state props
|
|
146352
|
+
emptyStatePlaceholder,
|
|
146353
|
+
emptyStateExample,
|
|
146354
|
+
showDesignWithAI = false,
|
|
146355
|
+
onDesignWithAI
|
|
145324
146356
|
} = props;
|
|
145325
146357
|
const mergedSlashConfig = { ...DEFAULT_SLASH_COMMAND_CONFIG, ...slashCommandConfig };
|
|
145326
146358
|
const mergedAIConfig = { ...DEFAULT_AI_CONFIG, ...aiConfig };
|
|
@@ -145328,13 +146360,16 @@ const MDEditor = forwardRef(
|
|
|
145328
146360
|
const lastEmittedMarkdownRef = useRef("");
|
|
145329
146361
|
const isInternalUpdateRef = useRef(false);
|
|
145330
146362
|
const editorContainerRef = useRef(null);
|
|
146363
|
+
const skipRawSyncRef = useRef(false);
|
|
146364
|
+
const skipEditorSyncRef = useRef(false);
|
|
145331
146365
|
const [asyncSuggestions, setAsyncSuggestions] = useState(null);
|
|
145332
146366
|
const [suggestionsLoading, setSuggestionsLoading] = useState(false);
|
|
145333
146367
|
const [variableMenuOpen, setVariableMenuOpen] = useState(false);
|
|
145334
146368
|
const [variableMenuPosition, setVariableMenuPosition] = useState({ top: 0, left: 0 });
|
|
145335
146369
|
const [variableMenuQuery, setVariableMenuQuery] = useState("");
|
|
145336
|
-
const [editingVariableChip, setEditingVariableChip] = useState(null);
|
|
145337
146370
|
const variableTriggerPosRef = useRef(null);
|
|
146371
|
+
const hasVariableSuggestionsRef = useRef(false);
|
|
146372
|
+
const variableMenuOpenRef = useRef(false);
|
|
145338
146373
|
const [editorMode, setEditorMode] = useState("editor");
|
|
145339
146374
|
const [rawMarkdown, setRawMarkdown] = useState("");
|
|
145340
146375
|
const isRawMode = editorMode === "preview";
|
|
@@ -145378,12 +146413,7 @@ const MDEditor = forwardRef(
|
|
|
145378
146413
|
contentVariables: mergedContentVariables,
|
|
145379
146414
|
loading: finalSuggestionsLoading
|
|
145380
146415
|
};
|
|
145381
|
-
|
|
145382
|
-
agentsCount: mergedAgents.length,
|
|
145383
|
-
toolsCount: mergedTools.length,
|
|
145384
|
-
knowledgeCount: mergedKnowledge.length,
|
|
145385
|
-
hasAsyncSuggestions: !!asyncSuggestions
|
|
145386
|
-
});
|
|
146416
|
+
hasVariableSuggestionsRef.current = mergedEnvVariables.length > 0 || mergedMemoryVariables.length > 0 || mergedSystemVariables.length > 0 || mergedContentVariables.length > 0;
|
|
145387
146417
|
const defaultCategories = useMemo(() => {
|
|
145388
146418
|
const categories = [];
|
|
145389
146419
|
if (mergedAgents.length > 0) {
|
|
@@ -145448,21 +146478,6 @@ const MDEditor = forwardRef(
|
|
|
145448
146478
|
(variable, triggerPos) => {
|
|
145449
146479
|
if (!editorRef.current) return;
|
|
145450
146480
|
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
146481
|
const deleteFrom = triggerPos ?? variableTriggerPosRef.current;
|
|
145467
146482
|
if (deleteFrom !== null) {
|
|
145468
146483
|
const { from: from2 } = editor2.state.selection;
|
|
@@ -145475,6 +146490,10 @@ const MDEditor = forwardRef(
|
|
|
145475
146490
|
displayName: variable.name
|
|
145476
146491
|
}
|
|
145477
146492
|
}).insertContent(" ").run();
|
|
146493
|
+
const posAfter = editor2.state.selection.from;
|
|
146494
|
+
if (posAfter + 2 <= editor2.state.doc.content.size && editor2.state.doc.textBetween(posAfter, posAfter + 2) === "}}") {
|
|
146495
|
+
editor2.chain().focus().deleteRange({ from: posAfter, to: posAfter + 2 }).run();
|
|
146496
|
+
}
|
|
145478
146497
|
} else {
|
|
145479
146498
|
editor2.chain().focus().insertContent({
|
|
145480
146499
|
type: "variableChip",
|
|
@@ -145489,7 +146508,19 @@ const MDEditor = forwardRef(
|
|
|
145489
146508
|
setVariableMenuQuery("");
|
|
145490
146509
|
variableTriggerPosRef.current = null;
|
|
145491
146510
|
},
|
|
145492
|
-
[
|
|
146511
|
+
[]
|
|
146512
|
+
);
|
|
146513
|
+
const handleVariableQueryChange = useCallback(
|
|
146514
|
+
(newQuery) => {
|
|
146515
|
+
setVariableMenuQuery(newQuery);
|
|
146516
|
+
if (!editorRef.current || variableTriggerPosRef.current === null) return;
|
|
146517
|
+
const editor2 = editorRef.current;
|
|
146518
|
+
const triggerPos = variableTriggerPosRef.current;
|
|
146519
|
+
const insertFrom = triggerPos + 2;
|
|
146520
|
+
const { from: from2 } = editor2.state.selection;
|
|
146521
|
+
editor2.chain().focus().deleteRange({ from: insertFrom, to: from2 }).insertContentAt(insertFrom, newQuery).run();
|
|
146522
|
+
},
|
|
146523
|
+
[]
|
|
145493
146524
|
);
|
|
145494
146525
|
const insertMention = useCallback(
|
|
145495
146526
|
(mention) => {
|
|
@@ -145524,14 +146555,23 @@ const MDEditor = forwardRef(
|
|
|
145524
146555
|
const json = editorRef.current.getJSON();
|
|
145525
146556
|
const markdown = editorJsonToMarkdown(json);
|
|
145526
146557
|
setRawMarkdown(markdown);
|
|
146558
|
+
lastEmittedMarkdownRef.current = markdown;
|
|
146559
|
+
skipRawSyncRef.current = true;
|
|
145527
146560
|
}
|
|
145528
146561
|
if (currentMode === "preview" && newMode === "editor") {
|
|
145529
146562
|
const parsedContent = markdownToEditorJson(rawMarkdown);
|
|
146563
|
+
isInternalUpdateRef.current = true;
|
|
145530
146564
|
editorRef.current.commands.setContent(parsedContent);
|
|
145531
146565
|
lastEmittedMarkdownRef.current = rawMarkdown;
|
|
146566
|
+
skipEditorSyncRef.current = true;
|
|
146567
|
+
onMarkdownChange == null ? void 0 : onMarkdownChange(rawMarkdown);
|
|
146568
|
+
if (onChange) {
|
|
146569
|
+
const doc2 = editorJsonToDocument(parsedContent);
|
|
146570
|
+
onChange(doc2, rawMarkdown);
|
|
146571
|
+
}
|
|
145532
146572
|
}
|
|
145533
146573
|
setEditorMode(newMode);
|
|
145534
|
-
}, [editorMode, rawMarkdown]);
|
|
146574
|
+
}, [editorMode, rawMarkdown, onChange, onMarkdownChange]);
|
|
145535
146575
|
const toggleRawMode = useCallback(() => {
|
|
145536
146576
|
handleModeChange(isRawMode ? "editor" : "preview");
|
|
145537
146577
|
}, [handleModeChange, isRawMode]);
|
|
@@ -145546,13 +146586,17 @@ const MDEditor = forwardRef(
|
|
|
145546
146586
|
dropcursor: false
|
|
145547
146587
|
}),
|
|
145548
146588
|
Placeholder.configure({
|
|
145549
|
-
placeholder: ({ node }) => {
|
|
146589
|
+
placeholder: ({ node, editor: placeholderEditor }) => {
|
|
146590
|
+
if (emptyStatePlaceholder && placeholderEditor.isEmpty) {
|
|
146591
|
+
return "";
|
|
146592
|
+
}
|
|
145550
146593
|
if (node.type.name === "heading") {
|
|
145551
146594
|
const level = node.attrs["level"];
|
|
145552
146595
|
return `Heading ${level}`;
|
|
145553
146596
|
}
|
|
145554
146597
|
if (node.type.name === "paragraph") {
|
|
145555
|
-
|
|
146598
|
+
const focusPlaceholder = "Type here or '/' to insert variables, agents, tools, memory & more";
|
|
146599
|
+
return placeholderEditor.isEmpty ? placeholder : focusPlaceholder;
|
|
145556
146600
|
}
|
|
145557
146601
|
return "";
|
|
145558
146602
|
},
|
|
@@ -145622,7 +146666,7 @@ const MDEditor = forwardRef(
|
|
|
145622
146666
|
);
|
|
145623
146667
|
}
|
|
145624
146668
|
return exts;
|
|
145625
|
-
}, [mergedFeatures, placeholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
|
|
146669
|
+
}, [mergedFeatures, placeholder, emptyStatePlaceholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
|
|
145626
146670
|
const editorRef = useRef(null);
|
|
145627
146671
|
const editor = useEditor({
|
|
145628
146672
|
extensions,
|
|
@@ -145656,12 +146700,24 @@ const MDEditor = forwardRef(
|
|
|
145656
146700
|
editorRef.current = editor;
|
|
145657
146701
|
}, [editor]);
|
|
145658
146702
|
const editorContent = editor ? editorJsonToMarkdown(editor.getJSON()) : "";
|
|
146703
|
+
const handleAIContentApplied = useCallback((markdown) => {
|
|
146704
|
+
lastEmittedMarkdownRef.current = markdown;
|
|
146705
|
+
if (onMarkdownChange) {
|
|
146706
|
+
onMarkdownChange(markdown);
|
|
146707
|
+
}
|
|
146708
|
+
if (onChange) {
|
|
146709
|
+
const json = markdownToEditorJson(markdown);
|
|
146710
|
+
const doc2 = editorJsonToDocument(json);
|
|
146711
|
+
onChange(doc2, markdown);
|
|
146712
|
+
}
|
|
146713
|
+
}, [onMarkdownChange, onChange]);
|
|
145659
146714
|
const { state: aiSessionState, actions: aiSessionActions, isOpen: aiPanelOpen } = useAIRefinementSession({
|
|
145660
146715
|
editor,
|
|
145661
146716
|
onRefine: onAIRefine,
|
|
145662
146717
|
editorContent,
|
|
145663
146718
|
promptType: props.promptType,
|
|
145664
|
-
agentContext: props.agentContext
|
|
146719
|
+
agentContext: props.agentContext,
|
|
146720
|
+
onContentApplied: handleAIContentApplied
|
|
145665
146721
|
});
|
|
145666
146722
|
const openAIRefine = useCallback(
|
|
145667
146723
|
(_type = "selection") => {
|
|
@@ -145688,6 +146744,22 @@ const MDEditor = forwardRef(
|
|
|
145688
146744
|
// autoGenerate
|
|
145689
146745
|
);
|
|
145690
146746
|
}, [aiSessionActions]);
|
|
146747
|
+
const handleDesignWithAI = useCallback(() => {
|
|
146748
|
+
aiSessionActions.openPanel(
|
|
146749
|
+
"generate",
|
|
146750
|
+
"",
|
|
146751
|
+
// Empty text since we're generating from scratch
|
|
146752
|
+
void 0,
|
|
146753
|
+
// No selection range
|
|
146754
|
+
void 0,
|
|
146755
|
+
// No custom prompt - AI will use context
|
|
146756
|
+
true
|
|
146757
|
+
// autoGenerate - start generation immediately
|
|
146758
|
+
);
|
|
146759
|
+
if (onDesignWithAI) {
|
|
146760
|
+
onDesignWithAI();
|
|
146761
|
+
}
|
|
146762
|
+
}, [aiSessionActions, onDesignWithAI]);
|
|
145691
146763
|
const handleCloseAIPanel = useCallback(() => {
|
|
145692
146764
|
if (editorRef.current) {
|
|
145693
146765
|
editorRef.current.setEditable(!readOnly);
|
|
@@ -145722,11 +146794,27 @@ const MDEditor = forwardRef(
|
|
|
145722
146794
|
from2
|
|
145723
146795
|
);
|
|
145724
146796
|
if (textAfterTrigger.includes("}}")) {
|
|
146797
|
+
const pathRaw = textAfterTrigger.split("}}")[0].trim();
|
|
146798
|
+
if (pathRaw) {
|
|
146799
|
+
const varType = inferVariableType(pathRaw);
|
|
146800
|
+
const cleanPath = removeTypePrefix(pathRaw);
|
|
146801
|
+
const displayName = cleanPath.split(".").pop() || cleanPath;
|
|
146802
|
+
editor.chain().focus().deleteRange({ from: triggerPos, to: from2 }).insertContent({
|
|
146803
|
+
type: "variableChip",
|
|
146804
|
+
attrs: {
|
|
146805
|
+
variableType: varType,
|
|
146806
|
+
path: cleanPath,
|
|
146807
|
+
displayName
|
|
146808
|
+
}
|
|
146809
|
+
}).insertContent(" ").run();
|
|
146810
|
+
}
|
|
145725
146811
|
setVariableMenuOpen(false);
|
|
145726
146812
|
variableTriggerPosRef.current = null;
|
|
145727
146813
|
return;
|
|
145728
146814
|
}
|
|
145729
146815
|
setVariableMenuQuery(textAfterTrigger);
|
|
146816
|
+
const coords = editor.view.coordsAtPos(from2);
|
|
146817
|
+
setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
|
|
145730
146818
|
};
|
|
145731
146819
|
const editorElement = editor.view.dom;
|
|
145732
146820
|
editorElement.addEventListener("keydown", handleKeyDown2);
|
|
@@ -145736,12 +146824,36 @@ const MDEditor = forwardRef(
|
|
|
145736
146824
|
editorElement.removeEventListener("input", handleInput);
|
|
145737
146825
|
};
|
|
145738
146826
|
}, [editor, mergedFeatures.variableChips, variableMenuOpen]);
|
|
146827
|
+
useEffect(() => {
|
|
146828
|
+
variableMenuOpenRef.current = variableMenuOpen;
|
|
146829
|
+
}, [variableMenuOpen]);
|
|
146830
|
+
useEffect(() => {
|
|
146831
|
+
if (!editor || !mergedFeatures.variableChips) return;
|
|
146832
|
+
const detectVariableContext = () => {
|
|
146833
|
+
if (variableMenuOpenRef.current) return;
|
|
146834
|
+
if (!hasVariableSuggestionsRef.current) return;
|
|
146835
|
+
const { from: from2 } = editor.state.selection;
|
|
146836
|
+
const context = getVariableContextAtPosition(editor, from2);
|
|
146837
|
+
if (context) {
|
|
146838
|
+
variableTriggerPosRef.current = context.triggerFrom;
|
|
146839
|
+
setVariableMenuQuery(context.query);
|
|
146840
|
+
const coords = editor.view.coordsAtPos(from2);
|
|
146841
|
+
setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
|
|
146842
|
+
setVariableMenuOpen(true);
|
|
146843
|
+
}
|
|
146844
|
+
};
|
|
146845
|
+
editor.on("focus", detectVariableContext);
|
|
146846
|
+
editor.on("selectionUpdate", detectVariableContext);
|
|
146847
|
+
return () => {
|
|
146848
|
+
editor.off("focus", detectVariableContext);
|
|
146849
|
+
editor.off("selectionUpdate", detectVariableContext);
|
|
146850
|
+
};
|
|
146851
|
+
}, [editor, mergedFeatures.variableChips]);
|
|
145739
146852
|
useEffect(() => {
|
|
145740
146853
|
if (!variableMenuOpen) return;
|
|
145741
146854
|
const handleKeyDown2 = (event) => {
|
|
145742
146855
|
if (event.key === "Escape") {
|
|
145743
146856
|
setVariableMenuOpen(false);
|
|
145744
|
-
setEditingVariableChip(null);
|
|
145745
146857
|
variableTriggerPosRef.current = null;
|
|
145746
146858
|
editor == null ? void 0 : editor.chain().focus().run();
|
|
145747
146859
|
}
|
|
@@ -145754,19 +146866,11 @@ const MDEditor = forwardRef(
|
|
|
145754
146866
|
const handleVariableChipEdit = (event) => {
|
|
145755
146867
|
const customEvent = event;
|
|
145756
146868
|
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);
|
|
146869
|
+
const innerPath = variableType === "system" || variableType === "custom" ? path : `${variableType}.${path}`;
|
|
146870
|
+
const fullText = `{{${innerPath}}}`;
|
|
146871
|
+
editor.chain().focus().deleteRange({ from: position, to: position + nodeSize2 }).insertContentAt(position, fullText).run();
|
|
146872
|
+
const cursorPos = position + 2 + innerPath.length;
|
|
146873
|
+
editor.chain().focus().setTextSelection(cursorPos).run();
|
|
145770
146874
|
};
|
|
145771
146875
|
const editorElement = editor.view.dom;
|
|
145772
146876
|
editorElement.addEventListener("variable-chip-edit", handleVariableChipEdit);
|
|
@@ -145775,6 +146879,10 @@ const MDEditor = forwardRef(
|
|
|
145775
146879
|
};
|
|
145776
146880
|
}, [editor]);
|
|
145777
146881
|
useEffect(() => {
|
|
146882
|
+
if (skipEditorSyncRef.current) {
|
|
146883
|
+
skipEditorSyncRef.current = false;
|
|
146884
|
+
return;
|
|
146885
|
+
}
|
|
145778
146886
|
if (!editor || isInternalUpdateRef.current) {
|
|
145779
146887
|
isInternalUpdateRef.current = false;
|
|
145780
146888
|
return;
|
|
@@ -145806,6 +146914,10 @@ const MDEditor = forwardRef(
|
|
|
145806
146914
|
return () => clearTimeout(timer);
|
|
145807
146915
|
}, [rawMarkdown, isRawMode, onMarkdownChange, onChange]);
|
|
145808
146916
|
useEffect(() => {
|
|
146917
|
+
if (skipRawSyncRef.current) {
|
|
146918
|
+
skipRawSyncRef.current = false;
|
|
146919
|
+
return;
|
|
146920
|
+
}
|
|
145809
146921
|
if (isRawMode && markdownValue !== void 0 && markdownValue !== lastEmittedMarkdownRef.current) {
|
|
145810
146922
|
setRawMarkdown(markdownValue);
|
|
145811
146923
|
}
|
|
@@ -145946,6 +147058,13 @@ const MDEditor = forwardRef(
|
|
|
145946
147058
|
editor,
|
|
145947
147059
|
className: "k-md-editor__content w-full h-full"
|
|
145948
147060
|
}
|
|
147061
|
+
),
|
|
147062
|
+
(editor == null ? void 0 : editor.isEmpty) && emptyStatePlaceholder && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
147063
|
+
EmptyStatePlaceholder,
|
|
147064
|
+
{
|
|
147065
|
+
placeholder: emptyStatePlaceholder,
|
|
147066
|
+
example: emptyStateExample
|
|
147067
|
+
}
|
|
145949
147068
|
)
|
|
145950
147069
|
] })
|
|
145951
147070
|
) }),
|
|
@@ -145954,20 +147073,18 @@ const MDEditor = forwardRef(
|
|
|
145954
147073
|
{
|
|
145955
147074
|
position: variableMenuPosition,
|
|
145956
147075
|
query: variableMenuQuery,
|
|
145957
|
-
onQueryChange:
|
|
147076
|
+
onQueryChange: handleVariableQueryChange,
|
|
145958
147077
|
onSelect: (variable) => insertVariable(variable),
|
|
145959
147078
|
onClose: () => {
|
|
145960
147079
|
setVariableMenuOpen(false);
|
|
145961
147080
|
setVariableMenuQuery("");
|
|
145962
|
-
setEditingVariableChip(null);
|
|
145963
147081
|
variableTriggerPosRef.current = null;
|
|
145964
147082
|
},
|
|
145965
147083
|
envVariables: mergedEnvVariables,
|
|
145966
147084
|
memoryVariables: mergedMemoryVariables,
|
|
145967
147085
|
systemVariables: mergedSystemVariables,
|
|
145968
147086
|
contentVariables: mergedContentVariables,
|
|
145969
|
-
editorControlled:
|
|
145970
|
-
isEditMode: !!editingVariableChip
|
|
147087
|
+
editorControlled: true
|
|
145971
147088
|
}
|
|
145972
147089
|
)
|
|
145973
147090
|
] }),
|
|
@@ -145981,7 +147098,9 @@ const MDEditor = forwardRef(
|
|
|
145981
147098
|
onAIAction: isAIEnabled ? handleAIToolbarAction : void 0,
|
|
145982
147099
|
theme: theme === "dark" || theme.includes("dark") ? "dark" : "light",
|
|
145983
147100
|
disabled: readOnly,
|
|
145984
|
-
containerRef: editorContainerRef
|
|
147101
|
+
containerRef: editorContainerRef,
|
|
147102
|
+
showDesignWithAI: showDesignWithAI && (editor == null ? void 0 : editor.isEmpty),
|
|
147103
|
+
onDesignWithAI: isAIEnabled ? handleDesignWithAI : onDesignWithAI
|
|
145985
147104
|
}
|
|
145986
147105
|
)
|
|
145987
147106
|
] }),
|
|
@@ -149524,6 +150643,7 @@ export {
|
|
|
149524
150643
|
AIRefineDropdown,
|
|
149525
150644
|
AIRefineExtension,
|
|
149526
150645
|
AIRefinePanel,
|
|
150646
|
+
AgentDefinitionExample,
|
|
149527
150647
|
AgentListView,
|
|
149528
150648
|
AnalyticsChart,
|
|
149529
150649
|
AnalyticsTable,
|
|
@@ -149549,6 +150669,7 @@ export {
|
|
|
149549
150669
|
DetailPage,
|
|
149550
150670
|
DetailPageService,
|
|
149551
150671
|
EmptyState,
|
|
150672
|
+
EmptyStatePlaceholder,
|
|
149552
150673
|
EndpointsConfigService,
|
|
149553
150674
|
EnvironmentContext,
|
|
149554
150675
|
EnvironmentProvider,
|