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.
Files changed (65) hide show
  1. package/dist/assets/agentic-ui-libs.css +69 -4
  2. package/dist/features/debug-logs/DebugPanel.d.ts.map +1 -1
  3. package/dist/features/debug-logs/components/DebugCard.d.ts.map +1 -1
  4. package/dist/features/debug-logs/index.d.ts +1 -1
  5. package/dist/features/debug-logs/index.d.ts.map +1 -1
  6. package/dist/features/debug-logs/services/ApiService.d.ts.map +1 -1
  7. package/dist/features/debug-logs/services/TreeBuilder.d.ts +3 -3
  8. package/dist/features/debug-logs/services/TreeBuilder.d.ts.map +1 -1
  9. package/dist/features/debug-logs/types.d.ts +13 -2
  10. package/dist/features/debug-logs/types.d.ts.map +1 -1
  11. package/dist/features/md-editor/MDEditor.d.ts.map +1 -1
  12. package/dist/features/md-editor/components/AIDesignPanel.d.ts.map +1 -1
  13. package/dist/features/md-editor/components/EmptyStatePlaceholder.d.ts +21 -0
  14. package/dist/features/md-editor/components/EmptyStatePlaceholder.d.ts.map +1 -0
  15. package/dist/features/md-editor/components/UnifiedToolbar.d.ts +4 -0
  16. package/dist/features/md-editor/components/UnifiedToolbar.d.ts.map +1 -1
  17. package/dist/features/md-editor/components/VariableMenu.d.ts.map +1 -1
  18. package/dist/features/md-editor/components/icons/CategoryIcons.d.ts +1 -0
  19. package/dist/features/md-editor/components/icons/CategoryIcons.d.ts.map +1 -1
  20. package/dist/features/md-editor/components/index.d.ts +2 -0
  21. package/dist/features/md-editor/components/index.d.ts.map +1 -1
  22. package/dist/features/md-editor/hooks/useAIRefinementSession.d.ts +3 -1
  23. package/dist/features/md-editor/hooks/useAIRefinementSession.d.ts.map +1 -1
  24. package/dist/features/md-editor/index.d.ts +1 -1
  25. package/dist/features/md-editor/index.d.ts.map +1 -1
  26. package/dist/features/md-editor/types.d.ts +58 -2
  27. package/dist/features/md-editor/types.d.ts.map +1 -1
  28. package/dist/features/md-editor/utils/index.d.ts +1 -0
  29. package/dist/features/md-editor/utils/index.d.ts.map +1 -1
  30. package/dist/features/md-editor/utils/variableContext.d.ts +38 -0
  31. package/dist/features/md-editor/utils/variableContext.d.ts.map +1 -0
  32. package/dist/features/tracing/components/SessionsList.d.ts.map +1 -1
  33. package/dist/features/tracing/components/TracesList.d.ts.map +1 -1
  34. package/dist/features/tracing/components/detail/DetailPage.d.ts +1 -1
  35. package/dist/features/tracing/components/detail/DetailPage.d.ts.map +1 -1
  36. package/dist/features/tracing/components/detail/NodeDetailPanel.d.ts +1 -1
  37. package/dist/features/tracing/components/detail/NodeDetailPanel.d.ts.map +1 -1
  38. package/dist/features/tracing/components/detail/ObservationNode.d.ts.map +1 -1
  39. package/dist/features/tracing/components/detail/TraceTree.d.ts +1 -1
  40. package/dist/features/tracing/components/detail/TraceTree.d.ts.map +1 -1
  41. package/dist/features/tracing/components/detail/config/observationFilterConfig.d.ts.map +1 -1
  42. package/dist/features/tracing/components/detail/services/DetailPageService.d.ts.map +1 -1
  43. package/dist/features/tracing/components/detail/types.d.ts +22 -0
  44. package/dist/features/tracing/components/detail/types.d.ts.map +1 -1
  45. package/dist/features/tracing/components/shared/CopyableId.d.ts +11 -0
  46. package/dist/features/tracing/components/shared/CopyableId.d.ts.map +1 -0
  47. package/dist/features/tracing/components/shared/TracingListHeader.d.ts +2 -1
  48. package/dist/features/tracing/components/shared/TracingListHeader.d.ts.map +1 -1
  49. package/dist/features/tracing/components/shared/TracingTable.d.ts.map +1 -1
  50. package/dist/features/tracing/components/shared/index.d.ts +1 -0
  51. package/dist/features/tracing/components/shared/index.d.ts.map +1 -1
  52. package/dist/features/tracing/services/TraceTreeService.d.ts +39 -2
  53. package/dist/features/tracing/services/TraceTreeService.d.ts.map +1 -1
  54. package/dist/features/tracing/services/TracingApiService.d.ts +13 -1
  55. package/dist/features/tracing/services/TracingApiService.d.ts.map +1 -1
  56. package/dist/features/tracing/types.d.ts +10 -0
  57. package/dist/features/tracing/types.d.ts.map +1 -1
  58. package/dist/index.angular.d.ts +1 -1
  59. package/dist/index.angular.d.ts.map +1 -1
  60. package/dist/index.d.ts +1 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +1554 -433
  63. package/dist/shared/ui/DataViewer.d.ts.map +1 -1
  64. package/dist/ui-libs.umd.js +1554 -433
  65. package/package.json +3 -2
@@ -30900,7 +30900,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
30900
30900
  listViewData.forEach((item) => {
30901
30901
  if (item.modelName) {
30902
30902
  options.push({
30903
- label: item.modelName,
30903
+ label: item.connectionName ? `${item.modelName} - ${item.connectionName}` : item.modelName,
30904
30904
  value: item.modelName.replace(/[-\.]/g, ""),
30905
30905
  icon: getModelIconPath2(item.provider),
30906
30906
  // Use actual SVG icon path
@@ -35549,6 +35549,31 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
35549
35549
  traces: data.traces || []
35550
35550
  };
35551
35551
  }
35552
+ /**
35553
+ * Get total count of traces matching filters (for pagination)
35554
+ * Endpoint: /tracing/api/trpc/traces.countAll
35555
+ */
35556
+ async fetchTracesCount(projectId, filters, options = {}) {
35557
+ const input = {
35558
+ json: {
35559
+ projectId,
35560
+ filter: filters,
35561
+ searchQuery: options.searchQuery ?? null,
35562
+ searchType: options.searchType ?? ["id"],
35563
+ page: 0,
35564
+ limit: 0,
35565
+ orderBy: options.orderBy ?? null
35566
+ },
35567
+ meta: {
35568
+ values: this.buildMetaValues(filters)
35569
+ }
35570
+ };
35571
+ const url = this.buildTrpcUrl("traces.countAll", input);
35572
+ const data = await this.makeRequest(url);
35573
+ return {
35574
+ totalCount: (data == null ? void 0 : data.totalCount) ?? 0
35575
+ };
35576
+ }
35552
35577
  /**
35553
35578
  * Fetch metrics for multiple traces (latency, tokens, cost)
35554
35579
  * Endpoint: /tracing/api/trpc/traces.metrics
@@ -36622,6 +36647,140 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
36622
36647
  ] }) })
36623
36648
  ] });
36624
36649
  }
36650
+ const CopyButton$1 = ({
36651
+ text,
36652
+ className = "",
36653
+ iconClassName = "",
36654
+ iconStyle,
36655
+ title = "Copy to clipboard",
36656
+ onCopySuccess,
36657
+ onCopyError,
36658
+ tooltipText = "Copied!",
36659
+ tooltipPosition = "bottom",
36660
+ size = "md"
36661
+ }) => {
36662
+ const [showTooltip, setShowTooltip] = React.useState(false);
36663
+ const getSizeClasses = () => {
36664
+ switch (size) {
36665
+ case "sm":
36666
+ return {
36667
+ button: "p-1",
36668
+ icon: "w-[12px] h-[12px]",
36669
+ tooltip: "text-xs py-1 px-2"
36670
+ };
36671
+ case "lg":
36672
+ return {
36673
+ button: "p-2",
36674
+ icon: "w-[20px] h-[20px]",
36675
+ tooltip: "text-sm py-2 px-3"
36676
+ };
36677
+ default:
36678
+ return {
36679
+ button: "p-1.5",
36680
+ icon: "w-[16px] h-[16px]",
36681
+ tooltip: "text-xs py-1 px-2"
36682
+ };
36683
+ }
36684
+ };
36685
+ const getTooltipPositionClasses = () => {
36686
+ const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
36687
+ switch (tooltipPosition) {
36688
+ case "bottom":
36689
+ return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
36690
+ case "left":
36691
+ return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
36692
+ case "right":
36693
+ return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
36694
+ default:
36695
+ return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
36696
+ }
36697
+ };
36698
+ const sizeClasses2 = getSizeClasses();
36699
+ const showCopyTooltip = React.useCallback(() => {
36700
+ setShowTooltip(true);
36701
+ setTimeout(() => setShowTooltip(false), 1e3);
36702
+ }, []);
36703
+ const copyToClipboard2 = React.useCallback(async () => {
36704
+ try {
36705
+ if (navigator.clipboard && navigator.clipboard.writeText) {
36706
+ await navigator.clipboard.writeText(text);
36707
+ showCopyTooltip();
36708
+ onCopySuccess == null ? void 0 : onCopySuccess();
36709
+ return;
36710
+ }
36711
+ const textArea = document.createElement("textarea");
36712
+ textArea.value = text;
36713
+ textArea.style.position = "fixed";
36714
+ textArea.style.left = "-999999px";
36715
+ textArea.style.top = "-999999px";
36716
+ document.body.appendChild(textArea);
36717
+ textArea.focus();
36718
+ textArea.select();
36719
+ try {
36720
+ document.execCommand("copy");
36721
+ showCopyTooltip();
36722
+ onCopySuccess == null ? void 0 : onCopySuccess();
36723
+ } catch (err) {
36724
+ const error = err instanceof Error ? err : new Error("Copy failed");
36725
+ console.warn("Copy to clipboard failed:", error);
36726
+ onCopyError == null ? void 0 : onCopyError(error);
36727
+ } finally {
36728
+ document.body.removeChild(textArea);
36729
+ }
36730
+ } catch (err) {
36731
+ const error = err instanceof Error ? err : new Error("Copy failed");
36732
+ console.warn("Copy to clipboard failed:", error);
36733
+ onCopyError == null ? void 0 : onCopyError(error);
36734
+ }
36735
+ }, [text, showCopyTooltip, onCopySuccess, onCopyError]);
36736
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
36737
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36738
+ "button",
36739
+ {
36740
+ onClick: copyToClipboard2,
36741
+ className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
36742
+ title,
36743
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
36744
+ }
36745
+ ),
36746
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36747
+ "div",
36748
+ {
36749
+ className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
36750
+ style: {
36751
+ visibility: showTooltip ? "visible" : "hidden"
36752
+ },
36753
+ children: tooltipText
36754
+ }
36755
+ )
36756
+ ] });
36757
+ };
36758
+ function CopyableId({ value, truncateLength = 30 }) {
36759
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "copyable-id-wrapper", title: value, children: [
36760
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: TracingUtils.truncate(value, truncateLength) }),
36761
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36762
+ "span",
36763
+ {
36764
+ className: "copyable-id-btn",
36765
+ onClick: (e) => {
36766
+ e.stopPropagation();
36767
+ e.preventDefault();
36768
+ },
36769
+ onMouseDown: (e) => e.stopPropagation(),
36770
+ onMouseUp: (e) => e.stopPropagation(),
36771
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
36772
+ CopyButton$1,
36773
+ {
36774
+ text: value,
36775
+ size: "sm",
36776
+ title: "Copy to clipboard",
36777
+ iconClassName: "text-[#667085]"
36778
+ }
36779
+ )
36780
+ }
36781
+ )
36782
+ ] });
36783
+ }
36625
36784
  function Shimmer$2({ className = "", children }) {
36626
36785
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-[#F2F4F7] rounded ${className}`, children });
36627
36786
  }
@@ -104632,6 +104791,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104632
104791
  }, [columns]);
104633
104792
  const handleRowClick = React.useCallback(
104634
104793
  (event) => {
104794
+ var _a;
104795
+ const target = (_a = event.event) == null ? void 0 : _a.target;
104796
+ if (target == null ? void 0 : target.closest(".copyable-id-btn")) return;
104635
104797
  if (onRowClick && event.data) {
104636
104798
  onRowClick(event.data);
104637
104799
  }
@@ -104728,9 +104890,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104728
104890
  onClick: goToFirstPage,
104729
104891
  disabled: currentPage === 0,
104730
104892
  className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
104893
+ style: { color: "var(--colors-gray-light-mode-700, #344054)" },
104731
104894
  title: "First page",
104732
104895
  "data-test-id": "tracing-table-first-page-btn",
104733
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, { className: "w-4 h-4" })
104896
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsLeft, { size: 16 })
104734
104897
  }
104735
104898
  ),
104736
104899
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -104739,12 +104902,13 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104739
104902
  onClick: goToPreviousPage,
104740
104903
  disabled: currentPage === 0,
104741
104904
  className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
104905
+ style: { color: "var(--colors-gray-light-mode-700, #344054)" },
104742
104906
  title: "Previous page",
104743
104907
  "data-test-id": "tracing-table-prev-page-btn",
104744
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-4 h-4" })
104908
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { size: 16 })
104745
104909
  }
104746
104910
  ),
104747
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-4 py-2 text-sm text-gray-700", "data-test-id": "tracing-table-page-info", children: [
104911
+ /* @__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: [
104748
104912
  "Page ",
104749
104913
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: currentPage + 1 }),
104750
104914
  " of",
@@ -104757,9 +104921,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104757
104921
  onClick: goToNextPage,
104758
104922
  disabled: currentPage >= totalPages - 1,
104759
104923
  className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
104924
+ style: { color: "var(--colors-gray-light-mode-700, #344054)" },
104760
104925
  title: "Next page",
104761
104926
  "data-test-id": "tracing-table-next-page-btn",
104762
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" })
104927
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { size: 16 })
104763
104928
  }
104764
104929
  ),
104765
104930
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -104768,13 +104933,14 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104768
104933
  onClick: goToLastPage,
104769
104934
  disabled: currentPage >= totalPages - 1,
104770
104935
  className: "p-2 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed",
104936
+ style: { color: "var(--colors-gray-light-mode-700, #344054)" },
104771
104937
  title: "Last page",
104772
104938
  "data-test-id": "tracing-table-last-page-btn",
104773
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, { className: "w-4 h-4" })
104939
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronsRight, { size: 16 })
104774
104940
  }
104775
104941
  )
104776
104942
  ] }),
104777
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center text-sm text-gray-700 shrink-0 absolute right-[24px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
104943
+ /* @__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: [
104778
104944
  "Showing ",
104779
104945
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: startRow }),
104780
104946
  " to",
@@ -104802,9 +104968,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104802
104968
  timeRangePresetLabel,
104803
104969
  onTimeRangeChange,
104804
104970
  filters,
104971
+ filterColumns: filterColumnsProp,
104805
104972
  onFiltersClick,
104806
104973
  onModifyColumnsClick,
104807
104974
  showModifyColumns = true,
104975
+ onClearFilters,
104976
+ onRemoveFilter,
104808
104977
  onRefresh,
104809
104978
  isRefreshing = false
104810
104979
  } = props;
@@ -104849,6 +105018,50 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104849
105018
  }
104850
105019
  return `Searches in ${fields}.`;
104851
105020
  };
105021
+ const activeFilters = filters.filter(TracingUtils.isFilterActive);
105022
+ const [filtersExpanded, setFiltersExpanded] = React.useState(false);
105023
+ const [isOverflowing, setIsOverflowing] = React.useState(false);
105024
+ const chipsContainerRef = React.useRef(null);
105025
+ const checkOverflow = React.useCallback(() => {
105026
+ const el = chipsContainerRef.current;
105027
+ if (!el) return;
105028
+ setIsOverflowing(el.scrollHeight > el.clientHeight);
105029
+ }, []);
105030
+ React.useEffect(() => {
105031
+ checkOverflow();
105032
+ window.addEventListener("resize", checkOverflow);
105033
+ return () => window.removeEventListener("resize", checkOverflow);
105034
+ }, [checkOverflow, activeFilters.length]);
105035
+ const getFilterChipLabel = (filter) => {
105036
+ const col = filterColumnsProp == null ? void 0 : filterColumnsProp.find((c2) => c2.field === filter.column);
105037
+ const label = (col == null ? void 0 : col.label) ?? filter.column;
105038
+ let valueText;
105039
+ if (filter.type === "datetime") {
105040
+ valueText = new Date(filter.value).toLocaleDateString();
105041
+ } else if (filter.type === "number") {
105042
+ valueText = parseFloat(filter.value).toLocaleString();
105043
+ } else if (Array.isArray(filter.value)) {
105044
+ valueText = filter.value.length <= 2 ? filter.value.join(", ") : `${filter.value.length} selected`;
105045
+ } else {
105046
+ valueText = String(filter.value ?? "");
105047
+ }
105048
+ const shortOp = {
105049
+ "=": "",
105050
+ "!=": "≠ ",
105051
+ ">": "> ",
105052
+ ">=": "≥ ",
105053
+ "<": "< ",
105054
+ "<=": "≤ ",
105055
+ "contains": "~ ",
105056
+ "does not contain": "!~ ",
105057
+ "starts with": "starts ",
105058
+ "ends with": "ends ",
105059
+ "any of": "",
105060
+ "none of": "not "
105061
+ };
105062
+ const op = shortOp[filter.operator] ?? `${filter.operator} `;
105063
+ return `${label}: ${op}${valueText}`;
105064
+ };
104852
105065
  const handleDateRangeChange = (dateRange, presetLabel) => {
104853
105066
  if (dateRange && dateRange.from && dateRange.to) {
104854
105067
  const fromDate = dateRange.from;
@@ -105001,7 +105214,66 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105001
105214
  }
105002
105215
  )
105003
105216
  ] })
105004
- ] })
105217
+ ] }),
105218
+ activeFilters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
105219
+ "div",
105220
+ {
105221
+ className: "flex items-start gap-[8px] border border-gray-200 rounded-[8px] px-[12px] py-[8px]",
105222
+ "data-test-id": "tracing-filter-chips",
105223
+ children: [
105224
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[28px] text-gray-500 shrink-0", children: "Filters" }),
105225
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
105226
+ "div",
105227
+ {
105228
+ ref: chipsContainerRef,
105229
+ className: `flex items-center gap-[8px] flex-wrap flex-1 min-w-0 ${!filtersExpanded ? "max-h-[28px] overflow-hidden" : ""}`,
105230
+ children: activeFilters.map((filter, idx) => {
105231
+ const originalIndex = filters.indexOf(filter);
105232
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
105233
+ "div",
105234
+ {
105235
+ 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]",
105236
+ children: [
105237
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-medium", children: getFilterChipLabel(filter) }),
105238
+ onRemoveFilter && /* @__PURE__ */ jsxRuntimeExports.jsx(
105239
+ "button",
105240
+ {
105241
+ onClick: () => onRemoveFilter(originalIndex),
105242
+ className: "flex items-center justify-center shrink-0 text-blue-400 hover:text-blue-700 transition-colors",
105243
+ title: "Remove filter",
105244
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[14px] h-[14px]", strokeWidth: 2 })
105245
+ }
105246
+ )
105247
+ ]
105248
+ },
105249
+ `chip-${idx}`
105250
+ );
105251
+ })
105252
+ }
105253
+ ),
105254
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] shrink-0 leading-[28px]", children: [
105255
+ (isOverflowing || filtersExpanded) && /* @__PURE__ */ jsxRuntimeExports.jsx(
105256
+ "button",
105257
+ {
105258
+ onClick: () => setFiltersExpanded((prev) => !prev),
105259
+ className: "text-[12px] font-medium text-blue-600 hover:text-blue-800 transition-colors whitespace-nowrap",
105260
+ "data-test-id": "tracing-filter-toggle",
105261
+ children: filtersExpanded ? "View less" : "View all"
105262
+ }
105263
+ ),
105264
+ onClearFilters && /* @__PURE__ */ jsxRuntimeExports.jsx(
105265
+ "button",
105266
+ {
105267
+ onClick: onClearFilters,
105268
+ className: "text-[12px] font-medium text-gray-500 hover:text-gray-700 transition-colors whitespace-nowrap",
105269
+ "data-test-id": "tracing-filter-clear-all",
105270
+ children: "Clear all"
105271
+ }
105272
+ )
105273
+ ] })
105274
+ ]
105275
+ }
105276
+ )
105005
105277
  ] });
