agentic-ui-libs 1.2.0-beta.18 → 1.2.0-beta.19

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 (30) hide show
  1. package/dist/assets/agentic-ui-libs.css +89 -0
  2. package/dist/features/tracing/components/SessionsList.d.ts.map +1 -1
  3. package/dist/features/tracing/components/TracesList.d.ts.map +1 -1
  4. package/dist/features/tracing/components/detail/DetailPage.d.ts +1 -1
  5. package/dist/features/tracing/components/detail/DetailPage.d.ts.map +1 -1
  6. package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts +58 -0
  7. package/dist/features/tracing/components/detail/EventLogsSlideout.d.ts.map +1 -0
  8. package/dist/features/tracing/components/detail/NodeDetailPanel.d.ts.map +1 -1
  9. package/dist/features/tracing/components/detail/TraceTree.d.ts +1 -1
  10. package/dist/features/tracing/components/detail/TraceTree.d.ts.map +1 -1
  11. package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts +11 -0
  12. package/dist/features/tracing/components/detail/VoiceEventLogsBanner.d.ts.map +1 -0
  13. package/dist/features/tracing/components/detail/index.d.ts +2 -0
  14. package/dist/features/tracing/components/detail/index.d.ts.map +1 -1
  15. package/dist/features/tracing/components/detail/services/DetailPageService.d.ts +1 -0
  16. package/dist/features/tracing/components/detail/services/DetailPageService.d.ts.map +1 -1
  17. package/dist/features/tracing/components/detail/types.d.ts +15 -0
  18. package/dist/features/tracing/components/detail/types.d.ts.map +1 -1
  19. package/dist/features/tracing/components/shared/CopyableId.d.ts +11 -0
  20. package/dist/features/tracing/components/shared/CopyableId.d.ts.map +1 -0
  21. package/dist/features/tracing/components/shared/TracingListHeader.d.ts +2 -1
  22. package/dist/features/tracing/components/shared/TracingListHeader.d.ts.map +1 -1
  23. package/dist/features/tracing/components/shared/TracingTable.d.ts.map +1 -1
  24. package/dist/features/tracing/components/shared/index.d.ts +1 -0
  25. package/dist/features/tracing/components/shared/index.d.ts.map +1 -1
  26. package/dist/features/tracing/types.d.ts +15 -0
  27. package/dist/features/tracing/types.d.ts.map +1 -1
  28. package/dist/index.js +974 -136
  29. package/dist/ui-libs.umd.js +974 -136
  30. package/package.json +1 -1
@@ -36647,6 +36647,140 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
36647
36647
  ] }) })
36648
36648
  ] });
36649
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
+ }
36650
36784
  function Shimmer$2({ className = "", children }) {
36651
36785
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-[#F2F4F7] rounded ${className}`, children });
36652
36786
  }
@@ -104657,6 +104791,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104657
104791
  }, [columns]);
104658
104792
  const handleRowClick = React.useCallback(
104659
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;
104660
104797
  if (onRowClick && event.data) {
104661
104798
  onRowClick(event.data);
104662
104799
  }
@@ -104831,9 +104968,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104831
104968
  timeRangePresetLabel,
104832
104969
  onTimeRangeChange,
104833
104970
  filters,
104971
+ filterColumns: filterColumnsProp,
104834
104972
  onFiltersClick,
104835
104973
  onModifyColumnsClick,
104836
104974
  showModifyColumns = true,
104975
+ onClearFilters,
104976
+ onRemoveFilter,
104837
104977
  onRefresh,
104838
104978
  isRefreshing = false
104839
104979
  } = props;
@@ -104878,6 +105018,50 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
104878
105018
  }
104879
105019
  return `Searches in ${fields}.`;
104880
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
+ };
104881
105065
  const handleDateRangeChange = (dateRange, presetLabel) => {
104882
105066
  if (dateRange && dateRange.from && dateRange.to) {
104883
105067
  const fromDate = dateRange.from;
@@ -105030,7 +105214,66 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
105030
105214
  }
105031
105215
  )
105032
105216
  ] })
105033
- ] })
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
+ )
105034
105277
  ] });
105035
105278
  }
105036
105279
  function ColumnCustomization(props) {
@@ -106109,6 +106352,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106109
106352
  * Observations are loaded separately per trace when user expands
106110
106353
  */
106111
106354
  async fetchSessionDetail(sessionId) {
106355
+ var _a, _b;
106112
106356
  const sessionResponse = await this.apiService.fetchSessionById({
106113
106357
  sessionId,
106114
106358
  projectId: this.projectId
@@ -106123,6 +106367,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106123
106367
  );
106124
106368
  traceDetails = traceResponses.map((trace) => this.transformToTraceDetailData(trace));
106125
106369
  }
106370
+ const firstTraceForSource = (_a = sessionResponse.traces) == null ? void 0 : _a[0];
106371
+ const sessionLevelSource = typeof sessionResponse.source === "string" && sessionResponse.source.length > 0 ? sessionResponse.source : void 0;
106372
+ const firstTraceSource = firstTraceForSource && typeof firstTraceForSource.source === "string" && firstTraceForSource.source.length > 0 ? firstTraceForSource.source : void 0;
106373
+ const resolvedSource = sessionLevelSource ?? firstTraceSource ?? ((_b = traceDetails[0]) == null ? void 0 : _b.source);
106126
106374
  return {
106127
106375
  id: sessionResponse.id,
106128
106376
  projectId: sessionResponse.projectId,
@@ -106130,7 +106378,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106130
106378
  bookmarked: false,
106131
106379
  public: false,
106132
106380
  traces: traceDetails,
106133
- scores: []
106381
+ scores: [],
106382
+ source: resolvedSource
106134
106383
  };
106135
106384
  }
106136
106385
  /**
@@ -106202,15 +106451,21 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106202
106451
  * @param onRemainingTrace - Callback for each additional trace as it loads (updates skeleton)
106203
106452
  */
106204
106453
  async fetchSessionDetailProgressive(sessionId, onSessionMeta, onFirstTrace, onRemainingTrace) {
106454
+ var _a, _b;
106205
106455
  const sessionResponse = await this.apiService.fetchSessionById({
106206
106456
  sessionId,
106207
106457
  projectId: this.projectId
106208
106458
  });
106209
106459
  const traceIds = (sessionResponse.traces || []).map((t) => t.id);
106460
+ const firstTrace = (_a = sessionResponse.traces) == null ? void 0 : _a[0];
106461
+ const firstTraceSource = firstTrace && typeof firstTrace.source === "string" && firstTrace.source.length > 0 ? firstTrace.source : void 0;
106462
+ const sessionLevelSource = typeof sessionResponse.source === "string" && sessionResponse.source.length > 0 ? sessionResponse.source : void 0;
106463
+ const resolvedSessionSource = sessionLevelSource ?? firstTraceSource;
106210
106464
  onSessionMeta({
106211
106465
  id: sessionResponse.id,
106212
106466
  traceCount: traceIds.length,
106213
- traceIds
106467
+ traceIds,
106468
+ source: resolvedSessionSource
106214
106469
  });
106215
106470
  if (traceIds.length === 0) {
106216
106471
  return {
@@ -106220,7 +106475,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106220
106475
  bookmarked: false,
106221
106476
  public: false,
106222
106477
  traces: [],
106223
- scores: []
106478
+ scores: [],
106479
+ source: resolvedSessionSource
106224
106480
  };
106225
106481
  }
106226
106482
  const firstTraceId = traceIds[0];
@@ -106267,7 +106523,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106267
106523
  bookmarked: false,
106268
106524
  public: false,
106269
106525
  traces: allTraces,
106270
- scores: []
106526
+ scores: [],
106527
+ source: resolvedSessionSource ?? ((_b = allTraces[0]) == null ? void 0 : _b.source)
106271
106528
  };
106272
106529
  }
