@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/cjs/index.js CHANGED
@@ -12939,7 +12939,7 @@ const createLucideIcon = (iconName, iconNode)=>{
12939
12939
  return Component;
12940
12940
  };
12941
12941
 
12942
- const __iconNode$y = [
12942
+ const __iconNode$z = [
12943
12943
  [
12944
12944
  "path",
12945
12945
  {
@@ -12955,9 +12955,9 @@ const __iconNode$y = [
12955
12955
  }
12956
12956
  ]
12957
12957
  ];
12958
- const ArrowLeft = createLucideIcon("arrow-left", __iconNode$y);
12958
+ const ArrowLeft = createLucideIcon("arrow-left", __iconNode$z);
12959
12959
 
12960
- const __iconNode$x = [
12960
+ const __iconNode$y = [
12961
12961
  [
12962
12962
  "path",
12963
12963
  {
@@ -12973,9 +12973,9 @@ const __iconNode$x = [
12973
12973
  }
12974
12974
  ]
12975
12975
  ];
12976
- const ArrowRight = createLucideIcon("arrow-right", __iconNode$x);
12976
+ const ArrowRight = createLucideIcon("arrow-right", __iconNode$y);
12977
12977
 
12978
- const __iconNode$w = [
12978
+ const __iconNode$x = [
12979
12979
  [
12980
12980
  "path",
12981
12981
  {
@@ -13023,9 +13023,9 @@ const __iconNode$w = [
13023
13023
  }
13024
13024
  ]
13025
13025
  ];
13026
- const Bot = createLucideIcon("bot", __iconNode$w);
13026
+ const Bot = createLucideIcon("bot", __iconNode$x);
13027
13027
 
13028
- const __iconNode$v = [
13028
+ const __iconNode$w = [
13029
13029
  [
13030
13030
  "path",
13031
13031
  {
@@ -13059,9 +13059,9 @@ const __iconNode$v = [
13059
13059
  }
13060
13060
  ]
13061
13061
  ];
13062
- const Calendar = createLucideIcon("calendar", __iconNode$v);
13062
+ const Calendar = createLucideIcon("calendar", __iconNode$w);
13063
13063
 
13064
- const __iconNode$u = [
13064
+ const __iconNode$v = [
13065
13065
  [
13066
13066
  "path",
13067
13067
  {
@@ -13118,9 +13118,9 @@ const __iconNode$u = [
13118
13118
  }
13119
13119
  ]
13120
13120
  ];
13121
- const ChartNetwork = createLucideIcon("chart-network", __iconNode$u);
13121
+ const ChartNetwork = createLucideIcon("chart-network", __iconNode$v);
13122
13122
 
13123
- const __iconNode$t = [
13123
+ const __iconNode$u = [
13124
13124
  [
13125
13125
  "path",
13126
13126
  {
@@ -13129,9 +13129,9 @@ const __iconNode$t = [
13129
13129
  }
13130
13130
  ]
13131
13131
  ];
13132
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$t);
13132
+ const ChevronDown = createLucideIcon("chevron-down", __iconNode$u);
13133
13133
 
13134
- const __iconNode$s = [
13134
+ const __iconNode$t = [
13135
13135
  [
13136
13136
  "path",
13137
13137
  {
@@ -13140,9 +13140,9 @@ const __iconNode$s = [
13140
13140
  }
13141
13141
  ]
13142
13142
  ];
13143
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$s);
13143
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$t);
13144
13144
 
13145
- const __iconNode$r = [
13145
+ const __iconNode$s = [
13146
13146
  [
13147
13147
  "path",
13148
13148
  {
@@ -13158,9 +13158,9 @@ const __iconNode$r = [
13158
13158
  }
13159
13159
  ]
13160
13160
  ];
13161
- const ChevronsDown = createLucideIcon("chevrons-down", __iconNode$r);
13161
+ const ChevronsDown = createLucideIcon("chevrons-down", __iconNode$s);
13162
13162
 
13163
- const __iconNode$q = [
13163
+ const __iconNode$r = [
13164
13164
  [
13165
13165
  "path",
13166
13166
  {
@@ -13176,9 +13176,9 @@ const __iconNode$q = [
13176
13176
  }
13177
13177
  ]
13178
13178
  ];
13179
- const ChevronsUp = createLucideIcon("chevrons-up", __iconNode$q);
13179
+ const ChevronsUp = createLucideIcon("chevrons-up", __iconNode$r);
13180
13180
 
13181
- const __iconNode$p = [
13181
+ const __iconNode$q = [
13182
13182
  [
13183
13183
  "circle",
13184
13184
  {
@@ -13209,9 +13209,9 @@ const __iconNode$p = [
13209
13209
  }
13210
13210
  ]
13211
13211
  ];
13212
- const CircleAlert = createLucideIcon("circle-alert", __iconNode$p);
13212
+ const CircleAlert = createLucideIcon("circle-alert", __iconNode$q);
13213
13213
 
13214
- const __iconNode$o = [
13214
+ const __iconNode$p = [
13215
13215
  [
13216
13216
  "path",
13217
13217
  {
@@ -13227,9 +13227,9 @@ const __iconNode$o = [
13227
13227
  }
13228
13228
  ]
13229
13229
  ];
13230
- const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$o);
13230
+ const CircleCheckBig = createLucideIcon("circle-check-big", __iconNode$p);
13231
13231
 
13232
- const __iconNode$n = [
13232
+ const __iconNode$o = [
13233
13233
  [
13234
13234
  "circle",
13235
13235
  {
@@ -13254,9 +13254,9 @@ const __iconNode$n = [
13254
13254
  }
13255
13255
  ]
13256
13256
  ];
13257
- const CircleDollarSign = createLucideIcon("circle-dollar-sign", __iconNode$n);
13257
+ const CircleDollarSign = createLucideIcon("circle-dollar-sign", __iconNode$o);
13258
13258
 
13259
- const __iconNode$m = [
13259
+ const __iconNode$n = [
13260
13260
  [
13261
13261
  "circle",
13262
13262
  {
@@ -13274,9 +13274,9 @@ const __iconNode$m = [
13274
13274
  }
13275
13275
  ]
13276
13276
  ];
13277
- const Clock = createLucideIcon("clock", __iconNode$m);
13277
+ const Clock = createLucideIcon("clock", __iconNode$n);
13278
13278
 
13279
- const __iconNode$l = [
13279
+ const __iconNode$m = [
13280
13280
  [
13281
13281
  "rect",
13282
13282
  {
@@ -13297,9 +13297,9 @@ const __iconNode$l = [
13297
13297
  }
13298
13298
  ]
13299
13299
  ];
13300
- const Copy = createLucideIcon("copy", __iconNode$l);
13300
+ const Copy = createLucideIcon("copy", __iconNode$m);
13301
13301
 
13302
- const __iconNode$k = [
13302
+ const __iconNode$l = [
13303
13303
  [
13304
13304
  "path",
13305
13305
  {
@@ -13407,9 +13407,9 @@ const __iconNode$k = [
13407
13407
  }
13408
13408
  ]
13409
13409
  ];
13410
- const Cpu = createLucideIcon("cpu", __iconNode$k);
13410
+ const Cpu = createLucideIcon("cpu", __iconNode$l);
13411
13411
 
13412
- const __iconNode$j = [
13412
+ const __iconNode$k = [
13413
13413
  [
13414
13414
  "line",
13415
13415
  {
@@ -13428,9 +13428,9 @@ const __iconNode$j = [
13428
13428
  }
13429
13429
  ]
13430
13430
  ];
13431
- const DollarSign = createLucideIcon("dollar-sign", __iconNode$j);
13431
+ const DollarSign = createLucideIcon("dollar-sign", __iconNode$k);
13432
13432
 
13433
- const __iconNode$i = [
13433
+ const __iconNode$j = [
13434
13434
  [
13435
13435
  "path",
13436
13436
  {
@@ -13460,9 +13460,9 @@ const __iconNode$i = [
13460
13460
  }
13461
13461
  ]
13462
13462
  ];
13463
- const FileInput = createLucideIcon("file-input", __iconNode$i);
13463
+ const FileInput = createLucideIcon("file-input", __iconNode$j);
13464
13464
 
13465
- const __iconNode$h = [
13465
+ const __iconNode$i = [
13466
13466
  [
13467
13467
  "path",
13468
13468
  {
@@ -13492,9 +13492,9 @@ const __iconNode$h = [
13492
13492
  }
13493
13493
  ]
13494
13494
  ];
13495
- const FileOutput = createLucideIcon("file-output", __iconNode$h);
13495
+ const FileOutput = createLucideIcon("file-output", __iconNode$i);
13496
13496
 
13497
- const __iconNode$g = [
13497
+ const __iconNode$h = [
13498
13498
  [
13499
13499
  "path",
13500
13500
  {
@@ -13552,9 +13552,9 @@ const __iconNode$g = [
13552
13552
  }
13553
13553
  ]
13554
13554
  ];
13555
- const FoldVertical = createLucideIcon("fold-vertical", __iconNode$g);
13555
+ const FoldVertical = createLucideIcon("fold-vertical", __iconNode$h);
13556
13556
 
13557
- const __iconNode$f = [
13557
+ const __iconNode$g = [
13558
13558
  [
13559
13559
  "line",
13560
13560
  {
@@ -13596,9 +13596,9 @@ const __iconNode$f = [
13596
13596
  }
13597
13597
  ]
13598
13598
  ];
13599
- const Hash = createLucideIcon("hash", __iconNode$f);
13599
+ const Hash = createLucideIcon("hash", __iconNode$g);
13600
13600
 
13601
- const __iconNode$e = [
13601
+ const __iconNode$f = [
13602
13602
  [
13603
13603
  "circle",
13604
13604
  {
@@ -13623,9 +13623,9 @@ const __iconNode$e = [
13623
13623
  }
13624
13624
  ]
13625
13625
  ];
13626
- const Info = createLucideIcon("info", __iconNode$e);
13626
+ const Info = createLucideIcon("info", __iconNode$f);
13627
13627
 
13628
- const __iconNode$d = [
13628
+ const __iconNode$e = [
13629
13629
  [
13630
13630
  "path",
13631
13631
  {
@@ -13662,7 +13662,39 @@ const __iconNode$d = [
13662
13662
  }
13663
13663
  ]
13664
13664
  ];
13665
- const ListChecks = createLucideIcon("list-checks", __iconNode$d);
13665
+ const ListChecks = createLucideIcon("list-checks", __iconNode$e);
13666
+
13667
+ const __iconNode$d = [
13668
+ [
13669
+ "path",
13670
+ {
13671
+ 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",
13672
+ key: "18887p"
13673
+ }
13674
+ ],
13675
+ [
13676
+ "path",
13677
+ {
13678
+ d: "M7 11h10",
13679
+ key: "1twpyw"
13680
+ }
13681
+ ],
13682
+ [
13683
+ "path",
13684
+ {
13685
+ d: "M7 15h6",
13686
+ key: "d9of3u"
13687
+ }
13688
+ ],
13689
+ [
13690
+ "path",
13691
+ {
13692
+ d: "M7 7h8",
13693
+ key: "af5zfr"
13694
+ }
13695
+ ]
13696
+ ];
13697
+ const MessageSquareText = createLucideIcon("message-square-text", __iconNode$d);
13666
13698
 
13667
13699
  const __iconNode$c = [
13668
13700
  [
@@ -16018,6 +16050,137 @@ const lightTheme = {
16018
16050
  slow: "0.3s ease-in-out"
16019
16051
  }
16020
16052
  };
16053
+ /** Light “Liquid Glass”–inspired palette (web approximation). */ const liquidGlassLightTheme = {
16054
+ colors: {
16055
+ background: "hsl(210 35% 92%)",
16056
+ foreground: "hsl(222 47% 11%)",
16057
+ card: "hsla(0 0% 100% / 0.88)",
16058
+ cardForeground: "hsl(222 47% 11%)",
16059
+ popover: "hsla(0 0% 100% / 0.94)",
16060
+ popoverForeground: "hsl(222 47% 11%)",
16061
+ primary: "hsl(211 92% 45%)",
16062
+ primaryForeground: "hsl(210 40% 98%)",
16063
+ secondary: "hsla(210 40% 98% / 0.45)",
16064
+ secondaryForeground: "hsl(222 47% 18%)",
16065
+ muted: "hsla(210 25% 98% / 0.35)",
16066
+ mutedForeground: "hsl(215 16% 40%)",
16067
+ accent: "hsla(210 60% 96% / 0.55)",
16068
+ accentForeground: "hsl(222 47% 18%)",
16069
+ destructive: "hsl(0 72% 51%)",
16070
+ destructiveForeground: "hsl(210 40% 98%)",
16071
+ success: "hsl(142.1 76.2% 32%)",
16072
+ successForeground: "hsl(210 40% 98%)",
16073
+ border: "hsla(210 28% 72% / 0.55)",
16074
+ mutedBorder: "hsla(210 22% 80% / 0.45)",
16075
+ input: "hsla(210 28% 88% / 0.65)",
16076
+ ring: "hsl(211 92% 45%)",
16077
+ tagTooluse: {
16078
+ bg: "hsla(199 89% 48% / 0.14)",
16079
+ border: "hsla(199 89% 48% / 0.35)",
16080
+ color: "hsl(200 98% 32%)"
16081
+ },
16082
+ tagLlminference: {
16083
+ bg: "hsla(271 91% 56% / 0.12)",
16084
+ border: "hsla(271 91% 56% / 0.35)",
16085
+ color: "hsl(271 81% 38%)"
16086
+ },
16087
+ tagJudge: {
16088
+ bg: "hsla(0 84% 60% / 0.12)",
16089
+ border: "hsla(0 84% 55% / 0.35)",
16090
+ color: "hsl(0 72% 40%)"
16091
+ },
16092
+ tagToolLevel1: {
16093
+ bg: "hsla(142 70% 42% / 0.15)",
16094
+ color: "hsl(142 71% 28%)"
16095
+ },
16096
+ tagToolLevel2: {
16097
+ bg: "hsla(217 91% 52% / 0.12)",
16098
+ color: "hsl(217 91% 38%)"
16099
+ },
16100
+ tagToolLevel3: {
16101
+ bg: "hsla(271 91% 56% / 0.12)",
16102
+ color: "hsl(271 81% 38%)"
16103
+ }
16104
+ },
16105
+ spacing: lightTheme.spacing,
16106
+ borderRadius: {
16107
+ sm: "calc(var(--radius) - 4px)",
16108
+ md: "calc(var(--radius) - 2px)",
16109
+ lg: "var(--radius)",
16110
+ xl: "1rem"
16111
+ },
16112
+ fontSize: lightTheme.fontSize,
16113
+ fontWeight: lightTheme.fontWeight,
16114
+ shadows: {
16115
+ sm: "0 1px 2px hsla(210 22% 25% / 0.06)",
16116
+ md: "0 8px 24px hsla(210 28% 18% / 0.08)",
16117
+ lg: "0 18px 48px hsla(210 28% 15% / 0.1)"
16118
+ },
16119
+ transitions: lightTheme.transitions
16120
+ };
16121
+ /** Dark “Liquid Glass”–inspired palette — translucent panels on a deep mesh-like base. */ const liquidGlassDarkTheme = {
16122
+ colors: {
16123
+ background: "hsl(222 28% 9%)",
16124
+ foreground: "hsl(210 36% 96%)",
16125
+ card: "hsla(222 22% 14% / 0.88)",
16126
+ cardForeground: "hsl(210 36% 96%)",
16127
+ popover: "hsla(222 24% 12% / 0.94)",
16128
+ popoverForeground: "hsl(210 36% 96%)",
16129
+ primary: "hsl(212 92% 62%)",
16130
+ primaryForeground: "hsl(222 47% 8%)",
16131
+ secondary: "hsla(217 28% 22% / 0.55)",
16132
+ secondaryForeground: "hsl(210 36% 94%)",
16133
+ muted: "hsla(217 22% 18% / 0.45)",
16134
+ mutedForeground: "hsl(215 18% 72%)",
16135
+ accent: "hsla(217 26% 22% / 0.55)",
16136
+ accentForeground: "hsl(210 36% 96%)",
16137
+ destructive: "hsl(0 72% 58%)",
16138
+ destructiveForeground: "hsl(210 40% 98%)",
16139
+ success: "hsl(142 76% 45%)",
16140
+ successForeground: "hsl(222 47% 8%)",
16141
+ border: "hsla(215 22% 42% / 0.45)",
16142
+ mutedBorder: "hsla(222 18% 28% / 0.5)",
16143
+ input: "hsla(217 22% 22% / 0.65)",
16144
+ ring: "hsl(212 92% 62%)",
16145
+ tagTooluse: {
16146
+ bg: "hsla(217 91% 55% / 0.18)",
16147
+ border: "hsla(217 91% 45% / 0.35)",
16148
+ color: "hsl(199 89% 72%)"
16149
+ },
16150
+ tagLlminference: {
16151
+ bg: "hsla(271 91% 58% / 0.15)",
16152
+ border: "hsla(271 91% 48% / 0.35)",
16153
+ color: "hsl(271 91% 78%)"
16154
+ },
16155
+ tagJudge: {
16156
+ bg: "hsla(0 72% 48% / 0.18)",
16157
+ border: "hsla(0 72% 42% / 0.35)",
16158
+ color: "hsl(0 84% 72%)"
16159
+ },
16160
+ tagToolLevel1: {
16161
+ bg: "hsla(142 70% 42% / 0.22)",
16162
+ color: "hsl(142 70% 72%)"
16163
+ },
16164
+ tagToolLevel2: {
16165
+ bg: "hsla(217 91% 52% / 0.2)",
16166
+ color: "hsl(217 91% 76%)"
16167
+ },
16168
+ tagToolLevel3: {
16169
+ bg: "hsla(271 91% 56% / 0.2)",
16170
+ color: "hsl(271 91% 76%)"
16171
+ }
16172
+ },
16173
+ spacing: lightTheme.spacing,
16174
+ borderRadius: liquidGlassLightTheme.borderRadius,
16175
+ fontSize: lightTheme.fontSize,
16176
+ fontWeight: lightTheme.fontWeight,
16177
+ shadows: {
16178
+ sm: "0 1px 2px hsla(0 0% 0% / 0.35)",
16179
+ md: "0 10px 28px hsla(0 0% 0% / 0.35)",
16180
+ lg: "0 22px 52px hsla(0 0% 0% / 0.45)"
16181
+ },
16182
+ transitions: lightTheme.transitions
16183
+ };
16021
16184
  const darkTheme = {
16022
16185
  colors: {
16023
16186
  background: "hsl(222.2 84% 4.9%)",
@@ -16079,81 +16242,124 @@ const darkTheme = {
16079
16242
  };
16080
16243
  const defaultTheme$1 = lightTheme;
16081
16244
 
16245
+ function normalizeStoredTheme(raw) {
16246
+ if (raw === "dark") return "dark";
16247
+ if (raw === "liquidGlassDark") return "liquidGlassDark";
16248
+ if (raw === "liquidGlassLight") return "liquidGlassLight";
16249
+ /* Migrate legacy single “Liquid Glass” preset */ if (raw === "liquidGlass") return "liquidGlassLight";
16250
+ return "light";
16251
+ }
16252
+ function themeForMode(mode) {
16253
+ switch(mode){
16254
+ case "dark":
16255
+ return darkTheme;
16256
+ case "liquidGlassLight":
16257
+ return liquidGlassLightTheme;
16258
+ case "liquidGlassDark":
16259
+ return liquidGlassDarkTheme;
16260
+ default:
16261
+ return lightTheme;
16262
+ }
16263
+ }
16264
+ function themeToMode(theme) {
16265
+ if (theme === darkTheme) return "dark";
16266
+ if (theme === liquidGlassDarkTheme) return "liquidGlassDark";
16267
+ if (theme === liquidGlassLightTheme) return "liquidGlassLight";
16268
+ return "light";
16269
+ }
16082
16270
  const ThemeContext = /*#__PURE__*/ React.createContext(undefined);
16083
16271
  const ThemeProvider = ({ children, theme: propTheme })=>{
16084
- const [currentTheme, setCurrentTheme] = React.useState(()=>{
16085
- // If a theme prop is provided, use it immediately
16272
+ const [themeMode, setThemeModeState] = React.useState(()=>{
16086
16273
  if (propTheme) {
16087
- return propTheme;
16274
+ return themeToMode(propTheme);
16088
16275
  }
16089
- // Only check localStorage if no theme prop is provided
16090
- // Handle cases where localStorage might not be available (e.g., test environments)
16091
16276
  try {
16092
- const savedTheme = localStorage.getItem("theme");
16093
- if (savedTheme === "dark") {
16094
- return darkTheme;
16095
- }
16096
- } catch (e) {
16097
- // localStorage not available, fall back to light theme
16098
- // This can happen in test environments or when localStorage is disabled
16099
- }
16100
- return lightTheme;
16277
+ return normalizeStoredTheme(localStorage.getItem("theme"));
16278
+ } catch {
16279
+ /* localStorage unavailable */ }
16280
+ return "light";
16101
16281
  });
16102
- // Update theme when propTheme changes
16282
+ const currentTheme = React.useMemo(()=>themeForMode(themeMode), [
16283
+ themeMode
16284
+ ]);
16103
16285
  React.useEffect(()=>{
16104
16286
  if (propTheme) {
16105
- setCurrentTheme(propTheme);
16287
+ setThemeModeState(themeToMode(propTheme));
16106
16288
  }
16107
16289
  }, [
16108
16290
  propTheme
16109
16291
  ]);
16110
- // Sync html.dark class for GlobalStyles and other CSS that uses html.dark
16111
16292
  React.useEffect(()=>{
16112
- const isDark = currentTheme === darkTheme;
16113
16293
  try {
16114
- if (isDark) {
16115
- document.documentElement.classList.add("dark");
16116
- } else {
16117
- document.documentElement.classList.remove("dark");
16118
- }
16119
- } catch (e) {
16120
- // document might not be available (e.g. SSR)
16121
- }
16294
+ const isClassicDark = themeMode === "dark";
16295
+ const isGlassLight = themeMode === "liquidGlassLight";
16296
+ const isGlassDark = themeMode === "liquidGlassDark";
16297
+ document.documentElement.classList.toggle("dark", isClassicDark);
16298
+ document.documentElement.classList.toggle("liquid-glass-light", isGlassLight);
16299
+ document.documentElement.classList.toggle("liquid-glass-dark", isGlassDark);
16300
+ /* Remove legacy class if present */ document.documentElement.classList.remove("liquid-glass");
16301
+ document.documentElement.dataset.theme = isClassicDark ? "dark" : isGlassLight ? "liquid-glass-light" : isGlassDark ? "liquid-glass-dark" : "light";
16302
+ } catch {
16303
+ /* document unavailable */ }
16122
16304
  }, [
16123
- currentTheme
16305
+ themeMode
16306
+ ]);
16307
+ React.useEffect(()=>{
16308
+ if (propTheme) return;
16309
+ try {
16310
+ localStorage.setItem("theme", themeMode);
16311
+ } catch {
16312
+ /* ignore */ }
16313
+ }, [
16314
+ themeMode,
16315
+ propTheme
16124
16316
  ]);
16125
- // Only listen for storage events if no theme prop is provided
16126
16317
  React.useEffect(()=>{
16127
16318
  if (propTheme) {
16128
- // If a theme prop is provided, don't listen for localStorage changes
16129
16319
  return;
16130
16320
  }
16131
16321
  const handleStorageChange = ()=>{
16132
16322
  try {
16133
- const savedTheme = localStorage.getItem("theme");
16134
- if (savedTheme === "dark") {
16135
- setCurrentTheme(darkTheme);
16136
- } else {
16137
- setCurrentTheme(lightTheme);
16138
- }
16139
- } catch (e) {
16140
- // localStorage not available, ignore storage changes
16141
- }
16323
+ setThemeModeState(normalizeStoredTheme(localStorage.getItem("theme")));
16324
+ } catch {
16325
+ /* ignore */ }
16142
16326
  };
16143
- // Listen for storage events (when localStorage changes in other tabs)
16144
16327
  window.addEventListener("storage", handleStorageChange);
16145
- return ()=>{
16146
- window.removeEventListener("storage", handleStorageChange);
16147
- };
16328
+ return ()=>window.removeEventListener("storage", handleStorageChange);
16148
16329
  }, [
16149
16330
  propTheme
16150
16331
  ]);
16332
+ const setThemeMode = React.useCallback((mode)=>{
16333
+ setThemeModeState(mode);
16334
+ }, []);
16335
+ const setTheme = React.useCallback((next)=>{
16336
+ setThemeModeState(themeToMode(next));
16337
+ }, []);
16338
+ const isLiquidGlassLight = themeMode === "liquidGlassLight";
16339
+ const isLiquidGlassDark = themeMode === "liquidGlassDark";
16340
+ const isLiquidGlass = isLiquidGlassLight || isLiquidGlassDark;
16341
+ const isClassicDarkTheme = themeMode === "dark";
16342
+ const isDarkMode = isClassicDarkTheme || isLiquidGlassDark;
16151
16343
  const value = React.useMemo(()=>({
16152
16344
  theme: currentTheme,
16153
- setTheme: setCurrentTheme,
16154
- isDarkMode: currentTheme === darkTheme
16345
+ themeMode,
16346
+ setTheme,
16347
+ setThemeMode,
16348
+ isDarkMode,
16349
+ isClassicDarkTheme,
16350
+ isLiquidGlass,
16351
+ isLiquidGlassLight,
16352
+ isLiquidGlassDark
16155
16353
  }), [
16156
- currentTheme
16354
+ currentTheme,
16355
+ themeMode,
16356
+ setTheme,
16357
+ setThemeMode,
16358
+ isDarkMode,
16359
+ isClassicDarkTheme,
16360
+ isLiquidGlass,
16361
+ isLiquidGlassLight,
16362
+ isLiquidGlassDark
16157
16363
  ]);
16158
16364
  return /*#__PURE__*/ React.createElement(ThemeContext.Provider, {
16159
16365
  value: value
@@ -16164,14 +16370,20 @@ const ThemeProvider = ({ children, theme: propTheme })=>{
16164
16370
  const useTheme$1 = ()=>{
16165
16371
  const context = React.useContext(ThemeContext);
16166
16372
  if (context === undefined) {
16167
- // Return a graceful fallback instead of throwing an error
16168
16373
  return {
16169
16374
  theme: lightTheme,
16375
+ themeMode: "light",
16170
16376
  setTheme: ()=>{
16171
- // No-op function when context is not available
16172
16377
  console.warn("Theme context not available. setTheme called but ignored.");
16173
16378
  },
16174
- isDarkMode: false // Default to light mode when no context
16379
+ setThemeMode: ()=>{
16380
+ console.warn("Theme context not available. setThemeMode called but ignored.");
16381
+ },
16382
+ isDarkMode: false,
16383
+ isClassicDarkTheme: false,
16384
+ isLiquidGlass: false,
16385
+ isLiquidGlassLight: false,
16386
+ isLiquidGlassDark: false
16175
16387
  };
16176
16388
  }
16177
16389
  return context;
@@ -16180,7 +16392,6 @@ const useThemeValue = ()=>{
16180
16392
  const { theme } = useTheme$1();
16181
16393
  return theme;
16182
16394
  };
16183
- // Helper hook for components that can accept a theme prop
16184
16395
  const useComponentTheme = (themeProp)=>{
16185
16396
  const { theme: contextTheme } = useTheme$1();
16186
16397
  return themeProp || contextTheme;
@@ -48586,7 +48797,7 @@ const CountUpLatency = ({ value })=>{
48586
48797
  };
48587
48798
  }
48588
48799
  const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48589
- const { theme } = useTheme$1();
48800
+ const { theme, isLiquidGlass } = useTheme$1();
48590
48801
  const [selectedRowIndex, setSelectedRowIndex] = React.useState(null);
48591
48802
  const [selectedLlmDetails, setSelectedLlmDetails] = React.useState(null);
48592
48803
  // Default to last row (total/aggregate) when drawer opens (only on first open)
@@ -48660,11 +48871,11 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48660
48871
  "data-testid": "node-details-drawer",
48661
48872
  styles: {
48662
48873
  body: {
48663
- background: theme.colors.background,
48874
+ background: isLiquidGlass ? theme.colors.popover : theme.colors.background,
48664
48875
  color: theme.colors.foreground
48665
48876
  },
48666
48877
  header: {
48667
- background: theme.colors.card,
48878
+ background: isLiquidGlass ? theme.colors.popover : theme.colors.card,
48668
48879
  borderBottom: `1px solid ${theme.colors.border}`
48669
48880
  }
48670
48881
  }
@@ -52025,8 +52236,7 @@ const SheetOverlay = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...
52025
52236
  bottom: 0,
52026
52237
  left: 0,
52027
52238
  zIndex: 50,
52028
- backgroundColor: "hsla(var(--background), 0.8)",
52029
- backdropFilter: "blur(4px)"
52239
+ backgroundColor: "rgba(0, 0, 0, 0.45)"
52030
52240
  },
52031
52241
  className: className,
52032
52242
  ...props,
@@ -52038,7 +52248,7 @@ const getSheetStyles = (side = "right")=>{
52038
52248
  position: "fixed",
52039
52249
  zIndex: 50,
52040
52250
  gap: "16px",
52041
- backgroundColor: "hsl(var(--background))",
52251
+ backgroundColor: "var(--background)",
52042
52252
  padding: "24px",
52043
52253
  boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
52044
52254
  transition: "all 0.3s ease-in-out"
@@ -52050,7 +52260,7 @@ const getSheetStyles = (side = "right")=>{
52050
52260
  left: 0,
52051
52261
  right: 0,
52052
52262
  top: 0,
52053
- borderBottom: "1px solid hsl(var(--border))"
52263
+ borderBottom: "1px solid var(--border)"
52054
52264
  };
52055
52265
  case "bottom":
52056
52266
  return {
@@ -52058,7 +52268,7 @@ const getSheetStyles = (side = "right")=>{
52058
52268
  left: 0,
52059
52269
  right: 0,
52060
52270
  bottom: 0,
52061
- borderTop: "1px solid hsl(var(--border))"
52271
+ borderTop: "1px solid var(--border)"
52062
52272
  };
52063
52273
  case "left":
52064
52274
  return {
@@ -52068,7 +52278,7 @@ const getSheetStyles = (side = "right")=>{
52068
52278
  left: 0,
52069
52279
  height: "100%",
52070
52280
  width: "75%",
52071
- borderRight: "1px solid hsl(var(--border))",
52281
+ borderRight: "1px solid var(--border)",
52072
52282
  maxWidth: "384px"
52073
52283
  };
52074
52284
  case "right":
@@ -52080,7 +52290,7 @@ const getSheetStyles = (side = "right")=>{
52080
52290
  right: 0,
52081
52291
  height: "100%",
52082
52292
  width: "75%",
52083
- borderLeft: "1px solid hsl(var(--border))",
52293
+ borderLeft: "1px solid var(--border)",
52084
52294
  maxWidth: "384px"
52085
52295
  };
52086
52296
  }
@@ -52141,7 +52351,7 @@ const SheetTitle = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...pr
52141
52351
  style: {
52142
52352
  fontSize: "18px",
52143
52353
  fontWeight: 600,
52144
- color: "hsl(var(--foreground))"
52354
+ color: "var(--foreground)"
52145
52355
  },
52146
52356
  className: className,
52147
52357
  ...props
@@ -52151,7 +52361,7 @@ const SheetDescription = /*#__PURE__*/ React__namespace.forwardRef(({ className,
52151
52361
  ref: ref,
52152
52362
  style: {
52153
52363
  fontSize: "14px",
52154
- color: "hsl(var(--muted-foreground))"
52364
+ color: "var(--muted-foreground)"
52155
52365
  },
52156
52366
  className: className,
52157
52367
  ...props
@@ -116318,7 +116528,18 @@ const useEvaluationsMock = ()=>{
116318
116528
  return React.useContext(EvaluationsMockContext);
116319
116529
  };
116320
116530
 
116321
- const API_BASE = "/api";
116531
+ /**
116532
+ * Railtracks HTTP API prefix. Same-origin `/api` by default (browser + viz proxy).
116533
+ * Set `VITE_API_ORIGIN` (e.g. `http://localhost:3030`) when the UI is served elsewhere (Electron, etc.).
116534
+ */ function resolveApiBase() {
116535
+ const origin = undefined.VITE_API_ORIGIN?.trim().replace(/\/$/, "") ?? "";
116536
+ if (!origin) {
116537
+ return "/api";
116538
+ }
116539
+ return `${origin}/api`;
116540
+ }
116541
+ const API_BASE = resolveApiBase();
116542
+
116322
116543
  const useEvaluations = ()=>{
116323
116544
  const mockContext = useEvaluationsMock();
116324
116545
  const [evaluations, setEvaluations] = React.useState([]);
@@ -116825,6 +117046,401 @@ function buildTreeFromProcessedData(latencyByTool, failureRateByTool, usageCount
116825
117046
  return buildTreeFromProcessedData(latencyByTool, failureRateByTool, usageCountByTool, latencyResults, failureResults, agentIdToSessionId);
116826
117047
  }
116827
117048
 
117049
+ const JUDGE_RESULT_PREFIX = "JudgeResult/";
117050
+ const JUDGE_REASONING_PREFIX = "JudgeReasoning/";
117051
+ /** Map agent node id -> session id from the agents array (new format only). */ function buildSessionByNodeId(agents) {
117052
+ const map = new Map();
117053
+ for (const agent of agents ?? []){
117054
+ for (const entry of agent.agent_node_ids ?? []){
117055
+ if (entry && typeof entry === "object" && "agent_node_id" in entry) {
117056
+ map.set(entry.agent_node_id, entry.session_id);
117057
+ }
117058
+ }
117059
+ }
117060
+ return map;
117061
+ }
117062
+ /** Map `${nodeId}::${metricName}` -> reasoning text from JudgeReasoning/* results. */ function buildReasoningByKey(rawResults) {
117063
+ const map = new Map();
117064
+ for (const item of rawResults){
117065
+ if (!isBaseResult(item)) continue;
117066
+ if (!item.result_name?.startsWith(JUDGE_REASONING_PREFIX)) continue;
117067
+ const metricName = item.result_name.slice(JUDGE_REASONING_PREFIX.length);
117068
+ const nodeId = item.agent_data_id?.[0];
117069
+ if (nodeId && typeof item.value === "string") {
117070
+ map.set(`${nodeId}::${metricName}`, item.value);
117071
+ }
117072
+ }
117073
+ return map;
117074
+ }
117075
+ function metricNameOf(agg) {
117076
+ return agg.metric?.name ?? agg.name?.replace(/^Aggregate\//, "") ?? "Unknown";
117077
+ }
117078
+ /** Collect the JudgeResult leaf nodes (label + node id) grouped by label. */ function groupNodesByLabel(agg, nodes, rawResults, metricName, sessionByNodeId, reasoningByKey) {
117079
+ const byLabel = new Map();
117080
+ const seen = new Set();
117081
+ const push = (label, nodeId)=>{
117082
+ const dedupeKey = `${label}::${nodeId}`;
117083
+ if (seen.has(dedupeKey)) return;
117084
+ seen.add(dedupeKey);
117085
+ const ref = {
117086
+ nodeId,
117087
+ sessionId: sessionByNodeId.get(nodeId),
117088
+ reasoning: reasoningByKey.get(`${nodeId}::${metricName}`)
117089
+ };
117090
+ const existing = byLabel.get(label);
117091
+ if (existing) existing.push(ref);
117092
+ else byLabel.set(label, [
117093
+ ref
117094
+ ]);
117095
+ };
117096
+ // Preferred: walk the aggregate's children leaf nodes.
117097
+ for (const childId of agg.children ?? []){
117098
+ const child = nodes[childId];
117099
+ if (child && isBaseResult(child)) {
117100
+ const nodeId = child.agent_data_id?.[0];
117101
+ if (nodeId) push(String(child.value), nodeId);
117102
+ }
117103
+ }
117104
+ // Fallback: derive from raw JudgeResult/<metric> results when no children are present.
117105
+ if (byLabel.size === 0) {
117106
+ const resultName = `${JUDGE_RESULT_PREFIX}${metricName}`;
117107
+ for (const item of rawResults){
117108
+ if (isBaseResult(item) && item.result_name === resultName) {
117109
+ const nodeId = item.agent_data_id?.[0];
117110
+ if (nodeId) push(String(item.value), nodeId);
117111
+ }
117112
+ }
117113
+ }
117114
+ return byLabel;
117115
+ }
117116
+ /** Build the Judge view model: one entry per categorical metric. */ function buildJudgeMetricsFromAggregate(input) {
117117
+ const { roots, nodes, agents, rawResults = [] } = input;
117118
+ const sessionByNodeId = buildSessionByNodeId(agents);
117119
+ const reasoningByKey = buildReasoningByKey(rawResults);
117120
+ // Prefer roots; fall back to scanning all nodes for categorical aggregates.
117121
+ const rootAggregates = roots.map((id)=>nodes[id]).filter((n)=>isAggregateCategorical(n));
117122
+ const aggregates = rootAggregates.length > 0 ? rootAggregates : Object.values(nodes).filter((n)=>isAggregateCategorical(n));
117123
+ return aggregates.map((agg, index)=>{
117124
+ const metricName = metricNameOf(agg);
117125
+ const counts = agg.counts ?? {};
117126
+ const categories = agg.categories ?? agg.metric?.categories ?? Object.keys(counts);
117127
+ const byLabel = groupNodesByLabel(agg, nodes, rawResults, metricName, sessionByNodeId, reasoningByKey);
117128
+ // Order labels by the metric's category order, then any extras found in the data.
117129
+ const orderedLabels = [
117130
+ ...categories
117131
+ ];
117132
+ for (const label of byLabel.keys()){
117133
+ if (!orderedLabels.includes(label)) orderedLabels.push(label);
117134
+ }
117135
+ const labels = orderedLabels.map((labelName)=>{
117136
+ const nodesForLabel = byLabel.get(labelName) ?? [];
117137
+ return {
117138
+ labelName,
117139
+ count: counts[labelName] ?? nodesForLabel.length,
117140
+ nodes: nodesForLabel
117141
+ };
117142
+ });
117143
+ const total = labels.reduce((sum, l)=>sum + l.count, 0);
117144
+ return {
117145
+ key: agg.identifier ?? `${metricName}-${index}`,
117146
+ metricName,
117147
+ description: agg.metric?.description ?? undefined,
117148
+ mostCommon: agg.most_common_label ?? undefined,
117149
+ leastCommon: agg.least_common_label ?? undefined,
117150
+ total,
117151
+ labels
117152
+ };
117153
+ });
117154
+ }
117155
+
117156
+ const SHORT_ID_LENGTH = 8;
117157
+ const shortenId = (id)=>id.length > SHORT_ID_LENGTH ? id.slice(0, SHORT_ID_LENGTH) : id;
117158
+ const NodeRow = ({ node, metricName, onAgentNodeClick })=>{
117159
+ const { theme } = useTheme$1();
117160
+ const [showReasoning, setShowReasoning] = React.useState(false);
117161
+ const clickable = !!onAgentNodeClick;
117162
+ const open = ()=>onAgentNodeClick?.(node.sessionId, node.nodeId);
117163
+ return /*#__PURE__*/ React.createElement("div", {
117164
+ style: {
117165
+ display: "flex",
117166
+ flexDirection: "column",
117167
+ gap: 8
117168
+ }
117169
+ }, /*#__PURE__*/ React.createElement("div", {
117170
+ style: {
117171
+ display: "flex",
117172
+ alignItems: "center",
117173
+ gap: 10,
117174
+ flexWrap: "wrap"
117175
+ }
117176
+ }, /*#__PURE__*/ React.createElement(Tooltip, {
117177
+ title: clickable ? `Inspect run · ${node.nodeId}` : node.nodeId
117178
+ }, /*#__PURE__*/ React.createElement("span", {
117179
+ role: clickable ? "button" : undefined,
117180
+ tabIndex: clickable ? 0 : undefined,
117181
+ onClick: clickable ? open : undefined,
117182
+ onKeyDown: clickable ? (e)=>{
117183
+ if (e.key === "Enter" || e.key === " ") {
117184
+ e.preventDefault();
117185
+ open();
117186
+ }
117187
+ } : undefined,
117188
+ style: {
117189
+ display: "inline-flex",
117190
+ alignItems: "center",
117191
+ gap: 6,
117192
+ padding: "3px 10px",
117193
+ borderRadius: 6,
117194
+ fontFamily: "monospace",
117195
+ fontSize: 12,
117196
+ fontWeight: 500,
117197
+ background: theme.colors.tagLlminference?.bg ?? theme.colors.muted,
117198
+ color: theme.colors.tagLlminference?.color ?? theme.colors.foreground,
117199
+ border: `1px solid ${theme.colors.tagLlminference?.border ?? theme.colors.border}`,
117200
+ cursor: clickable ? "pointer" : "default"
117201
+ }
117202
+ }, /*#__PURE__*/ React.createElement(Bot, {
117203
+ size: 13,
117204
+ style: {
117205
+ flexShrink: 0
117206
+ }
117207
+ }), shortenId(node.nodeId))), node.reasoning && /*#__PURE__*/ React.createElement("button", {
117208
+ type: "button",
117209
+ onClick: ()=>setShowReasoning((s)=>!s),
117210
+ style: {
117211
+ display: "inline-flex",
117212
+ alignItems: "center",
117213
+ gap: 5,
117214
+ padding: "3px 9px",
117215
+ borderRadius: 6,
117216
+ fontSize: 12,
117217
+ cursor: "pointer",
117218
+ background: "transparent",
117219
+ color: theme.colors.primary,
117220
+ border: `1px solid ${theme.colors.primary}`
117221
+ }
117222
+ }, /*#__PURE__*/ React.createElement(MessageSquareText, {
117223
+ size: 12
117224
+ }), showReasoning ? "Hide reasoning" : "Show reasoning")), node.reasoning && showReasoning && /*#__PURE__*/ React.createElement("div", {
117225
+ style: {
117226
+ padding: "10px 14px",
117227
+ background: theme.colors.muted,
117228
+ border: `1px solid ${theme.colors.border}`,
117229
+ borderRadius: 6,
117230
+ fontSize: 13,
117231
+ lineHeight: 1.5,
117232
+ whiteSpace: "pre-wrap",
117233
+ color: theme.colors.foreground
117234
+ }
117235
+ }, /*#__PURE__*/ React.createElement("div", {
117236
+ style: {
117237
+ fontWeight: 600,
117238
+ marginBottom: 6,
117239
+ color: theme.colors.mutedForeground
117240
+ }
117241
+ }, "Judge reasoning · ", metricName), node.reasoning));
117242
+ };
117243
+ const LabelPanelHeader = ({ label })=>{
117244
+ const { theme } = useTheme$1();
117245
+ const isEmpty = label.count === 0;
117246
+ return /*#__PURE__*/ React.createElement("div", {
117247
+ style: {
117248
+ display: "flex",
117249
+ alignItems: "center",
117250
+ gap: 10
117251
+ }
117252
+ }, /*#__PURE__*/ React.createElement("span", {
117253
+ style: {
117254
+ width: 7,
117255
+ height: 7,
117256
+ borderRadius: "50%",
117257
+ flexShrink: 0,
117258
+ background: isEmpty ? theme.colors.border : theme.colors.primary
117259
+ }
117260
+ }), /*#__PURE__*/ React.createElement("span", {
117261
+ style: {
117262
+ fontSize: 13,
117263
+ fontWeight: 600,
117264
+ color: isEmpty ? theme.colors.mutedForeground : undefined
117265
+ }
117266
+ }, label.labelName), /*#__PURE__*/ React.createElement("span", {
117267
+ style: {
117268
+ marginLeft: "auto",
117269
+ fontSize: 12,
117270
+ color: theme.colors.mutedForeground
117271
+ }
117272
+ }, label.count, " ", label.count === 1 ? "node" : "nodes"));
117273
+ };
117274
+ const MetricCard = ({ metric, onAgentNodeClick })=>{
117275
+ const { theme } = useTheme$1();
117276
+ const items = metric.labels.map((label)=>({
117277
+ key: label.labelName,
117278
+ label: /*#__PURE__*/ React.createElement(LabelPanelHeader, {
117279
+ label: label
117280
+ }),
117281
+ collapsible: label.count === 0 ? "disabled" : undefined,
117282
+ children: label.nodes.length === 0 ? /*#__PURE__*/ React.createElement("span", {
117283
+ style: {
117284
+ fontSize: 12,
117285
+ fontStyle: "italic",
117286
+ color: theme.colors.mutedForeground
117287
+ }
117288
+ }, "No evaluations") : /*#__PURE__*/ React.createElement("div", {
117289
+ style: {
117290
+ display: "flex",
117291
+ flexDirection: "column",
117292
+ gap: 12
117293
+ }
117294
+ }, label.nodes.map((node)=>/*#__PURE__*/ React.createElement(NodeRow, {
117295
+ key: node.nodeId,
117296
+ node: node,
117297
+ metricName: metric.metricName,
117298
+ onAgentNodeClick: onAgentNodeClick
117299
+ })))
117300
+ }));
117301
+ return /*#__PURE__*/ React.createElement("div", {
117302
+ style: {
117303
+ background: theme.colors.card,
117304
+ border: `1px solid ${theme.colors.border}`,
117305
+ borderRadius: 8,
117306
+ overflow: "hidden"
117307
+ }
117308
+ }, /*#__PURE__*/ React.createElement("div", {
117309
+ style: {
117310
+ padding: "14px 18px",
117311
+ borderBottom: `1px solid ${theme.colors.border}`,
117312
+ background: theme.colors.secondary
117313
+ }
117314
+ }, /*#__PURE__*/ React.createElement("div", {
117315
+ style: {
117316
+ display: "flex",
117317
+ alignItems: "center",
117318
+ gap: 12,
117319
+ flexWrap: "wrap"
117320
+ }
117321
+ }, /*#__PURE__*/ React.createElement(Scale, {
117322
+ size: 16,
117323
+ style: {
117324
+ color: theme.colors.primary,
117325
+ flexShrink: 0
117326
+ }
117327
+ }), /*#__PURE__*/ React.createElement("span", {
117328
+ style: {
117329
+ fontSize: 15,
117330
+ fontWeight: 600
117331
+ }
117332
+ }, metric.metricName), /*#__PURE__*/ React.createElement("div", {
117333
+ style: {
117334
+ display: "flex",
117335
+ flexWrap: "wrap",
117336
+ gap: 6,
117337
+ marginLeft: 4
117338
+ }
117339
+ }, metric.labels.map((label)=>/*#__PURE__*/ React.createElement(Tag, {
117340
+ key: label.labelName,
117341
+ style: {
117342
+ margin: 0,
117343
+ borderRadius: 12,
117344
+ fontSize: 12,
117345
+ ...label.count > 0 ? {
117346
+ background: theme.colors.tagLlminference?.bg ?? theme.colors.muted,
117347
+ color: theme.colors.tagLlminference?.color ?? theme.colors.foreground,
117348
+ border: `1px solid ${theme.colors.tagLlminference?.border ?? theme.colors.border}`
117349
+ } : {
117350
+ background: "transparent",
117351
+ color: theme.colors.mutedForeground,
117352
+ border: `1px solid ${theme.colors.border}`
117353
+ }
117354
+ }
117355
+ }, label.labelName, " ", /*#__PURE__*/ React.createElement("strong", null, label.count)))), /*#__PURE__*/ React.createElement("div", {
117356
+ style: {
117357
+ display: "flex",
117358
+ gap: 20,
117359
+ marginLeft: "auto",
117360
+ flexShrink: 0
117361
+ }
117362
+ }, /*#__PURE__*/ React.createElement(Meta, {
117363
+ label: "Most common",
117364
+ value: metric.mostCommon
117365
+ }), /*#__PURE__*/ React.createElement(Meta, {
117366
+ label: "Least common",
117367
+ value: metric.leastCommon
117368
+ }), /*#__PURE__*/ React.createElement(Meta, {
117369
+ label: "Evaluations",
117370
+ value: String(metric.total)
117371
+ }))), metric.description && /*#__PURE__*/ React.createElement("div", {
117372
+ style: {
117373
+ marginTop: 6,
117374
+ fontSize: 12,
117375
+ color: theme.colors.mutedForeground
117376
+ }
117377
+ }, metric.description)), /*#__PURE__*/ React.createElement(Collapse, {
117378
+ items: items,
117379
+ bordered: false,
117380
+ style: {
117381
+ background: theme.colors.card
117382
+ }
117383
+ }));
117384
+ };
117385
+ const Meta = ({ label, value })=>{
117386
+ const { theme } = useTheme$1();
117387
+ return /*#__PURE__*/ React.createElement("span", {
117388
+ style: {
117389
+ display: "flex",
117390
+ flexDirection: "column",
117391
+ alignItems: "flex-end",
117392
+ gap: 1
117393
+ }
117394
+ }, /*#__PURE__*/ React.createElement("span", {
117395
+ style: {
117396
+ fontSize: 10,
117397
+ textTransform: "uppercase",
117398
+ letterSpacing: 0.4,
117399
+ color: theme.colors.mutedForeground
117400
+ }
117401
+ }, label), /*#__PURE__*/ React.createElement("span", {
117402
+ style: {
117403
+ fontSize: 13,
117404
+ fontWeight: 500
117405
+ }
117406
+ }, value ?? "—"));
117407
+ };
117408
+ const JudgeAggregateView = ({ metrics, onAgentNodeClick })=>{
117409
+ const { theme } = useTheme$1();
117410
+ if (!metrics.length) {
117411
+ return /*#__PURE__*/ React.createElement("div", {
117412
+ style: {
117413
+ padding: 24,
117414
+ textAlign: "center",
117415
+ color: theme.colors.mutedForeground,
117416
+ fontSize: 14
117417
+ }
117418
+ }, "No judge metrics available");
117419
+ }
117420
+ return /*#__PURE__*/ React.createElement("div", {
117421
+ style: {
117422
+ width: "100%",
117423
+ minWidth: 0
117424
+ }
117425
+ }, /*#__PURE__*/ React.createElement("h3", {
117426
+ style: {
117427
+ margin: "0 0 16px",
117428
+ fontSize: 16,
117429
+ fontWeight: 600
117430
+ }
117431
+ }, "Judge Evaluator - Aggregate View"), /*#__PURE__*/ React.createElement("div", {
117432
+ style: {
117433
+ display: "flex",
117434
+ flexDirection: "column",
117435
+ gap: 12
117436
+ }
117437
+ }, metrics.map((metric)=>/*#__PURE__*/ React.createElement(MetricCard, {
117438
+ key: metric.key,
117439
+ metric: metric,
117440
+ onAgentNodeClick: onAgentNodeClick
117441
+ }))));
117442
+ };
117443
+
116828
117444
  function detectAggregateType(nodes) {
116829
117445
  const values = Object.values(nodes);
116830
117446
  if (values.some((n)=>n?.type === "ToolAggregate")) return "ToolUse";
@@ -116845,22 +117461,6 @@ function buildLLMInferenceFlatRows(nodes) {
116845
117461
  count: agg.values?.length ?? 0
116846
117462
  }));
116847
117463
  }
116848
- function buildJudgeRows(nodes) {
116849
- const values = Object.values(nodes);
116850
- const aggregates = values.filter((n)=>isAggregateCategorical(n));
116851
- return aggregates.map((agg)=>{
116852
- const counts = agg.counts ?? {};
116853
- const total = Object.values(counts).reduce((a, b)=>a + b, 0);
116854
- return {
116855
- key: agg.identifier ?? agg.metric?.name ?? "unknown",
116856
- metric: agg.metric?.name ?? "Unknown",
116857
- mostCommon: agg.most_common_label ?? "-",
116858
- leastCommon: agg.least_common_label ?? "-",
116859
- counts,
116860
- total
116861
- };
116862
- });
116863
- }
116864
117464
  // --- Shared helpers ---
116865
117465
  function getAllExpandableKeys(rows) {
116866
117466
  const keys = [];
@@ -116932,7 +117532,12 @@ const AggregateResultsTable = ({ rawResults = [], aggregateResults, agents, titl
116932
117532
  if (type === "Judge") {
116933
117533
  return {
116934
117534
  aggregateType: type,
116935
- dataSource: buildJudgeRows(aggregateResults.nodes),
117535
+ dataSource: buildJudgeMetricsFromAggregate({
117536
+ roots: aggregateResults.roots,
117537
+ nodes: aggregateResults.nodes,
117538
+ agents,
117539
+ rawResults
117540
+ }),
116936
117541
  llmIsTree: false,
116937
117542
  llmExpandableKeys: []
116938
117543
  };
@@ -117265,86 +117870,10 @@ const AggregateResultsTable = ({ rawResults = [], aggregateResults, agents, titl
117265
117870
  }));
117266
117871
  }
117267
117872
  if (aggregateType === "Judge") {
117268
- const rows = dataSource;
117269
- const columns = [
117270
- {
117271
- title: "METRIC",
117272
- dataIndex: "metric",
117273
- key: "metric",
117274
- render: (metric)=>/*#__PURE__*/ React.createElement("span", {
117275
- style: {
117276
- fontFamily: "monospace",
117277
- fontSize: 13
117278
- }
117279
- }, /*#__PURE__*/ React.createElement(Scale, {
117280
- size: 14,
117281
- style: {
117282
- marginRight: 8,
117283
- verticalAlign: "middle",
117284
- color: theme.colors.primary
117285
- }
117286
- }), metric)
117287
- },
117288
- {
117289
- title: "MOST COMMON",
117290
- dataIndex: "mostCommon",
117291
- key: "mostCommon",
117292
- render: (v)=>/*#__PURE__*/ React.createElement(Tag, {
117293
- style: {
117294
- background: theme.colors.success,
117295
- color: theme.colors.successForeground,
117296
- border: "none"
117297
- }
117298
- }, v)
117299
- },
117300
- {
117301
- title: "LEAST COMMON",
117302
- dataIndex: "leastCommon",
117303
- key: "leastCommon",
117304
- render: (v)=>/*#__PURE__*/ React.createElement("span", {
117305
- style: {
117306
- color: theme.colors.mutedForeground
117307
- }
117308
- }, v)
117309
- },
117310
- {
117311
- title: "DISTRIBUTION",
117312
- key: "distribution",
117313
- render: (_, row)=>{
117314
- const entries = Object.entries(row.counts).sort((a, b)=>b[1] - a[1]);
117315
- return /*#__PURE__*/ React.createElement("span", {
117316
- style: {
117317
- fontSize: 12,
117318
- color: theme.colors.mutedForeground
117319
- }
117320
- }, entries.map(([label, count])=>`${label}: ${count}`).join(" · "));
117321
- }
117322
- }
117323
- ];
117324
- return /*#__PURE__*/ React.createElement("div", {
117325
- style: {
117326
- width: "100%",
117327
- minWidth: 0,
117328
- overflow: "hidden"
117329
- }
117330
- }, /*#__PURE__*/ React.createElement("h3", {
117331
- style: {
117332
- margin: "0 0 16px",
117333
- fontSize: 16,
117334
- fontWeight: 600
117335
- }
117336
- }, resolvedTitle), /*#__PURE__*/ React.createElement(ForwardTable, {
117337
- dataSource: rows,
117338
- columns: columns,
117339
- rowKey: "key",
117340
- pagination: false,
117341
- size: "small",
117342
- style: {
117343
- width: "100%",
117344
- background: theme.colors.card,
117345
- border: `1px solid ${theme.colors.border}`
117346
- }
117347
- }));
117873
+ return /*#__PURE__*/ React.createElement(JudgeAggregateView, {
117874
+ metrics: dataSource,
117875
+ onAgentNodeClick: onAgentNodeClick
117876
+ });
117348
117877
  }
117349
117878
  // ToolUse (tree table)
117350
117879
  const toolRows = dataSource;
@@ -117897,7 +118426,7 @@ const EvaluatorResult = ({ evaluation, evaluatorId, backHref, onAgentNodeClick }
117897
118426
  minWidth: 0
117898
118427
  }
117899
118428
  }, /*#__PURE__*/ React.createElement(AggregateResultsTable, {
117900
- rawResults: rawResults.filter((r)=>isToolResult(r) || isToolAggregate(r)),
118429
+ rawResults: rawResults,
117901
118430
  aggregateResults: aggregateResults,
117902
118431
  agents: evaluation.agents,
117903
118432
  evaluatorName: evaluatorName,
@@ -119756,6 +120285,166 @@ const GlobalStyles = ()=>{
119756
120285
  --ring: #6366f1;
119757
120286
  --radius: 0.5rem;
119758
120287
  }
120288
+
120289
+ html.liquid-glass-light {
120290
+ color: hsl(222 47% 11%);
120291
+ }
120292
+
120293
+ html.liquid-glass-light::before {
120294
+ content: "";
120295
+ position: fixed;
120296
+ inset: 0;
120297
+ z-index: -1;
120298
+ pointer-events: none;
120299
+ background:
120300
+ radial-gradient(120% 90% at 10% 10%, hsl(210 55% 92%) 0%, transparent 52%),
120301
+ radial-gradient(90% 70% at 90% 20%, hsl(220 45% 88%) 0%, transparent 45%),
120302
+ radial-gradient(70% 60% at 50% 100%, hsl(200 35% 88%) 0%, transparent 50%), hsl(210 30% 91%);
120303
+ }
120304
+
120305
+ html.liquid-glass-light body {
120306
+ background-color: hsl(210 30% 91%);
120307
+ color: hsl(222 47% 11%);
120308
+ }
120309
+
120310
+ html.liquid-glass-light .react-flow {
120311
+ contain: paint;
120312
+ }
120313
+
120314
+ html.liquid-glass-light .react-flow__edge-label {
120315
+ background: hsla(0 0% 100% / 0.92);
120316
+ border: 1px solid hsla(210 28% 72% / 0.55);
120317
+ color: hsl(222 47% 11%);
120318
+ }
120319
+
120320
+ html.liquid-glass-light .file-selector-refresh-btn {
120321
+ border: 1px solid hsla(210 28% 72% / 0.55);
120322
+ background-color: hsla(0 0% 100% / 0.88);
120323
+ color: hsl(222 47% 11%);
120324
+ }
120325
+
120326
+ html.liquid-glass-light .file-selector-refresh-btn:hover {
120327
+ background-color: hsla(0 0% 100% / 0.96);
120328
+ color: hsl(222 47% 14%);
120329
+ }
120330
+
120331
+ html.liquid-glass-light .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120332
+ background-color: hsla(48 96% 53% / 0.22) !important;
120333
+ }
120334
+
120335
+ html.liquid-glass-light {
120336
+ --background: hsl(210 30% 91%);
120337
+ --foreground: hsl(222 47% 11%);
120338
+ --card: hsla(0 0% 100% / 0.88);
120339
+ --card-foreground: hsl(222 47% 11%);
120340
+ --popover: hsla(0 0% 100% / 0.94);
120341
+ --popover-foreground: hsl(222 47% 11%);
120342
+ --primary: hsl(211 92% 45%);
120343
+ --primary-foreground: hsl(210 40% 98%);
120344
+ --secondary: hsla(210 40% 98% / 0.45);
120345
+ --secondary-foreground: hsl(222 47% 18%);
120346
+ --muted: hsla(210 25% 98% / 0.35);
120347
+ --muted-foreground: hsl(215 16% 40%);
120348
+ --accent: hsla(210 60% 96% / 0.55);
120349
+ --accent-foreground: hsl(222 47% 18%);
120350
+ --destructive: hsl(0 72% 51%);
120351
+ --destructive-foreground: hsl(210 40% 98%);
120352
+ --border: hsla(210 28% 72% / 0.55);
120353
+ --input: hsla(210 28% 88% / 0.65);
120354
+ --ring: hsl(211 92% 45%);
120355
+ --radius: 0.75rem;
120356
+ }
120357
+
120358
+ html.liquid-glass-dark {
120359
+ color: hsl(210 36% 96%);
120360
+ }
120361
+
120362
+ html.liquid-glass-dark::before {
120363
+ content: "";
120364
+ position: fixed;
120365
+ inset: 0;
120366
+ z-index: -1;
120367
+ pointer-events: none;
120368
+ background:
120369
+ radial-gradient(130% 100% at 20% 0%, hsl(222 42% 14%) 0%, transparent 55%),
120370
+ radial-gradient(90% 80% at 95% 30%, hsl(232 38% 18%) 0%, transparent 45%),
120371
+ radial-gradient(80% 70% at 50% 100%, hsl(215 36% 12%) 0%, transparent 50%), hsl(222 28% 9%);
120372
+ }
120373
+
120374
+ html.liquid-glass-dark body {
120375
+ background-color: hsl(222 28% 9%);
120376
+ color: hsl(210 36% 96%);
120377
+ }
120378
+
120379
+ html.liquid-glass-dark .react-flow {
120380
+ contain: paint;
120381
+ }
120382
+
120383
+ html.liquid-glass-dark .react-flow__edge-label {
120384
+ background: hsla(222 22% 18% / 0.92);
120385
+ border: 1px solid hsla(215 22% 42% / 0.45);
120386
+ color: hsl(210 36% 96%);
120387
+ }
120388
+
120389
+ html.liquid-glass-dark .file-selector-refresh-btn {
120390
+ border: 1px solid hsla(215 22% 42% / 0.45);
120391
+ background-color: hsla(222 22% 14% / 0.88);
120392
+ color: hsl(210 36% 96%);
120393
+ }
120394
+
120395
+ html.liquid-glass-dark .file-selector-refresh-btn:hover {
120396
+ background-color: hsla(222 22% 18% / 0.96);
120397
+ color: hsl(210 40% 98%);
120398
+ }
120399
+
120400
+ html.liquid-glass-dark .ant-table-tbody > tr.evaluations-compare-diff-row > td {
120401
+ background-color: hsla(217 32% 28% / 0.55) !important;
120402
+ }
120403
+
120404
+ html.liquid-glass-dark {
120405
+ --background: hsl(222 28% 9%);
120406
+ --foreground: hsl(210 36% 96%);
120407
+ --card: hsla(222 22% 14% / 0.88);
120408
+ --card-foreground: hsl(210 36% 96%);
120409
+ --popover: hsla(222 24% 12% / 0.94);
120410
+ --popover-foreground: hsl(210 36% 96%);
120411
+ --primary: hsl(212 92% 62%);
120412
+ --primary-foreground: hsl(222 47% 8%);
120413
+ --secondary: hsla(217 28% 22% / 0.55);
120414
+ --secondary-foreground: hsl(210 36% 94%);
120415
+ --muted: hsla(217 22% 18% / 0.45);
120416
+ --muted-foreground: hsl(215 18% 72%);
120417
+ --accent: hsla(217 26% 22% / 0.55);
120418
+ --accent-foreground: hsl(210 36% 96%);
120419
+ --destructive: hsl(0 72% 58%);
120420
+ --destructive-foreground: hsl(210 40% 98%);
120421
+ --border: hsla(215 22% 42% / 0.45);
120422
+ --input: hsla(217 22% 22% / 0.65);
120423
+ --ring: hsl(212 92% 62%);
120424
+ --radius: 0.75rem;
120425
+ }
120426
+
120427
+ @media (prefers-reduced-transparency: reduce) {
120428
+ html.liquid-glass-light::before,
120429
+ html.liquid-glass-dark::before {
120430
+ display: none;
120431
+ }
120432
+
120433
+ html.liquid-glass-light body {
120434
+ background-color: hsl(210 30% 91%);
120435
+ }
120436
+
120437
+ html.liquid-glass-dark body {
120438
+ background-color: hsl(222 28% 9%);
120439
+ }
120440
+
120441
+ html.liquid-glass-light .react-flow__edge-label,
120442
+ html.liquid-glass-dark .react-flow__edge-label,
120443
+ html.liquid-glass-light .file-selector-refresh-btn,
120444
+ html.liquid-glass-dark .file-selector-refresh-btn {
120445
+ background-color: var(--card);
120446
+ }
120447
+ }
119759
120448
  `
119760
120449
  });
119761
120450
  };
@@ -119950,10 +120639,14 @@ exports.getStatusColor = getStatusColor;
119950
120639
  exports.isEvaluationDto = isEvaluationDto;
119951
120640
  exports.isPlainObject = isPlainObject;
119952
120641
  exports.lightTheme = lightTheme;
120642
+ exports.liquidGlassDarkTheme = liquidGlassDarkTheme;
120643
+ exports.liquidGlassLightTheme = liquidGlassLightTheme;
119953
120644
  exports.safeStyled = safeStyled;
119954
120645
  exports.safeThemeColor = safeThemeColor;
119955
120646
  exports.safeThemeSpacing = safeThemeSpacing;
119956
120647
  exports.safeThemeValue = safeThemeValue;
120648
+ exports.themeForMode = themeForMode;
120649
+ exports.themeToMode = themeToMode;
119957
120650
  exports.toTitleCase = toTitleCase;
119958
120651
  exports.transformEvaluation = transformEvaluation;
119959
120652
  exports.truncateText = truncateText;