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
package/dist/index.js CHANGED
@@ -36607,6 +36607,140 @@ function TokenBreakdownTooltip(props) {
36607
36607
  ] }) })
36608
36608
  ] });
36609
36609
  }
36610
+ const CopyButton$1 = ({
36611
+ text,
36612
+ className = "",
36613
+ iconClassName = "",
36614
+ iconStyle,
36615
+ title = "Copy to clipboard",
36616
+ onCopySuccess,
36617
+ onCopyError,
36618
+ tooltipText = "Copied!",
36619
+ tooltipPosition = "bottom",
36620
+ size = "md"
36621
+ }) => {
36622
+ const [showTooltip, setShowTooltip] = useState(false);
36623
+ const getSizeClasses = () => {
36624
+ switch (size) {
36625
+ case "sm":
36626
+ return {
36627
+ button: "p-1",
36628
+ icon: "w-[12px] h-[12px]",
36629
+ tooltip: "text-xs py-1 px-2"
36630
+ };
36631
+ case "lg":
36632
+ return {
36633
+ button: "p-2",
36634
+ icon: "w-[20px] h-[20px]",
36635
+ tooltip: "text-sm py-2 px-3"
36636
+ };
36637
+ default:
36638
+ return {
36639
+ button: "p-1.5",
36640
+ icon: "w-[16px] h-[16px]",
36641
+ tooltip: "text-xs py-1 px-2"
36642
+ };
36643
+ }
36644
+ };
36645
+ const getTooltipPositionClasses = () => {
36646
+ const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
36647
+ switch (tooltipPosition) {
36648
+ case "bottom":
36649
+ return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
36650
+ case "left":
36651
+ return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
36652
+ case "right":
36653
+ return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
36654
+ default:
36655
+ return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
36656
+ }
36657
+ };
36658
+ const sizeClasses2 = getSizeClasses();
36659
+ const showCopyTooltip = useCallback(() => {
36660
+ setShowTooltip(true);
36661
+ setTimeout(() => setShowTooltip(false), 1e3);
36662
+ }, []);
36663
+ const copyToClipboard2 = useCallback(async () => {
36664
+ try {
36665
+ if (navigator.clipboard && navigator.clipboard.writeText) {
36666
+ await navigator.clipboard.writeText(text);
36667
+ showCopyTooltip();
36668
+ onCopySuccess == null ? void 0 : onCopySuccess();
36669
+ return;
36670
+ }
36671
+ const textArea = document.createElement("textarea");
36672
+ textArea.value = text;
36673
+ textArea.style.position = "fixed";
36674
+ textArea.style.left = "-999999px";
36675
+ textArea.style.top = "-999999px";
36676
+ document.body.appendChild(textArea);
36677
+ textArea.focus();
36678
+ textArea.select();
36679
+ try {
36680
+ document.execCommand("copy");
36681
+ showCopyTooltip();
36682
+ onCopySuccess == null ? void 0 : onCopySuccess();
36683
+ } catch (err) {
36684
+ const error = err instanceof Error ? err : new Error("Copy failed");
36685
+ console.warn("Copy to clipboard failed:", error);
36686
+ onCopyError == null ? void 0 : onCopyError(error);
36687
+ } finally {
36688
+ document.body.removeChild(textArea);
36689
+ }
36690
+ } catch (err) {
36691
+ const error = err instanceof Error ? err : new Error("Copy failed");
36692
+ console.warn("Copy to clipboard failed:", error);
36693
+ onCopyError == null ? void 0 : onCopyError(error);
36694
+ }
36695
+ }, [text, showCopyTooltip, onCopySuccess, onCopyError]);
36696
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
36697
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36698
+ "button",
36699
+ {
36700
+ onClick: copyToClipboard2,
36701
+ className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
36702
+ title,
36703
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
36704
+ }
36705
+ ),
36706
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36707
+ "div",
36708
+ {
36709
+ className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
36710
+ style: {
36711
+ visibility: showTooltip ? "visible" : "hidden"
36712
+ },
36713
+ children: tooltipText
36714
+ }
36715
+ )
36716
+ ] });
36717
+ };
36718
+ function CopyableId({ value, truncateLength = 30 }) {
36719
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "copyable-id-wrapper", title: value, children: [
36720
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900 truncate", children: TracingUtils.truncate(value, truncateLength) }),
36721
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
36722
+ "span",
36723
+ {
36724
+ className: "copyable-id-btn",
36725
+ onClick: (e3) => {
36726
+ e3.stopPropagation();
36727
+ e3.preventDefault();
36728
+ },
36729
+ onMouseDown: (e3) => e3.stopPropagation(),
36730
+ onMouseUp: (e3) => e3.stopPropagation(),
36731
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
36732
+ CopyButton$1,
36733
+ {
36734
+ text: value,
36735
+ size: "sm",
36736
+ title: "Copy to clipboard",
36737
+ iconClassName: "text-[#667085]"
36738
+ }
36739
+ )
36740
+ }
36741
+ )
36742
+ ] });
36743
+ }
36610
36744
  function Shimmer$2({ className = "", children }) {
36611
36745
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `animate-pulse bg-[#F2F4F7] rounded ${className}`, children });
36612
36746
  }
@@ -104617,6 +104751,9 @@ function TracingTable(props) {
104617
104751
  }, [columns]);
104618
104752
  const handleRowClick = useCallback(
104619
104753
  (event) => {
104754
+ var _a;
104755
+ const target = (_a = event.event) == null ? void 0 : _a.target;
104756
+ if (target == null ? void 0 : target.closest(".copyable-id-btn")) return;
104620
104757
  if (onRowClick && event.data) {
104621
104758
  onRowClick(event.data);
104622
104759
  }
@@ -104791,9 +104928,12 @@ function TracingListHeader(props) {
104791
104928
  timeRangePresetLabel,
104792
104929
  onTimeRangeChange,
104793
104930
  filters,
104931
+ filterColumns: filterColumnsProp,
104794
104932
  onFiltersClick,
104795
104933
  onModifyColumnsClick,
104796
104934
  showModifyColumns = true,
104935
+ onClearFilters,
104936
+ onRemoveFilter,
104797
104937
  onRefresh,
104798
104938
  isRefreshing = false
104799
104939
  } = props;
@@ -104838,6 +104978,50 @@ function TracingListHeader(props) {
104838
104978
  }
104839
104979
  return `Searches in ${fields}.`;
104840
104980
  };
104981
+ const activeFilters = filters.filter(TracingUtils.isFilterActive);
104982
+ const [filtersExpanded, setFiltersExpanded] = useState(false);
104983
+ const [isOverflowing, setIsOverflowing] = useState(false);
104984
+ const chipsContainerRef = useRef(null);
104985
+ const checkOverflow = useCallback(() => {
104986
+ const el = chipsContainerRef.current;
104987
+ if (!el) return;
104988
+ setIsOverflowing(el.scrollHeight > el.clientHeight);
104989
+ }, []);
104990
+ useEffect(() => {
104991
+ checkOverflow();
104992
+ window.addEventListener("resize", checkOverflow);
104993
+ return () => window.removeEventListener("resize", checkOverflow);
104994
+ }, [checkOverflow, activeFilters.length]);
104995
+ const getFilterChipLabel = (filter) => {
104996
+ const col = filterColumnsProp == null ? void 0 : filterColumnsProp.find((c3) => c3.field === filter.column);
104997
+ const label = (col == null ? void 0 : col.label) ?? filter.column;
104998
+ let valueText;
104999
+ if (filter.type === "datetime") {
105000
+ valueText = new Date(filter.value).toLocaleDateString();
105001
+ } else if (filter.type === "number") {
105002
+ valueText = parseFloat(filter.value).toLocaleString();
105003
+ } else if (Array.isArray(filter.value)) {
105004
+ valueText = filter.value.length <= 2 ? filter.value.join(", ") : `${filter.value.length} selected`;
105005
+ } else {
105006
+ valueText = String(filter.value ?? "");
105007
+ }
105008
+ const shortOp = {
105009
+ "=": "",
105010
+ "!=": "≠ ",
105011
+ ">": "> ",
105012
+ ">=": "≥ ",
105013
+ "<": "< ",
105014
+ "<=": "≤ ",
105015
+ "contains": "~ ",
105016
+ "does not contain": "!~ ",
105017
+ "starts with": "starts ",
105018
+ "ends with": "ends ",
105019
+ "any of": "",
105020
+ "none of": "not "
105021
+ };
105022
+ const op = shortOp[filter.operator] ?? `${filter.operator} `;
105023
+ return `${label}: ${op}${valueText}`;
105024
+ };
104841
105025
  const handleDateRangeChange = (dateRange, presetLabel) => {
104842
105026
  if (dateRange && dateRange.from && dateRange.to) {
104843
105027
  const fromDate = dateRange.from;
@@ -104990,7 +105174,66 @@ function TracingListHeader(props) {
104990
105174
  }
104991
105175
  )
104992
105176
  ] })