106273
106530
  // ============================================================================
@@ -106361,6 +106618,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106361
106618
  totalCost: trace.totalCost || trace.calculatedTotalCost,
106362
106619
  totalTokens: trace.totalTokens,
106363
106620
  environment: trace.environment,
106621
+ source: typeof trace.source === "string" && trace.source.length > 0 ? trace.source : void 0,
106364
106622
  observations: (trace.observations || []).map(
106365
106623
  (obs) => this.transformObservation(obs)
106366
106624
  ),
@@ -106769,6 +107027,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106769
107027
  onNodeSelect,
106770
107028
  onExpandToggle,
106771
107029
  showTraceId = true,
107030
+ onTraceIdClick,
106772
107031
  isLoading = false,
106773
107032
  defaultExpandedNodeIds,
106774
107033
  runHeaderInputMode = "display"
@@ -106829,7 +107088,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106829
107088
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[4px] w-full mb-[8px]", children: [
106830
107089
  showTraceId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center px-0 py-[4px] w-full", children: [
106831
107090
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#98A2B3]", children: "Trace ID" }),
106832
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
107091
+ onTraceIdClick ? /* @__PURE__ */ jsxRuntimeExports.jsx(
107092
+ "button",
107093
+ {
107094
+ onClick: () => onTraceIdClick(trace.id),
107095
+ className: "font-medium text-[10px] leading-[12px] text-[#155EEF] hover:underline cursor-pointer bg-transparent border-none p-0",
107096
+ title: "View Trace Details",
107097
+ "data-test-id": `trace-tree-id-link-${trace.id}`,
107098
+ children: trace.id
107099
+ }
107100
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
106833
107101
  /* @__PURE__ */ jsxRuntimeExports.jsx(
106834
107102
  "button",
106835
107103
  {
@@ -106948,114 +107216,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
106948
107216
  ] })
106949
107217
  ] });
106950
107218
  }
106951
- const CopyButton$1 = ({
106952
- text,
106953
- className = "",
106954
- iconClassName = "",
106955
- iconStyle,
106956
- title = "Copy to clipboard",
106957
- onCopySuccess,
106958
- onCopyError,
106959
- tooltipText = "Copied!",
106960
- tooltipPosition = "bottom",
106961
- size = "md"
106962
- }) => {
106963
- const [showTooltip, setShowTooltip] = React.useState(false);
106964
- const getSizeClasses = () => {
106965
- switch (size) {
106966
- case "sm":
106967
- return {
106968
- button: "p-1",
106969
- icon: "w-[12px] h-[12px]",
106970
- tooltip: "text-xs py-1 px-2"
106971
- };
106972
- case "lg":
106973
- return {
106974
- button: "p-2",
106975
- icon: "w-[20px] h-[20px]",
106976
- tooltip: "text-sm py-2 px-3"
106977
- };
106978
- default:
106979
- return {
106980
- button: "p-1.5",
106981
- icon: "w-[16px] h-[16px]",
106982
- tooltip: "text-xs py-1 px-2"
106983
- };
106984
- }
106985
- };
106986
- const getTooltipPositionClasses = () => {
106987
- const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
106988
- switch (tooltipPosition) {
106989
- case "bottom":
106990
- return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
106991
- case "left":
106992
- return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
106993
- case "right":
106994
- return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
106995
- default:
106996
- return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
106997
- }
106998
- };
106999
- const sizeClasses2 = getSizeClasses();
107000
- const showCopyTooltip = React.useCallback(() => {
107001
- setShowTooltip(true);
107002
- setTimeout(() => setShowTooltip(false), 1e3);
107003
- }, []);
107004
- const copyToClipboard2 = React.useCallback(async () => {
107005
- try {
107006
- if (navigator.clipboard && navigator.clipboard.writeText) {
107007
- await navigator.clipboard.writeText(text);
107008
- showCopyTooltip();
107009
- onCopySuccess == null ? void 0 : onCopySuccess();
107010
- return;
107011
- }
107012
- const textArea = document.createElement("textarea");
107013
- textArea.value = text;
107014
- textArea.style.position = "fixed";
107015
- textArea.style.left = "-999999px";
107016
- textArea.style.top = "-999999px";
107017
- document.body.appendChild(textArea);
107018
- textArea.focus();
107019
- textArea.select();
107020
- try {
107021
- document.execCommand("copy");
107022
- showCopyTooltip();
107023
- onCopySuccess == null ? void 0 : onCopySuccess();
107024
- } catch (err) {
107025
- const error = err instanceof Error ? err : new Error("Copy failed");
107026
- console.warn("Copy to clipboard failed:", error);
107027
- onCopyError == null ? void 0 : onCopyError(error);
107028
- } finally {
107029
- document.body.removeChild(textArea);
107030
- }
107031
- } catch (err) {
107032
- const error = err instanceof Error ? err : new Error("Copy failed");
107033
- console.warn("Copy to clipboard failed:", error);
107034
- onCopyError == null ? void 0 : onCopyError(error);
107035
- }
107036
- }, [text, showCopyTooltip, onCopySuccess, onCopyError]);
107037
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
107038
- /* @__PURE__ */ jsxRuntimeExports.jsx(
107039
- "button",
107040
- {
107041
- onClick: copyToClipboard2,
107042
- className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
107043
- title,
107044
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
107045
- }
107046
- ),
107047
- /* @__PURE__ */ jsxRuntimeExports.jsx(
107048
- "div",
107049
- {
107050
- className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
107051
- style: {
107052
- visibility: showTooltip ? "visible" : "hidden"
107053
- },
107054
- children: tooltipText
107055
- }
107056
- )
107057
- ] });
107058
- };
107059
107219
  function __awaiter(thisArg, _arguments, P2, generator) {
107060
107220
  function adopt(value) {
107061
107221
  return value instanceof P2 ? value : new P2(function(resolve) {
@@ -108812,10 +108972,12 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
108812
108972
  showHeader: true,
108813
108973
  useEnhancedJsonView: true,
108814
108974
  collapseStringsAfterLength: 500,
108815
- collapseObjectsAfterLength: 20,
108975
+ collapseObjectsAfterLength: selectedTab === "metadata" ? 100 : 20,
108976
+ defaultExpanded: selectedTab === "metadata",
108816
108977
  maxHeight: "100%",
108817
108978
  className: "h-full border-0 rounded-none"
108818
- }
108979
+ },
108980
+ selectedTab
108819
108981
  ) })
