
    qilh                     `   d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlZddlmZ ddlmZmZ ddl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&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, dd
l-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z; ddl<m=Z=m>Z>m?Z? ddl@mAZA 	 ddlBmCZD e G d de>             ZI G d de      ZJ G d de      ZK G d de      ZL G d de;      ZMy# eE$ r7ZF ej                  deF         ej                  d        eHdeF       dZF[Fww xY w) zUltravox Realtime API service implementation.

This module provides real-time conversational AI capabilities using Ultravox's
Realtime API, supporting both text and audio modalities with
voice transcription, streaming responses, and tool usage.
    N)	dataclassfield)AnyDictListLiteralOptionalUnion)logger)	BaseModelField)ToolsSchema)create_stream_resampler)AggregationTypeCancelFrameEndFrameFrameInputAudioRawFrameInputTextRawFrameInterruptionFrameLLMContextFrameLLMFullResponseEndFrameLLMFullResponseStartFrameLLMTextFrame
StartFrameTranscriptionFrameTTSAudioRawFrameTTSStartedFrameTTSStoppedFrameTTSTextFrameUserAudioRawFrameVADUserStoppedSpeakingFrame)
LLMContext)LLMAssistantAggregatorParamsLLMUserAggregatorParams)LLMContextAggregatorPair)OpenAILLMContextOpenAILLMContextFrame)FrameDirection)FunctionCallFromLLM
LLMService)	NOT_GIVENLLMSettings	_NotGiven)time_now_iso8601)clientzException: zIIn order to use Ultravox, you need to `pip install pipecat-ai[ultravox]`.zMissing module: c                   4    e Zd ZU dZ ee      Zeez  e	d<   y)UltravoxRealtimeLLMSettingszSettings for UltravoxRealtimeLLMService.

    Parameters:
        output_medium: The output medium for the model ("voice" or "text").
    )defaultoutput_mediumN)
__name__
__module____qualname____doc__r   r,   r4   strr.   __annotations__     O/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/ultravox/llm.pyr2   r2   G   s     &+9%=M3?=r<   r2   c                   D   e Zd ZU dZeed<   ej                  ed<    ee	      Z
eeef   ed<    ee	      Zeeef   ed<   dZeed      ed	<    ed ej$                  d
       ej$                  d            Zeej$                     ed<    ee	      Zeeef   ed<   y)AgentInputParamsa  Input parameters for Ultravox Realtime generation using a pre-defined Agent.

    Parameters:
        api_key: Ultravox API key for authentication.
        agent_id: The ID of the Ultravox Realtime agent you'd like to use. Agents
            are pre-configured to handle calls consistently. You can create and edit
            agents in the Ultravox console (https://app.ultravox.ai/agents) or using
            the Ultravox API (https://docs.ultravox.ai/api-reference/agents/agents-post).
        template_context: Context variables to use when instantiating a call with the
            agent. Defaults to an empty dict.
        metadata: Metadata to attach to the call. Default to an empty dict.
        output_medium: The initial output medium for the agent. Use "text" for text
            responses or "voice" for audio responses. Defaults to None, which uses the
            agent's default.
        max_duration: The maximum duration of the call. Defaults to None, which will
            use the agent's default maximum duration.
        extra: Extra parameters to include in the agent call creation request. Defaults
            to an empty dict. See the Ultravox API documentation for valid arguments:
            https://docs.ultravox.ai/api-reference/agents/agents-calls-post
    api_keyagent_iddefault_factorytemplate_contextmetadataNtextvoicer4   
   seconds   hoursr3   gelemax_durationextra)r5   r6   r7   r8   r9   r:   uuidUUIDr   dictrD   r   r   rE   r4   r	   r   datetime	timedeltarR   rS   r;   r<   r=   r?   r?   R   s    * Lii',T'Bd38nB$T:Hd38n:8<M8GO45<16+++B7<NH<N<NUV<W2L(8--.  "$7E4S>7r<   r?   c                      e Zd ZU dZeed<   dZee   ed<    eddd      Z	e
ed<   dZee   ed	<   dZeej                     ed
<    ee      Zeeef   ed<   dZeed      ed<    e ej*                  d       ej*                  d       ej*                  d            Zej*                  ed<    ee      Zeeef   ed<   y)OneShotInputParamsa  Input parameters for Ultravox Realtime generation using a one-off call.

    Parameters:
        api_key: Ultravox API key for authentication.
        system_prompt: System prompt to guide the model's behavior. Defaults to None.
        temperature: Sampling temperature for response generation. Defaults to 0.
        model: Model identifier to use. Defaults to "fixie-ai/ultravox".
        voice: Voice identifier for speech generation. Defaults to None.
        metadata: Metadata to attach to the call. Default to an empty dict.
        output_medium: The initial output medium for the agent. Use "text" for text
            responses or "voice" for audio responses. Defaults to None (voice).
        max_duration: The maximum duration of the call. Defaults to one hour.
        extra: Extra parameters to include in the call creation request. Defaults
            to an empty dict. See the Ultravox API documentation for valid arguments:
            https://docs.ultravox.ai/api-reference/calls/calls-post
    r@   Nsystem_prompt              ?rO   temperaturemodelrH   rB   rE   rF   r4   rL   rM   rI   rJ   rR   rS   )r5   r6   r7   r8   r9   r:   r[   r	   r   r^   floatr_   rH   rT   rU   rV   rE   r   r4   r   rW   rX   rR   rS   r   r;   r<   r=   rZ   rZ   s   s    " L#'M8C='sss;K;E8C=!%E8DII%$T:Hd38n:8<M8GO45<',"""+8b)8A&(L($$ 
 "$7E4S>7r<   rZ   c                       e Zd ZU dZeed<   y)JoinUrlInputParamszInput parameters for joining an existing Ultravox Realtime call via join URL.

    Parameters:
        join_url: The join URL for the existing Ultravox Realtime call.
    join_urlN)r5   r6   r7   r8   r9   r:   r;   r<   r=   rb   rb      s     Mr<   rb   c            	       (    e Zd ZU dZeZeed<   ddddeee	e
f   dee   dee   f fdZd	efd
Zdef fdZedeed      d	ee   fd       Zded	efdZde	d	efdZded	eeeef      fdZdef fdZdef fdZd Z def fdZ!de"de#f fdZ$de%fdZ&de'fdZ(de)fdZ*defd Z+d!efd"Z,d#ee-eeef   f   fd$Z.d% Z/d&e-fd'Z0d( Z1d)ed*ed+eeef   fd,Z2defd-Z3dedee   dee   d.efd/Z4 e5        e6       d0de7d1e5d2e6d	e8fd3Z9 xZ:S )4UltravoxRealtimeLLMServicea  Provides access to the Ultravox Realtime API.

    This service enables real-time conversations with Ultravox, supporting both
    text and audio output. It handles voice transcription, streaming audio
    responses, and tool usage.

    Note: Ultravox is an audio-native model, so voice transcriptions are not used
    by the model and may not always align with its understanding of user input.
    	_settingsN)settingsone_shot_selected_toolsparamsrg   rh   c                n   t        dddddddddddd      }||j                  |       t        |   dd|i| || _        |r7t        | j                  t              st        j                  d       n|| _	        d| _
        d| _        d| _        d| _        d| _        d| _        t!               | _        y)a  Initialize the Ultravox Realtime LLM service.

        Args:
            params: Configuration parameters for the model.
            settings: Ultravox Realtime LLM settings. If provided, the ``settings``
                values take precedence over default values.
            one_shot_selected_tools: ToolsSchema for tools to use with this call.
                May only be set with OneShotInputParams.
            **kwargs: Additional arguments passed to parent LLMService.
        NF)r_   system_instructionr^   
max_tokenstop_ptop_kfrequency_penaltypresence_penaltyseedfilter_incomplete_user_turnsuser_turn_completion_configr4   rg   zPone_shot_selected_tools may only be set when using OneShotInputParams; ignoring.i  r;   )r2   apply_updatesuper__init___params
isinstancerZ   r   warning_selected_tools_socket_receive_task_disconnecting_bot_responding_last_user_id_sample_rater   
_resampler)selfri   rg   rh   kwargsdefault_settings	__class__s         r=   rv   z#UltravoxRealtimeLLMService.__init__   s    & 7#"!).(,
$ ))(3 	
%	
	
 "dll,>?f (?$DH59#?C,0!13r<   returnc                      y)zCheck if the service can generate usage metrics.

        Returns:
            True if metrics generation is supported.
        Tr;   r   s    r=   can_generate_metricsz/UltravoxRealtimeLLMService.can_generate_metrics   s     r<   framec                   K   t         |   |       d{    	 | j                  xt        d x\    | j                  j                  }nc xt
        d x'\    | j                  | j                         d{   }n1 t        d x&\   | j                  | j                         d{   }n t        j                  d        t        j                  |       d{   | _        | j                  | j                               | _        y7 7 7 i7 4# t"        $ r'}| j%                  d|d       d{  7   Y d}~yd}~ww xY ww)zgStart the service and establish connection.

        Args:
            frame: The start frame.
        Nr;   z(Joining Ultravox Realtime call via URL: zFailed to connect to UltravoxTfatal)ru   startrw   rb   rc   r?   _start_agent_callrZ   _start_one_shot_callr   infowebsocket_clientconnectr{   create_task_receive_messagesr|   	Exception
push_error)r   r   rc   er   s       r=   r   z UltravoxRealtimeLLMService.start   s     gmE"""	R,,)')#||44H *'%'%)%;%;DLL%IIH (')%)%>%>t||%LLH * KKB8*MN!1!9!9(!CCDL!%!1!1$2H2H2J!KD 	#  JL D 	R//"A1D/QQQ	Rs{   EDEAD 7D8/D 'D(6D D-D ED D D 	EE 5D86E ;E EEmediumrF   c                     | dk(  ry| dk(  ryy )NrG   MESSAGE_MEDIUM_TEXTrH   MESSAGE_MEDIUM_VOICEr;   )r   s    r=   _output_medium_to_apiz0UltravoxRealtimeLLMService._output_medium_to_api  s    V(w)r<   c                 L  K   |j                   |j                  dd| j                  iid}| j                  |j                        }|r||d<   |j
                  r!|j
                  j                         dd|d<   ||j                  z  }t        j                         4 d {   }|j                  d|j                   d	d
|j                  i|      4 d {   }|j                  dk7  r3|j                          d {   }t        d|j                   d|       |j!                          d {   d   cd d d       d {    cd d d       d {    S 7 7 7 `7 /7 7 # 1 d {  7  sw Y   nxY wd d d       d {  7   y # 1 d {  7  sw Y   y xY ww)NserverWebSocketinputSampleRate)templateContextrE   r   initialOutputMedium3fsmaxDurationz#https://api.ultravox.ai/api/agents/z/calls	X-Api-Keyheadersjson   Ultravox API error : joinUrl)rD   rE   r   r   r4   rR   total_secondsrS   aiohttpClientSessionpostrA   r@   statusrG   r   r   r   ri   request_bodyinitial_output_mediumsessionresponse
error_texts          r=   r   z,UltravoxRealtimeLLMService._start_agent_call  s    %66!%t'8'8$
 !% : :6;O;O P 2GL./-3-@-@-N-N-PQS,TTU*VL'#fll2((* 		: 		:g||5foo5FfM$fnn5! $  : : ??c)'/}}!6J#&9(//9J"ZL$YZZ&mmo-y9: : :		: 		: 		:: "7-:		:: : :		: 		: 		: 		: 		:s   BF$!E"F$%3FEF#E(?E  2E(2E"3E(9FE$F
