@railtownai/railtracks-visualizer 0.0.60 → 0.0.62

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
@@ -4,37 +4,35 @@ import { jsxs, Fragment, jsx as jsx$1 } from 'react/jsx-runtime';
4
4
  import * as ReactDOM from 'react-dom';
5
5
  import ReactDOM__default from 'react-dom';
6
6
  import CountUp from 'react-countup';
7
- import RcDrawer from '@rc-component/drawer';
8
- import useId$2 from '@rc-component/util/es/hooks/useId';
9
- import { composeRef, supportRef, getNodeRef, supportNodeRef, useComposeRef as useComposeRef$1 } from '@rc-component/util/es/ref';
10
- import '@rc-component/form';
7
+ import { render, unmount } from '@rc-component/util/es/React/render';
8
+ import { createTheme, useCacheToken, unit, useStyleRegister, StyleContext, Keyframes } from '@ant-design/cssinjs';
9
+ import IconContext from '@ant-design/icons/es/components/Context';
11
10
  import { warning as warning$2, merge, useEvent, toArray as toArray$1, omit, useComposeRef, useControlledState } from '@rc-component/util';
12
- import CloseOutlined from '@ant-design/icons/es/icons/CloseOutlined';
13
- import pickAttrs from '@rc-component/util/es/pickAttrs';
11
+ import useMemo$1 from '@rc-component/util/es/hooks/useMemo';
14
12
  import Pagination$1 from '@rc-component/pagination/es/locale/en_US';
15
- import { createTheme, useCacheToken, unit, useStyleRegister, StyleContext, Keyframes } from '@ant-design/cssinjs';
16
13
  import { generate, presetPrimaryColors, presetPalettes, gold } from '@ant-design/colors';
17
14
  import { FastColor } from '@ant-design/fast-color';
18
- import IconContext from '@ant-design/icons/es/components/Context';
19
- import useMemo$1 from '@rc-component/util/es/hooks/useMemo';
20
15
  import { UniqueProvider as UniqueProvider$1 } from '@rc-component/trigger';
21
16
  import CSSMotion, { Provider as Provider$2 } from '@rc-component/motion';
22
17
  import isEqual from '@rc-component/util/es/isEqual';
23
18
  import { genStyleUtils, mergeToken } from '@ant-design/cssinjs-utils';
24
- import useLayoutEffect$1 from '@rc-component/util/es/hooks/useLayoutEffect';
25
- import isVisible from '@rc-component/util/es/Dom/isVisible';
26
- import raf from '@rc-component/util/es/raf';
27
- import { render, unmount } from '@rc-component/util/es/React/render';
28
- import LoadingOutlined from '@ant-design/icons/es/icons/LoadingOutlined';
29
- import { Color as Color$1 } from '@rc-component/color-picker';
30
- import RightOutlined from '@ant-design/icons/es/icons/RightOutlined';
31
- import RcCollapse from '@rc-component/collapse';
32
19
  import CheckCircleFilled from '@ant-design/icons/es/icons/CheckCircleFilled';
33
20
  import CloseCircleFilled from '@ant-design/icons/es/icons/CloseCircleFilled';
34
21
  import ExclamationCircleFilled from '@ant-design/icons/es/icons/ExclamationCircleFilled';
35
22
  import InfoCircleFilled from '@ant-design/icons/es/icons/InfoCircleFilled';
23
+ import LoadingOutlined from '@ant-design/icons/es/icons/LoadingOutlined';
36
24
  import { Notice, useNotification, NotificationProvider } from '@rc-component/notification';
25
+ import CloseOutlined from '@ant-design/icons/es/icons/CloseOutlined';
26
+ import pickAttrs from '@rc-component/util/es/pickAttrs';
37
27
  import RcTooltip, { Popup } from '@rc-component/tooltip';
28
+ import '@rc-component/form';
29
+ import { Color as Color$1 } from '@rc-component/color-picker';
30
+ import useLayoutEffect$1 from '@rc-component/util/es/hooks/useLayoutEffect';
31
+ import isVisible from '@rc-component/util/es/Dom/isVisible';
32
+ import { composeRef, supportRef, getNodeRef, supportNodeRef, useComposeRef as useComposeRef$1 } from '@rc-component/util/es/ref';
33
+ import raf from '@rc-component/util/es/raf';
34
+ import RightOutlined from '@ant-design/icons/es/icons/RightOutlined';
35
+ import RcCollapse from '@rc-component/collapse';
38
36
  import RcTree, { TreeNode as TreeNode$1 } from '@rc-component/tree';
39
37
  import FileOutlined from '@ant-design/icons/es/icons/FileOutlined';
40
38
  import FolderOpenOutlined from '@ant-design/icons/es/icons/FolderOpenOutlined';
@@ -56,6 +54,8 @@ import RcInput from '@rc-component/input';
56
54
  import { triggerFocus } from '@rc-component/util/es/Dom/focus';
57
55
  import CheckOutlined from '@ant-design/icons/es/icons/CheckOutlined';
58
56
  import CopyOutlined from '@ant-design/icons/es/icons/CopyOutlined';
57
+ import RcDrawer from '@rc-component/drawer';
58
+ import useId$2 from '@rc-component/util/es/hooks/useId';
59
59
  import RcSwitch from '@rc-component/switch';
60
60
  import RcSelect, { Option, OptGroup } from '@rc-component/select';
61
61
  import DownOutlined from '@ant-design/icons/es/icons/DownOutlined';
@@ -96,7 +96,7 @@ function cc(names) {
96
96
  return out;
97
97
  }
98
98
 