108820
108982
  ] });
108821
108983
  }
@@ -109184,6 +109346,521 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109184
109346
  )
109185
109347
  ] });
109186
109348
  }
109349
+ const MicIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: { flexShrink: 0 }, children: [
109350
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109351
+ "path",
109352
+ {
109353
+ d: "M8 2C7.60218 2 7.22064 2.15804 6.93934 2.43934C6.65804 2.72064 6.5 3.10218 6.5 3.5V6.5C6.5 6.89782 6.65804 7.27936 6.93934 7.56066C7.22064 7.84196 7.60218 8 8 8C8.39782 8 8.77936 7.84196 9.06066 7.56066C9.34196 7.27936 9.5 6.89782 9.5 6.5V3.5C9.5 3.10218 9.34196 2.72064 9.06066 2.43934C8.77936 2.15804 8.39782 2 8 2Z",
109354
+ style: { fill: "#155EEF" }
109355
+ }
109356
+ ),
109357
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109358
+ "path",
109359
+ {
109360
+ d: "M5.5 6V6.5C5.5 7.16304 5.76339 7.79893 6.23223 8.26777C6.70107 8.73661 7.33696 9 8 9C8.66304 9 9.29893 8.73661 9.76777 8.26777C10.2366 7.79893 10.5 7.16304 10.5 6.5V6",
109361
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109362
+ }
109363
+ ),
109364
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109365
+ "path",
109366
+ {
109367
+ d: "M8 9V11",
109368
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109369
+ }
109370
+ ),
109371
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109372
+ "path",
109373
+ {
109374
+ d: "M6.5 11H9.5",
109375
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109376
+ }
109377
+ )
109378
+ ] });
109379
+ function VoiceEventLogsBanner({ onViewEventLogs }) {
109380
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between rounded-[8px] bg-[#FFFFFF] border border-[#D0D5DD] px-[12px] py-[8px] mb-[8px]", children: [
109381
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109382
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MicIcon, {}),
109383
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.04em]", children: "Voice-to-Voice Event Logs" })
109384
+ ] }),
109385
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109386
+ "button",
109387
+ {
109388
+ onClick: onViewEventLogs,
109389
+ className: "text-[12px] font-medium text-[#155EEF] hover:text-[#344054] hover:underline transition-colors cursor-pointer bg-transparent border-none p-0",
109390
+ "data-test-id": "view-event-logs-btn",
109391
+ children: "View Event Logs"
109392
+ }
109393
+ )
109394
+ ] });
109395
+ }
109396
+ function AlignLeftIcon({ className }) {
109397
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109398
+ "svg",
109399
+ {
109400
+ width: "16",
109401
+ height: "16",
109402
+ viewBox: "0 0 16 16",
109403
+ fill: "none",
109404
+ xmlns: "http://www.w3.org/2000/svg",
109405
+ className,
109406
+ "aria-hidden": "true",
109407
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109408
+ "path",
109409
+ {
109410
+ d: "M10.6667 6.66667H2M13.3333 4H2M13.3333 9.33333H2M10.6667 12H2",
109411
+ stroke: "currentColor",
109412
+ strokeWidth: "1.3",
109413
+ strokeLinecap: "round",
109414
+ strokeLinejoin: "round"
109415
+ }
109416
+ )
109417
+ }
109418
+ );
109419
+ }
109420
+ function JsonViewIcon({ className }) {
109421
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109422
+ "svg",
109423
+ {
109424
+ width: "16",
109425
+ height: "16",
109426
+ viewBox: "0 0 16 16",
109427
+ fill: "none",
109428
+ xmlns: "http://www.w3.org/2000/svg",
109429
+ className,
109430
+ "aria-hidden": "true",
109431
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109432
+ "path",
109433
+ {
109434
+ d: "M14 6.16602H8M14 2.66602H2M14 9.83268H8M14 13.3327H2M2.85333 5.70602L5.43111 7.63935C5.62411 7.78409 5.7206 7.85647 5.75511 7.94519C5.78533 8.02291 5.78533 8.10913 5.75511 8.18684C5.7206 8.27556 5.62411 8.34794 5.43111 8.49268L2.85333 10.426C2.57868 10.632 2.44135 10.735 2.3264 10.7326C2.22637 10.7305 2.13256 10.6836 2.07088 10.6048C2 10.5143 2 10.3427 2 9.99935V6.13268C2 5.78937 2 5.61771 2.07088 5.52718C2.13256 5.4484 2.22637 5.4015 2.3264 5.39942C2.44135 5.39703 2.57868 5.50003 2.85333 5.70602Z",
109435
+ stroke: "currentColor",
109436
+ strokeWidth: "1.3",
109437
+ strokeLinecap: "round",
109438
+ strokeLinejoin: "round"
109439
+ }
109440
+ )
109441
+ }
109442
+ );
109443
+ }
109444
+ function pickString(obj, keys2) {
109445
+ for (const key of keys2) {
109446
+ const value = obj[key];
109447
+ if (typeof value === "string" && value.length > 0) return value;
109448
+ if (typeof value === "number") return String(value);
109449
+ }
109450
+ return void 0;
109451
+ }
109452
+ function coerceDirection(raw) {
109453
+ if (raw === "incoming" || raw === "server" || raw === "response") return "in";
109454
+ return "out";
109455
+ }
109456
+ function normalizeEvent(raw, fallbackId, docTimestamp) {
109457
+ if (!raw || typeof raw !== "object") {
109458
+ return {
109459
+ id: fallbackId,
109460
+ timestamp: docTimestamp,
109461
+ name: "event",
109462
+ direction: "out",
109463
+ payload: raw
109464
+ };
109465
+ }
109466
+ const obj = raw;
109467
+ const id = pickString(obj, ["event_id", "eventId", "_id", "id"]) ?? fallbackId;
109468
+ const name = pickString(obj, ["type", "eventType", "event", "name"]) ?? "event";
109469
+ const direction = coerceDirection(obj.direction);
109470
+ return {
109471
+ id,
109472
+ timestamp: docTimestamp,
109473
+ name,
109474
+ direction,
109475
+ payload: raw
109476
+ };
109477
+ }
109478
+ function flattenEvents(data) {
109479
+ if (data === null || data === void 0) return [];
109480
+ const out = [];
109481
+ const visitDoc = (doc2, docIdx) => {
109482
+ if (!doc2 || typeof doc2 !== "object") return;
109483
+ const docObj = doc2;
109484
+ const docTimestamp = pickString(docObj, ["createdOn", "sT", "createdAt"]);
109485
+ const events = docObj.events;
109486
+ if (Array.isArray(events)) {
109487
+ events.forEach((ev, evIdx) => {
109488
+ out.push(normalizeEvent(ev, `${docIdx}-${evIdx}`, docTimestamp));
109489
+ });
109490
+ } else {
109491
+ out.push(normalizeEvent(doc2, String(docIdx), docTimestamp));
109492
+ }
109493
+ };
109494
+ if (Array.isArray(data)) {
109495
+ data.forEach((doc2, docIdx) => visitDoc(doc2, docIdx));
109496
+ return out;
109497
+ }
109498
+ if (typeof data === "object") {
109499
+ const obj = data;
109500
+ if (Array.isArray(obj.events)) {
109501
+ visitDoc(obj, 0);
109502
+ return out;
109503
+ }
109504
+ if (Array.isArray(obj.data)) {
109505
+ return flattenEvents(obj.data);
109506
+ }
109507
+ }
109508
+ return [];
109509
+ }
109510
+ function formatEventTime(iso) {
109511
+ if (!iso) return "--:--:--:---";
109512
+ const d = new Date(iso);
109513
+ if (Number.isNaN(d.getTime())) return "--:--:--:---";
109514
+ const hh = String(d.getHours()).padStart(2, "0");
109515
+ const mm = String(d.getMinutes()).padStart(2, "0");
109516
+ const ss = String(d.getSeconds()).padStart(2, "0");
109517
+ const ms = String(d.getMilliseconds()).padStart(3, "0");
109518
+ return `${hh}:${mm}:${ss}:${ms}`;
109519
+ }
109520
+ function stringifyPayload(payload) {
109521
+ if (payload === null || payload === void 0) return "";
109522
+ if (typeof payload === "string") {
109523
+ try {
109524
+ return JSON.stringify(JSON.parse(payload), null, 2);
109525
+ } catch {
109526
+ return payload;
109527
+ }
109528
+ }
109529
+ try {
109530
+ return JSON.stringify(payload, null, 2);
109531
+ } catch {
109532
+ return String(payload);
109533
+ }
109534
+ }
109535
+ function compactPayload(payload) {
109536
+ if (payload === null || payload === void 0) return "";
109537
+ if (typeof payload === "string") {
109538
+ try {
109539
+ return JSON.stringify(JSON.parse(payload));
109540
+ } catch {
109541
+ return payload;
109542
+ }
109543
+ }
109544
+ try {
109545
+ return JSON.stringify(payload);
109546
+ } catch {
109547
+ return String(payload);
109548
+ }
109549
+ }
109550
+ function PayloadPanel({ payload, compactText }) {
109551
+ const [viewMode, setViewMode] = React.useState("json");
109552
+ const [fullscreen, setFullscreen] = React.useState(false);
109553
+ const [copied, setCopied] = React.useState(false);
109554
+ const displayText = viewMode === "json" ? payload : compactText;
109555
+ const handleCopy = React.useCallback(async () => {
109556
+ try {
109557
+ await navigator.clipboard.writeText(displayText);
109558
+ setCopied(true);
109559
+ setTimeout(() => setCopied(false), 1500);
109560
+ } catch {
109561
+ }
109562
+ }, [displayText]);
109563
+ const toolbar = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[42px] px-[10px] border-b border-[#D0D5DD] flex items-center justify-between flex-shrink-0 bg-white", children: [
109564
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109565
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109566
+ "button",
109567
+ {
109568
+ type: "button",
109569
+ onClick: () => setViewMode("json"),
109570
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109571
+ title: "Pretty JSON",
109572
+ "aria-label": "Pretty JSON view",
109573
+ "aria-pressed": viewMode === "json",
109574
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109575
+ }
109576
+ ),
109577
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109578
+ "button",
109579
+ {
109580
+ type: "button",
109581
+ onClick: () => setViewMode("text"),
109582
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109583
+ title: "Compact text",
109584
+ "aria-label": "Compact text view",
109585
+ "aria-pressed": viewMode === "text",
109586
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109587
+ }
109588
+ )
109589
+ ] }),
109590
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109591
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109592
+ "button",
109593
+ {
109594
+ type: "button",
109595
+ onClick: () => setFullscreen((v) => !v),
109596
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109597
+ title: fullscreen ? "Exit fullscreen" : "Fullscreen",
109598
+ "aria-label": fullscreen ? "Exit fullscreen" : "Fullscreen",
109599
+ children: fullscreen ? /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-[16px] h-[16px]" })
109600
+ }
109601
+ ),
109602
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109603
+ "button",
109604
+ {
109605
+ type: "button",
109606
+ onClick: () => void handleCopy(),
109607
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109608
+ title: "Copy to clipboard",
109609
+ "aria-label": "Copy payload",
109610
+ "data-test-id": "event-logs-row-copy",
109611
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109612
+ }
109613
+ )
109614
+ ] })
109615
+ ] });
109616
+ if (fullscreen) {
109617
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[20000] flex flex-col bg-[#F9FAFB]", children: [
109618
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[48px] px-[16px] border-b border-[#E4E7EC] flex items-center justify-between flex-shrink-0 bg-white", children: [
109619
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109620
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109621
+ "button",
109622
+ {
109623
+ type: "button",
109624
+ onClick: () => setViewMode("json"),
109625
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109626
+ title: "Pretty JSON",
109627
+ "aria-label": "Pretty JSON view",
109628
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109629
+ }
109630
+ ),
109631
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109632
+ "button",
109633
+ {
109634
+ type: "button",
109635
+ onClick: () => setViewMode("text"),
109636
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109637
+ title: "Compact text",
109638
+ "aria-label": "Compact text view",
109639
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109640
+ }
109641
+ )
109642
+ ] }),
109643
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109644
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109645
+ "button",
109646
+ {
109647
+ type: "button",
109648
+ onClick: () => void handleCopy(),
109649
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109650
+ title: "Copy to clipboard",
109651
+ "aria-label": "Copy payload",
109652
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109653
+ }
109654
+ ),
109655
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109656
+ "button",
109657
+ {
109658
+ type: "button",
109659
+ onClick: () => setFullscreen(false),
109660
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109661
+ title: "Exit fullscreen",
109662
+ "aria-label": "Exit fullscreen",
109663
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" })
109664
+ }
109665
+ )
109666
+ ] })
109667
+ ] }),
109668
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "flex-1 overflow-auto m-0 p-[20px] text-[13px] leading-[20px] font-mono text-[#344054] whitespace-pre-wrap break-all", children: displayText })
109669
+ ] }) });
109670
+ }
109671
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[10px] border border-[#D0D5DD] overflow-hidden mt-[12px]", children: [
109672
+ toolbar,
109673
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "m-0 bg-[#F9FAFB] text-[#344054] p-[12px] text-[12px] leading-[18px] font-mono whitespace-pre-wrap break-all overflow-auto max-h-[360px]", children: displayText })
109674
+ ] });
109675
+ }
109676
+ function EventRow({ event, isExpanded, onToggle }) {
109677
+ const jsonText = React.useMemo(() => stringifyPayload(event.payload), [event.payload]);
109678
+ const compactText = React.useMemo(() => compactPayload(event.payload), [event.payload]);
109679
+ const hasPayload = jsonText.length > 0;
109680
+ const isInput = event.direction === "in";
109681
+ const DirectionIcon = isInput ? ArrowUp : ArrowDown;
109682
+ const directionLabel = isInput ? "Input" : "Output";
109683
+ const circleClasses = isInput ? "border-[#079455] text-[#079455]" : "border-[#D92D20] text-[#D92D20]";
109684
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex items-start gap-[12px]", "data-test-id": "event-logs-row", children: [
109685
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative flex-shrink-0 flex flex-col items-center w-[16px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109686
+ "div",
109687
+ {
109688
+ className: `relative z-10 w-[16px] h-[16px] rounded-full bg-white border flex items-center justify-center ${circleClasses}`,
109689
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(DirectionIcon, { className: "w-[8px] h-[8px]", strokeWidth: 2.5 })
109690
+ }
109691
+ ) }),
109692
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 pb-[24px]", children: [
109693
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-[16px]", children: [
109694
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
109695
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[12px] leading-[16px] text-[#667085]", children: directionLabel }),
109696
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] font-medium text-[#344054] mt-[2px] break-all", children: event.name }),
109697
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109698
+ "button",
109699
+ {
109700
+ type: "button",
109701
+ onClick: onToggle,
109702
+ className: "text-[13px] leading-[18px] text-[#155EEF] hover:underline mt-[4px] font-medium",
109703
+ "data-test-id": "event-logs-view-details",
109704
+ children: isExpanded ? "Hide details" : "View details"
109705
+ }
109706
+ )
109707
+ ] }),
109708
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-shrink-0 text-[12px] leading-[18px] text-[#344054] font-mono tabular-nums whitespace-nowrap pt-[2px]", children: formatEventTime(event.timestamp) })
109709
+ ] }),
109710
+ isExpanded && (hasPayload ? /* @__PURE__ */ jsxRuntimeExports.jsx(PayloadPanel, { payload: jsonText, compactText }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-[12px] text-[12px] text-[#667085] italic", children: "No payload recorded for this event." }))
109711
+ ] })
109712
+ ] });
109713
+ }
109714
+ function EventLogsSlideout({
109715
+ isOpen,
109716
+ onClose,
109717
+ sessionId,
109718
+ fetchEventLogs
109719
+ }) {
109720
+ const [rawData, setRawData] = React.useState(null);
109721
+ const [loading, setLoading] = React.useState(false);
109722
+ const [error, setError] = React.useState(null);
109723
+ const [expandedIds, setExpandedIds] = React.useState(() => /* @__PURE__ */ new Set());
109724
+ React.useEffect(() => {
109725
+ if (!isOpen || !sessionId || !fetchEventLogs) return;
109726
+ let cancelled = false;
109727
+ setLoading(true);
109728
+ setError(null);
109729
+ setRawData(null);
109730
+ (async () => {
109731
+ try {
109732
+ const data = await fetchEventLogs(sessionId);
109733
+ if (cancelled) return;
109734
+ setRawData(data);
109735
+ } catch (err) {
109736
+ if (cancelled) return;
109737
+ setError(err instanceof Error ? err.message : "Failed to fetch event logs");
109738
+ } finally {
109739
+ if (!cancelled) setLoading(false);
109740
+ }
109741
+ })();
109742
+ return () => {
109743
+ cancelled = true;
109744
+ };
109745
+ }, [isOpen, sessionId, fetchEventLogs]);
109746
+ const events = React.useMemo(() => flattenEvents(rawData), [rawData]);
109747
+ React.useEffect(() => {
109748
+ if (!isOpen) return;
109749
+ const handleKey = (e) => {
109750
+ if (e.key === "Escape") onClose();
109751
+ };
109752
+ document.addEventListener("keydown", handleKey);
109753
+ return () => document.removeEventListener("keydown", handleKey);
109754
+ }, [isOpen, onClose]);
109755
+ React.useEffect(() => {
109756
+ if (!isOpen) {
109757
+ setExpandedIds(/* @__PURE__ */ new Set());
109758
+ setRawData(null);
109759
+ setError(null);
109760
+ }
109761
+ }, [isOpen]);
109762
+ const toggleRow = React.useCallback((id) => {
109763
+ setExpandedIds((prev) => {
109764
+ const next = new Set(prev);
109765
+ if (next.has(id)) next.delete(id);
109766
+ else next.add(id);
109767
+ return next;
109768
+ });
109769
+ }, []);
109770
+ const expandAll = React.useCallback(() => {
109771
+ setExpandedIds(new Set(events.map((e) => e.id)));
109772
+ }, [events]);
109773
+ const collapseAll = React.useCallback(() => {
109774
+ setExpandedIds(/* @__PURE__ */ new Set());
109775
+ }, []);
109776
+ if (!isOpen) return null;
109777
+ const showToolbar = !loading && !error && events.length > 0;
109778
+ const allExpanded = showToolbar && expandedIds.size === events.length;
109779
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[10000]", children: [
109780
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109781
+ "div",
109782
+ {
109783
+ className: "absolute inset-0 bg-black/40",
109784
+ onClick: onClose,
109785
+ "aria-hidden": "true"
109786
+ }
109787
+ ),
109788
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
109789
+ "div",
109790
+ {
109791
+ className: "absolute top-0 right-0 bottom-0 bg-white shadow-2xl flex flex-col",
109792
+ style: { width: "720px", maxWidth: "100vw" },
109793
+ role: "dialog",
109794
+ "aria-label": "Event Logs",
109795
+ onClick: (e) => e.stopPropagation(),
109796
+ children: [
109797
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between h-[56px] px-[20px] border-b border-[#E4E7EC] flex-shrink-0", children: [
109798
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109799
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[16px] font-semibold text-[#101828]", children: "Event Logs" }),
109800
+ !loading && !error && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium text-[#667085] bg-[#F2F4F7] rounded-[10px] px-[8px] py-[2px]", children: events.length })
109801
+ ] }),
109802
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109803
+ showToolbar && /* @__PURE__ */ jsxRuntimeExports.jsx(
109804
+ "button",
109805
+ {
109806
+ type: "button",
109807
+ onClick: allExpanded ? collapseAll : expandAll,
109808
+ className: "text-[13px] font-medium text-[#155EEF] hover:underline px-[8px] py-[6px] rounded-[6px] transition-colors",
109809
+ "data-test-id": "event-logs-toggle-all",
109810
+ children: allExpanded ? "Collapse all" : "Expand all"
109811
+ }
109812
+ ),
109813
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109814
+ "button",
109815
+ {
109816
+ type: "button",
109817
+ onClick: onClose,
109818
+ className: "p-[8px] rounded-[6px] hover:bg-[#F2F4F7] transition-colors",
109819
+ title: "Close Event Logs",
109820
+ "aria-label": "Close Event Logs",
109821
+ "data-test-id": "event-logs-close-btn",
109822
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[16px] h-[16px] text-[#344054]" })
109823
+ }
109824
+ )
109825
+ ] })
109826
+ ] }),
109827
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto", children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-[8px] text-[13px] text-[#667085]", children: [
109828
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-[20px] h-[20px] animate-spin text-[#155EEF]" }),
109829
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Loading event logs…" })
109830
+ ] }) : error ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-full flex flex-col items-center justify-center gap-[8px] text-[13px] text-[#B42318] px-[24px] text-center", children: [
109831
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Couldn't load event logs" }),
109832
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] text-[#667085]", children: error })
109833
+ ] }) : events.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-full flex items-center justify-center text-[13px] text-[#667085]", children: "No events recorded for this session yet." }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative px-[24px] pt-[28px] pb-[8px]", children: [
109834
+ events.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
109835
+ "div",
109836
+ {
109837
+ className: "absolute w-px bg-[#D0D5DD]",
109838
+ style: { left: "32px", top: "36px", bottom: "28px" },
109839
+ "aria-hidden": "true"
109840
+ }
109841
+ ),
109842
+ events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(
109843
+ EventRow,
109844
+ {
109845
+ event,
109846
+ isExpanded: expandedIds.has(event.id),
109847
+ onToggle: () => toggleRow(event.id)
109848
+ },
109849
+ event.id
109850
+ ))
109851
+ ] }) })
109852
+ ]
109853
+ }
109854
+ )
109855
+ ] }) });
109856
+ }
109857
+ const SESSION_SOURCES_WITH_EVENT_LOGS = /* @__PURE__ */ new Set(["AIS-CC", "XO"]);
109858
+ function sessionSourceShowsEventLogs(source) {
109859
+ if (source === void 0 || source === "") {
109860
+ return false;
109861
+ }
109862
+ return SESSION_SOURCES_WITH_EVENT_LOGS.has(source);
109863
+ }
109187
109864
  function DetailPage({
109188
109865
  mode: initialMode,
109189
109866
  sessionId: initialSessionId,
@@ -109196,7 +109873,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109196
109873
  batchSize = DEFAULT_BATCH_SIZE,
109197
109874
  initialTraceCount,
109198
109875
  initialSessionData,
109199
- runHeaderInputMode = "display"
109876
+ runHeaderInputMode = "display",
109877
+ onViewEventLogs,
109878
+ fetchEventLogs
109200
109879
  }) {
109201
109880
  const [currentMode, setCurrentMode] = React.useState(initialMode);
109202
109881
  const [currentSessionId, setCurrentSessionId] = React.useState(initialSessionId);
@@ -109206,6 +109885,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109206
109885
  const traceId = currentTraceId;
109207
109886
  const [selectedNode, setSelectedNode] = React.useState(null);
109208
109887
  const [copiedId, setCopiedId] = React.useState(false);
109888
+ const [isEventLogsOpen, setIsEventLogsOpen] = React.useState(false);
109209
109889
  const minObservationLevel = "DEFAULT";
109210
109890
  const [hasAutoSelected, setHasAutoSelected] = React.useState(false);
109211
109891
  const hasInitialData = mode === "session" && initialSessionData;
@@ -109251,7 +109931,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109251
109931
  bookmarked: false,
109252
109932
  public: false,
109253
109933
  traces: [],
109254
- scores: []
109934
+ scores: [],
109935
+ source: meta.source
109255
109936
  });