F$E&F$F E("E($F&F$(E:	.E1/E:	6F=F$F	F$F!FF!F$c           
        K   |j                   |j                  |j                  |j                  rt	        |j                        nd |j
                  |j                  j                         dd| j                  r| j                  | j                        ng dd| j                  iid}| j                  |j                        }|r||d<   ||j                  z  }t        j                         4 d {   }|j!                  dd|j"                  i|	      4 d {   }|j$                  d
k7  r3|j'                          d {   }t)        d|j$                   d|       |j+                          d {   d   cd d d       d {    cd d d       d {    S 7 7 7 `7 /7 7 # 1 d {  7  sw Y   nxY wd d d       d {  7   y # 1 d {  7  sw Y   y xY ww)Nr   r   r   r   )systemPromptr^   r_   rH   rE   r   selectedToolsr   r   z!https://api.ultravox.ai/api/callsr   r   r   r   r   r   )r[   r^   r_   rH   r9   rE   rR   r   rz   _to_selected_toolsr   r   r4   rS   r   r   r   r@   r   rG   r   r   r   s          r=   r   z/UltravoxRealtimeLLMService._start_one_shot_call0  s    "00!--\\*0,,S&D$11??A"EQG## "44T5I5IJ!%t'8'8$
  !% : :6;O;O P 2GL./#fll2((* 		: 		:g||3$fnn5! $  : : ??c)'/}}!6J#&9(//9J"ZL$YZZ&mmo-y9: : :		: 		: 		:: "7-:		:: : :		: 		: 		: 		: 		:s   C/G&1F2G&5%GF G#F*F"2F*4F$5F*;GF&GG&F(G& G"F*$F*&G(G&*F<	0F31F<	8G?G&