105006
105278
  }
105007
105279
  function ColumnCustomization(props) {
@@ -105488,6 +105760,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105488
105760
  ] })
105489
105761
  ] });
105490
105762
  }
105763
+ const TRACE_PII_DISPLAY_USER_MESSAGE_KEY = "piiDisplayUserMessage";
105764
+ const TRACE_PII_DISPLAY_APP_RESPONSE_KEY = "piiDisplayAppResponse";
105491
105765
  class TraceTreeService {
105492
105766
  /**
105493
105767
  * Build a hierarchical tree from a flat list of observations
@@ -105660,43 +105934,205 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105660
105934
  });
105661
105935
  }
105662
105936
  /**
105663
- * Extract user message from trace input
105937
+ * Extract user message from trace input for display.
105938
+ * Handles string, object with message/content/text/query, and messages array (e.g. voice/chat).
105939
+ */
105940
+ /**
105941
+ * Parse trace metadata from API (string or object) into a plain object.
105942
+ */
105943
+ static parseTraceMetadata(metadata) {
105944
+ if (metadata === null || metadata === void 0) {
105945
+ return {};
105946
+ }
105947
+ if (typeof metadata === "string") {
105948
+ try {
105949
+ return JSON.parse(metadata);
105950
+ } catch {
105951
+ return {};
105952
+ }
105953
+ }
105954
+ if (typeof metadata === "object" && !Array.isArray(metadata)) {
105955
+ return metadata;
105956
+ }
105957
+ return {};
105958
+ }
105959
+ /**
105960
+ * Read PII display strings from Langfuse/Kore trace metadata (if present).
105664
105961
  */
105962
+ static extractPiiDisplayFromTraceMetadata(metadata) {
105963
+ const obj = this.parseTraceMetadata(metadata);
105964
+ const userRaw = obj[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
105965
+ const appRaw = obj[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
105966
+ const result = {};
105967
+ if (typeof userRaw === "string" && userRaw.length > 0) {
105968
+ result.displayUserMessage = userRaw;
105969
+ }
105970
+ if (typeof appRaw === "string" && appRaw.length > 0) {
105971
+ result.displayAppResponse = appRaw;
105972
+ }
105973
+ return result;
105974
+ }
105975
+ /**
105976
+ * Some tracing APIs expose custom PII display keys on trace root as well as under metadata.
105977
+ */
105978
+ static extractPiiDisplayFromApiTrace(trace) {
105979
+ const fromMeta = this.extractPiiDisplayFromTraceMetadata(trace.metadata);
105980
+ const userTop = trace[TRACE_PII_DISPLAY_USER_MESSAGE_KEY];
105981
+ const appTop = trace[TRACE_PII_DISPLAY_APP_RESPONSE_KEY];
105982
+ const fromTop = {};
105983
+ if (typeof userTop === "string" && userTop.length > 0) {
105984
+ fromTop.displayUserMessage = userTop;
105985
+ }
105986
+ if (typeof appTop === "string" && appTop.length > 0) {
105987
+ fromTop.displayAppResponse = appTop;
105988
+ }
105989
+ return {
105990
+ displayUserMessage: fromTop.displayUserMessage ?? fromMeta.displayUserMessage,
105991
+ displayAppResponse: fromTop.displayAppResponse ?? fromMeta.displayAppResponse
105992
+ };
105993
+ }
105665
105994
  static extractUserMessage(input) {
105666
105995
  if (!input) return "";
105667
105996
  if (typeof input === "string") {
105668
105997
  try {
105669
105998
  const parsed = JSON.parse(input);
105670
- return (parsed == null ? void 0 : parsed.message) || (parsed == null ? void 0 : parsed.content) || (parsed == null ? void 0 : parsed.text) || (parsed == null ? void 0 : parsed.query) || input;
105999
+ 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);
106000
+ if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
106001
+ if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
106002
+ return this.extractLastUserMessageFromArray(parsed.messages);
106003
+ }
106004
+ return input;
105671
106005
  } catch {
105672
106006
  return input;
105673
106007
  }
105674
106008
  }
105675
106009
  if (typeof input === "object") {
105676
106010
  const obj = input;
105677
- return String((obj == null ? void 0 : obj["message"]) || (obj == null ? void 0 : obj["content"]) || (obj == null ? void 0 : obj["text"]) || (obj == null ? void 0 : obj["query"]) || "");
106011
+ 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"]);
106012
+ if (direct !== void 0 && direct !== null && direct !== "") {
106013
+ return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
106014
+ }
106015
+ if (Array.isArray(obj == null ? void 0 : obj.messages)) {
106016
+ return this.extractLastUserMessageFromArray(obj.messages);
106017
+ }
106018
+ if (Array.isArray(input)) {
106019
+ return this.extractLastUserMessageFromArray(input);
106020
+ }
106021
+ return JSON.stringify(obj);
105678
106022
  }
105679
106023
  return String(input);
105680
106024
  }
105681
106025
  /**
105682
- * Extract app response from trace output
106026
+ * LangChain-serialized messages store role/content under `kwargs` and type in `id`.
106027
+ */
106028
+ static getLangchainMessageContent(msg) {
106029
+ if (msg["content"] !== void 0 && msg["content"] !== null) {
106030
+ return msg["content"];
106031
+ }
106032
+ const kwargs = msg["kwargs"];
106033
+ if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
106034
+ const c2 = kwargs["content"];
106035
+ if (c2 !== void 0 && c2 !== null) {
106036
+ return c2;
106037
+ }
106038
+ }
106039
+ return void 0;
106040
+ }
106041
+ static inferLangchainMessageRole(msg) {
106042
+ if (typeof msg["role"] === "string") {
106043
+ return msg["role"];
106044
+ }
106045
+ const kwargs = msg["kwargs"];
106046
+ if (kwargs && typeof kwargs === "object" && !Array.isArray(kwargs)) {
106047
+ const r2 = kwargs["role"];
106048
+ if (typeof r2 === "string") {
106049
+ return r2;
106050
+ }
106051
+ }
106052
+ const id = msg["id"];
106053
+ if (Array.isArray(id)) {
106054
+ const tail = id[id.length - 1];
106055
+ if (tail === "HumanMessage") {
106056
+ return "user";
106057
+ }
106058
+ if (tail === "AIMessage" || tail === "AIMessageChunk") {
106059
+ return "assistant";
106060
+ }
106061
+ if (tail === "SystemMessage") {
106062
+ return "system";
106063
+ }
106064
+ if (tail === "ToolMessage") {
106065
+ return "tool";
106066
+ }
106067
+ }
106068
+ return void 0;
106069
+ }
106070
+ /**
106071
+ * Get last user message content from a messages array (chat/voice format).
106072
+ */
106073
+ static extractLastUserMessageFromArray(messages) {
106074
+ if (!messages.length) return "";
106075
+ for (let i2 = messages.length - 1; i2 >= 0; i2--) {
106076
+ const msg = messages[i2];
106077
+ const role = this.inferLangchainMessageRole(msg);
106078
+ const content2 = this.getLangchainMessageContent(msg);
106079
+ if (role === "user" && content2 != null) {
106080
+ return typeof content2 === "string" ? content2 : JSON.stringify(content2);
106081
+ }
106082
+ }
106083
+ const last2 = messages[messages.length - 1];
106084
+ const content = this.getLangchainMessageContent(last2);
106085
+ if (content != null) {
106086
+ return typeof content === "string" ? content : JSON.stringify(content);
106087
+ }
106088
+ return JSON.stringify(messages[messages.length - 1]);
106089
+ }
106090
+ /**
106091
+ * Extract app response from trace output for display.
106092
+ * Handles string, object with message/content/text/response, and messages array.
105683
106093
  */
105684
106094
  static extractAppResponse(output) {
105685
106095
  if (!output) return "";
105686
106096
  if (typeof output === "string") {
105687
106097
  try {
105688
106098
  const parsed = JSON.parse(output);
105689
- return (parsed == null ? void 0 : parsed.message) || (parsed == null ? void 0 : parsed.content) || (parsed == null ? void 0 : parsed.text) || (parsed == null ? void 0 : parsed.response) || output;
106099
+ 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);
106100
+ if (fromParsed !== void 0 && fromParsed !== null) return String(fromParsed);
106101
+ if (Array.isArray(parsed == null ? void 0 : parsed.messages)) {
106102
+ return this.extractLastMessageContentFromArray(parsed.messages);
106103
+ }
106104
+ return output;
105690
106105
  } catch {
105691
106106
  return output;
105692
106107
  }
105693
106108
  }
105694
106109
  if (typeof output === "object") {
105695
106110
  const obj = output;
105696
- return String((obj == null ? void 0 : obj["message"]) || (obj == null ? void 0 : obj["content"]) || (obj == null ? void 0 : obj["text"]) || (obj == null ? void 0 : obj["response"]) || "");
106111
+ 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"]);
106112
+ if (direct !== void 0 && direct !== null && direct !== "") {
106113
+ return typeof direct === "object" ? JSON.stringify(direct) : String(direct);
106114
+ }
106115
+ if (Array.isArray(obj == null ? void 0 : obj.messages)) {
106116
+ return this.extractLastMessageContentFromArray(obj.messages);
106117
+ }
106118
+ if (Array.isArray(output)) {
106119
+ return this.extractLastMessageContentFromArray(output);
106120
+ }
106121
+ return JSON.stringify(obj);
105697
106122
  }
105698
106123
  return String(output);
105699
106124
  }
106125
+ /**
106126
+ * Get last message content from a messages array for output display.
106127
+ */
106128
+ static extractLastMessageContentFromArray(messages) {
106129
+ if (!messages.length) return "";
106130
+ const last2 = messages[messages.length - 1];
106131
+ const fromKwargs = this.getLangchainMessageContent(last2);
106132
+ const content = fromKwargs ?? (last2 == null ? void 0 : last2.message) ?? (last2 == null ? void 0 : last2.text);
106133
+ if (content != null) return typeof content === "string" ? content : JSON.stringify(content);
106134
+ return JSON.stringify(last2);
106135
+ }
105700
106136
  /**
105701
106137
  * Calculate trace metrics from observations
105702
106138
  */
@@ -105706,7 +106142,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105706
106142
  let maxEndTime = 0;
105707
106143
  let minStartTime = Infinity;
105708
106144
  observations.forEach((obs) => {
105709
- totalTokens += obs.totalTokens || 0;
106145
+ var _a;
106146
+ const obsTokens = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
106147
+ totalTokens += typeof obsTokens === "number" ? obsTokens : parseInt(String(obsTokens || 0), 10) || 0;
105710
106148
  const cost = parseFloat(obs.totalCost || "0");
105711
106149
  if (!isNaN(cost)) totalCost += cost;
105712
106150
  const startMs = new Date(obs.startTime).getTime();
@@ -105729,7 +106167,15 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105729
106167
  );
105730
106168
  const generation = sorted.find((obs) => obs.type === "GENERATION");
105731
106169
  if (!generation) {
105732
- return { observation: null, ancestorIds: [] };
106170
+ const tree = this.buildObservationTree(observations);
106171
+ if (tree.length === 0) return { observation: null, ancestorIds: [] };
106172
+ const findFirstLeaf = (node) => {
106173
+ if (node.children.length === 0) return node;
106174
+ return findFirstLeaf(node.children[0]);
106175
+ };
106176
+ const leafNode = findFirstLeaf(tree[0]);
106177
+ const ancestorIds2 = this.getAncestorIds(observations, leafNode.observation.id);
106178
+ return { observation: leafNode.observation, ancestorIds: ancestorIds2 };
105733
106179
  }
105734
106180
  const ancestorIds = this.getAncestorIds(observations, generation.id);
105735
106181
  return { observation: generation, ancestorIds };
@@ -105876,6 +106322,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105876
106322
  "toolNode",
105877
106323
  "agent_toolNode",
105878
106324
  "PreProcessor",
106325
+ "PostProcessor",
105879
106326
  "MergerNode"
105880
106327
  ]
105881
106328
  }
@@ -106135,6 +106582,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106135
106582
  * Transform API trace response to TraceDetailData
106136
106583
  */
106137
106584
  transformToTraceDetailData(trace) {
106585
+ const piiDisplay = TraceTreeService.extractPiiDisplayFromApiTrace(trace);
106138
106586
  return {
106139
106587
  id: trace.id,
106140
106588
  name: trace.name || "",
@@ -106147,6 +106595,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106147
106595
  input: trace.input,
106148
106596
  output: trace.output,
106149
106597
  metadata: trace.metadata,
106598
+ displayUserMessage: piiDisplay.displayUserMessage,
106599
+ displayAppResponse: piiDisplay.displayAppResponse,
106150
106600
  tags: trace.tags || [],
106151
106601
  bookmarked: trace.bookmarked || false,
106152
106602
  public: trace.public || false,
@@ -106208,6 +106658,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106208
106658
  timestamp: trace.timestamp,
106209
106659
  input: trace.input,
106210
106660
  output: trace.output,
106661
+ displayUserMessage: trace.displayUserMessage,
106662
+ displayAppResponse: trace.displayAppResponse,
106211
106663
  latency: trace.latency,
106212
106664
  totalTokens: trace.totalTokens,
106213
106665
  totalCost: typeof trace.totalCost === "number" ? String(trace.totalCost) : trace.totalCost,
@@ -106361,6 +106813,19 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106361
106813
  name
106362
106814
  };
106363
106815
  }
106816
+ function getObservationTokens(obs) {
106817
+ var _a;
106818
+ const total = ((_a = obs.usageDetails) == null ? void 0 : _a.total) ?? obs.totalUsage ?? obs.totalTokens;
106819
+ if (total === void 0 || total === null) return 0;
106820
+ return typeof total === "number" ? total : parseInt(String(total), 10) || 0;
106821
+ }
106822
+ function getAggregatedTotalTokens(node) {
106823
+ let sum2 = getObservationTokens(node.observation);
106824
+ node.children.forEach((child) => {
106825
+ sum2 += getAggregatedTotalTokens(child);
106826
+ });
106827
+ return sum2;
106828
+ }
106364
106829
  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: [
106365
106830
  /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "6", cy: "6", r: "5.5", fill: "#17B26A" }),
106366
106831
  /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 6L5.5 7.5L8 4.5", stroke: "white", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
@@ -106422,7 +106887,11 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106422
106887
  return observation.name || observation.type || "";
106423
106888
  };
106424
106889
  const displayName = getDisplayName2();
106425
- const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total) || observation.totalUsage || observation.totalTokens;
106890
+ const displayTokens = ((_d = observation.usageDetails) == null ? void 0 : _d.total) ?? observation.totalUsage ?? observation.totalTokens;
106891
+ const aggregatedTotalTokens = React.useMemo(() => {
106892
+ if (!isSupervisorOrAgent) return 0;
106893
+ return getAggregatedTotalTokens(node);
106894
+ }, [node, isSupervisorOrAgent]);
106426
106895
  const handleRowClick = () => {
106427
106896
  if (hasChildren) {
106428
106897
  onToggle(observation.id);
@@ -106469,34 +106938,43 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106469
106938
  className: "w-[24px] h-[24px] rounded-[8px]"
106470
106939
  }
106471
106940
  ) }),
106472
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[12px] leading-[16px] text-[#101828] truncate flex-1 min-w-0", title: displayName, children: displayName }),
106473
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] flex-shrink-0", children: [
106474
- isSupervisorOrAgent && (modelFromMetadata || observation.model) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal", children: modelFromMetadata || observation.model }),
106475
- (isGeneration || isSupervisorOrAgent) && displayTokens !== void 0 && displayTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: [
106476
- TraceTreeService.formatTokens(displayTokens),
106941
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[2px] flex-1 min-w-0", children: [
106942
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[12px] leading-[16px] text-[#101828] truncate", title: displayName, children: displayName }),
106943
+ isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[6px] flex-wrap text-[10px] leading-[12px] text-[#667085] font-normal", children: [
106944
+ modelFromMetadata || observation.model ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: modelFromMetadata || observation.model }) : null,
106945
+ aggregatedTotalTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
106946
+ (modelFromMetadata || observation.model) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }),
106947
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap", children: [
106948
+ TraceTreeService.formatTokens(aggregatedTotalTokens),
106949
+ " Tokens"
106950
+ ] })
106951
+ ] }),
106952
+ duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
106953
+ modelFromMetadata || observation.model || aggregatedTotalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "·" }) : null,
106954
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "whitespace-nowrap flex items-center gap-[4px]", children: [
106955
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
106956
+ TraceTreeService.formatDuration(duration)
106957
+ ] })
106958
+ ] })
106959
+ ] })
106960
+ ] }),
106961
+ !isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] flex-shrink-0", children: [
106962
+ isGeneration && displayTokens !== void 0 && Number(displayTokens) > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: [
106963
+ TraceTreeService.formatTokens(Number(displayTokens)),
106477
106964
  " Tokens"
106478
106965
  ] }),
106479
106966
  duration > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
106480
106967
  /* @__PURE__ */ jsxRuntimeExports.jsx(ClockIcon, {}),
106481
106968
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#667085] font-normal whitespace-nowrap", children: TraceTreeService.formatDuration(duration) })
106482
106969
  ] }),
106483
- isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
106484
- "div",
106485
- {
106486
- className: "flex-shrink-0 cursor-help",
106487
- title: statusTooltip,
106488
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {})
106489
- }
106490
- ),
106491
- isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx(
106492
- "div",
106493
- {
106494
- className: "flex-shrink-0 cursor-help",
106495
- title: statusTooltip,
106496
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {})
106497
- }
106498
- ),
106970
+ isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
106971
+ isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
106499
106972
  isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
106973
+ ] }),
106974
+ isSupervisorOrAgent && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-shrink-0 flex items-center", children: [
106975
+ isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorIcon, {}) }),
106976
+ isWarning && !isError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "cursor-help", title: statusTooltip, children: /* @__PURE__ */ jsxRuntimeExports.jsx(WarningIcon, {}) }),
106977
+ isCompleted && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(SuccessIcon, {}) })
106500
106978
  ] })
106501
106979
  ]
106502
106980
  }
@@ -106534,8 +107012,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106534
107012
  onNodeSelect,
106535
107013
  onExpandToggle,
106536
107014
  showTraceId = true,
107015
+ onTraceIdClick,
106537
107016
  isLoading = false,
106538
- defaultExpandedNodeIds
107017
+ defaultExpandedNodeIds,
107018
+ runHeaderInputMode = "display"
106539
107019
  }) {
106540
107020
  const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);
106541
107021
  const [expandedNodeIds, setExpandedNodeIds] = React.useState(
@@ -106553,11 +107033,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106553
107033
  return TraceTreeService.buildObservationTree(observations);
106554
107034
  }, [observations]);