104993
- ] })
105177
+ ] }),
105178
+ activeFilters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
105179
+ "div",
105180
+ {
105181
+ className: "flex items-start gap-[8px] border border-gray-200 rounded-[8px] px-[12px] py-[8px]",
105182
+ "data-test-id": "tracing-filter-chips",
105183
+ children: [
105184
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium leading-[28px] text-gray-500 shrink-0", children: "Filters" }),
105185
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
105186
+ "div",
105187
+ {
105188
+ ref: chipsContainerRef,
105189
+ className: `flex items-center gap-[8px] flex-wrap flex-1 min-w-0 ${!filtersExpanded ? "max-h-[28px] overflow-hidden" : ""}`,
105190
+ children: activeFilters.map((filter, idx) => {
105191
+ const originalIndex = filters.indexOf(filter);
105192
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
105193
+ "div",
105194
+ {
105195
+ className: "inline-flex items-center gap-[4px] h-[28px] px-[10px] py-[4px] bg-blue-50 border border-blue-200 rounded-[6px] text-[12px] leading-[16px] text-blue-800 max-w-[260px]",
105196
+ children: [
105197
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate font-medium", children: getFilterChipLabel(filter) }),
105198
+ onRemoveFilter && /* @__PURE__ */ jsxRuntimeExports.jsx(
105199
+ "button",
105200
+ {
105201
+ onClick: () => onRemoveFilter(originalIndex),
105202
+ className: "flex items-center justify-center shrink-0 text-blue-400 hover:text-blue-700 transition-colors",
105203
+ title: "Remove filter",
105204
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[14px] h-[14px]", strokeWidth: 2 })
105205
+ }
105206
+ )
105207
+ ]
105208
+ },
105209
+ `chip-${idx}`
105210
+ );
105211
+ })
105212
+ }
105213
+ ),
105214
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px] shrink-0 leading-[28px]", children: [
105215
+ (isOverflowing || filtersExpanded) && /* @__PURE__ */ jsxRuntimeExports.jsx(
105216
+ "button",
105217
+ {
105218
+ onClick: () => setFiltersExpanded((prev) => !prev),
105219
+ className: "text-[12px] font-medium text-blue-600 hover:text-blue-800 transition-colors whitespace-nowrap",
105220
+ "data-test-id": "tracing-filter-toggle",
105221
+ children: filtersExpanded ? "View less" : "View all"
105222
+ }
105223
+ ),
105224
+ onClearFilters && /* @__PURE__ */ jsxRuntimeExports.jsx(
105225
+ "button",
105226
+ {
105227
+ onClick: onClearFilters,
105228
+ className: "text-[12px] font-medium text-gray-500 hover:text-gray-700 transition-colors whitespace-nowrap",
105229
+ "data-test-id": "tracing-filter-clear-all",
105230
+ children: "Clear all"
105231
+ }
105232
+ )
105233
+ ] })
105234
+ ]
105235
+ }
105236
+ )
104994
105237
  ] });
104995
105238
  }
