async def aggregate(self, text: str) -> Optional[str]:
        """Aggregate text and process pattern pairs.

        This method adds the new text to the buffer, processes any complete pattern
        pairs, and returns processed text up to sentence boundaries if possible.
        If there are incomplete patterns (start without matching end), it will
        continue buffering text.

        Args:
            text: New text to add to the buffer.

        Returns:
            Processed text up to a sentence boundary, or None if more
            text is needed to form a complete sentence or pattern.
        """
        # Add new text to buffer
        self._text += text

        (self._current_tag, self._current_tag_index) = parse_start_end_tags(
            self._text, self._tags, self._current_tag, self._current_tag_index
        )

        # Find sentence boundary if no incomplete patterns
        if not self._current_tag:
            eos_marker = match_endofsentence(self._text)
            if eos_marker:
                # Extract text up to the sentence boundary
                result = self._text[:eos_marker]
                self._text = self._text[eos_marker:]
                return result

        # No complete sentence found yet
        return None
Aggregate text and process pattern pairs.

        This method adds the new text to the buffer, processes any complete pattern
        pairs, and returns processed text up to sentence boundaries if possible.
        If there are incomplete patterns (start without matching end), it will
        continue buffering text.

        Args:
            text: New text to add to the buffer.

        Returns:
            Processed text up to a sentence boundary, or None if more
            text is needed to form a complete sentence or pattern.
        
src/pipecat/utils/text/skip_tags_aggregator.py