106555
107035
  const userMessage = React.useMemo(() => {
107036
+ if (runHeaderInputMode !== "tokenized" && trace.displayUserMessage !== void 0 && trace.displayUserMessage.length > 0) {
107037
+ return trace.displayUserMessage;
107038
+ }
106556
107039
  return TraceTreeService.extractUserMessage(trace.input);
106557
- }, [trace.input]);
107040
+ }, [trace.input, trace.displayUserMessage, runHeaderInputMode]);
106558
107041
  const appResponse = React.useMemo(() => {
107042
+ if (runHeaderInputMode !== "tokenized" && trace.displayAppResponse !== void 0 && trace.displayAppResponse.length > 0) {
107043
+ return trace.displayAppResponse;
107044
+ }
106559
107045
  return TraceTreeService.extractAppResponse(trace.output);
106560
- }, [trace.output]);
107046
+ }, [trace.output, trace.displayAppResponse, runHeaderInputMode]);
107047
+ const traceMetrics = React.useMemo(() => {
107048
+ return TraceTreeService.calculateTraceMetrics(trace, observations);
107049
+ }, [trace, observations]);
106561
107050
  const handleTraceToggle = React.useCallback(() => {
106562
107051
  setIsExpanded((prev) => !prev);
106563
107052
  onExpandToggle == null ? void 0 : onExpandToggle();
@@ -106584,7 +107073,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106584
107073
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[4px] w-full mb-[8px]", children: [
106585
107074
  showTraceId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center px-0 py-[4px] w-full", children: [
106586
107075
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#98A2B3]", children: "Trace ID" }),
106587
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
107076
+ onTraceIdClick ? /* @__PURE__ */ jsxRuntimeExports.jsx(
107077
+ "button",
107078
+ {
107079
+ onClick: () => onTraceIdClick(trace.id),
107080
+ className: "font-medium text-[10px] leading-[12px] text-[#155EEF] hover:underline cursor-pointer bg-transparent border-none p-0",
107081
+ title: "View Trace Details",
107082
+ "data-test-id": `trace-tree-id-link-${trace.id}`,
107083
+ children: trace.id
107084
+ }
107085
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
106588
107086
  /* @__PURE__ */ jsxRuntimeExports.jsx(
106589
107087
  "button",
106590
107088
  {
@@ -106659,10 +107157,18 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106659
107157
  rootNode.observation.id
106660
107158
  )) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[16px] text-[12px] text-[#667085] text-center", children: "No observations available" }) }),
106661
107159
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white flex flex-col gap-[8px] p-[12px] border-t border-[#EAECF0]", children: [
106662
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-[8px] items-center w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center flex-1 min-w-0", children: [
106663
- /* @__PURE__ */ jsxRuntimeExports.jsx(AppResponseIcon, {}),
106664
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.02em] flex-1", children: "APP RESPONSE" })
106665
- ] }) }),
107160
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center w-full", children: [
107161
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center flex-1 min-w-0", children: [
107162
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AppResponseIcon, {}),
107163
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.02em]", children: "APP RESPONSE" })
107164
+ ] }),
107165
+ (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: [
107166
+ TraceTreeService.formatDuration(traceMetrics.latency),
107167
+ " · ",
107168
+ TraceTreeService.formatTokens(traceMetrics.totalTokens),
107169
+ " Tokens"
107170
+ ] })
107171
+ ] }),
106666
107172
  /* @__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: [
106667
107173
  appResponse.substring(0, 150),
106668
107174
  "...",
@@ -106695,114 +107201,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106695
107201
  ] })
106696
107202
  ] });
106697
107203
  }
106698
- const CopyButton$1 = ({
106699
- text,
106700
- className = "",
106701
- iconClassName = "",
106702
- iconStyle,
106703
- title = "Copy to clipboard",
106704
- onCopySuccess,
106705
- onCopyError,
106706
- tooltipText = "Copied!",
106707
- tooltipPosition = "bottom",
106708
- size = "md"
106709
- }) => {
106710
- const [showTooltip, setShowTooltip] = React.useState(false);
106711
- const getSizeClasses = () => {
106712
- switch (size) {
106713
- case "sm":
106714
- return {
106715
- button: "p-1",
106716
- icon: "w-[12px] h-[12px]",
106717
- tooltip: "text-xs py-1 px-2"
106718
- };
106719
- case "lg":
106720
- return {
106721
- button: "p-2",
106722
- icon: "w-[20px] h-[20px]",
106723
- tooltip: "text-sm py-2 px-3"
106724
- };
106725
- default:
106726
- return {
106727
- button: "p-1.5",
106728
- icon: "w-[16px] h-[16px]",
106729
- tooltip: "text-xs py-1 px-2"
106730
- };
106731
- }
106732
- };
106733
- const getTooltipPositionClasses = () => {
106734
- const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
106735
- switch (tooltipPosition) {
106736
- case "bottom":
106737
- return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
106738
- case "left":
106739
- return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
106740
- case "right":
106741
- return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
106742
- default:
106743
- return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
106744
- }
106745
- };
106746
- const sizeClasses2 = getSizeClasses();
106747
- const showCopyTooltip = React.useCallback(() => {
106748
- setShowTooltip(true);
106749
- setTimeout(() => setShowTooltip(false), 1e3);
106750
- }, []);
106751
- const copyToClipboard2 = React.useCallback(async () => {
106752
- try {
106753
- if (navigator.clipboard && navigator.clipboard.writeText) {
106754
- await navigator.clipboard.writeText(text);
106755
- showCopyTooltip();
106756
- onCopySuccess == null ? void 0 : onCopySuccess();
106757
- return;
106758
- }
106759
- const textArea = document.createElement("textarea");
106760
- textArea.value = text;
106761
- textArea.style.position = "fixed";
106762
- textArea.style.left = "-999999px";
106763
- textArea.style.top = "-999999px";
106764
- document.body.appendChild(textArea);
106765
- textArea.focus();
106766
- textArea.select();
106767
- try {
106768
- document.execCommand("copy");
106769
- showCopyTooltip();
106770
- onCopySuccess == null ? void 0 : onCopySuccess();
106771
- } catch (err) {
106772
- const error = err instanceof Error ? err : new Error("Copy failed");
106773
- console.warn("Copy to clipboard failed:", error);
106774
- onCopyError == null ? void 0 : onCopyError(error);
106775
- } finally {
106776
- document.body.removeChild(textArea);
106777
- }
106778
- } catch (err) {
106779
- const error = err instanceof Error ? err : new Error("Copy failed");
106780
- console.warn("Copy to clipboard failed:", error);
106781
- onCopyError == null ? void 0 : onCopyError(error);
106782
- }
106783
- }, [text, showCopyTooltip, onCopySuccess, onCopyError]);
106784
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
106785
- /* @__PURE__ */ jsxRuntimeExports.jsx(
106786
- "button",
106787
- {
106788
- onClick: copyToClipboard2,
106789
- className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
106790
- title,
106791
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
106792
- }
106793
- ),
106794
- /* @__PURE__ */ jsxRuntimeExports.jsx(
106795
- "div",
106796
- {
106797
- className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
106798
- style: {
106799
- visibility: showTooltip ? "visible" : "hidden"
106800
- },
106801
- children: tooltipText
106802
- }
106803
- )
106804
- ] });
106805
- };
106806
107204
  function __awaiter(thisArg, _arguments, P2, generator) {
106807
107205
  function adopt(value) {
106808
107206
  return value instanceof P2 ? value : new P2(function(resolve) {
@@ -107967,21 +108365,35 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
107967
108365
  )
107968
108366
  ] })
107969
108367
  ] }),
107970
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto bg-gray-800 p-4", children: viewMode === "interactive" && useEnhancedJsonView ? /* @__PURE__ */ jsxRuntimeExports.jsx(
107971
- JsonView,
108368
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
108369
+ "div",
107972
108370
  {
107973
- src: parsedData,
107974
- theme: "github",
107975
- dark: true,
107976
- collapseObjectsAfterLength: 20,
107977
- collapseStringsAfterLength: 500,
107978
- collapseStringMode: "word",
107979
- displaySize: "collapsed",
107980
- matchesURL: true,
107981
- customizeCopy: (node) => stringifyJsonNode(node),
107982
- className: "w-full text-xs"
108371
+ className: "flex-1 overflow-auto bg-gray-800 p-4",
108372
+ style: {
108373
+ "--json-property": "#ffffff",
108374
+ "--json-index": "#e2e8f0",
108375
+ "--json-number": "#e2e8f0",
108376
+ "--json-string": "#e2e8f0",
108377
+ "--json-boolean": "#e2e8f0",
108378
+ "--json-null": "#e2e8f0"
108379
+ },
108380
+ children: viewMode === "interactive" && useEnhancedJsonView ? /* @__PURE__ */ jsxRuntimeExports.jsx(
108381
+ JsonView,
108382
+ {
108383
+ src: parsedData,
108384
+ dark: true,
108385
+ collapseObjectsAfterLength: 20,
108386
+ collapseStringsAfterLength: 500,
108387
+ collapseStringMode: "word",
108388
+ displaySize: "collapsed",
108389
+ matchesURL: true,
108390
+ customizeCopy: (node) => stringifyJsonNode(node),
108391
+ className: "w-full text-xs",
108392
+ style: { color: "#f1f5f9" }
108393
+ }
108394
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs whitespace-pre text-white font-mono", children: stringifyJsonNode(parsedData) })
107983
108395
  }
107984
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs whitespace-pre text-gray-300 font-mono", children: stringifyJsonNode(parsedData) }) })
108396
+ )
107985
108397
  ] }) });
107986
108398
  };
107987
108399
  const JsonViewer = ({
@@ -108349,6 +108761,23 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108349
108761
  function isObservation(node) {
108350
108762
  return node !== null && "traceId" in node && "type" in node;
108351
108763
  }
108764
+ function metadataForDisplay(metadata) {
108765
+ if (metadata === null || metadata === void 0) return {};
108766
+ let obj;
108767
+ if (typeof metadata === "string") {
108768
+ try {
108769
+ obj = JSON.parse(metadata);
108770
+ } catch {
108771
+ return {};
108772
+ }
108773
+ } else if (typeof metadata === "object") {
108774
+ obj = metadata;
108775
+ } else {
108776
+ return {};
108777
+ }
108778
+ const { tools: _tools, ...rest } = obj;
108779
+ return rest;
108780
+ }
108352
108781
  const defaultMetrics = {
108353
108782
  totalCost: "0",
108354
108783
  totalTokens: 0,
@@ -108397,7 +108826,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108397
108826
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 h-[1px] bg-[#EAECF0]" })
108398
108827
  ] });
108399
108828
  }
108400
- function PreviewContent({ input, output, metadata, statusMessage, isLoading = false, modelParameters }) {
108829
+ function PreviewContent({ input, output, metadata, statusMessage, isLoading = false }) {
108401
108830
  const [showAllMetadata, setShowAllMetadata] = React.useState(false);
108402
108831
  const messages = React.useMemo(() => {
108403
108832
  if (!input || typeof input !== "object") return null;
@@ -108429,15 +108858,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108429
108858
  }
108430
108859
  return String(output);
108431
108860
  }, [output]);
108432
- const modelName = React.useMemo(() => {
108433
- if (!input || typeof input !== "object") return null;
108434
- return input["model"] ?? null;
108435
- }, [input]);
108436
- const formatParamValue = (value) => {
108437
- if (value === null || value === void 0) return "";
108438
- if (typeof value === "object") return JSON.stringify(value);
108439
- return String(value);
108440
- };
108441
108861
  if (isLoading) {
108442
108862
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[16px] p-[16px] overflow-y-auto h-full", children: [
108443
108863
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
@@ -108451,29 +108871,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108451
108871
  ] });
108452
108872
  }
108453
108873
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[20px] p-[16px] overflow-y-auto h-full", children: [
108454
- (modelName || modelParameters && Object.keys(modelParameters).length > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
108455
- modelName && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-[8px] py-[4px] bg-[#F2F4F7] rounded-[4px] text-[11px] font-medium text-[#344054]", children: [
108456
- "Model: ",
108457
- modelName
108458
- ] }),
108459
- modelParameters && typeof modelParameters === "object" && Object.entries(modelParameters).filter(([_2, value]) => value !== null && value !== void 0).map(([key, value]) => {
108460
- const valueString = formatParamValue(value);
108461
- const displayKey = key.replace(/_/g, " ");
108462
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
108463
- "span",
108464
- {
108465
- className: "px-[8px] py-[4px] bg-[#F2F4F7] border border-[#EAECF0] rounded-[4px] text-[11px] font-medium text-[#344054] max-w-[200px] truncate",
108466
- title: `${key}: ${valueString}`,
108467
- children: [
108468
- displayKey,
108469
- ": ",
108470
- valueString
108471
- ]
108472
- },
108473
- key
108474
- );
108475
- })
108476
- ] }),
108477
108874
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
108478
108875
  /* @__PURE__ */ jsxRuntimeExports.jsx(SectionHeader, { title: "Input" }),
108479
108876
  messages ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-[8px]", children: messages.map((msg, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -108560,14 +108957,21 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108560
108957
  showHeader: true,
108561
108958
  useEnhancedJsonView: true,
108562
108959
  collapseStringsAfterLength: 500,
108563
- collapseObjectsAfterLength: 20,
108960
+ collapseObjectsAfterLength: selectedTab === "metadata" ? 100 : 20,
108961
+ defaultExpanded: selectedTab === "metadata",
108564
108962
  maxHeight: "100%",
108565
108963
  className: "h-full border-0 rounded-none"
108566
- }
108964
+ },
108965
+ selectedTab
108567
108966
  ) })
108568
108967
  ] });
108569
108968
  }
108570
- function NodeDetailPanel({ node, nodeType: _nodeType, apiConfig }) {
108969
+ function NodeDetailPanel({
108970
+ node,
108971
+ nodeType: _nodeType,
108972
+ apiConfig,
108973
+ generationSummaryInputOverride = null
108974
+ }) {
108571
108975
  const [selectedTab, setSelectedTab] = React.useState("preview");
108572
108976
  const [showTokenTooltip, setShowTokenTooltip] = React.useState(false);
108573
108977
  const tooltipTimeoutRef = React.useRef(null);
@@ -108654,6 +109058,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108654
109058
  }
108655
109059
  return TraceTreeService.extractUserMessage(displayNode.input);
108656
109060
  }, [displayNode]);
109061
+ const summaryInputLine = generationSummaryInputOverride !== null && generationSummaryInputOverride.length > 0 ? generationSummaryInputOverride : inputText;
108657
109062
  const isGeneration = React.useMemo(() => {
108658
109063
  return node !== null && isObservation(node) && node.type === "GENERATION";
108659
109064
  }, [node]);
@@ -108737,7 +109142,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108737
109142
  case "response":
108738
109143
  return displayNode.output || {};
108739
109144
  case "metadata":
108740
- return isObservation(displayNode) ? displayNode.metadata || {} : {};
109145
+ return isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {};
108741
109146
  case "logs":
108742
109147
  return {
108743
109148
  id: isObservation(displayNode) ? displayNode.id : displayNode.id,
@@ -108757,11 +109162,17 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108757
109162
  return {
108758
109163
  input: formattedInput,
108759
109164
  output: displayNode.output || {},
108760
- metadata: isObservation(displayNode) ? displayNode.metadata || {} : {},
109165
+ metadata: isObservation(displayNode) ? metadataForDisplay(displayNode.metadata || {}) : {},
108761
109166
  statusMessage: isObservation(displayNode) ? displayNode.statusMessage : void 0,
108762
109167
  modelParameters: isObservation(displayNode) ? displayNode.modelParameters : void 0
108763
109168
  };
108764
109169
  }, [displayNode, formattedInput]);
109170
+ const summaryModelInfo = React.useMemo(() => {
109171
+ if (!isGeneration || !displayNode) return { modelName: null, modelParameters: {} };
109172
+ const modelName = typeof formattedInput === "object" && formattedInput !== null && "model" in formattedInput ? formattedInput.model ?? null : null;
109173
+ const modelParameters = isObservation(displayNode) && displayNode.modelParameters && typeof displayNode.modelParameters === "object" ? displayNode.modelParameters : {};
109174
+ return { modelName, modelParameters };
109175
+ }, [isGeneration, displayNode, formattedInput]);
108765
109176
  const tokenTooltipContent = metrics.totalTokens > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
108766
109177
  "div",
108767
109178
  {
@@ -108854,10 +109265,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108854
109265
  ] })
108855
109266
  ),
108856
109267
  /* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {}),
108857
- isGeneration && inputText.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
109268
+ isGeneration && summaryInputLine.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
108858
109269
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
108859
109270
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[16px] text-[#98A2B3]", children: "Input" }),
108860
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[12px] font-medium leading-[16px] text-[#101828] truncate", children: inputText })
109271
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[12px] font-medium leading-[16px] text-[#101828] truncate", children: summaryInputLine })
108861
109272
  ] }),
108862
109273
  /* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
108863
109274
  ] }),
@@ -108873,6 +109284,37 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108873
109284
  ] })
108874
109285
  ] }),
108875
109286
  /* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
109287
+ ] }),
109288
+ isGeneration && (summaryModelInfo.modelName || Object.keys(summaryModelInfo.modelParameters).length > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
109289
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[8px]", children: [
109290
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[16px] text-[#98A2B3]", children: "Model parameters" }),
109291
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-[6px]", children: [
109292
+ summaryModelInfo.modelName && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-[8px] py-[4px] bg-[#F2F4F7] rounded-[4px] text-[11px] font-medium text-[#344054]", children: [
109293
+ "Model: ",
109294
+ summaryModelInfo.modelName
109295
+ ] }),
109296
+ Object.entries(summaryModelInfo.modelParameters).filter(
109297
+ ([_2, value]) => value !== null && value !== void 0
109298
+ ).map(([key, value]) => {
109299
+ const valueStr = typeof value === "object" ? JSON.stringify(value) : String(value);
109300
+ const displayKey = key.replace(/_/g, " ");
109301
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
109302
+ "span",
109303
+ {
109304
+ className: "px-[8px] py-[4px] bg-[#F2F4F7] border border-[#EAECF0] rounded-[4px] text-[11px] font-medium text-[#344054] max-w-[200px] truncate",
109305
+ title: `${key}: ${valueStr}`,
109306
+ children: [
109307
+ displayKey,
109308
+ ": ",
109309
+ valueStr
109310
+ ]
109311
+ },
109312
+ key
109313
+ );
109314
+ })
109315
+ ] })
109316
+ ] }),
109317
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ContentDivider, {})
108876
109318
  ] })
108877
109319
  ] })
108878
109320
  ] }),
@@ -108900,7 +109342,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108900
109342
  selectedObservationId,
108901
109343
  batchSize = DEFAULT_BATCH_SIZE,
108902
109344
  initialTraceCount,
108903
- initialSessionData
109345
+ initialSessionData,
109346
+ runHeaderInputMode = "display"
108904
109347
  }) {
108905
109348
  const [currentMode, setCurrentMode] = React.useState(initialMode);
108906
109349
  const [currentSessionId, setCurrentSessionId] = React.useState(initialSessionId);
@@ -109141,12 +109584,52 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109141
109584
  }, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
109142
109585
  const traces = React.useMemo(() => {
109143
109586
  if (mode === "session" && sessionData) {
109144
- return sessionData.traces.map((t) => service.transformToTraceData(t));
109587
+ const sorted = [...sessionData.traces].sort((a2, b) => {
109588
+ const tA = a2.timestamp ? new Date(a2.timestamp).getTime() : 0;
109589
+ const tB = b.timestamp ? new Date(b.timestamp).getTime() : 0;
109590
+ return tA - tB;
109591
+ });
109592
+ return sorted.map((t) => service.transformToTraceData(t));
109145
109593
  } else if (mode === "trace" && traceData) {
109146
109594
  return [service.transformToTraceData(traceData)];
109147
109595
  }
109148
109596
  return [];
109149
109597
  }, [mode, sessionData, traceData, service]);
109598
+ const generationSummaryInputOverride = React.useMemo(() => {
109599
+ var _a;
109600
+ if (runHeaderInputMode === "tokenized") {
109601
+ return null;
109602
+ }
109603
+ if (!selectedNode || !("traceId" in selectedNode) || !("type" in selectedNode)) {
109604
+ return null;
109605
+ }
109606
+ const obs = selectedNode;
109607
+ if (obs.type !== "GENERATION") {
109608
+ return null;
109609
+ }
109610
+ const traceRow = traces.find((t) => t.id === obs.traceId);
109611
+ if (!traceRow) {
109612
+ return null;
109613
+ }
109614
+ const displayUser = traceRow.displayUserMessage && traceRow.displayUserMessage.length > 0 ? traceRow.displayUserMessage : TraceTreeService.extractUserMessage(traceRow.input);
109615
+ if (!displayUser || displayUser.length === 0) {
109616
+ return null;
109617
+ }
109618
+ const fromState = (_a = traceObservations[obs.traceId]) == null ? void 0 : _a.observations;
109619
+ const observations = fromState && fromState.length > 0 ? fromState : mode === "trace" && (traceData == null ? void 0 : traceData.id) === obs.traceId && traceData.observations.length > 0 ? traceData.observations : [];
109620
+ const { observation: firstGen } = TraceTreeService.findFirstGeneration(observations);
109621
+ if (!firstGen || firstGen.id !== obs.id) {
109622
+ return null;
109623
+ }
109624
+ return displayUser;
109625
+ }, [
109626
+ runHeaderInputMode,
109627
+ selectedNode,
109628
+ traces,
109629
+ traceObservations,
109630
+ mode,
109631
+ traceData
109632
+ ]);
109150
109633
  const handleNodeSelect = React.useCallback((node) => {
109151
109634
  setSelectedNode(node);
109152
109635
  }, []);
@@ -109195,6 +109678,23 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109195
109678
  firstTraceId: null
109196
109679
  });
109197
109680
  }, []);
109681
+ const handleNavigateToTrace = React.useCallback((targetTraceId) => {
109682
+ setSelectedNode(null);
109683
+ setSessionData(null);
109684
+ setTraceData(null);
109685
+ setTraceObservations({});
109686
+ setLoadingState("idle");
109687
+ setError(null);
109688
+ setHasAutoSelected(false);
109689
+ setCurrentMode("trace");
109690
+ setCurrentTraceId(targetTraceId);
109691
+ setProgressiveState({
109692
+ traceCount: 0,
109693
+ pendingTraceIds: [],
109694
+ firstTraceLoaded: false,
109695
+ firstTraceId: null
109696
+ });
109697
+ }, []);
109198
109698
  if (loadingState === "loading") {
109199
109699
  const canShowHeader = mode === "session" && initialSessionData;
109200
109700
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col bg-white ${className}`, children: [
@@ -109363,8 +109863,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109363
109863
  onNodeSelect: handleNodeSelect,
109364
109864
  onExpandToggle: () => handleTraceExpand(trace.id, trace.timestamp),
109365
109865
  showTraceId: mode === "session",
109866
+ onTraceIdClick: mode === "session" ? handleNavigateToTrace : void 0,
109366
109867
  isLoading: isLoadingObservations,
109367
- defaultExpandedNodeIds: autoExpandIds
109868
+ defaultExpandedNodeIds: autoExpandIds,
109869
+ runHeaderInputMode
109368
109870
  },
109369
109871
  trace.id
109370
109872
  );
@@ -109384,7 +109886,15 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109384
109886
  );
109385
109887
  }) })
109386
109888
  ] }) }),
109387
- !selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailPanel, { node: selectedNode, nodeType, apiConfig })
109889
+ !selectedNode && !hasAutoSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(NodeDetailSkeleton, { showFullSummary: true }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
109890
+ NodeDetailPanel,
109891
+ {
109892
+ node: selectedNode,
109893
+ nodeType,
109894
+ apiConfig,
109895
+ generationSummaryInputOverride
109896
+ }
109897
+ )
109388
109898
  ] })
109389
109899
  ] });
109390
109900
  }
@@ -109799,22 +110309,25 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109799
110309
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
109800
110310
  }
109801
110311
  function SessionsListContent(props) {
109802
- const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours" } = props;
109803
- const { environments } = useEnvironment();
109804
- const [selectedSessionId, setSelectedSessionId] = React.useState(null);
110312
+ const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
110313
+ const { environments, resolveEnvironmentName } = useEnvironment();
110314
+ const [selectedSessionId, setSelectedSessionId] = React.useState(() => initialSessionId ?? null);
109805
110315
  const [selectedSessionData, setSelectedSessionData] = React.useState(null);
109806
- const [isModalOpen, setIsModalOpen] = React.useState(false);
110316
+ const [isModalOpen, setIsModalOpen] = React.useState(() => !!initialSessionId);
109807
110317
  const [sessions, setSessions] = React.useState([]);
109808
110318
  const [totalCount, setTotalCount] = React.useState(0);
109809
110319
  const [loading, setLoading] = React.useState(true);
109810
110320
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = React.useState(false);
110321
+ const [appVersionOptions, setAppVersionOptions] = React.useState([]);
110322
+ const [searchTerm, setSearchTerm] = React.useState("");
109811
110323
  const initialFilters = React.useMemo(() => {
109812
110324
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
109813
- if (hasEnvFilter) {
109814
- return defaultFilters;
110325
+ const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter$1(), ...defaultFilters];
110326
+ if (initialSessionId) {
110327
+ return [...base2, { column: "id", type: "string", operator: "=", value: initialSessionId }];
109815
110328
  }
109816
- return [createDraftEnvironmentFilter$1(), ...defaultFilters];
109817
- }, [defaultFilters]);
110329
+ return base2;
110330
+ }, [defaultFilters, initialSessionId]);
109818
110331
  const [filters, setFilters] = React.useState(initialFilters);
109819
110332
  const [showFilterPanel, setShowFilterPanel] = React.useState(false);
109820
110333
  const [showColumnCustomization, setShowColumnCustomization] = React.useState(false);
@@ -109823,6 +110336,32 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109823
110336
  const [pagination, setPagination] = React.useState({ page: 0, limit: 50 });
109824
110337
  const [orderBy, setOrderBy] = React.useState({ column: "createdAt", order: "DESC" });
109825
110338
  const apiService = React.useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
110339
+ React.useEffect(() => {
110340
+ if (initialSessionId) {
110341
+ setSelectedSessionId(initialSessionId);
110342
+ setIsModalOpen(true);
110343
+ }
110344
+ }, [initialSessionId]);
110345
+ React.useEffect(() => {
110346
+ const fetchAppVersions = async () => {
110347
+ try {
110348
+ const filterOptionsData = await apiService.fetchFilterOptions({
110349
+ projectId: apiConfig.projectId
110350
+ });
110351
+ if ((filterOptionsData == null ? void 0 : filterOptionsData.appvIds) && Array.isArray(filterOptionsData.appvIds)) {
110352
+ setAppVersionOptions(
110353
+ filterOptionsData.appvIds.map((item) => ({
110354
+ value: item.value,
110355
+ label: item.value
110356
+ }))
110357
+ );
110358
+ }
110359
+ } catch (error) {
110360
+ console.warn("Failed to fetch app version filter options:", error);
110361
+ }
110362
+ };
110363
+ fetchAppVersions();
110364
+ }, [apiService, apiConfig.projectId]);
109826
110365
  const convertPresetToDateRange = (preset) => {
109827
110366
  const now2 = /* @__PURE__ */ new Date();
