@railtownai/railtracks-visualizer 0.0.66 → 0.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -12919,7 +12919,7 @@ const createLucideIcon = (iconName, iconNode)=>{
12919
12919
  return Component;
12920
12920
  };
12921
12921
 
12922
- const __iconNode$y = [
12922
+ const __iconNode$z = [
12923
12923
  [
12924
12924
  "path",
12925
12925
  {
@@ -12935,9 +12935,9 @@ const __iconNode$y = [
12935
12935
  }
12936
12936
  ]
12937
12937
  ];
12938
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$y);
12938
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$z);
12939
12939
 
12940
- const __iconNode$x = [
12940
+ const __iconNode$y = [
12941
12941
  [
12942
12942
  "path",
12943
12943
  {
@@ -12953,9 +12953,9 @@ const __iconNode$x = [
12953
12953
  }
12954
12954
  ]
12955
12955
  ];
12956
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$x);
12956
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$y);
12957
12957
 
12958
- const __iconNode$w = [
12958
+ const __iconNode$x = [
12959
12959
  [
12960
12960
  "path",
12961
12961
  {
@@ -13003,9 +13003,9 @@ const __iconNode$w = [
13003
13003
  }
13004
13004
  ]
13005
13005
  ];
13006
- const Bot = createLucideIcon("bot", __iconNode$w);
13006
+ const Bot = createLucideIcon("bot", __iconNode$x);
13007
13007
 
13008
- const __iconNode$v = [
13008
+ const __iconNode$w = [
13009
13009
  [
13010
13010
  "path",
13011
13011
  {
@@ -13039,9 +13039,9 @@ const __iconNode$v = [
13039
13039
  }
13040
13040
  ]
13041
13041
  ];
13042
- const Calendar = createLucideIcon("calendar", __iconNode$v);
13042
+ const Calendar = createLucideIcon("calendar", __iconNode$w);
13043
13043
 
13044
- const __iconNode$u = [
13044
+ const __iconNode$v = [
13045
13045
  [
13046
13046
  "path",
13047
13047
  {
@@ -13098,9 +13098,9 @@ const __iconNode$u = [
13098
13098
  }
13099
13099
  ]
13100
13100
  ];
13101
- const ChartNetwork = createLucideIcon("chart-network", __iconNode$u);
13101
+ const ChartNetwork = createLucideIcon("chart-network", __iconNode$v);
13102
13102
 
13103
- const __iconNode$t = [
13103
+ const __iconNode$u = [
13104
13104
  [
13105
13105
  "path",
13106
13106
  {
@@ -13109,9 +13109,9 @@ const __iconNode$t = [
13109
13109
  }
13110
13110
  ]
13111
13111
  ];
13112
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$t);
13112
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$u);
13113
13113
 
13114
- const __iconNode$s = [
13114
+ const __iconNode$t = [
13115
13115
  [
13116
13116
  "path",
13117
13117
  {
@@ -13120,9 +13120,9 @@ const __iconNode$s = [
13120
13120
  }
13121
13121
  ]
13122
13122
  ];
13123
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$s);
13123
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$t);
13124
13124
 
13125
- const __iconNode$r = [
13125
+ const __iconNode$s = [
13126
13126
  [
13127
13127
  "path",
13128
13128
  {
@@ -13138,9 +13138,9 @@ const __iconNode$r = [
13138
13138
  }
13139
13139
  ]
13140
13140
  ];
13141
- const ChevronsDown = createLucideIcon("chevrons-down", __iconNode$r);
13141
+ const ChevronsDown = createLucideIcon("chevrons-down", __iconNode$s);
13142
13142
 
13143
- const __iconNode$q = [
13143
+ const __iconNode$r = [
13144
13144
  [
13145
13145
  "path",
13146
13146
  {
@@ -13156,9 +13156,9 @@ const __iconNode$q = [
13156
13156
  }
13157
13157
  ]
13158
13158
  ];
13159
- const ChevronsUp = createLucideIcon("chevrons-up", __iconNode$q);
13159
+ const ChevronsUp = createLucideIcon("chevrons-up", __iconNode$r);
13160
13160
 
13161
- const __iconNode$p = [
13161
+ const __iconNode$q = [
13162
13162
  [
13163
13163
  "circle",
13164
13164
  {
@@ -13189,9 +13189,9 @@ const __iconNode$p = [
13189
13189
  }
13190
13190
  ]
13191
13191
  ];
13192
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$p);
13192
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$q);
13193
13193
 
13194
- const __iconNode$o = [
13194
+ const __iconNode$p = [
13195
13195
  [
13196
13196
  "path",
13197
13197
  {
@@ -13207,9 +13207,9 @@ const __iconNode$o = [
13207
13207
  }
13208
13208
  ]
13209
13209
  ];
13210
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$o);
13210
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$p);
13211
13211
 
13212
- const __iconNode$n = [
13212
+ const __iconNode$o = [
13213
13213
  [
13214
13214
  "circle",
13215
13215
  {
@@ -13234,9 +13234,9 @@ const __iconNode$n = [
13234
13234
  }
13235
13235
  ]
13236
13236
  ];
13237
- const CircleDollarSign = createLucideIcon("circle-dollar-sign", __iconNode$n);
13237
+ const CircleDollarSign = createLucideIcon("circle-dollar-sign", __iconNode$o);
13238
13238
 
13239
- const __iconNode$m = [
13239
+ const __iconNode$n = [
13240
13240
  [
13241
13241
  "circle",
13242
13242
  {
@@ -13254,9 +13254,9 @@ const __iconNode$m = [
13254
13254
  }
13255
13255
  ]
13256
13256
  ];
13257
- const Clock = createLucideIcon("clock", __iconNode$m);
13257
+ const Clock = createLucideIcon("clock", __iconNode$n);
13258
13258
 
13259
- const __iconNode$l = [
13259
+ const __iconNode$m = [
13260
13260
  [
13261
13261
  "rect",
13262
13262
  {
@@ -13277,9 +13277,9 @@ const __iconNode$l = [
13277
13277
  }
13278
13278
  ]
13279
13279
  ];
13280
- const Copy = createLucideIcon("copy", __iconNode$l);
13280
+ const Copy = createLucideIcon("copy", __iconNode$m);
13281
13281
 
13282
- const __iconNode$k = [
13282
+ const __iconNode$l = [
13283
13283
  [
13284
13284
  "path",
13285
13285
  {
@@ -13387,9 +13387,9 @@ const __iconNode$k = [
13387
13387
  }
13388
13388
  ]
13389
13389
  ];
13390
- const Cpu = createLucideIcon("cpu", __iconNode$k);
13390
+ const Cpu = createLucideIcon("cpu", __iconNode$l);
13391
13391
 
13392
- const __iconNode$j = [
13392
+ const __iconNode$k = [
13393
13393
  [
13394
13394
  "line",
13395
13395
  {
@@ -13408,9 +13408,9 @@ const __iconNode$j = [
13408
13408
  }
13409
13409
  ]
13410
13410
  ];
13411
- const DollarSign = createLucideIcon("dollar-sign", __iconNode$j);
13411
+ const DollarSign = createLucideIcon("dollar-sign", __iconNode$k);
13412
13412
 
13413
- const __iconNode$i = [
13413
+ const __iconNode$j = [
13414
13414
  [
13415
13415
  "path",
13416
13416
  {
@@ -13440,9 +13440,9 @@ const __iconNode$i = [
13440
13440
  }
13441
13441
  ]
13442
13442
  ];
13443
- const FileInput = createLucideIcon("file-input", __iconNode$i);
13443
+ const FileInput = createLucideIcon("file-input", __iconNode$j);
13444
13444
 
13445
- const __iconNode$h = [
13445
+ const __iconNode$i = [
13446
13446
  [
13447
13447
  "path",
13448
13448
  {
@@ -13472,9 +13472,9 @@ const __iconNode$h = [
13472
13472
  }
13473
13473
  ]
13474
13474
  ];
13475
- const FileOutput = createLucideIcon("file-output", __iconNode$h);
13475
+ const FileOutput = createLucideIcon("file-output", __iconNode$i);
13476
13476
 
13477
- const __iconNode$g = [
13477
+ const __iconNode$h = [
13478
13478
  [
13479
13479
  "path",
13480
13480
  {
@@ -13532,9 +13532,9 @@ const __iconNode$g = [
13532
13532
  }
13533
13533
  ]
13534
13534
  ];
13535
- const FoldVertical = createLucideIcon("fold-vertical", __iconNode$g);
13535
+ const FoldVertical = createLucideIcon("fold-vertical", __iconNode$h);
13536
13536
 
13537
- const __iconNode$f = [
13537
+ const __iconNode$g = [
13538
13538
  [
13539
13539
  "line",
13540
13540
  {
@@ -13576,9 +13576,9 @@ const __iconNode$f = [
13576
13576
  }
13577
13577
  ]
13578
13578
  ];
13579
- const Hash = createLucideIcon("hash", __iconNode$f);
13579
+ const Hash = createLucideIcon("hash", __iconNode$g);
13580
13580
 
13581
- const __iconNode$e = [
13581
+ const __iconNode$f = [
13582
13582
  [
13583
13583
  "circle",
13584
13584
  {
@@ -13603,9 +13603,9 @@ const __iconNode$e = [
13603
13603
  }
13604
13604
  ]
13605
13605
  ];
13606
- const Info = createLucideIcon("info", __iconNode$e);
13606
+ const Info = createLucideIcon("info", __iconNode$f);
13607
13607
 
13608
- const __iconNode$d = [
13608
+ const __iconNode$e = [
13609
13609
  [
13610
13610
  "path",
13611
13611
  {
@@ -13642,7 +13642,39 @@ const __iconNode$d = [
13642
13642
  }
13643
13643
  ]
13644
13644
  ];
13645
- const ListChecks = createLucideIcon("list-checks", __iconNode$d);
13645
+ const ListChecks = createLucideIcon("list-checks", __iconNode$e);
13646
+
13647
+ const __iconNode$d = [
13648
+ [
13649
+ "path",
13650
+ {
13651
+ d: "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
13652
+ key: "18887p"
13653
+ }
13654
+ ],
13655
+ [
13656
+ "path",
13657
+ {
13658
+ d: "M7 11h10",
13659
+ key: "1twpyw"
13660
+ }
13661
+ ],
13662
+ [
13663
+ "path",
13664
+ {
13665
+ d: "M7 15h6",
13666
+ key: "d9of3u"
13667
+ }
13668
+ ],
13669
+ [
13670
+ "path",
13671
+ {
13672
+ d: "M7 7h8",
13673
+ key: "af5zfr"
13674
+ }
13675
+ ]
13676
+ ];
13677
+ const MessageSquareText = createLucideIcon("message-square-text", __iconNode$d);
13646
13678
 
13647
13679
  const __iconNode$c = [
13648
13680
  [
@@ -15998,6 +16030,137 @@ const lightTheme = {
15998
16030
  slow: "0.3s ease-in-out"
15999
16031
  }
16000
16032
  };
16033
+ /** Light “Liquid Glass”–inspired palette (web approximation). */ const liquidGlassLightTheme = {
16034
+ colors: {
16035
+ background: "hsl(210 35% 92%)",
16036
+ foreground: "hsl(222 47% 11%)",
16037
+ card: "hsla(0 0% 100% / 0.88)",
16038
+ cardForeground: "hsl(222 47% 11%)",
16039
+ popover: "hsla(0 0% 100% / 0.94)",
16040
+ popoverForeground: "hsl(222 47% 11%)",
16041
+ primary: "hsl(211 92% 45%)",
16042
+ primaryForeground: "hsl(210 40% 98%)",
16043
+ secondary: "hsla(210 40% 98% / 0.45)",
16044
+ secondaryForeground: "hsl(222 47% 18%)",
16045
+ muted: "hsla(210 25% 98% / 0.35)",
16046
+ mutedForeground: "hsl(215 16% 40%)",
16047
+ accent: "hsla(210 60% 96% / 0.55)",
16048
+ accentForeground: "hsl(222 47% 18%)",
16049
+ destructive: "hsl(0 72% 51%)",
16050
+ destructiveForeground: "hsl(210 40% 98%)",
16051
+ success: "hsl(142.1 76.2% 32%)",
16052
+ successForeground: "hsl(210 40% 98%)",
16053
+ border: "hsla(210 28% 72% / 0.55)",
16054
+ mutedBorder: "hsla(210 22% 80% / 0.45)",
16055
+ input: "hsla(210 28% 88% / 0.65)",
16056
+ ring: "hsl(211 92% 45%)",
16057
+ tagTooluse: {
16058
+ bg: "hsla(199 89% 48% / 0.14)",
16059
+ border: "hsla(199 89% 48% / 0.35)",
16060
+ color: "hsl(200 98% 32%)"
16061
+ },
16062
+ tagLlminference: {
16063
+ bg: "hsla(271 91% 56% / 0.12)",
16064
+ border: "hsla(271 91% 56% / 0.35)",
16065
+ color: "hsl(271 81% 38%)"
16066
+ },
16067
+ tagJudge: {
16068
+ bg: "hsla(0 84% 60% / 0.12)",
16069
+ border: "hsla(0 84% 55% / 0.35)",
16070
+ color: "hsl(0 72% 40%)"
16071
+ },
16072
+ tagToolLevel1: {
16073
+ bg: "hsla(142 70% 42% / 0.15)",
16074
+ color: "hsl(142 71% 28%)"
16075
+ },
16076
+ tagToolLevel2: {
16077
+ bg: "hsla(217 91% 52% / 0.12)",
16078
+ color: "hsl(217 91% 38%)"
16079
+ },
16080
+ tagToolLevel3: {
16081
+ bg: "hsla(271 91% 56% / 0.12)",
16082
+ color: "hsl(271 81% 38%)"
16083
+ }
16084
+ },
16085
+ spacing: lightTheme.spacing,
16086
+ borderRadius: {
16087
+ sm: "calc(var(--radius) - 4px)",
16088
+ md: "calc(var(--radius) - 2px)",
16089
+ lg: "var(--radius)",
16090
+ xl: "1rem"
16091
+ },
16092
+ fontSize: lightTheme.fontSize,
16093
+ fontWeight: lightTheme.fontWeight,
16094
+ shadows: {
16095
+ sm: "0 1px 2px hsla(210 22% 25% / 0.06)",
16096
+ md: "0 8px 24px hsla(210 28% 18% / 0.08)",
16097
+ lg: "0 18px 48px hsla(210 28% 15% / 0.1)"
16098
+ },
16099
+ transitions: lightTheme.transitions
16100
+ };
16101
+ /** Dark “Liquid Glass”–inspired palette — translucent panels on a deep mesh-like base. */ const liquidGlassDarkTheme = {
16102
+ colors: {
16103
+ background: "hsl(222 28% 9%)",
16104
+ foreground: "hsl(210 36% 96%)",
16105
+ card: "hsla(222 22% 14% / 0.88)",
16106
+ cardForeground: "hsl(210 36% 96%)",
16107
+ popover: "hsla(222 24% 12% / 0.94)",
16108
+ popoverForeground: "hsl(210 36% 96%)",
16109
+ primary: "hsl(212 92% 62%)",
16110
+ primaryForeground: "hsl(222 47% 8%)",
16111
+ secondary: "hsla(217 28% 22% / 0.55)",
16112
+ secondaryForeground: "hsl(210 36% 94%)",
16113
+ muted: "hsla(217 22% 18% / 0.45)",
16114
+ mutedForeground: "hsl(215 18% 72%)",
16115
+ accent: "hsla(217 26% 22% / 0.55)",
16116
+ accentForeground: "hsl(210 36% 96%)",
16117
+ destructive: "hsl(0 72% 58%)",
16118
+ destructiveForeground: "hsl(210 40% 98%)",
16119
+ success: "hsl(142 76% 45%)",
16120
+ successForeground: "hsl(222 47% 8%)",
16121
+ border: "hsla(215 22% 42% / 0.45)",
16122
+ mutedBorder: "hsla(222 18% 28% / 0.5)",
16123
+ input: "hsla(217 22% 22% / 0.65)",
16124
+ ring: "hsl(212 92% 62%)",
16125
+ tagTooluse: {
16126
+ bg: "hsla(217 91% 55% / 0.18)",
16127
+ border: "hsla(217 91% 45% / 0.35)",
16128
+ color: "hsl(199 89% 72%)"
16129
+ },
16130
+ tagLlminference: {
16131
+ bg: "hsla(271 91% 58% / 0.15)",
16132
+ border: "hsla(271 91% 48% / 0.35)",
16133
+ color: "hsl(271 91% 78%)"
16134
+ },
16135
+ tagJudge: {
16136
+ bg: "hsla(0 72% 48% / 0.18)",
16137
+ border: "hsla(0 72% 42% / 0.35)",
16138
+ color: "hsl(0 84% 72%)"
16139
+ },
16140
+ tagToolLevel1: {
16141
+ bg: "hsla(142 70% 42% / 0.22)",
16142
+ color: "hsl(142 70% 72%)"
16143
+ },
16144
+ tagToolLevel2: {
16145
+ bg: "hsla(217 91% 52% / 0.2)",
16146
+ color: "hsl(217 91% 76%)"
16147
+ },
16148
+ tagToolLevel3: {
16149
+ bg: "hsla(271 91% 56% / 0.2)",
16150
+ color: "hsl(271 91% 76%)"
16151
+ }
16152
+ },
16153
+ spacing: lightTheme.spacing,
16154
+ borderRadius: liquidGlassLightTheme.borderRadius,
16155
+ fontSize: lightTheme.fontSize,
16156
+ fontWeight: lightTheme.fontWeight,
16157
+ shadows: {
16158
+ sm: "0 1px 2px hsla(0 0% 0% / 0.35)",
16159
+ md: "0 10px 28px hsla(0 0% 0% / 0.35)",
16160
+ lg: "0 22px 52px hsla(0 0% 0% / 0.45)"
16161
+ },
16162
+ transitions: lightTheme.transitions
16163
+ };
16001
16164
  const darkTheme = {
16002
16165
  colors: {
16003
16166
  background: "hsl(222.2 84% 4.9%)",
@@ -16059,81 +16222,124 @@ const darkTheme = {
16059
16222
  };
16060
16223
  const defaultTheme$1 = lightTheme;
16061
16224
 
16225
+ function normalizeStoredTheme(raw) {
16226
+ if (raw === "dark") return "dark";
16227
+ if (raw === "liquidGlassDark") return "liquidGlassDark";
16228
+ if (raw === "liquidGlassLight") return "liquidGlassLight";
16229
+ /* Migrate legacy single “Liquid Glass” preset */ if (raw === "liquidGlass") return "liquidGlassLight";
16230
+ return "light";
16231
+ }
16232
+ function themeForMode(mode) {
16233
+ switch(mode){
16234
+ case "dark":
16235
+ return darkTheme;
16236
+ case "liquidGlassLight":
16237
+ return liquidGlassLightTheme;
16238
+ case "liquidGlassDark":
16239
+ return liquidGlassDarkTheme;
16240
+ default:
16241
+ return lightTheme;
16242
+ }
16243
+ }
16244
+ function themeToMode(theme) {
16245
+ if (theme === darkTheme) return "dark";
16246
+ if (theme === liquidGlassDarkTheme) return "liquidGlassDark";
16247
+ if (theme === liquidGlassLightTheme) return "liquidGlassLight";
16248
+ return "light";
16249
+ }
16062
16250
  const ThemeContext = /*#__PURE__*/ createContext(undefined);
16063
16251
  const ThemeProvider = ({ children, theme: propTheme })=>{
16064
- const [currentTheme, setCurrentTheme] = React__default.useState(()=>{
16065
- // If a theme prop is provided, use it immediately
16252
+ const [themeMode, setThemeModeState] = React__default.useState(()=>{
16066
16253
  if (propTheme) {
16067
- return propTheme;
16254
+ return themeToMode(propTheme);
16068
16255
  }
16069
- // Only check localStorage if no theme prop is provided
16070
- // Handle cases where localStorage might not be available (e.g., test environments)
16071
16256
  try {
16072
- const savedTheme = localStorage.getItem("theme");
16073
- if (savedTheme === "dark") {
16074
- return darkTheme;
16075
- }
16076
- } catch (e) {
16077
- // localStorage not available, fall back to light theme
16078
- // This can happen in test environments or when localStorage is disabled
16079
- }
16080
- return lightTheme;
16257
+ return normalizeStoredTheme(localStorage.getItem("theme"));
16258
+ } catch {
16259
+ /* localStorage unavailable */ }
16260
+ return "light";
16081
16261
  });
16082
- // Update theme when propTheme changes
16262
+ const currentTheme = useMemo(()=>themeForMode(themeMode), [
16263
+ themeMode
16264
+ ]);
16083
16265
  useEffect(()=>{
16084
16266
  if (propTheme) {
16085
- setCurrentTheme(propTheme);
16267
+ setThemeModeState(themeToMode(propTheme));
16086
16268
  }
16087
16269
  }, [
16088
16270
  propTheme
16089
16271
  ]);
16090
- // Sync html.dark class for GlobalStyles and other CSS that uses html.dark
16091
16272
  useEffect(()=>{
16092
- const isDark = currentTheme === darkTheme;
16093
16273
  try {
16094
- if (isDark) {
16095
- document.documentElement.classList.add("dark");
16096
- } else {
16097
- document.documentElement.classList.remove("dark");
16098
- }
16099
- } catch (e) {
16100
- // document might not be available (e.g. SSR)
16101
- }
16274
+ const isClassicDark = themeMode === "dark";
16275
+ const isGlassLight = themeMode === "liquidGlassLight";
16276
+ const isGlassDark = themeMode === "liquidGlassDark";
16277
+ document.documentElement.classList.toggle("dark", isClassicDark);
16278
+ document.documentElement.classList.toggle("liquid-glass-light", isGlassLight);
16279
+ document.documentElement.classList.toggle("liquid-glass-dark", isGlassDark);
16280
+ /* Remove legacy class if present */ document.documentElement.classList.remove("liquid-glass");
16281
+ document.documentElement.dataset.theme = isClassicDark ? "dark" : isGlassLight ? "liquid-glass-light" : isGlassDark ? "liquid-glass-dark" : "light";
16282
+ } catch {
16283
+ /* document unavailable */ }
16102
16284
  }, [
16103
- currentTheme
16285
+ themeMode
16286
+ ]);
16287
+ useEffect(()=>{
16288
+ if (propTheme) return;
16289
+ try {
16290
+ localStorage.setItem("theme", themeMode);
16291
+ } catch {
16292
+ /* ignore */ }
16293
+ }, [
16294
+ themeMode,
16295
+ propTheme
16104
16296
  ]);
16105
- // Only listen for storage events if no theme prop is provided
16106
16297
  useEffect(()=>{
16107
16298
  if (propTheme) {
16108
- // If a theme prop is provided, don't listen for localStorage changes
16109
16299
  return;
16110
16300
  }
16111
16301
  const handleStorageChange = ()=>{
16112
16302
  try {
16113
- const savedTheme = localStorage.getItem("theme");
16114
- if (savedTheme === "dark") {
16115
- setCurrentTheme(darkTheme);
16116
- } else {
16117
- setCurrentTheme(lightTheme);
16118
- }
16119
- } catch (e) {
16120
- // localStorage not available, ignore storage changes
16121
- }
16303
+ setThemeModeState(normalizeStoredTheme(localStorage.getItem("theme")));
16304
+ } catch {
16305
+ /* ignore */ }
16122
16306
  };
16123
- // Listen for storage events (when localStorage changes in other tabs)
16124
16307
  window.addEventListener("storage", handleStorageChange);
16125
- return ()=>{
16126
- window.removeEventListener("storage", handleStorageChange);
16127
- };
16308
+ return ()=>window.removeEventListener("storage", handleStorageChange);
16128
16309
  }, [
16129
16310
  propTheme
16130
16311
  ]);
16131
- const value = React__default.useMemo(()=>({
16312
+ const setThemeMode = useCallback((mode)=>{
16313
+ setThemeModeState(mode);
16314
+ }, []);
16315
+ const setTheme = useCallback((next)=>{
16316
+ setThemeModeState(themeToMode(next));
16317
+ }, []);
16318
+ const isLiquidGlassLight = themeMode === "liquidGlassLight";
16319
+ const isLiquidGlassDark = themeMode === "liquidGlassDark";
16320
+ const isLiquidGlass = isLiquidGlassLight || isLiquidGlassDark;
16321
+ const isClassicDarkTheme = themeMode === "dark";
16322
+ const isDarkMode = isClassicDarkTheme || isLiquidGlassDark;
16323
+ const value = useMemo(()=>({
16132
16324
  theme: currentTheme,
16133
- setTheme: setCurrentTheme,
16134
- isDarkMode: currentTheme === darkTheme
16325
+ themeMode,
16326
+ setTheme,
16327
+ setThemeMode,
16328
+ isDarkMode,
16329
+ isClassicDarkTheme,
16330
+ isLiquidGlass,
16331
+ isLiquidGlassLight,
16332
+ isLiquidGlassDark
16135
16333
  }), [
16136
- currentTheme
16334
+ currentTheme,
16335
+ themeMode,
16336
+ setTheme,
16337
+ setThemeMode,
16338
+ isDarkMode,
16339
+ isClassicDarkTheme,
16340
+ isLiquidGlass,
16341
+ isLiquidGlassLight,
16342
+ isLiquidGlassDark
16137
16343
  ]);
16138
16344
  return /*#__PURE__*/ React__default.createElement(ThemeContext.Provider, {
16139
16345
  value: value
@@ -16144,14 +16350,20 @@ const ThemeProvider = ({ children, theme: propTheme })=>{
16144
16350
  const useTheme$1 = ()=>{
16145
16351
  const context = useContext(ThemeContext);
16146
16352
  if (context === undefined) {
16147
- // Return a graceful fallback instead of throwing an error
16148
16353
  return {
16149
16354
  theme: lightTheme,
16355
+ themeMode: "light",
16150
16356
  setTheme: ()=>{
16151
- // No-op function when context is not available
16152
16357
  console.warn("Theme context not available. setTheme called but ignored.");
16153
16358
  },
16154
- isDarkMode: false // Default to light mode when no context
16359
+ setThemeMode: ()=>{
16360
+ console.warn("Theme context not available. setThemeMode called but ignored.");
16361
+ },
16362
+ isDarkMode: false,
16363
+ isClassicDarkTheme: false,
16364
+ isLiquidGlass: false,
16365
+ isLiquidGlassLight: false,
16366
+ isLiquidGlassDark: false
16155
16367
  };
16156
16368
  }
16157
16369
  return context;
@@ -16160,7 +16372,6 @@ const useThemeValue = ()=>{
16160
16372
  const { theme } = useTheme$1();
16161
16373
  return theme;
16162
16374
  };
16163
- // Helper hook for components that can accept a theme prop
16164
16375
  const useComponentTheme = (themeProp)=>{
16165
16376
  const { theme: contextTheme } = useTheme$1();
16166
16377
  return themeProp || contextTheme;
@@ -48566,7 +48777,7 @@ const CountUpLatency = ({ value })=>{
48566
48777
  };
48567
48778
  }
48568
48779
  const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48569
- const { theme } = useTheme$1();
48780
+ const { theme, isLiquidGlass } = useTheme$1();
48570
48781
  const [selectedRowIndex, setSelectedRowIndex] = useState(null);
48571
48782
  const [selectedLlmDetails, setSelectedLlmDetails] = useState(null);
48572
48783
  // Default to last row (total/aggregate) when drawer opens (only on first open)
@@ -48640,11 +48851,11 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48640
48851
  "data-testid": "node-details-drawer",
48641
48852
  styles: {
48642
48853
  body: {
48643
- background: theme.colors.background,
48854
+ background: isLiquidGlass ? theme.colors.popover : theme.colors.background,
48644
48855
  color: theme.colors.foreground
48645
48856
  },
48646
48857
  header: {
48647
- background: theme.colors.card,
48858
+ background: isLiquidGlass ? theme.colors.popover : theme.colors.card,
48648
48859
  borderBottom: `1px solid ${theme.colors.border}`
48649
48860
  }
48650
48861
  }
@@ -52005,8 +52216,7 @@ const SheetOverlay = /*#__PURE__*/ React.forwardRef(({ className, ...props }, re
52005
52216
  bottom: 0,
52006
52217
  left: 0,
52007
52218
  zIndex: 50,
52008
- backgroundColor: "hsla(var(--background), 0.8)",
52009
- backdropFilter: "blur(4px)"
52219
+ backgroundColor: "rgba(0, 0, 0, 0.45)"
52010
52220
  },
52011
52221
  className: className,
52012
52222
  ...props,
@@ -52018,7 +52228,7 @@ const getSheetStyles = (side = "right")=>{
52018
52228
  position: "fixed",
52019
52229
  zIndex: 50,
52020
52230
  gap: "16px",
52021
- backgroundColor: "hsl(var(--background))",
52231
+ backgroundColor: "var(--background)",
52022
52232
  padding: "24px",
52023
52233
  boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
52024
52234
  transition: "all 0.3s ease-in-out"
@@ -52030,7 +52240,7 @@ const getSheetStyles = (side = "right")=>{
52030
52240
  left: 0,
52031
52241
  right: 0,
52032
52242
  top: 0,
52033
- borderBottom: "1px solid hsl(var(--border))"
52243
+ borderBottom: "1px solid var(--border)"
52034
52244
  };
52035
52245
  case "bottom":
52036
52246
  return {
@@ -52038,7 +52248,7 @@ const getSheetStyles = (side = "right")=>{
52038
52248
  left: 0,
52039
52249
  right: 0,
52040
52250
  bottom: 0,
52041
- borderTop: "1px solid hsl(var(--border))"
52251
+ borderTop: "1px solid var(--border)"
52042
52252
  };
52043
52253
  case "left":
52044
52254
  return {
@@ -52048,7 +52258,7 @@ const getSheetStyles = (side = "right")=>{
52048
52258
  left: 0,
52049
52259
  height: "100%",
52050
52260
  width: "75%",
52051
- borderRight: "1px solid hsl(var(--border))",
52261
+ borderRight: "1px solid var(--border)",
52052
52262
  maxWidth: "384px"
52053
52263
  };
52054
52264
  case "right":
@@ -52060,7 +52270,7 @@ const getSheetStyles = (side = "right")=>{
52060
52270
  right: 0,
52061
52271
  height: "100%",
52062
52272
  width: "75%",
52063
- borderLeft: "1px solid hsl(var(--border))",
52273
+ borderLeft: "1px solid var(--border)",
52064
52274
  maxWidth: "384px"
52065
52275
  };
52066
52276
  }
@@ -52121,7 +52331,7 @@ const SheetTitle = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)
52121
52331
  style: {
52122
52332
  fontSize: "18px",
52123
52333
  fontWeight: 600,
52124
- color: "hsl(var(--foreground))"
52334
+ color: "var(--foreground)"
52125
52335
  },
52126
52336
  className: className,
52127
52337
  ...props
@@ -52131,7 +52341,7 @@ const SheetDescription = /*#__PURE__*/ React.forwardRef(({ className, ...props }
52131
52341
  ref: ref,
52132
52342
  style: {
52133
52343
  fontSize: "14px",
52134
- color: "hsl(var(--muted-foreground))"
52344
+ color: "var(--muted-foreground)"
52135
52345
  },
52136
52346
  className: className,
52137
52347
  ...props
@@ -116298,7 +116508,18 @@ const useEvaluationsMock = ()=>{
116298
116508
  return useContext(EvaluationsMockContext);
116299
116509
  };
116300
116510
 
116301
- const API_BASE = "/api";
116511
+ /**
116512
+ * Railtracks HTTP API prefix. Same-origin `/api` by default (browser + viz proxy).
116513
+ * Set `VITE_API_ORIGIN` (e.g. `http://localhost:3030`) when the UI is served elsewhere (Electron, etc.).
116514
+ */ function resolveApiBase() {
116515
+ const origin = import.meta.env.VITE_API_ORIGIN?.trim().replace(/\/$/, "") ?? "";
116516
+ if (!origin) {
116517
+ return "/api";
116518
+ }
116519
+ return `${origin}/api`;
116520
+ }
116521
+ const API_BASE = resolveApiBase();
116522
+
116302
116523
  const useEvaluations = ()=>{
116303
116524
  const mockContext = useEvaluationsMock();
116304
116525
  const [evaluations, setEvaluations] = useState([]);
@@ -116805,6 +117026,401 @@ function buildTreeFromProcessedData(latencyByTool, failureRateByTool, usageCount
116805
117026
  return buildTreeFromProcessedData(latencyByTool, failureRateByTool, usageCountByTool, latencyResults, failureResults, agentIdToSessionId);
116806
117027
  }
116807
117028
 
117029
+ const JUDGE_RESULT_PREFIX = "JudgeResult/";
117030
+ const JUDGE_REASONING_PREFIX = "JudgeReasoning/";
117031
+ /** Map agent node id -> session id from the agents array (new format only). */ function buildSessionByNodeId(agents) {
117032
+ const map = new Map();
117033
+ for (const agent of agents ?? []){
117034
+ for (const entry of agent.agent_node_ids ?? []){
117035
+ if (entry && typeof entry === "object" && "agent_node_id" in entry) {
117036
+ map.set(entry.agent_node_id, entry.session_id);
117037
+ }
117038
+ }
117039
+ }
117040
+ return map;
117041
+ }
117042
+ /** Map `${nodeId}::${metricName}` -> reasoning text from JudgeReasoning/* results. */ function buildReasoningByKey(rawResults) {
117043
+ const map = new Map();
117044
+ for (const item of rawResults){
117045
+ if (!isBaseResult(item)) continue;
117046
+ if (!item.result_name?.startsWith(JUDGE_REASONING_PREFIX)) continue;
117047
+ const metricName = item.result_name.slice(JUDGE_REASONING_PREFIX.length);
117048
+ const nodeId = item.agent_data_id?.[0];
117049
+ if (nodeId && typeof item.value === "string") {
117050
+ map.set(`${nodeId}::${metricName}`, item.value);
117051
+ }
117052
+ }
117053
+ return map;
117054
+ }
117055
+ function metricNameOf(agg) {
117056
+ return agg.metric?.name ?? agg.name?.replace(/^Aggregate\//, "") ?? "Unknown";
117057
+ }
117058
+ /** Collect the JudgeResult leaf nodes (label + node id) grouped by label. */ function groupNodesByLabel(agg, nodes, rawResults, metricName, sessionByNodeId, reasoningByKey) {
117059
+ const byLabel = new Map();
117060
+ const seen = new Set();
117061
+ const push = (label, nodeId)=>{
117062
+ const dedupeKey = `${label}::${nodeId}`;
117063
+ if (seen.has(dedupeKey)) return;
117064
+ seen.add(dedupeKey);
117065
+ const ref = {
117066
+ nodeId,
117067
+ sessionId: sessionByNodeId.get(nodeId),
117068
+ reasoning: reasoningByKey.get(`${nodeId}::${metricName}`)
117069
+ };
117070
+ const existing = byLabel.get(label);
117071
+ if (existing) existing.push(ref);
117072
+ else byLabel.set(label, [
117073
+ ref
117074
+ ]);
117075
+ };
117076
+ // Preferred: walk the aggregate's children leaf nodes.
117077
+ for (const childId of agg.children ?? []){
117078
+ const child = nodes[childId];
117079
+ if (child && isBaseResult(child)) {
117080
+ const nodeId = child.agent_data_id?.[0];
117081
+ if (nodeId) push(String(child.value), nodeId);
117082
+ }
117083
+ }
117084
+ // Fallback: derive from raw JudgeResult/<metric> results when no children are present.
117085
+ if (byLabel.size === 0) {
117086
+ const resultName = `${JUDGE_RESULT_PREFIX}${metricName}`;
117087
+ for (const item of rawResults){
117088
+ if (isBaseResult(item) && item.result_name === resultName) {
117089
+ const nodeId = item.agent_data_id?.[0];
117090
+ if (nodeId) push(String(item.value), nodeId);
117091
+ }
117092
+ }
117093
+ }
117094
+ return byLabel;
117095
+ }
117096
+ /** Build the Judge view model: one entry per categorical metric. */ function buildJudgeMetricsFromAggregate(input) {
117097
+ const { roots, nodes, agents, rawResults = [] } = input;
117098
+ const sessionByNodeId = buildSessionByNodeId(agents);
117099
+ const reasoningByKey = buildReasoningByKey(rawResults);
117100
+ // Prefer roots; fall back to scanning all nodes for categorical aggregates.
117101
+ const rootAggregates = roots.map((id)=>nodes[id]).filter((n)=>isAggregateCategorical(n));
117102
+ const aggregates = rootAggregates.length > 0 ? rootAggregates : Object.values(nodes).filter((n)=>isAggregateCategorical(n));
117103
+ return aggregates.map((agg, index)=>{
117104
+ const metricName = metricNameOf(agg);
117105
+ const counts = agg.counts ?? {};
117106
+ const categories = agg.categories ?? agg.metric?.categories ?? Object.keys(counts);
117107
+ const byLabel = groupNodesByLabel(agg, nodes, rawResults, metricName, sessionByNodeId, reasoningByKey);
117108
+ // Order labels by the metric's category order, then any extras found in the data.
117109
+ const orderedLabels = [
117110
+ ...categories
117111
+ ];
117112
+ for (const label of byLabel.keys()){
117113
+ if (!orderedLabels.includes(label)) orderedLabels.push(label);
117114
+ }
117115
+ const labels = orderedLabels.map((labelName)=>{
117116
+ const nodesForLabel = byLabel.get(labelName) ?? [];
117117
+ return {
117118
+ labelName,
117119
+ count: counts[labelName] ?? nodesForLabel.length,
117120
+ nodes: nodesForLabel
117121
+ };
117122
+ });
117123
+ const total = labels.reduce((sum, l)=>sum + l.count, 0);
117124
+ return {
117125
+ key: agg.identifier ?? `${metricName}-${index}`,
117126
+ metricName,
117127
+ description: agg.metric?.description ?? undefined,
117128
+ mostCommon: agg.most_common_label ?? undefined,
117129
+ leastCommon: agg.least_common_label ?? undefined,
117130
+ total,
117131
+ labels
117132
+ };
117133
+ });
117134
+ }
117135
+
117136
+ const SHORT_ID_LENGTH = 8;
117137
+ const shortenId = (id)=>id.length > SHORT_ID_LENGTH ? id.slice(0, SHORT_ID_LENGTH) : id;
117138
+ const NodeRow = ({ node, metricName, onAgentNodeClick })=>{
117139
+ const { theme } = useTheme$1();
117140
+ const [showReasoning, setShowReasoning] = useState(false);
117141
+ const clickable = !!onAgentNodeClick;
117142
+ const open = ()=>onAgentNodeClick?.(node.sessionId, node.nodeId);
117143
+ return /*#__PURE__*/ React__default.createElement("div", {
117144
+ style: {
117145
+ display: "flex",
117146
+ flexDirection: "column",
117147
+ gap: 8
117148
+ }
117149
+ }, /*#__PURE__*/ React__default.createElement("div", {
117150
+ style: {
117151
+ display: "flex",
117152
+ alignItems: "center",
117153
+ gap: 10,
117154
+ flexWrap: "wrap"
117155
+ }
117156
+ }, /*#__PURE__*/ React__default.createElement(Tooltip, {
117157
+ title: clickable ? `Inspect run · ${node.nodeId}` : node.nodeId
117158
+ }, /*#__PURE__*/ React__default.createElement("span", {
117159
+ role: clickable ? "button" : undefined,
117160
+ tabIndex: clickable ? 0 : undefined,
117161
+ onClick: clickable ? open : undefined,
117162
+ onKeyDown: clickable ? (e)=>{
117163
+ if (e.key === "Enter" || e.key === " ") {
117164
+ e.preventDefault();
117165
+ open();
117166
+ }
117167
+ } : undefined,
117168
+ style: {
117169
+ display: "inline-flex",
117170
+ alignItems: "center",
117171
+ gap: 6,
117172
+ padding: "3px 10px",
117173
+ borderRadius: 6,
117174
+ fontFamily: "monospace",
117175
+ fontSize: 12,
117176
+ fontWeight: 500,
117177
+ background: theme.colors.tagLlminference?.bg ?? theme.colors.muted,
117178
+ color: theme.colors.tagLlminference?.color ?? theme.colors.foreground,
117179
+ border: `1px solid ${theme.colors.tagLlminference?.border ?? theme.colors.border}`,
117180
+ cursor: clickable ? "pointer" : "default"
117181
+ }
117182
+ }, /*#__PURE__*/ React__default.createElement(Bot, {
117183
+ size: 13,
117184
+ style: {
117185
+ flexShrink: 0
117186
+ }
117187
+ }), shortenId(node.nodeId))), node.reasoning && /*#__PURE__*/ React__default.createElement("button", {
117188
+ type: "button",
117189
+ onClick: ()=>setShowReasoning((s)=>!s),
117190
+ style: {
117191
+ display: "inline-flex",
117192
+ alignItems: "center",
117193
+ gap: 5,
117194
+ padding: "3px 9px",
117195
+ borderRadius: 6,
117196
+ fontSize: 12,
117197
+ cursor: "pointer",
117198
+ background: "transparent",
117199
+ color: theme.colors.primary,
117200
+ border: `1px solid ${theme.colors.primary}`
117201
+ }
117202
+ }, /*#__PURE__*/ React__default.createElement(MessageSquareText, {
117203
+ size: 12
117204
+ }), showReasoning ? "Hide reasoning" : "Show reasoning")), node.reasoning && showReasoning && /*#__PURE__*/ React__default.createElement("div", {
117205
+ style: {
117206
+ padding: "10px 14px",
117207
+ background: theme.colors.muted,
117208
+ border: `1px solid ${theme.colors.border}`,
117209
+ borderRadius: 6,
117210
+ fontSize: 13,
117211
+ lineHeight: 1.5,
117212
+ whiteSpace: "pre-wrap",
117213
+ color: theme.colors.foreground
117214
+ }
117215
+ }, /*#__PURE__*/ React__default.createElement("div", {
117216
+ style: {
117217
+ fontWeight: 600,
117218
+ marginBottom: 6,
117219
+ color: theme.colors.mutedForeground
117220
+ }
117221
+ }, "Judge reasoning · ", metricName), node.reasoning));
117222
+ };
117223
+ const LabelPanelHeader = ({ label })=>{
117224
+ const { theme } = useTheme$1();
117225
+ const isEmpty = label.count === 0;
117226
+ return /*#__PURE__*/ React__default.createElement("div", {
117227
+ style: {
117228
+ display: "flex",
117229
+ alignItems: "center",
117230
+ gap: 10
117231
+ }
117232
+ }, /*#__PURE__*/ React__default.createElement("span", {
117233
+ style: {
117234
+ width: 7,
117235
+ height: 7,
117236
+ borderRadius: "50%",
117237
+ flexShrink: 0,
117238
+ background: isEmpty ? theme.colors.border : theme.colors.primary
117239
+ }
117240
+ }), /*#__PURE__*/ React__default.createElement("span", {
117241
+ style: {
117242
+ fontSize: 13,
117243
+ fontWeight: 600,
117244
+ color: isEmpty ? theme.colors.mutedForeground : undefined
117245
+ }
117246
+ }, label.labelName), /*#__PURE__*/ React__default.createElement("span", {
117247
+ style: {
117248
+ marginLeft: "auto",
117249
+ fontSize: 12,
117250
+ color: theme.colors.mutedForeground
117251
+ }
117252
+ }, label.count, " ", label.count === 1 ? "node" : "nodes"));
117253
+ };
117254
+ const MetricCard = ({ metric, onAgentNodeClick })=>{
117255
+ const { theme } = useTheme$1();
117256
+ const items = metric.labels.map((label)=>({
117257
+ key: label.labelName,
117258
+ label: /*#__PURE__*/ React__default.createElement(LabelPanelHeader, {
117259
+ label: label
117260
+ }),
117261
+ collapsible: label.count === 0 ? "disabled" : undefined,
117262
+ children: label.nodes.length === 0 ? /*#__PURE__*/ React__default.createElement("span", {
117263
+ style: {
117264
+ fontSize: 12,
117265
+ fontStyle: "italic",
117266
+ color: theme.colors.mutedForeground
117267
+ }
117268
+ }, "No evaluations") : /*#__PURE__*/ React__default.createElement("div", {
117269
+ style: {
117270
+ display: "flex",
117271
+ flexDirection: "column",
117272
+ gap: 12
117273
+ }
117274
+ }, label.nodes.map((node)=>/*#__PURE__*/ React__default.createElement(NodeRow, {
117275
+ key: node.nodeId,
117276
+ node: node,
117277
+ metricName: metric.metricName,
117278
+ onAgentNodeClick: onAgentNodeClick
117279
+ })))
117280
+ }));
117281
+ return /*#__PURE__*/ React__default.createElement("div", {
117282
+ style: {
117283
+ background: theme.colors.card,
117284
+ border: `1px solid ${theme.colors.border}`,
117285
+ borderRadius: 8,
117286
+ overflow: "hidden"
117287
+ }
117288
+ }, /*#__PURE__*/ React__default.createElement("div", {
117289
+ style: {
117290
+ padding: "14px 18px",
117291
+ borderBottom: `1px solid ${theme.colors.border}`,
117292
+ background: theme.colors.secondary
117293
+ }
117294
+ }, /*#__PURE__*/ React__default.createElement("div", {
117295
+ style: {
117296
+ display: "flex",
117297
+ alignItems: "center",
117298
+ gap: 12,
117299
+ flexWrap: "wrap"
117300
+ }
117301
+ }, /*#__PURE__*/ React__default.createElement(Scale, {
117302
+ size: 16,
117303
+ style: {
117304
+ color: theme.colors.primary,
117305
+ flexShrink: 0
117306
+ }
117307
+ }), /*#__PURE__*/ React__default.createElement("span", {
117308
+ style: {
117309
+ fontSize: 15,
117310
+ fontWeight: 600
117311
+ }
117312
+ }, metric.metricName), /*#__PURE__*/ React__default.createElement("div", {
117313
+ style: {
117314
+ display: "flex",
117315
+ flexWrap: "wrap",
117316
+ gap: 6,
117317
+ marginLeft: 4
117318
+ }
117319
+ }, metric.labels.map((label)=>/*#__PURE__*/ React__default.createElement(Tag, {
117320
+ key: label.labelName,
117321
+ style: {
117322
+ margin: 0,
117323
+ borderRadius: 12,
117324
+ fontSize: 12,
117325
+ ...label.count > 0 ? {
117326
+ background: theme.colors.tagLlminference?.bg ?? theme.colors.muted,
117327
+ color: theme.colors.tagLlminference?.color ?? theme.colors.foreground,
117328
+ border: `1px solid ${theme.colors.tagLlminference?.border ?? theme.colors.border}`
117329
+ } : {
117330
+ background: "transparent",
117331
+ color: theme.colors.mutedForeground,
117332
+ border: `1px solid ${theme.colors.border}`
117333
+ }
117334
+ }
117335
+ }, label.labelName, " ", /*#__PURE__*/ React__default.createElement("strong", null, label.count)))), /*#__PURE__*/ React__default.createElement("div", {
117336
+ style: {
117337
+ display: "flex",
117338
+ gap: 20,
117339
+ marginLeft: "auto",
117340
+ flexShrink: 0
117341
+ }
117342
+ }, /*#__PURE__*/ React__default.createElement(Meta, {
117343
+ label: "Most common",
117344
+ value: metric.mostCommon
117345
+ }), /*#__PURE__*/ React__default.createElement(Meta, {
117346
+ label: "Least common",
117347
+ value: metric.leastCommon
117348
+ }), /*#__PURE__*/ React__default.createElement(Meta, {
117349
+ label: "Evaluations",
117350
+ value: String(metric.total)
117351
+ }))), metric.description && /*#__PURE__*/ React__default.createElement("div", {
117352
+ style: {
117353
+ marginTop: 6,
117354
+ fontSize: 12,
117355
+ color: theme.colors.mutedForeground
117356
+ }
117357
+ }, metric.description)), /*#__PURE__*/ React__default.createElement(Collapse$1, {
117358
+ items: items,
117359
+ bordered: false,
117360
+ style: {
117361
+ background: theme.colors.card
117362
+ }
117363
+ }));
117364
+ };
117365
+ const Meta = ({ label, value })=>{
117366
+ const { theme } = useTheme$1();
117367
+ return /*#__PURE__*/ React__default.createElement("span", {
117368
+ style: {
117369
+ display: "flex",
117370
+ flexDirection: "column",
117371
+ alignItems: "flex-end",
117372
+ gap: 1
117373
+ }
117374
+ }, /*#__PURE__*/ React__default.createElement("span", {
117375
+ style: {
117376
+ fontSize: 10,
117377
+ textTransform: "uppercase",
117378
+ letterSpacing: 0.4,
117379
+ color: theme.colors.mutedForeground
117380
+ }
117381
+ }, label), /*#__PURE__*/ React__default.createElement("span", {
117382
+ style: {
117383
+ fontSize: 13,
117384
+ fontWeight: 500
117385
+ }
117386
+ }, value ?? "—"));
117387
+ };
117388
+ const JudgeAggregateView = ({ metrics, onAgentNodeClick })=>{
117389
+ const { theme } = useTheme$1();
117390
+ if (!metrics.length) {
117391
+ return /*#__PURE__*/ React__default.createElement("div", {
117392
+ style: {
117393
+ padding: 24,
117394
+ textAlign: "center",
117395
+ color: theme.colors.mutedForeground,
117396
+ fontSize: 14
117397
+ }
117398
+ }, "No judge metrics available");
117399
+ }
117400
+ return /*#__PURE__*/ React__default.createElement("div", {
117401
+ style: {
117402
+ width: "100%",
117403
+ minWidth: 0
117404
+ }
117405
+ }, /*#__PURE__*/ React__default.createElement("h3", {
117406
+ style: {
117407
+ margin: "0 0 16px",
117408
+ fontSize: 16,
117409
+ fontWeight: 600
117410
+ }
117411
+ }, "Judge Evaluator - Aggregate View"), /*#__PURE__*/ React__default.createElement("div", {
117412
+ style: {
117413
+ display: "flex",
117414
+ flexDirection: "column",
117415
+ gap: 12
117416
+ }
117417
+ }, metrics.map((metric)=>/*#__PURE__*/ React__default.createElement(MetricCard, {
117418
+ key: metric.key,
117419
+ metric: metric,
117420
+ onAgentNodeClick: onAgentNodeClick
117421
+ }))));
117422
+ };
117423
+
116808
117424
  function detectAggregateType(nodes) {
116809
117425
  const values = Object.values(nodes);
116810
117426
  if (values.some((n)=>n?.type === "ToolAggregate")) return "ToolUse";
@@ -116825,22 +117441,6 @@ function buildLLMInferenceFlatRows(nodes) {
116825
117441
  count: agg.values?.length ?? 0
116826
117442
  }));
116827
117443
  }
116828
- function buildJudgeRows(nodes) {
116829
- const values = Object.values(nodes);
116830
- const aggregates = values.filter((n)=>isAggregateCategorical(n));
116831
- return aggregates.map((agg)=>{
116832
- const counts = agg.counts ?? {};
116833
- const total = Object.values(counts).reduce((a, b)=>a + b, 0);
116834
- return {
116835
- key: agg.identifier ?? agg.metric?.name ?? "unknown",
116836
- metric: agg.metric?.name ?? "Unknown",
116837
- mostCommon: agg.most_common_label ?? "-",
116838
- leastCommon: agg.least_common_label ?? "-",
116839
- counts,
116840
- total
116841
- };
116842
- });
116843
- }
116844
117444
  // --- Shared helpers ---
116845
117445
  function getAllExpandableKeys(rows) {
116846
117446
  const keys = [];
@@ -116912,7 +117512,12 @@ const AggregateResultsTable = ({ rawResults = [], aggregateResults, agents, titl
116912
117512
  if (type === "Judge") {
116913
117513
  return {
116914
117514
  aggregateType: type,
116915
- dataSource: buildJudgeRows(aggregateResults.nodes),
117515
+ dataSource: buildJudgeMetricsFromAggregate({
117516
+ roots: aggregateResults.roots,
117517
+ nodes: aggregateResults.nodes,
117518
+ agents,
117519
+ rawResults
117520
+ }),
116916
117521
  llmIsTree: false,
116917
117522
  llmExpandableKeys: []
116918
117523
  };
@@ -117245,86 +117850,10 @@ const AggregateResultsTable = ({ rawResults = [], aggregateResults, agents, titl
117245
117850
  }));
117246
117851
  }
117247
117852
  if (aggregateType === "Judge") {
117248
- const rows = dataSource;
117249
- const columns = [
117250
- {
117251
- title: "METRIC",
117252
- dataIndex: "metric",
117253
- key: "metric",
117254
- render: (metric)=>/*#__PURE__*/ React__default.createElement("span", {
117255
- style: {
117256
- fontFamily: "monospace",
117257
- fontSize: 13
117258
- }
117259
- }, /*#__PURE__*/ React__default.createElement(Scale, {
117260
- size: 14,
117261
- style: {
117262
- marginRight: 8,
117263
- verticalAlign: "middle",
117264
- color: theme.colors.primary
117265
- }
117266
- }), metric)
117267
- },
117268
- {
117269
- title: "MOST COMMON",
117270
- dataIndex: "mostCommon",
117271
- key: "mostCommon",
117272
- render: (v)=>/*#__PURE__*/ React__default.createElement(Tag, {
117273
- style: {
117274
- background: theme.colors.success,
117275
- color: theme.colors.successForeground,
117276
- border: "none"
117277
- }
117278
- }, v)
117279
- },
117280
- {
117281
- title: "LEAST COMMON",
117282
- dataIndex: "leastCommon",
117283
- key: "leastCommon",
117284
- render: (v)=>/*#__PURE__*/ React__default.createElement("span", {
117285
- style: {
117286
- color: theme.colors.mutedForeground
117287
- }
117288
- }, v)
117289
- },
117290
- {
117291
- title: "DISTRIBUTION",
117292
- key: "distribution",
117293
- render: (_, row)=>{
117294
- const entries = Object.entries(row.counts).sort((a, b)=>b[1] - a[1]);
117295
- return /*#__PURE__*/ React__default.createElement("span", {
117296
- style: {
117297
- fontSize: 12,
117298
- color: theme.colors.mutedForeground
117299
- }
117300
- }, entries.map(([label, count])=>`${label}: ${count}`).join(" · "));
117301
- }
117302
- }
117303
- ];
117304
- return /*#__PURE__*/ React__default.createElement("div", {
117305
- style: {
117306
- width: "100%",
117307
- minWidth: 0,
117308
- overflow: "hidden"
117309
- }
117310
- }, /*#__PURE__*/ React__default.createElement("h3", {
117311
- style: {
117312
- margin: "0 0 16px",
117313
- fontSize: 16,
117314
- fontWeight: 600
117315
- }
117316
- }, resolvedTitle), /*#__PURE__*/ React__default.createElement(ForwardTable, {
117317
- dataSource: rows,
117318
- columns: columns,
117319
- rowKey: "key",
117320
- pagination: false,
117321
- size: "small",
117322
- style: {
117323
- width: "100%",
117324
- background: theme.colors.card,
117325
- border: `1px solid ${theme.colors.border}`
117326
- }
117327
- }));
117853
+ return /*#__PURE__*/ React__default.createElement(JudgeAggregateView, {
117854
+ metrics: dataSource,
117855
+ onAgentNodeClick: onAgentNodeClick
117856
+ });
117328
117857
  }
117329
117858
  // ToolUse (tree table)
117330
117859
  const toolRows = dataSource;
@@ -117877,7 +118406,7 @@ const EvaluatorResult = ({ evaluation, evaluatorId, backHref, onAgentNodeClick }
117877
118406
  minWidth: 0
117878
118407
  }
117879
118408
  }, /*#__PURE__*/ React__default.createElement(AggregateResultsTable, {
117880
- rawResults: rawResults.filter((r)=>isToolResult(r) || isToolAggregate(r)),
118409
+ rawResults: rawResults,
117881
118410
  aggregateResults: aggregateResults,
117882
118411
  agents: evaluation.agents,
117883
118412
  evaluatorName: evaluatorName,
@@ -119736,6 +120265,166 @@ const GlobalStyles = ()=>{
119736
120265
  --ring: #6366f1;
119737
120266
  --radius: 0.5rem;
119738
120267
  }
120268
+
120269
+ html.liquid-glass-light {
120270
+ color: hsl(222 47% 11%);
120271
+ }
120272
+
120273
+ html.liquid-glass-light::before {
120274
+ content: "";
120275
+ position: fixed;
120276
+ inset: 0;
120277
+ z-index: -1;
120278
+ pointer-events: none;
120279
+ background:
120280
+ radial-gradient(120% 90% at 10% 10%, hsl(210 55% 92%) 0%, transparent 52%),
120281
+ radial-gradient(90% 70% at 90% 20%, hsl(220 45% 88%) 0%, transparent 45%),
120282
+ radial-gradient(70% 60% at 50% 100%, hsl(200 35% 88%) 0%, transparent 50%), hsl(210 30% 91%);
120283
+ }
120284
+
120285
+ html.liquid-glass-light body {
120286
+ background-color: hsl(210 30% 91%);
120287
+ color: hsl(222 47% 11%);
120288
+ }
120289
+
120290
+ html.liquid-glass-light .react-flow {
120291
+ contain: paint;
120292
+ }
120293
+
120294
+ html.liquid-glass-light .react-flow__edge-label {
120295
+ background: hsla(0 0% 100% / 0.92);
120296
+ border: 1px solid hsla(210 28% 72% / 0.55);
120297
+ color: hsl(222 47% 11%);
120298
+ }
120299
+
120300
+ html.liquid-glass-light .file-selector-refresh-btn {
120301
+ border: 1px solid hsla(210 28% 72% / 0.55);
120302
+ background-color: hsla(0 0% 100% / 0.88);
120303
+ color: hsl(222 47% 11%);
120304
+ }
120305
+
120306
+ html.liquid-glass-light .file-selector-refresh-btn:hover {
120307
+ background-color: hsla(0 0% 100% / 0.96);
120308
+ color: hsl(222 47% 14%);
120309
+ }
120310
+
120311
+ html.liquid-glass-light .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120312
+ background-color: hsla(48 96% 53% / 0.22) !important;
120313
+ }
120314
+
120315
+ html.liquid-glass-light {
120316
+ --background: hsl(210 30% 91%);
120317
+ --foreground: hsl(222 47% 11%);
120318
+ --card: hsla(0 0% 100% / 0.88);
120319
+ --card-foreground: hsl(222 47% 11%);
120320
+ --popover: hsla(0 0% 100% / 0.94);
120321
+ --popover-foreground: hsl(222 47% 11%);
120322
+ --primary: hsl(211 92% 45%);
120323
+ --primary-foreground: hsl(210 40% 98%);
120324
+ --secondary: hsla(210 40% 98% / 0.45);
120325
+ --secondary-foreground: hsl(222 47% 18%);
120326
+ --muted: hsla(210 25% 98% / 0.35);
120327
+ --muted-foreground: hsl(215 16% 40%);
120328
+ --accent: hsla(210 60% 96% / 0.55);
120329
+ --accent-foreground: hsl(222 47% 18%);
120330
+ --destructive: hsl(0 72% 51%);
120331
+ --destructive-foreground: hsl(210 40% 98%);
120332
+ --border: hsla(210 28% 72% / 0.55);
120333
+ --input: hsla(210 28% 88% / 0.65);
120334
+ --ring: hsl(211 92% 45%);
120335
+ --radius: 0.75rem;
120336
+ }
120337
+
120338
+ html.liquid-glass-dark {
120339
+ color: hsl(210 36% 96%);
120340
+ }
120341
+
120342
+ html.liquid-glass-dark::before {
120343
+ content: "";
120344
+ position: fixed;
120345
+ inset: 0;
120346
+ z-index: -1;
120347
+ pointer-events: none;
120348
+ background:
120349
+ radial-gradient(130% 100% at 20% 0%, hsl(222 42% 14%) 0%, transparent 55%),
120350
+ radial-gradient(90% 80% at 95% 30%, hsl(232 38% 18%) 0%, transparent 45%),
120351
+ radial-gradient(80% 70% at 50% 100%, hsl(215 36% 12%) 0%, transparent 50%), hsl(222 28% 9%);
120352
+ }
120353
+
120354
+ html.liquid-glass-dark body {
120355
+ background-color: hsl(222 28% 9%);
120356
+ color: hsl(210 36% 96%);
120357
+ }
120358
+
120359
+ html.liquid-glass-dark .react-flow {
120360
+ contain: paint;
120361
+ }
120362
+
120363
+ html.liquid-glass-dark .react-flow__edge-label {
120364
+ background: hsla(222 22% 18% / 0.92);
120365
+ border: 1px solid hsla(215 22% 42% / 0.45);
120366
+ color: hsl(210 36% 96%);
120367
+ }
120368
+
120369
+ html.liquid-glass-dark .file-selector-refresh-btn {
120370
+ border: 1px solid hsla(215 22% 42% / 0.45);
120371
+ background-color: hsla(222 22% 14% / 0.88);
120372
+ color: hsl(210 36% 96%);
120373
+ }
120374
+
120375
+ html.liquid-glass-dark .file-selector-refresh-btn:hover {
120376
+ background-color: hsla(222 22% 18% / 0.96);
120377
+ color: hsl(210 40% 98%);
120378
+ }
120379
+
120380
+ html.liquid-glass-dark .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120381
+ background-color: hsla(217 32% 28% / 0.55) !important;
120382
+ }
120383
+
120384
+ html.liquid-glass-dark {
120385
+ --background: hsl(222 28% 9%);
120386
+ --foreground: hsl(210 36% 96%);
120387
+ --card: hsla(222 22% 14% / 0.88);
120388
+ --card-foreground: hsl(210 36% 96%);
120389
+ --popover: hsla(222 24% 12% / 0.94);
120390
+ --popover-foreground: hsl(210 36% 96%);
120391
+ --primary: hsl(212 92% 62%);
120392
+ --primary-foreground: hsl(222 47% 8%);
120393
+ --secondary: hsla(217 28% 22% / 0.55);
120394
+ --secondary-foreground: hsl(210 36% 94%);
120395
+ --muted: hsla(217 22% 18% / 0.45);
120396
+ --muted-foreground: hsl(215 18% 72%);
120397
+ --accent: hsla(217 26% 22% / 0.55);
120398
+ --accent-foreground: hsl(210 36% 96%);
120399
+ --destructive: hsl(0 72% 58%);
120400
+ --destructive-foreground: hsl(210 40% 98%);
120401
+ --border: hsla(215 22% 42% / 0.45);
120402
+ --input: hsla(217 22% 22% / 0.65);
120403
+ --ring: hsl(212 92% 62%);
120404
+ --radius: 0.75rem;
120405
+ }
120406
+
120407
+ @media (prefers-reduced-transparency: reduce) {
120408
+ html.liquid-glass-light::before,
120409
+ html.liquid-glass-dark::before {
120410
+ display: none;
120411
+ }
120412
+
120413
+ html.liquid-glass-light body {
120414
+ background-color: hsl(210 30% 91%);
120415
+ }
120416
+
120417
+ html.liquid-glass-dark body {
120418
+ background-color: hsl(222 28% 9%);
120419
+ }
120420
+
120421
+ html.liquid-glass-light .react-flow__edge-label,
120422
+ html.liquid-glass-dark .react-flow__edge-label,
120423
+ html.liquid-glass-light .file-selector-refresh-btn,
120424
+ html.liquid-glass-dark .file-selector-refresh-btn {
120425
+ background-color: var(--card);
120426
+ }
120427
+ }
119739
120428
  `
119740
120429
  });
119741
120430
  };
@@ -119876,4 +120565,4 @@ const GlobalStyles = ()=>{
119876
120565
  return getSafeColor(props.theme, path, fallback);
119877
120566
  };
119878
120567
 
119879
- export { AgenticFlowVisualizer, AnthropicIcon, AppleIcon, Badge, Drawer, Edge, EvaluationDetailsDrawer, EvaluationsCompareDrawer, EvaluationsComparePage, EvaluationsCompareView, EvaluationsErrorCard, EvaluationsTable, EvaluatorResult, GlobalStyles, GoogleIcon, JsonTreeViewer, Node$1 as Node, OllamaIcon, OpenAIIcon, SafeThemeProvider, SessionDetails, Sheet, ThemeProvider, Timeline, Visualizer, calculateAutoLayout, cn, conditionalStyle, createSafeTheme, darkTheme, defaultTheme$1 as defaultTheme, detectContentType, escapeDotPathSegment, evaluationsHaveSameMetrics, formatCurrency, formatDateFriendly, formatDateRelative, formatDateShort, formatDuration, formatJsonTreePrimitive, formatLatency, formatMetricValue$1 as formatMetricValue, formatNumberWithCommas, formatToolCalls, getColor, getDefaultTimelineStepForRun, getSafeColor, getSafeSpacing, getSafeThemeValue, getSpacing, getStatusColor, isEvaluationDto, isPlainObject, lightTheme, safeStyled, safeThemeColor, safeThemeSpacing, safeThemeValue, toTitleCase, transformEvaluation, truncateText, useComponentTheme, useSafeTheme, useTheme$1 as useTheme, useThemeValue };
120568
+ export { AgenticFlowVisualizer, AnthropicIcon, AppleIcon, Badge, Drawer, Edge, EvaluationDetailsDrawer, EvaluationsCompareDrawer, EvaluationsComparePage, EvaluationsCompareView, EvaluationsErrorCard, EvaluationsTable, EvaluatorResult, GlobalStyles, GoogleIcon, JsonTreeViewer, Node$1 as Node, OllamaIcon, OpenAIIcon, SafeThemeProvider, SessionDetails, Sheet, ThemeProvider, Timeline, Visualizer, calculateAutoLayout, cn, conditionalStyle, createSafeTheme, darkTheme, defaultTheme$1 as defaultTheme, detectContentType, escapeDotPathSegment, evaluationsHaveSameMetrics, formatCurrency, formatDateFriendly, formatDateRelative, formatDateShort, formatDuration, formatJsonTreePrimitive, formatLatency, formatMetricValue$1 as formatMetricValue, formatNumberWithCommas, formatToolCalls, getColor, getDefaultTimelineStepForRun, getSafeColor, getSafeSpacing, getSafeThemeValue, getSpacing, getStatusColor, isEvaluationDto, isPlainObject, lightTheme, liquidGlassDarkTheme, liquidGlassLightTheme, safeStyled, safeThemeColor, safeThemeSpacing, safeThemeValue, themeForMode, themeToMode, toTitleCase, transformEvaluation, truncateText, useComponentTheme, useSafeTheme, useTheme$1 as useTheme, useThemeValue };