109256
109937
  setLoadingState("success");
109257
109938
  },
@@ -109259,7 +109940,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109259
109940
  (trace, observations) => {
109260
109941
  setSessionData((prev) => prev ? {
109261
109942
  ...prev,
109262
- traces: [trace]
109943
+ traces: [trace],
109944
+ source: prev.source ?? trace.source
109263
109945
  } : prev);
109264
109946
  setTraceObservations((prev) => ({
109265
109947
  ...prev,
@@ -109435,6 +110117,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109435
110117
  } : null
109436
110118
  };
109437
110119
  }, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
110120
+ const sessionSourceForEventLogs = React.useMemo(() => {
110121
+ return (initialSessionData == null ? void 0 : initialSessionData.source) ?? (sessionData == null ? void 0 : sessionData.source);
110122
+ }, [initialSessionData == null ? void 0 : initialSessionData.source, sessionData == null ? void 0 : sessionData.source]);
110123
+ const showEventLogsBanner = mode === "session" && sessionSourceShowsEventLogs(sessionSourceForEventLogs);
109438
110124
  const traces = React.useMemo(() => {
109439
110125
  if (mode === "session" && sessionData) {
109440
110126
  const sorted = [...sessionData.traces].sort((a2, b) => {
@@ -109483,6 +110169,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109483
110169
  mode,
109484
110170
  traceData
109485
110171
  ]);
110172
+ const handleViewEventLogs = React.useCallback(() => {
110173
+ setIsEventLogsOpen(true);
110174
+ if (onViewEventLogs && sessionId) {
110175
+ const firstTraceId = traces.length > 0 ? traces[0].id : void 0;
110176
+ onViewEventLogs(sessionId, firstTraceId);
110177
+ }
110178
+ }, [onViewEventLogs, sessionId, traces]);
110179
+ const handleCloseEventLogs = React.useCallback(() => {
110180
+ setIsEventLogsOpen(false);
110181
+ }, []);
109486
110182
  const handleNodeSelect = React.useCallback((node) => {
109487
110183
  setSelectedNode(node);
109488
110184
  }, []);
@@ -109531,6 +110227,23 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109531
110227
  firstTraceId: null
109532
110228
  });
109533
110229
  }, []);