109828
110367
  let pastDate;
@@ -109884,7 +110423,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109884
110423
  });
109885
110424
  }
109886
110425
  const allFilters = [...timeFilters, ...filters];
109887
- if (apiConfig.projectId) ;
109888
110426
  return allFilters;
109889
110427
  }, [timeRange, filters]);
109890
110428
  const fetchSessions = React.useCallback(async () => {
@@ -109944,6 +110482,28 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109944
110482
  React.useEffect(() => {
109945
110483
  fetchSessions();
109946
110484
  }, [fetchSessions]);
110485
+ const filteredSessions = React.useMemo(() => {
110486
+ const term = searchTerm.trim().toLowerCase();
110487
+ if (!term) return sessions;
110488
+ return sessions.filter((session) => {
110489
+ var _a;
110490
+ const envName = ((_a = resolveEnvironmentName(session.envId)) == null ? void 0 : _a.toLowerCase()) || "";
110491
+ const searchableFields = [
110492
+ session.id,
110493
+ envName,
110494
+ session.envId,
110495
+ session.appvId,
110496
+ session.source,
110497
+ session.environment,
110498
+ session.sessionReference,
110499
+ session.userReference,
110500
+ ...session.userIds || []
110501
+ ];
110502
+ return searchableFields.some(
110503
+ (field) => field && String(field).toLowerCase().includes(term)
110504
+ );
110505
+ });
110506
+ }, [sessions, searchTerm, resolveEnvironmentName]);
109947
110507
  const defaultColumns = React.useMemo(
109948
110508
  () => [
109949
110509
  {
@@ -109952,8 +110512,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109952
110512
  width: 320,
109953
110513
  pinned: "left",
109954
110514
  hide: false,
109955
- // Pinned columns should always be visible
109956
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
110515
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
109957
110516
  },
109958
110517
  {
109959
110518
  field: "envId",
@@ -110080,6 +110639,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110080
110639
  disabled: true,
110081
110640
  valueFormatter: (params) => TracingUtils.formatTokens(params.value),
110082
110641
  cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", children: TracingUtils.formatTokens(params.value) })
110642
+ },
110643
+ {
110644
+ field: "sessionReference",
110645
+ headerName: "Session Reference",
110646
+ width: 180,
110647
+ hide: true,
110648
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
110649
+ },
110650
+ {
110651
+ field: "identity",
110652
+ headerName: "User Reference",
110653
+ width: 180,
110654
+ hide: true,
110655
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
110083
110656
  }
110084
110657
  // {
110085
110658
  // field: 'traceTags',
@@ -110199,8 +110772,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110199
110772
  // User-friendly label
110200
110773
  apiColumnName: "App Version ID",
110201
110774
  // API expects "App Version ID" (koretracing uiTableName)
110202
- type: "string",
110203
- operators: ["=", "!=", "contains"]
110775
+ type: "stringOptions",
110776
+ operators: ["any of", "none of"],
110777
+ options: appVersionOptions
110204
110778
  },
110205
110779
  {
110206
110780
  field: "source",
@@ -110252,10 +110826,27 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110252
110826
  // API expects "Output Tokens" (koretracing uiTableName)
110253
110827
  type: "number",
110254
110828
  operators: ["=", ">", ">=", "<", "<="]
110829
+ },
110830
+ {
110831
+ field: "sessionReference",
110832
+ label: "Session Reference",
110833
+ apiColumnName: "Session Reference",
110834
+ type: "string",
110835
+ operators: ["=", "!=", "contains"]
110836
+ },
110837
+ {
110838
+ field: "identity",
110839
+ label: "User Reference",
110840
+ apiColumnName: "User Reference",
110841
+ type: "string",
110842
+ operators: ["=", "!=", "contains"]
110255
110843
  }
110256
110844
  ],
110257
- [environments]
110845
+ [environments, appVersionOptions]
110258
110846
  );
110847
+ const handleSearch = React.useCallback((term) => {
110848
+ setSearchTerm(term);
110849
+ }, []);
110259
110850
  const handleTimeRangeChange = (value, presetLabel) => {
110260
110851
  console.log("🗓️ SessionsList: Time range change requested:", value, presetLabel);
110261
110852
  setTimeRange(value);
@@ -110297,6 +110888,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110297
110888
  };
110298
110889
  const handleClearFilters = () => {
110299
110890
  setFilters([]);
110891
+ setSearchTerm("");
110300
110892
  setTimeRange("24 hours");
110301
110893
  };
110302
110894
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col w-full ${className}`, children: [
@@ -110305,11 +110897,19 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110305
110897
  {
110306
110898
  title: "Sessions",
110307
110899
  description: "Review session logs and trace details to analyze conversation logs and app behavior.",
110308
- showSearch: false,
110900
+ searchPlaceholder: "Search sessions...",
110901
+ showSearch: true,
110902
+ searchConfig: {
110903
+ metadataSearchFields: ["Session ID", "Environment", "App Version", "User ID", "Source"],
110904
+ updateQuery: handleSearch,
110905
+ currentQuery: searchTerm,
110906
+ tableAllowsFullTextSearch: false
110907
+ },
110309
110908
  timeRange,
110310
110909
  timeRangePresetLabel,
110311
110910
  onTimeRangeChange: handleTimeRangeChange,
110312
110911
  filters,
110912
+ filterColumns,
110313
110913
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
110314
110914
  onModifyColumnsClick: () => setShowColumnCustomization(true),
110315
110915
  onExportClick: handleExport,
@@ -110360,10 +110960,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110360
110960
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto p-[24px] pt-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
110361
110961
  TracingTable,
110362
110962
  {
110363
- data: sessions,
110963
+ data: filteredSessions,
110364
110964
  columns,
110365
110965
  loading,
110366
- totalCount,
110966
+ totalCount: searchTerm.trim() ? filteredSessions.length : totalCount,
110367
110967
  pagination,
110368
110968
  onPaginationChange: setPagination,
110369
110969
  onRowClick: handleRowClick,
@@ -110410,24 +111010,26 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110410
111010
  onTraceClick,
110411
111011
  className = "",
110412
111012
  defaultFilters = [],
110413
- sessionId
111013
+ sessionId,
111014
+ initialTraceId
110414
111015
  } = props;
110415
111016
  const { environments } = useEnvironment();
110416
- const [selectedTraceId, setSelectedTraceId] = React.useState(null);
110417
- const [isModalOpen, setIsModalOpen] = React.useState(false);
111017
+ const [selectedTraceId, setSelectedTraceId] = React.useState(() => initialTraceId ?? null);
111018
+ const [isModalOpen, setIsModalOpen] = React.useState(() => !!initialTraceId);
110418
111019
  const [traces, setTraces] = React.useState([]);
110419
111020
  const [totalCount, setTotalCount] = React.useState(0);
110420
111021
  const [loading, setLoading] = React.useState(true);
110421
111022
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = React.useState(false);
110422
111023
  const [searchTerm, setSearchTerm] = React.useState("");
110423
- const [searchType, setSearchType] = React.useState(["id"]);
111024
+ const [searchType, setSearchType] = React.useState(["id", "content"]);
110424
111025
  const initialFilters = React.useMemo(() => {
110425
111026
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
110426
- if (hasEnvFilter) {
110427
- return defaultFilters;
111027
+ const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter(), ...defaultFilters];
111028
+ if (initialTraceId) {
111029
+ return [...base2, { column: "id", type: "string", operator: "=", value: initialTraceId }];
110428
111030
  }
110429
- return [createDraftEnvironmentFilter(), ...defaultFilters];
110430
- }, [defaultFilters]);
111031
+ return base2;
111032
+ }, [defaultFilters, initialTraceId]);
110431
111033
  const [filters, setFilters] = React.useState(initialFilters);
110432
111034
  const [showFilterPanel, setShowFilterPanel] = React.useState(false);
110433
111035
  const [showColumnCustomization, setShowColumnCustomization] = React.useState(false);
@@ -110436,6 +111038,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110436
111038
  const [pagination, setPagination] = React.useState({ page: 0, limit: 50 });
110437
111039
  const [orderBy, setOrderBy] = React.useState({ column: "timestamp", order: "DESC" });
110438
111040
  const [detailedTraceData, setDetailedTraceData] = React.useState(/* @__PURE__ */ new Map());
111041
+ React.useEffect(() => {
111042
+ if (initialTraceId) {
111043
+ setSelectedTraceId(initialTraceId);
111044
+ setIsModalOpen(true);
111045
+ }
111046
+ }, [initialTraceId]);
110439
111047
  const apiService = React.useMemo(() => new TracingApiService(apiConfig), [apiConfig]);
110440
111048
  const convertPresetToDateRange = (preset) => {
110441
111049
  const now2 = /* @__PURE__ */ new Date();
@@ -110521,18 +111129,24 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110521
111129
  orderBy
110522
111130
  });
110523
111131
  const apiFilters = TracingUtils.convertFiltersToApiFormat(effectiveFilters, filterColumns);
110524
- const tracesResponse = await apiService.fetchTraces({
110525
- projectId: apiConfig.projectId,
110526
- filter: apiFilters,
110527
- orderBy,
110528
- page: pagination.page,
110529
- limit: pagination.limit,
110530
- searchQuery: searchTerm || null,
110531
- searchType
110532
- // 'id' for IDs/Names, ['id', 'content'] for Full Text
110533
- });
111132
+ const [tracesResponse, countResponse] = await Promise.all([
111133
+ apiService.fetchTraces({
111134
+ projectId: apiConfig.projectId,
111135
+ filter: apiFilters,
111136
+ orderBy,
111137
+ page: pagination.page,
111138
+ limit: pagination.limit,
111139
+ searchQuery: searchTerm || null,
111140
+ searchType
111141
+ }),
111142
+ apiService.fetchTracesCount(apiConfig.projectId, apiFilters, {
111143
+ searchQuery: searchTerm || null,
111144
+ searchType,
111145
+ orderBy
111146
+ })
111147
+ ]);
110534
111148
  const basicTraces = tracesResponse.traces || [];
110535
- console.log("✅ Basic traces loaded:", { count: basicTraces.length });
111149
+ console.log("✅ Basic traces loaded:", { count: basicTraces.length, total: countResponse.totalCount });
110536
111150
  if (basicTraces.length > 0) {
110537
111151
  const traceIds = basicTraces.map((t) => t.id);
110538
111152
  try {
@@ -110567,7 +111181,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110567
111181
  } else {
110568
111182
  setTraces([]);
110569
111183
  }
110570
- setTotalCount(basicTraces.length);
111184
+ setTotalCount(countResponse.totalCount);
110571
111185
  } catch (error) {
110572
111186
  console.error("❌ Error fetching traces:", error);
110573
111187
  setTraces([]);
@@ -110596,11 +111210,13 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110596
111210
  projectId: apiConfig.projectId,
110597
111211
  timestamp: trace.timestamp
110598
111212
  });
111213
+ const inputDisplay = TraceTreeService.extractUserMessage(detail["input"]);
111214
+ const outputDisplay = TraceTreeService.extractAppResponse(detail["output"]);
110599
111215
  setDetailedTraceData((prev) => {
110600
111216
  const newMap = new Map(prev);
110601
111217
  newMap.set(traceId, {
110602
- input: detail["input"],
110603
- output: detail["output"],
111218
+ input: inputDisplay,
111219
+ output: outputDisplay,
110604
111220
  totalCost: detail["totalCost"],
110605
111221
  envId: detail["envId"],
110606
111222
  source: detail["source"]
@@ -110637,8 +111253,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110637
111253
  width: 320,
110638
111254
  pinned: "left",
110639
111255
  hide: false,
110640
- // Pinned columns should always be visible
110641
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
111256
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
110642
111257
  }
110643
111258
  ];
110644
111259
  {
@@ -110649,11 +111264,13 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110649
111264
  hide: false,
110650
111265
  cellRenderer: (params) => {
110651
111266
  const detailData = detailedTraceData.get(params.data.id);
110652
- const inputText = detailData == null ? void 0 : detailData.input;
110653
- if (inputText === void 0) {
111267
+ const rawInput = detailData == null ? void 0 : detailData.input;
111268
+ if (rawInput === void 0) {
110654
111269
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
110655
111270
  }
110656
- return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: inputText, children: TracingUtils.truncate(inputText || "-", 50) });
111271
+ const inputText = typeof rawInput === "string" ? rawInput : TraceTreeService.extractUserMessage(rawInput);
111272
+ const displayText = TracingUtils.truncate(inputText || "-", 50);
111273
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: inputText || void 0, children: displayText });
110657
111274
  }
110658
111275
  });
110659
111276
  }
@@ -110682,11 +111299,13 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110682
111299
  hide: false,
110683
111300
  cellRenderer: (params) => {
110684
111301
  const detailData = detailedTraceData.get(params.data.id);
110685
- const outputText = detailData == null ? void 0 : detailData.output;
110686
- if (outputText === void 0) {
111302
+ const rawOutput = detailData == null ? void 0 : detailData.output;
111303
+ if (rawOutput === void 0) {
110687
111304
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-400 italic", children: "Loading..." });
110688
111305
  }
110689
- return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: outputText, children: TracingUtils.truncate(outputText || "-", 50) });
111306
+ const outputText = typeof rawOutput === "string" ? rawOutput : TraceTreeService.extractAppResponse(rawOutput);
111307
+ const displayText = TracingUtils.truncate(outputText || "-", 50);
111308
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: outputText || void 0, children: displayText });
110690
111309
  }
110691
111310
  });
110692
111311
  }
@@ -110749,11 +111368,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110749
111368
  // },
110750
111369
  {
110751
111370
  field: "timestamp",
110752
- headerName: "Timestamp",
111371
+ headerName: "Created At",
110753
111372
  width: 180,
110754
- hide: true,
110755
- // DISABLED - This is the main sort column for traces
110756
- disabled: true,
111373
+ hide: false,
110757
111374
  cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: params.value ? new Date(params.value).toLocaleString() : "-" })
110758
111375
  },
110759
111376
  {
@@ -110828,6 +111445,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110828
111445
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", children: source || "-" });
110829
111446
  }
110830
111447
  },
111448
+ {
111449
+ field: "sessionReference",
111450
+ headerName: "Session Reference",
111451
+ width: 180,
111452
+ hide: true,
111453
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111454
+ },
111455
+ {
111456
+ field: "identity",
111457
+ headerName: "User Reference",
111458
+ width: 180,
111459
+ hide: true,
111460
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111461
+ },
110831
111462
  {
110832
111463
  field: "promptTokens",
110833
111464
  headerName: "Input Tokens",
@@ -111004,10 +111635,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111004
111635
  },
111005
111636
  {
111006
111637
  field: "timestamp",
111007
- label: "Timestamp",
111008
- // Same as API
111638
+ label: "Created At",
111009
111639
  apiColumnName: "Timestamp",
111010
- // API expects "Timestamp" (koretracing uiTableName)
111640
+ // Backend payload: keep "Timestamp" for API
111011
111641
  type: "datetime",
111012
111642
  operators: [">=", "<=", "="]
111013
111643
  },
@@ -111098,6 +111728,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111098
111728
  label: "Output Tokens",
111099
111729
  type: "number",
111100
111730
  operators: ["=", ">", ">=", "<", "<="]
111731
+ },
111732
+ {
111733
+ field: "sessionReference",
111734
+ label: "Session Reference",
111735
+ apiColumnName: "Session Reference",
111736
+ type: "string",
111737
+ operators: ["=", "!=", "contains"]
111738
+ },
111739
+ {
111740
+ field: "identity",
111741
+ label: "User Reference",
111742
+ apiColumnName: "User Reference",
111743
+ type: "string",
111744
+ operators: ["=", "!=", "contains"]
111101
111745
  }
111102
111746
  );
111103
111747
  return baseColumns;
@@ -111164,6 +111808,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111164
111808
  timeRangePresetLabel,
111165
111809
  onTimeRangeChange: handleTimeRangeChange,
111166
111810
  filters,
111811
+ filterColumns,
111167
111812
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
111168
111813
  onModifyColumnsClick: () => setShowColumnCustomization(true),
111169
111814
  onExportClick: handleExport,
@@ -112215,12 +112860,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112215
112860
  * Process execution events and build a hierarchical tree structure
112216
112861
  * Session > Run > Node Tree
112217
112862
  */
112218
- static buildSessionTree(events, sessionId) {
112863
+ static buildSessionTree(events, sessionId, options) {
112219
112864
  var _a;
112220
112865
  const runGroups = this.groupEventsByRun(events);
112221
112866
  const runs = [];
112222
112867
  for (const [runId, runEvents] of runGroups.entries()) {
112223
- const runTree = this.buildRunTree(runId, runEvents);
112868
+ const runTree = this.buildRunTree(runId, runEvents, options);
112224
112869
  runs.push(runTree);
112225
112870
  }
112226
112871
  runs.sort((a2, b) => new Date(a2.startTime).getTime() - new Date(b.startTime).getTime());
@@ -112246,11 +112891,11 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112246
112891
  /**
112247
112892
  * Build tree for a single run
112248
112893
  */
112249
- static buildRunTree(runId, events) {
112894
+ static buildRunTree(runId, events, options) {
112250
112895
  var _a;
112251
112896
  const nodeEventMap = /* @__PURE__ */ new Map();
112252
112897
  events.forEach((event) => {
112253
- const nodeKey = `${event.data.id}|${event.data.name}|${event.data.toolName}`;
112898
+ const nodeKey = event.data.id;
112254
112899
  if (!nodeEventMap.has(nodeKey)) {
112255
112900
  nodeEventMap.set(nodeKey, {});
112256
112901
  }
@@ -112277,7 +112922,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112277
112922
  const status = this.calculateRunStatus(runEvents);
112278
112923
  const duration = endTime && startTime ? endTime - startTime : void 0;
112279
112924
  const totalTokens = this.calculateRunTokens(runEvents);
112280
- const userInput = this.extractUserInput(runEvents);
112925
+ const userInput = this.extractUserInput(runEvents, options);
112281
112926
  const finalOutput = this.extractFinalOutput(runEvents);
112282
112927
  return {
112283
112928
  runId,
@@ -112296,11 +112941,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112296
112941
  * Create TreeNode from paired started/completed events
112297
112942
  */
112298
112943
  static createTreeNodeFromEvents(startedEvent, completedEvent, runId) {
112944
+ var _a;
112299
112945
  const startTime = startedEvent.data.timestamp;
112300
112946
  const endTime = completedEvent == null ? void 0 : completedEvent.data.timestamp;
112301
112947
  const duration = endTime && startTime ? new Date(endTime).getTime() - new Date(startTime).getTime() : void 0;
112302
112948
  const primaryEvent = completedEvent || startedEvent;
112303
- 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";
112949
+ 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";
112304
112950
  const input = hasInputOutput ? startedEvent.data.input : void 0;
112305
112951
  let output = void 0;
112306
112952
  let error = void 0;
@@ -112314,7 +112960,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112314
112960
  const { toolInvocations, isResponse } = this.extractToolInvocations(output);
112315
112961
  console.log("toolInvocations", toolInvocations);
112316
112962
  console.log("isResponse", isResponse);
112317
- const provider = primaryEvent.data.type === "llm" ? this.extractProvider(primaryEvent.data.name || primaryEvent.data.toolName) : void 0;
112963
+ const extractedProvider = primaryEvent.data.type === "llm" ? this.extractProvider(primaryEvent.data.name || primaryEvent.data.toolName) : void 0;
112964
+ const provider = ((_a = primaryEvent.data.metadata) == null ? void 0 : _a.provider) || extractedProvider;
112318
112965
  return {
112319
112966
  id: primaryEvent.data.id,
112320
112967
  parentId: primaryEvent.data.parentId,
@@ -112473,12 +113120,22 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112473
113120
  /**
112474
113121
  * Extract initial user input from the first LLM node's input
112475
113122
  */
112476
- static extractUserInput(events) {
113123
+ static extractUserInput(events, options) {
113124
+ const preferDisplay = ((options == null ? void 0 : options.runHeaderInputMode) ?? "display") === "display";
112477
113125
  const llmEvents = events.filter(
112478
113126
  (e) => e.type === "node_started" && e.data.type === "llm"
112479
113127
  ).sort((a2, b) => new Date(a2.data.timestamp).getTime() - new Date(b.data.timestamp).getTime());
112480
113128
  if (llmEvents.length > 0) {
112481
113129
  const firstLlmEvent = llmEvents[0];
113130
+ if (preferDisplay && firstLlmEvent.data.displayInput !== void 0 && firstLlmEvent.data.displayInput !== null) {
113131
+ const d = firstLlmEvent.data.displayInput;
113132
+ if (typeof d === "string") {
113133
+ return d;
113134
+ }
113135
+ if (typeof d === "object") {
113136
+ return JSON.stringify(d);
113137
+ }
113138
+ }
112482
113139
  if (firstLlmEvent.data.input) {
112483
113140
  if (typeof firstLlmEvent.data.input === "string") {
112484
113141
  return firstLlmEvent.data.input;
@@ -112546,6 +113203,22 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112546
113203
  */
112547
113204
  static extractFinalOutput(events) {
112548
113205
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
113206
+ const postProcessorEvents = events.filter(
113207
+ (e) => {
113208
+ var _a2;
113209
+ return e.type === "node_completed" && e.data.type === "tool" && ((_a2 = e.data.metadata) == null ? void 0 : _a2.type) === "PostProcessor" && e.data.output;
113210
+ }
113211
+ );
113212
+ if (postProcessorEvents.length > 0) {
113213
+ const lastPP = postProcessorEvents[postProcessorEvents.length - 1];
113214
+ const ppOutput = lastPP.data.output;
113215
+ if (typeof ppOutput === "object" && ppOutput.output) {
113216
+ return typeof ppOutput.output === "string" ? ppOutput.output : JSON.stringify(ppOutput.output);
113217
+ }
113218
+ if (typeof ppOutput === "string") {
113219
+ return ppOutput;
113220
+ }
113221
+ }
112549
113222
  const errorEvents = events.filter(
112550
113223
  (e) => e.type === "node_completed" && e.data.error && (e.data.status === "errored" || e.data.status === "failed")
112551
113224
  );
@@ -112672,8 +113345,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
112672
113345
  /**
112673
113346
  * Update tree with new events (optimized for real-time updates)
112674
113347
  */
112675
- static updateTree(existingTree, _newEvents, allEvents) {
112676
- return this.buildSessionTree(allEvents, existingTree.sessionId);
113348
+ static updateTree(existingTree, _newEvents, allEvents, options) {
113349
+ return this.buildSessionTree(allEvents, existingTree.sessionId, options);
112677
113350
  }
112678
113351
  /**
112679
113352
  * Merge new events into existing events efficiently
@@ -113025,7 +113698,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113025
113698
  nodeId,
113026
113699
  totalObservations: observations.length
113027
113700
  });
113028
- const matchedObservation = observations.find((obs) => {
113701
+ const matchingObservations = observations.filter((obs) => {
113029
113702
  let metadata = obs.metadata;
113030
113703
  if (typeof metadata === "string") {
113031
113704
  try {
@@ -113046,6 +113719,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113046
113719
  });
113047
113720
  return nodeId === observationNodeId;
113048
113721
  });
113722
+ const matchedObservation = matchingObservations.find((obs) => obs.type === "GENERATION") || matchingObservations[0] || null;
113049
113723
  if (!matchedObservation) {
113050
113724
  const parts = nodeId.split("_");
113051
113725
  if (parts.length === 2) {
@@ -113187,6 +113861,36 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113187
113861
  return this.config;
113188
113862
  }
113189
113863
  }
113864
+ function sanitizeForTestId(value) {
113865
+ return value.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "") || "node";
113866
+ }
113867
+ function getDebuggerCallTypeTestId(node) {
113868
+ const name = (node.name ?? "unknown").toString();
113869
+ let slug = sanitizeForTestId(name);
113870
+ switch (node.type) {
113871
+ case "event":
113872
+ slug = slug.replace(/-event$/, "") || "event";
113873
+ return `debugger-event-${slug}`;
113874
+ case "Agent":
113875
+ return `debugger-${slug}-call`;
113876
+ case "tool":
113877
+ return `debugger-${slug}-call`;
113878
+ case "llm":
113879
+ return `debugger-llm-${slug}`;
113880
+ case "GuardrailsInputScan":
113881
+ return `debugger-guardrails-input-${slug}`;
113882
+ case "GuardrailsOutputScan":
113883
+ return `debugger-guardrails-output-${slug}`;
113884
+ case "External Orchestrator":
113885
+ return `debugger-orchestrator-${slug}`;
113886
+ case "ProxyWorker":
113887
+ return `debugger-proxy-${slug}`;
113888
+ case "PostProcessor":
113889
+ return `debugger-postprocessor-${slug}`;
113890
+ default:
113891
+ return `debugger-${String(node.type).toLowerCase().replace(/\s+/g, "-")}-${slug}`;
113892
+ }
113893
+ }
113190
113894
  function DebugCard({
113191
113895
  node,
113192
113896
  onToggle,
@@ -113198,9 +113902,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113198
113902
  projectId,
113199
113903
  nodeIndex = 0
113200
113904
  }) {
113905
+ var _a;
113906
+ const callTypeTestId = React.useMemo(() => getDebuggerCallTypeTestId(node), [node.type, node.name]);
113907
+ const cardTestId = React.useMemo(() => `${callTypeTestId}_${node.id}`, [callTypeTestId, node.id]);
113201
113908
  const isGuardrailsNode = React.useMemo(() => {
113202
- var _a;
113203
- return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((_a = node.name) == null ? void 0 : _a.toLowerCase().includes("guardrail"));
113909
+ var _a2;
113910
+ return node.type === "GuardrailsInputScan" || node.type === "GuardrailsOutputScan" || ((_a2 = node.name) == null ? void 0 : _a2.toLowerCase().includes("guardrail"));
113204
113911
  }, [node.type, node.name]);
113205
113912
  const availableTabs = React.useMemo(() => {
113206
113913
  switch (node.type) {
@@ -113377,7 +114084,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113377
114084
  }
113378
114085
  };
113379
114086
  const getNodeIcon = () => {
113380
- var _a, _b;
114087
+ var _a2, _b;
113381
114088
  if (isGuardrailsNode) {
113382
114089
  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(
113383
114090
  "path",
@@ -113412,7 +114119,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113412
114119
  size: "small",
113413
114120
  name: node.name,
113414
114121
  className: "w-[24px] h-[24px]",
113415
- toolType: node.type === "tool" ? (_a = node.metadata) == null ? void 0 : _a.type : void 0,
114122
+ toolType: node.type === "tool" ? (_a2 = node.metadata) == null ? void 0 : _a2.type : void 0,
113416
114123
  provider: node.type === "llm" ? (_b = node.metadata) == null ? void 0 : _b.provider : void 0,
113417
114124
  modelName: node.type === "llm" ? node.name : void 0
113418
114125
  }
@@ -113436,7 +114143,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113436
114143
  return availableTabs;
113437
114144
  };
113438
114145
  const renderActionContent = () => {
113439
- var _a, _b;
114146
+ var _a2, _b;
113440
114147
  let toolInvocations = node.toolInvocations || [];
113441
114148
  if (node.type === "llm" && Array.isArray(node.output)) {
113442
114149
  toolInvocations = node.output.filter(
@@ -113458,7 +114165,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113458
114165
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-600 truncate", children: child.name || "Unknown" })
113459
114166
  ] }, child.id || index))
113460
114167
  ] }),
113461
- toolInvocations.length > 0 && ((_b = (_a = toolInvocations[0]) == null ? void 0 : _a.args) == null ? void 0 : _b.reason) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
114168
+ toolInvocations.length > 0 && ((_b = (_a2 = toolInvocations[0]) == null ? void 0 : _a2.args) == null ? void 0 : _b.reason) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
113462
114169
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-400 mb-[4px]", children: "Reason" }),
113463
114170
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-600", children: toolInvocations[0].args.reason })
113464
114171
  ] })
@@ -113485,14 +114192,14 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113485
114192
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 italic", children: "No actions taken" });
113486
114193
  };
113487
114194
  const extractOutputMessage = (output) => {
113488
- var _a, _b, _c, _d;
114195
+ var _a2, _b, _c, _d;
113489
114196
  if (!output || typeof output !== "object") return void 0;
113490
114197
  if (Array.isArray(output)) {
113491
114198
  const routeToUserTool = output.find(
113492
114199
  (item) => item && typeof item === "object" && (item.name === "route_to_user" || item.toolName === "route_to_user")
113493
114200
  );
113494
114201
  if (routeToUserTool) {
113495
- return ((_a = routeToUserTool.args) == null ? void 0 : _a.message) || routeToUserTool.message || ((_b = routeToUserTool.output) == null ? void 0 : _b.message);
114202
+ return ((_a2 = routeToUserTool.args) == null ? void 0 : _a2.message) || routeToUserTool.message || ((_b = routeToUserTool.output) == null ? void 0 : _b.message);
113496
114203
  }
113497
114204
  } else if (output.name === "route_to_user" || output.toolName === "route_to_user") {
113498
114205
  return ((_c = output.args) == null ? void 0 : _c.message) || output.message || ((_d = output.output) == null ? void 0 : _d.message);
@@ -113589,7 +114296,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113589
114296
  ] });
113590
114297
  };
113591
114298
  const renderTabContent = () => {
113592
- var _a;
114299
+ var _a2;
113593
114300
  switch (activeTab) {
113594
114301
  case "summary":
113595
114302
  if (isGuardrailsNode) {
@@ -113780,7 +114487,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113780
114487
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
113781
114488
  DataViewer,
113782
114489
  {
113783
- data: ((_a = node.metadata) == null ? void 0 : _a["logs"]) || {},
114490
+ data: ((_a2 = node.metadata) == null ? void 0 : _a2["logs"]) || {},
113784
114491
  title: "Execution Logs",
113785
114492
  maxHeight: "250px",
113786
114493
  defaultExpanded: true,
@@ -113793,15 +114500,15 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113793
114500
  };
113794
114501
  return (
113795
114502
  // bg-white w-full border-t border-gray-200
113796
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id": `debug_card_${node.id}`, children: [
114503
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white w-full", "data-test-id": cardTestId, "data-call-type-test-id": callTypeTestId, children: [
113797
114504
  /* @__PURE__ */ jsxRuntimeExports.jsx(
113798
114505
  "div",
113799
114506
  {
113800
114507
  className: `flex items-center pl-[8px] pr-[8px] relative transition-colors cursor-pointer w-full
113801
114508
  ${isSelected ? "" : ""}`,
113802
114509
  onClick: handleNodeClick,
113803
- "data-test-id": `debug_card_header_${node.id}`,
113804
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id": `debug_card_header_content_${node.id}`, children: [
114510
+ "data-test-id": `${callTypeTestId}_header`,
114511
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[10px] w-full", "data-test-id": `${callTypeTestId}_header_content`, children: [
113805
114512
  /* @__PURE__ */ jsxRuntimeExports.jsx(
113806
114513
  "div",
113807
114514
  {
@@ -113815,7 +114522,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113815
114522
  }
113816
114523
  },
113817
114524
  title: hasChildren ? isExpanded ? "Collapse" : "Expand" : "Show details",
113818
- "data-test-id": `debug_card_toggle_${node.id}`,
114525
+ "data-test-id": `${callTypeTestId}_toggle`,
113819
114526
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
113820
114527
  ChevronRight,
113821
114528
  {
@@ -113824,28 +114531,28 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113824
114531
  )
113825
114532
  }
113826
114533
  ),
113827
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] w-full py-[8px] border-b border-gray-200", "data-test-id": `debug_card_node_info_${node.id}`, children: [
113828
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 rounded-[8px] bg-[#B2DDFF]", "data-test-id": `debug_card_node_icon_${node.id}`, children: getNodeIcon() }),
114534
+ /* @__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: [
114535
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 rounded-[8px] bg-[#B2DDFF]", "data-test-id": `${callTypeTestId}_node_icon`, children: getNodeIcon() }),
113829
114536
  /* @__PURE__ */ jsxRuntimeExports.jsx(
113830
114537
  "span",
113831
114538
  {
113832
114539
  className: "font-semibold text-gray-900 text-xs truncate w-full",
113833
114540
  title: node.type === "llm" ? node.name : void 0,
113834
- "data-test-id": `debug_card_node_name_${node.id}`,
113835
- 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
114541
+ "data-test-id": `${callTypeTestId}_node_name`,
114542
+ 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
113836
114543
  }
113837
114544
  ),
113838
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id": `debug_card_node_metadata_${node.id}`, children: [
114545
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[12px] text-[10px] text-gray-500", "data-test-id": `${callTypeTestId}_node_metadata`, children: [
113839
114546
  node.type === "Agent" && (() => {
113840
- var _a;
113841
- const llmChild = (_a = node.children) == null ? void 0 : _a.find((child) => child.type === "llm");
114547
+ var _a2;
114548
+ const llmChild = (_a2 = node.children) == null ? void 0 : _a2.find((child) => child.type === "llm");
113842
114549
  if (llmChild == null ? void 0 : llmChild.name) {
113843
114550
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
113844
114551
  "span",
113845
114552
  {
113846
114553
  className: "text-[10px] text-gray-500 truncate max-w-[100px]",
113847
114554
  title: llmChild.name,
113848
- "data-test-id": `debug_card_node_model_name_${node.id}`,
114555
+ "data-test-id": `${callTypeTestId}_node_model_name`,
113849
114556
  children: llmChild.name
113850
114557
  }
113851
114558
  );
@@ -113853,7 +114560,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113853
114560
  return null;
113854
114561
  })(),
113855
114562
  (node.type === "Agent" || node.type === "llm" || isGuardrailsNode) && (() => {
113856
- var _a, _b, _c;
114563
+ var _a2, _b, _c;
113857
114564
  let llmUsage = node.llmUsage;
113858
114565
  if (node.type === "Agent" && node.children) {
113859
114566
  const llmChildren = node.children.filter((child) => child.type === "llm");
@@ -113875,10 +114582,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
113875
114582
  "span",
113876
114583
  {
113877
114584
  className: "text-[10px] text-gray-500 whitespace-nowrap cursor-help",
113878
- title: `Input: ${((_a = llmUsage.input_tokens) == null ? void 0 : _a.toLocaleString()) || 0} tokens
114585
+ title: `Input: ${((_a2 = llmUsage.input_tokens) == null ? void 0 : _a2.toLocaleString()) || 0} tokens
113879
114586
  Output: ${((_b = llmUsage.output_tokens) == null ? void 0 : _b.toLocaleString()) || 0} tokens
113880
114587
  Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) || 0} tokens`,
113881
- "data-test-id": `debug_card_node_tokens_${node.id}`,
114588
+ "data-test-id": `${callTypeTestId}_node_tokens`,
113882
114589
  children: [
113883
114590
  llmUsage.total_tokens.toLocaleString(),
113884
114591
  " Tokens"
@@ -113888,34 +114595,34 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
113888
114595
  }
113889
114596
  return null;
113890
114597
  })(),