GG&G#GG#G&toolc                    g }|j                   D ]j  }|j                  d|j                  |j                  |j                  j                         D cg c]  \  }}|d|||j                  v d c}}i di       l |S c c}}w )NtemporaryToolPARAMETER_LOCATION_BODY)namelocationschemarequired)modelToolNamedescriptiondynamicParametersr0   )standard_toolsappendr   r   
propertiesitemsr   )r   r   resultstandard_toolkvs         r=   r   z-UltravoxRealtimeLLMService._to_selected_toolsP  s    ')!00 	MMM#)6););'4'@'@ )6(@(@(F(F(H. !%1 )*,E*+,-1G1G,G	. #%&	& .s   A>c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zaStop the service and close connections.

        Args:
            frame: The end frame.
        N)ru   stop_disconnectr   r   r   s     r=   r   zUltravoxRealtimeLLMService.stopg  s6      gl5!!!    	"    848688c                 t   K   t         |   |       d{    | j                          d{    y7 7 w)zfCancel the service and close connections.

        Args:
            frame: The cancel frame.
        N)ru   cancelr   r   s     r=   r   z!UltravoxRealtimeLLMService.cancelp  s6      gnU###    	$ r   c                    K   d| _         | j                  r)| j                  j                          d {    d | _        | j                  r-| j	                  | j                  d       d {    d | _        y y 7 E7 w)NTr]   )timeout)r}   r{   closer|   cancel_taskr   s    r=   r   z&UltravoxRealtimeLLMService._disconnecty  ss     "<<,,$$&&&DL""4#5#5s"CCC!%D  ' Ds!   1A=A97A=+A;,A=;A=deltac                    K   t         |   |       d {   }d|v r-| j                  | j                  j                         d {    | j                  |j                         dhz
         |S 7 Z7 +w)Nr4   )ru   _update_settings_update_output_mediumrf   r4    _warn_unhandled_updated_settingskeys)r   r   changedr   s      r=   r   z+UltravoxRealtimeLLMService._update_settings  si     077g%,,T^^-I-IJJJ--glln?P.PQ	 8Js!   A5A10A5A3*A53A5	directionc                   K   t         |   ||       d{    t        |t        t        f      rUt        |t              r|j
                  nt        j                  |j
                        }| j                  |       d{    yt        |t              r3| j                          d{    | j                  ||       d{    yt        |t              r>| j                  |j                         d{    | j                  ||       d{    yt        |t              r4| j!                  |       d{    | j                  ||       d{    yt        |t"              r4| j%                  |       d{    | j                  ||       d{    y| j                  ||       d{    y7 7 =7 7 7 7 7 7 u7 M7 57 w)zProcess incoming frames for the Ultravox Realtime service.

        Args:
            frame: The frame to process.
            direction: The frame processing direction.
        N)ru   process_framerx   r   r(   contextr#   from_openai_context_handle_contextr   stop_all_metrics
push_framer   _send_user_textrG   r   _send_user_audior"   !_handle_vad_user_stopped_speaking)r   r   r   r   r   s       r=   r   z(UltravoxRealtimeLLMService.process_frame  s     g#E9555eo/DEF e_5 33EMMB 
 &&w///01'')))//%33301&&uzz222//%33312''...//%333:;88???//%333//%333- 	6 0)323.3?33s   GF;A)GF>(G*G+GG3G8G9GG)G<G
=GG)G GGGG5G6G>GGGGG
GGGGGr   c                 >  K   t        |j                        D ]  }|j                  d      dk7  r y |j                  d      }d|j                  d      t        |t              r|ndj                  d |D              d}| j                  |       d {     y 7 w)	Nroler   contentclient_tool_resulttool_call_id c              3   >   K   | ]  }|j                  d         yw)rG   N)get).0ts     r=   	<genexpr>z=UltravoxRealtimeLLMService._handle_context.<locals>.<genexpr>  s     <qQUU6]<s   )typeinvocationIdr   )reversedmessagesr   rx   r9   join_send)r   r   messager   socket_messages        r=   r   z*UltravoxRealtimeLLMService._handle_context  s        0 01 	-G{{6"f,kk),G, 'N ;gs+ "WW<G<<N **^,,,	- -s   BBBBc                    K   |j                   dk(  ry|j                  |j                   z
  }| j                  |       d{    y7 w)a  Handle VAD user stopped speaking frame.

        Calculates the actual speech end time and starts a timeout task to wait
        for the final transcription before reporting TTFB.

        Args:
            frame: The VAD user stopped speaking frame.
        r\   N)
start_time)	stop_secs	timestampstart_ttfb_metrics)r   r   speech_end_times      r=   r   z<UltravoxRealtimeLLMService._handle_vad_user_stopped_speaking  sB      ??c!
  //EOO;%%%AAAs   ?A	AA	c                 b  K   | j                   syt        |t              r|j                  nd| _        |j
                  }|j                  | j                  k7  r9| j                  j                  ||j                  | j                         d{   }| j                  |       d{    y7 7 w)z+Send user audio frame to Ultravox Realtime.N)r{   rx   r!   user_idr   audiosample_rater   r   resampler   )r   r   r  s      r=   r   z+UltravoxRealtimeLLMService._send_user_audio  s     ||.8@Q.RU]]X\ 1 11//225%:K:KTM^M^__Ejj `s$   B