99
- var noop$3 = {
99
+ var noop$2 = {
100
100
  value: ()=>{}
101
101
  };
102
102
  function dispatch() {
@@ -163,7 +163,7 @@ function get$1(type, name) {
163
163
  function set$2(type, name, callback) {
164
164
  for(var i = 0, n = type.length; i < n; ++i){
165
165
  if (type[i].name === name) {
166
- type[i] = noop$3, type = type.slice(0, i).concat(type.slice(i + 1));
166
+ type[i] = noop$2, type = type.slice(0, i).concat(type.slice(i + 1));
167
167
  break;
168
168
  }
169
169
  }
@@ -11879,7 +11879,7 @@ function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTy
11879
11879
  * />);
11880
11880
  *}
11881
11881
  *```
11882
- */ var index$2 = fixedForwardRef(ReactFlow);
11882
+ */ var index = fixedForwardRef(ReactFlow);
11883
11883
  /**
11884
11884
  * This hook makes it easy to prototype a controlled flow where you manage the
11885
11885
  * state of nodes and edges outside the `ReactFlowInstance`. You can think of it
@@ -13241,24 +13241,6 @@ const __iconNode$l = [
13241
13241
  const Clock = createLucideIcon("clock", __iconNode$l);
13242
13242
 
13243
13243
  const __iconNode$k = [
13244
- [
13245
- "path",
13246
- {
13247
- d: "M6 16.326A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 .5 8.973",
13248
- key: "1cez44"
13249
- }
13250
- ],
13251
- [
13252
- "path",
13253
- {
13254
- d: "m13 12-3 5h4l-3 5",
13255
- key: "1t22er"
13256
- }
13257
- ]
13258
- ];
13259
- const CloudLightning = createLucideIcon("cloud-lightning", __iconNode$k);
13260
-
13261
- const __iconNode$j = [
13262
13244
  [
13263
13245
  "rect",
13264
13246
  {
@@ -13279,9 +13261,9 @@ const __iconNode$j = [
13279
13261
  }
13280
13262
  ]
13281
13263
  ];
13282
- const Copy = createLucideIcon("copy", __iconNode$j);
13264
+ const Copy = createLucideIcon("copy", __iconNode$k);
13283
13265
 
13284
- const __iconNode$i = [
13266
+ const __iconNode$j = [
13285
13267
  [
13286
13268
  "path",
13287
13269
  {
@@ -13389,9 +13371,9 @@ const __iconNode$i = [
13389
13371
  }
13390
13372
  ]
13391
13373
  ];
13392
- const Cpu = createLucideIcon("cpu", __iconNode$i);
13374
+ const Cpu = createLucideIcon("cpu", __iconNode$j);
13393
13375
 
13394
- const __iconNode$h = [
13376
+ const __iconNode$i = [
13395
13377
  [
13396
13378
  "line",
13397
13379
  {
@@ -13410,9 +13392,9 @@ const __iconNode$h = [
13410
13392
  }
13411
13393
  ]
13412
13394
  ];
13413
- const DollarSign = createLucideIcon("dollar-sign", __iconNode$h);
13395
+ const DollarSign = createLucideIcon("dollar-sign", __iconNode$i);
13414
13396
 
13415
- const __iconNode$g = [
13397
+ const __iconNode$h = [
13416
13398
  [
13417
13399
  "path",
13418
13400
  {
@@ -13442,9 +13424,9 @@ const __iconNode$g = [
13442
13424
  }
13443
13425
  ]
13444
13426
  ];
13445
- const FileInput = createLucideIcon("file-input", __iconNode$g);
13427
+ const FileInput = createLucideIcon("file-input", __iconNode$h);
13446
13428
 
13447
- const __iconNode$f = [
13429
+ const __iconNode$g = [
13448
13430
  [
13449
13431
  "path",
13450
13432
  {
@@ -13474,9 +13456,415 @@ const __iconNode$f = [
13474
13456
  }
13475
13457
  ]
13476
13458
  ];
13477
- const FileOutput = createLucideIcon("file-output", __iconNode$f);
13459
+ const FileOutput = createLucideIcon("file-output", __iconNode$g);
13460
+
13461
+ const __iconNode$f = [
13462
+ [
13463
+ "path",
13464
+ {
13465
+ d: "M12 22v-6",
13466
+ key: "6o8u61"
13467
+ }
13468
+ ],
13469
+ [
13470
+ "path",
13471
+ {
13472
+ d: "M12 8V2",
13473
+ key: "1wkif3"
13474
+ }
13475
+ ],
13476
+ [
13477
+ "path",
13478
+ {
13479
+ d: "M4 12H2",
13480
+ key: "rhcxmi"
13481
+ }
13482
+ ],
13483
+ [
13484
+ "path",
13485
+ {
13486
+ d: "M10 12H8",
13487
+ key: "s88cx1"
13488
+ }
13489
+ ],
13490
+ [
13491
+ "path",
13492
+ {
13493
+ d: "M16 12h-2",
13494
+ key: "10asgb"
13495
+ }
13496
+ ],
13497
+ [
13498
+ "path",
13499
+ {
13500
+ d: "M22 12h-2",
13501
+ key: "14jgyd"
13502
+ }
13503
+ ],
13504
+ [
13505
+ "path",
13506
+ {
13507
+ d: "m15 19-3-3-3 3",
13508
+ key: "e37ymu"
13509
+ }
13510
+ ],
13511
+ [
13512
+ "path",
13513
+ {
13514
+ d: "m15 5-3 3-3-3",
13515
+ key: "19d6lf"
13516
+ }
13517
+ ]
13518
+ ];
13519
+ const FoldVertical = createLucideIcon("fold-vertical", __iconNode$f);
13478
13520
 
13479
13521
  const __iconNode$e = [
13522
+ [
13523
+ "line",
13524
+ {
13525
+ x1: "4",
13526
+ x2: "20",
13527
+ y1: "9",
13528
+ y2: "9",
13529
+ key: "4lhtct"
13530
+ }
13531
+ ],
13532
+ [
13533
+ "line",
13534
+ {
13535
+ x1: "4",
13536
+ x2: "20",
13537
+ y1: "15",
13538
+ y2: "15",
13539
+ key: "vyu0kd"
13540
+ }
13541
+ ],
13542
+ [
13543
+ "line",
13544
+ {
13545
+ x1: "10",
13546
+ x2: "8",
13547
+ y1: "3",
13548
+ y2: "21",
13549
+ key: "1ggp8o"
13550
+ }
13551
+ ],
13552
+ [
13553
+ "line",
13554
+ {
13555
+ x1: "16",
13556
+ x2: "14",
13557
+ y1: "3",
13558
+ y2: "21",
13559
+ key: "weycgp"
13560
+ }
13561
+ ]
13562
+ ];
13563
+ const Hash = createLucideIcon("hash", __iconNode$e);
13564
+
13565
+ const __iconNode$d = [
13566
+ [
13567
+ "circle",
13568
+ {
13569
+ cx: "12",
13570
+ cy: "12",
13571
+ r: "10",
13572
+ key: "1mglay"
13573
+ }
13574
+ ],
13575
+ [
13576
+ "path",
13577
+ {
13578
+ d: "M12 16v-4",
13579
+ key: "1dtifu"
13580
+ }
13581
+ ],
13582
+ [
13583
+ "path",
13584
+ {
13585
+ d: "M12 8h.01",
13586
+ key: "e9boi3"
13587
+ }
13588
+ ]
13589
+ ];
13590
+ const Info = createLucideIcon("info", __iconNode$d);
13591
+
13592
+ const __iconNode$c = [
13593
+ [
13594
+ "path",
13595
+ {
13596
+ d: "M13 5h8",
13597
+ key: "a7qcls"
13598
+ }
13599
+ ],
13600
+ [
13601
+ "path",
13602
+ {
13603
+ d: "M13 12h8",
13604
+ key: "h98zly"
13605
+ }
13606
+ ],
13607
+ [
13608
+ "path",
13609
+ {
13610
+ d: "M13 19h8",
13611
+ key: "c3s6r1"
13612
+ }
13613
+ ],
13614
+ [
13615
+ "path",
13616
+ {
13617
+ d: "m3 17 2 2 4-4",
13618
+ key: "1jhpwq"
13619
+ }
13620
+ ],
13621
+ [
13622
+ "path",
13623
+ {
13624
+ d: "m3 7 2 2 4-4",
13625
+ key: "1obspn"
13626
+ }
13627
+ ]
13628
+ ];
13629
+ const ListChecks = createLucideIcon("list-checks", __iconNode$c);
13630
+
13631
+ const __iconNode$b = [
13632
+ [
13633
+ "path",
13634
+ {
13635
+ d: "M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",
13636
+ key: "1n2ejm"
13637
+ }
13638
+ ],
13639
+ [
13640
+ "path",
13641
+ {
13642
+ d: "M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",
13643
+ key: "1qfcsi"
13644
+ }
13645
+ ]
13646
+ ];
13647
+ const MessagesSquare = createLucideIcon("messages-square", __iconNode$b);
13648
+
13649
+ const __iconNode$a = [
13650
+ [
13651
+ "rect",
13652
+ {
13653
+ width: "18",
13654
+ height: "18",
13655
+ x: "3",
13656
+ y: "3",
13657
+ rx: "2",
13658
+ key: "afitv7"
13659
+ }
13660
+ ],
13661
+ [
13662
+ "path",
13663
+ {
13664
+ d: "M9 3v18",
13665
+ key: "fh3hqa"
13666
+ }
13667
+ ]
13668
+ ];
13669
+ const PanelLeft = createLucideIcon("panel-left", __iconNode$a);
13670
+
13671
+ const __iconNode$9 = [
13672
+ [
13673
+ "path",
13674
+ {
13675
+ d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",
13676
+ key: "v9h5vc"
13677
+ }
13678
+ ],
13679
+ [
13680
+ "path",
13681
+ {
13682
+ d: "M21 3v5h-5",
13683
+ key: "1q7to0"
13684
+ }
13685
+ ],
13686
+ [
13687
+ "path",
13688
+ {
13689
+ d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",
13690
+ key: "3uifl3"
13691
+ }
13692
+ ],
13693
+ [
13694
+ "path",
13695
+ {
13696
+ d: "M8 16H3v5",
13697
+ key: "1cv678"
13698
+ }
13699
+ ]
13700
+ ];
13701
+ const RefreshCw = createLucideIcon("refresh-cw", __iconNode$9);
13702
+
13703
+ const __iconNode$8 = [
13704
+ [
13705
+ "path",
13706
+ {
13707
+ d: "M12 3v18",
13708
+ key: "108xh3"
13709
+ }
13710
+ ],
13711
+ [
13712
+ "path",
13713
+ {
13714
+ d: "m19 8 3 8a5 5 0 0 1-6 0zV7",
13715
+ key: "zcdpyk"
13716
+ }
13717
+ ],
13718
+ [
13719
+ "path",
13720
+ {
13721
+ d: "M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1",
13722
+ key: "1yorad"
13723
+ }
13724
+ ],
13725
+ [
13726
+ "path",
13727
+ {
13728
+ d: "m5 8 3 8a5 5 0 0 1-6 0zV7",
13729
+ key: "eua70x"
13730
+ }
13731
+ ],
13732
+ [
13733
+ "path",
13734
+ {
13735
+ d: "M7 21h10",
13736
+ key: "1b0cd5"
13737
+ }
13738
+ ]
13739
+ ];
13740
+ const Scale = createLucideIcon("scale", __iconNode$8);
13741
+
13742
+ const __iconNode$7 = [
13743
+ [
13744
+ "path",
13745
+ {
13746
+ d: "M14 17H5",
13747
+ key: "gfn3mx"
13748
+ }
13749
+ ],
13750
+ [
13751
+ "path",
13752
+ {
13753
+ d: "M19 7h-9",
13754
+ key: "6i9tg"
13755
+ }
13756
+ ],
13757
+ [
13758
+ "circle",
13759
+ {
13760
+ cx: "17",
13761
+ cy: "17",
13762
+ r: "3",
13763
+ key: "18b49y"
13764
+ }
13765
+ ],
13766
+ [
13767
+ "circle",
13768
+ {
13769
+ cx: "7",
13770
+ cy: "7",
13771
+ r: "3",
13772
+ key: "dfmy0x"
13773
+ }
13774
+ ]
13775
+ ];
13776
+ const Settings2 = createLucideIcon("settings-2", __iconNode$7);
13777
+
13778
+ const __iconNode$6 = [
13779
+ [
13780
+ "path",
13781
+ {
13782
+ d: "M12 2v13",
13783
+ key: "1km8f5"
13784
+ }
13785
+ ],
13786
+ [
13787
+ "path",
13788
+ {
13789
+ d: "m16 6-4-4-4 4",
13790
+ key: "13yo43"
13791
+ }
13792
+ ],
13793
+ [
13794
+ "path",
13795
+ {
13796
+ d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8",
13797
+ key: "1b2hhj"
13798
+ }
13799
+ ]
13800
+ ];
13801
+ const Share = createLucideIcon("share", __iconNode$6);
13802
+
13803
+ const __iconNode$5 = [
13804
+ [
13805
+ "circle",
13806
+ {
13807
+ cx: "12",
13808
+ cy: "12",
13809
+ r: "10",
13810
+ key: "1mglay"
13811
+ }
13812
+ ],
13813
+ [
13814
+ "circle",
13815
+ {
13816
+ cx: "12",
13817
+ cy: "12",
13818
+ r: "6",
13819
+ key: "1vlfrh"
13820
+ }
13821
+ ],
13822
+ [
13823
+ "circle",
13824
+ {
13825
+ cx: "12",
13826
+ cy: "12",
13827
+ r: "2",
13828
+ key: "1c9p78"
13829
+ }
13830
+ ]
13831
+ ];
13832
+ const Target = createLucideIcon("target", __iconNode$5);
13833
+
13834
+ const __iconNode$4 = [
13835
+ [
13836
+ "line",
13837
+ {
13838
+ x1: "10",
13839
+ x2: "14",
13840
+ y1: "2",
13841
+ y2: "2",
13842
+ key: "14vaq8"
13843
+ }
13844
+ ],
13845
+ [
13846
+ "line",
13847
+ {
13848
+ x1: "12",
13849
+ x2: "15",
13850
+ y1: "14",
13851
+ y2: "11",
13852
+ key: "17fdiu"
13853
+ }
13854
+ ],
13855
+ [
13856
+ "circle",
13857
+ {
13858
+ cx: "12",
13859
+ cy: "14",
13860
+ r: "8",
13861
+ key: "1e1u0o"
13862
+ }
13863
+ ]
13864
+ ];
13865
+ const Timer = createLucideIcon("timer", __iconNode$4);
13866
+
13867
+ const __iconNode$3 = [
13480
13868
  [
13481
13869
  "path",
13482
13870
  {
@@ -13522,400 +13910,39 @@ const __iconNode$e = [
13522
13910
  [
13523
13911
  "path",
13524
13912
  {
13525
- d: "m15 19-3-3-3 3",
13526
- key: "e37ymu"
13527
- }
13528
- ],
13529
- [
13530
- "path",
13531
- {
13532
- d: "m15 5-3 3-3-3",
13533
- key: "19d6lf"
13534
- }
13535
- ]
13536
- ];
13537
- const FoldVertical = createLucideIcon("fold-vertical", __iconNode$e);
13538
-
13539
- const __iconNode$d = [
13540
- [
13541
- "line",
13542
- {
13543
- x1: "4",
13544
- x2: "20",
13545
- y1: "9",
13546
- y2: "9",
13547
- key: "4lhtct"
13548
- }
13549
- ],
13550
- [
13551
- "line",
13552
- {
13553
- x1: "4",
13554
- x2: "20",
13555
- y1: "15",
13556
- y2: "15",
13557
- key: "vyu0kd"
13558
- }
13559
- ],
13560
- [
13561
- "line",
13562
- {
13563
- x1: "10",
13564
- x2: "8",
13565
- y1: "3",
13566
- y2: "21",
13567
- key: "1ggp8o"
13568
- }
13569
- ],
13570
- [
13571
- "line",
13572
- {
13573
- x1: "16",
13574
- x2: "14",
13575
- y1: "3",
13576
- y2: "21",
13577
- key: "weycgp"
13578
- }
13579
- ]
13580
- ];
13581
- const Hash = createLucideIcon("hash", __iconNode$d);
13582
-
13583
- const __iconNode$c = [
13584
- [
13585
- "circle",
13586
- {
13587
- cx: "12",
13588
- cy: "12",
13589
- r: "10",
13590
- key: "1mglay"
13591
- }
13592
- ],
13593
- [
13594
- "path",
13595
- {
13596
- d: "M12 16v-4",
13597
- key: "1dtifu"
13598
- }
13599
- ],
13600
- [
13601
- "path",
13602
- {
13603
- d: "M12 8h.01",
13604
- key: "e9boi3"
13605
- }
13606
- ]
13607
- ];
13608
- const Info = createLucideIcon("info", __iconNode$c);
13609
-
13610
- const __iconNode$b = [
13611
- [
13612
- "path",
13613
- {
13614
- d: "M13 5h8",
13615
- key: "a7qcls"
13616
- }
13617
- ],
13618
- [
13619
- "path",
13620
- {
13621
- d: "M13 12h8",
13622
- key: "h98zly"
13623
- }
13624
- ],
13625
- [
13626
- "path",
13627
- {
13628
- d: "M13 19h8",
13629
- key: "c3s6r1"
13630
- }
13631
- ],
13632
- [
13633
- "path",
13634
- {
13635
- d: "m3 17 2 2 4-4",
13636
- key: "1jhpwq"
13637
- }
13638
- ],
13639
- [
13640
- "path",
13641
- {
13642
- d: "m3 7 2 2 4-4",
13643
- key: "1obspn"
13644
- }
13645
- ]
13646
- ];
13647
- const ListChecks = createLucideIcon("list-checks", __iconNode$b);
13648
-
13649
- const __iconNode$a = [
13650
- [
13651
- "path",
13652
- {
13653
- d: "M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z",
13654
- key: "1n2ejm"
13655
- }
13656
- ],
13657
- [
13658
- "path",
13659
- {
13660
- d: "M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1",
13661
- key: "1qfcsi"
13662
- }
13663
- ]
13664
- ];
13665
- const MessagesSquare = createLucideIcon("messages-square", __iconNode$a);
13666
-
13667
- const __iconNode$9 = [
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
- const MessageSquare = createLucideIcon("message-square", __iconNode$9);
13677
-
13678
- const __iconNode$8 = [
13679
- [
13680
- "rect",
13681
- {
13682
- width: "18",
13683
- height: "18",
13684
- x: "3",
13685
- y: "3",
13686
- rx: "2",
13687
- key: "afitv7"
13688
- }
13689
- ],
13690
- [
13691
- "path",
13692
- {
13693
- d: "M9 3v18",
13694
- key: "fh3hqa"
13695
- }
13696
- ]
13697
- ];
13698
- const PanelLeft = createLucideIcon("panel-left", __iconNode$8);
13699
-
13700
- const __iconNode$7 = [
13701
- [
13702
- "path",
13703
- {
13704
- d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",
13705
- key: "v9h5vc"
13706
- }
13707
- ],
13708
- [
13709
- "path",
13710
- {
13711
- d: "M21 3v5h-5",
13712
- key: "1q7to0"
13713
- }
13714
- ],
13715
- [
13716
- "path",
13717
- {
13718
- d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",
13719
- key: "3uifl3"
13720
- }
13721
- ],
13722
- [
13723
- "path",
13724
- {
13725
- d: "M8 16H3v5",
13726
- key: "1cv678"
13727
- }
13728
- ]
13729
- ];
13730
- const RefreshCw = createLucideIcon("refresh-cw", __iconNode$7);
13731
-
13732
- const __iconNode$6 = [
13733
- [
13734
- "path",
13735
- {
13736
- d: "M12 3v18",
13737
- key: "108xh3"
13738
- }
13739
- ],
13740
- [
13741
- "path",
13742
- {
13743
- d: "m19 8 3 8a5 5 0 0 1-6 0zV7",
13744
- key: "zcdpyk"
13745
- }
13746
- ],
13747
- [
13748
- "path",
13749
- {
13750
- d: "M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1",
13751
- key: "1yorad"
13752
- }
13753
- ],
13754
- [
13755
- "path",
13756
- {
13757
- d: "m5 8 3 8a5 5 0 0 1-6 0zV7",
13758
- key: "eua70x"
13913
+ d: "m15 19-3 3-3-3",
13914
+ key: "11eu04"
13759
13915
  }
13760
13916
  ],
13761
13917
  [
13762
13918
  "path",
13763
13919
  {
13764
- d: "M7 21h10",
13765
- key: "1b0cd5"
13920
+ d: "m15 5-3-3-3 3",
13921
+ key: "itvq4r"
13766
13922
  }
13767
13923
  ]
13768
13924
  ];
13769
- const Scale = createLucideIcon("scale", __iconNode$6);
13925
+ const UnfoldVertical = createLucideIcon("unfold-vertical", __iconNode$3);
13770
13926
 
13771
- const __iconNode$5 = [
13772
- [
13773
- "path",
13774
- {
13775
- d: "M12 2v13",
13776
- key: "1km8f5"
13777
- }
13778
- ],
13779
- [
13780
- "path",
13781
- {
13782
- d: "m16 6-4-4-4 4",
13783
- key: "13yo43"
13784
- }
13785
- ],
13927
+ const __iconNode$2 = [
13786
13928
  [
13787
13929
  "path",
13788
13930
  {
13789
- d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8",
13790
- key: "1b2hhj"
13791
- }
13792
- ]
13793
- ];
13794
- const Share = createLucideIcon("share", __iconNode$5);
13795
-
13796
- const __iconNode$4 = [
13797
- [
13798
- "circle",
13799
- {
13800
- cx: "12",
13801
- cy: "12",
13802
- r: "10",
13803
- key: "1mglay"
13804
- }
13805
- ],
13806
- [
13807
- "circle",
13808
- {
13809
- cx: "12",
13810
- cy: "12",
13811
- r: "6",
13812
- key: "1vlfrh"
13813
- }
13814
- ],
13815
- [
13816
- "circle",
13817
- {
13818
- cx: "12",
13819
- cy: "12",
13820
- r: "2",
13821
- key: "1c9p78"
13822
- }
13823
- ]
13824
- ];
13825
- const Target = createLucideIcon("target", __iconNode$4);
13826
-
13827
- const __iconNode$3 = [
13828
- [
13829
- "line",
13830
- {
13831
- x1: "10",
13832
- x2: "14",
13833
- y1: "2",
13834
- y2: "2",
13835
- key: "14vaq8"
13836
- }
13837
- ],
13838
- [
13839
- "line",
13840
- {
13841
- x1: "12",
13842
- x2: "15",
13843
- y1: "14",
13844
- y2: "11",
13845
- key: "17fdiu"
13931
+ d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
13932
+ key: "975kel"
13846
13933
  }
13847
13934
  ],
13848
13935
  [
13849
13936
  "circle",
13850
13937
  {
13851
13938
  cx: "12",
13852
- cy: "14",
13853
- r: "8",
13854
- key: "1e1u0o"
13855
- }
13856
- ]
13857
- ];
13858
- const Timer = createLucideIcon("timer", __iconNode$3);
13859
-
13860
- const __iconNode$2 = [
13861
- [
13862
- "path",
13863
- {
13864
- d: "M12 22v-6",
13865
- key: "6o8u61"
13866
- }
13867
- ],
13868
- [
13869
- "path",
13870
- {
13871
- d: "M12 8V2",
13872
- key: "1wkif3"
13873
- }
13874
- ],
13875
- [
13876
- "path",
13877
- {
13878
- d: "M4 12H2",
13879
- key: "rhcxmi"
13880
- }
13881
- ],
13882
- [
13883
- "path",
13884
- {
13885
- d: "M10 12H8",
13886
- key: "s88cx1"
13887
- }
13888
- ],
13889
- [
13890
- "path",
13891
- {
13892
- d: "M16 12h-2",
13893
- key: "10asgb"
13894
- }
13895
- ],
13896
- [
13897
- "path",
13898
- {
13899
- d: "M22 12h-2",
13900
- key: "14jgyd"
13901
- }
13902
- ],
13903
- [
13904
- "path",
13905
- {
13906
- d: "m15 19-3 3-3-3",
13907
- key: "11eu04"
13908
- }
13909
- ],
13910
- [
13911
- "path",
13912
- {
13913
- d: "m15 5-3-3-3 3",
13914
- key: "itvq4r"
13939
+ cy: "7",
13940
+ r: "4",
13941
+ key: "17ys0d"
13915
13942
  }
13916
13943
  ]
13917
13944
  ];
13918
- const UnfoldVertical = createLucideIcon("unfold-vertical", __iconNode$2);
13945
+ const User = createLucideIcon("user", __iconNode$2);
13919
13946
 
13920
13947
  const __iconNode$1 = [
13921
13948
  [
@@ -21196,6 +21223,23 @@ function cn(...inputs) {
21196
21223
  return "default";
21197
21224
  }
21198
21225
  }
21226
+ /**
21227
+ * Last timeline step for a run: max of stamp track (`stamps` / `steps`) and all node/edge stamp steps.
21228
+ * Used so the visualizer defaults past step 0 when the graph only appears at later steps.
21229
+ */ function getDefaultTimelineStepForRun(run) {
21230
+ let graphMax = 0;
21231
+ for (const node of run.nodes || []){
21232
+ const s = node.stamp?.step;
21233
+ if (typeof s === "number" && !Number.isNaN(s) && s > graphMax) graphMax = s;
21234
+ }
21235
+ for (const edge of run.edges || []){
21236
+ const s = edge.stamp?.step;
21237
+ if (typeof s === "number" && !Number.isNaN(s) && s > graphMax) graphMax = s;
21238
+ }
21239
+ const stamps = run.stamps || run.steps || [];
21240
+ const stampMax = stamps.length > 0 ? Math.max(0, ...stamps.map((s)=>s.step)) : 0;
21241
+ return Math.max(stampMax, graphMax);
21242
+ }
21199
21243
  /**
21200
21244
  * Formats tool calls for display in a code block
21201
21245
  */ const formatToolCalls = (toolCalls)=>{
@@ -21289,18 +21333,20 @@ const AppleIcon = ({ width = "1.5rem", height = "1.5rem" })=>/*#__PURE__*/ React
21289
21333
  viewBox: "0 0 24 24",
21290
21334
  role: "img",
21291
21335
  xmlns: "http://www.w3.org/2000/svg"
21292
- }, /*#__PURE__*/ React__default.createElement("title", null, "Apple"), /*#__PURE__*/ React__default.createElement("path", {
21336
+ }, /*#__PURE__*/ React__default.createElement("title", null, "Apple"), /*#__PURE__*/ React__default.createElement("g", {
21337
+ transform: "translate(12 12) scale(1.12) translate(-12 -12)"
21338
+ }, /*#__PURE__*/ React__default.createElement("path", {
21293
21339
  d: "M18.71 19.5C17.88 20.74 17 21.95 15.66 21.97C14.32 22 13.89 21.18 12.37 21.18C10.84 21.18 10.37 21.95 9.09997 22C7.78997 22.05 6.79997 20.68 5.95997 19.47C4.24997 17 2.93997 12.45 4.69997 9.39C5.56997 7.87 7.12997 6.91 8.81997 6.88C10.1 6.86 11.32 7.75 12.11 7.75C12.89 7.75 14.37 6.68 15.92 6.84C16.57 6.87 18.39 7.1 19.56 8.82C19.47 8.88 17.39 10.1 17.41 12.63C17.44 15.65 20.06 16.66 20.09 16.67C20.06 16.74 19.67 18.11 18.71 19.5ZM13 3.5C13.73 2.67 14.94 2.04 15.94 2C16.07 3.17 15.6 4.35 14.9 5.19C14.21 6.04 13.07 6.7 11.95 6.61C11.8 5.46 12.36 4.26 13 3.5Z"
21294
- }));
21340
+ })));
21295
21341
 
21296
- function noop$2() {}
21342
+ function noop$1() {}
21297
21343
  const { resetWarned: rcResetWarned } = warning$2;
21298
21344
  let deprecatedWarnList = null;
21299
21345
  function resetWarned() {
21300
21346
  deprecatedWarnList = null;
21301
21347
  rcResetWarned();
21302
21348
  }
21303
- let _warning = noop$2;
21349
+ let _warning = noop$1;
21304
21350
  if (process.env.NODE_ENV !== 'production') {
21305
21351
  _warning = (valid, component, message)=>{
21306
21352
  warning$2(valid, `[antd: ${component}] ${message}`);
@@ -21344,7 +21390,7 @@ const WarningContext = /*#__PURE__*/ React.createContext({});
21344
21390
  return typeWarning;
21345
21391
  } : ()=>{
21346
21392
  const noopWarning = ()=>{};
21347
- noopWarning.deprecated = noop$2;
21393
+ noopWarning.deprecated = noop$1;
21348
21394
  return noopWarning;
21349
21395
  };
21350
21396
 
@@ -47171,7 +47217,7 @@ const Paragraph = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47171
47217
  }, children);
47172
47218
  });
47173
47219
 
47174
- const Text$1 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47220
+ const Text$2 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47175
47221
  const { ellipsis, children, ...restProps } = props;
47176
47222
  const mergedEllipsis = React.useMemo(()=>{
47177
47223
  if (ellipsis && typeof ellipsis === 'object') {
@@ -47218,162 +47264,631 @@ const Title$1 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
47218
47264
  });
47219
47265
 
47220
47266
  const Typography = Typography$1;
47221
- Typography.Text = Text$1;
47267
+ Typography.Text = Text$2;
47222
47268
  Typography.Link = Link$1;
47223
47269
  Typography.Title = Title$1;
47224
47270
  Typography.Paragraph = Paragraph;
47225
47271
 
47226
- const ExpandableTextarea = ({ label, content, isExpanded, onToggle })=>{
47272
+ const MAX_TITLE_LEN = 200;
47273
+ const TOOLBAR_ICON_SIZE = 15;
47274
+ const JsonValueTree = ({ data, className, maxHeight = "auto" })=>{
47227
47275
  const { theme } = useTheme$1();
47228
- const themeColors = theme?.colors || {
47229
- muted: "hsl(210 40% 96%)",
47230
- mutedForeground: "hsl(215.4 16.3% 46.9%)",
47231
- border: "hsl(214.3 31.8% 91.4%)",
47232
- foreground: "hsl(222.2 84% 4.9%)"
47233
- };
47234
- const displayContent = isExpanded ? content : content?.slice(0, 100) + (content?.length > 100 ? "..." : "");
47235
- return /*#__PURE__*/ React__default.createElement(ExpandableSection, null, /*#__PURE__*/ React__default.createElement(ExpandableHeader, {
47236
- onClick: (e)=>{
47237
- e.stopPropagation();
47238
- onToggle(e);
47239
- },
47240
- onMouseEnter: (e)=>{
47241
- e.currentTarget.style.backgroundColor = themeColors.muted;
47242
- },
47243
- onMouseLeave: (e)=>{
47244
- e.currentTarget.style.backgroundColor = "transparent";
47276
+ const { mutedForeground } = theme.colors;
47277
+ const treeData = useMemo(()=>buildTreeData(data), [
47278
+ data
47279
+ ]);
47280
+ const defaultExpandedKeys = useMemo(()=>collectKeysToDepth(treeData, 2), [
47281
+ treeData
47282
+ ]);
47283
+ const allExpandableKeys = useMemo(()=>collectAllExpandableKeys(treeData), [
47284
+ treeData
47285
+ ]);
47286
+ const [expandedKeys, setExpandedKeys] = useState(()=>defaultExpandedKeys);
47287
+ const hasBranches = allExpandableKeys.length > 0;
47288
+ const isAllExpanded = hasBranches && allExpandableKeys.every((k)=>expandedKeys.includes(k));
47289
+ useEffect(()=>{
47290
+ setExpandedKeys(defaultExpandedKeys);
47291
+ }, [
47292
+ defaultExpandedKeys
47293
+ ]);
47294
+ const handleCopyJson = useCallback(async ()=>{
47295
+ try {
47296
+ const text = JSON.stringify(data, null, 2);
47297
+ await navigator.clipboard.writeText(text);
47298
+ staticMethods.success("JSON copied to clipboard");
47299
+ } catch {
47300
+ staticMethods.error("Could not copy to clipboard");
47245
47301
  }
47246
- }, /*#__PURE__*/ React__default.createElement(ExpandableLabel, null, label), /*#__PURE__*/ React__default.createElement(ChevronIcon, null, isExpanded ? /*#__PURE__*/ React__default.createElement(ChevronDown, {
47302
+ }, [
47303
+ data
47304
+ ]);
47305
+ const handleToggleExpandCollapse = useCallback(()=>{
47306
+ if (isAllExpanded) {
47307
+ setExpandedKeys([]);
47308
+ } else {
47309
+ setExpandedKeys(allExpandableKeys);
47310
+ }
47311
+ }, [
47312
+ isAllExpanded,
47313
+ allExpandableKeys
47314
+ ]);
47315
+ return /*#__PURE__*/ React__default.createElement("div", {
47316
+ className: className,
47247
47317
  style: {
47248
- width: "12px",
47249
- height: "12px",
47250
- color: themeColors.mutedForeground
47318
+ maxHeight,
47319
+ display: "flex",
47320
+ flexDirection: "column",
47321
+ borderRadius: 4,
47322
+ overflow: "hidden"
47251
47323
  }
47252
- }) : /*#__PURE__*/ React__default.createElement(ChevronRight, {
47324
+ }, /*#__PURE__*/ React__default.createElement("div", {
47253
47325
  style: {
47254
- width: "12px",
47255
- height: "12px",
47256
- color: themeColors.mutedForeground
47326
+ display: "flex",
47327
+ justifyContent: "flex-end",
47328
+ alignItems: "center",
47329
+ gap: 2,
47330
+ padding: "4px 6px 2px",
47331
+ flexShrink: 0,
47332
+ background: "transparent"
47257
47333
  }
47258
- }))), /*#__PURE__*/ React__default.createElement(ExpandableTextareaElement, {
47259
- onClick: (e)=>{
47260
- e.stopPropagation();
47261
- },
47262
- value: displayContent || "",
47263
- readOnly: true,
47264
- rows: isExpanded ? Math.max(3, Math.max(content?.split("\n").length || 0, Math.ceil((content?.length || 0) / 60))) : 2,
47334
+ }, /*#__PURE__*/ React__default.createElement(Tooltip$1, {
47335
+ title: "Copy JSON"
47336
+ }, /*#__PURE__*/ React__default.createElement(Button$1, {
47337
+ type: "text",
47338
+ size: "small",
47339
+ "aria-label": "Copy JSON to clipboard",
47340
+ icon: /*#__PURE__*/ React__default.createElement(Copy, {
47341
+ size: TOOLBAR_ICON_SIZE,
47342
+ color: mutedForeground
47343
+ }),
47344
+ onClick: handleCopyJson
47345
+ })), /*#__PURE__*/ React__default.createElement(Tooltip$1, {
47346
+ title: isAllExpanded ? "Collapse all" : "Expand all"
47347
+ }, /*#__PURE__*/ React__default.createElement(Button$1, {
47348
+ type: "text",
47349
+ size: "small",
47350
+ "aria-label": isAllExpanded ? "Collapse all tree nodes" : "Expand all tree nodes",
47351
+ disabled: !hasBranches,
47352
+ icon: isAllExpanded ? /*#__PURE__*/ React__default.createElement(FoldVertical, {
47353
+ size: TOOLBAR_ICON_SIZE,
47354
+ color: mutedForeground
47355
+ }) : /*#__PURE__*/ React__default.createElement(UnfoldVertical, {
47356
+ size: TOOLBAR_ICON_SIZE,
47357
+ color: mutedForeground
47358
+ }),
47359
+ onClick: handleToggleExpandCollapse
47360
+ }))), /*#__PURE__*/ React__default.createElement("div", {
47265
47361
  style: {
47266
- border: `1px solid ${themeColors.border}`,
47267
- backgroundColor: themeColors.muted,
47268
- color: themeColors.foreground
47362
+ flex: 1,
47363
+ minHeight: 0,
47364
+ overflow: "auto",
47365
+ padding: "4px 0"
47269
47366
  }
47270
- }));
47367
+ }, /*#__PURE__*/ React__default.createElement(Tree, {
47368
+ // No showLine — connector lines look like a floating spine for many top-level fields.
47369
+ showLine: true,
47370
+ blockNode: true,
47371
+ expandAction: "click",
47372
+ selectable: false,
47373
+ showIcon: false,
47374
+ treeData: treeData,
47375
+ expandedKeys: expandedKeys,
47376
+ onExpand: (keys)=>setExpandedKeys(keys),
47377
+ rootStyle: {
47378
+ backgroundColor: "transparent",
47379
+ padding: "0 4px"
47380
+ }
47381
+ })));
47271
47382
  };
47272
- // Styled components
47273
- const ExpandableSection = styled.div`
47274
- width: 100%;
47275
- `;
47276
- const ExpandableHeader = styled.div`
47277
- display: flex;
47278
- justify-content: space-between;
47279
- align-items: center;
47280
- padding: 0.25rem 0;
47281
- cursor: pointer;
47282
- user-select: none;
47283
- border-radius: 0.25rem;
47284
- padding-left: 0.25rem;
47285
- padding-right: 0.25rem;
47286
-
47287
- &:hover {
47288
- background-color: transparent;
47289
- }
47290
- `;
47291
- const ExpandableLabel = styled.span`
47292
- font-size: 0.75rem;
47293
- font-weight: 500;
47294
- color: ${(props)=>props.theme?.colors?.foreground || "hsl(222.2 84% 4.9%)"};
47295
- `;
47296
- const ExpandableTextareaElement = styled.textarea`
47297
- box-sizing: border-box;
47298
- width: 100%;
47299
- border-radius: 0.25rem;
47300
- padding: 0.5rem;
47301
- resize: none;
47302
- min-height: 40px;
47303
- font-family: inherit;
47304
-
47305
- &:focus {
47306
- outline: none;
47307
- border-color: ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
47308
- box-shadow: 0 0 0 1px ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
47309
- }
47310
-
47311
- transition: all 0.2s ease-in-out;
47312
- `;
47313
- const ChevronIcon = styled.div`
47314
- transition: transform 0.2s ease-in-out;
47315
- `;
47383
+ function collectKeysToDepth(nodes, maxDepth, depth = 0) {
47384
+ if (depth >= maxDepth) return [];
47385
+ const keys = [];
47386
+ for (const n of nodes){
47387
+ if (n.children && n.children.length > 0) {
47388
+ keys.push(n.key);
47389
+ keys.push(...collectKeysToDepth(n.children, maxDepth, depth + 1));
47390
+ }
47391
+ }
47392
+ return keys;
47393
+ }
47394
+ function collectAllExpandableKeys(nodes) {
47395
+ const keys = [];
47396
+ for (const n of nodes){
47397
+ if (n.children && n.children.length > 0) {
47398
+ keys.push(n.key);
47399
+ keys.push(...collectAllExpandableKeys(n.children));
47400
+ }
47401
+ }
47402
+ return keys;
47403
+ }
47404
+ /**
47405
+ * Object keys A→Z, but any property whose value is an array is listed after all non-array properties
47406
+ * (each block still A→Z). Tree has no built-in sort — this defines `treeData` order.
47407
+ */ function sortObjectEntriesForTree(entries) {
47408
+ return [
47409
+ ...entries
47410
+ ].sort((a, b)=>{
47411
+ const aArr = Array.isArray(a[1]);
47412
+ const bArr = Array.isArray(b[1]);
47413
+ if (aArr !== bArr) {
47414
+ return aArr ? 1 : -1;
47415
+ }
47416
+ return a[0].localeCompare(b[0], undefined, {
47417
+ sensitivity: "base",
47418
+ numeric: true
47419
+ });
47420
+ });
47421
+ }
47422
+ function valueToTreeNodes(value, path) {
47423
+ if (value === null || value === undefined) {
47424
+ return [
47425
+ {
47426
+ key: path,
47427
+ title: formatJsonTreePrimitive(value),
47428
+ isLeaf: true
47429
+ }
47430
+ ];
47431
+ }
47432
+ if (Array.isArray(value)) {
47433
+ if (value.length === 0) {
47434
+ return [
47435
+ {
47436
+ key: `${path}.__empty_arr__`,
47437
+ title: "[] (0 items)",
47438
+ isLeaf: true
47439
+ }
47440
+ ];
47441
+ }
47442
+ return value.map((item, i)=>{
47443
+ const seg = `[${i}]`;
47444
+ const childPath = `${path}.${escapeDotPathSegment(seg)}`;
47445
+ if (item === null || item === undefined || typeof item !== "object") {
47446
+ return {
47447
+ key: childPath,
47448
+ title: `${seg}: ${formatJsonTreePrimitive(item)}`,
47449
+ isLeaf: true
47450
+ };
47451
+ }
47452
+ if (Array.isArray(item) || isPlainObject(item)) {
47453
+ const children = valueToTreeNodes(item, childPath);
47454
+ return {
47455
+ key: childPath,
47456
+ title: `${seg} (${Array.isArray(item) ? `Array(${item.length})` : `Object(${Object.keys(item).length})`})`,
47457
+ children
47458
+ };
47459
+ }
47460
+ return {
47461
+ key: childPath,
47462
+ title: `${seg}: ${formatJsonTreePrimitive(item)}`,
47463
+ isLeaf: true
47464
+ };
47465
+ });
47466
+ }
47467
+ if (isPlainObject(value)) {
47468
+ const entries = sortObjectEntriesForTree(Object.entries(value));
47469
+ if (entries.length === 0) {
47470
+ return [
47471
+ {
47472
+ key: `${path}.__empty_obj__`,
47473
+ title: "{} (0 keys)",
47474
+ isLeaf: true
47475
+ }
47476
+ ];
47477
+ }
47478
+ return entries.map(([k, v])=>{
47479
+ const childPath = `${path}.${escapeDotPathSegment(k)}`;
47480
+ if (v === null || v === undefined || typeof v !== "object") {
47481
+ const text = `${k}: ${formatJsonTreePrimitive(v)}`;
47482
+ const title = text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
47483
+ title: text
47484
+ }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text;
47485
+ return {
47486
+ key: childPath,
47487
+ title,
47488
+ isLeaf: true
47489
+ };
47490
+ }
47491
+ if (Array.isArray(v) || isPlainObject(v)) {
47492
+ const children = valueToTreeNodes(v, childPath);
47493
+ const summary = Array.isArray(v) ? `Array(${v.length})` : `Object(${Object.keys(v).length})`;
47494
+ return {
47495
+ key: childPath,
47496
+ title: `${k}: ${summary}`,
47497
+ children
47498
+ };
47499
+ }
47500
+ const text = `${k}: ${formatJsonTreePrimitive(v)}`;
47501
+ return {
47502
+ key: childPath,
47503
+ title: text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
47504
+ title: text
47505
+ }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text,
47506
+ isLeaf: true
47507
+ };
47508
+ });
47509
+ }
47510
+ const text = formatJsonTreePrimitive(value);
47511
+ return [
47512
+ {
47513
+ key: path,
47514
+ title: text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
47515
+ title: text
47516
+ }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text,
47517
+ isLeaf: true
47518
+ }
47519
+ ];
47520
+ }
47521
+ /** Top-level tree for tabular session output: plain object or array of plain objects. */ function buildTreeData(data) {
47522
+ if (data === null || data === undefined) {
47523
+ return [
47524
+ {
47525
+ key: "root",
47526
+ title: String(data),
47527
+ isLeaf: true
47528
+ }
47529
+ ];
47530
+ }
47531
+ if (Array.isArray(data)) {
47532
+ if (data.length === 0) {
47533
+ return [
47534
+ {
47535
+ key: "$top",
47536
+ title: "Array (0 items)",
47537
+ isLeaf: true
47538
+ }
47539
+ ];
47540
+ }
47541
+ const children = data.map((item, index)=>{
47542
+ const path = `$root[${index}]`;
47543
+ if (!isPlainObject(item)) {
47544
+ return {
47545
+ key: path,
47546
+ title: `[${index}]: ${formatJsonTreePrimitive(item)}`,
47547
+ isLeaf: true
47548
+ };
47549
+ }
47550
+ const itemChildren = valueToTreeNodes(item, path);
47551
+ return {
47552
+ key: path,
47553
+ title: `[${index}] (${Object.keys(item).length} keys)`,
47554
+ children: itemChildren
47555
+ };
47556
+ });
47557
+ return [
47558
+ {
47559
+ key: "$top",
47560
+ title: `Array (${data.length} items)`,
47561
+ children
47562
+ }
47563
+ ];
47564
+ }
47565
+ if (isPlainObject(data)) {
47566
+ const objectKeys = Object.keys(data);
47567
+ if (objectKeys.length === 0) {
47568
+ return [
47569
+ {
47570
+ key: "$top",
47571
+ title: "Object (0 keys)",
47572
+ isLeaf: true
47573
+ }
47574
+ ];
47575
+ }
47576
+ const children = valueToTreeNodes(data, "$root");
47577
+ return [
47578
+ {
47579
+ key: "$top",
47580
+ title: `Object (${objectKeys.length} keys)`,
47581
+ children
47582
+ }
47583
+ ];
47584
+ }
47585
+ return valueToTreeNodes(data, "$root");
47586
+ }
47316
47587
 
47317
- const CodeBlock = ({ content, language = "text", showHeader = false })=>{
47318
- const { theme } = useTheme$1();
47319
- const themeColors = theme?.colors || {
47320
- muted: "hsl(210 40% 96%)",
47321
- mutedForeground: "hsl(215.4 16.3% 46.9%)",
47322
- border: "hsl(214.3 31.8% 91.4%)",
47323
- foreground: "hsl(222.2 84% 4.9%)",
47324
- background: "hsl(0 0% 100%)"
47588
+ const { Text: Text$1 } = Typography;
47589
+ function themedCodeSurface(theme) {
47590
+ return {
47591
+ background: theme.colors.muted,
47592
+ border: `1px solid ${theme.colors.border}`,
47593
+ borderRadius: theme.borderRadius.sm,
47594
+ color: theme.colors.foreground,
47595
+ padding: `calc(${theme.spacing.sm} + ${theme.spacing.xs})`
47325
47596
  };
47326
- return /*#__PURE__*/ React__default.createElement(CodeBlockContainer, {
47597
+ }
47598
+ function formatContentAsText(content) {
47599
+ if (typeof content === "string") {
47600
+ return content;
47601
+ }
47602
+ if (Array.isArray(content)) {
47603
+ return content.map((item)=>formatContentAsText(item)).join("\n\n");
47604
+ }
47605
+ return JSON.stringify(content, null, 2);
47606
+ }
47607
+ function isTabularData(data) {
47608
+ if (data === null || data === undefined) {
47609
+ return false;
47610
+ }
47611
+ if (typeof data === "object" && !Array.isArray(data) && data.constructor === Object) {
47612
+ return true;
47613
+ }
47614
+ if (Array.isArray(data) && data.length > 0) {
47615
+ return data.every((item)=>item !== null && item !== undefined && typeof item === "object" && !Array.isArray(item) && item.constructor === Object);
47616
+ }
47617
+ return false;
47618
+ }
47619
+ function getRoleDisplayName(role) {
47620
+ return role.charAt(0).toUpperCase() + role.slice(1);
47621
+ }
47622
+ function formatOutputAsText(output, toolOutput) {
47623
+ if (toolOutput !== null && toolOutput !== undefined) {
47624
+ return formatContentAsText(toolOutput);
47625
+ }
47626
+ if (output) {
47627
+ const role = getRoleDisplayName(output.role);
47628
+ const content = formatContentAsText(output.content);
47629
+ return `${role}:\n${content}`;
47630
+ }
47631
+ return "";
47632
+ }
47633
+ const ROLE_ICON_SIZE = 14;
47634
+ function getRoleIcon(role) {
47635
+ const iconProps = {
47636
+ size: ROLE_ICON_SIZE,
47637
+ strokeWidth: 2,
47638
+ "aria-hidden": true
47639
+ };
47640
+ switch(role.toLowerCase()){
47641
+ case "system":
47642
+ return /*#__PURE__*/ React__default.createElement(Settings2, iconProps);
47643
+ case "user":
47644
+ return /*#__PURE__*/ React__default.createElement(User, iconProps);
47645
+ case "assistant":
47646
+ return /*#__PURE__*/ React__default.createElement(Bot, iconProps);
47647
+ case "tool":
47648
+ return /*#__PURE__*/ React__default.createElement(Wrench, iconProps);
47649
+ default:
47650
+ return /*#__PURE__*/ React__default.createElement(Wrench, iconProps);
47651
+ }
47652
+ }
47653
+ function renderContentForDisplay(content) {
47654
+ if (typeof content === "string") {
47655
+ return content;
47656
+ }
47657
+ return JSON.stringify(content, null, 2);
47658
+ }
47659
+ function filterKeysWithName(obj) {
47660
+ if (obj === null || obj === undefined) return obj;
47661
+ if (typeof obj !== "object") return obj;
47662
+ if (Array.isArray(obj)) return obj.map(filterKeysWithName);
47663
+ return Object.fromEntries(Object.entries(obj).filter(([key])=>!key.toLowerCase().includes("name")).map(([key, value])=>[
47664
+ key,
47665
+ filterKeysWithName(value)
47666
+ ]));
47667
+ }
47668
+ const LLMInputsRenderer = ({ input, modelProvider, modelName, toolStatusMap })=>{
47669
+ const { theme } = useTheme$1();
47670
+ if (!input || input.length === 0) return null;
47671
+ const collapseItems = input.map((item, index)=>{
47672
+ const modelIcon = modelProvider || modelName ? getNodeIcon({
47673
+ modelProvider,
47674
+ modelName
47675
+ }) : null;
47676
+ const isSystemInput = item.role.toLowerCase() === "system";
47677
+ const showModelInfo = isSystemInput && (modelProvider || modelName);
47678
+ const isToolInput = item.role.toLowerCase() === "tool";
47679
+ const isAssistantInput = item.role.toLowerCase() === "assistant";
47680
+ const isUserInput = item.role.toLowerCase() === "user";
47681
+ const toolName = isToolInput && item.content?.name ? item.content.name : null;
47682
+ const toolStatus = toolName && toolStatusMap ? toolStatusMap.get(toolName) : undefined;
47683
+ let assistantToolName = null;
47684
+ if (isAssistantInput && Array.isArray(item.content) && item.content.length > 0) {
47685
+ const firstToolCall = item.content[0];
47686
+ if (firstToolCall?.name) {
47687
+ assistantToolName = firstToolCall.name;
47688
+ }
47689
+ }
47690
+ const roleLabel = toolName ? `Tool` : assistantToolName ? `Assistant` : getRoleDisplayName(item.role);
47691
+ return {
47692
+ key: `input-${index}`,
47693
+ label: /*#__PURE__*/ React__default.createElement(Text$1, {
47694
+ strong: true,
47695
+ style: {
47696
+ display: "inline-flex",
47697
+ alignItems: "center",
47698
+ lineHeight: 1.35,
47699
+ color: theme.colors.foreground
47700
+ }
47701
+ }, /*#__PURE__*/ React__default.createElement("span", {
47702
+ style: {
47703
+ display: "inline-flex",
47704
+ alignItems: "center",
47705
+ justifyContent: "center",
47706
+ flexShrink: 0,
47707
+ lineHeight: 0,
47708
+ color: theme.colors.foreground
47709
+ }
47710
+ }, getRoleIcon(item.role)), /*#__PURE__*/ React__default.createElement("span", {
47711
+ style: {
47712
+ display: "inline-flex",
47713
+ alignItems: "center",
47714
+ marginLeft: theme.spacing.sm
47715
+ }
47716
+ }, roleLabel)),
47717
+ extra: showModelInfo ? /*#__PURE__*/ React__default.createElement(Space, {
47718
+ size: "small"
47719
+ }, modelIcon && /*#__PURE__*/ React__default.createElement("span", null, modelIcon), modelName && /*#__PURE__*/ React__default.createElement("span", {
47720
+ style: {
47721
+ fontSize: theme.fontSize.xs,
47722
+ color: theme.colors.mutedForeground
47723
+ }
47724
+ }, getModelLabel(modelName))) : isToolInput ? /*#__PURE__*/ React__default.createElement(Tag, {
47725
+ color: toolStatus === "Failed" ? "red" : "blue"
47726
+ }, toolName || "Tool Response") : isUserInput ? /*#__PURE__*/ React__default.createElement(Tag, {
47727
+ color: "purple"
47728
+ }, "Text") : undefined,
47729
+ children: /*#__PURE__*/ React__default.createElement("pre", {
47730
+ style: {
47731
+ margin: 0,
47732
+ ...themedCodeSurface(theme),
47733
+ whiteSpace: "pre-wrap",
47734
+ wordWrap: "break-word",
47735
+ fontFamily: "monospace",
47736
+ fontSize: theme.fontSize.xs,
47737
+ lineHeight: 1.5,
47738
+ maxHeight: "300px",
47739
+ overflow: "auto"
47740
+ }
47741
+ }, renderContentForDisplay(typeof item.content === "object" && item.content !== null && !Array.isArray(item.content) ? filterKeysWithName(item.content) : item.content))
47742
+ };
47743
+ });
47744
+ return /*#__PURE__*/ React__default.createElement(Collapse$1, {
47745
+ items: collapseItems,
47746
+ expandIcon: ()=>null,
47747
+ defaultActiveKey: collapseItems.length > 0 ? [
47748
+ collapseItems[0].key
47749
+ ] : [],
47327
47750
  style: {
47328
- width: "100%",
47329
- border: `1px solid ${themeColors.border}`,
47330
- backgroundColor: themeColors.muted,
47331
- color: themeColors.foreground
47751
+ background: "transparent",
47752
+ padding: 0,
47753
+ margin: 0
47332
47754
  }
47333
- }, showHeader && /*#__PURE__*/ React__default.createElement(CodeBlockHeader, {
47755
+ });
47756
+ };
47757
+ function getToolInputText(inputs) {
47758
+ if (inputs.length === 0) return "";
47759
+ const first = inputs[0].content;
47760
+ return renderContentForDisplay(typeof first === "object" && first !== null && !Array.isArray(first) ? filterKeysWithName(first) : first);
47761
+ }
47762
+ const InputsOutputsCollapse = ({ inputs, output, toolOutput, modelProvider, modelName, toolStatusMap, toolInputAsTextarea = false, largeInputsTitle = false, hasInputs: hasInputsProp })=>{
47763
+ const { theme } = useTheme$1();
47764
+ const hasInputs = hasInputsProp ?? inputs.length > 0;
47765
+ const hasOutputs = output !== null || toolOutput !== null;
47766
+ const outputsText = hasOutputs ? formatOutputAsText(output, toolOutput) : "";
47767
+ const isToolOutputTabular = toolOutput !== null && toolOutput !== undefined && isTabularData(toolOutput);
47768
+ const toolInputText = getToolInputText(inputs);
47769
+ const inputsLabel = largeInputsTitle ? /*#__PURE__*/ React__default.createElement("div", {
47334
47770
  style: {
47335
- borderBottom: `1px solid ${themeColors.border}`,
47336
- backgroundColor: themeColors.background
47771
+ display: "flex",
47772
+ alignItems: "center",
47773
+ gap: theme.spacing.sm
47337
47774
  }
47338
- }, /*#__PURE__*/ React__default.createElement(CodeBlockLanguage, {
47775
+ }, /*#__PURE__*/ React__default.createElement(Typography.Title, {
47776
+ level: 2,
47339
47777
  style: {
47340
- color: themeColors.mutedForeground
47778
+ margin: 0,
47779
+ color: theme.colors.foreground
47341
47780
  }
47342
- }, language)), /*#__PURE__*/ React__default.createElement(CodeBlockContent, {
47781
+ }, "Inputs"), hasInputs && /*#__PURE__*/ React__default.createElement("span", {
47343
47782
  style: {
47344
- color: themeColors.foreground
47783
+ display: "inline-flex",
47784
+ alignItems: "center",
47785
+ gap: theme.spacing.xs,
47786
+ color: theme.colors.mutedForeground
47345
47787
  }
47346
- }, content));
47788
+ }, /*#__PURE__*/ React__default.createElement(MessagesSquare, {
47789
+ size: 12,
47790
+ color: theme.colors.mutedForeground,
47791
+ strokeWidth: 2
47792
+ }), inputs.length)) : /*#__PURE__*/ React__default.createElement("div", {
47793
+ style: {
47794
+ display: "flex",
47795
+ alignItems: "center",
47796
+ gap: theme.spacing.sm
47797
+ }
47798
+ }, /*#__PURE__*/ React__default.createElement(Text$1, {
47799
+ strong: true,
47800
+ style: {
47801
+ color: theme.colors.foreground
47802
+ }
47803
+ }, "Inputs"), hasInputs && /*#__PURE__*/ React__default.createElement("span", {
47804
+ style: {
47805
+ display: "inline-flex",
47806
+ alignItems: "center",
47807
+ gap: theme.spacing.xs,
47808
+ color: theme.colors.mutedForeground
47809
+ }
47810
+ }, /*#__PURE__*/ React__default.createElement(MessagesSquare, {
47811
+ size: 12,
47812
+ color: theme.colors.mutedForeground,
47813
+ strokeWidth: 2
47814
+ }), inputs.length));
47815
+ const textareaStyle = {
47816
+ width: "100%",
47817
+ minHeight: "200px",
47818
+ resize: "vertical",
47819
+ fontFamily: "monospace",
47820
+ fontSize: theme.fontSize.xs,
47821
+ lineHeight: 1.5,
47822
+ ...themedCodeSurface(theme)
47823
+ };
47824
+ const outputPreStyle = {
47825
+ margin: 0,
47826
+ ...themedCodeSurface(theme),
47827
+ whiteSpace: "pre-wrap",
47828
+ wordWrap: "break-word",
47829
+ fontFamily: "inherit",
47830
+ fontSize: theme.fontSize.sm,
47831
+ lineHeight: 1.5
47832
+ };
47833
+ const collapseItems = [
47834
+ {
47835
+ key: "inputs",
47836
+ label: inputsLabel,
47837
+ children: hasInputs ? toolInputAsTextarea ? /*#__PURE__*/ React__default.createElement("textarea", {
47838
+ readOnly: true,
47839
+ value: toolInputText,
47840
+ style: textareaStyle
47841
+ }) : /*#__PURE__*/ React__default.createElement(LLMInputsRenderer, {
47842
+ input: inputs,
47843
+ modelProvider: modelProvider,
47844
+ modelName: modelName,
47845
+ toolStatusMap: toolStatusMap
47846
+ }) : /*#__PURE__*/ React__default.createElement(Empty, {
47847
+ description: "No inputs available"
47848
+ })
47849
+ },
47850
+ {
47851
+ key: "outputs",
47852
+ label: /*#__PURE__*/ React__default.createElement(Text$1, {
47853
+ strong: true,
47854
+ style: {
47855
+ color: theme.colors.foreground
47856
+ }
47857
+ }, "Outputs"),
47858
+ children: hasOutputs ? isToolOutputTabular ? /*#__PURE__*/ React__default.createElement(JsonValueTree, {
47859
+ data: toolOutput
47860
+ }) : /*#__PURE__*/ React__default.createElement("pre", {
47861
+ style: outputPreStyle
47862
+ }, outputsText) : /*#__PURE__*/ React__default.createElement("div", {
47863
+ style: {
47864
+ padding: theme.spacing.md
47865
+ }
47866
+ }, /*#__PURE__*/ React__default.createElement(Empty, {
47867
+ description: "No outputs available"
47868
+ }))
47869
+ }
47870
+ ];
47871
+ return /*#__PURE__*/ React__default.createElement(Collapse$1, {
47872
+ ghost: true,
47873
+ bordered: false,
47874
+ items: collapseItems,
47875
+ defaultActiveKey: [
47876
+ "inputs",
47877
+ "outputs"
47878
+ ],
47879
+ style: {
47880
+ background: "transparent",
47881
+ padding: 0,
47882
+ margin: 0
47883
+ },
47884
+ styles: {
47885
+ header: {
47886
+ paddingLeft: 0,
47887
+ color: theme.colors.foreground
47888
+ }
47889
+ }
47890
+ });
47347
47891
  };
47348
- const CodeBlockContainer = styled.div`
47349
- box-sizing: border-box;
47350
- border-radius: 0.375rem;
47351
- overflow: hidden;
47352
- font-family: monospace;
47353
- font-size: 0.75rem;
47354
- line-height: 1.4;
47355
- max-height: 150px;
47356
- overflow-y: auto;
47357
- `;
47358
- const CodeBlockHeader = styled.div`
47359
- padding: 0.5rem 0.75rem;
47360
- display: flex;
47361
- justify-content: space-between;
47362
- align-items: center;
47363
- `;
47364
- const CodeBlockLanguage = styled.span`
47365
- font-size: 0.625rem;
47366
- font-weight: 500;
47367
- text-transform: uppercase;
47368
- letter-spacing: 0.05em;
47369
- `;
47370
- const CodeBlockContent = styled.pre`
47371
- margin: 0;
47372
- padding: 0.75rem;
47373
- white-space: pre-wrap;
47374
- word-break: break-word;
47375
- overflow-x: auto;
47376
- `;
47377
47892
 
47378
47893
  // Styled Components
47379
47894
  const TreeNodeContainer = styled.div``;
@@ -47641,485 +48156,6 @@ const JsonTreeViewer = ({ data, maxDepth = 4, initialExpanded = false, expanded
47641
48156
  })()));
47642
48157
  };
47643
48158
 
47644
- /** Max width for rich content (drawer output blocks, etc.) */ const NODE_MAX_WIDTH = 500;
47645
- /** Compact xyflow node card width range */ const FLOW_NODE_MIN_WIDTH = 176;
47646
- const FLOW_NODE_MAX_WIDTH = 250;
47647
- /** Used by auto-layout horizontal spacing (~typical card width between min and max) */ const LAYOUT_NODE_WIDTH = Math.round((FLOW_NODE_MIN_WIDTH + FLOW_NODE_MAX_WIDTH) / 2);
47648
-
47649
- const OutputRenderer = ({ data })=>{
47650
- const [isExpanded, setIsExpanded] = useState(false);
47651
- const contentType = detectContentType(data);
47652
- const handleToggle = ()=>{
47653
- setIsExpanded(!isExpanded);
47654
- };
47655
- switch(contentType){
47656
- case "string":
47657
- return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
47658
- className: "agent-node-scrollable"
47659
- }, /*#__PURE__*/ React__default.createElement(ExpandableTextarea, {
47660
- label: "Output",
47661
- content: data.content,
47662
- isExpanded: isExpanded,
47663
- onToggle: handleToggle
47664
- }));
47665
- case "toolResponse":
47666
- return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
47667
- className: "agent-node-scrollable"
47668
- }, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, "Output - Tool Response"), /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
47669
- data: data,
47670
- expanded: true
47671
- }));
47672
- case "toolCallList":
47673
- const formattedCode = formatToolCalls(data.content);
47674
- return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
47675
- className: "agent-node-scrollable"
47676
- }, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, /*#__PURE__*/ React__default.createElement("span", null, "Output - Tool Calls"), /*#__PURE__*/ React__default.createElement("span", {
47677
- style: {
47678
- display: "flex",
47679
- alignItems: "center",
47680
- gap: "0.25rem"
47681
- }
47682
- }, /*#__PURE__*/ React__default.createElement(CloudLightning, {
47683
- size: 14
47684
- }), data.content.length)), /*#__PURE__*/ React__default.createElement(CodeBlock, {
47685
- content: formattedCode,
47686
- language: "tool-calls",
47687
- showHeader: false
47688
- })));
47689
- case "other":
47690
- default:
47691
- return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(OutputScrollableContent, null, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, "Output - JSON"), /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
47692
- data: data,
47693
- expanded: true
47694
- })));
47695
- }
47696
- };
47697
- // Styled component for the sub-header
47698
- const NodeSubHeader = styled.span`
47699
- margin: 0;
47700
- padding: 0;
47701
- font-size: 0.75rem;
47702
- font-weight: 500;
47703
- display: flex;
47704
- justify-content: space-between;
47705
- align-items: center;
47706
- color: ${(props)=>props.theme?.colors?.foreground || "hsl(222.2 84% 4.9%)"};
47707
-
47708
- & span {
47709
- color: ${(props)=>props.theme?.colors?.mutedForeground || "hsl(215.4 16.3% 46.9%)"};
47710
- }
47711
- `;
47712
- const OutputScrollableContent = styled.div`
47713
- width: 100%;
47714
- max-width: ${NODE_MAX_WIDTH}px;
47715
- display: flex;
47716
- flex-direction: column;
47717
- align-items: stretch;
47718
- padding-bottom: 0.5rem;
47719
- padding-right: 2px;
47720
- gap: 0.5rem;
47721
- `;
47722
-
47723
- function _objectWithoutPropertiesLoose(r, e) {
47724
- if (null == r) return {};
47725
- var t = {};
47726
- for(var n in r)if (({}).hasOwnProperty.call(r, n)) {
47727
- if (-1 !== e.indexOf(n)) continue;
47728
- t[n] = r[n];
47729
- }
47730
- return t;
47731
- }
47732
-
47733
- var index$1 = useLayoutEffect;
47734
-
47735
- var useLatest = function useLatest(value) {
47736
- var ref = React__default.useRef(value);
47737
- index$1(function() {
47738
- ref.current = value;
47739
- });
47740
- return ref;
47741
- };
47742
-
47743
- // basically Exclude<React.ClassAttributes<T>["ref"], string>
47744
- var updateRef = function updateRef(ref, value) {
47745
- if (typeof ref === 'function') {
47746
- ref(value);
47747
- return;
47748
- }
47749
- ref.current = value;
47750
- };
47751
- var useComposedRef = function useComposedRef(libRef, userRef) {
47752
- var prevUserRef = React__default.useRef();
47753
- return React__default.useCallback(function(instance) {
47754
- libRef.current = instance;
47755
- if (prevUserRef.current) {
47756
- updateRef(prevUserRef.current, null);
47757
- }
47758
- prevUserRef.current = userRef;
47759
- if (!userRef) {
47760
- return;
47761
- }
47762
- updateRef(userRef, instance);
47763
- }, [
47764
- userRef
47765
- ]);
47766
- };
47767
-
47768
- var HIDDEN_TEXTAREA_STYLE = {
47769
- 'min-height': '0',
47770
- 'max-height': 'none',
47771
- height: '0',
47772
- visibility: 'hidden',
47773
- overflow: 'hidden',
47774
- position: 'absolute',
47775
- 'z-index': '-1000',
47776
- top: '0',
47777
- right: '0',
47778
- display: 'block'
47779
- };
47780
- var forceHiddenStyles = function forceHiddenStyles(node) {
47781
- Object.keys(HIDDEN_TEXTAREA_STYLE).forEach(function(key) {
47782
- node.style.setProperty(key, HIDDEN_TEXTAREA_STYLE[key], 'important');
47783
- });
47784
- };
47785
- var forceHiddenStyles$1 = forceHiddenStyles;
47786
- var hiddenTextarea = null;
47787
- var getHeight = function getHeight(node, sizingData) {
47788
- var height = node.scrollHeight;
47789
- if (sizingData.sizingStyle.boxSizing === 'border-box') {
47790
- // border-box: add border, since height = content + padding + border
47791
- return height + sizingData.borderSize;
47792
- }
47793
- // remove padding, since height = content
47794
- return height - sizingData.paddingSize;
47795
- };
47796
- function calculateNodeHeight(sizingData, value, minRows, maxRows) {
47797
- if (minRows === void 0) {
47798
- minRows = 1;
47799
- }
47800
- if (maxRows === void 0) {
47801
- maxRows = Infinity;
47802
- }
47803
- if (!hiddenTextarea) {
47804
- hiddenTextarea = document.createElement('textarea');
47805
- hiddenTextarea.setAttribute('tabindex', '-1');
47806
- hiddenTextarea.setAttribute('aria-hidden', 'true');
47807
- forceHiddenStyles$1(hiddenTextarea);
47808
- }
47809
- if (hiddenTextarea.parentNode === null) {
47810
- document.body.appendChild(hiddenTextarea);
47811
- }
47812
- var paddingSize = sizingData.paddingSize, borderSize = sizingData.borderSize, sizingStyle = sizingData.sizingStyle;
47813
- var boxSizing = sizingStyle.boxSizing;
47814
- Object.keys(sizingStyle).forEach(function(_key) {
47815
- var key = _key;
47816
- hiddenTextarea.style[key] = sizingStyle[key];
47817
- });
47818
- forceHiddenStyles$1(hiddenTextarea);
47819
- hiddenTextarea.value = value;
47820
- var height = getHeight(hiddenTextarea, sizingData);
47821
- // Double set and calc due to Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1795904
47822
- hiddenTextarea.value = value;
47823
- height = getHeight(hiddenTextarea, sizingData);
47824
- // measure height of a textarea with a single row
47825
- hiddenTextarea.value = 'x';
47826
- var rowHeight = hiddenTextarea.scrollHeight - paddingSize;
47827
- var minHeight = rowHeight * minRows;
47828
- if (boxSizing === 'border-box') {
47829
- minHeight = minHeight + paddingSize + borderSize;
47830
- }
47831
- height = Math.max(minHeight, height);
47832
- var maxHeight = rowHeight * maxRows;
47833
- if (boxSizing === 'border-box') {
47834
- maxHeight = maxHeight + paddingSize + borderSize;
47835
- }
47836
- height = Math.min(maxHeight, height);
47837
- return [
47838
- height,
47839
- rowHeight
47840
- ];
47841
- }
47842
- var noop$1 = function noop() {};
47843
- var pick = function pick(props, obj) {
47844
- return props.reduce(function(acc, prop) {
47845
- acc[prop] = obj[prop];
47846
- return acc;
47847
- }, {});
47848
- };
47849
- var SIZING_STYLE = [
47850
- 'borderBottomWidth',
47851
- 'borderLeftWidth',
47852
- 'borderRightWidth',
47853
- 'borderTopWidth',
47854
- 'boxSizing',
47855
- 'fontFamily',
47856
- 'fontSize',
47857
- 'fontStyle',
47858
- 'fontWeight',
47859
- 'letterSpacing',
47860
- 'lineHeight',
47861
- 'paddingBottom',
47862
- 'paddingLeft',
47863
- 'paddingRight',
47864
- 'paddingTop',
47865
- // non-standard
47866
- 'tabSize',
47867
- 'textIndent',
47868
- // non-standard
47869
- 'textRendering',
47870
- 'textTransform',
47871
- 'width',
47872
- 'wordBreak',
47873
- 'wordSpacing',
47874
- 'scrollbarGutter'
47875
- ];
47876
- var isIE = !!document.documentElement.currentStyle;
47877
- var getSizingData = function getSizingData(node) {
47878
- var style = window.getComputedStyle(node);
47879
- if (style === null) {
47880
- return null;
47881
- }
47882
- var sizingStyle = pick(SIZING_STYLE, style);
47883
- var boxSizing = sizingStyle.boxSizing;
47884
- // probably node is detached from DOM, can't read computed dimensions
47885
- if (boxSizing === '') {
47886
- return null;
47887
- }
47888
- // IE (Edge has already correct behaviour) returns content width as computed width
47889
- // so we need to add manually padding and border widths
47890
- if (isIE && boxSizing === 'border-box') {
47891
- sizingStyle.width = parseFloat(sizingStyle.width) + parseFloat(sizingStyle.borderRightWidth) + parseFloat(sizingStyle.borderLeftWidth) + parseFloat(sizingStyle.paddingRight) + parseFloat(sizingStyle.paddingLeft) + 'px';
47892
- }
47893
- var paddingSize = parseFloat(sizingStyle.paddingBottom) + parseFloat(sizingStyle.paddingTop);
47894
- var borderSize = parseFloat(sizingStyle.borderBottomWidth) + parseFloat(sizingStyle.borderTopWidth);
47895
- return {
47896
- sizingStyle: sizingStyle,
47897
- paddingSize: paddingSize,
47898
- borderSize: borderSize
47899
- };
47900
- };
47901
- var getSizingData$1 = getSizingData;
47902
- function useListener(target, type, listener) {
47903
- var latestListener = useLatest(listener);
47904
- React.useLayoutEffect(function() {
47905
- var handler = function handler(ev) {
47906
- return latestListener.current(ev);
47907
- };
47908
- // might happen if document.fonts is not defined, for instance
47909
- if (!target) {
47910
- return;
47911
- }
47912
- target.addEventListener(type, handler);
47913
- return function() {
47914
- return target.removeEventListener(type, handler);
47915
- };
47916
- }, []);
47917
- }
47918
- var useFormResetListener = function useFormResetListener(libRef, listener) {
47919
- useListener(document.body, 'reset', function(ev) {
47920
- if (libRef.current.form === ev.target) {
47921
- listener(ev);
47922
- }
47923
- });
47924
- };
47925
- var useWindowResizeListener = function useWindowResizeListener(listener) {
47926
- useListener(window, 'resize', listener);
47927
- };
47928
- var useFontsLoadedListener = function useFontsLoadedListener(listener) {
47929
- useListener(document.fonts, 'loadingdone', listener);
47930
- };
47931
- var _excluded = [
47932
- "cacheMeasurements",
47933
- "maxRows",
47934
- "minRows",
47935
- "onChange",
47936
- "onHeightChange"
47937
- ];
47938
- var TextareaAutosize = function TextareaAutosize(_ref, userRef) {
47939
- var cacheMeasurements = _ref.cacheMeasurements, maxRows = _ref.maxRows, minRows = _ref.minRows, _ref$onChange = _ref.onChange, onChange = _ref$onChange === void 0 ? noop$1 : _ref$onChange, _ref$onHeightChange = _ref.onHeightChange, onHeightChange = _ref$onHeightChange === void 0 ? noop$1 : _ref$onHeightChange, props = _objectWithoutPropertiesLoose(_ref, _excluded);
47940
- var isControlled = props.value !== undefined;
47941
- var libRef = React.useRef(null);
47942
- var ref = useComposedRef(libRef, userRef);
47943
- var heightRef = React.useRef(0);
47944
- var measurementsCacheRef = React.useRef();
47945
- var resizeTextarea = function resizeTextarea() {
47946
- var node = libRef.current;
47947
- var nodeSizingData = cacheMeasurements && measurementsCacheRef.current ? measurementsCacheRef.current : getSizingData$1(node);
47948
- if (!nodeSizingData) {
47949
- return;
47950
- }
47951
- measurementsCacheRef.current = nodeSizingData;
47952
- var _calculateNodeHeight = calculateNodeHeight(nodeSizingData, node.value || node.placeholder || 'x', minRows, maxRows), height = _calculateNodeHeight[0], rowHeight = _calculateNodeHeight[1];
47953
- if (heightRef.current !== height) {
47954
- heightRef.current = height;
47955
- node.style.setProperty('height', height + "px", 'important');
47956
- onHeightChange(height, {
47957
- rowHeight: rowHeight
47958
- });
47959
- }
47960
- };
47961
- var handleChange = function handleChange(event) {
47962
- if (!isControlled) {
47963
- resizeTextarea();
47964
- }
47965
- onChange(event);
47966
- };
47967
- {
47968
- React.useLayoutEffect(resizeTextarea);
47969
- useFormResetListener(libRef, function() {
47970
- if (!isControlled) {
47971
- var currentValue = libRef.current.value;
47972
- requestAnimationFrame(function() {
47973
- var node = libRef.current;
47974
- if (node && currentValue !== node.value) {
47975
- resizeTextarea();
47976
- }
47977
- });
47978
- }
47979
- });
47980
- useWindowResizeListener(resizeTextarea);
47981
- useFontsLoadedListener(resizeTextarea);
47982
- return /*#__PURE__*/ React.createElement("textarea", _extends$1({}, props, {
47983
- onChange: handleChange,
47984
- ref: ref
47985
- }));
47986
- }
47987
- };
47988
- var index = /* #__PURE__ */ React.forwardRef(TextareaAutosize);
47989
-
47990
- // Helper function to get emoji for role
47991
- const getRoleEmoji$1 = (role)=>{
47992
- switch(role.toLowerCase()){
47993
- case "system":
47994
- return "⚙️";
47995
- case "user":
47996
- return "👤";
47997
- case "assistant":
47998
- return "🤖";
47999
- case "tool":
48000
- return "🔧";
48001
- default:
48002
- return "🔧"; // fallback
48003
- }
48004
- };
48005
- // Helper function to get display name for role
48006
- const getRoleDisplayName$1 = (role)=>{
48007
- return role.charAt(0).toUpperCase() + role.slice(1);
48008
- };
48009
- // Component to render input array
48010
- const InputArrayRenderer = ({ input })=>{
48011
- const { theme } = useTheme$1();
48012
- const themeColors = theme?.colors || {
48013
- muted: "hsl(210 40% 96%)",
48014
- border: "hsl(214.3 31.8% 91.4%)",
48015
- foreground: "hsl(222.2 84% 4.9%)"
48016
- };
48017
- if (!input || input.length === 0) return null;
48018
- const renderContent = (content)=>{
48019
- if (typeof content === "string") {
48020
- return content;
48021
- }
48022
- return JSON.stringify(content);
48023
- };
48024
- return /*#__PURE__*/ React__default.createElement(InputArrayContainer, null, /*#__PURE__*/ React__default.createElement(InputArrayHeader, null, /*#__PURE__*/ React__default.createElement("h3", null, "Input"), /*#__PURE__*/ React__default.createElement("span", {
48025
- style: {
48026
- display: "flex",
48027
- alignItems: "center",
48028
- gap: "0.25rem"
48029
- }
48030
- }, /*#__PURE__*/ React__default.createElement(MessageSquare, {
48031
- size: 12
48032
- }), input.length)), /*#__PURE__*/ React__default.createElement(InputArrayScrollableContent, {
48033
- className: "agent-node-scrollable"
48034
- }, input.map((item, index)=>/*#__PURE__*/ React__default.createElement(InputItem, {
48035
- key: index
48036
- }, /*#__PURE__*/ React__default.createElement(InputItemHeader, null, /*#__PURE__*/ React__default.createElement(InputItemLabel, null, getRoleEmoji$1(item.role), " ", getRoleDisplayName$1(item.role))), /*#__PURE__*/ React__default.createElement(InputItemTextarea, {
48037
- onClick: (e)=>{
48038
- e.stopPropagation();
48039
- },
48040
- value: renderContent(item.content) || "",
48041
- readOnly: true,
48042
- style: {
48043
- border: `1px solid ${themeColors.border}`,
48044
- backgroundColor: themeColors.muted,
48045
- color: themeColors.foreground
48046
- },
48047
- className: "agent-node-scrollable"
48048
- })))));
48049
- };
48050
- // Styled components
48051
- const InputArrayContainer = styled.div`
48052
- width: 100%;
48053
- display: flex;
48054
- flex-direction: column;
48055
- gap: 0.5rem;
48056
- `;
48057
- const InputArrayScrollableContent = styled.div`
48058
- width: 100%;
48059
- display: flex;
48060
- flex-direction: column;
48061
- padding-bottom: 0.5rem;
48062
- padding-right: 2px;
48063
- gap: 0.5rem;
48064
- max-height: 200px;
48065
- overflow-y: auto;
48066
- `;
48067
- const InputArrayHeader = styled.div`
48068
- display: flex;
48069
- align-items: center;
48070
- justify-content: space-between;
48071
- font-weight: 500;
48072
- font-size: 0.75rem;
48073
- color: ${(props)=>props.theme?.colors?.foreground || "hsl(222.2 84% 4.9%)"};
48074
-
48075
- & h3 {
48076
- margin: 0;
48077
- padding: 0;
48078
- font-size: 0.75rem;
48079
- font-weight: 500;
48080
- color: ${(props)=>props.theme?.colors?.foreground || "hsl(222.2 84% 4.9%)"};
48081
- }
48082
-
48083
- & span {
48084
- font-size: 0.75rem;
48085
- font-weight: 500;
48086
- opacity: 0.5;
48087
- color: ${(props)=>props.theme?.colors?.foreground || "hsl(222.2 84% 4.9%)"};
48088
- }
48089
- `;
48090
- const InputItem = styled.div`
48091
- width: 100%;
48092
- display: flex;
48093
- flex-direction: column;
48094
- gap: 0.25rem;
48095
- `;
48096
- const InputItemHeader = styled.div`
48097
- display: flex;
48098
- align-items: center;
48099
- gap: 0.25rem;
48100
- `;
48101
- const InputItemLabel = styled.span`
48102
- font-weight: 600;
48103
- font-size: 0.75rem;
48104
- color: ${(props)=>props.theme?.colors?.mutedForeground || "hsl(215.4 16.3% 46.9%)"};
48105
- `;
48106
- const InputItemTextarea = styled(index)`
48107
- box-sizing: border-box;
48108
- width: 100%;
48109
- border-radius: 0.25rem;
48110
- padding: 0.5rem;
48111
- resize: none;
48112
- font-family: inherit;
48113
- font-size: 0.75rem;
48114
- &:focus {
48115
- outline: none;
48116
- border-color: ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
48117
- box-shadow: 0 0 0 1px ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
48118
- }
48119
-
48120
- transition: all 0.2s ease-in-out;
48121
- `;
48122
-
48123
48159
  const DEFAULT_COUNTUP_DURATION = 0.6;
48124
48160
  // Helper component for animating currency values
48125
48161
  const CountUpCurrency = ({ value, prefix = "", suffix = "" })=>{
@@ -48184,6 +48220,36 @@ const CountUpLatency = ({ value })=>{
48184
48220
  }
48185
48221
  return Object.keys(base).length > 0 ? base : null;
48186
48222
  }
48223
+ /** Tool drawer I/O from first edge detail (aligned with session-details getNodeInputsOutputs for Tool). */ function buildToolDrawerIo(nodeData) {
48224
+ const toolName = nodeData.label || "Tool";
48225
+ const d0 = nodeData.edgeDetails?.[0];
48226
+ const toolInputs = {};
48227
+ if (d0?.input_args && d0.input_args.length > 0) {
48228
+ toolInputs.args = d0.input_args;
48229
+ }
48230
+ if (d0?.input_kwargs && Object.keys(d0.input_kwargs).length > 0) {
48231
+ Object.assign(toolInputs, d0.input_kwargs);
48232
+ }
48233
+ const inputs = Object.keys(toolInputs).length > 0 ? [
48234
+ {
48235
+ role: "tool",
48236
+ content: {
48237
+ name: toolName,
48238
+ ...toolInputs
48239
+ }
48240
+ }
48241
+ ] : [];
48242
+ const toolOutput = d0?.output !== undefined ? d0.output : null;
48243
+ const toolStatusMap = new Map();
48244
+ if (d0?.status) {
48245
+ toolStatusMap.set(toolName, d0.status);
48246
+ }
48247
+ return {
48248
+ inputs,
48249
+ toolOutput,
48250
+ toolStatusMap
48251
+ };
48252
+ }
48187
48253
  const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48188
48254
  const { theme } = useTheme$1();
48189
48255
  const [selectedRowIndex, setSelectedRowIndex] = useState(null);
@@ -48225,12 +48291,15 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48225
48291
  const totalOutputTokens = sumTotalOutputTokens(llmDetailsList);
48226
48292
  const totalLatency = sumTotalLatency(llmDetailsList);
48227
48293
  const toolDrawerPayload = nodeType === "Tool" ? buildToolDrawerPayload(nodeData) : null;
48294
+ const toolDrawerIo = nodeType === "Tool" ? buildToolDrawerIo(nodeData) : null;
48295
+ const hasToolEdgeIo = toolDrawerIo != null && (toolDrawerIo.inputs.length > 0 || toolDrawerIo.toolOutput != null);
48296
+ const showToolLegacyJson = nodeType === "Tool" && !hasToolEdgeIo && toolDrawerPayload != null;
48228
48297
  const nodeLatencySeconds = nodeData.details?.internals?.latency?.total_time;
48229
48298
  const drawerTitle = /*#__PURE__*/ React__default.createElement(DrawerTitleContent, null, /*#__PURE__*/ React__default.createElement(NodeIcon$2, null, getNodeIcon({
48230
48299
  nodeType: (nodeData.nodeType || "Agent").toLowerCase(),
48231
48300
  modelProvider: llOverviewDetails?.model_provider,
48232
48301
  modelName: llOverviewDetails?.model_name
48233
- })), /*#__PURE__*/ React__default.createElement("span", null, nodeData.label, " Details"));
48302
+ })), /*#__PURE__*/ React__default.createElement("span", null, nodeData.label));
48234
48303
  return /*#__PURE__*/ React__default.createElement(Drawer$2, {
48235
48304
  title: drawerTitle,
48236
48305
  placement: "right",
@@ -48250,7 +48319,7 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48250
48319
  "aria-label": "Close drawer"
48251
48320
  })
48252
48321
  },
48253
- size: "500px",
48322
+ size: "600px",
48254
48323
  getContainer: ()=>document.body,
48255
48324
  zIndex: 1100,
48256
48325
  "data-testid": "node-details-drawer",
@@ -48266,7 +48335,16 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48266
48335
  }
48267
48336
  }, /*#__PURE__*/ React__default.createElement(DrawerBodyContent, {
48268
48337
  "data-testid": "node-details-drawer-content"
48269
- }, nodeType === "Tool" && /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, nodeLatencySeconds != null && /*#__PURE__*/ React__default.createElement(Section, null, /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Latency"), /*#__PURE__*/ React__default.createElement(InfoValue, null, formatLatency(nodeLatencySeconds)))), toolDrawerPayload ? /*#__PURE__*/ React__default.createElement(Section, {
48338
+ }, nodeType === "Tool" && /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, nodeLatencySeconds != null && /*#__PURE__*/ React__default.createElement(Section, null, /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Latency"), /*#__PURE__*/ React__default.createElement(InfoValue, null, formatLatency(nodeLatencySeconds)))), hasToolEdgeIo && toolDrawerIo ? /*#__PURE__*/ React__default.createElement(Section, {
48339
+ "data-testid": "tool-drawer-json"
48340
+ }, /*#__PURE__*/ React__default.createElement(InputsOutputsCollapse, {
48341
+ inputs: toolDrawerIo.inputs,
48342
+ output: null,
48343
+ toolOutput: toolDrawerIo.toolOutput,
48344
+ toolStatusMap: toolDrawerIo.toolStatusMap,
48345
+ toolInputAsTextarea: true,
48346
+ hasInputs: toolDrawerIo.inputs.length > 0
48347
+ })) : showToolLegacyJson ? /*#__PURE__*/ React__default.createElement(Section, {
48270
48348
  "data-testid": "tool-drawer-json"
48271
48349
  }, /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
48272
48350
  excludeKeys: [
@@ -48278,7 +48356,7 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48278
48356
  const isAggregateSelected = selectedRowIndex === llmDetails.length;
48279
48357
  const selectedDetails = isAggregateSelected ? null // Use aggregate values
48280
48358
  : llmDetails[selectedRowIndex || 0];
48281
- return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Model"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? llOverviewDetails.model_name : selectedDetails?.model_name || "N/A")), /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Provider"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? getProviderLabel(llOverviewDetails.model_name, llOverviewDetails.model_provider) : selectedDetails ? getProviderLabel(selectedDetails.model_name, selectedDetails.model_provider) : "N/A")), /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, isAggregateSelected ? "Total" : "", " Latency"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? totalLatency ? /*#__PURE__*/ React__default.createElement(CountUpLatency, {
48359
+ return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Model"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? getModelLabel(llOverviewDetails.model_name) || "N/A" : getModelLabel(selectedDetails?.model_name) || "N/A")), /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, "Provider"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? getProviderLabel(llOverviewDetails.model_name, llOverviewDetails.model_provider) : selectedDetails ? getProviderLabel(selectedDetails.model_name, selectedDetails.model_provider) : "N/A")), /*#__PURE__*/ React__default.createElement(InfoItem, null, /*#__PURE__*/ React__default.createElement(InfoLabel, null, isAggregateSelected ? "Total" : "", " Latency"), /*#__PURE__*/ React__default.createElement(InfoValue, null, isAggregateSelected ? totalLatency ? /*#__PURE__*/ React__default.createElement(CountUpLatency, {
48282
48360
  value: totalLatency
48283
48361
  }) : "N/A" : selectedDetails?.latency ? /*#__PURE__*/ React__default.createElement(CountUpLatency, {
48284
48362
  value: selectedDetails.latency
@@ -48313,11 +48391,13 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48313
48391
  }) : "N/A")));
48314
48392
  })())), nodeType === "Agent" && llOverviewDetails && llmDetailsList.length === 1 && /*#__PURE__*/ React__default.createElement(Section, {
48315
48393
  "data-testid": "agent-single-llm-messages"
48316
- }, /*#__PURE__*/ React__default.createElement(InputArrayRenderer, {
48317
- input: llOverviewDetails.input || []
48318
- }), llOverviewDetails.output ? /*#__PURE__*/ React__default.createElement(OutputRenderer, {
48319
- data: llOverviewDetails.output
48320
- }) : null), nodeType === "Agent" && llmDetailsList.length > 1 && /*#__PURE__*/ React__default.createElement(Section, null, /*#__PURE__*/ React__default.createElement(TableWrapper, null, /*#__PURE__*/ React__default.createElement("table", null, /*#__PURE__*/ React__default.createElement("thead", null, /*#__PURE__*/ React__default.createElement("tr", null, /*#__PURE__*/ React__default.createElement("th", {
48394
+ }, /*#__PURE__*/ React__default.createElement(InputsOutputsCollapse, {
48395
+ inputs: llOverviewDetails.input || [],
48396
+ output: llOverviewDetails.output ?? null,
48397
+ toolOutput: null,
48398
+ modelProvider: llOverviewDetails.model_provider,
48399
+ modelName: llOverviewDetails.model_name
48400
+ })), nodeType === "Agent" && llmDetailsList.length > 1 && /*#__PURE__*/ React__default.createElement(Section, null, /*#__PURE__*/ React__default.createElement(TableWrapper, null, /*#__PURE__*/ React__default.createElement("table", null, /*#__PURE__*/ React__default.createElement("thead", null, /*#__PURE__*/ React__default.createElement("tr", null, /*#__PURE__*/ React__default.createElement("th", {
48321
48401
  style: {
48322
48402
  textAlign: "center"
48323
48403
  }
@@ -48415,10 +48495,12 @@ const NodeDetailsDrawer = ({ isVisible, onClose, nodeData })=>{
48415
48495
  }
48416
48496
  }, totalLatency ? /*#__PURE__*/ React__default.createElement(CountUpLatency, {
48417
48497
  value: totalLatency
48418
- }) : "N/A"))))), selectedLlmDetails ? /*#__PURE__*/ React__default.createElement(FadingSection, null, /*#__PURE__*/ React__default.createElement(InputArrayRenderer, {
48419
- input: selectedLlmDetails.input || []
48420
- }), /*#__PURE__*/ React__default.createElement(OutputRenderer, {
48421
- data: selectedLlmDetails.output
48498
+ }) : "N/A"))))), selectedLlmDetails ? /*#__PURE__*/ React__default.createElement(FadingSection, null, /*#__PURE__*/ React__default.createElement(InputsOutputsCollapse, {
48499
+ inputs: selectedLlmDetails.input || [],
48500
+ output: selectedLlmDetails.output ?? null,
48501
+ toolOutput: null,
48502
+ modelProvider: selectedLlmDetails.model_provider,
48503
+ modelName: selectedLlmDetails.model_name
48422
48504
  })) : null)));
48423
48505
  };
48424
48506
  // Styled components
@@ -48546,6 +48628,10 @@ const NodeIcon$2 = styled.div`
48546
48628
  color: ${(p)=>p.theme?.colors?.foreground ?? "inherit"};
48547
48629
  `;
48548
48630
 
48631
+ /** Compact xyflow node card width range */ const FLOW_NODE_MIN_WIDTH = 176;
48632
+ const FLOW_NODE_MAX_WIDTH = 250;
48633
+ /** Used by auto-layout horizontal spacing (~typical card width between min and max) */ const LAYOUT_NODE_WIDTH = Math.round((FLOW_NODE_MIN_WIDTH + FLOW_NODE_MAX_WIDTH) / 2);
48634
+
48549
48635
  // Helper to resolve icon when provider is Unknown - use model_name as fallback (e.g. "apple-on-device" -> Apple)
48550
48636
  const resolveProviderFromModelName = (modelName)=>{
48551
48637
  const normalized = modelName?.toLowerCase();
@@ -48557,7 +48643,11 @@ const resolveProviderFromModelName = (modelName)=>{
48557
48643
  */ const getNodeIcon = (options = {})=>{
48558
48644
  const { nodeType, modelProvider, modelName, size = 16 } = options ?? {};
48559
48645
  const normalizedNodeType = nodeType?.toLowerCase();
48560
- if (normalizedNodeType === "tool") return "🔧";
48646
+ if (normalizedNodeType === "tool") return /*#__PURE__*/ React__default.createElement(Wrench, {
48647
+ size: size,
48648
+ strokeWidth: 2,
48649
+ "aria-hidden": true
48650
+ });
48561
48651
  const normalizedProvider = modelProvider?.toLowerCase();
48562
48652
  const resolvedProvider = !normalizedProvider || normalizedProvider === "unknown" ? resolveProviderFromModelName(modelName) : normalizedProvider;
48563
48653
  if (resolvedProvider === "openai") return /*#__PURE__*/ React__default.createElement(OpenAIIcon, {
@@ -48607,6 +48697,17 @@ const PROVIDER_LABELS = {
48607
48697
  }
48608
48698
  return PROVIDER_LABELS[normalizedProvider] ?? toTitleCase(modelProvider);
48609
48699
  };
48700
+ const MODEL_DISPLAY_NAMES = {
48701
+ "apple-on-device": "Apple on Device"
48702
+ };
48703
+ /**
48704
+ * Display label for a Railtracks model_name slug (frontend copy only; does not alter data).
48705
+ */ const getModelLabel = (modelName)=>{
48706
+ const trimmed = modelName?.trim() ?? "";
48707
+ if (!trimmed) return "";
48708
+ const key = trimmed.toLowerCase();
48709
+ return MODEL_DISPLAY_NAMES[key] ?? trimmed;
48710
+ };
48610
48711
  const getOverviewLlmDetails = (llmDetails)=>{
48611
48712
  if (!llmDetails) return null;
48612
48713
  return llmDetails[llmDetails.length - 1];
@@ -48678,7 +48779,7 @@ const AgentNode = ({ data, id, onInspect, defaultDrawerOpen })=>{
48678
48779
  }, /*#__PURE__*/ React__default.createElement(Cpu, {
48679
48780
  size: 12,
48680
48781
  strokeWidth: 2
48681
- })), /*#__PURE__*/ React__default.createElement(MetaLineText, null, providerLine)), /*#__PURE__*/ React__default.createElement(CostLine, null, /*#__PURE__*/ React__default.createElement(CostLineIcon, {
48782
+ })), /*#__PURE__*/ React__default.createElement(MetaLineText, null, getModelLabel(modelName) || "—")), /*#__PURE__*/ React__default.createElement(CostLine, null, /*#__PURE__*/ React__default.createElement(CostLineIcon, {
48682
48783
  "aria-hidden": true
48683
48784
  }, /*#__PURE__*/ React__default.createElement(CircleDollarSign, {
48684
48785
  size: 13,
@@ -52309,19 +52410,18 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52309
52410
  width: typeof width === "number" ? width : 1200,
52310
52411
  height: typeof height === "number" ? height : 600
52311
52412
  });
52312
- // Timeline state
52313
- const [currentStep, setCurrentStep] = useState(0);
52413
+ // Timeline state — start at final step so first paint isn't empty when the graph begins after step 0
52414
+ const [currentStep, setCurrentStep] = useState(()=>getDefaultTimelineStepForRun(flowData));
52314
52415
  const [isPlaying, setIsPlaying] = useState(false);
52315
52416
  const playIntervalRef = useRef(null);
52316
52417
  // Timeline visibility state
52317
52418
  const [showTimelines, setShowTimelines] = useState(false);
52318
- // Get max step from stamps or steps
52319
- const maxStep = useMemo(()=>{
52320
- const stamps = flowData.stamps || flowData.steps || [];
52321
- return stamps.length > 0 ? Math.max(...stamps.map((s)=>s.step)) : 0;
52322
- }, [
52419
+ const maxStep = useMemo(()=>getDefaultTimelineStepForRun(flowData), [
52420
+ flowData.nodes,
52421
+ flowData.edges,
52323
52422
  flowData.stamps,
52324
- flowData.steps
52423
+ flowData.steps,
52424
+ flowData.run_id
52325
52425
  ]);
52326
52426
  // Auto-play functionality
52327
52427
  useEffect(()=>{
@@ -52350,15 +52450,13 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52350
52450
  isPlaying,
52351
52451
  maxStep
52352
52452
  ]);
52353
- // Initialize current step to last step and pan to hub node
52354
- useEffect(()=>{
52355
- const stamps = flowData.stamps || flowData.steps || [];
52356
- if (stamps.length > 0) {
52357
- setCurrentStep(Math.max(...stamps.map((s)=>s.step)));
52358
- }
52453
+ // Default to the final step for this run so the full graph is visible (stamps may be missing).
52454
+ // useLayoutEffect: align step before paint so getNodesForStep(currentStep) never briefly filters out the whole graph.
52455
+ useLayoutEffect(()=>{
52456
+ setCurrentStep(maxStep);
52359
52457
  }, [
52360
- flowData.stamps,
52361
- flowData.steps
52458
+ maxStep,
52459
+ flowData.run_id
52362
52460
  ]);
52363
52461
  // Update dimensions when width/height props change
52364
52462
  useEffect(()=>{
@@ -52407,12 +52505,12 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52407
52505
  if (!flowData.nodes) {
52408
52506
  return [];
52409
52507
  }
52410
- return flowData.nodes.filter((node)=>node.stamp.step <= step);
52508
+ return flowData.nodes.filter((node)=>(node.stamp?.step ?? 0) <= step);
52411
52509
  }, [
52412
52510
  flowData.nodes
52413
52511
  ]);
52414
52512
  const getEdgesForStep = useCallback((step)=>{
52415
- return (flowData.edges || []).filter((edge)=>edge.stamp.step <= step);
52513
+ return (flowData.edges || []).filter((edge)=>(edge.stamp?.step ?? 0) <= step);
52416
52514
  }, [
52417
52515
  flowData.edges
52418
52516
  ]);
@@ -52441,7 +52539,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52441
52539
  x: 0,
52442
52540
  y: 0
52443
52541
  };
52444
- const isActive = node.stamp.step === currentStep;
52542
+ const isActive = node.stamp?.step === currentStep;
52445
52543
  const rawType = node.node_type || "Agent";
52446
52544
  const resolvedType = rawType === "Coordinator" ? "Agent" : rawType;
52447
52545
  // Extract edge details for Tool nodes
@@ -52475,7 +52573,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52475
52573
  const edges = useMemo(()=>{
52476
52574
  const stepEdges = getEdgesForStep(currentStep);
52477
52575
  return stepEdges.filter((edge)=>edge.source && edge.target).map((edge)=>{
52478
- const isActive = edge.stamp.step === currentStep;
52576
+ const isActive = edge.stamp?.step === currentStep;
52479
52577
  return {
52480
52578
  id: edge.identifier,
52481
52579
  type: "smoothstep",
@@ -52503,14 +52601,14 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52503
52601
  ]);
52504
52602
  const [nodesState, setNodes, onNodesChange] = useNodesState(nodes);
52505
52603
  const [edgesState, setEdges, onEdgesChange] = useEdgesState(edges);
52506
- // Update nodes and edges when currentStep changes
52507
- useEffect(()=>{
52604
+ // Keep React Flow store in sync with derived nodes/edges before paint to avoid transient empty graphs.
52605
+ useLayoutEffect(()=>{
52508
52606
  setNodes(nodes);
52509
52607
  }, [
52510
52608
  nodes,
52511
52609
  setNodes
52512
52610
  ]);
52513
- useEffect(()=>{
52611
+ useLayoutEffect(()=>{
52514
52612
  setEdges(edges);
52515
52613
  }, [
52516
52614
  edges,
@@ -52751,7 +52849,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
52751
52849
  whiteSpace: "nowrap",
52752
52850
  border: 0
52753
52851
  }
52754
- }, "Close"))))), /*#__PURE__*/ React__default.createElement(index$2, {
52852
+ }, "Close"))))), /*#__PURE__*/ React__default.createElement(index, {
52755
52853
  colorMode: isDarkMode ? "dark" : "light",
52756
52854
  nodes: nodesState,
52757
52855
  edges: edgesState,
@@ -112227,322 +112325,6 @@ class ErrorBoundary extends Component {
112227
112325
  }
112228
112326
  }
112229
112327
 
112230
- const MAX_TITLE_LEN = 200;
112231
- const TOOLBAR_ICON_SIZE = 15;
112232
- const JsonValueTree = ({ data, className, maxHeight = "auto" })=>{
112233
- const { theme } = useTheme$1();
112234
- const { mutedForeground } = theme.colors;
112235
- const treeData = useMemo(()=>buildTreeData(data), [
112236
- data
112237
- ]);
112238
- const defaultExpandedKeys = useMemo(()=>collectKeysToDepth(treeData, 2), [
112239
- treeData
112240
- ]);
112241
- const allExpandableKeys = useMemo(()=>collectAllExpandableKeys(treeData), [
112242
- treeData
112243
- ]);
112244
- const [expandedKeys, setExpandedKeys] = useState(()=>defaultExpandedKeys);
112245
- const hasBranches = allExpandableKeys.length > 0;
112246
- const isAllExpanded = hasBranches && allExpandableKeys.every((k)=>expandedKeys.includes(k));
112247
- useEffect(()=>{
112248
- setExpandedKeys(defaultExpandedKeys);
112249
- }, [
112250
- defaultExpandedKeys
112251
- ]);
112252
- const handleCopyJson = useCallback(async ()=>{
112253
- try {
112254
- const text = JSON.stringify(data, null, 2);
112255
- await navigator.clipboard.writeText(text);
112256
- staticMethods.success("JSON copied to clipboard");
112257
- } catch {
112258
- staticMethods.error("Could not copy to clipboard");
112259
- }
112260
- }, [
112261
- data
112262
- ]);
112263
- const handleToggleExpandCollapse = useCallback(()=>{
112264
- if (isAllExpanded) {
112265
- setExpandedKeys([]);
112266
- } else {
112267
- setExpandedKeys(allExpandableKeys);
112268
- }
112269
- }, [
112270
- isAllExpanded,
112271
- allExpandableKeys
112272
- ]);
112273
- return /*#__PURE__*/ React__default.createElement("div", {
112274
- className: className,
112275
- style: {
112276
- maxHeight,
112277
- display: "flex",
112278
- flexDirection: "column",
112279
- borderRadius: 4,
112280
- overflow: "hidden"
112281
- }
112282
- }, /*#__PURE__*/ React__default.createElement("div", {
112283
- style: {
112284
- display: "flex",
112285
- justifyContent: "flex-end",
112286
- alignItems: "center",
112287
- gap: 2,
112288
- padding: "4px 6px 2px",
112289
- flexShrink: 0,
112290
- background: "transparent"
112291
- }
112292
- }, /*#__PURE__*/ React__default.createElement(Tooltip$1, {
112293
- title: "Copy JSON"
112294
- }, /*#__PURE__*/ React__default.createElement(Button$1, {
112295
- type: "text",
112296
- size: "small",
112297
- "aria-label": "Copy JSON to clipboard",
112298
- icon: /*#__PURE__*/ React__default.createElement(Copy, {
112299
- size: TOOLBAR_ICON_SIZE,
112300
- color: mutedForeground
112301
- }),
112302
- onClick: handleCopyJson
112303
- })), /*#__PURE__*/ React__default.createElement(Tooltip$1, {
112304
- title: isAllExpanded ? "Collapse all" : "Expand all"
112305
- }, /*#__PURE__*/ React__default.createElement(Button$1, {
112306
- type: "text",
112307
- size: "small",
112308
- "aria-label": isAllExpanded ? "Collapse all tree nodes" : "Expand all tree nodes",
112309
- disabled: !hasBranches,
112310
- icon: isAllExpanded ? /*#__PURE__*/ React__default.createElement(FoldVertical, {
112311
- size: TOOLBAR_ICON_SIZE,
112312
- color: mutedForeground
112313
- }) : /*#__PURE__*/ React__default.createElement(UnfoldVertical, {
112314
- size: TOOLBAR_ICON_SIZE,
112315
- color: mutedForeground
112316
- }),
112317
- onClick: handleToggleExpandCollapse
112318
- }))), /*#__PURE__*/ React__default.createElement("div", {
112319
- style: {
112320
- flex: 1,
112321
- minHeight: 0,
112322
- overflow: "auto",
112323
- padding: "4px 0"
112324
- }
112325
- }, /*#__PURE__*/ React__default.createElement(Tree, {
112326
- // No showLine — connector lines look like a floating spine for many top-level fields.
112327
- showLine: true,
112328
- blockNode: true,
112329
- expandAction: "click",
112330
- selectable: false,
112331
- showIcon: false,
112332
- treeData: treeData,
112333
- expandedKeys: expandedKeys,
112334
- onExpand: (keys)=>setExpandedKeys(keys),
112335
- rootStyle: {
112336
- backgroundColor: "transparent",
112337
- padding: "0 4px"
112338
- }
112339
- })));
112340
- };
112341
- function collectKeysToDepth(nodes, maxDepth, depth = 0) {
112342
- if (depth >= maxDepth) return [];
112343
- const keys = [];
112344
- for (const n of nodes){
112345
- if (n.children && n.children.length > 0) {
112346
- keys.push(n.key);
112347
- keys.push(...collectKeysToDepth(n.children, maxDepth, depth + 1));
112348
- }
112349
- }
112350
- return keys;
112351
- }
112352
- function collectAllExpandableKeys(nodes) {
112353
- const keys = [];
112354
- for (const n of nodes){
112355
- if (n.children && n.children.length > 0) {
112356
- keys.push(n.key);
112357
- keys.push(...collectAllExpandableKeys(n.children));
112358
- }
112359
- }
112360
- return keys;
112361
- }
112362
- /**
112363
- * Object keys A→Z, but any property whose value is an array is listed after all non-array properties
112364
- * (each block still A→Z). Tree has no built-in sort — this defines `treeData` order.
112365
- */ function sortObjectEntriesForTree(entries) {
112366
- return [
112367
- ...entries
112368
- ].sort((a, b)=>{
112369
- const aArr = Array.isArray(a[1]);
112370
- const bArr = Array.isArray(b[1]);
112371
- if (aArr !== bArr) {
112372
- return aArr ? 1 : -1;
112373
- }
112374
- return a[0].localeCompare(b[0], undefined, {
112375
- sensitivity: "base",
112376
- numeric: true
112377
- });
112378
- });
112379
- }
112380
- function valueToTreeNodes(value, path) {
112381
- if (value === null || value === undefined) {
112382
- return [
112383
- {
112384
- key: path,
112385
- title: formatJsonTreePrimitive(value),
112386
- isLeaf: true
112387
- }
112388
- ];
112389
- }
112390
- if (Array.isArray(value)) {
112391
- if (value.length === 0) {
112392
- return [
112393
- {
112394
- key: `${path}.__empty_arr__`,
112395
- title: "[] (0 items)",
112396
- isLeaf: true
112397
- }
112398
- ];
112399
- }
112400
- return value.map((item, i)=>{
112401
- const seg = `[${i}]`;
112402
- const childPath = `${path}.${escapeDotPathSegment(seg)}`;
112403
- if (item === null || item === undefined || typeof item !== "object") {
112404
- return {
112405
- key: childPath,
112406
- title: `${seg}: ${formatJsonTreePrimitive(item)}`,
112407
- isLeaf: true
112408
- };
112409
- }
112410
- if (Array.isArray(item) || isPlainObject(item)) {
112411
- const children = valueToTreeNodes(item, childPath);
112412
- return {
112413
- key: childPath,
112414
- title: `${seg} (${Array.isArray(item) ? `Array(${item.length})` : `Object(${Object.keys(item).length})`})`,
112415
- children
112416
- };
112417
- }
112418
- return {
112419
- key: childPath,
112420
- title: `${seg}: ${formatJsonTreePrimitive(item)}`,
112421
- isLeaf: true
112422
- };
112423
- });
112424
- }
112425
- if (isPlainObject(value)) {
112426
- const entries = sortObjectEntriesForTree(Object.entries(value));
112427
- if (entries.length === 0) {
112428
- return [
112429
- {
112430
- key: `${path}.__empty_obj__`,
112431
- title: "{} (0 keys)",
112432
- isLeaf: true
112433
- }
112434
- ];
112435
- }
112436
- return entries.map(([k, v])=>{
112437
- const childPath = `${path}.${escapeDotPathSegment(k)}`;
112438
- if (v === null || v === undefined || typeof v !== "object") {
112439
- const text = `${k}: ${formatJsonTreePrimitive(v)}`;
112440
- const title = text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
112441
- title: text
112442
- }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text;
112443
- return {
112444
- key: childPath,
112445
- title,
112446
- isLeaf: true
112447
- };
112448
- }
112449
- if (Array.isArray(v) || isPlainObject(v)) {
112450
- const children = valueToTreeNodes(v, childPath);
112451
- const summary = Array.isArray(v) ? `Array(${v.length})` : `Object(${Object.keys(v).length})`;
112452
- return {
112453
- key: childPath,
112454
- title: `${k}: ${summary}`,
112455
- children
112456
- };
112457
- }
112458
- const text = `${k}: ${formatJsonTreePrimitive(v)}`;
112459
- return {
112460
- key: childPath,
112461
- title: text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
112462
- title: text
112463
- }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text,
112464
- isLeaf: true
112465
- };
112466
- });
112467
- }
112468
- const text = formatJsonTreePrimitive(value);
112469
- return [
112470
- {
112471
- key: path,
112472
- title: text.length > MAX_TITLE_LEN ? /*#__PURE__*/ React__default.createElement(Tooltip$1, {
112473
- title: text
112474
- }, /*#__PURE__*/ React__default.createElement("span", null, text.slice(0, MAX_TITLE_LEN), "…")) : text,
112475
- isLeaf: true
112476
- }
112477
- ];
112478
- }
112479
- /** Top-level tree for tabular session output: plain object or array of plain objects. */ function buildTreeData(data) {
112480
- if (data === null || data === undefined) {
112481
- return [
112482
- {
112483
- key: "root",
112484
- title: String(data),
112485
- isLeaf: true
112486
- }
112487
- ];
112488
- }
112489
- if (Array.isArray(data)) {
112490
- if (data.length === 0) {
112491
- return [
112492
- {
112493
- key: "$top",
112494
- title: "Array (0 items)",
112495
- isLeaf: true
112496
- }
112497
- ];
112498
- }
112499
- const children = data.map((item, index)=>{
112500
- const path = `$root[${index}]`;
112501
- if (!isPlainObject(item)) {
112502
- return {
112503
- key: path,
112504
- title: `[${index}]: ${formatJsonTreePrimitive(item)}`,
112505
- isLeaf: true
112506
- };
112507
- }
112508
- const itemChildren = valueToTreeNodes(item, path);
112509
- return {
112510
- key: path,
112511
- title: `[${index}] (${Object.keys(item).length} keys)`,
112512
- children: itemChildren
112513
- };
112514
- });
112515
- return [
112516
- {
112517
- key: "$top",
112518
- title: `Array (${data.length} items)`,
112519
- children
112520
- }
112521
- ];
112522
- }
112523
- if (isPlainObject(data)) {
112524
- const objectKeys = Object.keys(data);
112525
- if (objectKeys.length === 0) {
112526
- return [
112527
- {
112528
- key: "$top",
112529
- title: "Object (0 keys)",
112530
- isLeaf: true
112531
- }
112532
- ];
112533
- }
112534
- const children = valueToTreeNodes(data, "$root");
112535
- return [
112536
- {
112537
- key: "$top",
112538
- title: `Object (${objectKeys.length} keys)`,
112539
- children
112540
- }
112541
- ];
112542
- }
112543
- return valueToTreeNodes(data, "$root");
112544
- }
112545
-
112546
112328
  const getNodeLatency = (node)=>node.details?.internals?.latency?.total_time ?? 0;
112547
112329
  /** Tool/agent failure is carried on the incoming edge's details.status (e.g. Failed), same as flow edges and session I/O. */ function isNodeFailureFromIncomingEdge(run, nodeId) {
112548
112330
  const incoming = run.edges?.filter((e)=>e.target === nodeId) ?? [];
@@ -112796,158 +112578,6 @@ const useShareAgentSession = (session)=>{
112796
112578
  };
112797
112579
 
112798
112580
  const { Text } = Typography;
112799
- // Shared theme color fallbacks
112800
- const DEFAULT_THEME_COLORS = {
112801
- border: "hsl(214.3 31.8% 91.4%)",
112802
- foreground: "hsl(222.2 84% 4.9%)"
112803
- };
112804
- // Helper function to format content as text
112805
- const formatContentAsText = (content)=>{
112806
- if (typeof content === "string") {
112807
- return content;
112808
- }
112809
- if (Array.isArray(content)) {
112810
- return content.map((item)=>formatContentAsText(item)).join("\n\n");
112811
- }
112812
- return JSON.stringify(content, null, 2);
112813
- };
112814
- // Helper function to check if data is tabular (object or array of objects)
112815
- const isTabularData = (data)=>{
112816
- if (data === null || data === undefined) {
112817
- return false;
112818
- }
112819
- // Check if it's a plain object (not array, Date, etc.)
112820
- if (typeof data === "object" && !Array.isArray(data) && data.constructor === Object) {
112821
- return true;
112822
- }
112823
- // Check if it's an array of plain objects
112824
- if (Array.isArray(data) && data.length > 0) {
112825
- return data.every((item)=>item !== null && item !== undefined && typeof item === "object" && !Array.isArray(item) && item.constructor === Object);
112826
- }
112827
- return false;
112828
- };
112829
- // Helper function to format output as text
112830
- const formatOutputAsText = (output, toolOutput)=>{
112831
- if (toolOutput !== null && toolOutput !== undefined) {
112832
- return formatContentAsText(toolOutput);
112833
- }
112834
- if (output) {
112835
- const role = getRoleDisplayName(output.role);
112836
- const content = formatContentAsText(output.content);
112837
- return `${role}:\n${content}`;
112838
- }
112839
- return "";
112840
- };
112841
- // Helper function to get emoji for role
112842
- const getRoleEmoji = (role)=>{
112843
- switch(role.toLowerCase()){
112844
- case "system":
112845
- return "⚙️";
112846
- case "user":
112847
- return "👤";
112848
- case "assistant":
112849
- return "🤖";
112850
- case "tool":
112851
- return "🔧";
112852
- default:
112853
- return "🔧"; // fallback
112854
- }
112855
- };
112856
- // Helper function to get display name for role
112857
- const getRoleDisplayName = (role)=>{
112858
- return role.charAt(0).toUpperCase() + role.slice(1);
112859
- };
112860
- // Helper function to render content
112861
- const renderContent = (content)=>{
112862
- if (typeof content === "string") {
112863
- return content;
112864
- }
112865
- return JSON.stringify(content, null, 2);
112866
- };
112867
- // Helper to filter out keys containing "name" from objects (recursive)
112868
- const filterKeysWithName = (obj)=>{
112869
- if (obj === null || obj === undefined) return obj;
112870
- if (typeof obj !== "object") return obj;
112871
- if (Array.isArray(obj)) return obj.map(filterKeysWithName);
112872
- return Object.fromEntries(Object.entries(obj).filter(([key])=>!key.toLowerCase().includes("name")).map(([key, value])=>[
112873
- key,
112874
- filterKeysWithName(value)
112875
- ]));
112876
- };
112877
- const LLMInputsRenderer = ({ input, isDarkMode, modelProvider, modelName, toolStatusMap })=>{
112878
- const { theme } = useTheme$1();
112879
- const themeColors = theme?.colors || DEFAULT_THEME_COLORS;
112880
- if (!input || input.length === 0) return null;
112881
- const collapseItems = input.map((item, index)=>{
112882
- const modelIcon = modelProvider || modelName ? getNodeIcon({
112883
- modelProvider,
112884
- modelName
112885
- }) : null;
112886
- const isSystemInput = item.role.toLowerCase() === "system";
112887
- const showModelInfo = isSystemInput && (modelProvider || modelName);
112888
- const isToolInput = item.role.toLowerCase() === "tool";
112889
- const isAssistantInput = item.role.toLowerCase() === "assistant";
112890
- const isUserInput = item.role.toLowerCase() === "user";
112891
- // Extract tool name for tool inputs
112892
- const toolName = isToolInput && item.content?.name ? item.content.name : null;
112893
- // Look up status for this specific tool
112894
- const toolStatus = toolName && toolStatusMap ? toolStatusMap.get(toolName) : undefined;
112895
- // Extract tool call name(s) for assistant inputs
112896
- let assistantToolName = null;
112897
- if (isAssistantInput && Array.isArray(item.content) && item.content.length > 0) {
112898
- const firstToolCall = item.content[0];
112899
- if (firstToolCall?.name) {
112900
- assistantToolName = firstToolCall.name;
112901
- }
112902
- }
112903
- return {
112904
- key: `input-${index}`,
112905
- label: /*#__PURE__*/ React__default.createElement(Text, {
112906
- strong: true
112907
- }, getRoleEmoji(item.role), " ", toolName ? `Tool` : assistantToolName ? `Assistant` : getRoleDisplayName(item.role)),
112908
- extra: showModelInfo ? /*#__PURE__*/ React__default.createElement(Space, {
112909
- size: "small"
112910
- }, modelIcon && /*#__PURE__*/ React__default.createElement("span", null, modelIcon), modelName && /*#__PURE__*/ React__default.createElement("span", {
112911
- style: {
112912
- fontSize: "12px",
112913
- opacity: 0.7
112914
- }
112915
- }, modelName)) : isToolInput ? /*#__PURE__*/ React__default.createElement(Tag, {
112916
- color: toolStatus === "Failed" ? "red" : "blue"
112917
- }, toolName || "Tool Response") : isUserInput ? /*#__PURE__*/ React__default.createElement(Tag, {
112918
- color: "purple"
112919
- }, "Text") : undefined,
112920
- children: /*#__PURE__*/ React__default.createElement("pre", {
112921
- style: {
112922
- margin: 0,
112923
- padding: "12px",
112924
- background: isDarkMode ? "#1f1f1f" : "#fafafa",
112925
- border: `1px solid ${themeColors.border}`,
112926
- borderRadius: "4px",
112927
- color: themeColors.foreground,
112928
- whiteSpace: "pre-wrap",
112929
- wordWrap: "break-word",
112930
- fontFamily: "monospace",
112931
- fontSize: "12px",
112932
- lineHeight: "1.5",
112933
- maxHeight: "300px",
112934
- overflow: "auto"
112935
- }
112936
- }, renderContent(typeof item.content === "object" && item.content !== null && !Array.isArray(item.content) ? filterKeysWithName(item.content) : item.content))
112937
- };
112938
- });
112939
- return /*#__PURE__*/ React__default.createElement(Collapse$1, {
112940
- items: collapseItems,
112941
- defaultActiveKey: collapseItems.length > 0 ? [
112942
- collapseItems[0].key
112943
- ] : [],
112944
- style: {
112945
- background: "transparent",
112946
- padding: 0,
112947
- margin: 0
112948
- }
112949
- });
112950
- };
112951
112581
  // Extract inputs/outputs for a specific node
112952
112582
  const getNodeInputsOutputs = (node, run)=>{
112953
112583
  if (node.node_type === "Tool") {
@@ -113063,89 +112693,7 @@ const NodeDetailsPanel = ({ selectedNode, session, isDarkMode })=>{
113063
112693
  }
113064
112694
  const { inputs, output, toolOutput, modelProvider, modelName, toolStatusMap } = nodeIO;
113065
112695
  const hasInputs = (node.node_type === "Agent" || node.node_type === "Tool") && inputs.length > 0;
113066
- const hasOutputs = output !== null || toolOutput !== null;
113067
- const outputsText = hasOutputs ? formatOutputAsText(output, toolOutput) : "";
113068
- const isToolOutputTabular = toolOutput !== null && toolOutput !== undefined && isTabularData(toolOutput);
113069
- // For Tool nodes: render input as JSON in a textarea (no nested collapsibles)
113070
112696
  const isToolNode = node.node_type === "Tool";
113071
- const toolInputText = isToolNode && inputs.length > 0 ? renderContent(typeof inputs[0].content === "object" && inputs[0].content !== null && !Array.isArray(inputs[0].content) ? filterKeysWithName(inputs[0].content) : inputs[0].content) : "";
113072
- const collapseItems = [
113073
- {
113074
- key: "inputs",
113075
- label: /*#__PURE__*/ React__default.createElement("div", {
113076
- style: {
113077
- display: "flex",
113078
- alignItems: "center",
113079
- gap: "0.5rem"
113080
- }
113081
- }, /*#__PURE__*/ React__default.createElement(Text, {
113082
- strong: true
113083
- }, "Inputs"), hasInputs && /*#__PURE__*/ React__default.createElement("span", {
113084
- style: {
113085
- display: "inline-flex",
113086
- alignItems: "center",
113087
- gap: "0.25rem",
113088
- color: theme?.colors?.mutedForeground
113089
- }
113090
- }, /*#__PURE__*/ React__default.createElement(MessagesSquare, {
113091
- size: 12
113092
- }), inputs.length)),
113093
- children: hasInputs ? isToolNode ? /*#__PURE__*/ React__default.createElement("textarea", {
113094
- readOnly: true,
113095
- value: toolInputText,
113096
- style: {
113097
- width: "100%",
113098
- minHeight: "200px",
113099
- padding: "12px",
113100
- background: isDarkMode ? "#1f1f1f" : "#fafafa",
113101
- border: `1px solid ${theme?.colors?.border || "#d9d9d9"}`,
113102
- borderRadius: "4px",
113103
- color: theme?.colors?.foreground || "inherit",
113104
- fontFamily: "monospace",
113105
- fontSize: "12px",
113106
- lineHeight: "1.5",
113107
- resize: "vertical"
113108
- }
113109
- }) : /*#__PURE__*/ React__default.createElement(LLMInputsRenderer, {
113110
- input: inputs,
113111
- isDarkMode: isDarkMode,
113112
- modelProvider: modelProvider,
113113
- modelName: modelName,
113114
- toolStatusMap: toolStatusMap
113115
- }) : /*#__PURE__*/ React__default.createElement(Empty, {
113116
- description: "No inputs available"
113117
- })
113118
- },
113119
- {
113120
- key: "outputs",
113121
- label: /*#__PURE__*/ React__default.createElement(Text, {
113122
- strong: true
113123
- }, "Outputs"),
113124
- children: hasOutputs ? isToolOutputTabular ? /*#__PURE__*/ React__default.createElement(JsonValueTree, {
113125
- data: toolOutput
113126
- }) : /*#__PURE__*/ React__default.createElement("pre", {
113127
- style: {
113128
- margin: 0,
113129
- padding: "12px",
113130
- background: isDarkMode ? "#1f1f1f" : "#fafafa",
113131
- border: `1px solid ${theme?.colors?.border || "#d9d9d9"}`,
113132
- borderRadius: "4px",
113133
- color: theme?.colors?.foreground || "inherit",
113134
- whiteSpace: "pre-wrap",
113135
- wordWrap: "break-word",
113136
- fontFamily: "inherit",
113137
- fontSize: "13px",
113138
- lineHeight: "1.5"
113139
- }
113140
- }, outputsText) : /*#__PURE__*/ React__default.createElement("div", {
113141
- style: {
113142
- padding: "12px"
113143
- }
113144
- }, /*#__PURE__*/ React__default.createElement(Empty, {
113145
- description: "No outputs available"
113146
- }))
113147
- }
113148
- ];
113149
112697
  const llmDetails = node.details?.internals?.llm_details || [];
113150
112698
  const totalCost = node.node_type === "Agent" ? sumTotalCost(llmDetails) : 0;
113151
112699
  const totalInputTokens = node.node_type === "Agent" ? sumTotalInputTokens(llmDetails) : 0;
@@ -113202,19 +112750,15 @@ const NodeDetailsPanel = ({ selectedNode, session, isDarkMode })=>{
113202
112750
  }
113203
112751
  }, formatNumberWithCommas(totalInputTokens), " ", /*#__PURE__*/ React__default.createElement(ArrowRight, {
113204
112752
  size: 12
113205
- }), " ", formatNumberWithCommas(totalOutputTokens)))), /*#__PURE__*/ React__default.createElement(Collapse$1, {
113206
- ghost: true,
113207
- bordered: false,
113208
- items: collapseItems,
113209
- defaultActiveKey: [
113210
- "inputs",
113211
- "outputs"
113212
- ],
113213
- style: {
113214
- background: "transparent",
113215
- padding: 0,
113216
- margin: 0
113217
- }
112753
+ }), " ", formatNumberWithCommas(totalOutputTokens)))), /*#__PURE__*/ React__default.createElement(InputsOutputsCollapse, {
112754
+ inputs: inputs,
112755
+ output: output,
112756
+ toolOutput: toolOutput,
112757
+ modelProvider: modelProvider,
112758
+ modelName: modelName,
112759
+ toolStatusMap: toolStatusMap,
112760
+ hasInputs: hasInputs,
112761
+ toolInputAsTextarea: isToolNode
113218
112762
  }));
113219
112763
  };
113220
112764
  // Component for rendering a single run's content
@@ -114664,6 +114208,7 @@ const EvaluationsTable = ({ evaluations, loading = false, error = null, onRefres
114664
114208
  dataIndex: "completed_at",
114665
114209
  key: "completed_at",
114666
114210
  width: 180,
114211
+ defaultSortOrder: "descend",
114667
114212
  sorter: (a, b)=>{
114668
114213
  const aVal = a.completed_at ? moment(a.completed_at).unix() : 0;
114669
114214
  const bVal = b.completed_at ? moment(b.completed_at).unix() : 0;
@@ -120223,4 +119768,4 @@ const GlobalStyles = ()=>{
120223
119768
  return getSafeColor(props.theme, path, fallback);
120224
119769
  };
120225
119770
 
120226
- 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, getSafeColor, getSafeSpacing, getSafeThemeValue, getSpacing, getStatusColor, isEvaluationDto, isPlainObject, lightTheme, safeStyled, safeThemeColor, safeThemeSpacing, safeThemeValue, toTitleCase, transformEvaluation, truncateText, useComponentTheme, useSafeTheme, useTheme$1 as useTheme, useThemeValue };
119771
+ 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 };