113891
- node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id": `debug_card_node_duration_${node.id}`, children: [
114598
+ node.duration && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", "data-test-id": `${callTypeTestId}_node_duration`, children: [
113892
114599
  /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-[12px] h-[12px]" }),
113893
114600
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-gray-500 whitespace-nowrap", children: formatDuration(node.duration) })
113894
114601
  ] })
113895
114602
  ] }),
113896
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id": `debug_card_node_status_${node.id}`, children: getStatusIcon() })
114603
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", "data-test-id": `${callTypeTestId}_node_status`, children: getStatusIcon() })
113897
114604
  ] })
113898
114605
  ] })
113899
114606
  }
113900
114607
  ),
113901
- isSelected && availableTabs.length > 0 && showDetailView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `debug_card_detail_panel_${node.id}`, children: [
113902
- /* @__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": `debug_card_detail_panel_connector_${node.id}` }),
113903
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-[4px] py-[8px] w-full", "data-test-id": `debug_card_detail_panel_content_${node.id}`, children: [
113904
- /* @__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": `debug_card_detail_panel_tabs_${node.id}`, children: getTabsForNodeType().map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsx(
114608
+ isSelected && availableTabs.length > 0 && showDetailView && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_detail_panel`, children: [
114609
+ /* @__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` }),
114610
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-[4px] py-[8px] w-full", "data-test-id": `${callTypeTestId}_detail_panel_content`, children: [
114611
+ /* @__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(
113905
114612
  "button",
113906
114613
  {
113907
114614
  onClick: () => handleTabClick(tab),
113908
114615
  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"}`,
113909
- "data-test-id": `debug_card_detail_panel_tab_${node.id}_${tab}`,
114616
+ "data-test-id": `${callTypeTestId}_detail_panel_tab_${tab}`,
113910
114617
  children: tab.charAt(0).toUpperCase() + tab.slice(1)
113911
114618
  },
113912
114619
  tab
113913
114620
  )) }),
113914
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id": `debug_card_detail_panel_tab_content_${node.id}`, children: renderTabContent() })
114621
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-[4px]", "data-test-id": `${callTypeTestId}_detail_panel_tab_content`, children: renderTabContent() })
113915
114622
  ] })
113916
114623
  ] }),
113917
- isExpanded && hasChildren && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `debug_card_children_${node.id}`, children: [
113918
- /* @__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": `debug_card_children_connector_${node.id}` }),
114624
+ isExpanded && hasChildren && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full pl-[32px] relative", "data-test-id": `${callTypeTestId}_children`, children: [
114625
+ /* @__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` }),
113919
114626
  node.children.map((child, index) => /* @__PURE__ */ jsxRuntimeExports.jsx(
113920
114627
  DebugCard,
113921
114628
  {
@@ -113951,6 +114658,7 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
113951
114658
  expansionMode = "none",
113952
114659
  showExpansionControls = false,
113953
114660
  defaultDetailView = true,
114661
+ runHeaderInputMode = "display",
113954
114662
  apiConfig
113955
114663
  } = config2;
113956
114664
  console.log("🔧 DebugPanel - Config received:", {
@@ -114011,10 +114719,12 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
114011
114719
  }
114012
114720
  }), []);