104996
105239
  function ColumnCustomization(props) {
@@ -106069,6 +106312,7 @@ class DetailPageService {
106069
106312
  * Observations are loaded separately per trace when user expands
106070
106313
  */
106071
106314
  async fetchSessionDetail(sessionId) {
106315
+ var _a, _b;
106072
106316
  const sessionResponse = await this.apiService.fetchSessionById({
106073
106317
  sessionId,
106074
106318
  projectId: this.projectId
@@ -106083,6 +106327,10 @@ class DetailPageService {
106083
106327
  );
106084
106328
  traceDetails = traceResponses.map((trace) => this.transformToTraceDetailData(trace));
106085
106329
  }
106330
+ const firstTraceForSource = (_a = sessionResponse.traces) == null ? void 0 : _a[0];
106331
+ const sessionLevelSource = typeof sessionResponse.source === "string" && sessionResponse.source.length > 0 ? sessionResponse.source : void 0;
106332
+ const firstTraceSource = firstTraceForSource && typeof firstTraceForSource.source === "string" && firstTraceForSource.source.length > 0 ? firstTraceForSource.source : void 0;
106333
+ const resolvedSource = sessionLevelSource ?? firstTraceSource ?? ((_b = traceDetails[0]) == null ? void 0 : _b.source);
106086
106334
  return {
106087
106335
  id: sessionResponse.id,
106088
106336
  projectId: sessionResponse.projectId,
@@ -106090,7 +106338,8 @@ class DetailPageService {
106090
106338
  bookmarked: false,
106091
106339
  public: false,
106092
106340
  traces: traceDetails,
106093
- scores: []
106341
+ scores: [],
106342
+ source: resolvedSource
106094
106343
  };
106095
106344
  }
106096
106345
  /**
@@ -106162,15 +106411,21 @@ class DetailPageService {
106162
106411
  * @param onRemainingTrace - Callback for each additional trace as it loads (updates skeleton)
106163
106412
  */
106164
106413
  async fetchSessionDetailProgressive(sessionId, onSessionMeta, onFirstTrace, onRemainingTrace) {
106414
+ var _a, _b;
106165
106415
  const sessionResponse = await this.apiService.fetchSessionById({
106166
106416
  sessionId,
106167
106417
  projectId: this.projectId
106168
106418
  });
106169
106419
  const traceIds = (sessionResponse.traces || []).map((t2) => t2.id);
106420
+ const firstTrace = (_a = sessionResponse.traces) == null ? void 0 : _a[0];
106421
+ const firstTraceSource = firstTrace && typeof firstTrace.source === "string" && firstTrace.source.length > 0 ? firstTrace.source : void 0;
106422
+ const sessionLevelSource = typeof sessionResponse.source === "string" && sessionResponse.source.length > 0 ? sessionResponse.source : void 0;
106423
+ const resolvedSessionSource = sessionLevelSource ?? firstTraceSource;
106170
106424
  onSessionMeta({
106171
106425
  id: sessionResponse.id,
106172
106426
  traceCount: traceIds.length,
106173
- traceIds
106427
+ traceIds,
106428
+ source: resolvedSessionSource
106174
106429
  });
106175
106430
  if (traceIds.length === 0) {
106176
106431
  return {
@@ -106180,7 +106435,8 @@ class DetailPageService {
106180
106435
  bookmarked: false,
106181
106436
  public: false,
106182
106437
  traces: [],
106183
- scores: []
106438
+ scores: [],
106439
+ source: resolvedSessionSource
106184
106440
  };
106185
106441
  }
106186
106442
  const firstTraceId = traceIds[0];
@@ -106227,7 +106483,8 @@ class DetailPageService {
106227
106483
  bookmarked: false,
106228
106484
  public: false,
106229
106485
  traces: allTraces,
106230
- scores: []
106486
+ scores: [],
106487
+ source: resolvedSessionSource ?? ((_b = allTraces[0]) == null ? void 0 : _b.source)
106231
106488
  };
106232
106489
  }
106233
106490
  // ============================================================================
@@ -106321,6 +106578,7 @@ class DetailPageService {
106321
106578
  totalCost: trace.totalCost || trace.calculatedTotalCost,
106322
106579
  totalTokens: trace.totalTokens,
106323
106580
  environment: trace.environment,
106581
+ source: typeof trace.source === "string" && trace.source.length > 0 ? trace.source : void 0,
106324
106582
  observations: (trace.observations || []).map(
106325
106583
  (obs) => this.transformObservation(obs)
106326
106584
  ),
@@ -106729,6 +106987,7 @@ function TraceTree({
106729
106987
  onNodeSelect,
106730
106988
  onExpandToggle,
106731
106989
  showTraceId = true,
106990
+ onTraceIdClick,
106732
106991
  isLoading = false,
106733
106992
  defaultExpandedNodeIds,
106734
106993
  runHeaderInputMode = "display"
@@ -106789,7 +107048,16 @@ function TraceTree({
106789
107048
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-[4px] w-full mb-[8px]", children: [
106790
107049
  showTraceId && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-[8px] items-center px-0 py-[4px] w-full", children: [
106791
107050
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] leading-[12px] text-[#98A2B3]", children: "Trace ID" }),
106792
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
107051
+ onTraceIdClick ? /* @__PURE__ */ jsxRuntimeExports.jsx(
107052
+ "button",
107053
+ {
107054
+ onClick: () => onTraceIdClick(trace.id),
107055
+ className: "font-medium text-[10px] leading-[12px] text-[#155EEF] hover:underline cursor-pointer bg-transparent border-none p-0",
107056
+ title: "View Trace Details",
107057
+ "data-test-id": `trace-tree-id-link-${trace.id}`,
107058
+ children: trace.id
107059
+ }
107060
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-[10px] leading-[12px] text-[#667085]", children: trace.id }),
106793
107061
  /* @__PURE__ */ jsxRuntimeExports.jsx(
106794
107062
  "button",
106795
107063
  {
@@ -106908,114 +107176,6 @@ function TraceTree({
106908
107176
  ] })
106909
107177
  ] });
106910
107178
  }
106911
- const CopyButton$1 = ({
106912
- text,
106913
- className = "",
106914
- iconClassName = "",
106915
- iconStyle,
106916
- title = "Copy to clipboard",
106917
- onCopySuccess,
106918
- onCopyError,
106919
- tooltipText = "Copied!",
106920
- tooltipPosition = "bottom",
106921
- size = "md"
106922
- }) => {
106923
- const [showTooltip, setShowTooltip] = useState(false);
106924
- const getSizeClasses = () => {
106925
- switch (size) {
106926
- case "sm":
106927
- return {
106928
- button: "p-1",
106929
- icon: "w-[12px] h-[12px]",
106930
- tooltip: "text-xs py-1 px-2"
106931
- };
106932
- case "lg":
106933
- return {
106934
- button: "p-2",
106935
- icon: "w-[20px] h-[20px]",
106936
- tooltip: "text-sm py-2 px-3"
106937
- };
106938
- default:
106939
- return {
106940
- button: "p-1.5",
106941
- icon: "w-[16px] h-[16px]",
106942
- tooltip: "text-xs py-1 px-2"
106943
- };
106944
- }
106945
- };
106946
- const getTooltipPositionClasses = () => {
106947
- const baseClasses = "absolute bg-gray-800 text-white rounded whitespace-nowrap z-50";
106948
- switch (tooltipPosition) {
106949
- case "bottom":
106950
- return `${baseClasses} top-full mt-1 left-1/2 -translate-x-1/2`;
106951
- case "left":
106952
- return `${baseClasses} right-full mr-1 top-1/2 -translate-y-1/2`;
106953
- case "right":
106954
- return `${baseClasses} left-full ml-1 top-1/2 -translate-y-1/2`;
106955
- default:
106956
- return `${baseClasses} bottom-full mb-1 left-1/2 -translate-x-1/2`;
106957
- }
106958
- };
106959
- const sizeClasses2 = getSizeClasses();
106960
- const showCopyTooltip = useCallback(() => {
106961
- setShowTooltip(true);
106962
- setTimeout(() => setShowTooltip(false), 1e3);
106963
- }, []);
106964
- const copyToClipboard2 = useCallback(async () => {
106965
- try {
106966
- if (navigator.clipboard && navigator.clipboard.writeText) {
106967
- await navigator.clipboard.writeText(text);
106968
- showCopyTooltip();
106969
- onCopySuccess == null ? void 0 : onCopySuccess();
106970
- return;
106971
- }
106972
- const textArea = document.createElement("textarea");
106973
- textArea.value = text;
106974
- textArea.style.position = "fixed";
106975
- textArea.style.left = "-999999px";
106976
- textArea.style.top = "-999999px";
106977
- document.body.appendChild(textArea);
106978
- textArea.focus();
106979
- textArea.select();
106980
- try {
106981
- document.execCommand("copy");
106982
- showCopyTooltip();
106983
- onCopySuccess == null ? void 0 : onCopySuccess();
106984
- } catch (err) {
106985
- const error = err instanceof Error ? err : new Error("Copy failed");
106986
- console.warn("Copy to clipboard failed:", error);
106987
- onCopyError == null ? void 0 : onCopyError(error);
106988
- } finally {
106989
- document.body.removeChild(textArea);
106990
- }
106991
- } catch (err) {
106992
- const error = err instanceof Error ? err : new Error("Copy failed");
106993
- console.warn("Copy to clipboard failed:", error);
106994
- onCopyError == null ? void 0 : onCopyError(error);
106995
- }
106996
- }, [text, showCopyTooltip, onCopySuccess, onCopyError]);
106997
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative inline-flex", children: [
106998
- /* @__PURE__ */ jsxRuntimeExports.jsx(
106999
- "button",
107000
- {
107001
- onClick: copyToClipboard2,
107002
- className: `${sizeClasses2.button} hover:bg-gray-100 rounded transition-colors ${className}`,
107003
- title,
107004
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: `${sizeClasses2.icon} text-gray-400 ${iconClassName}`, style: iconStyle })
107005
- }
107006
- ),
107007
- /* @__PURE__ */ jsxRuntimeExports.jsx(
107008
- "div",
107009
- {
107010
- className: `${getTooltipPositionClasses()} ${sizeClasses2.tooltip} transition-opacity duration-150 ${showTooltip ? "opacity-100 animate-fade-in" : "opacity-0 pointer-events-none"}`,
107011
- style: {
107012
- visibility: showTooltip ? "visible" : "hidden"
107013
- },
107014
- children: tooltipText
107015
- }
107016
- )
107017
- ] });
107018
- };
107019
107179
  function __awaiter(thisArg, _arguments, P2, generator) {
107020
107180
  function adopt(value) {
107021
107181
  return value instanceof P2 ? value : new P2(function(resolve) {
@@ -108772,10 +108932,12 @@ function CodeEditorSection({
108772
108932
  showHeader: true,
108773
108933
  useEnhancedJsonView: true,
108774
108934
  collapseStringsAfterLength: 500,
108775
- collapseObjectsAfterLength: 20,
108935
+ collapseObjectsAfterLength: selectedTab === "metadata" ? 100 : 20,
108936
+ defaultExpanded: selectedTab === "metadata",
108776
108937
  maxHeight: "100%",
108777
108938
  className: "h-full border-0 rounded-none"
108778
- }
108939
+ },
108940
+ selectedTab
108779
108941
  ) })
108780
108942
  ] });
108781
108943
  }
@@ -109144,6 +109306,521 @@ function NodeDetailPanel({
109144
109306
  )
109145
109307
  ] });
109146
109308
  }
