
    qi)8                         d Z ddlmZmZ ddlmZ ddlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZ ddlmZmZ ddlmZmZ ddlmZ  G d d	e      Z G d
 de      Z G d de      Z G d d      Zy)zTranscript processing utilities for conversation recording and analysis.

This module provides processors that convert speech and text frames into structured
transcript messages with timestamps, enabling conversation history tracking and analysis.
    )ListOptional)logger)BotStoppedSpeakingFrameCancelFrameEndFrameFrameInterruptionFrameLLMThoughtEndFrameLLMThoughtStartFrameLLMThoughtTextFrameThoughtTranscriptionMessageTranscriptionFrameTranscriptionMessageTranscriptionUpdateFrameTTSTextFrame)FrameDirectionFrameProcessor)TextPartForConcatenationconcatenate_aggregated_text)time_now_iso8601c                   4     e Zd ZdZ fdZdee   fdZ xZS )BaseTranscriptProcessorzBase class for processing conversation transcripts.

    Provides common functionality for handling transcript messages and updates.
    c                 T    t        |   di | g | _        | j                  d       y)zInitialize processor with empty message store.

        Args:
            **kwargs: Additional arguments passed to parent class.
        on_transcript_updateN )super__init___processed_messages_register_event_handler)selfkwargs	__class__s     Y/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/processors/transcript_processor.pyr   z BaseTranscriptProcessor.__init__+   s,     	"6"?A $$%;<    messagesc                    K   |r[| j                   j                  |       t        |      }| j                  d|       d{    | j	                  |       d{    yy7 7 w)zwEmit transcript updates for new messages.

        Args:
            messages: New messages to emit in update.
        )r&   r   N)r   extendr   _call_event_handler
push_frame)r!   r&   update_frames      r$   _emit_updatez$BaseTranscriptProcessor._emit_update5   sa      $$++H53XFL**+A<PPP//,///	  Q/s#   ?A%A!A%A#A%#A%)	__name__
__module____qualname____doc__r   r   r   r,   __classcell__r#   s   @r$   r   r   %   s    
=
040D+E 
0r%   r   c                   ,     e Zd ZdZdedef fdZ xZS )UserTranscriptProcessorzKProcesses user transcription frames into timestamped conversation messages.frame	directionc                 ,  K   t         |   ||       d{    t        |t              rGt	        d|j
                  |j                  |j                        }| j                  |g       d{    | j                  ||       d{    y7 v7 !7 	w)zProcess TranscriptionFrames into user conversation messages.

        Args:
            frame: Input frame to process.
            direction: Frame processing direction.
        Nuser)roleuser_idcontent	timestamp)
