@railtownai/railtracks-visualizer 0.0.37 → 0.0.38

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
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import React__default, { memo, useMemo, useState, useCallback, forwardRef, createContext, useContext, useRef, useLayoutEffect, useEffect, createElement } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import * as ReactDOM from 'react-dom';
5
- import ReactDOM__default, { createPortal } from 'react-dom';
5
+ import ReactDOM__default from 'react-dom';
6
6
  import CountUp from 'react-countup';
7
7
 
8
8
  function cc(names) {
@@ -5986,7 +5986,7 @@ function createPanZoomEndHandler({ zoomPanValues, panOnDrag, panOnScroll, onDrag
5986
5986
  return (!event.ctrlKey || isWheelEvent) && buttonAllowed;
5987
5987
  };
5988
5988
  }
5989
- function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onDraggingChange }) {
5989
+ function XYPanZoom({ domNode, minZoom, maxZoom, translateExtent, viewport, onPanZoom, onPanZoomStart, onPanZoomEnd, onDraggingChange }) {
5990
5990
  const zoomPanValues = {
5991
5991
  isZoomingOrPanning: false,
5992
5992
  usedRightMouseButton: false,
@@ -5998,7 +5998,7 @@ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExte
5998
5998
  isPanScrolling: false
5999
5999
  };
6000
6000
  const bbox = domNode.getBoundingClientRect();
6001
- const d3ZoomInstance = zoom().clickDistance(!isNumeric(paneClickDistance) || paneClickDistance < 0 ? 0 : paneClickDistance).scaleExtent([
6001
+ const d3ZoomInstance = zoom().scaleExtent([
6002
6002
  minZoom,
6003
6003
  maxZoom
6004
6004
  ]).translateExtent(translateExtent);
@@ -6029,11 +6029,12 @@ function XYPanZoom({ domNode, minZoom, maxZoom, paneClickDistance, translateExte
6029
6029
  return Promise.resolve(false);
6030
6030
  }
6031
6031
  // public functions
6032
- function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib, onTransformChange, connectionInProgress }) {
6032
+ function update({ noWheelClassName, noPanClassName, onPaneContextMenu, userSelectionActive, panOnScroll, panOnDrag, panOnScrollMode, panOnScrollSpeed, preventScrolling, zoomOnPinch, zoomOnScroll, zoomOnDoubleClick, zoomActivationKeyPressed, lib, onTransformChange, connectionInProgress, paneClickDistance, selectionOnDrag }) {
6033
6033
  if (userSelectionActive && !zoomPanValues.isZoomingOrPanning) {
6034
6034
  destroy();
6035
6035
  }
6036
6036
  const isPanOnScroll = panOnScroll && !zoomActivationKeyPressed && !userSelectionActive;
6037
+ d3ZoomInstance.clickDistance(selectionOnDrag ? Infinity : !isNumeric(paneClickDistance) || paneClickDistance < 0 ? 0 : paneClickDistance);
6037
6038
  const wheelHandler = isPanOnScroll ? createPanOnScrollHandler({
6038
6039
  zoomPanValues,
6039
6040
  noWheelClassName,
@@ -7315,7 +7316,6 @@ const reactFlowFieldsToTrack = [
7315
7316
  'onBeforeDelete',
7316
7317
  'debug',
7317
7318
  'autoPanSpeed',
7318
- 'paneClickDistance',
7319
7319
  'ariaLabelConfig'
7320
7320
  ];
7321
7321
  // rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
@@ -7331,8 +7331,7 @@ const selector$l = (s)=>({
7331
7331
  setTranslateExtent: s.setTranslateExtent,
7332
7332
  setNodeExtent: s.setNodeExtent,
7333
7333
  reset: s.reset,
7334
- setDefaultNodesAndEdges: s.setDefaultNodesAndEdges,
7335
- setPaneClickDistance: s.setPaneClickDistance
7334
+ setDefaultNodesAndEdges: s.setDefaultNodesAndEdges
7336
7335
  });
7337
7336
  const initPrevValues = {
7338
7337
  /*
@@ -7345,11 +7344,10 @@ const initPrevValues = {
7345
7344
  maxZoom: 2,
7346
7345
  elementsSelectable: true,
7347
7346
  noPanClassName: 'nopan',
7348
- rfId: '1',
7349
- paneClickDistance: 0
7347
+ rfId: '1'
7350
7348
  };
7351
7349
  function StoreUpdater(props) {
7352
- const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, setPaneClickDistance } = useStore(selector$l, shallow$1);
7350
+ const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges } = useStore(selector$l, shallow$1);
7353
7351
  const store = useStoreApi();
7354
7352
  useEffect(()=>{
7355
7353
  setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges);
@@ -7373,7 +7371,6 @@ function StoreUpdater(props) {
7373
7371
  else if (fieldName === 'maxZoom') setMaxZoom(fieldValue);
7374
7372
  else if (fieldName === 'translateExtent') setTranslateExtent(fieldValue);
7375
7373
  else if (fieldName === 'nodeExtent') setNodeExtent(fieldValue);
7376
- else if (fieldName === 'paneClickDistance') setPaneClickDistance(fieldValue);
7377
7374
  else if (fieldName === 'ariaLabelConfig') store.setState({
7378
7375
  ariaLabelConfig: mergeAriaLabelConfig(fieldValue)
7379
7376
  });
@@ -8435,7 +8432,7 @@ const selector$j = (s)=>({
8435
8432
  lib: s.lib,
8436
8433
  connectionInProgress: s.connection.inProgress
8437
8434
  });
8438
- function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, paneClickDistance }) {
8435
+ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, paneClickDistance, selectionOnDrag }) {
8439
8436
  const store = useStoreApi();
8440
8437
  const zoomPane = useRef(null);
8441
8438
  const { userSelectionActive, lib, connectionInProgress } = useStore(selector$j, shallow$1);
@@ -8465,7 +8462,6 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8465
8462
  maxZoom,
8466
8463
  translateExtent,
8467
8464
  viewport: defaultViewport,
8468
- paneClickDistance,
8469
8465
  onDraggingChange: (paneDragging)=>store.setState({
8470
8466
  paneDragging
8471
8467
  }),
@@ -8517,7 +8513,9 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8517
8513
  noWheelClassName,
8518
8514
  lib,
8519
8515
  onTransformChange,
8520
- connectionInProgress
8516
+ connectionInProgress,
8517
+ selectionOnDrag,
8518
+ paneClickDistance
8521
8519
  });
8522
8520
  }, [
8523
8521
  onPaneContextMenu,
@@ -8535,7 +8533,9 @@ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
8535
8533
  noWheelClassName,
8536
8534
  lib,
8537
8535
  onTransformChange,
8538
- connectionInProgress
8536
+ connectionInProgress,
8537
+ selectionOnDrag,
8538
+ paneClickDistance
8539
8539
  ]);
8540
8540
  return jsx("div", {
8541
8541
  className: "react-flow__renderer",
@@ -8577,17 +8577,16 @@ const selector$h = (s)=>({
8577
8577
  connectionInProgress: s.connection.inProgress,
8578
8578
  dragging: s.paneDragging
8579
8579
  });
8580
- function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.Full, panOnDrag, selectionOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children }) {
8580
+ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.Full, panOnDrag, paneClickDistance, selectionOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children }) {
8581
8581
  const store = useStoreApi();
8582
8582
  const { userSelectionActive, elementsSelectable, dragging, connectionInProgress } = useStore(selector$h, shallow$1);
8583
- const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
8583
+ const isSelectionEnabled = elementsSelectable && (isSelecting || userSelectionActive);
8584
8584
  const container = useRef(null);
8585
8585
  const containerBounds = useRef();
8586
8586
  const selectedNodeIds = useRef(new Set());
8587
8587
  const selectedEdgeIds = useRef(new Set());
8588
8588
  // Used to prevent click events when the user lets go of the selectionKey during a selection
8589
8589
  const selectionInProgress = useRef(false);
8590
- const selectionStarted = useRef(false);
8591
8590
  const onClick = (event)=>{
8592
8591
  // We prevent click events when the user let go of the selectionKey during a selection
8593
8592
  // We also prevent click events when a connection is in progress
@@ -8610,29 +8609,27 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8610
8609
  };
8611
8610
  const onWheel = onPaneScroll ? (event)=>onPaneScroll(event) : undefined;
8612
8611
  const onClickCapture = (event)=>{
8613
- const isSelectionOnDragActive = selectionOnDrag && container.current === event.target || !selectionOnDrag || selectionKeyPressed;
8614
- if (!isSelectionOnDragActive) {
8615
- return;
8612
+ if (selectionInProgress.current) {
8613
+ event.stopPropagation();
8614
+ selectionInProgress.current = false;
8616
8615
  }
8617
- event.stopPropagation();
8618
8616
  };
8619
8617
  // We are using capture here in order to prevent other pointer events
8620
8618
  // to be able to create a selection above a node or an edge
8621
8619
  const onPointerDownCapture = (event)=>{
8622
- const { resetSelectedElements, domNode } = store.getState();
8620
+ const { domNode } = store.getState();
8623
8621
  containerBounds.current = domNode?.getBoundingClientRect();
8624
- const isNoKeyEvent = event.target !== container.current && !!event.target.closest('.nokey');
8625
- const isSelectionActive = selectionOnDrag && container.current === event.target || !selectionOnDrag || selectionKeyPressed;
8626
- if (!elementsSelectable || !isSelecting || event.button !== 0 || !containerBounds.current || isNoKeyEvent || !isSelectionActive || !event.isPrimary) {
8622
+ if (!containerBounds.current) return;
8623
+ const eventTargetIsContainer = event.target === container.current;
8624
+ // if a child element has the 'nokey' class, we don't want to swallow the event and don't start a selection
8625
+ const isNoKeyEvent = !eventTargetIsContainer && !!event.target.closest('.nokey');
8626
+ const isSelectionActive = selectionOnDrag && eventTargetIsContainer || selectionKeyPressed;
8627
+ if (isNoKeyEvent || !isSelecting || !isSelectionActive || event.button !== 0 || !event.isPrimary) {
8627
8628
  return;
8628
8629
  }
8629
- event.stopPropagation();
8630
- event.preventDefault();
8631
8630
  event.target?.setPointerCapture?.(event.pointerId);
8632
- selectionStarted.current = true;
8633
8631
  selectionInProgress.current = false;
8634
8632
  const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current);
8635
- resetSelectedElements();
8636
8633
  store.setState({
8637
8634
  userSelectionRect: {
8638
8635
  width: 0,
@@ -8643,16 +8640,28 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8643
8640
  y
8644
8641
  }
8645
8642
  });
8646
- onSelectionStart?.(event);
8643
+ if (!eventTargetIsContainer) {
8644
+ event.stopPropagation();
8645
+ event.preventDefault();
8646
+ }
8647
8647
  };
8648
8648
  const onPointerMove = (event)=>{
8649
- const { userSelectionRect, transform, nodeLookup, edgeLookup, connectionLookup, triggerNodeChanges, triggerEdgeChanges, defaultEdgeOptions } = store.getState();
8649
+ const { userSelectionRect, transform, nodeLookup, edgeLookup, connectionLookup, triggerNodeChanges, triggerEdgeChanges, defaultEdgeOptions, resetSelectedElements } = store.getState();
8650
8650
  if (!containerBounds.current || !userSelectionRect) {
8651
8651
  return;
8652
8652
  }
8653
- selectionInProgress.current = true;
8654
8653
  const { x: mouseX, y: mouseY } = getEventPosition(event.nativeEvent, containerBounds.current);
8655
8654
  const { startX, startY } = userSelectionRect;
8655
+ if (!selectionInProgress.current) {
8656
+ const requiredDistance = selectionKeyPressed ? 0 : paneClickDistance;
8657
+ const distance = Math.hypot(mouseX - startX, mouseY - startY);
8658
+ if (distance <= requiredDistance) {
8659
+ return;
8660
+ }
8661
+ resetSelectedElements();
8662
+ onSelectionStart?.(event);
8663
+ }
8664
+ selectionInProgress.current = true;
8656
8665
  const nextUserSelectRect = {
8657
8666
  startX,
8658
8667
  startY,
@@ -8692,30 +8701,26 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8692
8701
  });
8693
8702
  };
8694
8703
  const onPointerUp = (event)=>{
8695
- if (event.button !== 0 || !selectionStarted.current) {
8704
+ if (event.button !== 0) {
8696
8705
  return;
8697
8706
  }
8698
8707
  event.target?.releasePointerCapture?.(event.pointerId);
8699
- const { userSelectionRect } = store.getState();
8700
8708
  /*
8701
8709
  * We only want to trigger click functions when in selection mode if
8702
8710
  * the user did not move the mouse.
8703
- */ if (!userSelectionActive && userSelectionRect && event.target === container.current) {
8711
+ */ if (!userSelectionActive && event.target === container.current && store.getState().userSelectionRect) {
8704
8712
  onClick?.(event);
8705
8713
  }
8706
8714
  store.setState({
8707
8715
  userSelectionActive: false,
8708
- userSelectionRect: null,
8709
- nodesSelectionActive: selectedNodeIds.current.size > 0
8716
+ userSelectionRect: null
8710
8717
  });
8711
- onSelectionEnd?.(event);
8712
- /*
8713
- * If the user kept holding the selectionKey during the selection,
8714
- * we need to reset the selectionInProgress, so the next click event is not prevented
8715
- */ if (selectionKeyPressed || selectionOnDrag) {
8716
- selectionInProgress.current = false;
8718
+ if (selectionInProgress.current) {
8719
+ onSelectionEnd?.(event);
8720
+ store.setState({
8721
+ nodesSelectionActive: selectedNodeIds.current.size > 0
8722
+ });
8717
8723
  }
8718
- selectionStarted.current = false;
8719
8724
  };
8720
8725
  const draggable = panOnDrag === true || Array.isArray(panOnDrag) && panOnDrag.includes(0);
8721
8726
  return jsxs("div", {
@@ -8727,14 +8732,14 @@ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.
8727
8732
  selection: isSelecting
8728
8733
  }
8729
8734
  ]),
8730
- onClick: hasActiveSelection ? undefined : wrapHandler(onClick, container),
8735
+ onClick: isSelectionEnabled ? undefined : wrapHandler(onClick, container),
8731
8736
  onContextMenu: wrapHandler(onContextMenu, container),
8732
8737
  onWheel: wrapHandler(onWheel, container),
8733
- onPointerEnter: hasActiveSelection ? undefined : onPaneMouseEnter,
8734
- onPointerMove: hasActiveSelection ? onPointerMove : onPaneMouseMove,
8735
- onPointerUp: hasActiveSelection ? onPointerUp : undefined,
8736
- onPointerDownCapture: hasActiveSelection ? onPointerDownCapture : undefined,
8737
- onClickCapture: hasActiveSelection ? onClickCapture : undefined,
8738
+ onPointerEnter: isSelectionEnabled ? undefined : onPaneMouseEnter,
8739
+ onPointerMove: isSelectionEnabled ? onPointerMove : onPaneMouseMove,
8740
+ onPointerUp: isSelectionEnabled ? onPointerUp : undefined,
8741
+ onPointerDownCapture: isSelectionEnabled ? onPointerDownCapture : undefined,
8742
+ onClickCapture: isSelectionEnabled ? onClickCapture : undefined,
8738
8743
  onPointerLeave: onPaneMouseLeave,
8739
8744
  ref: container,
8740
8745
  style: containerStyle,
@@ -9284,6 +9289,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
9284
9289
  onViewportChange: onViewportChange,
9285
9290
  isControlledViewport: isControlledViewport,
9286
9291
  paneClickDistance: paneClickDistance,
9292
+ selectionOnDrag: _selectionOnDrag,
9287
9293
  children: jsxs(Pane, {
9288
9294
  onSelectionStart: onSelectionStart,
9289
9295
  onSelectionEnd: onSelectionEnd,
@@ -9297,6 +9303,7 @@ function FlowRendererComponent({ children, onPaneClick, onPaneMouseEnter, onPane
9297
9303
  isSelecting: !!isSelecting,
9298
9304
  selectionMode: selectionMode,
9299
9305
  selectionKeyPressed: selectionKeyPressed,
9306
+ paneClickDistance: paneClickDistance,
9300
9307
  selectionOnDrag: _selectionOnDrag,
9301
9308
  children: [
9302
9309
  children,
@@ -11379,9 +11386,6 @@ const createStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height,
11379
11386
  translateExtent
11380
11387
  });
11381
11388
  },
11382
- setPaneClickDistance: (clickDistance)=>{
11383
- get().panZoom?.setClickDistance(clickDistance);
11384
- },
11385
11389
  resetSelectedElements: ()=>{
11386
11390
  const { edges, nodes, triggerNodeChanges, triggerEdgeChanges, elementsSelectable } = get();
11387
11391
  if (!elementsSelectable) {
@@ -11710,7 +11714,6 @@ function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTy
11710
11714
  nodeDragThreshold: nodeDragThreshold,
11711
11715
  connectionDragThreshold: connectionDragThreshold,
11712
11716
  onBeforeDelete: onBeforeDelete,
11713
- paneClickDistance: paneClickDistance,
11714
11717
  debug: debug,
11715
11718
  ariaLabelConfig: ariaLabelConfig
11716
11719
  }),
@@ -12676,7 +12679,7 @@ var css_248z = "/* this gets exported as style.css and can be used for the defau
12676
12679
  styleInject(css_248z);
12677
12680
 
12678
12681
  /**
12679
- * @license lucide-react v0.546.0 - ISC
12682
+ * @license lucide-react v0.553.0 - ISC
12680
12683
  *
12681
12684
  * This source code is licensed under the ISC license.
12682
12685
  * See the LICENSE file in the root directory of this source tree.
@@ -12698,7 +12701,7 @@ const hasA11yProp = (props)=>{
12698
12701
  };
12699
12702
 
12700
12703
  /**
12701
- * @license lucide-react v0.546.0 - ISC
12704
+ * @license lucide-react v0.553.0 - ISC
12702
12705
  *
12703
12706
  * This source code is licensed under the ISC license.
12704
12707
  * See the LICENSE file in the root directory of this source tree.
@@ -15781,6 +15784,8 @@ const Label$1 = styled.span`
15781
15784
  `;
15782
15785
  const Value$1 = styled.span`
15783
15786
  font-size: 0.75rem;
15787
+ overflow-wrap: break-word;
15788
+ word-wrap: break-word;
15784
15789
  color: ${(props)=>props.themeColors.primary};
15785
15790
  `;
15786
15791
  const EmptyIndicator = styled.span`
@@ -15800,8 +15805,8 @@ const TreeContainer = styled.div`
15800
15805
  `;
15801
15806
  const TreeScrollContainer = styled.div`
15802
15807
  width: 100%;
15803
- max-height: 16rem;
15804
15808
  overflow-y: auto;
15809
+ max-height: 16rem;
15805
15810
  padding: 0.5rem;
15806
15811
  `;
15807
15812
  const NoDataMessage = styled.div`
@@ -15822,7 +15827,8 @@ const SimpleValueContainer = styled.div`
15822
15827
  border: 1px solid ${(props)=>props.themeColors.border};
15823
15828
  font-size: 0.75rem;
15824
15829
  color: ${(props)=>props.themeColors.foreground};
15825
- word-break: break-all;
15830
+ overflow-wrap: break-word;
15831
+ word-wrap: break-word;
15826
15832
  `;
15827
15833
  styled.div`
15828
15834
  width: 100%;
@@ -15842,6 +15848,8 @@ const SimpleValueLabel = styled.span`
15842
15848
  `;
15843
15849
  const SimpleValueText = styled.span`
15844
15850
  color: ${(props)=>props.themeColors.foreground};
15851
+ word-wrap: break-word;
15852
+ overflow-wrap: break-word;
15845
15853
  font-size: 0.875rem;
15846
15854
  `;
15847
15855
  const EmptyStateContainer = styled.div`
@@ -16011,6 +16019,8 @@ const JsonTreeViewer = ({ data, maxDepth = 4, initialExpanded = false, expanded
16011
16019
  })()));
16012
16020
  };
16013
16021
 
16022
+ const NODE_MAX_WIDTH = 500;
16023
+
16014
16024
  const OutputRenderer = ({ data })=>{
16015
16025
  const [isExpanded, setIsExpanded] = useState(false);
16016
16026
  const contentType = detectContentType(data);
@@ -16019,20 +16029,26 @@ const OutputRenderer = ({ data })=>{
16019
16029
  };
16020
16030
  switch(contentType){
16021
16031
  case "string":
16022
- return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, null, /*#__PURE__*/ React__default.createElement(ExpandableTextarea, {
16032
+ return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
16033
+ className: "agent-node-scrollable"
16034
+ }, /*#__PURE__*/ React__default.createElement(ExpandableTextarea, {
16023
16035
  label: "Output",
16024
16036
  content: data.content,
16025
16037
  isExpanded: isExpanded,
16026
16038
  onToggle: handleToggle
16027
16039
  }));
16028
16040
  case "toolResponse":
16029
- return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, null, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, "Output - Tool Response"), /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
16041
+ return /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
16042
+ className: "agent-node-scrollable"
16043
+ }, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, "Output - Tool Response"), /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
16030
16044
  data: data,
16031
16045
  expanded: true
16032
16046
  }));
16033
16047
  case "toolCallList":
16034
16048
  const formattedCode = formatToolCalls(data.content);
16035
- return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(OutputScrollableContent, null, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, /*#__PURE__*/ React__default.createElement("span", null, "Output - Tool Calls"), /*#__PURE__*/ React__default.createElement("span", {
16049
+ return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(OutputScrollableContent, {
16050
+ className: "agent-node-scrollable"
16051
+ }, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, /*#__PURE__*/ React__default.createElement("span", null, "Output - Tool Calls"), /*#__PURE__*/ React__default.createElement("span", {
16036
16052
  style: {
16037
16053
  display: "flex",
16038
16054
  alignItems: "center",
@@ -16047,7 +16063,7 @@ const OutputRenderer = ({ data })=>{
16047
16063
  })));
16048
16064
  case "other":
16049
16065
  default:
16050
- return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(OutputScrollableContent, null, /*#__PURE__*/ React__default.createElement(NodeSubHeader, null, "Output"), /*#__PURE__*/ React__default.createElement(JsonTreeViewer, {
16066
+ 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, {
16051
16067
  data: data,
16052
16068
  expanded: true
16053
16069
  })));
@@ -16070,12 +16086,13 @@ const NodeSubHeader = styled.span`
16070
16086
  `;
16071
16087
  const OutputScrollableContent = styled.div`
16072
16088
  width: 100%;
16089
+ max-width: ${NODE_MAX_WIDTH}px;
16073
16090
  display: flex;
16074
16091
  flex-direction: column;
16092
+ align-items: stretch;
16075
16093
  padding-bottom: 0.5rem;
16094
+ padding-right: 2px;
16076
16095
  gap: 0.5rem;
16077
- max-height: 200px;
16078
- overflow-y: auto;
16079
16096
  `;
16080
16097
 
16081
16098
  function _objectWithoutPropertiesLoose(r, e) {
@@ -16387,7 +16404,9 @@ const InputArrayRenderer = ({ input })=>{
16387
16404
  }
16388
16405
  }, /*#__PURE__*/ React__default.createElement(MessageSquare, {
16389
16406
  size: 12
16390
- }), input.length)), /*#__PURE__*/ React__default.createElement(InputArrayScrollableContent, null, input.map((item, index)=>/*#__PURE__*/ React__default.createElement(InputItem, {
16407
+ }), input.length)), /*#__PURE__*/ React__default.createElement(InputArrayScrollableContent, {
16408
+ className: "agent-node-scrollable"
16409
+ }, input.map((item, index)=>/*#__PURE__*/ React__default.createElement(InputItem, {
16391
16410
  key: index
16392
16411
  }, /*#__PURE__*/ React__default.createElement(InputItemHeader, null, /*#__PURE__*/ React__default.createElement(InputItemLabel, null, getRoleEmoji(item.role), " ", getRoleDisplayName(item.role))), /*#__PURE__*/ React__default.createElement(InputItemTextarea, {
16393
16412
  onClick: (e)=>{
@@ -16399,7 +16418,8 @@ const InputArrayRenderer = ({ input })=>{
16399
16418
  border: `1px solid ${themeColors.border}`,
16400
16419
  backgroundColor: themeColors.muted,
16401
16420
  color: themeColors.foreground
16402
- }
16421
+ },
16422
+ className: "agent-node-scrollable"
16403
16423
  })))));
16404
16424
  };
16405
16425
  // Styled components
@@ -16414,6 +16434,7 @@ const InputArrayScrollableContent = styled.div`
16414
16434
  display: flex;
16415
16435
  flex-direction: column;
16416
16436
  padding-bottom: 0.5rem;
16437
+ padding-right: 2px;
16417
16438
  gap: 0.5rem;
16418
16439
  max-height: 200px;
16419
16440
  overflow-y: auto;
@@ -16543,12 +16564,7 @@ const getNodeIcon$1 = (nodeType, modelProvider)=>{
16543
16564
  }
16544
16565
  return "🤖";
16545
16566
  };
16546
- const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16547
- const [position, setPosition] = useState({
16548
- top: 0,
16549
- left: 0,
16550
- arrowPosition: "right"
16551
- });
16567
+ const NodeDetailsPopover = ({ isVisible, onClose, nodeData })=>{
16552
16568
  const [selectedRowIndex, setSelectedRowIndex] = useState(null);
16553
16569
  const [selectedLlmDetails, setSelectedLlmDetails] = useState(null);
16554
16570
  // Default to last row (total/aggregate) when popover opens (only on first open)
@@ -16573,54 +16589,6 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16573
16589
  setSelectedLlmDetails(nodeData.details.internals.llm_details[nodeData.details.internals.llm_details.length]);
16574
16590
  }
16575
16591
  };
16576
- // Calculate popover position based on trigger element
16577
- useEffect(()=>{
16578
- if (isVisible && triggerRef.current) {
16579
- const rect = triggerRef.current.getBoundingClientRect();
16580
- const viewportWidth = window.innerWidth;
16581
- const viewportHeight = window.innerHeight;
16582
- const popoverWidth = DEFAULT_POPOVER_WIDTH; // Match the width from styled component
16583
- const popoverHeight = DEFAULT_POPOVER_HEIGHT; // Approximate max height
16584
- const gap = 12; // Gap between node and popover
16585
- // Check if the rect is valid (has non-zero dimensions and is in viewport)
16586
- const isValidRect = rect.width > 0 && rect.height > 0 && rect.top >= 0 && rect.left >= 0;
16587
- if (isValidRect) {
16588
- // Normal positioning logic for ReactFlow
16589
- let left = rect.right + gap;
16590
- let top = rect.top;
16591
- let arrowPosition = "right"; // Arrow points right (popover is to the right)
16592
- // If popover would go off-screen, position it to the left of the node
16593
- if (left + popoverWidth > viewportWidth) {
16594
- left = rect.left - popoverWidth - gap;
16595
- arrowPosition = "left"; // Arrow points left (popover is to the left)
16596
- }
16597
- // Ensure popover doesn't go off the top or bottom of the viewport
16598
- if (top < 0) {
16599
- top = 20; // Small margin from top
16600
- } else if (top + popoverHeight > viewportHeight) {
16601
- top = viewportHeight - popoverHeight - 20; // Small margin from bottom
16602
- }
16603
- setPosition({
16604
- top,
16605
- left,
16606
- arrowPosition
16607
- });
16608
- } else {
16609
- // Fallback positioning for isolated environments (like Storybook)
16610
- // Center the popover in the viewport
16611
- const centerLeft = Math.max(20, (viewportWidth - popoverWidth) / 2);
16612
- const centerTop = Math.max(20, (viewportHeight - popoverHeight) / 2);
16613
- setPosition({
16614
- top: centerTop,
16615
- left: centerLeft,
16616
- arrowPosition: "none" // No arrow in fallback mode
16617
- });
16618
- }
16619
- }
16620
- }, [
16621
- isVisible,
16622
- triggerRef
16623
- ]);
16624
16592
  // Handle ESC key to close popover
16625
16593
  useEffect(()=>{
16626
16594
  const handleEscKey = (event)=>{
@@ -16646,7 +16614,7 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16646
16614
  // Handle click outside to close popover
16647
16615
  useEffect(()=>{
16648
16616
  const handleClickOutside = (event)=>{
16649
- if (isVisible && triggerRef.current && !triggerRef.current.contains(event.target) && !event.target.closest("[data-popover-content]")) {
16617
+ if (isVisible && !event.target.closest("[data-popover-content]") && !event.target.closest(".react-flow__node")) {
16650
16618
  onClose();
16651
16619
  }
16652
16620
  };
@@ -16656,8 +16624,7 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16656
16624
  }
16657
16625
  }, [
16658
16626
  isVisible,
16659
- onClose,
16660
- triggerRef
16627
+ onClose
16661
16628
  ]);
16662
16629
  if (!isVisible) return null;
16663
16630
  const llOverviewDetails = getOverviewLlmDetails(nodeData.details?.internals?.llm_details || []);
@@ -16665,16 +16632,14 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16665
16632
  const totalInputTokens = sumTotalInputTokens(nodeData.details?.internals?.llm_details || []);
16666
16633
  const totalOutputTokens = sumTotalOutputTokens(nodeData.details?.internals?.llm_details || []);
16667
16634
  const totalLatency = sumTotalLatency(nodeData.details?.internals?.llm_details || []);
16668
- const popoverContent = /*#__PURE__*/ React__default.createElement(PopoverPortal, {
16669
- style: {
16670
- top: position.top,
16671
- left: position.left
16672
- }
16673
- }, /*#__PURE__*/ React__default.createElement(PopoverContent, {
16635
+ const popoverContent = /*#__PURE__*/ React__default.createElement(PopoverPortal, null, /*#__PURE__*/ React__default.createElement(PopoverContent, {
16674
16636
  "data-popover-content": true,
16675
- $arrowPosition: position.arrowPosition
16637
+ $arrowPosition: "left"
16676
16638
  }, /*#__PURE__*/ React__default.createElement(PopoverHeader, null, /*#__PURE__*/ React__default.createElement(PopoverTitle, null, /*#__PURE__*/ React__default.createElement(NodeIcon$3, null, getNodeIcon$1(nodeData.nodeType || "Agent", llOverviewDetails?.model_provider)), /*#__PURE__*/ React__default.createElement("span", null, nodeData.label, " Details")), /*#__PURE__*/ React__default.createElement(PopoverHeaderButtons, null, /*#__PURE__*/ React__default.createElement(CloseButton, {
16677
- onClick: onClose
16639
+ onClick: (e)=>{
16640
+ e.stopPropagation();
16641
+ onClose();
16642
+ }
16678
16643
  }, /*#__PURE__*/ React__default.createElement(X, {
16679
16644
  size: 16
16680
16645
  })))), /*#__PURE__*/ React__default.createElement(PopoverBody, null, llOverviewDetails && /*#__PURE__*/ React__default.createElement(Section, null, /*#__PURE__*/ React__default.createElement(InfoGrid, null, (()=>{
@@ -16818,14 +16783,20 @@ const NodeDetailsPopover = ({ isVisible, onClose, nodeData, triggerRef })=>{
16818
16783
  }), /*#__PURE__*/ React__default.createElement(OutputRenderer, {
16819
16784
  data: selectedLlmDetails.output
16820
16785
  })) : null))));
16821
- // Use React Portal to render outside of ReactFlow container
16822
- return /*#__PURE__*/ createPortal(popoverContent, document.body);
16786
+ return popoverContent;
16823
16787
  };
16824
16788
  // Styled components
16825
16789
  const PopoverPortal = styled.div`
16826
- position: fixed;
16790
+ position: absolute;
16791
+ left: calc(100% + 12px);
16792
+ top: 0;
16827
16793
  z-index: 99999;
16828
- pointer-events: none;
16794
+
16795
+ /* Position to the left of the node if there's not enough space on the right */
16796
+ @media (max-width: 768px) {
16797
+ left: auto;
16798
+ right: calc(100% + 12px);
16799
+ }
16829
16800
  `;
16830
16801
  const PopoverContent = styled.div`
16831
16802
  width: ${DEFAULT_POPOVER_WIDTH}px;
@@ -16861,7 +16832,7 @@ const PopoverContent = styled.div`
16861
16832
  height: 0;
16862
16833
  border-top: 6px solid transparent;
16863
16834
  border-bottom: 6px solid transparent;
16864
- ${props.$arrowPosition === "right" ? `
16835
+ ${props.$arrowPosition === "left" ? `
16865
16836
  left: -6px;
16866
16837
  border-right: 6px solid ${props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
16867
16838
  ` : `
@@ -16878,7 +16849,7 @@ const PopoverContent = styled.div`
16878
16849
  height: 0;
16879
16850
  border-top: 6px solid transparent;
16880
16851
  border-bottom: 6px solid transparent;
16881
- ${props.$arrowPosition === "right" ? `
16852
+ ${props.$arrowPosition === "left" ? `
16882
16853
  left: -5px;
16883
16854
  border-right: 6px solid ${props.theme?.colors?.background || "hsl(0 0% 100%)"};
16884
16855
  ` : `
@@ -16959,7 +16930,7 @@ const PopoverHeaderButtons = styled.div`
16959
16930
  display: flex;
16960
16931
  align-items: center;
16961
16932
  gap: 0.5rem;
16962
- justify-content: flex-start;
16933
+ justify-content: flex-end;
16963
16934
  `;
16964
16935
  const CloseButton = styled.button`
16965
16936
  display: flex;
@@ -16973,6 +16944,8 @@ const CloseButton = styled.button`
16973
16944
  color: ${(props)=>props.theme?.colors?.mutedForeground || "hsl(215.4 16.3% 46.9%)"};
16974
16945
  cursor: pointer;
16975
16946
  transition: all 0.2s ease-in-out;
16947
+ pointer-events: auto;
16948
+ flex-shrink: 0;
16976
16949
 
16977
16950
  &:hover {
16978
16951
  background-color: ${(props)=>props.theme?.colors?.muted || "hsl(210 40% 96%)"};
@@ -16983,9 +16956,13 @@ const CloseButton = styled.button`
16983
16956
  outline: 2px solid ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
16984
16957
  outline-offset: 2px;
16985
16958
  }
16959
+
16960
+ &:active {
16961
+ transform: scale(0.95);
16962
+ }
16986
16963
  `;
16987
16964
  const PopoverBody = styled.div`
16988
- max-height: 500px;
16965
+ max-height: 400px; /* Reduced by 100px to account for PopoverHeader and spacing */
16989
16966
  overflow-y: auto;
16990
16967
  padding: 1rem;
16991
16968
  display: flex;
@@ -16998,6 +16975,7 @@ const Section = styled.div`
16998
16975
  gap: 0.75rem;
16999
16976
  `;
17000
16977
  const FadingSection = styled(Section)`
16978
+ overflow-y: auto; /* Base style: enables scrolling after animation completes */
17001
16979
  animation:
17002
16980
  expandHeight 300ms ease-out,
17003
16981
  fadeInContent 200ms ease-in-out 200ms both;
@@ -17008,8 +16986,8 @@ const FadingSection = styled(Section)`
17008
16986
  overflow: hidden;
17009
16987
  }
17010
16988
  to {
17011
- max-height: 500px; /* Adjust based on expected content height */
17012
- overflow: visible;
16989
+ max-height: 350px; /* Reduced to fit within PopoverBody (400px) accounting for padding and gaps */
16990
+ overflow: hidden; /* Keep hidden during animation, base overflow-y: auto takes effect after */
17013
16991
  }
17014
16992
  }
17015
16993
 
@@ -17118,7 +17096,7 @@ const AgentNode = ({ data, id, onInspect })=>{
17118
17096
  return /*#__PURE__*/ React__default.createElement(React__default.Fragment, null, /*#__PURE__*/ React__default.createElement(NodeContainer$2, {
17119
17097
  ref: nodeRef,
17120
17098
  onClick: handleNodeClick,
17121
- className: "nowheel"
17099
+ className: "nowheel agent-node"
17122
17100
  }, hasIncomingEdges && /*#__PURE__*/ React__default.createElement(Handle$1, {
17123
17101
  type: "target",
17124
17102
  position: Position.Top,
@@ -17151,15 +17129,14 @@ const AgentNode = ({ data, id, onInspect })=>{
17151
17129
  cursor: "default"
17152
17130
  },
17153
17131
  isConnectable: false
17154
- })), /*#__PURE__*/ React__default.createElement(NodeDetailsPopover, {
17132
+ }), /*#__PURE__*/ React__default.createElement(NodeDetailsPopover, {
17155
17133
  isVisible: isPopoverOpen,
17156
17134
  onClose: handleClosePopover,
17157
17135
  nodeData: {
17158
17136
  ...data,
17159
17137
  id: id
17160
- },
17161
- triggerRef: nodeRef
17162
- }));
17138
+ }
17139
+ })));
17163
17140
  };
17164
17141
  // Styled components
17165
17142
  const NodeContainer$2 = styled.div`
@@ -17168,9 +17145,9 @@ const NodeContainer$2 = styled.div`
17168
17145
  border: 2px solid ${(props)=>props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
17169
17146
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
17170
17147
  min-width: 300px;
17148
+ max-width: ${NODE_MAX_WIDTH}px;
17171
17149
  transition: all 0.2s ease-in-out;
17172
17150
  position: relative;
17173
- cursor: pointer;
17174
17151
 
17175
17152
  &:hover {
17176
17153
  border-color: ${(props)=>props.theme?.colors?.primary || "hsl(221.2 83.2% 53.3%)"};
@@ -17351,15 +17328,15 @@ const ToolNode = ({ data, id, onInspect })=>{
17351
17328
  nodeData = {
17352
17329
  ...baseData,
17353
17330
  input: {
17354
- args: data.edgeDetails[0]?.input_args,
17355
- kwargs: data.edgeDetails[0]?.input_kwargs
17331
+ ...data.edgeDetails[0]?.input_kwargs
17356
17332
  },
17357
17333
  output: data.edgeDetails[0]?.output,
17358
17334
  status: data.edgeDetails[0]?.status
17359
17335
  };
17360
17336
  }
17361
17337
  return /*#__PURE__*/ React__default.createElement(NodeContainer, {
17362
- onClick: handleNodeClick
17338
+ onClick: handleNodeClick,
17339
+ className: "nowheel"
17363
17340
  }, hasIncomingEdges && /*#__PURE__*/ React__default.createElement(Handle$1, {
17364
17341
  type: "target",
17365
17342
  position: Position.Top,
@@ -17400,6 +17377,7 @@ const NodeContainer = styled.div`
17400
17377
  border: 2px solid ${(props)=>props.theme?.colors?.border || "hsl(214.3 31.8% 91.4%)"};
17401
17378
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
17402
17379
  min-width: 300px;
17380
+ max-width: ${NODE_MAX_WIDTH}px;
17403
17381
  transition: all 0.2s ease-in-out;
17404
17382
  position: relative;
17405
17383
  cursor: pointer;
@@ -20671,7 +20649,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20671
20649
  ]);
20672
20650
  // Pan to specific node when panToNodeId prop is provided
20673
20651
  useEffect(()=>{
20674
- if (!panToNodeId || !reactFlowInstance || disableAutoFit || nodes.length === 0) {
20652
+ if (!panToNodeId || !reactFlowInstance || nodes.length === 0) {
20675
20653
  return;
20676
20654
  }
20677
20655
  // Check if the specified node ID exists in the current nodes array
@@ -20696,7 +20674,6 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20696
20674
  }, [
20697
20675
  panToNodeId,
20698
20676
  reactFlowInstance,
20699
- disableAutoFit,
20700
20677
  nodes,
20701
20678
  defaultAutoFitDuration,
20702
20679
  defaultAutoFitDelay,
@@ -20832,6 +20809,7 @@ const AgenticFlowVisualizer = ({ flowData: propFlowData, width = "100dvw", heigh
20832
20809
  colorMode: isDarkMode ? "dark" : "light",
20833
20810
  nodes: nodesState,
20834
20811
  edges: edgesState,
20812
+ minZoom: 0.2,
20835
20813
  onNodesChange: onNodesChange,
20836
20814
  onEdgesChange: onEdgesChange,
20837
20815
  onConnect: onConnect,