110230
+ const handleNavigateToTrace = React.useCallback((targetTraceId) => {
110231
+ setSelectedNode(null);
110232
+ setSessionData(null);
110233
+ setTraceData(null);
110234
+ setTraceObservations({});
110235
+ setLoadingState("idle");
110236
+ setError(null);
110237
+ setHasAutoSelected(false);
110238
+ setCurrentMode("trace");
110239
+ setCurrentTraceId(targetTraceId);
110240
+ setProgressiveState({
110241
+ traceCount: 0,
110242
+ pendingTraceIds: [],
110243
+ firstTraceLoaded: false,
110244
+ firstTraceId: null
110245
+ });
110246
+ }, []);
109534
110247
  if (loadingState === "loading") {
109535
110248
  const canShowHeader = mode === "session" && initialSessionData;
109536
110249
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col bg-white ${className}`, children: [
@@ -109682,6 +110395,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109682
110395
  ] }),
109683
110396
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
109684
110397
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-[480px] min-w-[400px] max-w-[600px] border-r border-[#E4E7EC] flex flex-col bg-[#F9FAFB] overflow-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 p-[16px]", children: [
110398
+ showEventLogsBanner && /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceEventLogsBanner, { onViewEventLogs: handleViewEventLogs }),
109685
110399
  traces.length === 0 && loadingState === "success" && progressiveState.traceCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "py-[32px] text-center text-[13px] text-[#667085]", children: "No traces available" }),
109686
110400
  traces.map((trace, index) => {
109687
110401
  var _a, _b, _c, _d;
@@ -109699,6 +110413,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109699
110413
  onNodeSelect: handleNodeSelect,
109700
110414
  onExpandToggle: () => handleTraceExpand(trace.id, trace.timestamp),
109701
110415
  showTraceId: mode === "session",
110416
+ onTraceIdClick: mode === "session" ? handleNavigateToTrace : void 0,
109702
110417
  isLoading: isLoadingObservations,
109703
110418
  defaultExpandedNodeIds: autoExpandIds,
109704
110419
  runHeaderInputMode
@@ -109730,7 +110445,16 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
109730
110445
  generationSummaryInputOverride
109731
110446
  }
109732
110447
  )
109733
- ] })
110448
+ ] }),
110449
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
110450
+ EventLogsSlideout,
110451
+ {
110452
+ isOpen: isEventLogsOpen,
110453
+ onClose: handleCloseEventLogs,
110454
+ sessionId: sessionId ?? null,
110455
+ fetchEventLogs
110456
+ }
110457
+ )
109734
110458
  ] });
109735
110459
  }
109736
110460
  const trace1Observations = [
@@ -110144,8 +110868,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110144
110868
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
110145
110869
  }
110146
110870
  function SessionsListContent(props) {
110147
- const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
110148
- const { environments } = useEnvironment();
110871
+ const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId, onViewEventLogs, fetchEventLogs } = props;
110872
+ const { environments, resolveEnvironmentName } = useEnvironment();
110149
110873
  const [selectedSessionId, setSelectedSessionId] = React.useState(() => initialSessionId ?? null);
110150
110874
  const [selectedSessionData, setSelectedSessionData] = React.useState(null);
110151
110875
  const [isModalOpen, setIsModalOpen] = React.useState(() => !!initialSessionId);
@@ -110153,6 +110877,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110153
110877
  const [totalCount, setTotalCount] = React.useState(0);
110154
110878
  const [loading, setLoading] = React.useState(true);
110155
110879
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = React.useState(false);
110880
+ const [appVersionOptions, setAppVersionOptions] = React.useState([]);
110881
+ const [searchTerm, setSearchTerm] = React.useState("");
110156
110882
  const initialFilters = React.useMemo(() => {
110157
110883
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
110158
110884
  const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter$1(), ...defaultFilters];
@@ -110175,6 +110901,26 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110175
110901
  setIsModalOpen(true);
110176
110902
  }
110177
110903
  }, [initialSessionId]);
110904
+ React.useEffect(() => {
110905
+ const fetchAppVersions = async () => {
110906
+ try {
110907
+ const filterOptionsData = await apiService.fetchFilterOptions({
110908
+ projectId: apiConfig.projectId
110909
+ });
110910
+ if ((filterOptionsData == null ? void 0 : filterOptionsData.appvIds) && Array.isArray(filterOptionsData.appvIds)) {
110911
+ setAppVersionOptions(
110912
+ filterOptionsData.appvIds.map((item) => ({
110913
+ value: item.value,
110914
+ label: item.value
110915
+ }))
110916
+ );
110917
+ }
110918
+ } catch (error) {
110919
+ console.warn("Failed to fetch app version filter options:", error);
110920
+ }
110921
+ };
110922
+ fetchAppVersions();
110923
+ }, [apiService, apiConfig.projectId]);
110178
110924
  const convertPresetToDateRange = (preset) => {
110179
110925
  const now2 = /* @__PURE__ */ new Date();
110180
110926
  let pastDate;
@@ -110236,7 +110982,6 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110236
110982
  });
110237
110983
  }
110238
110984
  const allFilters = [...timeFilters, ...filters];
110239
- if (apiConfig.projectId) ;
110240
110985
  return allFilters;
110241
110986
  }, [timeRange, filters]);
110242
110987
  const fetchSessions = React.useCallback(async () => {
@@ -110296,6 +111041,28 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110296
111041
  React.useEffect(() => {
110297
111042
  fetchSessions();
110298
111043
  }, [fetchSessions]);
111044
+ const filteredSessions = React.useMemo(() => {
111045
+ const term = searchTerm.trim().toLowerCase();
111046
+ if (!term) return sessions;
111047
+ return sessions.filter((session) => {
111048
+ var _a;
111049
+ const envName = ((_a = resolveEnvironmentName(session.envId)) == null ? void 0 : _a.toLowerCase()) || "";
111050
+ const searchableFields = [
111051
+ session.id,
111052
+ envName,
111053
+ session.envId,
111054
+ session.appvId,
111055
+ session.source,
111056
+ session.environment,
111057
+ session.sessionReference,
111058
+ session.userReference,
111059
+ ...session.userIds || []
111060
+ ];
111061
+ return searchableFields.some(
111062
+ (field) => field && String(field).toLowerCase().includes(term)
111063
+ );
111064
+ });
111065
+ }, [sessions, searchTerm, resolveEnvironmentName]);
110299
111066
  const defaultColumns = React.useMemo(
110300
111067
  () => [
110301
111068
  {
@@ -110304,8 +111071,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110304
111071
  width: 320,
110305
111072
  pinned: "left",
110306
111073
  hide: false,
110307
- // Pinned columns should always be visible
110308
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
111074
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
110309
111075
  },
110310
111076
  {
110311
111077
  field: "envId",
@@ -110432,6 +111198,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110432
111198
  disabled: true,
110433
111199
  valueFormatter: (params) => TracingUtils.formatTokens(params.value),
110434
111200
  cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", children: TracingUtils.formatTokens(params.value) })
111201
+ },
111202
+ {
111203
+ field: "sessionReference",
111204
+ headerName: "Session Reference",
111205
+ width: 180,
111206
+ hide: true,
111207
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111208
+ },
111209
+ {
111210
+ field: "identity",
111211
+ headerName: "User Reference",
111212
+ width: 180,
111213
+ hide: true,
111214
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
110435
111215
  }
110436
111216
  // {
110437
111217
  // field: 'traceTags',
@@ -110551,8 +111331,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110551
111331
  // User-friendly label
110552
111332
  apiColumnName: "App Version ID",
110553
111333
  // API expects "App Version ID" (koretracing uiTableName)
110554
- type: "string",
110555
- operators: ["=", "!=", "contains"]
111334
+ type: "stringOptions",
111335
+ operators: ["any of", "none of"],
111336
+ options: appVersionOptions
110556
111337
  },
110557
111338
  {
110558
111339
  field: "source",
@@ -110604,10 +111385,27 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110604
111385
  // API expects "Output Tokens" (koretracing uiTableName)
110605
111386
  type: "number",
110606
111387
  operators: ["=", ">", ">=", "<", "<="]
111388
+ },
111389
+ {
111390
+ field: "sessionReference",
111391
+ label: "Session Reference",
111392
+ apiColumnName: "Session Reference",
111393
+ type: "string",
111394
+ operators: ["=", "!=", "contains"]
111395
+ },
111396
+ {
111397
+ field: "identity",
111398
+ label: "User Reference",
111399
+ apiColumnName: "User Reference",
111400
+ type: "string",
111401
+ operators: ["=", "!=", "contains"]
110607
111402
  }
110608
111403
  ],
110609
- [environments]
111404
+ [environments, appVersionOptions]
110610
111405
  );
111406
+ const handleSearch = React.useCallback((term) => {
111407
+ setSearchTerm(term);
111408
+ }, []);
110611
111409
  const handleTimeRangeChange = (value, presetLabel) => {
110612
111410
  console.log("🗓️ SessionsList: Time range change requested:", value, presetLabel);
110613
111411
  setTimeRange(value);
@@ -110631,7 +111429,8 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110631
111429
  totalCost: session.totalCost,
110632
111430
  totalTokens: session.totalTokens,
110633
111431
  sessionDuration: session.sessionDuration,
110634
- createdAt: session.createdAt
111432
+ createdAt: session.createdAt,
111433
+ source: session.source
110635
111434
  });
110636
111435
  setIsModalOpen(true);
110637
111436
  if (onSessionClick) {
@@ -110649,6 +111448,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110649
111448
  };
110650
111449
  const handleClearFilters = () => {
110651
111450
  setFilters([]);
111451
+ setSearchTerm("");
110652
111452
  setTimeRange("24 hours");
110653
111453
  };
110654
111454
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col w-full ${className}`, children: [
@@ -110657,11 +111457,19 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110657
111457
  {
110658
111458
  title: "Sessions",
110659
111459
  description: "Review session logs and trace details to analyze conversation logs and app behavior.",
110660
- showSearch: false,
111460
+ searchPlaceholder: "Search sessions...",
111461
+ showSearch: true,
111462
+ searchConfig: {
111463
+ metadataSearchFields: ["Session ID", "Environment", "App Version", "User ID", "Source"],
111464
+ updateQuery: handleSearch,
111465
+ currentQuery: searchTerm,
111466
+ tableAllowsFullTextSearch: false
111467
+ },
110661
111468
  timeRange,
110662
111469
  timeRangePresetLabel,
110663
111470
  onTimeRangeChange: handleTimeRangeChange,
110664
111471
  filters,
111472
+ filterColumns,
110665
111473
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
110666
111474
  onModifyColumnsClick: () => setShowColumnCustomization(true),
110667
111475
  onExportClick: handleExport,
@@ -110712,10 +111520,10 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110712
111520
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto p-[24px] pt-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
110713
111521
  TracingTable,
110714
111522
  {
110715
- data: sessions,
111523
+ data: filteredSessions,
110716
111524
  columns,
110717
111525
  loading,
110718
- totalCount,
111526
+ totalCount: searchTerm.trim() ? filteredSessions.length : totalCount,
110719
111527
  pagination,
110720
111528
  onPaginationChange: setPagination,
110721
111529
  onRowClick: handleRowClick,
@@ -110732,7 +111540,9 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110732
111540
  sessionId: selectedSessionId,
110733
111541
  apiConfig,
110734
111542
  onClose: handleModalClose,
110735
- initialSessionData: selectedSessionData || void 0
111543
+ initialSessionData: selectedSessionData || void 0,
111544
+ onViewEventLogs,
111545
+ fetchEventLogs
110736
111546
  }
110737
111547
  ) })