r   process_frame
isinstancer   r   r:   textr<   r,   r*   )r!   r5   r6   messager#   s       r$   r=   z%UserTranscriptProcessor.process_frameE   s      g#E9555e/0*U]]EJJRWRaRaG ##WI...ooeY/// 	6 //s4   BBAB.B/BB	BBB)r-   r.   r/   r0   r	   r   r=   r1   r2   s   @r$   r4   r4   B   s    U0 0> 0 0r%   r4   c                   N     e Zd ZdZdddef fdZd Zd Zded	e	f fd
Z
 xZS )AssistantTranscriptProcessoral  Processes assistant TTS text frames and LLM thought frames into timestamped messages.

    This processor aggregates both TTS text frames and LLM thought frames into
    complete utterances and thoughts, emitting them as transcript messages.

    An assistant utterance is completed when:
    - The bot stops speaking (BotStoppedSpeakingFrame)
    - The bot is interrupted (InterruptionFrame)
    - The pipeline ends (EndFrame, CancelFrame)

    A thought is completed when:
    - The thought ends (LLMThoughtEndFrame)
    - The bot is interrupted (InterruptionFrame)
    - The pipeline ends (EndFrame, CancelFrame)
    Fprocess_thoughtsrD   c                x    t        |   di | || _        g | _        d| _        g | _        d| _        d| _        y)zInitialize processor with aggregation state.

        Args:
            process_thoughts: Whether to process LLM thought frames. Defaults to False.
            **kwargs: Additional arguments passed to parent class.
        NFr   )r   r   _process_thoughts_current_assistant_text_parts_assistant_text_start_time_current_thought_parts_thought_start_time_thought_active)r!   rD   r"   r#   s      r$   r   z%AssistantTranscriptProcessor.__init__h   sE     	"6"!1MO*9='FH#26 $r%   c                 N  K   | j                   r| j                  rt        | j                         }|rKt        j                  d|        t        d|| j                        }| j                  |g       d{    nt        j                  d       g | _         d| _        yyy7 +w)zAggregates and emits text fragments as a transcript message.

        This method aggregates text fragments that may arrive in multiple
        TTSTextFrame instances and emits them as a single TranscriptionMessage.
        z'Emitting aggregated assistant message: 	assistant)r9   r;   r<   Nz-No content to emit after stripping whitespace)rG   rH   r   r   tracer   r,   r!   r;   r@   s      r$   _emit_aggregated_assistant_textz<AssistantTranscriptProcessor._emit_aggregated_assistant_texty   s      --$2Q2Q1$2T2TUGFwiPQ.$#"==
 ''	222LM 24D..2D+ 3R- 3s   A5B%7B#8,B%c                 Z  K   | j                   r| j                  rt        | j                         }|rJt        j                  d|        t        || j                        }| j                  |g       d{    nt        j                  d       g | _         d| _        d| _        yyy7 2w)a  Aggregates and emits thought text fragments as a thought transcript message.

        This method aggregates thought fragments that may arrive in multiple
        LLMThoughtTextFrame instances and emits them as a single ThoughtTranscriptionMessage.
        z%Emitting aggregated thought message: )r;   r<   Nz5No thought content to emit after stripping whitespaceF)rI   rJ   r   r   rN   r   r,   rK   rO   s      r$   _emit_aggregated_thoughtz5AssistantTranscriptProcessor._emit_aggregated_thought   s      &&4+C+C1$2M2MNGDWINO5#"66 ''	222TU +-D''+D$#(D  ,D& 3s   A4B+6B)73B+r5   r6   c                   K   t         |   ||       d{    t        |t        t        f      re| j                  ||       d{    | j                          d{    | j                  r&| j                  r| j                          d{    yyyt        |t              rD| j                  rd| _        t               | _        g | _        | j                  ||       d{    yt        |t              rm| j                  rF| j                  r:| j                  j                  t!        |j"                  |j$                               | j                  ||       d{    yt        |t&              rK| j                  r$| j                  r| j                          d{    | j                  ||       d{    yt        |t(              rp| j*                  st               | _        | j,                  j                  t!        |j"                  |j$                               | j                  ||       d{    yt        |t.        t0        f      rs| j                          d{    t        |t0              r0| j                  r$| j                  r| j                          d{    | j                  ||       d{    y| j                  ||       d{    y7 7 7 7 a7 7 7 V7 ?7 7 7 V7 >7 %w)a  Process frames into assistant conversation messages and thought messages.

        Handles different frame types:

        - TTSTextFrame: Aggregates text for current utterance
        - LLMThoughtStartFrame: Begins aggregating a new thought
        - LLMThoughtTextFrame: Aggregates text for current thought
        - LLMThoughtEndFrame: Completes current thought
        - BotStoppedSpeakingFrame: Completes current utterance
        - InterruptionFrame: Completes current utterance and thought due to interruption
        - EndFrame: Completes current utterance and thought at pipeline end
        - CancelFrame: Completes current utterance and thought due to cancellation

        Args:
            frame: Input frame to process.
            direction: Frame processing direction.
        NT)includes_inter_part_spaces)r   r=   r>   r
   r   r*   rP   rF   rK   rR   r   r   rJ   rI   r   appendr   r?   includes_inter_frame_spacesr   r   rH   rG   r   r   )r!   r5   r6   r#   s      r$   r=   z*AssistantTranscriptProcessor.process_frame   s|    $ g#E9555e/=> //%33366888%%$*>*>33555 +?%34%%'+$+;+=(.0+//%33323%%$*>*>++22,

u?`?` //%33312%%$*>*>33555//%333|,222B2D/..55(JJ5;\;\ //%333 7BC66888%*t/E/E$J^J^33555//%333//%333q 	6
 485 4 4 63 4 9 633s   L	K'/L	K*L	K- /L	K0AL	%K3&A<L	"K6#A L	#K9$L	=K<>A?L	=K?>.L	,L-?L	,L-L	LL	!L"L	*L	-L	0L	3L	6L	9L	<L	?L	L	L	L	L	)r-   r.   r/   r0   boolr   rP   rR   r	   r   r=   r1   r2   s   @r$   rB   rB   W   s?      49 %D %"3.).J4 J4> J4 J4r%   rB   c                   F    e Zd ZdZdddefdZdefdZdefdZ	d	e