B/B+B/%B-&B/-B/rG   c                 b   K   | j                   sy| j                  d|d       d{    y7 w)zoSend user text via Ultravox Realtime.

        Args:
            text: The text to send as user input.
        Nuser_text_message)r   rG   )r{   r   r   rG   s     r=   r   z*UltravoxRealtimeLLMService._send_user_text  s*      ||jj"5tDEEEs   %/-/r4   c                    K   |j                         }|dk(  rd}|j                         dvrt        j                  d|        y | j                  d|d       d {    y 7 w)Nr  rH   >   rG   rH   z$Unsupported Ultravox output medium: set_output_medium)r   r   )lowerr   ry   r   )r   r4   s     r=   r   z0UltravoxRealtimeLLMService._update_output_medium  sb     %++-G##M (99NNA-QRjj"5OPPPs   AA$A"A$r   c                   K   | j                   s| j                  sy	 t        |t              r$| j                  j	                  |       d{    y| j                  j	                  t        j                  |             d{    y7 <7 # t        $ rD}| j                   s| j                  sY d}~y| j                  d|d       d{  7   Y d}~yd}~ww xY ww)zSend content via the WebSocket connection.

        Args:
            content: The content to send, either as bytes or a JSON-serializable dict.
        NzUltravox websocket send errorTr   )	r}   r{   rx   bytessendr   dumpsr   r   )r   r   r   s      r=   r   z UltravoxRealtimeLLMService._send  s      dll	R'5)ll''000ll''

