From 96d245c72a68a9d1b80a365dbe15f8b9a2f443bf Mon Sep 17 00:00:00 2001 From: DarkSkyXD Date: Wed, 25 Mar 2026 16:17:52 -0500 Subject: [PATCH] fix: resolve memory graph hover highlight and click detection on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nodeReducer captured hoveredNode state in a closure at Sigma creation time, so it was always null — preventing fade/highlight effects. Fixed by using a ref that stays in sync with state. Also fixed the Sigma container positioning so its canvas properly receives pointer events above the stacking context. Co-Authored-By: Claude Opus 4.6 (1M context) --- interface/src/components/MemoryGraph.tsx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/interface/src/components/MemoryGraph.tsx b/interface/src/components/MemoryGraph.tsx index 14082d5f8..4f62e34db 100644 --- a/interface/src/components/MemoryGraph.tsx +++ b/interface/src/components/MemoryGraph.tsx @@ -64,6 +64,7 @@ export function MemoryGraph({ agentId, sort, typeFilter }: MemoryGraphProps) { const [edgeCount, setEdgeCount] = useState(0); const [selectedNode, setSelectedNode] = useState(null); const [hoveredNode, setHoveredNode] = useState(null); + const hoveredNodeRef = useRef(null); const [expandingNode, setExpandingNode] = useState(null); // Track loaded node IDs so we can exclude them when fetching neighbors const loadedNodeIds = useRef>(new Set()); @@ -156,11 +157,17 @@ export function MemoryGraph({ agentId, sort, typeFilter }: MemoryGraphProps) { }, nodeReducer: (node, data) => { const res = { ...data }; - if (hoveredNode && hoveredNode !== node) { - const graph = graphRef.current; - if (graph && !graph.hasEdge(hoveredNode, node) && !graph.hasEdge(node, hoveredNode)) { - res.color = FADED_NODE_COLOR; - res.label = ""; + const hovered = hoveredNodeRef.current; + if (hovered) { + if (hovered === node) { + res.highlighted = true; + res.zIndex = 1; + } else { + const g = graphRef.current; + if (g && !g.hasEdge(hovered, node) && !g.hasEdge(node, hovered)) { + res.color = FADED_NODE_COLOR; + res.label = ""; + } } } return res; @@ -271,8 +278,9 @@ export function MemoryGraph({ agentId, sort, typeFilter }: MemoryGraphProps) { }; }, [isLoading]); - // Re-render sigma when hoveredNode changes (for fade effect) + // Sync ref and re-render sigma when hoveredNode changes (for fade effect) useEffect(() => { + hoveredNodeRef.current = hoveredNode; sigmaRef.current?.refresh(); }, [hoveredNode]); @@ -495,7 +503,7 @@ export function MemoryGraph({ agentId, sort, typeFilter }: MemoryGraphProps) { {/* Sigma container */}