110738
111548
  ] });
@@ -110773,7 +111583,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
110773
111583
  const [loading, setLoading] = React.useState(true);
110774
111584
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = React.useState(false);
110775
111585
  const [searchTerm, setSearchTerm] = React.useState("");
110776
- const [searchType, setSearchType] = React.useState(["id"]);
111586
+ const [searchType, setSearchType] = React.useState(["id", "content"]);
110777
111587
  const initialFilters = React.useMemo(() => {
110778
111588
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
110779
111589
  const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter(), ...defaultFilters];
@@ -111005,8 +111815,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111005
111815
  width: 320,
111006
111816
  pinned: "left",
111007
111817
  hide: false,
111008
- // Pinned columns should always be visible
111009
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
111818
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
111010
111819
  }
111011
111820
  ];
111012
111821
  {
@@ -111198,6 +112007,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111198
112007
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", children: source || "-" });
111199
112008
  }
111200
112009
  },
112010
+ {
112011
+ field: "sessionReference",
112012
+ headerName: "Session Reference",
112013
+ width: 180,
112014
+ hide: true,
112015
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
112016
+ },
112017
+ {
112018
+ field: "identity",
112019
+ headerName: "User Reference",
112020
+ width: 180,
112021
+ hide: true,
112022
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
112023
+ },
111201
112024
  {
111202
112025
  field: "promptTokens",
111203
112026
  headerName: "Input Tokens",
@@ -111467,6 +112290,20 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111467
112290
  label: "Output Tokens",
111468
112291
  type: "number",
111469
112292
  operators: ["=", ">", ">=", "<", "<="]
112293
+ },
112294
+ {
112295
+ field: "sessionReference",
112296
+ label: "Session Reference",
112297
+ apiColumnName: "Session Reference",
112298
+ type: "string",
112299
+ operators: ["=", "!=", "contains"]
112300
+ },
112301
+ {
112302
+ field: "identity",
112303
+ label: "User Reference",
112304
+ apiColumnName: "User Reference",
112305
+ type: "string",
112306
+ operators: ["=", "!=", "contains"]
111470
112307
  }
111471
112308
  );
111472
112309
  return baseColumns;
@@ -111533,6 +112370,7 @@ For more info see: https://www.ag-grid.com/javascript-grid/modules/`;
111533
112370
  timeRangePresetLabel,
111534
112371
  onTimeRangeChange: handleTimeRangeChange,
111535
112372
  filters,
112373
+ filterColumns,
111536
112374
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
111537
112375
  onModifyColumnsClick: () => setShowColumnCustomization(true),
111538
112376
  onExportClick: handleExport,