109309
+ 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: [
109310
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109311
+ "path",
109312
+ {
109313
+ 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",
109314
+ style: { fill: "#155EEF" }
109315
+ }
109316
+ ),
109317
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109318
+ "path",
109319
+ {
109320
+ 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",
109321
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109322
+ }
109323
+ ),
109324
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109325
+ "path",
109326
+ {
109327
+ d: "M8 9V11",
109328
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109329
+ }
109330
+ ),
109331
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109332
+ "path",
109333
+ {
109334
+ d: "M6.5 11H9.5",
109335
+ style: { stroke: "#155EEF", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }
109336
+ }
109337
+ )
109338
+ ] });
109339
+ function VoiceEventLogsBanner({ onViewEventLogs }) {
109340
+ 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: [
109341
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109342
+ /* @__PURE__ */ jsxRuntimeExports.jsx(MicIcon, {}),
109343
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold text-[11px] leading-[14px] text-[#98A2B3] uppercase tracking-[0.04em]", children: "Voice-to-Voice Event Logs" })
109344
+ ] }),
109345
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109346
+ "button",
109347
+ {
109348
+ onClick: onViewEventLogs,
109349
+ className: "text-[12px] font-medium text-[#155EEF] hover:text-[#344054] hover:underline transition-colors cursor-pointer bg-transparent border-none p-0",
109350
+ "data-test-id": "view-event-logs-btn",
109351
+ children: "View Event Logs"
109352
+ }
109353
+ )
109354
+ ] });
109355
+ }
109356
+ function AlignLeftIcon({ className }) {
109357
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109358
+ "svg",
109359
+ {
109360
+ width: "16",
109361
+ height: "16",
109362
+ viewBox: "0 0 16 16",
109363
+ fill: "none",
109364
+ xmlns: "http://www.w3.org/2000/svg",
109365
+ className,
109366
+ "aria-hidden": "true",
109367
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109368
+ "path",
109369
+ {
109370
+ d: "M10.6667 6.66667H2M13.3333 4H2M13.3333 9.33333H2M10.6667 12H2",
109371
+ stroke: "currentColor",
109372
+ strokeWidth: "1.3",
109373
+ strokeLinecap: "round",
109374
+ strokeLinejoin: "round"
109375
+ }
109376
+ )
109377
+ }
109378
+ );
109379
+ }
109380
+ function JsonViewIcon({ className }) {
109381
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
109382
+ "svg",
109383
+ {
109384
+ width: "16",
109385
+ height: "16",
109386
+ viewBox: "0 0 16 16",
109387
+ fill: "none",
109388
+ xmlns: "http://www.w3.org/2000/svg",
109389
+ className,
109390
+ "aria-hidden": "true",
109391
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109392
+ "path",
109393
+ {
109394
+ 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",
109395
+ stroke: "currentColor",
109396
+ strokeWidth: "1.3",
109397
+ strokeLinecap: "round",
109398
+ strokeLinejoin: "round"
109399
+ }
109400
+ )
109401
+ }
109402
+ );
109403
+ }
109404
+ function pickString(obj, keys2) {
109405
+ for (const key of keys2) {
109406
+ const value = obj[key];
109407
+ if (typeof value === "string" && value.length > 0) return value;
109408
+ if (typeof value === "number") return String(value);
109409
+ }
109410
+ return void 0;
109411
+ }
109412
+ function coerceDirection(raw) {
109413
+ if (raw === "incoming" || raw === "server" || raw === "response") return "in";
109414
+ return "out";
109415
+ }
109416
+ function normalizeEvent(raw, fallbackId, docTimestamp) {
109417
+ if (!raw || typeof raw !== "object") {
109418
+ return {
109419
+ id: fallbackId,
109420
+ timestamp: docTimestamp,
109421
+ name: "event",
109422
+ direction: "out",
109423
+ payload: raw
109424
+ };
109425
+ }
109426
+ const obj = raw;
109427
+ const id = pickString(obj, ["event_id", "eventId", "_id", "id"]) ?? fallbackId;
109428
+ const name = pickString(obj, ["type", "eventType", "event", "name"]) ?? "event";
109429
+ const direction = coerceDirection(obj.direction);
109430
+ return {
109431
+ id,
109432
+ timestamp: docTimestamp,
109433
+ name,
109434
+ direction,
109435
+ payload: raw
109436
+ };
109437
+ }
109438
+ function flattenEvents(data) {
109439
+ if (data === null || data === void 0) return [];
109440
+ const out = [];
109441
+ const visitDoc = (doc2, docIdx) => {
109442
+ if (!doc2 || typeof doc2 !== "object") return;
109443
+ const docObj = doc2;
109444
+ const docTimestamp = pickString(docObj, ["createdOn", "sT", "createdAt"]);
109445
+ const events = docObj.events;
109446
+ if (Array.isArray(events)) {
109447
+ events.forEach((ev, evIdx) => {
109448
+ out.push(normalizeEvent(ev, `${docIdx}-${evIdx}`, docTimestamp));
109449
+ });
109450
+ } else {
109451
+ out.push(normalizeEvent(doc2, String(docIdx), docTimestamp));
109452
+ }
109453
+ };
109454
+ if (Array.isArray(data)) {
109455
+ data.forEach((doc2, docIdx) => visitDoc(doc2, docIdx));
109456
+ return out;
109457
+ }
109458
+ if (typeof data === "object") {
109459
+ const obj = data;
109460
+ if (Array.isArray(obj.events)) {
109461
+ visitDoc(obj, 0);
109462
+ return out;
109463
+ }
109464
+ if (Array.isArray(obj.data)) {
109465
+ return flattenEvents(obj.data);
109466
+ }
109467
+ }
109468
+ return [];
109469
+ }
109470
+ function formatEventTime(iso) {
109471
+ if (!iso) return "--:--:--:---";
109472
+ const d3 = new Date(iso);
109473
+ if (Number.isNaN(d3.getTime())) return "--:--:--:---";
109474
+ const hh = String(d3.getHours()).padStart(2, "0");
109475
+ const mm = String(d3.getMinutes()).padStart(2, "0");
109476
+ const ss = String(d3.getSeconds()).padStart(2, "0");
109477
+ const ms = String(d3.getMilliseconds()).padStart(3, "0");
109478
+ return `${hh}:${mm}:${ss}:${ms}`;
109479
+ }
109480
+ function stringifyPayload(payload) {
109481
+ if (payload === null || payload === void 0) return "";
109482
+ if (typeof payload === "string") {
109483
+ try {
109484
+ return JSON.stringify(JSON.parse(payload), null, 2);
109485
+ } catch {
109486
+ return payload;
109487
+ }
109488
+ }
109489
+ try {
109490
+ return JSON.stringify(payload, null, 2);
109491
+ } catch {
109492
+ return String(payload);
109493
+ }
109494
+ }
109495
+ function compactPayload(payload) {
109496
+ if (payload === null || payload === void 0) return "";
109497
+ if (typeof payload === "string") {
109498
+ try {
109499
+ return JSON.stringify(JSON.parse(payload));
109500
+ } catch {
109501
+ return payload;
109502
+ }
109503
+ }
109504
+ try {
109505
+ return JSON.stringify(payload);
109506
+ } catch {
109507
+ return String(payload);
109508
+ }
109509
+ }
109510
+ function PayloadPanel({ payload, compactText }) {
109511
+ const [viewMode, setViewMode] = useState("json");
109512
+ const [fullscreen, setFullscreen] = useState(false);
109513
+ const [copied, setCopied] = useState(false);
109514
+ const displayText = viewMode === "json" ? payload : compactText;
109515
+ const handleCopy = useCallback(async () => {
109516
+ try {
109517
+ await navigator.clipboard.writeText(displayText);
109518
+ setCopied(true);
109519
+ setTimeout(() => setCopied(false), 1500);
109520
+ } catch {
109521
+ }
109522
+ }, [displayText]);
109523
+ 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: [
109524
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109525
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109526
+ "button",
109527
+ {
109528
+ type: "button",
109529
+ onClick: () => setViewMode("json"),
109530
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109531
+ title: "Pretty JSON",
109532
+ "aria-label": "Pretty JSON view",
109533
+ "aria-pressed": viewMode === "json",
109534
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109535
+ }
109536
+ ),
109537
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109538
+ "button",
109539
+ {
109540
+ type: "button",
109541
+ onClick: () => setViewMode("text"),
109542
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109543
+ title: "Compact text",
109544
+ "aria-label": "Compact text view",
109545
+ "aria-pressed": viewMode === "text",
109546
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109547
+ }
109548
+ )
109549
+ ] }),
109550
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109551
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109552
+ "button",
109553
+ {
109554
+ type: "button",
109555
+ onClick: () => setFullscreen((v) => !v),
109556
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109557
+ title: fullscreen ? "Exit fullscreen" : "Fullscreen",
109558
+ "aria-label": fullscreen ? "Exit fullscreen" : "Fullscreen",
109559
+ children: fullscreen ? /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "w-[16px] h-[16px]" })
109560
+ }
109561
+ ),
109562
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109563
+ "button",
109564
+ {
109565
+ type: "button",
109566
+ onClick: () => void handleCopy(),
109567
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109568
+ title: "Copy to clipboard",
109569
+ "aria-label": "Copy payload",
109570
+ "data-test-id": "event-logs-row-copy",
109571
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109572
+ }
109573
+ )
109574
+ ] })
109575
+ ] });
109576
+ if (fullscreen) {
109577
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[20000] flex flex-col bg-[#F9FAFB]", children: [
109578
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "h-[48px] px-[16px] border-b border-[#E4E7EC] flex items-center justify-between flex-shrink-0 bg-white", children: [
109579
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109580
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109581
+ "button",
109582
+ {
109583
+ type: "button",
109584
+ onClick: () => setViewMode("json"),
109585
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "json" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109586
+ title: "Pretty JSON",
109587
+ "aria-label": "Pretty JSON view",
109588
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonViewIcon, { className: "w-[16px] h-[16px]" })
109589
+ }
109590
+ ),
109591
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109592
+ "button",
109593
+ {
109594
+ type: "button",
109595
+ onClick: () => setViewMode("text"),
109596
+ className: `p-[5px] rounded-[4px] transition-colors ${viewMode === "text" ? "text-[#155EEF] bg-[#EFF4FF]" : "text-[#98A2B3] hover:bg-[#F2F4F7]"}`,
109597
+ title: "Compact text",
109598
+ "aria-label": "Compact text view",
109599
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeftIcon, { className: "w-[16px] h-[16px]" })
109600
+ }
109601
+ )
109602
+ ] }),
109603
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109604
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109605
+ "button",
109606
+ {
109607
+ type: "button",
109608
+ onClick: () => void handleCopy(),
109609
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109610
+ title: "Copy to clipboard",
109611
+ "aria-label": "Copy payload",
109612
+ children: copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-[16px] h-[16px] text-[#12B76A]" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-[16px] h-[16px]" })
109613
+ }
109614
+ ),
109615
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109616
+ "button",
109617
+ {
109618
+ type: "button",
109619
+ onClick: () => setFullscreen(false),
109620
+ className: "p-[5px] rounded-[4px] text-[#98A2B3] hover:bg-[#F2F4F7] transition-colors",
109621
+ title: "Exit fullscreen",
109622
+ "aria-label": "Exit fullscreen",
109623
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Minimize2, { className: "w-[16px] h-[16px]" })
109624
+ }
109625
+ )
109626
+ ] })
109627
+ ] }),
109628
+ /* @__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 })
109629
+ ] }) });
109630
+ }
109631
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-[10px] border border-[#D0D5DD] overflow-hidden mt-[12px]", children: [
109632
+ toolbar,
109633
+ /* @__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 })
109634
+ ] });
109635
+ }
109636
+ function EventRow({ event, isExpanded, onToggle }) {
109637
+ const jsonText = useMemo(() => stringifyPayload(event.payload), [event.payload]);
109638
+ const compactText = useMemo(() => compactPayload(event.payload), [event.payload]);
109639
+ const hasPayload = jsonText.length > 0;
109640
+ const isInput = event.direction === "in";
109641
+ const DirectionIcon = isInput ? ArrowUp : ArrowDown;
109642
+ const directionLabel = isInput ? "Input" : "Output";
109643
+ const circleClasses = isInput ? "border-[#079455] text-[#079455]" : "border-[#D92D20] text-[#D92D20]";
109644
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex items-start gap-[12px]", "data-test-id": "event-logs-row", children: [
109645
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "relative flex-shrink-0 flex flex-col items-center w-[16px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
109646
+ "div",
109647
+ {
109648
+ className: `relative z-10 w-[16px] h-[16px] rounded-full bg-white border flex items-center justify-center ${circleClasses}`,
109649
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(DirectionIcon, { className: "w-[8px] h-[8px]", strokeWidth: 2.5 })
109650
+ }
109651
+ ) }),
109652
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 pb-[24px]", children: [
109653
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-[16px]", children: [
109654
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
109655
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[12px] leading-[16px] text-[#667085]", children: directionLabel }),
109656
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[14px] leading-[20px] font-medium text-[#344054] mt-[2px] break-all", children: event.name }),
109657
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109658
+ "button",
109659
+ {
109660
+ type: "button",
109661
+ onClick: onToggle,
109662
+ className: "text-[13px] leading-[18px] text-[#155EEF] hover:underline mt-[4px] font-medium",
109663
+ "data-test-id": "event-logs-view-details",
109664
+ children: isExpanded ? "Hide details" : "View details"
109665
+ }
109666
+ )
109667
+ ] }),
109668
+ /* @__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) })
109669
+ ] }),
109670
+ 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." }))
109671
+ ] })
109672
+ ] });
109673
+ }
109674
+ function EventLogsSlideout({
109675
+ isOpen,
109676
+ onClose,
109677
+ sessionId,
109678
+ fetchEventLogs
109679
+ }) {
109680
+ const [rawData, setRawData] = useState(null);
109681
+ const [loading, setLoading] = useState(false);
109682
+ const [error, setError] = useState(null);
109683
+ const [expandedIds, setExpandedIds] = useState(() => /* @__PURE__ */ new Set());
109684
+ useEffect(() => {
109685
+ if (!isOpen || !sessionId || !fetchEventLogs) return;
109686
+ let cancelled = false;
109687
+ setLoading(true);
109688
+ setError(null);
109689
+ setRawData(null);
109690
+ (async () => {
109691
+ try {
109692
+ const data = await fetchEventLogs(sessionId);
109693
+ if (cancelled) return;
109694
+ setRawData(data);
109695
+ } catch (err) {
109696
+ if (cancelled) return;
109697
+ setError(err instanceof Error ? err.message : "Failed to fetch event logs");
109698
+ } finally {
109699
+ if (!cancelled) setLoading(false);
109700
+ }
109701
+ })();
109702
+ return () => {
109703
+ cancelled = true;
109704
+ };
109705
+ }, [isOpen, sessionId, fetchEventLogs]);
109706
+ const events = useMemo(() => flattenEvents(rawData), [rawData]);
109707
+ useEffect(() => {
109708
+ if (!isOpen) return;
109709
+ const handleKey = (e3) => {
109710
+ if (e3.key === "Escape") onClose();
109711
+ };
109712
+ document.addEventListener("keydown", handleKey);
109713
+ return () => document.removeEventListener("keydown", handleKey);
109714
+ }, [isOpen, onClose]);
109715
+ useEffect(() => {
109716
+ if (!isOpen) {
109717
+ setExpandedIds(/* @__PURE__ */ new Set());
109718
+ setRawData(null);
109719
+ setError(null);
109720
+ }
109721
+ }, [isOpen]);
109722
+ const toggleRow = useCallback((id) => {
109723
+ setExpandedIds((prev) => {
109724
+ const next = new Set(prev);
109725
+ if (next.has(id)) next.delete(id);
109726
+ else next.add(id);
109727
+ return next;
109728
+ });
109729
+ }, []);
109730
+ const expandAll = useCallback(() => {
109731
+ setExpandedIds(new Set(events.map((e3) => e3.id)));
109732
+ }, [events]);
109733
+ const collapseAll = useCallback(() => {
109734
+ setExpandedIds(/* @__PURE__ */ new Set());
109735
+ }, []);
109736
+ if (!isOpen) return null;
109737
+ const showToolbar = !loading && !error && events.length > 0;
109738
+ const allExpanded = showToolbar && expandedIds.size === events.length;
109739
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Portal, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-[10000]", children: [
109740
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109741
+ "div",
109742
+ {
109743
+ className: "absolute inset-0 bg-black/40",
109744
+ onClick: onClose,
109745
+ "aria-hidden": "true"
109746
+ }
109747
+ ),
109748
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
109749
+ "div",
109750
+ {
109751
+ className: "absolute top-0 right-0 bottom-0 bg-white shadow-2xl flex flex-col",
109752
+ style: { width: "720px", maxWidth: "100vw" },
109753
+ role: "dialog",
109754
+ "aria-label": "Event Logs",
109755
+ onClick: (e3) => e3.stopPropagation(),
109756
+ children: [
109757
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between h-[56px] px-[20px] border-b border-[#E4E7EC] flex-shrink-0", children: [
109758
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[8px]", children: [
109759
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[16px] font-semibold text-[#101828]", children: "Event Logs" }),
109760
+ !loading && !error && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] font-medium text-[#667085] bg-[#F2F4F7] rounded-[10px] px-[8px] py-[2px]", children: events.length })
109761
+ ] }),
109762
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-[4px]", children: [
109763
+ showToolbar && /* @__PURE__ */ jsxRuntimeExports.jsx(
109764
+ "button",
109765
+ {
109766
+ type: "button",
109767
+ onClick: allExpanded ? collapseAll : expandAll,
109768
+ className: "text-[13px] font-medium text-[#155EEF] hover:underline px-[8px] py-[6px] rounded-[6px] transition-colors",
109769
+ "data-test-id": "event-logs-toggle-all",
109770
+ children: allExpanded ? "Collapse all" : "Expand all"
109771
+ }
109772
+ ),
109773
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
109774
+ "button",
109775
+ {
109776
+ type: "button",
109777
+ onClick: onClose,
109778
+ className: "p-[8px] rounded-[6px] hover:bg-[#F2F4F7] transition-colors",
109779
+ title: "Close Event Logs",
109780
+ "aria-label": "Close Event Logs",
109781
+ "data-test-id": "event-logs-close-btn",
109782
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-[16px] h-[16px] text-[#344054]" })
109783
+ }
109784
+ )
109785
+ ] })
109786
+ ] }),
109787
+ /* @__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: [
109788
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-[20px] h-[20px] animate-spin text-[#155EEF]" }),
109789
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Loading event logs…" })
109790
+ ] }) : 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: [
109791
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Couldn't load event logs" }),
109792
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[12px] text-[#667085]", children: error })
109793
+ ] }) : 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: [
109794
+ events.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
109795
+ "div",
109796
+ {
109797
+ className: "absolute w-px bg-[#D0D5DD]",
109798
+ style: { left: "32px", top: "36px", bottom: "28px" },
109799
+ "aria-hidden": "true"
109800
+ }
109801
+ ),
109802
+ events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(
109803
+ EventRow,
109804
+ {
109805
+ event,
109806
+ isExpanded: expandedIds.has(event.id),
109807
+ onToggle: () => toggleRow(event.id)
109808
+ },
109809
+ event.id
109810
+ ))
109811
+ ] }) })
109812
+ ]
109813
+ }
109814
+ )
109815
+ ] }) });
109816
+ }
109817
+ const SESSION_SOURCES_WITH_EVENT_LOGS = /* @__PURE__ */ new Set(["AIS-CC", "XO"]);
109818
+ function sessionSourceShowsEventLogs(source) {
109819
+ if (source === void 0 || source === "") {
109820
+ return false;
109821
+ }
109822
+ return SESSION_SOURCES_WITH_EVENT_LOGS.has(source);
109823
+ }
109147
109824
  function DetailPage({
109148
109825
  mode: initialMode,
109149
109826
  sessionId: initialSessionId,
@@ -109156,7 +109833,9 @@ function DetailPage({
109156
109833
  batchSize = DEFAULT_BATCH_SIZE,
109157
109834
  initialTraceCount,
109158
109835
  initialSessionData,
109159
- runHeaderInputMode = "display"
109836
+ runHeaderInputMode = "display",
109837
+ onViewEventLogs,
109838
+ fetchEventLogs
109160
109839
  }) {
109161
109840
  const [currentMode, setCurrentMode] = useState(initialMode);
109162
109841
  const [currentSessionId, setCurrentSessionId] = useState(initialSessionId);
@@ -109166,6 +109845,7 @@ function DetailPage({
109166
109845
  const traceId = currentTraceId;
109167
109846
  const [selectedNode, setSelectedNode] = useState(null);
109168
109847
  const [copiedId, setCopiedId] = useState(false);
109848
+ const [isEventLogsOpen, setIsEventLogsOpen] = useState(false);
109169
109849
  const minObservationLevel = "DEFAULT";
109170
109850
  const [hasAutoSelected, setHasAutoSelected] = useState(false);
109171
109851
  const hasInitialData = mode === "session" && initialSessionData;
@@ -109211,7 +109891,8 @@ function DetailPage({
109211
109891
  bookmarked: false,
109212
109892
  public: false,
109213
109893
  traces: [],
109214
- scores: []
109894
+ scores: [],
109895
+ source: meta.source
109215
109896
  });
109216
109897
  setLoadingState("success");
109217
109898
  },
@@ -109219,7 +109900,8 @@ function DetailPage({
109219
109900
  (trace, observations) => {
109220
109901
  setSessionData((prev) => prev ? {
109221
109902
  ...prev,
109222
- traces: [trace]
109903
+ traces: [trace],
109904
+ source: prev.source ?? trace.source
109223
109905
  } : prev);
109224
109906
  setTraceObservations((prev) => ({
109225
109907
  ...prev,
@@ -109395,6 +110077,10 @@ function DetailPage({
109395
110077
  } : null
109396
110078
  };
109397
110079
  }, [mode, sessionData, traceData, sessionId, traceId, initialSessionData]);
110080
+ const sessionSourceForEventLogs = useMemo(() => {
110081
+ return (initialSessionData == null ? void 0 : initialSessionData.source) ?? (sessionData == null ? void 0 : sessionData.source);
110082
+ }, [initialSessionData == null ? void 0 : initialSessionData.source, sessionData == null ? void 0 : sessionData.source]);
110083
+ const showEventLogsBanner = mode === "session" && sessionSourceShowsEventLogs(sessionSourceForEventLogs);
109398
110084
  const traces = useMemo(() => {
109399
110085
  if (mode === "session" && sessionData) {
109400
110086
  const sorted = [...sessionData.traces].sort((a4, b2) => {
@@ -109443,6 +110129,16 @@ function DetailPage({
109443
110129
  mode,
109444
110130
  traceData
109445
110131
  ]);
110132
+ const handleViewEventLogs = useCallback(() => {
110133
+ setIsEventLogsOpen(true);
110134
+ if (onViewEventLogs && sessionId) {
110135
+ const firstTraceId = traces.length > 0 ? traces[0].id : void 0;
110136
+ onViewEventLogs(sessionId, firstTraceId);
110137
+ }
110138
+ }, [onViewEventLogs, sessionId, traces]);
110139
+ const handleCloseEventLogs = useCallback(() => {
110140
+ setIsEventLogsOpen(false);
110141
+ }, []);
109446
110142
  const handleNodeSelect = useCallback((node) => {
109447
110143
  setSelectedNode(node);
109448
110144
  }, []);
@@ -109491,6 +110187,23 @@ function DetailPage({
109491
110187
  firstTraceId: null
109492
110188
  });
109493
110189
  }, []);
110190
+ const handleNavigateToTrace = useCallback((targetTraceId) => {
110191
+ setSelectedNode(null);
110192
+ setSessionData(null);
110193
+ setTraceData(null);
110194
+ setTraceObservations({});
110195
+ setLoadingState("idle");
110196
+ setError(null);
110197
+ setHasAutoSelected(false);
110198
+ setCurrentMode("trace");
110199
+ setCurrentTraceId(targetTraceId);
110200
+ setProgressiveState({
110201
+ traceCount: 0,
110202
+ pendingTraceIds: [],
110203
+ firstTraceLoaded: false,
110204
+ firstTraceId: null
110205
+ });
110206
+ }, []);
109494
110207
  if (loadingState === "loading") {
109495
110208
  const canShowHeader = mode === "session" && initialSessionData;
109496
110209
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col bg-white ${className}`, children: [
@@ -109642,6 +110355,7 @@ function DetailPage({
109642
110355
  ] }),
109643
110356
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
109644
110357
  /* @__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: [
110358
+ showEventLogsBanner && /* @__PURE__ */ jsxRuntimeExports.jsx(VoiceEventLogsBanner, { onViewEventLogs: handleViewEventLogs }),
109645
110359
  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" }),
109646
110360
  traces.map((trace, index) => {
109647
110361
  var _a, _b, _c, _d;
@@ -109659,6 +110373,7 @@ function DetailPage({
109659
110373
  onNodeSelect: handleNodeSelect,
109660
110374
  onExpandToggle: () => handleTraceExpand(trace.id, trace.timestamp),
109661
110375
  showTraceId: mode === "session",
110376
+ onTraceIdClick: mode === "session" ? handleNavigateToTrace : void 0,
109662
110377
  isLoading: isLoadingObservations,
109663
110378
  defaultExpandedNodeIds: autoExpandIds,
109664
110379
  runHeaderInputMode
@@ -109690,7 +110405,16 @@ function DetailPage({
109690
110405
  generationSummaryInputOverride
109691
110406
  }
109692
110407
  )
109693
- ] })
110408
+ ] }),
110409
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
110410
+ EventLogsSlideout,
110411
+ {
110412
+ isOpen: isEventLogsOpen,
110413
+ onClose: handleCloseEventLogs,
110414
+ sessionId: sessionId ?? null,
110415
+ fetchEventLogs
110416
+ }
110417
+ )
109694
110418
  ] });
109695
110419
  }
109696
110420
  const trace1Observations = [
@@ -110104,8 +110828,8 @@ function EnvironmentNameCell$1({ envId }) {
110104
110828
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", title: envId || "-", children: displayName });
110105
110829
  }
110106
110830
  function SessionsListContent(props) {
110107
- const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId } = props;
110108
- const { environments } = useEnvironment();
110831
+ const { apiConfig, onSessionClick, className = "", defaultFilters = [], defaultTimeRange = "24 hours", initialSessionId, onViewEventLogs, fetchEventLogs } = props;
110832
+ const { environments, resolveEnvironmentName } = useEnvironment();
110109
110833
  const [selectedSessionId, setSelectedSessionId] = useState(() => initialSessionId ?? null);
110110
110834
  const [selectedSessionData, setSelectedSessionData] = useState(null);
110111
110835
  const [isModalOpen, setIsModalOpen] = useState(() => !!initialSessionId);
@@ -110113,6 +110837,8 @@ function SessionsListContent(props) {
110113
110837
  const [totalCount, setTotalCount] = useState(0);
110114
110838
  const [loading, setLoading] = useState(true);
110115
110839
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
110840
+ const [appVersionOptions, setAppVersionOptions] = useState([]);
110841
+ const [searchTerm, setSearchTerm] = useState("");
110116
110842
  const initialFilters = useMemo(() => {
110117
110843
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
110118
110844
  const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter$1(), ...defaultFilters];
@@ -110135,6 +110861,26 @@ function SessionsListContent(props) {
110135
110861
  setIsModalOpen(true);
110136
110862
  }
110137
110863
  }, [initialSessionId]);
110864
+ useEffect(() => {
110865
+ const fetchAppVersions = async () => {
110866
+ try {
110867
+ const filterOptionsData = await apiService.fetchFilterOptions({
110868
+ projectId: apiConfig.projectId
110869
+ });
110870
+ if ((filterOptionsData == null ? void 0 : filterOptionsData.appvIds) && Array.isArray(filterOptionsData.appvIds)) {
110871
+ setAppVersionOptions(
110872
+ filterOptionsData.appvIds.map((item) => ({
110873
+ value: item.value,
110874
+ label: item.value
110875
+ }))
110876
+ );
110877
+ }
110878
+ } catch (error) {
110879
+ console.warn("Failed to fetch app version filter options:", error);
110880
+ }
110881
+ };
110882
+ fetchAppVersions();
110883
+ }, [apiService, apiConfig.projectId]);
110138
110884
  const convertPresetToDateRange = (preset) => {
110139
110885
  const now2 = /* @__PURE__ */ new Date();
110140
110886
  let pastDate;
@@ -110196,7 +110942,6 @@ function SessionsListContent(props) {
110196
110942
  });
110197
110943
  }
110198
110944
  const allFilters = [...timeFilters, ...filters];
110199
- if (apiConfig.projectId) ;
110200
110945
  return allFilters;
110201
110946
  }, [timeRange, filters]);
110202
110947
  const fetchSessions = useCallback(async () => {
@@ -110256,6 +111001,28 @@ function SessionsListContent(props) {
110256
111001
  useEffect(() => {
110257
111002
  fetchSessions();
110258
111003
  }, [fetchSessions]);
111004
+ const filteredSessions = useMemo(() => {
111005
+ const term = searchTerm.trim().toLowerCase();
111006
+ if (!term) return sessions;
111007
+ return sessions.filter((session) => {
111008
+ var _a;
111009
+ const envName = ((_a = resolveEnvironmentName(session.envId)) == null ? void 0 : _a.toLowerCase()) || "";
111010
+ const searchableFields = [
111011
+ session.id,
111012
+ envName,
111013
+ session.envId,
111014
+ session.appvId,
111015
+ session.source,
111016
+ session.environment,
111017
+ session.sessionReference,
111018
+ session.userReference,
111019
+ ...session.userIds || []
111020
+ ];
111021
+ return searchableFields.some(
111022
+ (field) => field && String(field).toLowerCase().includes(term)
111023
+ );
111024
+ });
111025
+ }, [sessions, searchTerm, resolveEnvironmentName]);
110259
111026
  const defaultColumns = useMemo(
110260
111027
  () => [
110261
111028
  {
@@ -110264,8 +111031,7 @@ function SessionsListContent(props) {
110264
111031
  width: 320,
110265
111032
  pinned: "left",
110266
111033
  hide: false,
110267
- // Pinned columns should always be visible
110268
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
111034
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
110269
111035
  },
110270
111036
  {
110271
111037
  field: "envId",
@@ -110392,6 +111158,20 @@ function SessionsListContent(props) {
110392
111158
  disabled: true,
110393
111159
  valueFormatter: (params) => TracingUtils.formatTokens(params.value),
110394
111160
  cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", children: TracingUtils.formatTokens(params.value) })
111161
+ },
111162
+ {
111163
+ field: "sessionReference",
111164
+ headerName: "Session Reference",
111165
+ width: 180,
111166
+ hide: true,
111167
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111168
+ },
111169
+ {
111170
+ field: "identity",
111171
+ headerName: "User Reference",
111172
+ width: 180,
111173
+ hide: true,
111174
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
110395
111175
  }
110396
111176
  // {
110397
111177
  // field: 'traceTags',
@@ -110511,8 +111291,9 @@ function SessionsListContent(props) {
110511
111291
  // User-friendly label
110512
111292
  apiColumnName: "App Version ID",
110513
111293
  // API expects "App Version ID" (koretracing uiTableName)
110514
- type: "string",
110515
- operators: ["=", "!=", "contains"]
111294
+ type: "stringOptions",
111295
+ operators: ["any of", "none of"],
111296
+ options: appVersionOptions
110516
111297
  },
110517
111298
  {
110518
111299
  field: "source",
@@ -110564,10 +111345,27 @@ function SessionsListContent(props) {
110564
111345
  // API expects "Output Tokens" (koretracing uiTableName)
110565
111346
  type: "number",
110566
111347
  operators: ["=", ">", ">=", "<", "<="]
111348
+ },
111349
+ {
111350
+ field: "sessionReference",
111351
+ label: "Session Reference",
111352
+ apiColumnName: "Session Reference",
111353
+ type: "string",
111354
+ operators: ["=", "!=", "contains"]
111355
+ },
111356
+ {
111357
+ field: "identity",
111358
+ label: "User Reference",
111359
+ apiColumnName: "User Reference",
111360
+ type: "string",
111361
+ operators: ["=", "!=", "contains"]
110567
111362
  }
110568
111363
  ],
110569
- [environments]
111364
+ [environments, appVersionOptions]
110570
111365
  );
111366
+ const handleSearch = useCallback((term) => {
111367
+ setSearchTerm(term);
111368
+ }, []);
110571
111369
  const handleTimeRangeChange = (value, presetLabel) => {
110572
111370
  console.log("🗓️ SessionsList: Time range change requested:", value, presetLabel);
110573
111371
  setTimeRange(value);
@@ -110591,7 +111389,8 @@ function SessionsListContent(props) {
110591
111389
  totalCost: session.totalCost,
110592
111390
  totalTokens: session.totalTokens,
110593
111391
  sessionDuration: session.sessionDuration,
110594
- createdAt: session.createdAt
111392
+ createdAt: session.createdAt,
111393
+ source: session.source
110595
111394
  });
110596
111395
  setIsModalOpen(true);
110597
111396
  if (onSessionClick) {
@@ -110609,6 +111408,7 @@ function SessionsListContent(props) {
110609
111408
  };
110610
111409
  const handleClearFilters = () => {
110611
111410
  setFilters([]);
111411
+ setSearchTerm("");
110612
111412
  setTimeRange("24 hours");
110613
111413
  };
110614
111414
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `h-full flex flex-col w-full ${className}`, children: [
@@ -110617,11 +111417,19 @@ function SessionsListContent(props) {
110617
111417
  {
110618
111418
  title: "Sessions",
110619
111419
  description: "Review session logs and trace details to analyze conversation logs and app behavior.",
110620
- showSearch: false,
111420
+ searchPlaceholder: "Search sessions...",
111421
+ showSearch: true,
111422
+ searchConfig: {
111423
+ metadataSearchFields: ["Session ID", "Environment", "App Version", "User ID", "Source"],
111424
+ updateQuery: handleSearch,
111425
+ currentQuery: searchTerm,
111426
+ tableAllowsFullTextSearch: false
111427
+ },
110621
111428
  timeRange,
110622
111429
  timeRangePresetLabel,
110623
111430
  onTimeRangeChange: handleTimeRangeChange,
110624
111431
  filters,
111432
+ filterColumns,
110625
111433
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
110626
111434
  onModifyColumnsClick: () => setShowColumnCustomization(true),
110627
111435
  onExportClick: handleExport,
@@ -110672,10 +111480,10 @@ function SessionsListContent(props) {
110672
111480
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-auto p-[24px] pt-[8px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
110673
111481
  TracingTable,
110674
111482
  {
110675
- data: sessions,
111483
+ data: filteredSessions,
110676
111484
  columns,
110677
111485
  loading,
110678
- totalCount,
111486
+ totalCount: searchTerm.trim() ? filteredSessions.length : totalCount,
110679
111487
  pagination,
110680
111488
  onPaginationChange: setPagination,
110681
111489
  onRowClick: handleRowClick,
@@ -110692,7 +111500,9 @@ function SessionsListContent(props) {
110692
111500
  sessionId: selectedSessionId,
110693
111501
  apiConfig,
110694
111502
  onClose: handleModalClose,
110695
- initialSessionData: selectedSessionData || void 0
111503
+ initialSessionData: selectedSessionData || void 0,
111504
+ onViewEventLogs,
111505
+ fetchEventLogs
110696
111506
  }
110697
111507
  ) })
110698
111508
  ] });
@@ -110733,7 +111543,7 @@ function TracesListContent(props) {
110733
111543
  const [loading, setLoading] = useState(true);
110734
111544
  const [hasInitiallyLoaded, setHasInitiallyLoaded] = useState(false);
110735
111545
  const [searchTerm, setSearchTerm] = useState("");
110736
- const [searchType, setSearchType] = useState(["id"]);
111546
+ const [searchType, setSearchType] = useState(["id", "content"]);
110737
111547
  const initialFilters = useMemo(() => {
110738
111548
  const hasEnvFilter = defaultFilters.some((f) => f.column === "envId");
110739
111549
  const base2 = hasEnvFilter ? defaultFilters : [createDraftEnvironmentFilter(), ...defaultFilters];
@@ -110965,8 +111775,7 @@ function TracesListContent(props) {
110965
111775
  width: 320,
110966
111776
  pinned: "left",
110967
111777
  hide: false,
110968
- // Pinned columns should always be visible
110969
- cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-900", title: params.value, children: TracingUtils.truncate(params.value, 30) })
111778
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableId, { value: params.value, truncateLength: 30 })
110970
111779
  }
110971
111780
  ];
110972
111781
  {
@@ -111158,6 +111967,20 @@ function TracesListContent(props) {
111158
111967
  return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600", children: source || "-" });
111159
111968
  }
111160
111969
  },
111970
+ {
111971
+ field: "sessionReference",
111972
+ headerName: "Session Reference",
111973
+ width: 180,
111974
+ hide: true,
111975
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111976
+ },
111977
+ {
111978
+ field: "identity",
111979
+ headerName: "User Reference",
111980
+ width: 180,
111981
+ hide: true,
111982
+ cellRenderer: (params) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-700", title: params.value || "-", children: params.value || "-" })
111983
+ },
111161
111984
  {
111162
111985
  field: "promptTokens",
111163
111986
  headerName: "Input Tokens",
@@ -111427,6 +112250,20 @@ function TracesListContent(props) {
111427
112250
  label: "Output Tokens",
111428
112251
  type: "number",
111429
112252
  operators: ["=", ">", ">=", "<", "<="]
112253
+ },
112254
+ {
112255
+ field: "sessionReference",
112256
+ label: "Session Reference",
112257
+ apiColumnName: "Session Reference",
112258
+ type: "string",
112259
+ operators: ["=", "!=", "contains"]
112260
+ },
112261
+ {
112262
+ field: "identity",
112263
+ label: "User Reference",
112264
+ apiColumnName: "User Reference",
112265
+ type: "string",
112266
+ operators: ["=", "!=", "contains"]
111430
112267
  }
111431
112268
  );
111432
112269
  return baseColumns;
@@ -111493,6 +112330,7 @@ function TracesListContent(props) {
111493
112330
  timeRangePresetLabel,
111494
112331
  onTimeRangeChange: handleTimeRangeChange,
111495
112332
  filters,
112333
+ filterColumns,
111496
112334
  onFiltersClick: () => setShowFilterPanel(!showFilterPanel),
111497
112335
  onModifyColumnsClick: () => setShowColumnCustomization(true),
111498
112336
  onExportClick: handleExport,