async def _handle_turn_started(self, turn_number: int):
        """Handle a turn start event by creating a new span."""
        if not is_tracing_available() or not self._tracer:
            return

        # If this is the first turn and no conversation span exists yet,
        # start the conversation tracing (will generate ID if needed)
        if turn_number == 1 and not self._conversation_span:
            self.start_conversation_tracing(self._conversation_id)

        # Get the parent context - conversation if available, otherwise use root context
        parent_context = None
        if self._conversation_span:
            context_provider = ConversationContextProvider.get_instance()
            parent_context = context_provider.get_current_conversation_context()

        # Create a new span for this turn
        self._current_span = self._tracer.start_span("turn", context=parent_context)
        self._current_turn_number = turn_number

        # Set span attributes
        self._current_span.set_attribute("turn.number", turn_number)
        self._current_span.set_attribute("turn.type", "conversation")

        # Add conversation ID attribute if available
        if self._conversation_id:
            self._current_span.set_attribute("conversation.id", self._conversation_id)

        # Store the span context so services can become children of this span
        self._trace_context_map[turn_number] = self._current_span.get_span_context()

        # Update the context provider so services can access this span
        context_provider = TurnContextProvider.get_instance()
        context_provider.set_current_turn_context(self._current_span.get_span_context())

        logger.debug(f"Started tracing for Turn {turn_number}")
Handle a turn start event by creating a new span.
src/pipecat/utils/tracing/turn_trace_observer.py