114013
114721
  const sessionTree = React.useMemo(() => {
114014
- const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId);
114722
+ const tree = TreeBuilder.buildSessionTree(executionEvents, sessionId, {
114723
+ runHeaderInputMode
114724
+ });
114015
114725
  prevSessionTreeRef.current = tree;
114016
114726
  return tree;
114017
- }, [executionEvents, sessionId]);
114727
+ }, [executionEvents, sessionId, runHeaderInputMode]);
114018
114728
  const getAllNodeIds = (tree) => {
114019
114729
  const nodeIds = [];
114020
114730
  const collectIds = (node) => {
@@ -114422,16 +115132,25 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
114422
115132
  const findFinalOutput = (nodes) => {
114423
115133
  let lastOutput = void 0;
114424
115134
  let routeToUserOutput = void 0;
115135
+ let postProcessorOutput = void 0;
114425
115136
  const traverse = (nodeList) => {
114426
- var _a, _b, _c, _d, _e;
115137
+ var _a, _b, _c, _d, _e, _f;
114427
115138
  for (const node of nodeList) {
115139
+ if (node.type === "tool" && ((_a = node.metadata) == null ? void 0 : _a.type) === "PostProcessor" && node.output) {
115140
+ const ppOut = node.output;
115141
+ if (typeof ppOut === "object" && ppOut.output) {
115142
+ postProcessorOutput = typeof ppOut.output === "string" ? ppOut.output : JSON.stringify(ppOut.output);
115143
+ } else if (typeof ppOut === "string") {
115144
+ postProcessorOutput = ppOut;
115145
+ }
115146
+ }
114428
115147
  if (node.type === "tool" && (node.name === "route_to_user" || node.name === "route_to_user")) {
114429
115148
  if (node.output) {
114430
115149
  if (typeof node.output === "string") {
114431
115150
  routeToUserOutput = node.output;
114432
- } else if ((_a = node.output) == null ? void 0 : _a.message) {
115151
+ } else if ((_b = node.output) == null ? void 0 : _b.message) {
114433
115152
  routeToUserOutput = node.output.message;
114434
- } else if ((_b = node.output) == null ? void 0 : _b.result) {
115153
+ } else if ((_c = node.output) == null ? void 0 : _c.result) {
114435
115154
  routeToUserOutput = node.output.result;
114436
115155
  }
114437
115156
  }
@@ -114441,7 +115160,7 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
114441
115160
  (item) => (item == null ? void 0 : item.name) === "route_to_user" || (item == null ? void 0 : item.toolName) === "route_to_user"
114442
115161
  );
114443
115162
  if (routeItem) {
114444
- if ((_c = routeItem.args) == null ? void 0 : _c.message) {
115163
+ if ((_d = routeItem.args) == null ? void 0 : _d.message) {
114445
115164
  routeToUserOutput = routeItem.args.message;
114446
115165
  } else if (routeItem.message) {
114447
115166
  routeToUserOutput = routeItem.message;
@@ -114452,9 +115171,9 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
114452
115171
  if (typeof node.output === "string") {
114453
115172
  lastOutput = node.output;
114454
115173
  } else if (!Array.isArray(node.output)) {
114455
- if ((_d = node.output) == null ? void 0 : _d.message) {
115174
+ if ((_e = node.output) == null ? void 0 : _e.message) {
114456
115175
  lastOutput = node.output.message;
114457
- } else if ((_e = node.output) == null ? void 0 : _e.result) {
115176
+ } else if ((_f = node.output) == null ? void 0 : _f.result) {
114458
115177
  lastOutput = node.output.result;
114459
115178
  } else if (typeof node.output === "object") {
114460
115179
  if (!node.output.name && !node.output.toolName) {
@@ -114469,7 +115188,7 @@ Total: ${((_c = llmUsage.total_tokens) == null ? void 0 : _c.toLocaleString()) |
114469
115188
  }
114470
115189
  };
114471
115190
  traverse(nodes);
114472
- return routeToUserOutput || lastOutput;
115191
+ return postProcessorOutput || routeToUserOutput || lastOutput;
114473
115192
  };
114474
115193
  const outputFromNodes = run2.rootNodes ? findFinalOutput(run2.rootNodes) : void 0;
114475
115194
  const finalOutput = outputFromNodes || run2.finalOutput;
@@ -141290,6 +142009,57 @@ ${code2}
141290
142009
  };
141291
142010
  });
141292
142011
  }
142012
+ function getVariableContextAtPosition(editor, pos) {
142013
+ const { doc: doc2 } = editor.state;
142014
+ if (pos < 2 || pos > doc2.content.size) {
142015
+ return null;
142016
+ }
142017
+ const $pos = doc2.resolve(pos);
142018
+ const parent = $pos.parent;
142019
+ if (!parent.isTextblock) {
142020
+ return null;
142021
+ }
142022
+ const contentStart = $pos.start();
142023
+ let text = "";
142024
+ const posMap = [];
142025
+ parent.forEach((node, offset2) => {
142026
+ const nodeDocStart = contentStart + offset2;
142027
+ if (nodeDocStart >= pos) return;
142028
+ if (node.isText && node.text) {
142029
+ const charsToTake = Math.min(node.text.length, pos - nodeDocStart);
142030
+ for (let i2 = 0; i2 < charsToTake; i2++) {
142031
+ posMap.push(nodeDocStart + i2);
142032
+ text += node.text[i2];
142033
+ }
142034
+ }
142035
+ });
142036
+ const lastOpen = text.lastIndexOf("{{");
142037
+ if (lastOpen === -1) {
142038
+ return null;
142039
+ }
142040
+ const queryText = text.substring(lastOpen + 2);
142041
+ if (queryText.includes("}}")) {
142042
+ return null;
142043
+ }
142044
+ const triggerFrom = posMap[lastOpen];
142045
+ if (triggerFrom === void 0) {
142046
+ return null;
142047
+ }
142048
+ const trimmedQuery = /^\}*$/.test(queryText) ? "" : queryText;
142049
+ return { triggerFrom, query: trimmedQuery };
142050
+ }
142051
+ const TYPE_PREFIXES = ["env", "memory", "system", "content"];
142052
+ function inferVariableType(path) {
142053
+ const firstDot = path.indexOf(".");
142054
+ if (firstDot === -1) return "custom";
142055
+ const prefix2 = path.substring(0, firstDot).toLowerCase();
142056
+ return TYPE_PREFIXES.includes(prefix2) ? prefix2 : "custom";
142057
+ }
142058
+ function removeTypePrefix(path) {
142059
+ const type = inferVariableType(path);
142060
+ if (type === "custom") return path;
142061
+ return path.substring(type.length + 1);
142062
+ }
141293
142063
  const buildVariableSyntax = (variableType, path) => {
141294
142064
  if (variableType === "system" || variableType === "custom") {
141295
142065
  return `{{${path}}}`;
@@ -142008,6 +142778,27 @@ ${code2}
142008
142778
  )
142009
142779
  }
142010
142780
  );
142781
+ const AIStarIcon = ({ size = 14, className }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
142782
+ "svg",
142783
+ {
142784
+ width: size,
142785
+ height: size,
142786
+ viewBox: "0 0 14 14",
142787
+ fill: "none",
142788
+ xmlns: "http://www.w3.org/2000/svg",
142789
+ className,
142790
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
142791
+ "path",
142792
+ {
142793
+ 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",
142794
+ stroke: "currentColor",
142795
+ strokeWidth: "1.3",
142796
+ strokeLinecap: "round",
142797
+ strokeLinejoin: "round"
142798
+ }
142799
+ )
142800
+ }
142801
+ );
142011
142802
  const CATEGORY_ICON_MAP = {
142012
142803
  agents: AgentsIcon,
142013
142804
  tools: ToolsIcon,
@@ -142884,7 +143675,7 @@ ${code2}
142884
143675
  setCurrentPath(parsedQuery.path);
142885
143676
  }
142886
143677
  }, [parsedQuery.category, parsedQuery.path, activeCategory]);
142887
- React.useEffect(() => {
143678
+ React.useLayoutEffect(() => {
142888
143679
  if (!menuRef.current) return;
142889
143680
  const menuRect = menuRef.current.getBoundingClientRect();
142890
143681
  const viewportWidth = window.innerWidth;
@@ -142905,7 +143696,7 @@ ${code2}
142905
143696
  newTop = padding;
142906
143697
  }
142907
143698
  setAdjustedPosition({ top: newTop, left: newLeft });
142908
- }, [position]);
143699
+ }, [position, activeCategory, currentPath.length, query]);
142909
143700
  const categories = [
142910
143701
  { id: "env", label: "Environment Variables", icon: VariableIcon, variables: envVariables },
142911
143702
  { id: "memory", label: "Memory", icon: MemoryIcon, variables: memoryVariables },
@@ -142980,13 +143771,21 @@ ${code2}
142980
143771
  }
142981
143772
  }, [editorControlled]);
142982
143773
  React.useEffect(() => {
143774
+ const isEventInsideMenu = (event) => {
143775
+ if (!menuRef.current) return false;
143776
+ const path = typeof event.composedPath === "function" ? event.composedPath() : [];
143777
+ if (path.length > 0) {
143778
+ return path.includes(menuRef.current);
143779
+ }
143780
+ return menuRef.current.contains(event.target);
143781
+ };
142983
143782
  const handleClickOutside = (e) => {
142984
- if (menuRef.current && !menuRef.current.contains(e.target)) {
143783
+ if (!isEventInsideMenu(e)) {
142985
143784
  onClose();
142986
143785
  }
142987
143786
  };
142988
- document.addEventListener("mousedown", handleClickOutside);
142989
- return () => document.removeEventListener("mousedown", handleClickOutside);
143787
+ document.addEventListener("mousedown", handleClickOutside, true);
143788
+ return () => document.removeEventListener("mousedown", handleClickOutside, true);
142990
143789
  }, [onClose]);
142991
143790
  React.useEffect(() => {
142992
143791
  const handleKeyDown2 = (e) => {
@@ -143073,6 +143872,10 @@ ${code2}
143073
143872
  "button",
143074
143873
  {
143075
143874
  type: "button",
143875
+ onMouseDown: (e) => {
143876
+ e.preventDefault();
143877
+ e.stopPropagation();
143878
+ },
143076
143879
  onClick: handleBack,
143077
143880
  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]",
143078
143881
  "aria-label": "Go back",
@@ -143098,7 +143901,7 @@ ${code2}
143098
143901
  )
143099
143902
  ] }) }),
143100
143903
  !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:" }) }),
143101
- /* @__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) => {
143904
+ /* @__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) => {
143102
143905
  var _a;
143103
143906
  const isCategory = "variables" in item;
143104
143907
  const Icon = isCategory ? item.icon : getIconForType(item.type);
@@ -143107,7 +143910,11 @@ ${code2}
143107
143910
  "button",
143108
143911
  {
143109
143912
  type: "button",
143110
- onClick: () => handleItemClick(item),
143913
+ onMouseDown: (e) => {
143914
+ e.preventDefault();
143915
+ e.stopPropagation();
143916
+ handleItemClick(item);
143917
+ },
143111
143918
  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]"}`,
143112
143919
  onMouseEnter: () => setSelectedIndex(index),
143113
143920
  "data-test-id": `md-editor-variable-item-${isCategory ? item.id : item.id}`,
@@ -143683,7 +144490,9 @@ ${code2}
143683
144490
  theme = "light",
143684
144491
  disabled = false,
143685
144492
  containerRef,
143686
- followSelection = false
144493
+ followSelection = false,
144494
+ showDesignWithAI = false,
144495
+ onDesignWithAI
143687
144496
  }) => {
143688
144497
  const [position, setPosition] = React.useState(null);
143689
144498
  const [isAtSelection, setIsAtSelection] = React.useState(false);
@@ -144041,7 +144850,30 @@ ${code2}
144041
144850
  )
144042
144851
  ] }),
144043
144852
  /* @__PURE__ */ jsxRuntimeExports.jsx(ToolbarDivider$2, {}),
