def _run_sequential(self, verbose: bool = False, show_progress: bool = True) -> State:
        """
        Runs tasks sequentially with support for decision nodes.
        
        Args:
            verbose: Whether to print detailed information
            show_progress: Whether to display a progress bar
            
        Returns:
            The final state object
        """
        if verbose:
            console.print(f"[blue]Executing graph with decision support[/blue]")
            spacing()
        
        # We can't use topological sort with decisions, so we use a dynamic execution approach
        execution_queue = self._get_start_nodes()
        executed_nodes = set()
        
        # Count all possible nodes in the graph including all branches
        all_nodes = self._count_all_possible_nodes()
        
        if show_progress:
            with Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                BarColumn(),
                TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
                TimeElapsedColumn(),
                console=console
            ) as progress:
                # Set total to all possible nodes
                overall_task = progress.add_task("[bold blue]Graph Execution", total=all_nodes)
                
                # Process nodes until the queue is empty
                completed_nodes = 0
                while execution_queue:
                    node = execution_queue.pop(0)
                    
                    # Update progress description
                    if isinstance(node, TaskNode):
                        desc = f"[bold blue]Graph Execution - Current: [cyan]{escape_rich_markup(node.task.description[:40])}{'...' if len(node.task.description) > 40 else ''}[/cyan]"
                    else:
                        desc = f"[bold blue]Graph Execution - Evaluating Decision: [yellow]{escape_rich_markup(node.description)}[/yellow]"
                    
                    # Update the progress bar
                    progress.update(overall_task, description=desc)
                    
                    # Process the node
                    if isinstance(node, TaskNode):
                        # Get the latest output for debugging
                        if verbose:
                            latest_output = self.state.get_latest_output()
                            if latest_output:
                                console.print(f"[dim]********latest_output[/dim]")
                                console.print(f"[dim]{escape_rich_markup(str(latest_output))}[/dim]")
                                
                        # If this task doesn't have context but there are previous outputs, add them as context
                        if not node.task.context and self.state.task_outputs:
                            # Get the latest output to use as context
                            latest_output = self.state.get_latest_output()
                            if latest_output:
                                # Set the context for this task
                                node.task.context = [latest_output]
                                if verbose:
                                    console.print(f"[dim]Setting context from previous output for task: {escape_rich_markup(node.task.description)}[/dim]")
                        
                        output = self._execute_task(node, self.state, verbose)
                        self.state.update(node.id, output)
                        executed_nodes.add(node.id)
                        
                        # Add successor nodes to the queue
                        for next_node in self._get_next_nodes(node):
                            # Only add if all predecessors have been executed
                            predecessors = self._get_predecessors(next_node)
                            if all(pred.id in executed_nodes for pred in predecessors):
                                execution_queue.append(next_node)
                    
                    elif isinstance(node, (DecisionFunc, DecisionLLM)):
                        # Evaluate the decision
                        branch = self._evaluate_decision(node, self.state, verbose)
                        executed_nodes.add(node.id)
                        
                        # Add the appropriate branch to the execution queue
                        if branch:
                            if isinstance(branch, TaskNode):
                                # Make sure the task in the branch has context from previous outputs
                                if not branch.task.context and self.state.task_outputs:
                                    latest_output = self.state.get_latest_output()
                                    if latest_output:
                                        branch.task.context = [latest_output]
                                        if verbose:
                                            console.print(f"[dim]Setting context from previous output for branch task: {escape_rich_markup(branch.task.description)}[/dim]")
                                
                                execution_queue.insert(0, branch)
                            elif isinstance(branch, TaskChain):
                                # Add all nodes from the branch to the queue in reverse order
                                branch_nodes = list(reversed(branch.nodes))
                                
                                # Set context for the first task in the branch if it doesn't have context
                                if branch_nodes and isinstance(branch_nodes[-1], TaskNode):
                                    first_task = branch_nodes[-1]
                                    if not first_task.task.context and self.state.task_outputs:
                                        latest_output = self.state.get_latest_output()
                                        if latest_output:
                                            first_task.task.context = [latest_output]
                                            if verbose:
                                                console.print(f"[dim]Setting context from previous output for first branch chain task: {escape_rich_markup(first_task.task.description)}[/dim]")
                                
                                for branch_node in branch_nodes:
                                    execution_queue.insert(0, branch_node)
                            elif isinstance(branch, (DecisionFunc, DecisionLLM)):
                                # Handle the case where a decision returns another decision node
                                # Insert at the front of the queue to be processed next
                                if verbose:
                                    console.print(f"[dim]Decision returned another decision node: {escape_rich_markup(branch.description)}[/dim]")
                                execution_queue.insert(0, branch)
                    
                    # Increment completed nodes and update progress
                    completed_nodes += 1
                    progress.update(overall_task, completed=completed_nodes)
                
                # Make sure the progress bar reaches 100% at the end
                progress.update(overall_task, completed=all_nodes)
        else:
            # Process nodes without progress bar
            while execution_queue:
                node = execution_queue.pop(0)
                
                # Process the node
                if isinstance(node, TaskNode):
                    # If this task doesn't have context but there are previous outputs, add them as context
                    if not node.task.context and self.state.task_outputs:
                        # Get the latest output to use as context
                        latest_output = self.state.get_latest_output()
                        if latest_output:
                            # Set the context for this task
                            node.task.context = [latest_output]
                    
                    output = self._execute_task(node, self.state, verbose)
                    self.state.update(node.id, output)
                    executed_nodes.add(node.id)
                    
                    # Add successor nodes to the queue
                    for next_node in self._get_next_nodes(node):
                        # Only add if all predecessors have been executed
                        predecessors = self._get_predecessors(next_node)
                        if all(pred.id in executed_nodes for pred in predecessors):
                            execution_queue.append(next_node)
                
                elif isinstance(node, (DecisionFunc, DecisionLLM)):
                    # Evaluate the decision
                    branch = self._evaluate_decision(node, self.state, verbose)
                    executed_nodes.add(node.id)
                    
                    # Add the appropriate branch to the execution queue
                    if branch:
                        if isinstance(branch, TaskNode):
                            # Make sure the task in the branch has context from previous outputs
                            if not branch.task.context and self.state.task_outputs:
                                latest_output = self.state.get_latest_output()
                                if latest_output:
                                    branch.task.context = [latest_output]
                                    
                            execution_queue.insert(0, branch)
                        elif isinstance(branch, TaskChain):
                            # Add all nodes from the branch to the queue in reverse order
                            branch_nodes = list(reversed(branch.nodes))
                            
                            # Set context for the first task in the branch if it doesn't have context
                            if branch_nodes and isinstance(branch_nodes[-1], TaskNode):
                                first_task = branch_nodes[-1]
                                if not first_task.task.context and self.state.task_outputs:
                                    latest_output = self.state.get_latest_output()
                                    if latest_output:
                                        first_task.task.context = [latest_output]
                            
                            for branch_node in branch_nodes:
                                execution_queue.insert(0, branch_node)
                        elif isinstance(branch, (DecisionFunc, DecisionLLM)):
                            # Handle the case where a decision returns another decision node
                            # Insert at the front of the queue to be processed next
                            if verbose:
                                console.print(f"[dim]Decision returned another decision node: {escape_rich_markup(branch.description)}[/dim]")
                            execution_queue.insert(0, branch)
        
        if verbose:
            console.print("[bold green]Graph Execution Completed[/bold green]")
            spacing()
        
        return self.state

        Runs tasks sequentially with support for decision nodes.
        
        Args:
            verbose: Whether to print detailed information
            show_progress: Whether to display a progress bar
            
        Returns:
            The final state object
        
src/upsonic/client/graph.py