async def run(self):
        """Starts and manages the pipeline execution until completion or cancellation."""
        if self.has_finished():
            return
        cleanup_pipeline = True
        try:
            # Setup processors.
            await self._setup()

            # Create all main tasks and wait of the main push task. This is the
            # task that pushes frames to the very beginning of our pipeline (our
            # controlled PipelineTaskSource processor).
            push_task = await self._create_tasks()
            await self._task_manager.wait_for_task(push_task)

            # We have already cleaned up the pipeline inside the task.
            cleanup_pipeline = False
        except asyncio.CancelledError:
            # We are awaiting on the push task and it might be cancelled
            # (e.g. Ctrl-C). This means we will get a CancelledError here as
            # well, because you get a CancelledError in every place you are
            # awaiting a task.
            pass
        finally:
            # It's possibe that we get an asyncio.CancelledError from the
            # outside, if so we need to make sure everything gets cancelled
            # properly.
            if cleanup_pipeline:
                await self._cancel()
            await self._cancel_tasks()
            await self._cleanup(cleanup_pipeline)
            if self._check_dangling_tasks:
                self._print_dangling_tasks()
            self._finished = True
Starts and manages the pipeline execution until completion or cancellation.
src/pipecat/pipeline/task.py