144044
- showAIButton && onAIAction && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: aiDropdownRef, className: "relative shrink-0", children: [
144853
+ showDesignWithAI && onDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs(
144854
+ "button",
144855
+ {
144856
+ type: "button",
144857
+ onClick: (e) => {
144858
+ e.preventDefault();
144859
+ e.stopPropagation();
144860
+ onDesignWithAI();
144861
+ },
144862
+ disabled,
144863
+ className: `
144864
+ flex items-center justify-center gap-1 px-3 py-1 rounded-[4px]
144865
+ text-[12px] leading-[16px] font-medium transition-colors duration-150 whitespace-nowrap
144866
+ border border-[#6A11CB] text-[#004EEB] hover:bg-[#EFF4FF]
144867
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
144868
+ `,
144869
+ "data-id": "toolbar-design-with-ai",
144870
+ children: [
144871
+ /* @__PURE__ */ jsxRuntimeExports.jsx(AIStarIcon, { size: 14, className: "text-[#155EEF]" }),
144872
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Design with AI" })
144873
+ ]
144874
+ }
144875
+ ),
144876
+ showAIButton && onAIAction && !showDesignWithAI && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: aiDropdownRef, className: "relative shrink-0", children: [
144045
144877
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
144046
144878
  "button",
144047
144879
  {
@@ -144156,7 +144988,8 @@ ${code2}
144156
144988
  "make-shorter": "Make Shorter",
144157
144989
  "make-longer": "Make Longer",
144158
144990
  "convert-to-yaml": "Convert to YAML",
144159
- "custom": "Custom Modify"
144991
+ "custom": "Custom Modify",
144992
+ "generate": "Generate"
144160
144993
  };
144161
144994
  function calculateTextSimilarity(text1, text2) {
144162
144995
  if (text1 === text2) return 1;
@@ -144190,7 +145023,7 @@ ${code2}
144190
145023
  sessionState,
144191
145024
  sessionActions
144192
145025
  }) => {
144193
- var _a, _b;
145026
+ var _a, _b, _c;
144194
145027
  const useSessionMode = !!sessionState && !!sessionActions;
144195
145028
  const [messages, setMessages] = React.useState([]);
144196
145029
  const [inputValue, setInputValue] = React.useState("");
@@ -144206,6 +145039,36 @@ ${code2}
144206
145039
  const modificationReason = useSessionMode ? sessionState.modificationReason : selectionModifiedReason;
144207
145040
  const currentGeneratedContent = useSessionMode ? (_b = sessionState.session) == null ? void 0 : _b.lastGeneratedContent : generatedContent;
144208
145041
  const displayMessages = useSessionMode ? convertSessionHistoryToMessages(sessionState) : messages;
145042
+ const [appliedFeedback, setAppliedFeedback] = React.useState(null);
145043
+ const [copiedFeedback, setCopiedFeedback] = React.useState(false);
145044
+ const [pendingApplyMode, setPendingApplyMode] = React.useState(null);
145045
+ const [autocopiedOnFail, setAutocopiedOnFail] = React.useState(false);
145046
+ const appliedTimerRef = React.useRef(null);
145047
+ const copiedTimerRef = React.useRef(null);
145048
+ const lastAssistantMsgId = React.useMemo(() => {
145049
+ const assistantMsgs = displayMessages.filter(
145050
+ (m) => m.type === "assistant" && !m.isGenerating && !m.isError
145051
+ );
145052
+ return assistantMsgs.length > 0 ? assistantMsgs[assistantMsgs.length - 1].id : null;
145053
+ }, [displayMessages]);
145054
+ const showInsertButton = isSelectionMode;
145055
+ const cursorInsertActive = useSessionMode && sessionState.cursorInsertPosition !== null;
145056
+ const replaceTooltip = isSelectionMode ? "Replace selection" : "Replace all";
145057
+ const insertTooltip = cursorInsertActive ? "Insert at cursor" : "Insert below selection";
145058
+ React.useEffect(() => {
145059
+ return () => {
145060
+ if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
145061
+ if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
145062
+ };
145063
+ }, []);
145064
+ React.useEffect(() => {
145065
+ if (isCurrentlyGenerating) {
145066
+ setAppliedFeedback(null);
145067
+ setCopiedFeedback(false);
145068
+ setPendingApplyMode(null);
145069
+ setAutocopiedOnFail(false);
145070
+ }
145071
+ }, [isCurrentlyGenerating]);
144209
145072
  React.useEffect(() => {
144210
145073
  var _a2;
144211
145074
  (_a2 = messagesEndRef.current) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth" });
@@ -144309,8 +145172,9 @@ ${code2}
144309
145172
  setGeneratedContent(response.refinedText);
144310
145173
  onContentGenerated == null ? void 0 : onContentGenerated(true);
144311
145174
  } catch (error) {
145175
+ const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
144312
145176
  setMessages((prev) => prev.map(
144313
- (msg) => msg.id === aiMsgId ? { ...msg, content: "Failed to generate. Please try again.", isGenerating: false, isError: true } : msg
145177
+ (msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
144314
145178
  ));
144315
145179
  } finally {
144316
145180
  setIsGenerating(false);
@@ -144352,8 +145216,9 @@ ${code2}
144352
145216
  setGeneratedContent(response.refinedText);
144353
145217
  onContentGenerated == null ? void 0 : onContentGenerated(true);
144354
145218
  } catch (error) {
145219
+ const errorMsg = error instanceof Error ? error.message : "Failed to generate. Please try again.";
144355
145220
  setMessages((prev) => prev.map(
144356
- (msg) => msg.id === aiMsgId ? { ...msg, content: "Failed to generate. Please try again.", isGenerating: false, isError: true } : msg
145221
+ (msg) => msg.id === aiMsgId ? { ...msg, content: errorMsg, isGenerating: false, isError: true } : msg
144357
145222
  ));
144358
145223
  } finally {
144359
145224
  setIsGenerating(false);
@@ -144388,6 +145253,52 @@ ${code2}
144388
145253
  };
144389
145254
  }
144390
145255
  }, [useSessionMode, sessionActions, generatedContent, onReplace, isSelectionMode]);
145256
+ const handleCopy = React.useCallback(async () => {
145257
+ var _a2;
145258
+ const content = useSessionMode ? (_a2 = sessionState == null ? void 0 : sessionState.session) == null ? void 0 : _a2.lastGeneratedContent : generatedContent;
145259
+ if (content) {
145260
+ await navigator.clipboard.writeText(content);
145261
+ setCopiedFeedback(true);
145262
+ if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);
145263
+ copiedTimerRef.current = setTimeout(() => setCopiedFeedback(false), 2e3);
145264
+ }
145265
+ }, [useSessionMode, sessionState, generatedContent]);
145266
+ const handleInsertWithFeedback = React.useCallback(() => {
145267
+ setPendingApplyMode("insert");
145268
+ setAutocopiedOnFail(false);
145269
+ handleInsert();
145270
+ }, [handleInsert]);
145271
+ const handleReplaceWithFeedback = React.useCallback(() => {
145272
+ setPendingApplyMode("replace");
145273
+ setAutocopiedOnFail(false);
145274
+ handleReplace();
145275
+ }, [handleReplace]);
145276
+ React.useEffect(() => {
145277
+ var _a2;
145278
+ if (!pendingApplyMode) return;
145279
+ if (useSessionMode) {
145280
+ if (sessionState.status === "applied") {
145281
+ setAppliedFeedback(pendingApplyMode);
145282
+ setPendingApplyMode(null);
145283
+ if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
145284
+ appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
145285
+ } else if (sessionState.isOriginalModified) {
145286
+ const content = (_a2 = sessionState.session) == null ? void 0 : _a2.lastGeneratedContent;
145287
+ if (content) {
145288
+ navigator.clipboard.writeText(content).catch(() => {
145289
+ });
145290
+ setAutocopiedOnFail(true);
145291
+ }
145292
+ setAppliedFeedback(null);
145293
+ setPendingApplyMode(null);
145294
+ }
145295
+ } else {
145296
+ setAppliedFeedback(pendingApplyMode);
145297
+ setPendingApplyMode(null);
145298
+ if (appliedTimerRef.current) clearTimeout(appliedTimerRef.current);
145299
+ appliedTimerRef.current = setTimeout(() => setAppliedFeedback(null), 2500);
145300
+ }
145301
+ }, [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]);
144391
145302
  const handleStop = React.useCallback(() => {
144392
145303
  if (useSessionMode) {
144393
145304
  return;
@@ -144487,34 +145398,71 @@ ${code2}
144487
145398
  // Result - gray background bubble
144488
145399
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full", children: [
144489
145400
  /* @__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 }) }),
144490
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
144491
- /* @__PURE__ */ jsxRuntimeExports.jsx(
144492
- "button",
144493
- {
144494
- type: "button",
144495
- onClick: handleInsert,
144496
- disabled: isModified,
144497
- title: isModified ? modificationReason || "Selected text has been modified" : void 0,
144498
- className: `px-2.5 py-0.5 text-sm font-medium rounded-full border transition-colors ${isModified ? "text-[#98A2B3] bg-[#F9FAFB] border-[#EAECF0] cursor-not-allowed" : "text-[#344054] bg-white border-[#EAECF0] hover:bg-gray-50 cursor-pointer"}`,
144499
- children: "Insert"
144500
- }
144501
- ),
144502
- (onReplace || useSessionMode) && /* @__PURE__ */ jsxRuntimeExports.jsx(
144503
- "button",
144504
- {
144505
- type: "button",
144506
- onClick: handleReplace,
144507
- disabled: isModified,
144508
- title: isModified ? modificationReason || "Selected text has been modified" : void 0,
144509
- className: `px-2.5 py-0.5 text-sm font-medium rounded-full border transition-colors ${isModified ? "text-[#98A2B3] bg-[#F9FAFB] border-[#EAECF0] cursor-not-allowed" : "text-[#344054] bg-white border-[#EAECF0] hover:bg-gray-50 cursor-pointer"}`,
144510
- children: "Replace"
144511
- }
144512
- )
144513
- ] }),
144514
- isModified && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-[#F79009] mt-1.5 flex items-center gap-1", children: [
144515
- /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 4V6M6 8H6.005M10.5 6C10.5 8.48528 8.48528 10.5 6 10.5C3.51472 10.5 1.5 8.48528 1.5 6C1.5 3.51472 3.51472 1.5 6 1.5C8.48528 1.5 10.5 3.51472 10.5 6Z", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
144516
- modificationReason || "Original text was modified"
144517
- ] })
145401
+ message.id === lastAssistantMsgId && /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: appliedFeedback ? (
145402
+ /* Success feedback */
145403
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 mt-2 text-[#12B76A] animate-[fadeIn_0.2s_ease-out]", children: [
145404
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, strokeWidth: 2.5 }),
145405
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium", children: appliedFeedback === "replace" ? "Replaced" : "Inserted" }),
145406
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-[#667085] ml-1", children: [
145407
+ navigator.platform.includes("Mac") ? "⌘Z" : "Ctrl+Z",
145408
+ " to undo"
145409
+ ] })
145410
+ ] })
145411
+ ) : isModified ? (
145412
+ /* Recovery UI -- original text was modified, apply would fail */
145413
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 animate-[fadeIn_0.2s_ease-out]", children: [
145414
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
145415
+ "button",
145416
+ {
145417
+ type: "button",
145418
+ onClick: handleCopy,
145419
+ 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",
145420
+ children: copiedFeedback || autocopiedOnFail ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
145421
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 12, className: "text-[#12B76A]" }),
145422
+ " Copied"
145423
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
145424
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 12 }),
145425
+ " Copy content"
145426
+ ] })
145427
+ }
145428
+ ) }),
145429
+ /* @__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.` })
145430
+ ] })
145431
+ ) : (
145432
+ /* Normal action buttons */
145433
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
145434
+ (onReplace || useSessionMode) && /* @__PURE__ */ jsxRuntimeExports.jsx(
145435
+ "button",
145436
+ {
145437
+ type: "button",
145438
+ onClick: handleReplaceWithFeedback,
145439
+ title: replaceTooltip,
145440
+ 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",
145441
+ children: "Replace"
145442
+ }
145443
+ ),
145444
+ showInsertButton && /* @__PURE__ */ jsxRuntimeExports.jsx(
145445
+ "button",
145446
+ {
145447
+ type: "button",
145448
+ onClick: handleInsertWithFeedback,
145449
+ title: insertTooltip,
145450
+ 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",
145451
+ children: "Insert"
145452
+ }
145453
+ ),
145454
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
145455
+ "button",
145456
+ {
145457
+ type: "button",
145458
+ onClick: handleCopy,
145459
+ title: copiedFeedback ? "Copied!" : "Copy to clipboard",
145460
+ className: "p-1 text-[#667085] hover:text-[#344054] hover:bg-gray-100 rounded transition-colors cursor-pointer",
145461
+ children: copiedFeedback ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { size: 14, className: "text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { size: 14 })
145462
+ }
145463
+ )
145464
+ ] })
145465
+ ) })
144518
145466
  ] })
144519
145467
  ) })
144520
145468
  ) }, message.id)),
@@ -144597,6 +145545,32 @@ ${code2}
144597
145545
  }
144598
145546
  return messages;
144599
145547
  }
145548
+ const EmptyStatePlaceholder = ({
145549
+ placeholder = "Write your agent definition here or type '/' to insert variables, agents, tools, memory & more",
145550
+ example,
145551
+ isFocused = false
145552
+ }) => {
145553
+ if (isFocused) return null;
145554
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
145555
+ "div",
145556
+ {
145557
+ className: "absolute inset-0 pointer-events-none px-[32px] py-[24px] overflow-hidden",
145558
+ "data-id": "md-editor-empty-state",
145559
+ children: [
145560
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3] mb-[8px]", children: placeholder }),
145561
+ example && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] text-[#98A2B3]", children: example })
145562
+ ]
145563
+ }
145564
+ );
145565
+ };
145566
+ const AgentDefinitionExample = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
145567
+ /* @__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." }),
145568
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-disc ml-[21px]", children: [
145569
+ /* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Match prospect needs with sales expertise" }) }),
145570
+ /* @__PURE__ */ jsxRuntimeExports.jsx("li", { className: "mb-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Find optimal meeting times across calendars" }) }),
145571
+ /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "leading-[20px]", children: "Distribute meeting agenda and materials" }) })
145572
+ ] })
145573
+ ] });
144600
145574
  function hashString(str) {
144601
145575
  let hash2 = 5381;
144602
145576
  for (let i2 = 0; i2 < str.length; i2++) {
@@ -144806,7 +145780,8 @@ ${code2}
144806
145780
  modificationReason: "",
144807
145781
  pendingSelection: null,
144808
145782
  showSwitchBanner: false,
144809
- error: null
145783
+ error: null,
145784
+ cursorInsertPosition: null
144810
145785
  };
144811
145786
  function refinementReducer(state, action) {
144812
145787
  switch (action.type) {
@@ -144917,7 +145892,7 @@ ${code2}
144917
145892
  }
144918
145893
  case "APPLY_CONTENT": {
144919
145894
  if (!state.session) return state;
144920
- const { appliedContent } = action.payload;
145895
+ const { appliedContent, newFingerprint } = action.payload;
144921
145896
  return {
144922
145897
  ...state,
144923
145898
  status: "applied",
@@ -144925,8 +145900,11 @@ ${code2}
144925
145900
  ...state.session,
144926
145901
  appliedContent,
144927
145902
  applyCount: state.session.applyCount + 1,
144928
- workingContent: appliedContent
145903
+ workingContent: appliedContent,
144929
145904
  // For subsequent refinements
145905
+ // Update fingerprint to track the newly applied content's position
145906
+ // This enables subsequent iterations to work on the replaced content
145907
+ fingerprint: newFingerprint || state.session.fingerprint
144930
145908
  },
144931
145909
  isOriginalModified: false,
144932
145910
  modificationReason: ""
@@ -144934,9 +145912,9 @@ ${code2}
144934
145912
  }
144935
145913
  case "SELECTION_CHANGED": {
144936
145914
  if (!state.session) return state;
144937
- const { fingerprint } = action.payload;
144938
- const isFullDocument = fingerprint.contextBefore === "" && fingerprint.contextAfter === "";
144939
- const newMode = isFullDocument ? "full-document" : "selection";
145915
+ const { fingerprint, explicitMode } = action.payload;
145916
+ const inferredMode = fingerprint.contextBefore === "" && fingerprint.contextAfter === "" ? "full-document" : "selection";
145917
+ const newMode = explicitMode ?? inferredMode;
144940
145918
  return {
144941
145919
  ...state,
144942
145920
  session: {
@@ -144944,8 +145922,10 @@ ${code2}
144944
145922
  mode: newMode,
144945
145923
  fingerprint,
144946
145924
  workingContent: fingerprint.selectedMarkdown,
144947
- // Reset applied content since selection changed
144948
- appliedContent: null
145925
+ // Reset apply state since selection changed -- previous apply context is irrelevant
145926
+ appliedContent: null,
145927
+ applyCount: 0,
145928
+ lastGeneratedContent: null
144949
145929
  },
144950
145930
  // Clear modification state since we have a fresh selection
144951
145931
  isOriginalModified: false,
@@ -144953,7 +145933,8 @@ ${code2}
144953
145933
  // Only show switch banner if there was content and this is user-initiated selection change
144954
145934
  // For now, keep it simple - don't show banner, just update context
144955
145935
  pendingSelection: null,
144956
- showSwitchBanner: false
145936
+ showSwitchBanner: false,
145937
+ cursorInsertPosition: null
144957
145938
  };
144958
145939
  }
144959
145940
  case "CONFIRM_SWITCH": {
@@ -145022,6 +146003,11 @@ ${code2}
145022
146003
  }
145023
146004
  };
145024
146005
  }
146006
+ case "SET_CURSOR_INSERT_POSITION":
146007
+ return {
146008
+ ...state,
146009
+ cursorInsertPosition: action.payload.position
146010
+ };
145025
146011
  default:
145026
146012
  return state;
145027
146013
  }
@@ -145031,7 +146017,8 @@ ${code2}
145031
146017
  onRefine,
145032
146018
  editorContent,
145033
146019
  promptType,
145034
- agentContext
146020
+ agentContext,
146021
+ onContentApplied
145035
146022
  }) {
145036
146023
  const [state, dispatch] = React.useReducer(refinementReducer, initialState);
145037
146024
  const hasGeneratedContentRef = React.useRef(false);
@@ -145050,14 +146037,18 @@ ${code2}
145050
146037
  });
145051
146038
  if (editor) {
145052
146039
  let fingerprint;
145053
- if (range2 && range2.from !== range2.to) {
146040
+ const isSelection = !!range2 && range2.from !== range2.to;
146041
+ if (isSelection) {
145054
146042
  fingerprint = createSelectionFingerprint(editor, range2.from, range2.to);
145055
146043
  } else {
145056
146044
  fingerprint = createFullDocumentFingerprint(editor);
145057
146045
  }
145058
146046
  dispatch({
145059
146047
  type: "SELECTION_CHANGED",
145060
- payload: { fingerprint }
146048
+ payload: {
146049
+ fingerprint,
146050
+ explicitMode: isSelection ? "selection" : "full-document"
146051
+ }
145061
146052
  });
145062
146053
  }
145063
146054
  }, [editor]);
@@ -145067,13 +146058,24 @@ ${code2}
145067
146058
  }, []);
145068
146059
  const startGeneration = React.useCallback(async (action, instruction) => {
145069
146060
  if (!onRefine || !state.session) return;
145070
- const contextText = state.session.applyCount > 0 ? state.session.appliedContent || state.session.workingContent : state.session.lastGeneratedContent || state.session.workingContent;
146061
+ let contextText;
146062
+ if (state.session.mode === "full-document" && state.session.applyCount > 0) {
146063
+ contextText = editorContent || state.session.appliedContent || state.session.workingContent;
146064
+ } else if (state.session.applyCount > 0) {
146065
+ contextText = state.session.appliedContent || state.session.workingContent;
146066
+ } else {
146067
+ contextText = state.session.lastGeneratedContent || state.session.workingContent;
146068
+ }
146069
+ if (!contextText) {
146070
+ contextText = editorContent;
146071
+ }
145071
146072
  const actionLabels = {
145072
146073
  "improve": "Improve",
145073
146074
  "make-shorter": "Make Shorter",
145074
146075
  "make-longer": "Make Longer",
145075
146076
  "convert-to-yaml": "Convert to YAML",
145076
- "custom": instruction || "Custom"
146077
+ "custom": instruction || "Custom",
146078
+ "generate": "Generate new content"
145077
146079
  };
145078
146080
  const displayMessage = instruction || actionLabels[action] || action;
145079
146081
  const isFirstMessage = state.session.conversationHistory.length === 0;
@@ -145133,7 +146135,7 @@ ${code2}
145133
146135
  "custom": instruction || "Custom"
145134
146136
  };
145135
146137
  const displayMessage = instruction || actionLabels[action] || action;
145136
- const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent;
146138
+ const contentForAI = ((_a = state.session.fingerprint) == null ? void 0 : _a.selectedMarkdown) || state.session.workingContent || editorContent;
145137
146139
  const quotedText = contentForAI.length > 100 ? `${contentForAI.substring(0, 100)}...` : contentForAI;
145138
146140
  dispatch({
145139
146141
  type: "START_GENERATION",
@@ -145177,11 +146179,13 @@ ${code2}
145177
146179
  if (!editor || !state.session || !state.session.lastGeneratedContent) return;
145178
146180
  const refinedText = state.session.lastGeneratedContent;
145179
146181
  let result;
146182
+ let newFingerprint;
145180
146183
  if (state.session.mode === "full-document") {
145181
146184
  try {
145182
146185
  const parsed = markdownToEditorJson(refinedText);
145183
146186
  editor.commands.setContent(parsed);
145184
146187
  result = { success: true };
146188
+ newFingerprint = createFullDocumentFingerprint(editor);
145185
146189
  } catch (error) {
145186
146190
  result = {
145187
146191
  success: false,
@@ -145201,10 +146205,17 @@ ${code2}
145201
146205
  } else {
145202
146206
  try {
145203
146207
  const parsedContent = markdownToEditorJson(refinedText);
146208
+ const insertionStart = matchedRange.from;
145204
146209
  if (mode === "replace") {
145205
146210
  editor.chain().focus().setTextSelection(matchedRange).deleteSelection().insertContent(parsedContent).run();
146211
+ const newEndPos = editor.state.selection.to;
146212
+ newFingerprint = createSelectionFingerprint(editor, insertionStart, newEndPos);
145206
146213
  } else {
145207
- editor.chain().focus().setTextSelection({ from: matchedRange.to, to: matchedRange.to }).insertContent("\n\n").insertContent(parsedContent).run();
146214
+ const useCursorPos = state.cursorInsertPosition !== null && state.cursorInsertPosition !== matchedRange.to;
146215
+ const insertPos = useCursorPos ? state.cursorInsertPosition : matchedRange.to;
146216
+ editor.chain().focus().setTextSelection({ from: insertPos, to: insertPos }).insertContent("\n\n").insertContent(parsedContent).run();
146217
+ const newEndPos = editor.state.selection.to;
146218
+ newFingerprint = createSelectionFingerprint(editor, insertPos + 2, newEndPos);
145208
146219
  }
145209
146220
  result = { success: true };
145210
146221
  } catch (error) {
@@ -145219,8 +146230,12 @@ ${code2}
145219
146230
  if (result.success) {
145220
146231
  dispatch({
145221
146232
  type: "APPLY_CONTENT",
145222
- payload: { mode, appliedContent: refinedText }
146233
+ payload: { mode, appliedContent: refinedText, newFingerprint }
145223
146234
  });
146235
+ if (onContentApplied && editor) {
146236
+ const fullMarkdown = state.session.mode === "full-document" ? refinedText : editorJsonToMarkdown(editor.getJSON());
146237
+ onContentApplied(fullMarkdown);
146238
+ }
145224
146239
  } else {
145225
146240
  dispatch({
145226
146241
  type: "SET_MODIFIED",
@@ -145230,7 +146245,7 @@ ${code2}
145230
146245
  }
145231
146246
  });
145232
146247
  }
145233
- }, [editor, state.session]);
146248
+ }, [editor, state.session, state.cursorInsertPosition, onContentApplied]);
145234
146249
  const handleSelectionChange = React.useCallback((from, to, _text) => {
145235
146250
  if (!editor || !state.session) return;
145236
146251
  if (from === to) return;
@@ -145242,7 +146257,7 @@ ${code2}
145242
146257
  }
145243
146258
  dispatch({
145244
146259
  type: "SELECTION_CHANGED",
145245
- payload: { fingerprint: newFingerprint }
146260
+ payload: { fingerprint: newFingerprint, explicitMode: "selection" }
145246
146261
  });
145247
146262
  }, [editor, state.session]);
145248
146263
  const confirmSwitch = React.useCallback(() => {
@@ -145281,19 +146296,31 @@ ${code2}
145281
146296
  React.useEffect(() => {
145282
146297
  if (!editor || state.status === "idle") return;
145283
146298
  const handleSelectionUpdate = () => {
146299
+ var _a, _b;
145284
146300
  const { from, to } = editor.state.selection;
145285
146301
  const hasSelection2 = from !== to;
145286
- if (!hasSelection2 || !hasGeneratedContentRef.current) {
145287
- return;
146302
+ if (hasSelection2) {
146303
+ if (hasGeneratedContentRef.current) {
146304
+ const selectedText = editor.state.doc.textBetween(from, to, " ", "\n");
146305
+ handleSelectionChange(from, to, selectedText);
146306
+ }
146307
+ if (state.cursorInsertPosition !== null) {
146308
+ dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: null } });
146309
+ }
146310
+ } else if (((_a = state.session) == null ? void 0 : _a.mode) === "selection" && ((_b = state.session) == null ? void 0 : _b.fingerprint) && hasGeneratedContentRef.current) {
146311
+ const fp = state.session.fingerprint;
146312
+ const isOutside = from < fp.originalRange.from || from > fp.originalRange.to;
146313
+ const newPos = isOutside ? from : null;
146314
+ if (newPos !== state.cursorInsertPosition) {
146315
+ dispatch({ type: "SET_CURSOR_INSERT_POSITION", payload: { position: newPos } });
146316
+ }
145288
146317
  }
145289
- const selectedText = editor.state.doc.textBetween(from, to, " ", "\n");
145290
- handleSelectionChange(from, to, selectedText);
145291
146318
  };
145292
146319
  editor.on("selectionUpdate", handleSelectionUpdate);
145293
146320
  return () => {
145294
146321
  editor.off("selectionUpdate", handleSelectionUpdate);
145295
146322
  };
145296
- }, [editor, state.status, handleSelectionChange]);
146323
+ }, [editor, state.status, state.session, state.cursorInsertPosition, handleSelectionChange]);
145297
146324
  const actions = {
145298
146325
  openPanel,
145299
146326
  closePanel,
@@ -145360,7 +146387,12 @@ ${code2}
145360
146387
  onFocus,
145361
146388
  onBlur,
145362
146389
  onLoadSuggestions,
145363
- suggestionsLoading: propSuggestionsLoading = false
146390
+ suggestionsLoading: propSuggestionsLoading = false,
146391
+ // Empty state props
146392
+ emptyStatePlaceholder,
146393
+ emptyStateExample,
146394
+ showDesignWithAI = false,
146395
+ onDesignWithAI
145364
146396
  } = props;