fd
Zy)TranscriptProcessoraY  Factory for creating and managing transcript processors.

    Provides unified access to user and assistant transcript processors
    with shared event handling. The assistant processor handles both TTS text
    and LLM thought frames.

    Example::

        transcript = TranscriptProcessor()

        pipeline = Pipeline(
            [
                transport.input(),
                stt,
                transcript.user(),              # User transcripts
                context_aggregator.user(),
                llm,
                tts,
                transport.output(),
                transcript.assistant(),         # Assistant transcripts (including thoughts)
                context_aggregator.assistant(),
            ]
        )

        @transcript.event_handler("on_transcript_update")
        async def handle_update(processor, frame):
            print(f"New messages: {frame.messages}")

    .. deprecated:: 0.0.99
        `TranscriptProcessor` is deprecated and will be removed in a future version.
        Use `LLMUserAggregator`'s and `LLMAssistantAggregator`'s new events instead.
    FrC   rD   c                    || _         d| _        d| _        i | _        ddl}|j                         5  |j                  d       |j                  dt               ddd       y# 1 sw Y   yxY w)zInitialize factory.

        Args:
            process_thoughts: Whether the assistant processor should handle LLM thought
                frames. Defaults to False.
        Nr   alwaysz`TranscriptProcessor` is deprecated and will be removed in a future version. Use `LLMUserAggregator`'s and `LLMAssistantAggregator`'s new events instead.)	rF   _user_processor_assistant_processor_event_handlerswarningscatch_warningssimplefilterwarnDeprecationWarning)r!   rD   r_   s      r$   r   zTranscriptProcessor.__init__  sk     "2#$(!!$$& 	!!(+MM_"	 	 	s   (A""A+returnc                     | j                   Ut        di || _         | j                  j                         D ](  \  }| j                   j	                  |      fd       }* | j                   S )zGet the user transcript processor.

        Args:
            **kwargs: Arguments specific to UserTranscriptProcessor.

        Returns:
            The user transcript processor instance.
        c                 2   K    | |       d {   S 7 wNr   	processorr5   handlers     r$   user_handlerz.TranscriptProcessor.user.<locals>.user_handler:       !(E!::::   r   )r\   r4   r^   itemsevent_handler)r!   r"   
event_namerk   rj   s       @r$   r8   zTranscriptProcessor.user,  sv     '#:#DV#DD '+';';'A'A'C ;#
G%%33J?; @;; ###r%   c                     | j                   at        dd| j                  i|| _         | j                  j	                         D ](  \  }| j                   j                  |      fd       }* | j                   S )zGet the assistant transcript processor.

        Args:
            **kwargs: Arguments specific to AssistantTranscriptProcessor.

        Returns:
            The assistant transcript processor instance.
        rD   c                 2   K    | |       d {   S 7 wrg   r   rh   s     r$   assistant_handlerz8TranscriptProcessor.assistant.<locals>.assistant_handlerP  rl   rm   r   )r]   rB   rF   r^   rn   ro   )r!   r"   rp   rs   rj   s       @r$   rM   zTranscriptProcessor.assistant@  s     $$,(D )!%!7!7);A)D% (,';';'A'A'C ;#
G**88D; E;; (((r%   rp   c                       fd}|S )zRegister event handler for both processors.

        Args:
            event_name: Name of event to handle.

        Returns:
            Decorator function that registers handler with both processors.
        c                       j                   <   j                  r#j                  j                         fd       }j                  r#j                  j                         fd       } S )Nc                 2   K    | |       d {   S 7 wrg   r   rh   s     r$   rk   zJTranscriptProcessor.event_handler.<locals>.decorator.<locals>.user_handlerf  rl   rm   c                 2   K    | |       d {   S 7 wrg   r   rh   s     r$   rs   zOTranscriptProcessor.event_handler.<locals>.decorator.<locals>.assistant_handlerl  rl   rm   )r^   r\   ro   r]   )rj   rk   rs   rp   r!   s   `  r$   	decoratorz4TranscriptProcessor.event_handler.<locals>.decorator`  sx    /6D  , ##%%33J?; @; ((**88D; E; Nr%   r   )r!   rp   rx   s   `` r$   ro   z!TranscriptProcessor.event_handlerV  s    	$ r%   N)r-   r.   r/   r0   rW   r   r4   r8   rB   rM   strro   r   r%   r$   rY   rY      s?    B 49 D ,$ 7 $()%A ), r%   rY   N) r0   typingr   r   logurur   pipecat.frames.framesr   r   r   r	   r
   r   r   r   r   r   r   r   r   "pipecat.processors.frame_processorr   r   pipecat.utils.stringr   r   pipecat.utils.timer   r   r4   rB   rY   r   r%   r$   <module>r      sg    "     N V /0n 0:05 0*Z4#: Z4z~ ~r%   