diff --git a/sim/app/w/[id]/components/chat/chat.tsx b/sim/app/w/[id]/components/chat/chat.tsx index 7587d1ecab..6aa3fc7574 100644 --- a/sim/app/w/[id]/components/chat/chat.tsx +++ b/sim/app/w/[id]/components/chat/chat.tsx @@ -8,7 +8,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip import { useChatStore } from '@/stores/chat/store' export function Chat() { - const { messages, isProcessing, error, sendMessage } = useChatStore() + const { sendMessage } = useChatStore() const [isOpen, setIsOpen] = useState(false) const [message, setMessage] = useState('') diff --git a/sim/app/w/[id]/components/panel/components/chat/chat.tsx b/sim/app/w/[id]/components/panel/components/chat/chat.tsx index b0d4f3bfcb..4fab551d3b 100644 --- a/sim/app/w/[id]/components/panel/components/chat/chat.tsx +++ b/sim/app/w/[id]/components/panel/components/chat/chat.tsx @@ -52,6 +52,9 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { // Process blocks to extract outputs Object.values(blocks).forEach((block) => { + // Skip starter/start blocks + if (block.type === 'starter') return + const blockName = block.name.replace(/\s+/g, '').toLowerCase() // Add response outputs @@ -194,6 +197,44 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { // Group output options by block const groupedOutputs = useMemo(() => { const groups: Record = {} + const blockDistances: Record = {} + const edges = useWorkflowStore.getState().edges + + // Find the starter block + const starterBlock = Object.values(blocks).find((block) => block.type === 'starter') + const starterBlockId = starterBlock?.id + + // Calculate distances from starter block if it exists + if (starterBlockId) { + // Build an adjacency list for faster traversal + const adjList: Record = {} + for (const edge of edges) { + if (!adjList[edge.source]) { + adjList[edge.source] = [] + } + adjList[edge.source].push(edge.target) + } + + // BFS to find distances from starter block + const visited = new Set() + const queue: [string, number][] = [[starterBlockId, 0]] // [nodeId, distance] + + while (queue.length > 0) { + const [currentNodeId, distance] = queue.shift()! + + if (visited.has(currentNodeId)) continue + visited.add(currentNodeId) + blockDistances[currentNodeId] = distance + + // Get all outgoing edges from the adjacency list + const outgoingNodeIds = adjList[currentNodeId] || [] + + // Add all target nodes to the queue with incremented distance + for (const targetId of outgoingNodeIds) { + queue.push([targetId, distance + 1]) + } + } + } // Group by block name workflowOutputs.forEach((output) => { @@ -203,8 +244,27 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { groups[output.blockName].push(output) }) - return groups - }, [workflowOutputs]) + // Convert to array of [blockName, outputs] for sorting + const groupsArray = Object.entries(groups).map(([blockName, outputs]) => { + // Find the blockId for this group (using the first output's blockId) + const blockId = outputs[0]?.blockId + // Get the distance for this block (or default to 0 if not found) + const distance = blockId ? blockDistances[blockId] || 0 : 0 + return { blockName, outputs, distance } + }) + + // Sort by distance (descending - furthest first) + groupsArray.sort((a, b) => b.distance - a.distance) + + // Convert back to record + return groupsArray.reduce( + (acc, { blockName, outputs }) => { + acc[blockName] = outputs + return acc + }, + {} as Record + ) + }, [workflowOutputs, blocks]) // Get block color for an output const getOutputColor = (blockId: string, blockType: string) => { @@ -255,7 +315,7 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { {isOutputDropdownOpen && workflowOutputs.length > 0 && ( -
+
{Object.entries(groupedOutputs).map(([blockName, outputs]) => (