diff --git a/mesh-llm/ui/src/App.tsx b/mesh-llm/ui/src/App.tsx index fbe9bfb0ae..752837f407 100644 --- a/mesh-llm/ui/src/App.tsx +++ b/mesh-llm/ui/src/App.tsx @@ -2881,6 +2881,24 @@ function layoutTopologyNodes( clients: TopologyNode[], nodeRadius: number, ): PositionedTopologyNode[] { + const placeRow = ( + row: TopologyNode[], + bucket: PositionedTopologyNode['bucket'], + y: number, + horizontalSpacing: number, + positioned: PositionedTopologyNode[], + ) => { + const startX = -((row.length - 1) * horizontalSpacing) / 2; + row.forEach((node, index) => { + positioned.push({ + ...node, + bucket, + x: startX + (index * horizontalSpacing), + y, + }); + }); + }; + const all: Array = [ ...serving.map((n) => ({ ...n, bucket: 'serving' as const, x: 0, y: 0 })), ...workers.map((n) => ({ ...n, bucket: 'worker' as const, x: 0, y: 0 })), @@ -2891,6 +2909,42 @@ function layoutTopologyNodes( const peerCount = all.length; if (peerCount === 0) return positioned; + if (peerCount <= 6) { + const horizontalSpacing = 270; + const bandOffset = 215; + const rowStep = 118; + const topRows: Array<{ nodes: TopologyNode[]; bucket: PositionedTopologyNode['bucket'] }> = []; + const bottomRows: Array<{ nodes: TopologyNode[]; bucket: PositionedTopologyNode['bucket'] }> = []; + + if (serving.length) { + topRows.push({ nodes: serving, bucket: 'serving' }); + } + + if (workers.length) { + if (serving.length === 0) { + topRows.push({ nodes: workers, bucket: 'worker' }); + } else { + bottomRows.push({ nodes: workers, bucket: 'worker' }); + } + } + + if (clients.length) { + bottomRows.push({ nodes: clients, bucket: 'client' }); + } + + topRows.forEach((row, index) => { + const distanceFromCenter = bandOffset + ((topRows.length - index - 1) * rowStep); + placeRow(row.nodes, row.bucket, -distanceFromCenter, horizontalSpacing, positioned); + }); + + bottomRows.forEach((row, index) => { + const distanceFromCenter = bandOffset + (index * rowStep); + placeRow(row.nodes, row.bucket, distanceFromCenter, horizontalSpacing, positioned); + }); + + return positioned; + } + // Small meshes get a larger first ring so the graph uses the available canvas. const baseRadius = peerCount <= 3 ? 190