7(;<<< 1< 	R""$,,//"A1D/QQQ	Rsv   C.B BB C1B B
B CB 
B 	CC-C2C	C
CCCCc           
        K   | j                   sy| j                   2 3 d{   }	 t        |t              r| j                  |       d{    4t	        j
                  |      }|j                  d      xdk(  r= | j                  ry|j                  d      dk7  rd| j                          d{    nJxdk(  rJ | j                  |j                  d      |j                  d      |j                  d             d{    nd	k(  r|j                  d
      xdk(  rQ |j                  d      st        j                  d       n| j                  |j                  d             d{    ndk(  rZ| j                  |j                  d      |j                  d      |j                  d      |j                  dd             d{    n3	 t        j                  d|        n	 t        j                  d|        7 7 7 Y7 7 7 H# t        $ rF}| j                   s| j                   sY d}~ y| j#                  d|d       d{  7   Y d}~Ad}~ww xY w6 yw)z6Receive messages from the Ultravox Realtime WebSocket.Nr   statespeakingclient_tool_invocationtoolNamer   
parameters
transcriptr   userfinalzFUnexpected non-final user transcript from Ultravox Realtime; ignoring.rG   agentr   r   Fz>Received transcript with unknown role from Ultravox Realtime: z%Received unhandled Ultravox message: z Ultravox websocket receive errorTr   )r{   rx   r  _handle_audior   loadsr   r~   _handle_response_end_handle_tool_invocationr   ry   _handle_user_transcript_handle_agent_transcriptdebugr   r}   r   )r   r   datar   s       r=   r   z,UltravoxRealtimeLLMService._receive_messages  s    ||!\\ (	Y (	Y''Ygu-,,W555zz'*hhv& //DHHW4E4S"&";";"===1":: HHZ0$((>2JDHHUaLb   &"hhv.!''+xx'8$*NN(p%& +/*F*FtxxPVGW*X$X$X!(&*&C&C$(HHX$6$(HHV$4$(HHW$5$(HHWe$<	'" !" !" "# &&deidj$k!" 'LTF%STI(	Y 6 > %Y!"  Y&&dlloo&H!SWoXXXYK *s   I'I%HI%I'$H
HHI'A H0H	1AH HA)H*H+AHH	8HI'I%H	HHHH	I"I4I':IIII'I""I'r  c                   K   |sy| j                   sy| j                          d{    | j                          d{    | j                  t	                      d{    | j                  t                      d{    d| _         | j                  t        || j                  d             d{    y7 7 ~7 _7 @7 w)z3Handle incoming audio bytes from Ultravox Realtime.NrH   rL   )r~   start_processing_metricsstop_ttfb_metricsr   r   r   r   r   )r   r  s     r=   r  z(UltravoxRealtimeLLMService._handle_audio2  s     ##//111((***//";"=>>>///"3444#*D oo.ud6G6GKLLL 2*>4LsU   #CB:CB< CB> C?C  4C4C5C<C>C CCc                    K   | j                          d {    | j                  dk(  r!| j                  t                      d {    | j                  t	                      d {    d | _        y 7 ]7 /7 w)NrH   )stop_processing_metricsr~   r   r   r   r   s    r=   r!  z/UltravoxRealtimeLLMService._handle_response_end>  sf     **,,,7*///"3444oo57888#	 	-48s3   A:A4/A:A6 A:'A8(A:6A:8A:	tool_nameinvocation_idr  c                 ^   K   | j                  t        |||d       g       d {    y 7 w)N)function_namer   	argumentsr   )run_function_callsr*   )r   r,  r-  r  s       r=   r"  z2UltravoxRealtimeLLMService._handle_tool_invocationE  s9      %%#"+!.( 		
 		
 		
s   #-+-c                    K   | j                  t        | j                  xs dt               ||      t        j
                         d {    y 7 w)Nr   )r  r  r   rG   )r   r   r   r/   r)   UPSTREAMr  s     r=   r#  z2UltravoxRealtimeLLMService._handle_user_transcriptS  sI     oo**0b*,	 ##
 	
 	
s   AA	A
Ar  c                   K   |dk(  ru|s|r2|s0t        |xs |      }d|_        | j                  |       d {    |r<t        |t        j
                        }d|_        | j                  |       d {    y y |dk(  r|rA| j                          d {    | j                  t                      d {    d | _	        y |s|r| j                  sX| j                          d {    | j                          d {    | j                  t                      d {    d| _	        | j                  t        |xs |             d {    y y y 7 7 7 7 7 w7 a7 B7 w)NrH   )rG   F)rG   aggregated_byTrG   )r   append_to_contextr   r    r   WORDincludes_inter_frame_spacesr+  r   r~   r(  r)  r   )r   r   rG   r   r  r   	tts_frames          r=   r$  z3UltravoxRealtimeLLMService._handle_agent_transcript^  sN     W u$$-%8*/'ooe,,,(e?CWCWX	8<	5ooi000  v22444oo&=&?@@@'+$++7799900222//*C*EFFF+1D(ool&FGGG   - 1 5@ :2FGs   7E(E<E(6E7 E(E E(8E9/E((E )E( E" E(!E$"-E(E&E(E(E(E( E("E($E(&E(user_paramsassistant_paramsr;  r<  c                V    t        j                  |      }d|_        t        |||      S )a  Create an instance of LLMContextAggregatorPair from an OpenAILLMContext.

        Constructor keyword arguments for both the user and assistant aggregators can be provided.

        NOTE: this method exists only for backward compatibility. New code
        should instead do::

            context = LLMContext(...)
            context_aggregator = LLMContextAggregatorPair(context)

        Args:
            context: The LLM context to use.
            user_params: User aggregator parameters. Defaults to LLMUserAggregatorParams().
            assistant_params: Assistant aggregator parameters. Defaults to LLMAssistantAggregatorParams().

        Returns:
            A pair of user and assistant context aggregators.

        .. deprecated:: 0.0.99
            `create_context_aggregator()` is deprecated and will be removed in a future version.
            Use the universal `LLMContext` and `LLMContextAggregatorPair` instead.
            See `OpenAILLMContext` docstring for migration guide.
        Fr:  )r#   r   expect_stripped_wordsr&   )r   r   r;  r<  s       r=   create_context_aggregatorz4UltravoxRealtimeLLMService.create_context_aggregatory  s2    > 00916.'?O
 	
r<   );r5   r6   r7   r8   r2   Settingsr:   r
   r?   rZ   rb   r	   r   rv   boolr   r   r   staticmethodr   r9   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r   r#   r   r"   r   r   r   r   r   r  r   r   r  r!  r"  r#  r$  r%   r$   r'   r&   r?  __classcell__)r   s   @r=   re   re      sG    +H** ;?9=<4 &(:<NNO<4 67	<4
 "*+!6<4|d R R. hw/G&H XVY]  :.> :3 :6:1C : :@{ tDcN7K .! !!+ !&,G 4 4> 4>-Z - B=X B& ,>  F# FQ QR5S#X)>#? R.,Y\
M 
M$

-0
>B38n
	
# 	
HH!)#H7?}HMQH> 0G/H9U9W#
!#
 -	#

 7#
 
"#
r<   re   )Nr8   asynciorW   r   rT   dataclassesr   r   typingr   r   r   r   r	   r
   r   logurur   pydanticr   r   %pipecat.adapters.schemas.tools_schemar   pipecat.audio.utilsr   pipecat.frames.framesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   *pipecat.processors.aggregators.llm_contextr#   +pipecat.processors.aggregators.llm_responser$   r%   5pipecat.processors.aggregators.llm_response_universalr&   1pipecat.processors.aggregators.openai_llm_contextr'   r(   "pipecat.processors.frame_processorr)   pipecat.services.llm_servicer*   r+   pipecat.services.settingsr,   r-   r.   pipecat.utils.timer/   websockets.asyncior0   r   ModuleNotFoundErrorr   errorr   r2   r?   rZ   rb   re   r;   r<   r=   <module>rW     s       ( < <   % = 7     * B [ > H G G /,= >+ > >8y 8B8 8B ~
 ~
{  ,FLL;qc"#FLL\]
&qc*
++,s   .C1 1D-62D((D-