145365
146397
  const mergedSlashConfig = { ...DEFAULT_SLASH_COMMAND_CONFIG, ...slashCommandConfig };
145366
146398
  const mergedAIConfig = { ...DEFAULT_AI_CONFIG, ...aiConfig };
@@ -145368,13 +146400,16 @@ ${code2}
145368
146400
  const lastEmittedMarkdownRef = React.useRef("");
145369
146401
  const isInternalUpdateRef = React.useRef(false);
145370
146402
  const editorContainerRef = React.useRef(null);
146403
+ const skipRawSyncRef = React.useRef(false);
146404
+ const skipEditorSyncRef = React.useRef(false);
145371
146405
  const [asyncSuggestions, setAsyncSuggestions] = React.useState(null);
145372
146406
  const [suggestionsLoading, setSuggestionsLoading] = React.useState(false);
145373
146407
  const [variableMenuOpen, setVariableMenuOpen] = React.useState(false);
145374
146408
  const [variableMenuPosition, setVariableMenuPosition] = React.useState({ top: 0, left: 0 });
145375
146409
  const [variableMenuQuery, setVariableMenuQuery] = React.useState("");
145376
- const [editingVariableChip, setEditingVariableChip] = React.useState(null);
145377
146410
  const variableTriggerPosRef = React.useRef(null);
146411
+ const hasVariableSuggestionsRef = React.useRef(false);
146412
+ const variableMenuOpenRef = React.useRef(false);
145378
146413
  const [editorMode, setEditorMode] = React.useState("editor");
145379
146414
  const [rawMarkdown, setRawMarkdown] = React.useState("");
145380
146415
  const isRawMode = editorMode === "preview";
@@ -145418,12 +146453,7 @@ ${code2}
145418
146453
  contentVariables: mergedContentVariables,
145419
146454
  loading: finalSuggestionsLoading
145420
146455
  };
145421
- console.log("MDEditor render: suggestionsRef updated with:", {
145422
- agentsCount: mergedAgents.length,
145423
- toolsCount: mergedTools.length,
145424
- knowledgeCount: mergedKnowledge.length,
145425
- hasAsyncSuggestions: !!asyncSuggestions
145426
- });
146456
+ hasVariableSuggestionsRef.current = mergedEnvVariables.length > 0 || mergedMemoryVariables.length > 0 || mergedSystemVariables.length > 0 || mergedContentVariables.length > 0;
145427
146457
  const defaultCategories = React.useMemo(() => {
145428
146458
  const categories = [];
145429
146459
  if (mergedAgents.length > 0) {
@@ -145488,21 +146518,6 @@ ${code2}
145488
146518
  (variable, triggerPos) => {
145489
146519
  if (!editorRef.current) return;
145490
146520
  const editor2 = editorRef.current;
145491
- if (editingVariableChip) {
145492
- const { position, nodeSize: nodeSize2 } = editingVariableChip;
145493
- editor2.chain().focus().deleteRange({ from: position, to: position + nodeSize2 }).insertContentAt(position, {
145494
- type: "variableChip",
145495
- attrs: {
145496
- variableType: variable.type,
145497
- path: variable.path,
145498
- displayName: variable.name
145499
- }
145500
- }).run();
145501
- setEditingVariableChip(null);
145502
- setVariableMenuOpen(false);
145503
- setVariableMenuQuery("");
145504
- return;
145505
- }
145506
146521
  const deleteFrom = triggerPos ?? variableTriggerPosRef.current;
145507
146522
  if (deleteFrom !== null) {
145508
146523
  const { from } = editor2.state.selection;
@@ -145515,6 +146530,10 @@ ${code2}
145515
146530
  displayName: variable.name
145516
146531
  }
145517
146532
  }).insertContent(" ").run();
146533
+ const posAfter = editor2.state.selection.from;
146534
+ if (posAfter + 2 <= editor2.state.doc.content.size && editor2.state.doc.textBetween(posAfter, posAfter + 2) === "}}") {
146535
+ editor2.chain().focus().deleteRange({ from: posAfter, to: posAfter + 2 }).run();
146536
+ }
145518
146537
  } else {
145519
146538
  editor2.chain().focus().insertContent({
145520
146539
  type: "variableChip",
@@ -145529,7 +146548,19 @@ ${code2}
145529
146548
  setVariableMenuQuery("");
145530
146549
  variableTriggerPosRef.current = null;
145531
146550
  },
145532
- [editingVariableChip]
146551
+ []
146552
+ );
146553
+ const handleVariableQueryChange = React.useCallback(
146554
+ (newQuery) => {
146555
+ setVariableMenuQuery(newQuery);
146556
+ if (!editorRef.current || variableTriggerPosRef.current === null) return;
146557
+ const editor2 = editorRef.current;
146558
+ const triggerPos = variableTriggerPosRef.current;
146559
+ const insertFrom = triggerPos + 2;
146560
+ const { from } = editor2.state.selection;
146561
+ editor2.chain().focus().deleteRange({ from: insertFrom, to: from }).insertContentAt(insertFrom, newQuery).run();
146562
+ },
146563
+ []
145533
146564
  );
145534
146565
  const insertMention = React.useCallback(
145535
146566
  (mention) => {
@@ -145564,14 +146595,23 @@ ${code2}
145564
146595
  const json = editorRef.current.getJSON();
145565
146596
  const markdown = editorJsonToMarkdown(json);
145566
146597
  setRawMarkdown(markdown);
146598
+ lastEmittedMarkdownRef.current = markdown;
146599
+ skipRawSyncRef.current = true;
145567
146600
  }
145568
146601
  if (currentMode === "preview" && newMode === "editor") {
145569
146602
  const parsedContent = markdownToEditorJson(rawMarkdown);
146603
+ isInternalUpdateRef.current = true;
145570
146604
  editorRef.current.commands.setContent(parsedContent);
145571
146605
  lastEmittedMarkdownRef.current = rawMarkdown;
146606
+ skipEditorSyncRef.current = true;
146607
+ onMarkdownChange == null ? void 0 : onMarkdownChange(rawMarkdown);
146608
+ if (onChange) {
146609
+ const doc2 = editorJsonToDocument(parsedContent);
146610
+ onChange(doc2, rawMarkdown);
146611
+ }
145572
146612
  }
145573
146613
  setEditorMode(newMode);
145574
- }, [editorMode, rawMarkdown]);
146614
+ }, [editorMode, rawMarkdown, onChange, onMarkdownChange]);
145575
146615
  const toggleRawMode = React.useCallback(() => {
145576
146616
  handleModeChange(isRawMode ? "editor" : "preview");
145577
146617
  }, [handleModeChange, isRawMode]);
@@ -145586,13 +146626,17 @@ ${code2}
145586
146626
  dropcursor: false
145587
146627
  }),
145588
146628
  Placeholder.configure({
145589
- placeholder: ({ node }) => {
146629
+ placeholder: ({ node, editor: placeholderEditor }) => {
146630
+ if (emptyStatePlaceholder && placeholderEditor.isEmpty) {
146631
+ return "";
146632
+ }
145590
146633
  if (node.type.name === "heading") {
145591
146634
  const level = node.attrs["level"];
145592
146635
  return `Heading ${level}`;
145593
146636
  }
145594
146637
  if (node.type.name === "paragraph") {
145595
- return placeholder;
146638
+ const focusPlaceholder = "Type here or '/' to insert variables, agents, tools, memory & more";
146639
+ return placeholderEditor.isEmpty ? placeholder : focusPlaceholder;
145596
146640
  }
145597
146641
  return "";
145598
146642
  },
@@ -145662,7 +146706,7 @@ ${code2}
145662
146706
  );
145663
146707
  }
145664
146708
  return exts;
145665
- }, [mergedFeatures, placeholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
146709
+ }, [mergedFeatures, placeholder, emptyStatePlaceholder, defaultCategories, handleSlashCommandSelect, mergedSlashConfig.highlightMentions]);
145666
146710
  const editorRef = React.useRef(null);
145667
146711
  const editor = useEditor({
145668
146712
  extensions,
@@ -145696,12 +146740,24 @@ ${code2}
145696
146740
  editorRef.current = editor;
145697
146741
  }, [editor]);
145698
146742
  const editorContent = editor ? editorJsonToMarkdown(editor.getJSON()) : "";
146743
+ const handleAIContentApplied = React.useCallback((markdown) => {
146744
+ lastEmittedMarkdownRef.current = markdown;
146745
+ if (onMarkdownChange) {
146746
+ onMarkdownChange(markdown);
146747
+ }
146748
+ if (onChange) {
146749
+ const json = markdownToEditorJson(markdown);
146750
+ const doc2 = editorJsonToDocument(json);
146751
+ onChange(doc2, markdown);
146752
+ }
146753
+ }, [onMarkdownChange, onChange]);
145699
146754
  const { state: aiSessionState, actions: aiSessionActions, isOpen: aiPanelOpen } = useAIRefinementSession({
145700
146755
  editor,
145701
146756
  onRefine: onAIRefine,
145702
146757
  editorContent,
145703
146758
  promptType: props.promptType,
145704
- agentContext: props.agentContext
146759
+ agentContext: props.agentContext,
146760
+ onContentApplied: handleAIContentApplied
145705
146761
  });
145706
146762
  const openAIRefine = React.useCallback(
145707
146763
  (_type = "selection") => {
@@ -145728,6 +146784,22 @@ ${code2}
145728
146784
  // autoGenerate
145729
146785
  );
145730
146786
  }, [aiSessionActions]);
146787
+ const handleDesignWithAI = React.useCallback(() => {
146788
+ aiSessionActions.openPanel(
146789
+ "generate",
146790
+ "",
146791
+ // Empty text since we're generating from scratch
146792
+ void 0,
146793
+ // No selection range
146794
+ void 0,
146795
+ // No custom prompt - AI will use context
146796
+ true
146797
+ // autoGenerate - start generation immediately
146798
+ );
146799
+ if (onDesignWithAI) {
146800
+ onDesignWithAI();
146801
+ }
146802
+ }, [aiSessionActions, onDesignWithAI]);
145731
146803
  const handleCloseAIPanel = React.useCallback(() => {
145732
146804
  if (editorRef.current) {
145733
146805
  editorRef.current.setEditable(!readOnly);
@@ -145762,11 +146834,27 @@ ${code2}
145762
146834
  from
145763
146835
  );
145764
146836
  if (textAfterTrigger.includes("}}")) {
146837
+ const pathRaw = textAfterTrigger.split("}}")[0].trim();
146838
+ if (pathRaw) {
146839
+ const varType = inferVariableType(pathRaw);
146840
+ const cleanPath = removeTypePrefix(pathRaw);
146841
+ const displayName = cleanPath.split(".").pop() || cleanPath;
146842
+ editor.chain().focus().deleteRange({ from: triggerPos, to: from }).insertContent({
146843
+ type: "variableChip",
146844
+ attrs: {
146845
+ variableType: varType,
146846
+ path: cleanPath,
146847
+ displayName
146848
+ }
146849
+ }).insertContent(" ").run();
146850
+ }
145765
146851
  setVariableMenuOpen(false);
145766
146852
  variableTriggerPosRef.current = null;
145767
146853
  return;
145768
146854
  }
145769
146855
  setVariableMenuQuery(textAfterTrigger);
146856
+ const coords = editor.view.coordsAtPos(from);
146857
+ setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
145770
146858
  };
145771
146859
  const editorElement = editor.view.dom;
145772
146860
  editorElement.addEventListener("keydown", handleKeyDown2);
@@ -145776,12 +146864,36 @@ ${code2}
145776
146864
  editorElement.removeEventListener("input", handleInput);
145777
146865
  };
145778
146866
  }, [editor, mergedFeatures.variableChips, variableMenuOpen]);
146867
+ React.useEffect(() => {
146868
+ variableMenuOpenRef.current = variableMenuOpen;
146869
+ }, [variableMenuOpen]);
146870
+ React.useEffect(() => {
146871
+ if (!editor || !mergedFeatures.variableChips) return;
146872
+ const detectVariableContext = () => {
146873
+ if (variableMenuOpenRef.current) return;
146874
+ if (!hasVariableSuggestionsRef.current) return;
146875
+ const { from } = editor.state.selection;
146876
+ const context = getVariableContextAtPosition(editor, from);
146877
+ if (context) {
146878
+ variableTriggerPosRef.current = context.triggerFrom;
146879
+ setVariableMenuQuery(context.query);
146880
+ const coords = editor.view.coordsAtPos(from);
146881
+ setVariableMenuPosition({ top: coords.bottom + 8, left: coords.left });
146882
+ setVariableMenuOpen(true);
146883
+ }
146884
+ };
146885
+ editor.on("focus", detectVariableContext);
146886
+ editor.on("selectionUpdate", detectVariableContext);
146887
+ return () => {
146888
+ editor.off("focus", detectVariableContext);
146889
+ editor.off("selectionUpdate", detectVariableContext);
146890
+ };
146891
+ }, [editor, mergedFeatures.variableChips]);
145779
146892
  React.useEffect(() => {
145780
146893
  if (!variableMenuOpen) return;
145781
146894
  const handleKeyDown2 = (event) => {
145782
146895
  if (event.key === "Escape") {
145783
146896
  setVariableMenuOpen(false);
145784
- setEditingVariableChip(null);
145785
146897
  variableTriggerPosRef.current = null;
145786
146898
  editor == null ? void 0 : editor.chain().focus().run();
145787
146899
  }
@@ -145794,19 +146906,11 @@ ${code2}
145794
146906
  const handleVariableChipEdit = (event) => {
145795
146907
  const customEvent = event;
145796
146908
  const { variableType, path, position, nodeSize: nodeSize2 } = customEvent.detail;
145797
- const coords = editor.view.coordsAtPos(position);
145798
- setEditingVariableChip({
145799
- position,
145800
- nodeSize: nodeSize2,
145801
- variableType,
145802
- path
145803
- });
145804
- setVariableMenuPosition({
145805
- top: coords.bottom + 8,
145806
- left: coords.left
145807
- });
145808
- setVariableMenuQuery("");
145809
- setVariableMenuOpen(true);
146909
+ const innerPath = variableType === "system" || variableType === "custom" ? path : `${variableType}.${path}`;
146910
+ const fullText = `{{${innerPath}}}`;
146911
+ editor.chain().focus().deleteRange({ from: position, to: position + nodeSize2 }).insertContentAt(position, fullText).run();
146912
+ const cursorPos = position + 2 + innerPath.length;
146913
+ editor.chain().focus().setTextSelection(cursorPos).run();
145810
146914
  };
145811
146915
  const editorElement = editor.view.dom;
145812
146916
  editorElement.addEventListener("variable-chip-edit", handleVariableChipEdit);
@@ -145815,6 +146919,10 @@ ${code2}
145815
146919
  };
145816
146920
  }, [editor]);
145817
146921
  React.useEffect(() => {
146922
+ if (skipEditorSyncRef.current) {
146923
+ skipEditorSyncRef.current = false;
146924
+ return;
146925
+ }
145818
146926
  if (!editor || isInternalUpdateRef.current) {
145819
146927
  isInternalUpdateRef.current = false;
145820
146928
  return;
@@ -145846,6 +146954,10 @@ ${code2}
145846
146954
  return () => clearTimeout(timer);
145847
146955
  }, [rawMarkdown, isRawMode, onMarkdownChange, onChange]);
145848
146956
  React.useEffect(() => {
146957
+ if (skipRawSyncRef.current) {
146958
+ skipRawSyncRef.current = false;
146959
+ return;
146960
+ }
145849
146961
  if (isRawMode && markdownValue !== void 0 && markdownValue !== lastEmittedMarkdownRef.current) {
145850
146962
  setRawMarkdown(markdownValue);
145851
146963
  }
@@ -145986,6 +147098,13 @@ ${code2}
145986
147098
  editor,
145987
147099
  className: "k-md-editor__content w-full h-full"
145988
147100
  }
147101
+ ),
147102
+ (editor == null ? void 0 : editor.isEmpty) && emptyStatePlaceholder && /* @__PURE__ */ jsxRuntimeExports.jsx(
147103
+ EmptyStatePlaceholder,
147104
+ {
147105
+ placeholder: emptyStatePlaceholder,
147106
+ example: emptyStateExample
147107
+ }
145989
147108
  )
145990
147109
  ] })
145991
147110
  ) }),
@@ -145994,20 +147113,18 @@ ${code2}
145994
147113
  {
145995
147114
  position: variableMenuPosition,
145996
147115
  query: variableMenuQuery,
145997
- onQueryChange: setVariableMenuQuery,
147116
+ onQueryChange: handleVariableQueryChange,
145998
147117
  onSelect: (variable) => insertVariable(variable),
145999
147118
  onClose: () => {
146000
147119
  setVariableMenuOpen(false);
146001
147120
  setVariableMenuQuery("");
146002
- setEditingVariableChip(null);
146003
147121
  variableTriggerPosRef.current = null;
146004
147122
  },
146005
147123
  envVariables: mergedEnvVariables,
146006
147124
  memoryVariables: mergedMemoryVariables,
146007
147125
  systemVariables: mergedSystemVariables,
146008
147126
  contentVariables: mergedContentVariables,
146009
- editorControlled: !editingVariableChip,
146010
- isEditMode: !!editingVariableChip
147127
+ editorControlled: true
146011
147128
  }
146012
147129
  )
146013
147130
  ] }),
@@ -146021,7 +147138,9 @@ ${code2}
146021
147138
  onAIAction: isAIEnabled ? handleAIToolbarAction : void 0,
146022
147139
  theme: theme === "dark" || theme.includes("dark") ? "dark" : "light",
146023
147140
  disabled: readOnly,
146024
- containerRef: editorContainerRef
147141
+ containerRef: editorContainerRef,
147142
+ showDesignWithAI: showDesignWithAI && (editor == null ? void 0 : editor.isEmpty),
147143
+ onDesignWithAI: isAIEnabled ? handleDesignWithAI : onDesignWithAI
146025
147144
  }
146026
147145
  )
146027
147146
  ] }),
@@ -149563,6 +150682,7 @@ export class AnalyticsDashboardComponent implements OnInit, AfterViewInit, OnDes
149563
150682
  exports2.AIRefineDropdown = AIRefineDropdown;
149564
150683
  exports2.AIRefineExtension = AIRefineExtension;
149565
150684
  exports2.AIRefinePanel = AIRefinePanel;
150685
+ exports2.AgentDefinitionExample = AgentDefinitionExample;
149566
150686
  exports2.AgentListView = AgentListView;
149567
150687
  exports2.AnalyticsChart = AnalyticsChart;
149568
150688
  exports2.AnalyticsTable = AnalyticsTable;
@@ -149588,6 +150708,7 @@ export class AnalyticsDashboardComponent implements OnInit, AfterViewInit, OnDes
149588
150708
  exports2.DetailPage = DetailPage;
149589
150709
  exports2.DetailPageService = DetailPageService;
149590
150710
  exports2.EmptyState = EmptyState;
150711
+ exports2.EmptyStatePlaceholder = EmptyStatePlaceholder;
149591
150712
  exports2.EndpointsConfigService = EndpointsConfigService;
149592
150713
  exports2.EnvironmentContext = EnvironmentContext;
149593
150714
  exports2.EnvironmentProvider = EnvironmentProvider;