def _get_predecessors(self, node: Union[TaskNode, DecisionFunc, DecisionLLM]) -> List[Union[TaskNode, DecisionFunc, DecisionLLM]]:
        """
        Gets the predecessor nodes that feed into the given node.
        
        Args:
            node: The node to find predecessors for
            
        Returns:
            List of predecessor nodes
        """
        predecessors = []
        # Check node connections in the edges dictionary
        for n_id, next_ids in self.edges.items():
            if node.id in next_ids:
                # Find the node object
                for n in self.nodes:
                    if n.id == n_id:
                        predecessors.append(n)
                        break
        
        # Also check TaskNode's next_nodes connections
        for n in self.nodes:
            if isinstance(n, TaskNode):
                for next_node in n.next_nodes:
                    if next_node.id == node.id:
                        predecessors.append(n)
        
        return predecessors

        Gets the predecessor nodes that feed into the given node.
        
        Args:
            node: The node to find predecessors for
            
        Returns:
            List of predecessor nodes
        
src/upsonic/client/graph.py